Adding Hooks

Hooks are automated actions that run at specific points in the development session.

Hook Events

Event When It Fires
SessionStart When a Claude Code session begins
SessionEnd When a session ends
PostToolUse After a tool (Write, Edit, Bash, etc.) completes
PreToolUse Before a tool executes
Stop When Claude finishes responding

Adding a New Hook

Edit hooks/hooks.json to add a new hook entry:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${CLAUDE_PLUGIN_ROOT}/scripts/my-script.ps1\"",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Writing Hook Scripts

Scripts receive JSON on stdin with the hook context. Create PowerShell scripts in scripts/:

# Read hook payload
$input_json = [Console]::In.ReadToEnd()
$hookData = $input_json | ConvertFrom-Json

# Extract file path from tool input
$filePath = $hookData.tool_input.file_path

# Your logic here...

# Exit codes:
# 0 = success (silent)
# 1 = error (blocks the operation)
# 2 = non-blocking message (displayed to user)
exit 0

Best Practices

  • Keep hooks fast — they run on every tool use
  • Use exit code 2 for non-blocking warnings, not exit code 1
  • Use ${CLAUDE_PLUGIN_ROOT} to reference files relative to the prompt collection
  • Set reasonable timeouts (30s for format, 60s for build)

This site uses Just the Docs, a documentation theme for Jekyll.