#!/usr/bin/env bash # ABOUTME: Ralph outer loop script for autonomous development. # ABOUTME: Runs Claude in headless mode, iterating on IMPLEMENTATION_PLAN.md. # Usage: ./loop.sh [plan] [max_iterations] # Examples: # ./loop.sh # Build mode, unlimited iterations # ./loop.sh 20 # Build mode, max 20 iterations # ./loop.sh plan # Plan mode, unlimited iterations # ./loop.sh plan 5 # Plan mode, max 5 iterations set -e # Parse arguments if [ "$1" = "plan" ]; then MODE="plan" PROMPT_FILE="PROMPT_plan.md" MAX_ITERATIONS=${2:-0} elif [[ "$1" =~ ^[0-9]+$ ]]; then MODE="build" PROMPT_FILE="PROMPT_build.md" MAX_ITERATIONS=$1 else MODE="build" PROMPT_FILE="PROMPT_build.md" MAX_ITERATIONS=0 fi ITERATION=0 CURRENT_BRANCH=$(git branch --show-current) echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🔄 Ralph Loop Starting" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Mode: $MODE" echo "Prompt: $PROMPT_FILE" echo "Branch: $CURRENT_BRANCH" [ $MAX_ITERATIONS -gt 0 ] && echo "Max iterations: $MAX_ITERATIONS" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # Verify prompt file exists if [ ! -f "$PROMPT_FILE" ]; then echo "Error: $PROMPT_FILE not found" exit 1 fi # Verify we're in a git repo if ! git rev-parse --git-dir > /dev/null 2>&1; then echo "Error: Not in a git repository" exit 1 fi while true; do if [ $MAX_ITERATIONS -gt 0 ] && [ $ITERATION -ge $MAX_ITERATIONS ]; then echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "✅ Reached max iterations: $MAX_ITERATIONS" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" break fi ITERATION=$((ITERATION + 1)) echo "" echo "═══════════════════════════════════════════" echo "🔄 ITERATION $ITERATION" echo "═══════════════════════════════════════════" echo "" # Run Ralph iteration with selected prompt # -p: Headless mode (non-interactive, reads from stdin) # --dangerously-skip-permissions: Auto-approve all tool calls # --output-format=stream-json: Structured output for logging # --model opus: Use Opus for complex reasoning cat "$PROMPT_FILE" | claude -p \ --dangerously-skip-permissions \ --output-format=stream-json \ --model opus \ --verbose # Push changes after each iteration if git diff --quiet && git diff --cached --quiet; then echo "No changes to push" else git push origin "$CURRENT_BRANCH" 2>/dev/null || { echo "Creating remote branch..." git push -u origin "$CURRENT_BRANCH" } fi echo "" echo "───────────────────────────────────────────" echo "Iteration $ITERATION complete" echo "───────────────────────────────────────────" done echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🏁 Ralph Loop Complete" echo "Total iterations: $ITERATION" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"