orchestratr
referenceCLI reference

orcr agent

every orcr agent command (run, ask, send, logs, wait, attach, kill, ls) with its flags, behavior, and JSON result shape.

orcr agent spawns, messages, awaits, reads, and stops agents. paths and patterns follow the path grammar throughout: relative to the caller's scope, leading / for absolute, * and ** as the only wildcards (bulk verbs only), quote patterns in the shell.

orcr agent run    (--name <name> | --path <path>) [-a <provider>] [-p <prompt>]
                  [--gc auto|immediate|never] [--model <m>] [--effort <e>]
                  [--cwd <dir>] [--timeout <dur>] [--json]
orcr agent ask    (--name <name> | --path <path>) [-a <provider>] [-p <prompt>]
                  [--model <m>] [--effort <e>] [--cwd <dir>] [--timeout <dur>] [--json]
orcr agent send   <path|uuid> (<prompt> | -p <prompt>) [--json]
orcr agent logs   <path|uuid> [--last-response] [--tail <n>] [--follow] [--json]
orcr agent wait   <pattern|uuid>... [--timeout <dur>] [--json]
orcr agent attach <path|uuid> [--takeover]
orcr agent kill   <pattern|uuid>... [--force] [-y] [--json]
orcr agent ls     [<pattern|uuid>] [-a <provider>] [--status <s>]
                  [--managed|--unmanaged] [--all] [--json]

shared rules

naming is mandatory on run and ask: pass exactly one of --name <name> (the agent lands directly in your scope; the value is its name) or --path <path> (the last segment is the name, the rest is where it lives; relative to your scope, / for absolute). {rand} expands to 5 random lowercase alphanumeric characters anywhere in the value. there are no auto-generated agent names.

prompts: run and ask take -p/--prompt <text>; send takes the prompt as its positional argument (and also accepts -p). in all of them, -p - reads the prompt from stdin, which is the long-prompt escape hatch; there is no file flag.

provider: -a <provider> is optional on run, ask, and ls. it falls back to defaults.agent in config (default claude); precedence is CLI over config. the provider must have both integration layers installed or run fails with integration_missing (see providers and integrations).

run

async, always. run validates, enqueues, prints <path> <uuid> on one stdout line, and returns. the server processes the queue and manages the whole lifecycle. there is no blocking flag; request/response is run then wait then logs --last-response (one call in the SDK: ask()).

orcr agent run --path refactor/reviewer -a codex -p "Review the diff on this branch."
# → refactor/reviewer 018f3c…-…
  • --gc auto|immediate|never governs pane lifetime only, never store history. auto (default) parks then reaps on idle; immediate closes the pane after the first turn's final response is captured; never keeps it alive until an explicit kill. see lifecycle and GC.
  • --model <m> and --effort <e> map to the provider's model / reasoning-effort flags (empty means the provider default).
  • --cwd <dir> sets the pane's working directory (default: the caller's cwd).
  • --timeout <dur> kills the agent with exit_reason: timeout when it expires. there is no default timeout; without this flag an agent never times out.

on a TTY, run also prints a stderr hint with the follow-up commands (wait, logs --last-response, attach).

JSON result:

{
  "agent": {
    "uuid": "018f…", "path": "refactor/reviewer", "status": "queued",
    "agent": "codex", "managed": true, "cwd": "/repo",
    "data_dir": "/Users/you/.orcr/data/refactor/reviewer/018f…",
    "queue_position": 3, "parent_id": "…", "parent_path": "…"
  },
  "permissions": "bypass"
}

queue_position, parent_id, and parent_path are present only when they apply.

ask

the request/response one-liner, as a real verb. it is documented sugar for run --gc immediate then wait then logs --last-response, and nothing more: it spawns, blocks through the queue and the first completion, prints the final response on stdout, and cleans up the pane.

answer=$(orcr agent ask --name quick_check -a claude -p "Is this regex safe? …")

naming rules are identical to run, so parallel asks need distinct names (verify/check_1, verify/check_2). a blocked agent exits 4; no identifiable response is transcript_unavailable (exit 1).

JSON result: {uuid, path, response:{text, final}}. without --json, only the response text goes to stdout.

send

exact target only. send types the prompt into the agent's TUI and submits it, whatever status the agent is in; provider TUIs queue mid-turn input natively. it waits for delivery to be confirmed on the pane and returns success or failure. it confirms terminal delivery, not provider acceptance (see status and completion).

orcr agent send refactor/reviewer "Also check error handling in parser.rs."

sending to a parked agent un-parks it atomically, before delivery, and resets its GC clocks. an ended target returns not_found (exit 6).

JSON result: {uuid, path, delivered_while:"working|idle|blocked|parked", input_seq}. delivered_while is the agent's status at the moment of delivery.

logs

exact target. a bare path resolves to the active agent first, else the most recent ended one; history is addressed by uuid (from ls --all). logs reads the provider's native transcript through the integration's adapter (ordered turns, tool calls, token counts where available). orcr keeps no response copies.

