show running opencode turns in the live panel

The Live panel asked `claude:list` and nothing else, so a running OpenCode turn was invisible — the panel
claimed to show what the agent is doing and silently omitted half of it.

Adds `opencode:list` / `opencode:sessions` and merges both harnesses in `/chat/live`, asked in parallel,
each failing toward empty so one sidecar being down contributes nothing rather than breaking the panel.

The OpenCode row is deliberately thinner than the Claude one rather than faked into parity:

  isGenerating  always true — a subprocess exists only while it generates, so there is no "merely open"
  pendingTasks  always 0    — `opencode run` has no background-task concept; reporting a number would
                              suggest a capability that does not exist
  title / cwd   null        — the session store is keyed on the `ses_…` id the runner reports, not on
                              our sessionKey, so an unreported turn shows unnamed rather than guessed

This is the incremental option from docs/opencode-serve-path.md — enumeration without moving turns onto
the serve, so it buys the Live panel with no warm sessions, no SSE loop and no lifetime questions.

NOT verified end to end: no OpenCode turn was running to enumerate, so the verb is wired and typechecked
but has never returned a non-empty list. See COMMS/BLOCKERS.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 03:00:43 +00:00
co-authored by Claude Opus 5
parent 8b409e8af8
commit e8bd946272
5 changed files with 76 additions and 4 deletions
+15
View File
@@ -200,6 +200,21 @@ export function runOpenCodeTurn(params: OpenCodeRunParams, config: RunnerConfig,
});
}
/**
* The turns this process is running right now.
*
* The OpenCode analog of `claude-manager.listSessions`, and deliberately thinner. Claude holds a warm
* session that outlives a turn, so it can report one that is merely open; OpenCode spawns a subprocess
* per turn and has nothing between them. So a session appears here only while it is generating — which
* is exactly the state the Live panel exists to show, and the state that was invisible for OpenCode.
*
* No `pendingTasks`: `opencode run` has no background-task concept, so reporting 0 would suggest a
* capability that does not exist rather than an empty one.
*/
export function listRunningOpenCodeTurns(): { sessionKey: string }[] {
return Array.from(running.keys()).map((sessionKey) => ({ sessionKey }));
}
export function killOpenCodeTurn(sessionKey: string): void {
const handle = running.get(sessionKey);
if (!handle) return;