# Selectors and JSON output

> Global CLI flags (`--json`, `--help`, `--pairing-code`, `--environment`), worktree/repo selector grammar (`id:`, `path:`, `branch:`, `active`), JSON error shapes, and remote-runtime resolution rules.

- 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/args.ts`
- `src/cli/selectors.ts`
- `src/cli/format.ts`
- `src/cli/runtime-client.ts`
- `src/shared/runtime-rpc-envelope.ts`
- `src/cli/index.test.ts`

---

---
title: "Selectors and JSON output"
description: "Global CLI flags (`--json`, `--help`, `--pairing-code`, `--environment`), worktree/repo selector grammar (`id:`, `path:`, `branch:`, `active`), JSON error shapes, and remote-runtime resolution rules."
---

The `orca` CLI parses global flags and typed selectors in `src/cli/args.ts` and `src/cli/selectors.ts`, resolves worktrees against the runtime RPC in `src/main/runtime/orca-runtime.ts`, and prints either human text or a shared RPC envelope (`src/shared/runtime-rpc-envelope.ts`) controlled by `--json`.

## Global flags

Four flags are global across command groups (`GLOBAL_FLAGS` in `src/cli/args.ts`). Each command’s `allowedFlags` in `src/cli/specs/` must include them explicitly; unknown flags fail validation before any runtime connection.

| Flag | Type | Role |
|------|------|------|
| `--help` | boolean | Print help for the current command path, or `orca help <command>` |
| `--json` | boolean | Emit machine-readable JSON on stdout for success and failure |
| `--pairing-code` | string | Connect to a remote runtime via `orca://pair#...` or bare pairing payload |
| `--environment` | string | Connect using a saved environment id or name from `orca-environments.json` |

<ParamField body="--pairing-code" type="string">
One-time remote pairing. Parsed by `parsePairingCode` in `src/shared/pairing.ts`. Also available as `ORCA_PAIRING_CODE` or `ORCA_REMOTE_PAIRING` when the flag is omitted.
</ParamField>

<ParamField body="--environment" type="string">
Saved remote target. Resolved from the Orca user-data store (`orca-environments.json`). Also available as `ORCA_ENVIRONMENT` when the flag is omitted.
</ParamField>

<Warning>
`--pairing-code` and `--environment` are mutually exclusive. Combining them throws `invalid_argument` before RPC calls.
</Warning>

### Commands that ignore remote selection

`orca environment`, `orca serve`, and `orca agent hooks` pass `null` into `RuntimeClient` so env-var fallbacks for pairing/environment do not apply. Environment management and headless `serve` always run against local user data even when `ORCA_ENVIRONMENT` is set.

### Flag parsing rules

`parseArgs` treats tokens starting with `--` as flags:

- `--flag=value` assigns the substring after `=` (required when the value itself starts with `--`, e.g. `--text=--help`).
- `--flag value` consumes the next token unless it also starts with `--`, in which case the flag becomes boolean `true`.
- Positional arguments that share names with declared positional flags (e.g. `orca automations show auto-1`) are normalized into flags; supplying both positional and `--flag` forms is an `invalid_argument` error.

## Remote runtime resolution

Remote mode is active when `RuntimeClient` holds a non-null pairing offer (`isRemote === true`). Resolution order in `resolveRemotePairing`:

1. Reject if both `--pairing-code` and `--environment` are set.
2. If `--environment` (or `ORCA_ENVIRONMENT`): load pairing offer from the saved environment store.
3. Else if `--pairing-code` (or `ORCA_PAIRING_CODE` / `ORCA_REMOTE_PAIRING`): `parsePairingCode`; invalid codes yield `invalid_argument`.
4. Else: local mode — Unix domain socket / local metadata from user data.

```mermaid
sequenceDiagram
  participant CLI as orca CLI
  participant RC as RuntimeClient
  participant Store as orca-environments.json
  participant RT as Remote runtime

  CLI->>RC: new RuntimeClient(flags / env)
  alt --environment
    RC->>Store: resolveEnvironmentPairingOffer
    Store-->>RC: PairingOffer
  else --pairing-code / env var
    RC->>RC: parsePairingCode
  else local
    RC->>RC: readMetadata (local socket)
  end
  RC->>RT: WebSocket RPC (non-status.get)
  Note over RC,RT: status.get checks protocol compatibility first
```

After connect, non-`status.get` calls run `ensureRemoteRuntimeCompatible` once per client: protocol versions must pass `evaluateRuntimeCompat` or the CLI throws `incompatible_runtime`. Successful RPCs with `--environment` update `lastUsedAt` / `runtimeId` on the saved record.

