Visual Studio Code のエージェントフック (プレビュー)
フックを使用すると、エージェントセッション中の重要なライフサイクルポイントでカスタムシェルコマンドを実行できます。フックを使用して、ワークフローの自動化、セキュリティポリシーの強制、操作の検証、および外部ツールとの統合を行います。
AIカスタマイズフレームワークにおけるフックの役割については、「カスタマイズの概念」を参照してください。
この記事では、VS Codeでフックを設定および使用する方法を説明します。
エージェントフックは現在プレビュー版です。設定形式や動作は将来のリリースで変更される可能性があります。
組織によっては、VS Codeでのフックの使用が無効になっている場合があります。詳細については管理者にお問い合わせください。「エンタープライズポリシー」も参照してください。
[チャットカスタマイズエディター](Preview) を使用して、すべてのチャットカスタマイズを 1 か所で発見、作成、管理できます。コマンドパレットから **チャット: チャットカスタマイズを開く** を実行します。
フックは、ローカルエージェント、バックグラウンドエージェント、クラウドエージェントなど、すべてのエージェントタイプで機能するように設計されています。各フックは構造化されたJSON入力を受け取り、エージェントの動作に影響を与えるJSON出力を返すことができます。
なぜフックを使用するのか?
フックは、決定的かつコード駆動型の自動化を提供します。エージェントの動作をガイドする指示やカスタムプロンプトとは異なり、フックは特定のライフサイクルポイントでコードを実行し、確実な結果を保証します。
-
セキュリティポリシーの強制: エージェントへの指示内容に関わらず、
rm -rfやDROP TABLEなどの危険なコマンドが実行される前にブロックします。 -
コード品質の自動化: ファイル変更後にフォーマッタ、リンター、またはテストを自動的に実行します。
-
監査証跡の作成: コンプライアンスとデバッグのために、すべてのツール呼び出し、コマンド実行、またはファイル変更をログに記録します。
-
コンテキストの注入: プロジェクト固有の情報、APIキー、または環境の詳細を追加して、エージェントがより適切な意思決定を行えるようにします。
-
承認の制御: 安全な操作は自動的に承認し、機密性の高い操作には確認を求めるようにします。
クイックスタート: 最初のフック
次の例では、ファイル編集のたびにPrettierを実行するフックを作成します。ワークスペースに .github/hooks/format.json ファイルを作成してください。
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"command": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\""
}
]
}
}
このファイルを保存すると、VS Codeは自動的にフックを読み込みます。次にエージェントがファイルを編集するとき、変更されたファイルに対してPrettierが実行されます。GitHub Copilot Chat Hooks 出力チャネルを確認して、フックが実行されたかどうかを確認してください。
カスタムスクリプトを使用するより複雑なフックについては、「利用シナリオ」を参照してください。
フックのライフサイクルイベント
VS Codeは、エージェントセッション中の特定のポイントで実行される8つのフックイベントをサポートしています。
| フックイベント | 実行タイミング | 一般的なユースケース |
|---|---|---|
SessionStart |
ユーザーが新しいセッションの最初のプロンプトを送信したとき | リソースの初期化、セッション開始の記録、プロジェクト状態の検証 |
UserPromptSubmit |
ユーザーがプロンプトを送信したとき | ユーザーリクエストの監査、システムコンテキストの注入 |
PreToolUse |
エージェントがツールを呼び出す前 | 危険な操作のブロック、承認の要求、ツール入力の変更 |
PostToolUse |
ツールが正常に完了した後 | フォーマッタの実行、結果のログ記録、後続のアクションのトリガー |
PreCompact |
会話コンテキストが圧縮される前 | 重要なコンテキストのエクスポート、切り捨て前の状態保存 |
SubagentStart |
サブエージェントが生成されたとき | ネストされたエージェントの使用状況の追跡、サブエージェントのリソース初期化 |
SubagentStop |
サブエージェントが完了したとき | 結果の集計、サブエージェントのリソースクリーンアップ |
Stop |
エージェントセッションが終了したとき | レポートの生成、リソースのクリーンアップ、通知の送信 |
フックの設定
フックは、ワークスペースまたはユーザーディレクトリに保存されたJSONファイルで設定されます。
フックファイルの場所
VS Codeは以下の場所でフック設定ファイルを検索します。
モノレポでは、 chat.useCustomizationsInParentRepositories を有効にして、親リポジトリのルートからフックを検出できるようにします。「親リポジトリの検出」の詳細をご覧ください。
| スコープ | デフォルトのファイル場所 |
|---|---|
| ワークスペース | .github/hooks/*.json |
| ワークスペース (Claude形式) | .claude/settings.json, .claude/settings.local.json |
| ユーザー | ~/.copilot/hooks, ~/.claude/settings.json |
| カスタムエージェント | .agent.md フロントマター内の hooks フィールド(「エージェントスコープのフック」を参照) |
| プラグイン | プラグイン形式に応じて hooks.json または hooks/hooks.json(「プラグイン内のフック」を参照) |
同じイベントタイプの場合、ワークスペースのフックがユーザーのフックよりも優先されます。
どのフックファイルを読み込むかをカスタマイズするには、 chat.hookFilesLocations 設定を使用します。フォルダへのパス(VS Codeはそのフォルダ内のすべての *.json ファイルを読み込みます)や、個別の .json ファイルへの直接パスを指定できます。相対パスとチルダ (~) パスのみがサポートされています。
デフォルト値にはこれらの場所が含まれています。
"chat.hookFilesLocations": {
".github/hooks": true,
".claude/settings.local.json": true,
".claude/settings.json": true,
"~/.claude/settings.json": true
}
カスタムの場所を追加するには、この設定にエントリーを追加します。
"chat.hookFilesLocations": {
"custom/hooks": true,
"~/my-hooks/security.json": true
}
その場所からのフック読み込みを無効にするには、パスを false に設定します(デフォルトの場所を含む)。たとえば、Claude Code設定ファイルからのフック読み込みを停止するには、以下のようにします。
"chat.hookFilesLocations": {
".claude/settings.json": false,
".claude/settings.local.json": false,
"~/.claude/settings.json": false
}
エージェントスコープのフック
エージェントスコープのフックは現在プレビュー中です。
フックは、カスタムエージェントのYAMLフロントマター内で直接定義できます。エージェントスコープのフックは、そのカスタムエージェントがアクティブな場合(ユーザーによって選択された場合、またはサブエージェントとして呼び出された場合)にのみ実行されます。エージェントスコープのフックは、同じイベントに対して設定されたワークスペースまたはユーザーレベルのフックに加えて実行されます。
エージェントスコープのフックを有効にするには、 chat.useCustomAgentHooks を true に設定します。
エージェントのフロントマターに、フック設定ファイルと同じ構造(イベント名とフックコマンドオブジェクトの配列)を持つ hooks フィールドを追加します。
---
name: "Strict Formatter"
description: "Agent that auto-formats code after every edit"
hooks:
PostToolUse:
- type: command
command: "./scripts/format-changed-files.sh"
---
You are a code editing agent. After making changes, files are automatically formatted.
フック設定形式
各イベントタイプのフックコマンドの配列を含む hooks オブジェクトを持つJSONファイルを作成します。VS Codeは互換性のために、Claude CodeやCopilot CLIと同じフック形式を使用します。
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/validate-tool.sh",
"timeout": 15
}
],
"PostToolUse": [
{
"type": "command",
"command": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\""
}
]
}
}
フックコマンドのプロパティ
各フックエントリーには type: "command" と少なくとも1つのコマンドプロパティが必要です。
| プロパティ | タイプ | 説明 |
|---|---|---|
type |
string | "command" である必要があります |
command |
string | 実行するデフォルトコマンド(クロスプラットフォーム) |
windows |
string | Windows専用のコマンド上書き |
linux |
string | Linux専用のコマンド上書き |
osx |
string | macOS専用のコマンド上書き |
cwd |
string | 作業ディレクトリ(リポジトリルートからの相対パス) |
env |
object | 追加の環境変数 |
timeout |
number | タイムアウト(秒単位、デフォルト: 30) |
OS固有のコマンドは、拡張ホストプラットフォームに基づいて選択されます。リモート開発シナリオ(SSH、コンテナ、WSL)では、ローカルのOSと異なる場合があります。
OS固有のコマンド
オペレーティングシステムごとに異なるコマンドを指定します。
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"command": "./scripts/format.sh",
"windows": "powershell -File scripts\\format.ps1",
"linux": "./scripts/format-linux.sh",
"osx": "./scripts/format-mac.sh"
}
]
}
}
実行サービスは、OSに基づいて適切なコマンドを選択します。OS固有のコマンドが定義されていない場合は、command プロパティにフォールバックします。
フックの入力と出力
フックは、JSONを使用してstdin(入力)およびstdout(出力)を介してVS Codeと通信します。
共通の入力フィールド
すべてのフックは、これらの共通フィールドを含むJSONオブジェクトをstdinを介して受け取ります。
{
"timestamp": "2026-02-09T10:30:00.000Z",
"cwd": "/path/to/workspace",
"sessionId": "session-identifier",
"hookEventName": "PreToolUse",
"transcript_path": "/path/to/transcript.json"
}
共通の出力形式
フックは、エージェントの動作に影響を与えるためにstdoutを介してJSONを返すことができます。すべてのフックは以下の出力フィールドをサポートしています。
{
"continue": true,
"stopReason": "Security policy violation",
"systemMessage": "Unit tests failed"
}
| フィールド | タイプ | 説明 |
|---|---|---|
continue |
boolean | 処理を停止するには false に設定(デフォルト: true) |
stopReason |
string | continue が false の場合の停止理由(ユーザーに表示されます) |
systemMessage |
string | ユーザーに表示される警告メッセージ |
終了コード
フックの終了コードにより、VS Codeが結果をどのように処理するかが決まります。
| 終了コード | の動作 |
|---|---|
0 |
成功: stdoutをJSONとして解析 |
2 |
ブロックエラー: 処理を停止し、モデルにエラーを表示 |
| その他 | 非ブロック警告: ユーザーに警告を表示し、処理を続行 |
データの返し方の選択
フックには、エージェントの動作を制御するいくつかの方法(終了コード、最上位の出力フィールド(continue、stopReason)、フック固有の出力フィールド(hookSpecificOutput))があります。これらを以下のように組み合わせて使用します。
- 終了コード2は、操作をブロックする最も簡単な方法です。フックのstderrはコンテキストとしてモデルに表示されます。JSON出力は不要です。
- JSON出力の
continue: falseは、エージェントセッション全体を停止します。ユーザーに理由を伝えるにはstopReasonを使用します。これは単一のツール呼び出しをブロックするよりも大幅な制御です。 hookSpecificOutputは、各フックイベント固有のきめ細かな制御を提供します。たとえば、PreToolUseフックはpermissionDecisionを使用して、セッションを停止せずに単一のツール呼び出しを許可、拒否、または確認を求めることができます。systemMessageは、他の決定に関わらず、チャットでユーザーに警告を表示します。
複数の制御メカニズムを組み合わせて使用する場合、最も制限の強いものが優先されます。たとえば、フックが continue: false と permissionDecision: "allow" を返した場合でも、セッションは停止します。
PreToolUse
PreToolUse フックは、エージェントがツールを呼び出す前に実行されます。
PreToolUseの入力
共通フィールドに加えて、PreToolUse フックは以下を受け取ります。
{
"tool_name": "editFiles",
"tool_input": { "files": ["src/main.ts"] },
"tool_use_id": "tool-123"
}
PreToolUseの出力
PreToolUse フックは、hookSpecificOutput オブジェクトを介してツール実行を制御できます。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by policy",
"updatedInput": { "files": ["src/safe.ts"] },
"additionalContext": "User has read-only access to production files"
}
}
| フィールド | 値 | 説明 |
|---|---|---|
permissionDecision |
"allow", "deny", "ask" |
ツールの承認を制御 |
permissionDecisionReason |
string | ユーザーに表示される理由 |
updatedInput |
object | 変更されたツール入力(オプション) |
additionalContext |
string | モデルのための追加コンテキスト |
権限決定の優先度: 同じツール呼び出しに対して複数のフックが実行される場合、最も制限の強い決定が優先されます。
deny(最も制限が強い): ツール実行をブロックask: ユーザーの確認を要求allow(最も制限が緩い): 実行を自動承認
updatedInput 形式: updatedInput の形式を確認するには、エージェントログを開き、記録されたツールスキーマを見つけてください。updatedInput が予期されるスキーマと一致しない場合、無視されます。
PostToolUse
PostToolUse フックは、ツールが正常に完了した後に実行されます。
PostToolUseの入力
共通フィールドに加えて、PostToolUse フックは以下を受け取ります。
{
"tool_name": "editFiles",
"tool_input": { "files": ["src/main.ts"] },
"tool_use_id": "tool-123",
"tool_response": "File edited successfully"
}
PostToolUseの出力
PostToolUse フックは、モデルに追加のコンテキストを提供したり、それ以上の処理をブロックしたりできます。
{
"decision": "block",
"reason": "Post-processing validation failed",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "The edited file has lint errors that need to be fixed"
}
}
| フィールド | 値 | 説明 |
|---|---|---|
decision |
"block" |
後続の処理をブロック(オプション) |
reason |
string | ブロックの理由(モデルに表示されます) |
hookSpecificOutput.additionalContext |
string | 会話に注入される追加のコンテキスト |
UserPromptSubmit
UserPromptSubmit フックは、ユーザーがプロンプトを送信したときに実行されます。
UserPromptSubmitの入力
共通フィールドに加えて、UserPromptSubmit フックはユーザーが送信したテキストを含む prompt フィールドを受け取ります。
UserPromptSubmit フックは、共通の出力形式のみを使用します。
SessionStart
SessionStart フックは、新しいエージェントセッションが開始されたときに実行されます。
SessionStartの入力
共通フィールドに加えて、SessionStart フックは以下を受け取ります。
{
"source": "new"
}
| フィールド | タイプ | 説明 |
|---|---|---|
source |
string | セッションがどのように開始されたか。現在は常に "new" です。 |
SessionStartの出力
SessionStart フックは、エージェントの会話に追加のコンテキストを注入できます。
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Project: my-app v2.1.0 | Branch: main | Node: v20.11.0"
}
}
| フィールド | タイプ | 説明 |
|---|---|---|
additionalContext |
string | エージェントの会話に追加されるコンテキスト |
Stop
Stop フックは、エージェントセッションが終了したときに実行されます。カスタムエージェントにスコープ設定されている場合、Stop フックは SubagentStop としても扱われます。
Stopの入力
共通フィールドに加えて、Stop フックは以下を受け取ります。
{
"stop_hook_active": false
}
| フィールド | タイプ | 説明 |
|---|---|---|
stop_hook_active |
boolean | 以前の停止フックの結果としてエージェントがすでに続行している場合に true となります。エージェントが無限に実行されるのを防ぐために、この値を確認してください。 |
Stopの出力
Stop フックは、エージェントが停止するのを防ぐことができます。
{
"hookSpecificOutput": {
"hookEventName": "Stop",
"decision": "block",
"reason": "Run the test suite before finishing"
}
}
| フィールド | 値 | 説明 |
|---|---|---|
decision |
"block" |
エージェントの停止を防止 |
reason |
string | decision が "block" の場合に必須です。なぜ続行すべきかをエージェントに伝えます。 |
Stop フックがエージェントの停止をブロックすると、エージェントは実行を継続し、追加のターンは プレミアムリクエスト を消費します。エージェントが無限に実行されるのを防ぐため、常に stop_hook_active フィールドを確認してください。
SubagentStart
SubagentStart フックは、サブエージェントが生成されたときに実行されます。
SubagentStartの入力
共通フィールドに加えて、SubagentStart フックは以下を受け取ります。
{
"agent_id": "subagent-456",
"agent_type": "Plan"
}
| フィールド | タイプ | 説明 |
|---|---|---|
agent_id |
string | サブエージェントの一意の識別子 |
agent_type |
string | エージェント名(例: ビルトインエージェントの場合は "Plan"、またはカスタムエージェント名) |
SubagentStartの出力
SubagentStart フックは、サブエージェントの会話に追加のコンテキストを注入できます。
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "This subagent should follow the project coding guidelines"
}
}
| フィールド | タイプ | 説明 |
|---|---|---|
additionalContext |
string | サブエージェントの会話に追加されるコンテキスト |
SubagentStop
SubagentStop フックは、サブエージェントが完了したときに実行されます。
SubagentStopの入力
共通フィールドに加えて、SubagentStop フックは以下を受け取ります。
{
"agent_id": "subagent-456",
"agent_type": "Plan",
"stop_hook_active": false
}
| フィールド | タイプ | 説明 |
|---|---|---|
agent_id |
string | サブエージェントの一意の識別子 |
agent_type |
string | エージェント名(例: ビルトインエージェントの場合は "Plan"、またはカスタムエージェント名) |
stop_hook_active |
boolean | 以前の停止フックの結果としてサブエージェントがすでに続行している場合に true となります。サブエージェントが無限に実行されるのを防ぐために、この値を確認してください。 |
SubagentStopの出力
SubagentStop フックは、サブエージェントが停止するのを防ぐことができます。
{
"decision": "block",
"reason": "Verify subagent results before completing"
}
| フィールド | 値 | 説明 |
|---|---|---|
decision |
"block" |
サブエージェントの停止を防止 |
reason |
string | decision が "block" の場合に必須です。なぜ続行すべきかをサブエージェントに伝えます。 |
PreCompact
PreCompact フックは、会話コンテキストが圧縮される前に実行されます。
PreCompactの入力
共通フィールドに加えて、PreCompact フックは以下を受け取ります。
{
"trigger": "auto"
}
| フィールド | タイプ | 説明 |
|---|---|---|
trigger |
string | 圧縮がどのようにトリガーされたか。会話がプロンプト予算に対して長すぎる場合に "auto" となります。 |
PreCompact フックは、共通の出力形式のみを使用します。
UIを使用したフックの設定
フックは、いくつかの方法で対話型UIを通じて設定できます。
- チャット入力に
/hooksと入力し、Enter キーを押します。 - コマンドパレット (⇧⌘P (Windows, Linux Ctrl+Shift+P)) を開き、Chat: Configure Hooks を実行します。
- チャットビューの上部にある Settings アイコン () を選択し、Hooks を選択します。
フック設定メニュー内では
-
リストからフックイベントタイプを選択します。
-
既存のフックを選択して編集するか、Add new hook を選択して新しいフックを作成します。
-
フック設定ファイルを選択または作成します。
コマンドを実行すると、エディタでフックファイルが開き、カーソルがコマンドフィールドに配置されるため、すぐに編集できます。
AIを使用したフックの生成
AIを使用してフック設定を生成できます。チャットで /create-hook と入力し、目的の自動化について説明します(例: 「ファイル編集のたびにESLintを実行する」)。エージェントは明確化のための質問を行い、適切なイベントタイプ、コマンド、設定を含むフック設定ファイルを生成します。
利用シナリオ
以下の例は、一般的なフックパターンを示しています。
危険なターミナルコマンドのブロック
破壊的なコマンドを防ぐ PreToolUse フックを作成します
.github/hooks/security.json:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/block-dangerous.sh",
"timeoutSec": 5
}
]
}
}
scripts/block-dangerous.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')
if [ "$TOOL_NAME" = "runTerminalCommand" ]; then
COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command // empty')
if echo "$COMMAND" | grep -qE '(rm\s+-rf|DROP\s+TABLE|DELETE\s+FROM)'; then
echo '{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"Destructive command blocked by security policy"}}'
exit 0
fi
fi
echo '{"continue":true}'
編集後のコードの自動フォーマット
ファイル変更後にPrettierを自動的に実行します
.github/hooks/formatting.json:
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"command": "./scripts/format-changed-files.sh",
"windows": "powershell -File scripts\\format-changed-files.ps1",
"timeout": 30
}
]
}
}
scripts/format-changed-files.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
if [ "$TOOL_NAME" = "editFiles" ] || [ "$TOOL_NAME" = "createFile" ]; then
FILES=$(echo "$INPUT" | jq -r '.tool_input.files[]? // .tool_input.path // empty')
for FILE in $FILES; do
if [ -f "$FILE" ]; then
npx prettier --write "$FILE" 2>/dev/null
fi
done
fi
echo '{"continue":true}'
監査のためのツール使用ログ記録
すべてのツール呼び出しの監査証跡を作成します
.github/hooks/audit.json:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/log-tool-use.sh",
"env": {
"AUDIT_LOG": ".github/hooks/audit.log"
}
}
]
}
}
scripts/log-tool-use.sh:
#!/bin/bash
INPUT=$(cat)
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
SESSION_ID=$(echo "$INPUT" | jq -r '.sessionId')
echo "[$TIMESTAMP] Session: $SESSION_ID, Tool: $TOOL_NAME" >> "${AUDIT_LOG:-audit.log}"
echo '{"continue":true}'
特定のツールの承認要求
インフラストラクチャを変更するツールには手動確認を強制します
.github/hooks/approval.json:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/require-approval.sh"
}
]
}
}
scripts/require-approval.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
# Tools that should always require approval
SENSITIVE_TOOLS="runTerminalCommand|deleteFile|pushToGitHub"
if echo "$TOOL_NAME" | grep -qE "^($SENSITIVE_TOOLS)$"; then
echo '{"hookSpecificOutput":{"permissionDecision":"ask","permissionDecisionReason":"This operation requires manual approval"}}'
else
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
fi
セッション開始時のプロジェクトコンテキストの注入
セッション開始時にプロジェクト固有の情報を提供します
.github/hooks/context.json:
{
"hooks": {
"SessionStart": [
{
"type": "command",
"command": "./scripts/inject-context.sh"
}
]
}
}
scripts/inject-context.sh:
#!/bin/bash
PROJECT_INFO=$(cat package.json 2>/dev/null | jq -r '.name + " v" + .version' || echo "Unknown project")
BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Project: $PROJECT_INFO | Branch: $BRANCH | Node: $(node -v 2>/dev/null || echo 'not installed')"
}
}
EOF
安全性
エージェントがフックによって実行されるスクリプトを編集する権限を持っている場合、エージェントは実行中にそれらのスクリプトを変更し、自身が記述したコードを実行する可能性があります。手動承認なしでエージェントがフックスクリプトを編集できないように、chat.tools.edits.autoApprove の使用を無効にすることを推奨します。
トラブルシューティング
フック診断の表示
どのフックが読み込まれているかを確認し、設定エラーがないかチェックするには
-
View Logs を選択してすべてのログを表示します。
-
「Load Hooks」を探して、読み込まれたフックとそれらが読み込まれた場所を確認します。
フック出力の表示
フックの出力とエラーを確認するには
-
Output パネルを開きます。
-
チャネルリストから GitHub Copilot Chat Hooks を選択します。
一般的な問題
フックが実行されない: フックファイルが .github/hooks/ にあり、.json 拡張子を持っていることを確認してください。type プロパティが "command" に設定されているか確認します。
権限拒否エラー: フックスクリプトに実行権限があることを確認してください (chmod +x script.sh)。
タイムアウトエラー: timeout 値を増やすか、フックスクリプトを最適化してください。デフォルトは30秒です。
JSON解析エラー: フックスクリプトがstdoutに有効なJSONを出力していることを確認してください。出力の構築には jq やJSONライブラリを使用してください。
よくある質問
VS CodeはClaude Codeのフック設定をどのように扱いますか?
VS Codeはデフォルトで .claude/settings.json, .claude/settings.local.json, ~/.claude/settings.json からフック設定を読み込みます。VS Codeは、マッチャー構文を含むClaude Codeのフック設定形式を解析します。現在、VS Codeはマッチャー値を無視するため、マッチャーの内容に関わらずすべてのツール呼び出しでフックが実行されます。
Claude CodeのフックをVS Codeに適応させる場合は、以下の違いに注意してください。
- ツール入力プロパティ名: Claude Codeはツール入力プロパティにsnake_caseを使用しますが(例:
tool_input.file_path)、VS CodeのツールはcamelCaseを使用します(例:tool_input.filePath)。正しいプロパティ名を読み込むようにフックスクリプトを更新してください。 - ツール名: Claude CodeとVS Codeは異なるツール名を使用します。たとえば、Claude Codeはファイル操作に
WriteやEditを使用しますが、VS Codeはcreate_fileやreplace_string_in_fileなどのツール名を使用します。tool_name入力フィールドのツール名を確認し、それに応じてフックロジックを更新してください。 - マッチャーは無視されます:
"Edit|Write"のようなフックマッチャーは解析されますが、適用されません。すべてのフックは、マッチャー内のツール名に関係なく、すべてのマッチングイベントで実行されます。
VS CodeはCopilot CLIのフック設定をどのように扱いますか?
VS CodeはCopilot CLIのフック設定を解析し、lowerCamelCaseのフックイベント名(preToolUseなど)をVS Codeで使用されるPascalCase形式(PreToolUse)に変換します。bash および powershell コマンドプロパティは、OS固有のコマンドにマッピングされます(powershell は windows に、bash は osx および linux にマッピングされます)。
セキュリティに関する考慮事項
フックは、VS Codeと同じ権限でシェルコマンドを実行します。特に信頼できないソースからのフックを使用する場合は、フック設定を注意深く確認してください。
-
フックスクリプトのレビュー: フックを有効にする前に、すべてのフックスクリプトを検査してください。特に共有リポジトリでは重要です。
-
フック権限の制限: 最小権限の原則に従ってください。フックは必要なものにのみアクセスできるようにする必要があります。
-
入力の検証: フックスクリプトはエージェントから入力を受け取ります。インジェクション攻撃を防ぐため、すべての入力を検証およびサニタイズしてください。
-
資格情報の保護: フックスクリプトにシークレットをハードコードしないでください。環境変数または安全な資格情報ストレージを使用してください。
関連リソース
- エージェントでツールを使用する - ツールの承認と実行について学ぶ
- カスタムエージェント - 特殊なエージェント設定を作成する
- サブエージェント - コンテキストが隔離されたサブエージェントにタスクを委任する
- セキュリティに関する考慮事項 - VS CodeにおけるAIセキュリティのベストプラクティス