An implementation of Geoffrey Huntley's Ralph Wiggum technique for multiple AI coding agents, enabling autonomous AI development with deliberate context management.
Supported Agents:
- Cursor Agent (
cursor-agent) - Original Cursor CLI - Claude Code (
claude) - Anthropic's Claude Code CLI - OpenAI Codex CLI (
codex) - OpenAI's Codex CLI - Gemini CLI (
gemini) - Google's Gemini CLI - GitHub Copilot CLI (
copilot) - GitHub's Copilot CLI
"That's the beauty of Ralph - the technique is deterministically bad in an undeterministic world."
Ralph is a technique for autonomous AI development that treats LLM context like memory:
while :; do cat PROMPT.md | agent ; doneThe same prompt is fed repeatedly to an AI agent. Progress persists in files and git, not in the LLM's context window. When context fills up, you get a fresh agent with fresh context.
In traditional programming:
malloc()allocates memoryfree()releases memory
In LLM context:
- Reading files, tool outputs, conversation =
malloc() - There is no
free()- context cannot be selectively released - Only way to free: start a new conversation
This creates two problems:
- Context pollution - Failed attempts, unrelated code, and mixed concerns accumulate and confuse the model
- The gutter - Once polluted, the model keeps referencing bad context. Like a bowling ball in the gutter, there's no saving it.
Ralph's solution: Deliberately rotate to fresh context before pollution builds up. State lives in files and git, not in the LLM's memory.
┌─────────────────────────────────────────────────────────────┐
│ ralph-setup.sh │
│ │ │
│ ┌────────────┴────────────┐ │
│ ▼ ▼ │
│ [gum UI] [fallback] │
│ Agent selection Simple prompts │
│ Model selection │
│ Max iterations │
│ Options (branch, PR) │
│ │ │ │
│ └────────────┬────────────┘ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ Agent Adapters │ │
│ │ ┌─────┬──────┬─────┐ │ │
│ │ │Cursor│Claude│Gemini│ │ │
│ │ │ │ Code │ CLI │ │ │
│ │ ├─────┴──────┴─────┤ │ │
│ │ │ Copilot CLI │ │ │
│ │ └──────────────────┘ │ │
│ └────────────────────────┘ │
│ │ │
│ <agent> --output-format stream-json │
│ │ │
│ ▼ │
│ stream-parser.sh │
│ │ │ │
│ ┌────────────────┴────────┴────────────────┐ │
│ ▼ ▼ │
│ .ralph/ Signals │
│ ├── activity.log (tool calls) ├── WARN at 70k │
│ ├── errors.log (failures) ├── ROTATE at 80k│
│ ├── progress.md (agent writes) ├── COMPLETE │
│ └── guardrails.md (lessons learned) └── GUTTER │
│ │
│ When ROTATE → fresh context, continue from git │
└─────────────────────────────────────────────────────────────┘
Key features:
- Multi-agent support - Use Cursor, Claude Code, Gemini CLI, or Copilot CLI
- Interactive setup - Beautiful gum-based UI for agent, model selection and options
- Accurate token tracking - Parser counts actual bytes from every file read/write
- Gutter detection - Detects when agent is stuck (same command failed 3x, file thrashing)
- Learning from failures - Agent updates
.ralph/guardrails.mdwith lessons - State in git - Commits frequently so next agent picks up from git history
- Branch/PR workflow - Optionally work on a branch and open PR when complete
| Requirement | Check | How to Set Up |
|---|---|---|
| Git repo | git status works |
git init |
| At least one agent | See below | Install any supported agent |
| gum (optional) | which gum |
Installer offers to install, or brew install gum |
Install at least one of these AI coding agents:
| Agent | CLI | Install Command | Stream JSON |
|---|---|---|---|
| Cursor Agent | cursor-agent |
curl https://cursor.com/install -fsS | bash |
✅ Full |
| Claude Code | claude |
npm install -g @anthropic-ai/claude-code |
✅ Full |
| OpenAI Codex CLI | codex |
npm install -g @openai/codex |
✅ Full |
| Gemini CLI | gemini |
npm install -g @google/gemini-cli |
✅ Full |
| GitHub Copilot CLI | copilot |
npm install -g @github/copilot |
*GitHub Copilot CLI does not yet support --output-format stream-json (github/copilot-cli#52). Token tracking will be limited when using this agent.
Ralph will automatically detect which agents are installed and let you choose.
cd your-project
curl -fsSL https://raw.githubusercontent.com/agrimsingh/ralph-wiggum-cursor/main/install.sh | bashThis creates:
your-project/
├── .cursor/ralph-scripts/ # Ralph scripts
│ ├── ralph-setup.sh # Main entry point (interactive)
│ ├── ralph-loop.sh # CLI mode (for scripting)
│ ├── ralph-once.sh # Single iteration (testing)
│ ├── stream-parser.sh # Token tracking
│ ├── ralph-common.sh # Shared functions
│ ├── init-ralph.sh # Re-initialize if needed
│ └── agents/ # Agent adapters
│ ├── agent-base.sh # Base agent system
│ ├── cursor.sh # Cursor Agent adapter
│ ├── claude-code.sh # Claude Code adapter
│ ├── gemini-cli.sh # Gemini CLI adapter
│ └── copilot-cli.sh # Copilot CLI adapter
├── .ralph/ # State files (tracked in git)
│ ├── progress.md # Agent updates: what's done
│ ├── guardrails.md # Lessons learned (Signs)
│ ├── activity.log # Tool call log (parser writes)
│ └── errors.log # Failure log (parser writes)
└── RALPH_TASK.md # Your task definition
The installer will offer to install gum automatically. You can also:
- Skip the prompt and auto-install:
curl ... | INSTALL_GUM=1 bash - Install manually:
brew install gum(macOS) or see gum installation
With gum, you get a beautiful interactive menu for selecting agents, models and options:
? Select AI agent:
◉ Cursor Agent
◯ Claude Code
◯ Gemini CLI
◯ GitHub Copilot CLI
? Select model:
◉ claude-sonnet-4-20250514
◯ claude-opus-4-20250514
◯ claude-3-5-sonnet-20241022
◯ Custom...
? Max iterations: 20
? Options:
◯ Commit to current branch
◯ Run single iteration first
◯ Work on new branch
◯ Open PR when complete
Without gum, Ralph falls back to simple numbered prompts. Model options are dynamically loaded based on the selected agent.
Edit RALPH_TASK.md:
---
task: Build a REST API
test_command: "npm test"
---
# Task: REST API
Build a REST API with user management.
## Success Criteria
1. [ ] GET /health returns 200
2. [ ] POST /users creates a user
3. [ ] GET /users/:id returns user
4. [ ] All tests pass
## Context
- Use Express.js
- Store users in memory (no database needed)Important: Use [ ] checkboxes. Ralph tracks completion by counting unchecked boxes.
./.cursor/ralph-scripts/ralph-setup.shRalph will:
- Show interactive UI for model and options (or simple prompts if gum not installed)
- Run
cursor-agentwith your task - Parse output in real-time, tracking token usage
- At 70k tokens: warn agent to wrap up current work
- At 80k tokens: rotate to fresh context
- Repeat until all
[ ]are[x](or max iterations reached)
# Watch activity in real-time
tail -f .ralph/activity.log
# Example output:
# [12:34:56] 🟢 READ src/index.ts (245 lines, ~24.5KB)
# [12:34:58] 🟢 WRITE src/routes/users.ts (50 lines, 2.1KB)
# [12:35:01] 🟢 SHELL npm test → exit 0
# [12:35:10] 🟢 TOKENS: 45,230 / 80,000 (56%) [read:30KB write:5KB assist:10KB shell:0KB]
# Check for failures
cat .ralph/errors.log| Command | Description |
|---|---|
ralph-setup.sh |
Primary - Interactive setup + run loop |
ralph-once.sh |
Test single iteration before going AFK |
ralph-loop.sh |
CLI mode for scripting (see flags below) |
init-ralph.sh |
Re-initialize Ralph state |
./ralph-loop.sh [options] [workspace]
Options:
-a, --agent AGENT Agent to use (cursor, claude-code, codex-cli, gemini-cli, copilot-cli)
-n, --iterations N Max iterations (default: 20)
-m, --model MODEL Model to use (defaults based on agent)
--branch NAME Create and work on a new branch
--pr Open PR when complete (requires --branch)
-y, --yes Skip confirmation promptExamples:
# Use Claude Code with default model
./ralph-loop.sh -a claude-code
# Use OpenAI Codex with specific model
./ralph-loop.sh -a codex-cli -m gpt-5-codex
# Use Gemini CLI with specific model
./ralph-loop.sh -a gemini-cli -m gemini-2.5-pro
# Scripted PR workflow with Copilot
./ralph-loop.sh -a copilot-cli --branch feature/api --pr -y
# Use Cursor (default) with more iterations
./ralph-loop.sh -n 50 -m gpt-5.2-highIteration 1 Iteration 2 Iteration N
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Fresh context │ │ Fresh context │ │ Fresh context │
│ │ │ │ │ │ │ │ │
│ ▼ │ │ ▼ │ │ ▼ │
│ Read RALPH_TASK │ │ Read RALPH_TASK │ │ Read RALPH_TASK │
│ Read guardrails │──────────│ Read guardrails │──────────│ Read guardrails │
│ Read progress │ (state │ Read progress │ (state │ Read progress │
│ │ │ in git) │ │ │ in git) │ │ │
│ ▼ │ │ ▼ │ │ ▼ │
│ Work on criteria │ │ Work on criteria │ │ Work on criteria │
│ Commit to git │ │ Commit to git │ │ Commit to git │
│ │ │ │ │ │ │ │ │
│ ▼ │ │ ▼ │ │ ▼ │
│ 80k tokens │ │ 80k tokens │ │ All [x] done! │
│ ROTATE ──────────┼──────────┼──────────────────┼──────────┼──► COMPLETE │
└──────────────────┘ └──────────────────┘ └──────────────────┘
Each iteration:
- Reads task and state from files (not from previous context)
- Works on unchecked criteria
- Commits progress to git
- Updates
.ralph/progress.mdand.ralph/guardrails.md - Rotates when context is full
The agent is instructed to commit frequently:
# After each criterion
git add -A && git commit -m 'ralph: [criterion] - description'
# Push periodically
git pushCommits are the agent's memory. The next iteration picks up from git history.
When something fails, the agent adds a "Sign" to .ralph/guardrails.md:
### Sign: Check imports before adding
- **Trigger**: Adding a new import statement
- **Instruction**: First check if import already exists in file
- **Added after**: Iteration 3 - duplicate import caused build failureFuture iterations read guardrails first and follow them, preventing repeated mistakes.
Error occurs → errors.log → Agent analyzes → Updates guardrails.md → Future agents follow
The activity log shows context health with emoji:
| Emoji | Status | Token % | Meaning |
|---|---|---|---|
| 🟢 | Healthy | < 60% | Plenty of room |
| 🟡 | Warning | 60-80% | Approaching limit |
| 🔴 | Critical | > 80% | Rotation imminent |
Example:
[12:34:56] 🟢 READ src/index.ts (245 lines, ~24.5KB)
[12:40:22] 🟡 TOKENS: 58,000 / 80,000 (72%) - approaching limit [read:40KB write:8KB assist:10KB shell:0KB]
[12:45:33] 🔴 TOKENS: 72,500 / 80,000 (90%) - rotation imminent
The parser detects when the agent is stuck:
| Pattern | Trigger | What Happens |
|---|---|---|
| Repeated failure | Same command failed 3x | GUTTER signal |
| File thrashing | Same file written 5x in 10 min | GUTTER signal |
| Agent signals | Agent outputs <ralph>GUTTER</ralph> |
GUTTER signal |
When gutter is detected:
- Check
.ralph/errors.logfor the pattern - Fix the issue manually or add a guardrail
- Re-run the loop
Ralph detects completion in two ways:
- Checkbox check: All
[ ]in RALPH_TASK.md changed to[x] - Agent sigil: Agent outputs
<ralph>COMPLETE</ralph>
Both are verified before declaring success.
| File | Purpose | Who Uses It |
|---|---|---|
RALPH_TASK.md |
Task definition + success criteria | You define, agent reads |
.ralph/progress.md |
What's been accomplished | Agent writes after work |
.ralph/guardrails.md |
Lessons learned (Signs) | Agent reads first, writes after failures |
.ralph/activity.log |
Tool call log with token counts | Parser writes, you monitor |
.ralph/errors.log |
Failures + gutter detection | Parser writes, agent reads |
.ralph/.iteration |
Current iteration number | Parser reads/writes |
Configuration is set via command-line flags or environment variables:
# Via flags (recommended)
./ralph-loop.sh -a claude-code -n 50 -m claude-sonnet-4-20250514
# Via environment
RALPH_AGENT=claude-code RALPH_MODEL=claude-sonnet-4-20250514 MAX_ITERATIONS=50 ./ralph-loop.sh| Environment Variable | Description | Default |
|---|---|---|
RALPH_AGENT |
Agent to use | cursor |
RALPH_MODEL |
Model name | Agent-specific default |
MAX_ITERATIONS |
Max rotations | 20 |
WARN_THRESHOLD |
Token warning | 70000 |
ROTATE_THRESHOLD |
Token rotation | 80000 |
Default thresholds in ralph-common.sh:
RALPH_AGENT=cursor # Default agent
MAX_ITERATIONS=20 # Max rotations before giving up
WARN_THRESHOLD=70000 # Tokens: send wrapup warning
ROTATE_THRESHOLD=80000 # Tokens: force rotationInstall at least one agent:
# Cursor Agent
curl https://cursor.com/install -fsS | bash
# Claude Code
npm install -g @anthropic-ai/claude-code
# OpenAI Codex CLI
npm install -g @openai/codex
# Gemini CLI
npm install -g @google/gemini-cli
# GitHub Copilot CLI
npm install -g @github/copilotMake sure the selected agent's CLI is installed and in your PATH:
| Agent | Check Command |
|---|---|
| Cursor | which cursor-agent |
| Claude Code | which claude |
| OpenAI Codex | which codex |
| Gemini CLI | which gemini |
| Copilot CLI | which copilot |
Check .ralph/errors.log for the pattern. Either:
- Fix the underlying issue manually
- Add a guardrail to
.ralph/guardrails.mdexplaining what to do differently
The agent might be reading too many large files. Check activity.log for large READs and consider:
- Adding a guardrail: "Don't read the entire file, use grep to find relevant sections"
- Breaking the task into smaller pieces
Check if criteria are too vague. Each criterion should be:
- Specific and testable
- Achievable in a single iteration
- Not dependent on manual steps
./ralph-setup.sh # Interactive setup → runs loop → done./ralph-once.sh # Run ONE iteration
# Review changes...
./ralph-setup.sh # Continue with full loop./ralph-loop.sh --branch feature/foo --pr -y- Original Ralph technique - Geoffrey Huntley
- Context as memory - The malloc/free metaphor
- gum - A tool for glamorous shell scripts
- Original technique: Geoffrey Huntley - the Ralph Wiggum methodology
- Cursor port: Agrim Singh - original Cursor implementation
- Multi-agent support: Extended to support Claude Code, Gemini CLI, and Copilot CLI
MIT