diff --git a/src/main/ipc/pty.test.ts b/src/main/ipc/pty.test.ts index 39752745d4a..8de2e6bd40d 100644 --- a/src/main/ipc/pty.test.ts +++ b/src/main/ipc/pty.test.ts @@ -2097,6 +2097,42 @@ describe('registerPtyHandlers', () => { expect(daemonSpawn.mock.calls.at(-1)![0].env.ORCA_SEQUENCED_STARTUP_COMMAND).toBe(sequenced) }) + posixOnlyIt( + 'strips the sequenced startup command on the local-provider spawn path too', + async () => { + // Why: the daemon branch is the only one that re-derives the spawn env from + // baseEnv, so a local spawn is where a strip that lands on the wrong variable + // silently survives — and the wrapper would `eval` the resume anyway. + const mockProc = createMockProc() + spawnMock.mockReturnValue(mockProc.proc) + registerWithTrustedHomes([OTHER_HOME], OTHER_HOME) + + await spawnCodexResume(ORIGIN_ROLLOUT, { + env: { ORCA_SEQUENCED_STARTUP_COMMAND: `codex 'resume' '${RESUME_SESSION_ID}'` } + }) + + const env = spawnMock.mock.calls.at(-1)![2].env as Record + expect(env.ORCA_SEQUENCED_STARTUP_COMMAND).toBe('codex') + } + ) + + posixOnlyIt( + 'leaves the local-provider sequenced startup command alone when provenance is verified', + async () => { + const mockProc = createMockProc() + spawnMock.mockReturnValue(mockProc.proc) + registerWithTrustedHomes([ORIGIN_HOME], OTHER_HOME) + const sequenced = `codex 'resume' '${RESUME_SESSION_ID}'` + + await spawnCodexResume(ORIGIN_ROLLOUT, { + env: { ORCA_SEQUENCED_STARTUP_COMMAND: sequenced } + }) + + const env = spawnMock.mock.calls.at(-1)![2].env as Record + expect(env.ORCA_SEQUENCED_STARTUP_COMMAND).toBe(sequenced) + } + ) + it('omits the notice on a reattach that never ran this launch command', async () => { setupResumeDaemonProvider({ isReattach: true }) registerWithTrustedHomes([OTHER_HOME], OTHER_HOME) diff --git a/src/main/ipc/pty.ts b/src/main/ipc/pty.ts index ffbe1b528cd..1bf38567061 100644 --- a/src/main/ipc/pty.ts +++ b/src/main/ipc/pty.ts @@ -4472,7 +4472,6 @@ export function registerPtyHandlers( // Why: SSH can strip ORCA_PANE_KEY when remote hooks are off; IPC tab/leaf metadata still names the pane. const reservationPaneKey = metadataPaneKey ?? validatedPaneKey const validatedLeafId = verifiedLeafId ?? metadataLeafId - let env: Record | undefined = baseEnv const effectiveShellOverride = terminalRuntimeOptions.shellOverride const nativeWindowsConptySpawn = isNativeWindowsLocalPtySpawn({ connectionId: args.connectionId, @@ -4498,6 +4497,9 @@ export function registerPtyHandlers( const codexResumeHome = codexResumeLaunch.codexResumeHome const launchCommand = codexResumeLaunch.command baseEnv = stripSequencedStartupResumeArgv(baseEnv, codexResumeLaunch) + // Why: declared after the strip so a local-provider spawn cannot capture the + // pre-strip env — only the daemon branch below re-derives this from baseEnv. + let env: Record | undefined = baseEnv const selectedCodexHomePath = isDaemonHostSpawn ? getCompatibleSelectedCodexHomePath( codexSelectionTarget,