メインコンテンツへスキップ

Documentation Index

Fetch the complete documentation index at: https://factory-docs-auto-sync-jp-docs.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

例付きのクイックスタートガイドは、フックを始めるを参照してください。

設定

Droidフックはsettings filesで設定します:
  • ~/.factory/settings.json - ユーザー設定
  • .factory/settings.json - プロジェクト設定
  • .factory/settings.local.json - ローカルプロジェクト設定(コミットされない)
  • Enterprise管理ポリシー設定

構造

フックはマッチャーによって整理され、各マッチャーは複数のフックを持つことができます:
{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command",
            "command": "your-command-here"
          }
        ]
      }
    ]
  }
}
  • matcher: ツール名にマッチするパターン、大文字小文字を区別(PreToolUsePostToolUseにのみ適用)
    • 単純な文字列は完全一致:CreateはCreateツールのみにマッチ
    • 正規表現をサポート:Edit|CreateまたはNotebook.*
    • *を使用してすべてのツールにマッチ。空文字列("")を使用するか、matcherを空白のままにすることもできます。
  • hooks: パターンがマッチしたときに実行するコマンドの配列
    • type:現在"command"のみサポート
    • command:実行するbashコマンド($FACTORY_PROJECT_DIR環境変数を使用可能)
    • timeout:(オプション)その特定のコマンドをキャンセルするまでの実行時間(秒)
フックコマンドとスクリプトには相対パスではなく、必ず絶対パスを使用してください。 フックはDroidの現在の作業ディレクトリから実行されます。このディレクトリは実行中に変わる可能性があります。 プロジェクト相対スクリプトには"$FACTORY_PROJECT_DIR"/path/to/script.shを使用し、グローバルスクリプトには次のようなフルパスを使用します: /usr/local/bin/script.shまたは~/.factory/hooks/script.sh
UserPromptSubmitNotificationStopSubagentStopなどのマッチャーを使用しないイベントについては、matcherフィールドを省略できます:
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/prompt-validator.py"
          }
        ]
      }
    ]
  }
}

プロジェクト固有のフックスクリプト

環境変数FACTORY_PROJECT_DIR(DroidがフックコマンドをSpawnしたときのみ利用可能)を使用して、プロジェクトに保存されたスクリプトを参照できます。これにより、Droidの現在のディレクトリに関係なくスクリプトが動作することを保証します:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Create|Edit|ApplyPatch",
        "hooks": [
          {
            "type": "command",
            "command": "\"$FACTORY_PROJECT_DIR\"/.factory/hooks/check-style.sh"
          }
        ]
      }
    ]
  }
}

プラグインフック

プラグインは、ユーザーおよびプロジェクトフックとシームレスに統合されるフックを提供できます。プラグインフックは、プラグインが有効になると自動的に設定にマージされます。 プラグインフックの仕組み
  • プラグインフックはプラグインのhooks/hooks.jsonファイルまたはhooksフィールドのカスタムパスで指定されたファイルで定義されます
  • プラグインが有効になると、そのフックはユーザーおよびプロジェクトフックとマージされます
  • 異なるソースからの複数のフックが同じイベントに応答できます
  • プラグインフックは${DROID_PLUGIN_ROOT}環境変数を使用してプラグインファイルを参照します
プラグインフック設定の例
{
  "description": "Automatic code formatting",
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Create|Edit|ApplyPatch",
        "hooks": [
          {
            "type": "command",
            "command": "${DROID_PLUGIN_ROOT}/scripts/format.sh",
            "timeout": 30
          }
        ]
      }
    ]
  }
}
プラグインフックは通常のフックと同じ形式を使用し、フックの目的を説明する任意のdescriptionフィールドを指定できます。
プラグインフックはカスタムフックと並行して実行されます。複数のフックが同じイベントに一致した場合、それらはすべて並列に実行されます。
プラグインの環境変数
  • ${DROID_PLUGIN_ROOT}:プラグインディレクトリの絶対パス
  • ${FACTORY_PROJECT_DIR}:プロジェクトルートディレクトリ(プロジェクトフックと同じ)
  • すべての標準環境変数が利用可能
