mirror of
https://github.com/harivansh-afk/ralph-cli.git
synced 2026-04-15 09:01:17 +00:00
init
This commit is contained in:
commit
f1df2259ca
3 changed files with 515 additions and 0 deletions
122
README.md
Normal file
122
README.md
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
# Ralph CLI
|
||||||
|
|
||||||
|
Run AI coding agents in a loop. Based on [Matt Pocock's Ralph Wiggum pattern](https://www.aihero.dev/posts/tips-for-ai-coding-with-ralph).
|
||||||
|
|
||||||
|
## What is Ralph?
|
||||||
|
|
||||||
|
Ralph runs Claude Code (or other AI CLIs) in a loop, letting it work autonomously on a list of tasks. You define what needs to be done in a PRD. Ralph figures out how - and keeps going until it's finished.
|
||||||
|
|
||||||
|
```
|
||||||
|
Iteration 1: Claude reads PRD, picks highest priority task, implements it, commits
|
||||||
|
Iteration 2: Claude reads PRD + progress, picks next task, implements, commits
|
||||||
|
...
|
||||||
|
Iteration N: Claude sees all tasks done, outputs COMPLETE, loop exits
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone and install
|
||||||
|
git clone https://github.com/rathi/ralph-cli.git
|
||||||
|
cd ralph-cli
|
||||||
|
./install.sh
|
||||||
|
|
||||||
|
# Or one-liner
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/rathi/ralph-cli/main/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Initialize Ralph in your repo
|
||||||
|
cd your-project
|
||||||
|
ralph init
|
||||||
|
|
||||||
|
# 2. Edit the PRD with your tasks
|
||||||
|
vim .ralph/prd.md
|
||||||
|
|
||||||
|
# 3. Run Ralph
|
||||||
|
ralph run 10
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ralph init # Set up Ralph in current repo
|
||||||
|
ralph run <iterations> # Run the loop
|
||||||
|
ralph run 10 -p custom.md # Use custom PRD file
|
||||||
|
ralph generate tests # Auto-generate PRD from codebase
|
||||||
|
ralph status # Show progress
|
||||||
|
ralph reset # Clear progress and start over
|
||||||
|
ralph --help # See all options
|
||||||
|
```
|
||||||
|
|
||||||
|
## PRD Format
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# My Feature PRD
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
What you want Ralph to accomplish.
|
||||||
|
|
||||||
|
## Tasks (Priority Order)
|
||||||
|
|
||||||
|
- [ ] CRITICAL: Set up database schema
|
||||||
|
Create migrations for users and posts tables.
|
||||||
|
Source: src/db/
|
||||||
|
|
||||||
|
- [ ] HIGH: Add user authentication
|
||||||
|
Implement login/logout with JWT.
|
||||||
|
Source: src/auth/
|
||||||
|
|
||||||
|
- [ ] MEDIUM: Build API endpoints
|
||||||
|
REST endpoints for CRUD operations.
|
||||||
|
|
||||||
|
- [ ] LOW: Add tests
|
||||||
|
Unit tests for auth module.
|
||||||
|
|
||||||
|
## Completion Criteria
|
||||||
|
All endpoints working, tests passing.
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. **PRD File** (`.ralph/prd.md`): Your task list with priorities
|
||||||
|
2. **Progress File** (`ralph-progress.txt`): Tracks what's done between iterations
|
||||||
|
3. **Loop**: Each iteration, Claude:
|
||||||
|
- Reads PRD and progress
|
||||||
|
- Picks highest priority incomplete task
|
||||||
|
- Implements it
|
||||||
|
- Updates progress file
|
||||||
|
- Commits changes
|
||||||
|
4. **Completion**: When all tasks done, outputs `<promise>COMPLETE</promise>` and exits
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `-p, --prd <file>` | Custom PRD file (default: `.ralph/prd.md`) |
|
||||||
|
| `--docker` | Run in Docker sandbox (safer for AFK) |
|
||||||
|
| `--dry-run` | Show what would happen |
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
1. **Start with HITL**: Run `ralph run 1` and watch before going AFK
|
||||||
|
2. **Small tasks**: One logical unit per PRD item
|
||||||
|
3. **Priority matters**: CRITICAL > HIGH > MEDIUM > LOW
|
||||||
|
4. **Feedback loops**: Add "run tests" to your PRD tasks
|
||||||
|
5. **Check progress**: `ralph status` or `cat ralph-progress.txt`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
|
||||||
|
- Bash 3.x+ (macOS default works)
|
||||||
|
- Optional: Docker Desktop 4.50+ for sandboxed runs
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Based on [Matt Pocock's Ralph Wiggum pattern](https://www.aihero.dev/posts/tips-for-ai-coding-with-ralph).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
39
install.sh
Executable file
39
install.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Ralph CLI Installer
|
||||||
|
|
||||||
|
INSTALL_DIR="$HOME/.local/bin"
|
||||||
|
REPO_URL="https://raw.githubusercontent.com/rathi/ralph-cli/main/ralph"
|
||||||
|
|
||||||
|
echo "Installing Ralph CLI..."
|
||||||
|
|
||||||
|
# Create install directory if needed
|
||||||
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
|
||||||
|
# Download or copy ralph
|
||||||
|
if [ -f "$(dirname "$0")/ralph" ]; then
|
||||||
|
# Local install
|
||||||
|
cp "$(dirname "$0")/ralph" "$INSTALL_DIR/ralph"
|
||||||
|
else
|
||||||
|
# Remote install
|
||||||
|
curl -fsSL "$REPO_URL" -o "$INSTALL_DIR/ralph"
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod +x "$INSTALL_DIR/ralph"
|
||||||
|
|
||||||
|
# Check if in PATH
|
||||||
|
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "Add this to your shell profile (.bashrc, .zshrc, etc.):"
|
||||||
|
echo ""
|
||||||
|
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Ralph installed to $INSTALL_DIR/ralph"
|
||||||
|
echo ""
|
||||||
|
echo "Usage:"
|
||||||
|
echo " ralph init # Initialize in a repo"
|
||||||
|
echo " ralph run 10 # Run 10 iterations"
|
||||||
|
echo " ralph --help # See all options"
|
||||||
354
ralph
Executable file
354
ralph
Executable file
|
|
@ -0,0 +1,354 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Ralph - AI Coding Loop Runner
|
||||||
|
# Based on Matt Pocock's Ralph Wiggum pattern
|
||||||
|
# https://github.com/rathi/ralph-cli
|
||||||
|
|
||||||
|
VERSION="1.0.0"
|
||||||
|
RALPH_DIR=".ralph"
|
||||||
|
PROGRESS_FILE="ralph-progress.txt"
|
||||||
|
|
||||||
|
# Colors (optional)
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat << EOF
|
||||||
|
Ralph v$VERSION - AI Coding Loop Runner
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
ralph <command> [options]
|
||||||
|
|
||||||
|
COMMANDS:
|
||||||
|
run <iterations> [prd-file] Run Ralph loop with PRD file
|
||||||
|
init Initialize Ralph in current directory
|
||||||
|
generate <type> Generate PRD from codebase analysis
|
||||||
|
status Show current progress
|
||||||
|
reset Clear progress file
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-p, --prd <file> PRD file to use (default: .ralph/prd.md)
|
||||||
|
-m, --module <name> Run specific module only
|
||||||
|
--docker Run in Docker sandbox (safer for AFK)
|
||||||
|
--dry-run Show what would happen without executing
|
||||||
|
-h, --help Show this help
|
||||||
|
|
||||||
|
EXAMPLES:
|
||||||
|
ralph init # Set up Ralph in current repo
|
||||||
|
ralph run 10 # Run 10 iterations with default PRD
|
||||||
|
ralph run 5 -p my-prd.md # Run 5 iterations with custom PRD
|
||||||
|
ralph generate tests # Generate test PRD from codebase
|
||||||
|
ralph status # Check progress
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialize Ralph in a repo
|
||||||
|
init_ralph() {
|
||||||
|
echo "Initializing Ralph in $(pwd)..."
|
||||||
|
|
||||||
|
mkdir -p "$RALPH_DIR"
|
||||||
|
touch "$PROGRESS_FILE"
|
||||||
|
|
||||||
|
# Create template PRD
|
||||||
|
cat > "$RALPH_DIR/prd.md" << 'EOF'
|
||||||
|
# Project PRD
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Describe what you want Ralph to accomplish.
|
||||||
|
|
||||||
|
## Tasks (Priority Order)
|
||||||
|
|
||||||
|
- [ ] CRITICAL: First high-priority task
|
||||||
|
Description and acceptance criteria.
|
||||||
|
|
||||||
|
- [ ] HIGH: Second task
|
||||||
|
Description.
|
||||||
|
|
||||||
|
- [ ] MEDIUM: Third task
|
||||||
|
Description.
|
||||||
|
|
||||||
|
- [ ] LOW: Lower priority task
|
||||||
|
Description.
|
||||||
|
|
||||||
|
## Completion Criteria
|
||||||
|
All tasks checked off and verified.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Add any context Claude needs
|
||||||
|
- Reference specific files if helpful
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create .gitignore entry
|
||||||
|
if [ -f .gitignore ]; then
|
||||||
|
if ! grep -q "ralph-progress.txt" .gitignore; then
|
||||||
|
echo "" >> .gitignore
|
||||||
|
echo "# Ralph" >> .gitignore
|
||||||
|
echo "ralph-progress.txt" >> .gitignore
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Ralph initialized!"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Edit $RALPH_DIR/prd.md with your tasks"
|
||||||
|
echo " 2. Run: ralph run 10"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate PRD from codebase
|
||||||
|
generate_prd() {
|
||||||
|
local type=${1:-"general"}
|
||||||
|
local output="$RALPH_DIR/prd-$type.md"
|
||||||
|
|
||||||
|
mkdir -p "$RALPH_DIR"
|
||||||
|
|
||||||
|
echo "Generating $type PRD..."
|
||||||
|
|
||||||
|
# Use Claude to analyze codebase and generate PRD
|
||||||
|
claude --dangerously-skip-permissions -p \
|
||||||
|
"Analyze this codebase and generate a PRD for: $type
|
||||||
|
|
||||||
|
Create a markdown PRD file with:
|
||||||
|
1. Overview of what needs to be done
|
||||||
|
2. Tasks in priority order (CRITICAL, HIGH, MEDIUM, LOW)
|
||||||
|
3. Each task should have:
|
||||||
|
- [ ] checkbox
|
||||||
|
- Priority label
|
||||||
|
- Clear description
|
||||||
|
- File paths if relevant
|
||||||
|
4. Completion criteria
|
||||||
|
|
||||||
|
Output ONLY the PRD content, no explanations.
|
||||||
|
Format it exactly like this example:
|
||||||
|
|
||||||
|
# [Type] PRD
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Brief description.
|
||||||
|
|
||||||
|
## Tasks (Priority Order)
|
||||||
|
|
||||||
|
- [ ] CRITICAL: Task name
|
||||||
|
Description. Source: path/to/file.ts
|
||||||
|
|
||||||
|
- [ ] HIGH: Another task
|
||||||
|
Description.
|
||||||
|
|
||||||
|
## Completion Criteria
|
||||||
|
What done looks like.
|
||||||
|
" > "$output"
|
||||||
|
|
||||||
|
echo "Generated: $output"
|
||||||
|
echo ""
|
||||||
|
cat "$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show status
|
||||||
|
show_status() {
|
||||||
|
echo "=== Ralph Status ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ -f "$PROGRESS_FILE" ]; then
|
||||||
|
echo "Progress file: $PROGRESS_FILE"
|
||||||
|
echo "---"
|
||||||
|
cat "$PROGRESS_FILE"
|
||||||
|
else
|
||||||
|
echo "No progress file found. Run 'ralph init' first."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "PRD files in $RALPH_DIR/:"
|
||||||
|
ls -la "$RALPH_DIR"/*.md 2>/dev/null || echo " (none)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reset progress
|
||||||
|
reset_progress() {
|
||||||
|
if [ -f "$PROGRESS_FILE" ]; then
|
||||||
|
rm "$PROGRESS_FILE"
|
||||||
|
touch "$PROGRESS_FILE"
|
||||||
|
echo "Progress reset."
|
||||||
|
else
|
||||||
|
echo "No progress file to reset."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main Ralph loop
|
||||||
|
run_ralph() {
|
||||||
|
local iterations=$1
|
||||||
|
local prd_file=${2:-"$RALPH_DIR/prd.md"}
|
||||||
|
local use_docker=${3:-false}
|
||||||
|
|
||||||
|
if [ ! -f "$prd_file" ]; then
|
||||||
|
echo "Error: PRD file not found: $prd_file"
|
||||||
|
echo "Run 'ralph init' first or specify a PRD file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch "$PROGRESS_FILE"
|
||||||
|
|
||||||
|
echo "=== Ralph Loop Starting ==="
|
||||||
|
echo "PRD: $prd_file"
|
||||||
|
echo "Progress: $PROGRESS_FILE"
|
||||||
|
echo "Iterations: $iterations"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for ((i=1; i<=$iterations; i++)); do
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo "=== RALPH ITERATION $i of $iterations ==="
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local claude_cmd="claude --dangerously-skip-permissions"
|
||||||
|
if [ "$use_docker" = true ]; then
|
||||||
|
claude_cmd="docker sandbox run claude --permission-mode acceptEdits"
|
||||||
|
fi
|
||||||
|
|
||||||
|
result=$($claude_cmd -p \
|
||||||
|
"@$prd_file @$PROGRESS_FILE
|
||||||
|
|
||||||
|
You are an AI coding assistant running in a loop (Ralph pattern).
|
||||||
|
|
||||||
|
PROCESS:
|
||||||
|
1. Read the PRD to see what needs to be done.
|
||||||
|
2. Read ralph-progress.txt to see what's already completed.
|
||||||
|
3. Choose the HIGHEST PRIORITY incomplete task.
|
||||||
|
Priority order: CRITICAL > HIGH > MEDIUM > LOW
|
||||||
|
4. Implement the task thoroughly.
|
||||||
|
5. Run any relevant checks (tests, types, linting).
|
||||||
|
6. Append your progress to ralph-progress.txt:
|
||||||
|
- Task completed
|
||||||
|
- Files created/modified
|
||||||
|
- Any issues or notes
|
||||||
|
7. Make a git commit with a clear message.
|
||||||
|
|
||||||
|
RULES:
|
||||||
|
- ONLY WORK ON ONE TASK PER ITERATION.
|
||||||
|
- Be thorough - quality over speed.
|
||||||
|
- If a task is blocked, note it and move to the next.
|
||||||
|
|
||||||
|
If ALL tasks in the PRD are complete, output: <promise>COMPLETE</promise>
|
||||||
|
")
|
||||||
|
|
||||||
|
echo "$result"
|
||||||
|
|
||||||
|
# Check for completion
|
||||||
|
if [[ "$result" == *"<promise>COMPLETE</promise>"* ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo -e "${GREEN}ALL TASKS COMPLETE after $i iteration(s)${NC}"
|
||||||
|
echo "=============================================="
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $i -lt $iterations ]; then
|
||||||
|
echo ""
|
||||||
|
echo "--- Iteration $i done, continuing in 2s ---"
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo -e "${YELLOW}Reached max iterations ($iterations)${NC}"
|
||||||
|
echo "Run 'ralph status' to see progress."
|
||||||
|
echo "=============================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
COMMAND=""
|
||||||
|
ITERATIONS=""
|
||||||
|
PRD_FILE=""
|
||||||
|
USE_DOCKER=false
|
||||||
|
DRY_RUN=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
init)
|
||||||
|
COMMAND="init"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
run)
|
||||||
|
COMMAND="run"
|
||||||
|
shift
|
||||||
|
ITERATIONS=${1:-10}
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
generate)
|
||||||
|
COMMAND="generate"
|
||||||
|
shift
|
||||||
|
GEN_TYPE=${1:-"general"}
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
COMMAND="status"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
reset)
|
||||||
|
COMMAND="reset"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-p|--prd)
|
||||||
|
PRD_FILE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--docker)
|
||||||
|
USE_DOCKER=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--dry-run)
|
||||||
|
DRY_RUN=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-v|--version)
|
||||||
|
echo "Ralph v$VERSION"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Check if it's a number (iterations) or file path
|
||||||
|
if [[ $1 =~ ^[0-9]+$ ]]; then
|
||||||
|
ITERATIONS=$1
|
||||||
|
elif [[ -f $1 ]]; then
|
||||||
|
PRD_FILE=$1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Execute command
|
||||||
|
case $COMMAND in
|
||||||
|
init)
|
||||||
|
init_ralph
|
||||||
|
;;
|
||||||
|
run)
|
||||||
|
if [ -z "$ITERATIONS" ]; then
|
||||||
|
echo "Error: Specify number of iterations"
|
||||||
|
echo "Usage: ralph run <iterations> [prd-file]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
run_ralph "$ITERATIONS" "$PRD_FILE" "$USE_DOCKER"
|
||||||
|
;;
|
||||||
|
generate)
|
||||||
|
generate_prd "$GEN_TYPE"
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
reset)
|
||||||
|
reset_progress
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Loading…
Add table
Add a link
Reference in a new issue