Skip to content
/

pi-ralph

pi-ralph-orch · samfoy/pi-ralph · ★ 13 · last commit 2026-05-14

Add YAML-configurable hat-based multi-phase orchestration loops to the pi coding agent, with event-driven hat transitions and guard rails.

Best whenRole transitions should be event-driven (agent publishes explicit events) rather than time-based or iteration-based — makes orchestration state visible in ag…
Skip ifImplementing tasks out of dependency order, Writing implementation before tests (in code-assist preset)
vs seeds
superpowers' Iron Laws but defined per…
Primitive shape 13 total
Commands 7 Skills 6
00

Summary

pi-ralph — Summary

pi-ralph (samfoy/pi-ralph) is a TypeScript extension for the pi coding agent that adds hat-based multi-agent orchestration loops. Roles are defined as "hats" in YAML preset files — each hat has a name, description, trigger events, published events, and instructions injected into the system prompt when active. Hats hand off work via an event protocol: when a hat publishes an event (>>> EVENT: event_name), the loop transitions to the hat triggered by that event. Preset files are loaded from three locations (built-in, user, project-specific), allowing override without forking. Six presets ship out of the box: feature, code-assist, spec-driven, debug, refactor, review. A PDD (Prompt-Driven Development) planning mode (/plan) produces structured specs in specs/<task-name>/. Guard rails (max iterations, max runtime, completion promise) prevent runaway loops. The extension integrates with pi-slack-bot for Slack-driven orchestration. Compared to seeds, pi-ralph is closest to spec-driver's sequential skill chain but implemented as a YAML-configurable hat system within a pi extension, rather than a static skill pack — the YAML presets allow workflow customization without modifying source code, which no seed framework provides.

01

Overview

pi-ralph — Overview

Origin

Created by samfoy (single contributor). 13 stars. MIT license. Last pushed 2026-05-14. Inspired by ralph-orchestrator by @mikeyobrien.

Philosophy

From the README:

"A pi extension for hat-based multi-agent orchestration loops. Ralph keeps the agent iterating through specialized 'hats' (roles) until a task is complete — each hat has its own instructions, triggers, and events that drive the workflow forward."

The "hat" metaphor positions roles as temporary identities the agent wears for a phase of work, rather than persistent personas. Hats are transient, event-driven, and composable via YAML.

Credits

"Inspired by ralph-orchestrator (https://github.com/mikeyobrien/ralph-orchestrator) by @mikeyobrien — the original Ralph Wiggum technique for autonomous AI agent orchestration."

This places pi-ralph in the snarktank/ralph lineage but implemented as a YAML-configurable pi extension rather than a bash loop.

Key Design Opinions

  • YAML over code: Presets are pure YAML; no TypeScript knowledge needed to define workflows
  • Event-driven transitions: Hats publish events rather than calling the next hat by name — decoupled, composable
  • Guard rails are mandatory: max_iterations, max_runtime_seconds, and completion_promise prevent runaway loops
  • Session persistence: Loop state survives session restarts
  • PDD as a planning primitive: /plan creates structured specs before implementation begins

PDD (Prompt-Driven Development)

The /plan command implements a 4-phase interactive planning session:

  1. Requirements (iterative Q&A)
  2. Research (technology investigation)
  3. Design (architecture with diagrams)
  4. Implementation plan (numbered steps)

All artifacts saved to specs/<task-name>/. User-driven; Ralph won't proceed without confirmation.

02

Architecture

pi-ralph — Architecture

Distribution & Install

  • Distribution type: standalone-repo (pi extension, installed via git clone)
  • Install:
    cd ~/.pi/agent/extensions
    git clone https://github.com/samfoy/pi-ralph.git
    cd ralph && npm install
    
    pi auto-discovers and loads the extension on next start.
  • Version: 0.x (no version tag, TypeScript)
  • License: MIT
  • Required runtime: node (for pi), pi coding agent installed

Directory Tree (repo)

