CLI Reference¶
TL;DR
ralph run <path> -n 5 runs the loop. ralph scaffold <name> creates a ralph from a template. Pass user args as --name value flags. Everything is configured in a single RALPH.md file with YAML frontmatter.
ralph¶
With no subcommand, prints the banner and help text.
| Option | Short | Description |
|---|---|---|
--version |
-V |
Show version and exit |
--install-completion |
Install tab completion for your current shell | |
--show-completion |
Print the completion script (for manual setup) | |
--help |
Show help and exit |
Shell completion¶
Restart your shell after installing. Use --show-completion to print the script for manual setup.
ralph run¶
Start the autonomous coding loop.
ralph run my-ralph # Run forever (Ctrl+C to stop)
ralph run my-ralph -n 5 # Run 5 iterations
ralph run my-ralph --stop-on-error # Stop if agent exits non-zero or times out
ralph run my-ralph --delay 10 # Wait 10s between iterations
ralph run my-ralph --timeout 300 # Kill agent after 5 minutes per iteration
ralph run my-ralph --log-dir ralph_logs # Save output to log files
ralph run my-ralph --dir ./src # Pass user args to the ralph
| Argument / Option | Short | Default | Description |
|---|---|---|---|
PATH |
(required) | Path to a ralph directory containing RALPH.md, a direct path to a RALPH.md file, or the name of an installed ralph in .agents/ralphs/ |
|
-n |
unlimited | Max number of iterations | |
--stop-on-error |
-s |
off | Stop loop if agent exits non-zero or times out |
--delay |
-d |
0 |
Seconds to wait between iterations |
--timeout |
-t |
none | Max seconds per iteration |
--log-dir |
-l |
none | Directory for iteration log files |
User arguments¶
User arguments are passed as named flags after the ralph path. Use {{ args.<name> }} placeholders in your RALPH.md to reference them.
Named flags (--name value) work without any frontmatter declaration. The args field is only required when you want to pass positional arguments — it tells ralphify which names to map them to:
---
agent: claude -p --dangerously-skip-permissions
args: [dir, focus]
---
Research the codebase at {{ args.dir }}.
Focus area: {{ args.focus }}
# Named flags (work with or without args declared in frontmatter)
ralph run research --dir ./my-project --focus "performance"
# Equals syntax works too
ralph run research --dir=./my-project --focus="performance"
# Positional args (requires args: [dir, focus] in frontmatter)
ralph run research ./my-project "performance"
# Mixed — positional args skip names already provided via flags
ralph run research --focus "performance" ./my-project
# dir="./my-project", focus="performance"
# -- ends flag parsing — everything after is positional
ralph run research -- --verbose ./src
# dir="--verbose", focus="./src"
Use -- when a positional value starts with -- and would otherwise be parsed as a flag.
Missing args resolve to an empty string.
Stopping the loop¶
Press Ctrl+C to stop the loop. Ralphify uses two-stage signal handling:
| Action | Behavior |
|---|---|
Ctrl+C (first) |
Finishes the current iteration gracefully, then stops the loop |
Ctrl+C (second) |
Force-kills the agent process and exits immediately |
The first press lets the agent complete its current work (e.g. finish a commit). If you don't want to wait, press Ctrl+C again to terminate immediately.
The loop also stops automatically when:
- All
-niterations have completed --stop-on-erroris set and the agent exits non-zero or times out
Peeking at live agent output¶
When you run ralph run in an interactive terminal, the agent's stdout and stderr stream live to the console by default. Press p to silence the stream (useful for quieter loops) and press p again to resume it. The default is off whenever the output is not a real terminal (piped, redirected, or captured in CI), so ralph run ... | cat is unaffected.
The compact peek panel shows the ten most recent activity lines to keep the terminal tidy. When you need to see earlier activity from the current iteration, press shift+P to enter full-screen peek — a scrollable view of the entire buffer that takes over the terminal on the alt screen.
Inside full-screen peek:
| Key | Action |
|---|---|
j / k |
Scroll one line down / up |
space / b |
Page down / page up |
g / G |
Jump to the top / bottom (bottom re-enables follow mode) |
q or P |
Exit back to the compact view |
Activity keeps streaming into the buffer while you scroll, so follow mode (G or scrolling back to the bottom) catches up to the tail. The full-screen view exits automatically when the iteration ends, returning you to the normal terminal.
Live streaming works with line-buffered agents such as Claude Code, OpenAI Codex, Aider, and any other process that writes one line at a time. For Claude running in stream-json mode you'll see the raw JSON events; for other agents you'll see the agent's plain output. Agents that repaint their own terminal UI (full-screen curses or TUI apps) are not supported — ralphify pipes their stdio, so they detect a non-TTY and fall back to plain output.
When --log-dir is set, output is captured to the log file and also echoed after each iteration completes; live peek still works the same way in that mode.
Some runtimes block-buffer their stdout when it is piped, which can make lines appear in bursts rather than as they are produced. If you notice stuttering, set PYTHONUNBUFFERED=1 (or the equivalent for your agent) in the environment where you launch ralph.
ralph scaffold¶
Scaffold a new ralph with a ready-to-customize template.
ralph scaffold my-task # Creates my-task/RALPH.md with a generic template
ralph scaffold # Creates RALPH.md in the current directory
| Argument | Default | Description |
|---|---|---|
[NAME] |
none | Directory name. If omitted, creates RALPH.md in the current directory |
The generated template includes an example command (git-log), an example arg (focus), and a prompt body with placeholders for both. Edit it, then run ralph run. See Getting Started for a full walkthrough.
Errors if RALPH.md already exists at the target location.
RALPH.md format¶
The RALPH.md file is the single configuration and prompt file for a ralph. It uses YAML frontmatter for settings and the body for the prompt text.
---
agent: claude -p --dangerously-skip-permissions
commands:
- name: tests
run: uv run pytest -x
- name: git-log
run: git log --oneline -10
args: [dir, focus]
---
# Prompt body
{{ commands.tests }}
{{ commands.git-log }}
Your instructions here. Reference args with {{ args.dir }}.
Frontmatter fields¶
| Field | Type | Required | Description |
|---|---|---|---|
agent |
string | yes | The full agent command to pipe the prompt to |
commands |
list | no | Commands to run each iteration (each has name and run) |
args |
list of strings | no | Declared argument names for user arguments. Letters, digits, hyphens, and underscores only. |
credit |
bool | no | Append co-author trailer instruction to prompt (default: true) |
Commands¶
Each command has these fields:
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | (required) | Identifier used in {{ commands.<name> }} placeholders. Letters, digits, hyphens, and underscores only. |
run |
string | (required) | Shell command to execute each iteration (supports {{ args.<name> }} placeholders). Commands starting with ./ run from the ralph directory; others run from the project root. |
timeout |
number | 60 |
Max seconds before the command is killed |
Commands run in order. Output (stdout + stderr) is captured regardless of exit code. Commands are parsed with shlex.split() — no shell features (pipes, redirections, &&). For shell features, point the run field at a script. See the Cookbook for real-world command patterns.
If a command exceeds its timeout, the process is killed and the captured output up to that point is used.
Placeholders¶
| Syntax | Resolves to |
|---|---|
{{ commands.<name> }} |
Output of the named command |
{{ args.<name> }} |
Value of the named user argument |
{{ ralph.name }} |
ralph directory name (e.g. my-ralph) |
{{ ralph.iteration }} |
Current iteration number (1-based) |
{{ ralph.max_iterations }} |
Total iterations if -n was set, empty otherwise |
ralph.* placeholders are automatically available — no frontmatter configuration needed.
Unmatched placeholders resolve to an empty string.
Next steps¶
- How it Works — what happens inside each iteration
- Quick Reference — condensed cheat sheet for daily use
- Python API — run loops programmatically instead of via the CLI