Ralphify is the open-source framework for ralph loop harness engineering, published on PyPI. It's a CLI tool (ralph) that runs AI coding agents in autonomous loops — piping prompts to agents, running commands to capture dynamic data, and repeating with fresh context each iteration.
For full architecture details, see docs/contributing/codebase-map.md.
uv run pytest # Run tests (required before any commit)
uv run pytest -x # Stop on first failure
uv run ruff check . # Lint
uv run ruff format --check . # Check formatting
uv run ty check # Type check
uv run mkdocs build --strict # Build docs (must pass with zero warnings)
uv run mkdocs serve # Preview docs at http://127.0.0.1:8000All source code is in src/ralphify/. The main file is cli.py — it contains the CLI commands and delegates to the engine for the core loop.
Key modules:
cli.py— CLI commands (run,scaffold); delegates to_console_emitter.pyfor terminal event renderingengine.py— Core run loop orchestration with structured event emissionmanager.py— Multi-run orchestration (concurrent runs via threads)_frontmatter.py— YAML frontmatter parsing (uses PyYAML) and theRALPH_MARKERconstant_run_types.py—RunConfig,RunState,RunStatus,Commanddataclasses_resolver.py— Template placeholder resolution ({{ commands.name }},{{ args.name }})_agent.py— Run agent subprocesses (streaming + blocking modes, log writing)_runner.py— Generic command execution with timeout_events.py— Event types, emitter protocol (NullEmitter, QueueEmitter, FanoutEmitter), and BoundEmitter convenience wrapper_console_emitter.py— Rich terminal rendering of events_output.py—ProcessResultbase class, combine stdout+stderr, format durations_brand.py— Brand color constants shared across CLI and console rendering
Tests are in tests/ with one file per module. Docs are in docs/ using MkDocs with Material theme.
A ralph is a directory containing a RALPH.md file. That's it. No project-level config, no special directories.
RALPH.md has YAML frontmatter + a prompt body:
agent(required) — the agent command to runcommands(optional) — list of{name, run}commands whose output fills{{ commands.<name> }}placeholdersargs(optional) — declared argument names for{{ args.<name> }}placeholders
The loop: run commands → assemble prompt (resolve placeholders) → pipe to agent → repeat.
- Commit messages:
docs: explain X for users who want to Y,feat: add X so users can Y,fix: resolve X that caused Y - Dependencies: Minimal by design. Runtime deps are
typer,rich, andpyyaml. Prefer stdlib over new deps. - Tests: No external services, no API keys. All tests use temporary directories.
- Docs: Every user-facing feature needs a docs page. Run
mkdocs build --strictbefore committing doc changes. - Keeping docs surfaces in sync: When making user-facing changes (new features, changed behavior, new CLI flags), update all relevant surfaces:
docs/(MkDocs) — user-facing docs: CLI reference, quick reference, writing prompts guide, cookbook. Only include what's relevant for users.docs/contributing/— contributor/agent docs: codebase map, architecture. Only include what's relevant for contributors and coding agents.README.md— keep short and high-level. Update only when the change affects the quickstart, install, or core concepts.CHANGELOG.md— add an entry for every release.
- Run
uv run pytestanduv run ruff check .before committing
- The ralph marker filename (
RALPH.md) is defined asRALPH_MARKERin_frontmatter.py. All modules import from there. - Frontmatter parsing uses PyYAML (
yaml.safe_load). Thecommandsfield is a list of dicts,argsis a list of strings. - Commands use
_runner.py:run_command()withshlex.split()— no shell features (pipes, redirections,&&). Scripts are the escape hatch. - Commands starting with
./run relative to the ralph directory. Other commands run from the project root. - The
agentfield in frontmatter is split withshlex.split()to build the command list. - Placeholder resolution uses
_resolver.py—{{ commands.<name> }}and{{ args.<name> }}are the two supported kinds.
The project has a website called ralphify.co and the docs live a ralphify.co/docs/