# Repository: frankbria/ralph-claude-code # Stars: 8709 ## CLAUDE.md # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Repository Overview This is the Ralph for Claude Code repository - an autonomous AI development loop system that enables continuous development cycles with intelligent exit detection and rate limiting. See [README.md](README.md) for version info, changelog, and user documentation. ## Core Architecture The system consists of four main bash scripts and a modular library system: ### Main Scripts 1. **ralph_loop.sh** - The main autonomous loop that executes Claude Code repeatedly 2. **ralph_monitor.sh** - Live monitoring dashboard for tracking loop status 3. **setup.sh** - Project initialization script for new Ralph projects 4. **create_files.sh** - Bootstrap script that creates the entire Ralph system 5. **ralph_import.sh** - PRD/specification import tool that converts documents to Ralph format - Uses modern Claude Code CLI with `--output-format json` for structured responses - Implements `detect_response_format()` and `parse_conversion_response()` for JSON parsing - Backward compatible with older CLI versions (automatic text fallback) 6. **ralph_enable.sh** - Interactive wizard for enabling Ralph in existing projects - Multi-step wizard with environment detection, task source selection, configuration - Imports tasks from beads, GitHub Issues, or PRD documents - Generates `.ralphrc` project configuration file 7. **ralph_enable_ci.sh** - Non-interactive version for CI/automation - Same functionality as interactive version with CLI flags - JSON output mode for machine parsing - Exit codes: 0 (success), 1 (error), 2 (already enabled) ### Library Components (lib/) The system uses a modular architecture with reusable components in the `lib/` directory: 1. **lib/circuit_breaker.sh** - Circuit breaker pattern implementation - Prevents runaway loops by detecting stagnation - Three states: CLOSED (normal), HALF_OPEN (monitoring), OPEN (halted) - Configurable thresholds for no-progress and error detection - Automatic state transitions and recovery 2. **lib/response_analyzer.sh** - Intelligent response analysis - Analyzes Claude Code output for completion signals - **JSON output format detection and parsing** (with text fallback) - Supports both flat JSON format and Claude CLI format (`result`, `sessionId`, `metadata`) - Extracts structured fields: status, exit_signal, work_type, files_modified, asking_questions, question_count - **Question detection**: `detect_questions()` with `QUESTION_PATTERNS` array — detects when Claude asks questions instead of acting autonomously (Issue #190) - **Session management**: `store_session_id()`, `get_last_session_id()`, `should_resume_session()` - Automatic session persistence to `.ralph/.claude_session_id` file with 24-hour expiration - Session lifecycle: `get_session_id()`, `reset_session()`, `log_session_transition()`, `init_session_tracking()` - Session history tracked in `.ralph/.ralph_session_history` (last 50 transitions) - Session auto-reset on: circuit breaker open, manual interrupt, project completion - Detects test-only loops, stuck error patterns, and question-only loops - Two-stage error filtering to eliminate false positives - Multi-line error matching for accurate stuck loop detection - **Mode-specific heuristic exit**: In JSON mode, heuristics are suppressed entirely — only an explicit `EXIT_SIGNAL: true` in a RALPH_STATUS block can set `exit_signal=true` (Issue #224). In text mode, exit requires `confidence_score >= 70` AND `has_completion_signal=true` (raised from the old `>= 40 OR has_completion_signal` to prevent documentation keywords like "setup is done" from triggering false-positive exits). 3. **lib/date_utils.sh** - Cross-platform date utilities - ISO timestamp generation for logging - Epoch time calculations for rate limiting - ISO-to-epoch conversion for cooldown timer comparisons (`parse_iso_to_epoch()`) 4. **lib/timeout_utils.sh** - Cross-platform timeout command utilities - Detects and uses appropriate timeout command for the platform - Linux: Uses standard `timeout` from GNU coreutils - macOS: Uses `gtimeout` from Homebrew coreutils - `portable_timeout()` function for seamless cross-platform execution - Automatic detection with caching for performance 5. **lib/enable_core.sh** - Shared logic for ralph enable commands - Idempotency checks: `check_existing_ralph()`, `is_ralph_enabled()` - Safe file operations: `safe_create_file()`, `safe_create_dir()` - Project detection: `detect_project_context()`, `detect_git_info()`, `detect_task_sources()` - Template generation: `generate_prompt_md()`, `generate_agent_md()`, `generate_fix_plan_md()`, `generate_ralphrc()` 6. **lib/wizard_utils.sh** - Interactive prompt utilities for enable wizard - User prompts: `confirm()`, `prompt_text()`, `prompt_number()` - Selection utilities: `select_option()`, `select_multiple()`, `select_with_default()` - Output formatting: `print_header()`, `print_bullet()`, `print_success/warning/error/info()` - POSIX-compatible: Uses `tr '[:upper:]' '[:lower:]'` instead of `${,,}` for bash 3.x support (Issue #187) 7. **lib/task_sources.sh** - Task import from external sources - Beads integration: `check_beads_available()`, `fetch_beads_tasks()`, `get_beads_count()` - GitHub integration: `check_github_available()`, `fetch_github_tasks()`, `get_github_issue_count()` - PRD extraction: `extract_prd_tasks()`, supports checkbox and numbered list formats - Task normalization: `normalize_tasks()`, `prioritize_tasks()`, `import_tasks_from_sources()` 8. **lib/file_protection.sh** - File integrity validation for Ralph projects (Issue #149) - `RALPH_REQUIRED_PATHS` array: critical files needed for the loop to function - `validate_ralph_integrity()`: checks all required paths exist, sets `RALPH_MISSING_FILES` - `get_integrity_report()`: human-readable report with missing files and recovery instructions - Lightweight validation that runs every loop iteration 9. **lib/log_utils.sh** - Log management utilities (Issue #18) - `rotate_logs()`: rotates `$LOG_DIR/ralph.log` at 10MB, keeping 4 archived files (`.log.1`–`.log.4`) - Cross-platform `stat` support: GNU (`stat -c%s`) with BSD (`stat -f%z`) fallback ## Key Commands ### Installation ```bash # Install Ralph globally (run once) ./install.sh # Uninstall Ralph ./install.sh uninstall ``` ### Setting Up a New Project ```bash # Create a new Ralph-managed project (run from anywhere) ralph-setup my-project-name cd my-project-name ``` ### Migrating Existing Projects ```bash # Migrate from flat structure to .ralph/ subfolder (v0.10.0+) cd existing-project ralph-migrate ``` ### Enabling Ralph in Existing Projects ```bash # Interactive wizard (recommended for humans) cd existing-project ralph-enable # With specific task source ralph-enable --from beads ralph-enable --from github --label "sprint-1" ralph-enable --from prd ./docs/requirements.md # Force overwrite existing .ralph/ ralph-enable --force # Non-interactive for CI/scripts ralph-enable-ci # Sensible defaults ralph-enable-ci --from github # With task source ralph-enable-ci --project-type typescript # Override detection ralph-enable-ci --json # Machine-readable output ``` ### Running the Ralph Loop ```bash # Start with integrated tmux monitoring (recommended) ralph --monitor # Start without monitoring ralph # With custom parameters and monitoring ralph --monitor --calls 50 --prompt my_custom_prompt.md # Check current status ralph --status # Circuit breaker management ralph --reset-circuit ralph --circuit-status ralph --auto-reset-circuit # Auto-reset OPEN state on startup # Session management ralph --reset-session # Reset session state manually # Backup and rollback (requires git; Issue #23) ralph --backup # Enable automatic backup before each loop ralph -b # Short form of --backup ralph --rollback # List available backup branches ralph --rollback ralph-backup-loop-3-1775155286 # Roll back to a specific backup ``` ### Monitoring ```bash # Integrated tmux monitoring (recommended) ralph --monitor # Manual monitoring in separate terminal ralph-monitor # tmux session management tmux list-sessions tmux attach -t ``` ### Running Tests ```bash # Run all tests npm test # Run specific test suites npm run test:unit npm run test:integration # Run individual test files bats tests/unit/test_cli_parsing.bats bats tests/unit/test_json_parsing.bats bats tests/unit/test_cli_modern.bats bats tests/unit/test_enable_core.bats bats tests/unit/test_task_sources.bats bats tests/unit/test_ralph_enable.bats bats tests/unit/test_circuit_breaker_recovery.bats bats tests/unit/test_file_protection.bats bats tests/unit/test_integrity_check.bats ``` ## Ralph Loop Configuration The loop is controlled by several key files and environment variables within the `.ralph/` subfolder: - **.ralph/PROMPT.md** - Main prompt file that drives each loop iteration - **.ralph/fix_plan.md** - Prioritized task list that Ralph follows - **.ralph/AGENT.md** - Build and run instructions maintained by Ralph - **.ralph/status.json** - Real-time status tracking (JSON format) - **.ralph/logs/** - Execution logs for each loop iteration ### Rate Limiting - Default: 100 API calls per hour (configurable via `--calls` flag) - Optional token limit per hour via `MAX_TOKENS_PER_HOUR` in `.ralphrc` (0 = disabled, default) - Extracts `input_tokens + output_tokens` from each Claude response (both stream-json and CLI formats) - Blocks further calls once the hourly token budget is exhausted - Counters reset together on the hour - Automatic hourly reset with countdown display - Call and token tracking persists across script restarts ### Modern CLI Configuration (Phase 1.1) Ralph uses modern Claude Code CLI flags for structured communication: **Configuration Variables:** ```bash CLAUDE_CODE_CMD="claude" # Claude Code CLI command (configurable via .ralphrc, Issue #97) CLAUDE_OUTPUT_FORMAT="json" # Output format: json (default) or text CLAUDE_ALLOWED_TOOLS="Write,Read,Edit,Bash(git add *),Bash(git commit *),...,Bash(npm *),Bash(pytest)" # Allowed tool permissions (see File Protection) CLAUDE_USE_CONTINUE=true # Enable session continuity CLAUDE_MIN_VERSION="2.0.76" # Minimum Claude CLI version CLAUDE_AUTO_UPDATE=true # Auto-update Claude CLI at startup (set false for air-gapped environments) CLAUDE_MODEL="" # Model override (e.g. claude-sonnet-4-6); empty = CLI default (Issue #228) CLAUDE_EFFORT="" # Effort level override (e.g. high, low); empty = CLI default (Issue #228) ENABLE_NOTIFICATIONS=false # Desktop notifications (Issue #22); set true or use --notify / -n flag ENABLE_BACKUP=false # Automatic git backup branches (Issue #23); set true or use --backup / -b flag ``` **Auto-Update Configuration:** - `CLAUDE_AUTO_UPDATE` controls whether Ralph checks npm registry and attempts `npm update -g` at startup - **Local workstation / home server**: Keep `true` (default) — CLI updates include bug fixes and new features that improve Ralph's effectiveness. The 200-500ms startup overhead is negligible for loops that run hours - **Docker container**: Set `false` in `.ralphrc` — container is ephemeral and version is pinned at image build time. The npm registry query and potential update are pure overhead - **Air-gapped environment**: Set `false` — npm registry is unreachable, the check will timeout and log a warning - Update failure is non-blocking: Ralph logs a warning and continues the loop normally **Claude Code CLI Command (Issue #97):** - `CLAUDE_CODE_CMD` defaults to `"claude"` (global install) - Configurable via `.ralphrc` for alternative installations (e.g., `"npx @anthropic-ai/claude-code"`) - Auto-detected during `ralph-enable` and `ralph-setup` (prefers `claude` if available, falls back to npx) - Validated at startup with `validate_claude_command()` — displays clear error with installation instructions if not found - After validation, `check_claude_version()` verifies minimum version compatibility and `check_claude_updates()` queries npm registry for latest version with auto-update attempt (Issue #190) - Both functions use `compare_semver()` for proper major→minor→patch sequential comparison (safe for any patch number, unlike integer arithmetic) - Environment variable `CLAUDE_CODE_CMD` takes precedence over `.ralphrc` **Model and Effort Overrides (Issue #228):** - `CLAUDE_MODEL` sets the `--model` flag on every Claude invocation (e.g., `CLAUDE_MODEL=claude-sonnet-4-6`). Leave empty to use the CLI's default model. - `CLAUDE_EFFORT` sets the `--effort` flag (e.g., `CLAUDE_EFFORT=high` or `CLAUDE_EFFORT=low`). Leave empty to use the CLI's default. - Both variables can be set in `.ralphrc` or as environment variables. The environment variable takes precedence over `.ralphrc`. **CLI Options:** - `--output-format json|text` - Set Claude output format (default: json). Note: `--live` mode requires JSON and will auto-switch from text to json. - `--allowed-tools "Write,Read,Bash(git *)"` - Restrict allowed tools - `--no-continue` - Disable session continuity, start fresh each loop **Loop Context:** Each loop iteration injects context via `build_loop_context()`: - Current loop number - Remaining tasks from fix_plan.md - Circuit breaker state (if not CLOSED) - Previous loop work summary - Corrective guidance if previous loop detected questions (Issue #190) **Session Continuity:** - Sessions are preserved in `.ralph/.claude_session_id` - Use `--continue` flag to maintain context across loops - Disable with `--no-continue` for isolated iterations ### Intelligent Exit Detection The loop uses a dual-condition check to prevent premature exits during productive iterations: **Exit requires BOTH conditions:** 1. `recent_completion_indicators >= 2` (heuristic-based detection from natural language patterns) 2. Claude's explicit `EXIT_SIGNAL: true` in the RALPH_STATUS block The `EXIT_SIGNAL` value is read from `.ralph/.response_analysis` (at `.analysis.exit_signal`) which is populated by `response_analyzer.sh` from Claude's RALPH_STATUS output block. **Other exit conditions (checked before completion indicators):** - Multiple consecutive "done" signals from Claude Code (`done_signals >= 2`) - Too many test-only loops indicating feature completeness (`test_loops >= 3`) - All items in .ralph/fix_plan.md marked as completed **Example behavior when EXIT_SIGNAL is false:** ``` Loop 5: Claude outputs "Phase complete, moving to next feature" → completion_indicators: 3 (high confidence from patterns) → EXIT_SIGNAL: false (Claude explicitly says more work needed) → Result: CONTINUE (respects Claude's explicit intent) Loop 8: Claude outputs "All tasks complete, project ready" → completion_indicators: 4 → EXIT_SIGNAL: true (Claude confirms project is done) → Result: EXIT with "project_complete" ``` **Rationale:** Natural language patterns like "done" or "complete" can trigger false positives during productive work (e.g., writing a CHANGELOG entry that says "implementation complete"). Two defences are layered: - **JSON mode** (default): heuristics are suppressed entirely. Only an explicit `EXIT_SIGNAL: true` inside a RALPH_STATUS block triggers exit. Completion keywords in tool output or generated docs are ignored (Issue #224). - **Text mode**: requires `confidence_score >= 70` AND `has_completion_signal=true` before setting `exit_signal=true`. The old threshold (`>= 40 OR has_completion_signal`) was too sensitive to documentation language (Issue #224). ## CI/CD Pipeline Ralph uses GitHub Actions for continuous integration: ### Workflows (`.github/workflows/`) 1. **test.yml** - Main test suite - Runs on push to `main`/`develop` and PRs to `main` - Executes unit, integration, and E2E tests - Coverage reporting with kcov (informational only) - Uploads coverage artifacts 2. **claude.yml** - Claude Code GitHub Actions integration - Automated code review capabilities 3. **claude-code-review.yml** - PR code review workflow - Automated review on pull requests ### Coverage Note Bash code coverage measurement with kcov has fundamental limitations when tracing subprocess executions. The `COVERAGE_THRESHOLD` is set to 0 (disabled) because kcov cannot instrument subprocesses spawned by bats. **Test pass rate (100%) is the quality gate.** See [bats-core#15](https://github.com/bats-core/bats-core/issues/15) for details. ## Project Structure for Ralph-Managed Projects Each project created with `./setup.sh` follows this structure with a `.ralph/` subfolder: ``` project-name/ ├── .ralph/ # Ralph configuration and state (hidden folder) │ ├── PROMPT.md # Main development instructions │ ├── fix_plan.md # Prioritized TODO list │ ├── AGENT.md # Build/run instructions │ ├── specs/ # Project specifications │ ├── examples/ # Usage examples │ ├── logs/ # Loop execution logs │ └── docs/generated/ # Auto-generated documentation └── src/ # Source code (at project root) ``` > **Migration**: Existing projects can be migrated with `ralph-migrate`. ## Template System Templates in `templates/` provide starting points for new projects: - **PROMPT.md** - Instructions for Ralph's autonomous behavior - **fix_plan.md** - Initial task structure - **AGENT.md** - Build system template ## File Naming Conventions - Ralph control files (`fix_plan.md`, `AGENT.md`, `PROMPT.md`) reside in the `.ralph/` directory - Hidden files within `.ralph/` (e.g., `.ralph/.call_count`, `.ralph/.exit_signals`) track loop state - `.ralph/logs/` contains timestamped execution logs - `.ralph/docs/generated/` for Ralph-created documentation - `docs/code-review/` for code review reports (at project root) ## Global Installation Ralph installs to: - **Commands**: `~/.local/bin/` (ralph, ralph-monitor, ralph-setup, ralph-import, ralph-migrate, ralph-enable, ralph-enable-ci, ralph-stats) - **Templates**: `~/.ralph/templates/` - **Scripts**: `~/.ralph/` (ralph_loop.sh, ralph_monitor.sh, setup.sh, ralph_import.sh, migrate_to_ralph_folder.sh, ralph_enable.sh, ralph_enable_ci.sh, ralph-stats.sh) - **Libraries**: `~/.ralph/lib/` (circuit_breaker.sh, response_analyzer.sh, date_utils.sh, timeout_utils.sh, enable_core.sh, wizard_utils.sh, task_sources.sh, file_protection.sh) After installation, the following global commands are available: - `ralph` - Start the autonomous development loop - `ralph-monitor` - Launch the monitoring dashboard - `ralph-setup` - Create a new Ralph-managed project - `ralph-import` - Import PRD/specification documents to Ralph format - `ralph-migrate` - Migrate existing projects from flat structure to `.ralph/` subfolder - `ralph-enable` - Interactive wizard to enable Ralph in existing projects - `ralph-enable-ci` - Non-interactive version for CI/automation - `ralph-stats` - Show metrics summary for loop execution analytics ## Integration Points Ralph integrates with: - **Claude Code CLI**: Uses `npx @anthropic/claude-code` as the execution engine - **tmux**: Terminal multiplexer for integrated monitoring sessions - **Git**: Expects projects to be git repositories - **jq**: For JSON processing of status and exit signals - **GitHub Actions**: CI/CD pipeline for automated testing - **Standard Unix tools**: bash, grep, date, etc. ## Exit Conditions and Thresholds Ralph uses multiple mechanisms to detect when to exit: ### Exit Detection Thresholds - `MAX_CONSECUTIVE_TEST_LOOPS=3` - Exit if too many test-only iterations - `MAX_CONSECUTIVE_DONE_SIGNALS=2` - Exit on repeated completion signals - `TEST_PERCENTAGE_THRESHOLD=30%` - Flag if testing dominates recent loops - Completion detection via .ralph/fix_plan.md checklist items ### Startup State Reset (Issue #194) Every new `ralph` invocation unconditionally resets `.exit_signals` and removes `.response_analysis` **before** the main loop begins. This prevents stale completion signals from a prior run (crash, SIGKILL, API-limit exit) from triggering `should_exit_gracefully()` on the first iteration before any Claude execution occurs. The API-limit "user chose exit" path also calls `reset_session()` to clean up state. ### Completion Indicators with EXIT_SIGNAL Gate The `completion_indicators` exit condition requires dual verification: | completion_indicators | EXIT_SIGNAL | .response_analysis | Result | |-----------------------|-------------|-------------------|--------| | >= 2 | `true` | exists | **Exit** ("project_complete") | | >= 2 | `false` | exists | **Continue** (Claude still working) | | >= 2 | N/A | missing | **Continue** (defaults to false) | | >= 2 | N/A | malformed | **Continue** (defaults to false) | | < 2 | `true` | exists | **Continue** (threshold not met) | **Implementation** (`ralph_loop.sh:312-327`): ```bash local claude_exit_signal="false" if [[ -f "$RALPH_DIR/.response_analysis" ]]; then claude_exit_signal=$(jq -r '.analysis.exit_signal // false' "$RALPH_DIR/.response_analysis" 2>/dev/null || echo "false") fi if [[ $recent_completion_indicators -ge 2 ]] && [[ "$claude_exit_signal" == "true" ]]; then echo "project_complete" return 0 fi ``` **Conflict Resolution:** When `STATUS: COMPLETE` but `EXIT_SIGNAL: false` in RALPH_STATUS, the explicit EXIT_SIGNAL takes precedence. This allows Claude to mark a phase complete while indicating more phases remain. ### Timeout Handling (Issues #175, #198) When Claude Code exceeds `CLAUDE_TIMEOUT_MINUTES`, `portable_timeout` terminates the process with exit code **124**. The loop handles this differently depending on the execution mode: **Live mode** (`--live`/`--monitor`): The streaming pipeline captures per-command exit codes via `PIPESTATUS`. Timeout events are logged as a WARN: ```text [timestamp] [WARN] Claude Code execution timed out after 15 minutes ``` **Background mode** (default): The Claude process runs in a background subshell (`&`). The exit code is captured via `wait $claude_pid`. **Productive Timeout Detection (Issue #198):** In both modes, when exit code 124 is detected, the timeout handler checks git for actual work done during the execution (comparing HEAD to `.loop_start_sha`). This prevents treating productive timeouts as failures: | Timeout + Git State | Result | |---|---| | Files changed (committed/staged/unstaged) | **Productive timeout**: runs full analysis pipeline (`save_claude_session`, `analyze_response`, `update_exit_signals`, `record_loop_result`), writes `timed_out_productive` status, returns 0 | | No files changed | **Idle timeout**: returns 1 (generic error) | **Session ID Fallback:** When the stream is truncated (missing `"type":"result"` message), session ID is extracted from the `"type":"system"` message, which is always written first and survives truncation. ### API Limit Detection (Issues #183, #100) The API limit detection uses a four-layer approach to avoid false positives. In stream-json mode, output files contain echoed file content from tool results (`"type":"user"` lines). If project files mention "5-hour limit", naive grep patterns match those echoed strings, incorrectly triggering the API limit recovery flow. **Layer 1 — Timeout guard:** Exit code 124 (timeout) is checked first. Productive timeouts (files changed) return 0; idle timeouts return 1 (generic error). Neither returns code 2 (API limit). **Layer 2 — Structural JSON detection (primary):** Parses `rate_limit_event` JSON in the output for `"status":"rejected"`. This is the definitive signal from the Claude CLI. **Layer 3 — Filtered text fallback:** Only searches `tail -30` of the output file, filtering out `"type":"user"`, `"tool_result"`, and `"tool_use_id"` lines before matching text patterns for standard 5-hour limit messages. **Layer 4 — Extra Usage quota (Issue #100):** Detects Claude Code "Extra Usage" mode exhaustion (`"You're out of extra usage · resets 9pm"`). Uses the same noise filtering as Layer 3. **Unattended mode:** When the API limit prompt times out (no user response within 30s), Ralph auto-waits instead of exiting, supporting unattended operation. ### Circuit Breaker Thresholds - `CB_NO_PROGRESS_THRESHOLD=3` - Open circuit after 3 loops with no file changes - `CB_SAME_ERROR_THRESHOLD=5` - Open circuit after 5 loops with repeated errors - `CB_OUTPUT_DECLINE_THRESHOLD=70%` - Open circuit if output declines by >70% - `CB_PERMISSION_DENIAL_THRESHOLD=2` - Open circuit after 2 loops with permission denials (Issue #101) - **Question loop suppression** (Issue #190): When `asking_questions=true`, the `consecutive_no_progress` counter is held steady (not incremented). This prevents the circuit breaker from opening prematurely when Claude asks questions in headless mode. A corrective message is injected via `build_loop_context()` in the next loop iteration. ### Circuit Breaker Auto-Recovery (Issue #160) The OPEN state is no longer terminal. Two recovery mechanisms are available: **Cooldown Timer (default):** After `CB_COOLDOWN_MINUTES` (default: 30) in OPEN state, the circuit transitions to HALF_OPEN on next `init_circuit_breaker()` call. The existing HALF_OPEN logic handles recovery (progress → CLOSED) or re-trip (no progress → OPEN). **Auto-Reset:** When `CB_AUTO_RESET=true`, the circuit resets directly to CLOSED on startup, bypassing the cooldown. Use for fully unattended operation. **Configuration:** ```bash CB_COOLDOWN_MINUTES=30 # Minutes before OPEN → HALF_OPEN (0 = immediate) CB_AUTO_RESET=false # true = bypass cooldown, reset to CLOSED on startup ``` **CLI flag:** `ralph --auto-reset-circuit` sets `CB_AUTO_RESET=true` for a single run. **State file:** The `opened_at` field tracks when the circuit entered OPEN state. Old state files without this field fall back to `last_change` for backward compatibility. ### Permission Denial Detection (Issue #101) When Claude Code is denied permission to execute commands (e.g., `npm install`), Ralph detects this from the `permission_denials` array in the JSON output and halts the loop immediately: 1. **Detection**: The `parse_json_response()` function extracts `permission_denials` from Claude Code output 2. **Fields tracked**: - `has_permission_denials` (boolean) - `permission_denial_count` (integer) - `denied_commands` (array of command strings) 3. **Exit behavior**: When `has_permission_denials=true`, Ralph exits with reason "permission_denied" 4. **User guidance**: Ralph displays instructions to update `ALLOWED_TOOLS` in `.ralphrc` **Example `.ralphrc` tool patterns:** ```bash # Broad patterns (recommended for development) ALLOWED_TOOLS="Write,Read,Edit,Bash(git *),Bash(npm *),Bash(pytest)" # Specific patterns (more restrictive) ALLOWED_TOOLS="Write,Read,Edit,Bash(git commit),Bash(npm install)" ``` ### API Error Detection via `is_error` Field (Issues #134, #199) The Claude CLI can exit with code 0 but set `is_error: true` in the JSON output for API-level failures (400 concurrency errors, 401 OAuth token expiry). Ralph detects this before persisting any session state: 1. **Detection**: In `execute_claude_code()`, after exit code 0, `jq` reads `.is_error` from the output JSON 2. **Session protection**: If `is_error` is true, the session is NOT persisted (prevents infinite retry with bad session ID) 3. **Session reset**: The session is explicitly reset so the next loop starts fresh 4. **Specific handling**: "tool use concurrency" errors get a targeted reset reason for logging clarity 5. **Defense in depth**: `save_claude_session()` independently checks `is_error` as a guard, preventing bad sessions even if call order changes in refactors ### Error Detection Ralph uses advanced error detection with two-stage filtering to eliminate false positives: **Stage 1: JSON Field Filtering** - Filters out JSON field patterns like `"is_error": false` that contain the word "error" but aren't actual errors - Pattern: `grep -v '"[^"]*error[^"]*":'` **Stage 2: Actual Error Detection** - Detects real error messages in specific contexts: - Error prefixes: `Error:`, `ERROR:`, `error:` - Context-specific errors: `]: error`, `Link: error` - Error occurrences: `Error occurred`, `failed with error` - Exceptions: `Exception`, `Fatal`, `FATAL` - Pattern: `grep -cE '(^Error:|^ERROR:|^error:|\]: error|Link: error|Error occurred|failed with error|[Ee]xception|Fatal|FATAL)'` **Multi-line Error Matching** - Detects stuck loops by verifying ALL error lines appear in ALL recent history files - Uses literal fixed-string matching (`grep -qF`) to avoid regex edge cases - Prevents false negatives when multiple distinct errors occur simultaneously ### File Protection (Issue #149) Ralph uses a multi-layered strategy to prevent Claude from accidentally deleting its own configuration files: **Layer 1: ALLOWED_TOOLS Restriction** - The default `CLAUDE_ALLOWED_TOOLS` uses granular `Bash(git add *)`, `Bash(git commit *)` etc. instead of `Bash(git *)`, preventing `git clean`, `git rm`, and other destructive git commands - Users can override in `.ralphrc` but the defaults are safe **Layer 2: PROMPT.md Warning** - The PROMPT.md template includes a "Protected Files (DO NOT MODIFY)" section listing `.ralph/` and `.ralphrc` - This instructs Claude to never delete, move, rename, or overwrite these files **Layer 3: Pre-Loop Integrity Check** - `validate_ralph_integrity()` from `lib/file_protection.sh` runs at startup and before every loop iteration - Checks for required paths: `.ralph/`, `.ralph/PROMPT.md`, `.ralph/fix_plan.md`, `.ralph/AGENT.md`, `.ralphrc` - On failure: logs error, displays recovery report, resets session, and halts the loop - Recovery: `ralph-enable --force` restores missing files **Required vs Optional Files:** | Required (validation fails) | Optional (no validation) | |---|---| | `.ralph/` directory | `.ralph/logs/` | | `.ralph/PROMPT.md` | `.ralph/status.json` | | `.ralph/fix_plan.md` | `.ralph/.call_count` | | `.ralph/AGENT.md` | `.ralph/.exit_signals` | | `.ralphrc` | `.ralph/.circuit_breaker_state` | ## Test Suite ### Test Files (483 unit tests + integration; see `npm test` for current count) | File | Tests | Description | |------|-------|-------------| | `test_circuit_breaker_recovery.bats` | 22 | Cooldown timer, auto-reset, parse_iso_to_epoch, CLI flag (Issue #160) + current_loop init/display fix (#194) | | `test_cli_parsing.bats` | 35 | CLI argument parsing for all flags + monitor parameter forwarding | | `test_cli_modern.bats` | 111 | Modern CLI commands (Phase 1.1) + build_claude_command fix + live mode text format fix (#164) + errexit pipeline guard (#175) + ALLOWED_TOOLS tightening (#149) + API limit false positive detection (#183) + Claude CLI command validation (#97) + stale call counter fix (#196) + is_error detection (#134, #199) + set-e removal (#208) + question detection + version check + semver comparison + stderr separation (#190) + productive timeout detection + session ID fallback + stale analysis cleanup (#198) + Extra Usage quota detection (#100) | | `test_json_parsing.bats` | 56 | JSON output format parsing + Claude CLI format + session management + array format + question detection (#190) + heuristic exit threshold tests (#224) | | `test_session_continuity.bats` | 26 | Session lifecycle management + expiration + circuit breaker integration + issue #91 fix | | `test_exit_detection.bats` | 54 | Exit signal detection + EXIT_SIGNAL-based completion indicators + progress detection + question detection integration (#190) + stale exit signal prevention (#194) | | `test_rate_limiting.bats` | 25 | Rate limiting behavior including token-based limiting (Issue #223) | | `test_loop_execution.bats` | 20 | Integration tests | | `test_edge_cases.bats` | 25 | Edge case handling | | `test_installation.bats` | 15 | Global installation/uninstall workflows + dotfile template copying (#174) | | `test_project_setup.bats` | 50 | Project setup (setup.sh) validation + .ralphrc permissions + .gitignore (#174) | | `test_prd_import.bats` | 33 | PRD import (ralph_import.sh) workflows + modern CLI tests | | `test_enable_core.bats` | 38 | Enable core library (idempotency, project detection, template generation, .gitignore #174) | | `test_task_sources.bats` | 23 | Task sources (beads, GitHub, PRD extraction, normalization) | | `test_ralph_enable.bats` | 24 | Ralph enable integration tests (wizard, CI version, JSON output, .ralphrc validation #149) | | `test_wizard_utils.bats` | 20 | Wizard utility functions (stdout/stderr separation, prompt functions) | | `test_file_protection.bats` | 15 | File integrity validation (RALPH_REQUIRED_PATHS, validate_ralph_integrity, get_integrity_report) (Issue #149) | | `test_integrity_check.bats` | 10 | Pre-loop integrity check in ralph_loop.sh (startup + in-loop validation) (Issue #149) | | `test_log_rotation.bats` | 5 | Log rotation (rotate_logs in lib/log_utils.sh): threshold, shift order, content assertions, missing file, stat fallback (Issue #18) | | `test_metrics_tracking.bats` | 4 | Metrics tracking: track_metrics() JSON Lines format, per-loop append, ralph-stats output, print_metrics_summary (Issue #21) | | `test_notifications.bats` | 5 | Desktop notifications: send_notification() cross-platform (macOS/Linux/bell), disabled by default, --notify flag (Issue #22) | | `test_backup_rollback.bats` | 6 | Backup/rollback: create_backup() branch naming, disabled by default, graceful git-less handling, commit message, --backup flag, rollback_to_backup() checkout (Issue #23) | ### Running Tests ```bash # All tests npm test # Unit tests only npm run test:unit # Specific test file bats tests/unit/test_cli_parsing.bats ``` ## Feature Development Quality Standards **CRITICAL**: All new features MUST meet the following mandatory requirements before being considered complete. ### Testing Requirements - **Test Pass Rate**: 100% - all tests must pass, no exceptions - **Test Types Required**: - Unit tests for bash script functions (if applicable) - Integration tests for Ralph loop behavior - End-to-end tests for full development cycles - **Test Quality**: Tests must validate behavior, not just achieve coverage metrics - **Test Documentation**: Complex test scenarios must include comments explaining the test strategy > **Note on Coverage**: The 85% coverage threshold is aspirational for bash scripts. Due to kcov subprocess limitations, test pass rate is the enforced quality gate. ### E2E Testing Philosophy (v2 UI) When Ralph introduces a web-based UI (v2), end-to-end testing is the primary quality gate for all frontend work: - **Framework**: Playwright for all browser automation and E2E tests - **Real services only**: E2E tests run against real backends — no mocked APIs or stubbed services - **User journey coverage**: Every user-facing workflow must have at least one E2E test covering the happy path - **Visual regression**: Use Playwright screenshot comparisons for layout-critical components - **Accessibility**: Include automated a11y checks (e.g., `@axe-core/playwright`) in E2E runs - **CI integration**: E2E tests must pass in the GitHub Actions pipeline before merge ### Git Workflow Requirements Before moving to the next feature, ALL changes must be: 1. **Committed with Clear Messages**: ```bash git add . git commit -m "feat(module): descriptive message following conventional commits" ``` - Use conventional commit format: `feat:`, `fix:`, `docs:`, `test:`, `refactor:`, etc. - Include scope when applicable: `feat(loop):`, `fix(monitor):`, `test(setup):` - Write descriptive messages that explain WHAT changed and WHY 2. **Pushed to Remote Repository**: ```bash git push origin ``` - Never leave completed features uncommitted - Push regularly to maintain backup and enable collaboration - Ensure CI/CD pipelines pass before considering feature complete 3. **Branch Hygiene**: - Work on feature branches, never directly on `main` - Branch naming convention: `feature/`, `fix/`, `docs/` - Create pull requests for all significant changes 4. **Ralph Integration**: - Update .ralph/fix_plan.md with new tasks before starting work - Mark items complete in .ralph/fix_plan.md upon completion - Update .ralph/PROMPT.md if Ralph's behavior needs modification - Test Ralph loop with new features before completion ### Documentation Requirements **ALL implementation documentation MUST remain synchronized with the codebase**: 1. **Script Documentation**: - Bash: Comments for all functions and complex logic - Update inline comments when implementation changes - Remove outdated comments immediately 2. **Implementation Documentation**: - Update relevant sections in this CLAUDE.md file - Keep template files in `templates/` current - Update configuration examples when defaults change - Document breaking changes prominently 3. **README Updates**: - Keep feature lists current - Update setup instructions when commands change - Maintain accurate command examples - Update version compatibility information 4. **Template Maintenance**: - Update template files when new patterns are introduced - Keep PROMPT.md template current with best practices - Update AGENT.md template with new build patterns - Document new Ralph configuration options 5. **CLAUDE.md Maintenance**: - Add new commands to "Key Commands" section - Update "Exit Conditions and Thresholds" when logic changes - Keep installation instructions accurate and tested - Document new Ralph loop behaviors or quality gates ### Feature Completion Checklist Before marking ANY feature as complete, verify: - [ ] All tests pass (if applicable) - [ ] Script functionality manually tested - [ ] All changes committed with conventional commit messages - [ ] All commits pushed to remote repository - [ ] CI/CD pipeline passes - [ ] .ralph/fix_plan.md task marked as complete - [ ] Implementation documentation updated - [ ] Inline code comments updated or added - [ ] CLAUDE.md updated (if new patterns introduced) - [ ] Template files updated (if applicable) - [ ] Breaking changes documented - [ ] Ralph loop tested with new features - [ ] Installation process verified (if applicable) ### Rationale These standards ensure: - **Quality**: Thorough testing prevents regressions in Ralph's autonomous behavior - **Traceability**: Git commits and fix_plan.md provide clear history of changes - **Maintainability**: Current documentation reduces onboarding time and prevents knowledge loss - **Collaboration**: Pushed changes enable team visibility and code review - **Reliability**: Consistent quality gates maintain Ralph loop stability - **Automation**: Ralph integration ensures continuous development practices **Enforcement**: AI agents should automatically apply these standards to all feature development tasks without requiring explicit instruction for each task. ## README.md # Ralph for Claude Code [![CI](https://github.com/frankbria/ralph-claude-code/actions/workflows/test.yml/badge.svg)](https://github.com/frankbria/ralph-claude-code/actions/workflows/test.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) ![Version](https://img.shields.io/badge/version-0.11.5-blue) ![Tests](https://img.shields.io/badge/tests-556%20passing-green) [![GitHub Issues](https://img.shields.io/github/issues/frankbria/ralph-claude-code)](https://github.com/frankbria/ralph-claude-code/issues) [![Mentioned in Awesome Claude Code](https://awesome.re/mentioned-badge.svg)](https://github.com/hesreallyhim/awesome-claude-code) [![Follow on X](https://img.shields.io/twitter/follow/FrankBria18044?style=social)](https://x.com/FrankBria18044) > **Autonomous AI development loop with intelligent exit detection and rate limiting** Ralph is an implementation of the Geoffrey Huntley's technique for Claude Code that enables continuous autonomous development cycles he named after [Ralph Wiggum](https://ghuntley.com/ralph/). It enables continuous autonomous development cycles where Claude Code iteratively improves your project until completion, with built-in safeguards to prevent infinite loops and API overuse. **Install once, use everywhere** - Ralph becomes a global command available in any directory. ## Project Status **Version**: v0.11.5 - Active Development **Core Features**: Working and tested **Test Coverage**: 566 tests, 100% pass rate ### What's Working Now - Autonomous development loops with intelligent exit detection - **Dual-condition exit gate**: Requires BOTH completion indicators AND explicit EXIT_SIGNAL - Rate limiting with hourly reset (100 calls/hour, configurable) - Circuit breaker with advanced error detection (prevents runaway loops) - Response analyzer with semantic understanding and two-stage error filtering - **JSON output format support with automatic fallback to text parsing** - **Session continuity with `--resume` flag for context preservation (no session hijacking)** - **Session expiration with configurable timeout (default: 24 hours)** - **Modern CLI flags: `--output-format`, `--allowed-tools`, `--no-continue`** - **Interactive project enablement with `ralph-enable` wizard** - **`.ralphrc` configuration file for project settings** - **Live streaming output with `--live` flag for real-time Claude Code visibility** - Multi-line error matching for accurate stuck loop detection - 5-hour API limit handling with user prompts - tmux integration for live monitoring - PRD import functionality - **CI/CD pipeline with GitHub Actions** - **Dedicated uninstall script for clean removal** ### Recent Improvements **v0.11.5 - Community Bug Fixes** (latest) - Fixed API limit false positive: Timeout (exit code 124) no longer misidentified as API 5-hour limit (#183) - Three-layer API limit detection: timeout guard → structural JSON (`rate_limit_event`) → filtered text fallback - Unattended mode: API limit prompt now auto-waits on timeout instead of exiting - Fixed bash 3.x compatibility: `${,,}` lowercase substitution replaced with POSIX `tr` (#187) - Added 8 new tests for API limit detection (548 → 566 tests) **v0.11.4 - Bug Fixes & Compatibility** - Fixed progress detection: Git commits within a loop now count as progress (#141) - Fixed checkbox regex: Date entries `[2026-01-29]` no longer counted as checkboxes (#144) - Fixed session hijacking: Use `--resume ` instead of `--continue` (#151) - Fixed EXIT_SIGNAL override: `STATUS: COMPLETE` with `EXIT_SIGNAL: false` now continues working (#146) - Fixed ralph-import hanging indefinitely (added `--print` flag for non-interactive mode) - Fixed ralph-import absolute path handling - Fixed cross-platform date commands for macOS with Homebrew coreutils - Added configurable circuit breaker thresholds via environment variables (#99) - Added tmux support for non-zero `base-index` configurations - Added 13 new regression tests for progress detection and checkbox regex **v0.11.3 - Live Streaming & Beads Fix** - Added live streaming output mode with `--live` flag for real-time Claude Code visibility (#125) - Fixed beads task import using correct `bd list` arguments (#150) - Applied CodeRabbit review fixes: camelCase variables, status-respecting fallback, jq guards - Added 12 new tests for live streaming and beads import improvements **v0.11.2 - Setup Permissions Fix** - Fixed issue #136: `ralph-setup` now creates `.ralphrc` with consistent tool permissions - Updated default `ALLOWED_TOOLS` to include `Edit`, `Bash(npm *)`, and `Bash(pytest)` - Both `ralph-setup` and `ralph-enable` now create identical `.ralphrc` configurations - Monitor now forwards all CLI parameters to inner ralph loop (#126) - Added 16 new tests for permissions and parameter forwarding **v0.11.1 - Completion Indicators Fix** - Fixed premature exit after exactly 5 loops in JSON output mode - `completion_indicators` now only accumulates when `EXIT_SIGNAL: true` - Aligns with documented dual-condition exit gate behavior **v0.11.0 - Ralph Enable Wizard** - Added `ralph-enable` interactive wizard for enabling Ralph in existing projects - 5-phase wizard: Environment Detection → Task Source Selection → Configuration → File Generation → Verification - Auto-detects project type (TypeScript, Python, Rust, Go) and framework (Next.js, FastAPI, Django) - Imports tasks from beads, GitHub Issues, or PRD documents - Added `ralph-enable-ci` non-interactive version for CI/automation - New library components: `enable_core.sh`, `wizard_utils.sh`, `task_sources.sh` **v0.10.1 - Bug Fixes & Monitor Path Corrections** - Fixed `ralph_monitor.sh` hardcoded paths for v0.10.0 compatibility - Fixed EXIT_SIGNAL parsing in JSON format - Added safety circuit breaker (force exit after 5 consecutive completion indicators) - Fixed checkbox parsing for indented markdown **v0.10.0 - .ralph/ Subfolder Structure (BREAKING CHANGE)** - **Breaking**: Moved all Ralph-specific files to `.ralph/` subfolder - Project root stays clean: only `src/`, `README.md`, and user files remain - Added `ralph-migrate` command for upgrading existing projects
Earlier versions (v0.9.x) **v0.9.9 - EXIT_SIGNAL Gate & Uninstall Script** - Fixed premature exit bug: completion indicators now require Claude's explicit `EXIT_SIGNAL: true` - Added dedicated `uninstall.sh` script for clean Ralph removal **v0.9.8 - Modern CLI for PRD Import** - Modernized `ralph_import.sh` to use Claude Code CLI JSON output format - Enhanced error handling with structured JSON error messages **v0.9.7 - Session Lifecycle Management** - Complete session lifecycle management with automatic reset triggers - Added `--reset-session` CLI flag for manual session reset **v0.9.6 - JSON Output & Session Management** - Extended `parse_json_response()` to support Claude Code CLI JSON format - Added session management functions **v0.9.5 - v0.9.0** - PRD import tests, project setup tests, installation tests, prompt file fix, modern CLI commands, circuit breaker enhancements
### In Progress - Expanding test coverage - [Automated badge updates](#138) **Timeline to v1.0**: ~4 weeks | [Full roadmap](IMPLEMENTATION_PLAN.md) | **Contributions welcome!** ## Features - **Autonomous Development Loop** - Continuously executes Claude Code with your project requirements - **Intelligent Exit Detection** - Dual-condition check requiring BOTH completion indicators AND explicit EXIT_SIGNAL - **Session Continuity** - Preserves context across loop iterations with automatic session management - **Session Expiration** - Configurable timeout (default: 24 hours) with automatic session reset - **Rate Limiting** - Built-in API call management with hourly limits and countdown timers - **5-Hour API Limit Handling** - Three-layer detection (timeout guard, JSON parsing, filtered text) with auto-wait for unattended mode - **Live Monitoring** - Real-time dashboard showing loop status, progress, and logs - **Task Management** - Structured approach with prioritized task lists and progress tracking - **Project Templates** - Quick setup for new projects with best-practice structure - **Interactive Project Setup** - `ralph-enable` wizard for existing projects with task import - **Configuration Files** - `.ralphrc` for project-specific settings and tool permissions - **Comprehensive Logging** - Detailed execution logs with timestamps and status tracking - **Configurable Timeouts** - Set execution timeout for Claude Code operations (1-120 minutes) - **Verbose Progress Mode** - Optional detailed progress updates during execution - **Response Analyzer** - AI-powered analysis of Claude Code responses with semantic understanding - **Circuit Breaker** - Advanced error detection with two-stage filtering, multi-line error matching, and automatic recovery - **CI/CD Integration** - GitHub Actions workflow with automated testing - **Clean Uninstall** - Dedicated uninstall script for complete removal - **Live Streaming Output** - Real-time visibility into Claude Code execution with `--live` flag ## Quick Start Ralph has two phases: **one-time installation** and **per-project setup**. ``` INSTALL ONCE USE MANY TIMES +-----------------+ +----------------------+ | ./install.sh | -> | ralph-setup project1 | | | | ralph-enable | | Adds global | | ralph-import prd.md | | commands | | ... | +-----------------+ +----------------------+ ``` ### Phase 1: Install Ralph (One Time Only) Install Ralph globally on your system: ```bash git clone https://github.com/frankbria/ralph-claude-code.git cd ralph-claude-code ./install.sh ``` This adds `ralph`, `ralph-monitor`, `ralph-setup`, `ralph-import`, `ralph-migrate`, `ralph-enable`, and `ralph-enable-ci` commands to your PATH. > **Note**: You only need to do this once per system. After installation, you can delete the cloned repository if desired. ### Phase 2: Initialize Projects (Per Project) #### Option A: Enable Ralph in Existing Project (Recommended) ```bash cd my-existing-project # Interactive wizard - auto-detects project type and imports tasks ralph-enable # Or with specific task source ralph-enable --from beads ralph-enable --from github --label "sprint-1" ralph-enable --from prd ./docs/requirements.md # Start autonomous development ralph --monitor ``` #### Option B: Import Existing PRD/Specifications ```bash # Convert existing PRD/specs to Ralph format ralph-import my-requirements.md my-project cd my-project # Review and adjust the generated files: # - .ralph/PROMPT.md (Ralph instructions) # - .ralph/fix_plan.md (task priorities) # - .ralph/specs/requirements.md (technical specs) # Start autonomous development ralph --monitor ``` #### Option C: Create New Project from Scratch ```bash # Create blank Ralph project ralph-setup my-awesome-project cd my-awesome-project # Configure your project requirements manually # Edit .ralph/PROMPT.md with your project goals # Edit .ralph/specs/ with detailed specifications # Edit .ralph/fix_plan.md with initial priorities # Start autonomous development ralph --monitor ``` ### Ongoing Usage (After Setup) Once Ralph is installed and your project is initialized: ```bash # Navigate to any Ralph project and run: ralph --monitor # Integrated tmux monitoring (recommended) # Or use separate terminals: ralph # Terminal 1: Ralph loop ralph-monitor # Terminal 2: Live monitor dashboard ``` ### Uninstalling Ralph To completely remove Ralph from your system: ```bash # Run the uninstall script ./uninstall.sh # Or if you deleted the repo, download and run: curl -sL https://raw.githubusercontent.com/frankbria/ralph-claude-code/main/uninstall.sh | bash ``` ## Understanding Ralph Files After running `ralph-enable` or `ralph-import`, you'll have a `.ralph/` directory with several files. Here's what each file does and whether you need to edit it: | File | Auto-Generated? | You Should... | |------|-----------------|---------------| | `.ralph/PROMPT.md` | Yes (smart defaults) | **Review & customize** project goals and principles | | `.ralph/fix_plan.md` | Yes (can import tasks) | **Add/modify** specific implementation tasks | | `.ralph/AGENT.md` | Yes (detects build commands) | Rarely edit (auto-maintained by Ralph) | | `.ralph/specs/` | Empty directory | Add files when PROMPT.md isn't detailed enough | | `.ralph/specs/stdlib/` | Empty directory | Add reusable patterns and conventions | | `.ralphrc` | Yes (project-aware) | Rarely edit (sensible defaults) | ### Key File Relationships ``` PROMPT.md (high-level goals) ↓ specs/ (detailed requirements when needed) ↓ fix_plan.md (specific tasks Ralph executes) ↓ AGENT.md (build/test commands - auto-maintained) ``` ### When to Use specs/ - **Simple projects**: PROMPT.md + fix_plan.md is usually enough - **Complex features**: Add specs/feature-name.md for detailed requirements - **Team conventions**: Add specs/stdlib/convention-name.md for reusable patterns See the [User Guide](docs/user-guide/) for detailed explanations and the [examples/](examples/) directory for realistic project configurations. ## How It Works Ralph operates on a simple but powerful cycle: 1. **Read Instructions** - Loads `PROMPT.md` with your project requirements 2. **Execute Claude Code** - Runs Claude Code with current context and priorities 3. **Track Progress** - Updates task lists and logs execution results 4. **Evaluate Completion** - Checks for exit conditions and project completion signals 5. **Repeat** - Continues until project is complete or limits are reached ### Intelligent Exit Detection Ralph uses a **dual-condition check** to prevent premature exits during productive iterations: **Exit requires BOTH conditions:** 1. `completion_indicators >= 2` (heuristic detection from natural language patterns) 2. Claude's explicit `EXIT_SIGNAL: true` in the RALPH_STATUS block **Example behavior:** ``` Loop 5: Claude outputs "Phase complete, moving to next feature" → completion_indicators: 3 (high confidence from patterns) → EXIT_SIGNAL: false (Claude says more work needed) → Result: CONTINUE (respects Claude's explicit intent) Loop 8: Claude outputs "All tasks complete, project ready" → completion_indicators: 4 → EXIT_SIGNAL: true (Claude confirms done) → Result: EXIT with "project_complete" ``` **Other exit conditions:** - All tasks in `.ralph/fix_plan.md` marked complete - Multiple consecutive "done" signals from Claude Code - Too many test-focused loops (indicating feature completeness) - Claude API 5-hour usage limit reached (with user prompt to wait or exit) ## Enabling Ralph in Existing Projects The `ralph-enable` command provides an interactive wizard for adding Ralph to existing projects: ```bash cd my-existing-project ralph-enable ``` **The wizard:** 1. **Detects Environment** - Identifies project type (TypeScript, Python, etc.) and framework 2. **Selects Task Sources** - Choose from beads, GitHub Issues, or PRD documents 3. **Configures Settings** - Set tool permissions and loop parameters 4. **Generates Files** - Creates `.ralph/` directory and `.ralphrc` configuration 5. **Verifies Setup** - Confirms all files are created correctly **Non-interactive mode for CI/automation:** ```bash ralph-enable-ci # Sensible defaults ralph-enable-ci --from github # Import from GitHub Issues ralph-enable-ci --project-type typescript # Override detection ralph-enable-ci --json # Machine-readable output ``` ## Importing Existing Requirements Ralph can convert existing PRDs, specifications, or requirement documents into the proper Ralph format using Claude Code. ### Supported Formats - **Markdown** (.md) - Product requirements, technical specs - **Text files** (.txt) - Plain text requirements - **JSON** (.json) - Structured requirement data - **Word documents** (.docx) - Business requirements - **PDFs** (.pdf) - Design documents, specifications - **Any text-based format** - Ralph will intelligently parse the content ### Usage Examples ```bash # Convert a markdown PRD ralph-import product-requirements.md my-app # Convert a text specification ralph-import requirements.txt webapp # Convert a JSON API spec ralph-import api-spec.json backend-service # Let Ralph auto-name the project from filename ralph-import design-doc.pdf ``` ### What Gets Generated Ralph-import creates a complete project with: - **.ralph/PROMPT.md** - Converted into Ralph development instructions - **.ralph/fix_plan.md** - Requirements broken down into prioritized tasks - **.ralph/specs/requirements.md** - Technical specifications extracted from your document - **.ralphrc** - Project configuration file with tool permissions - **Standard Ralph structure** - All necessary directories and template files in `.ralph/` The conversion is intelligent and preserves your original requirements while making them actionable for autonomous development. ## Configuration ### Project Configuration (.ralphrc) Each Ralph project can have a `.ralphrc` configuration file: ```bash # .ralphrc - Ralph project configuration PROJECT_NAME="my-project" PROJECT_TYPE="typescript" # Claude Code CLI command (auto-detected, override if needed) CLAUDE_CODE_CMD="claude" # CLAUDE_CODE_CMD="npx @anthropic-ai/claude-code" # Alternative: use npx # Shell init file — source before running claude (useful for zsh/fish users # whose PATH or env vars are only set in their shell's init file) #RALPH_SHELL_INIT_FILE="~/.zshrc" # Loop settings MAX_CALLS_PER_HOUR=100 CLAUDE_TIMEOUT_MINUTES=15 CLAUDE_OUTPUT_FORMAT="json" # Token budget per hour (0 = disabled). One Claude call can use 100k+ tokens. #MAX_TOKENS_PER_HOUR=500000 # Tool permissions ALLOWED_TOOLS="Write,Read,Edit,Bash(git *),Bash(npm *),Bash(pytest)" # Session management SESSION_CONTINUITY=true SESSION_EXPIRY_HOURS=24 # Circuit breaker thresholds CB_NO_PROGRESS_THRESHOLD=3 CB_SAME_ERROR_THRESHOLD=5 ``` ### Rate Limiting & Circuit Breaker Ralph includes intelligent rate limiting and circuit breaker functionality: ```bash # Default: 100 calls per hour ralph --calls 50 # With integrated monitoring ralph --monitor --calls 50 # Check current usage (shows calls and tokens used this hour) ralph --status ``` Rate limiting supports two independent limits — both reset hourly: | Setting | Default | Description | |---------|---------|-------------| | `MAX_CALLS_PER_HOUR` | `100` | Max Claude invocations per hour | | `MAX_TOKENS_PER_HOUR` | `0` (disabled) | Max cumulative tokens per hour | Token tracking extracts `input_tokens + output_tokens` from each Claude response. A single call can consume 100k+ tokens, so `MAX_TOKENS_PER_HOUR` provides cost control that `MAX_CALLS_PER_HOUR` alone cannot. The circuit breaker automatically: - Detects API errors and rate limit issues with advanced two-stage filtering - Opens circuit after 3 loops with no progress or 5 loops with same errors - Eliminates false positives from JSON fields containing "error" - Accurately detects stuck loops with multi-line error matching - Gradually recovers with half-open monitoring state - **Auto-recovers** after cooldown period (default: 30 minutes) — OPEN → HALF_OPEN → CLOSED - Provides detailed error tracking and logging with state history **Auto-recovery options:** ```bash # Default: 30-minute cooldown before auto-recovery attempt CB_COOLDOWN_MINUTES=30 # Set in .ralphrc (0 = immediate) # Auto-reset on startup (for fully unattended operation) ralph --auto-reset-circuit # Or set in .ralphrc: CB_AUTO_RESET=true ``` ### Claude API 5-Hour Limit When Claude's 5-hour usage limit is reached, Ralph: 1. Detects the limit using three-layer verification (timeout guard → structural JSON → filtered text fallback) 2. Prompts you to choose: - **Option 1**: Wait 60 minutes for the limit to reset (with countdown timer) - **Option 2**: Exit gracefully 3. **Unattended mode**: Auto-waits on prompt timeout (30s) instead of exiting 4. Prevents false positives from echoed file content mentioning "5-hour limit" ### Custom Prompts ```bash # Use custom prompt file ralph --prompt my_custom_instructions.md # With integrated monitoring ralph --monitor --prompt my_custom_instructions.md ``` ### Execution Timeouts ```bash # Set Claude Code execution timeout (default: 15 minutes) ralph --timeout 30 # 30-minute timeout for complex tasks # With monitoring and custom timeout ralph --monitor --timeout 60 # 60-minute timeout # Short timeout for quick iterations ralph --verbose --timeout 5 # 5-minute timeout with progress ``` ### Verbose Mode ```bash # Enable detailed progress updates during execution ralph --verbose # Combine with other options ralph --monitor --verbose --timeout 30 ``` ### Live Streaming Output ```bash # Enable real-time visibility into Claude Code execution ralph --live # Combine with monitoring for best experience ralph --monitor --live # Live output is written to .ralph/live.log tail -f .ralph/live.log # Watch in another terminal ``` Live streaming mode shows Claude Code's output in real-time as it works, providing visibility into what's happening during each loop iteration. ### Session Continuity Ralph maintains session context across loop iterations for improved coherence: ```bash # Sessions are enabled by default with --continue flag ralph --monitor # Uses session continuity # Start fresh without session context ralph --no-continue # Isolated iterations # Reset session manually (clears context) ralph --reset-session # Clears current session # Check session status cat .ralph/.ralph_session # View current session file cat .ralph/.ralph_session_history # View session transition history ``` **Session Auto-Reset Triggers:** - Circuit breaker opens (stagnation detected) - Manual interrupt (Ctrl+C / SIGINT) - Project completion (graceful exit) - Manual circuit breaker reset (`--reset-circuit`) - Session expiration (default: 24 hours) Sessions are persisted to `.ralph/.ralph_session` with a configurable expiration (default: 24 hours). The last 50 session transitions are logged to `.ralph/.ralph_session_history` for debugging. ### Exit Thresholds Modify these variables in `~/.ralph/ralph_loop.sh`: **Exit Detection Thresholds:** ```bash MAX_CONSECUTIVE_TEST_LOOPS=3 # Exit after 3 test-only loops MAX_CONSECUTIVE_DONE_SIGNALS=2 # Exit after 2 "done" signals TEST_PERCENTAGE_THRESHOLD=30 # Flag if 30%+ loops are test-only ``` **Circuit Breaker Thresholds:** ```bash CB_NO_PROGRESS_THRESHOLD=3 # Open circuit after 3 loops with no file changes CB_SAME_ERROR_THRESHOLD=5 # Open circuit after 5 loops with repeated errors CB_OUTPUT_DECLINE_THRESHOLD=70 # Open circuit if output declines by >70% CB_COOLDOWN_MINUTES=30 # Minutes before OPEN → HALF_OPEN auto-recovery CB_AUTO_RESET=false # true = reset to CLOSED on startup (bypasses cooldown) ``` **Completion Indicators with EXIT_SIGNAL Gate:** | completion_indicators | EXIT_SIGNAL | Result | |-----------------------|-------------|--------| | >= 2 | `true` | **Exit** ("project_complete") | | >= 2 | `false` | **Continue** (Claude still working) | | >= 2 | missing | **Continue** (defaults to false) | | < 2 | `true` | **Continue** (threshold not met) | ## Project Structure Ralph creates a standardized structure for each project with a `.ralph/` subfolder for configuration: ``` my-project/ ├── .ralph/ # Ralph configuration and state (hidden folder) │ ├── PROMPT.md # Main development instructions for Ralph │ ├── fix_plan.md # Prioritized task list │ ├── AGENT.md # Build and run instructions │ ├── specs/ # Project specifications and requirements │ │ └── stdlib/ # Standard library specifications │ ├── examples/ # Usage examples and test cases │ ├── logs/ # Ralph execution logs │ └── docs/generated/ # Auto-generated documentation ├── .ralphrc # Ralph configuration file (tool permissions, settings) └── src/ # Source code implementation (at project root) ``` > **Migration**: If you have existing Ralph projects using the old flat structure, run `ralph-migrate` to automatically move files to the `.ralph/` subfolder. ## Best Practices ### Writing Effective Prompts 1. **Be Specific** - Clear requirements lead to better results 2. **Prioritize** - Use `.ralph/fix_plan.md` to guide Ralph's focus 3. **Set Boundaries** - Define what's in/out of scope 4. **Include Examples** - Show expected inputs/outputs ### Project Specifications - Place detailed requirements in `.ralph/specs/` - Use `.ralph/fix_plan.md` for prioritized task tracking - Keep `.ralph/AGENT.md` updated with build instructions - Document key decisions and architecture ### Monitoring Progress - Use `ralph-monitor` for live status updates - Check logs in `.ralph/logs/` for detailed execution history - Monitor `.ralph/status.json` for programmatic access - Watch for exit condition signals ## System Requirements - **Bash 4.0+** - For script execution - **Claude Code CLI** - `npm install -g @anthropic-ai/claude-code` (or use npx — set `CLAUDE_CODE_CMD` in `.ralphrc`) - **tmux** - Terminal multiplexer for integrated monitoring (recommended) - **jq** - JSON processing for status tracking - **Git** - Version control (projects are initialized as git repos) - **GNU coreutils** - For the `timeout` command (execution timeouts) - Linux: Pre-installed on most distributions - macOS: Install via `brew install coreutils` (provides `gtimeout`) - **Standard Unix tools** - grep, date, etc. ### Testing Requirements (Development) See [TESTING.md](TESTING.md) for the comprehensive testing guide. If you want to run the test suite: ```bash # Install BATS testing framework npm install -g bats bats-support bats-assert # Run all tests (566 tests) npm test # Run specific test suites bats tests/unit/test_rate_limiting.bats bats tests/unit/test_exit_detection.bats bats tests/unit/test_json_parsing.bats bats tests/unit/test_cli_modern.bats bats tests/unit/test_cli_parsing.bats bats tests/unit/test_session_continuity.bats bats tests/unit/test_enable_core.bats bats tests/unit/test_task_sources.bats bats tests/unit/test_ralph_enable.bats bats tests/unit/test_wizard_utils.bats bats tests/unit/test_circuit_breaker_recovery.bats bats tests/integration/test_loop_execution.bats bats tests/integration/test_prd_import.bats bats tests/integration/test_project_setup.bats bats tests/integration/test_installation.bats # Run error detection and circuit breaker tests ./tests/test_error_detection.sh ./tests/test_stuck_loop_detection.sh ``` Current test status: - **566 tests** across 18 test files - **100% pass rate** (556/556 passing) - Comprehensive unit and integration tests - Specialized tests for JSON parsing, CLI flags, circuit breaker, EXIT_SIGNAL behavior, enable wizard, and installation workflows > **Note on Coverage**: Bash code coverage measurement with kcov has fundamental limitations when tracing subprocess executions. Test pass rate (100%) is the quality gate. See [bats-core#15](https://github.com/bats-core/bats-core/issues/15) for details. ### Installing tmux ```bash # Ubuntu/Debian sudo apt-get install tmux # macOS brew install tmux # CentOS/RHEL sudo yum install tmux ``` ### Installing GNU coreutils (macOS) Ralph uses the `timeout` command for execution timeouts. On macOS, you need to install GNU coreutils: ```bash # Install coreutils (provides gtimeout) brew install coreutils # Verify installation gtimeout --version ``` Ralph automatically detects and uses `gtimeout` on macOS. No additional configuration is required after installation. ## Monitoring and Debugging ### Live Dashboard ```bash # Integrated tmux monitoring (recommended) ralph --monitor # Manual monitoring in separate terminal ralph-monitor ``` Shows real-time: - Current loop count and status - API calls used vs. limit - Recent log entries - Rate limit countdown **tmux Controls:** - `Ctrl+B` then `D` - Detach from session (keeps Ralph running) - `Ctrl+B` then `←/→` - Switch between panes - `tmux list-sessions` - View active sessions - `tmux attach -t ` - Reattach to session ### Status Checking ```bash # JSON status output ralph --status # Manual log inspection tail -f .ralph/logs/ralph.log ``` ### Common Issues - **Ralph exits silently on first loop** - Claude Code CLI may not be installed or not in PATH. Ralph validates the command at startup and shows installation instructions. If using npx, add `CLAUDE_CODE_CMD="npx @anthropic-ai/claude-code"` to `.ralphrc` - **Rate Limits** - Ralph automatically waits and displays countdown - **5-Hour API Limit** - Ralph detects and prompts for user action (wait or exit) - **Stuck Loops** - Check `fix_plan.md` for unclear or conflicting tasks - **Early Exit** - Review exit thresholds if Ralph stops too soon - **Premature Exit** - Check if Claude is setting `EXIT_SIGNAL: false` (Ralph now respects this) - **Execution Timeouts** - Increase `--timeout` value for complex operations - **Missing Dependencies** - Ensure Claude Code CLI and tmux are installed - **tmux Session Lost** - Use `tmux list-sessions` and `tmux attach` to reconnect - **Session Expired** - Sessions expire after 24 hours by default; use `--reset-session` to start fresh - **timeout: command not found (macOS)** - Install GNU coreutils: `brew install coreutils` - **Permission Denied** - Ralph halts when Claude Code is denied permission for commands: 1. Edit `.ralphrc` and update `ALLOWED_TOOLS` to include required tools 2. Common patterns: `Bash(npm *)`, `Bash(git *)`, `Bash(pytest)` 3. Run `ralph --reset-session` after updating `.ralphrc` 4. Restart with `ralph --monitor` ## Contributing Ralph is actively seeking contributors! We're working toward v1.0.0 with clear priorities and a detailed roadmap. **See [CONTRIBUTING.md](CONTRIBUTING.md) for the complete contributor guide** including: - Getting started and setup instructions - Development workflow and commit conventions - Code style guidelines - Testing requirements (100% pass rate mandatory) - Pull request process and code review guidelines - Quality standards and checklists ### Quick Start ```bash # Fork and clone git clone https://github.com/YOUR_USERNAME/ralph-claude-code.git cd ralph-claude-code # Install dependencies and run tests npm install npm test # All 566 tests must pass ``` ### Priority Contribution Areas 1. **Test Implementation** - Help expand test coverage 2. **Feature Development** - Log rotation, dry-run mode, metrics 3. **Documentation** - Tutorials, troubleshooting guides, examples 4. **Real-World Testing** - Use Ralph, report bugs, share feedback **Every contribution matters** - from fixing typos to implementing major features! ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Acknowledgments - Inspired by the [Ralph technique](https://ghuntley.com/ralph/) created by Geoffrey Huntley - Built for [Claude Code](https://claude.ai/code) by Anthropic - Community feedback and contributions ## Related Projects - [Claude Code](https://claude.ai/code) - The AI coding assistant that powers Ralph - [Aider](https://github.com/paul-gauthier/aider) - Original Ralph technique implementation --- ## Command Reference ### Installation Commands (Run Once) ```bash ./install.sh # Install Ralph globally ./uninstall.sh # Remove Ralph from system (dedicated script) ./install.sh uninstall # Alternative: Remove Ralph from system ./install.sh --help # Show installation help ralph-migrate # Migrate existing project to .ralph/ structure ``` ### Ralph Loop Options ```bash ralph [OPTIONS] -h, --help Show help message -c, --calls NUM Set max calls per hour (default: 100) -p, --prompt FILE Set prompt file (default: PROMPT.md) -s, --status Show current status and exit -m, --monitor Start with tmux session and live monitor -v, --verbose Show detailed progress updates during execution -l, --live Enable live streaming output (real-time Claude Code visibility) -t, --timeout MIN Set Claude Code execution timeout in minutes (1-120, default: 15) --output-format FORMAT Set output format: json (default) or text --allowed-tools TOOLS Set allowed Claude tools (default: Write,Read,Edit,Bash(git *),Bash(npm *),Bash(pytest)) --no-continue Disable session continuity (start fresh each loop) --reset-circuit Reset the circuit breaker --circuit-status Show circuit breaker status --auto-reset-circuit Auto-reset circuit breaker on startup (bypasses cooldown) --reset-session Reset session state manually -b, --backup Enable automatic git backup branch before each loop (requires git) --rollback [BRANCH] Roll back to a backup branch (lists available branches if none given) ``` ### Project Commands (Per Project) ```bash ralph-setup project-name # Create new Ralph project ralph-enable # Enable Ralph in existing project (interactive) ralph-enable-ci # Enable Ralph in existing project (non-interactive) ralph-import prd.md project # Convert PRD/specs to Ralph project ralph --monitor # Start with integrated monitoring ralph --status # Check current loop status ralph --verbose # Enable detailed progress updates ralph --timeout 30 # Set 30-minute execution timeout ralph --calls 50 # Limit to 50 API calls per hour ralph --reset-session # Reset session state manually ralph --live # Enable live streaming output ralph-monitor # Manual monitoring dashboard ``` ### tmux Session Management ```bash tmux list-sessions # View active Ralph sessions tmux attach -t # Reattach to detached session # Ctrl+B then D # Detach from session (keeps running) ``` --- ## Development Roadmap Ralph is under active development with a clear path to v1.0.0. See [IMPLEMENTATION_PLAN.md](IMPLEMENTATION_PLAN.md) for the complete roadmap. ### Current Status: v0.11.5 **What's Delivered:** - Core loop functionality with intelligent exit detection - **Dual-condition exit gate** (completion indicators + EXIT_SIGNAL) - Rate limiting (100 calls/hour) and circuit breaker pattern - Response analyzer with semantic understanding - **556 comprehensive tests** (100% pass rate) - **Live streaming output mode** for real-time Claude Code visibility - tmux integration and live monitoring - PRD import functionality with modern CLI JSON parsing - Installation system and project templates - Modern CLI commands with JSON output support - CI/CD pipeline with GitHub Actions - **Interactive `ralph-enable` wizard for existing projects** - **`.ralphrc` configuration file support** - Session lifecycle management with auto-reset triggers - Session expiration with configurable timeout - Dedicated uninstall script **Test Coverage Breakdown:** - Unit Tests: 477 (CLI parsing, JSON, exit detection, rate limiting + token budgets, session continuity, enable wizard, live streaming, circuit breaker recovery, file protection, integrity checks) - Integration Tests: 136 (loop execution, edge cases, installation, project setup, PRD import) - Test Files: 18 ### Path to v1.0.0 (~4 weeks) **Enhanced Testing** - Installation and setup workflow tests - tmux integration tests - Monitor dashboard tests **Core Features** - Log rotation functionality - Dry-run mode **Advanced Features & Polish** - End-to-end tests - Final documentation and release prep See [IMPLEMENTATION_STATUS.md](IMPLEMENTATION_STATUS.md) for detailed progress tracking. ### How to Contribute Ralph is seeking contributors! See [CONTRIBUTING.md](CONTRIBUTING.md) for the complete guide. Priority areas: 1. **Test Implementation** - Help expand test coverage ([see plan](IMPLEMENTATION_PLAN.md)) 2. **Feature Development** - Log rotation, dry-run mode, metrics 3. **Documentation** - Usage examples, tutorials, troubleshooting guides 4. **Bug Reports** - Real-world usage feedback and edge cases --- **Ready to let AI build your project?** Start with `./install.sh` and let Ralph take it from there! ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=frankbria/ralph-claude-code&type=date&legend=top-left)](https://www.star-history.com/#frankbria/ralph-claude-code&type=date&legend=top-left)