Files
2025-11-30 09:05:19 +08:00

387 lines
7.8 KiB
Markdown

# Codex CLI
Automate code, bash scripting, web research with clean output.
## Install
```bash
npm install -g @openai/codex
codex --version
```
## Config
`~/.codex/config.toml`:
```toml
model = "gpt-5-codex"
model_reasoning_effort = "high"
approval_policy = "never"
sandbox_mode = "workspace-write"
web_search = true
```
## Commands
**Interactive:** Real-time development
```bash
codex "Create a Python REST API"
```
**Exec:** Automation
```bash
codex exec "Task" --full-auto
```
---
## Bash Scripting
### Basic
```bash
#!/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
```bash
codex exec "Your task" --full-auto --output-last-message /tmp/result.txt
cat /tmp/result.txt
```
### Idempotent
```bash
#!/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
```bash
#!/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
```bash
#!/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
```bash
#!/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
```bash
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
```bash
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.
```bash
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.
```bash
codex exec "Task" --full-auto --json 2>/dev/null | jq '.type' | sort | uniq -c
```
**Suppress console:** Redirect to /dev/null
```bash
codex exec "Task" --full-auto --output-last-message /tmp/answer.txt >/dev/null 2>&1
cat /tmp/answer.txt
```
**Save audit log + clean output:**
```bash
codex exec "Task" --full-auto \
--output-last-message /tmp/answer.txt \
--json >/tmp/audit.jsonl 2>&1
cat /tmp/answer.txt
```
---
## Python
### Simple
```python
import subprocess
result = subprocess.run(
['codex', 'exec', 'Create test module', '--full-auto'],
cwd='/tmp/project',
capture_output=True,
text=True
)
print(result.stdout)
```
### Wrapper
```python
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**
```bash
codex exec "Find X. Return JSON with: pattern, description, code." \
-c web_search=true --full-auto --output-last-message /tmp/result.json
```
**Batch docs**
```bash
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**
```bash
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, cheap
- `gpt-5-codex`: Default, code-optimized
- `o3`: Powerful, slow
---
## Security
**Safe:**
- `workspace-write` sandbox (default)
- Git checkpoints before Codex
- Validate generated code
**Avoid:**
- `danger-full-access` without 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
```bash
# 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
```