# CLI scripting workflow

> End-to-end agent automation with `orca open`, `orca status`, repo/worktree discovery, terminal read/send/wait, file open helpers, and worktree comment updates at checkpoints.

- Repository: stablyai/orca
- GitHub: https://github.com/stablyai/orca
- Human docs: https://grok-wiki.com/public/docs/stablyai-orca-2036d532bf1c
- Complete Markdown: https://grok-wiki.com/public/docs/stablyai-orca-2036d532bf1c/llms-full.txt

## Source Files

- `src/cli/index.ts`
- `src/cli/dispatch.ts`
- `src/cli/runtime-client.ts`
- `src/cli/specs/core.ts`
- `src/cli/specs/file.ts`
- `src/cli/help.ts`
- `skills/orca-cli/SKILL.md`

---

---
title: "CLI scripting workflow"
description: "End-to-end agent automation with `orca open`, `orca status`, repo/worktree discovery, terminal read/send/wait, file open helpers, and worktree comment updates at checkpoints."
---

The `orca` command-line interface is a Node entrypoint (`src/cli/index.ts`) that parses argv, validates command specs before any runtime lookup, constructs a `RuntimeClient`, and dispatches to thin handlers that call Orca runtime RPC methods over local metadata transport or a paired remote WebSocket. Scripting workflows treat Orca as the source of truth for repos, worktrees, terminals, and editor tabs—use `--json` for machine-driven loops and selectors plus runtime-issued terminal handles for repeated live I/O.

## Preconditions

| Requirement | Verification |
| --- | --- |
| Public CLI on `PATH` | `command -v orca` (macOS/Windows); Linux installs expose `orca` via `resources/linux/bin/orca` while the desktop binary is `orca-ide` to avoid the GNOME Orca screen reader |
| Running runtime | `orca status --json` → `result.runtime.reachable: true` |
| Machine output | Pass `--json` on every scripted call |

<Note>
On Linux, substitute `orca-ide` only when referring to the desktop app binary. The scripting command name remains `orca` for the packaged launcher symlink.
</Note>

Remote runtimes accept `--pairing-code` or `--environment` (or `ORCA_PAIRING_CODE` / `ORCA_ENVIRONMENT`). `active` and `current` worktree selectors resolve from the client machine `cwd` and are invalid against a remote runtime—use explicit server-side selectors such as `id:<id>`, `branch:<branch>`, `issue:<number>`, or `path:<absolute-server-path>`.

## Control-plane flow

```mermaid
sequenceDiagram
  participant Agent as Script / agent
  participant CLI as src/cli/index.ts
  participant RC as RuntimeClient
  participant RT as Orca runtime RPC

  Agent->>CLI: orca &lt;command&gt; [--json]
  CLI->>CLI: validateCommandAndFlags
  CLI->>RC: new RuntimeClient(pairing, environment)
  alt Local desktop runtime
    RC->>RT: sendRequest(metadata, method, params)
  else Remote paired runtime
    RC->>RT: sendWebSocketRequest(pairing, method, params)
  end
  RT-->>RC: RuntimeRpcSuccess / failure
  RC-->>CLI: result
  CLI-->>Agent: human text or JSON (prepareCliJsonResult)
```

Syntax and flag errors are reported before runtime contact so typos do not surface as false “Orca is not running” messages.

## Startup and health

### `orca open`

Launches Orca when the runtime is unreachable: `open` calls `RuntimeClient.openOrca()`, which reads status, invokes `launchOrcaApp()` if needed, then polls `getCliStatus()` every 250 ms until `runtime.reachable` or a 15 s timeout (`runtime_open_timeout`). Override launch with `ORCA_OPEN_COMMAND` or `ORCA_APP_EXECUTABLE`.

<RequestExample>

```bash
orca open --json
```

</RequestExample>

### `orca status`

Returns app PID, runtime state, reachability, runtime id, and graph state (`CliStatusResult`). In human mode, `status` sets exit code `1` when `runtime.reachable` is false. JSON mode always prints the structured payload; callers inspect `result.runtime.reachable`.

<RequestExample>

```bash
orca status --json
```

</RequestExample>

<Warning>
When the runtime is down, human-mode errors append `Run 'orca open' first.` JSON failures use `RuntimeRpcFailure` or local `RuntimeClientError` shapes from `reportCliError`.
</Warning>

Headless automation without a desktop window uses `orca serve` (foreground runtime server). Pairing and saved environments are covered on the runtime environments page.

## Discovery: repos and worktrees

Use selectors for identity and handles for live terminals.

### Repo selectors

| Form | Example |
| --- | --- |
| `id:<repoId>` | `id:repo-abc` |
| `name:<name>` | `name:orca` |
| `path:<absolute-path>` | `path:/Users/me/projects/orca` |

```bash
orca repo list --json
orca repo show --repo id:<repoId> --json
orca repo add --path /abs/repo --json
```