### Environment selectors (saved runtimes)

Separate from worktree/repo selectors. `resolveEnvironmentFromStore` matches:

| Input | Match |
|-------|--------|
| Exact `id` | Single environment |
| `name` | Unique name match |
| Duplicate names | `invalid_argument` — use id |
| No match | `Unknown environment: …` |

`environment list` / `show` / `add` / `rm` redact `deviceToken` and `publicKeyB64` from JSON and text output via `redactRuntimeEnvironment`.

## Worktree and repo selectors

Runtime resolution lives in `OrcaRuntimeService.resolveWorktreeSelector` and `resolveRepoSelector`. The CLI may rewrite selectors before RPC (especially `active` / `current`).

### Worktree selector grammar

| Form | Runtime behavior |
|------|------------------|
| `id:<worktreeId>` | Exact worktree id (format `repoId::<absolute-path>`, separator `::`) |
| `path:<absolute-path>` | Path equality (normalized); if multiple repo registrations share the same git path, **first** candidate wins |
| `branch:<ref>` | Branch match via `branchSelectorMatches` (`refs/heads/foo` and `foo` equivalent) |
| `issue:<number>` | `linkedIssue` string match |
| Bare string | Tries id, then path, then branch |
| `active` (unresolved) | Runtime throws `selector_not_found` — CLI must resolve first |

<Note>
`active` and `current` are CLI-only shortcuts. They are **not** valid on the wire as literal `active` selectors.
</Note>

#### Local `active` / `current` resolution

On a **local** runtime only:

1. `worktree.list` with `limit: 10000`.
2. Find Orca-managed worktrees whose path encloses `process.cwd()` (longest path wins).
3. Rewrite to `id:<enclosingWorktree.id>` before RPC.

`normalizeWorktreeSelector('active', cwd)` without listing maps to `path:<resolved cwd>`; full resolution to `id:` happens in `resolveCurrentWorktreeSelector`.

On a **remote** runtime, `active` / `current` throw `invalid_argument` immediately — the client cwd is not on the server. Use explicit server-side selectors: `id:`, `branch:`, `issue:`, or `path:` with an **absolute server path**.

### Repo selector grammar

| Form | Runtime behavior |
|------|------------------|
| `id:<repoId>` | Exact registered repo id |
| `path:<path>` | Registered repo root path (normalized) |
| `name:<displayName>` | Exact display name |
| Bare string | Tries id, then path, then display name |

Ambiguous bare or typed matches → `selector_ambiguous`. No match → `repo_not_found` (repos) or `selector_not_found` (worktrees).

### Default worktree targeting (CLI)

