Mod API リファレンス

開発・検証・配布

出典: Claude Code 2.1.294 が書き出す型定義 Early access:リリースごとに変更される可能性あり ← 私家版 Claude Mods まとめ

validate と型チェック

claude plugin validate <mod のフォルダ>    # manifest とソースを読み、Claude Code 本体が拒否する箇所を報告する
tsc -p <mod のフォルダ>                    # 一度読み込まれた mod には tsconfig が配置されている
claude plugin test <mod のフォルダ>        # *.test.ts を実行する
claude --debug                             # 失敗したフックや拒否された結果をすべてログに出力する

validate は、モジュールがフックするイベント、呼び出す $ のメソッド、使用する $.state のキーと環境変数名、拒否できるイベントのフックに .catch があるかどうかを一覧にします。読み込まれた mod のフォルダには、.claude-plugin/types/ に次の型定義が配置されます: claude-code/index.d.ts(API)、claude-code-tools/index.d.ts(組み込みツール。e.tool === "Bash" と書くと e の型が絞り込まれる)、claude-code-mcp/index.d.ts(接続中の MCP ツール)、依存プラグインの型定義、tsconfig.json。これらの型定義は Claude Code 本体が生成するもので、手で編集するものではありません。

テスト(claude-code/testing)

claude plugin test は、フックと同じ実行環境(ファイルシステム、ネットワーク、プロセスは使えない)で *.test.ts と *.test.tsx を実行します。テスト対象のプラグインは、Claude Code 本体のホストによってフォルダから読み込まれます。

import { test, expect, mock } from 'claude-code/testing'

test('Edit で .env への書き込みを拒否する', async ($, on) => {
  const r = await $.tool.call({ tool: 'Edit', file_path: '.env', old_string: 'a', new_string: 'b' })
  expect(r.deny).toBeDefined()
})

test('どの表示環境でも帯を描画できる', async $ => {
  for (const surface of ['terminal', 'desktop'] as const) {
    const ui = await $.ui.mount({ plugin: 'turn-band', surface, component: 'AbovePrompt', props: { /* … */ } })
    await ui.press({ key: 'hide' })
    await ui.unmount()
  }
})
  • test(name, async ($, on) => …) の $ は Claude Code 本体のもので、on で登録したフックはテスト対象のプラグインより内側(Claude Code 本体の位置)に入る。
  • test(name, { options }, body) と書くと、userConfig の値を指定できる。
  • mock の clock、store、env はメモリ上で動作する。mock.session(on) を使うと、追加された行を読み出せる。
  • $.ui.mount では、表示環境を必ず指定する。find、press、input、key、post で操作し、await の直後に検証してよい。
  • describe、expect、tier も使える。

読み込み方

方法説明
claude --plugin-dir <folder>そのセッションに限り、ディスク上のフォルダからプラグインを読み込む(複数回指定できる)。対話セッションではフォルダを監視し、ファイルを保存するとリロードする。
CLAUDE_CODE_PLUGIN_DIRSコマンドラインのフラグを渡せない環境(デスクトップアプリ、SDK)で使う。パス区切り文字で区切って複数指定できる。プロセスの環境変数か、~/.claude/settings.json の env で設定する(プロジェクトの設定では指定できない)。
CLAUDE_CODE_PLUGIN_DIR_WATCH=1長時間動作するヘッドレスセッションでも、フォルダを監視する。
フォルダを marketplace にするclaude plugin marketplace add <folder> で追加し、エントリの source が相対パスの場合は、インストール時のコピーではなくフォルダそのものを読み込む。編集後は /reload-plugins を実行する。

リロードとは、モジュールの読み直しのことです。register と session.start がもう一度実行され、モジュール変数とタイマーは破棄されます。$.state と $.store はホスト側で管理されているため、リロード後も保持されます。ターンの実行中に保存したファイルは、ターンの終了時にまとめて1回だけリロードされます。userConfig の値は settings の pluginConfigs に、プラグイン名をキーとして保存されます。秘密情報でないフィールドは /config の項目としても表示されます(options を列挙した string 型のフィールドは選択式になります)。

配布

mod のリポジトリに .claude-plugin/marketplace.json を1つ置くと、そのリポジトリが marketplace になります。

{
  "name": "<marketplace>",
  "owner": { "name": "<author>" },
  "plugins": [{ "name": "<mod>", "source": "./" }]
}

利用者は、ターミナルのセッションで次のコマンドを実行するだけでインストールできます。README のインストール手順にも、このコマンドを記載します。

/plugin install <mod> --marketplace <owner>/<repo>

実行すると、Add marketplace? に y で答え、スコープを選択し(先頭は user)、userConfig がある場合は設定画面で値を入力します。最後に Installed <mod>. Plugin is now active. と表示されます。フックモジュールだけで構成された mod は、リロードせずにその場で有効になります。デスクトップアプリの Code タブではこのコマンドは使えませんが、ターミナルから user スコープでインストールした mod はそこでも読み込まれ、表示環境 desktop 向けに描画されます。

絞り込みの条件に一致する行がありません。