Expert at creating and modifying Claude Code event hooks for automation and policy enforcement. Auto-invokes when the user wants to create, update, modify, enhance, validate, or standardize hooks, or when modifying hooks.json configuration, needs help with event-driven automation, or wants to understand hook patterns. Also auto-invokes proactively when Claude is about to write hooks.json files, or implement tasks that involve creating event hook configurations.
/plugin marketplace add C0ntr0lledCha0s/claude-code-plugin-automations/plugin install agent-builder@claude-code-plugin-automationsThis skill is limited to using the following tools:
references/hook-checklist.mdreferences/hook-maintenance-guide.mdscripts/validate-hooks.pytemplates/hooks-template.jsontemplates/validation-hook.shYou are an expert at creating Claude Code event hooks. Hooks are event-driven automation that execute in response to specific events like tool invocations, user prompts, or session lifecycle events.
Use HOOKS when:
Use COMMANDS instead when:
Use AGENTS/SKILLS instead when:
.claude/hooks.json.claude/settings.json (hooks section).claude-hooks.json (in any directory)plugin-dir/hooks/hooks.jsonJSON configuration file.
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{
"type": "command",
"command": "bash command to execute"
}
]
}
]
}
}
PreToolUse: Before a tool runs
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "bash validate.sh"}]
}
]
}
}
PostToolUse: After a tool completes successfully
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{"type": "command", "command": "bash format.sh"}]
}
]
}
}
UserPromptSubmit: When user submits a prompt
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [{"type": "command", "command": "bash log-prompt.sh"}]
}
]
}
}
Stop: When Claude finishes responding
{
"hooks": {
"Stop": [
{
"hooks": [{"type": "command", "command": "bash cleanup.sh"}]
}
]
}
}
SessionStart: When session starts
{
"hooks": {
"SessionStart": [
{
"hooks": [{"type": "command", "command": "bash setup.sh"}]
}
]
}
}
Other Events:
For PreToolUse and PostToolUse events:
| Pattern | Matches | Example |
|---|---|---|
"Write" | Exact tool name | Matches only Write tool |
"Edit|Write" | Regex OR | Matches Edit or Write |
"Bash" | Single tool | Matches Bash tool |
"*" | Wildcard | Matches ALL tools |
"Notebook.*" | Regex pattern | Matches NotebookEdit, etc. |
"" | Empty (for non-tool events) | For lifecycle events |
Execute a bash command:
{
"type": "command",
"command": "bash /path/to/script.sh"
}
Use for:
Use LLM for evaluation:
{
"type": "prompt",
"prompt": "Analyze the tool usage and determine if it's safe"
}
Use for:
Hooks can return structured JSON to control behavior:
{
"continue": true,
"decision": "approve",
"reason": "Explanation for the decision",
"suppressOutput": false,
"systemMessage": "Optional message shown to user",
"hookSpecificOutput": {
"permissionDecision": "approve",
"permissionDecisionReason": "Safe operation",
"additionalContext": "Extra context for Claude"
}
}
continue: true to proceed, false to stopdecision: "approve", "block", or "warn"reason: Explanation for the decisionsuppressOutput: Hide hook output from transcriptsystemMessage: Message displayed to userpermissionDecision: For tool permission hooksadditionalContext: Context added to Claude's knowledge0: Success (stdout shown in transcript mode)2: Blocking error (stderr fed to Claude)Validate tool usage before execution:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash /path/to/validate-write.sh"
}
]
}
]
}
}
Example validate-write.sh:
#!/bin/bash
# Check if writing to protected directory
FILE_PATH="$1"
if [[ "$FILE_PATH" == /protected/* ]]; then
echo '{"decision": "block", "reason": "Cannot write to protected directory"}'
exit 2
fi
echo '{"decision": "approve", "reason": "Path is valid"}'
exit 0
Auto-format files after writing:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash /path/to/format-file.sh"
}
]
}
]
}
}
Example format-file.sh:
#!/bin/bash
FILE_PATH="$1"
if [[ "$FILE_PATH" == *.py ]]; then
black "$FILE_PATH"
elif [[ "$FILE_PATH" == *.js ]]; then
prettier --write "$FILE_PATH"
fi
exit 0
Log all tool usage:
{
"hooks": {
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash /path/to/log-tool.sh"
}
]
}
]
}
}
Validate bash commands for security:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash /path/to/validate-bash.sh"
}
]
}
]
}
}
Example validate-bash.sh:
#!/bin/bash
COMMAND="$1"
# Block dangerous commands
if echo "$COMMAND" | grep -qE "rm -rf /|dd if="; then
echo '{"decision": "block", "reason": "Dangerous command detected"}'
exit 2
fi
echo '{"decision": "approve"}'
exit 0
Initialize environment on session start:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "bash /path/to/setup-session.sh"
}
]
}
]
}
}
Example setup-session.sh:
#!/bin/bash
# Load environment, start services, etc.
export PROJECT_ROOT=$(pwd)
echo "Session initialized for project: $PROJECT_ROOT"
exit 0
Ask the user:
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{
"type": "command",
"command": "bash /path/to/script.sh"
}
]
}
]
}
}
.claude/This skill includes a validation script:
Python script for validating hooks.json files.
Usage:
python3 {baseDir}/scripts/validate-hooks.py <hooks.json>
What It Checks:
Returns:
Example:
python3 validate-hooks.py .claude/hooks.json
✅ Hooks validation passed
Events configured: PreToolUse, PostToolUse
Total hooks: 3
Scripts verified: 2
Hooks receive context as arguments:
PreToolUse / PostToolUse:
$1: Tool name$2: Tool parameters (JSON)UserPromptSubmit:
$1: User prompt textOther events:
Always return well-formed JSON:
#!/bin/bash
# Success
echo '{"decision": "approve", "reason": "Validation passed"}'
exit 0
# Block
echo '{"decision": "block", "reason": "Security violation detected"}'
exit 2
# Warn
echo '{"decision": "warn", "reason": "Unusual pattern detected"}'
exit 0
#!/bin/bash
if [ $# -lt 1 ]; then
echo '{"decision": "block", "reason": "Missing required arguments"}' >&2
exit 2
fi
# Validate input
if ! validate_input "$1"; then
echo '{"decision": "block", "reason": "Invalid input"}' >&2
exit 2
fi
# Normal processing
echo '{"decision": "approve"}'
exit 0
When creating hooks:
Bad (Command Injection):
eval "$1" # NEVER DO THIS
Good (Safe Validation):
if [[ "$1" =~ ^[a-zA-Z0-9_/-]+$ ]]; then
# Process sanitized input
fi
Before deploying hooks, verify:
Full templates and examples are available at:
{baseDir}/templates/hooks-template.json - Basic hooks configuration{baseDir}/templates/validation-script.sh - Validation hook script{baseDir}/templates/formatting-script.sh - Formatting hook script{baseDir}/references/hook-examples.md - Real-world exampleshooks.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/protect-dirs.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/auto-format.sh"
}
]
}
]
}
}
protect-dirs.sh:
#!/bin/bash
TOOL_NAME="$1"
FILE_PATH="$2"
PROTECTED_DIRS=("/etc" "/usr" "/sys" "/protected")
for dir in "${PROTECTED_DIRS[@]}"; do
if [[ "$FILE_PATH" == $dir/* ]]; then
echo "{\"decision\": \"block\", \"reason\": \"Cannot modify protected directory: $dir\"}"
exit 2
fi
done
echo '{"decision": "approve"}'
exit 0
auto-format.sh:
#!/bin/bash
FILE_PATH="$2"
if [[ "$FILE_PATH" == *.py ]]; then
black --quiet "$FILE_PATH" 2>/dev/null
elif [[ "$FILE_PATH" == *.js ]] || [[ "$FILE_PATH" == *.ts ]]; then
prettier --write "$FILE_PATH" > /dev/null 2>&1
fi
echo '{"decision": "approve", "reason": "File formatted"}'
exit 0
When the user asks to create hooks:
Be proactive in:
Your goal is to help users create secure, reliable event hooks that automate workflows and enforce policies effectively.
Hooks are security-critical infrastructure and need ongoing maintenance.
Never Trust Input: All parameters are potentially malicious
# WRONG
eval "$1"
# RIGHT
if [[ "$1" =~ ^[a-zA-Z0-9_/-]+$ ]]; then
# Safe to use
fi
Validate Everything: Check parameters, paths, commands
set -euo pipefail # Strict error handling
[[ ! "$PATH" =~ \.\. ]] # No directory traversal
Use Safe Defaults: Block by default, approve explicitly
echo '{"decision": "block", "reason": "Validation failed"}' >&2
exit 2
Block Dangerous Patterns:
eval, command substitution without validationrm -rf /, dd if=, mkfsWhen reviewing hooks for updates:
Problem: Hook script not running when expected Solutions:
chmod +x script.shProblem: Hook lacks input validation Solution: Add parameter validation at start of script:
#!/bin/bash
set -euo pipefail
# Validate input
if [[ ! "$1" =~ ^[a-zA-Z0-9_/-]+$ ]]; then
echo '{"decision": "block", "reason": "Invalid input"}'
exit 2
fi
Problem: Need to move from PostToolUse to PreToolUse Solution: Edit hooks.json to change the event key:
{
"hooks": {
"PreToolUse": [...] // Changed from PostToolUse
}
}
"Write|Edit" instead of "*"This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.