mcpField
R
ralph-builder

ralph-builder

github.com/jimwellerエージェントワークフロー69 回インストール
リポジトリ

ralph-builder について

指定された目標に向けて、Ralph ループを実行する準備をリポジトリ内で行うスキルです。Beads のタスクグラフ、実行計画、セッション内・外部ドライバー向けの個別プロンプトを作成します。

主な機能

  1. 01Beads の実行用エピックを初期化
  2. 02目標を依存関係付きタスクに分割
  3. 03リポジトリ固有の実行計画を作成
  4. 042つのループ方式向けプロンプトを作成
  5. 05タスクグラフと出力ファイルを検証

活用シーン

  1. 01プロジェクト目標から自律実行を準備
  2. 02ワークツリーごとに並行 Ralph 実行を整理
  3. 03タスク単位の検証指示を用意

MCP 対応

このスキルは MCP インターフェースを説明していません。Ralph ループドライバー向けに Beads タスクとプロンプトファイルを準備します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jimweller/clanker-skills --skill ralph-builder

インストール後、Claude Code で/ralph-builderを入力して読み込まれたか確認します。

詳細

STARTER_CHARACTER = 🔁

Ralph Builder

現在のリポジトリを対象に、ralph ループを自律的に実行するために必要な成果物を作成します。タスクは beads(bd)グラフデータベースに保存されます。計画と 2 つのプロンプトラッパーは .llmtmp/ に保存されます。

引数

ユーザーが目標の説明を指定します。PRD、計画、またはタスクリストを含むファイルが参照される場合があります。呼び出しメッセージから目標を抽出します。

出力成果物

パス目的
.beads/Beads データベース(タスク状態の唯一の情報源)
.llmtmp/ralph-plan.mdモードに依存しない実行計画
.llmtmp/ralph-prompt-insession.mdセッション内の ralph-loop プラグイン用スラッシュコマンドラッパー
.llmtmp/ralph-prompt-external.mdscripts/ralph.sh が claude --print に渡す本文

各プロンプトラッパーには、モード固有の本文が含まれます。セッション内ループは継続して実行し、外部ループは各タスクの後に停止します。

手順

ステップ 1:コンテキストを収集する

計画の根拠を得るため、リポジトリを確認します。

  1. README.md(プロジェクトルート)
  2. .llmdocs/ 内のすべての .md ファイル
  3. ユーザーの目標の引数で参照されているファイル

.llmtmp/ が存在しない場合は作成します。

ステップ 2:beads を初期化し、実行エピックを作成する

bead グラフは、同じリポジトリのワークツリー間で共有されます。並行して実行する別々のワークツリー間で各 ralph の実行が分離されるよう、実行ごとにエピックを作成し、--parent フィルターを使用して整理します。

if ! bd list >/dev/null 2>&1; then
  bd init --skip-agents
fi

slug=$(git branch --show-current | tr '/' '-')
epic=$(bd q "Ralph: ${slug}" -t epic -p 1 -l "ralph:${slug}")

--skip-agents は、bd による既定の AGENTS.md 生成、CLAUDE.md の変更、.claude/settings.json への挿入を抑制します。プロジェクト既存のエージェント向けガイダンスと beads スキルが bd のワークフローに関するコンテキストを提供するため、bd がプロジェクトごとに生成するエージェント用ファイルは不要であり、プロジェクトの規約とも競合します。

エピックには実行識別子として ralph:${slug} ラベルを付けます。ステップ 3 で作成する子には --parent "${epic}" と同じラベルの両方を付けます。これにより独立した 2 つの識別情報が用意され、レビュー担当者が孤立したタスクを検出できます。

ステップ 3:目標を bd グラフに変換する

ralph の実行におけるすべての作業は bead です。各 bead には、タイトル(命令形の一行)と説明(そのタスクに対する作業者向けの詳細な指示)があります。ブランチの作成、BEGIN タグ、END タグといったライフサイクルの足場は、すべて通常の bead として記述し、実行エピックを親に設定します。

