Skip to main content

Iterative work/review loop for Claude Code

Project description

ralphkit

ralphkit

A step-based pipeline for Claude Code. Define setup, loop, and cleanup phases in a YAML config. The loop iterates until the reviewer says SHIP or max iterations are reached.

Inspired by the ralph loop.

Install

pip install ralphkit

With uv:

uv tool install ralphkit

Or run directly without installing:

uvx ralphkit ralph-loop "your task here" --config ralph.yaml

Quick Start

# Run with built-in defaults (no config needed)
ralph-loop "Create a Python function in prime.py that checks if a number is prime. Include unit tests."

# Or with a custom config
ralph-loop "Create a Python function in prime.py that checks if a number is prime. Include unit tests." --config configs/example.yaml

Usage

ralph-loop TASK [OPTIONS]

Arguments:

Argument Description Default
TASK Task description (string or path to .md file) required
--config PATH Path to YAML config file built-in defaults
--max-iterations N Override max iterations from config 10
-f / --force Skip confirmation prompt off

Examples:

# No config — uses built-in worker/reviewer loop
ralph-loop "Build a REST API"

# With a custom config
ralph-loop "Build a REST API" --config ralph.yaml

# Task from a markdown file
ralph-loop task.md --config ralph.yaml

# Override max iterations
ralph-loop "Build a REST API" --max-iterations 5

# Skip confirmation
ralph-loop "Build a REST API" -f

Config file

The config file is optional. Without one, ralphkit uses a built-in default loop with a worker (opus) and reviewer (sonnet) step. When a config is provided, all sections are optional — any section not specified uses defaults.

# All top-level keys are optional
max_iterations: 10    # default: 10
default_model: sonnet  # default: sonnet

# Optional: runs once before the loop
setup:
  - step_name: init
    task_prompt: "Initialize the project."
    system_prompt: "You are a setup agent."

# Optional: overrides the built-in worker/reviewer loop
loop:
  - step_name: worker
    task_prompt: "Read {state_dir}/task.md and begin working. This is iteration {iteration} of {max_iterations}."
    system_prompt: "You are a worker in a RALPH LOOP..."
    model: opus
  - step_name: reviewer
    task_prompt: "Review the work done for the task in {state_dir}/task.md. Read the project files, run tests, then write your verdict to {state_dir}/review-result.md"
    system_prompt: "You are a code reviewer in a RALPH LOOP..."
    model: sonnet

# Optional: runs once after the loop (always, even on failure)
cleanup:
  - step_name: finalize
    task_prompt: "Clean up temporary files."
    system_prompt: "You are a cleanup agent."

Each step requires step_name, task_prompt, and system_prompt. The optional model field overrides default_model for that step.

Template variables

Both task_prompt and system_prompt support template variables via {variable_name}. Unrecognized variables are left as-is.

All phases:

Variable Description
{step_name} Current step's name
{max_iterations} Configured max iterations
{default_model} Pipeline's default model
{model} Resolved model for this step
{state_dir} State directory path (.ralphkit)

Loop phase only:

Variable Description
{iteration} Current iteration number (1-based)

See configs/example.yaml for a complete working config.

How It Works

 Setup (once)          Loop (iterate)              Cleanup (once, always)
┌──────────┐    ┌───────────────────────┐    ┌──────────────┐
│ step 1   │    │ step 1 (e.g. worker)  │    │ step 1       │
│ step 2   │    │ step 2 (e.g. reviewer)│    │ ...          │
│ ...      │    │ ...                   │    └──────────────┘
└──────────┘    │ SHIP? → done          │
                │ REVISE? → loop again  │
                └───────────────────────┘

Each loop iteration runs all loop steps in order, then checks the review result:

  1. Loop steps — each step runs claude with its configured prompts and model.
  2. After all steps, the verdict is read from .ralphkit/review-result.md.
  3. SHIP → exit successfully. REVISE → feedback is preserved for the next iteration.

The cleanup phase always runs (even if the loop exits with an error), similar to a finally block.

State Files

State is persisted in .ralphkit/ in the current working directory so each stateless claude -p invocation can pick up where the last left off.

File Purpose
task.md The task description
iteration.md Current iteration number
work-summary.md What the worker did this iteration
work-complete.md Created when the worker thinks it's done
review-result.md SHIP or REVISE
review-feedback.md Specific feedback from the reviewer
RALPH-BLOCKED.md Created by a step if it cannot proceed

Requirements

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ralphkit-0.1.1.tar.gz (2.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ralphkit-0.1.1-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file ralphkit-0.1.1.tar.gz.

File metadata

  • Download URL: ralphkit-0.1.1.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for ralphkit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 63d2fb79d3fa4e6de066f1aaf6d23086759a3be816b59c4b4a08a6a6c3012543
MD5 41ca2af20ad5390a8af865eead3cbc7a
BLAKE2b-256 e0421d6472abb9cd7718a760f8260faaa40c506a2225be2304393078c08c5e15

See more details on using hashes here.

File details

Details for the file ralphkit-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: ralphkit-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for ralphkit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c470b5d6fda6745c3569b4c43c73f956d42122451476a7f66d3a5aef4a6e8ae8
MD5 2a35f1c11c93a25c924c70ad30059db2
BLAKE2b-256 c7910d75e7be50515b021d8c1bc5f113ec71a6df20ff9fdf3b64c886a0848c98

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page