Claude Codeのhookifyで失敗パターンからhookを自動生成する
hookifyは会話の失敗や明示した指示から、.claude/hookify.*.local.mdの規則を作るプラグインです。導入から規則の書き方、手書きhooksとの使い分けまでまとめます。
hookifyは、Claude Codeのhookをmarkdownファイル1枚で定義できるプラグインです。settings.jsonやhooks.jsonを編集せず、/hookifyに「rm -rfを使うときは警告して」と伝えるだけで.claude/hookify.warn-rm.local.mdのような規則ファイルが作られます。規則は次のツール呼び出しから効きます。Claude Codeを再起動する必要はありません。
本記事は、導入から最初の規則づくり、会話の失敗からの規則生成、規則の書式、運用上の注意までを順に扱います。手書きのhooks.jsonとの違いは、途中の比較表で示します。
hookifyとは何か
hookifyは、Anthropicのclaude-plugins-officialリポジトリにあるプラグインです。READMEの説明は「会話のパターンの分析、または明示的な指示から、望ましくない振る舞いを防ぐカスタムhookを簡単に作れる」というものです。
通常のhookは、settings.jsonにイベント名・matcher・コマンドを書き、必要ならシェルスクリプトも用意します。hookifyは、この部分を「パターンと表示メッセージ」だけを書いたmarkdownに置き換えます。特徴は次の5点です。
- 会話を分析して、望ましくない振る舞いを自動で見つける
- YAMLフロントマター付きのmarkdownで設定する
- 正規表現でパターンを照合する
- コードを書かず、避けたい振る舞いを説明するだけで済む
- 再起動なしで有効化・無効化できる
hookの仕組み自体はClaude Code本体のものです。hookifyはその上に載った規則エンジンで、規則の照合にはPython 3.7以上が要ります(標準ライブラリのみで動き、外部依存はありません)。
導入の手順
公式マーケットプレイスのプラグインは、/plugin install <名前>@claude-plugins-officialで入れます。公式ドキュメントはこの手順をcommit-commandsで例示しており、別のプラグインでも名前を差し替えるだけだと説明しています。hookifyも同じ形です。
/plugin install hookify@claude-plugins-officialセッション中の/plugin installは、その場で入れずに/pluginパネルを詳細表示で開きます。スコープを選んで確定すると、有効化には/reload-pluginsが要ると表示されることがあります。プラグインはインストール後の次回起動か、/reload-pluginsの実行で読み込まれます。
なお「再起動不要」が指すのは規則ファイルの追加・変更です。プラグインそのものを入れた直後は、この読み込みの手順が別に要ります。ここを混同すると「/hookifyが見つからない」で止まります。
Python 3が使えるかは、先に確認しておくと安全です。importエラーが出たときの確認項目にもpython3 --versionが挙がっています。
python3 --version最初の規則を作って確かめる
最初の規則づくりは2手です。まず/hookifyに避けたい振る舞いを書きます。
/hookify Warn me when I use rm -rf commandsこの指示は分析され、.claude/hookify.warn-rm.local.mdが作られます。次に、規則に当たるコマンドを実際に頼みます。
Run rm -rf /tmp/test警告メッセージがすぐに表示されます。規則は「次のツール使用」から有効で、再起動は要りません。例はすべて英語の指示です。生成された規則ファイルは、必ず中身を開いてpatternが意図どおりか目で確認してください。
規則ファイルは、プラグインのディレクトリではなくプロジェクトルートの.claude/に置かれます。ここを取り違えると規則が読み込まれません。
会話の失敗パターンから規則を作る
hookifyの独自性は、引数なしの/hookifyにあります。
/hookify引数を付けない場合は、直近の会話を分析して、あなたが訂正した振る舞いやいらだった振る舞いを見つけます。たとえば、次のような場面が当てはまります。
- Claudeが
console.logを残したままコミットしようとして、あなたが止めた .envを書き換えようとして、あなたが取り消した- テストを走らせずに「完了しました」と言われ、やり直させた
こうした訂正が会話に残っていると、そこから規則の候補が組み立てられます。出てきた規則を採るかどうかは、人間が判断する工程です。
使い方のコツは、失敗の直後に実行することです。訂正のやりとりが会話に新しいうちなら、分析の材料が揃っています。セッションが長く伸びたあとで実行すると、どの訂正を指しているのかが曖昧になります。同じ失敗を一度繰り返してから規則にする、という運用でもかまいません。
規則の元になる再発しやすい失敗の類型は、Claude Codeのアンチパターン5選にまとめています。何を規則にするか迷ったら、そこから拾うと決めやすくなります。
規則ファイルの書式
規則は、YAMLフロントマターとmarkdown本文の組み合わせです。本文は、規則に当たったときにClaudeへ見せるメッセージになります。
単一パターンの規則
.claude/hookify.dangerous-rm.local.mdの例です(READMEの例に沿った形)。
---
name: block-dangerous-rm
enabled: true
event: bash
pattern: rm\s+-rf
action: block
---
⚠️ **Dangerous rm command detected!**
This command could delete important files. Please:
- Verify the path is correct
- Consider using a safer approach
- Make sure you have backups主なフィールドは次のとおりです。
| フィールド | 意味 |
|---|---|
name | 意味規則の名前 |
enabled | 意味trueで有効、falseで無効 |
event | 意味どのイベントに反応するか |
pattern | 意味照合する正規表現(Pythonの正規表現構文) |
action | 意味warn(警告して続行・既定)かblock |
action: blockは、PreToolUse系のイベントでは操作の実行を止めます。stopイベントではセッションの停止を止めます。warnは警告を見せるだけで、操作は通ります。
イベントの種類
eventには5つの値があります。
bash: Bashツールのコマンドfile: Edit・Write・MultiEditツールstop: Claudeが止まろうとしたとき(完了チェック用)prompt: ユーザーのプロンプト送信時all: すべてのイベント
allは全イベントで照合が走るので重くなります。bashやfileに絞るのが基本です。
複数条件の規則
patternの代わりにconditionsを書くと、複数のフィールドを同時に検査できます。
---
name: api-key-in-typescript
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.tsx?$
- field: new_text
operator: regex_match
pattern: (API_KEY|SECRET|TOKEN)\s*=\s*["']
---
🔐 **Hardcoded credential in TypeScript!**
Use environment variables instead of hardcoded values.すべての条件が一致したときだけ、規則が発動します。照合できるフィールドはイベントごとに決まっています。
| イベント | 使えるフィールド |
|---|---|
| bash | 使えるフィールドcommand |
| file | 使えるフィールドfile_path、new_text(Edit・Write)、old_text(Editのみ)、content(Writeのみ) |
| prompt | 使えるフィールドuser_prompt |
| stop | 使えるフィールドtranscript(セッションの記録) |
operatorはregex_match、contains、equals、not_contains、starts_with、ends_withの6種類です。最もよく使うのはregex_matchです。
パターンの書き方
YAMLの中では、パターンをクォートせずに書くのが基本です。エスケープの混乱を避けられます。空白は\s、ドットは\.で書き、OR条件は(foo|bar)にします。
rm\s+-rf:rm -rf /tmpに一致chmod\s+777:chmod 777 file.txtに一致\.env$:.envやconfig/.envのように、末尾が.envのパスに一致($で末尾に固定するので.env.localには一致しません。含めたいなら\.env(\..+)?$)console\.log\(:console.log("test")に一致
パターンがうまく当たらないときは、規則に書く前にPythonで試せます。
python3 -c "import re; print(re.search(r'rm\s+-rf', 'rm -rf /tmp'))"一致すればマッチオブジェクトが、しなければNoneが出ます。
完了前にテストを走らせる規則
stopイベントのblockは、Claudeが止まる前にやってほしい作業を強制するのに使えます。次の例は、会話の記録にテストコマンドが出てこなければ止まらせる規則です。
---
name: require-tests-run
enabled: false
event: stop
action: block
conditions:
- field: transcript
operator: not_contains
pattern: npm test|pytest|cargo test
---
**Tests not detected in transcript!**
Before stopping, please run tests to verify your changes work correctly.この規則はenabled: falseで載せてあり、厳格に強制したいときだけ有効にします。手書きのStop hookで同じことをする流れは、Claude Codeでテスト駆動開発(TDD)を回す手順で扱っています。
注意点が1つあります。公式のhooksガイドによると、Claude CodeはStop hookが連続8回ブロックし、その間にClaudeのツール呼び出しが挟まらないと、hookを上書きして止まらせます。hookify経由のstop規則がこの上限にどう従うかは、READMEに記載がありません。規則が止まらずに空回りするときは、この上限が働いている可能性を考えます。
規則の管理
規則は普通のファイルなので、管理も単純です。
- 一時的に止める:
.local.mdを開き、enabled: falseにする - 再開する:
enabled: trueに戻す - 削除する: ファイルを消す(
rm .claude/hookify.my-rule.local.md) - 一覧を見る:
/hookify:list - 対話的に有効・無効を切り替える:
/hookify:configure - ヘルプを見る:
/hookify:help
チームで共有するかどうかは、規則ファイルをバージョン管理に入れるかで決まります。共有する規則は、通常のコードと同じくレビューを通してから入れる形が扱いやすくなります。
手書きのhooksとどう使い分けるか
hookifyの規則は、settings.jsonのhooksに直接書くhookの代わりになるものではありません。向き不向きがあります。
| 観点 | hookify | 手書きのhooks |
|---|---|---|
| 設定の形 | hookifymarkdown + YAMLフロントマター | 手書きのhookssettings.jsonのJSON + スクリプト |
| 照合 | hookify正規表現・文字列比較 | 手書きのhooks任意のスクリプトで判定 |
| 置き場所 | hookify.claude/hookify.*.local.md | 手書きのhooks.claude/settings.jsonなど |
| 向く用途 | hookify禁止コマンド、危険なパスやコードの検知 | 手書きのhooks外部コマンド連携、整形、JSONでの細かい制御 |
規則が「このパターンに当たったら止める・警告する」で済むなら、hookifyのほうが早く書けます。反対に、ファイルを整形する、外部APIを呼ぶ、入力を書き換えるといった処理は、スクリプトを持てる手書きのhookの領分です。PreToolUseで許可・拒否・改変の決定を細かく返す方法はPreToolUse hookでツール実行前に許可・拒否・改変するに、レシピ集はhooks活用レシピ集にあります。
手書きの側の代表例として、公式のhooksガイドには、保護対象のファイルへの編集を止めるスクリプトがあります。編集対象のパスを.envなどの保護パターンと照合し、一致したら標準エラーにメッセージを出してexit 2で終了します。hookifyなら、同じ用途が次の規則で足ります。
---
name: protect-env-files
enabled: true
event: file
action: block
conditions:
- field: file_path
operator: regex_match
pattern: \.env$|package-lock\.json
---
🛑 **Protected file edit blocked.**
Do not modify this file. Ask the user before changing it.パターンは.envで終わるパスか、package-lock.jsonを含むパスに当たります。スクリプトもchmod +xも、フックの登録もいりません。一方で、複雑な判定や、ブロック理由に実行結果を含めるような処理は手書きが向きます。
既存の手書きhooksとの併用では、置き場所が別です。hookifyは.claude/hookify.*.local.md、手書きはsettings.jsonに書きます。同じ操作に両方がかかったときの競合の扱いはREADMEに記載がないので、実機で動きを確かめてください。
運用で気をつけること
- 規則は少なく絞る: 動作が遅いと感じたら、規則の数を限り、パターンを単純にします。
blockは慎重に: 広すぎる正規表現のblockは、正当な作業まで止めます。まずwarnで運用し、誤検知がないことを確かめてからblockに上げます。- 規則が効かないとき:
.claude/がプロジェクトルートにあるか、enabled: trueか、パターンが単体で当たるか、/hookify:listで読み込まれているかを順に見ます。 - 生成された規則を鵜呑みにしない: 自動生成された
patternは、広すぎたり狭すぎたりします。
READMEの「今後の拡張」には、重大度レベル、規則のテンプレート集、対話的なパターンビルダー、hookのテスト用ツール、JSON形式への対応が挙がっています。パターンビルダーやhookのテスト用ツールが今後の項目に並んでいるので、READMEの範囲では、規則を事前に試す専用の仕組みは説明されていません。上のPythonでの確認と、warnでの試運転で代わりにします。
まとめ
禁止コマンドや危険なパス、書いてはいけないコードの検知で足りるなら、hookifyが最短です。失敗した直後に/hookifyを打てば、その失敗を止める規則の下書きができます。外部コマンドの呼び出し、整形、入力の書き換え、JSONでの細かい制御が要る処理は、手書きのhooksに残してください。まずwarnで試し、誤検知がないと確かめてからblockに上げる運用が安全です。