* Give Session History's rows one decision for open and resume A session row decided "can ▶ resume this" twice: once for the button's disabled state and again inside its click handler, and the chat/CLI and switch-to-pane offers were each gated inline. A second caller of those offers would have had to copy the same conditions again. - One projection, resolveAiVaultSessionRowChatActions, now decides every open/resume offer a row makes; ▶'s greyed-out state and its target come from the same value. - The panel's host-scope menu and per-session resume lookups move into their own hooks unchanged, and the session-list request reads the panel's workspace through one selector. The sidebar behaves exactly as before. * Let Session History host a chat-bound panel with keyboard selection A second Session History panel (the /resume dialog that follows) needs to describe a chat's own workspace rather than the active one, and to let ↑/↓/Enter pick a row. Mounting it beside the sidebar also exposed a place where two panels stepped on each other. - AiVaultPanel takes an optional workspace, an initial query, a header action slot, a small search handle, and onSessionOpened, which also turns on row keys. A thin sidebar wrapper now owns Settings' "focus the search" request, so only the sidebar widens to All. - Keyboard rows store the chosen row, its session and the search text; a session listed twice no longer traps the arrows, and editing the search starts again at the top match. Enter takes the row's best offer: switch to it if open, else open it as a chat, else the row's own ▶, else show details. A clicked row moves focus to the panel, so the keys keep working, and a row scrolled into view stops below the pinned group header. - Switching to an open session reports whether it found something to switch to. - Mounted panels share one copy of the saved view options, so a filter changed in one is not undone by the other. * Make /resume in a structured native chat open Agent Session History Resuming a past session was only reachable from the Agents sidebar, so people in a chat had no way to find it. In a structured native chat, /resume [search] now opens Agent Session History for the chat's own workspace in a dialog, with the search filled in. - The dialog lives in the app's modal slot: a dialog rendered inside a chat would bubble its key and pointer events through the chat's own capture handlers. It closes once the tab on screen changes or a switch to an open session succeeds; a failed action leaves it open. Focus goes back to the chat unless the user was taken elsewhere. - /resume is an ordinary row in the structured chat's / menu, in place of an agent command of that name, or last when there is none. A skill named resume keeps its own row and a picked skill still goes to the agent. Typing it in any case opens the dialog; attachments stay. - Terminal-backed chats (SSH, WSL runtimes, custom start folders, reused terminals, older hosts) are unchanged: /resume reaches the agent as before. The phone is unchanged too. * Start /resume's Session History on the chat's own agent The dialog's agent filter starts on the agent recorded for the chat, the same one its tab icon shows, and stays local to the dialog: the sidebar's saved filter is never read or written by it. Sort, grouping and limit stay shared. An agent the filter doesn't list leaves every agent shown. * Start an OpenCode chat's Session History on both OpenCode names A structured OpenCode chat records its provider as opencode, but the scanner lists current OpenCode sessions as opencode2, so filtering on the recorded name alone hid every OpenCode row, the chat's own included. * feat(native-chat): /resume rows resume the conversation in place of the chat In the /resume dialog a row is now only a "resume here" target: clicking it or pressing Enter opens the picked conversation as a chat right after the chat /resume was typed in, and closes that chat once the new one is confirmed and the old one is idle. A conversation already open elsewhere is switched to, the chat's own conversation just closes the dialog, a closed chat of this workspace and agent is reopened in its place, and anything else only expands its details. A failed resume closes its own tab and leaves the old chat as it was. Dialog rows drop every other action (overflow and context menus, title drag, hover buttons, detail and subagent buttons); the chevron still shows the details. The dialog widens from 480px to 560px. The sidebar's Session History panel is unchanged. * test(native-chat): type the launch-plan mock in the /resume flow test * fix(native-chat): find the reopened chat by its tab, typed test settlement * fix(native-chat): /resume picker review fixes (R5) - Subagent lines in a picker row offer no View Log either (resume null switches them off). - An unsaved row in the picker drops the "open the log" hint, since the picker has no log button. - The sidebar title drag handler is restored, so a row whose resume is disabled still blocks text drags. - Only a failed resume closes its new tab; an unknown outcome keeps both tabs (the new one has its own badge and Retry). - The replaced chat closes only when its last turn finished, its composer draft is empty, and it is not pinned. - One pick at a time: a pick is ignored while an earlier one is still settling. * fix(native-chat): a new, empty chat is idle for /resume replacement A chat with no status entry closes when its launch has finished and its host, observed live, reports no message and no provider still starting. Still-starting and unobservable chats stay open. * fix(native-chat): /resume knows a stale row's open chat; no Copy in picker details - A row listed before its chat took the conversation over has no ownership link. The pick now also reads each open chat's own record (its host status feed's provider session, else the conversation its launch resumes): the chat /resume was typed in just closes the dialog, and another open chat is switched to, instead of trying the takeover again and failing. - The first prompt's Copy button is hidden in picker rows (same switch). * fix(native-chat): act on the host's ownership verdict for stale /resume rows Drop the renderer's own "which chat holds this conversation" lookup: it keyed on the record's head handle, which differs from the host's ownership key (Pi rows, older chain links). Instead, when a resume-here launch is refused because the conversation is held elsewhere, the refusal's owner decides: this chat closes the picker, another chat is switched to, the temporary tab closes, and no failure toast is shown. Rows with an ownership link keep the existing fast path. * refactor(native-chat): share the composer editor setters with the /resume hook Keeps NativeChatComposer under its line cap once current main is merged in. * feat(native-chat): /resume replaces its chat, asking first only when the agent is busy Picking a row now always closes the chat /resume was typed in once the picked conversation's chat is confirmed, pinned or not; the unsent-draft and finished-turn checks are gone. When that chat's agent is replying, waiting on an approval or question, or still starting, Session History closes and a small "Replace this chat?" prompt asks first; Cancel or Esc changes nothing. The prompt reuses the shared confirmation dialog with a new compact look matching the close prompts. * fix(ui): compact confirmation look through dialog title/description sizes The primitives own their typography, so the short close-prompt look is a size variant on DialogTitle and DialogDescription rather than class overrides. * fix(native-chat): command picker takes the full structured transport * fix(ui): compact confirmation width through a DialogContent size The /resume replace prompt matches the close prompts width (max-w-sm) via a compact size on the primitive; callers that pass no size render as before. * fix(editor): pan-zoom dialog props keep their own image size DialogContent now has a size prop; the pan-zoom dialog s size means the image, so it is omitted from the inherited props. * fix(native-chat): /resume asks when the chat's state is unknown; prompt ignores the opening gesture - R8-1: a chat whose host isn't observed live (old host without the status feed, lost contact, no host stamped on the tab) counts as busy, so replacing it asks. - R8-2: the confirmation dialog takes ignoresOpeningGesture: an outside press doesn't dismiss it, a repeated Enter doesn't confirm, and a double-click's second click doesn't press Replace. Other callers are unchanged. * Point the resume-command test at the moved picker-items module * Reopen a closed owner in place of the chat on a refused /resume A row listed before its conversation was adopted has no structured link, so /resume launches a new chat and the host refuses it, naming the closed chat that holds the conversation. That branch reopened the owner but never closed the source chat. Both the reveal path and the refusal path now share one reveal-in-place step; an owner open in another tab is still switched to and the source kept. * Put a reopened chat in the replaced chat's slot Reveal appends the reopened tab to the end of its group, so a /resume that reopened a closed chat left it after unrelated tabs. Move it right after the source with the existing anchor-insertion helper before the source closes, the way a new chat lands. * Keep the typed search when the /resume row is picked With the caret right after /resume and a search typed past it, picking the menu row opened Session History with an empty search. Read the search from the draft, as a typed send does.
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 · Install guide
Community & Support
-
Discord: Join the community on Discord.
-
Twitter / X: Follow @orca_build for updates and announcements.
-
WeChat: Group 11 is full. Scan to join the Orca community WeChat group 12.
-
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.










