A tiny, no-prompt autopilot wrapper around codex exec so Codex can run headless forever while showing a clean status stream.
- Pretty, bead-aware output by default (auto-detects current
bdissue and title) - Shows event kind, status, exit codes, and compact messages/JSON payloads
- Approval-less, sandbox-bypass defaults for local trusted environments
- Auto-retries every
SLEEP_SECONDS(default 5s) - Works without git (uses
--skip-git-repo-check)
# optional: ensure jq and bd are installed
sudo apt-get install -y jq # or brew install jq
npm i -g @openai/codex # if codex not installed yet
# run from your project workspace
~/projects/ralph-loop-runner/ralph-loop.sh /path/to/workspaceCommon env vars:
PRETTY_OUTPUT=1(default) – keep terse status linesBEAD_TAG=project_tag– override bead auto-detectSLEEP_SECONDS=5– delay between runsCODEX_BIN=codex– alternate codex binaryPROMPT_FILE(second arg) – override the autopilot prompt (default:~/.codex/hooks/ralph-loop.prompt.md)COLOR_OUTPUT=1(default) – adds ANSI colors per event kind.
| Event kind | Meaning | Color |
|---|---|---|
command_execution |
Shell/command activity | Cyan |
agent_message |
Codex text response | Green |
reasoning |
Internal reasoning step | Magenta |
thread.*/item.* |
Lifecycle events | Yellow/White |
turn.* |
Turn boundaries | Cyan/Green |
plan / status |
Status updates | Yellow/Green |
Before each run the runner queries bd ready --json, picks the highest-priority in-progress bead (or the next open bead if none are in progress), and injects the bead’s title/description/labels into the prompt. That means Codex “knows” the current bead and treats it as the work item to edit—no extra instructions required.
The dynamic context also reaffirms the editing mandate, so Codex writes code/docs directly to move the bead forward.
If Codex uncovers a new gap, blocker, or missing integration while executing a bead, the prompt now instructs it to call bd create with a descriptive title/description/labels before continuing. That keeps your bead list current without any extra prompts.
[bead|title] [event_kind] status? exit? message-or-snippet
Examples:
[jason-ejc|Scaffold Big Brain multi-agent OS] [command_execution] completed exit=0 ls agents
[jason-ejc|Scaffold Big Brain multi-agent OS] [reasoning] Checking AGENTS.md for relevant info
[jason-ejc|Scaffold Big Brain multi-agent OS] [agent_message] pong
By default the runner uses ~/.codex/hooks/ralph-loop.prompt.md. Edit or supply another prompt file as the second arg.
- Defaults to
--dangerously-bypass-approvals-and-sandbox; only use on trusted local machines. - Draft-only / no-secrets rules belong in your prompt (the bundled prompt includes them).
Run once to copy the runner into ~/.codex/hooks and make hooks executable:
cd ~/projects/ralph-loop-runner
./install.shinstall.sh wires the prompt, runner, and helper scripts for local use.
nohup ~/projects/ralph-loop-runner/ralph-loop.sh /path/to/workspace > /tmp/ralph.log 2>&1 &
tail -f /tmp/ralph.logOr use the helper:
LOG_FILE=/tmp/ralph.log ~/projects/ralph-loop-runner/start.sh /path/to/workspaceReturns 0 if a codex exec is running, 1 otherwise:
~/projects/ralph-loop-runner/healthcheck.sh # any codex exec
~/projects/ralph-loop-runner/healthcheck.sh big-brain # match workspace substringSave as ~/.config/systemd/user/ralph-loop.service:
[Unit]
Description=Ralph Loop Runner
After=network.target
[Service]
ExecStart=%h/projects/ralph-loop-runner/ralph-loop.sh /home/jason/projects/big-brain
Restart=always
RestartSec=5
Environment=PRETTY_OUTPUT=1
[Install]
WantedBy=default.target
Enable & start:
systemctl --user daemon-reload
systemctl --user enable --now ralph-loop.service
journalctl --user -fu ralph-loop.serviceCreate /etc/logrotate.d/ralph-loop (requires sudo):
/tmp/ralph.log {
rotate 5
daily
missingok
notifempty
compress
copytruncate
}
- codex CLI (
@openai/codex) - jq (for pretty output)
- bd (optional, for bead auto-detect)
MIT