Initial commit
This commit is contained in:
386
skills/using-codex.md
Normal file
386
skills/using-codex.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user