| flag | does |
|---|---|
-p, --prompt QUERY | run one query headlessly and print the answer to stdout |
-q, --query QUESTION | the pipe-friendly spelling: only the answer on stdout; progress and a recorded: replay line on stderr; the run auto-exports |
--json | with -p: a structured JSON result instead of the bare answer |
--export FILE | with -p or -q: write the run's export record to FILE after the turn |
--yolo | open the approval gate for the whole run, headless or interactive, the same as /policy open |
--replay FILE | render an exported run record offline, then exit (0 if it rendered, 1 if not) |
--version | print the version |
The CLI is strict: an unknown flag or an invalid combination (-p with -q, --json with -q, --export without a query, --replay with a query, an empty -p "") exits 2 instead of silently launching the chat loop.
saturn -p "what changed in local LLMs this week?"
git diff | saturn -p "review this change"
saturn -q "summarize notes.md" > summary.txt
saturn -p "..." --json --export run.json::-p vs -q
Both run the same turn: same loop, same gate, same trace recording. -p prints the answer. With --json it prints status, query, answer, plan, tools_called, tool_events, a gates record of which calls were prompted and denied, documents_retrieved, iterations, context_tokens, tok_per_sec, duration_s, run_id, and version. -q puts only the answer on stdout, sends progress to stderr, and exports the run so the closing recorded: saturn --replay <file> line names a file that actually replays. A completed run exits 0. An error exits 1, as JSON with status: "error" under --json. A failed export write also exits 1, after the answer is already out.
::the gate with no human present
Read-only tools run freely. Gated calls are denied by default, because nobody is at the gate to say yes, and the answer says what was denied. --yolo opens the gate for the run, with five exceptions it never covers:
- –
send_message: a send to another person always needs a human to read it first; - –
create_skill: saving a skill always shows you the whole skill first; - –
add_documentandremove_document: changing what the knowledge base holds is refused headless; - –under the air-gap, a shell command, a shortcut, or an MCP call, since nobody is there to check whether it touches the network;
- –a
web_extractURL the gate held: one the model composed after reading outside content, or a private address you didn't type.
Each denial is explained on stderr. ask_user gets no answer headless, and the model has to say what stays unknown. Piped stdin attaches to the turn when something arrives within a second, and is scanned like an @file attachment.
A headless run never learns a fact on its own, since nobody reads a remembered line on stdout: a remember faces the gate like any other side-effecting call. It never saves a skill either. saturn -p "/think <request>" runs that request at deep, and saturn -p "/weekly-review" runs your skill, the same as typing either at the prompt.
note
The home page's gate figure is a real headless run: the model reached for write_file, the gate denied it, and notes.md was never written.