orchestratr
guides

run and manage agents

the orcr agent verb set for everyday work: run, ask, send, logs, wait, ls, and kill.

orcr agent is the CLI surface for spawning agents, reading their output, steering them, and stopping them. every verb here is a thin client of one socket method, and every one takes --json (a single envelope object on stdout, logs on stderr). this page covers the whole set except attach, which has its own page: steer and attach to a running agent.

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]

two contracts apply across all of them. durations always carry units (45s, 20m, 3h). destructive verbs confirm on a TTY; details are under kill.

targets follow one path model everywhere: a path is relative to your scope unless it starts with /; * matches one whole segment and ** matches any depth; quote patterns in the shell so it does not expand them against real files. <path|uuid> accepts an exact path or a uuid prefix; <pattern|uuid> also accepts */** wildcards and is only allowed on the bulk verbs (wait, kill, ls). the exact-target verbs (send, logs, attach) reject wildcards. the full grammar lives in identity: paths and uuids and the path grammar reference.

naming is mandatory

every agent-creating verb (run and ask) requires exactly one of:

  • --name <name>: one segment; the agent lands directly in your scope.
  • --path <path>: the last segment is the name, the rest is where it lives (relative to your scope, / for absolute).

there are no auto-generated agent names. anywhere in a --name or --path value, {rand} is replaced with a random 5-character lowercase string before validation, so --path "review_{rand}/file_1" yields a fresh root each run. {rand} works on creation only, never in a selector.

prompts

run takes the prompt with -p/--prompt <text>. send takes it as a positional argument and also accepts -p. in both, -p - reads the prompt from stdin, the escape hatch for long prompts (there is no file flag).

# inline
orcr agent run --name reviewer -a codex -p "Review src/auth.ts for auth bugs. Say DONE."

# from stdin
cat prompt.txt | orcr agent run --name reviewer -a codex -p -

prompts are plain text. if a step needs files attached or a guaranteed-format answer, say so in the prompt and use the data-dir file convention (see data and file conventions).

shared flags

  • -a <provider>: the provider (also the filter on ls). optional; falls back to defaults.agent in config (default claude). precedence is CLI over config. see choose providers and models.
  • --model <m> / --effort <e>: provider-specific model and reasoning-effort mapping; empty means the provider default.
  • --cwd <dir>: the working directory of the agent's pane. defaults to the caller's cwd.
  • --timeout <dur>: kill the agent with exit_reason: timeout when the duration expires. there is no default timeout; an agent never times out unless you pass this. set it on anything unattended.
  • --gc auto|immediate|never: pane lifetime policy (run only). see agent lifecycle and GC.

run: spawn asynchronously

run is always async. it validates, enqueues the agent, prints <path> <uuid> on one space-separated stdout line, and returns. the agent then moves through the queue and starts on its own.

$ orcr agent run --name reviewer -a codex -p "Review src/auth.ts. Say DONE."
reviewer 0192f8a1-7c3e-7abc-9def-0123456789ab

on a TTY, run also prints a stderr hint with the follow-up commands (wait, logs --last-response, attach). there is no blocking flag: request/response is run then wait then logs --last-response, which the SDK collapses into one ask() call. the --json result carries both fields plus placement:

{
  "agent": {
    "uuid": "0192f8a1-7c3e-7abc-9def-0123456789ab",
    "path": "reviewer",
    "status": "queued",
    "agent": "codex",
    "managed": true,
    "cwd": "/repo",
    "data_dir": "/home/you/.orcr/data/reviewer/0192f8a1-.../",
    "queue_position": 3
  },
  "permissions": "bypass"
}

ask: the request/response one-liner

ask is documented sugar: exactly run --gc immediate, then wait, then logs --last-response. it spawns, blocks through the queue and the first completion, prints the final response on stdout, and cleans up the pane. any language gets the three-step dance in one call without the SDK.

$ orcr agent ask --name quick_check -a claude -p 'Is foo() in src/x.ts pure? One word.'
yes

naming rules match run, so parallel asks need distinct names (verify/check_1, verify/check_2). a blocked agent exits 4; no identifiable response fails with transcript_unavailable. the --json result is {uuid, path, response:{text, final}}.

send: deliver a follow-up prompt

send targets one active agent (no wildcards). it types the prompt into the agent's TUI and submits, whatever status the agent is in; provider TUIs queue mid-turn input natively. it waits for the pane to confirm delivery, then reports the agent's status at delivery and the resulting input sequence:

{ "uuid": "...", "path": "reviewer", "delivered_while": "idle", "input_seq": 2 }

sending to a parked agent un-parks it atomically before delivery. an ended target fails with not_found (exit 6). steering a live agent mid-turn is covered in depth in steer and attach to a running agent.

logs: read the native transcript

logs reads the provider's native transcript through the integration's adapter (structured turns, tool calls, token counts where the provider records them). a bare path resolves to the active agent first, else the most recent ended one; address a specific historical agent by uuid (from ls --all).

orcr agent logs reviewer --last-response   # only the final assistant message
orcr agent logs reviewer --tail 50         # the last 50 entries
orcr agent logs reviewer --tail 50 --follow # tail then keep streaming

--tail <n> and --follow compose the same way as tail -n and tail -f. --last-response 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. orcr never copies responses anywhere; if a provider later rotates or deletes its transcript files, historical --last-response fails with transcript_unavailable rather than returning a stale copy.

wait: block until targets settle

wait takes 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. waiting has one meaning: block until every target reaches a point where the caller can or must act.

settle pointoutcome
turn complete (idle / parked)success: the answer is ready
ended with completed or reapedsuccess: finished work, pane closed or tidied
blockedneeds a human (exit 4)
ended any other way, or lostcut short or 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 in the JSON). a target that un-settles discards its earlier reason and is waited on again, so the result is the state at decision time, not a stale reading.

the output is always one line per agent, <path> <reason>, whether you waited on one agent or a subtree:

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 and exit_reason:

observedreason tokenokexit
idle / parkedturn_completeyes0
ended + completedcompletedyes0
ended + reapedreapedyes0
blockedblocked:question|limit|login|unknownno4
ended + killed / canceled / failedsame tokenno5
ended + timeouttimeoutno5
ended + lost / status lost confirmedlostno5
unsettled when the wait's --timeout expireswait_timeoutno3

wait is idempotent: targets already settled report immediately, so running it again returns the same listing at once. every target is listed on every outcome, including a timed-out wait, where settled targets show their real reason and unsettled ones show wait_timeout.

when a wait's own --timeout expires, the envelope is still ok:true with timed_out:true and exit 3; the call succeeded, the result is partial. the timeout error code is reserved for an agent's own --timeout expiring.

the --json result carries {uuid, path, status, ok, reason, exit_reason?, next} per target, plus all_ok, timed_out, and decision_seq. next is structured ({kind, command} from a stable enum: logs_last_response, attach, logs_history, none), rendered as a command string by the CLI.

ls: list active agents

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

orcr agent ls                       # everything active
orcr agent ls "review/**"           # a subtree
orcr agent ls --status blocked      # who needs a human
orcr agent ls --unmanaged           # agents you started by hand
orcr agent ls --all                 # include ended history (paths disambiguated by uuid)

TTY columns are PATH UUID STATUS AGENT AGE (uuid shown as a short prefix). filters: a pattern or uuid, -a <provider>, --status <s>, --managed/--unmanaged, and --all (include ended agents, including every past loop run). JSON rows are flat: {uuid, path, status, managed, agent, cwd, pane_id, queue_position?, parent_id?, parent_path?, blocked_kind?, created_at, ended_at?, exit_reason?}.

kill: stop agents

kill takes patterns and/or uuids. on a TTY it confirms by default, showing every matched agent as a tree with a count before asking; -y/--yes skips the prompt, and non-interactive callers (no TTY, or --json) proceed without prompting.

orcr agent kill reviewer                 # confirms on a TTY
orcr agent kill "review/**" -y           # kill a subtree, no prompt (quote the pattern)
orcr agent kill review "review/**" -y     # the agent named review AND its subtree

kill runs the per-integration graceful shutdown recipe, then closes the pane so herdr can clear the empty tab and workspace. the row ends ended with exit_reason: killed; history remains. queued agents are dequeued (canceled); a starting agent is canceled through the internal cancel_requested interlock.

killing an unmanaged agent closes a pane orcr does not own, so it requires --force. without it, unmanaged targets are skipped.

result classification: no matched targets exits 6; matched but every target skipped (already ended, or needs --force) exits 7; any kills performed exits 0 with killed[], skipped[{uuid, path, reason}], and all_killed.

exit codes

codemeaning
0ok (including wait: every target settled successfully)
1other (invalid_request, transcript_unavailable, server_error)
2environment (integration_missing, environment_error)
3timeout (an agent's own --timeout, or a wait's --timeout)
4blocked (an agent needs a human)
5killed / ended (a wait target died)
6not found
7state conflict (wrong state; force_required for unmanaged kills)

next

On this page