Hooks は Qoder CLI の主要な実行フローの要所に介入しつつ、CLI 本体とは疎結合を保つための仕組みです。代表的な用途には、ツール実行前の危険なコマンドの遮断、タスク完了時のデスクトップ通知、ファイル書き込み後の自動 lint などがあります。
Hooks は JSON 設定ファイルで定義します。コードを変更する必要はなく、設定ファイルを編集すればすぐに有効になります。
以下は、Agent が
手順 2: 設定ファイルを編集する
手順 3: 動作確認
Qoder CLI を起動し、Agent に
Hook 設定は以下の 3 ファイルから読み込まれ、3 つのソースは読み込まれてマージ実行されます (同じイベントの hook が互いに上書きすることはありません):
1 つのイベントに対して複数の matcher グループを設定でき、各グループに複数の hook エントリを含められます。
グループ (HookDefinition) のフィールド:
各 hook エントリは
選び方:
hook の入力を JSON として指定 URL に POST し、レスポンスとして JSON HookOutput を期待します。
独立した 1 ターンのモデル呼び出しで hook イベントを評価します。モデルは
独立した評価。 評価モデルは独立したセッションで実行され、入力はあなたの
子 Agent を起動して条件を検証します。子 Agent は
独立した評価。
Hook スクリプトは stdin で JSON 入力を受け取り、exit code と stdout で動作を制御します。本節ではすべてのイベント共通の入出力フォーマットを示します。イベント固有のフィールドはイベントリファレンスを参照してください。
Hook スクリプトは stdin から JSON データを受け取ります。すべてのイベントには次の共通フィールドが含まれます:
イベントごとに上記に追加フィールドが付加されます(各イベントの説明を参照)。
Hook は exit code と stdout で動作を制御します。
exit が 0 で stdout が正しい JSON のとき、CLI は次のフィールドで解析します。JSON でなければプレーンテキストとして扱われます(
イベント固有のきめ細かい制御フィールド(
Hook スクリプト実行時に利用できる環境変数:
用途別にイベントを並べます。各イベントの matcher 対象、stdin 追加フィールド、ブロック対応の有無、利用可能な
セッション開始時に発火。
matcher 対象: セッションのソース
追加入力フィールド:
hookSpecificOutput:
セッション終了時に発火。
matcher 対象: 終了理由
追加入力フィールド:
ユーザーがプロンプトを送信した直後、Agent 処理前に発火。プロンプトの対話投入をブロック可能。
追加入力フィールド:
ブロック: exit 2 でプロンプトを拒否。stderr がユーザーに表示されます。
hookSpecificOutput:
ツール実行前に発火。ツール実行のブロック、入力の改変が可能。
matcher 対象: ツール名(
ツールが正常終了した後に発火。
matcher 対象: ツール名
追加入力フィールド:
ツール実行が失敗した後に発火。
matcher 対象: ツール名
追加入力フィールド:
hookSpecificOutput:
ツール実行にユーザー認可が必要なときに発火。自動許可、拒否、入力改変が可能。
matcher 対象: ツール名
追加入力フィールド:
hookSpecificOutput:
権限分類器がツール呼び出しを拒否したときに発火。リトライを要求可能。
matcher 対象: ツール名
追加入力フィールド:
hookSpecificOutput:
メイン Agent が応答を完了し未実行ツール呼び出しがないときに発火。Agent の停止をブロックして継続させることが可能。
追加入力フィールド:
ブロック: exit 2、stderr がメッセージとして対話に注入され、Agent が継続します。
hookSpecificOutput:
Agent がエラーで予期せず停止したときに発火。通知のみで、出力と exit code は無視されます。
追加入力フィールド:
子 Agent 起動時に発火。
matcher 対象: Agent タイプ名
追加入力フィールド:
hookSpecificOutput:
子 Agent 完了時に発火。
ブロック: exit 2、stderr が子 Agent の対話に注入されます。
hookSpecificOutput:
コンテキスト圧縮の前に発火。圧縮をブロック可能。
matcher 対象: トリガー方式
追加入力フィールド:
ブロック: exit 2 で今回の圧縮を阻止。
コンテキスト圧縮完了後に発火。
matcher 対象: トリガー方式(PreCompact と同じ)
追加入力フィールド:
hookSpecificOutput:
ユーザー向けの通知(権限要求、アイドル通知、elicitation など)が発生したときに発火。
matcher 対象: 通知タイプ
追加入力フィールド:
hookSpecificOutput:
指示/メモリファイルが読み込まれたときに発火。通知のみで、出力と exit code は無視されます。
追加入力フィールド:
セッション中に設定ファイルが変更されたときに発火。
matcher 対象: 設定ソース
追加入力フィールド:
ブロック: exit 2 で今回の変更を現在のセッションに適用しません。
作業ディレクトリ変更時に発火。
追加入力フィールド:
hookSpecificOutput:
監視対象ファイルが変化したときに発火。
追加入力フィールド:
隔離 worktree の作成が必要になったときに発火。Hook は worktree の絶対パスを返す必要があります。非ゼロ exit code は失敗扱い。
追加入力フィールド:
パスの返却: stdout に絶対パスを書き出すか、
worktree が削除されるときに発火。通知のみで、失敗時は stderr のみ表示します。
追加入力フィールド:
MCP server がユーザー入力(elicitation)を要求したときに発火。Hook は自動的に accept / decline / cancel できます。
matcher 対象:
ブロック: exit 2 で elicitation を拒否。
hookSpecificOutput:
ユーザーが elicitation に応答した後に発火。応答を上書き可能。
matcher 対象:
ブロック: exit 2 で action を
Agent が認可を必要とした、もしくは通知を発行したときにデスクトップ通知を出します。
スクリプト
設定:
Agent がファイルを書き込み/編集するたびに自動で lint を実行します。
スクリプト
設定: イベント
Agent が停止する際に未完了タスクをチェックし、ある場合はメッセージを注入して継続させます。
スクリプト
設定: イベント
クイックスタート
以下は、Agent が rm -rf を実行しようとしたときに自動でブロックする Hook の例です。
手順 1: スクリプトを作成する
~/.qoder/settings.json に以下を追加します:
rm -rf を含むコマンドの実行を依頼します。Hook が実行をブロックし、Agent に通知します。
設定
設定ファイルの場所
Hook 設定は以下の 3 ファイルから読み込まれ、3 つのソースは読み込まれてマージ実行されます (同じイベントの hook が互いに上書きすることはありません):
設定フォーマット
| フィールド | 必須 | 説明 |
|---|---|---|
matcher | いいえ | マッチ条件、省略時はすべてにマッチ |
hooks | はい | このグループの hook エントリ配列 |
async | いいえ | true のとき、グループ内のすべての hook がバックグラウンドで実行され現在の操作をブロックしません。結果は次のモデルターンで追加コンテキストとして注入されます |
Hook エントリの種類
各 hook エントリは type で種類を宣言します。種類ごとに専用フィールドがあります。
command (シェルコマンドを実行)
| フィールド | 必須 | 説明 |
|---|---|---|
command | はい | 実行するシェルコマンド |
timeout | いいえ | タイムアウト秒数、デフォルト 600 |
shell | いいえ | "bash" または "powershell"、未指定時はシステムデフォルト |
env | いいえ | 追加の環境変数。システム環境にマージされる |
if | いいえ | 条件フィルタ。"ToolName" または "ToolName(arg_pattern)" 形式。ツール名/引数が一致するときのみ発火 |
async | いいえ | true のとき、この単一 hook をバックグラウンド実行。グループ単位の async を上書き |
asyncRewake | いいえ | true のときバックグラウンド実行。exit 2 で終了した場合、stderr/stdout/error の内容からシステムリマインダーを生成してモデルを起こします。長時間チェックに有用 |
rewakeMessage | いいえ | asyncRewake と併用。注入メッセージのプレフィックスを上書き |
rewakeSummary | いいえ | asyncRewake と併用。1 行サマリーを上書き(最大 300 文字) |
once | いいえ | true のとき、初回成功実行後にレジストリから削除。セッションスコープの hook のみ有効 |
statusMessage | いいえ | スピナー/ステータス行の表示文を上書き |
args | いいえ | 任意の argv 配列。設定するとフックは exec 形式(シェルを介さない)で実行されます。詳細は下の Exec form vs Shell form を参照。 |
command でのプレースホルダの参照
${QODER_PROJECT_DIR} や ${QODER_PLUGIN_ROOT} などのプレースホルダは、hook サブプロセスに環境変数として注入されます(環境変数参照)。bash ではコマンドテンプレートは CLI 側で事前置換されず、シェルが実行時に展開します。推奨される書き方:
- プレースホルダをダブルクォートで囲む(推奨):
"${QODER_PLUGIN_ROOT}"/scripts/hook.sh。空白や shell メタ文字('、$、バッククォートなど)を含むパスでも単一トークンとして正しく解析されます。 - シェル変数構文:
"$QODER_PLUGIN_ROOT/scripts/hook.sh"。ダブルクォート内であれば上と等価です。 - クォートなし(非推奨):
${QODER_PLUGIN_ROOT}/scripts/hook.sh。POSIX シェルでは未クォートのパラメータ展開でもフィールド分割とパス名展開が行われるため、空白を含むパスは分割され、*を含むパスは glob 展開されます。
プラグイン以外の hook で${QODER_PLUGIN_ROOT}や${QODER_PLUGIN_DATA}が使われたことを検知するプリフライトは${...}形式のみを対象とします(リテラル$VARの文字列に対する誤検出を避けるため)。プリフライトの保護を受けたいプラグイン作者は${...}形式を推奨します。
powershell では ${QODER_PROJECT_DIR}、${QODER_PLUGIN_ROOT} と ${QODER_PLUGIN_DATA} が CLI 側でコマンドテンプレートに置換されてから実行されます(PowerShell は環境変数アクセスに ${NAME} ではなく $env:NAME を用いるため)。
Exec form vs Shell form
コマンド hook は 2 つの実行形式をサポートします:- Shell 形式(デフォルト):
commandはシェルコード片。CLI がbash -c "<command>"(または PowerShell)を実行します。パイプ、リダイレクト、glob 展開、${VAR}環境変数展開がすべて使えます。 - Exec 形式(
argsを指定したとき):commandは単一の実行ファイルのパス/名前、argsの各要素はリテラルな argv 1 要素です。CLI はシェルを介さず直接バイナリを起動します — 引用処理、単語分割、glob 展開は一切行いません。argsを指定するとshellフィールドは無視されます。
- 基本は shell 形式 — プレースホルダをダブルクォートで囲めば(
"${QODER_PLUGIN_ROOT}"/scripts/check.sh)、空白・シングルクォート・$・バッククォートを含むパスも env 透し出しで安全に扱えます。 - shell 形式を使う場面: パイプ(
grep | tee)、リダイレクト(>)、glob(*.json)など、シェル機能が必要なとき。 - exec 形式を使う場面: パスや引数に複雑な引用が必要なシェルメタ文字が含まれるとき、またはシェル解釈を完全に避けたいとき。
.bat/.cmdスクリプトは直接 exec できません。{"command": "cmd.exe", "args": ["/c", "script.bat"]}のように書いてください。- MSYS / Cygwin プログラムの argv セマンティクスは各プログラムが定義します。内部で必要となる引数の引用は対象プログラムのドキュメントを確認してください。
http (HTTP リクエスト送信)
hook の入力を JSON として指定 URL に POST し、レスポンスとして JSON HookOutput を期待します。
| フィールド | 必須 | 説明 |
|---|---|---|
url | はい | POST 先 URL |
headers | いいえ | カスタムリクエストヘッダ。値は ${ENV_VAR} 補間をサポート |
allowedEnvVars | いいえ | headers で補間可能な環境変数のホワイトリスト。未指定時はすべて許可 |
timeout | いいえ | タイムアウト秒数、デフォルト 600 |
if / once / statusMessage | いいえ | command と同じ |
prompt (1 ターンの LLM 呼び出し)
独立した 1 ターンのモデル呼び出しで hook イベントを評価します。モデルは { ok, reason } を返します: ok=true で許可、ok=false でブロック、ブロック時は reason が Agent に表示されます。
| フィールド | 必須 | 説明 |
|---|---|---|
prompt | はい | 評価モデルに送るプロンプトテンプレート。直列化されたイベント JSON が末尾に付与される |
model | いいえ | モデル上書き。未指定時はセッションのデフォルトモデル |
timeout | いいえ | タイムアウト秒数、デフォルト 30 |
if / once / statusMessage | いいえ | command と同じ |
prompt と現在のイベントのみです。メイン会話の以前のツール呼び出し、モデル出力、それまでの状態は参照できません。判定条件は現在のイベント自体から決定できるものに限定してください。会話履歴に依存するルールはここでは信頼できる評価ができないため、独自に状態を保持する command hook か、ファイルシステムを調査できる agent hook を使用してください。
agent (子 Agent による検証)
子 Agent を起動して条件を検証します。子 Agent は StructuredOutput ツールを呼び出し { ok: boolean, reason?: string } を返す必要があります。ok=true で許可、ok=false でブロック。
| フィールド | 必須 | 説明 |
|---|---|---|
prompt | はい | 検証プロンプト。$ARGUMENTS プレースホルダ(hook 入力 JSON に置換)をサポート |
tools | いいえ | 子 Agent が使えるツールのホワイトリスト。未指定時は利用可能なツールをすべて継承しますが、hook 内で安全でないツール (再帰的な Agent 呼び出し、計画モード、対話的な質問など) は自動的に除外されます |
maxTurns | いいえ | 最大エージェントターン数、デフォルト 50 |
model | いいえ | モデル上書き |
timeout | いいえ | タイムアウト秒数、デフォルト 60 |
if / once / statusMessage | いいえ | command と同じ |
prompt と同様に子 Agent は独立したセッションで実行され、メインの会話履歴は参照できません。違いはツールアクセスで、ファイルの読み取り・grep・各種チェックの実行が可能なため、実際の状態を調査する必要がある検証に適しています。
matcher と if のマッチング規則
matcher (グループレベル) は hook の発火範囲を絞り込みます。比較対象のフィールドはイベントごとに異なり (各イベントの説明を参照)、ツール名・トリガー・ソースなどです:
| 書き方 | 意味 | 例 |
|---|---|---|
省略または "*" | すべてにマッチ | すべてのツールで発火 |
| 完全一致 | 完全一致 | "Bash" は Bash ツールのみ |
| 区切り | 複数値マッチ | "Write|Edit" は Write または Edit |
| 正規表現 | 正規表現マッチ | "mcp__.*" はすべての MCP ツール |
if (エントリレベル) はより細かいフィルタで、形式は "ToolName" または "ToolName(arg_pattern)" です:
- ツール名部分は
matcherと同じツール名マッチ規則を再利用します (正規表現や|も使えます)。 - 括弧内の
arg_patternは glob パターン(正規表現ではありません)で、ツールの主要引数(Bash のcommand、ファイル系ツールのfile_pathなど)に対して照合されます。
if の値 | 意味 |
|---|---|
"Bash" | ツールが Bash のとき発火 |
"Bash(git *)" | ツールが Bash かつコマンドが git で始まるとき発火 |
"Edit(*.ts)" | ツールが Edit かつ file_path が *.ts にマッチするとき発火 |
Hook スクリプトの書き方
Hook スクリプトは stdin で JSON 入力を受け取り、exit code と stdout で動作を制御します。本節ではすべてのイベント共通の入出力フォーマットを示します。イベント固有のフィールドはイベントリファレンスを参照してください。
入力
Hook スクリプトは stdin から JSON データを受け取ります。すべてのイベントには次の共通フィールドが含まれます:
| フィールド | 説明 |
|---|---|
session_id | 現在のセッション ID |
transcript_path | 現在の transcript ファイルパス |
cwd | 現在の作業ディレクトリ |
hook_event_name | 発火したイベント名 |
permission_mode | 現在の権限モード(イベントが提供する場合) |
agent_id | 現在の Agent ID(イベントが提供する場合) |
agent_type | 現在の Agent タイプ(イベントが提供する場合) |
jq で入力を解析する例:
出力
Hook は exit code と stdout で動作を制御します。
exit code
0: 成功。stdout は下記ルールで解析されます。2: ブロック。stderr の内容が Agent にフィードバックされます(ブロックをサポートするイベントのみ有効)。- それ以外: 非ブロックエラー。stdout は無視され、stderr が診断ログに書き込まれ、メインフローは継続します。
stdout JSON 共通フィールド
exit が 0 で stdout が正しい JSON のとき、CLI は次のフィールドで解析します。JSON でなければプレーンテキストとして扱われます(SessionStart / UserPromptSubmit のみ、プレーンテキスト stdout を追加コンテキストとして対話に注入します)。
| フィールド | 説明 |
|---|---|
continue | false で後続実行の停止を要求 |
stopReason | continue: false と併用、Agent に停止理由を伝える |
suppressOutput | true のとき、hook 出力をユーザーに表示しない |
systemMessage | ユーザーに表示される hook システムメッセージ。モデルコンテキストには注入されない |
decision | "allow" または "deny"、イベント固有の決定。"deny" は exit 2 と等価。ユーザー認可の要求 ("ask") は PreToolUse の hookSpecificOutput.permissionDecision でのみ使用可 |
reason | 決定理由。ユーザー/モデルに表示 |
hookSpecificOutput | イベント固有フィールドのコンテナ(各イベント参照) |
PreToolUse の permissionDecision、PostToolUse の updatedToolOutput など)は hookSpecificOutput オブジェクトに入ります。hookSpecificOutput を返す際は hookEventName を必ず含めてください。含まれていない場合は JSON 出力全体が拒否され、TUI に <hookName> hook error: hookSpecificOutput is missing required field "hookEventName" が表示されます。例:
環境変数
Hook スクリプト実行時に利用できる環境変数:
| 変数 | 説明 |
|---|---|
QODER_PROJECT_DIR | 現在のプロジェクトの作業ディレクトリ |
QODER_PLUGIN_ROOT | hook がプラグイン由来のとき、そのプラグインのルートディレクトリ |
QODER_PLUGIN_DATA | hook がプラグイン由来のとき、そのプラグインのデータディレクトリ |
イベントリファレンス
用途別にイベントを並べます。各イベントの matcher 対象、stdin 追加フィールド、ブロック対応の有無、利用可能な hookSpecificOutput フィールドを示します。
一覧
| イベント | matcher 対象 | exit 2 ブロック | 主な入力フィールド |
|---|---|---|---|
SessionStart | source (startup/resume/clear/compact/new) | — | source, model |
SessionEnd | reason | — | reason |
UserPromptSubmit | — | ✅ | prompt |
PreToolUse | ツール名 | ✅ | tool_name, tool_input |
PostToolUse | ツール名 | — | tool_name, tool_input, tool_response |
PostToolUseFailure | ツール名 | — | tool_name, error, error_type |
PermissionRequest | ツール名 | — | tool_name, tool_input |
PermissionDenied | ツール名 | — | tool_name, tool_input, reason |
Stop | — | ✅ | stop_hook_active, last_assistant_message |
StopFailure | error_type | — | error_type, error |
SubagentStart | Agent タイプ | — | agent_id, agent_type |
SubagentStop | Agent タイプ | ✅ | agent_id, agent_type, stop_hook_active |
PreCompact | trigger | ✅ | trigger, custom_instructions |
PostCompact | trigger | — | trigger, compact_summary |
Notification | notification_type | — | notification_type, message |
InstructionsLoaded | load_reason | — | file_path, memory_type, load_reason |
ConfigChange | source | ✅ (policy_settings ソースを除く) | source, file_path |
CwdChanged | — | — | old_cwd, new_cwd |
FileChanged | ファイル basename | — | file_path, event |
WorktreeCreate | — | 非ゼロ exit で失敗 | name |
WorktreeRemove | — | — | worktree_path |
Elicitation | mcp_server_name | ✅ | mcp_server_name, message, requested_schema |
ElicitationResult | mcp_server_name | ✅ | mcp_server_name, action, content |
セッションライフサイクル
SessionStart
セッション開始時に発火。
matcher 対象: セッションのソース
| matcher 値 | 発火シナリオ |
|---|---|
startup | 新規セッション起動 |
resume | 既存セッション再開 |
clear | /clear でリセット |
compact | コンテキスト圧縮完了後 |
new | 新規セッション(その他のソース) |
additionalContext(対話に注入されるコンテキスト)
プレーンテキスト(JSON 以外)を返した場合も、stdout がコンテキストとして対話に注入されます。
SessionEnd
セッション終了時に発火。
matcher 対象: 終了理由
| matcher 値 | 発火シナリオ |
|---|---|
clear | /clear で終了 |
resume | 別セッションへ切り替え |
logout | ログアウト |
prompt_input_exit | ユーザーが入力を終了(Ctrl+D など) |
bypass_permissions_disabled | 権限バイパスモードが無効化された |
other | その他 |
UserPromptSubmit
ユーザーがプロンプトを送信した直後、Agent 処理前に発火。プロンプトの対話投入をブロック可能。
追加入力フィールド:
additionalContext: プロンプトと共に対話に注入sessionTitle: 推奨セッションタイトル
プレーンテキスト(JSON 以外)を返した場合も、stdout がコンテキストとして対話に注入されます。
ツール呼び出し
PreToolUse
ツール実行前に発火。ツール実行のブロック、入力の改変が可能。
matcher 対象: ツール名(Bash、Write、Edit、Read、Glob、Grep など。MCP ツールは mcp__server__tool 形式)
追加入力フィールド:
ツールが MCP 由来の場合はブロック: exit 2、stderr がエラーとして Agent に返ります。 hookSpecificOutput:mcp_context(server_name、tool_name、接続情報を含む)とoriginal_request_nameも付与されます。
| フィールド | 説明 |
|---|---|
permissionDecision | "allow" / "deny" / "ask"。トップレベル decision と等価で、こちらが優先 |
permissionDecisionReason | 決定理由。トップレベル reason を上書き |
updatedInput | 改変済みのツール入力(元の tool_input を置換) |
additionalContext | 対話に注入される追加コンテキスト |
PostToolUse
ツールが正常終了した後に発火。
matcher 対象: ツール名
追加入力フィールド:
hookSpecificOutput:tool_responseはオブジェクトで、構造はツールごとに異なります。MCP ツールもmcp_context/original_request_nameを受け取ります。
| フィールド | 説明 |
|---|---|
updatedToolOutput | ツール応答を置換(任意のツールで利用可) |
updatedMCPToolOutput | MCP ツール応答のみ置換(updatedToolOutput より優先度が低い) |
additionalContext | 対話に注入される追加コンテキスト |
PostToolUseFailure
ツール実行が失敗した後に発火。
matcher 対象: ツール名
追加入力フィールド:
additionalContext
PermissionRequest
ツール実行にユーザー認可が必要なときに発火。自動許可、拒否、入力改変が可能。
matcher 対象: ツール名
追加入力フィールド:
decision オブジェクト。フィールドは behavior の値によって異なります。
behavior: "allow" (許可。同時に入力を書き換えたり権限を永続化できる):
| フィールド | 説明 |
|---|---|
behavior | "allow" 固定 |
updatedInput | 改変済みのツール入力 (元の tool_input を置換) |
updatedPermissions | 永続化される権限ルール更新 |
behavior: "deny" (拒否。ユーザー向けメッセージを付加可能):
| フィールド | 説明 |
|---|---|
behavior | "deny" 固定 |
message | ユーザーに表示するメッセージ |
interrupt | 現在の操作を中断してユーザーに表示するか |
PermissionRequestの hook は"ask"をサポートしません。ユーザーに対話的に確認したい場合はPreToolUseのpermissionDecision: "ask"を使ってください。
PermissionDenied
権限分類器がツール呼び出しを拒否したときに発火。リトライを要求可能。
matcher 対象: ツール名
追加入力フィールド:
retry: true でツール呼び出しのリトライを要求。
Agent フロー
Stop
メイン Agent が応答を完了し未実行ツール呼び出しがないときに発火。Agent の停止をブロックして継続させることが可能。
追加入力フィールド:
| フィールド | 説明 |
|---|---|
stop_hook_active | 現在のターンが Stop hook 駆動の継続中かどうか(無限ループ回避に使う) |
last_assistant_message | 停止前の最後の Assistant メッセージ |
clearContext: true で対話コンテキストをクリア。
StopFailure
Agent がエラーで予期せず停止したときに発火。通知のみで、出力と exit code は無視されます。
追加入力フィールド:
error_type の値: rate_limit / authentication_failed / billing_error / invalid_request / server_error / max_output_tokens / unknown。
SubagentStart
子 Agent 起動時に発火。
matcher 対象: Agent タイプ名
追加入力フィールド:
additionalContext
SubagentStop
子 Agent 完了時に発火。Stop 同様に停止をブロック可能。
matcher 対象: Agent タイプ名
追加入力フィールド:
clearContext: true で子 Agent のコンテキストをクリア。
コンテキスト圧縮
PreCompact
コンテキスト圧縮の前に発火。圧縮をブロック可能。
matcher 対象: トリガー方式
| matcher 値 | 発火シナリオ |
|---|---|
manual | ユーザーが /compact を手動実行 |
auto | コンテキストウィンドウが上限に近づき自動発火 |
PostCompact
コンテキスト圧縮完了後に発火。
matcher 対象: トリガー方式(PreCompact と同じ)
追加入力フィールド:
additionalContext
通知
Notification
ユーザー向けの通知(権限要求、アイドル通知、elicitation など)が発生したときに発火。
matcher 対象: 通知タイプ
| matcher 値 | 発火シナリオ |
|---|---|
permission_prompt | ツール権限要求 |
idle_prompt | アイドル通知 |
auth_success | 認証成功 |
elicitation_dialog | MCP elicitation ダイアログ表示 |
elicitation_response | ユーザーが elicitation に応答 |
elicitation_complete | elicitation フロー完了 |
additionalContext
コンテキストと設定の読み込み
InstructionsLoaded
指示/メモリファイルが読み込まれたときに発火。通知のみで、出力と exit code は無視されます。
追加入力フィールド:
load_reason の値: session_start / nested_traversal / path_glob_match / include / compact。
ConfigChange
セッション中に設定ファイルが変更されたときに発火。
matcher 対象: 設定ソース
| matcher 値 | 発火シナリオ |
|---|---|
user_settings | ユーザー ~/.qoder/settings.json |
project_settings | プロジェクト ${project}/.qoder/settings.json |
local_settings | プロジェクトローカル ${project}/.qoder/settings.local.json |
policy_settings | ポリシー設定 |
skills | Skill ディレクトリの変更 |
agents | カスタム Agent ディレクトリの変更 |
作業ディレクトリとファイル
CwdChanged
作業ディレクトリ変更時に発火。
追加入力フィールド:
| フィールド | 説明 |
|---|---|
additionalContext | 対話に注入されるコンテキスト |
watchPaths | FileChanged ウォッチャに登録する絶対パスの配列 |
FileChanged
監視対象ファイルが変化したときに発火。
追加入力フィールド:
event の値: change / add / unlink。
hookSpecificOutput: additionalContext、watchPaths(CwdChanged と同じ)
Worktree 隔離
WorktreeCreate
隔離 worktree の作成が必要になったときに発火。Hook は worktree の絶対パスを返す必要があります。非ゼロ exit code は失敗扱い。
追加入力フィールド:
hookSpecificOutput.worktreePath に設定します。
WorktreeRemove
worktree が削除されるときに発火。通知のみで、失敗時は stderr のみ表示します。
追加入力フィールド:
MCP 連携
Elicitation
MCP server がユーザー入力(elicitation)を要求したときに発火。Hook は自動的に accept / decline / cancel できます。
matcher 対象: mcp_server_name
追加入力フィールド:
| フィールド | 説明 |
|---|---|
action | "accept" / "decline" / "cancel" |
content | accept 時に提供する入力内容 |
ElicitationResult
ユーザーが elicitation に応答した後に発火。応答を上書き可能。
matcher 対象: mcp_server_name
追加入力フィールド:
decline に書き換え。
hookSpecificOutput: action、content(応答を上書き)
実用例
デスクトップ通知
Agent が認可を必要とした、もしくは通知を発行したときにデスクトップ通知を出します。
スクリプト ~/.qoder/hooks/notify.sh(macOS):
ファイル書き込み後の自動 Lint
Agent がファイルを書き込み/編集するたびに自動で lint を実行します。
スクリプト ${project}/.qoder/hooks/auto-lint.sh:
PostToolUse、matcher Write|Edit、command .qoder/hooks/auto-lint.sh。
Agent に作業を継続させる
Agent が停止する際に未完了タスクをチェックし、ある場合はメッセージを注入して継続させます。
スクリプト ~/.qoder/hooks/check-continue.sh:
Stop、command ~/.qoder/hooks/check-continue.sh。