# codex exec Cookbook: 12 Non-Interactive Recipes

Twelve copy-paste codex exec recipes: PR review, TODO extraction, doc and changelog generation, cron digests, webhook handlers, jq pipelines, and resumed multi-stage chains.

*Published 2026-06-12 · https://proxyllm.ai/blog/codex-exec-cookbook*

Twelve `codex exec` recipes you can paste into a shell today. Each takes one prompt in, prints a result to stdout, and exits, which is the entire trick: once Codex behaves like a Unix tool, the rest of your toolchain does the integrating. Setup is the same for all of them:

```bash
npm i -g @openai/codex   # or: brew install codex
codex login              # plan-backed; use --device-auth on headless boxes
cd your-repo             # exec works best inside a repository
```

Two flags appear throughout: `--sandbox read-only` for recipes that only inspect the repo, `--full-auto` for recipes allowed to edit it. The command surface behind them is in [the codex exec guide](/blog/codex-exec-non-interactive-mode-guide).

## 1. PR review to markdown

Setup: run inside the repo with `origin/main` fetched; read-only is enough.

```bash
codex exec --sandbox read-only \
  "Review the diff between origin/main and HEAD for bugs, missing tests, and risky changes. Cite file and line. Output markdown." > review.md
```

## 2. TODO extraction as JSON

Setup: none beyond the repo; the output contract does the work.

```bash
codex exec --sandbox read-only \
  "Find every TODO and FIXME comment. Output only a JSON array of {file, line, text}." > todos.json
```

## 3. Coverage gaps, piped to jq

Setup: `jq -e` turns the answer into an exit code, so this recipe is a gate.

```bash
codex exec --sandbox read-only \
  "List exported functions with zero test references. Output only a JSON array of {file, symbol}." \
  | jq -e 'length == 0' && echo "all exports covered"
```

## 4. Commit message from the staged diff

Setup: stage your changes first; `head -c` caps the prompt size on big diffs.

```bash
codex exec --sandbox read-only \
  "Write a one-line conventional commit message for this staged diff. Output only the message: $(git diff --staged | head -c 16000)" \
  | git commit -F -
```

## 5. Docs generation

Setup: needs `--full-auto`, since the job writes a file.

```bash
codex exec --full-auto \
  "Update docs/api.md so it documents every exported function in src/lib/, matching the existing heading style. Create the file if it is missing."
```

## 6. Test triage

Setup: command substitution feeds the failures straight into the prompt.

```bash
codex exec --sandbox read-only \
  "Group these test failures by root cause and name the most likely fix for each. Output markdown: $(npm test 2>&1 | tail -n 150)"
```

## 7. Changelog draft

Setup: point the range at your last release tag.

```bash
codex exec --sandbox read-only \
  "Draft a CHANGELOG entry for these commits, grouped as Added/Changed/Fixed: $(git log --oneline v2.3.0..HEAD)" >> CHANGELOG.draft.md
```

## 8. Lint-fix pass

Setup: `--full-auto` again; review the result as a normal diff.

```bash
codex exec --full-auto \
  "Run npm run lint. Fix every error it reports. Rerun until clean, then list the files you touched."
```

## 9. Multi-stage chains with resume

Setup: `codex exec resume --last` continues the previous session with its context intact.

```bash
codex exec --full-auto "Read TODO.md and pick the single smallest item. Implement it and run the tests."
codex exec resume --last "Update CHANGELOG.md with what you just did."
codex exec resume --last "Write a one-paragraph PR description for the change."
```

This is the building block for pipelines that think in stages: plan, act, document, each step seeing the ones before.

## 10. Cron digest

Setup: one crontab line; absolute binary path because cron's PATH is bare.

```bash
# crontab -e
0 7 * * 1-5  cd /srv/app && /usr/local/bin/codex exec --sandbox read-only "Summarize yesterday's commits in 10 bullets with risk flags: $(git log --since=yesterday --stat | head -c 12000)" >> /var/log/codex-digest.log 2>&1
```

Scheduling deserves its own page, alerting and all: [run Codex on a schedule](/blog/run-codex-on-a-schedule).

## 11. Webhook handler

Setup: `node hook.mjs`; put auth in front, because anything that can POST can now spend your usage window.

```js
// hook.mjs: POST a payload, get a Codex triage line appended to triage.log
import { execFile } from "node:child_process";
import { appendFile } from "node:fs/promises";
import http from "node:http";

http
  .createServer((req, res) => {
    let body = "";
    req.on("data", (c) => (body += c));
    req.on("end", () => {
      execFile(
        "codex",
        [
          "exec",
          "--sandbox",
          "read-only",
          `Classify this alert as page-now, business-hours, or ignore, one line with a reason: ${body.slice(0, 4000)}`,
        ],
        (err, stdout) =>
          appendFile("triage.log", (stdout || String(err)) + "\n"),
      );
      res.writeHead(202);
      res.end("queued\n");
    });
  })
  .listen(8787);
```

## 12. n8n, or any tool that only speaks HTTP

Setup: `codex exec` needs a shell, and n8n cloud, Make, and Zapier do not have one. They call an OpenAI-compatible endpoint that fronts a Codex container instead; this curl is exactly what an n8n HTTP Request node replicates.

```bash
curl -s https://api.proxyllm.ai/v1/chat/completions \
  -H "Authorization: Bearer $PROXYLLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-5-mini", "messages": [{"role": "user", "content": "Summarize this payload for the ops channel: ..."}]}' \
  | jq -r '.choices[0].message.content'
```

The node-by-node n8n version is in [use your ChatGPT subscription in n8n](/blog/use-chatgpt-subscription-with-n8n).

## Make the recipes repo-aware

Every recipe above gets sharper when the repo carries standing instructions: which test command to run, what never to touch, what "done" means. That file is `AGENTS.md`, Codex reads it on every run including exec, and [the AGENTS.md guide](/blog/codex-agents-md-guide) includes a complete example for exec-driven repos. Write the contract once and recipes 1 through 9 stop needing it restated in every prompt.

## Where these recipes go to live

On your laptop, all twelve run today for free, billed to the ChatGPT plan you already pay for. The gap shows up when they need to run while your laptop is closed: recipes 10 through 12 want a machine that stays up, a session that stays signed in, a queue when two fire at once, and a log of what ran. That is the operational line between a script and a service, and [Codex Hosted vs running Codex yourself](/blog/codex-hosted-vs-running-codex-yourself) prices both sides of it honestly. [Codex Hosted](/) is the service side: your account, our container, one endpoint everything above can call.