| Context | Local default | Remote default |
|---------|---------------|----------------|
| `--worktree` omitted (browser, many terminals) | Resolve enclosing worktree from cwd; if none, omit filter | `undefined` — runtime uses server-side focus |
| `--worktree all` | No worktree filter | Same |
| `terminal create` | Auto-resolve from cwd | **Requires** explicit `--worktree` |
| `file` commands | Auto-resolve from cwd | **Requires** explicit `--worktree` |
| `repo add --path` | Resolve relative paths against CLI cwd | Path must be **absolute on the server** (`/`, `C:\`, `\\`, `//`) |

### Terminal handles

`--terminal <handle>` is not a selector prefix grammar item. Handles are opaque runtime-issued strings (from `orca terminal list --json`). When omitted, `getTerminalHandle` calls `terminal.resolveActive` in the resolved worktree context.

## JSON output

### Success responses

With `--json`, `printResult` writes pretty-printed JSON of the full RPC success envelope:

<ResponseField name="envelope" type="RuntimeRpcSuccess">
  <ResponseField name="id" type="string">Request id (e.g. RPC id or `local` for purely local handlers)</ResponseField>
  <ResponseField name="ok" type="true">Always `true`</ResponseField>
  <ResponseField name="result" type="object">Command-specific payload</ResponseField>
  <ResponseField name="_meta.runtimeId" type="string">Runtime that served the call; `local` for environment store commands</ResponseField>
</ResponseField>

Computer-use snapshots with base64 screenshot data: JSON replaces inline `data` with a temp file path under `$TMPDIR/orca-computer-use/`, sets `dataOmitted: true`, and adds `expiresAt` (24h TTL).

### Error responses

`reportCliError` always prints JSON to **stdout** when `--json` is set (stderr is used for human text mode). Exit code is set to `1`.

**Runtime RPC failure** — passthrough of the server envelope:

<RequestExample>
```json
{
  "id": "req_1",
  "ok": false,
  "error": {
    "code": "selector_not_found",
    "message": "selector_not_found"
  },
  "_meta": {
    "runtimeId": "runtime-1"
  }
}
```
</RequestExample>

**Local CLI errors** (`RuntimeClientError`, validation, selector preflight) — synthesized envelope:

<RequestExample>
```json
{
  "id": "local",
  "ok": false,
  "error": {
    "code": "invalid_argument",
    "message": "Remote terminal create requires --worktree because the client cwd cannot identify a server worktree."
  },
  "_meta": {
    "runtimeId": null
  }
}
```
</RequestExample>

| `error.code` (common) | Origin |
|------------------------|--------|
| `invalid_argument` | CLI validation, flag conflicts, remote preflight |
| `runtime_unavailable` | Local runtime not reachable; human mode appends “Run `orca open` first.” |
| `runtime_error` | Unclassified local errors |
| `incompatible_runtime` | Remote protocol version mismatch |
| `selector_not_found` | Runtime: no matching worktree/repo |
| `selector_ambiguous` | Runtime: multiple matches |
| `repo_not_found` | Runtime: repo selector miss |
| `LINEAGE_*` | Lineage errors; may include `error.data.nextSteps[]` |

Structured `error.data.nextSteps` (string array) is rendered in **human** mode as `Next step: …` lines under the message; JSON mode returns the raw `data` object on RPC failures.

### Runtime passthrough codes

The RPC error mapper in `src/main/runtime/rpc/errors.ts` forwards these codes unchanged to the CLI (message often equals code): `runtime_unavailable`, `selector_not_found`, `selector_ambiguous`, `terminal_handle_stale`, `terminal_not_writable`, `terminal_exited`, `terminal_gone`, `no_active_terminal`, `repo_not_found`, `timeout`, `invalid_limit`, plus computer-use codes and `LINEAGE_*` with optional `data`.

### Keepalive frames

WebSocket transports may emit `{ "_keepalive": true }` between request/response frames. These are not CLI output; they are stripped by envelope parsing (`RuntimeRpcEnvelopeSchema`).

## Selector resolution flow (runtime)

```text
selector string
    |
    +-- id:     --> filter worktrees/repos by id
    +-- path:   --> filter by normalized path (worktree: dedupe to first if >1)
    +-- branch: --> branchSelectorMatches
    +-- issue:  --> linkedIssue match (worktree only)
    +-- name:   --> displayName (repo only)
    +-- bare    --> try id, path, branch/displayName
    |
    v
  0 matches --> selector_not_found / repo_not_found
  1 match   --> resolved record
  2+ matches --> selector_ambiguous
```

## Scripting patterns

<Steps>
<Step title="Discover ids in JSON">
Run list commands with `--json`, read stable ids from `result` (e.g. `worktrees[].id`, `repos[].id`, `terminals[].handle`).
</Step>
<Step title="Pin targets with typed selectors">
Prefer `id:repo-1::/srv/orca/feature` on remote hosts; avoid `active`/`current` over SSH or pairing.
</Step>
<Step title="Parse failures structurally">
Check `ok === false`, branch on `error.code`, read `error.data.nextSteps` when present.
</Step>
</Steps>

<CodeGroup>
```bash title="Local worktree from cwd"
orca worktree current --json
```

```bash title="Remote explicit worktree"
orca terminal list \
  --worktree 'id:repo-1::/srv/orca/feature' \
  --environment desk \
  --json
```

```bash title="Saved environment by name"
orca status --environment 'work-laptop' --json
```
</CodeGroup>

<Tip>
Command validation runs before runtime lookup, so typos in subcommands or disallowed flags surface as `invalid_argument` instead of `runtime_unavailable`.
</Tip>

## Related pages

<CardGroup>
<Card title="CLI core reference" href="/cli-core-reference">
Command groups, per-command flags, and handler entry points beyond global options.
</Card>
<Card title="Runtime environments" href="/runtime-environments">
Headless `orca serve`, pairing codes, and saving environments targeted by `--environment`.
</Card>
<Card title="Worktrees and repos" href="/worktrees-and-repos">
Create/list/remove semantics that consume worktree and repo selectors.
</Card>
<Card title="SSH remote worktrees" href="/ssh-remote-worktrees">
SSH relay constraints that compound remote selector rules.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Selector ambiguity, runtime reachability, and remote CLI failure modes.
</Card>
</CardGroup>
