Autonomous AI agent loop for Claude Code CLI. Iteratively works through features defined in a PRD until completion.
Implemented in Rust, based on a ralph shell script that I've used to educate teams and deploy code to production.
paru -S ralphcargo install --path .Requires Claude CLI in PATH.
cd <project>
ralph --init # Create template prd.jsonc
# Edit prd.jsonc with your features
ralph # Run the loop
# sandboxing and using --dangerously-skip-permissions
# is recommended to avoid getting stuck on approval-
Generate template — In your project directory, run:
ralph --init
This creates a
prd.jsoncfile with the basic structure. -
Populate the PRD — The template needs to be filled with features for ralph to process. Start a Claude session and ask it to break down your task:
claude
Then prompt:
Evaluate [YOUR TASK HERE] and break it down into implementation steps. Output the result in prd.jsonc format with features array containing id, category, description, steps, and status fields. -
Copy the output — Replace the template content in
prd.jsoncwith Claude's structured breakdown. -
Run the loop — Exit Claude and start ralph:
ralph
Ralph will iterate through each feature, spawning Claude sessions to implement them one by one until all are complete.
- Initialize — Validates PRD, checks git status, shows feature summary
- Loop — For each iteration:
- Spawns Claude with PRD context
- Claude implements one pending feature
- Validates only status field was modified
- Commits changes, updates progress
- Repeats until all features complete
-p, --prd <PATH> PRD file path [default: prd.jsonc]
-P, --prompt <PATH> Custom system prompt file
-c, --completion-marker <TEXT> Completion marker (overrides PRD)
-m, --max-iterations <N> Max iterations, 0=unlimited [default: 10]
-d, --delay <SECONDS> Delay between iterations [default: 2]
-t, --timeout <SECONDS> Claude timeout [default: 1800]
--permission-mode <MODE> default|acceptEdits|plan [default: acceptEdits]
--continue-session Preserve context between iterations
--skip-init Skip initialization phase
--dry-run Validate PRD, run verifications, exit without Claude
--webhook <URL> Webhook URL for session event notifications
--max-iteration-errors <N> Auto-block feature after N errors [default: 0] (experimental)
--dangerously-skip-permissions Auto-approve all Claude actions
--init-prompt Generate prompt.md template and exit
Ralph uses a built-in system prompt by default. To customize agent behavior, provide your own prompt file.
ralph --init-prompt # Creates prompt.mdralph --prompt my-prompt.md # Use custom prompt
ralph -P prompt.md # Short formCustom prompts support these placeholders, replaced at runtime:
| Placeholder | Description |
|---|---|
{prd_path} |
Path to the PRD file |
{progress_path} |
Path to the progress file |
{verification_commands} |
Formatted list of verification commands |
{completion_marker} |
Completion marker from PRD |
{prd_content} |
Full contents of the PRD file |
Specialized prompts for different project types:
# Rust projects - strict linting, no unsafe
ralph --prompt prompts/rust-strict.md
# Python projects - pytest focus, type hints
ralph --prompt prompts/python.md
# Documentation - markdown style, grammar checks
ralph --prompt prompts/docs.mdSend HTTP POST notifications to a URL when session events occur:
ralph --webhook https://example.com/webhook| Event | Trigger |
|---|---|
session_start |
Session begins |
session_complete |
All features completed successfully |
session_failed |
Session exits due to too many failures |
{
"event": "session_start",
"timestamp": "2024-01-15T10:30:00Z",
"message": "Starting session for my-project"
}| Field | Description |
|---|---|
event |
Event type string |
timestamp |
RFC3339 timestamp |
message |
Human-readable description |
- Validation — Only PRD status field changes allowed per iteration
- Failure limit — Exits after 3 consecutive failures
- Loop detection — Detects stuck patterns and reports
- Rate limiting — Auto-retries after 60s cooldown
- Ctrl+C — Graceful shutdown with progress logged
MIT
{ "project": { "name": "my-project", "description": "What this project does" }, "verification": { "commands": [ { "name": "check", "command": "cargo check" }, { "name": "test", "command": "cargo test" } ], "runAfterEachFeature": true }, "features": [ { "id": "feature-id", "category": "functional", // functional|bugfix|refactor|test|docs "description": "What needs to be done", "steps": ["Step 1", "Step 2"], "status": "pending" // pending|in-progress|complete|blocked } ], "completion": { "allFeaturesComplete": true, "allVerificationsPassing": true, "marker": "<promise>COMPLETE</promise>" } }