pi-ralph/
├── index.ts              # Extension entry point; /ralph and /plan command handlers
├── lib.ts                # Core loop logic: preset loading, hat transitions, event protocol
├── lib.test.ts           # Test suite
├── presets/              # Built-in YAML preset files
│   ├── feature.yml
│   ├── code-assist.yml
│   ├── debug.yml
│   ├── refactor.yml
│   ├── review.yml
│   └── spec-driven.yml
│   (+ iterate.yml)
├── skills/
│   └── ralph-loop/       # (referenced but not listed in root)
└── package.json

Preset Discovery Order

  1. ~/.pi/agent/extensions/ralph/presets/ (built-in — this repo)
  2. ~/.pi/agent/ralph/presets/ (user-level overrides)
  3. <project>/.pi/ralph/presets/ (project-specific overrides)

Later locations override earlier ones. This allows project-specific presets without modifying the extension.

Event Protocol

Hats communicate via published events:

>>> EVENT: event_name

When the agent outputs this string, the loop detects it and transitions to the hat triggered by that event. The default_publishes field is the fallback if no explicit event is detected.

Target AI Tool

pi coding agent (@earendil-works/pi-coding-agent) exclusively. Uses the pi TypeScript Extension API.

03

Components

pi-ralph — Components

Commands

Command Purpose
/ralph [preset] [prompt] Start a loop (interactive picker if no args)
/ralph stop Stop the current loop
/ralph status Show loop status
/ralph history Show iteration history for current loop
/ralph loops Browse past loop records
/ralph presets List available presets
/plan [idea] Start a PDD planning session

Built-in Presets

Preset Hats Description
feature Builder → Reviewer General feature development with quality review
code-assist Planner → Builder → Validator → Committer Full TDD pipeline
spec-driven Spec Writer → Critic → Implementer → Verifier Spec-first development
debug Investigator → Tester → Fixer → Verifier Scientific debugging
refactor Refactorer → Verifier Safe refactoring
review Reviewer → Deep Analyzer Code review

YAML Preset Structure

event_loop:
  starting_event: "build.start"
  completion_promise: "LOOP_COMPLETE"
  max_iterations: 50
  max_runtime_seconds: 14400

core:
  guardrails:
    - "Tests must pass before committing"

hats:
  planner:
    name: "📋 Planner"
    triggers: ["build.start"]
    publishes: ["tasks.ready"]
    default_publishes: "tasks.ready"
    instructions: |
      ## PLANNER MODE
      [detailed instructions injected into system prompt]

Library Functions (lib.ts)

Function Purpose
loadPresetsFromDir Load and parse YAML preset files
detectPublishedEvent Parse agent output for >>> EVENT: name
containsCompletionPromise Check for LOOP_COMPLETE signal
findHatForEvent Resolve which hat handles an event
buildHatInjection Construct system prompt injection for a hat
inferEventFromContent Fallback event inference from agent text
determineNextAction Decide loop state transition
loadLoopRecords Load history of past loops
saveLoopRecord Persist completed loop to history

UI (pi Extension)

  • Loops modal — popup overlay to browse past loop records
  • History modal — popup overlay to browse iteration history for current loop
05

Prompts

pi-ralph — Prompts

Verbatim Excerpt 1 — presets/code-assist.yml (Planner and Builder hat instructions)