bd create -t task --parent "${epic}" -l "ralph:${slug}" -q --json | jq -r .id を使って子 bead を作成します。後続の bd link 呼び出しで使うため、各 ID を取得します。bd update <id> -d "<text>"(複数行の場合は --body-file - とヒアドキュメント)で説明を設定します。bd link <a> <b> で依存関係を設定します(b が a をブロックします)。すべての実行はブランチタスクと BEGIN タグタスクから始まり、他のすべてのタスクに推移的に依存する END タグタスクで終わります。

例

以下のブロックは、lib/greeting.go にあいさつ関数を3つ追加し、READMEを更新する仮想的な実行例です。リテラル値(SLUG、ファイルパス、関数名、コミットプレフィックス)は例示用です。実際の実行内容に合わせて置き換えてください。Beadの説明には、そのタスク固有の事実だけを記載します。各コーディングタスクの説明では、以下で定義するRED/GREEN/VERIFYの構成を使用します。共通ルール(Conventional Commits、ペルソナの制約)はすでにCLAUDE.mdに記載されています。実行全体の規約(ビルド、テスト、Lintのコマンド)はralph-plan.mdに記載します。説明でこれらを繰り返しません。

DATE=$(date +%Y%m%d)
SLUG=greeting   # derive from the goal; lowercase alphanumeric plus hyphen, max ~20 chars
HASH=$(openssl rand -hex 2 | head -c 3)
RUN="${DATE}-${SLUG}-${HASH}"
BRANCH="ralph/${RUN}"

# slug and epic are in scope from Step 2.

bdc() {
  bd create "$1" -t task -p 2 --parent "${epic}" -l "ralph:${slug}" -q --json | jq -r .id
}

T_BRANCH=$(bdc "Switch to branch ${BRANCH}")
bd update "$T_BRANCH" -d "Switch to branch ${BRANCH}, creating it if missing. Verify: git rev-parse --abbrev-ref HEAD prints ${BRANCH}."

T_BEGIN=$(bdc "Tag RALPH-${RUN}-BEGIN")
bd link "$T_BEGIN" "$T_BRANCH"
bd update "$T_BEGIN" -d "Run: git tag RALPH-${RUN}-BEGIN. Verify: git tag -l RALPH-${RUN}-BEGIN is non-empty."

T1=$(bdc "Add hello() to lib/greeting.go")
bd link "$T1" "$T_BEGIN"
bd update "$T1" --body-file - <<'DESC'
TDD workflow: write failing tests first, then implement minimum code to pass.

RED phase (write first):
Create lib/greeting_test.go. Test cases: hello() returns "world".

GREEN phase (then implement):
Create hello() in lib/greeting.go returning "world".

VERIFY: go test ./lib/... passes. Commit: feat(greeting): add hello
DESC

T2=$(bdc "Add goodbye() to lib/greeting.go")
bd link "$T2" "$T_BEGIN"
bd update "$T2" --body-file - <<'DESC'
TDD workflow: write failing tests first, then implement minimum code to pass.

RED phase (write first):
Add to lib/greeting_test.go. Test cases: goodbye() returns "bye".

GREEN phase (then implement):
Create goodbye() in lib/greeting.go returning "bye".

VERIFY: go test ./lib/... passes. Commit: feat(greeting): add goodbye
DESC

T3=$(bdc "Add greet(name) to lib/greeting.go")
bd link "$T3" "$T1"
bd link "$T3" "$T2"
bd update "$T3" --body-file - <<'DESC'
TDD workflow: write failing tests first, then implement minimum code to pass.

RED phase (write first):
Add to lib/greeting_test.go. Test cases: greet("Jim") returns
"world Jim bye".

GREEN phase (then implement):
Create greet(name) in lib/greeting.go composing hello() and goodbye().

VERIFY: go test ./lib/... passes. Commit: feat(greeting): add greet
DESC

T4=$(bdc "Document greetings API")
bd link "$T4" "$T3"
bd update "$T4" -d "Run the docs skill (/docs, \$docs) to document hello(), goodbye(), and greet() now exposed by lib/greeting.go. Commit: docs: document greetings API"

T_END=$(bdc "Tag RALPH-${RUN}-END")
bd link "$T_END" "$T4"
bd update "$T_END" -d "Run: git tag RALPH-${RUN}-END. Verify: git tag -l RALPH-${RUN}-END is non-empty."

