Skip to content

Keep Orca CLI first after shell startup - #25130

Merged
nwparker merged 11 commits into
mainfrom
fix/orca-cli-path-after-shell-startup
Oct 4, 2026
Merged

nwparker merged 11 commits into
mainfrom
fix/orca-cli-path-after-shell-startup

Conversation

@nwparker

@nwparker nwparker commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 18 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​691 $\color{#cf222e}{\Huge{\mathbf{−}}}$​26 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​665
Prod 11 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​102 $\color{#cf222e}{\Huge{\mathbf{−}}}$​4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​98

ELI5

Agents launched by Orca could select an older globally installed CLI after shell startup reordered PATH. Re-sourcing the zsh wrapper could also replace the user's restored line editor with a recursive Orca callback. Orca now restores its selected CLI and leaves completed startup initialization retired when the wrapper is sourced again.

What Changed

The execution host publishes its selected CLI directory. Local, daemon and relay Bash wrappers restore it after profiles; the shared zsh wrapper restores it after user startup. A one-shot scheduler invokes the existing deferred initializer after user prompt hooks, preserving the user's hooks, exit status, options, history and scheduled jobs. Registration and arming now share the existing completed-initialization guard, preventing re-sourcing from installing that callback again.

SSH replaces or clears the client's directory with the execution host's directory. The optional marker retains its feature-selection contract, and Windows retains WSL handling. Generated fixtures and shell-contract selection cover the same behavior.

Why

Profiles can undo the initial PATH prepend. Reusing host path selection and deferred initialization restores the app runtime after stock zsh startup, even when it clears the prompt-hook array. Reusing the initialization guard also preserves the user's line editor after startup without adding another state mechanism.

Linked Issue

Found during the OpenCode worker-dispatch reproduction for #19980. This startup repair does not close that broader issue on its own.

Visual Proof

N/A — shell startup and command lookup have no rendered UI changes. Raw private PTY before/after transcripts are retained.

Testing

  • 811a3593 passes 426 tests across 25 suites, with four existing platform skips; all three desktop typechecks, full owned formatting, changed-code checks and the configured repository scan pass. Full owned lint retains one unchanged directive warning.
  • Two genuine macOS zsh controls execute installed OpenCode 2.0.16 during startup and then re-source the wrapper. Each reproduces six recursive line-editor diagnostics on parent 0716bd6f; each has zero after this correction, with the user's widget retained, no saved widget or dead prompt hook, and startup occurring once. The same final regression tests fail on the parent and pass after the fix.
  • Earlier four macOS controls preserve incoming status 42, sticky options, user hook order and future scheduled jobs while executing the installed OpenCode version command exactly once. Scheduler unavailability now checks its own diagnostic precisely and retains the complete raw output.
  • Source-pinned Ubuntu 24.04 ARM before reproduces stock line-editor replacement and cleared prompt hooks selecting the ambient CLI. The parent fixed-source run selects the private CLI and initializes once in all four controls, consuming its own callback and retaining future scheduled jobs. These runs compile exact named source inputs and use identical stock zsh 5.9 startup bytes.

The new repeat-source runtime controls run on macOS, not Linux. Mac controls execute OpenCode's version command; the prior Linux controls establish lookup and startup behavior without running OpenCode. Model/task completion and fresh/nested startup remain separately demonstrated on their frozen combined source.

Review

Independent reviews verify all 30 owned files, all 32,337 other source files against parent 0716bd6f, the complete physical source and raw checks. Only the shell template, its live-shell test and three generated fixtures change in this correction. All 329 recorded correction process observations are freshly absent; the parent qualification retains its separate cleanup bounds. The worker preamble and wire opcodes remain unchanged. Fresh public CI must pass before merge.

Agent skill upstream boundary

  • Not applicable; no upstream skill-installer material is copied or translated.

Notes

Executed platforms are macOS and the source-pinned parent on native Ubuntu ARM. SSH/Windows/WSL ownership cases are automated; no live SSH or Windows shell run is claimed. Older wrappers ignore the optional environment field. Temporary Linux diagnostic branches are evidence carriers and will not be merged.

Checklist

  • Focused startup fix with generated fixtures and causal controls.
  • Before/after behavior, mechanism and reason explained.
  • N/A visual proof explained.
  • Self-reviewed and independently reviewed.
  • Cross-platform, folder workspace and SSH ownership considered.
  • Fresh public CI passes before merge.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 601d4ae6-8289-4fc0-9482-b78ca39f194e
📥 Commits

Reviewing files that changed from the base of the PR and between 0716bd6 and 811a359.

📒 Files selected for processing (5)
  • src/main/__fixtures__/shell-wrapper-snapshots/daemon-zsh-zshenv.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/local-zsh-zshenv.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/relay-zsh-zshenv.txt
  • src/main/shell-templates.ts
  • src/main/zsh-deferred-startup-line-init.live-shell.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/main/shell-templates.ts
  • src/main/fixtures/shell-wrapper-snapshots/relay-zsh-zshenv.txt
  • src/main/fixtures/shell-wrapper-snapshots/daemon-zsh-zshenv.txt
  • src/main/fixtures/shell-wrapper-snapshots/local-zsh-zshenv.txt

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The changes set ORCA_CLI_BIN_DIR in supported child environments and restore it to PATH in Bash and Zsh startup wrappers. The Zsh wrapper adds deferred line-init initialization, restores any saved widget, and avoids duplicate OSC 133 hooks. Tests cover child environment selection, shell PATH precedence, and Zsh startup scenarios.

Priority: ⬆️ High

Merge Risk: 🔵 Low · up to 811a3

In this uncommon Zsh configuration, the ambient CLI may remain ahead of Orca and startup readiness may not be installed. The risk is bounded, but merits owner awareness.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 811a3

The change keeps command lookup tied to the selected local or remote installation. No new privilege grant or cross-host bypass was established, but uncommon startup and recovery cases remain uncertain.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The supported exposure is command resolution in affected child shells and descendants on the local or selected remote host. The inspected restoration code changes PATH, not execution identity. Modifying startup files already permits code execution within that shell context; no additional privilege acquisition was established.

Trust Boundaries and Controls

  • observed — SSH removes the inherited client directory before applying remote bridge state. The session constructs the bridge directory beneath the deployment result's remote home, passes it to the PTY provider, and installs launcher files through the ready SSH connection. This supports remote-host path provenance rather than restoration of a client-host directory; filesystem ownership and connection authentication were not independently assessed.

Resilience and Maintainability Implications

  • inferred — If scheduler loading fails and later startup files both replace the temporary widget and clear the prompt-hook array, no inspected registered trigger remains to restore CLI precedence or readiness. The test covers those conditions separately. Interruption recovery is also unproven because the completion flag precedes restoration and cleanup without an enclosing always block. These are residual guarantee limits, not established PR-introduced security regressions.

Hardening Proposals

  • proposed — Consider an interruption-safe completion and cleanup protocol, with explicit recovery behavior when all startup triggers are displaced. Validate the combined scheduler-unavailable and widget-replacement state before treating post-startup CLI precedence as unconditional.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 23 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: keeping Orca’s selected CLI first in PATH after shell startup.
Description check ✅ Passed The description covers the required sections with a clear explanation of the change, its purpose, linked issue context, testing, platform scope, and checklist. It explains why visual proof is not appl…
Full details: Docstring Coverage

Explanation

Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 23 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1a727570-2c60-4882-b07c-4eab0d8ffb34
📥 Commits

Reviewing files that changed from the base of the PR and between af13da5 and 2746e62.

📒 Files selected for processing (18)
  • src/main/__fixtures__/shell-wrapper-snapshots/daemon-bash-rcfile.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/daemon-zsh-zshenv.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/local-bash-rcfile.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/local-zsh-zshenv.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/relay-bash-rcfile.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/relay-zsh-zshenv.txt
  • src/main/cli/orca-cli-child-path.test.ts
  • src/main/cli/orca-cli-child-path.ts
  • src/main/daemon/daemon-bash-shell-ready-rcfile.ts
  • src/main/daemon/shell-ready-bash-wrapper.test.ts
  • src/main/providers/local-pty-shell-ready-bash-rcfile.ts
  • src/main/providers/ssh-pty-spawn-env.test.ts
  • src/main/providers/ssh-pty-spawn-env.ts
  • src/main/shell-startup-feature-channel.test.ts
  • src/main/shell-startup-features.ts
  • src/main/zsh-startup-wrapper-builder.ts
  • src/relay/pty-shell-overlay-wrappers.ts
  • src/shared/orca-cli-shell-path.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Comment thread src/main/zsh-startup-wrapper-builder.ts Resolved

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Two existing SSH provider tests fail once buildSshPtySpawnEnv starts injecting ORCA_CLI_BIN_DIR — their expected env objects were not updated, so this reds CI. One design question on the overlay-key broadening is noted inline.

Reviewed changes

  • prependOrcaCliDirToChildPath now records the CLI directory it selects (dev launcher dir, packaged Linux shim dir, packaged macOS Resources/bin) in a new ORCA_CLI_BIN_DIR env key on non-Windows platforms.
  • A shared POSIX snippet re-prepends that directory in every local/daemon/relay bash rcfile and zsh .zshenv, so a profile that reset or reordered PATH cannot hide this app's CLI. SSH replaces the client value with the remote bridge dir; Windows clears it.
  • ORCA_CLI_BIN_DIR is added to OVERLAY_ENV_KEYS; six wrapper snapshots are regenerated and Bash/zsh/SSH tests were added.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread src/main/providers/ssh-pty-spawn-env.ts Resolved
Comment thread src/main/shell-startup-features.ts Resolved

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one minor maintainability suggestion.

Reviewed changes

Reviewed the two commits added since the prior pullfrog review (5a2479b7b6, c6bc30f831).

  • Added a one-shot zsh zle-line-init fallback that runs Orca's deferred init even when a user config replaces precmd_functions, saving the prior widget in __orca_saved_line_init and restoring it before the readiness hook captures it.
  • Moved ORCA_CLI_POSIX_PATH_RESTORE out of the zsh overlay guard so any wrapped pane re-prepends the app CLI dir, and removed ORCA_CLI_BIN_DIR from OVERLAY_ENV_KEYS so a bare pane still selects no features.
  • Updated the SSH spawn-env expectations and added SSH/WSL/plain-pane controls, strengthened the scoped-histfile live test, added a chained-prompt live test, and regenerated the six wrapper snapshots.

ℹ️ Nitpicks

  • src/main/zsh-deferred-startup-line-init.ts:11 — local __orca_prev_line_init_fn="" is a load-bearing recursion guard (it keeps __orca_prompt_mark from re-entering the add-zle-hook-widget dispatcher that is already on the stack). It is the only statement in this file without a Why: comment; a one-line note would keep a future reader from removing it as redundant.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@nwparker

nwparker commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

The original Linux shell failure is now reproduced on Ubuntu 24.04 ARM with stock zsh 5.9-6ubuntu2 in the isolated diagnostic run. The exact published c6 shell code initializes correctly in three controls. When the stock global zshrc replaces the keyboard initialization widget and the user clears the prompt-hook array, both initialization paths are lost: CLI lookup selects the controlled ambient executable and deferred initialization never runs.

This is cause evidence for the current failure, not a successful repair. The diagnostic captures real Linux shell initialization and CLI lookup only; it does not launch OpenCode or a model task on Linux. The production successor is still private while we verify that it preserves user prompt hooks, their previous-command status and zsh options.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e924e6d4-c161-4bed-b886-e1f33cff0eda
📥 Commits

Reviewing files that changed from the base of the PR and between c6bc30f and 0716bd6.

📒 Files selected for processing (11)
  • .github/workflows/pr.yml
  • config/scripts/ci-unit-files.mjs
  • config/scripts/pr-workflow-parallelism.test.mjs
  • src/main/__fixtures__/shell-wrapper-snapshots/daemon-zsh-zshenv.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/local-zsh-zshenv.txt
  • src/main/__fixtures__/shell-wrapper-snapshots/relay-zsh-zshenv.txt
  • src/main/codex/codex-structured-child-environment.test.ts
  • src/main/codex/codex-structured-session-adapter.test.ts
  • src/main/runtime/structured-session-child-identity-env.test.ts
  • src/main/zsh-deferred-startup-line-init.live-shell.test.ts
  • src/main/zsh-deferred-startup-line-init.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the four commits added since the prior pullfrog review (f4bd404827, db9634c0c3, 5098be93ec, 0716bd6fc2), which replace the precmd-override fallback with a one-shot sched callback and expand the live-shell controls.

  • Replaced the __orca_deferred_precmd / __orca_saved_precmd monkey-patch of functions[precmd] with __orca_deferred_sched_init, a one-shot sched +0 callback that runs Orca's deferred init after the user's own prompt hooks and preserves the incoming $? so %? in the prompt is not clobbered.
  • __orca_arm_deferred_line_init now also arms that callback when zsh/sched loads, while keeping the zle-line-init binding for shells where the module is unavailable or the widget is chained through add-zle-hook-widget.
  • Cleanup unfunctions the callback immediately when sched is unavailable, otherwise lets the callback retire itself; the new append guard keeps __orca_osc133_precmd in precmd_functions when a config replaced the array.
  • Expanded the live-shell test matrix to cover status/option preservation, replaced and reordered precmd hooks, scheduled-event cleanup and the unavailable-module path; added ORCA_CLI_BIN_DIR expectations to the Codex/structured-session tests and registered the new live-shell file in the shell-contract CI lists.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one documentation suggestion.

Reviewed changes

Reviewed the single commit added since the prior pullfrog review (811a3593d3), which keeps completed zsh startup hooks retired when the wrapper .zshenv is sourced again.

  • Guarded the re-registration of __orca_deferred_init and the __orca_arm_deferred_line_init call on _orca_deferred_init_done being unset, so a repeat source of the wrapper cannot re-bind zle-line-init to __orca_deferred_line_init (which recursed through zle zle-line-init) or leave a dead hook in precmd_functions.
  • Regenerated the daemon/local/relay zsh wrapper fixtures to match.
  • Added repeat-history / repeat-startup live-shell controls that source the wrapper twice and assert no job table full or recursion limit exceeded and no __orca_deferred_init left in precmd_functions; narrowed the unavailable-module output assertion to the specific zsh/sched / arm-function diagnostics.

ℹ️ Nitpicks

  • src/main/shell-templates.ts:105 — the new _orca_deferred_init_done guard has no rationale, while the block's JSDoc "Why guarded on absence" explains only the inner precmd_functions[(Ie)] check. A one-line Why on the outer guard (keep completed startup hooks retired on re-source, so re-arming cannot recurse) would match the file's convention.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@nwparker
nwparker merged commit d9173ff into main Oct 4, 2026
65 checks passed
Jinwoo-H added a commit that referenced this pull request Oct 5, 2026
* fix(daemon): bump the terminal daemon protocol to v40

Daemon-side changes landed under v39 after v1.4.220 shipped v39: the #25130
and #24636 shell-wrapper changes and a wider agent list (jcode, qoder-cn, dsb;
resume claims for qoder-cn, qwen-code, cursor and jcode). Without a bump, an
update keeps new tabs on the running v39 daemon, which misses the wrapper
fixes and rejects those resume claims with agent_session_identity_required.

* fix(local-builds): record daemon protocol v40 in the local build compatibility contract
OmarHung pushed a commit to OmarHung/orca that referenced this pull request Oct 6, 2026
Daemon-side changes landed under v39 after v1.4.220 shipped v39: the stablyai#25130
and stablyai#24636 shell-wrapper changes and a wider agent list (jcode, qoder-cn, dsb;
resume claims for qoder-cn, qwen-code, cursor and jcode). Without a bump, an
update keeps new tabs on the running v39 daemon, which misses the wrapper
fixes and rejects those resume claims with agent_session_identity_required.

(cherry picked from commit a9d4587)
8bitbish pushed a commit to 8bitbish/orca that referenced this pull request Oct 7, 2026
* fix(daemon): bump the terminal daemon protocol to v40

Daemon-side changes landed under v39 after v1.4.220 shipped v39: the stablyai#25130
and stablyai#24636 shell-wrapper changes and a wider agent list (jcode, qoder-cn, dsb;
resume claims for qoder-cn, qwen-code, cursor and jcode). Without a bump, an
update keeps new tabs on the running v39 daemon, which misses the wrapper
fixes and rejects those resume claims with agent_session_identity_required.

* fix(local-builds): record daemon protocol v40 in the local build compatibility contract

(cherry picked from commit 1787585)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants