diff --git a/src/main/runtime/orca-runtime-agent-session-operation.test.ts b/src/main/runtime/orca-runtime-agent-session-operation.test.ts index 56fa18cbb5b..9199e46783a 100644 --- a/src/main/runtime/orca-runtime-agent-session-operation.test.ts +++ b/src/main/runtime/orca-runtime-agent-session-operation.test.ts @@ -129,6 +129,26 @@ describe('agent-session create operation ledger', () => { expect(createTerminal).not.toHaveBeenCalled() }) + it('waits for Codex shell launch preparation before a structured resume', async () => { + const runtime = createRuntime() + const createTerminal = vi.spyOn(runtime, 'createTerminal').mockResolvedValue(terminal()) + + await runtime.ensureAgentSession({ + kind: 'explicit', + worktree: 'id:worktree-1', + agent: 'codex', + providerSession: { key: 'session_id', id: 'provider-session-1' } + }) + + expect(createTerminal).toHaveBeenCalledWith( + 'id:worktree-1', + expect.objectContaining({ + command: expect.stringContaining("'resume' 'provider-session-1'"), + startupCommandDelivery: 'shell-ready' + }) + ) + }) + it('selects nested SSH legacy fallback before reading a Pi transcript path locally', async () => { const runtime = createRuntime() const internal = runtime as unknown as { diff --git a/src/main/runtime/orca-runtime.ts b/src/main/runtime/orca-runtime.ts index 62d6534693f..1e1523e7bf6 100644 --- a/src/main/runtime/orca-runtime.ts +++ b/src/main/runtime/orca-runtime.ts @@ -26449,6 +26449,7 @@ export class OrcaRuntimeService { env: startup.env, launchConfig: startup.launchConfig, launchAgent: request.agent, + startupCommandDelivery: startup.startupCommandDelivery, presentation: request.presentation ?? 'background', tabId: request.placement?.tabId, leafId: request.placement?.leafId, diff --git a/src/renderer/src/components/terminal-pane/pty-connection.test.ts b/src/renderer/src/components/terminal-pane/pty-connection.test.ts index 375eac4cf55..12940d28ce9 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection.test.ts @@ -8444,6 +8444,7 @@ describe('connectPanePty', () => { expect.objectContaining({ sessionId: 'restored-session', command: "codex '--dangerously-bypass-approvals-and-sandbox' 'resume' 'codex-session-1'", + startupCommandDelivery: 'shell-ready', env: expect.objectContaining({ ORCA_PANE_KEY: paneKey, ORCA_AGENT_LAUNCH_TOKEN: expect.stringMatching(new RegExp(`^${UUID_RE}$`)) diff --git a/src/renderer/src/components/terminal-pane/pty-connection.ts b/src/renderer/src/components/terminal-pane/pty-connection.ts index 157679e0952..c4e67e6f1f8 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection.ts @@ -556,6 +556,9 @@ type ColdRestoreAgentResumeStartup = PendingStartupCommand & { agent: ResumableTuiAgent resumeProviderSession: AgentProviderSessionMetadata launchConfig: NonNullable>['launchConfig'] + startupCommandDelivery: NonNullable< + ReturnType + >['startupCommandDelivery'] launchToken: string useLiveEntry: boolean hasSleepingRecord: boolean @@ -5067,6 +5070,7 @@ export function connectPanePty( ORCA_AGENT_LAUNCH_TOKEN: coldRestoreLaunchToken }, launchConfig: startupPlan.launchConfig, + startupCommandDelivery: startupPlan.startupCommandDelivery, resumeProviderSession: providerSession, launchToken: coldRestoreLaunchToken, useLiveEntry: Boolean(useLiveEntry), @@ -5274,9 +5278,11 @@ export function connectPanePty( ...(connectionId && startupOverride?.command && !shouldDeliverStartupViaTerminalPaste ? { commandDelivery: 'provider' as const } : {}), - ...(connectionId && startupOverride?.command - ? { startupCommandDelivery: 'shell-ready' as const } - : {}), + ...(coldRestoreOverride?.startupCommandDelivery + ? { startupCommandDelivery: coldRestoreOverride.startupCommandDelivery } + : connectionId && startupOverride?.command + ? { startupCommandDelivery: 'shell-ready' as const } + : {}), ...(startupOverride?.env ? { env: mergeStartupEnvWithPaneIdentity(startupOverride.env) } : {}), @@ -8718,6 +8724,9 @@ export function connectPanePty( ? { launchToken: coldRestoreStartup.launchToken } : {}), ...(coldRestoreStartup?.agent ? { launchAgent: coldRestoreStartup.agent } : {}), + ...(coldRestoreStartup?.startupCommandDelivery + ? { startupCommandDelivery: coldRestoreStartup.startupCommandDelivery } + : {}), ...(shouldDeclareHiddenAtSpawn() ? { initiallyHidden: true } : {}), ...(directSshRetryAttempt ? { admitPtyId: claimCapturedDirectSshRetryPty } : {}), callbacks: outputCallbacks.callbacks @@ -8963,6 +8972,9 @@ export function connectPanePty( : {}), ...(coldRestoreStartup?.launchToken ? { launchToken: coldRestoreStartup.launchToken } : {}), ...(coldRestoreStartup?.agent ? { launchAgent: coldRestoreStartup.agent } : {}), + ...(coldRestoreStartup?.startupCommandDelivery + ? { startupCommandDelivery: coldRestoreStartup.startupCommandDelivery } + : {}), ...(shouldDeclareHiddenAtSpawn() ? { initiallyHidden: true } : {}), ...(directSshRetryAttempt ? { admitPtyId: claimCapturedDirectSshRetryPty } : {}), callbacks: outputCallbacks.callbacks diff --git a/src/shared/tui-agent-resume-startup.ts b/src/shared/tui-agent-resume-startup.ts index 5b64598f98d..f4924b83c47 100644 --- a/src/shared/tui-agent-resume-startup.ts +++ b/src/shared/tui-agent-resume-startup.ts @@ -64,6 +64,7 @@ export function buildAgentResumeStartupPlan(args: { expectedProcess: TUI_AGENT_CONFIG[args.agent].expectedProcess, followupPrompt: null, launchConfig, + ...(args.agent === 'codex' ? { startupCommandDelivery: 'shell-ready' as const } : {}), ...(Object.keys(applied).length > 0 ? { sessionOptions: { ...applied } } : {}), ...(args.agentEnv ? { env: { ...args.agentEnv } } : {}) } diff --git a/src/shared/tui-agent-startup.test.ts b/src/shared/tui-agent-startup.test.ts index b3220956677..d088e35a0eb 100644 --- a/src/shared/tui-agent-startup.test.ts +++ b/src/shared/tui-agent-startup.test.ts @@ -591,6 +591,7 @@ describe('tui agent startup plans', () => { }) expect(plan?.launchCommand).toBe("codex 'resume' 's1'") + expect(plan?.startupCommandDelivery).toBe('shell-ready') }) it('quotes Windows resume argv for cmd.exe when shell is cmd', () => {