afk-cook について
afk-cookは、readyなGitHub issueごとに新しい`claude -p`を起動するBashランナーです。依存関係に沿ってissueを並べ、TDD向けプロンプトを適用し、完了した作業単位にコミットがあることを確認してからトラッカーを更新します。
主な機能
- 01issueごとに新しいエージェントコンテキスト
- 02依存関係順のissueキュー
- 03各作業単位向けのTDDプロンプト
- 04再試行と完了確認
- 05コミットを記録して完了issueをクローズ
活用シーン
- 01ready-for-agentのGitHub issueをまとめて処理
- 02独立した作業単位を順番に実行
- 03要件が明確な実装作業を自動化
- 04ブロック中または未完了のissue作業を検出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ guillermomurillo/ memo-flow --skill afk-cookインストール後、Claude Code で/afk-cookを入力して読み込まれたか確認します。
同梱ファイルafk-cookslice-prompt.md
詳細
AFK runner
afk-cook は、GitHub の issue ごとに新しい claude -p の呼び出しを起動する bash の for ループです。各反復は空のコンテキストから開始します。状態は git ツリー、CLAUDE.md、GitHub の issue 本文に保存されます。プロンプトテンプレートには TDD の手順が埋め込まれているため、ヘッドレス呼び出しは RED、GREEN、REFACTOR の順に進め、コミットすることを理解できます。
スライスごとに新しいコンテキストを使う理由
単一の長い Claude セッションでは、スライスを重ねるごとにコンテキストが蓄積して方向がずれ、最終的に本筋を見失います。afk-cook はスライスごとに claude -p を呼び出し、毎回空のコンテキストで実行します。エージェントは記憶ではなく、issue から仕様を読み取ります。このため、このスクリプトは長時間実行する単一のセッションではなく、bash の for ループになっています。
インストール
インストールは、薄いラッパーを使う 2 層構成です。
- スキルフォルダー。
npx skills@latest add GuillermoMurillo/memo-flow -a claude-codeは、実際のランナースクリプトとプロンプトテンプレートを.claude/skills/afk-cook/afk-cookと.claude/skills/afk-cook/slice-prompt.mdに並べて配置します。 - ラッパー。
/memo-flowは、スキルフォルダーの外にファイルを 1 つだけ書き込みます。配置先は<project-root>/.claude/memo-flow/bin/afk-cookです。
#!/usr/bin/env bash
exec "$(dirname "$0")/../../skills/afk-cook/afk-cook" "$@"
slice-prompt.md がラッパーの隣にコピーされないのは、この間接化のためです。exec はラッパーのプロセスを、解決済みのパスで呼び出される実際のスクリプトに置き換えます。そのため、ランナー内の $0 はラッパーではなく、.claude/skills/afk-cook/ にある実際のスクリプトを指します。デフォルトのプロンプトパス($(dirname "$0")/slice-prompt.md)は、実際のスクリプトの隣にあるテンプレートを指します。正しくインストールされたプロジェクトでは、スキルフォルダー外にある afk-cook ファイルは 1 つだけです。ファイルをあちこちにコピーして「修正」しないでください。
プロジェクトのルートから ./.claude/memo-flow/bin/afk-cook を実行します。
何かが見つからない場合:
.claude/memo-flow/bin/afk-cookにラッパーがない →/memo-flowを再実行し、確認が表示されたら AFK のインストールを承認してください。ラッパーが再作成されます。.claude/skills/afk-cook/に実際のスクリプトまたはslice-prompt.mdがない → スキルのインストール自体が不完全です。npx skills@latest add GuillermoMurillo/memo-flow -a claude-codeを再実行してから、/memo-flowを実行してください。
使い方
.claude/memo-flow/bin/afk-cookという完全なパスを使うのは意図的です。memo-flow はPATHに変更を加えません。エイリアス、direnv、シンボリックリンクの設定方法については、ルート README の afk-cook のオプションのショートカット を参照してください。
./.claude/memo-flow/bin/afk-cook # all open ready-for-agent issues
./.claude/memo-flow/bin/afk-cook <N> # one slice (good for first try)
./.claude/memo-flow/bin/afk-cook <N> <M> <O> # explicit batch
依存関係の順序
実行前に、afk-cook は各 issue の本文を読み取り、Blocked by #N マーカー(/to-issues が出力するものと同じ形式)を確認して依存関係を解決します。その後、キューをトポロジカル順に実行します。ある issue は、ブロック元のすべての issue がトラッカー上で CLOSED になっているか、同じ実行内ですでに完了している場合にのみ開始します。
起動時に実行順序が通知されます。
afk: resolving dependencies for 4 issue(s): 9 10 11 12
afk: dependency-ordered queue: 9 10 11 12
キューに依存関係の循環がある場合、または解決できない issue(オープン状態でキューに含まれていない issue)を参照している場合、afk-cook は issue ごとのブロッカー一覧を表示して終了コード 4 で終了し、何も実行しません。
トポロジカル層内(グラフ上の深さが同じスライス内)では、決定性を保つため、数値順に並べます。
環境変数による上書き
| 変数 | デフォルト | 効果 |
|---|---|---|
MAX_RETRIES | 2 | エージェントが最初の試行で SLICE_COMPLETE を出力しなかった場合の、issue ごとの再試行回数です。厳密に 1 回だけ実行するには 1 に設定します。 |
LABEL | ready-for-agent | 引数が指定されていない場合に検索するラベルです |
PROMPT_FILE | <script-dir>/slice-prompt.md | プロンプトテンプレートを上書きします |
例:単一のスライスを 1 回だけ実行するには、MAX_RETRIES=1 ./.claude/memo-flow/bin/afk-cook <N> を実行します。
実行時に表示される内容
- スライスごとのバナー(
═══...)と試行ごとのバナー(─── attempt N of M ───) - エージェントの出力全体がターミナルにストリーミングされると同時に、
/tmp/ralph-slice-<N>-<attempt>.logにも書き込まれます - 成功時:
─── slice #<N>: SLICE_COMPLETE after attempt <N> ───の後、次のスライスに進みます - エージェントがブロッカーを報告した場合:
─── slice #<N>: SLICE_BLOCKED ... ───が表示され、スクリプトは終了コード 2 で終了します - 再試行を使い切った場合:
─── slice #<N>: exhausted <N> attempts without completion ───が表示され、スクリプトは終了コード 3 で終了します - 依存関係を解決できない場合:
afk: cannot proceed — dependency cycle or unsatisfiable depsが表示され、スクリプトは終了コード 4 で終了します
SLICE_COMPLETE が出力されると、ランナーは試行中に新しいコミットが作成されたことを確認します(試行前後の HEAD を比較します)。エージェントがコミットせずにセンチネルを出力した場合、その試行は失敗として扱われ、再試行されます。コミットが確認されると、トラッカー上でイシューのラベルが解除され、SHA を参照するコメントが追加されたうえでクローズされます。そのため、後続の実行(今日でも来週でも)では、そのイシューは依存先として完了済みと見なされます。
Ctrl-C を押すと、現在の反復が中断されます。スクリプトはデフォルトの動作を超えるシグナル処理を行わないため、部分的に書き込まれたコミットは作業ツリーに残ります。
終了コード 4 の読み方
exit 4 は、キュー内に、トラッカー上でクローズされておらず、今回の実行でも先に完了していない依存関係によってブロックされているオープンイシューが少なくとも 1 つあることを意味します。スクリプトはイシューごとのブロッカー報告を出力し、状況に応じたヒントを追加します。
- マシン上で別の
afk-cookプロセスが実行中の場合、ブロッカーは、その別の実行によって処理されている可能性が最も高いです。処理が終わるまで待ってから再実行してください。並列実行を始めたり、ロジックの不具合を疑ってイシューの状態を変更したりしないでください。適切な方法は、依存するすべてのスライスを 1 回の実行にまとめ、依存関係リゾルバーに順序を決めさせることです。 - 他に実行中の
afk-cookがない場合、ブロッカーは実際に未出荷か、以前に出荷されたもののトラッカー上でクローズされていないかのどちらかです。GitHub でイシューを確認してください。出荷済みであれば、手動でクローズしてから再実行してください。
同じリポジトリでの同時実行は安全ではありません(git HEAD、作業ツリー、ラベル更新が競合します)が、afk-cook はロックによってこれを防止しません。依存関係のチェックでは、並列実行が処理中のブロッカーに依存するイシューに影響する一般的なケースに対応します。同じリポジトリに対して、2 つの afk-cook を同時に実行しないでください。1 回の実行にまとめてください。
インタラクティブな /tdd との使い分け
afk-cook を使う場合:
- スライスが
ready-for-agent(PRD が明確で、設計上の判断が不要) - 離席して処理を任せたい
- 順次実行できる 2 つ以上のスライスをまとめて処理する
/tdd を使う場合:
- スライスが
ready-for-human(設計上の判断、コピーの選択、アーキテクチャ上のトレードオフが必要) - RED、GREEN のループをインタラクティブに監督したい
- 単一のスライスで、作業に取り組む時間がある
ready-for-agent とラベル付けされていても、誤って分類されたスライスは SLICE_BLOCKED 終了として報告されます。エージェントは、必要だった入力を説明するコメントをイシューに残します。
引き継ぎの慣例
ready-for-agent のスライスで /tdd のインタラクティブセッションを終えるときは、残りのスライスを処理するためのコピー&ペースト可能な行でセッションノートを締めくくります。
#<N> done. Remaining ready-for-agent: #<M>, #<O>, #<P>.
To batch them, run:
./.claude/memo-flow/bin/afk-cook <M> <O> <P>
現在オープンなイシュー番号は、gh issue list --label ready-for-agent --state open --json number,title を実行して取得してください。このドキュメントに番号をハードコードしないでください。番号は古くなります。
失敗モード
サブプロセスのハング
スライスがハングすると(テストランナーが停止する、pre-commit フックが戻らないなど)、claude -p の呼び出しもハングします。次のような症状が見られます。
- 数分間、新しい出力がない
SLICE_COMPLETEもSLICE_BLOCKEDも出力されないps aux | grep claudeに実行中のプロセスが表示される
復旧方法:スクリプトに Ctrl-C を送信します。残った claude プロセスやテストランナープロセスを手動で終了します。根本原因となったハングを調査します(初期化されていないテストデータベース、欠落しているマイグレーション、エージェントが起動したままにしたウォッチモードのプロセスなどがよくある原因です)。
エージェントが誤ったブランチにコミットする
スクリプトはブランチを確認したり切り替えたりしません。現在いるブランチにコミットされます。誤って main にいる場合、コミットは main に行われます。起動する前に git branch --show-current を確認してください。
プリコミットフックが失敗する
プロンプトでは、エージェントにコミット前にプロジェクトのテストと型チェックを実行するよう指示しているため、通常はプリコミットフックを通過するはずです。それでも失敗する場合、そのスライスのテストに本当に問題があります。修正して再実行してください。
AFK ループ内で --no-verify を使ってプリコミットフックを回避しないでください。スクリプトはそのフラグを渡しません。スライスで本当に必要な場合は、明確な理由を示したうえで、ループの外で手動でコミットしてください。
エージェントがコミットメッセージに Issue 番号を入れ忘れる
プロンプトでは、コミットメッセージに [#<N>] または Refs #<N> を含めるよう明示的に求めています。それを含めずにスライスを公開した場合、プロンプトが無視されています。プロンプトテンプレートを読み直し、指示を強化してください。