すでに設定ファイルベースのPreToolUse/PostToolUseフックの書き方を知っていますが、特にModsを学ぶ必要はありますか?
必ずしもそうではない。両者は異なるレイヤーの問題を解決する:あなたのニーズが「特定のツール呼び出しの前後でチェックを行い、特定の動作をブロックまたは記録する」ことであれば、設定ファイルベースのフックシステムで完全に十分であり、アーキテクチャはよりシンプルで、JavaScript/TypeScriptを書く必要もない。
Modsを学ぶ価値が本当に出てくるのは、自分のニーズが設定ファイルベースのフックではそもそも触れられないものだと気づいたときだ——例えば、画面上に状態を継続的に表示したい場合(burn-meterのようなリアルタイムの支出バー)、あるいは完全な対話ターンを待たずに即座に実行されるスラッシュコマンドが必要な場合。こうしたニーズはインターフェースのレンダリングとリアルタイムのイベント書き換えの領域に属し、設定ファイルベースのフックはプロセス外部で動作するため、アーキテクチャ上そもそもこれらを見ることができない。Claude Codeプロセスの内部で動作するModsだけがそこに到達できる。
Mod内のobserve、rewrite、answerの3つの挙動は、実務上どう選べばいいですか?
選択のロジックは、イベントを先に進めたいかどうか、そしてその内容を変更する必要があるかどうかにかかっている。あるイベントが発生したことを単に「知りたい」だけなら(例えばツール呼び出しが発生した時刻を記録する)、observeを使う——nextを呼び出し、そのまま通過させ、以降の挙動には何の影響も与えない。リスクは最も低い。
イベント自体の内容を変更したいが、それでも通常のフローを継続させたい場合(例えばプロンプトが送信される前に追加のコンテキストを自動的に付加する)は、rewriteを使う——修正済みのコピーを伴ってnextを呼び出す。直接横取りして、イベントがそれ以上先に進まないようにしたい場合(例えば危険な操作を検知して、即座に拒否結果を返す)は、answerを使う——nextを呼び出さず、その場でチェーンを停止させる。この3つはリスクと影響範囲がこの順で増大していくため、最初のModはobserveから練習を始め、イベントサブスクリプションのロジックに問題がないことを確認してから、rewrite、answerへと進めることが推奨される。
ドキュメントには、例外をスローするhookは「静かに失敗する」と書かれていますが、これは実務上どんなリスクを生みますか?
それは、あなたのModがしばらく壊れたままになっていても、画面上に明確な警告が一切出ないということを意味する——失敗はトランスクリプトに目立たない一行を残すだけで、エラーポップアップや作業の中断は起きない。あなたのModがセキュリティや監視用途(危険なコマンドの検知など)を担当している場合、この「静かな失敗」は特に危険だ。保護がまだ機能していると思い込んでいても、実際にはすでに応答を停止している可能性があるからだ。
実務上の対処法は、テストを必須の手順として扱い、選択肢の一つとしないことだ:Modのhookロジックを変更するたびに、そのhookを発火させるはずの状況を意図的に引き起こし、正しく反応しているかを自分で確認する——エラーメッセージが見えなかったからすべて正常だと仮定しないことだ。
作成したModが再読み込みされると、画面上の状態が消えてしまいます。どこが間違っているのでしょうか?
最も可能性が高い原因は、まさにドキュメントが特に指摘している落とし穴だ:保持したい値をモジュール自身の変数に保存し、セッションの状態ストアに保存していないことだ。Claude Codeはホットリロードをサポートしており、Modのコードを編集してもセッション全体を再起動せずに変更を適用できるが、ホットリロードはモジュール自身の変数をリセットしてしまう。あなたの状態が通常のJavaScript変数に保存されている場合、リロードが起きた瞬間にそのデータは消えてしまう。
修正方法は、エンジンが提供する状態保存メカニズムに切り替え、持続させたいデータ(burn-meterの累積支出、code-petの現在の状態など)を、モジュールのトップレベルの通常変数として宣言するのではなく、このメカニズムを通じて読み書きすることだ。これにより、コードを繰り返し編集してホットリロードを何度発生させても、画面に表示される情報はリセットされない。
Claude Code v2.1.287(2026年10月1日リリース)は、Modsと呼ばれる新しい拡張レイヤーを導入した。公式の説明「plugins may now modify deeper behavior」は、プラグインシステムの通常のアップグレードのように聞こえるが、実際に分解してみると、Modsは通常のプラグイン、さらには既存の設定ファイルベースのフックシステムとも、根本的に異なる層で動作していることがわかる。
技術解説によると、Modは本質的に通常のClaude Codeプラグインに、hooksモジュールと呼ばれる追加ファイルを1つ加えたものであり、このファイルはregisterという名前の関数をエクスポートする。完全なModは3つのコアファイルで構成される:プラグインマニフェスト、hooksモジュールを指すhooks.json、そしてモジュール本体だ。注目すべきは、Modsがビルドステップを一切必要としないことだ——Claude Codeは.jsや.tsファイルを直接読み込む。
最も重要な違いは、どこで実行されるかだ。既存の設定ファイルベースのフックシステム(settings.jsonで設定するPreToolUse、PostToolUseなど)は、Claude Codeプロセスの外部でシェルコマンド、HTTPリクエスト、またはプロンプトを実行し、ライフサイクルイベントに応答する。それに対してModsは、Claude Codeプロセスの内部で直接動作し、プロンプト内容、ツール呼び出し、さらにはインターフェースのレンダリングにまで直接アクセスできる——これらは、設定ファイルベースのフックシステムがアーキテクチャ上そもそも到達できない領域だ。
Modは、固定された3引数パターン——mods API、イベント自体、そしてnext関数——に従うハンドラを通じて、名前付きイベントをサブスクライブする。ハンドラは連鎖し、3つのうち1つを行える:観察(nextを呼び出し、イベントをそのまま通過させる)、書き換え(修正済みのコピーを伴ってnextを呼び出し、以降の挙動に影響を与える)、応答(nextを呼び出さずに直接結果を返し、その場でチェーンを停止させる)。現在、tool.call、prompt.submit、turn.step、ui.renderを含む7つのイベントカテゴリがカバーされている。
公式ドキュメントは機能の境界について率直に述べている:「paneを描画できる、Claudeのターンを経由せずに即座に実行されるスラッシュコマンドを追加できる、あるいは飛行中のイベントを書き換えられるのは、Modだけだ」——この3つはすべて、外部拡張機能がアーキテクチャ上絶対にできないことだ。
1つ目はcode-pet:モデル選択器の横にピクセル風の生物を表示し、ツール呼び出しとテスト結果にフックする——テスト失敗後は「病気」状態になり、破壊的なコマンドの実行時には「パニック」する。この視覚的インジケーターはステータスラインに存在し、Modが単純なモジュール変数ではなくセッションレベルの状態を追跡する必要がある。
2つ目はinbox-alerts:claude.aiのコネクタを通じてGmail、Slack、カレンダーをポーリングし、新しい項目をトースト通知と常駐paneとして表示する——トーストは一時的なもので、paneはそのまま残り、ターミナルを離れずに新しい作業が入ってきたことを確認できる。
3つ目はburn-meter:専用のpaneで、セッションの支出を示す成長する炎のバー、リセット時刻付きのプラン上限バー、そして支出額をハンバーガーとチーズバーガーの個数に換算して表示する。このpaneは継続的にレンダリングされるため、Modはローカルに保存するのではなくエンジンから状態を読み取る必要がある。
1つ目の落とし穴はエラー処理に関するものだ:例外をスローするhookは「静かに失敗」し、トランスクリプトに目立たない一行を残すだけで、明確なエラーメッセージは表示されない——これは、Modを書く際にテストが特に重要であることを意味する。失敗が自ら積極的に知らせてくれるわけではないからだ。
2つ目の落とし穴は状態の保存方法に関するものだ:よくある間違いは、保持したい値をセッションの状態ストアではなくモジュール変数に保存することだ——ホットリロードはモジュール自身の変数をリセットしてしまうからだ。burn-meterのような継続的にレンダリングされるpaneは、エンジンが提供する状態保存メカニズムを使わなければならない。そうしないと、コードが編集され再読み込みされた瞬間に画面上の情報が消えてしまう。
現在のニーズが単にツール呼び出しの前後でチェックを行い、危険なコマンドをブロックすることだけなら、設定ファイルベースのフックシステム(PreToolUse/PostToolUse)で完全に十分であり、Modを書く必要はない。しかし、画面レベルのもの——状態を継続的に表示するpane、完全な対話ターンを経ずに実行できるスラッシュコマンド、あるいはイベントの内容をリアルタイムで書き換える必要がある効果——を求めているなら、これらのニーズはModsという拡張レイヤーでしか満たせない。これこそが、公式が通常のプラグインシステムとは別の名前をあえて与えた理由だ。