プラグインフックの作成については、プラグインコンポーネントリファレンスを参照してください。

フックイベント

PreToolUse

Droidがツールパラメータを作成した後、ツール呼び出しを処理する前に実行されます。 一般的なマッチャー:
  • Task - サブdroidタスク(subagents documentationを参照)
  • Execute - シェルコマンド
  • Glob - ファイルパターンマッチング
  • Grep - コンテンツ検索
  • Read - ファイル読み取り
  • Edit - ファイル編集
  • Create - ファイル作成
  • FetchUrlWebSearch - Web操作

PostToolUse

ツールが正常に完了した直後に実行されます。 PreToolUseと同じマッチャー値を認識します。

Notification

Droidが通知を送信するときに実行されます。通知は以下の場合に送信されます:
  1. Droidがツールを使用する許可を必要とする場合。例:「DroidはExecuteの使用許可を必要としています」
  2. プロンプト入力が少なくとも60秒間アイドル状態の場合。「Droidはあなたの入力を待っています」

UserPromptSubmit

ユーザーがプロンプトを送信したときに、Droidが処理する前に実行されます。これにより、プロンプト/会話に基づいて追加のコンテキストを追加したり、プロンプトを検証したり、特定のタイプのプロンプトをブロックしたりできます。

Stop

Droidが応答を完了したときに実行されます。ユーザーの割り込みによって停止が発生した場合は実行されません。

SubagentStop

サブdroid(Taskツール呼び出し)が応答を完了したときに実行されます。

PreCompact

Droidがコンパクト操作を実行しようとする前に実行されます。 マッチャー:
  • manual - /compactから呼び出される
  • auto - 自動コンパクトから呼び出される(コンテキストウィンドウが満杯のため)

SessionStart

Droidが新しいセッションを開始するか既存のセッションを再開するときに実行されます(現在内部的には新しいセッションを開始します)。既存の問題やコードベースへの最近の変更などの開発コンテキストの読み込み、依存関係のインストール、または環境変数の設定に役立ちます。 マッチャー:
  • startup - スタートアップから呼び出される
  • resume - --resume--continue、または/resumeから呼び出される
  • clear - /clearから呼び出される
  • compact - 自動または手動コンパクトから呼び出される

SessionEnd

Droidセッションが終了するときに実行されます。クリーンアップタスク、セッション統計のログ記録、またはセッション状態の保存に役立ちます。 フック入力のreasonフィールドは以下のいずれかになります:
  • clear - /clearまたは/newコマンドでセッションがクリアされた
  • logout - ユーザーがログアウトした
  • prompt_input_exit - プロンプト入力が表示されている間にユーザーが終了した
  • other - その他の終了理由

フック入力

フックは、セッション情報とイベント固有のデータを含むJSONデータをstdinを通じて受信します:
{
  // Common fields
  session_id: string
  transcript_path: string  // Path to conversation JSON
  cwd: string              // The current working directory when the hook is invoked
  permission_mode: string  // Current permission mode: "off", "spec", "auto-low", "auto-medium", or "auto-high"

  // Event-specific fields
  hook_event_name: string
  ...
}

PreToolUse入力

tool_inputの正確なスキーマはツールに依存します。
{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "PreToolUse",
  "tool_name": "Create",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  }
}

PostToolUse入力

tool_inputtool_responseの正確なスキーマはツールに依存します。
{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "PostToolUse",
  "tool_name": "Create",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  },
  "tool_response": {
    "filePath": "/path/to/file.txt",
    "success": true
  }
}

Notification入力

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "Notification",
  "message": "Task completed successfully"
}

UserPromptSubmit入力

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "UserPromptSubmit",
  "prompt": "Write a function to calculate the factorial of a number"
}

