Visual Studio Code のエージェントフック (プレビュー)
フックを使用すると、エージェントセッション中の主要なライフサイクルポイントでカスタムシェルコマンドを実行できます。フックを活用してワークフローの自動化、セキュリティポリシーの強制、操作の検証、外部ツールとの統合を行ってください。
AI カスタマイズフレームワークにおけるフックの背景については、「カスタマイズの概念」を参照してください。
この記事では、VS Code でフックを設定および使用する方法を説明します。
エージェントフックは現在プレビュー段階です。設定形式や動作は将来のリリースで変更される可能性があります。
組織によって VS Code でのフックの使用が無効化されている場合があります。詳細については管理者に問い合わせてください。詳細は「エンタープライズポリシー」を参照してください。
エージェントカスタマイズエディター (プレビュー) を使用すると、すべてのエージェントカスタマイズを1か所で検出、作成、管理できます。コマンドパレットから Chat: Open Customizations を実行してください。
フックは、ローカルエージェント、バックグラウンドエージェント、クラウドエージェントなど、あらゆるエージェントタイプで機能するように設計されています。各フックは構造化された 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 | 決定が "block" の場合に必要です。継続すべき理由をエージェントに伝えます。 |
Stop フックがエージェントの停止を阻止した場合、エージェントは実行を継続し、追加のターンが AI クレジット を消費します。エージェントの無限実行を防ぐため、必ず 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 | 決定が "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" に設定されていることをチェックします。
Permission denied エラー: フックスクリプトに実行権限があることを確認してください(chmod +x script.sh)。
タイムアウトエラー: timeout 値を増やすか、フックスクリプトを最適化してください。デフォルトは 30 秒です。
JSON 解析エラー: フックスクリプトが有効な JSON を stdout に出力していることを確認してください。出力を構成するには 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 セキュリティのベストプラクティス