ADE for working with a fleet of parallel agents
Go to file
Neil cb9aa12fff
test(terminal): pin the macOS key-binding substitution against #11170 (#13315)
* fix(terminal): show a preedit the IME resumes without a compositionstart

Typing 2-Set Korean shows committed syllables but not the in-progress jamo, so
the user composes each syllable blind. Long-standing hole in the vendored
terminal library, not a regression: the same test fails identically against the
bundle this branch starts from.

The `.active` class that CSS keys `display: block` off is added only in
`compositionstart` and dropped in `_finalizeComposition`. Some IMEs (observed on
Windows/WSL Korean) resume a composition with a bare `compositionupdate` and no
second `compositionstart`, by which point `compositionend` has already hidden the
overlay, so the resumed preedit is written into a hidden element and never
positioned. `updateCompositionElements` also early-returned on `!_isComposing`,
so it would not lay the overlay out either.

Re-show the overlay on an update that carries data, and key the layout guard on
the shown overlay instead. `_isComposing` is deliberately left alone, so no
commit bookkeeping changes and `onData` stays byte-identical. The two guards are
equivalent on every pre-existing path: `compositionstart` sets both,
`_finalizeComposition` clears both.

The bundle hunks are the same two edits applied to the shipped minified output;
the sourcemaps are carried through unchanged.

* test(terminal): prove the resumed-preedit fix against a recorded Windows capture

The synthetic test pins the shape; this replays events a real Microsoft Korean
IME emitted on Windows/WSL. The capture holds three compositionupdates that
resume a composition with no second compositionstart — the exact ordering that
wrote the preedit into a hidden overlay.

Without the fix all three report shown:false; with it all three are visible.
Fixture derived from the sealed 11919-windows-wsl-current capture, which is
read-only and unmodified.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): stop the recorded Hangul fixture pinning a derivation artifact

The capture logs each event twice — a dispatch record and a batched next-frame
re-log. Deriving from both replayed every event twice, which made three
compositionupdates appear to land after a session had ended. Filtered to
dispatch records the capture holds zero resumes and 11 balanced sessions, so
the previous toHaveLength(3) was pinning an artifact of the derivation.

Re-scoped to what the capture does prove: the preedit stays visible across all
37 real updates. Verified by reverting the patch that this passes either way,
so it is coverage and the synthetic test remains the discriminator. Both facts
are now stated in the file.

Co-authored-by: Orca <help@stably.ai>

* fix(terminal): restore the preedit visibility patch onto its own branch

The previous commit accidentally reverted it: checking main's patch and lockfile
into the worktree to test whether a test discriminates also stages them, so the
commit that followed swept them up.

Co-authored-by: Orca <help@stably.ai>

* fix(terminal): claim printable keydowns structurally so committed text survives

Co-authored-by: Orca <help@stably.ai>

* chore(reliability-gates): retarget the IME forwarding gate after the allowlist removal

The gate listed terminal-ime-input-source.test.ts, which went with the
input-source allowlist. Points at the substituted-text commit test instead,
which covers what the gate is actually protecting: text committed outside a
composition session reaching the pty exactly once.

Co-authored-by: Orca <help@stably.ai>

* docs(terminal): record why withholding a claimed keydown needs no timer

The predicate withholds a keydown's byte until the commit arrives, so a key the
IME eats without committing would be dropped. Measured across the recorded
corpus that case does not occur, and the browser marks IME-owned presses on the
keydown itself. Both facts belong next to the predicate rather than only in a
handoff note, since the obvious fix for the imagined gap is a timer, and a timer
here once wrote a newline the user never typed.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): pin the kitty all-keys-as-escape-codes hole explicitly

Flag 8 asks for every printable key as an escape code; this path sends the
committed text raw instead. That is a deliberate trade, not an oversight, but it
was untested — the suite only covered the disambiguate flag. Pinning it makes
the choice visible and records the gate to use if it ever needs closing.

Co-authored-by: Orca <help@stably.ai>

* fix(terminal): keep the kitty key-release report for presses that reached the pty

Claiming the keyup unconditionally suppressed xterm's release report. That was
sized for the old design, which claimed only a short punctuation list; the
structural claim takes every printable keydown, so on macOS an app that
negotiated kitty report_event_types stopped seeing releases for ordinary typing
and would treat every printable key as held down.

Suppress the release only when the press put nothing on the wire — swallowed by
the input source, or owned by a composition transaction. xterm emits nothing
from keyup unless kitty report_event_types (or win32 input mode) is on, so
letting it through is inert everywhere else.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): pin the macOS key-binding substitution against #11170

An OS key-binding remap of the character a Korean layout puts on Backquote
is honoured everywhere on macOS except the terminal, which sent the raw
layout character to the PTY. The substitution is applied inside the system
text input path, so it exists only on keypress.charCode and the input
event's data; the keydown still carries the layout character. Nothing needs
to parse the binding file - Chromium has already applied it by the time
`input` fires.