orcr agent logs refactor/reviewer --tail 50 --follow
orcr agent logs refactor/reviewer --last-response
  • --tail <n> shows the last n entries.
  • --follow keeps streaming after that. --tail and --follow compose, the same as tail -n / tail -f.
  • --last-response prints only the final assistant message. it fails loudly rather than guessing: exit 1 transcript_unavailable when no final response is identifiable, exit 2 integration_missing when the provider has no orcr integration.

if a provider later rotates or deletes its transcript files, historical --last-response fails with transcript_unavailable rather than returning a stale copy.

JSON result: {uuid, path, resolved:"active|latest_ended", entries:[…]}, or with --last-response, {uuid, path, resolved, response:{text, final}}.

wait

targets are patterns and/or uuids. membership is the set of active agents matching any target, snapshotted at invocation; ended rows are never wait targets, and no match at all exits 6. there is no status flag. waiting has one meaning: block until every target settles.

orcr agent wait "refactor/**" --timeout 20m

a target settles at one of these points:

settle pointoutcome
turn complete (idle / parked; an already-complete agent settles immediately)success: the answer is ready
ended with exit_reason: completed or reapedsuccess: done
blockedneeds a human (exit 4)
ended any other way, or lostcut short / never ran (exit 5)

a queued agent is waited through promotion and its first turn. settle states can un-settle (a blocked agent gets a send, a parked one is revived, external input starts a new turn), so a multi-target wait returns only when all snapshotted targets are simultaneously settled at one event sequence (the decision_seq, included in the JSON). a target that un-settles discards its earlier reason and is waited on again, so the result is the actual state at decision time, not a stale reading.

the human-readable result is one line per agent, <path> <reason>, on every outcome:

refactor/phase_1/file_1  turn_complete
refactor/phase_1/review  blocked:question
refactor/phase_1/file_2  wait_timeout

the reason tokens map exhaustively from status × exit_reason; the full table with exit contributions is in the status model reference. exit codes: 0 every target settled successfully, 4 any target blocked, 5 any target dead, 3 the wait's --timeout expired, 6 no target matched.

wait is idempotent: targets already settled report immediately, so running it again returns the same listing at once.

JSON result:

{
  "targets": [
    { "uuid": "…", "path": "refactor/phase_1/file_1", "status": "idle",
      "ok": true, "reason": "turn_complete",
      "next": { "kind": "logs_last_response", "command": "orcr agent logs … --last-response" } }
  ],
  "all_ok": true, "timed_out": false, "decision_seq": 4821
}

next is structured from a stable enum (logs_last_response, attach, logs_history, none) and rendered as a command string by the CLI. on a wait --timeout, the envelope stays ok:true with timed_out:true and exit 3.

attach

exact target. this is the one terminal-mediated verb. the CLI calls agent.attach.prepare, which validates the target, inserts the attach lease first, then reads the pane locator under the same transaction (so GC can never move or reap between resolution and lease), and returns the exec command. the CLI then execs herdr agent attach locally, heartbeating the lease while it runs and releasing it on exit. if the pane moved between prepare and attach, the CLI refreshes once by terminal_id.

orcr agent attach refactor/reviewer            # observe
orcr agent attach refactor/reviewer --takeover  # claim input

observe is the default; --takeover claims input (typed input creates a synthetic external turn; see status and completion). queued or ended targets return state_conflict. attach has no --json; the SDK exposes prepareAttach(), which returns the command rather than a fake interactive method.

kill

targets are patterns and/or uuids. on a TTY, kill confirms by default: it shows every matched agent as a tree with a count, then asks. -y skips the prompt; non-interactive callers (no TTY, or --json) proceed.

orcr agent kill "refactor/**" -y

a matched managed agent gets the graceful per-integration shutdown recipe (shutdown_grace_ms), then its pane is closed so herdr can clear empty tabs and workspaces. its status ends ended (exit_reason: killed); history remains. queued agents are dequeued (canceled); starting agents are canceled via the cancel_requested interlock. unmanaged targets require --force (killing a pane orcr does not own).

result classification:

  • no matched targets → exit 6.
  • matched but every target skipped (already ended, or needs --force) → exit 7.
  • any kills performed → exit 0.

JSON result: {killed:[{uuid,path}], skipped:[{uuid,path,reason:"ended|force_required|…"}], all_killed:bool}.

ls

active agents (managed and unmanaged) as a flat table sorted by path: ancestors before descendants, grouped by level-1 segment, so it reads in tree order and stays greppable. the indented tree view is orcr top.

orcr agent ls --status blocked          # who needs a human
orcr agent ls "review/**" --managed --json
orcr agent ls --all                     # include ended history

filters: a pattern or uuid, -a <provider>, --status <s>, --managed / --unmanaged, --all (include ended agents: full history, including every past loop run; reused paths are disambiguated by uuid and created_at). TTY columns are PATH UUID STATUS AGENT AGE (uuid shown as a short prefix).

JSON rows are flat:

{
  "uuid": "…", "path": "…", "status": "working", "managed": true,
  "agent": "claude", "cwd": "/repo", "pane_id": "w8:p1",
  "queue_position": 2, "parent_id": "…", "parent_path": "…",
  "blocked_kind": "question", "created_at": "…", "ended_at": "…", "exit_reason": "…"
}

optional fields appear only when they apply. see the status model reference for the status and blocked_kind vocabularies.

On this page