diff --git a/src/renderer/src/components/terminal-pane/TerminalPane.tsx b/src/renderer/src/components/terminal-pane/TerminalPane.tsx index fbe614a12..95038053f 100644 --- a/src/renderer/src/components/terminal-pane/TerminalPane.tsx +++ b/src/renderer/src/components/terminal-pane/TerminalPane.tsx @@ -130,6 +130,7 @@ import { readPrimarySelectionText } from '@/lib/primary-selection' import { APP_MENU_PASTE_EVENT } from '@/lib/app-menu-paste' +import { CODEX_ACCOUNT_RESTART_STARTUP } from '@/lib/codex-session-restart' import { WORKSPACE_FILE_PATH_MIME, WORKSPACE_FILE_PATHS_MIME } from '@/lib/workspace-file-drag' import { isTerminalSessionStateSaveFailure } from '../../../../shared/terminal-session-state-save-failure' import { isTerminalZeroDimensionsDiagnostic } from '../../../../shared/terminal-zero-dimensions-diagnostic' @@ -1620,7 +1621,7 @@ export default function TerminalPane({ tabId, worktreeId, cwd, - startup: { command: 'codex' }, + startup: CODEX_ACCOUNT_RESTART_STARTUP, paneTransportsRef, paneMode2031Ref, paneKittyKeyboardModesRef, diff --git a/src/renderer/src/lib/codex-session-restart.test.ts b/src/renderer/src/lib/codex-session-restart.test.ts index b75a961c5..6f8a83c82 100644 --- a/src/renderer/src/lib/codex-session-restart.test.ts +++ b/src/renderer/src/lib/codex-session-restart.test.ts @@ -1,6 +1,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { useAppStore } from '@/store' -import { markLiveCodexSessionsForRestart } from './codex-session-restart' +import { shouldUseShellReadyStartupDelivery } from '../../../shared/codex-startup-delivery' +import { + CODEX_ACCOUNT_RESTART_STARTUP, + markLiveCodexSessionsForRestart +} from './codex-session-restart' import { createCompatibleRuntimeStatusResponseIfNeeded, type RuntimeEnvironmentCallRequest @@ -11,6 +15,16 @@ const ACCOUNT_A = 'account-a@example.com' const ACCOUNT_B = 'account-b@example.com' const ACCOUNT_C = 'account-c@example.com' +describe('CODEX_ACCOUNT_RESTART_STARTUP', () => { + it('waits for shell readiness before relaunching Codex after an account switch', () => { + expect(CODEX_ACCOUNT_RESTART_STARTUP).toEqual({ + command: 'codex', + startupCommandDelivery: 'shell-ready' + }) + expect(shouldUseShellReadyStartupDelivery(CODEX_ACCOUNT_RESTART_STARTUP)).toBe(true) + }) +}) + describe('markLiveCodexSessionsForRestart', () => { const originalWindow = (globalThis as { window?: typeof window }).window const runtimeEnvironmentCall = vi.fn() diff --git a/src/renderer/src/lib/codex-session-restart.ts b/src/renderer/src/lib/codex-session-restart.ts index 36778b7be..29ef8af63 100644 --- a/src/renderer/src/lib/codex-session-restart.ts +++ b/src/renderer/src/lib/codex-session-restart.ts @@ -2,6 +2,13 @@ import type { AppState } from '@/store' import { useAppStore } from '@/store' import { inspectRuntimeTerminalProcess } from '@/runtime/runtime-terminal-inspection' +// Why: prompt integrations such as Starship can outlast the daemon's 300ms +// Codex fast-path timeout; account restarts must wait until the shell accepts input. +export const CODEX_ACCOUNT_RESTART_STARTUP = { + command: 'codex', + startupCommandDelivery: 'shell-ready' +} as const + function normalizeProcessName(processName: string | null): string | null { if (!processName) { return null