3文字のハッシュ接尾辞により、複数のralph実行で日付とスラッグが同じ場合に、ブランチとタグの衝突を防ぎます。

作成後、循環がないこと、すべての子に説明があること、少なくとも1つのタスクが実行可能であること、親の集合がラベルの集合(エピックを除く)と一致することを確認します。

bd dep cycles
bd list --parent "${epic}" --json | jq -e 'all(.[]; (.description // "") | length > 0)'
bd ready --parent "${epic}" --json | jq 'length'

parent_ids=$(bd list --parent "${epic}" --json | jq -r '.[].id' | sort)
label_ids=$(bd list --label "ralph:${slug}" --json | jq -r '.[] | select(.issue_type != "epic") | .id' | sort)
[[ "${parent_ids}" == "${label_ids}" ]] || { echo "parent/label set mismatch: orphans or misclassified beads"; exit 1; }

タイトルのルール:

  • 命令形で1行にする
  • 手順ではなく成果物を示す
  • 「コードベースを読む」や「アーキテクチャを理解する」などのメタタスクにしない

説明のルール:

  • タスク固有の事実のみを記載する:対象ファイル、動作、このタスクのコミットメッセージ
  • 検証コマンドは、実行全体で標準のテストコマンドと異なる場合にのみ記載する(通常はタグとブランチのタスク)
  • コードスタイルやペルソナのルールを繰り返さない。これらはCLAUDE.mdに記載されています。実行全体のビルド、テスト、Lintのコマンドも繰り返さない。これらはralph-plan.mdに記載されています。
  • すべてのコーディングタスクの説明では、RED/GREEN/VERIFYの構成を使用する:REDフェーズではテストファイルを示し、期待される動作を具体的なテストケースごとに列挙します。GREENフェーズでは実装のみを説明します。VERIFYではテストコマンドとConventional Commit形式のコミットメッセージを記載します。ライフサイクル、設定、SQL、シェル、Helm、ドキュメントのBeadは対象外です。
  • 「テストを書く」「単体テストを追加する」「統合チェックポイント」のような独立したBeadは作成しないでください。テストはREDフェーズを通じて各コーディングタスクに含めます。テスト専用のBeadや、後回しにするテストスイートのBeadは作成しないでください。

スキルへの委任(必須):

作業スキル
README.md、CLAUDE.md、または.llmdocs/内のファイルの更新docs (/docs, $docs)

このカテゴリのBeadでは、説明内でスキルを呼び出す必要があります。編集内容を直接記述しないでください。例:Run the docs skill to document the new auth middlewareではなく、Edit .llmdocs/architecture.md to add an Authentication subsectionとします。スキルには独自のガードレールと並列処理の仕組みがあり、作業内容を説明に直接記述すると、その両方が失われます。

ステップ4:.llmtmp/ralph-plan.mdを作成する

各イテレーションでは、過去の実行に関する記憶がない状態でこのファイルを読み込みます。すべてのコマンド、パターン、規約をここに記載してください。リポジトリ固有の詳細は、密度が高くても問題ありません。

「Run Identity」セクションには、エージェントが各イテレーションで値を再導出せずに直接読み取れるよう、ステップ2で生成された${slug}と${epic}のリテラル値を記録します。

「Inputs」セクションのplan documents:行には、ユーザーの引数を通じてプランナーに渡されたソースドキュメントを記録します。レビュアーはこの行を解析し、各パスを意図の根拠として読み込みます。これはそのまま引き継ぐ項目です。ユーザーの引数に含まれるファイルだけを、過不足なく列挙してください。参照先のパスが存在しない場合は、除外せず、明確なエラーを表示してビルドを失敗させてください。

必須セクション:

# Ralph Plan

## Goal

<one paragraph>

## Approach

<strategy specific to this goal; include all relevant repo-specific detail directly>

## Inputs

plan documents: <comma-separated paths from the user's arguments, or empty if none>

## Run Identity

- Branch slug: `<slug from Step 2>`
- Epic ID: `<epic ID from Step 2>`
- Epic label: `ralph:<slug>`
- Driver: `scripts/ralph.sh .llmtmp/ralph-prompt-external.md`