hats:
  planner:
    name: "📋 Planner"
    description: "Explores codebase and creates implementation plan."
    triggers: ["build.start"]
    publishes: ["tasks.ready"]
    default_publishes: "tasks.ready"
    instructions: |
      ## PLANNER MODE

      Explore the codebase and create an implementation plan.

      ### Process
      1. Analyze the task requirements
      2. Search codebase for relevant patterns and similar implementations
      3. Identify files to create/modify
      4. Create a numbered implementation plan

      ### Scratchpad Format
      Write a task checklist to the scratchpad:

      ```
      ## Tasks
      - [ ] 1. Description of first task
      - [ ] 2. Description of second task
      ```

      ### DON'T
      - ❌ Start implementing — just plan
      - ❌ Create overly complex plans
      - ❌ Skip codebase exploration

  builder:
    name: "⚙️ Builder"
    description: "TDD implementation of ONE task: RED → GREEN → REFACTOR."
    triggers: ["tasks.ready", "validation.failed"]
    publishes: ["implementation.ready"]
    default_publishes: "implementation.ready"
    single_task: true
    instructions: |
      ## BUILDER MODE — TDD Cycle (SINGLE TASK)

      Your current task has been extracted from the scratchpad and provided above.
      Implement ONLY that one task using strict TDD.

      ### Process
      1. READ SCRATCHPAD — Get context from the previous hat's notes
      2. EXPLORE — Read task requirements, search for similar code
      3. RED — Write failing tests first
      4. GREEN — Write minimal code to make tests pass
      5. REFACTOR — Clean up while keeping tests green
      6. VERIFY — Run full test suite
      7. UPDATE SCRATCHPAD — Add notes about what you did

      ### SCOPE RULES (non-negotiable)
      - ❌ Do NOT implement any task other than the one assigned above
      - ❌ Do NOT write implementation before tests

Technique: Explicit TDD enforcement via hat instructions (RED→GREEN→REFACTOR as numbered steps). The single_task: true field tells the loop to extract and provide only one task from the scratchpad, preventing scope creep. The DON'T list uses negative constraints to shape behavior.

Verbatim Excerpt 2 — Event Protocol (from README)

How It Works:
1. The loop starts by finding the hat triggered by starting_event
2. Hat instructions are injected into the system prompt
3. The agent works under that hat's guidance
4. When done, the agent publishes an event: >>> EVENT: event_name
5. Ralph finds the next hat triggered by that event
6. Repeat until the agent outputs the completion_promise or limits are hit

Technique: Structured event string protocol (>>> EVENT: event_name) as the handoff mechanism. The agent must explicitly publish the event string in its output — this is a deliberate output format constraint that makes hat transitions detectable by the extension's text parsing.

09

Uniqueness

pi-ralph — Uniqueness & Positioning

Differs from Seeds

pi-ralph is closest to spec-driver in its sequential phase execution model (Planner → Builder → Validator → Committer), but the YAML-configurable hat system makes the workflow composable and overridable without code changes — something no seed framework provides. The event-driven hat transition mechanism (>>> EVENT: event_name) is a novel explicit protocol that makes orchestration state visible in the agent's output, unlike implicit skill activation in superpowers or explicit command invocations in spec-driver. The guardrails array (injected into all hats) is functionally equivalent to superpowers' Iron Laws but defined per-preset in YAML rather than globally in a skill file. The PDD planning mode is similar to kiro's spec-first workflow (requirements → design → tasks) but without the IDE integration and with full user confirmation gates at each phase. Among Ralph variants, pi-ralph is unique in supporting multiple named roles within a single autonomous loop (compared to snarktank/ralph's single-role per iteration and frankbria's no-role continuous loop).

Positioning

pi-ralph targets pi users who want structured multi-phase workflows without using a heavyweight framework like BMAD. The YAML preset system makes it accessible to non-TypeScript developers. The Slack integration positions it for teams using pi-slack-bot for remote/async AI development.

Observable Failure Modes

  • Event string parsing brittleness: The >>> EVENT: event_name protocol relies on the agent outputting this exact string. A verbose or distracted agent that buries the event string in prose may cause default_publishes fallback instead of the intended event.
  • Scratchpad context loss: The Planner's task list lives in the agent's context; if context is compacted aggressively, the Builder may lose access to the scratchpad.
  • No file-based task tracking: Unlike snarktank/ralph's prd.json, pi-ralph has no persistent external task list. Loop interruption loses task state unless the session is recoverable.
  • pi-only: Works only with the pi coding agent; not portable to Claude Code, Cursor, or other tools.
  • Small community: 13 stars, 1 contributor; may not receive updates as pi-mono evolves.