### Worktree selectors

| Form | Resolves |
| --- | --- |
| `id:<worktreeId>` | Stable runtime id (preferred after `worktree current`) |
| `path:<absolute-path>` | Filesystem path |
| `branch:<branch-name>` | Git branch |
| `issue:<number>` | Linked issue number |
| `active` / `current` | Enclosing Orca-managed worktree from shell `cwd` (local only) |

```bash
orca worktree ps --json          # compact cross-worktree summary
orca worktree list --json
orca worktree current --json     # cwd → id:… via worktree.list + path match
orca worktree show --worktree branch:feature-x --json
```

`worktree ps` rows include repo, branch, live terminal count, PTY attachment, unread flag, path, and optional preview—useful as the first map when many workspaces exist.

### Create and metadata

```bash
orca worktree create \
  --repo id:<repoId> \
  --name my-task \
  --issue 123 \
  --comment "seed" \
  --json

orca worktree set --worktree active --comment "reproduced auth failure; running integration tests" --json
```

`worktree create` infers parent lineage from `ORCA_TERMINAL_HANDLE`, caller `cwd`, or `--parent-worktree`. Use `--no-parent` for independent work. `--activate` reveals the workspace in the UI; `--run-hooks` forces setup hooks and implies activation.

<Tip>
Treat `orca worktree set --worktree active --comment "…" --json` as a best-effort checkpoint whenever work inside an Orca-managed tree reaches a meaningful state (repro found, fix landed, blocked on review). Skip trivial command noise; write short status snapshots.
</Tip>

## Terminal scripting loop

Terminals are runtime-scoped. After Orca reloads, handles may return `terminal_handle_stale`—re-list and adopt a fresh handle.

### Resolve a handle

```bash
orca terminal list --worktree id:<worktreeId> --json
# → terminals[].handle, preview, connected, worktreePath
```

Omit `--terminal` to target the **active** terminal in the current (or `--worktree`) scope via `terminal.resolveActive`.

### Read → act → wait → read

<Steps>
<Step title="Baseline transcript">

```bash
orca terminal read --terminal term_abc --json
```

Default read returns a bounded tail plus cursor fields: `nextCursor`, `oldestCursor`, `latestCursor`, `limited`, `truncated`.

</Step>
<Step title="Send input (non-agent shells)">

```bash
orca terminal send --terminal term_abc --text "pnpm test" --enter --json
```

`--interrupt` sends interrupt-style input when supported. Use `terminal send` for shell/build commands—not for agent-to-agent messaging (see orchestration).

</Step>
<Step title="Wait for completion">

```bash
orca terminal wait --terminal term_abc --for exit --timeout-ms 600000 --json
```

`--for tui-idle` waits for recognized agent TUIs (OSC title working→idle). Unsatisfied waits set exit code `1` even in JSON mode. Client RPC timeout extends to `timeoutMs + 5000` (minimum five-minute cap) so long waits are not cut off at the default 60 s transport limit.

</Step>
<Step title="Page retained output">

After a limited tail, page from `oldestCursor`:

```bash
orca terminal read --terminal term_abc --cursor 0 --limit 1000 --json
```

Continue with `nextCursor` while `limited` is true and `nextCursor !== latestCursor`. If `truncated` is true, older lines left the retained buffer.

</Step>
</Steps>

### Create and boot agent terminals

```bash
orca terminal create --worktree active --title "Agent" --command "claude" --json
orca terminal wait --terminal term_new --for tui-idle --timeout-ms 120000 --json
```

Local interactive agent commands (`codex`, `claude`, etc.) may use the renderer-backed terminal path for correct geometry. `terminal create` stays in the background unless `--focus` is passed. Remote `terminal create` requires an explicit `--worktree` because client `cwd` does not identify a server worktree.

## File helpers

Paths are relative to the selected worktree. Without `--worktree`, local commands infer the enclosing worktree from `cwd`; remote commands require `--worktree`.

```bash
orca file open src/App.tsx --json
orca file diff src/App.tsx --staged --json
orca file open-changed --mode diff --worktree active --json
```

`file open-changed` loads `git.status` for the worktree, then opens targets per `--mode`:

| Mode | Behavior |
| --- | --- |
| `diff` (default) | Opens unstaged/staged diffs; skips unresolved conflicts without a single diff target |
| `edit` | Opens modified/untracked files; skips deleted paths |
| `both` | Edit plus diff where applicable |

## Example end-to-end script

