Repository navigation
refactor(pty): one host-env step for both terminal spawn lanes - #29297
Conversation
…env differently Characterization on main's code before the host-env step merges: which failed env builds sweep per-PTY state (minted ids only, both lanes), the empty-id split, the host-only WSL Pi/OMP guest readiness wait, and that a host create operation still waits on a managed Codex login.
The window (pty:spawn) and host (runtime controller) lanes each carried a copy of Codex resume, Codex home selection, the managed-auth wait, backfill recovery and the daemon host-env build. Both now call resolvePtySpawnHostEnv. Lane differences are explicit inputs: two TEMPORARY ones (the host-only WSL Pi/OMP guest readiness wait; the host skipping host env for an empty id) and three that mean the same in both lanes. The resume step's launchEnv was never read and is gone.
…-shared-host-env # Conflicts: # src/main/startup/codex-session-resume-launch.ts
…ODEX_HOME orca serve (#29209) skips resume prep for a launch whose env names a client-sent CODEX_HOME.
|
Two terminal-start paths each maintained their own account and environment preparation, allowing the same change to reach one path and miss the other. This PR consolidates that preparation into one function while preserving the existing behavior of each path; users should see the same terminals, commands, accounts and notices. The review covered the full diff with independent correctness and entry-point traces plus an architecture challenger. It added a missing integrated test for resuming a conversation during an account-switch restart and corrected an unsupported timing claim in the description. Removing selected-account forwarding makes that test fail; restoring it passes. No production regression was found. The final main integrations preserve main's terminal-image setting in the shared builder and carry its dropped-resume decision to the new resume-identity consumer. The continued reviewer approved the image-setting integration, and a fresh narrow reviewer approved the resume-identity integration with no findings. Verification: 34 named suites / 491 tests passed on this head, including both new resume-identity contracts, the SQLite runtime boundary, existing provider routing contract and main's repaired headless renderer tests. Full CI passed on this exact head, including static analysis/typecheck, both packaging jobs, all five unit-test shards and the aggregate gate. GitHub confirms CLEAN, out of draft and zero unresolved threads. The remote-resume review claim was traced through the actual renderer, preload and both spawn paths and refuted: both reject nonempty connection IDs before shared environment preparation. Production is net −49 lines. The existing differences in WSL readiness, empty-session handling and lifecycle environment reporting remain deliberate follow-ups; the existing host cleanup difference is unchanged. The shared async call adds a promise boundary, so identical microtask timing is not claimed. Real Electron QA used hidden Windows high spec copies, CDP, isolated homes and Command Prompt: main For Brennan's review Main/PR screenshots, in pairs: Three deliberate boundaries to inspect:
|
📝 Walkthrough
Priority: ➖ Normal Merge Risk: 🟡 Moderate · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
ad9641b1-4a42-4a5d-8c3a-c340e9a27658
📒 Files selected for processing: 7
src/main/ipc/pty-daemon-spawn-session-identity.test.tssrc/main/ipc/pty-spawn-codex-home-unavailable.test.tssrc/main/ipc/pty/ipc/spawn-env-codex.tssrc/main/ipc/pty/ipc/spawn-types.tssrc/main/ipc/pty/runtime/controller-deps.tssrc/main/ipc/pty/runtime/spawn-preflight.tssrc/main/ipc/pty/spawn-host-env.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
…-shared-host-env # Conflicts: # src/main/ipc/pty/runtime/spawn-preflight.ts






ELI5
Orca can start a terminal two ways: the window asks for it directly, or Orca's host starts it (for the CLI, agent launches and paired devices). Each way kept its own copy of the step that builds the terminal's environment: resuming a Codex session, picking which Codex account home to use, waiting for a managed Codex login, and adding Orca's own variables (agent status hooks, the Orca CLI path, proxy settings and so on). Two copies drift apart, and "the environment differs between the two paths" was one of the reasons an earlier attempt to move the "+" button onto the host's path had to be reverted (#27173). This PR makes that step one shared function. Nothing changes for users yet: the places where the copies still disagree are passed in as explicit inputs, and the temporary ones name the follow-up that removes them.
What Changed
Before (on main): the window lane (
pty:spawn,ipc/spawn-env-codex.ts) and the host lane (runtime/spawn-preflight.ts) each had about 120 near-identical lines covering:After:
resolvePtySpawnHostEnv(src/main/ipc/pty/spawn-host-env.ts, next to last PR'sspawn-startup-target.ts) does all of that once and returns:PtySpawnCodexResumeDeps).Lane differences, now explicit inputs:
awaitsWslPiOmpGuestReadinessemptySessionIdSkipsHostEnvcallerNamedSessionargs.sessionId !== undefinedmintedSessionIdrequestedSessionId === undefined, which is the same fact (sessionId = requested ?? mint)resumeOnSelectedAccountreplacesPtyId)Removed with no behavior change, because it was unreachable:
getProviderthrows for any non-empty connection id before this step runs, in both lanes. The existing "only this machine spawns here" comment covers it.The resume step's
launchEnvis now the lane's env before the resume strip, in both lanes. The window already passed exactly that. The host passed the raw request env; it now passes the same env plus its Claude profile pointer and terminal handle.orca servereadsCODEX_HOMEfrom this env, to skip resume prep for a client-sent account home. The desktop implementation ignores it.CODEX_HOMEis the same in both envs: the Claude profile adds onlyCLAUDE_*keys, the handle addsORCA_TERMINAL_HANDLE, and Claude auth never runs for a Codex resume.CODEX_HOME.Not part of this step, so unchanged here:
Orderings that move, with no behavior change:
Users see: no change.
Why
This is row 4 (first half) of the launch-convergence plan. Every later step that moves a producer onto one spawn path needs each spawn step to exist once. The host-env step was the largest duplicated block. A one-line host-env option added in one lane and forgotten in the other is exactly how the two paths drift (#28180 currently has to add its new option twice). Passing the differences as named inputs keeps this PR a pure merge. Fixing the Pi/OMP wait or the empty-id split here would change behavior, so each gets its own PR.
Alternatives considered:
ownsNewSession). That would quietly widen the host's env-failure sweep to create-operation and new-session ids. It is kept asmintedSessionIdand noted for row 7.Linked Issue
Part of the launch-convergence plan (row 4, first half); no issue.
Visual Proof
Real Electron comparison on Windows high spec, driven through Chrome DevTools Protocol with isolated homes: main
d9521f9991bversus PRccff2d60308. Command Prompt was selected through Settings in both builds. The "+" terminal environment, Codex command/environment up to its sign-in screen, and system-default account-home UI matched. Build-specific labels and resource/shadow rendering differed as expected. No authenticated Codex turn is claimed.Blocked: Session History resume would inspect WSL homes outside the rig's isolation; Windows PowerShell would load a real Documents profile; an alternate managed account requires a sign-in. Resume and selected-account wiring have automated contract coverage. Real-config hash/stat guards held, and the QA worker stopped every recorded process.
Screenshots (main, then PR):






Testing
Commit 1 pins main's behavior before the refactor (passes on main):
pty-daemon-spawn-session-identity.test.ts:pty-spawn-codex-home-unavailable.test.ts: a host create operation waits on a managed Codex login; a caller-named session does not, in either lane.After syncing main once (#29209): a pin that both lanes hand Codex resume prep the request's
CODEX_HOME. The same test now covers a window account restart with resume metadata: only the restart resumes into the selected home, while ordinary resumes retain their source home. Removing the selected-account forwarding makes that restart row fail.Commit 2 keeps every suite unchanged and green. After the main sync: 27 files / 414 tests, including #29209's
orcad-account-services:pty-launch-parity,pty-launch-race-parity,pty-daemon-spawn-session-identity;pty-daemon-spawn-codex-auth,pty-daemon-spawn-agent-home-env,pty-spawn-env-codex-home-routing,pty-spawn-env-codex-resume-provenance,pty-spawn-codex-home-unavailable,pty-codex-account-attribution);codex-account-restart-resume,codex-session-resume-daemon-guard,codex-launch-per-agent-hook-opt-out);pty-spawn-env-agent-overlays,pty-agent-pane-launch,pty-daemon-spawn-wsl-runtime,pty-spawn-cwd-fallback,runtime/spawn-preflight-requested-shell, and the neighbouring spawn suites.Final main integration: the shared builder preserves main's terminal-image setting once, and both lanes preserve main's dropped-resume decision for the new identity consumer. Final head
e874c02c3168b547ad7b086458c21a66efeafda9passed all 34 explicitly named suites (491 tests), including both new resume-identity contracts, environment, parity/races, SQLite boundary, provider routing and repaired renderer fixtures. The narrow integration reviewer agreed with no findings. Full PR CI passed on this exact head, including static analysis/typecheck, both packaging jobs, all five test shards and the aggregate. The PR is out of draft, CLEAN and has zero unresolved review threads.The builder checked readiness always on, empty-id skip off, always sweep and always wait against the parity pins. Review also removed selected-account forwarding temporarily: the new restart row failed, then the restored implementation passed.
Platforms: Windows and WSL behavior is covered by the platform-switching suites. SSH: an SSH connection never reaches this step (the provider lookup refuses it first), and the remote host runs its own host lane.
Size
Production net −49 (+322 / −371) against the final merged main. Test additions remain below production additions; review extends the existing home-selection contract test rather than adding another fixture.
spawn-host-env.ts(new shared step)spawn-env-codex.tsruntime/spawn-preflight.tsOverlaps with open PRs
buildPtyHostEnvoption lands once inspawn-host-env.tsinstead of twice.runtime/spawn-preflight.ts.Agent skill upstream boundary
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)