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)