Cross-References

  • Built on: pi-mono (@earendil-works/pi-coding-agent)
  • Inspired by: ralph-orchestrator by mikeyobrien → snarktank/ralph lineage
  • Contrasted with: snarktank/ralph (bash loop) and ralph-claude-code (Claude Code-specific)
04

Workflow

pi-ralph — Workflow

Phases

Phase Description Artifact
Loop start /ralph [preset] [prompt] — select preset and provide initial prompt Active loop
Starting hat Hat triggered by starting_event receives system prompt injection Instructions injected
Hat work Agent works under hat's guidance; uses tools, edits code, runs tests Code changes
Event publication Agent outputs >>> EVENT: event_name to signal completion of hat Transition trigger
Hat transition Loop finds next hat triggered by that event New system prompt injection
Completion Agent outputs LOOP_COMPLETE or limits reached Loop record saved
PDD (optional) /plan [idea] → 4-phase interactive spec creation specs/<task-name>/

Phase-to-Artifact Map

Phase Artifact
Loop start Active loop state (in-memory)
PDD specs/<task-name>/requirements.md, design.md, implementation-plan.md
Completion Loop record (browsable via /ralph loops)

Approval Gates

Gate Type Trigger
PDD phase confirmation Manual User must confirm before moving to next PDD phase
max_iterations Automatic Loop exits after N iterations
max_runtime_seconds Automatic Loop exits after N seconds
completion_promise Automatic Agent outputs LOOP_COMPLETE

The PDD mode is explicitly user-driven: "Ralph won't proceed to the next phase without your confirmation."

Guard Rails (per preset)

core:
  guardrails:
    - "Verification is mandatory — tests/typecheck/lint must pass"
    - "YAGNI ruthlessly — no speculative features"
    - "KISS always — simplest solution that works"

Guardrails are injected into every hat's system prompt, providing persistent behavioral constraints across hat transitions.

Example code-assist Workflow

/ralph code-assist "Add rate limiting to the API"
  → PLANNER hat: explore codebase, create task checklist
  → >>> EVENT: tasks.ready
  → BUILDER hat (single_task=true): TDD RED→GREEN→REFACTOR for one task
  → >>> EVENT: implementation.ready
  → VALIDATOR hat: run tests, typecheck, lint
  → >>> EVENT: validation.passed or validation.failed
  → (on failed: back to BUILDER)
  → COMMITTER hat: conventional commit message, git commit
  → >>> EVENT: committed
  → (repeat BUILDER for next task until all done)
  → LOOP_COMPLETE
06

Memory Context

pi-ralph — Memory & Context

State Storage

State Storage Persistence
Active loop state In-memory (pi extension) Session
Loop records File-based (pi extension storage) Project
Iteration history File-based Project
PDD specs specs/<task-name>/ files Project
Scratchpad In-agent context (written/read by hats) Per-loop

Session Persistence

Loop state survives session restarts. If pi is restarted mid-loop, the loop can be resumed. This is implemented via pi's session file system (pi-mono's session branching/persistence).

Scratchpad Pattern

Hats communicate across hat transitions via a shared scratchpad written to the agent context. The Planner hat writes a task checklist; the Builder hat reads it to extract its current task. This is an in-context memory mechanism (not a file on disk), limiting its persistence to the current pi session.

Cross-Session Handoff

Loop records persist across sessions (browsable via /ralph loops). Active loop state persists (session restart resumption). Specs from PDD persist in specs/ directory.

Context Compaction

Relies on pi-mono's built-in context compaction. Long loops with many hat transitions may require compaction; pi handles this at the session level.

Memory Compared to snarktank/ralph

Feature snarktank/ralph pi-ralph
Task tracking prd.json Hat event protocol + scratchpad
Learnings progress.txt (file) Scratchpad (in-context, per-loop)
Cross-session prd.json + progress.txt Loop records + session file
Pattern storage AGENTS.md none explicit
07

Orchestration

pi-ralph — Orchestration