## Conventions

<repo-specific patterns, tools, test commands, build commands, commit style>

## Git Workflow

All git operations execute as bd tasks per the per-task workflow. Branch creation, BEGIN tag, code commits, docs commits, and END tag are first-class beads in the graph, parented to the run epic. Never commit on `main`.

## Per-Task Workflow

Exactly ONE task per iteration. After step 5, follow the driver instruction. The driver controls whether the agent loops in-session or stops for a fresh context.

Each iteration:

1. Read the epic ID and slug from the "Run Identity" section above.
2. Run `bd ready --parent <epic-id> --json`. If the result is `[]`, run `bd close <epic-id> -m "ralph run complete"`, output `<promise>ALLDONE</promise>`, and stop.
3. Pick the first task. Run `bd show <id>` to read the title and description.
4. Execute the description exactly. The description names the files, commands, verification step, and commit message for this task.
5. Run `bd close <id>`. Follow the driver instruction below.

The sentinel `<promise>ALLDONE</promise>` is emitted only on the iteration where step 2 finds the ready queue empty (all children closed and the epic just closed).

## Driver Instruction




プランのルール:

  • 実際のリポジトリ構成とツールに基づいて指示を記述する
  • 判明している場合は、ビルド、テスト、Lintのコマンドを含める
  • プロジェクトのCLAUDE.mdと内容を重複させない
  • タスクの完了条件を定義する(テストが通る、リンターのエラーがない)
  • 現在の事実のみを記載する
  • plan documents:には、ユーザーの引数で参照されたファイルのみを正確に列挙する。README.md、CLAUDE.md、.llmdocs/*は追加しない(レビュアーがこれらをベースラインとして個別に読み込みます)。.llmtmp/などから関連ファイルを推測しないでください。参照先のパスが存在しない場合は、除外せず、明確なエラーを表示してビルドを失敗させてください。
ステップ 5:プロンプトラッパーを作成する

ドライバーの指示が異なるため、モードごとに個別の本文を用意します。

セッション内の本文(停止せずにループします):

Read .llmtmp/ralph-plan.md and follow it. After closing each task, return to step 1 of the Per-Task Workflow to pick the next ready task. Do not stop between tasks.

外部の本文(1 回の呼び出しにつき 1 つのタスク):

Read .llmtmp/ralph-plan.md and follow it. After closing each task, STOP. The driver spawns a fresh context for the next task.

.llmtmp/ralph-prompt-insession.md は、セッション内の本文を使った 1 行のファイルです:

/ralph-loop:ralph-loop "<in-session body>" --max-iterations 100 --completion-promise ALLDONE

.llmtmp/ralph-prompt-external.md は、ラッパーのない外部の本文のみです。

検証

完了する前に、次の項目を確認します:

  • bd list >/dev/null 2>&1 が 0 で終了する

  • bd dep cycles が 0 で終了する

  • この実行用に未完了のエピックが 1 つだけ存在する:bd list -t epic -l "ralph:${slug}" --json | jq -e 'length == 1'

  • bd ready --parent "${epic}" --json | jq 'length' の値が 0 より大きい

  • エピックのすべての子に空でない説明がある:bd list --parent "${epic}" --json | jq -e 'all(.[]; (.description // "") | length > 0)'

  • 親の集合がラベルの集合と一致する(エピック自体を除く):

    diff <(bd list --parent "${epic}" --json | jq -r '.[].id' | sort) \
         <(bd list --label "ralph:${slug}" --json | jq -r '.[] | select(.issue_type != "epic") | .id' | sort)
    
  • .llmtmp/ralph-plan.md、.llmtmp/ralph-prompt-insession.md、.llmtmp/ralph-prompt-external.md がすべて存在する

  • 計画の「Run Identity」セクションに、スラッグのリテラルとエピック ID が記録されている

  • セッション内プロンプトに「return to step 1」と「Do not stop between tasks」が含まれている

  • 外部プロンプトに「STOP」と「fresh context」が含まれている

確認項目に不合格があれば、修正して再検証します。

コメント