surface

Headless runs and JSON events.

Run one Code turn from a prompt or standard input, constrain workspace authority and cost, and consume JSON events without confusing them with session SSE.

Written for
Developers scripting a single Code task.
You need
Kaitoi CLI installed and the chosen provider configured

A positional prompt runs one Code turn and exits. This is useful for bounded investigation or automation that needs a result and an exit status. For several turns in an ongoing session, use the session API. Examples describe CLI 0.9.0.

Supply the prompt

For a project containing src/main.py:

kaitoi code --workspace . --mode plan --trust-workspace-read-only \
  --max-credits 100 --json "Explain @src/main.py"

The explicit workspace is trusted for reads. The model can still incur usage. Replace the path with a real project file and choose a credit bound appropriate to your account and task.

With no positional prompt, piped UTF-8 stdin supplies the prompt. A literal - also selects stdin. When you supply a prompt argument, stdin is left unread. --json requires a nonempty prompt; it does not start a persistent server. To use a literal prompt beginning with a reserved subcommand word such as crew, acp, or serve, place -- before it.

Read the event stream

A headless process emits one turn's events and then exits.

A prompt enters one process. JSON event records describe turn start, text deltas, tools, permissions, and completion or failure. Each EventRecord has a sequence, timestamp, and kind. An optional final trace object has a different shape. Consume complete lines and inspect the process exit status.

The figure shows selected JSON record excerpts for turn.started, assistant.text.delta and turn.completed; intervening records are omitted. A line parser routes event kinds to handlers, while the optional type: trace record takes its own branch. Stderr remains outside that parser.

Normal EventRecord lines include sequence, timestamp, and kind, plus event-specific fields. Kinds include turn.started, assistant.text.delta, tool.called, permission.requested, and turn.completed, turn.failed, or turn.cancelled. A distinct final object can use {"type":"trace","data":...}. Handle that separately instead of requiring every line to have kind.

These terminal JSON events are different from served-session SSE. In particular, turn.end belongs to the served session's per-turn boundary, not the normal terminal CLI event vocabulary.

Grant only the intended authority

--auto-approve-edits permits file writes and edits; it does not grant deletion, moves, command execution, or transfers. --auto-approve enables routine approval review with hard exclusions, including credit spending and risky operations. Existing saved command and MCP approvals can apply independently. Prepare the exact needed approvals rather than treating either flag as a universal unattended permission grant.

Plan mode and read-only workspace trust do not make a turn free or side-effect free: model usage, session logs, and previously approved hooks can still occur. Some requests can be denied or remain unavailable in an unattended context.

Bound and finish the task

--max-credits is checked before the next model step. The current step can finish beyond the bound. --max-steps limits model steps, not the duration or number of shell commands. See limits for those boundaries.

The process exits according to the turn result and stops its session background processes, MCP connections, and language servers. Read the exit status together with the terminal event and actual outputs. Stopping or failing does not roll back completed file edits or prove that remote work was canceled.

Last reviewed against Kaitoi on 24 October 2026. View this page as Markdown

Type at least two characters.