Jinwoo Hong 2fccacadbe test(mobile): mount screens, declared device stores and declared OS state in the RPC recorder (#20884)
* test(mobile): mount screens, declared device stores and declared OS state in the RPC recorder

Three recorder capabilities, each with a test, plus four holdout sites recorded against main's
product code to prove them. No product source changes.

- JSX compiles through the automatic runtime, which is what product sources use; the classic
  `React.createElement` emit threw `React is not defined` on the first render of every screen.
- An unlisted package answers `__esModule` as undefined, so a default import loads and the refusal
  defers to the first real member read instead of killing the module at load.
- The substitutes table gains the inert view packages a screen needs, split into
  `screen-native-substitutes.ts` behind the same rule: only what a screen reads is listed.
- A scenario may declare `deviceStore` and `deviceState.notificationTray`. Reads resolve the
  declaration or null and never a write; writes are recorded as effects. Undeclared is unchanged.
- `screenMount` mounts a component with a crash boundary, so a reply partition that takes a screen
  down is a recording rather than a suite failure.

Every pre-existing golden re-records byte-identical except `recorderSha256`, recorded from a
detached worktree at the pinned baseline.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): declare the crash boundary's state type instead of asserting it

The changed-code casting gate counts `null as string | null` as a type assertion. Re-records every
golden from the pinned baseline, because the edit moves `recorderSha256`.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): refuse an unlisted native package by the member a mount reads

Both emitted interop helpers short-circuit on `__esModule`, so answering `true`
hands the refusing trap back unwrapped to `__importDefault` and `__importStar`.
All three import forms now load the importer and throw the named refusal at the
first member read, instead of a namespace import silently yielding `undefined`
and failing later at the call.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): run a task deferred past interactions instead of dropping it

An inert `runAfterInteractions` swallows whatever send the screen deferred, and
the recording then claims the screen sends nothing. It runs the task on a
microtask and returns the RN-shaped handle, so a cancel before the task runs
still prevents it. `Alert.alert` stays inert.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): re-record every golden for the two recorder engine changes

Only `recorderSha256` moves, from c58067de to a59b30e7. Recorded from a detached
worktree at the pinned baseline c6a7216984 with this branch's recorder and
scenario file overlaid, so no golden body is a claim about migrated source.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): stop exporting three recorder symbols with no importer

`projectScreenTree`, `DeviceEffect` and `DeclaredNotification` are only used by
the file that declares them.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): re-record every golden for the dropped exports

Only `recorderSha256` moves, from a59b30e7 to 4df43aef. Recorded from a detached
worktree at the pinned baseline c6a7216984 with this branch's recorder and
scenario file overlaid.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): list only the native members a recording is known to read

Instrumenting `partialNativeModule` across all 522 recordings found 68 declared
members and 23 read. The unread ones are gone: the whole react-native-svg,
react-native-reanimated and react-native-gesture-handler entries, two expo-router
hooks, and twelve react-native members including `InteractionManager` and
`Alert`. A member listed before a recording reads it turns a refusal that would
have forced a decision into a silent stand-in, which is how an inert scheduler
swallows a deferred send. Wave 3 re-adds each one with the recording that reads
it.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): order each effect against the sends with a send count

Sender and effects are two independent lists, so a send reordered ahead of a
device write moved neither. Scheduling the codex journal write on a timer instead
of awaiting it left all 520 goldens byte-identical; with `sent` it moves two.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): report a boundary crash through the effect sink

A hook mount projects the hook's own value and never a crash, so an adapter that
never reads `crash()` recorded a screen that quietly stopped rendering. The
boundary now reports to the effect sink as well, which forces a cleanup
checkpoint and puts the crash in the golden with no adapter cooperation. Two
reply-matrix goldens gain the effect. Also folds the two near-identical tree
walkers into one `walk(tree, visit)`.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): state the __esModule interop rule once

It was restated at four sites with four different answers. The canonical
paragraph is in `native-module-traps.ts`; the loader and the declared tray point
at it in a line. The loader comment also said the refusal names the member the
product read, which for a default import is `.default` instead.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): re-record for the send ordinal, the crash effect and the pruned table

`recorderSha256` moves on all 520. Of the 509 pre-existing goldens, 260 are
header-only and 249 gain `sent` on their effects and nothing else; two of this
branch's own reply-matrix goldens also gain a `screen.crash` effect. Recorded
from a detached worktree at the pinned baseline c6a7216984.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* fix(lint): drop Reflect.get from the native traps

main adopted anti-slop's `no-reflect-get` in #20874 and fixed the copy that lived
in `native-mounting-substitutes.ts`. This branch moved both traps into
`native-module-traps.ts`, so the rule lands here instead and the static-analysis
gate is red without the same narrowing.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): re-record for the Reflect.get narrowing

`recorderSha256` only, 8ca81bc6 to 0ddc0dc4. No golden body moves, which is the
claim the narrowing makes: the trap reads the same member it always did.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* test(mobile): re-record every golden at main's new baseline pin

One record from a detached worktree at `e7206f62a8` — main's pin since #20895 —
with this branch's `rpc-recording/`, `pilot-scenarios.json` and
`scripts/rpc-recording.mts` laid over it, so the goldens are recorded against
main's product tree rather than a branch that edits the engine.

All 520 goldens now share one `recorderSha256`
(`0ddc0dc472e2efbe58004c6dfaf5360e368fed321e40dfe15c11a9ad1817dea4`) and one
`baseline`. Against main, 262 move on the header alone and 247 also gain the
`sent` ordinal on an effect, which is the whole of the body change; the nine
goldens #20895 re-digested carry a byte-identical body, and the six the new
worktree catalog adapter (#20873) recorded keep main's observation.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
2026-09-15 18:52:47 -04:00
2026-09-15 18:29:06 +00: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.48 · 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 8. Group 8 may be full; if so, scan the Group 9 QR code instead.

    WeChat group 8 QR code for the Orca community  WeChat group 9 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.

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.

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.4 GiB
Languages
TypeScript 95.2%
JavaScript 4.1%
Swift 0.2%
CSS 0.1%
HCL 0.1%