7.8 KiB
7.8 KiB
Codex CLI
Automate code, bash scripting, web research with clean output.
Install
npm install -g @openai/codex
codex --version
Config
~/.codex/config.toml:
model = "gpt-5-codex"
model_reasoning_effort = "high"
approval_policy = "never"
sandbox_mode = "workspace-write"
web_search = true
Commands
Interactive: Real-time development
codex "Create a Python REST API"
Exec: Automation
codex exec "Task" --full-auto
Bash Scripting
Basic
#!/bin/bash
set -euo pipefail
cd /tmp/project
git init && git config user.email "bot@example.com" && git config user.name "Bot"
codex exec "Your task" --full-auto
With Clean Output
codex exec "Your task" --full-auto --output-last-message /tmp/result.txt
cat /tmp/result.txt
Idempotent
#!/bin/bash
set -euo pipefail
log() { printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*"; }
ensure_tool() { command -v "$1" >/dev/null || { log "install $1"; exit 1; }; }
case "${1:-help}" in
bootstrap)
ensure_tool jq
[[ -f .ready ]] || { ./setup.sh && touch .ready; }
;;
ci)
for step in lint test build; do
log "running $step"
./scripts/$step.sh || exit 1
done
;;
watch)
ensure_tool entr
find src -type f | entr -r bash -lc './scripts/test.sh'
;;
*)
printf 'usage: %s {bootstrap|ci|watch}\n' "$0" >&2; exit 64
;;
esac
Git Checkpoint
#!/bin/bash
set -euo pipefail
git add . && git commit -m "Before Codex" || true
codex exec "Run tests and fix failures" --full-auto || {
git reset --hard HEAD~1
exit 1
}
git add . && git commit -m "Codex: Fixed" || true
Batch
#!/bin/bash
for project in project1 project2 project3; do
(
cd "$project"
git init && git config user.email "bot@example.com" && git config user.name "Bot" || true
if codex exec "Update dependencies" --full-auto; then
git add . && git commit -m "Updated" --allow-empty || true
echo "✓ $project"
else
git reset --hard HEAD~1
echo "✗ $project"
fi
)
done
Web Search
Enable with -c web_search=true.
Research with JSON
#!/bin/bash
cd /tmp/research
git init && git config user.email "bot@example.com"
task="Find top 3 bash patterns. Return ONLY valid JSON with: pattern, description, code_example."
codex exec "$task" \
-c web_search=true \
--full-auto \
--output-last-message /tmp/result.json
cat /tmp/result.json | jq .
View Searches
codex exec "Research bash best practices" \
-c web_search=true \
--full-auto \
--json 2>/dev/null | \
jq -r 'select(.type=="web_search") | .item.query'
View Reasoning
codex exec "Research X" \
-c web_search=true \
--full-auto \
--json 2>/dev/null | \
jq -r 'select(.type=="reasoning") | .item.text'
Output Control
--output-last-message FILE - Writes final answer to FILE only.
codex exec "Task" --full-auto --output-last-message /tmp/answer.txt
cat /tmp/answer.txt
Result:
- FILE: Clean plaintext answer
- STDOUT: 5 lines metadata
- STDERR: Empty
--json - JSONL events: thread.started, turn.started, reasoning, web_search, agent_message, turn.completed.
codex exec "Task" --full-auto --json 2>/dev/null | jq '.type' | sort | uniq -c
Suppress console: Redirect to /dev/null
codex exec "Task" --full-auto --output-last-message /tmp/answer.txt >/dev/null 2>&1
cat /tmp/answer.txt
Save audit log + clean output:
codex exec "Task" --full-auto \
--output-last-message /tmp/answer.txt \
--json >/tmp/audit.jsonl 2>&1
cat /tmp/answer.txt
Python
Simple
import subprocess
result = subprocess.run(
['codex', 'exec', 'Create test module', '--full-auto'],
cwd='/tmp/project',
capture_output=True,
text=True
)
print(result.stdout)
Wrapper
from dataclasses import dataclass
from typing import Optional
import subprocess
import os
@dataclass
class CodexResult:
returncode: int
stdout: str
stderr: str
task: str
@property
def success(self) -> bool:
return self.returncode == 0
class CodexCLI:
def __init__(self, model="gpt-5-codex", web_search=False):
self.model = model
self.web_search = web_search
def execute(self, task: str, cwd: Optional[str] = None) -> CodexResult:
output_file = f"/tmp/codex-{os.urandom(4).hex()}.txt"
cmd = [
'codex', 'exec', task,
'--full-auto',
'-m', self.model,
'--output-last-message', output_file
]
if self.web_search:
cmd.extend(['-c', 'web_search=true'])
result = subprocess.run(
cmd,
cwd=cwd or os.getcwd(),
capture_output=True,
text=True
)
try:
with open(output_file) as f:
output = f.read()
os.unlink(output_file)
except:
output = result.stdout
return CodexResult(
returncode=result.returncode,
stdout=output,
stderr=result.stderr,
task=task
)
# Usage
codex = CodexCLI(web_search=True)
result = codex.execute("Research X")
print(result.stdout)
Flags
| Flag | Purpose |
|---|---|
--full-auto |
Auto-approve, workspace-write sandbox |
-c web_search=true |
Enable web search |
--output-last-message FILE |
Write final answer to FILE |
--json |
Stream JSONL events |
-m, --model |
gpt-5 (fast), gpt-5-codex (code), o3 (powerful) |
-C, --cd |
Working directory |
Patterns
Research + JSON
codex exec "Find X. Return JSON with: pattern, description, code." \
-c web_search=true --full-auto --output-last-message /tmp/result.json
Batch docs
for module in auth utils data; do
codex exec "Generate API docs for $module.py" \
--full-auto --output-last-message "/tmp/${module}_docs.md"
done
Research → Generate → Commit
codex exec "Research Python testing best practices 2025" \
-c web_search=true --full-auto --output-last-message /tmp/research.txt
codex exec "Using this research, generate test suite for module.py" --full-auto
git add . && git commit -m "Generated tests from latest best practices"
Performance
| Task | Time | Success |
|---|---|---|
| Simple | 30-60s | 99%+ |
| Web search | 60-120s | 95%+ |
| Complex | 120+s | 90%+ |
Models:
gpt-5: Fast, cheapgpt-5-codex: Default, code-optimizedo3: Powerful, slow
Security
Safe:
workspace-writesandbox (default)- Git checkpoints before Codex
- Validate generated code
Avoid:
danger-full-accesswithout external sandboxing- Running without git checkpoints
- Web search on untrusted domains
Troubleshooting
| Problem | Solution |
|---|---|
codex not found |
npm install -g @openai/codex |
| Not in trusted directory | git init in working directory |
| Web search returns nothing | Rephrase as task ("Find X"), not question |
| Too much output | Use --output-last-message FILE |
| Can't parse output | Use --json with jq |
| Auth failed | codex login or set OPENAI_API_KEY |
Quick Reference
# Basic
codex exec "Task" --full-auto
# Web search
codex exec "Research X" -c web_search=true --full-auto
# Clean output
codex exec "Task" --full-auto --output-last-message /tmp/out.txt
# View searches
codex exec "Task" -c web_search=true --full-auto --json 2>/dev/null | \
jq -r 'select(.type=="web_search") | .item.query'
# Token usage
codex exec "Task" --full-auto --json 2>/dev/null | \
jq 'select(.type=="turn.completed") | .usage'
# Different model
codex exec "Task" -m o3 --full-auto
# Specific directory
codex exec "Task" -C /path/to/project --full-auto