* feat(native-chat): show each interrupted chat's workspace as its read-only sidebar card The resume-on-restart dialog listed workspaces as a bare name and glyph, so users could not tell their sessions apart. It now renders each workspace with the sidebar's own WorktreeCard in a new read-only mode, with the offered chats in place of its live agent rows, and nests child workspaces under a listed parent the way the sidebar does. The dialog is wider and the chat rows use the sidebar's compact agent row layout. Co-Authored-By: Claude <noreply@anthropic.com> * test(native-chat): name the nesting helper for what it returns Co-Authored-By: Claude <noreply@anthropic.com> * fix(native-chat): resume dialog cards show no status The dialog's cards stand in for the chats before the restart, so the sidebar's live status (Failed, now Interrupted) read as a verdict on chats the dialog offers to resume. A read-only card shows no status, and in the new card style its PR joins the badges because the status lane that normally holds it is gone. Co-Authored-By: Claude <noreply@anthropic.com> * fix(sidebar): a read-only card is inert and shows no live state, whatever its caller passes A read-only card stayed inert only because each control checked `readOnly` on its own and the caller left out the handlers that would turn the rest on: passing `onLineageToggle` put a live child-workspaces toggle on it. It also still painted live state over the resume dialog's chat rows: the sleep dim, the "Queued for deletion" overlay (which blocked unticking a pre-ticked chat) and the prompt-cache countdown. WorktreeCard now reduces a read-only card's props to what it pictures (every handler, selection and active flag dropped), and the controller resolves `readOnly` once into what the views already read: card properties without status, ports or live agents (and with the host), no sleep or delete state, no cache countdown, and one `interactive` flag for its own controls. A contract test renders a read-only card with every feature and handler on in all three card styles and fails on any control outside the caller's rows or any live state. * fix(native-chat): nest and indent the resume dialog's child workspaces as the sidebar does A child workspace whose parent has older metadata with no host id stayed at the top of the dialog, though the sidebar nests it: the dialog copied a strict same-host filter, while the sidebar treats a hostless row as belonging to the host. The nesting rule now lives in one sidebar lineage helper, getWorktreeLineageAncestorsOnHost, which scopes by host the way the sidebar's lineage inputs do. In the legacy card style a nested child was inset for its parent's depth instead of its own, so it sat one sidebar step too far left (0px instead of 14px), outdented into the parent's padding. Each child is now inset for its own depth, as a sidebar row is. A groups-level test renders real sidebar cards from the store, with the child nested under a hostless parent, and checks every offered chat's checkbox renders and the legacy inset. * fix(native-chat): the resume dialog places every workspace even if lineage loops Nesting followed each workspace's parent chain, so two workspaces listed as each other's ancestors (possible only when two hosts report opposite lineage for the same ids) were placed under no top-level entry and vanished, while their pre-ticked chats would still be resumed. The loop is now cut where the walk first comes back, so every workspace renders. * fix(native-chat): keep "Don't ask again" above the resume dialog's buttons when narrow Below the small breakpoint the footer stacks bottom-up, so the option moved into it rendered under Resume and Dismiss all. It now reads top to bottom: the option, then the actions; wider windows keep the single row. * test(sidebar): import the card statically in the read-only contract test Its dynamic import ran in a beforeAll with a 20 s timeout, below the suite's 60 s hook timeout, and timed out under parallel load, which skipped all six contract tests. * fix(sidebar): legacy lineage children step in as far without a status lane Legacy cards outdent their nested child list by 1.125rem to pull it back over the 22px status lane. A card without that lane (a read-only card in the resume dialog, or the sidebar with the Status property off) kept the outdent, so a child's title sat 3px right of its parent's instead of 25px. Without a lane the list now sits at ml-1, which gives the same 25px step (39px at depth 2). Cards with a status lane, the default sidebar, render exactly as before. * fix(native-chat): nest resume dialog children by the sidebar's own row rule Round one nested a child under a parent whenever either had no host id, but the sidebar's row builder looks a parent up on the child's own host, so a row with no host id nests only under a parent with none either. The dialog showed a parent/child pair nested that the sidebar shows side by side. The row builder's parent lookup is now one function, getSidebarLineageParent, and the dialog walks ancestors with it (getSidebarLineageAncestors) over the same non-archived rows and cycle set. The chat's workspace is still found on its host, falling back to a row with no host id. A test checks the four host pairings against the real row builder, and the dialog test renders each pairing with every chat's checkbox. * test(sidebar): pin child-workspace indent with and without a status lane Covers legacy, compact and new card styles with the Status property on and off. With Status on, the legacy and compact sidebar keep their outdent unchanged; with it off they now step children in by the same amount; the new card style is identical either way. The file now imports the card statically, since its 15 s per-test dynamic import timed out under load. * fix(sidebar): a read-only card's child workspaces step in as the sidebar's do The legacy outdent on a card's child list cancels its status lane, which in the sidebar is the unread button plus the row gap: 1.125rem, exactly the outdent, not the 22px the previous fix assumed. Its ml-1 for a card with no lane put the resume dialog's children 4px deeper per level than the sidebar's (25px against 21px). With no lane there is now nothing to cancel and no margin, which gives the sidebar's 21px (35px at depth 2). Status is a fixed card property, so every live card has the lane: only a read-only card takes this branch, and the live sidebar is unchanged. The tests now pin the outdent for live legacy and compact cards and no margin for a read-only one, instead of an unreachable Status-off state. * test(sidebar): a read-only card never carries main's multi-selected marker Main now styles a multi-selected card through data-worktree-card-selected. The contract test passes isMultiSelected, so it now asserts the marker stays off a read-only card, and drops the context-menu event constant main removed from that module. * fix(sidebar): preserve quiet read-only card geometry * fix(native-chat): match resume cards to sidebar rows * fix(sidebar): preserve passive SSH identity on read-only cards * fix(native-chat): keep resume focus and folder host identity * fix(native-chat): remove resume dialog list border * fix(sidebar): keep passive SSH pills static * fix(native-chat): align resume card vertical spacing * fix(native-chat): preserve cache-only card header spacing * fix(native-chat): lay the resume dialog out as a checkbox-column list Every row of the resume list (Select all, workspace, chat) now keeps its checkbox in one left column; nesting indents only the content after it, and a divider separates every row. A workspace checkbox is tri-state over its own chats and those of the workspaces nested under it; Select all heads the list with an "N of M selected" count. Failures a retry cannot fix stay out of both. Up/Down move between the list's checkboxes. The dialog no longer renders the sidebar's WorktreeCard, so the read-only card mode and the sidebar changes that only served it are reverted to main. The sidebar lineage helpers stay: the dialog still nests child workspaces by the sidebar's own rule. * fix(native-chat): name SSH hosts by their saved label in the resume dialog The workspace row's host chip spelled an SSH host with its raw target id (e.g. ssh-1728291234567-abc12d) because it never got the sidebar's host labels. It now takes them from useSidebarHostScopeOptions, as the delete dialog does, so the chip reads "devbox" like the sidebar. Also translates the dialog's five new strings in es, fr, ja, ko and zh. * fix(native-chat): group the resume list in bands and let a project select its chats The resume list now follows the common grouped-list pattern: each workspace heads its chats with a full-width tinted band (lighter for a nested child, at its own indent), chats are split by plain hairlines, and groups meet without gaps or rounded row corners. The project row gets a checkbox in the same left column, tri-state over every eligible chat in the project (nested workspaces included, failures a retry cannot fix left out) with an "x of y" count, on a band a step stronger than a workspace's. The list takes arrow keys, so it is now a named group (role="group"). * fix(native-chat): no project row for workspaces the resume list cannot place Workspaces the store cannot place in a repo were grouped under a header with an empty name, so the new project checkbox was announced as "Select all chats in ". Main and the earlier heads showed that header as a bare folder glyph with no name, and there is no id to fall back to. Those workspaces now get no project row; their own rows and Select all still cover their chats. * fix(native-chat): lay the resume list out as nested workspace boxes Brennan chose the nested-box layout without row dividers. A project is a tinted band; each workspace is a bordered, rounded box one step in from its project, holding its header band and its chats, and a child workspace's box sits inside its parent's, after the parent's chats, at the parent's chat indent. The boxes are drawn in the content area only, so every checkbox stays in the one left column outside them. Rows carry no dividers; the box border is the only line. * fix(native-chat): show the resume list as a tree Brennan chose the Resume Tree. The list is now a tree: machine, then project, then workspace (a child workspace is a node inside its parent, after the parent's chats), then the chats. Every row keeps its checkbox in one left column, then an 18px indent per level, a disclosure arrow (an empty slot on a leaf), the icon and label, and its count. Levels read apart by icon and weight; there are no boxes, bands or row dividers, only the divider under Select all. The machine level shows only when the machine is not obvious (a remote host, or chats on more than one), named with the sidebar's host labels and an SSH chip; it replaces the per-workspace host chip. Chats are grouped per machine first, so one workspace id on two hosts stays two nodes. Every node is tri-state over the eligible chats under it, through the existing per-chat onToggle. Nodes start expanded; collapsing is local to this opening and keeps the selection. The list is a role="tree" of leveled treeitems: Up/Down move between checkboxes, Left collapses and Right expands the focused node. * refactor(native-chat): read each resume chat through one key helper Every per-chat read in the resume tree (its tick, its toggle, its failure, and each group's coverage) now goes through chatState, so a later change of chat key stays in one function. Tests pin the machine level's host rules: a runtime host gets a machine node but no SSH chip. * fix(native-chat): make the resume tree's keys work from its Tab stop and after a click Tab lands on the tree itself, where the arrow keys did nothing. Down and Home now enter at the first checkbox, Up and End at the last; Home and End also jump to the ends from a row. Clicking an arrow with the mouse left focus on the arrow, where no tree key works. After a collapse or expand click, focus now moves to that row's checkbox, or to the tree when the checkbox is disabled. --------- Co-authored-by: Claude <noreply@anthropic.com>
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
Muse
DeepSeek Harness
ZCode
OpenCode
MiMo Code
Amp
OpenClaude
Antigravity
Pi
oh-my-pi
Hermes Agent
Devin
Goose
Auggie
Autohand Code
Charm
Cline
CodeBuddy
Codebuff
Freebuff
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
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
- Android: Download APK 0.0.52 · 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 11.
-
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.










