mirror of
https://github.com/stablyai/orca.git
synced 2026-10-05 08:02:33 +00:00
<!-- orca-pr-loc -->
<!-- Programmatic LoC summary. Do not edit by hand; rewritten on every commit. -->
| | Files | Added | Deleted | Net |
| :--- | ---: | ---: | ---: | ---: |
| Test | 225 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$21666 | $\color{#cf222e}{\Huge{\mathbf{−}}}$2820 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$18846 |
| Prod | 348 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$17107 | $\color{#cf222e}{\Huge{\mathbf{−}}}$4706 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$12401 |
<!-- /orca-pr-loc -->
## ELI5
Orca now treats orchestration like a durable control plane instead of inferring success from terminal keystrokes. Agents can tell whether a prompt was accepted or a turn started, replay an ambiguous request without sending twice, and recover coordinator mail after a crash. Completed workers can be inspected, released, or retained, and their panes no longer auto-resume as if the work were still running.
## What changed
- **Run receipts** from `run-create/use/current/show/list` are the row without routing plumbing (`home_database`, `coordinator_pane_key`) and without the duplicate `binding` object.
- **`terminal send` receipts are honest and idempotent.** `input_accepted` and `turn_started` are the only stages; `--wait-submit` observes without resending; `--retry-request <uuid>` replays the exact request against the same process incarnation. A transport timeout keeps the retry ID; only a different runtime answering strips it. Value-less or non-UUID `--retry-request` is rejected on the CLI and the SSH shim.
- **Mailbox delivery is committed before wakeup.** Pointer writes are staged in the DB before any PTY byte, replayed once after restart, and never emit a naked Enter. The watermark that parks concurrent deliveries is released with the DB reservation. Restart rescans pointer-pending and `dispatch:` mailboxes.
- **Lifecycle is a guarded transition graph** (`lifecycle-transition.ts`) with a table-driven test over every caller edge. Task reopen/overturn stays in the public contract. A PTY exit during `worker-stop` is the stop succeeding, not a failure.
- **Worker lifecycle CLI:** `worker-start` (`--spec` creates Task + attempt in one call), `worker-show`, `worker-read` (provider transcript first, bounded terminal fallback with a typed reason, local/WSL/SSH), `worker-stop`, `worker-abandon`, `worker-release`, `worker-retain`, `worker-list` (rowid-fenced pagination, fleet liveness, `attention`, literal `nextAction`).
- **Release is an explicit ownership table** (`decideWorkerTerminalRelease`): only an `owned` resource can be settled, the archive is mandatory where reachable, and an owner whose process is proven exited can always get out of `retained` via `archive_status: unavailable`. User-taken-over, external, and transferred panes stay retained.
- **Settled-worker resume fence** (folds in #17651): a settled dispatch whose pane is still open is fenced at settlement, on stop/abandon/exit, and at startup; lifted on release, retain, takeover, and pane reuse.
- **Liveness is `live` / `unverifiable` / `exited` only**, from execution-host evidence. Fleet projection reads the evidence clock, not the relay delivery clock. A host-certified exit outranks the worker's settled state. `unverifiable` never authorizes stop, abandon, retry, or release, in code or in the guide.
- **Federation:** structured reads negotiate by `method_not_found` so every shipped host keeps transcript-first output; exited remote workers are closed before being reported closed; epoch fencing holds across peer restart, downgrade, and pairing rotation; no per-second forced capability probe.
- **Schema v35:** repairs databases stamped v34 by the pre-fix branch (mailbox_handle default, index predicates), drops the write-only `lifecycle_transition_receipts` ledger and five never-read v31 identity columns.
- **Schema v36:** `dispatch:<id>` mailboxes get a real consumer generation on `dispatch_contexts` and `remote_dispatch_attachments`, bumped and fenced in the same transaction on every re-attach (manual inject, worker-start, federated attach). A stale worker whose Dispatch moved to another process now gets `consumer_fenced` instead of silently acking the new worker's Delivery. Run mailboxes already worked this way.
- **Schema v37:** `dispatch_contexts` records its creator (`creator_handle`, `creator_pane_key`), so a coordinator's context-only self-dispatch is bookkeeping rather than a nesting parent; before this, one self-dispatch made every later `worker-start` from that coordinator fail the depth cap. Pre-v37 rows keep counting (fails closed).
- **Dispatch-mailbox ownership is checked, not inferred.** A `check` from a process whose pane no longer holds the Dispatch, or whose last Attempt was abandoned/failed and moved to another terminal, gets `consumer_fenced` instead of an empty inbox that reads as "no mail yet". `--peek`/`--all` stay readable. A paneless caller still gets `stable_pane_required` with the rebind recovery.
- **Liveness certification is stricter:** a `process_exited` stage whose termination reason is `unknown` (a stop that was issued but never observed) projects `unverifiable`, not `exited`. Federated `worker-show` carries the execution host's verdict and host kind instead of a local guess. A live, ready worker with nothing pending has `nextAction: none` rather than pointing at the `worker-show` that produced it.
- **Wire:** `workerShow` keeps `dispatch.task_id` next to `taskId` for shipped CLIs. `ask --json` uses the standard `{ok, result}` envelope like every sibling verb.
- **Migration start-version detection** treats the two v32 recovery columns as versioned. Before this, every shipped database stamped below 32 resolved to the v6 floor and replayed the whole chain (the v23 backfill synthesized 68 phantom retained workers on a real v30 profile). Verified on a copy of a real 62 MB v30 profile: starts at 30, no row delta, integrity ok, 11 ms.
- **Skill guide** rewritten as a ≤200-line kernel plus seven references, to the outcome-first standard (Result / Done / Safe failure first, conditions not case lists, one done bar, references loaded at the point of use). The canonical loop uses `worker-start --spec`, names `worker-list` for completion accounting, documents `--retry-request` / `request-show` / `--wait-submit`, and requires positive evidence before any stall action. The other seven guides get the same treatment in #18724, split out so this PR stays orchestration-only.
- **`rpc/methods/orchestration-*`** (126 flat files) regrouped into `orchestration/{worker,federation,messaging,runs,gates}/`.
## Why
User reports showed the same boundary failures: false `agent_prompt_stalled` causing duplicate sends (#15180), coordinators unable to trust screen scrapes, cold-parked terminals receiving a pointer without the submit, settled workers accumulating as live tabs and auto-resuming after restart, and no way to tell a stalled worker from a working one.
## Linked issues
Fixes #15180. Fixes #17935 (orchestration skill description is 866 characters; a guard now caps every bundled skill at 1,024). Supersedes #17651 (fence folded in). Advances #16660, #16522, #14907, #13047.
## Review record
This PR was reviewed adversarially after revival: eight independent lenses (lifecycle, mailbox, send, worker, federation, transcript, complexity, live ergonomics), each required to prove findings with a failing test. That produced 16 proven blockers, all fixed with red-then-green regression tests, followed by two re-review rounds and a third fix wave that caught 3 regressions introduced by the fixes and 7 fixes that missed their target; all closed. A final pass (five lenses incl. a live built-runtime smoke, then a re-review of the fix wave) found and fixed seven more, chiefly the stale-worker mailbox steal, the self-dispatch depth wedge, and the unproven-exit certification. Three independent Codex (gpt-6-astra) passes followed: the first found nothing new, the second found and fixed 3 defects (task-status reachability, WSL-local host classification, peer-capability epoch), the third found and fixed 6 (production PTY controller never installed settled writes, ambiguous in-flight pointer failures allowed duplicate replay, SSH/relay deadlines cut off a valid `--wait-submit`, stop-vs-exit race during inspection, and two release-recovery paths for vanished or exited terminals). The full record (findings, proof tests, triage, declines with reasons) is archived outside the repo.
**Rework after the live smoke.** A first live cross-host run on the shipped adhoc build (this Mac, a paired Windows host on the same build, a paired Mac on 1.4.195, and an SSH host) found a P1: a running local worker read `unverifiable`/`missing_status` because the fleet snapshot rows lacked the terminal handle the matcher keyed on. A 59-row failure table over every bug fixed during review showed the same two classes recurring: a fact dropped in transit through optional fields, and two authorities for one fact. Two blind designs (Opus, Codex) converged on the same mechanisms, and the scoped tranches landed here with red-then-green seam tests from the real producer to the real consumer, faults injected only at the transport or hook-ingest boundary:
- **Settlement (data-loss class):** one three-valued `WriteSettlement` (`accepted | refused{reason} | unverifiable{reason, bytesHandedToTransport}`) from the SSH multiplexer through daemon client, providers, controller, to pointer staging. No boolean, no rejection-as-third-state. The two silent degrades that fabricated a handoff are deleted; a provider that cannot settle refuses before any effect. Pointer text and Enter share the contract; a partial flush is `unverifiable`, never `refused`.
- **Evidence identity (false-liveness class):** fleet agent-status evidence is a tagged union (`binding: worker | pane | unresolved{reason}`, `clock: observed | delivery`) minted once at ingest, so a hook row captured on one process incarnation can never bind to a later dispatch on the same pane. The matcher's `!worker.paneKey ||` defaults are gone. One host-scope parser replaces two.
- **Small pre-merge items:** `capability_unsupported` from an old peer is no longer relabelled `host_unavailable`; a producer census test asserts every agent-status consumer path projects a pane-only hook row as `live`.
Two ergonomics defects the second live run surfaced on a real database are fixed here too: a pre-v3 dispatch already marked `completed` projected as `outcome_unknown` / `requiresAction: true` forever (three copies of the outcome ladder disagreed on legacy rows; now one resolver, legacy `completed` reads `succeeded` with nothing to act on, legacy `failed` stays actionable on the failure), and an unscoped `worker-list` enumerated the entire database (now defaults to the Run bound to the calling terminal, `--run` overrides, and the receipt's additive `scope` field says which).
A third live round on the shipped adhoc build of `b082443e1f` (same four hosts) plus an unscripted run in the user's own prompt style (a plain Claude Code shell, `/orchestration`, three workers, zero errors, bound-Run default confirmed) found two more branch defects, fixed with red-then-green tests: a worker freshly started on a paired server projected `unverifiable`/`host_indeterminate` with `requiresAction` for ~3 minutes, including after its own `worker_done`, because the host's federation observation returned `missing_liveness_verdict` for any PTY the liveness register had not yet swept (the host now reads a connected pane it owns locally as `live`; disconnected or SSH-scoped panes stay `unverifiable`); and six pre-v3 completed rows still carried an `input` category because settling through the task-status path or `failDispatch` never closed the Dispatch's pending question threads (both paths close them now, and schema v38 closes threads already pending on settled rows). The guide's `worker-start` examples now show `--model sonnet`, since an omitted model inherits the launcher's default.
A Codex adversarial pass on the tranche diff found one real design hole (identity minted at read time instead of ingest, now closed) and two daemon settlement paths that threw instead of settling (fixed). Two `@ts-nocheck` runtime mixins on these paths were extracted into checked modules; the repo-wide `@ts-nocheck` count is unchanged at 171.
Deletions during review: ~1,900 lines (write-only ledger, unread columns, dead v1 archive path, test harnesses shipped in prod, duplicated liveness and state-machine copies, self-capability checks that were compile-time true).
## Testing
- `pnpm typecheck:tsc:node|cli|web` clean
- `pnpm run check:code-quality:changed` 0 findings; `check:react-doctor:changed` 0
- `pnpm verify:bundled-skill-guides`, `verify:skill-bundle-manifest`
- full `pnpm test` on the integrated head: 72,332 pass / 292 skipped; the only failures were three non-PR files (two zsh live-shell suites hit a node-pty spawn-helper ENOENT while a concurrent native rebuild ran, 44/44 in isolation; `release-checkout.unit.test.ts` is a known 30 s load timeout that passes in isolation on `origin/main` too).
- CI on 70b4811267 (rerun, pre-Codex): the only reds are five SSH e2e specs plus `terminal-send-agent-prompt-submit:198`, each shown failing identically on main (main's E2E workflow is red on its last 40 runs). The terminal-send spec is root-caused and fixed separately in #18707. The Windows hook-service flake (#17721) and the federation load flake did not recur.
- Skills: `pnpm exec vitest run` over the skill gate files plus `src/cli`, `config/scripts`, `src/main/skills` pass; live smoke on the built CLI of `skills get orchestration` and `--full` (7 references).
- live headless runtime (`orca-dev serve`, isolated profile): canonical loop, stop, release, archive read, retry rejection, stale-handle check, SIGKILL-and-replay all verified with receipts
- Live cross-host smoke on the shipped adhoc build of `0d465e7931` (this Mac and a paired Windows host on the build, a paired Mac left on 1.4.195, an SSH host): local, paired-new, paired-old and SSH loops all settle; running workers read `live` on every host and `exited` after release; the old peer reads `capability_unsupported` and refuses release honestly. Injected 10 s relay stall with a send in flight: delivered exactly once after recovery, zero duplicates. Every liveness field across 104 receipts is only `live` / `unverifiable` / `exited`.
- Final live cross-host smoke on the shipped adhoc build of `b082443e1f` (same hosts): every loop settles; 942 of 948 legacy completed rows read settled with `requiresAction: false` before the question-thread fix and all of them after; `worker-list` scope reads `bound` / `flag` / `all` correctly; 122 JSON receipts carry only `live` / `unverifiable` / `exited`. Unscripted prompt-style run: clean.
- Confirmation smoke on the shipped adhoc build of `2da076d4e9` (this Mac and the paired Windows host, both updated): a freshly started Windows worker reads `live` on the first fleet poll and on all 20 that follow, with no `host_indeterminate` at any point, and `exited` after release; all 948 legacy completed rows read `requiresAction: false` with `nextAction: none` after schema v38; every verdict across 60 receipts is `live` / `unverifiable` / `exited`.
- Not physically exercised: WSL hosts, the renderer notification bell (headless has no renderer), same-session fence via a real pane close (renderer-only state), restart mid-delivery on a real app (covered by e2e only).
## Notes
- Remote-wire additions are optional fields or `method_not_found`-negotiated methods; one new Electron-only IPC channel (`agentStatus:legacyWorkerTerminalResumeFence`) never crosses the wire.
- SSH contact loss remains `unverifiable`; the execution host stays authoritative.
- Intentional wire projection change: an SSH host scope with an empty `targetId` now projects host id `ssh` instead of an empty string (remote-wire-compatibility rule 3, old clients decode the same field). A fleet pane key without a terminal handle is now `unidentifiable` rather than matched by pane key alone.
- Found live but pre-existing on main, filed separately: a relay daemon-start collision during transport loss rewrites the endpoint credential and wedges the surviving relay (host needs a manual kill); `terminal create` on a reconnecting SSH host reports an opaque `No PTY provider for connection`; `terminal list` reports `orphaned:false` and `terminal close` reports `ptyKilled:true` for a pane whose relay is gone (orchestration's own projection reads `unverifiable` correctly at the same moment).
- Downgrade after this PR is not a supported path: main opens a v37 database and early-returns (its inserts still work against the v36/v37 defaulted columns), but its one-outstanding-Delivery-per-Run index is a no-op against the branch's mailbox-scoped index of the same name.
- Known follow-ups (not blockers): `worker-list` materializes every dispatch row per call; a positive "agent absent" signal distinct from PTY liveness is a product decision left open (a headless fake agent never reaches `live`, so its `nextAction` stays `inspect`); a context-only self-dispatch still lists as `role: worker` in `worker-list`; `dispatch` task-not-found / task-not-ready / inject-rejected still surface as `runtime_error`; task and inbox receipts still expose raw row columns. Deferred skill product decisions live on #18724.
369 lines
17 KiB
Plaintext
369 lines
17 KiB
Plaintext
---
|
|
title: Orca CLI reference
|
|
description: Commands, selectors, and agent-friendly patterns for driving Orca from a shell.
|
|
---
|
|
|
|
import { Callout } from '@/components/docs/prose'
|
|
|
|
The `orca` CLI talks to a running Orca runtime. Use it when a shell script or agent needs to inspect worktrees, launch terminals, open files, automate the built-in browser, or report progress back into Orca.
|
|
|
|
## Verify the runtime
|
|
|
|
Register the CLI under [Settings → General → Orca CLI](/docs/settings), then check that it can reach Orca.
|
|
|
|
<Callout title="On Linux the command is orca-ide">
|
|
GNOME Orca — the screen reader that ships with most GNOME desktops — already owns `/usr/bin/orca`,
|
|
so Orca's Linux CLI installs as `orca-ide`. Do not check for it with `command -v orca`: that
|
|
succeeds on a GNOME desktop and resolves to the screen reader, not to Orca. This page writes
|
|
`orca` throughout — read it as `orca-ide` on Linux. See [Install → Linux](/docs/install#linux).
|
|
</Callout>
|
|
|
|
On macOS and Windows:
|
|
|
|
```bash
|
|
command -v orca
|
|
orca status --json
|
|
```
|
|
|
|
On Linux:
|
|
|
|
```bash
|
|
command -v orca-ide
|
|
orca-ide status --json
|
|
```
|
|
|
|
If Orca is not already running:
|
|
|
|
```bash
|
|
orca open --json
|
|
orca status --json
|
|
```
|
|
|
|
Use `--json` when another tool will parse the result. Human-readable output is for quick terminal checks.
|
|
|
|
## Selectors
|
|
|
|
Most commands accept selectors instead of requiring long IDs:
|
|
|
|
```bash
|
|
orca repo show --repo id:<repoId> --json
|
|
orca worktree show --worktree active --json
|
|
orca worktree show --worktree path:/abs/path/to/worktree --json
|
|
orca worktree show --worktree branch:feature-name --json
|
|
orca worktree show --worktree issue:123 --json
|
|
```
|
|
|
|
`active` and `current` resolve to the enclosing Orca-managed worktree from the shell's current directory or terminal context. Use explicit selectors in scripts that may run outside the target worktree. For remote runtimes, prefer full server-side selectors such as `id:<repoId>::<absolute-worktree-path>` or `path:<absolute-server-path>` because the local shell's current directory may not exist on the runtime host.
|
|
|
|
## Choose a host
|
|
|
|
List every machine the current Orca host can target and the selector for each one:
|
|
|
|
```bash
|
|
orca host list --json
|
|
```
|
|
|
|
The result includes this machine, its registered [SSH targets](/docs/ssh), and paired [Remote Orca Servers](/docs/remote-servers). Use `--host local` for this machine, `--host ssh:<target-id>` for an SSH target, and `--environment <server-name>` for a paired server. SSH rows include the detected remote platform (`linux`, `darwin`, or `win32`) after the target connects; older or disconnected targets report `platform unknown`. They also include `connected` and, when known, the SSH lifecycle `connectionStatus`. SSH labels and paired-server names also resolve when they are unique; use the IDs from `host list` when names collide. If you put a machine name on the wrong selector, Orca reports the matching machine and the flag to use instead of returning an empty result.
|
|
|
|
## Runtime commands
|
|
|
|
```bash
|
|
orca open --json
|
|
orca status --json
|
|
orca serve --port 6768 --pairing-address 100.64.1.20 --json
|
|
```
|
|
|
|
`orca serve` starts a runtime server in the foreground without opening the desktop window. Use it for [Remote Orca Servers](/docs/remote-servers) or headless environments, and stop it with `Ctrl-C`.
|
|
|
|
## Repos
|
|
|
|
```bash
|
|
orca repo list --json
|
|
orca repo add --path /abs/path/to/repo --json
|
|
orca repo show --repo id:<repoId> --json
|
|
orca repo set-base-ref --repo id:<repoId> --ref origin/main --json
|
|
orca repo search-refs --repo id:<repoId> --query main --limit 10 --json
|
|
```
|
|
|
|
Set the repo base ref before creating lots of worktrees so new tasks branch from the right place by default.
|
|
|
|
## Worktrees
|
|
|
|
```bash
|
|
orca worktree list --repo id:<repoId> --json
|
|
orca worktree ps --json
|
|
orca worktree current --json
|
|
orca worktree show --worktree active --json
|
|
orca worktree create --repo id:<repoId> --name fix-login --json
|
|
orca worktree create --name child-task --agent codex --prompt "Investigate the flaky login test" --json
|
|
orca worktree set --worktree active --comment "reproduced failure; testing token refresh fix" --json
|
|
orca worktree rm --worktree id:<worktreeId> --force --json
|
|
```
|
|
|
|
When `worktree create` runs from inside an Orca-managed worktree, Orca records the new worktree as a child when it can infer the relationship. Pass `--parent-worktree active` to be explicit, or `--no-parent` when the new work is independent.
|
|
|
|
Agent startup flags:
|
|
|
|
```bash
|
|
orca worktree create --name review-api --agent claude --setup run --json
|
|
orca worktree create --name quick-check --agent codex --prompt "Summarize the diff" --setup skip --json
|
|
orca worktree create --name hidden-setup --setup inherit --json
|
|
```
|
|
|
|
`--agent` launches the selected agent in the first terminal. `--prompt` sends initial work to that agent. `--setup run|skip|inherit` controls repo setup hooks; `inherit` follows the repo policy.
|
|
|
|
## Terminals
|
|
|
|
```bash
|
|
orca terminal list --worktree active --json
|
|
orca terminal show --terminal <handle> --json
|
|
orca terminal read --terminal <handle> --json
|
|
orca terminal read --terminal <handle> --screen --json
|
|
orca terminal read --terminal <handle> --cursor <cursor> --limit 1000 --json
|
|
orca terminal send --terminal <handle> --text "continue" --enter --json
|
|
orca terminal wait --terminal <handle> --for tui-idle --timeout-ms 300000 --json
|
|
orca terminal create --worktree active --title "tests" --command "npm test" --json
|
|
orca terminal split --terminal <handle> --direction horizontal --command "npm run dev" --json
|
|
orca terminal rename --terminal <handle> --title "runner" --json
|
|
orca terminal switch --terminal <handle> --json
|
|
orca terminal close --terminal <handle> --json
|
|
orca terminal close --worktree active --all --json
|
|
```
|
|
|
|
Omit `--terminal` to target the active terminal in the current worktree. Read before sending when you are not sure what the terminal is waiting for.
|
|
|
|
Close stops the process as part of removing the terminal. Use `--terminal <handle>` for one
|
|
terminal, or `--worktree <selector> --all` to durably close every terminal in exactly that
|
|
workspace, including its saved layouts and agent-resume records. Use workspace Sleep when those
|
|
terminals should resume later. If the execution host cannot confirm that every PTY stopped, bulk
|
|
close returns a failing `unverifiable` result rather than claiming the processes exited.
|
|
`terminal stop` remains only for compatibility with older tooling.
|
|
|
|
<Callout title="Terminal handles">
|
|
Terminal handles are runtime-scoped. If Orca restarts or a command reports a stale terminal
|
|
handle, run `orca terminal list --json` and reacquire the handle.
|
|
</Callout>
|
|
|
|
`terminal list` reports each terminal's `executionHostId` when Orca can verify it, plus a result-level `hostScope` with covered and omitted host IDs. Treat a missing host identity or scope as **unverifiable**, not local. A missing terminal is evidence that it exited only when its execution host is listed in `hostScope.hostIds`.
|
|
|
|
By default, `terminal read` returns the accumulated output stream with terminal escapes stripped. Programs that redraw lines can therefore appear as stacked fragments. Use `--screen` when you need the currently rendered frame; the response's `source` identifies `stream`, `screen`, or `screen-unavailable`. Screen reads have no history to page, so `--screen` and `--cursor` are mutually exclusive.
|
|
|
|
For long output, use cursor reads. Save `nextCursor` from one stream read, then pass it back with `--cursor` to fetch only new output.
|
|
|
|
## Files
|
|
|
|
```bash
|
|
orca file open src/App.tsx --worktree active --json
|
|
orca file diff src/App.tsx --staged --worktree active --json
|
|
orca file open-changed --mode both --worktree active --json
|
|
```
|
|
|
|
Paths are relative to the selected worktree. `open-changed` reads git status and opens changed files in edit, diff, or both modes.
|
|
|
|
## Built-in browser
|
|
|
|
Browser commands control Orca's embedded browser tab for the selected worktree. They do not control Chrome, Safari, or the Orca desktop UI.
|
|
|
|
Use a snapshot -> act -> snapshot loop:
|
|
|
|
```bash
|
|
orca goto --url http://localhost:3000 --worktree active --json
|
|
orca snapshot --worktree active --json
|
|
orca click --element @e3 --worktree active --json
|
|
orca fill --element @e1 --value "user@example.com" --worktree active --json
|
|
orca wait --text "Welcome" --worktree active --json
|
|
orca screenshot --worktree active --json
|
|
```
|
|
|
|
Refs such as `@e3` come from `snapshot`. Re-snapshot after navigation, tab switches, clicks that change the page, and any stale-ref error.
|
|
|
|
Tab and capture commands:
|
|
|
|
```bash
|
|
orca tab list --worktree active --json
|
|
orca tab create --url http://localhost:3000 --worktree active --json
|
|
orca tab switch --index 1 --worktree active --json
|
|
orca capture start --worktree active --json
|
|
orca console --limit 50 --worktree active --json
|
|
orca network --limit 50 --worktree active --json
|
|
orca full-screenshot --worktree active --json
|
|
orca pdf --worktree active --json
|
|
```
|
|
|
|
Use `orca exec --command "<agent-browser command>" --json` only for browser actions that do not have a typed Orca command yet.
|
|
|
|
Browser device emulation:
|
|
|
|
```bash
|
|
orca set device --name "iPhone 12" --worktree active --json
|
|
orca screenshot --worktree active --json
|
|
```
|
|
|
|
## Desktop computer use
|
|
|
|
Use `orca computer` for native desktop apps outside the built-in browser:
|
|
|
|
```bash
|
|
orca computer permissions --json
|
|
orca computer list-apps --json
|
|
orca computer get-app-state --app com.apple.Safari --json
|
|
orca computer click --app com.apple.Safari --element-index 12 --json
|
|
orca computer paste-text --app com.apple.Safari --text "hello" --json
|
|
```
|
|
|
|
See [Computer use](/docs/cli/computer-use) for the full workflow and permission setup.
|
|
|
|
## Mobile emulator
|
|
|
|
The mobile emulator commands control iOS Simulator devices through Orca's worktree-scoped bridge. Use them instead of raw `serve-sim` or `simctl` when an agent is operating from inside Orca, so lifecycle and active-device state stay attached to the current worktree.
|
|
|
|
```bash
|
|
orca emulator list --worktree active --json
|
|
orca emulator attach "<device-name-or-udid>" --worktree active --json
|
|
orca emulator tap 0.5 0.7 --worktree active --json
|
|
orca emulator type "hello" --worktree active --json
|
|
orca emulator gesture '[{"type":"begin","x":0.5,"y":0.8},{"type":"move","x":0.5,"y":0.4},{"type":"end","x":0.5,"y":0.2}]' --worktree active --json
|
|
orca emulator button home --worktree active --json
|
|
orca emulator rotate landscape_left --worktree active --json
|
|
orca emulator exec --command "tap 0.5 0.7" --worktree active --json
|
|
orca emulator kill --worktree active --json
|
|
orca emulator shutdown --worktree active --json
|
|
```
|
|
|
|
Coordinates are normalized from `0` to `1`. Prefer `tap` for single taps, and use `gesture` for drags or multi-step touch input. Pass `--device <udid-or-name>` or `--emulator <id>` when a script must target a specific simulator instead of the worktree's active emulator.
|
|
|
|
## Linear
|
|
|
|
The `orca linear` surface is what agents use via the `orca-linear` skill (legacy install name `linear-tickets` still works). Prefer `--json`. Linked worktrees resolve with `--current`.
|
|
|
|
### Read
|
|
|
|
```bash
|
|
orca linear issue --current --full --json
|
|
orca linear issue ENG-123 --comments --children --relations --activity --json
|
|
orca linear search "auth bug" --workspace all --json
|
|
orca linear list --filter assigned --limit 10 --json
|
|
orca linear list-issues --team ENG --state started --assignee me --json
|
|
orca linear list-issues --query auth --updated-at -P7D --cursor <cursor> --workspace <id> --json
|
|
orca linear team list --json
|
|
orca linear team states --team ENG --json
|
|
orca linear team labels --team ENG --json
|
|
orca linear project list --query launch --json
|
|
```
|
|
|
|
`--full` expands comments, children, attachments, relations, and activity. Section flags (`--comments`, `--children`, `--attachments`, `--relations`, `--activity`) work individually.
|
|
|
|
### MCP-style write
|
|
|
|
```bash
|
|
# Create or update (omit id/--current to create; requires --team and --title on create)
|
|
orca linear save-issue --team ENG --title "Fix auth" --priority high --json
|
|
orca linear save-issue ENG-123 --state "In Progress" --assignee me --json
|
|
orca linear save-issue --current --project null --due-date null --json
|
|
|
|
orca linear relation add ENG-1 --related ENG-2 --type blocks --json
|
|
orca linear relation remove ENG-1 --related ENG-2 --type related --json
|
|
```
|
|
|
|
`save-issue` labels **replace** the full label set (Linear MCP `save_issue` semantics). Literal `null` clears assignee, estimate, due date, project, or parent.
|
|
|
|
### Field helpers (still valid)
|
|
|
|
```bash
|
|
orca linear status set --current --to "In Progress" --json
|
|
orca linear assignee set --current --me --json
|
|
orca linear priority set ENG-123 --to high --json
|
|
orca linear estimate set --current --to 3 --json
|
|
orca linear due-date set --current --to 2026-08-01 --json
|
|
orca linear label add --current --label backend --json
|
|
orca linear comment add --current --body "Investigating regression" --json
|
|
orca linear attach --current --url https://example.com/repro --title "Repro" --json
|
|
orca linear create --title "Flaky login test" --team ENG --priority high --json
|
|
```
|
|
|
|
Run `orca linear --help` or `orca skills get orca-linear` for the version-matched list. Pass an explicit issue id (e.g. `ENG-123`) when a script may run outside an Orca-linked worktree.
|
|
|
|
## Skills (local, no runtime required)
|
|
|
|
List bundled guides, print a version-matched guide, or install/update hybrid skill packages without the desktop Settings UI:
|
|
|
|
```bash
|
|
orca skills list
|
|
orca skills get orca-cli
|
|
orca skills get orchestration --references
|
|
orca skills get orchestration --reference recovery-and-cleanup
|
|
orca skills get orchestration --full
|
|
orca skills install --skill orca-cli --skill orchestration
|
|
orca skills install --all --dry-run
|
|
orca skills update --all
|
|
```
|
|
|
|
`install` / `update` shell out to the same `npx skills` commands Settings uses. They do not contact the Orca runtime. See [Orca skills](/docs/cli/skills#keep-skills-up-to-date).
|
|
|
|
## Account (host-local runtime)
|
|
|
|
On a headless host running Orca (`orca serve` or the desktop app), add managed Claude/Codex accounts when the remote client cannot use **Add account** (remote runtime scope disables that button):
|
|
|
|
```bash
|
|
orca account list
|
|
orca account add # Claude by default
|
|
orca account add --agent codex
|
|
```
|
|
|
|
`account add` runs `claude login` / `codex login` in **this** terminal on the host, then registers the captured credentials with the local runtime. Codex uses device authorization so the browser can finish on another machine. Run these on the machine that owns the accounts — not through a client-only remote session.
|
|
|
|
## Artifacts
|
|
|
|
Publish HTML or Markdown through the signed-in Orca account. Viewing a public link does not require sign-in; create/list/update/delete do. **Publishing is off by default** — a human must enable **Settings → Artifacts → Allow publishing public artifact links** on the device. There is no CLI flag that grants the gate. `list`, `unshare`, and `delete` stay available so you can audit or revoke links after turning publishing off.
|
|
|
|
```bash
|
|
orca artifacts share ./report.html --json
|
|
orca artifacts share ./notes.md --json
|
|
orca artifacts update ./notes.md --json
|
|
orca artifacts unshare ./notes.md --json
|
|
orca artifacts list --json
|
|
orca artifacts list --cursor <cursor> --json
|
|
orca artifacts delete <id> --json
|
|
```
|
|
|
|
- Accepted files: `.html`, `.htm`, `.md`, `.markdown`.
|
|
- `share` stores the edit token in the active Orca profile and does not print it. `update` / `unshare` resolve by the same local path and profile that originally shared the file.
|
|
- `list` is paged (`nextCursor` → `--cursor`). `delete` takes the artifact id from `list` and does not need the original file.
|
|
- Relative HTML assets are not uploaded — share self-contained HTML or absolute asset URLs.
|
|
- Denied publish/update fails with `artifact_sharing_disabled`; fix Settings instead of retrying.
|
|
- Desktop: open a local HTML or Markdown file and use **Share as artifact**, or manage links from the sidebar **Artifacts** page.
|
|
|
|
## Automations, environments, and hooks
|
|
|
|
Scheduled prompts:
|
|
|
|
```bash
|
|
orca automations list --json
|
|
orca automations create --name "Daily review" --trigger daily --time 09:00 --prompt "Review open changes" --provider codex --repo id:<repoId> --disabled --json
|
|
orca automations run <automationId> --json
|
|
```
|
|
|
|
Remote runtime environments:
|
|
|
|
```bash
|
|
orca environment add --name work-laptop --pairing-code "orca://pair?code=..." --json
|
|
orca environment list --json
|
|
orca environment rm --environment <selector> --json
|
|
```
|
|
|
|
Agent status hooks:
|
|
|
|
```bash
|
|
orca agent hooks status --json
|
|
orca agent hooks on --json
|
|
orca agent hooks off --json
|
|
```
|
|
|
|
## Agent habits
|
|
|
|
- Prefer `--json` for automation and agent calls.
|
|
- Prefer selectors over parsing UI labels.
|
|
- Read terminal state before sending input unless the next input is obvious.
|
|
- Use worktree comments for progress checkpoints. See [Worktree checkpoints](/docs/cli/worktree-checkpoints).
|
|
- Use [Orchestration](/docs/cli/orchestration) for tracked multi-agent dispatches instead of ad hoc terminal prompts.
|