StopおよびSubagentStop入力

stop_hook_activeは、ストップフックの結果としてDroidがすでに継続している場合にtrueになります。この値をチェックするか、トランスクリプトを処理してDroidが無限に実行されるのを防いでください。
{
  "session_id": "abc123",
  "transcript_path": "~/.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "Stop",
  "stop_hook_active": true
}

PreCompact入力

manualの場合、custom_instructionsはユーザーが/compactに渡すものから来ます。autoの場合、custom_instructionsは空です。
{
  "session_id": "abc123",
  "transcript_path": "~/.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "PreCompact",
  "trigger": "manual",
  "custom_instructions": ""
}

SessionStart入力

{
  "session_id": "abc123",
  "transcript_path": "~/.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "SessionStart",
  "source": "startup"
}

SessionEnd入力

{
  "session_id": "abc123",
  "transcript_path": "~/.factory/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "off",
  "hook_event_name": "SessionEnd",
  "reason": "other"
}

フック出力

フックがDroidに出力を返す方法は2つあります。出力は、ブロックするかどうかと、Droidとユーザーに表示すべきフィードバックを伝えます。

シンプル:終了コード

フックは終了コード、stdout、stderrを通じて状態を伝えます:
  • 終了コード0:成功。stdoutはトランスクリプトモード(CTRL-R)でユーザーに表示されますが、UserPromptSubmitSessionStartでは例外で、stdoutがコンテキストに追加されます。
  • 終了コード2:ブロッキングエラー。stderrはDroidに自動的に処理するためにフィードバックされます。以下のフックイベント別の動作を参照してください。
  • その他の終了コード:非ブロッキングエラー。stderrがユーザーに表示され、実行は継続されます。
注意: 終了コードが0の場合、UserPromptSubmitフックを除いてDroidはstdoutを確認しません。 UserPromptSubmitフックではstdoutがコンテキストとして注入されます。

終了コード2の動作

フックイベント動作
PreToolUseツール呼び出しをブロックし、stderrをDroidに表示
PostToolUsestderrをDroidに表示(ツールはすでに実行済み)
NotificationN/A、stderrをユーザーのみに表示
UserPromptSubmitプロンプト処理をブロック、プロンプトを消去、stderrをユーザーのみに表示
Stop停止をブロック、stderrをDroidに表示
SubagentStop停止をブロック、stderrをサブdroidに表示
PreCompactN/A、stderrをユーザーのみに表示
SessionStartN/A、stderrをユーザーのみに表示
SessionEndN/A、stderrをユーザーのみに表示

上級:JSON出力

フックは、より洗練された制御のためにstdoutで構造化JSONを返すことができます:

共通JSONフィールド

すべてのフックタイプは以下のオプションフィールドを含めることができます:
{
  "continue": true, // Whether Droid should continue after hook execution (default: true)
  "stopReason": "string", // Message shown when continue is false

  "suppressOutput": true, // Hide stdout from transcript mode (default: false)
  "systemMessage": "string" // Optional warning message shown to the user
}
continueがfalseの場合、Droidはフック実行後に処理を停止します。
  • PreToolUseの場合、これは"permissionDecision": "deny"とは異なり、特定のツール呼び出しのみをブロックしてDroidに自動フィードバックを提供します。
  • PostToolUseの場合、これは"decision": "block"とは異なり、Droidに自動フィードバックを提供します。
  • UserPromptSubmitの場合、これはプロンプトの処理を防ぎます。
  • StopSubagentStopの場合、これは任意の"decision": "block"出力より優先されます。
  • すべての場合において、"continue" = falseは任意の"decision": "block"出力より優先されます。
stopReasoncontinueに付随し、ユーザーに表示される理由を示しますが、Droidには表示されません。

PreToolUse決定制御

