メインコンテンツまでスキップ

Mod: プロセス内拡張

上級

mod は、Claude Code が 自身のプロセス内で 呼び出す JavaScript または TypeScript の関数を提供するプラグインです。フックが JSON ペイロードを受け取って終了コードで答えるシェルコマンドであるのに対し、mod のハンドラは Claude Code 自身の振る舞いの手前にある ミドルウェアチェーンに座ります。イベントを監視することも、書き換えることも、組み込みの振る舞いが一切走らないように自分で応答することもできます。

最後の能力こそが要点です。Claude Code 自身の機能のいくつかは、いまや mod です。/diff と AGENTS.md の読み込みは cc-plugin-diff と cc-plugin-agents-md として出荷されており、ソースは Claude Code リポジトリの mods/ ディレクトリにあります。ベンダーが組み込みコマンドを mod で置き換えられるなら、あなたにもできます。

What you'll learn
  • ミドルウェアモデル: イベントを観測する、書き換える、あるいは応答する — そして next(e) がエンジン自身にまで届く理由
  • mod に必要な 3 つのファイルと、--plugin-dir による編集・リロードのループ
  • 静的解析のゲート: const ui = $.ui がスタイルの些事ではなくロードエラーになる理由
  • イベントマップ (ツール、プロンプト、ターン、セッション、UI) とフックが呼べる $ の名前空間
  • 本番で刺さる 5 つの落とし穴: フェイルオープンするフック、共有ワーカー、10 秒の予算、状態のリセット、deny ルールの非対称性
  • mod があなたのマシン上で何に手を伸ばせるか、インストール前の監査方法、そして管理者が囲い込むための managed settings

mod、フック、スキル、それとも MCP サーバー?​

4 つはいずれも Claude Code を拡張し、互いに重なります。何を変えたいか で選んでください。

mod設定フックスキルMCP サーバー
正体プラグイン内の関数。Claude Code のプロセスで動くライフサイクルイベントで発火するシェルコマンド / HTTP リクエスト / プロンプト指示を書いた SKILL.mdツールを公開する外部プロセス
変えられるものツール呼び出し、プロンプト、ターン、コマンド、そしてインターフェイスが描くものアクションを進めるか否か。ツールの引数と結果。Claude 向けのコンテキストClaude が知っていること・することClaude が持つツール
UI を描ける?はいいいえいいえいいえ
書くものJS / TSスクリプト + settings.json のエントリMarkdownサーバー。言語は自由
こんなときにペイン、プロンプト上のバンド、即応の /command が欲しい、あるいはイベントを書き換えたいブロック・許可・ログを行うスクリプトが既にある同じ指示を貼り続けているClaude が外部システムを必要としている

非推奨になったものはありません。設定フックは mod と並んで今も動きます。1 つのプラグインに mod、スキル、コマンド、MCP サーバーをまとめて載せることもできます。プラグインとマーケットプレイスを参照してください。

ミドルウェアモデル​

すべてのフックは同じ 3 つの引数を受け取ります。mods API の $、凍結されたイベントの e、そして next です。1 つのイベントに対するハンドラはチェーンを形成し、最後の next が Claude Code 自身の振る舞いです。next をどう扱うかで、3 つのうちどれをやっているのかが決まります。

モードやり方効果
観測return next(e)イベントはそのまま進む。イベントの 後 に動きたいなら先に await next(e)。
書き換えreturn next({ ...e, text })後続のハンドラとエンジンはあなたのコピーだけを見て、元のイベントは見ない。
応答結果を返し、next を呼ばないチェーンを短絡させる。後続の mod と組み込みの振る舞い は走らない。
// Observe: log the tool, then let it run
on('tool.call', async ($, e, next) => {
$.ui.log('Claude is about to use ' + e.tool)
return next(e)
})

// Rewrite: trim every prompt before the turn starts
on('prompt.submit', async ($, e, next) => next({ ...e, text: e.text.trim() }))

// Answer: refuse force-pushes, and tell Claude why
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
if (/git push .*--force/.test(e.command)) {
return { deny: 'Force pushes are not allowed here. Push to a new branch instead.' }
}
return next(e)
})

内在化すべきことが 2 つあります。第一に、e は 深く凍結されています。フィールドへの代入は例外を投げるので、コピーを next に渡します。第二に、next を呼ばずに tool.call に応答した場合、権限プロンプトは出ず、ツールも実行されません。したがって、あなたが返したものが、何が起きたかについて Claude が知るすべてになります。

