From e259e276ddedebaf3800fc12cb5ce478a00ed5eb Mon Sep 17 00:00:00 2001 From: Neil Date: Wed, 11 Nov 2026 01:21:09 -0800 Subject: [PATCH] fix(cloud): PC-3b Start Claude on the held strip brings the agent's tab forward composer-redo (pc3b-390-394/4-started.png): Start opened the Claude tab in the background (a create's first agent asks for activate:false), so the person stayed on the plain Terminal and never saw the queued prompt run. A hold released by the person's Start now creates the agent with activate:true; a Renew-driven auto-start (possibly on a background tab) keeps the original args and never steals focus. --- .../src/lib/orca-cloud/cloud-agent-launch-hold.ts | 14 +++++++++++++- .../orca-cloud/cloud-web-host-launch-hold.test.ts | 6 ++++-- .../lib/orca-cloud/cloud-web-host-launch-hold.ts | 9 +++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/renderer/src/lib/orca-cloud/cloud-agent-launch-hold.ts b/src/renderer/src/lib/orca-cloud/cloud-agent-launch-hold.ts index a40286ecde8..ef420d0cadc 100644 --- a/src/renderer/src/lib/orca-cloud/cloud-agent-launch-hold.ts +++ b/src/renderer/src/lib/orca-cloud/cloud-agent-launch-hold.ts @@ -121,7 +121,19 @@ export function readCloudAgentHold(paneKey: string): CloudAgentHold | null { } export function releaseCloudAgentHold(paneKey: string, outcome: 'proceed' | 'cancel'): void { - holds.get(paneKey)?.release(outcome) + const hold = holds.get(paneKey) + if (hold && outcome === 'proceed') { + // The strip's Start: the person asked for the agent here and now (a Renew's auto-start didn't). + startedByPerson.add(paneKey) + } + hold?.release(outcome) +} + +const startedByPerson = new Set() + +/** Whether this hold was released by the person's Start (read once): its agent should take focus. */ +export function takeCloudAgentHoldStartedByPerson(paneKey: string): boolean { + return startedByPerson.delete(paneKey) } // A launch decides within this budget; a slow or failed read never holds the agent. diff --git a/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.test.ts b/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.test.ts index e1a93d041c7..dc8ec5c7c38 100644 --- a/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.test.ts +++ b/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.test.ts @@ -120,7 +120,8 @@ describe('createWithCloudAgentHold (the one hold for every Orca Cloud agent laun releaseCloudAgentHold(key, 'proceed') await expect(result).resolves.toBe(AGENT) // The original launch, untouched: its command still carries the first prompt. - expect(create).toHaveBeenLastCalledWith(CREATE_AGENT) + // Started by the person's click: the agent's tab comes forward. + expect(create).toHaveBeenLastCalledWith({ ...CREATE_AGENT, activate: true }) expect(host.close).toHaveBeenCalledWith( expect.objectContaining({ tabId: toWebTerminalSurfaceTabId('h1'), reason: 'user' }) ) @@ -141,7 +142,7 @@ describe('createWithCloudAgentHold (the one hold for every Orca Cloud agent laun await expect(result).resolves.toBe(AGENT) const agentCreates = create.mock.calls.filter(([args]) => args.launchAgent === 'claude') // The prompt rides in the prepared command, delivered once by the one agent create. - expect(agentCreates).toEqual([[launch]]) + expect(agentCreates).toEqual([[{ ...launch, activate: true }]]) expect(create).toHaveBeenCalledTimes(2) expect(readCloudAgentHold(key)).toBeNull() }) @@ -159,6 +160,7 @@ describe('createWithCloudAgentHold (the one hold for every Orca Cloud agent laun }) setOrcaCloudAgentAccountsStateForTest(accounts({ state: 'active' })) await expect(result).resolves.toBe(AGENT) + // Renew's auto-start: the original args, no focus taken (the tab may be in the background). expect(create).toHaveBeenLastCalledWith(args) }) diff --git a/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.ts b/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.ts index 46c905b9884..d6813a37685 100644 --- a/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.ts +++ b/src/renderer/src/lib/orca-cloud/cloud-web-host-launch-hold.ts @@ -18,7 +18,8 @@ import { isOrcaCloudEnvironmentId } from './orca-cloud-environment-id' import { cloudAgentLaunchDecision, cloudTabHoldKey, - holdCloudAgentLaunch + holdCloudAgentLaunch, + takeCloudAgentHoldStartedByPerson } from './cloud-agent-launch-hold' type CreateHostTerminal = ( @@ -86,7 +87,11 @@ export async function createWithCloudAgentHold( ) return placeholder } - const created = await create(args) + // Started by the person's click in the held pane: bring the agent's tab forward so they see their + // queued prompt run. A Renew's auto-start (maybe on a background tab) never steals focus. + const created = await create( + takeCloudAgentHoldStartedByPerson(cloudTabHoldKey(tabId)) ? { ...args, activate: true } : args + ) // The agent opened in its own tab; the placeholder shell has done its job. if (args.environmentId) { void closeWebRuntimeSessionTab({