PreToolUseフックはツール呼び出しを実行するかどうかを制御できます。
  • "allow"は許可システムをバイパスします。permissionDecisionReasonはユーザーに表示されますが、Droidには表示されません。
  • "deny"はツール呼び出しの実行を防ぎます。permissionDecisionReasonはDroidに表示されます。
  • "ask"はUIでツール呼び出しの確認をユーザーに求めます。permissionDecisionReasonはユーザーに表示されますが、Droidには表示されません。
さらに、フックはupdatedInputを使用して実行前にツール入力を変更できます:
  • updatedInputにより、ツールが実行される前にツールの入力パラメータを変更できます。これは変更または追加したいフィールドを含むRecord<string, unknown>オブジェクトです。
  • これは"permissionDecision": "allow"と組み合わせてツール呼び出しを変更および承認する際に最も有用です。
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "My reason here",
    "updatedInput": {
      "field_to_modify": "new value"
    }
  }
}
PreToolUseフックではdecisionフィールドとreasonフィールドは非推奨です。 hookSpecificOutput.permissionDecisionと 代わりにhookSpecificOutput.permissionDecisionReasonを使用してください。非推奨フィールド "approve""block"はそれぞれ"allow""deny"にマッピングされます。

PostToolUse決定制御

PostToolUseフックはツール実行後にDroidにフィードバックを提供できます。
  • "block"は自動的にDroidにreasonでプロンプトします。
  • undefinedは何もしません。reasonは無視されます。
  • "hookSpecificOutput.additionalContext"はDroidが考慮するコンテキストを追加します。
{
  "decision": "block" | undefined,
  "reason": "Explanation for decision",
  "hookSpecificOutput": {
    "hookEventName": "PostToolUse",
    "additionalContext": "Additional information for Droid"
  }
}

UserPromptSubmit決定制御

UserPromptSubmitフックはユーザープロンプトが処理されるかどうかを制御できます。
  • "block"はプロンプトの処理を防ぎます。送信されたプロンプトはコンテキストから消去されます。"reason"はユーザーに表示されますが、コンテキストには追加されません。
  • undefinedはプロンプトを正常に続行させます。"reason"は無視されます。
  • "hookSpecificOutput.additionalContext"はブロックされない場合に文字列をコンテキストに追加します。
{
  "decision": "block" | undefined,
  "reason": "Explanation for decision",
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "My additional context here"
  }
}

Stop/SubagentStop決定制御

StopSubagentStopフックはDroidが継続する必要があるかどうかを制御できます。
  • "block"はDroidの停止を防ぎます。Droidが続行方法を知るためにreasonを入力する必要があります。
  • undefinedはDroidの停止を許可します。reasonは無視されます。
{
  "decision": "block" | undefined,
  "reason": "Must be provided when Droid is blocked from stopping"
}

SessionStart決定制御

SessionStartフックにより、セッション開始時にコンテキストを読み込むことができます。
  • "hookSpecificOutput.additionalContext"は文字列をコンテキストに追加します。
  • 複数のフックのadditionalContext値が連結されます。
{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "additionalContext": "My additional context here"
  }
}

SessionEnd決定制御

SessionEndフックはセッション終了時に実行されます。セッション終了をブロックすることはできませんが、クリーンアップタスクを実行できます。

終了コード例:Executeコマンド検証

#!/usr/bin/env python3
import json
import re
import sys

# Define validation rules as a list of (regex pattern, message) tuples
VALIDATION_RULES = [
    (
        r"\bgrep\b(?!.*\|)",
        "Use 'rg' (ripgrep) instead of 'grep' for better performance and features",
    ),
    (
        r"\bfind\s+\S+\s+-name\b",
        "Use 'rg --files | rg pattern' or 'rg --files -g pattern' instead of 'find -name' for better performance",
    ),
]


def validate_command(command: str) -> list[str]:
    issues = []
    for pattern, message in VALIDATION_RULES:
        if re.search(pattern, command):
            issues.append(message)
    return issues


try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")

if tool_name != "Execute" or not command:
    sys.exit(1)

