← back to Codex Review 2026 04 30

run-fix.sh

75 lines

#!/usr/bin/env bash
# Run codex in fix mode for one project. Reads review.md from out dir,
# copies it into the project as CODEX_REVIEW.md (so codex can read it from cwd),
# runs codex with workspace-write, captures CHANGES.md + diff.
set -uo pipefail

PROJECT="$1"
ROOT="$HOME/Projects/codex-review-2026-04-30"
SRC="$HOME/Projects/$PROJECT"
OUT_DIR="$ROOT/$PROJECT"
PROMPT_FILE="$ROOT/FIX_PROMPT.txt"

if [ ! -s "$OUT_DIR/review.md" ]; then
  echo "No review.md, skipping $PROJECT" > "$OUT_DIR/fix-error.log"
  exit 1
fi

# Stage review into project so codex can read it from cwd
cp "$OUT_DIR/review.md" "$SRC/CODEX_REVIEW.md"

# Capture pre-state (file list + sha) for diff later
( cd "$SRC" && find . -type f \
    -not -path './node_modules/*' \
    -not -path './venv/*' -not -path './.venv/*' \
    -not -path './.next/*' -not -path './dist/*' -not -path './build/*' \
    -not -path './.git/*' -not -path './data/*' \
    -not -name '*.sqlite' -not -name '*.db' \
    -not -name '*.png' -not -name '*.jpg' -not -name '*.jpeg' -not -name '*.gif' -not -name '*.webp' \
    -not -name '*.mp4' -not -name '*.zip' -not -name '*.tar.gz' \
    | sort > "$OUT_DIR/files-before.txt" )

START=$(date +%s)
echo "=== fix pass $PROJECT @ $(date -Iseconds) ===" > "$OUT_DIR/fix.log"

codex exec \
  --skip-git-repo-check \
  --sandbox workspace-write \
  -C "$SRC" \
  --output-last-message "$OUT_DIR/CHANGES.md" \
  "$(cat "$PROMPT_FILE")" \
  >> "$OUT_DIR/fix.log" 2>&1 &
CODEX_PID=$!
( sleep 900; kill -TERM "$CODEX_PID" 2>/dev/null ) &
WATCH_PID=$!
wait "$CODEX_PID" 2>/dev/null
RC=$?
kill "$WATCH_PID" 2>/dev/null

END=$(date +%s)
echo "=== fix exit=$RC duration=$((END-START))s ===" >> "$OUT_DIR/fix.log"
echo "$RC" > "$OUT_DIR/fix_exit_code"
echo "$((END-START))" > "$OUT_DIR/fix_duration_s"

# Capture file diff snapshot
( cd "$SRC" && find . -type f \
    -not -path './node_modules/*' \
    -not -path './venv/*' -not -path './.venv/*' \
    -not -path './.next/*' -not -path './dist/*' -not -path './build/*' \
    -not -path './.git/*' -not -path './data/*' \
    -not -name '*.sqlite' -not -name '*.db' \
    -not -name '*.png' -not -name '*.jpg' -not -name '*.jpeg' -not -name '*.gif' -not -name '*.webp' \
    -not -name '*.mp4' -not -name '*.zip' -not -name '*.tar.gz' \
    | sort > "$OUT_DIR/files-after.txt" )

# If git repo, capture git diff stats
if [ -d "$SRC/.git" ]; then
  ( cd "$SRC" && git diff --stat 2>/dev/null > "$OUT_DIR/git-diff-stat.txt" )
  ( cd "$SRC" && git status --short 2>/dev/null > "$OUT_DIR/git-status.txt" )
fi

# Cleanup the staged review marker (not authoritative; keep one in OUT_DIR)
rm -f "$SRC/CODEX_REVIEW.md"

exit $RC