on の第 2 引数は マッチャー です。イベントとフィールド単位で比較されるオブジェクトです。フィールドには値、配列、正規表現を指定できます。

on('tool.call', { tool: 'Bash' }, hook) // one tool
on('tool.call', { tool: ['Edit', 'Write'] }, hook) // any of these
on('tool.call', { tool: /^mcp__github__/ }, hook) // one MCP server's tools

'*' はテレメトリ系を除くすべてのイベントにマッチします。各イベントは マッチャーごとに 1 回だけ 登録してください。マッチャーなしの on('session.start', …) を 2 回呼ぶと、on("session.start") is registered twice without a matcher でモジュールのロードが失敗します。

3 つのファイルで作る​

Node.js もバンドラもビルドステップも不要です。Claude Code は .js と .ts を直接ロードします。

Guided walkthrough1 of 6
  1. mkdir -p first-mod/.claude-plugin first-mod/hooks — mod はプラグインそのものなので、通常のプラグインマニフェストが .claude-plugin/plugin.json に必要です。

定番のスターターは、ツール呼び出しを数えてスピナーの隣にその数を表示します。

// hooks/register.js — shared by every hook in this module
let calls = 0

export function register(on) {
on('session.start', async ($, e, next) => {
await $.command.register({ name: 'tally', description: 'Show how many tool calls Claude has made' })
return next(e)
})

on('tool.call', async ($, e, next) => {
calls += 1
$.ui.invalidate('ui.render') // ask for a redraw so the new count shows
return next(e)
})

on('command.run', { command: 'tally' }, async () => {
return { text: 'Claude has made ' + calls + ' tool calls since this mod loaded' }
})

on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
return next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } })
})
}

モジュールレベルで共有される calls 変数が定番のパターンです。一方のフックが集め、もう一方が表示する。 これは設定フックが構造上できないことです。設定フックはそれぞれ別のプロセスだからです。

手で書く必要はありません。Claude Code には組み込みの plugin-authoring スキルが同梱されており(/plugin では cc-plugin-plugin-authoring として表示されます)、mod を説明するだけで動きます。

Claude に mod を書かせる

make a mod that shows the current git branch above the prompt

Claude は ~/.claude/dev-mods/<session-id>/<mod-name>/ 以下に書き、そのセッションでホットリロードを有効にするかを一度だけ尋ね、ファイルを変更したターンの終わりごとにリロードします。罠に注意してください。そのフォルダは セッション単位 で、cleanupPeriodDays より古くなると Claude Code が削除します。mod を残したいなら、ディレクトリを自分の場所にコピーしてください。

実行前に mod の能力を監査する

claude plugin validate ./some-mod

静的解析のゲート​

ここが経験豊富な JS 開発者を驚かせる部分で、このページで最も重要な仕組みです。Claude Code は $ の使い方を静的に読み取れない mod のロードを拒否します。 だからこそ claude plugin validate は信頼できる能力マニフェストになります。ローダーは、mod が何をできるかを知るためにコードを実行する必要がないのです。

したがって、以下はすべて バリデーションに失敗します。

書いたもの失敗内容
const ui = $.ui$.ui is used as a value
変数を使った on(eventName, hook)、または名前のリストに対するループthe event name passed to on() is not a string literal
register の内側で宣言された 2 つめの on"on" is declared again (shadowed)
await import('./other.js')a dynamic import(); a hooks module imports its own files with an import declaration
require(...)、または claude-code 以外のベア importモジュールが有効なフックモジュールではない
on('tool.calls', …)"tool.calls" is not an event

すべての呼び出しを省略せずに書いてください。$.store.get('notes') のように $、名前空間、メソッドを揃えます。同一ファイルのトップレベルで宣言された関数に $ を渡すことは できます。その場合 validate は呼び出しを帰属させ、たとえば $.store.get (via loadNotes) と出ます。メソッド、フック内部で定義されたクロージャ、import された関数に $ を渡すと失敗します。

読むべき出力はこれです。

❯ ./register.js hooks: session.start, tool.call, command.run{command=tally}, ui.render{component=Spinner}
❯ ./register.js calls: $.command.register, $.ui.invalidate

✔ Validation passed

環境変数や $.state に触る mod には env reads: / env writes: / state reads: / state writes: の行も出ます。--strict は警告をエラーに変え、--json は機械可読にします。CI で欲しいのは後者です。

イベントマップ​

イベントは Claude Code が何かをしようとするあらゆる地点で発火します。v2.1.287 時点の全集合をグループ分けしたものです。