```bash
#!/usr/bin/env bash
set -euo pipefail

command -v orca >/dev/null

orca open --json >/dev/null
orca status --json | jq -e '.result.runtime.reachable' >/dev/null

WT=$(orca worktree current --json | jq -r '.result.worktree.id')
orca worktree set --worktree "id:${WT}" --comment "script: starting test run" --json >/dev/null

HANDLE=$(orca terminal list --worktree "id:${WT}" --json \
  | jq -r '.result.terminals[0].handle')

CURSOR=$(orca terminal read --terminal "$HANDLE" --json | jq -r '.result.terminal.nextCursor')

orca terminal send --terminal "$HANDLE" --text "pnpm test" --enter --json
orca terminal wait --terminal "$HANDLE" --for exit --timeout-ms 900000 --json

orca terminal read --terminal "$HANDLE" --cursor "$CURSOR" --limit 2000 --json \
  | jq -r '.result.terminal.tail[]'

orca worktree set --worktree "id:${WT}" --comment "script: tests finished" --json
```

## Global flags and JSON shape

<ParamField body="json" type="boolean">
Emit `RuntimeRpcSuccess` JSON (`ok`, `result`, `_meta`) via `prepareCliJsonResult`. Failures print a failure object when `ok: false`.
</ParamField>

<ParamField body="pairing-code" type="string">
Connect to a remote runtime with an `orca://pair#…` code. Mutually exclusive with `--environment`. Suppressed for `environment` and `serve` command groups.
</ParamField>

<ParamField body="environment" type="string">
Connect using a saved environment id or name from `orca environment list`.
</ParamField>

Human `status` output fields: `appRunning`, `pid`, `runtimeState`, `runtimeReachable`, `runtimeId`, `graphState`.

## Agent vs orchestration boundary

| Surface | Use for |
| --- | --- |
| `orca terminal read` / `wait` | Observe any Orca-managed terminal, including agent TUIs |
| `orca terminal send` | Shell commands, builds, prompts typed into **non-agent** PTYs |
| `orca orchestration send` / `check` / `reply` | Structured agent-to-agent messages, task DAGs, coordinator loops (experimental; requires runtime) |

Reading and waiting stay in the terminal CLI; messaging another coding agent belongs in orchestration.

## Common failure modes

| Code / signal | Meaning | Recovery |
| --- | --- | --- |
| `runtime_unavailable` | No reachable runtime | `orca open`, or start `orca serve` / desktop app |
| `runtime_open_timeout` | Launch poll exceeded 15 s | Start Orca manually; check `ORCA_OPEN_COMMAND` |
| `selector_not_found` | No worktree contains `cwd` | `orca worktree list`; create or `cd` into a managed tree |
| `terminal_handle_stale` | Handle invalid after reload | `orca terminal list --json` and re-select |
| `wait.satisfied: false` | Timeout or idle not detected | Increase `--timeout-ms`; re-read transcript |
| Exit code `1` on `status` | Human mode, runtime down | Use `--json` and branch on `reachable` |

<Info>
Flag validation runs in `index.ts` before `RuntimeClient` construction. Unknown commands fail with `invalid_argument` from dispatch, not from the runtime.
</Info>

## Command map (scripting-focused)

| Group | Commands |
| --- | --- |
| Startup | `open`, `status`, `serve` |
| Repo | `repo list`, `add`, `show`, `set-base-ref`, `search-refs` |
| Worktree | `worktree list`, `show`, `current`, `create`, `set`, `rm`, `ps` |
| Terminal | `terminal list`, `show`, `read`, `send`, `wait`, `stop`, `create`, `split`, `switch`, `close`, `rename` |
| File | `file open`, `diff`, `open-changed` |

Handler registration lives in `src/cli/dispatch.ts` (`CORE_HANDLERS`, `WORKTREE_HANDLERS`, `TERMINAL_HANDLERS`, `FILE_HANDLERS`). Command grammar and examples are defined in `src/cli/specs/core.ts`, `src/cli/specs/file.ts`, and `src/cli/help.ts`. Agent-oriented conventions are summarized in `skills/orca-cli/SKILL.md`.

## Related pages

<CardGroup>
<Card title="CLI core reference" href="/cli-core-reference">
Flags and signatures for `open`, `status`, `repo`, `worktree`, `terminal`, and `file` command groups.
</Card>
<Card title="Selectors and JSON output" href="/selectors-json-output">
Selector grammar, `--json` shapes, and remote-runtime resolution rules.
</Card>
<Card title="Terminals and agents" href="/terminals-and-agents">
PTY lifecycle, agent detection, `ORCA_*` env injection, and when to prefer orchestration messaging.
</Card>
<Card title="Worktrees and repos" href="/worktrees-and-repos">
Worktree create/remove semantics, lineage, sparse checkout, and workspace statuses.
</Card>
<Card title="Runtime environments" href="/runtime-environments">
Headless `orca serve`, pairing codes, and `--environment` targeting.
</Card>
<Card title="Agent orchestration" href="/agent-orchestration">
Multi-agent `send` / `check` / `reply`, task DAGs, and coordinator `run`.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Runtime reachability, stale handles, wait timeouts, and remote selector constraints.
</Card>
</CardGroup>