# Validate the command
issues = validate_command(command)

if issues:
    for message in issues:
        print(f"• {message}", file=sys.stderr)
    # Exit code 2 blocks tool call and shows stderr to Droid
    sys.exit(2)

JSON出力例:コンテキスト追加と検証のためのUserPromptSubmit

UserPromptSubmitフックでは、どちらの方法でもコンテキストを注入できます:
  • stdout付きの終了コード0: Droidがコンテキストを確認します(UserPromptSubmitの特別なケース)
  • JSON出力: 動作をより細かく制御できます
#!/usr/bin/env python3
import json
import sys
import re
import datetime

# Load input from stdin
try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

prompt = input_data.get("prompt", "")

# Check for sensitive patterns
sensitive_patterns = [
    (r"(?i)\b(password|secret|key|token)\s*[:=]", "Prompt contains potential secrets"),
]

for pattern, message in sensitive_patterns:
    if re.search(pattern, prompt):
        # Use JSON output to block with a specific reason
        output = {
            "decision": "block",
            "reason": f"Security policy violation: {message}. Please rephrase your request without sensitive information."
        }
        print(json.dumps(output))
        sys.exit(0)

# Add current time to context
context = f"Current time: {datetime.datetime.now()}"
print(context)

"""
The following is also equivalent:
print(json.dumps({
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": context,
  },
}))
"""

# Allow the prompt to proceed with the additional context
sys.exit(0)

JSON出力例:承認付きPreToolUse

#!/usr/bin/env python3
import json
import sys

# Load input from stdin
try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})

# Example: Auto-approve file reads for documentation files
if tool_name == "Read":
    file_path = tool_input.get("file_path", "")
    if file_path.endswith((".md", ".mdx", ".txt", ".json")):
        # Use JSON output to auto-approve the tool call
        output = {
            "decision": "approve",
            "reason": "Documentation file auto-approved",
            "suppressOutput": True  # Don't show in transcript mode
        }
        print(json.dumps(output))
        sys.exit(0)

# For other cases, let the normal permission flow proceed
sys.exit(0)

MCPツールとの連携

DroidフックはModel Context Protocol (MCP) toolsとシームレスに動作します。MCPサーバーがツールを提供する場合、フックでマッチできる特別な命名パターンで表示されます。

MCPツールの命名

MCPツールはmcp__<server>__<tool>のパターンに従います。例:
  • mcp__memory__create_entities - Memoryサーバーのcreate entitiesツール
  • mcp__filesystem__read_file - Filesystemサーバーのread fileツール
  • mcp__github__search_repositories - GitHubサーバーのsearchツール

MCPツール用フックの設定

特定のMCPツールまたはMCPサーバー全体をターゲットにできます:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__memory__.*",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Memory operation initiated' >> ~/mcp-operations.log"
          }
        ]
      },
      {
        "matcher": "mcp__.*__write.*",
        "hooks": [
          {
            "type": "command",
            "command": "/home/user/scripts/validate-mcp-write.py"
          }
        ]
      }
    ]
  }
}

コード整形、通知、ファイル保護などの実践的な例は、入門ガイドのその他の例を参照してください。

セキュリティに関する考慮事項

免責事項

自己責任で使用してください:Droidフックはシステム上で任意のシェルコマンドを自動的に実行します。フックを使用することにより、以下について承認したものとします:
  • 設定するコマンドについて全責任を負う
  • フックはユーザーアカウントがアクセスできる任意のファイルを変更、削除、アクセスできる
  • 悪意のあるまたは不適切に記述されたフックは、データ損失やシステム損傷を引き起こす可能性がある
  • Factory AIは一切の保証を提供せず、フック使用によるいかなる損害についても責任を負わない
  • 本番環境で使用する前に、安全な環境でフックを十分にテストすべきである
設定に追加する前に、フックコマンドを必ず確認し理解してください。

セキュリティのベストプラクティス

