* fix(orchestration): stop worktree ps reporting a busy structured session as idle A worktree running a structured Claude or Codex chat read as idle to `orca worktree ps`, while the desktop sidebar showed the same session working. The sidebar was right: the host already projects a status summary for every structured session and publishes it, and the renderer maps it into an agent row. `worktree ps` simply never consumed it, so the agent-facing surface was the blind one. Structured sessions have no PTY, so they reach neither the hook snapshots nor the retained ones that every other row is built from. This reads the summaries the host has already published and applies the same projection the sidebar does — working, attention as blocked, otherwise done — so the CLI and the GUI cannot disagree about one session. Two things worth knowing: The connected-PTY evidence gate had to be skipped for these rows. It exists to drop a row whose PTY is gone, which is the wrong question for a session that never had one; a structured row's liveness evidence is the status feed that produced it. The exemption is keyed on the row being structured, so every PTY-backed row keeps today's behaviour. `RuntimeWorktreeAgentRow` needed no change. It was already a non-PTY shape — paneKey, state, agentType, and no ptyId, connected or writable — so a structured row fits without inventing a fake terminal coordinate. The pane key is the DERIVED one the renderer already publishes, never the orchestration bearer handle or the minted worker pane key: both are credentials, since `orchestration check` is identity-gated and accepts a caller-supplied pane key. `orca terminal list` is deliberately untouched, and a test pins that. Adding rows there breaks real consumers: mobile mounts a terminal WebView per row that can never receive a frame, a `connected`-keyed refresh check goes permanently true and pins shipped clients to a fast cadence with no exit, and the plugin projection has no field that can carry `writable: false`. Every safe consumer of a terminal summary checks `ptyId`; the breaking ones key off `connected` or mere row presence, which no added field can qualify. An honest partial-listing count there is a separate change. * fix(runtime): report only live structured sessions in worktree ps The status feed's `published` map is a broadcast cache, not a roster. It deliberately never retracts — an evicted idle session is still idle, and a reloading renderer must not lose every settled row — so enumerating it lists every session the host has ever opened, and eviction's `forget-session` step deletes the session from the live map while touching nothing else. Reading it as a roster made `worktree ps` report a closed chat forever. The sharp edge is a chat closed while an approval was pending: a deliberate close does not settle a pending prompt, so the retained summary stays `attention`, maps to a `blocked` row, and merges the worktree to `permission` for the whole 30-minute freshness window — on the CLI and on the mobile sidebar it backs. The poller now answers from the sessions the host still holds, intersecting the live map with the retained projections. `subscribe()` and its snapshot are untouched: retention there is the point. Gating on the live session set rather than the visible tabs keeps a headless orchestration worker listed, which is what the agent-facing surface is for. Also folds out two things the enumerator left behind: the working/attention/idle to working/blocked/done mapping now lives once in the shared projection module instead of once per process, which is what actually enforces "the CLI and the GUI cannot disagree"; and the structured row source no longer builds a write-only `payload` behind an `as` cast that compensated for nothing. The structured source construction moves to its own module to keep runtime-worktree-agent-rows.ts clear of the 300-line cap. * test(runtime): execute the structured-host call site in worktree ps Both structured-row suites called attachRuntimeWorktreeAgentRows directly with summaries they built themselves, so nothing ever ran getWorktreePs's own `getStructuredAgentSessionHost()?.liveSessionStatusSummaries()`. That file carries `@ts-nocheck`, so renaming the accessor was green in typecheck and in the suite, while `orca worktree ps` and mobile's 3s poll would throw a TypeError for every user — the `?.` optional-chains the host, not the method. Swapping the call back to a whole-cache read was equally invisible: the liveness suite injects feed.liveSessionSummaries() itself, and the string-match guard only needs the identifier to appear somewhere in the file. Drives the real runtime with a stub host over a real status feed that has published two sessions and forgotten one, asserting the live session's row reaches ps output, that the live accessor is the one called, and that the `?? []` fallback still returns a page with no host installed. The stub is typed against the real host, so a class-side rename reddens tc here. * refactor(runtime): admit agent sources before worktree row projection * fix(runtime): preserve host-authoritative structured status * Fix structured host session activity lifecycle --------- Co-authored-by: Merge Sim <sim@local>
Orca
中文 · 日本語 · 한국어 · 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
Features
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
Codex
Grok
Cursor
GitHub Copilot
OpenCode
MiMo Code
Amp
OpenClaude
Antigravity
Pi
oh-my-pi
Hermes Agent
Devin
Goose
Auggie
Autohand Code
Charm
Cline
Codebuff
Command Code
Continue
Droid
Kilocode
Kimi
Kiro
Mistral Vibe
Qwen Code
Rovo Dev
+ any CLI agent
Install
Desktop — macOS, Windows, Linux
- Download from onOrca.dev
- Or grab a build directly: macOS Apple Silicon · macOS Intel · Windows (.exe) · Linux AppImage · All builds
- Running
orca serveon a headless Linux server? See the headless Linux server guide.
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.
- iOS: Download on the App Store or join TestFlight
- Android: Download APK 0.0.48 · Install guide
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 8. Group 8 may be full; if so, scan the Group 9 QR code instead.
-
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.
The relay that pairs the mobile app with a desktop host is also in this repository under
cloud/, with a separate pnpm workspace and setup guide.
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.












