Tech 5 min read

Letting Claude Code and Codex Run Overnight in tmux to Build a Game (Setup)

The Goal

Let Claude Code implement, have OpenAI Codex review it, then have Claude fix it — automatically looping. Can something get built overnight without intervention?

Claude Code (implement)
    ↓ code output
Codex (review)
    ↓ review result
Claude Code (fix)
    ↓ repeat...

Running both extensions inside VS Code doesn’t give them a way to communicate. Each extension runs as an isolated process with no communication API.

tmux makes it possible.

Why tmux

tmux has features that allow communication between panes.

FeatureDescription
send-keysSend commands/text to another pane
capture-paneCapture output from a pane
pipe-panePipe pane output to an external process

That said, this is a linear pipeline, so inter-pane communication isn’t actually used here. Data passes through files instead.

Environment Setup

macOS

brew install tmux

Windows (WSL2)

sudo apt update && sudo apt install tmux -y

tmux doesn’t run in PowerShell. WSL2 is required.

Basic Script

#!/bin/bash
# ai-review-loop.sh

WORK_DIR="/tmp/ai-review"
mkdir -p "$WORK_DIR"

TASK="$1"
MAX_ROUNDS=3

# Log files (for monitoring in tmux panes)
CLAUDE_LOG="$WORK_DIR/claude.log"
CODEX_LOG="$WORK_DIR/codex.log"

# 1. Initial implementation (Claude)
echo "=== Round 1: Claude implements ===" | tee -a "$CLAUDE_LOG"
echo "$TASK" | claude -p 2>&1 | tee "$WORK_DIR/code-v1.txt" >> "$CLAUDE_LOG"

for i in $(seq 1 $MAX_ROUNDS); do
  # 2. Review (Codex)
  echo "=== Round $((i+1)): Codex review ===" | tee -a "$CODEX_LOG"
  cat "$WORK_DIR/code-v$i.txt" | \
    codex exec "Review this code. List issues as bullet points" 2>&1 | tee "$WORK_DIR/review-$i.txt" >> "$CODEX_LOG"

  # 3. Fix (Claude)
  echo "=== Round $((i+1)): Claude fixes ===" | tee -a "$CLAUDE_LOG"
  NEXT=$((i+1))
  cat <<EOF | claude -p 2>&1 | tee "$WORK_DIR/code-v$NEXT.txt" >> "$CLAUDE_LOG"
Original code:
$(cat "$WORK_DIR/code-v$i.txt")

Review feedback:
$(cat "$WORK_DIR/review-$i.txt")

Output the fixed code based on the review.
EOF

  # 4. Save to Git (preserve intermediate progress)
  git add -A
  git commit -m "Round $i complete: $(date '+%Y-%m-%d %H:%M')"
  git push origin main

done

echo "=== Done ===" | tee -a "$CLAUDE_LOG" "$CODEX_LOG"
echo "Final code: $WORK_DIR/code-v$((MAX_ROUNDS+1)).txt"

Challenges for Overnight Runs and How to Handle Them

1. Claude Stops to Ask Questions (Severity: High)

When Claude is unsure, it asks “How should I handle this?” That stops everything.

Fix 1: Allow all permissions

claude -p --dangerously-skip-permissions "task"

Fix 2: Settings file

.claude/settings.json:

{
  "permissions": {
    "allow": ["Edit", "Write", "Bash(*)"],
    "deny": []
  }
}

Fix 3: Explicit instruction in the prompt

Never ask questions. Make your own decisions when in doubt.

2. Context Gets Compacted (Severity: Medium)

Running for a long time causes Claude’s context to be compressed, making it forget earlier history. It may repeat the same mistakes.

Fix: Keep history in files

Don’t rely on Claude’s memory — save history to the filesystem and reload it each round.

# Append each round's result to a file
echo "=== Round $i ===" >> $WORK_DIR/history.log
cat $WORK_DIR/review.txt >> $WORK_DIR/history.log

# Feed recent history to Claude
tail -100 $WORK_DIR/history.log | claude -p "Based on the history so far..."

3. Usage Limits (Severity: Low)

Max plan ($200/month) is effectively unlimited. Pro plan and below will struggle with 5 hours.

Two-Phase Structure

For best overnight success, front-load human involvement to lock in the details.

Phase 1: Plan (human present)
├── Clarify spec, answer questions
├── Make design decisions
└── Declare "no questions from here on — run on your own"

Phase 2: Implementation loop (unattended)
├── Claude: implement
├── Codex: review
├── Claude: fix
└── repeat...

Phase 1 Prompt Example

We're going to build a game. First, let's finalize the design.

## Game Overview
(write spec here)

## Question Phase
Ask anything you need to know about the design while you can.
Once this phase ends, no more questions will be accepted.

Phase 2 Prompt Example

## Implementation Phase Rules (strictly enforced)

1. Never ask questions. Decide for yourself when in doubt.
2. If there's an error, fix it yourself.
3. Keep looping until the completion criteria are met.
4. Save each round's results to /tmp/game-dev/round-N.md
5. When done, create /tmp/game-dev/DONE.txt

## Completion Criteria
- Game runs in the browser
- All major features implemented
- No critical issues flagged in Codex's review

## Decision Guidelines When Unsure
- Library choice: prefer lightweight options
- Multiple implementation paths: choose the simpler one
- Ambiguous spec: go with what feels natural for the game

Visualizing Progress with tmux

To monitor progress while running in the background, split the screen left/right with Claude and Codex output side by side.

┌─────────────────────┬─────────────────────┐
│ Claude Code         │ Codex               │
│ (implement/fix)     │ (review)            │
└─────────────────────┴─────────────────────┘
#!/bin/bash
# ai-review-tmux.sh

SESSION="ai-review"
WORK_DIR="/tmp/ai-review"
mkdir -p "$WORK_DIR"

# Create session
tmux new-session -d -s $SESSION

# Left pane: monitor Claude Code output
tmux send-keys -t $SESSION "watch -n 2 'echo \"=== Claude Code ===\"; tail -30 $WORK_DIR/claude.log 2>/dev/null'" C-m

# Right pane: monitor Codex output
tmux split-window -h -t $SESSION
tmux send-keys -t $SESSION "watch -n 2 'echo \"=== Codex Review ===\"; tail -30 $WORK_DIR/codex.log 2>/dev/null'" C-m

# Attach
tmux attach -t $SESSION

Main processing runs in a separate window. Writing output to separate log files lets each pane show its own progress.

Check in later:

tmux attach -t ai-review

Detach and leave it running: Ctrl+bd

Next

Actually running this overnight on a Mac and seeing if a game gets built. Results in a follow-up article.