グループイベントフックが典型的に返せるもの
ツールtool.call, tool.check, tool.describenext(e), { deny: reason }, { result }。tool.check は { decision } = allow / ask / deny を返す
プロンプトとコンテキストprompt.submit, prompt.fill, prompt.suggest, prompt.edit, prompt.compose, prompt.section, prompt.context, prompt.attachment, skill.prompt, attribution.text変更後のテキスト、{ sections }、{ blocks }、省略するための { text: null }、{ drop: reason }
コマンドと設定command.run, command.describe, config.set, config.describe{ text }, { description, argumentHint, isHidden }, { deny: reason }
ターンturn.start, turn.step, turn.completeturn.step は非同期ジェネレータ — yield* next(e)。リクエストごとに model や effort を差し替えられる
セッションsession.start, session.end, session.compact, session.send, session.receive, session.append, session.attach, session.detach, session.measurecompact では { skip: reason }、receive では { consumed: reason }、append では書き換えた行
サブエージェントagent.offer, agent.spawnタイプを出さないための { isOffered: false }、{ model } または { deny: reason }
インターフェイスui.render, ui.resolve, ui.press, ui.input, ui.select, ui.focus, ui.scroll, ui.close, ui.message要素ツリー、または props を変えた next
他の modplugin.register, engine.create他の mod のロードを止める { refuse: reason }
テレメトリtelemetry.log, telemetry.mark{ to: 'collector' } マッチャーが必須で、ないと validate が失敗する。'*' はこれらにマッチしない

見落としやすいイベントが 2 種類あります。

  • classic.<Event> — すべての設定フックイベントは mod イベントでもあるので、on('classic.Stop', …) や on('classic.PostToolUse', …) が機能し、e は設定フックが stdin で読むのと同じ JSON(transcript_path も含む)になります。'classic.*' はそのすべてにマッチします。
  • すべての mods API メソッドはそれ自体がイベント でもあり、$. を外した名前になります。fs.read、model.complete、ui.open のように。あるメソッドにフックを掛けると、それ以降に走るすべての mod が行うその呼び出しを傍受 でき、next(e)、{ deny: reason }、{ value } を返せます。組織ポリシー mod が他の mod のふるまいを監査したり拒否したりするのに使うのが、このフックです。

本物のトークン数を読む​

turn.step はストリームするので、そのフックは非同期ジェネレータになります。これは自分のプロンプトキャッシュのヒット率をリクエストごとに見る、最も安くて正直な方法です。

on('turn.step', async function* ($, e, next) {
const result = yield* next(e)
if (result.usage) {
$.ui.log('cache read ' + result.usage.cache_read_input_tokens +
' · wrote ' + result.usage.cache_creation_input_tokens)
}
return result
})

result.usage は input_tokens、output_tokens、cache_read_input_tokens、cache_creation_input_tokens と、応答した model を保持します。このフックは サブエージェント のリクエストでも発火するので、メインスレッドだけを見たいときは e.agentId でフィルタしてください。そして prompt.section や prompt.context を書き換える人への当然の帰結として、それらのフックが出すテキストがリクエスト間で変わると プロンプトキャッシュが無効化されます。

$ の名前空間​

名前空間メソッド
$.pluginname, root
$.uiresolve, invalidate, open, close, panes, focus, scroll, toast, status, log, notice, ask, copy, blit
$.command / $.tool / $.agentregister, run/call, list($.tool には check も)
$.modelcomplete, fork, classify
$.promptsubmit, read, fill, suggest, compose
$.turnabort
$.sessionmessages, cwd, root, model, turns, id, repo, surfaces, usage, version, compact, send, append, authorize
$.config / $.settings / $.envlist/set, read, get/set
$.fsread, write, list, exists, stat, ancestors
$.storeget, set, delete, keys — マシン全体で、すべてのセッションが共有する
$.stateget, set。加えて claude-code から import する atom, read, update, derive, memberOf
$.clock / $.http / $.process / $.mcpnow, sleep, after, every · fetch · run, spawn · call, connect
$.audio / $.telemetryplay, speak · log, mark

名前で覚えておく価値があるのは $.session.usage() です。{ startedAt, context, rateLimits, cost } を返し、context は tokens、window、percent を持ち、rateLimits は { kind, percentUsed, resetsAt } のリストです。これでプラン上限のゲージが 4 行ほどで作れます。その数字をどう使うかはコンテキスト予算の監査を参照してください。

描画​

