> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open4rena.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Print mode and scripting

> Run o4 once without the interface, for scripts, pipelines, and CI.

Print mode runs one prompt without the terminal interface. o4 works on the task, prints the model's reply, and exits. Use it in shell scripts, Git hooks, and CI jobs, or whenever you want an answer on standard output.

## Run a prompt

Pass the prompt with `-p` (or `--prompt`):

```bash theme={null}
o4 -p "Summarize what this repository does in three sentences"
```

A prompt on the command line is what starts print mode. The `--print` flag is accepted for compatibility, but it doesn't change anything on its own: `o4 --print -p "..."` behaves exactly like `o4 -p "..."`, and `o4 --print` with no prompt starts the normal interface. Without a terminal, for example in a script, that plain interface waits for input, so always pass `-p`.

The agent can read files, search, edit, run commands and start subagents, subject to the permission mode and sandbox described below. A few interactive tools aren't offered, such as `ask_user_question`, `undo`, `todo_write` and the task tools; see [where each tool is available](/reference/tools#where-each-tool-is-available). It works in the current directory unless you pass `-C`.

Other options work as usual:

```bash theme={null}
o4 -m gpt-5.4-mini --reasoning low -C ~/code/api -p "List the HTTP routes and the handler for each"
```

| Flag | Use |
| - | - |
| `-m`, `--model` | Pick the model. See [Choosing a model](/models/overview). |
| `--reasoning` | Reasoning effort: `default`, `low`, `medium`, `high` or `max`. |
| `-C`, `--cd` | Run in another directory. |
| `--add-dir` | Let o4 write to another directory as well. You can repeat it. |
| `-s`, `--system-prompt` | Add your own instructions to the end of o4's system prompt. |
| `-v`, `--verbose` | Also stream the model's reasoning, to standard error. |
| `--prompt-profile` | Override the prompt profile. See [Reasoning and prompt profiles](/models/reasoning). |
| `--no-onboarding` | With no default model set, fail with `No default model configured` instead of picking one. |

## What goes where

Print mode keeps the answer and the progress apart, so you can capture one without the other:

| Stream | Contents |
| - | - |
| Standard output | Only the model's reply text, streamed as it arrives, with a newline at the end. |
| Standard error | Progress lines such as `[tool: read]`, `[error] ...`, `[retry 1/3 in 2s] ...` and `[context compacted: 40 -> 12 messages]`, warnings, errors, and reasoning when you pass `-v`. |

A failed model request is retried up to 3 times. When standard output is a terminal, o4 strips terminal control sequences from the reply; when you redirect it, the bytes pass through unchanged.

The reply is plain text in whatever format the model wrote it, often Markdown. There is no JSON output mode for a prompt run. If you need structured output, ask for it in the prompt and check it in your script.

```bash theme={null}
o4 -p "Write a one-paragraph release note for the changes in the last commit" > release-note.md
```

## Exit codes

| Code | Meaning |
| - | - |
| `0` | The run finished. |
| `1` | The run failed, for example an unknown model, a failed model request, or a hook that blocked the run. o4 prints `Error: ...` to standard error. |
| `2` | Invalid command-line arguments, such as an unknown flag or an invalid `--permission-mode` value. Also returned for an invalid `/context` or `/stats` diagnostic request. |

Exit code `0` means o4 finished, not that the task succeeded. If your script depends on the result, check it yourself, for example by running the tests afterwards.

## Give o4 input from other commands

Print mode doesn't read standard input, so `cat file | o4 -p "..."` doesn't send the file. Put the text into the prompt with command substitution instead:

```bash theme={null}
o4 -p "Explain this stack trace and point to the likely cause:
$(cat crash.log)"
```

```bash theme={null}
o4 -p "Write a commit message for this diff. Reply with the message only.
$(git diff --staged)"
```

For large files, it's usually better to name the file in the prompt and let o4 read it with its tools:

```bash theme={null}
o4 -p "Read logs/build.log and tell me why the build failed"
```

A command line can only be so long, and your operating system limits it. Very large substitutions can fail before o4 starts.

## Permissions in print mode

Print mode can't show approval prompts, so it handles permissions differently from the interface:

* It starts in `auto` permission mode, which runs ordinary tool calls without asking.
* Anything that would still need your approval is denied, and the model is told it was denied. Even in `auto`, this includes package installs that would run install scripts.
* `--permission-mode` picks another mode for the run.

