- Claude に書かせる: Claude Code セッションで何をしたいかを説明します
- 自分で書く: チュートリアルに従ってmod のコードがどのように機能するかを学びます。Node.js、バンドラー、またはビルドステップは必要ありません。Claude Code は
.jsファイルと.tsファイルを直接読み込むためです。
Mod には Claude Code v2.1.287 以降が必要です。シェルで
claude --version を実行してチェックしてください。mod がロードできるかどうかを確認するには、mod がロードできるかどうかを確認するを参照してください。Claude に mod を書かせる
インタラクティブな Claude Code セッションで、作成したい mod について説明すると、Claude がそれを書きます。Claude はplugin-authoring という組み込みスキルから動作します。このスキルは、mod をどこに書くか、バージョンにどのイベントとメソッドがあるか、mod がどのようにロードされるかを Claude に伝えます。Claude は mod を要求するときにスキルをロードできます。または、Claude Code プロンプトで /plugin-authoring を実行して自分でロードできます。
mod は承認すると実行されます。ただし、mod Claude が書いたものがロードできないセッションでは実行されません。
1
mod について説明する
自分の言葉で mod を要求します。たとえば、
make a mod that shows the current git branch above the prompt のように。Claude は、セッションの mods フォルダ内の独自のディレクトリに mod を書きます。これは ~/.claude/dev-mods/ の後にセッションの ID が続きます。mod の完全なパスは ~/.claude/dev-mods/3f2a9c1e-5b7d-4e8a-9c21-6d0f4b8a7e13/git-branch/ のようになります。default および acceptEdits 権限モードでは、~/.claude は保護されたパスであるため、Claude Code は Claude が mod の各ファイルを作成する前に確認を求めます。各ファイルが表示されたら承認してください。2
mod を承認する
Claude が最初のファイルを保存すると、Claude Code はセッションのホットリロードを有効にするかどうかを尋ねます。ホットリロードは、このセッションで Claude が書いた mod を実行し、後で変更されるたびにそれを取得します。次のいずれかの答えを選択してください。
- このセッションで有効にする: セッションの mods フォルダ内の mod はターンの終了時にロードされ、それらを変更するターンの終了時に再ロードされます。答えはセッション全体に対して有効です。再開後も含まれます。
- 今はしない: 今のところ何もロードされません。ファイルは Claude が書いた場所に留まり、mod は次回そのセッションが開始されるときにロードされます。mod がロードされないようにするには、そのディレクトリを削除してください。
3
mod がロードされたことを確認する
Claude Code プロンプトで
/plugin を実行し、Tab キーを押して Installed タブが選択されるまで続けます。mod が一覧表示され、そこでオフにできます。4
mod を試す
要求したものを使用します。例のプロンプトの場合、現在のブランチ名がプロンプトボックスの上に表示されます。mod が期待したことをしない場合は、Claude に何を変更するかを伝えてください。mod は、そのファイルを変更するターンの終了時に再ロードされるため、Claude が終了するとすぐに変更を試すことができます。
他のセッションで mod を使用する
Claude が書いた mod は、それを作成したセッションでのみロードされます。Claude Code は、そのセッションの mods フォルダをcleanupPeriodDays より古くなると削除します。mod を保持するには、mods フォルダからそのディレクトリを ~/mods/git-branch などの自分の場所にコピーしてください。次に、ロード方法を選択します。
- 開始するセッションで: シェルで
claude --plugin-dir ~/mods/git-branchを実行します - 他の人向け: マーケットプレイスに追加して、インストールできるようにします
mod Claude が書いたものがロードできないセッション
Claude が書いた mod は、信頼できるワークスペースで承認後にのみロードされます。このワークスペースでは mod の実行が許可されています。これらのセッションではロードされません。- 誰も承認する人がいない:
claude -p実行やdontAskモードのように、セッションはプロンプトを表示できません - ワークスペースが信頼されていない: ディレクトリの信頼プロンプトを受け入れていません
- Mod が停止している:
--safe-modeまたは--bareで開始した、disableAllHooksを設定した、または組織の管理設定がそれをブロックしている
自分で mod を書く
このチュートリアルでは、first-mod という名前の mod を構築します。この mod は Claude が行うツール呼び出しをカウントし、Claude が動作している間にスピナーの横にカウントを表示し、/tally コマンドを追加して印刷します。その後、Claude Code がモジュールの横に書いた型宣言を読み、claude plugin validate を実行します。これらは、バージョンが提供するイベントとメソッド、および Claude Code がコードから読み取るものを示します。
この記録は完成した mod を示しています。スピナーはツール呼び出しをカウントし、/tally はカウントを印刷し、セッションの実行中にコードの編集が有効になります。
plugin.json: プラグインのマニフェストhooks.json: コードファイルを指しますregister.js: コード。hooks module と呼ばれます
1
プラグインディレクトリを作成する
ファイルを保持する 2 つのディレクトリを作成します。
- Bash or Zsh
- PowerShell
2
マニフェストを書く
mod はプラグインで、mod にはマニフェストが必要です。この mod のマニフェストには特別なフィールドはありません。これを
first-mod/.claude-plugin/plugin.json として保存します。first-mod/.claude-plugin/plugin.json
3
Claude Code にコードの場所を伝える
Claude Code がプラグインをロードするとき、プラグインの
hooks/hooks.json を読みます。そのファイルの modules キーはコードへのパスを提供し、それを持つことがプラグインを mod にします。1 つのパスをリストします。これは hooks.json に相対的です。ここでは、次のステップで書く register.js を指します。これを first-mod/hooks/hooks.json として保存します。first-mod/hooks/hooks.json
4
コードを書く
このファイルは mod のコード。hooks module と呼ばれます。mod がロードされると、Claude Code はファイルがエクスポートする ファイルは
register 関数を呼び出し、on という関数を渡します。on への各呼び出しは、イベントハンドラー(hook と呼ばれる)をそれが名前を付けるイベントに登録します。これを first-mod/hooks/register.js として保存します。first-mod/hooks/register.js
calls にカウントを保持し、4 つの hook を登録します。session.startはセッションが開始されるときに実行されます。最初のプロンプトの前に、mod が再ロードされるたびに実行されます。Claude Code に/tallyコマンドを追加します。tool.callは Claude がツールを使用しようとするたびに実行されます。callsに 1 を追加し、Claude Code にインターフェイスを再度描画するよう要求します。command.runは/tallyを入力するときに実行されます。印刷するテキストを返します。ui.renderは Claude Code がスピナーを描画するたびに実行されます。スピナーの単語の後にカウントを追加します。
5
mod をロードする
--plugin-dir フラグで Claude Code を開始します。これはプラグインディレクトリを 1 つのセッションにロードします。インストールしません。6
mod を試す
Claude に、いくつかのツール呼び出しを必要とするものを実行するよう要求します。たとえば、
list the files here and read the README のように。Claude が動作している間、スピナーの単語の後に、Thinking · tool calls: 2… のように上昇するカウントが続きます。Claude が終了したら、/tally を入力して Enter キーを押します。トランスクリプトは first-mod: Claude has made 2 tool calls since this mod loaded を表示します。独自のカウント付きです。Claude Code はプラグインの名前をコマンドのテキストの前に置きます。インタラクティブセッションなしでコマンドをチェックするには、非インタラクティブモードで実行します。/tally がコマンドリストにない場合、モジュールはロードされませんでした。mod が何もしない理由を見つけるを参照してください。7
セッションの実行中にコードを変更する
セッションを開いたままにします。トランスクリプトの行は
register.js で、ui.render hook の ' · tool calls: ' を ' · tools used: ' に変更して保存します。強調表示された行は変更される行です。first-mod/hooks/register.js
first-mod が再ロードされたことを示し、その hook をリストします。次のスピナーは新しいテキストを使用します。たとえば、Thinking · tools used: 1… のように。例の mod がどのように機能するか
on に渡す各関数は hook で、イベントハンドラーです。Claude Code はすべての hook に同じ 3 つの引数を渡します。
- mods API。
$という名前です。mod が自身の外に到達するために呼び出すことができるすべてのメソッド。$.uiや$.commandなどの名前空間内です - イベント。
eという名前です。ツール呼び出しの名前と引数などのイベントの入力。プレーンデータとして - 次のハンドラー。
nextという名前です。イベントを他の mod に渡し、次に Claude Code 独自の動作に渡す関数。結果を返します
first-mod の hook は、hook ができる 3 つの方法でイベントを処理します。
- 観察:
session.starthook はコマンドを登録し、tool.callhook はコールをカウントして再描画を要求します。どちらもnext(e)を返すため、セッションが開始され、ツールが通常どおり実行されます。 - 回答:
command.runhook は独自の結果を返し、nextを呼び出しません。onへの 2 番目の引数{ command: 'tally' }はフィルターで、matcher と呼ばれます。hook は/tallyに対してのみ実行されます。 - 書き直す:
ui.renderhook はeのコピーでnextを呼び出します。そのsuffixはカウントを保持します。Claude Code は通常のスピナーを描画し、単語の後にテキストを描画します
--plugin-dir でロードされたディレクトリを監視し、ファイルが変更されると hooks module をホットリロードします。各リロードは register を再度実行するため、calls は 0 に戻り、/tally は再度カウントを開始します。リロード全体で値を保持するには、状態を保持するを参照してください。
mod の作業を続ける
mod がロードされたら、Claude に変更させたり、コードをバージョンの型定義と照合したり、Claude Code が見つけたイベントと呼び出しをリストしたり、テストしたりできます。Claude で mod を変更する
既に持っている mod を変更するには、--plugin-dir を mod のディレクトリに向けてセッションを開始します。Claude が書いたものが同じセッションでロードされるようにします。
add a /tally-reset command to this mod that sets the tally back to zero のように。Claude は hooks module を編集し、claude plugin validate を実行し、報告されたものを修正します。--plugin-dir でロードするディレクトリは保護されたパスであるため、default および acceptEdits モードでは、Claude の mod への各編集を承認するよう求められます。保護されたパステーブルは他の権限モードの結果を示します。
Claude がターンの終了時に保存したファイルは、ターンの終了時に再ロードされるため、Claude が終了するとすぐに /tally-reset を試すことができます。
バージョンの型定義を取得する
Claude Code が--plugin-dir に渡すディレクトリから mod をロードまたは再ロードするたびに、または Claude が書いた mod の場合、TypeScript 宣言ファイル(.d.ts で終わる)を mod のディレクトリ内の .claude-plugin/types/ に書き込みます。実行している Claude Code バージョンの正確なイベント、mods API メソッド、および要素について説明しているため、エディターは hook を自動補完および型チェックできます。宣言をオンラインで参照するには、Claude Code リポジトリの mods/types/claude-code.d.ts を読んでください。その最初の行は、それを書いたバージョンに名前を付けます。ディレクトリには次のファイルが含まれます。
mod に独自の
tsconfig.json がない場合、Claude Code は mod のルートに生成されたものを拡張する tsconfig.json を追加します。エディターと tsc -p ./first-mod は、さらにセットアップなしで mod を型チェックできます。
イベントとメソッドはリリース間で変更される可能性があるため、意見が異なる場合は、このページを含むすべてのページよりもこれらのファイルを信頼してください。
claude-code/index.d.ts はビルドの最も完全なリファレンスで、すべての mods API メソッドにコメントと例があります。何かを検索するには、ファイルで名前を検索します。たとえば、'tool.call' のように。
Claude Code がモジュールから読み取るものを確認する
セッションを実行したり、コードを実行したりせずに、Claude Code がモジュールをどのように見るかを確認するには、claude plugin validate を使用します。マニフェストをチェックし、Claude Code が mod をロードするときに hooks module のソースで実行するのと同じ静的分析を実行します。シェルで、mod のディレクトリで実行します。
first-mod の場合、出力には次の行が含まれます。
hooks: 行は、モジュールが hook するイベントをリストします。各イベントは、中括弧内のフィルター付きです。calls: 行は、呼び出すすべての mods API メソッドをリストします。環境変数を読み取るまたは設定するモジュールは、env reads: および env writes: 行も取得します。$.state を使用するモジュールは、state reads: および state writes: を取得します。
hook するつもりだったイベントが最初の行から欠落している場合、Claude Code はその hook も呼び出しません。通常の原因は、イベント名のスペルミスです。コマンドは "tool.calls" is not an event などのエラーとして報告します。
静的分析がすべての hook と呼び出しを見つけることができるように、これらのルールに従ってください。
- 各 mods API 呼び出しを完全に綴ります。
$、名前空間、メソッド。$.store.get('notes')のように。$を同じファイルの最上位で宣言された関数に渡すことができます。loadNotesという名前の関数の場合、calls:行は$.store.get (via loadNotes)を読みます。$をメソッド、hook 内で定義された関数、または別のファイルからインポートした関数に渡すと、検証が失敗します。$.stateが使用するreadおよびupdate関数は、それを取ることができるインポートです。$またはその名前空間の 1 つを変数に割り当てたり、分割したり、計算された名前でインデックスを付けたりしないでください。const ui = $.uiは$.ui is used as a valueで失敗します。 - 各
on呼び出しでイベント名を文字列リテラルとして書きます。'tool.call'のように。変数、または名前のリストのループは、the event name passed to on() is not a string literalで失敗します。 register内で、onという名前の 2 番目の変数またはパラメーターを宣言しないでください。検証は"on" is declared again (shadowed)で失敗します。- プラグインディレクトリ内のファイルからのみインポートします。相対パスで。許可される唯一の裸のインポートは、型といくつかのヘルパーの
claude-codeです。 - ファイルの最上部で
import宣言を使用します。import { name } from './file.js'のように。動的なimport()はa dynamic import(); a hooks module imports its own files with an import declarationで失敗します。 - すべてのファイルを ES モジュールとして書きます。
importを使用し、requireは使用しません。リファレンスは Claude Code がロードするファイル拡張子をリストします。
mod をテストする
mod の自動テストを書き、シェルからclaude plugin test で実行できます。セッション、サインイン、またはネットワークはありません。テストは hook が処理するイベントを発生させ、hook が何をしたかをチェックします。
このテストは 2 つのツール呼び出しを発生させ、/tally を実行し、hook が両方をカウントしたことをチェックします。これを first-mod/tests/first-mod.test.ts として保存します。
first-mod/tests/first-mod.test.ts
first-mod ディレクトリからテストを実行します。
mod を共有する
mod はプラグインであるため、マニフェストでバージョン管理し、人々は/plugin コマンドでインストールおよび更新します。他の人に提供するには、マーケットプレイスに追加してください。
その前に、プラグインの name をチェックしてください。claude plugin validate は、Anthropic 独自のように見える名前で失敗します。たとえば、claude- で始まる名前。イベントとメソッドはリリース間で変更される可能性があるため、README はテストした Claude Code バージョンを示す場所です。
インストールされたコピーに対してではなく、--plugin-dir を使用してディレクトリに対して開発を続けます。Claude Code はインストールされたプラグインをバージョンでキャッシュするため、バージョンを上げてもう一度インストールするまで、編集はインストールされたコピーに到達しません。
次のステップ
- インターフェイスに描画する: ペインを開き、プロンプトの上に描画し、ボタンとテキストフィールドを追加します
- イベントに反応する: ツール呼び出し、プロンプト、ターンをフック化します
- mods API を使用する: コマンドとツールを追加し、モデルを呼び出し、タイマーで作業を実行します
- mod をテストする: Claude Code が答えるものをスタブ化し、タイマーと描画をテストします
- mod をトラブルシューティングする: mod が何もしない理由とデバッグログ
- 組み込み mod のソースを読む: 完全なプラグイン。各 hooks module とテスト付き