Skip to content

fix(cli): orca file open no longer moves your view unless you pass --focus - #24244

Merged
brennanb2025 merged 7 commits into
mainfrom
brennanb2025/file-open-help-states-it-switches-view
Oct 1, 2026
Merged

brennanb2025 merged 7 commits into
mainfrom
brennanb2025/file-open-help-states-it-switches-view

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 11 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​803 $\color{#cf222e}{\Huge{\mathbf{−}}}$​19 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​784
Prod 29 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​242 $\color{#cf222e}{\Huge{\mathbf{−}}}$​104 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​138

ELI5

orca file open, orca file diff and orca file open-changed used to drag Orca to the file every time: switch to its worktree, swap to the editor, scroll the sidebar. In #9944 a user's own agent skill ran orca file open to show its answers, so every answer pulled them out of whatever they were typing in — even in the same worktree, where their terminal got swapped for the editor. Now these commands open the file as a tab in its worktree without changing what you're looking at. Pass --focus to be taken to it.

Scope: the three orca file commands run from the CLI. Not changed: opening a file from the Orca phone app (it still switches the desktop), older CLIs (they send no preference, so they keep switching), and a new CLI talking to an older Orca (it ignores the preference and switches). orca worktree create and orca terminal create already stay put unless asked (--activate / --focus) and are untouched.

What Changed

Before: every orca file open / file diff / file open-changed made the target worktree active, switched to the editor, selected the new tab and scrolled the sidebar to it — whatever you were doing.

After:

  • Without --focus: the file opens as a tab in its worktree and nothing on your screen changes — your worktree, active tab, editor, sidebar and keyboard focus stay put, including when the target is the worktree you are looking at (the tab waits in the tab bar). In a worktree you are not viewing, it is the tab in front when you go there.
  • With --focus: today's behaviour — switch to the worktree, select the tab, reveal it in the sidebar. open-changed --focus switches once, not once per file.
  • Help text (orca --help, orca file --help, each command's help including its own --focus line, and the CLI docs pages) says what the default does and that agents should pass --focus only when the user asked to see the file.

Mechanism: Orca already has a per-request setting for which screens a request may move (caller / host / clients / all); orca worktree create --activate sends all. The file-open requests now carry it as an optional field: the CLI sends caller without --focus and all with it, and the desktop moves only for host / all — or when the field is missing, which keeps phones and older CLIs on today's path. For a no-move open, the editor store adds the tab without selecting it in the worktree you are viewing; in another worktree it selects it there without counting it as a visit (so it does not jump to the top of your recent tabs, while Ctrl+Tab history still works), and it only updates the global "what's on screen" state for the worktree on screen — the same rule terminal tabs follow since #22603.

Why

Every other Orca command that can move your view only does so when asked (worktree create --activate, terminal create --focus); file open was the exception, and an agent calling it had no way to avoid interrupting you. Rewording the help alone (this PR's first version) would not have helped the reporter: their skill hard-codes the call.

Alternatives considered:

  • Keep switching, only document it. Rejected: the reported interruption keeps happening.
  • Decide by where the call came from (switch only if it came from the worktree you are viewing). Rejected: a new rule nothing else in Orca uses, and harder to predict.
  • Also stop phone opens from moving the desktop. Rejected for this PR: the phone's diff review ("Open in session") relies on the desktop selecting the diff, and phones already in use would break.

Linked Issue

Refs #9944 — this is the remaining part. The new-workspace part was fixed in #23974; the agent-launch part was already fixed by #22603.

Visual Proof

Live QA on a separate macOS machine (isolated dev build, CLI built from this branch). Before = today's behaviour: every one of these calls switched you to worktree A.

Viewing worktree B with a file open; orca file open d.txt --worktree A: nothing on screen changes (the before and after captures are byte-identical). The tab is in front when you switch to A.

after: still on B, unchanged

Typing in A's terminal; orca file open README.md --worktree A: the terminal stays active and focused; README.md is added as an unselected tab.

after: terminal still active, README.md added behind it

orca file diff b.txt --worktree A while viewing B: no move.

after: still on B after file diff

orca file open a.txt --worktree A --focus while viewing B: switches to A with a.txt selected (today's behaviour, now opt-in). open-changed --focus with four changed files switched once, with no cycling through files.

after: --focus brought the user to a.txt in A

Phone-style open (no preference sent): the desktop still switches, unchanged.

after: phone-style open still switches

Testing

  • I manually tested these changes locally (live QA above, macOS)

  • Automated tests added/updated, or explained why not below

  • Desktop handler tests on the real store: a terminal focused in the viewed worktree stays focused and active when a file opens there without --focus; background file and diff opens leave the viewed editor untouched and the tab is in front when you switch; --focus moves; a request with no field (phone) still moves and selects the diff.

  • CLI tests: what each command sends with and without --focus, including a CLI paired to a remote server; open-changed --focus focuses only the first opened file.

  • Main/RPC tests: the field passes through untouched and an absent field stays absent.

  • Each behaviour was checked by breaking it on purpose and watching its tests fail (9 checks). CLI, node and web typechecks pass; 1485 CLI, 3248 renderer and 859 main/shared tests pass; lint and the code-quality gate are clean.

Review

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Security: no new inputs beyond an optional enum field. Cross-platform: no platform-specific code. SSH / remote servers: a CLI paired to a remote Orca server no longer switches that server's window unless --focus. Mobile: unchanged by design. Backwards compatibility: optional field; older peers ignore it. Performance: none.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium risk] Adds optional navigation flag to file open commands.

The PR does not appear safe to merge while reopening an existing preview without --focus can leave its tab replaceable.

Findings

  1. P1 Preview tab remains replaceable ▶

Summary

The PR makes CLI file and diff opens add tabs without moving the desktop view by default, while --focus retains navigation. It carries the preference through RPC and renderer state, updates help and documentation, and adds tests for the navigation paths.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  CLI["CLI file command"] --> NAV{"--focus?"}
  NAV -->|Yes| ALL["navigation: all"]
  NAV -->|No| CALLER["navigation: caller"]
  ALL --> RPC["RPC and desktop notifier"]
  CALLER --> RPC
  RPC --> RENDERER{"Host targeted?"}
  RENDERER -->|Yes or field absent| FOCUS["Select tab and move desktop view"]
  RENDERER -->|No| BACKGROUND["Add tab without moving desktop view"]
Loading

Reviews (6) · Last reviewed commit: "fix(cli): file open/diff/open-changed --..."

Comment thread src/cli/root-help-text-primary.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 new issues found.

Reviewed changes

Help-text-only change with no behavioral surface, so this is a coverage confirmation rather than a deep review.

  • Root help summaries (src/cli/root-help-text-primary.ts) — file open / file diff / file open-changed now say "Show … to the user (switches Orca to its worktree)" instead of "Open … in the Orca editor".
  • Per-command summaries (src/cli/specs/file.ts) — reworded to "Show … to the user" for all three commands.
  • New leading notes line on all three specs — states the command switches the Orca window to the target worktree, interrupts the user, and should run only when the user asked to see it.

I confirmed no test or docs page pins the old or new wording (grep across the repo and docs/ found no references), and the hand-written CLI docs in docs/site/content/docs/cli/reference.mdx and overview.mdx describe these commands in prose without restating the summaries, so nothing diverges.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

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

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: 66eaf0e3-f976-4e12-bda9-02edb22e5117

📥 Commits

Reviewing files that changed from the base of the PR and between 15c11a5 and 9e170df.

📒 Files selected for processing (2)
  • src/cli/command-scoped-flag-help.ts
  • src/cli/specs/file.test.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.


📝 Walkthrough

Walkthrough

File commands now accept --focus and pass a navigation target through RPC, runtime, and renderer message paths. The renderer uses the target to control worktree switching and tab selection. Without a host-directed target, a file or diff can open without changing the current view. With a host-directed target, the renderer activates the target worktree and opened tab. open-changed applies its focus target to the first successful open.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 9e170

File opens are intended to leave the current view unchanged unless --focus is requested. The supplied coverage addresses that behavior, and no concrete merge-blocking issue is established; the change appears ready for normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 9e170

The change controls whether opening a file moves the current view. Existing file-target checks remain in place, and no expanded file-access privilege was identified. Risk is low, although authorization and mixed-version recovery behavior were not fully verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The new caller-controlled field affects desktop view movement and worktree-scoped tab selection through existing file-open methods. It does not supply a new file target, credential, execution command, or authorization decision.

Trust Boundaries and Controls

  • observed — The file RPC methods use enum-constrained schemas before forwarding navigation. File-target validation is independent of navigation, so requesting background behavior does not skip the inspected relative-path or file-existence controls.

Resilience and Maintainability Implications

  • observed — Editor ownership resolution prefers explicit worktree routes and rejects ambiguous or mismatched ownership. Diff ownership derives from the target worktree rather than the focused runtime. Editor operation context also checks ownership provenance and rejects incomplete SSH mutation authority.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 27 functions across 37 files. 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 describes the primary behavior change: orca file open no longer changes the current view unless --focus is used. It is concise and related to the broader file-command changes.
Description check ✅ Passed The description is mostly complete. It explains the user impact, implementation, rationale, compatibility scope, visual proof, and testing. The linked issue is referenced as Refs #9944 instead of th…
  • 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

Autopilot is currently an internal CodeRabbit preview.


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.

…ess --focus

`orca file open`, `file diff` and `file open-changed` always switched the
desktop to the target worktree, selected the tab and revealed it in the
sidebar. An agent skill that opens its answer pulled the user out of whatever
they were typing in (#9944), and a phone opening a file moved the desktop too.

The commands now add the tab in its worktree without changing anything on
screen, including when that worktree is the one being viewed: the new tab is
added to the tab bar but the active tab, tab type and focus stay put. In a
worktree the user is not viewing, the tab becomes that worktree's selection so
it is in front when they go there. `--focus` keeps today's behavior.

files.open / files.openDiff take an optional `navigation` target (the existing
RUNTIME_NAVIGATION_TARGETS vocabulary); the CLI sends 'all' for --focus, like
`worktree create --activate`, and nothing otherwise. The renderer moves the
host view only when the target reaches the host; a missing field (phones,
older CLIs) leaves it still. Editor opens for a worktree other than the
on-screen one no longer write the global activeFileId/activeTabType.

Refs #9944
Comment on lines 27 to 31
if (activate) {
// Why: sidebar preview reopens focus the tab without promoting it; explicit activation still promotes previews by default.
state.activateTab?.(existing.id, { preservePreview: isPreview })
}
return existing.id

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Preview tab remains replaceable When orca file open without --focus reopens a file that is already a preview, openFile marks the file as non-preview, but this path skips activateTab and leaves its tab marked as a preview. The next preview open removes that tab while leaving the file in openFiles, so the existing editor tab disappears and an orphaned file record remains.

@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 code issues found — one description mismatch to correct.

Reviewed changes

This re-review covers commits 4fafdcc and d00ffcd, which turn the earlier help-text-only change into a behavior change: orca file open / file diff / file open-changed no longer move the Orca window by default, and a new --focus flag opts back in.

  • Added --focus and reworded the root help, command specs, and CLI docs so the default reads "open as a tab without changing your view".
  • Threaded an optional navigation param through files.open / files.openDiff via a new FileOpenTab schema, down to the renderer notifier.
  • Renderer moves the host view only for navigation: 'all' | 'host'; other or absent values open the tab in its worktree without touching the current view.
  • Gated the editor store's global active-file write on worktreeId === activeWorktreeId, with a new activate option to add a tab without selecting it.
  • Added tests across the CLI, RPC, window lifecycle, and renderer bridge/store.

ℹ️ PR description describes the opposite of what the code now does

The PR body still says "Scope: CLI help text only", "No behavior change", "This PR keeps the behavior and makes the help text say what the commands do", and "Notes: Security, cross-platform, SSH, mobile, performance: no runtime change." The head commits do the opposite: they change these commands to leave your view alone by default, add --focus to switch it, and change the renderer notifier, RPC schema, and editor store. The title ("file open says it switches your view") is now inverted too.

This is more than tidiness. The body's "Alternative considered" paragraph rejects exactly the per-request switching this branch now implements, and it makes no mention that mobile file-opens (which send no navigation) also stop moving the desktop. A reviewer or merger reading only the description would be approving a different change than the one on the branch.

Technical details
# Stale PR description

## Affected sites
- PR #24244 body — "Scope: CLI help text only ... No behavior change ... keeps the behavior" contradicts `src/cli/handlers/file.ts:120-126` (`getFileOpenNavigation`) and `src/renderer/src/hooks/ipc-events/mobile-terminal-close-ipc-bridge.ts:16-31` (navigation-gated view switch).
- PR #24244 title — "file open says it switches your view and is only for when you ask to see a file" describes the pre-`4fafdcc` wording.
- PR body "Notes" — "mobile ... no runtime change" contradicts the new `mobile-terminal-close-ipc-bridge.test.ts` case for phone opens with no navigation field.

## Required outcome
- Title and body describe the shipped behavior: default opens a tab without moving the view; `--focus` moves it.
- Body notes the mobile/paired-client behavior change (the host desktop no longer moves on a phone file-open).
- The LoC summary and checklist sections reflect the now ~33-file diff.

## Open questions for the human (optional)
- Is this still intended as a docs change, or should it be re-scoped/retitled as a CLI + renderer behavior change?

Pullfrog  | Fix it ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@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: 35adae03-127b-4db9-aa45-abf1292f21d3

📥 Commits

Reviewing files that changed from the base of the PR and between 37dd4cc and d00ffcd.

⛔ Files ignored due to path filters (1)
  • src/shared/rpc-contract/rpc-params-catalog.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing (32)
  • docs/site/content/docs/cli/overview.mdx
  • docs/site/content/docs/cli/reference.mdx
  • src/cli/handlers/file.test.ts
  • src/cli/handlers/file.ts
  • src/cli/root-help-text-primary.ts
  • src/cli/root-help-text-secondary.ts
  • src/cli/specs/file.ts
  • src/main/runtime/orca-runtime-file-commands.ts
  • src/main/runtime/orca-runtime-files-mobile-explorer-reads.test.ts
  • src/main/runtime/rpc/methods/files-open-navigation.test.ts
  • src/main/runtime/rpc/methods/files.test.ts
  • src/main/runtime/rpc/methods/files.ts
  • src/main/runtime/runtime-file-command-host.ts
  • src/main/runtime/runtime-file-commands-constructor.ts
  • src/main/runtime/runtime-notifier-contract.ts
  • src/main/runtime/runtime-rpc-mobile-method-allowlist.test.ts
  • src/main/window/runtime-window-lifecycle-file-open.test.ts
  • src/main/window/runtime-window-lifecycle.ts
  • src/preload/api/ui-bridge-clipboard-and-window-controls.ts
  • src/preload/api/ui-bridge-terminal-and-session-tabs.ts
  • src/preload/api/ui-command-event-api.ts
  • src/renderer/src/hooks/ipc-events/mobile-terminal-close-ipc-bridge.test.ts
  • src/renderer/src/hooks/ipc-events/mobile-terminal-close-ipc-bridge.ts
  • src/renderer/src/store/slices/editor-recently-closed-tabs.test.ts
  • src/renderer/src/store/slices/editor/actions/open-file-action.ts
  • src/renderer/src/store/slices/editor/actions/open-file-apply.ts
  • src/renderer/src/store/slices/editor/actions/open-unstaged-diff.ts
  • src/renderer/src/store/slices/editor/tabs/editor-open-target-group.ts
  • src/renderer/src/store/slices/editor/tabs/workspace-editor-item.ts
  • src/renderer/src/store/slices/editor/types/editor-files-slice.ts
  • src/renderer/src/store/slices/new-markdown.test.ts
  • src/shared/rpc-contract/files-params.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/cli/root-help-text-primary.ts

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

Comment on lines +93 to +94
// Why: only the on-screen worktree owns the main editor; a background or floating open updates only the per-worktree maps.
...(worktreeId === FLOATING_TERMINAL_WORKTREE_ID || worktreeId !== state.activeWorktreeId

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

#!/bin/bash
rg -nP --type=ts -C4 'setActiveWorktree\s*:\s*\(' src/renderer/src/store
rg -nP --type=ts -B6 -A2 '\.(openFile|openDiff)\(' src/renderer/src -g '!**/*.test.ts' | rg -n 'setActiveWorktree|openFile\(|openDiff\(' | head -80

Repository: stablyai/orca

Length of output: 3153


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- diff ---'
git diff --no-ext-diff --unified=30 3ab3c9239fba5eaa36c3c4ce10aab4cf346ee812 d00ffcd459fd442a0e3b77b2d4ed45a5819416e1 -- src/renderer/src/store/slices/editor/tabs/editor-open-target-group.ts

printf '%s\n' '--- changed file ---'
cat -n src/renderer/src/store/slices/editor/tabs/editor-open-target-group.ts | sed -n '1,180p'

printf '%s\n' '--- setActiveWorktree declaration and implementation ---'
rg -n -C18 'setActiveWorktree\s*[:=]\s*(async\s*)?\(' src/renderer/src/store/slices/worktree-helpers.ts src/renderer/src/store
rg -n -C10 'setActiveWorktree\s*\(' src/renderer/src/store/slices/worktree-helpers.ts src/renderer/src/store | head -240

printf '%s\n' '--- active editor state symbols ---'
rg -n -C8 'active(FileId|TabType)(ByWorktree)?' src/renderer/src/store/slices/editor src/renderer/src/store/slices/worktree-helpers.ts | head -320

printf '%s\n' '--- named caller terms ---'
rg -n -i -C8 'notification|Cmd|Control|Shift|new-markdown|rename|recently.closed|markdown.*link|setActiveWorktree|openDiff|openFile' src/renderer/src/hooks src/renderer/src/store/slices src/renderer/src/components -g '*.ts' -g '*.tsx' | head -500

Repository: stablyai/orca

Length of output: 41950


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- all setActiveWorktree definitions/usages ---'
rg -n -g '*.ts' -g '*.tsx' 'setActiveWorktree' src/renderer/src | head -400

printf '%s\n' '--- helper usages ---'
rg -n -C12 'buildEditorActiveResult' src/renderer/src

printf '%s\n' '--- exact active editor restoration assignments ---'
rg -n -C12 'activeFileId\s*[:=]|activeTabType\s*[:=]' src/renderer/src/store/slices | rg -n 'activeWorktree|activeFileIdByWorktree|activeTabTypeByWorktree|setActiveWorktree|openFile|openDiff|restore' | head -400

printf '%s\n' '--- likely implementation files ---'
rg -n -i -C20 'function setActiveWorktree|const setActiveWorktree|setActiveWorktree\s*\(|activeWorktreeId\s*:' src/renderer/src/store -g '*.ts' | head -600

Repository: stablyai/orca

Length of output: 41712


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- set-active-worktree implementation ---'
cat -n src/renderer/src/store/slices/worktrees/session/set-active-worktree.ts | sed -n '1,280p'

printf '%s\n' '--- worktree slice wiring ---'
cat -n src/renderer/src/store/slices/worktrees.ts | sed -n '80,130p'

printf '%s\n' '--- helper callers ---'
rg -n -C18 'buildEditorActiveResult' src/renderer/src/store/slices/editor src/renderer/src | head -320

printf '%s\n' '--- tab-surface restoration ---'
cat -n src/renderer/src/store/slices/editor/tabs/tabs-surface.ts | sed -n '1,180p'

printf '%s\n' '--- relevant open actions ---'
cat -n src/renderer/src/store/slices/editor/actions/open-file-apply.ts | sed -n '1,170p'
cat -n src/renderer/src/store/slices/editor/actions/open-unstaged-diff.ts | sed -n '1,120p'
cat -n src/renderer/src/store/slices/editor/actions/markdown-preview-actions.ts | sed -n '70,130p'

Repository: stablyai/orca

Length of output: 41744


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- activated surface resolver ---'
rg -n -C30 'resolveActivatedWorktreeSurface' src/renderer/src/store/slices/worktrees src/renderer/src/store/slices | head -260

printf '%s\n' '--- reopen and rename flows ---'
rg -n -i -C18 'recently.closed|closed.*tab|reopen|new.*markdown|markdown.*rename|rename.*markdown|open.*notification|notification.*open|Cmd|Control.*Shift|Shift.*T' src/renderer/src -g '*.ts' -g '*.tsx' | head -600

printf '%s\n' '--- openFile/openDiff caller context excluding tests ---'
rg -n -B12 -A18 '\.(openFile|openDiff)\s*\(' src/renderer/src -g '*.ts' -g '*.tsx' -g '!**/*.test.ts' -g '!**/*.test.tsx' | head -700

Repository: stablyai/orca

Length of output: 42337


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- derive active surface ---'
cat -n src/renderer/src/store/slices/tabs/tabs-surface.ts | sed -n '1,260p'

printf '%s\n' '--- recently closed editor tabs ---'
cat -n src/renderer/src/store/slices/editor/actions/recently-closed-editor-tabs.ts | sed -n '1,150p'
rg -n -i -C18 'recently.closed|reopen.*tab|reopen.*editor|open.*recently|Cmd.*Shift.*T|Control.*Shift.*T|Shift.*T' src/renderer/src -g '*.ts' -g '*.tsx' | head -360

printf '%s\n' '--- markdown creation and rename ---'
rg -n -i -C20 'rename.*markdown|markdown.*rename|rename.*file|new.*markdown|create.*markdown|openMarkdown|activateAndReveal' src/renderer/src -g '*.ts' -g '*.tsx' | head -500

Repository: stablyai/orca

Length of output: 41824


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- reopen symbol callers ---'
rg -n -B12 -A20 'reopenClosedEditorTab' src/renderer/src -g '*.ts' -g '*.tsx'

printf '%s\n' '--- focused markdown action callers ---'
rg -n -B12 -A24 'createUntitledMarkdownFile|openMarkdownFile|openMarkdownPreview|rename.*file|file.*rename' src/renderer/src/components src/renderer/src/hooks src/renderer/src/store/slices -g '*.ts' -g '*.tsx' | head -500

printf '%s\n' '--- focused markdown-link callers ---'
cat -n src/renderer/src/store/slices/editor/actions/markdown-link-action.ts | sed -n '80,190p'

Repository: stablyai/orca

Length of output: 42489


🏁 Script executed:

#!/bin/bash
set -e
cat -n src/renderer/src/store/slices/recently-closed-tabs.ts | sed -n '130,215p'
rg -n -B20 -A20 'reopenMostRecentClosedTab|reopen.*closed.*tab|recentlyClosedTabKinds' src/renderer/src -g '*.ts' -g '*.tsx' | head -260

Repository: stablyai/orca

Length of output: 31981


Activate focus-sensitive opens before openFile.

When activeWorktreeId is null or differs from the target, buildEditorActiveResult updates only the per-worktree maps. reopenClosedEditorTab calls openFile without activating the target, so reopening from the landing state can leave the global editor selection stale or empty. Activate the target before focus-sensitive reopen and rename flows. Keep background opens non-activating.

…or 'caller'

Phone opens send no `navigation` field, and the phone's diff-review "Open in
session" relies on the desktop selecting the diff it opened. A missing field
now keeps the original switch exactly; the CLI says what it wants instead:
'caller' (no host move) by default and 'all' for --focus. Older CLIs, which
send nothing, keep switching as they always have.

Refs #9944
@brennanb2025 brennanb2025 changed the title docs(cli): file open says it switches your view and is only for when you ask to see a file fix(cli): orca file open no longer moves your view unless you pass --focus Oct 1, 2026

@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 code issues found in this delta.

Reviewed changes

This re-review covers commit 83dc90a since the prior pullfrog review (d00ffcd). It fixes a regression the prior revision introduced for paired phone clients and makes the CLI name its navigation intent explicitly.

  • Restored the legacy host switch for an absent navigation — openRuntimeEditorTab now moves the host view when navigation is undefined, so phone/paired file-opens (which send no field) switch the desktop again; only an explicit non-host target (caller/clients) opens without moving it.
  • CLI names its target explicitly — getFileOpenNavigation sends caller by default and all under --focus, replacing the previous "omit the field" encoding, so a missing field no longer doubles as the CLI's quiet request.
  • open-changed --focus switches once — the first tab that actually opens carries all; after one opens, later tabs fall back to caller (a skipped/open-failed entry correctly passes focus to the next).
  • Tests — new CLI cases pin caller vs all, the leave-alone behavior against a paired remote runtime, and open-changed's switch-once; the renderer bridge test now asserts a phone open switches the desktop while a CLI caller open does not.

The FileOpenTab/FileOpenDiff schema split and the notifier/window-lifecycle plumbing read consistently with the new encoding, and no other caller of files.open/files.openDiff relies on the old absent-means-quiet rule.

Pullfrog  | Fix it ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

…visit

A CLI open into a worktree the user is not viewing selected the new tab with
the same activation a user click uses, which stamps lastFocusedAt and the
group's recency list. The worktree jump palette sorts recent tabs by that
time, so every agent `orca file open` into another worktree jumped to the top
of the user's recent tabs.

Editor opens now take a selection mode: 'focus' (default, unchanged),
'background' (select within its worktree without recording focus or recency)
and 'none' (add only). createUnifiedTab and activateTab gain recordFocus:false
for the background case.

Also: tests for reopening an already-open file or diff without --focus, a
comment that file opens move only the host window ('all' acts as 'host'),
root help lines back under 100 columns, and an accurate remote test title.

Refs #9944

@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

This incremental re-review covers commit 3c9c2a5 since the prior pullfrog review at 83dc90a. It refines how a CLI file open into a worktree you are not viewing selects its tab.

  • Replaced the activate: boolean plumbing with a three-state EditorTabSelection ('focus' | 'background' | 'none') threaded through openFile / openDiff and openWorkspaceEditorItem.
  • Background opens now select the tab inside their own worktree without stamping lastFocusedAt or adding it to the group's recentTabIds, via a new recordFocus: false option on createUnifiedTab and activateTab.
  • Added renderer tests for reopening an already-open file and diff with navigation: 'caller', and for a background open not recording a visit (lastFocusedAt undefined, recentTabIds unchanged).
  • Reworded the CLI getFileOpenNavigation comment, the notifier openFile JSDoc, and the root help lines.

I traced the palette path (orderRecentWorkspaceTabs treats an unknown visit time as 0, and use-worktree-jump-palette-recent-tabs reads tab.lastFocusedAt), so the gating is causally connected to the reported "jumped to the top of recent tabs" symptom. The viewed-worktree ('none') and phone/absent-navigation paths are behaviorally unchanged from 83dc90a.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

recordFocus:false skipped both the focus-time stamp and the group's
recentTabIds append while still making the tab the group's active tab. Ctrl+Tab
looks the active tab up in that history, so after a background CLI open it
did nothing (or went to the wrong tab) once the user switched to that
worktree, and hydrate kept the broken history across a restart.

Only the focus-time stamp is skipped now; the jump palette's recent rows sort
by that alone, so the palette fix stands.

Refs #9944

@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

This incremental re-review covers commit 15c11a5 since the prior pullfrog review at 3c9c2a5. It keeps a background CLI open in its group's tab history so Ctrl+Tab can return to what the user was on, while still not marking the tab as visited.

  • Background open keeps the group MRU — createUnifiedTab gates nextRecent on shouldActivate (not recordsFocus), and activateTab always pushes to the group's recentTabIds; only lastFocusedAt is skipped when recordFocus: false.
  • Ctrl+Tab regression coverage — a new parametrized renderer test drives the real handleSwitchRecentTab for both a newly created and a reopened background file tab, asserting it switches back to the previous terminal tab.
  • Recency assertion sharpened — the "no visit" test now checks lastFocusedAt is unstamped and recentTabIds ends on the active tab, for both the first open and a reopen.
  • Doc/comment rewording — the EditorTabSelection / recordFocus JSDoc now states the group history still updates.

I confirmed the only recordFocus: false caller is workspace-editor-item.ts (the background selection path), and worktree-jump palette ordering (orderRecentWorkspaceTabs) reads lastFocusedAt only, so re-admitting the tab to recentTabIds does not reintroduce the palette jump that motivated the earlier exclusion. Ran the renderer bridge, ipc-tab-switch, and the store's tabs/editor tests; all pass.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

… user to the file

The three commands borrowed the shared --focus line written for terminal
create ("Reveal the created terminal session in Orca"). They now use the
per-command flag help table; terminal create's line is unchanged.

Refs #9944

@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

This incremental re-review covers commit 9e170df since the prior pullfrog review at 15c11a5. It gives the three orca file commands their own --focus help line, which they had been borrowing from terminal create.

  • Per-command --focus help — src/cli/command-scoped-flag-help.ts adds a FILE_OPEN_FOCUS_HELP entry for file open / file diff / file open-changed; formatCommandFlagHelp consults the scoped table before the shared FLAG_HELP_TEXT, so terminal create --focus is untouched.
  • Regression test — new src/cli/specs/file.test.ts pins the exact rendered line for all three file commands and asserts terminal create --focus still reads "Reveal the created terminal session in Orca". It would fail if the override were dropped, so it is real coverage.

I traced the lookup path (formatCommandFlagHelp → formatCommandScopedFlagHelp) and confirmed the help text matches the shipped --focus behavior. Ran src/cli/specs/file.test.ts (4 tests) — pass. No open prior review threads to retire.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review status (head 9e170dfef1d)

The problem (#9944): a user's own agent skill ran orca file open to show its answers, and every call pulled them out of the worktree they were working in — even within the same worktree, where their terminal was swapped for the editor. orca file open, file diff and file open-changed always switched your view; every other Orca command that can move you only does so when asked (worktree create --activate, terminal create --focus).

What changes for you: these three commands now open the file as a tab in its worktree without changing what you're looking at. In the worktree on screen the tab waits in the tab bar; in another worktree it is the tab in front when you go there. --focus brings you to it (the old behaviour). Opening a file from the Orca phone app, and older CLIs, still switch the desktop as today.

Fixed during review

  • The first version only reworded the help, which would not have stopped the reported interruption; replaced with opt-in --focus.
  • A file opened in another worktree jumped to the top of your recent tabs as if you had visited it; it no longer records a visit.
  • The fix for that briefly broke Ctrl+Tab in that worktree; fixed, with a test that fails without it.
  • Reopening the same file again and again (the reporter's pattern) is now covered by tests.
  • orca file open --help described --focus with terminal create's wording; the file commands now have their own line.
  • Help lines no longer wrap; one code comment and one test title no longer overstate what they cover.

Deferred

  • The logic lives in files and message channels named for mobile, though the CLI is now the main caller; a rename is a follow-up.
  • --focus on a CLI paired to a remote Orca server moves that server's window, not a phone or paired desktop watching it (documented in code as intended).

Verified

  • Independent review and a readiness checklist: no P0–P2 findings remain.
  • Live QA on a separate macOS machine at 83dc90ac574 (screenshots in the PR body): no move when viewing another worktree; terminal stays focused when the file opens in the worktree you are typing in; file diff does not move; --focus switches; open-changed --focus switches once; phone-style open still switches; help wording.
  • CLI, node and web typechecks; ~1,500 CLI, ~3,600 renderer and ~860 main/shared tests; each new behaviour checked by breaking it and watching its tests fail. CI green on 9e170dfef1d.

Not verified

  • Live: the three fixes made after the QA run (recent tabs, Ctrl+Tab, the --focus help line) — unit-tested only.
  • SSH and folder workspaces, a real paired phone (QA sent a phone-shaped request), Windows and Linux.

Not merged; that is the maintainer's call.

@brennanb2025
brennanb2025 merged commit a4606cc into main Oct 1, 2026
49 checks passed
@brennanb2025
brennanb2025 deleted the brennanb2025/file-open-help-states-it-switches-view branch October 1, 2026 05:54
sj900211 added a commit to sj900211/orcinus that referenced this pull request Oct 13, 2026
Measured from the post-stage-3 main: 794 commits, 22 conflicting files, only 2 of
them in the PTY delivery subsystem. The wall this staged plan existed to isolate
is behind us; this stage is identity, usage accounting and renderer surface.

Three upstream commits produce most of the conflicts: `9700030689` (headless
renderer delivery), `82412dab8b` (profile state in SQLite), `d443320af2`
(terminal handoff removal), plus `d2dbe2c385` and `f1463683ee` below.

## The two decisions this merge turned on

**OpenCode field meanings: adopt upstream's.** The fork's distinguishing
behaviour was counting cache writes in token totals. Upstream `f1463683ee` now
does that itself — its `scanner.test` expects 1775, which is the fork's number.
What remained was bucketing: upstream has `inputTokens` = uncached+read+write,
`cachedInputTokens` = read+write, `cacheWriteInputTokens` for the write subset.
Keeping the fork's narrower meanings would have left four cleanly-merged upstream
files silently wrong, one of them producing a negative telemetry `input_tokens`
that the schema rejects — and the divergence would be invisible to typecheck,
since the field names match and only the meanings differ. All five cluster files
are therefore byte-identical to `b601b98644`, and every asserted total in
`cache-write-tokens.test.ts` is unchanged (1120, 2000, 3125): the feature is
preserved, only its composition moved. Fork files adapted: `snapshot-rollups.ts`,
`usage-provider-normalization.ts` (restored to upstream — otherwise cache is
counted as new input and writes are counted twice), `usage-overview-model.test.ts`,
`cache-write-tokens.test.ts`.

**`agent-state-rules` URL: keep the fork repo.** Upstream stablyai#24387 downloads rules
from `${MAIN_RELEASE_REPO}`, which the fork rebranded to `sj900211/orcinus`. A
404 is non-fatal — the updater warns and serves the bundled rules — so the fork
keeps pointing at itself rather than fetching runtime data from a repository it
does not control. Upstream tests that pinned `stablyai/orca` had a premise that is
false by a ratified decision (`release-channel.ts:27`), so their expectations were
corrected, following the precedent of rebrand commit `222baedec6`. Each edited
assertion carries a `// Why` marker so a future sync does not revert it. This is
correcting a stale premise, not weakening a guard: the tests still pin how the URL
is built.

## The Windows CLI launcher was replaced wholesale

Upstream `d2dbe2c385` deleted `OrcaCliLauncher.cs` and shipped a Rust crate. The
fork's `Orcinus.exe` fix (hidden quest ③) is ported into
`native/windows-cli-launcher/src/main.rs` at the four call sites; the `.cs` is
removed, which a cross-host test now requires because its MSIL image was
vendor-flagged (stablyai#23383). The three `Orca CLI` strings and every
`ORCA_*` environment name stay — the CLI is still named `orca`. Without this port
the packaged `orca` CLI fails on every Orcinus Windows install, which is the
precondition for all orchestration work in this repo.
`.github/workflows/orcinus-cd.yml` gains a Rust toolchain step on the Windows leg.
Deferred by decision: rebranding the launcher's `build.rs` metadata and icon
(cosmetic, and the three pieces must move together).

## Defects found that no conflict marker could show

Six files merged cleanly and were still wrong:
- `pty/session.ts` family — carried from stage 3's pattern, handled there.
- `usage-web-client-fallback.test.ts` lost two slice imports upstream narrowed.
- `ui-slice-preference-actions.ts` breached `max-lines` at 302 (fork +10, upstream
  +12). Resolved without a disable by moving the fork's number-format action to a
  sibling module; the file is now identical to upstream.
- `startup-window-role-reconnect.ts` and `folder-workspace-initial-terminal.ts`
  are fork-only extractions made for `max-lines`; upstream rewrote the originals,
  so stablyai#24203 and stablyai#23693 were ported into them by hand.
- Upstream's new Reset Terminal bypassed owner-window routing; it now routes.
- Upstream's new `terminal-intentional-stop-exit.test.ts` saw zero `pty:exit`
  sends until given a routed main window.
- `satellite-open-interception.ts` would have raised a satellite window on a
  background CLI open, breaking the "change nothing on screen" guarantee stablyai#24244
  added.

## Review

An independent critic returned REJECT with **no production defect**: every fork
behaviour present, both decisions correctly applied, every gate reproducible. The
rejection was for 14 tests in 6 files that the gate's directory scope never ran —
all of them new upstream tests pinning upstream identity, the same class the
`agent-state-rules` decision had ruled on and which it had been applied to too
narrowly. All six are fixed, test-only, each with a `// Why` marker. The critic
also corrected a claim in the implementation report: the fork already carries
upstream's `agent-state-rules-publish.yml`, so live rule updates need only an
`agent-state-rules` environment and a `publish-next` dispatch, not new machinery.

`sftp-upload.test.ts` deserves a note: upstream's new cases assert a direct
`createWriteStream`, but the fork uploads atomically to `.orcinus-part-<uuid>` and
publishes by rename (`sftp-upload.ts:61-63`). The fork's contract stands; the
expectations moved to it. One of those cases is `skipIf(win32)` and could not be
observed here, but fork CI runs on ubuntu, so it was fixed from the code.

## Gates

Cold typecheck (after deleting `config/*.tsbuildinfo`): 0 errors, measured twice
by different workers. oxlint: 0 warnings, 0 errors across 29,465 files.
verify-orcinus-identity: OK, `upstreamRefs=0`. Unsigned smoke: OK,
`icon=orcinus.icns`. Fork contract tests: 24/24. Windows CLI launcher tests: the
Rust build actually runs here and passes.

Attribution, using the critic's harness across three trees (this merge, main, and
`b601b98644`): a 1,236-file fork-adjacent sweep and a 54-file identity sweep went
from 14 merge-only failures to 1. That one is the release-tag census entry for the
fork-only `verify-orcinus-release-assets.mjs`: the census builds its keys with
`join()`, so on win32 they carry backslashes. Six upstream sibling cases fail the
same way on the upstream baseline, a direct POSIX evaluation of the key logic
passes, and a negative control confirms the entry is detected. The census's
upstream key logic was deliberately left alone.

Known and not addressed here: `updater-prerelease-feed.ts:156` matches only
`stablyai/orca` asset URLs — present on `main`, not merge-caused, and invisible to
the identity verifier. The release path has not been exercised with this merge
(`build:orcad` moved from bun to node); an `orcinus-cd` dry run is advisable before
the next fork release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant