`opencode attach` was invoked inside a freshly-split tmux pane before the
child session appeared in the opencode server's status map. The process
exited immediately (session not found), tmux auto-closed the pane, and the
subagent ran invisibly in the background — the race documented in #3505.
Fix: call `waitForSessionReady` *before* `executeActions` in
`session-created-handler.ts`, mirroring the guard already present in
`TmuxSessionManager.ensureSessionReadyBeforeSpawn()`. If the session does
not become attachable within the timeout the handler returns early without
spawning a pane at all, eliminating the transient-pane and silent-close
failure modes. The now-unreachable post-spawn readiness-check / pane-close
cleanup branch is removed.
Adds a regression test suite (session-created-handler.test.ts) covering:
- not-ready session → no pane spawned, no polling started
- duplicate session.created → idempotent
- non session.created event type → no action
- already-tracked session → idempotent
Closes#3505
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Handle OpenCode session events that carry the session ID under properties.info.id or properties.info.sessionID so background tasks and continuation hooks do not miss idle/error/delete events.
Add regression coverage for nested session.idle events completing background tasks and waking continuation hooks.
The previous commit (2dfa6336f) used 'git add -A' which swept up files that
prior commits had intentionally deleted but were still present untracked in
the local workspace. This commit re-deletes them to match the upstream intent.
Files removed (each was previously deleted in the cited commit):
- drafts/gpt-5-5/{README,deep,hephaestus,oracle,sisyphus-junior,sisyphus}.md
(deleted in 40ded422c chore(drafts): remove stale gpt-5.5 prompt drafts)
- src/plugin-dispose.{ts,test.ts}
(deleted in e2f5c0d36 refactor(plugin): remove orphaned createPluginDispose)
- src/features/tmux-subagent/{cleanup,session-created-handler,session-deleted-handler}.ts
(deleted in 7a7926f22 chore(tmux-subagent): remove dead event-handler modules)
- src/tools/delegate-task/{model-string-parser,resolve-call-id,resolve-call-id.test}.ts
(model-string-parser deleted in db056346d; resolve-call-id was scratch)
- src/__debug-test.test.ts (debug scratch never intended for git)
Typecheck + model-requirements tests still pass. The legitimate metis +
AGENTS.md edits from the previous commit remain on dev.
Source code change:
- src/shared/model-requirements.ts: prepend claude-sonnet-4-6 to metis fallback
chain so Sonnet becomes the default. Opus 4.7 max remains as the immediate
fallback for callers who want extra reasoning.
- src/shared/model-requirements.test.ts: update assertion to expect Sonnet
primary + Opus secondary.
AGENTS.md accuracy fixes (verified against source):
- Agent modes: Sisyphus/Hephaestus are 'primary' (not 'all'); Sisyphus-Junior
is 'subagent' (not 'all'). Confirmed via 'const MODE: AgentMode = ...' in
each agent file. Also clarified Prometheus has no agentSources factory and
is built via buildPrometheusAgentConfig.
- Sisyphus fallback chain: corrected order to kimi-k2.6 → k2p5 → kimi-k2.5
→ gpt-5.5 medium → glm-5 → big-pickle (was missing kimi-k2.5).
- Librarian/Explore: added missing minimax-m2.7 step between -highspeed and
claude-haiku-4-5.
- Metis chain: removed fictitious gemini-3.1-pro entry.
- Sisyphus-Junior chain: spelled out the actual fallback (was 'user-configurable').
- Temperatures: Sisyphus/Hephaestus do not set explicit temperature (model
default); Sisyphus-Junior is 0.1 via SISYPHUS_JUNIOR_DEFAULTS.
- Quick category default: gpt-5.4-mini (not gpt-5.4-mini-fast).
Team-mode corrections:
- Eligibility registry has 3 verdicts: eligible (sisyphus, atlas, sisyphus-junior),
conditional (hephaestus — needs D-36 teammate permission), hard-reject
(oracle, librarian, explore, multimodal-looker, metis, momus, prometheus).
- Schema has 11 fields, not 4: added max_messages_per_run, max_wall_clock_minutes,
max_member_turns, base_dir, message_payload_max_bytes, recipient_unread_max_bytes,
mailbox_poll_interval_ms.
- Hooks: 'team-session-events' is 4 sub-handlers in src/plugin/event.ts
(team-idle-wake-hint, team-lead-orphan-handler, team-member-error-handler,
team-member-status-handler), not a single Continuation-tier hook.
- Tier counts now show base + team-mode: ToolGuard 14/15, Transform 5/7.
- Total: 52 base hooks, 59 with team-mode.
Doc cascade for the Metis change:
- docs/guide/orchestration.md, agent-model-matching.md, installation.md
- docs/reference/configuration.md, features.md
Drop cleanup.ts, session-created-handler.ts, and session-deleted-handler.ts
which were never wired up; the lifecycle logic they contained lives inline
in TmuxSessionManager. Barrels trimmed to match.
When queryWindowState returned null during session deletion, the
session mapping was deleted but the real tmux pane stayed alive,
creating zombie panes.
- Add closePending/closeRetryCount fields to TrackedSession
- Mark sessions closePending instead of deleting on close failure
- Add retryPendingCloses() called from onSessionCreated and cleanup
- Force-remove mappings after 3 failed retry attempts
- Extract TrackedSessionState helper for field initialization
Tests: 3 pass, 9 expects