ui.render フックは レンダーサイト に要素ツリーを返します。サイトには Pane と AbovePrompt(あなた自身の領地)があり、さらに Claude Code が既に描いているものを再スタイルできるものとして、UserMessage、AssistantMessage、ToolUse、ToolResult、ToolGroup、CommandOutput、AskUserQuestion、Spinner、TurnDuration、InfoNotice、SessionMode、PromptHint、そしてターミナル専用の ToolProgress があります。

要素は Box、Text、Button、Link、Code、Markdown、Input、Select、Client、加えて Svg(Desktop のみ)と Raster / Image(ターミナルのみ)です。e.props.placement が 'dock' のときは、幅を e.props.bodyColumns、高さを e.props.scroll.bodyRows で読んで、ツリーをサイトに合わせてください。

mod が実際に現れる場所は、そのフックが走る場所とは別です。 同僚にペインを約束する前に確認すべきなのは、この表です。

Claude Code を動かしている場所フックは走る描画は現れる
ターミナルの claude(エディタ内ターミナル、JetBrains プラグインを含む)はいはい
Desktop アプリの Code タブはいはい。ターミナル専用要素を除く
Desktop アプリの WSL セッションいいえ — そこではプラグインが利用できないいいえ
VS Code 拡張のチャットパネルはいいいえ
claude -p と Agent SDKはいいいえ
claude.ai / モバイルからのリモートコントロールはい。あなたのマシン上のセッションでそのターミナルの中で
クラウドセッションはい。プラグインがそこまで届けばいいえ

ですから、描画する mod は自分のサーフェスを確認し、トランスクリプトの 1 行やコマンドのテキスト応答にフォールバックすべきです。

本番で刺さる 5 つの落とし穴​

いずれもバグではなく文書化された挙動です。そしてどれも、すでに誰かを焼いています。

1. ガードフックは オープン に失敗する。 フックが next を呼ぶ 前に 例外を投げる、タイムアウトする、あるいは不正な形を返した場合、Claude Code はそのフックをスキップし、代わりに次のハンドラが走ります。つまりあなたが守ろうとしていたコマンドは 実行されます。next が解決した 後 に失敗した場合は、その結果が有効になります。クローズに失敗させたいなら .catch を付けてください。

on('tool.call', { tool: 'Bash' }, guard).catch(async ($, e, next) => {
// next.error.kind is 'throw' or 'timeout'
return { deny: 'The command guard failed, so this command was not run: ' + next.error.kind }
})

2. 10 秒の予算は あなたの await を数える。API のものは数えない。 フックはイベントごとに自分自身の実行時間として 10 秒を得ますが、next の内部や、$.clock.sleep 以外の mods API 呼び出しの内部の時間は除外されます。だから await $.ui.ask(...) はユーザーが判断するまでツール呼び出しを無期限に保留できます。しかし await myOwnPromise() は予算を消費し、タイムアウトしたフックは スキップ されるので、保留していたコマンドが実行されます。残りを知りたければ next.budget.remainingMs を読んでください。

3. インストール済みの mod は 1 つのワーカースレッドを共有する。 それをブロックするフック(await しないループなど)は、it crashed the hooks worker であなたの mod をアンロードさせます。ワーカーが 3 回死に、Claude Code がそのクラッシュを 1 つの mod に帰属させられない場合、そのセッションでは すべて の非組み込み mod が、あなたの組織のものを含めてアンロードされ、誰かが /reload-plugins を実行するまで戻りません。

4. 状態は 3 通りの仕方でリセットされる。 モジュールレベルの変数はリロードごとに再初期化されます(だから保存するたびに calls は 0 に戻ります)。$.state は /clear、/resume、/branch の後にデフォルトへ戻ります。しかも session.start は 再発火しない ので、保存した値は classic.SessionStart フックから読み直してください。複数セッションが書くものは $.fs.write ではなく $.store に置きます。$.fs.write はアトミックではなく、別のプロセスが書きかけのファイルを読めてしまうからです。

5. あなたの編集はインストール済みのコピーには届かない。 Claude Code はインストール済みプラグインを バージョン単位で キャッシュするので、開発は --plugin-dir に対して行い、再インストールの前にマニフェストのバージョンを上げてください。

知っておく価値のある小さめのものが 2 つ。ユーザーの操作を伴わない $.ui.open は、初回は ターミナルの 144 カラム を必要とします(ユーザーが自分でそのペインを開いたことがあれば 110)。そして $.session.messages() は最新の 4,096 件しか返しません。

