From 42190f007f4f9950e7ef0ef2fb36d94d5861b224 Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Mon, 10 Aug 2026 12:50:36 +0100 Subject: [PATCH] say what the live opencode rows actually do MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two comments describing behaviour the code does not have. LiveOpenCodeSession had been inserted between LiveClaudeSession and its docblock, so a comment about isGenerating, pendingTasks and the idle GC read as documentation for the OpenCode type — where it is contradicted by the correct comment directly beneath it. Moved below, and it now states that it carries no ses_ id. That absence is the point: /chat/live claimed title and cwd come from the session store "so a turn whose id has not been reported yet shows unnamed". Nothing is looked up, and there is no id here to look one up with. They are null permanently, not until-known. Co-Authored-By: Claude Opus 5 --- src/servers/api/chat/chat.ts | 10 +++++++--- src/servers/sidecar/protocol.ts | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/servers/api/chat/chat.ts b/src/servers/api/chat/chat.ts index 08c7d89e..d29113f5 100644 --- a/src/servers/api/chat/chat.ts +++ b/src/servers/api/chat/chat.ts @@ -122,9 +122,13 @@ chatRouter.get('/live', async (ctx) => { // OpenCode rows carry less, and the shape says so rather than faking parity. `isGenerating` is always // true because a subprocess exists only while it generates; `pendingTasks` is 0 because `opencode run` - // has no background-task concept. Title and cwd come from the session store, which is keyed on the - // `ses_…` id the runner reports — not on our sessionKey — so a turn whose id has not been reported yet - // shows unnamed rather than guessing. + // has no background-task concept. + // + // Title and cwd are ALWAYS null here, not merely null-until-known: naming a session means reading + // OpenCode's store, which is keyed on the `ses_…` id, and `LiveOpenCodeSession` does not carry one — + // the runner reports it separately over `opencode:session` and nothing correlates the two. So a + // running OpenCode turn shows up unnamed, every time. Giving it a title means widening that type + // first; guessing from `sessionKey` would be inventing one. const openCodeSessions = liveOpenCode.map((session) => ({ sessionKey: session.sessionKey, claudeSessionId: null, diff --git a/src/servers/sidecar/protocol.ts b/src/servers/sidecar/protocol.ts index ad05f5ae..198c9cac 100644 --- a/src/servers/sidecar/protocol.ts +++ b/src/servers/sidecar/protocol.ts @@ -11,14 +11,6 @@ export type SidecarMessage = SidecarCommand | SidecarEvent; * together with `isGenerating` it is exactly what the agent's own idle GC consults before deciding a * session may be collected, so a caller can tell "busy" from "merely open" the same way it does. */ -/** - * An OpenCode turn in flight. Only ever the generating ones — see `listRunningOpenCodeTurns` for why - * this carries neither `isGenerating` (it is always true) nor `pendingTasks` (no such concept). - */ -export type LiveOpenCodeSession = { - sessionKey: string; -}; - export type LiveClaudeSession = { sessionKey: string; /** @@ -33,6 +25,18 @@ export type LiveClaudeSession = { pendingTasks: number; }; +/** + * An OpenCode turn in flight. Only ever the generating ones — see `listRunningOpenCodeTurns` for why + * this carries neither `isGenerating` (it is always true) nor `pendingTasks` (no such concept). + * + * It also carries no id for OpenCode's own `ses_…` session, which is why a live OpenCode row cannot be + * named: the runner reports that id separately, over `opencode:session`, and nothing correlates the two + * back here. Adding it is what a titled OpenCode row in the Live panel would need. + */ +export type LiveOpenCodeSession = { + sessionKey: string; +}; + // ── Commands (API server → sidecar) ── export type SidecarCommand =