Unified bash script for running Claude Code with the Ralph approach in both HITL (Human-in-the-Loop) and AFK (Away From Keyboard) modes.
- Unified script for both HITL and AFK modes
- Conventional Commits - Claude writes proper commit messages to
.pending-commit - Signed commits after each iteration (handled by script, not Claude)
- Auto-completion detection - Stops when all PRD tasks are complete
- Docker sandbox support for isolated execution (optional, requires setup)
- Configurable PRD and progress file paths
┌─────────────────────────────────────────────────────────────┐
│ 1. Claude reads PRD.json and progress.txt │
│ 2. Claude implements the next task │
│ 3. Claude writes commit message to .pending-commit │
│ 4. Script reads .pending-commit and creates signed commit │
│ 5. Repeat until PRD complete │
└─────────────────────────────────────────────────────────────┘
- Claude Code CLI - The
claudecommand must be installed and authenticated - jq (optional) - For auto-completion detection (checks if all PRD tasks are done)
# macOS brew install jq # Ubuntu/Debian sudo apt install jq # Fedora sudo dnf install jq
- GPG (optional) - For signed commits
chmod +x install-ralph.sh
./install-ralph.sh# 1. Copy ralph.sh to your local bin
mkdir -p ~/.local/bin
cp ralph.sh ~/.local/bin/ralph
chmod +x ~/.local/bin/ralph
# 2. Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"Ralph supports Docker sandboxes for isolated execution. Sandbox is disabled by default because it requires one-time setup per project.
Docker sandboxes provide lightweight microVMs that isolate AI coding agents from your host system:
- Complete isolation: Agent runs in a separate microVM, preventing host system access
- Private Docker daemon: Each sandbox has its own isolated Docker environment
- File synchronization: Your workspace syncs between host and sandbox at matching paths
- Persistent state: Authentication persists within the sandbox
- Docker Desktop 4.57+ with sandbox support enabled
- macOS or Windows: Full microVM-based sandbox support
- Linux: Legacy container-based sandboxes with Docker Desktop 4.57+
Docker sandboxes are isolated and cannot access your host's Claude credentials. You need to authenticate inside the sandbox once.
Option 1: Default sandbox name (recommended)
cd /path/to/your/project
# Creates sandbox named 'claude-<foldername>' (e.g., 'claude-my-project')
docker sandbox run claude .
# Inside the sandbox:
/login
# Follow prompts, then exit (Ctrl+C or /exit)
# Now use ralph:
ralph -m afk -s 5Option 2: Custom sandbox name
cd /path/to/your/project
# Create with custom name
docker sandbox run --name my-custom-sandbox claude .
# Login and exit
/login
# Use ralph with the name:
ralph -m afk -s my-custom-sandbox 5# List all sandboxes (shows name and workspace)
docker sandbox ls
# Remove a sandbox (will need to re-authenticate)
docker sandbox rm <sandbox-name>By default, ralph runs without sandbox isolation:
ralph -m afk 5 # No sandbox, uses host Claude authenticationFor more information, see the Docker AI Sandboxes documentation.
# Show help
ralph -h
# HITL mode (default) - single iteration
ralph
# HITL mode - multiple iterations with pause between each
ralph 3
# AFK mode - 5 autonomous iterations
ralph -m afk 5
# AFK mode with Docker sandbox (requires one-time setup)
ralph -m afk -s 5
# AFK mode with named sandbox
ralph -m afk -s my-sandbox 5
# Custom PRD and progress files
ralph -p docs/PRD.json -r docs/progress.txt
# Without signed commits
ralph --no-sign| Option | Description | Default |
|---|---|---|
-m, --mode |
Mode: hitl or afk |
hitl |
-s, --sandbox [name] |
Run in Docker sandbox. Optional: specify sandbox name | false |
--no-sandbox |
Disable Docker sandbox | default |
-p, --prd |
PRD file path | PRD.json |
-r, --progress |
Progress file path | progress.txt |
--no-sign |
Disable GPG commit signing | signing enabled |
Claude is instructed to write proper conventional commit messages to .pending-commit. The format follows:
<type>(<scope>): <description>
<optional body>
Ralph automatically detects commitlint configuration files and instructs Claude to follow your project's commit rules. Supported config files:
commitlint.config.js,.cjs,.mjs,.ts.commitlintrc,.commitlintrc.json,.commitlintrc.yaml,.commitlintrc.yml.commitlintrc.js,.commitlintrc.cjs,.commitlintrc.mjs,.commitlintrc.tspackage.json(with"commitlint"key)
When a config is detected, you'll see:
Commitlint config: commitlint.config.js
Claude will read the config and follow your custom rules (types, scopes, max lengths, etc.) in addition to the default conventional commit format.
| Type | Description |
|---|---|
feat |
A new feature |
fix |
A bug fix |
docs |
Documentation changes |
style |
Code style (formatting, semicolons) |
refactor |
Code change without fix/feature |
perf |
Performance improvement |
test |
Adding/correcting tests |
build |
Build system or dependencies |
ci |
CI configuration |
chore |
Other maintenance |
feat(auth): add JWT token refresh mechanism
fix(api): handle null response in user endpoint
refactor(components): extract shared button styles
docs: add API documentation for v2 endpoints
- Claude works on one task at a time
- Pauses between iterations for human review
- You can stop anytime with
Ctrl+C - Best for: supervised work, learning, critical tasks
- Claude works autonomously through tasks
- Shows Claude's normal terminal output
- Auto-stops when all PRD tasks have
passes: true(requires jq) - Falls back to running all iterations if jq not installed
- Optional Docker sandbox for extra isolation (
-sflag) - Best for: overnight runs, bulk work, trusted environments
your-project/
├── PRD.json # Project requirements document
├── progress.txt # Progress log (auto-created if missing)
├── .pending-commit # Temporary commit message (auto-cleaned)
└── .gitignore # Add .pending-commit here
.pending-commitTo use signed commits, ensure GPG is configured:
# Check if you have a GPG key
gpg --list-secret-keys --keyid-format=long
# If not, generate one
gpg --full-generate-key
# Configure git to use your key
git config --global user.signingkey YOUR_KEY_ID
git config --global commit.gpgsign true{
"project": "My Awesome App",
"overview": "Brief description of the project.",
"tasks": [
{ "id": 1, "title": "Set up project with Vite + React + TypeScript", "status": "pending" },
{ "id": 2, "title": "Create basic routing structure", "status": "pending" },
{ "id": 3, "title": "Implement authentication flow", "status": "pending" },
{ "id": 4, "title": "Build dashboard component", "status": "pending" },
{ "id": 5, "title": "Add unit tests", "status": "pending" },
{ "id": 6, "title": "Configure CI/CD pipeline", "status": "pending" }
]
}# Progress Log
## 2025-01-25
### 14:32 - Setup
- Initialized Vite project with React and TypeScript
- Configured ESLint and Prettier
- Created initial folder structure
### 15:45 - Routing
- Added React Router v6
- Created Layout component with header/footer
- Implemented route guards for auth# Ensure ~/.local/bin is in PATH
echo $PATH | grep -q ".local/bin" || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc# Test GPG signing
echo "test" | gpg --clearsign
# If it fails, set GPG_TTY
export GPG_TTY=$(tty)This is normal if Claude didn't make any changes. The script falls back to a default commit message.
# Check Docker Desktop is running
docker info
# Verify sandbox support
docker sandbox lsIf docker sandbox ls fails:
- Ensure Docker Desktop is version 4.57 or later
- Update Docker Desktop if needed
- Restart Docker Desktop
- Check that sandbox feature is enabled in Docker Desktop settings
If you get "Invalid API key" or "/login" error in sandbox mode:
You need to authenticate inside the sandbox (one-time per project):
cd /your/project
docker sandbox run claude .
/login
# Follow prompts, then exitThe sandbox is isolated and cannot access your host's credentials.
If sandbox still doesn't work:
# Run without sandbox (this is the default behavior)
ralph -m afk 5For more help, see the Docker AI Sandboxes documentation.
MIT