From 1c1cb7115ac571b19fed27ade99eb40d1d33dbca Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Tue, 8 Sep 2026 21:50:51 -0700 Subject: [PATCH] fix(orchestration): unify structured-session status across worktree ps and sidebar (#19217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(orchestration): stop worktree ps reporting a busy structured session as idle A worktree running a structured Claude or Codex chat read as idle to `orca worktree ps`, while the desktop sidebar showed the same session working. The sidebar was right: the host already projects a status summary for every structured session and publishes it, and the renderer maps it into an agent row. `worktree ps` simply never consumed it, so the agent-facing surface was the blind one. Structured sessions have no PTY, so they reach neither the hook snapshots nor the retained ones that every other row is built from. This reads the summaries the host has already published and applies the same projection the sidebar does — working, attention as blocked, otherwise done — so the CLI and the GUI cannot disagree about one session. Two things worth knowing: The connected-PTY evidence gate had to be skipped for these rows. It exists to drop a row whose PTY is gone, which is the wrong question for a session that never had one; a structured row's liveness evidence is the status feed that produced it. The exemption is keyed on the row being structured, so every PTY-backed row keeps today's behaviour. `RuntimeWorktreeAgentRow` needed no change. It was already a non-PTY shape — paneKey, state, agentType, and no ptyId, connected or writable — so a structured row fits without inventing a fake terminal coordinate. The pane key is the DERIVED one the renderer already publishes, never the orchestration bearer handle or the minted worker pane key: both are credentials, since `orchestration check` is identity-gated and accepts a caller-supplied pane key. `orca terminal list` is deliberately untouched, and a test pins that. Adding rows there breaks real consumers: mobile mounts a terminal WebView per row that can never receive a frame, a `connected`-keyed refresh check goes permanently true and pins shipped clients to a fast cadence with no exit, and the plugin projection has no field that can carry `writable: false`. Every safe consumer of a terminal summary checks `ptyId`; the breaking ones key off `connected` or mere row presence, which no added field can qualify. An honest partial-listing count there is a separate change. * fix(runtime): report only live structured sessions in worktree ps The status feed's `published` map is a broadcast cache, not a roster. It deliberately never retracts — an evicted idle session is still idle, and a reloading renderer must not lose every settled row — so enumerating it lists every session the host has ever opened, and eviction's `forget-session` step deletes the session from the live map while touching nothing else. Reading it as a roster made `worktree ps` report a closed chat forever. The sharp edge is a chat closed while an approval was pending: a deliberate close does not settle a pending prompt, so the retained summary stays `attention`, maps to a `blocked` row, and merges the worktree to `permission` for the whole 30-minute freshness window — on the CLI and on the mobile sidebar it backs. The poller now answers from the sessions the host still holds, intersecting the live map with the retained projections. `subscribe()` and its snapshot are untouched: retention there is the point. Gating on the live session set rather than the visible tabs keeps a headless orchestration worker listed, which is what the agent-facing surface is for. Also folds out two things the enumerator left behind: the working/attention/idle to working/blocked/done mapping now lives once in the shared projection module instead of once per process, which is what actually enforces "the CLI and the GUI cannot disagree"; and the structured row source no longer builds a write-only `payload` behind an `as` cast that compensated for nothing. The structured source construction moves to its own module to keep runtime-worktree-agent-rows.ts clear of the 300-line cap. * test(runtime): execute the structured-host call site in worktree ps Both structured-row suites called attachRuntimeWorktreeAgentRows directly with summaries they built themselves, so nothing ever ran getWorktreePs's own `getStructuredAgentSessionHost()?.liveSessionStatusSummaries()`. That file carries `@ts-nocheck`, so renaming the accessor was green in typecheck and in the suite, while `orca worktree ps` and mobile's 3s poll would throw a TypeError for every user — the `?.` optional-chains the host, not the method. Swapping the call back to a whole-cache read was equally invisible: the liveness suite injects feed.liveSessionSummaries() itself, and the string-match guard only needs the identifier to appear somewhere in the file. Drives the real runtime with a stub host over a real status feed that has published two sessions and forgotten one, asserting the live session's row reaches ps output, that the live accessor is the one called, and that the `?? []` fallback still returns a page with no host installed. The stub is typed against the real host, so a class-side rename reddens tc here. * refactor(runtime): admit agent sources before worktree row projection * fix(runtime): preserve host-authoritative structured status * Fix structured host session activity lifecycle --------- Co-authored-by: Merge Sim --- docs/review-evidence/pr-19217/README.md | 46 +++++ docs/review-evidence/pr-19217/closed.png | Bin 0 -> 105757 bytes docs/review-evidence/pr-19217/working.png | Bin 0 -> 111788 bytes ...structured-agent-session-attach-context.ts | 1 + ...structured-agent-session-event-recovery.ts | 1 + .../structured-agent-session-host-handoff.ts | 3 + .../structured-agent-session-host-lifetime.ts | 14 +- .../structured-agent-session-host.ts | 24 +-- ...ructured-agent-session-status-feed.test.ts | 82 ++++++++- .../structured-agent-session-status-feed.ts | 38 +++++ ...tructured-agent-session-unexpected-exit.ts | 3 + .../structured-rewind-claude-owner.ts | 1 + .../runtime/orca-runtime-get-worktree-ps.ts | 14 +- .../worktree-ps-structured-host.spec.ts | 146 ++++++++++++++++ src/main/runtime/orca-runtime.test.ts | 1 + ...ime-worktree-agent-rows-structured.test.ts | 120 +++++++++++++ .../runtime/runtime-worktree-agent-rows.ts | 142 ++-------------- .../runtime/runtime-worktree-agent-source.ts | 21 +++ .../runtime-worktree-agent-sources.test.ts | 70 ++++++++ .../runtime/runtime-worktree-agent-sources.ts | 22 +++ .../runtime-worktree-pty-agent-sources.ts | 121 ++++++++++++++ ...ree-structured-agent-rows-liveness.test.ts | 157 ++++++++++++++++++ .../runtime-worktree-structured-agent-rows.ts | 48 ++++++ ...tructuredAgentSessionStatusBridge.test.tsx | 22 +++ .../StructuredAgentSessionStatusBridge.tsx | 19 ++- src/renderer/src/lib/pane-agent-evidence.ts | 10 +- ...gent-session-status-feed-lifecycle.test.ts | 115 +++++++++++++ .../structured-agent-session-status-feed.ts | 44 ++++- .../src/store/slices/agent-status-contract.ts | 2 + .../slices/agent-status-live-entry-builder.ts | 1 + src/shared/agent-session-wire.ts | 2 + src/shared/agent-status-freshness.ts | 4 +- src/shared/agent-status-types.ts | 2 + .../structured-agent-session-projection.ts | 8 + 34 files changed, 1132 insertions(+), 172 deletions(-) create mode 100644 docs/review-evidence/pr-19217/README.md create mode 100644 docs/review-evidence/pr-19217/closed.png create mode 100644 docs/review-evidence/pr-19217/working.png create mode 100644 src/main/runtime/orca-runtime-tests/worktree-ps-structured-host.spec.ts create mode 100644 src/main/runtime/runtime-worktree-agent-rows-structured.test.ts create mode 100644 src/main/runtime/runtime-worktree-agent-source.ts create mode 100644 src/main/runtime/runtime-worktree-agent-sources.test.ts create mode 100644 src/main/runtime/runtime-worktree-agent-sources.ts create mode 100644 src/main/runtime/runtime-worktree-pty-agent-sources.ts create mode 100644 src/main/runtime/runtime-worktree-structured-agent-rows-liveness.test.ts create mode 100644 src/main/runtime/runtime-worktree-structured-agent-rows.ts create mode 100644 src/renderer/src/runtime/structured-agent-session-status-feed-lifecycle.test.ts diff --git a/docs/review-evidence/pr-19217/README.md b/docs/review-evidence/pr-19217/README.md new file mode 100644 index 00000000000..ca664ae0c9a --- /dev/null +++ b/docs/review-evidence/pr-19217/README.md @@ -0,0 +1,46 @@ +# Structured worktree status validation + +Validated on September 7, 2026 in a background Electron dev instance of +`pr19217-review-r2`, based on `ce1024096b` with the source-adapter refactor. +CDP app identity confirmed the checkout; screenshots show the full hidden renderer. +The command output is the real `orca worktree ps --json` response reduced to status, +agent state, provider, and pane key for readability. + +## Functional correctness + +A real Codex structured session appeared as `working` in `worktree.ps` while the +sidebar showed working. Closing its chat tab removed that exact session's row and +returned the worktree to `active`. A different completed chat remained present, +confirming that closure removed only the selected session. + +- [Working: CLI and sidebar](working.png) +- [Closed: CLI and sidebar](closed.png) + +The disappearing session is `codex_40677067_f492_4d7d_86dd_ec566ede04c3`. +The host's held-session roster controls eligibility; its retained broadcast cache +is history, not a roster. Failed eviction intentionally keeps an entry for retry. + +## Architecture + +PTY reconciliation and process admission belong to the PTY source adapter. +Structured input comes from the current host's held-session projections. One +admitted collection feeds row shaping and worktree aggregation, with no structured +boolean bypass. PTY hooks and retained reports still arrive independently, so their +precedence and conservative remote evidence rules remain necessary. No second +persistent status store or provider polling was introduced. + +## Validation and limits + +Independent final review found no proven issues. Runtime, host lifecycle, status +feed and source-admission suites passed: 1,344 tests, one skipped. Node typecheck, +targeted lint and diff checks passed. Ablating the runtime call to enumerate +retained history caused the executable call-site test to fail with two rows where +one was expected; restoring the live accessor passed both call-site tests. + +Live screenshots prove Codex working and closure on macOS. Claude provider turns, +approval/input states, live Windows/Linux/WSL/SSH/relay/mobile scenarios and +release-scale latency/heap measurements remain unverified. Existing tests cover +remote/WSL evidence, monitoring precedence and lifecycle cases. The existing +30-minute freshness rule and CLI activity timestamps are preserved; complete +CLI/sidebar timing parity is not claimed. The wire keeps its existing row shape +and status vocabulary; mobile receives the new rows without a new opcode. diff --git a/docs/review-evidence/pr-19217/closed.png b/docs/review-evidence/pr-19217/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..7f1d816084489b4b21274caaa9933ef068c314ab GIT binary patch literal 105757 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

t- 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 literal 0 HcmV?d00001 diff --git a/docs/review-evidence/pr-19217/working.png b/docs/review-evidence/pr-19217/working.png new file mode 100644 index 0000000000000000000000000000000000000000..8ee570521348e613259e8f24b02c32a0e8378458 GIT binary patch literal 111788 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%0AciO~urB3i*wxg}JQcuH82rb5k-o|?+vk)vOD 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 literal 0 HcmV?d00001 diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-attach-context.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-attach-context.ts index 412aa88025d..986fcefadbf 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-attach-context.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-attach-context.ts @@ -38,4 +38,5 @@ export type StructuredAgentSessionAttachContext = { reconcileLeases: (sessionId: string) => Promise serialize: (sessionId: string, task: () => Promise) => Promise now: () => number + publishStatus?: (sessionId: string) => void } diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-event-recovery.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-event-recovery.ts index 5f9894c3280..728942b6347 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-event-recovery.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-event-recovery.ts @@ -22,6 +22,7 @@ export class StructuredAgentSessionEventRecovery { sessions: Map flushLifecycle: (sessionId: string) => Promise publishFence: (sessionId: string, session: StructuredAgentSessionHostSession) => void + publishStatus?: (sessionId: string) => void hasResumeCapableHolder: (sessionId: string) => boolean serialize: (sessionId: string, task: () => Promise) => Promise now: () => number diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-host-handoff.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-host-handoff.ts index 7c8c65a5292..3495409f127 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-host-handoff.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-host-handoff.ts @@ -25,6 +25,7 @@ type HostHandoffAccess = { flush: (sessionId: string) => Promise serialize: (sessionId: string, task: () => Promise) => Promise subscribers: AgentSessionSubscribers + publishStatus?: (sessionId: string) => void now: () => number } @@ -82,6 +83,7 @@ export function createStructuredAgentSessionHostHandoff( return { state: 'live' } } host.session(sessionId).hasProviderChild = false + host.publishStatus?.(sessionId) try { await host.flush(sessionId) host.eventSink(sessionId).unbind() @@ -243,6 +245,7 @@ export async function acquireNativeHandoffOwner( return rethrowAfterAgentSessionAcquisitionCleanup(deps.adapter, input.sessionId, error) } session.hasProviderChild = true + host.publishStatus?.(input.sessionId) session.fence = proved.lease.runtimeFence session.acquisitionGeneration = acquired.acquisitionGeneration ?? null eventSink.bind({ diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-host-lifetime.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-host-lifetime.ts index ba62db1704e..d1664bc985b 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-host-lifetime.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-host-lifetime.ts @@ -93,13 +93,19 @@ export async function resumeStructuredAgentSessionForHold( export function createStructuredAgentSessionHolds( context: StructuredAgentSessionLifetimeContext, input: { - resume: (sessionId: string) => Promise - evict: (sessionId: string) => Promise + reconcileLeases: (sessionId: string) => Promise + attach: Parameters[0]['attach'] + close: (sessionId: string) => Promise } ): StructuredAgentSessionHolds { return new StructuredAgentSessionHolds({ - resume: input.resume, - evict: input.evict, + resume: (sessionId) => + resumeStructuredAgentSessionForHold( + { ...context, reconcileLeases: input.reconcileLeases }, + sessionId, + input.attach + ), + evict: input.close, hasProviderChild: (sessionId) => hasProviderChild(context, sessionId), isTurnActive: (sessionId) => { const session = context.sessions.get(sessionId) diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts index 257c7a4e4f7..2df2fdf5412 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-host.ts @@ -27,7 +27,6 @@ import { attachStructuredAgentSession } from './structured-agent-session-attach- import { createStructuredAgentSessionHolds, evictHeldStructuredAgentSession, - resumeStructuredAgentSessionForHold, type StructuredAgentSessionLifetimeContext } from './structured-agent-session-host-lifetime' import type { @@ -118,16 +117,13 @@ export class StructuredAgentSessionHost { flush: (sessionId) => this.flushStreamedEvents(sessionId), serialize: (sessionId, task) => this.serialize(sessionId, task), subscribers: this.subscribers, + publishStatus: (sessionId) => this.statusFeed.publish(sessionId), now: this.now }) this.holds = createStructuredAgentSessionHolds(this.lifetimeContext(), { - resume: (sessionId) => - resumeStructuredAgentSessionForHold( - { ...this.lifetimeContext(), reconcileLeases: this.reconcileLeases }, - sessionId, - (params) => this.attach({ callerKey: 'trusted-local:surface-hold' }, params) - ), - evict: (sessionId) => this.close(sessionId) + reconcileLeases: this.reconcileLeases, + attach: (params) => this.attach({ callerKey: 'trusted-local:surface-hold' }, params), + close: (sessionId) => this.close(sessionId) }) this.restore = createStructuredAgentSessionHostRestore(deps, this.sessions, () => this.now(), { reconcile: this.reconcileLeases, @@ -149,6 +145,7 @@ export class StructuredAgentSessionHost { flushLifecycle: (sessionId) => this.runtimeState.lifecycleBarrier(sessionId), publishFence: (sessionId, session) => this.subscribers.snapshot(sessionId, session.journal, session.fence), + publishStatus: (sessionId) => this.statusFeed.publish(sessionId), hasResumeCapableHolder: (sessionId) => this.holds.hasResumeCapableHolder(sessionId), serialize: (sessionId, task) => this.serialize(sessionId, task), now: () => this.now(), @@ -193,7 +190,8 @@ export class StructuredAgentSessionHost { subscribers: this.subscribers, tasks: this.tasks, reconcileLeases: (sessionId) => this.reconcileLeases(sessionId), - serialize: (sessionId, task) => this.serialize(sessionId, task) + serialize: (sessionId, task) => this.serialize(sessionId, task), + publishStatus: (sessionId) => this.statusFeed.publish(sessionId) } } /** Releases a session's resources without ending the conversation: the record and journal stay @@ -202,6 +200,7 @@ export class StructuredAgentSessionHost { return this.serialize(sessionId, async () => { await this.handoffs.closeRetainedTuiOwner(sessionId) await evictHeldStructuredAgentSession(this.lifetimeContext(), sessionId) + this.statusFeed.revokeLive(sessionId) // Whoever asked for the close, the surfaces that were holding this session are looking at a // session that no longer exists. A failed eviction throws above and keeps them. this.holds.forget(sessionId) @@ -213,8 +212,11 @@ export class StructuredAgentSessionHost { listSessionTabs = () => listStructuredAgentSessionTabs(this.sessions) - getPersistedVisibleSessionTabIndex = (): { present: boolean; sessionIds: string[] } => - this.deps.store.getVisibleSessionTabIndex() + /** Last projected status for every structured session this host still holds, for non-subscribing + * readers. The retained projections of forgotten sessions are deliberately not included. */ + readonly liveSessionStatusSummaries = () => this.statusFeed.liveSessionSummaries() + + getPersistedVisibleSessionTabIndex = () => this.deps.store.getVisibleSessionTabIndex() setSessionTabVisibility = (sessionId: string, visible: boolean): Promise => this.deps.store.setSessionTabVisibility(sessionId, visible) diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.test.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.test.ts index c1b52f879d4..1e3b9bb25a3 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.test.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.test.ts @@ -53,15 +53,24 @@ async function openJournal(sessionId = SESSION, now?: () => number) { }) } -function indexed(session: { journal: Awaited> }) { +function indexed(session: { + journal: Awaited> + hasProviderChild?: boolean +}) { return { journal: session.journal, + ...(session.hasProviderChild !== undefined + ? { hasProviderChild: session.hasProviderChild } + : {}), params: { location: { workspaceId: 'workspace-1' }, provider: 'codex' as const } } } function feedFor( - sessions: Map> }>, + sessions: Map< + string, + { journal: Awaited>; hasProviderChild?: boolean } + >, record: Partial | null = null, onStatusChanged?: StructuredAgentSessionStatusFeedDeps['onStatusChanged'] ) { @@ -88,6 +97,41 @@ function feedFor( } describe('StructuredAgentSessionStatusFeed', () => { + it('publishes provider ownership transitions without changing journal time', async () => { + const journal = await openJournal() + const sessions = new Map([[SESSION, { journal, hasProviderChild: true }]]) + const { feed, events, dispose } = feedFor(sessions) + events.length = 0 + await journal.appendItem( + USER_IDENTITY, + { kind: 'message', role: 'user', blocks: [{ type: 'text', text: 'hello' }] }, + { fence: 1 } + ) + feed.publish(SESSION, journal) + expect(events.at(-1)).toEqual({ + type: 'status', + session: expect.objectContaining({ hostExecutionOwned: true, updatedAt: expect.any(Number) }) + }) + const firstStatus = events.at(-1) + expect(firstStatus?.type).toBe('status') + if (firstStatus?.type !== 'status') { + throw new Error('status publication missing') + } + const journalTime = firstStatus.session.updatedAt + sessions.get(SESSION)!.hasProviderChild = false + feed.publish(SESSION, journal) + expect(events.at(-1)).toEqual({ + type: 'status', + session: expect.objectContaining({ status: 'idle', updatedAt: journalTime }) + }) + const secondStatus = events.at(-1) + expect(secondStatus?.type).toBe('status') + if (secondStatus?.type === 'status') { + expect(secondStatus.session).not.toHaveProperty('hostExecutionOwned') + } + dispose() + }) + it('opens with every readable session and reports no status before a persisted turn', async () => { const journal = await openJournal() const { events } = feedFor(new Map([[SESSION, { journal }]])) @@ -523,3 +567,37 @@ describe('StructuredAgentSessionStatusFeed', () => { }) }) }) + +/** + * `published` is a broadcast cache, not a roster. It deliberately never retracts — an evicted idle + * session is still idle, and a reloading renderer must not lose every settled row — so enumerating + * it lists every session this host has ever opened. Eviction's `forget-session` step deletes the + * session from the live map and touches nothing else, so a poller has to intersect with that map. + */ +describe('the polling reader answers from the live sessions, not the retained cache', () => { + it('drops an evicted session from the poll while a late subscriber still sees it', async () => { + const journal = await openJournal() + const sessions = new Map([[SESSION, { journal }]]) + const { feed } = feedFor(sessions) + await journal.appendItem( + USER_IDENTITY, + { kind: 'message', role: 'user', blocks: [{ type: 'text', text: 'hello' }] }, + { fence: 1 } + ) + feed.publish(SESSION, journal) + expect(feed.liveSessionSummaries().map((summary) => summary.sessionId)).toEqual([SESSION]) + + // Exactly what eviction's `forget-session` step does; nothing else touches the feed. + sessions.delete(SESSION) + + expect(feed.liveSessionSummaries()).toEqual([]) + const late: AgentSessionStatusEvent[] = [] + feed.subscribe({ id: 'list-2', emit: (event) => late.push(event) }) + expect(late).toEqual([ + { + type: 'snapshot', + sessions: [expect.objectContaining({ sessionId: SESSION, status: 'idle' })] + } + ]) + }) +}) diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.ts index cfd85ff4648..61d9649587e 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-status-feed.ts @@ -30,6 +30,7 @@ export type StructuredAgentSessionStatusSubscriber = { type StatusFeedSession = { journal: AgentSessionJournal params: { location: { workspaceId: string }; provider: AgentSessionRecord['provider'] } + hasProviderChild?: boolean } export type StructuredAgentSessionStatusFeedDeps = { @@ -46,6 +47,7 @@ function summariesEqual(a: AgentSessionStatusSummary, b: AgentSessionStatusSumma a.workspaceId === b.workspaceId && a.agent === b.agent && a.status === b.status && + a.hostExecutionOwned === b.hostExecutionOwned && a.rewindBlockedReason === b.rewindBlockedReason && // Settled activity changes ranking; streaming active turns must stay quiet. (a.status !== 'idle' || a.updatedAt === b.updatedAt) && @@ -76,6 +78,27 @@ export class StructuredAgentSessionStatusFeed { return () => this.unsubscribe(subscriber.id) } + /** + * Summaries for the sessions this host still holds, for readers that poll instead of subscribing. + * + * `published` never retracts, so it is a broadcast cache and not a roster: enumerating it lists + * every session ever opened here. A caller asking what is running gets the live intersection, + * while the retained view a subscriber opens on stays whole. + * + * Deliberately does NOT re-project: a subscriber's snapshot is the live read, and re-running the + * journal reduction per caller would make an enumerating command pay for every session it lists. + */ + liveSessionSummaries(): AgentSessionStatusSummary[] { + const summaries: AgentSessionStatusSummary[] = [] + for (const [sessionId] of this.deps.sessions) { + const summary = this.published.get(sessionId) + if (summary) { + summaries.push(summary) + } + } + return summaries + } + unsubscribe(id: string): void { const subscriber = this.subscribers.get(id) if (!subscriber) { @@ -89,6 +112,20 @@ export class StructuredAgentSessionStatusFeed { } } + /** Revoke live execution authority while retaining the last projection for reload history. */ + revokeLive(sessionId: string): void { + const previous = this.published.get(sessionId) + if (!previous) { + return + } + const { hostExecutionOwned: _hostExecutionOwned, ...retained } = previous + this.published.set(sessionId, retained) + this.broadcast({ + type: 'status', + session: retained + }) + } + /** Re-projects one session after its journal changed; equal projections are not re-sent. */ publish(sessionId: string, journal?: AgentSessionJournal, options?: { replay?: boolean }): void { const session = this.deps.sessions.get(sessionId) @@ -126,6 +163,7 @@ export class StructuredAgentSessionStatusFeed { sessionId, workspaceId: session.params.location.workspaceId, agent: session.params.provider, + ...(session.hasProviderChild ? { hostExecutionOwned: true as const } : {}), ...projectStructuredAgentSessionStatusSummary(items), ...(record?.rewind?.phase === 'prepared' || record?.rewind?.phase === 'provider-succeeded' ? { rewindBlockedReason: 'outcome-unknown' as const } diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-unexpected-exit.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-unexpected-exit.ts index 87fe0cbbeec..ddc4af9f2d3 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-unexpected-exit.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-unexpected-exit.ts @@ -32,6 +32,7 @@ export type StructuredAgentSessionUnexpectedExitContext = { sessions: Map flushLifecycle: (sessionId: string) => Promise publishFence: (sessionId: string, session: StructuredAgentSessionHostSession) => void + publishStatus?: (sessionId: string) => void hasResumeCapableHolder: (sessionId: string) => boolean serialize: (sessionId: string, task: () => Promise) => Promise now: () => number @@ -59,6 +60,7 @@ export async function settleUnexpectedStructuredAgentSessionExit( if (!record || record.lease.handoffStage !== null) { // The handoff coordinator owns an already-started transition. session.hasProviderChild = false + context.publishStatus?.(unexpectedEvent.sessionId) return null } @@ -117,6 +119,7 @@ export async function settleUnexpectedStructuredAgentSessionExit( context.onBarrierError?.(unexpectedEvent.sessionId, error) } finally { session.hasProviderChild = false + context.publishStatus?.(unexpectedEvent.sessionId) if (released) { session.fence = released.lease.runtimeFence context.publishFence(unexpectedEvent.sessionId, session) diff --git a/src/main/native-chat/agent-session-wire/structured-rewind-claude-owner.ts b/src/main/native-chat/agent-session-wire/structured-rewind-claude-owner.ts index f1108df181c..13d2b51f284 100644 --- a/src/main/native-chat/agent-session-wire/structured-rewind-claude-owner.ts +++ b/src/main/native-chat/agent-session-wire/structured-rewind-claude-owner.ts @@ -21,6 +21,7 @@ export async function replaceClaudeRewindOwner( return rewindRefusal('outcome-unknown') } session.hasProviderChild = false + context.publishStatus?.(sessionId) const head = agentSessionProviderHandleChainHead( context.deps.store.getRecord(sessionId)!.providerHandleChain )?.handle diff --git a/src/main/runtime/orca-runtime-get-worktree-ps.ts b/src/main/runtime/orca-runtime-get-worktree-ps.ts index 240156d93c6..3dbd8809018 100644 --- a/src/main/runtime/orca-runtime-get-worktree-ps.ts +++ b/src/main/runtime/orca-runtime-get-worktree-ps.ts @@ -1,4 +1,5 @@ // @ts-nocheck -- mechanically split from OrcaRuntimeService; behavior is covered by AST equivalence and characterization tests. +import { collectRuntimeWorktreeAgentSources } from './runtime-worktree-agent-sources' import { OrcaRuntimeWithStructuredAgentSessionRecoverTuiOwner } from './orca-runtime-structured-agent-session-recover-tui-owner' import { DEFAULT_WORKTREE_PS_LIMIT } from './orca-runtime-postlude' import type { RuntimeWorktreePsResult } from '../../shared/runtime-types' @@ -9,6 +10,7 @@ import { applyRuntimeWorktreePsTerminalActivity } from './runtime-worktree-ps-activity' import { attachRuntimeWorktreeAgentRows } from './runtime-worktree-agent-rows' +import { getStructuredAgentSessionHost } from '../native-chat/agent-session-wire/structured-agent-session-registry' import { compareWorktreePs } from './runtime-worktree-status-projection' import type { AgentSessionRecord } from '../../shared/agent-session-record' import type { Repo } from '../../shared/repo-types' @@ -102,11 +104,15 @@ export class OrcaRuntimeWithGetWorktreePs extends OrcaRuntimeWithStructuredAgent summaries, pathIndex: runtimeWorktreeSummaryPathIndex, missingWorktreeIds: missingRuntimeWorktreeIds, - mirroredWorktreeIdByTabId, - connectedPtyEvidence, workingTerminalEvidenceByWorktreeId, - retainedSnapshots: this.agentRows.values(), - hookSnapshots: this.getAgentStatusSnapshotFn?.() ?? [], + rowSources: collectRuntimeWorktreeAgentSources({ + mirroredWorktreeIdByTabId, + connectedPtyEvidence, + retainedSnapshots: this.agentRows.values(), + hookSnapshots: this.getAgentStatusSnapshotFn?.() ?? [], + // Broadcast history outlives closed sessions; only the host roster is eligible. + structuredSummaries: getStructuredAgentSessionHost()?.liveSessionStatusSummaries() ?? [] + }), orchestrationByPaneKey: this.agentOrchestrationProjection.buildByPaneKey(), getSummary: (summaryMap, pathIndex, missingIds, worktreeId) => this.getSummaryForRuntimeWorktreeId(summaryMap, pathIndex, missingIds, worktreeId) diff --git a/src/main/runtime/orca-runtime-tests/worktree-ps-structured-host.spec.ts b/src/main/runtime/orca-runtime-tests/worktree-ps-structured-host.spec.ts new file mode 100644 index 00000000000..58e7de1b674 --- /dev/null +++ b/src/main/runtime/orca-runtime-tests/worktree-ps-structured-host.spec.ts @@ -0,0 +1,146 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { OrcaRuntimeService } from '../orca-runtime-test-mocks.spec' +import { TEST_WORKTREE_ID, store } from '../orca-runtime-test-fixtures.spec' +import type { AgentJournalRenderItem } from '../../../shared/agent-session-journal-types' +import type { + AgentSessionStatusEvent, + AgentSessionStatusSummary +} from '../../../shared/agent-session-wire' +import type { AgentSessionJournal } from '../../native-chat/agent-session-journal/journal-store' +import type { StructuredAgentSessionHost } from '../../native-chat/agent-session-wire/structured-agent-session-host' +import { + getStructuredAgentSessionHost, + setStructuredAgentSessionHost +} from '../../native-chat/agent-session-wire/structured-agent-session-registry' +import { StructuredAgentSessionStatusFeed } from '../../native-chat/agent-session-wire/structured-agent-session-status-feed' + +/** + * The production wiring, not the projection. Both structured-row suites call + * `attachRuntimeWorktreeAgentRows` directly with summaries they built themselves, so nothing + * executed `getWorktreePs`'s own `getStructuredAgentSessionHost()?.liveSessionStatusSummaries()` + * — and that file carries `@ts-nocheck`, so renaming the accessor stayed green in typecheck AND + * in the suite while `orca worktree ps` and mobile's poll would throw for every user. + */ + +const HELD_SESSION = 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d' +const FORGOTTEN_SESSION = 'b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e' +const OBSERVED_AT = 1_757_030_400_000 + +function runningTurn(prompt: string): AgentJournalRenderItem[] { + return [ + { + itemId: 'user-1', + sequence: 1, + revision: 1, + observedAt: OBSERVED_AT, + body: { kind: 'message', role: 'user', blocks: [{ type: 'text', text: prompt }] } + }, + { + itemId: 'turn-1', + sequence: 2, + revision: 1, + observedAt: OBSERVED_AT, + body: { + kind: 'status', + text: 'Working', + turnLifecycle: { turnId: 'turn-1', state: 'running' } + } + } + ] +} + +function journalWith(prompt: string): AgentSessionJournal { + return { + isReadOnly: false, + lastActivityAt: () => OBSERVED_AT, + snapshot: () => ({ items: runningTurn(prompt) }) + } as unknown as AgentSessionJournal +} + +/** A real feed the host still holds one session on, having forgotten the other. Its `published` + * cache never retracts, so the two views genuinely differ. */ +function statusFeed(): StructuredAgentSessionStatusFeed { + const session = (prompt: string) => ({ + journal: journalWith(prompt), + params: { location: { workspaceId: TEST_WORKTREE_ID }, provider: 'claude' as const } + }) + const sessions = new Map([ + [HELD_SESSION, session('ship the thing')], + [FORGOTTEN_SESSION, session('rm the branch')] + ]) + const feed = new StructuredAgentSessionStatusFeed({ + sessions, + getRecord: () => null, + now: () => OBSERVED_AT + }) + feed.publish(HELD_SESSION) + feed.publish(FORGOTTEN_SESSION) + // `forget-session`, the last eviction step, drops the session and leaves the feed alone. + sessions.delete(FORGOTTEN_SESSION) + return feed +} + +/** Everything the feed retained, read through the snapshot a subscriber opens on. No production + * code reads this; it is here so swapping the call site back to a whole-cache read is a one-line + * edit that this suite must catch. */ +function retainedSummaries(feed: StructuredAgentSessionStatusFeed): AgentSessionStatusSummary[] { + let retained: AgentSessionStatusSummary[] = [] + feed.subscribe({ + id: 'retained-probe', + emit: (event: AgentSessionStatusEvent) => { + if (event.type === 'snapshot') { + retained = event.sessions + } + } + })() + return retained +} + +function installHost(feed: StructuredAgentSessionStatusFeed) { + const liveSessionStatusSummaries = vi.fn(() => feed.liveSessionSummaries()) + const retainedSessionStatusSummaries = vi.fn(() => retainedSummaries(feed)) + // Typed against the real host, so renaming the accessor on the class reddens `tc` here — the + // caller cannot, because `orca-runtime-get-worktree-ps.ts` is `@ts-nocheck`. + const host: Pick & { + retainedSessionStatusSummaries: () => AgentSessionStatusSummary[] + } = { liveSessionStatusSummaries, retainedSessionStatusSummaries } + setStructuredAgentSessionHost(host as unknown as StructuredAgentSessionHost) + return { liveSessionStatusSummaries, retainedSessionStatusSummaries } +} + +describe('worktree ps reads the installed structured host', () => { + afterEach(() => { + setStructuredAgentSessionHost(null) + }) + + it('reports the held session and asks the host for its live summaries', async () => { + const feed = statusFeed() + const { liveSessionStatusSummaries } = installHost(feed) + + const { worktrees } = await new OrcaRuntimeService(store).getWorktreePs() + + const worktree = worktrees.find((entry) => entry.worktreeId === TEST_WORKTREE_ID) + expect(worktree).toBeDefined() + // Exactly one: the forgotten session is still in the feed's retained cache, so a call site + // that enumerated that cache instead would report two. + expect(worktree?.agents).toHaveLength(1) + expect(worktree?.agents[0]).toMatchObject({ + state: 'working', + agentType: 'claude', + prompt: 'ship the thing' + }) + // Pins the call site to the live-intersecting accessor, not merely to some accessor. + expect(liveSessionStatusSummaries).toHaveBeenCalledTimes(1) + }) + + it('succeeds with no structured rows when no host is installed', async () => { + // Guard the guard: these specs share one module registry, so state the premise. + expect(getStructuredAgentSessionHost()).toBeNull() + + const { worktrees } = await new OrcaRuntimeService(store).getWorktreePs() + + const worktree = worktrees.find((entry) => entry.worktreeId === TEST_WORKTREE_ID) + expect(worktree).toBeDefined() + expect(worktree?.agents).toEqual([]) + }) +}) diff --git a/src/main/runtime/orca-runtime.test.ts b/src/main/runtime/orca-runtime.test.ts index 829c2ca321e..74098040c27 100644 --- a/src/main/runtime/orca-runtime.test.ts +++ b/src/main/runtime/orca-runtime.test.ts @@ -85,6 +85,7 @@ await import('./orca-runtime-tests/mobile-summaries.spec') await import('./orca-runtime-tests/mobile-summaries-part-02.spec') await import('./orca-runtime-tests/mobile-summaries-part-03.spec') await import('./orca-runtime-tests/mobile-summaries-part-04.spec') +await import('./orca-runtime-tests/worktree-ps-structured-host.spec') await import('./orca-runtime-tests/terminal-sleep-and-teardown.spec') await import('./orca-runtime-tests/terminal-sleep-and-teardown-part-02.spec') await import('./orca-runtime-tests/terminal-sleep-and-teardown-part-03.spec') diff --git a/src/main/runtime/runtime-worktree-agent-rows-structured.test.ts b/src/main/runtime/runtime-worktree-agent-rows-structured.test.ts new file mode 100644 index 00000000000..84966846be7 --- /dev/null +++ b/src/main/runtime/runtime-worktree-agent-rows-structured.test.ts @@ -0,0 +1,120 @@ +import { collectRuntimeWorktreeAgentSources } from './runtime-worktree-agent-sources' +import { describe, expect, it } from 'vitest' +import { attachRuntimeWorktreeAgentRows } from './runtime-worktree-agent-rows' +import { + structuredAgentSessionPaneKey, + structuredAgentSessionTabId +} from '../../shared/structured-agent-session-projection' +import type { AgentSessionStatusSummary } from '../../shared/agent-session-wire' +import type { RuntimeWorktreePsSummary } from '../../shared/runtime-types' + +/** + * A structured session has no PTY, so it reaches none of the hook or retained snapshots that every + * other row comes from. Before this, `worktree ps` reported a worktree running one as idle while + * the sidebar showed it working — the CLI, which is the agent-facing surface, was the blind one. + */ +const WORKTREE_ID = 'repo-1::/workspace/app' + +function summary(over: Partial = {}): AgentSessionStatusSummary { + return { + sessionId: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d', + workspaceId: WORKTREE_ID, + agent: 'claude', + status: 'working', + latestPrompt: 'ship the thing', + updatedAt: 1_757_030_400_000, + hostExecutionOwned: true, + ...over + } as AgentSessionStatusSummary +} + +function attach(summaries: AgentSessionStatusSummary[]): RuntimeWorktreePsSummary { + const row = { + worktreeId: WORKTREE_ID, + status: 'inactive', + hasHostSidebarActivity: false, + agents: [] + } as unknown as RuntimeWorktreePsSummary + const summariesById = new Map([[WORKTREE_ID, row]]) + attachRuntimeWorktreeAgentRows({ + summaries: summariesById, + pathIndex: { byPath: new Map(), byRealPath: new Map() } as never, + missingWorktreeIds: new Set(), + workingTerminalEvidenceByWorktreeId: new Map(), + rowSources: collectRuntimeWorktreeAgentSources({ + mirroredWorktreeIdByTabId: new Map(), + connectedPtyEvidence: { tabIds: new Set(), paneKeys: new Set(), ptyIds: new Set() }, + retainedSnapshots: [], + hookSnapshots: [], + structuredSummaries: summaries + }), + orchestrationByPaneKey: null, + getSummary: (map, _p, _m, id) => map.get(id) ?? null + }) + return row +} + +describe('worktree ps reports structured sessions', () => { + it('a busy structured session is not reported idle', () => { + const row = attach([summary()]) + expect(row.agents).toHaveLength(1) + expect(row.agents[0]?.state).toBe('working') + expect(row.agents[0]?.agentType).toBe('claude') + expect(row.agents[0]?.prompt).toBe('ship the thing') + }) + + // The same projection the sidebar applies, so the two surfaces cannot disagree about one session. + it('maps attention to blocked and idle to done', () => { + expect(attach([summary({ status: 'attention' })]).agents[0]?.state).toBe('blocked') + expect(attach([summary({ status: 'idle' })]).agents[0]?.state).toBe('done') + }) + + it('does not turn a completed host-held session into permission', () => { + const row = attach([summary({ status: 'idle' })]) + expect(row.status).toBe('inactive') + expect(row.hasHostSidebarActivity).toBe(false) + }) + + it('reports the DERIVED pane key, never an orchestration credential', () => { + const row = attach([summary()]) + const sessionId = 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d' + expect(row.agents[0]?.paneKey).toBe( + structuredAgentSessionPaneKey(structuredAgentSessionTabId(sessionId), sessionId) + ) + }) + + // Null status means no turn has been persisted; the chat itself shows nothing, so neither does this. + it('omits a session with no projected status', () => { + expect(attach([summary({ status: null })]).agents).toHaveLength(0) + }) +}) + +/** + * The deliberate non-goal. Adding structured rows to `terminal list` was investigated and rejected: + * mobile mounts a terminal WebView per row that can never receive a frame, a `connected`-keyed + * refresh check goes permanently true and pins shipped clients to a fast cadence with no exit, and + * the plugin projection has no field that can carry `writable: false`. Every SAFE consumer of a + * terminal summary checks `ptyId`; the breaking ones key off `connected` or mere row presence, + * which no added field can qualify. A separate change publishes an honest partial-listing count + * there instead. This pins that only `worktree ps` gained the enumerator. + */ +describe('terminal listing is deliberately left alone', () => { + it('only worktree ps consumes the structured status summaries', async () => { + const { readFile } = await import('node:fs/promises') + // orca-runtime-subscribe-to-terminal-resize.ts owns listTerminals. + const listing = await readFile( + new URL('./orca-runtime-subscribe-to-terminal-resize.ts', import.meta.url), + 'utf8' + ) + // Guard the guard: an empty read would make every assertion below vacuously true. + expect(listing).toContain('async listTerminals(') + expect(listing).not.toContain('liveSessionStatusSummaries') + expect(listing).not.toContain('structuredSummaries') + + const worktreePs = await readFile( + new URL('./orca-runtime-get-worktree-ps.ts', import.meta.url), + 'utf8' + ) + expect(worktreePs).toContain('liveSessionStatusSummaries') + }) +}) diff --git a/src/main/runtime/runtime-worktree-agent-rows.ts b/src/main/runtime/runtime-worktree-agent-rows.ts index 1853f704471..80802cf11a3 100644 --- a/src/main/runtime/runtime-worktree-agent-rows.ts +++ b/src/main/runtime/runtime-worktree-agent-rows.ts @@ -1,34 +1,10 @@ -import { - AGENT_STATUS_STALE_AFTER_MS, - isFreshNonDoneAgentStatus, - pickParsedAgentStatusPayload, - type AgentStatusIpcPayload, - type ParsedAgentStatusPayload -} from '../../shared/agent-status-types' -import { terminalStatusPayloadMatchesHook } from '../../shared/agent-terminal-status-equivalence' +import { isFreshNonDoneAgentStatus } from '../../shared/agent-status-types' import type { RuntimeWorktreeAgentRow, RuntimeWorktreePsSummary } from '../../shared/runtime-types' -import { parseLegacyNumericPaneKey, parsePaneKey } from '../../shared/stable-pane-id' -import { isWslHookRelayConnectionId } from '../../shared/wsl-hook-relay-contract' import { mergeWorktreeSummaryStatus } from './runtime-worktree-status-projection' import type { RuntimeWorktreeSummaryPathIndex } from './runtime-worktree-summary-paths' import type { RuntimeWorkingTerminalEvidence } from './runtime-worktree-ps-activity' - -export type RuntimeAgentRowSnapshot = { - paneKey: string - ptyId: string - worktreeId?: string - tabId?: string - connectionId: string | null - payload: ParsedAgentStatusPayload - stateStartedAt: number - updatedAt: number -} - -type ConnectedPtyEvidence = { - tabIds: ReadonlySet - paneKeys: ReadonlySet - ptyIds: ReadonlySet -} +import type { RuntimeWorktreeAgentSource } from './runtime-worktree-agent-source' +export type { RuntimeAgentRowSnapshot } from './runtime-worktree-pty-agent-sources' type OrchestrationDisplay = { taskTitle?: string | null @@ -36,38 +12,15 @@ type OrchestrationDisplay = { parentPaneKey?: string | null } -type RuntimeWorktreeAgentSource = { - paneKey: string - ptyId?: string - tabId?: string - worktreeId?: string - connectionId: string | null - payload: ParsedAgentStatusPayload - state: ParsedAgentStatusPayload['state'] - workingMode?: ParsedAgentStatusPayload['workingMode'] - agentType: string | null - prompt: string - lastAssistantMessage: string | null - toolName: string | null - toolInput: string | null - interrupted: boolean - stateStartedAt: number - updatedAt: number - restoredUnconfirmed?: boolean -} - export function attachRuntimeWorktreeAgentRows(args: { summaries: Map pathIndex: RuntimeWorktreeSummaryPathIndex missingWorktreeIds: Set - mirroredWorktreeIdByTabId: ReadonlyMap - connectedPtyEvidence: ConnectedPtyEvidence + rowSources: ReadonlyMap workingTerminalEvidenceByWorktreeId: ReadonlyMap< string, readonly RuntimeWorkingTerminalEvidence[] > - retainedSnapshots: Iterable - hookSnapshots: readonly AgentStatusIpcPayload[] orchestrationByPaneKey: Record | null | undefined getSummary: ( summaries: Map, @@ -76,88 +29,11 @@ export function attachRuntimeWorktreeAgentRows(args: { worktreeId: string ) => RuntimeWorktreePsSummary | null }): void { - const rowSources = new Map() + const { rowSources } = args const now = Date.now() - for (const snapshot of args.retainedSnapshots) { - const { payload } = snapshot - rowSources.set(snapshot.paneKey, { - paneKey: snapshot.paneKey, - ptyId: snapshot.ptyId, - tabId: snapshot.tabId, - worktreeId: snapshot.worktreeId, - connectionId: snapshot.connectionId, - payload, - state: payload.state, - ...(payload.workingMode ? { workingMode: payload.workingMode } : {}), - agentType: payload.agentType ?? null, - prompt: payload.prompt, - lastAssistantMessage: payload.lastAssistantMessage ?? null, - toolName: payload.toolName ?? null, - toolInput: payload.toolInput ?? null, - interrupted: payload.interrupted ?? false, - stateStartedAt: snapshot.stateStartedAt, - updatedAt: snapshot.updatedAt - }) - } - for (const entry of args.hookSnapshots) { - if (entry.restoredUnconfirmed === true) { - continue - } - const existing = rowSources.get(entry.paneKey) - const hookPayload = pickParsedAgentStatusPayload(entry) - if (existing && existing.updatedAt > entry.receivedAt) { - if ( - entry.workingMode === 'monitoring' && - now - entry.receivedAt <= AGENT_STATUS_STALE_AFTER_MS && - terminalStatusPayloadMatchesHook(hookPayload, existing.payload) - ) { - existing.workingMode = 'monitoring' - if (existing.payload.workingMode === undefined) { - existing.payload = { ...existing.payload, workingMode: 'monitoring' } - } - } - continue - } - rowSources.set(entry.paneKey, { - paneKey: entry.paneKey, - ptyId: existing?.ptyId, - tabId: entry.tabId, - worktreeId: entry.worktreeId, - connectionId: entry.connectionId, - payload: hookPayload, - state: entry.state, - ...(entry.workingMode ? { workingMode: entry.workingMode } : {}), - agentType: entry.agentType ?? null, - prompt: entry.prompt, - lastAssistantMessage: entry.lastAssistantMessage ?? null, - toolName: entry.toolName ?? null, - toolInput: entry.toolInput ?? null, - interrupted: entry.interrupted ?? false, - stateStartedAt: entry.stateStartedAt, - updatedAt: entry.receivedAt - }) - } - if (rowSources.size === 0) { - return - } const rowsByWorktree = new Map() for (const source of rowSources.values()) { - const tabId = - source.tabId ?? - parsePaneKey(source.paneKey)?.tabId ?? - parseLegacyNumericPaneKey(source.paneKey)?.tabId - const mirroredWorktreeId = tabId ? args.mirroredWorktreeIdByTabId.get(tabId) : undefined - if ( - tabId !== undefined && - mirroredWorktreeId === undefined && - (source.connectionId === null || isWslHookRelayConnectionId(source.connectionId)) && - !args.connectedPtyEvidence.tabIds.has(tabId) && - !args.connectedPtyEvidence.paneKeys.has(source.paneKey) && - (source.ptyId === undefined || !args.connectedPtyEvidence.ptyIds.has(source.ptyId)) - ) { - continue - } - const worktreeId = mirroredWorktreeId ?? source.worktreeId + const { worktreeId } = source if (!worktreeId) { continue } @@ -204,13 +80,15 @@ export function attachRuntimeWorktreeAgentRows(args: { let hasForegroundWorkingAgent = false const monitoringSources: RuntimeWorktreeAgentSource[] = [] for (const row of rows) { - if (!isFreshNonDoneAgentStatus(row, now)) { + const source = rowSources.get(row.paneKey) + const hostHeldStructuredSession = + source?.authority === 'structured-host' && row.state !== 'done' + if (!hostHeldStructuredSession && !isFreshNonDoneAgentStatus(row, now)) { continue } summary.hasHostSidebarActivity = true if (row.state === 'working') { if (row.workingMode === 'monitoring') { - const source = rowSources.get(row.paneKey) if (source) { monitoringSources.push(source) } diff --git a/src/main/runtime/runtime-worktree-agent-source.ts b/src/main/runtime/runtime-worktree-agent-source.ts new file mode 100644 index 00000000000..2e8bc833b23 --- /dev/null +++ b/src/main/runtime/runtime-worktree-agent-source.ts @@ -0,0 +1,21 @@ +import type { ParsedAgentStatusPayload } from '../../shared/agent-status-types' + +export type RuntimeWorktreeAgentSource = { + paneKey: string + ptyId?: string + tabId?: string + worktreeId?: string + connectionId: string | null + state: ParsedAgentStatusPayload['state'] + workingMode?: ParsedAgentStatusPayload['workingMode'] + agentType: string | null + prompt: string + lastAssistantMessage: string | null + toolName: string | null + toolInput: string | null + interrupted: boolean + stateStartedAt: number + updatedAt: number + /** Structured host projections remain authoritative after PTY freshness expiry. */ + authority?: 'structured-host' +} diff --git a/src/main/runtime/runtime-worktree-agent-sources.test.ts b/src/main/runtime/runtime-worktree-agent-sources.test.ts new file mode 100644 index 00000000000..c0395cd6831 --- /dev/null +++ b/src/main/runtime/runtime-worktree-agent-sources.test.ts @@ -0,0 +1,70 @@ +import { describe, expect, it } from 'vitest' +import { collectRuntimeWorktreeAgentSources } from './runtime-worktree-agent-sources' +import type { RuntimeAgentRowSnapshot } from './runtime-worktree-pty-agent-sources' +import type { AgentStatusIpcPayload } from '../../shared/agent-status-types' + +const paneKey = 'worktree:tab:0' +const now = Date.now() +const retained: RuntimeAgentRowSnapshot = { + paneKey, + ptyId: 'pty', + tabId: 'tab', + worktreeId: 'worktree', + connectionId: null, + payload: { state: 'working', prompt: 'implement', agentType: 'codex' }, + stateStartedAt: now, + updatedAt: now +} +const base = { + retainedSnapshots: [retained], + hookSnapshots: [] as AgentStatusIpcPayload[], + structuredSummaries: [], + mirroredWorktreeIdByTabId: new Map(), + connectedPtyEvidence: { + tabIds: new Set(), + paneKeys: new Set(), + ptyIds: new Set() + } +} + +describe('worktree agent source admission', () => { + it('rejects a disconnected local terminal before row assembly', () => { + expect(collectRuntimeWorktreeAgentSources(base).size).toBe(0) + const connected = { + ...base, + connectedPtyEvidence: { ...base.connectedPtyEvidence, ptyIds: new Set(['pty']) } + } + expect(collectRuntimeWorktreeAgentSources(connected).get(paneKey)?.state).toBe('working') + }) + + it('keeps remote evidence and resolves mirrored workspace ownership', () => { + const remote = { ...retained, connectionId: 'ssh-connection' } + expect(collectRuntimeWorktreeAgentSources({ ...base, retainedSnapshots: [remote] }).size).toBe( + 1 + ) + const sources = collectRuntimeWorktreeAgentSources({ + ...base, + mirroredWorktreeIdByTabId: new Map([['tab', 'remote-worktree']]) + }) + expect(sources.get(paneKey)?.worktreeId).toBe('remote-worktree') + }) + + it('preserves fresh monitoring enrichment on a newer retained report', () => { + const hook: AgentStatusIpcPayload = { + ...retained.payload, + paneKey, + tabId: 'tab', + worktreeId: 'worktree', + connectionId: null, + stateStartedAt: now - 1, + receivedAt: now - 1, + workingMode: 'monitoring' + } + const sources = collectRuntimeWorktreeAgentSources({ + ...base, + hookSnapshots: [hook], + connectedPtyEvidence: { ...base.connectedPtyEvidence, ptyIds: new Set(['pty']) } + }) + expect(sources.get(paneKey)).toMatchObject({ updatedAt: now, workingMode: 'monitoring' }) + }) +}) diff --git a/src/main/runtime/runtime-worktree-agent-sources.ts b/src/main/runtime/runtime-worktree-agent-sources.ts new file mode 100644 index 00000000000..44ce7848960 --- /dev/null +++ b/src/main/runtime/runtime-worktree-agent-sources.ts @@ -0,0 +1,22 @@ +import type { AgentSessionStatusSummary } from '../../shared/agent-session-wire' +import { collectRuntimeWorktreePtyAgentSources } from './runtime-worktree-pty-agent-sources' +import { structuredRuntimeWorktreeAgentSources } from './runtime-worktree-structured-agent-rows' +import type { RuntimeWorktreeAgentSource } from './runtime-worktree-agent-source' + +/** One admitted roster for row and worktree-status projection. */ +export function collectRuntimeWorktreeAgentSources( + args: Parameters[0] & { + structuredSummaries: readonly AgentSessionStatusSummary[] + } +): ReadonlyMap { + const sources = new Map() + for (const source of collectRuntimeWorktreePtyAgentSources(args)) { + sources.set(source.paneKey, source) + } + for (const source of structuredRuntimeWorktreeAgentSources(args.structuredSummaries)) { + if (!sources.has(source.paneKey)) { + sources.set(source.paneKey, source) + } + } + return sources +} diff --git a/src/main/runtime/runtime-worktree-pty-agent-sources.ts b/src/main/runtime/runtime-worktree-pty-agent-sources.ts new file mode 100644 index 00000000000..04e8dffc04e --- /dev/null +++ b/src/main/runtime/runtime-worktree-pty-agent-sources.ts @@ -0,0 +1,121 @@ +import { + AGENT_STATUS_STALE_AFTER_MS, + pickParsedAgentStatusPayload, + type AgentStatusIpcPayload, + type ParsedAgentStatusPayload +} from '../../shared/agent-status-types' +import { terminalStatusPayloadMatchesHook } from '../../shared/agent-terminal-status-equivalence' +import { parseLegacyNumericPaneKey, parsePaneKey } from '../../shared/stable-pane-id' +import { isWslHookRelayConnectionId } from '../../shared/wsl-hook-relay-contract' +import type { RuntimeWorktreeAgentSource } from './runtime-worktree-agent-source' + +export type RuntimeAgentRowSnapshot = { + paneKey: string + ptyId: string + worktreeId?: string + tabId?: string + connectionId: string | null + payload: ParsedAgentStatusPayload + stateStartedAt: number + updatedAt: number +} + +export type ConnectedPtyEvidence = { + tabIds: ReadonlySet + paneKeys: ReadonlySet + ptyIds: ReadonlySet +} + +/** Reconcile terminal status, then admit rows using their execution-host evidence. */ +export function collectRuntimeWorktreePtyAgentSources(args: { + retainedSnapshots: Iterable + hookSnapshots: readonly AgentStatusIpcPayload[] + mirroredWorktreeIdByTabId: ReadonlyMap + connectedPtyEvidence: ConnectedPtyEvidence +}): RuntimeWorktreeAgentSource[] { + const rowSources = new Map< + string, + RuntimeWorktreeAgentSource & { payload: ParsedAgentStatusPayload } + >() + const now = Date.now() + for (const snapshot of args.retainedSnapshots) { + const { payload } = snapshot + rowSources.set(snapshot.paneKey, { + paneKey: snapshot.paneKey, + ptyId: snapshot.ptyId, + tabId: snapshot.tabId, + worktreeId: snapshot.worktreeId, + connectionId: snapshot.connectionId, + payload, + state: payload.state, + ...(payload.workingMode ? { workingMode: payload.workingMode } : {}), + agentType: payload.agentType ?? null, + prompt: payload.prompt, + lastAssistantMessage: payload.lastAssistantMessage ?? null, + toolName: payload.toolName ?? null, + toolInput: payload.toolInput ?? null, + interrupted: payload.interrupted ?? false, + stateStartedAt: snapshot.stateStartedAt, + updatedAt: snapshot.updatedAt + }) + } + for (const entry of args.hookSnapshots) { + if (entry.restoredUnconfirmed === true) { + continue + } + const existing = rowSources.get(entry.paneKey) + const hookPayload = pickParsedAgentStatusPayload(entry) + if (existing && existing.updatedAt > entry.receivedAt) { + if ( + entry.workingMode === 'monitoring' && + now - entry.receivedAt <= AGENT_STATUS_STALE_AFTER_MS && + terminalStatusPayloadMatchesHook(hookPayload, existing.payload) + ) { + existing.workingMode = 'monitoring' + if (existing.payload.workingMode === undefined) { + existing.payload = { ...existing.payload, workingMode: 'monitoring' } + } + } + continue + } + rowSources.set(entry.paneKey, { + paneKey: entry.paneKey, + ptyId: existing?.ptyId, + tabId: entry.tabId, + worktreeId: entry.worktreeId, + connectionId: entry.connectionId, + payload: hookPayload, + state: entry.state, + ...(entry.workingMode ? { workingMode: entry.workingMode } : {}), + agentType: entry.agentType ?? null, + prompt: entry.prompt, + lastAssistantMessage: entry.lastAssistantMessage ?? null, + toolName: entry.toolName ?? null, + toolInput: entry.toolInput ?? null, + interrupted: entry.interrupted ?? false, + stateStartedAt: entry.stateStartedAt, + updatedAt: entry.receivedAt + }) + } + const sources: RuntimeWorktreeAgentSource[] = [] + for (const source of rowSources.values()) { + const tabId = + source.tabId ?? + parsePaneKey(source.paneKey)?.tabId ?? + parseLegacyNumericPaneKey(source.paneKey)?.tabId + const mirroredWorktreeId = tabId ? args.mirroredWorktreeIdByTabId.get(tabId) : undefined + if ( + tabId !== undefined && + mirroredWorktreeId === undefined && + (source.connectionId === null || isWslHookRelayConnectionId(source.connectionId)) && + !args.connectedPtyEvidence.tabIds.has(tabId) && + !args.connectedPtyEvidence.paneKeys.has(source.paneKey) && + (source.ptyId === undefined || !args.connectedPtyEvidence.ptyIds.has(source.ptyId)) + ) { + continue + } + const worktreeId = mirroredWorktreeId ?? source.worktreeId + sources.push({ ...source, tabId, worktreeId }) + } + return sources +} diff --git a/src/main/runtime/runtime-worktree-structured-agent-rows-liveness.test.ts b/src/main/runtime/runtime-worktree-structured-agent-rows-liveness.test.ts new file mode 100644 index 00000000000..063ee0b36cf --- /dev/null +++ b/src/main/runtime/runtime-worktree-structured-agent-rows-liveness.test.ts @@ -0,0 +1,157 @@ +import { collectRuntimeWorktreeAgentSources } from './runtime-worktree-agent-sources' +import { mkdtemp, rm } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { StructuredAgentSessionStatusFeed } from '../native-chat/agent-session-wire/structured-agent-session-status-feed' +import { createTrackedJournalOpener } from '../native-chat/agent-session-journal/journal-store-test-open' +import type { RuntimeWorktreePsSummary } from '../../shared/runtime-types' +import { attachRuntimeWorktreeAgentRows } from './runtime-worktree-agent-rows' + +/** + * The whole chain `worktree ps` walks: journal -> status feed -> agent rows -> worktree status. + * + * The feed's `published` map never retracts, so reading it as a roster reports every session the + * app has ever opened. A closed chat that was waiting on an approval is the sharp edge: deliberate + * close does not settle a pending prompt, so the retained summary stays `attention`, which maps to + * a `blocked` row and merges the worktree to `permission` for the 30-minute freshness window. + */ +const WORKTREE_ID = 'repo-1::/workspace/app' +const SESSION = 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d' +const IDENTITY = { + provider: 'codex', + threadId: 'thread-1', + turnId: 'turn-1', + ordinal: 0 +} as const + +let root: string +const journals = createTrackedJournalOpener() + +beforeEach(async () => { + root = await mkdtemp(join(tmpdir(), 'orca-structured-ps-liveness-')) +}) + +afterEach(async () => { + await journals.closeAll() + await rm(root, { recursive: true, force: true }) +}) + +/** A session parked on an approval nobody answered — the state a deliberate close leaves behind. */ +async function awaitingApproval() { + const journal = await journals.open({ + identity: { + sessionId: SESSION, + workspaceId: WORKTREE_ID, + hostId: 'local', + agent: 'codex', + providerHandle: { kind: 'codex', threadId: 'thread-1' } + }, + journalDir: join(root, SESSION) + }) + await journal.appendItem( + { ...IDENTITY, ordinal: 1 }, + { kind: 'message', role: 'user', blocks: [{ type: 'text', text: 'rm the branch' }] }, + { fence: 1 } + ) + await journal.appendItem( + { ...IDENTITY, ordinal: 2 }, + { + kind: 'approval', + title: 'Run the command?', + detail: null, + options: [{ id: 'allow', label: 'Allow' }], + resolution: { state: 'pending', selectedOptionId: null, resolvedBy: null, resolvedAt: null } + }, + { fence: 1 } + ) + const sessions = new Map([ + [ + SESSION, + { journal, params: { location: { workspaceId: WORKTREE_ID }, provider: 'codex' as const } } + ] + ]) + const feed = new StructuredAgentSessionStatusFeed({ + sessions, + getRecord: () => null, + now: () => Date.now() + }) + feed.publish(SESSION, journal) + return { feed, sessions } +} + +function worktreeFor( + feed: StructuredAgentSessionStatusFeed, + summaries = feed.liveSessionSummaries() +): RuntimeWorktreePsSummary { + const row = { + worktreeId: WORKTREE_ID, + status: 'inactive', + agents: [] + } as unknown as RuntimeWorktreePsSummary + attachRuntimeWorktreeAgentRows({ + summaries: new Map([[WORKTREE_ID, row]]), + pathIndex: { byPath: new Map(), byRealPath: new Map() } as never, + missingWorktreeIds: new Set(), + workingTerminalEvidenceByWorktreeId: new Map(), + rowSources: collectRuntimeWorktreeAgentSources({ + mirroredWorktreeIdByTabId: new Map(), + connectedPtyEvidence: { tabIds: new Set(), paneKeys: new Set(), ptyIds: new Set() }, + retainedSnapshots: [], + hookSnapshots: [], + structuredSummaries: summaries + }), + orchestrationByPaneKey: null, + getSummary: (map, _paths, _missing, id) => map.get(id) ?? null + }) + return row +} + +describe('worktree ps and a closed structured chat', () => { + it('reports the blocked row while the session is still held', async () => { + const { feed } = await awaitingApproval() + const row = worktreeFor(feed) + expect(row.agents).toHaveLength(1) + expect(row.agents[0]?.state).toBe('blocked') + expect(row.status).toBe('permission') + }) + + it('stops reporting it once eviction forgets the session', async () => { + const { feed, sessions } = await awaitingApproval() + // `forget-session`, the last eviction step, does exactly this and nothing to the feed. + sessions.delete(SESSION) + + const row = worktreeFor(feed) + expect(row.agents).toHaveLength(0) + expect(row.status).toBe('inactive') + }) + + it('keeps an aged host-held working state authoritative', async () => { + const { feed } = await awaitingApproval() + const aged = feed.liveSessionSummaries().map((summary) => ({ + ...summary, + hostExecutionOwned: true as const, + updatedAt: Date.now() - 30 * 60 * 1000 - 1, + status: 'working' as const + })) + const row = worktreeFor(feed, aged) + expect(row.agents).toHaveLength(1) + expect(row.agents[0]?.state).toBe('working') + expect(row.status).toBe('working') + expect(row.agents[0]?.updatedAt).toBe(aged[0]?.updatedAt) + }) + + it('keeps an aged host-held approval state authoritative', async () => { + const { feed } = await awaitingApproval() + const aged = feed.liveSessionSummaries().map((summary) => ({ + ...summary, + hostExecutionOwned: true as const, + updatedAt: Date.now() - 30 * 60 * 1000 - 1 + })) + const row = worktreeFor(feed, aged) + expect(row.agents).toHaveLength(1) + expect(row.agents[0]?.state).toBe('blocked') + expect(row.status).toBe('permission') + expect(row.agents[0]?.updatedAt).toBe(aged[0]?.updatedAt) + }) +}) diff --git a/src/main/runtime/runtime-worktree-structured-agent-rows.ts b/src/main/runtime/runtime-worktree-structured-agent-rows.ts new file mode 100644 index 00000000000..c4d075fbd9c --- /dev/null +++ b/src/main/runtime/runtime-worktree-structured-agent-rows.ts @@ -0,0 +1,48 @@ +import type { AgentSessionStatusSummary } from '../../shared/agent-session-wire' +import { + structuredAgentSessionPaneKey, + structuredAgentSessionStatusState, + structuredAgentSessionTabId +} from '../../shared/structured-agent-session-projection' +import type { RuntimeWorktreeAgentSource } from './runtime-worktree-agent-source' + +/** + * Row sources for the structured (non-PTY) sessions a host still holds. + * + * A structured session reaches none of the hook or retained snapshots every other row comes from, + * so `worktree ps` projects it from the host's status feed instead. The feed's retained + * projections are not a roster — the caller passes only sessions the host still holds. + */ +export function structuredRuntimeWorktreeAgentSources( + summaries: readonly AgentSessionStatusSummary[] +): RuntimeWorktreeAgentSource[] { + const sources: RuntimeWorktreeAgentSource[] = [] + for (const summary of summaries) { + // No turn has been persisted yet, so there is nothing to report - the same read the chat shows. + if (!summary.status) { + continue + } + const tabId = structuredAgentSessionTabId(summary.sessionId) + // The DERIVED pane key the renderer already publishes, never the orchestration bearer handle + // or the minted worker pane key: both of those are credentials. + sources.push({ + paneKey: structuredAgentSessionPaneKey(tabId, summary.sessionId), + tabId, + worktreeId: summary.workspaceId, + connectionId: null, + // The shared mapping the sidebar applies, so the CLI and the GUI cannot disagree about one + // session. No hook payload: nothing reads one off a structured row. + state: structuredAgentSessionStatusState(summary.status), + agentType: summary.agent, + prompt: summary.latestPrompt, + lastAssistantMessage: summary.lastAssistantMessage ?? null, + toolName: summary.toolName ?? null, + toolInput: summary.toolInput ?? null, + interrupted: false, + stateStartedAt: summary.updatedAt, + updatedAt: summary.updatedAt, + ...(summary.hostExecutionOwned ? { authority: 'structured-host' as const } : {}) + }) + } + return sources +} diff --git a/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsx b/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsx index c4376dbf66e..1276287aca0 100644 --- a/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsx +++ b/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.test.tsx @@ -7,6 +7,7 @@ import type { AgentSessionStatusSummary } from '../../../../shared/agent-session-wire' import { resolveAttention } from '../sidebar/smart-attention' +import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' import type { AgentStatusEntry } from '../../../../shared/agent-status-types' import type { Tab } from '../../../../shared/tab-types' import type { AppState } from '@/store/types' @@ -88,6 +89,7 @@ function summary(overrides: Partial = {}): AgentSessi workspaceId: 'wt-1', agent: 'codex', status: 'working', + hostExecutionOwned: true, latestPrompt: 'hello', providerSession, updatedAt: 1, @@ -180,6 +182,26 @@ describe('StructuredAgentSessionStatusBridge', () => { // Hiddenness is the host's side of this: see structured-agent-session-subscribers.test.ts, // which drives an unsubscribed journal through the feed. Here the transport is a mock, so // only the summary-to-store mapping is under test. + it('keeps host-held working evidence active past the normal freshness window', async () => { + render() + await waitFor(() => expect(mocks.subscribeStatus).toHaveBeenCalledOnce()) + const updatedAt = Date.now() - 30 * 60 * 1000 - 1 + act(() => feed().emit({ type: 'status', session: summary({ updatedAt }) })) + const entry = statuses()[0] + expect(entry).toEqual(expect.objectContaining({ state: 'working', structuredHostOwned: true })) + expect(isExplicitAgentStatusFresh(entry, Date.now(), 30 * 60 * 1000)).toBe(true) + }) + + it('clears host-held evidence when the status stream disconnects', async () => { + render() + await waitFor(() => expect(mocks.subscribeStatus).toHaveBeenCalledOnce()) + act(() => feed().emit({ type: 'status', session: summary() })) + expect(statuses()).toHaveLength(1) + act(() => feed().emit({ type: 'end' })) + expect(statuses()).toHaveLength(1) + expect(statuses()[0]).not.toHaveProperty('structuredHostOwned') + }) + it('maps each host status onto the sidebar agent state', async () => { render() await waitFor(() => expect(mocks.subscribeStatus).toHaveBeenCalledOnce()) diff --git a/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsx b/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsx index a72f28d7c08..47d6aec460f 100644 --- a/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsx +++ b/src/renderer/src/components/native-chat/StructuredAgentSessionStatusBridge.tsx @@ -2,7 +2,10 @@ import { useEffect, useMemo, useSyncExternalStore } from 'react' import { useShallow } from 'zustand/react/shallow' import { agentProviderSessionsEqual } from '../../../../shared/agent-session-resume' import type { AgentSessionStatusSummary } from '../../../../shared/agent-session-wire' -import { structuredAgentSessionPaneKey } from '../../../../shared/structured-agent-session-projection' +import { + structuredAgentSessionPaneKey, + structuredAgentSessionStatusState +} from '../../../../shared/structured-agent-session-projection' import type { Tab } from '../../../../shared/tab-types' import { isAgentSessionHandleProvider } from '../../../../shared/agent-session-provider-handle' import { getRuntimeEnvironmentIdForWorktree } from '@/lib/worktree-runtime-owner' @@ -67,12 +70,8 @@ function projectStatus(tab: StructuredTab, summary: AgentSessionStatusSummary | return } const desired = { - state: - summary.status === 'working' - ? 'working' - : summary.status === 'attention' - ? 'blocked' - : 'done', + // Shared with `worktree ps`, so the CLI and this row cannot disagree about one session. + state: structuredAgentSessionStatusState(summary.status), prompt: summary.latestPrompt, agentType: tab.agentSessionAgent, // The host projects these from the journal so the row reads like a hook-reported one: @@ -99,6 +98,7 @@ function projectStatus(tab: StructuredTab, summary: AgentSessionStatusSummary | current.tabId === tab.id && current.worktreeId === tab.worktreeId && current.terminalResumeEligible === false && + current.structuredHostOwned === summary.hostExecutionOwned && agentProviderSessionsEqual( tab.agentSessionAgent, current.providerSession, @@ -119,12 +119,13 @@ function projectStatus(tab: StructuredTab, summary: AgentSessionStatusSummary | desired.state !== 'done' && current?.state === desired.state ? current.stateStartedAt : summary.updatedAt, - evidenceObservedAt: Date.now() + evidenceObservedAt: summary.updatedAt }, { tabId: tab.id, worktreeId: tab.worktreeId }, { ...(summary.providerSession ? { providerSession: summary.providerSession } : {}), - terminalResumeEligible: false + terminalResumeEligible: false, + ...(summary.hostExecutionOwned ? { structuredHostOwned: true as const } : {}) } ) } diff --git a/src/renderer/src/lib/pane-agent-evidence.ts b/src/renderer/src/lib/pane-agent-evidence.ts index 51e306becca..67dbbf85c6f 100644 --- a/src/renderer/src/lib/pane-agent-evidence.ts +++ b/src/renderer/src/lib/pane-agent-evidence.ts @@ -18,14 +18,20 @@ import { export function isExplicitAgentStatusFresh( entry: Pick< AgentStatusEntry, - 'updatedAt' | 'evidenceObservedAt' | 'mirroredEvidenceReceivedAt' | 'restoredUnconfirmed' + | 'updatedAt' + | 'evidenceObservedAt' + | 'mirroredEvidenceReceivedAt' + | 'restoredUnconfirmed' + | 'structuredHostOwned' >, now: number, staleAfterMs: number ): boolean { // Why: an unconfirmed hydrated row may describe a turn that ended while no receiver was up; never fresh. return ( - entry.restoredUnconfirmed !== true && now - agentStatusEvidenceObservedAt(entry) <= staleAfterMs + entry.restoredUnconfirmed !== true && + (entry.structuredHostOwned === true || + now - agentStatusEvidenceObservedAt(entry) <= staleAfterMs) ) } diff --git a/src/renderer/src/runtime/structured-agent-session-status-feed-lifecycle.test.ts b/src/renderer/src/runtime/structured-agent-session-status-feed-lifecycle.test.ts new file mode 100644 index 00000000000..4f98700d806 --- /dev/null +++ b/src/renderer/src/runtime/structured-agent-session-status-feed-lifecycle.test.ts @@ -0,0 +1,115 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { + AgentSessionStatusEvent, + AgentSessionStatusSummary +} from '../../../shared/agent-session-wire' + +const mocks = vi.hoisted(() => ({ subscribe: vi.fn() })) +vi.mock('./structured-agent-session-client', () => ({ + subscribeStructuredAgentSessionStatus: mocks.subscribe +})) +vi.mock('./runtime-rpc-client', () => ({ runtimeEnvironmentSupportsCapability: vi.fn() })) + +import { + getStructuredAgentSessionStatusFeed, + resetStructuredAgentSessionStatusFeedsForTests +} from './structured-agent-session-status-feed' + +type Subscription = { + emit: (event: AgentSessionStatusEvent) => void + unsubscribe: ReturnType +} +const subscriptions: Subscription[] = [] +const owned: AgentSessionStatusSummary = { + sessionId: 'running', + workspaceId: 'workspace', + agent: 'codex', + status: 'working', + latestPrompt: 'work', + updatedAt: 1, + hostExecutionOwned: true +} +const done: AgentSessionStatusSummary = { + ...owned, + sessionId: 'completed', + status: 'idle', + hostExecutionOwned: undefined +} + +function subscription(index = 0): Subscription { + const value = subscriptions[index] + if (!value) { + throw new Error('missing subscription') + } + return value +} + +describe('structured status feed execution authority lifecycle', () => { + beforeEach(() => { + vi.useFakeTimers() + resetStructuredAgentSessionStatusFeedsForTests() + subscriptions.length = 0 + mocks.subscribe.mockReset() + mocks.subscribe.mockImplementation((_target, emit: Subscription['emit']) => { + const unsubscribe = vi.fn(() => emit({ type: 'end' })) + subscriptions.push({ emit, unsubscribe }) + return Promise.resolve({ unsubscribe }) + }) + }) + + afterEach(() => { + resetStructuredAgentSessionStatusFeedsForTests() + vi.useRealTimers() + }) + + it('revokes on end before reentrant unsubscribe and ignores late frames', async () => { + const feed = getStructuredAgentSessionStatusFeed({ kind: 'local' }) + feed.activate() + await vi.advanceTimersByTimeAsync(0) + subscription().emit({ type: 'snapshot', sessions: [owned, done] }) + subscription().emit({ type: 'end' }) + expect(subscription().unsubscribe).toHaveBeenCalledOnce() + expect(feed.getSnapshot().get('running')).toEqual({ ...owned, hostExecutionOwned: undefined }) + expect(feed.getSnapshot().get('completed')).toBe(done) + subscription().emit({ type: 'status', session: owned }) + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBeUndefined() + expect(vi.getTimerCount()).toBe(1) + await vi.advanceTimersByTimeAsync(250) + subscription(1).emit({ type: 'snapshot', sessions: [done] }) + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBeUndefined() + subscription(1).emit({ type: 'status', session: owned }) + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBe(true) + }) + + it('retains history without ownership while stopped and until remount receives fresh evidence', async () => { + const feed = getStructuredAgentSessionStatusFeed({ kind: 'local' }) + const deactivate = feed.activate() + await vi.advanceTimersByTimeAsync(0) + subscription().emit({ type: 'snapshot', sessions: [owned, done] }) + deactivate() + expect(vi.getTimerCount()).toBe(0) + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBeUndefined() + expect(feed.getSnapshot().get('running')?.updatedAt).toBe(owned.updatedAt) + expect(feed.getSnapshot().get('completed')).toBe(done) + feed.activate() + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBeUndefined() + await vi.advanceTimersByTimeAsync(0) + subscription().emit({ type: 'status', session: owned }) + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBeUndefined() + subscription(1).emit({ type: 'snapshot', sessions: [owned] }) + expect(feed.getSnapshot().get('running')?.hostExecutionOwned).toBe(true) + }) + + it('does not notify or reallocate already unowned historical rows on teardown', async () => { + const feed = getStructuredAgentSessionStatusFeed({ kind: 'local' }) + const deactivate = feed.activate() + await vi.advanceTimersByTimeAsync(0) + subscription().emit({ type: 'snapshot', sessions: [done] }) + const previous = feed.getSnapshot() + const listener = vi.fn() + feed.subscribe(listener) + deactivate() + expect(feed.getSnapshot()).toBe(previous) + expect(listener).not.toHaveBeenCalled() + }) +}) diff --git a/src/renderer/src/runtime/structured-agent-session-status-feed.ts b/src/renderer/src/runtime/structured-agent-session-status-feed.ts index 2b550679315..8308ac8729a 100644 --- a/src/renderer/src/runtime/structured-agent-session-status-feed.ts +++ b/src/renderer/src/runtime/structured-agent-session-status-feed.ts @@ -82,6 +82,32 @@ function createOwner(target: RuntimeClientTarget): OwnedStatusFeed { handle?.unsubscribe() handle = null } + const revokeSnapshotOwnership = (): void => { + let next: Map | null = null + for (const [sessionId, summary] of snapshot) { + if (!summary.hostExecutionOwned) { + continue + } + if (!next) { + next = new Map(snapshot) + } + const { hostExecutionOwned: _owned, ...retained } = summary + next.set(sessionId, retained) + } + if (next) { + snapshot = next + emit() + } + } + const fenceCandidateAndReconnect = (candidate: number): void => { + if (candidate !== generation) { + return + } + generation += 1 + revokeSnapshotOwnership() + dropHandle() + scheduleReconnect(generation) + } let open = (): void => {} const scheduleReconnect = (candidate: number): void => { if (!active(candidate) || reconnectTimer) { @@ -104,22 +130,19 @@ function createOwner(target: RuntimeClientTarget): OwnedStatusFeed { return } if (event.type === 'end') { - dropHandle() - scheduleReconnect(candidate) + fenceCandidateAndReconnect(candidate) return } applyEvent(event) }, () => { if (active(candidate)) { - dropHandle() - scheduleReconnect(candidate) + fenceCandidateAndReconnect(candidate) } }, () => { if (active(candidate)) { - dropHandle() - scheduleReconnect(candidate) + fenceCandidateAndReconnect(candidate) } } ) @@ -130,7 +153,13 @@ function createOwner(target: RuntimeClientTarget): OwnedStatusFeed { opened.unsubscribe() } }) - .catch(() => scheduleReconnect(candidate)) + .catch(() => { + if (active(candidate)) { + fenceCandidateAndReconnect(candidate) + } else { + scheduleReconnect(candidate) + } + }) } open = (): void => { const candidate = ++generation @@ -163,6 +192,7 @@ function createOwner(target: RuntimeClientTarget): OwnedStatusFeed { generation += 1 clearReconnect() dropHandle() + revokeSnapshotOwnership() reconnectAttempt = 0 } diff --git a/src/renderer/src/store/slices/agent-status-contract.ts b/src/renderer/src/store/slices/agent-status-contract.ts index 39bbde535d1..453fef02139 100644 --- a/src/renderer/src/store/slices/agent-status-contract.ts +++ b/src/renderer/src/store/slices/agent-status-contract.ts @@ -108,6 +108,8 @@ export type AgentStatusRouting = { } export type AgentStatusMetadata = { + /** Structured status rows remain fresh while the host owns the session; cleared on feed loss. */ + structuredHostOwned?: true providerSession?: AgentProviderSessionMetadata launchConfig?: SleepingAgentLaunchConfig launchToken?: string diff --git a/src/renderer/src/store/slices/agent-status-live-entry-builder.ts b/src/renderer/src/store/slices/agent-status-live-entry-builder.ts index 5c3ef89bdaf..63ba0a5afc9 100644 --- a/src/renderer/src/store/slices/agent-status-live-entry-builder.ts +++ b/src/renderer/src/store/slices/agent-status-live-entry-builder.ts @@ -227,6 +227,7 @@ export function buildAgentStatusLiveEntry( ...(timing?.evidenceObservedAt !== undefined ? { evidenceObservedAt: timing.evidenceObservedAt } : {}), + ...(metadata?.structuredHostOwned === true ? { structuredHostOwned: true as const } : {}), stateStartedAt, agentType: identity.agentType, model: diff --git a/src/shared/agent-session-wire.ts b/src/shared/agent-session-wire.ts index 70d464d5392..0f7c453752f 100644 --- a/src/shared/agent-session-wire.ts +++ b/src/shared/agent-session-wire.ts @@ -196,6 +196,8 @@ export type AgentSessionStatusSummary = { agent: AgentSessionRecord['provider'] /** Null until the journal holds a persisted user or assistant message. */ status: StructuredAgentSessionProjectedStatus | null + /** Present only while this host has the provider child executing the session. */ + hostExecutionOwned?: true latestPrompt: string /** Provider model in force for the next turn; absent until the host has read the options. */ model?: string diff --git a/src/shared/agent-status-freshness.ts b/src/shared/agent-status-freshness.ts index 84a3218e3dd..616879b93e9 100644 --- a/src/shared/agent-status-freshness.ts +++ b/src/shared/agent-status-freshness.ts @@ -37,6 +37,7 @@ export function isFreshNonDoneAgentStatus( | 'evidenceObservedAt' | 'mirroredEvidenceReceivedAt' | 'restoredUnconfirmed' + | 'structuredHostOwned' > | undefined, now = Date.now(), @@ -47,6 +48,7 @@ export function isFreshNonDoneAgentStatus( entry && entry.state !== 'done' && entry.restoredUnconfirmed !== true && - now - agentStatusEvidenceObservedAt(entry) <= staleAfterMs + (entry.structuredHostOwned === true || + now - agentStatusEvidenceObservedAt(entry) <= staleAfterMs) ) } diff --git a/src/shared/agent-status-types.ts b/src/shared/agent-status-types.ts index 128e2f80f82..cc0ad487565 100644 --- a/src/shared/agent-status-types.ts +++ b/src/shared/agent-status-types.ts @@ -114,6 +114,8 @@ export type AgentStatusEntry = { * which is the delivery/ordering clock a relay reconnect must restamp to stay monotonic. * Absent for locally derived rows and old hosts; freshness falls back to `updatedAt`. */ evidenceObservedAt?: number + /** True only while a host-held structured session is represented by its live status feed. */ + structuredHostOwned?: true /** Timestamp (ms) when the current `state` was first reported. * Why: separate from updatedAt so tool/prompt pings (which reset updatedAt) don't move it. */ stateStartedAt: number diff --git a/src/shared/structured-agent-session-projection.ts b/src/shared/structured-agent-session-projection.ts index 02ad872c211..1301f766e2b 100644 --- a/src/shared/structured-agent-session-projection.ts +++ b/src/shared/structured-agent-session-projection.ts @@ -299,6 +299,14 @@ export function projectStructuredAgentSessionStatusSummary( } } +/** The agent-status state one projected session status stands for. Shared across the process + * boundary so `worktree ps` and the sidebar cannot disagree about the same session. */ +export function structuredAgentSessionStatusState( + status: StructuredAgentSessionProjectedStatus +): 'working' | 'blocked' | 'done' { + return status === 'working' ? 'working' : status === 'attention' ? 'blocked' : 'done' +} + export function structuredAgentSessionPaneKey(tabId: string, sessionId: string): string { const bytes = sha256(new TextEncoder().encode(sessionId)) const hex = Array.from(bytes.slice(0, 16), (byte) => byte.toString(16).padStart(2, '0')).join('')