Multi-Agent Support

Single agent — the same pi session iterates through hat transitions. Hat instructions are injected per-transition; no separate agent processes are spawned.

Orchestration Pattern

Sequential with event-driven transitions. The loop transitions from hat to hat based on published events. Within a hat, the agent works until it publishes an event or the loop detects the completion promise.

This is closest to a state machine — the preset YAML defines states (hats) and transitions (event → hat mappings). The orchestration is reactive to agent output rather than timer-based or scheduler-based.

Execution Mode

Continuous-ralph (loop until completion or limits). The loop iterates automatically through hat transitions without human intervention between hats.

Isolation Mechanism

None — the same pi session and project directory throughout. Hat transitions are context-injection changes, not process changes.

Multi-Model Support

No at the pi-ralph level. Pi-mono supports multi-provider via @earendil-works/pi-ai, but pi-ralph does not route different hats to different models. The model used is whatever pi session model is active.

Guard Rails

  • max_iterations — prevents infinite loops
  • max_runtime_seconds — prevents runaway sessions
  • completion_promise — agent-side exit signal
  • guardrails array — per-preset behavioral constraints injected into all hats

Event-Driven Transitions vs. Ralph's PRD-Driven Transitions

Feature snarktank/ralph pi-ralph
Task list prd.json (external) Scratchpad (in-context)
Task completion passes:true in JSON Event publication in output
Multi-role No (one role per iteration) Yes (multiple hats per loop)
Role definition Single prompt file Per-hat instructions in YAML

Slack Integration

With pi-slack-bot, /ralph commands are accessible via Slack chat. The extension handles !ralph prefix instead of /ralph.

08

Ui Cli Surface

pi-ralph — UI & CLI Surface

CLI Surface (within pi)

pi-ralph adds commands to the pi TUI:

Command Purpose
/ralph [preset] [prompt] Start loop with preset selection
/ralph stop Stop current loop
/ralph status Show loop status in TUI
/ralph history Show iteration history modal
/ralph loops Browse past loop records modal
/ralph presets List available presets
/plan [idea] Start PDD planning session

Local UI

pi-ralph extends pi's TUI with two modal overlays:

  • Loops modal — popup to browse past loop records
  • History modal — popup to browse iteration history for the current loop

No web dashboard.

Dedicated CLI Binary

No — pi-ralph is a pi extension, not a standalone CLI. All interaction happens within the pi TUI.

IDE Integration

None. pi-mono is terminal-based; pi-ralph inherits this.

Slack Integration

If pi-slack-bot is configured, /ralph commands become !ralph commands in Slack:

!ralph feature Add user authentication
!ralph stop
!plan Build a notification system

The Slack bot provides an interactive preset picker for !ralph with no arguments.

Observability

  • Active loop status displayed in pi TUI footer
  • /ralph history — per-loop iteration log
  • /ralph loops — cross-loop history browser
  • PDD artifacts in specs/<task-name>/ for human review

Related frameworks

same archetype · same primary tool · same memory type

Claude-Flow / Ruflo ★ 55k

Eliminates single-agent context limits and sequential bottlenecks by orchestrating fault-tolerant swarms of specialized AI agents…

Hermes Agent (NousResearch) ★ 168k

Self-improving personal AI agent with closed learning loop, 7 terminal backends, and messaging gateway — not tied to any AI…

OpenCode ★ 165k

Terminal-first AI coding agent with multi-model routing, native desktop app, and a typed .opencode/ configuration system for…

OpenHands ★ 75k

Open-source AI software development platform (open-source Devin alternative) with Docker sandbox isolation, 77.6% SWE-bench…

DeerFlow ★ 70k

Long-horizon superagent that researches, codes, and creates by orchestrating parallel sub-agents with isolated contexts in Docker…

oh-my-openagent (omo) ★ 60k

Multi-provider AI agent orchestration for OpenCode: escape vendor lock-in by routing Sisyphus (Claude/Kimi/GLM) and Hephaestus…