```bash theme={null}
# Read and answer only. Edits and commands are refused.
o4 --permission-mode plan -p "Review src/auth.rs for security problems"

# Allow edits, but refuse any command that would need approval.
o4 --permission-mode accept-edits -p "Add doc comments to the public functions in src/lib.rs"
```

| Mode | In print mode |
| - | - |
| `auto` | The default. Ordinary edits and commands run without asking. |
| `plan` | Only tools that never need approval, such as reading and searching, run. Nothing is changed. |
| `accept-edits` | File edits run. Commands that need approval are denied. |
| `ask` | Tools that never need approval run. Everything else is denied. |
| `review` | A reviewer model checks each call that needs approval. Calls it doesn't allow are denied. |
| `bypass` | Every tool call runs without any check. o4 prints a warning to standard error. |

Your permission rules from the configuration still apply. See [Permissions](/safety/permissions) for what each mode allows. The same goes for [CodeMode](/extend/codemode): a tool call inside a CodeMode program that would need approval fails instead of asking.

## Sandbox for commands

Without `--sandbox`, commands in print mode always run in the `guarded` tier: o4 doesn't apply your `default_tier` setting, and it starts no egress proxy, so commands have no network unless a `[sandbox]` table without `allowedDomains` lifts the limit. See [Sandbox](/safety/sandbox).

`--sandbox` sets how shell commands that the model runs are sandboxed for the whole run:

| Value | Effect |
| - | - |
| `read-only` | Commands can't write files or use the network. |
| `workspace-write` | Commands can write in the workspace and the directories you add with `--add-dir`, and reach package registries plus any domains your sandbox configuration allows. |
| `danger-full-access` | No sandbox. |

```bash theme={null}
o4 --sandbox read-only --permission-mode auto -p "Run the test suite and summarize the failures"
```

See [Sandbox](/safety/sandbox) for the details of each policy and what your platform supports.

<Warning>
  `--permission-mode bypass` together with `--sandbox danger-full-access` lets the model run anything on the machine with no checks. Use it only in a disposable environment, such as a throwaway container.
</Warning>

## Use it in CI

A CI job usually runs on a fresh machine with no saved login. Install o4 in the job (see [Install o4](/installation)) and give it an API key through the environment. See [Providers and API keys](/models/providers) for the variable each provider reads.

```yaml theme={null}
# GitHub Actions steps
- name: Install o4
  run: |
    curl -fsSL https://open4rena.ai/install.sh | bash
    echo "$HOME/.local/bin" >> "$GITHUB_PATH"

- name: Review the change
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
  run: |
    o4 -m anthropic:claude-sonnet-4-6 --permission-mode plan \
      -p "Review the changes on this branch against origin/main. List bugs and risky changes." \
      > review.md
```

Things to know for automation:

* Print mode never opens the setup wizard. If no default model is set, o4 picks one based on the credentials it finds. Pass `-m` in automation so the model doesn't change when the environment does. See [Choosing a model](/models/overview).
* Project hooks and MCP servers from a repository only run once the workspace is trusted. Run `o4 trust` in the checkout, or see [Workspace trust](/safety/workspace-trust).
* `--dangerously-bypass-hook-trust` runs enabled hooks without the saved hook trust, for this run only. Use it only when your pipeline already checks where the hooks come from. See [Hooks](/extend/hooks).
* Print-mode runs aren't saved as sessions. You can't resume them.
* Slash commands aren't run in print mode, except the two diagnostics below. `^model` mentions are refused with an error.

## Check context and usage from a script

Two slash commands work as the whole prompt in print mode. They read local data only and don't call the model:

```bash theme={null}
o4 -p "/context --json"
o4 -p "/stats --json"
```

Each prints one JSON document on a single line: `/context --json` describes the model's context window and the configured compaction threshold, and `/stats --json` adds session statistics. Without a session, most values are `null` with a `reason`, since nothing has been sent yet. `o4 -p "/stats"` without `--json` prints the usage statistics recorded on this machine as text.

Any other argument makes these commands fail with `o4: diagnostic command error: invalid_arguments` on standard error and exit code `2`. See [Context and cost](/guides/context-and-cost).

## Related pages

* [CLI reference](/reference/cli): every flag.
* [Watch mode](/guides/watch): run a check when files change and let o4 fix failures.
* [Environment variables](/reference/environment-variables): API keys and other settings.
