Lesley Murfin de6fe8b7ea fix(worktrees): resolve id: worktree selectors by path equivalence (#16243) (#16494)
* test(worktrees): cover id: selector path-spelling parity with path: (#16243)

The renderer can only address a workspace by id (toRuntimeWorktreeSelector always
emits id:<repoId>::<path>), and the runtime matches that id byte for byte while a
path: selector has always compared through normalizeRuntimePathForComparison. A
stored id that spells its path differently from `git worktree list` therefore
resolves for the CLI and answers selector_not_found for the UI, which reads that
as a stale local mirror, calls forgetLocal, reports success, and lets the row
return on the next catalog refresh: a silent delete.

These tests fail on both resolution sites -- the fleet `id:` branch of
resolveWorktreeSelector and the scoped resolveScopedWorktreeIdRow a
host-qualified removal takes -- and pin what must stay closed: an exact repo id
(STA-4343), host qualification, dot segments neither selector canonicalizes, and
a refusal rather than a guess when two rows spell one path.

13 failing, 35 passing.

* fix(worktrees): resolve id: worktree selectors by path equivalence (#16243)

worktreeIdComparisonKey names one repo, one filesystem location, and one
folder-workspace instance, folding exactly the path spellings
normalizeRuntimePathForComparison already folds for a path: selector -- and
nothing more, so dot segments stay unresolved for both shapes. Both id:
resolution sites consult it only after an exact match finds nothing: the fleet
branch of resolveWorktreeSelector and resolveScopedWorktreeIdRow, which a
host-qualified removal takes. runtimeWorktreeIdsEqual now derives from the same
key so the runtime has one normalizer rather than a parallel one.

Not a pure refactor at that last site: runtimeWorktreeIdsEqual used to
normalize-compare ids that parse but carry an empty repoId or an empty path
('::/p', or 'repo::' against 'repo::/'), and worktreeIdComparisonKey returns
null for those, so across its call sites (PTY identity, refresh, mutation
queue) such ids now compare byte-exact instead. That narrows matching rather
than widening it, no real worktree carries such an id, and it is the behavior
#15616 guarantees for malformed ids -- but it is a behavior delta, not just a
tidy-up.

Perf (#14399): the exact match is still tried first and still wins outright, so
a resolvable id costs exactly what it did before. Neither site adds a scan --
the fleet branch re-filters the array it had already listed, the scoped lookup
re-filters the single owning repo's projected rows -- so an explicit id still
never scans every repo.

Fail-closed behavior is unchanged: the repo id compares exactly (STA-4343), host
qualification is untouched, the folder-workspace instance suffix stays part of
the path, and a scoped lookup with two equivalent rows refuses instead of
guessing. The bare unprefixed selector branch keeps byte-exact id matching,
since only the id: shape reaches a renderer caller.

Shares src/shared/worktree/id.ts with the open #15616, which introduces
worktreeIdComparisonKey for the same divergence in lineage pruning and
authoritative-scan purging; this adopts that helper rather than adding a second
one. Complementary to the open #16295, which makes the miss visible; this
removes the miss.

* chore(worktrees): satisfy oxfmt and oxlint on #16243 tests

oxfmt --check flagged both new test files and oxlint's
unicorn/no-useless-fallback-in-spread flagged the store mock; the full
lint and format gates now match the pre-change baseline.

* test(worktrees): pin Windows spellings and malformed-id exactness (#16243)

Review found two axes the first pass left unproven at the two id: resolution
sites. Both are the invariants the open #15616 guarantees for the shared
worktreeIdComparisonKey it introduces for #15598, so violating either here would
break a contract a sibling PR depends on.

Windows: #15598's whole defect is that one checkout is recorded under both
`D:\Agentic\game2` and `D:/Agentic/game2`. The fleet branch, the scoped removal
lookup, and the key itself now each resolve the backslash spelling against the
forward-slash spelling git reports, and fold drive-letter case -- while a
backslash inside a POSIX path stays a filename character and a POSIX root stays
case-sensitive, exactly as normalizeRuntimePathForComparison already decides for
a path: selector.

Malformed ids keep exact matching at both sites: an id with no repo boundary or
an empty path still refuses, and the scoped lookup still refuses it without
scanning.

Four of these fail without the production change (three fleet/removal Windows
cases and the scoped one); the malformed-id and POSIX-backslash cases are
invariant guards that hold either way.

Verified: 58 passed in the three files; 18 fail with the production hunks
reverted; orca-runtime.test.ts and worktree-teardown-unstopped-pty.test.ts green
(1270 passed | 1 skipped); pnpm tc:node clean.

* test(worktrees): pin Windows id: spelling folds and fleet ambiguity refusal (#16243)

The Windows backslash spelling now rides the ID_SPELLINGS rows, so it is driven
through both id: sites -- resolveWorktreeSelector and the scoped removal target --
and compared against what the same workspace's path: selector resolves, rather
than only through worktreeIdComparisonKey. That is the spelling #15598/#15616
found in the wild and the one the owner's Windows client produces.

The fleet path's ambiguity refusal had no test: two same-repo rows spelling one
directory, an id: matching neither exactly, must reject selector_ambiguous. It is
the fail-closed guard on a delete-capable resolver, and the property a later
refactor is most likely to turn into a silent pick.

Also records two limits at the source instead of leaving them to be rediscovered:
a UNC or WSL root never folds into a drive-letter location (while Windows' two
WSL UNC aliases do name one location), and a folder-workspace id keeps a trailing
slash placed before the ::workspace:<uuid> suffix, so that spelling stays
exact-match-only. Neither behavior changes here.

The file docblock overclaimed parity. path: collapses duplicate same-host
registrations to the first row while a folded id: refuses them; the contract this
file pins is path-spelling parity, not dedup parity, and the divergence is
deliberate because this resolver also serves delete.

Non-vacuity, verified by temporarily reverting the production hunks: neutralizing
both id: fallbacks turns 10 of these tests red, including both new Windows rows
and the ambiguity refusal (it degrades to selector_not_found). Making the fleet
fallback pick the first folded match instead of collecting all of them turns the
ambiguity test red on its own. The remaining cases -- malformed ids, dot
segments, the POSIX backslash, the folder-workspace slash -- pass against the
pre-fix code too: they guard against future widening rather than proving this
fix.

Drops the two Windows cases the ID_SPELLINGS row subsumes.

The drive-letter case test asserted only the Windows half its name promised; it
now also pins that a POSIX root does NOT fold case, since an unconditional
lowercase would merge /data/Foo with /data/foo on the platform CI runs on.

Fixture paths use the upstream-attested /srv/projects prefix (and a neutral
plugin-host leaf) instead of a local install root; the spelling variations the
tests exist to pin -- doubled separator, dot segment, trailing slash, uppercase
POSIX, cafe NFC/NFD, and the Windows D: rows -- are unchanged in form.

* docs(worktrees): trim the id: selector test header and document the comparison key (#16243)
2026-08-26 23:35:18 -07:00
2026-08-27 02:00:49 +00:00
2026-07-11 20:53:20 -07:00
2026-05-04 20:42:03 -07:00
2026-03-16 22:27:51 -07:00
2026-03-28 10:19:14 -07:00

Orca Orca

GitHub stars Total downloads across all releases License: MIT Join the Orca Discord Follow Orca on X Supported platforms: macOS, Windows, and Linux

中文 · 日本語 · 한국어 · Español · Français · Português

The AI Orchestrator for 100x builders.
Run Codex, ClaudeCode, OpenCode or Pi side-by-side — each in its own worktree, tracked in one place.

Download Orca

Orca desktop app running agents in parallel worktrees, with the Orca mobile companion app in the corner

Features

Mobile Companion

Monitor and steer your agents from your phone — get notified when an agent finishes and send follow-ups from anywhere.

iOS App Store · TestFlight · Android APK 0.0.44 · Docs →

Orca desktop with the mobile companion app

Parallel Worktrees

Fan one prompt across five agents, each in its own isolated git worktree — compare the results and merge the winner.

Docs →

Parallel worktree orchestration

Terminal Splits

Ghostty-class terminals with WebGL rendering, infinite splits, and scrollback that survives restarts.

Docs →

Terminal splits

Design Mode

Click any UI element in a real Chromium window to send its HTML, CSS, and a cropped screenshot straight into your agent's prompt.

Docs →

Embedded browser and Design Mode

GitHub & Linear, Native

Browse PRs, issues, and project boards in-app — open a worktree from any task and review without a context switch.

Docs →

GitHub and Linear task workflows in Orca

SSH Worktrees

Run agents on a beefy remote box with full file editing, git, and terminals — auto-reconnect and port forwarding included.

Docs →

Remote worktrees over SSH

Annotate AI Diffs

Drop comments on any diff line and ship them back to the agent — review, edit, and commit without leaving Orca.

Docs →

Annotate AI-generated diffs

Drag Files to Agents

VS Code's editor with autosave everywhere — drag files or images straight into an agent prompt.

Docs →

Drag files and images into an agent prompt

Orca CLI

Agents drive Orca too — script every workflow with orca worktree create, snapshot, click, and fill.

Docs →

Script Orca from the CLI

Also in the box:

  • Quick open — Search across worktrees, files, agents, commands, and repo context without leaving your flow.
  • Account switcher & usage tracking — See Claude and Codex usage and rate-limit resets, and hot-swap accounts without re-logging in.
  • Rich repo previews — Preview Markdown, images, PDFs, and repo docs in the workspace.
  • Computer Use — Let agents operate desktop apps and visible UI when a workflow needs real interaction.
  • Notifications and unread state — Know when an agent finishes or needs attention, then mark threads unread to come back later.
  • And many, many more — we ship daily, so this list is perpetually behind. The changelog is the real feature list.

Supported Agents

Works with any CLI agent — if it runs in a terminal, it runs in Orca.

Claude Code logo Claude Code   Codex logo Codex   Grok logo Grok   Cursor logo Cursor   GitHub Copilot logo GitHub Copilot   OpenCode logo OpenCode   MiMo Code logo MiMo Code   Amp logo Amp   OpenClaude logo OpenClaude   Antigravity logo Antigravity   Pi logo Pi   oh-my-pi logo oh-my-pi   Hermes Agent logo Hermes Agent   Devin logo Devin   Goose logo Goose   Auggie logo Auggie   Autohand Code logo Autohand Code   Charm logo Charm   Cline logo Cline   Codebuff logo Codebuff   Command Code logo Command Code   Continue logo Continue   Droid logo Droid   Kilocode logo Kilocode   Kimi logo Kimi   Kiro logo Kiro   Mistral Vibe logo Mistral Vibe   Qwen Code logo Qwen Code   Rovo Dev logo Rovo Dev   + any CLI agent


Install

Desktop — macOS, Windows, Linux

Or via a package manager:

# macOS (Homebrew)
brew install --cask stablyai/orca/orca

# Arch Linux (AUR) — or stably-orca-git to build from source
yay -S stably-orca-bin

Mobile Companion — iOS, Android

Pair with your desktop app to monitor and steer your agents from your phone.


Community & Support

  • Discord: Join the community on Discord.

  • Twitter / X: Follow @orca_build for updates and announcements.

  • WeChat: Scan to join the Orca community WeChat group 7. If it is full, use group 8.

    WeChat group 7 QR code for the Orca community   WeChat group 8 QR code for the Orca community

  • Feedback & Ideas: We ship fast. Missing something? Request a new feature.

  • Privacy: See the privacy & telemetry docs for what anonymous usage data Orca collects and how to opt out.

  • Show Support: Star this repo to follow along with our daily ships.


Developing

Want to contribute or run locally? See our CONTRIBUTING.md guide.

Orca contributors

GitHub star history chart for stablyai/orca

Signed Builds

Windows code signing sponored/provided by SignPath.io, certificate by SignPath Foundation.

License

Orca is free and open source under the MIT License.

S
Description
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.
Readme MIT
1.5 GiB
Languages
TypeScript 95.1%
JavaScript 4.1%
Swift 0.2%
CSS 0.2%
HCL 0.1%