From e525f3fe15e29daa31fed9f7fc9d64da94ff10f5 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 13 Aug 2026 11:43:48 -0700 Subject: [PATCH] fix(mobile): stop republishing stale launch agent identity (#14244) --- ...le-agent-status-title-truthfulness.test.ts | 55 +++++++++++++++++++ src/main/runtime/orca-runtime.test.ts | 6 +- src/main/runtime/orca-runtime.ts | 6 +- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/main/runtime/orca-runtime-mobile-agent-status-title-truthfulness.test.ts b/src/main/runtime/orca-runtime-mobile-agent-status-title-truthfulness.test.ts index 8a4fae0dfac..7d19f23db22 100644 --- a/src/main/runtime/orca-runtime-mobile-agent-status-title-truthfulness.test.ts +++ b/src/main/runtime/orca-runtime-mobile-agent-status-title-truthfulness.test.ts @@ -113,6 +113,52 @@ function publishRendererWorkingPane(runtime: OrcaRuntimeService, paneTitle: stri }) } +function publishRendererReleasedPane(runtime: OrcaRuntimeService, title: string): void { + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { + tabs: [ + { + tabId: TAB_ID, + worktreeId: WORKTREE_ID, + title, + activeLeafId: LEAF_ID, + layout: null + } + ], + leaves: [ + { + tabId: TAB_ID, + worktreeId: WORKTREE_ID, + leafId: LEAF_ID, + paneRuntimeId: 1, + ptyId: PTY_ID, + paneTitle: 'zsh' + } + ], + mobileSessionTabs: [ + { + worktree: WORKTREE_ID, + publicationEpoch: 'epoch-released', + snapshotVersion: 1, + activeGroupId: null, + activeTabId: `${TAB_ID}::${LEAF_ID}`, + activeTabType: 'terminal', + tabs: [ + { + type: 'terminal', + id: `${TAB_ID}::${LEAF_ID}`, + parentTabId: TAB_ID, + leafId: LEAF_ID, + ptyId: PTY_ID, + title, + isActive: true + } + ] + } + ] + }) +} + async function projectAgentStatus( runtime: OrcaRuntimeService ): Promise | undefined> { @@ -124,6 +170,15 @@ async function projectAgentStatus( } describe('mobile session tabs: live-title evidence vs published agent status', () => { + it('does not resurrect launch identity after the renderer clears it', async () => { + const runtime = await createRuntime() + publishRendererReleasedPane(runtime, '[Image #1] Inspect this') + + const result = await runtime.listMobileSessionTabs(`id:${WORKTREE_ID}`) + expect(result.tabs[0]).toEqual(expect.objectContaining({ type: 'terminal' })) + expect(result.tabs[0]).not.toHaveProperty('launchAgent') + }) + it('keeps renderer-published working under a neutral live title', async () => { const runtime = await createRuntime() publishRendererWorkingPane(runtime, 'Terminal') diff --git a/src/main/runtime/orca-runtime.test.ts b/src/main/runtime/orca-runtime.test.ts index 9597ecde0b5..8b1a8fa134e 100644 --- a/src/main/runtime/orca-runtime.test.ts +++ b/src/main/runtime/orca-runtime.test.ts @@ -24549,7 +24549,7 @@ describe('OrcaRuntimeService', () => { ) }) - it('derives remote OMP owner from live PTY metadata when the tab snapshot omits it', async () => { + it('normalizes a remote OMP title without republishing omitted launch identity', async () => { const spawn = vi.fn().mockResolvedValue({ id: 'pty-omp' }) const runtime = new OrcaRuntimeService(store) runtime.setPtyController({ @@ -24623,10 +24623,10 @@ describe('OrcaRuntimeService', () => { expect(result.tabs[0]).toEqual( expect.objectContaining({ type: 'terminal', - title: '\u280b OMP', - launchAgent: 'omp' + title: '\u280b OMP' }) ) + expect(result.tabs[0]).not.toHaveProperty('launchAgent') }) it('skips the foreground-process probe when the PTY launch agent is already known', async () => { diff --git a/src/main/runtime/orca-runtime.ts b/src/main/runtime/orca-runtime.ts index 917d8c1de40..daf9af49386 100644 --- a/src/main/runtime/orca-runtime.ts +++ b/src/main/runtime/orca-runtime.ts @@ -30859,11 +30859,13 @@ export class OrcaRuntimeService { { title: pty.lastOscTitle, updatedAt: pty.lastOscTitleAt } ) : null - const launchAgent = tab.launchAgent ?? liveLeafPty?.launchAgent ?? pty?.launchAgent ?? null + // Renderer omission is authoritative: PTY launch provenance outlives agent exit. + const launchAgent = tab.launchAgent ?? null + const launchOwnerAgent = launchAgent ?? liveLeafPty?.launchAgent ?? pty?.launchAgent ?? null // Why: a retained OMP hook stays stable while wrapper foreground reads can report Pi. const ownerAgent = resolvePaneAgentOwner({ - launchAgent, + launchAgent: launchOwnerAgent, hookAgent: tab.agentStatus?.agentType ?? hookAgentStatus?.agentType ??