The reported build sent the raw character. A later punctuation table
happened to list that one character, which closed the issue by enumeration
rather than by design, and the structural claim removes the table entirely.
Without a test the fix could regress silently on a change that never
mentions the issue.

Replays the reporter's captured event shape and pairs it with the same
physical key carrying no substitution, so a fix that rewrote the Backquote
position unconditionally would fail. Discrimination checked by mutation:
suppressing the structural claim, and separately removing the single table
character on a pre-rewrite tree, each make the replay send the raw layout
character while both negatives stay green.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): cover the other Korean layout on the remapped key

Korean layouts disagree about what the backquote position produces: two of
them give the currency sign the issue reports, one gives an asterisk. One
key-binding entry has to survive either, but honouring the substitution by
listing characters covers only the ones someone remembered to list - which
is why the reported character worked and this one did not.

This arm discriminates without a mutation: it fails on the pre-rewrite tree
and passes on the structural claim. The harness supplies no input-source
classification, modelling a source the older design did not recognise,
including the window before its async probe resolves. With the source
recognised the older design claimed all ASCII punctuation and covered this
too, so the gap was real but conditional; the header says so rather than
letting the failure read as unconditional.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): drop the Won-setting arm from the keybinding-dict replay

The Won-to-backquote feature was reverted, so the module this replay imported
no longer exists. The #11170 coverage is unaffected: the remaining arms pin the
substitution itself, which never depended on that setting.

Co-authored-by: Orca <help@stably.ai>

* test(terminal): correct the fixture's provenance count

The header said two derived cases when there are four, and counted the
second layout arm as a negative when it is a positive. Each case already
carries its own recorded flag and note; this stops the summary contradicting
them, which matters in the one field whose whole job is provenance.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-09 16:03:52 -07:00
.github fix(terminal): agent pane auto-launch lost under fish + Starship (STA-3417) (#12840) 2026-08-09 14:29:14 -07:00
.husky
Casks
config test(terminal): pin the macOS key-binding substitution against #11170 (#13315) 2026-08-09 16:03:52 -07:00
docs docs: update GitHub star history chart (#13380) 2026-08-09 15:17:11 -07:00
examples/plugins feat: bound direct SSH reconnect fan-out and recovery (#11003) 2026-07-28 12:33:17 -07:00
mobile fix(mobile): load the repo list in GitHub Project mode (#12972) 2026-08-09 14:55:31 -07:00
native fix(computer-use): settle macOS permission checks (#13025) 2026-08-07 15:59:00 -07:00
resources Add account-backed artifact sharing (#13012) 2026-08-07 23:02:29 -07:00
skill-guides Gate artifact publishing behind off-by-default capability (#13368) 2026-08-09 13:19:08 -07:00
skill-stubs feat(skills): land remaining hybrid stubs (#9846) 2026-07-22 11:43:01 -07:00
skills Add account-backed artifact sharing (#13012) 2026-08-07 23:02:29 -07:00
src test(terminal): pin the macOS key-binding substitution against #11170 (#13315) 2026-08-09 16:03:52 -07:00
tests fix(orchestration): release context-only dispatches (#13376) 2026-08-09 14:49:36 -07:00
.gitattributes Revert the terminal IME composition-ownership change (#13282) 2026-08-08 19:06:50 -07:00
.gitignore Revert the terminal IME composition-ownership change (#13282) 2026-08-08 19:06:50 -07:00
.npmrc Update .npmrc 2026-07-11 20:53:20 -07:00
.oxfmtrc.json
.oxlintrc.json fix(terminal): defer metric option writes to unmeasurable panes (#12944) 2026-08-07 10:14:37 -07:00
AGENTS.md test(remote-runtime): run an old client and an old server against current code (#12682) 2026-08-05 01:31:29 -07:00
CLAUDE.md
LICENSE
README.md docs: update Android APK link to v0.0.37 (#12515) 2026-08-04 03:12:23 -07:00
components.json
electron.vite.config.ts fix(browser): align cookie import safeguards (#12607) 2026-08-05 12:51:05 -07:00
orca.yaml
package.json fix(git): bypass WSL login shells for status reads (#13207) 2026-08-09 14:41:40 -07:00
pnpm-lock.yaml Show a preedit the IME resumes without a compositionstart (#13284) 2026-08-09 15:30:26 -07:00
pnpm-workspace.yaml fix(build): stop `pnpm -r` from crawling the mobile workspace (#11291) 2026-07-28 21:34:55 -07:00
tsconfig.json
vite.web.config.ts chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841) 2026-06-29 22:38:29 -07:00

README.md

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.37 · 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.

    WeChat group 7 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.