Ralphe 0.1.1

There is a newer version of this package available.
See the version list below for details.
dotnet tool install --global Ralphe --version 0.1.1
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Ralphe --version 0.1.1
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Ralphe&version=0.1.1
                    
nuke :add-package Ralphe --version 0.1.1
                    

Ralphe

Ralphe is a loop orchestrator for Claude Code. It automates task execution described as GitHub Issues — from implementation, through review, to commit and issue closure.

How it works

Ralphe fetches the specified GitHub Issue along with its sub-issues, then runs an agent pipeline for each open sub-issue. The pipeline is fully dynamic — you can define multiple named pipelines and assign them per sub-issue.

By default (without configuration), Ralphe uses a single-agent pipeline with a default agent that implements the task, verifies it (including running tests when appropriate), and reports a verdict. Each sub-issue can specify a different pipeline using a GitHub Alert in the issue body:

> [!IMPORTANT]
> Do not remove this. Ralphe uses this to select the agent pipeline for this issue.
> pipeline: tdd

If the last agent in the pipeline approves the changes (PASS), Ralphe commits them and closes the issue. If it rejects (FAIL), the pipeline is retried with feedback — up to 10 times.

Requirements

Installation

dotnet tool install -g Ralphe

# Update to the latest version:
dotnet tool update -g Ralphe

Usage

ralphe <issue-number> [options]
ralphe init

Options

Option Description
<issue-number> GitHub parent issue number (required)
--max-retries <N> Maximum retry attempts per sub-issue (default: 10)
--claude-path <path> Path to Claude Code CLI (default: claude)
--disallowed-tools <tools> Tools blocked for agents
--log-directory <dir> Log directory (default: .temp/ralphe)
--file-logging Enable file logging
--debug Enable debug mode
--debug-filter <filter> Debug log filter
--config <path> Path to ralphe.yml file
--help Display help and exit

Commands

Command Description
ralphe <issue-number> Process the issue with the given number
ralphe init Interactive wizard — creates ralphe.yml and optionally pipelines

Examples

ralphe 42                              # Process issue #42 with default settings
ralphe 42 --debug                      # With debug logging
ralphe 42 --max-retries 5              # Maximum 5 attempts per sub-issue
ralphe init                            # Initialize project configuration

Interruption (Ctrl+C)

  • First Ctrl+C — graceful shutdown: Ralphe cancels current operations, kills Claude processes, and exits with code 130
  • Second Ctrl+C — force quit: immediate process termination

Exit codes

Code Meaning
0 All sub-issues approved (or --help was used)
1 At least one sub-issue failed after exhausting retries
130 Execution interrupted by user (Ctrl+C)

Configuration

Configuration hierarchy: CLI args > ralphe.yml > hardcoded defaults.

Run ralphe init to generate .claude/ralphe/ralphe.yml with default values:

max-retries: 10
claude-path: claude
disallowed-tools:
  - "Bash(git:*)"
log-directory: .temp/ralphe

pipelines:
  require-match: false
  .default:
    description: Default pipeline
    agents:
      - name: default
        model: opus
Setting Default value Description
max-retries 10 Maximum retry attempts for a single sub-issue
claude-path claude Path to Claude Code CLI
disallowed-tools ["Bash(git:*)"] Tools blocked for agents
log-directory .temp/ralphe Log directory
file-logging false File logging
pipelines Pipeline definitions (see below)
pipelines.require-match false Error when issue references an unknown pipeline

Prompt templates

To use custom prompts for an agent, set SystemPrompt or UserPrompt in the agent definition to a file path. The file will be loaded at runtime.

Template variables

Use {{VARIABLE_NAME}} in prompt files. Variables are replaced with values from the pipeline context:

Variable Description
{{ISSUE_NUMBER}} Number of the processed sub-issue
{{ISSUE_TITLE}} Sub-issue title
{{ISSUE_BODY}} Sub-issue body (Markdown)
{{PARENT_ISSUE_NUMBER}} Parent issue number
{{PARENT_ISSUE_TITLE}} Parent issue title
{{PARENT_ISSUE_BODY}} Parent issue body
{{ATTEMPT_NUMBER}} Current attempt number (starting from 1)
{{RETRY_FEEDBACK}} Feedback from the previous failed attempt
{{PREVIOUS_OUTPUT}} Output from the previous agent in the pipeline
{{CHANGED_FILES}} List of changed files in the working directory
{{AGENT_NAME}} Current agent name

Conditional blocks

Use {{#if KEY}}...{{/if}} to include a section only when the variable is non-empty:

{{#if RETRY_FEEDBACK}}
## Previous feedback (attempt {{ATTEMPT_NUMBER}})
{{RETRY_FEEDBACK}}
{{/if}}

Custom agent pipelines

Pipelines are defined in ralphe.yml under the pipelines key. Prompt directories are located in .claude/ralphe/pipelines/. Use ralphe init to generate the structure, or create it manually:

Directory structure:

.claude/ralphe/
  ralphe.yml                        # configuration + pipeline definitions
  pipelines/                       # prompt directory
    tdd/
      01-test-writer/              # numeric prefix = fallback ordering
        prompt-system.md           # required
        prompt-user.md             # required
      02-implementor/
        prompt-system.md
        prompt-user.md
      03-reviewer/
        prompt-system.md
        prompt-user.md

Pipeline definition in ralphe.yml:

pipelines:
  require-match: false
  tdd:
    description: "TDD red-green-refactor pipeline"
    agents:
      - name: test-writer
        model: opus                # optional, default: sonnet
        timeout: "00:05:00"        # optional, default: 00:10:00
      - name: implementor
        model: opus
      - name: reviewer             # uses default values

Key principles:

  • Agents execute sequentially in the order defined in ralphe.yml
  • Each agent's output is passed to the next via the {{PREVIOUS_OUTPUT}} variable
  • The last agent in the pipeline acts as a gate — it decides the loop outcome
  • Agent defaults: model=sonnet, timeout=00:10:00

Pipeline selection per sub-issue — add a GitHub Alert in the issue body:

> [!IMPORTANT]
> Do not remove this. Ralphe uses this to select the agent pipeline for this issue.
> pipeline: tdd

Fallback when no alert is present: default pipeline → first in directory → hardcoded default agent.

Lifecycle hooks

Hooks are Claude agents invoked at specific points of the Ralphe loop. They run synchronously — each hook must complete before the main flow continues.

Hook When Extra variables
on-start After fetching sub-issues, before the loop begins SUB_ISSUE_COUNT
on-pre-iteration Before processing each sub-issue ISSUE_NUMBER, ISSUE_TITLE, ISSUE_BODY
on-post-iteration After processing each sub-issue above + ITERATION_SUCCESS
on-end After all sub-issues are processed LOOP_PROCESSED, LOOP_SUCCEEDED, LOOP_FAILED

All hooks share parent issue variables (PARENT_ISSUE_NUMBER, PARENT_ISSUE_TITLE, PARENT_ISSUE_BODY, SUB_ISSUE_COUNT).

Configuration

Hooks are configured in ralphe.yml under the hooks key. All hooks are disabled by default.

hooks:
  on-start:
    enabled: true
    fail-fast: false       # true = error aborts the loop
    model: sonnet
    timeout: 120           # seconds
    disallowed-tools: []   # override global disallowed-tools
  on-end:
    enabled: true
    fail-fast: true
Setting Default Description
enabled false Enable/disable the hook
fail-fast false If true, hook failure aborts the entire loop
model sonnet Claude model to use
timeout 120 Timeout in seconds
disallowed-tools (global fallback) Per-hook tool restrictions

Prompt files

Hook prompts are stored in .claude/ralphe/hooks/{hook-name}/:

.claude/ralphe/hooks/
  on-start/
    prompt-system.md
    prompt-user.md
  on-pre-iteration/
  on-post-iteration/
  on-end/

Run ralphe init to generate placeholder prompt files for all hooks.

Per-agent disallowed-tools

The disallowed-tools setting can be overridden per agent (in pipeline definitions) or per hook. If not specified, the global disallowed-tools value is used as a fallback.

disallowed-tools:
  - "Bash(git:*)"           # global fallback

pipelines:
  .default:
    agents:
      - name: coder
        disallowed-tools:    # override for this agent
          - "Bash(git:*)"
          - "Bash(rm:*)"
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
1.2.4 0 4/16/2026
1.2.3 0 4/16/2026
1.2.2 0 4/16/2026
1.2.1 27 4/15/2026
1.2.0 32 4/15/2026
1.1.1 38 4/14/2026
1.1.0 46 4/14/2026
1.0.7 97 4/12/2026
1.0.6 73 4/12/2026
1.0.5 77 4/12/2026
1.0.4 77 4/12/2026
1.0.3 87 4/12/2026
1.0.2 90 4/11/2026
1.0.1 86 4/10/2026
1.0.0 79 4/10/2026
0.1.7 84 4/10/2026
0.1.6 79 4/10/2026
0.1.5 77 4/10/2026
0.1.4 81 4/10/2026
0.1.1 88 4/9/2026
Loading failed