arbiter --send

One-shot, non-interactive invocation. Sends a single message to a specific agent, prints the reply on stdout, exits.

arbiter --send <agent> <message>

<agent> is the id of an agent under ~/.arbiter/agents/. <message> is everything after that — multiple positional args are joined with spaces, so quoting is up to your shell.

Behaviour

The agent runs the full orchestration loop: it can fire /fetch, /exec, /agent, /mem, /write, etc. internally, just as it would in interactive mode. You don't see the intermediate steps — only the final synthesised reply lands on stdout. Tool-call output is consumed by the agent, not echoed.

If the agent succeeds, the reply prints to stdout and the process exits 0. If it fails (provider error, missing API key, unknown agent id), an ERR: <reason> line lands on stderr and the process exits 1.

No TTY required. No alt-screen. No persistent session — the conversation history starts and ends with this one invocation. This is the right mode for scripts, cron jobs, CI hooks, and any pipeline where you want a deterministic-shape reply.

Examples

Pipe input via your shell:

arbiter --send reviewer "review: if (arr.length = 0) return;"

Capture output:

SUMMARY=$(arbiter --send research "summarise the last week of my git log")
echo "$SUMMARY" | mail -s "Weekly summary" me@example.com

Compose with other tools:

git log --since='1 week ago' --oneline \
  | arbiter --send writer "Turn this changelog into release notes" \
  > RELEASE_NOTES.md

CI gate:

arbiter --send reviewer "$(git diff main...HEAD)" \
  | grep -q '^APPROVED' || exit 1

Differences from interactive mode

AspectInteractive (arbiter)One-shot (--send)
TTYRequired (alt-screen)Not required; works under pipes / cron
Session persistenceGlobal conversations/ storeNone — fresh history every run
Tool-call outputStreams into scrollbackHidden; agent consumes internally
Streaming visibilityReal-time deltasReply printed once, on completion
Multi-agent panesYes (/pane, ^W chords)No — single agent per invocation
Background loops/loop, /watch, etc.No
/cmd slash commandsAvailableNot parsed — message is sent verbatim
Memory / scratchpadtenants.db via wired /memSame DB wiring — agent can /mem internally; schedules persist but do not fire until TUI/--api

--send is intentionally minimal. Anything that needs streaming, queueing, or multi-agent coordination should use either the interactive mode or the HTTP API.

Provider keys

The same precedence as the other modes (see Environment):

  1. OPENROUTER_API_KEY env var for hosted models (preferred for scripts).
  2. ~/.arbiter/openrouter_api_key file.
  3. OLLAMA_HOST plus an ollama/<model> id for local models.

If a script can't find a key, the agent's first model call fails with ERR: <provider-error> and the process exits 1. There's no interactive prompt.