From claude-code
Configures event-driven hooks (SessionStart, PreToolUse, PostToolUse, Stop) to inject context, block dangerous tool calls, enforce completion standards, and manage lifecycle automation in Claude Code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-code:claude-hooksThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Hooks are shell commands or prompts that Claude Code executes in response to events. They are the only mechanism that can compel behavior — Claude reads memory and skills as guidance, but the harness runs hooks, not Claude.
Hooks are shell commands or prompts that Claude Code executes in response to events. They are the only mechanism that can compel behavior — Claude reads memory and skills as guidance, but the harness runs hooks, not Claude.
| Scope | Path | Use case |
|---|---|---|
| User | ~/.claude/settings.json under hooks | Personal automation across all projects |
| Project | <project>/.claude/settings.json under hooks | Repo-shared automation |
| Plugin | <plugin-root>/hooks/hooks.json | Distribute hooks via plugin install |
| Skill/Subagent | Skill or subagent frontmatter hooks: field | Lifecycle-scoped hooks |
Plugin hooks at <plugin-root>/hooks/hooks.json are auto-discovered. No registration in plugin.json required.
Plugin hooks/hooks.json uses the wrapper format:
{
"description": "Brief explanation of what these hooks do",
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/check.sh",
"timeout": 5
}
]
}
]
}
}
description — optional, surfaced in plugin metadatahooks — required wrapper containing event arraysmatcher — regex of tool names (PreToolUse/PostToolUse) or session lifecycle phases (SessionStart)${CLAUDE_PLUGIN_ROOT} — absolute path to the plugin root, expanded at runtime| Event | When it fires | Common use |
|---|---|---|
SessionStart | Session start, resume, clear | Inject binding context to turn 1 |
SessionEnd | Session ends | Cleanup, telemetry |
UserPromptSubmit | User submits a prompt | Augment prompt, log interaction |
PreToolUse | Before a tool executes | Block dangerous calls, validate input |
PostToolUse | After a tool completes | Format, lint, sync, log |
Stop | Agent finishes responding | Enforce completion standards |
SubagentStop | Spawned subagent finishes | Subagent-specific cleanup |
PreCompact | Before context compaction | Inject context to preserve |
Notification | A notification fires | Custom notification routing |
Execute a shell command. Deterministic, fast.
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
"timeout": 60
}
Send a prompt to a model for context-aware decisions. Slower but flexible.
{
"type": "prompt",
"prompt": "Evaluate if this tool use is appropriate: $TOOL_INPUT",
"timeout": 30
}
Supported events for prompt hooks: Stop, SubagentStop, UserPromptSubmit, PreToolUse.
SessionStart is the strongest compliance mechanism: stdout from the hook script becomes part of the model's first input. Memory and skills inform; SessionStart compels.
Plugin example (plugins/example/hooks/hooks.json):
{
"description": "Inject project conventions at session start",
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh",
"timeout": 5
}
]
}
]
}
}
Companion script (plugins/example/hooks/session-start.sh):
#!/usr/bin/env bash
set -u
cat >/dev/null 2>&1 || true # consume stdin
cat <<'EOF'
[PLUGIN-NAME — SESSION-START COMMAND CONTRACT]
These are commands with triggers, not informational text.
1. Run mise run ci before any commit.
2. Conventional commits, no Co-Authored-By attribution.
3. ...
EOF
The header in the heredoc lands as turn-1 context. Keep it tight — every session pays this token cost.
Exit code from a PreToolUse command hook controls whether the tool runs:
Example — block force-push to main:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/guard-push.sh"
}
]
}
]
}
}
guard-push.sh reads the tool input from stdin (JSON), parses with jq, and exits non-zero on a forbidden pattern.
PostToolUse runs after the tool completes. Exit codes are logged but do not affect the tool result.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/format.sh"
}
]
}
]
}
}
The hook reads the tool input from stdin and runs the formatter on the modified file.
Hook scripts receive event JSON on stdin:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/path/to/project",
"hook_event_name": "PreToolUse",
"tool_name": "Write",
"tool_input": { "file_path": "...", "content": "..." }
}
Parse with jq in the hook script:
file_path=$(jq -r '.tool_input.file_path' < /dev/stdin)
Stdout from SessionStart and UserPromptSubmit hooks is injected into the model's context. Stdout from other events is logged but not surfaced.
PreToolUse/PostToolUse. Set explicit timeout values.${CLAUDE_PLUGIN_ROOT}. Never hardcode plugin paths.jq and exit cleanly on parse failure.Write|Edit over matching all tools.chmod +x after creating shell scripts; the hook will fail silently otherwise.echo '{...}' | bash hooks/script.sh before relying on the hook to fire.jq to parse, never eval.PreToolUse Bash hooks (rm -rf /, dd if=, force-push to protected branches).realpath and verify they remain inside the project root.Validate hook behavior with actual execution before claiming it works. Run the hook script standalone, observe stdin parsing, exit codes, and stdout. Do not assume an event fires without verifying the hook entry in the harness logs.
templates/plugin-hook.md — plugin hooks/hooks.json configuration with PostToolUse, Write|Edit matcher, and ${CLAUDE_PLUGIN_ROOT}templates/skill-hook.md — skill/subagent frontmatter hook example for PreToolUse, PostToolUse, Stopnpx claudepluginhub vinnie357/claude-skills --plugin claude-code2plugins reuse this skill
First indexed Jun 3, 2026
Configures event-driven hooks (SessionStart, PreToolUse, PostToolUse, Stop) to inject context, block dangerous tool calls, enforce completion standards, and manage lifecycle automation in Claude Code.
Guides development of event-driven hooks for Claude Code plugins using prompt-based and command-based configurations in hooks.json for events like PreToolUse, PostToolUse, Stop, and SessionStart to validate tools and automate workflows.
Configures and develops Claude Code hooks for lifecycle events (PreToolUse, PostToolUse, SessionStart, etc.) to automate workflows, enforce best practices, and control permissions.