Skip to content

Getting Started

This tutorial walks through setting up ralphify, creating a ralph with commands, and running a productive autonomous loop. By the end, you'll have a self-healing coding loop that validates its own work.

Prerequisites

  • Python 3.11+
  • An AI coding agent CLI — this tutorial uses Claude Code, but ralphify works with any agent that accepts piped input
  • A project with a test suite (we'll use this for the feedback loop)

Step 1: Install ralphify

uv tool install ralphify

Verify it's working:

ralph --version

Step 2: Create a ralph directory

A ralph is a directory with a RALPH.md file. Create one in your project:

mkdir my-ralph

Step 3: Write the RALPH.md

Create my-ralph/RALPH.md with the agent field — this is the only required frontmatter:

---
agent: claude -p --dangerously-skip-permissions
---

You are an autonomous coding agent running in a loop. Each iteration
starts with a fresh context. Your progress lives in the code and git.

Read TODO.md for the current task list. Pick the top uncompleted task,
implement it fully, then mark it done.

## Rules

- One task per iteration
- No placeholder code — full, working implementations only
- Run `uv run pytest -x` before committing
- Commit with a descriptive message like `feat: add X` or `fix: resolve Y`
- Mark the completed task in TODO.md

What does --dangerously-skip-permissions do?

Claude Code normally asks for your approval before running shell commands, editing files, or making git commits. The --dangerously-skip-permissions flag disables these interactive prompts so the agent can work autonomously without waiting for input. The -p flag enables non-interactive ("print") mode, which reads the prompt from stdin instead of opening a chat session.

Step 4: Do a test run

Verify the basic loop works before adding commands:

ralph run my-ralph -n 1 --log-dir ralph_logs

This runs a single iteration and saves the output to ralph_logs/. Review the log to see what the agent did:

ls ralph_logs/
cat ralph_logs/001_*.log

Add ralph_logs/ to .gitignore

Log files are useful for debugging but shouldn't be committed:

echo "ralph_logs/" >> .gitignore

If the agent produced useful work, you're ready to add commands.

Step 5: Add a test command

Commands run each iteration and their output is available in the prompt via placeholders. Add a test command to your RALPH.md frontmatter:

---
agent: claude -p --dangerously-skip-permissions
commands:
  - name: tests
    run: uv run pytest -x
---

You are an autonomous coding agent running in a loop. Each iteration
starts with a fresh context. Your progress lives in the code and git.

Read TODO.md for the current task list. Pick the top uncompleted task,
implement it fully, then mark it done.

## Rules

- One task per iteration
- No placeholder code — full, working implementations only
- Run tests before committing
- Commit with a descriptive message like `feat: add X` or `fix: resolve Y`
- Mark the completed task in TODO.md

The tests command runs uv run pytest -x each iteration. Its output is available via {{ commands.tests }} — but you don't have to use the placeholder if you just want the command to run.

Step 6: Add the command output to the prompt

Place the {{ commands.tests }} placeholder where you want the test output to appear:

---
agent: claude -p --dangerously-skip-permissions
commands:
  - name: tests
    run: uv run pytest -x
---

# Prompt

## Test results

{{ commands.tests }}

You are an autonomous coding agent running in a loop. Each iteration
starts with a fresh context. Your progress lives in the code and git.

Read TODO.md for the current task list. Pick the top uncompleted task,
implement it fully, then mark it done.

If tests are failing, fix them before starting new work.

## Rules

- One task per iteration
- No placeholder code — full, working implementations only
- Commit with a descriptive message like `feat: add X` or `fix: resolve Y`
- Mark the completed task in TODO.md

Now each iteration, the agent sees the current test output. If tests fail, the agent fixes them — that's the self-healing loop.

Step 7: Add more commands

Add a lint command and a git log for context:

---
agent: claude -p --dangerously-skip-permissions
commands:
  - name: tests
    run: uv run pytest -x
  - name: lint
    run: uv run ruff check .
  - name: git-log
    run: git log --oneline -10
---

# Prompt

## Recent commits

{{ commands.git-log }}

## Test results

{{ commands.tests }}

## Lint results

{{ commands.lint }}

You are an autonomous coding agent running in a loop. Each iteration
starts with a fresh context. Your progress lives in the code and git.

Read TODO.md for the current task list. Pick the top uncompleted task,
implement it fully, then mark it done.

If tests or lint are failing, fix them before starting new work.

## Rules

- One task per iteration
- No placeholder code — full, working implementations only
- Commit with a descriptive message like `feat: add X` or `fix: resolve Y`
- Mark the completed task in TODO.md

Step 8: Run the loop

Start with a few iterations to verify everything works:

ralph run my-ralph -n 3 --log-dir ralph_logs

Watch the output. Each iteration runs the commands, assembles the prompt with the command output, and pipes it to the agent:

── Iteration 1 ──
✓ Iteration 1 completed (45.2s) → ralph_logs/001_20250115-142301.log

── Iteration 2 ──
✗ Iteration 2 failed with exit code 1 (23.1s)

── Iteration 3 ──
✓ Iteration 3 completed (38.5s) → ralph_logs/003_20250115-142812.log

If the agent breaks a test, the next iteration sees the failure output via {{ commands.tests }} and fixes it automatically.

Once you're confident the loop works, drop the -n 3 to let it run indefinitely. Press Ctrl+C to stop.

Use ralph new for AI-guided setup

Instead of creating ralph directories manually, you can run ralph new my-task to launch an AI-guided session that creates a complete ralph via conversation with your agent.

Next steps

  • Writing Prompts — patterns for writing effective autonomous loop prompts
  • Cookbook — copy-pasteable setups for Python, TypeScript, Rust, and more
  • How it Works — what happens inside each iteration
  • CLI Reference — all commands and options