Help us improve
Share bugs, ideas, or general feedback.
From claude-code
Configures, creates, and troubleshoots Claude Code hooks like PreToolUse, PostToolUse, and UserPromptSubmit for automating tasks such as running tests before file edits or formatting outputs with jq.
npx claudepluginhub bendrucker/claude --plugin claude-codeHow this skill is triggered — by the user, by Claude, or both
Slash command
/claude-code:hookThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Reference for creating and configuring Claude Code hooks. When uncertain about syntax or features, use the Task tool with `subagent_type='claude-code-guide'` to consult official documentation.
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 event-driven hooks for Claude Code to run shell commands before/after tool calls, on lifecycle events, or user prompts for automations and validations.
Guides creation of Claude Code plugin hooks for event-driven automation, including prompt-based and command hooks to validate tool use, enforce policies, and integrate external tools.
Share bugs, ideas, or general feedback.
Reference for creating and configuring Claude Code hooks. When uncertain about syntax or features, use the Task tool with subagent_type='claude-code-guide' to consult official documentation.
| Type | Trigger | Use Cases |
|---|---|---|
| PreToolUse | Before tool execution | Validate inputs, block operations, modify parameters |
| PostToolUse | After tool completes | Check results, run linters, provide feedback |
| UserPromptSubmit | When user sends message | Pre-process input, add context |
| Stop | Session ends | Cleanup, save state |
| SubagentStop | Subagent completes | Process results |
| PreCompact | Before context compaction | Save important state |
| Notification | System notification | Log events |
~/.claude/settings.json - User-level (global).claude/settings.json - Project-level.claude/settings.local.json - Local (not committed)plugins/<name>/hooks/hooks.json{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "bun ./hooks/biome"
}
]
}
]
}
}
Matcher Patterns:
"Write", "Edit""Edit|Write|MultiEdit""Bash(npm:*)", "Bash(osascript:*)|Bash(open:*)""mcp__linear__create_issue""mcp__plugin_<plugin>_<namespace>__<tool>""mcp__claude_ai_<DisplayName>__<tool>""mcp__linear__create_issue|mcp__plugin_linear_linear__create_issue|mcp__claude_ai_Linear__save_issue"Commands receive JSON on stdin:
{
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.ts",
"content": "..."
},
"cwd": "/project/root",
"session_id": "...",
"transcript_path": "..."
}
Parse in shell:
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
Or use @constellos/claude-code-kit/runners:
import { readStdinJson, writeStdoutJson } from "@constellos/claude-code-kit/runners";
const input = await readStdinJson<PreToolUseHookInput>();
PreToolUse - Control execution:
{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": "Use gh cli instead"}}
{"hookSpecificOutput": {"hookEventName": "PreToolUse", "updatedInput": {"state": "Todo"}}}
PostToolUse - Provide feedback:
{"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": "Lint errors found..."}}
Exit with no output to allow without modification.
Store complex hooks in .claude/hooks/ or project hooks/ directory:
.claude/
├── settings.json
└── hooks/
└── my-hook.ts
Reference with:
"command": "bun $CLAUDE_PROJECT_DIR/.claude/hooks/my-hook.ts"
See these repositories for hook implementations:
For troubleshooting hook failures, see debugging.