上限​

上限値
フックの実行時間(1 イベント)10 秒
.catch ハンドラ1 秒
すべての session.end フックの合計1.5 秒
$.process.run のタイムアウトデフォルト 30 秒、最大 10 分
$.model.complete の maxTokensデフォルト 1024、最大 64,000 またはモデルの出力上限
$.fs.read / $.fs.write(1 ファイル)4 MiB
$.store の合計JSON で 4 MiB
$.session.messages()最新 4,096 件
ui.render の再描画10/秒に制限(ターミナルでは表示中のペイン、展開されたバンド、ヒント行で 30/秒)
Text の 1 つの文字列の子10,000 文字
Code / Markdown のテキスト10,000 文字 · Svg 131,072 · Image 2 MiB
Rastercolumns ≤ 512、rows ≤ 256
コマンド / ツール / エージェント / ペインの名前英字、数字、_、-、64 文字以下
claude plugin test の 1 テストtimeoutMs を設定しない場合 5 秒

セキュリティ: mod が実際に手を伸ばせる範囲​

mod はサンドボックス化されていません

mod は Claude Code のプロセス内で、あなたの権限で 動きます。いったんロードされれば、あなたのアカウントが読み書きできるあらゆるファイルを読み書きし、プログラムを起動し、ネットワークリクエストを送り、環境変数や設定ファイル(どちらかに置かれた API キーを含む)を読み、すべてのプロンプトとすべてのツール呼び出しを見て、それらを書き換え、あなたが入力したかのようにプロンプトを送信し、あなたが尋ねられる前にツール呼び出しを承認し、$.model.complete 経由であなたのプランや API クレジットを消費できます。サンドボックス化を有効にしても、それが隔離するのは Claude が実行する Bash コマンドであり、mod が起動したプロセスはその 外側 で動きます。

それ自体で 1 行を割く価値のある非対称性が 1 つあります。もっとも一般的なメンタルモデルを打ち砕くからです。deny 権限ルールは Claude のツール呼び出しを縛るが、mod 自身の呼び出しは縛らない。 Read(.env) を deny していても、mod は $.fs.read でそのファイルを読めますし、読むプログラムを起動することもできます。権限ルールは mod コードに対する封じ込め境界ではありません。一方で、mod が権限プロンプトそれ自体を再スタイルすることもできません。その 1 つのサーフェスは立入禁止なので、プロンプトが見せるものは常に本物です。

実務上の防御は信頼ではなく監査行です。ディレクトリに対して claude plugin validate を実行し、calls: を読んでください。手を止めてソースを読むべきエントリはこれらです。$.fs.read / $.fs.write、$.process.run / $.process.spawn、$.http.fetch、$.env.get / $.settings.read(API キー)、$.env.set(以降のすべてのコマンドと MCP サーバーが何を実行するかを変える)、$.model.complete(あなたのクレジット)、$.prompt.submit(ユーザー自身の言葉として テキストを送信できる)、$.session.send(別のセッションの Claude に流し込む)。hooks: の行では、tool.call と prompt.submit はすべてを見て変更できることを意味し、session.append は保存された会話の行を書き換えられることを意味し、tool.check はどんなプロンプトも出る前に許可または拒否できることを意味します。

Anthropic は claude-code-playground にサンプル mod を公開しています。token-weather(プロンプト上にコンテキストウィンドウの予報を表示)、blast-radius(危険なシェルコマンドを保留し、何が変わるかを表示)、replay-theater(そのターンの編集を順に辿る /replay コマンド)です。現状のまま、サポートなしで共有されており、他と同様にあなたの権限で動きます。サードパーティコードのレビューと同じ審査の規律を適用してください。

オフにする​

範囲やり方
1 つの mod/plugin の Installed タブからそのプラグインを無効化またはアンインストールする
インストール済みの全 mod、1 セッションclaude --safe-mode(他のカスタマイズも無効になる)
インストール済みの全 mod、常時~/.claude/settings.json の "disableAllHooks": true — 設定フックとカスタムステータスラインも止まる

組み込み mod はこれらのいずれにも影響されません。それぞれ /plugin に独自のスイッチがあります。mod がそもそもロードできるかをテストするには、mod のないディレクトリから claude plugin test を実行します。no hooks module to load ならロードできます。hooks modules are turned off here なら設定または組織ポリシーがブロックしています。hooks modules are turned off in this process なら Anthropic がインストール済み mod をリモートで無効化しており、ローカルでは何をしても再有効化できません。

