Stop stressing over not having an agent running. Ralph is always running
Project description
A ralph is a directory that defines an autonomous agent loop. It bundles a prompt, commands, and any files your agent needs. Ralphify is the CLI runtime that executes them.
grow-coverage/
├── RALPH.md # the prompt (only required file)
├── check-coverage.sh # command that runs each iteration
└── testing-conventions.md # context for the agent
---
agent: claude -p --dangerously-skip-permissions
commands:
- name: coverage
run: ./check-coverage.sh
---
You are an autonomous coding agent working in a loop.
Each iteration, write tests for one untested module, then stop.
Follow the conventions in testing-conventions.md.
## Current coverage
{{ commands.coverage }}
ralph run grow-coverage # loops until Ctrl+C
That's it. One directory. One command. The agent loops — running commands, building a fresh prompt with the latest output, and piping it to your agent. Every iteration starts with clean context and current data.
Works with any agent CLI. Swap claude -p for Codex, Aider, or your own — just change the agent field.
Why loops
A single agent run can fix a bug or write a function. But the real leverage is sustained, autonomous work — campaigns that run for hours, chipping away at a goal one commit at a time while you do something else.
Ralph loops give you:
- Incremental progress in small chunks. Each iteration does one thing, tests it, and commits. Small changes are easier to review and safer to ship.
- Fresh context every iteration. No context window bloat. The agent starts clean each loop and sees the current state of the codebase — including everything it changed last iteration.
- Continuous work toward a goal. The loop keeps running until you hit Ctrl+C or it reaches the iteration limit. Walk away, come back to a pile of commits.
- No micromanagement. Define the goal once in the prompt, tune with commands that feed live data back in. The agent figures out what to do next.
- The prompt is a tuning knob. When the agent does something dumb, add a rule. Like putting up a sign: "SLIDE DOWN, DON'T JUMP."
What people build ralphs for
| Ralph | What it does |
|---|---|
| grow-coverage | Write tests for untested modules, one per iteration, until coverage hits the target |
| security-audit | Hunt for vulnerabilities — scan, find, fix, verify, repeat |
| clear-backlog | Work through a TODO list or issue tracker, one task per loop |
| write-docs | Generate documentation for undocumented modules, one at a time |
| improve-codebase | Find and fix code smells, refactor patterns, modernize APIs |
| migrate | Incrementally migrate files from one framework or pattern to another |
| research | Deep-dive into a topic — gather sources, synthesize, and build a knowledge base |
| bug-hunter | Run the test suite, find edge cases, write regression tests |
| perf-sweep | Profile, find bottlenecks, optimize, benchmark, repeat |
The ralph format is intentionally simple — if you've written a skill file or a GitHub Action, you already know how it works. YAML frontmatter for config, markdown body for the prompt, {{ commands.name }} placeholders for live data.
Install
uv tool install ralphify # recommended
Or if you don't have uv:
pipx install ralphify # isolated install via pipx
pip install ralphify # plain pip (use a virtualenv or --user)
Any of these gives you the ralph command.
Quickstart
Scaffold a ralph and start experimenting:
ralph scaffold my-ralph
Edit my-ralph/RALPH.md, then run it:
ralph run my-ralph # loops until Ctrl+C
ralph run my-ralph -n 5 # run 5 iterations then stop
What ralph run does
Each iteration:
- Runs commands — executes all commands in the ralph, captures output
- Builds prompt — reads the RALPH.md body, replaces
{{ commands.<name> }}placeholders with fresh output - Pipes to agent — runs the agent command with the assembled prompt on stdin
- Repeats — goes back to step 1 with updated data
What it looks like
$ ralph run grow-coverage -n 3
▶ Running: grow-coverage
1 command · max 3 iterations
── Iteration 1 ──
Commands: 1 ran
✓ Iteration 1 completed (52.3s)
── Iteration 2 ──
Commands: 1 ran
✗ Iteration 2 failed with exit code 1 (23.1s)
── Iteration 3 ──
Commands: 1 ran
✓ Iteration 3 completed (41.7s)
──────────────────────
Done: 3 iterations — 2 succeeded, 1 failed
The ralph format
A ralph is a directory containing a RALPH.md file. Everything the ralph needs lives in that directory — scripts, reference docs, test data, whatever the agent might need.
my-ralph/
├── RALPH.md # the prompt (required)
├── check-coverage.sh # script (optional)
├── style-guide.md # reference doc (optional)
└── test-data.json # any supporting file (optional)
RALPH.md has YAML frontmatter for configuration and a markdown body that becomes the prompt:
| Frontmatter field | Required | Description |
|---|---|---|
agent |
Yes | The agent command to run |
commands |
No | List of commands (name + run) whose output fills {{ commands.<name> }} placeholders |
args |
No | Declared argument names for {{ args.<name> }} placeholders |
credit |
No | Append co-author trailer instruction to prompt (default: true) |
Commands run before each iteration. Their output replaces {{ commands.<name> }} placeholders in the prompt. Use them for test results, coverage reports, git history, lint output — anything that changes between iterations.
The technique
The Ralph Wiggum technique works because:
- One thing per loop. The agent picks the most important task, implements it, tests it, and commits. Then the next iteration starts fresh.
- Fresh context every time. No context window bloat. Each loop starts clean and reads the current state of the codebase.
- Progress lives in git. Code, commits, and a plan file are the only state that persists between iterations. If something goes wrong,
git reset --hardand run more loops.
Read the full writeup: Ralph Wiggum as a "software engineer"
Share ralphs
Use agr to install shared ralphs from GitHub:
agr add owner/repo/grow-coverage # install a ralph from GitHub
ralph run grow-coverage # run it by name
Ralphs installed by agr go to .agents/ralphs/ and are automatically discovered by ralph run.
Documentation
Full documentation at ralphify.co/docs — getting started tutorial, format spec, cookbook, CLI reference, and troubleshooting.
Requirements
- Python 3.11+
- An agent CLI that accepts piped input (Claude Code, Codex, Aider, or your own)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ralphify-0.4.0b1.tar.gz.
File metadata
- Download URL: ralphify-0.4.0b1.tar.gz
- Upload date:
- Size: 641.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6e8a1c4d6fc3b27920bea6fb2caddf4673f67037be9ac421c74c0805cbd333e
|
|
| MD5 |
f3312852904f404dad658b1fe10c3198
|
|
| BLAKE2b-256 |
26e7377592c8a2c63bd47f6efe55f95864b059e75a717ce8b0a70b35dcdaa4f6
|
Provenance
The following attestation bundles were made for ralphify-0.4.0b1.tar.gz:
Publisher:
publish.yml on computerlovetech/ralphify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ralphify-0.4.0b1.tar.gz -
Subject digest:
f6e8a1c4d6fc3b27920bea6fb2caddf4673f67037be9ac421c74c0805cbd333e - Sigstore transparency entry: 1257544502
- Sigstore integration time:
-
Permalink:
computerlovetech/ralphify@6beb0d876d37ba0ff901774304adc4ea5854e420 -
Branch / Tag:
refs/tags/v0.4.0b1 - Owner: https://github.com/computerlovetech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6beb0d876d37ba0ff901774304adc4ea5854e420 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ralphify-0.4.0b1-py3-none-any.whl.
File metadata
- Download URL: ralphify-0.4.0b1-py3-none-any.whl
- Upload date:
- Size: 47.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab1557457da8d699a721a5042e8b696c52e08fe8498ea189b3b8bda543925c49
|
|
| MD5 |
effd73193053d260c059c60c11869cc0
|
|
| BLAKE2b-256 |
1a89e3ad5808a81228c38680c1887e227336a0d0e116f80c5f2026b502477290
|
Provenance
The following attestation bundles were made for ralphify-0.4.0b1-py3-none-any.whl:
Publisher:
publish.yml on computerlovetech/ralphify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ralphify-0.4.0b1-py3-none-any.whl -
Subject digest:
ab1557457da8d699a721a5042e8b696c52e08fe8498ea189b3b8bda543925c49 - Sigstore transparency entry: 1257544667
- Sigstore integration time:
-
Permalink:
computerlovetech/ralphify@6beb0d876d37ba0ff901774304adc4ea5854e420 -
Branch / Tag:
refs/tags/v0.4.0b1 - Owner: https://github.com/computerlovetech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6beb0d876d37ba0ff901774304adc4ea5854e420 -
Trigger Event:
push
-
Statement type: