Claude
Skills
Sign in
Back

ralph-loop-init

Included with Lifetime
$97 forever

Transform approved plans into ralph loop infrastructure. Triggers on: '/ralph-loop-init', '/ralph-init', 'setup ralph loop', 'generate ralph loop'. Creates .ralph/ directory with prd.json, loop.py, CLAUDE.md, and supporting files.

General

What this skill does


# Ralph Loop Init Skill

Transform approved plans into executable ralph loop infrastructure.

## What is Ralph Loop?

Ralph Loop is an autonomous execution system that runs Claude (or compatible tools) in a loop to complete multi-step implementation work. It transforms a PRD into:

1. **prd.json** - Machine-readable stories with progress tracking
2. **loop.py** - Python UV script that orchestrates iterations with rich output
3. **CLAUDE.md** - Per-iteration instructions for the AI
4. **progress.txt** - Human-readable execution log
5. **guardrails.md** - Quality gates and constraints

Each iteration: read one story, implement it, run quality gates, commit, update progress, exit. The loop script handles the next iteration.

## When This Skill Activates

| Category | Trigger Phrases |
|----------|-----------------|
| **Initialize** | `/ralph-loop-init <plan-path>`, `/ralph-init <plan-path>` |
| **Setup** | `setup ralph loop`, `generate ralph loop` |
| **From plan** | `create ralph loop from .claude/plans/...` |

---

## Workflow

### Phase 1: Plan Selection

Identify the approved plan to transform.

**If path provided:**
```
/ralph-loop-init .claude/plans/user-authentication.md
```
Read the plan at the specified path.

**If no path provided:**
```
/ralph-loop-init
```
List available plans in `.claude/plans/` (excluding drafts/) and ask user to select one.

**Validation:**
- Plan file must exist
- Plan must have "## Implementation Steps" section
- Plan should be in `.claude/plans/` (not drafts/)

---

### Phase 2: Pre-flight Check

Before generating files, check for existing ralph loop infrastructure.

```bash
if [ -d ".ralph" ]; then
    # Existing ralph loop detected
fi
```

**If .ralph/ exists:**

Present options to user:
```
Existing ralph loop detected at .ralph/

Options:
1. "overwrite" - Delete existing .ralph/ and create fresh
2. "resume" - Keep existing, show current progress
3. "cancel" - Abort initialization

Which would you like?
```

**Handle response:**

| User Says | Action |
|-----------|--------|
| "overwrite", "fresh", "start over" | Delete .ralph/, proceed with generation |
| "resume", "continue", "keep" | Show progress from existing prd.json, do not regenerate |
| "cancel", "abort", "stop" | Exit skill |

---

### Phase 3: Story Extraction

Parse the plan's "## Implementation Steps" section into structured stories.

**Input format (from plan):**
```markdown
## Implementation Steps

1. Create the auth middleware in src/middleware/auth.ts with JWT validation logic
2. Add login endpoint to src/routes/auth.ts that validates credentials and returns tokens
3. Add logout endpoint that invalidates the current token
4. Create token refresh endpoint for extending sessions
5. Update User model with password hashing using bcrypt
```

**Extraction rules:**

1. Find the "## Implementation Steps" section
2. Parse numbered list items (1., 2., 3., etc.)
3. For each item:
   - **id**: `story-{N}` where N is the step number
   - **title**: First sentence or line of the step (truncated at 80 chars if needed)
   - **description**: Full step text
   - **priority**: Sequential (1, 2, 3...) based on order
   - **passes**: `false` (all stories start incomplete)

**Output structure:**
```json
{
  "stories": [
    {
      "id": "story-1",
      "title": "Create auth middleware with JWT validation",
      "description": "Create the auth middleware in src/middleware/auth.ts with JWT validation logic",
      "priority": 1,
      "passes": false
    }
  ]
}
```

---

### Phase 4: Quality Detection

Detect project quality gates by scanning for common configuration files.

**Detection Logic:**

| File/Pattern | Quality Gate Command |
|--------------|---------------------|
| `package.json` with `scripts.test` | `npm test` |
| `package.json` with `scripts.lint` | `npm run lint` |
| `tsconfig.json` | `npx tsc --noEmit` |
| `.eslintrc*` or `eslint.config.*` | `npx eslint .` |
| `pytest.ini` or `pyproject.toml` with pytest | `pytest` |
| `Makefile` with `test` target | `make test` |
| `Makefile` with `lint` target | `make lint` |
| `.github/workflows/*.yml` | Note: "CI will run on push" |

**Detection process:**

1. Check for `package.json`:
   ```bash
   if [ -f "package.json" ]; then
       # Check for test/lint scripts
   fi
   ```

2. Check for TypeScript:
   ```bash
   if [ -f "tsconfig.json" ]; then
       # Add tsc --noEmit
   fi
   ```

3. Check for ESLint:
   ```bash
   if ls .eslintrc* eslint.config.* 2>/dev/null; then
       # Add eslint
   fi
   ```

4. Check for Python testing:
   ```bash
   if [ -f "pytest.ini" ] || grep -q "pytest" pyproject.toml 2>/dev/null; then
       # Add pytest
   fi
   ```

5. Check for Makefile targets:
   ```bash
   if [ -f "Makefile" ]; then
       grep -q "^test:" Makefile && # Add make test
       grep -q "^lint:" Makefile && # Add make lint
   fi
   ```

**Output:** List of quality gate commands for CLAUDE.md template.

---

### Phase 5: File Generation

Generate all ralph loop files in `.ralph/` directory.

#### Create Directory Structure

```bash
mkdir -p .ralph
```

#### File 1: prd.json

```json
{
  "plan_source": ".claude/plans/{topic-slug}.md",
  "created_at": "{ISO-8601-timestamp}",
  "stories": [
    {
      "id": "story-1",
      "title": "{extracted title}",
      "description": "{full step description}",
      "priority": 1,
      "passes": false
    },
    {
      "id": "story-2",
      "title": "{extracted title}",
      "description": "{full step description}",
      "priority": 2,
      "passes": false
    }
  ]
}
```

#### File 2: progress.txt

```
Ralph Loop Progress
===================
Plan: {plan title}
Source: {plan path}
Started: {timestamp}

Stories: 0/{total} complete

---

[Execution log will appear below]
```

#### File 3: CLAUDE.md

```markdown
# Ralph Loop Task

You are executing ONE iteration of a ralph loop. Complete ONE story, then exit.

## Your Task

1. Read `.ralph/prd.json` to find the next incomplete story (passes: false, lowest priority)
2. Implement ONLY that story
3. Run quality gates
4. Commit your changes
5. Update progress
6. Exit

## Quality Gates

Run these commands before committing. ALL must pass:

{detected quality gate commands, one per line with backticks}

If any gate fails, fix the issue before committing.

## Story Completion Protocol

When you complete a story:

1. **Check for changes and commit if needed:**
   ```bash
   git status --porcelain
   ```

   If there ARE changes:
   - Stage changes: `git add -A`
   - Commit with a conventional commit message describing your implementation
   - The `commit_quality_enforcer` hook validates format automatically
   - If commit is rejected, read the error, fix the message, retry (max 3 attempts)
   - After 3 failures, log the error to progress.txt and exit

   If there are NO changes, proceed directly to step 2.

2. **Update prd.json:**
   - Set `passes: true` for the completed story

3. **Append to progress.txt:**
   ```
   [{timestamp}] Completed: {story-id} - {story-title}
   ```

4. **Exit immediately** - Do not start another story

## Guardrails

See `.ralph/guardrails.md` for constraints and boundaries.

## Important

- Complete exactly ONE story per iteration
- Do not skip quality gates
- Do not modify stories you are not implementing
- If blocked, document in progress.txt and exit
- Trust the loop script to handle the next iteration
```

#### File 4: loop.py

```python
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = ["rich"]
# ///
"""
Ralph Loop Runner

Executes AI iterations until all stories complete.
Uses rich for beautiful terminal output with progress tracking.
"""

import json
import os
import subprocess
import sys
from pathlib import Path

from rich.console import Console
from rich.panel import Panel

console = Console()

RALPH_DIR = Path(".ralph")
PRD_FILE = RALPH_DIR / "prd.json"
PROGRESS_FILE = RALPH_DIR / "progress.txt"


def load_prd() -> dict:
    """Load and return 

Related in General