早期アクセス時に CLAUDE_CODE_ENABLE_FUNCTION_HOOKS を設定していたなら、外してください。v2.1.287 以降はどんな値でも無視するので、そこに 0 を置いても mod はオフに なりません。

組織側​

managed settings があるマシン、または Team/Enterprise のサインインでは、Claude Code は組み込みのガード — sec-default@builtin、cc-plugin-sec-default として表示されます — を、ユーザーがインストールしたすべての mod の前にロードします。デフォルトでは、組織が管理するもの(managed フックの入力と判断、システムプロンプト、managed instructions、どの mod が読んでも設定、managed MCP ツール)だけを保護し、ユーザーの mod が deny ルールで拒否される呼び出しを承認できないことを強制します。それ以外はすべて許可されたままです。ソースは mods/sec-default で公開されています。

管理者の目的managed setting
ユーザーがインストールした mod を禁止し、フックはそのままpluginConfigs → cc-plugin-sec-default@builtin → options の下に allowManagedModsOnly: true
組織の mod だけ上記 + 組織のものとして数えられるようインストールする
承認済みマーケットプレイスの mod だけマーケットプレイスの制限を維持 + disableSideloadFlags: true
どの mod も可。ただし組織の mod がそれらを取り締まる組織の mod を sec-default@builtin とともに prependPlugins に列挙する
managed フックも含めて一切なしdisableAllHooks: true

ガードはオプションを managed settings からのみ 読み、キーは cc-plugin-sec-default@builtin のみ です(prependPlugins は短い sec-default@builtin も受け付けますが、pluginConfigs は受け付けません)。そして クローズに失敗します。managed settings を読めない場合、ユーザーの mod をすべて拒否します。prependPlugins を自分で設定するなら、リストにガードを含めてください。でなければガードはロードされなくなります。

ポリシー mod は、ロードされようとしているすべての mod について plugin.register を受け取り、e.tier(prepend / user / append / builtin)と e.uses.calls を得ます。後者は validate が出力するのと同じリストで、$. を外した形で書かれています。{ refuse: reason } を返すとその mod のロードが止まります。上と同じフェイルオープンの罠に注意してください。あなたのチェックが例外を投げると、チェック対象の mod は ロードされます。ですからチェックは名前付き関数に入れ、user ティアを拒否する .catch を追加してください。

デバッグ​

失敗を示す行がどこに現れるかはセッションによって変わります。だから「mod が何もしない」がこれほど多いのです。

  • プラグインディレクトリのホットリロード(--plugin-dir、またはホットリロードを有効にした Claude が書いた mod): トランスクリプトの薄い色の行。
  • それ以外のあらゆる対話セッション(マーケットプレイスからインストールした mod を含む): デバッグログのみ。まず claude --debug から。
  • claude -p --plugin-dir: デフォルトのテキスト形式では stderr へ。他の mod による拒否はデバッグログのみ。
claude --debug-file ./mod-debug.log --plugin-dir ./first-mod
tail -f ./mod-debug.log | grep first-mod

ロードされた mod は hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render のような行を出力します。--plugin-dir でロードされた mod には @inline サフィックスが付きます。自分の行は $.ui.log('message', { to: 'debug' }) で書きます。第 2 引数がない場合、$.ui.log は代わりにトランスクリプトへ薄い色の行を追加します。見分けられるようにしておく価値のあるメッセージは、hook skipped: + 理由(例外、タイムアウト、形が不正)、reload failed, the previous version stays loaded:(最後に動いたバージョンが走り続ける)、ui.render (Pane) refused:(あなたのツリーがバリデーションを通らず、エンジンが自前のものを描いた)、そして … registered /tally but no command.run hook answered it です。

mod の用語
Enter キーまたはスペースキーでカードを裏返します。左右の矢印キーでカードを移動できます。用語を表示しました。
1 / 8

Check yourself

0/5
  1. あなたの tool.call フックは危険な Bash コマンドをブロックします。ところが next(e) に到達する前に予期しない TypeError を投げました。コマンドはどうなりますか?
  2. なぜ `const ui = $.ui` は mod のロードを失敗させるのですか?
  3. あなたの設定の deny ルールが Read(.env) を拒否しています。インストールした mod が $.fs.read('.env') を呼びました。何が起きますか?
  4. あなたの mod が描くペインを VS Code 拡張のチャットパネルで見えるようにしたい。可能ですか?
  5. 10 秒のフック予算について正しい主張はどれですか?

出典とさらに読む​

次へ​