Local web dashboard for orchestrating Claude↔Codex iterative review loops. Uses your existing CLI subscriptions (no API keys).
- Node 22+
- pnpm
claudeCLI installed and logged in (Pro/Max subscription)codexCLI installed and logged in (ChatGPT subscription)
Verify:
claude --version
codex --versionpnpm install
pnpm db:migrate
pnpm devOpen http://127.0.0.1:4170.
Environment variables (all optional):
| Variable | Default | Purpose |
|---|---|---|
PORT |
4170 |
HTTP port (always bound to 127.0.0.1) |
LOOP_DB_PATH |
./loop.db |
SQLite file location |
LOOP_ARTIFACTS_DIR |
./.loops |
Where iteration artifacts are written |
LOOP_CLAUDE_BIN |
claude |
Path or name of Claude CLI |
LOOP_CODEX_BIN |
codex |
Path or name of Codex CLI |
LOOP_MAX_ITERATIONS |
10 |
Default iteration cap (per task) |
LOOP_ITERATION_TIMEOUT_MS |
1800000 |
Per-iteration timeout (30 min) |
LOOP_MAX_QUEUE_DEPTH |
5 |
Max pending tasks; further submissions return 429 until the queue drains |
- File a task via the dashboard (title, prompt, working directory, optional iteration cap)
- Worker picks it up serially (one task at a time — see "Concurrency" below)
- Each iteration:
- Build a prompt for Claude (task + prior history)
- Run
claude --printwith the prompt via stdin - Build a review prompt for Codex (task + history + Claude's latest output)
- Run
codex exec --sandbox read-onlywith the prompt via stdin - Parse Codex's first non-empty line for
STATUS: DONEorSTATUS: ISSUES_FOUND
- Loop terminates when:
- Codex emits
STATUS: DONE→ task marked done maxIterationsreached with issues remaining → task marked needs_attention- A subprocess fails → task marked failed
- Codex emits
- Live progress streams to the dashboard via SSE; reconnecting clients replay full event history
- All inputs/outputs persist to
.loops/<task-id>/as flat .md files for inspection and replay
- Serial execution by design. Only one loop runs at a time. Subsequent submissions queue. This caps subscription burn and keeps provider rate limits predictable.
- No mid-loop cancellation in v1. To stop a runaway loop,
Ctrl-Cthe dashboard process. On next start the in-flight task is markedfailedautomatically. - No restart-resume. A running task whose process died is marked
failedon the next startup. Re-submit it manually if you want to retry.
This dashboard invokes claude and codex CLIs as subprocesses, using your existing
OAuth login for each. You are responsible for compliance with each provider's terms.
Both providers explicitly support headless/non-interactive CLI use (the --print and
exec flags exist for exactly this), but their subscription tiers are sized for
ordinary individual usage. Heavy queue-based async use can hit weekly caps quickly
and may attract enforcement. v1's serial execution + per-task iteration caps are
designed to keep usage shaped like normal interactive sessions.
If you find yourself wanting heavy parallelism or 24/7 unattended runs, the provider-prescribed path is API key billing (Anthropic Console, OpenAI API). The orchestrator code is provider-agnostic and would only need a small wrapper change.
References (verify current state of each before relying on this summary):
- Anthropic Claude Code legal/compliance: https://code.claude.com/docs/en/legal-and-compliance
- Anthropic Consumer Terms: https://www.anthropic.com/legal/consumer-terms
- OpenAI Terms of Use: https://openai.com/policies/terms-of-use/
- OpenAI Codex CLI docs: see
codex --helpand your~/.codex/config.toml
- Server binds to
127.0.0.1only — never0.0.0.0. - No authentication. Do not run this on a shared machine, and do not expose it.
- The dashboard accepts an arbitrary
workingDirper task. Each task's CLI subprocesses inherit your full shell environment and run inside that directory. Treat task creation as equivalent to running CLI commands yourself.