より安全なフックを記述するための主要な実践事項:
  1. 入力の検証とサニタイズ - 入力データを盲目的に信頼しない
  2. シェル変数を常にクォートする - $VARではなく"$VAR"を使用
  3. パストラバーサルをブロック - ファイルパスの..をチェック
  4. 絶対パスを使用 - スクリプトには常に完全パスを指定。Droidの現在ディレクトリに応じて不正に解決される可能性があるため、./script.shhooks/script.shなどの相対パスは使用しない。プロジェクトスクリプトには"$FACTORY_PROJECT_DIR"/path/to/script.shを使用するか、グローバルスクリプトには/usr/local/bin/script.sh~/.factory/hooks/script.shなどの完全パスを使用する。
  5. 機密ファイルをスキップ - .env.git/、キーなどを避ける

設定の安全性

設定ファイル内のフックの直接編集は即座に有効になりません。Droid:
  1. スタートアップ時にフックのスナップショットをキャプチャ
  2. セッション全体でこのスナップショットを使用
  3. フックが外部で変更された場合に警告
  4. 変更を適用するために/hooksメニューでのレビューが必要
これにより、悪意のあるフック変更が現在のセッションに影響することを防ぎます。

フック実行の詳細

  • タイムアウト:デフォルトで60秒の実行制限、コマンドごとに設定可能
    • 個別のコマンドのタイムアウトは他のコマンドに影響しません
  • 並列化:マッチするすべてのフックが並列で実行
  • 重複排除:同一のフックコマンドが複数ある場合は自動的に重複排除
  • 環境:Droidの環境で現在のディレクトリで実行
    • FACTORY_PROJECT_DIR環境変数が利用可能で、プロジェクトルートディレクトリ(Droidが開始された場所)の絶対パスが含まれます
  • 入力:stdinを通じてJSON
  • 出力
    • PreToolUse/PostToolUse/Stop/SubagentStop:トランスクリプト(Ctrl-R)で進行状況表示
    • Notification/SessionEnd:デバッグのみにログ(--debug
    • UserPromptSubmit/SessionStart:stdoutがDroidのコンテキストとして追加

デバッグ

基本的なトラブルシューティング

フックが動作しない場合:
  1. 設定を確認 - /hooksを実行してフックが登録されているか確認
  2. 構文を検証 - JSON設定が有効であることを確認
  3. コマンドをテスト - 最初にフックコマンドを手動で実行
  4. 権限を確認 - スクリプトが実行可能であることを確認
  5. ログを確認 - droid --debugを使用してフック実行の詳細を確認
一般的な問題:
  • クォートがエスケープされていない - JSON文字列内で\"を使用
  • 間違ったマッチャー - ツール名が完全に一致することを確認(大文字小文字を区別)
  • コマンドが見つからない - スクリプトには完全パスを使用

高度なデバッグ

複雑なフックの問題について:
  1. フック実行を検査 - droid --debugを使用して詳細なフック実行を確認
  2. JSONスキーマを検証 - 外部ツールでフック入力/出力をテスト
  3. 環境変数を確認 - Droidの環境が正しいことを確認
  4. エッジケースをテスト - 異常なファイルパスや入力でフックを試行
  5. システムリソースを監視 - フック実行中のリソース枯渇をチェック
  6. 構造化ログを使用 - フックスクリプトにログを実装

デバッグ出力例

droid --debugを使用してフック実行の詳細を確認:
[DEBUG] Executing hooks for PostToolUse:Create
[DEBUG] Getting matching hook commands for PostToolUse with query: Create
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 hooks for query "Create"
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: <Your command> with timeout 60000ms
[DEBUG] Hook command completed with status 0: <Your stdout>
進行状況メッセージはトランスクリプトモード(Ctrl-R)に表示され、以下を示します:
  • 実行中のフック
  • 実行されているコマンド
  • 成功/失敗ステータス
  • 出力またはエラーメッセージ