scaffold-hooks について
scaffold-hooksは、Claude Code、Codex、GitHub Copilot、Devin CLI、OpenCode向けに、リポジトリ管理のライフサイクルフックを作成・移行するエージェントスキルです。既存設定を検出してカスタムフックを維持し、ドライランや検証の手順も提供します。
主な機能
- 015つのハーネス向けフック作成
- 02既存設定の検出と更新
- 03管理対象の旧フックを移行
- 04カスタムフックとスクリプトを維持
- 05ドライラン、監査、検証
活用シーン
- 01新規リポジトリへのフック導入
- 02検出済みハーネスのフック更新
- 03旧生成フックディレクトリの移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jpcaparas/ skills --skill scaffold-hooksインストール後、Claude Code で/scaffold-hooksを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdagents/.gitkeepassets/harnesses.jsonevals/evals.jsonharnesses/claude/PLAYBOOK.mdharnesses/claude/assets/hook-events.jsonharnesses/claude/references/gotchas.mdhook-events.mdmerge-strategy.mdproject-analysis.mdREADME.mdreusable-scripts.mdscaffold-layout.mdharnesses/claude/scripts/audit_project.shcheck_workspace_trust.shmerge_settings.shrender_hooks_readme.shscaffold_hooks.shscaffold_paths.shtest_skill.pyvalidate.pyharnesses/claude/templates/event-script.sh.tmplhook-plan.example.jsonharnesses/codex/PLAYBOOK.mdharnesses/codex/assets/hook-events.jsonharnesses/codex/references/feature-flag.mdgotchas.mdhook-events.mdmerge-strategy.mdproject-analysis.md詳細
Universal Agent Hook Scaffold
エージェントのライフサイクルフックをスキャフォールドするか移行し、選択したすべてのハーネスがリポジトリ所有のフックスキャフォールドを参照するようにします。これが唯一のフックスキャフォルダーです。以前の scaffold-cc-hooks、scaffold-codex-hooks、scaffold-github-copilot-hooks、scaffold-devin-hooks、scaffold-opencode-hooks スキルは廃止され、ここで harnesses/<name>/ 配下の内部ハーネスコンポーネントとして管理されています。
Decision Tree
- ユーザーが
/scaffold-hooks、hooks、ライフサイクルフック、フックの移行、または Claude Code、Codex、GitHub Copilot、Devin CLI、OpenCode のフックを指定した場合は、このスキルを使用します。 - ユーザーがハーネスを指定した場合は、指定されたハーネスのみを
--harnesses <list>で渡します。単一ハーネスの依頼では--harnesses <name>を指定します。 - ユーザーが対象パスを指定しない場合は、現在のワークスペースまたはリポジトリのルートを対象プロジェクトとして使用します。
- ユーザーがハーネスの希望を指定しない場合は、対象プロジェクトを調査します。サポート対象のフック設定箇所または管理対象のスキャフォールド状態が存在する場合は、
--harnessesを指定せずにユニバーサルスクリプトを実行し、検出されたハーネスのみを正確に更新します。ユーザーが明示的に求めない限り、新しいハーネスを追加しないでください。 - サポート対象のフック設定箇所が存在しない場合は、どのハーネスをスキャフォールドするか尋ねます。新規スキャフォールドでは、サポート対象の全ハーネス(
claude、codex、copilot、devin、opencode)をデフォルトとして使用します。 - 既存の設定が
.claude/hooks/generated、.codex/hooks/generated、または.devin/hooks/generatedを参照している場合は、移行として扱います。管理対象のコマンドエントリを削除し、hooks/をスキャフォールドして、マニフェストを含むレガシー管理対象フォルダーのみを削除します。 - プロジェクトに管理対象ルート以外のカスタムフックがある場合、ユーザーが削除を明示的に求めない限り保持します。
Harness Selection
選択順序は決定論的です。
- ユーザーが明示した
--harnesses。 - 指定されている場合は、カスタムユニバーサルプランの
harnessesリスト。 - 対象リポジトリ内で検出された既存のフック設定箇所または管理対象スキャフォールド状態。
- 上記のいずれも存在しない場合に限り、サポート対象の全ハーネスをデフォルトとして使用します。
検出対象には、現在の管理対象マニフェスト、レガシーの生成済みマニフェスト、hooks/ 配下の共有アダプター、フックエントリを含むハーネス設定ファイルが含まれます。いずれかのハーネスが検出された場合、ユーザーから明示的な指示がない限り、他のハーネスを追加しないでください。
claude— Claude Code、.claude/settings.jsoncodex— Codex CLI、.codex/hooks.json(フックの機能フラグが必要です。harnesses/codex/references/feature-flag.mdを参照してください)copilot— GitHub Copilot(クラウドエージェント+CLI)、.github/hooks/copilot-hooks.jsonと.github/copilot/hooks/generated/配下の生成イベントdevin— Devin CLI、.devin/hooks.v1.jsonopencode— OpenCode、opencode.jsonとopencode-froggy経由の.opencode/hook/hooks.md
追加するハーネスを明示するには、--harnesses claude,codex,copilot,devin,opencode(またはその一部)を指定します。すでにフックがあるリポジトリで引数を指定せずに実行した場合は、拡張ではなく更新になります。
Quick Reference
| タスク | コマンド |
|---|---|
| 検出済みの既存ハーネスを更新する、またはクリーンなリポジトリですべてをスキャフォールドする | scripts/scaffold_all_hooks.sh --project /path/to/project |
| 書き込みを行わずにプレビューする | scripts/scaffold_all_hooks.sh --project /path/to/project --dry-run |
| プロジェクト固有のユニバーサルプランを使用する | scripts/scaffold_all_hooks.sh --project /path/to/project --plan /path/to/scaffold-hooks.json |
| 選択したハーネスのみをスキャフォールドする | scripts/scaffold_all_hooks.sh --project /path/to/project --harnesses claude,codex |
| 共有イベントスクリプトを保持したままハーネスアダプターを更新する | scripts/scaffold_all_hooks.sh --project /path/to/project --mode overhaul |
| 対象リポジトリの単一ハーネスを監査する | harnesses/<name>/scripts/audit_project.sh /path/to/project |
| ハーネスコンポーネントを検証する | python3 harnesses/<name>/scripts/validate.py harnesses/<name> |
| ハーネスのテストスイートを実行する | python3 harnesses/<name>/scripts/test_skill.py harnesses/<name> |
標準的なワークフロー
- まず、対象プロジェクトを確認します。
- 既存の
.claude/settings*.json .codex/hooks.jsonと.codex/config.toml.devin/hooks.v1.jsonと.devin/config*.jsonopencode.json、.opencode/hook/hooks.md、旧.opencode/plugins/.managed/、およびカスタムの.opencode/plugins/.github/hooks/copilot-hooks.jsonと.github/copilot/hooks/generated/- 既存の
hooks/ツリーと、リポジトリ管理下にあるscripts/内の検証スクリプト
- 既存の
- 新しいスキャフォールドを作成する場合、またはハーネスを追加する場合に限り、ハーネスのセットを確認します。既存のフック設定があるリポジトリで単独で実行する場合は、検出されたセットのみを更新します。
- リポジトリの設定、インストール済みバージョンの根拠、および選択したハーネスの
PLAYBOOK.mdを使って、修復を計画します。それらの根拠だけでは不十分な場合、古く見える場合、またはイベントの意味が変わる場合は、関連する公式ドキュメントを現在の状態で確認します。安定したローカル修復のために、すべてのハーネスを調べる必要はありません。各コンポーネントは、バンドルされている仕様をharnesses/<name>/assets/hook-events.jsonに記録します。未解決の疑問に関係するリファレンスのみを読み込みます。 - プロジェクトに、より明確な計画がすでにある場合を除き、
templates/hook-plan.example.jsonを出発点にします。 scripts/scaffold_all_hooks.shを--dry-run付きで実行し、その後--dry-runを付けずに実行します。hooks/README.md、hooks/.state/scaffold-hooks/manifest.json、ハーネスの設定ファイル、および選択したアダプターを確認します。- プロジェクトで通常行う検証を実行します。
出力形式
バンドルされている Claude、Codex、Devin、Copilot のジェネレーターは Bash エントリーポイントを使用し、マニフェスト内のすべてのイベントを生成して、有効なイベントのみを接続します。共有ツリーはジェネレーター上の規約であり、すべてのハーネスやリポジトリで必須ではありません。リポジトリ管理下にある適切なプログラムは、Bash プロトコルの境界の内側に配置してください。これらのヘルパーは、選択したイベントのみを対象とするファイルレイアウトには対応していません。このパターンに合わせるためだけに既存のカスタムアーキテクチャを置き換えず、そのまま維持してください。
hooks/
README.md
lib/
agent-hook-runtime.sh
claude.sh
codex.sh
devin.sh
.state/
scaffold-hooks/
manifest.json
claude/
codex/
devin/
stop/
script.sh
claude.sh
claude.json
codex.sh
codex.json
devin.sh
devin.json
.opencode/
hook/
hooks.md
README.md
.managed/
manifest.json
plan.snapshot.json
opencode.json
ハーネスの設定ファイルは、ドキュメントに記載された場所に置きます。
- Claude:
.claude/settings.json - Codex:
.codex/hooks.json - Devin:
.devin/hooks.v1.json - OpenCode:
opencode.jsonがopencode-froggyを読み込みます。Froggy は.opencode/hook/hooks.mdを読み取ります - GitHub Copilot:
.github/hooks/copilot-hooks.json。生成されたイベントは.github/copilot/hooks/generated/に配置します(Copilot のクラウドエージェントはリポジトリからすべてを読み取るため、自己完結型です)
計画の形式
共通の計画スキーマの正本として、templates/hook-plan.example.json を使用します。最上位の計画で、共通の動作を制御します。
mode:additiveまたはoverhaulhooks_root:通常はhookscleanup_legacy:古い管理対象の生成フォルダーにマニフェストが含まれている場合に限り、削除しますharnesses:claude、codex、copilot、devin、opencodeのサブセット。意図的にハーネスのセットを選択または拡張する場合にのみ使用しますplans:ハーネスのコンポーネントに渡す、ハーネスごとの計画オブジェクト
プロジェクト固有のスクリプトやコマンドを追加する前に、references/plan-format.md を読んでください。
信頼と出力境界
プランや既存のフック設定は、任意のリポジトリから取得した安全でないデータではなく、実行可能なプロジェクトポリシーです。フックを有効にしたり、フックを実行するテストを実行したりする前に、そのコマンド、スクリプトのパス、作業ディレクトリ、参照されているコードを確認してください。シェルコマンドや Froggy のアクションは、エージェントのファイルシステム、ネットワーク、認証情報を使用できます。出力パスのチェックでは、これらのコマンドはサンドボックス化されません。信頼できないフックをテストする場合は、機密性の高い認証情報を含まない隔離環境を使用してください。
プロジェクトのスキャフォールディングでは、絶対パス、ホーム相対パス、親ディレクトリをたどるパス、シンボリックリンクされた出力パスが拒否されます。これには、管理対象ツリー内のリンクも含まれます。Universal の実行では、設定を変更したり管理対象の出力を削除したりする前に、選択したすべてのハーネスを事前チェックします。拒否された出力先は、リンクを削除したり、プライベートな設定をリポジトリに移動したりせず、ユーザーと相談して解決してください。
OpenCode のグローバルスコープを使用するには、ユーザーの明示的な承認と --allow-global-targets が必要です。また、出力は ~/.config/opencode/ 配下にとどめる必要があります。Codex のユーザー機能を有効にする場合も、ユーザースコープを選択する前に承認が必要です。プロジェクトパスのチェックを回避するために、いずれかのスコープを変更しないでください。これらのチェックが保護するのは安定したファイルシステムであり、攻撃者によって同時に変更されているファイルシステムではありません。
競合ポリシー
このスキルは慎重に動作します。
- 既存の管理対象の生成ルートコマンドを削除してから、新しい
hooks/<event>/<harness>.shコマンドを追加します。 - 同じ設定ファイル内の、管理対象ではないカスタムフックは保持します。
- 既存の
hooks/<event>/script.shファイルは保持し、別のハーネスによって共有プロジェクトの動作が書き換えられないようにします。 overhaulモードでは、hooks/配下にある選択したハーネスのアダプターと状態のみを削除し、シェルハーネスについてはハーネスコンポーネントを追加モードで呼び出します。- OpenCode では、管理対象外の
.opencode/plugins/ファイルを保持しますが、スキャフォールディングが所有するプラグイン出力はopencode-froggyと.opencode/hook/hooks.mdに移行します。
マージ動作を変更する前に、references/collision-policy.md を読んでください。
ハーネスコンポーネント
サポート対象の各ハーネスは、harnesses/<name>/ 配下にある自己完結型のコンポーネントです。独自の PLAYBOOK.md、スキャフォールディングスクリプト、イベントマニフェスト、テンプレート、リファレンス、バリデーター、テストスイートを備えています。
harnesses/claude/は、Claude Code のイベントセマンティクスと.claude/settings.jsonのマージを管理します。harnesses/codex/は、Codex のイベントセマンティクス、機能フラグの処理、.codex/hooks.jsonのマージを管理します。harnesses/devin/は、Devin のイベントセマンティクスと.devin/hooks.v1.jsonのマージを管理します。harnesses/opencode/は、OpenCode の Froggy 設定、opencode.jsonのプラグインマージ、以前のスキャフォールディング所有のローカルプラグインアーティファクトのクリーンアップを管理します。harnesses/copilot/は、クラウドエージェントと Copilot CLI 向けの GitHub Copilot のイベントセマンティクスと.github/hooks/copilot-hooks.jsonのマージを管理します。
イベント名、マッチャー、出力コントラクト、機能フラグを変更する場合は、以下のソース更新手順に従ってください。承認されたパッケージ更新では、まずハーネスコンポーネント(マニフェスト、リファレンス、スクリプト、テスト)を変更し、その後にユニバーサルなオーケストレーションを変更してください。構成順序を変更する場合やハーネスを追加する場合は、references/harness-composition.md を読んでください。
プロトコル出力の適切な管理
標準出力は一時ログではなく、ハーネスプロトコルの一部として扱ってください。JSON を出力するフックでは、標準出力は最終的なプロトコル JSON ペイロード専用です。イベントの契約で標準出力が明示的に許可されていない限り、正常に何も行わない場合は出力を控えてください。診断、デバッグテキスト、ファイル名、人間が読める形式の失敗詳細は、ハーネスが標準出力を要求しない限り、標準エラーに送ってください。
述語は出力せず、終了ステータスのみを返す必要があります。その他のヘルパーは、キャプチャされていない出力をプロトコルの標準出力に漏らしてはいけません。値を生成するヘルパーはキャプチャしたデータを返してもよく、指定されたプロトコル出力処理はイベントの JSON を書き出してもかまいません。grep -q/grep -Eq などの静かなチェックを使用するか、標準出力を /dev/null にリダイレクトしてください。出力がキャプチャされ、フックの標準出力に漏れない場合を除き、grep ... | head -1 のようなファイル名を調べる方法は使用しないでください。既知のリグレッションとして、hook_has_code_changes は終了ステータスのみを返す述語のままにしてください。
生成された JSON 出力フックは、静かな成功/何もしない場合に標準出力が空であること、コンテキストや判断を出力する際に、接頭辞や接尾辞のない解析可能なイベントに適した JSON ペイロードが 1 つだけ出力されること、共有ヘルパーからファイル名/デバッグ行/ステータス行が漏れないことを検証してください。イベントごとの終了コード契約は個別に維持してください。
注意事項
- ユニバーサル実行から、シェルハーネスのスキャフォルダーに
overhaulを直接渡さないでください。共有のscript.shファイルが書き換えられます。ユニバーサルスクリプトは、まずハーネスのクリーンアップを実行し、その後、追加方式でスキャフォルダーを呼び出します。 - OpenCode では、プラグイン層として
opencode-froggyを使用するようになりました。ユーザーからカスタムプラグインコードを明示的に求められない限り、以前の生成済み.opencode/plugins/*.tsライフサイクルアダプターを再作成しないでください。 - レガシーの生成済みフォルダーは、管理対象マニフェストが含まれている場合に限り削除してください。それ以外の場合は、パス名が適切でないだけのユーザー所有ファイルである可能性があります。
- すっきり見える設定でも、古い生成済みコマンドが残っていると競合する可能性があります。最終的な設定では、必ず
.claude/hooks/generated、.codex/hooks/generated、.devin/hooks/generatedを検索してください。 - プロジェクトのポリシーは
./scripts/agent-stop-checks.shなど、リポジトリが所有するスクリプトにまとめてください。フックアダプターはプロトコルを変換し、検証ロジックを重複させてはいけません。生成されるシェル Stop アダプターのrun_on_code_changes: trueがデフォルトであり、検出されたソース/設定拡張子を使用するため、変更のないターンでは負荷の高いチェックは実行されません。 - Copilot は共有の
hooks/ツリーにアダプターを書き込みません。Copilot のクラウドエージェントはリポジトリにコミットされたファイルしか読み取らないため、生成されたイベントは.github/copilot/hooks/generated/の下に置かれます。両レイヤーが呼び出す、リポジトリが所有するscripts/に共有ポリシーを維持してください。 - 共有の
SessionStartコンテキストスクリプトでは、Claude、Codex、Devin について特に検証済みのhookSpecificOutput.additionalContextJSON 形式を使用できます。この共有形式は、他のイベントやフィールドとの互換性を意味するものではありません。Devin のドキュメント記載の JSON と、過去に発生したプレーンテキストの失敗例については、references/harness-composition.mdを参照してください。 - 終了コードと出力ストリームは別々の契約として扱ってください。終了コードは成功、失敗、またはブロックを制御します。標準エラーは診断や失敗理由用であり、成功ステータスメッセージ用ではありません。正常な処理における通常のスキップでは、ハーネスプロトコルで許可されている場合にのみ標準出力に書き込み、それ以外は出力を控えてください。
- Froggy の
isMainSession条件は、OpenCode フックでメインセッションをフィルタリングします。子/サブエージェントのセッションをスキップする必要があるセッションのライフサイクルフックで使用してください。 - 管理対象マニフェストには、スキャフォールドスキルの来歴、プラン/テンプレートのハッシュ、選択されたハーネス、検出されたハーネス、選択元、管理対象ファイルのハッシュが記録されます。再実行時にはこれらのスナップショットを使って、変更されていない管理対象アダプターを更新し、ユーザーが変更したファイルは維持してください。
- 引数なしの
/scaffold-hooks呼び出しは慎重に動作します。対応するフックの対象が検出された場合は、その検出された対象だけを更新してください。ユーザーから明示的に求められない限り、他のハーネスに対象を拡大しないでください。
フックの可視性マトリクス
ハーネスの TUI にフックの動作が表示されるかどうかは、ハーネスによって異なります。ユーザーが無反応を失敗と誤解しないよう、スキャフォールディングの段階で期待値を設定してください。
| ハーネス | TUI でフックの実行を表示 | フックの確認方法 |
|---|---|---|
| Claude Code | 一部(エラー、詳細モード) | /hooks、トランスクリプト |
| Codex CLI | はい(「Running SessionStart hook」、フックのコンテキストをインライン表示) | インライン表示 |
| Devin CLI | いいえ(成功時も無表示。v2026.5.26-8 時点で systemMessage は表示されません) | /hooks、CLI ログ、トランスクリプト JSON、エージェントに尋ねる |
| OpenCode | プラグインによって定義 | プラグインログ |
| GitHub Copilot | クラウドエージェント:セッションログ、CLI:環境によって異なる | セッションログ、.github/copilot/hooks/generated/ の出力 |
メンテナー向けの段階的な仕様乖離チェック
記録されたバージョンと日付は、検証の基準として扱い、常時適用される実行要件とは見なさないでください。不確かな仕様や変更中の仕様については、関連する公式ドキュメントを確認し、必要に応じて、インストール済みリリースに対応するソースやスキーマの証拠も確認してください。main ブランチには、未リリースの動作が記載されている場合があります。検証済みの対象範囲内の変更で更新が必要にならない限り、決定論的なピン留めを維持してください。
証拠から古いガイダンスが判明した場合は、該当箇所、現在の公式ソースと適用されるバージョンまたは日付、修正案、回帰チェックを記録してください。インストール済みのスキルを黙って編集するのではなく、更新を提案してください。そのメンテナンスが対象範囲内にある場合にのみ正規パッケージを編集し、その後、汎用的なオーケストレーションを変更する前に、影響を受けるマニフェスト、参照、ジェネレーター、テンプレート、バリデーター、テストを整合させてください。未対応の仕様乖離については、同梱のヘルパーがすでに実装していると主張せず、その旨を報告してください。文言のみの変更や、把握済みのローカル修正に、ライブドキュメント全体の確認は不要です。
信頼状態と実効的な機能状態は早い段階で確認しますが、有効化が未解決の間も、独立した読み取り専用の診断は可能にしてください。信頼状態、ユーザー設定やグローバル設定、ポリシーを変更する前に許可を得てください。スキャフォールドを有効に見せるために、これらのゲートを回避してはいけません。