moai-workflow-loop について
moai-workflow-loop は、Claude Code 向けの反復的なコード品質チェックと修正を行うスキルです。LSP 診断、AST-grep スキャン、テスト検証を組み合わせ、設定した完了条件を満たすまで処理を続けます。
主な機能
- 01ファイル編集後の LSP 診断
- 02AST-grep によるセキュリティ・品質スキャン
- 03完了条件を確認する修正ループ
- 04Claude Code の PostToolUse・Stop フック
活用シーン
- 01診断が解消するまでコードを修正
- 02コードのセキュリティ・品質ルールを確認
- 03修正中にテストとカバレッジを検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ modu-ai/ moai-adk --skill moai-workflow-loopインストール後、Claude Code で/moai-workflow-loopを入力して読み込まれたか確認します。
同梱ファイルreferences/examples.mdreferences/reference.md
詳細
Ralph Engine
LSP 診断、AST-grep によるセキュリティスキャン、テスト検証を統合し、コード品質を継続的に向上させる自動フィードバックループシステムです。
プリセットアーキテクチャ — 目標プリセットとしての Ralph Engine
/moai loop スキル(~/.claude/skills/moai/workflows/loop.md)は、この Ralph エンジンを目標エンジン上に構築された目標プリセットとして再定義します。スキャン段階で有限の課題キューを作成し、完了まで反復するかどうかの判断は、あらかじめ入力された条件「キューが空になり、診断に問題がない」を用いて、目標エンジン(stop-goal)に委ねます。このプリセットアーキテクチャでは、この SKILL.md で、目標プリセットによるスイープが駆動する基盤となる LSP/AST-grep/テスト/カバレッジ診断の仕組みを説明します。プリセットはこの仕組みを変更せず、その上に目標エンジンの構成を重ねます。4 つのループ象限(目標ベースのスイープ、ターンベースの /moai fix、時間ベースの定期実行、プロアクティブな CI 監視)は、独立したエンジンではなく、1 つの目標エンジンに対するプリセットです。
クイックリファレンス
主な機能:
- LSP 統合:言語サーバーからリアルタイムで診断情報を取得
- AST-grep スキャン:構造的なコード分析とセキュリティチェック
- フィードバックループ:完了条件を満たすまでエラーを反復的に修正
- フックシステム:PostToolUse フックと Stop フックによるシームレスな Claude Code 統合
主なコンポーネント:
- .claude/hooks/moai/handle-post-tool.sh(PostToolUse):Write/Edit 操作後の LSP 診断
- .claude/hooks/moai/handle-stop.sh(Stop):ループの反復を制御
- ralph.yaml:設定
コマンド:
- /moai:ワンクリックの Plan-Run-Sync 自動化(デフォルト)
- /moai loop:フィードバックループを開始
- /moai fix:1 回限りの自動修正
使用する場面:
- エラーゼロを目標とする機能の実装
- コード品質の自動改善
- 継続的インテグレーションのワークフロー
- エラー駆動型の開発パターン
実装ガイド
アーキテクチャの概要
Ralph Engine は階層化アーキテクチャに従います。/moai:loop、/moai:fix、/moai などのユーザーコマンドはコマンドレイヤーに入ります。コマンドレイヤーはフックシステムを呼び出します。フックシステムには、LSP 診断用の PostToolUse フックと、ループ制御用の Stop フックが含まれます。フックシステムは、LSP クライアント(MoAILSPClient)、AST-grep スキャナー、テストランナーを含むバックエンドサービスに接続します。バックエンドサービスは完了チェックに情報を渡し、エラーがゼロか、テストに合格したか、カバレッジの基準を満たしたかを評価します。完了チェックの結果に基づいて、システムはループを続行するか、完了します。
設定
ralph.yaml 設定ファイルには、以下のセクションと設定が含まれています。
ralph セクションでは、enabled で Ralph を有効にするかどうかを制御します(デフォルトは true です)。
lsp セクションでは、auto_start で言語サーバーの自動起動を制御します(デフォルトは true です)。timeout_seconds では接続タイムアウトを設定します(デフォルトは 30 秒です)。graceful_degradation では、LSP が利用できない場合にリンターへフォールバックするかどうかを設定します(デフォルトは true です)。
ast_grep セクションでは、enabled で AST-grep 統合を制御します(デフォルトは true です)。security_scan でセキュリティルールのチェックを有効にし(デフォルトは true です)、quality_scan でコード品質ルールのチェックを有効にします(デフォルトは true です)。
loop セクションでは、max_iterations でループの最大反復回数を設定します(デフォルトは 10 です)。auto_fix では修正の自動適用を制御します(デフォルトは false で、適用には確認が必要です)。require_confirmation では修正前にユーザーの承認を必要とするかどうかを設定します(デフォルトは true です)。
loop の completion サブセクションでは、zero_errors で LSP またはコンパイラーのエラーがないことを必須にします(デフォルトは true です)。zero_warnings で警告がないことを必須にします(デフォルトは false で、任意の条件です)。tests_pass で、すべてのテストに合格することを必須にします(デフォルトは true です)。coverage_threshold では、カバレッジの最小割合を設定します(デフォルトは 85 です)。
hooks セクションでは、post_tool_lsp に enabled(デフォルトは true)と severity_threshold(デフォルトは error)を設定します。stop_loop_controller の enabled はデフォルトで true に設定されています。
フックの統合
PostToolUse フック
PostToolUse フックは、Write および Edit の操作後にトリガーされます。呼び出されると、Claude Code は tool_name(Write など)と、file_path および content を含む tool_input を含んだフック入力を提供します。
このフックは診断を処理し、hookEventName(PostToolUse)と、診断結果を説明する additionalContext を含む hookSpecificOutput を含んだフック出力を返します。たとえば、LSP により file.py で 2 件のエラーと 3 件の警告が見つかったことや、行番号を含む具体的なエラーメッセージがコンテキストに報告されます。
終了コード 0 は、対応が不要であることを示します。終了コード 2 は、エラーが見つかったため対応が必要であることを示します。
ループコントローラー用 Stop フック
Stop フックは、Claude の応答ごとにトリガーされます。このフックは、.moai/cache/.moai_loop_state.json にあるループ状態ファイルを読み取ります。この状態には、active ステータス(true または false)、現在のイテレーション番号、max_iterations の上限、前回のイテレーションの last_error_count、および完了時の completion_reason が含まれます。
このフックは、hookEventName(Stop)とループの状態を報告する additionalContext を含む hookSpecificOutput を含んだ出力を返します。たとえば、Ralph Loop が Iteration 3 of 10 で 2 Errors の状態で CONTINUE しており、残りのエラーを修正するための次のアクションが示される場合があります。
終了コード 0 は、ループが完了しているか非アクティブであることを示します。終了コード 1 は、さらに作業が必要なためループを続行することを示します。
LSP クライアントの使用方法
Go LSP クライアントはフックシステムに統合されています。LSP 診断は、post-tool フック(moai hook post-tool-use)によって自動的に収集されます。
ファイルの診断を取得するには、ファイルパスを指定して get_diagnostics メソッドを非同期で呼び出します。
返された診断は、各診断オブジェクトを順に処理します。エラーを特定するには、severity プロパティを DiagnosticSeverity.ERROR と照合します。行番号は diag.range.start.line から、メッセージは diag.message から取得します。
完了条件
有効になっているすべての条件を満たすと、ループは完了します。
zero_errors 条件(デフォルトは true)は、LSP またはコンパイラーのエラーがないことを要求します。
zero_warnings 条件(デフォルトは false)は、警告がないことを任意で要求します。
tests_pass 条件(デフォルトは true)は、すべてのテストが合格することを要求します。
coverage_threshold 条件(デフォルトは 85)は、最低カバレッジ率を要求します。
高度なパターン
カスタム完了条件
チェック関数を実装することで、カスタム条件をループコントローラーに追加できます。たとえば、コードベース内の TODO コメントを数え、その数がゼロになった場合にのみ true を返す関数を作成できます。
CI/CD との統合
GitHub Actions と統合するには、/moai:loop コマンドと max-iterations フラグを指定して Claude を実行するワークフローステップを作成します。ループモードを有効にするには、MOAI_LOOP_ACTIVE 環境変数を true に設定します。
グレースフルデグラデーション
LSP を利用できない場合、システムは ruff や eslint などのツールを使ったリンターによる診断にフォールバックし、次にコンパイラーのエラー検出、最後にテスト失敗の検出へと移行します。
トラブルシューティング
ループが開始しない
設定で ralph.enabled が true に設定されていることを確認します。MOAI_DISABLE_LOOP_CONTROLLER 環境変数が設定されていないことを確認します。状態ファイルの保存先が書き込み可能であることを確認します。
LSP 診断がない
.moai/config/sections/lsp.yaml の LSP サーバー設定を確認します。使用している言語の言語サーバーがインストールされていることを確認します。MOAI_DISABLE_LSP_DIAGNOSTIC 環境変数が設定されていないことを確認します。
ループが停止しない
max_iterations の設定を確認し、十分なイテレーションが許可されていることを確かめます。完了条件を確認し、達成可能であることを確かめます。ループを中断するには任意のメッセージを送信します。または、状態ファイル(.moai/cache/.moai_loop_state.json)を削除してリセットします。
うまく連携するもの
スキル:
- moai-foundation-quality:TRUST 5 検証
moai ast-grep/moai ast-edit:セキュリティスキャンのパターンと書き換え- moai-workflow-testing:DDD 統合
.claude/rules/moai/languages/python.md:Python 固有のパターン(paths frontmatter を介して自動読み込み).claude/rules/moai/languages/typescript.md:TypeScript のパターン(paths frontmatter を介して自動読み込み)
エージェント:
- manager-develop:DDD の実装
- manager-develop(cycle_type=autofix):複雑なデバッグと修正案の提示(旧 manager-quality のデバッグ担当)
- /moai gate スキルまたは Stop フックの sync-phase-quality-gate.sh:品質検証(旧 manager-quality のゲート担当)
コマンド:
- /moai:run:DDD の実装
- /moai:sync:ドキュメントの同期
リファレンス
環境変数
MOAI_DISABLE_LSP_DIAGNOSTIC が設定されている場合、LSP フックを無効にします。
MOAI_DISABLE_LOOP_CONTROLLER が設定されている場合、ループフックを無効にします。
MOAI_LOOP_ACTIVE は、ループが現在アクティブかどうかを示します。
MOAI_LOOP_ITERATION には、現在の反復回数が含まれます。
CLAUDE_PROJECT_DIR には、プロジェクトのルートパスが含まれます。
ファイルの場所
設定は .moai/config/sections/ralph.yaml に保存されます。
ループの状態は .moai/cache/.moai_loop_state.json に保存されます。
LSP フックは .claude/hooks/moai/handle-post-tool.sh にあります。
ループフックは .claude/hooks/moai/handle-stop.sh にあります。
サポート対象の言語
LSP 診断は、MoAI がサポートする 16 言語すべてで利用できます:C++、C#、Elixir、Flutter、Go、Java、JavaScript、Kotlin、PHP、Python、R、Ruby、Rust、Scala、Swift、TypeScript。Ralph はマーカーファイル(たとえば、Go の場合は go.mod、Python の場合は pyproject.toml、TypeScript の場合は tsconfig.json、Rust の場合は Cargo.toml、Flutter の場合は pubspec.yaml)を使ってプロジェクトの言語を検出し、必要に応じて対応する言語サーバーを起動します。ユーザーは、実際にプロジェクトで必要なサーバーのみをインストールします。サーバーが見つからない場合は、インストール方法を案内して警告を表示したうえでスキップされ、処理が完全に失敗することはありません。言語サーバーとバイナリの対応表全体については、references/reference.md を参照してください。.claude/rules/moai/development/coding-standards.md の § Language Policy(16 言語中立性の取り決め)に従い、特定の言語が他の言語より優先されることはありません。
バージョン:1.2.0 ステータス:有効 統合:Claude Code Hooks、LSP Protocol、AST-grep スキル名:moai-workflow-loop(旧 moai-ralph)
よくある正当化
| 正当化 | 実態 |
|---|---|
| "ループの後で残りのエラーを手動で修正します" | 手動での後続対応が必要ということは、ループの仕事が完了していないということです。残ったエラーは、そのままリリースされるエラーです。 |
| "ループが最大反復回数に達しましたが、残りの問題は軽微です" | 反復回数の上限はコスト管理のためのものであり、品質を保証するものではありません。未解決の項目を報告してください。 |
| "LSP の警告は本当のエラーではありません" | 反復を重ねても残る警告は、構造上の問題を見過ごしていることを示します。対処するか、明示的に抑制してください。 |
| "根本原因を修正したので、他の診断結果は自動的に解消されます" | 連鎖的に修正される保証はありません。診断を再実行し、それぞれが解消されたことを確認してください。 |
| "ast-grep のルールはこのコードベースには厳しすぎます" | ルールはプロジェクトの規約を反映しています。スキャン全体を省略せず、根拠を示して特定のルールを無効にしてください。 |
| "この反復では進展がなかったので、停止すべきです" | 2 回の反復後に停滞した場合は、何も報告せずに終了するのではなく、エスカレーションが必要です。エスカレーション手順に従ってください。 |
500 のルール:500 行を超える変更には、診断に集中する独立したループ反復を割り当ててください。大きな変更は個々のリグレッションを見えにくくします。
危険信号
- 未解決のエラーがある状態でループが終了し、停滞レポートもない
- 同じ診断結果が対処されないまま連続する反復で現れる
- 特定のルールのみを無効にせず、ast-grep のスキャン全体を無効にする
- 反復の開始時に LSP のベースラインを取得せずにループを実行する
- 診断を再実行せずに、ループの反復間でコードを手動変更する
検証
- 各イテレーションがエラー数の差分とともに進捗ログに記録されている
- 最終イテレーションでエラーがゼロになっているか、停滞状況が明示的に報告されている
- ループ開始時に LSP のベースラインが取得されている(診断数を表示)
- ループ中に少なくとも一度 ast-grep スキャンが実行されている(出力を表示)
- 未解決項目について、修正できなかった理由が記録されている
- 連続するイテレーション間で診断数が増加していない