Codex CLI / cookbook

Recipes built on what Codex leans into: a sandbox you configure rather than negotiate with, subagents declared as TOML, and a codex exec whose stdout is clean enough to pipe. Hand-written, unlike the cheat sheet — the commands are real, the combinations are editorial.

Cheat sheet Cookbook Changes

Sandbox & approvals

Audit a repo you don't trust yet starter

You cloned something and want Codex to explain it before anything in it gets a chance to run.

on the sheet: sandboxflags

  1. Pin the sandbox to read-only for the run. It's the mode where Codex can look but not touch — no writes, no network.

    codex exec \
      --sandbox read-only \
      "Map this repo: entry points, where it talks to the network, anything that runs at install time."
    
  2. When you do want writes, workspace-write scopes them to the working directory rather than the whole filesystem.

    codex --sandbox workspace-write "Fix the failing tests."
    

The three modes are read-only, workspace-write, and danger-full-access — and the third is named that way on purpose. Reaching for it because a tool call got blocked is how a supply-chain payload in a postinstall script gets its wish.

Decide once how much you want to be asked starter

You are either being interrupted constantly, or not enough — and you'd rather set the dial than fight it per-command.

on the sheet: sandboxconfig

  1. Set the two dials together in config.toml. Approvals and sandbox are separate knobs: the sandbox decides what's possible, the approval policy decides what you get asked about.

    ~/.codex/config.toml
    # Sensible default: work freely inside the repo, ask before anything wider.
    sandbox_mode = "workspace-write"
    approval_policy = "on-request"
    model_reasoning_effort = "medium"
    
  2. Override per-run from the flags when a task genuinely needs something different.

    codex --ask-for-approval never --sandbox read-only \
      "Summarize the architecture. Don't change anything."
    

--ask-for-approval never is safe because it is paired with read-only — never-ask plus full-access is the combination that ends badly. Treat the two flags as one decision, not two.

Subagents

Declare a reviewer once, reuse it forever intermediate

You keep re-typing the same "review this like an owner, focus on X" preamble and getting a slightly different reviewer each time.

on the sheet: agentsconfig

  1. Define the subagent as TOML. Giving it its own sandbox_mode is the useful part: an explorer that cannot write can't wander off and start fixing things.

    ~/.codex/agents/pr_explorer.toml
    name = "pr_explorer"
    description = "Read-only codebase explorer for gathering evidence before changes are proposed."
    model_reasoning_effort = "medium"
    sandbox_mode = "read-only"
    developer_instructions = """
    Gather evidence, propose nothing.
    Cite every claim as file:line. If you cannot cite it, don't say it.
    """
    
  2. Bound the fan-out globally so a recursive spawn can't run away with your quota.

    ~/.codex/config.toml
    [agents]
    max_threads = 6
    max_depth = 1
    

max_depth = 1 is the guardrail worth setting on day one: it stops subagents from spawning subagents, which is the failure mode that turns one prompt into a hundred and is invisible until the bill arrives.

Split a PR review across parallel agents intermediate

One reviewer on a big branch finds the obvious things and misses the interesting ones.

on the sheet: agents

  1. Ask for one agent per concern, then a synthesis. Naming the concerns is what makes them independent — an unprompted "review this" collapses back into one perspective.

    Review this branch against main with parallel subagents.
    Spawn one agent per point, wait for all of them, then summarize
    the result for each with file references:
    
    1. Security
    2. Race conditions
    3. Test gaps
    4. Maintainability
    

The "wait for all of them, then summarize" clause matters more than it looks: without it you get a stream of partial findings and no synthesis, which is more to read and less to act on.

Config & profiles

Keep one config per kind of work intermediate

Your CI runs, your spikes, and your production repo all want different defaults, and you're tired of remembering which flags to pass.

on the sheet: configflags

  1. Put shared defaults in config.toml and let each profile carry only what differs.

    ~/.codex/ci.config.toml
    sandbox_mode = "read-only"
    approval_policy = "never"
    model_reasoning_effort = "low"
    
  2. Select it by name.

    codex exec --profile ci "Check the diff for missing tests."
    

Precedence runs flags → profile → config.toml, so a profile is a named set of overrides, not a full config. Keep them thin: the more a profile restates, the more places you have to remember to change.

Headless & CI

Pipe Codex into another command starter

You want the output of a Codex run to become the input of something else, without progress chatter polluting it.

on the sheet: launchflags

  1. codex exec streams progress to stderr and prints only the final agent message to stdout — so a plain pipe just works, no flag needed.

    codex exec "generate release notes for the last 10 commits" | tee release-notes.md
    
  2. Use --ephemeral when the run should leave no session behind.

    codex exec --ephemeral "triage this repository and suggest next steps"
    

That stdout/stderr split is the whole reason codex exec composes with Unix. It means you can | tee, | jq, or $( ) a run without first teaching a parser to skip the spinner.