Skip to content
 
 

Repository files navigation

Ralph

Ralph

Ralph is an autonomous AI agent loop that runs OpenCode repeatedly until all PRD items are complete. Each iteration is a fresh OpenCode instance with clean context. Memory persists via git history, progress.txt, and prd.json.

Based on Geoffrey Huntley's Ralph pattern.

Read my in-depth article on how I use Ralph

Prerequisites

  • OpenCode CLI installed and authenticated
  • jq installed (brew install jq on macOS)
  • A git repository for your project

Setup

Install OpenCode

Install OpenCode via the install script or your package manager:

curl -fsSL https://opencode.ai/install | bash

Or via Homebrew, npm, or other package managers. See OpenCode installation docs for details.

Authenticate with LLM Provider

Set up your LLM provider API keys:

opencode auth login

Follow the prompts to configure your preferred provider (OpenAI, Anthropic, Gemini, etc.).

Option 1: Copy to your project

Copy the ralph files into your project:

# From your project root
mkdir -p scripts/ralph
cp /path/to/ralph/ralph.sh scripts/ralph/
cp /path/to/ralph/prompt.md scripts/ralph/
chmod +x scripts/ralph/ralph.sh

Option 2: Initialize OpenCode in your project

Run OpenCode initialization to generate project context:

cd /path/to/your/project
opencode
/init

This creates AGENTS.md with project context. Commit this file to version control.

Configure OpenCode

The project includes an opencode.json configuration file that sets up the build agent with all tools enabled. You can customize this file to:

  • Set your preferred model provider
  • Configure tool permissions
  • Add MCP servers for external integrations

See OpenCode configuration docs for details.

Workflow

1. Create a PRD

Create a Product Requirements Document for your feature. You can:

  • Write it manually in markdown format
  • Use OpenCode to help generate it: opencode run "Create a PRD for [your feature description]"
  • Use the example format in prd.json.example as a template

Save it to tasks/prd-[feature-name].md.

2. Convert PRD to Ralph format

Convert the markdown PRD to prd.json format. You can:

  • Use OpenCode to convert it: opencode run "Convert tasks/prd-[feature-name].md to prd.json format following the structure in prd.json.example"
  • Manually create prd.json following the example format

This creates prd.json with user stories structured for autonomous execution.

3. Run Ralph

./ralph.sh [max_iterations]

Default is 10 iterations.

Ralph will:

  1. Create a feature branch (from PRD branchName)
  2. Pick the highest priority story where passes: false
  3. Implement that single story
  4. Run quality checks (typecheck, tests)
  5. Commit if checks pass
  6. Update prd.json to mark story as passes: true
  7. Append learnings to progress.txt
  8. Repeat until all stories pass or max iterations reached

Key Files

File Purpose
ralph.sh The bash loop that spawns fresh OpenCode instances
prompt.md Instructions given to each OpenCode instance
prd.json User stories with passes status (the task list)
prd.json.example Example PRD format for reference
progress.txt Append-only learnings for future iterations
opencode.json OpenCode configuration for the project
flowchart/ Interactive visualization of how Ralph works

Flowchart

Ralph Flowchart

View Interactive Flowchart - Click through to see each step with animations.

The flowchart/ directory contains the source code. To run locally:

cd flowchart
npm install
npm run dev

Critical Concepts

Each Iteration = Fresh Context

Each iteration spawns a new OpenCode instance with clean context. The only memory between iterations is:

  • Git history (commits from previous iterations)
  • progress.txt (learnings and context)
  • prd.json (which stories are done)
  • AGENTS.md (project patterns and conventions)

Small Tasks

Each PRD item should be small enough to complete in one context window. If a task is too big, the LLM runs out of context before finishing and produces poor code.

Right-sized stories:

  • Add a database column and migration
  • Add a UI component to an existing page
  • Update a server action with new logic
  • Add a filter dropdown to a list

Too big (split these):

  • "Build the entire dashboard"
  • "Add authentication"
  • "Refactor the API"

AGENTS.md Updates Are Critical

After each iteration, Ralph updates the relevant AGENTS.md files with learnings. This is key because OpenCode automatically reads these files, so future iterations (and future human developers) benefit from discovered patterns, gotchas, and conventions.

Examples of what to add to AGENTS.md:

  • Patterns discovered ("this codebase uses X for Y")
  • Gotchas ("do not forget to update Z when changing W")
  • Useful context ("the settings panel is in component X")

Feedback Loops

Ralph only works if there are feedback loops:

  • Typecheck catches type errors
  • Tests verify behavior
  • CI must stay green (broken code compounds across iterations)

Browser Verification for UI Stories

Frontend stories must include browser verification in acceptance criteria. Ralph will use available browser testing tools to navigate to the page, interact with the UI, and confirm changes work.

Stop Condition

When all stories have passes: true, Ralph outputs <promise>COMPLETE</promise> and the loop exits.

Debugging

Check current state:

# See which stories are done
cat prd.json | jq '.userStories[] | {id, title, passes}'

# See learnings from previous iterations
cat progress.txt

# Check git history
git log --oneline -10

Customizing prompt.md

Edit prompt.md to customize Ralph's behavior for your project:

  • Add project-specific quality check commands
  • Include codebase conventions
  • Add common gotchas for your stack

Archiving

Ralph automatically archives previous runs when you start a new feature (different branchName). Archives are saved to archive/YYYY-MM-DD-feature-name/.

References

About

Ralph is an autonomous AI agent loop that runs repeatedly until all PRD items are complete.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages