Agent skill
hook-development
Create, validate, and audit event-driven hooks for intercepting events, enforcing security patterns, and automating interventions. Use when building or reviewing hooks, implementing event handlers, or adding safety guardrails. Includes matcher patterns, action types, timeout configuration, and security enforcement. Not for manual actions, passive knowledge, or non-event-driven automation.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/hook-development-git-fg-meta-plugin-manager
SKILL.md
<mission_control> Create event-driven hooks that intercept operations and enforce security patterns <success_criteria>Generated hook has valid matcher, action type, and timeout configuration</success_criteria> </mission_control>
<interaction_schema> event_analysis → matcher_design → action_definition → security_review → output</interaction_schema>
Hook Development
Skill Location: This file
Quick Start
Create hook: Follow matcher + action structure with timeout configuration
Review hook: Use quality-standards skill → Apply security patterns
Test matcher: Verify with Bash command before deployment
Why: Hooks intercept operations at runtime—prevention is more valuable than post-hoc correction.
Critical Reference Loading
Key Reference: references/pattern_advanced.md contains critical event handling patterns. Read in full when implementing complex hooks—partial understanding leads to runtime errors.
Navigation
| If you need... | Read... |
|---|---|
| Create hook | ## Implementation Patterns |
| Review hook quality | Use quality-standards skill |
| Test matcher | See Bash examples in this file |
| Event matcher patterns | references/pattern_advanced.md |
| Security anti-patterns | references/lookup_quality.md |
| Migration guidance | references/workflow_migration.md |
External References
- Hooks Reference - Complete API documentation
- Hooks Guide - Getting started tutorial
System Requirements
- Hook config: JSON format with
matcher+hooksarray - Action types:
prompt(requires user confirmation) orcommand(silent blocking) - Timeout: Required for
prompthooks (prevents blocking operations) - Matcher syntax:
"Bash","Write|Edit","*", or regex patterns (tool names only) - Portability: Use project-relative paths, no hardcoded environment paths
Operational Patterns
This skill follows these behavioral patterns:
- Planning: Switch to planning mode for architectural decisions
- Discovery: Locate files matching patterns and search file contents for hook integration points
- Delegation: Delegate planning and exploration to specialized workers
- Tracking: Maintain a visible task list for hook development
<critical_constraint> Use native tools to fulfill these patterns. The System Prompt selects the correct implementation for semantic directives. </critical_constraint>
Implementation Patterns
Pattern: Destructive Operation Block
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/scripts/rm-safety.sh"
}
]
}
See scripts/rm-safety.sh for portable rm -rf and path traversal blocking.
Pattern: Project-Specific Dangerous Commands
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/scripts/dangerous-commands.sh"
}
]
}
See scripts/dangerous-commands.sh for project-specific patterns. Edit this file to add/remove patterns without modifying hook logic.
Pattern: Sudo Confirmation
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'Sudo requires explicit confirmation.'"
}
]
}
Pattern: Protected File Guard
if [[ "$file_path" == *".env"* ]]; then
echo '{"decision": "deny", "reason": "Protected file"}' >&2
exit 2
fi
Troubleshooting
| Issue | Symptom | Solution |
|---|---|---|
| Broad match blocking all operations | Matcher "*" or overly generic |
Target specific tool + dangerous args |
| User confused why operation failed | Silent block with no explanation | Use prompt type with clear message |
| Hook blocking forever | Missing timeout on prompt hook | Add timeout: 30 or similar |
| Hook failing on different machines | Hardcoded paths like /home/user/ |
Use project-relative paths with ${CLAUDE_PROJECT_DIR} |
| Variable injection vulnerability | Unquoted variables with spaces | Always quote variables: "$file_path" |
| Security bypass | No confirmation for destructive ops | Add prompt hook with confirmation requirement |
Hooks are event-driven automation that intercept operations before execution. They provide safety mechanisms, enforce patterns, and enable automated intervention based on event matching.
Core principle: Hooks must be event-specific, security-conscious, and provide clear intervention logic.
What Hooks Are
Hooks provide:
- Event interception: Pre-execution validation and control
- Safety mechanisms: Prevent destructive operations
- Pattern enforcement: Ensure compliance with standards
- Automated intervention: Proactive issue prevention
- Security controls: Authentication and authorization checks
Hook Architecture
Event-Driven: Hooks respond to specific events (Bash commands, tool usage, file operations)
Two-Phase Operation:
- Matcher: Identifies target events
- Action: Executes intervention logic
Core Structure
Hook Configuration
{
"hooks": {
"[EventName]": [
{
"matcher": "Event matching criteria",
"hooks": [
{
"type": "prompt" | "command",
"prompt": "Intervention message or validation",
"timeout": 30
}
]
}
]
}
}
Hook Body
- Event identification: What events to intercept
- Matching logic: How to identify target operations
- Intervention strategy: What action to take
- Security implications: Safety and risk considerations
- Timeout handling: Prevention of blocking operations
Common Mistakes to Avoid
Mistake 1: The Broad Match
❌ Wrong:
"matcher": "*"
Generates noise and blocks legitimate operations.
✅ Correct:
"matcher": "Bash"
Then filter inside the script using the JSON input from stdin.
Mistake 2: The Silent Block
❌ Wrong:
"type": "command",
"command": "exit 1"
User sees generic failure with no guidance.
✅ Correct:
"type": "prompt",
"prompt": "Destructive rm -rf detected. This cannot be undone. Type 'DELETE' to confirm.",
"timeout": 30
Mistake 3: The Missing Timeout
❌ Wrong:
"type": "prompt"
Operations without timeouts can deadlock the system.
✅ Correct:
"type": "prompt",
"prompt": "Confirm destructive operation",
"timeout": 30
Mistake 4: The Hardcoded Path
❌ Wrong:
"command": "/home/user/scripts/validate.sh"
Fails when team members have different home directories.
✅ Correct:
"command": "bash ${CLAUDE_PROJECT_DIR}/.claude/scripts/validate.sh"
Mistake 5: The Unquoted Variable
❌ Wrong:
rm -rf $file_path
Injection risk with spaces or special chars.
✅ Correct:
rm -rf "$file_path"
Correct Patterns
Prompt for destructive operations:
{
"matcher": "Bash",
"hooks": [
{
"type": "prompt",
"prompt": "rm -rf detected. This cannot be undone. Type 'DELETE' to confirm.",
"timeout": 30
}
]
}
Block sudo with clear message:
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'Sudo requires explicit confirmation. Remove this block if needed.'"
}
]
}
Protect sensitive files:
# Check for .env before allowing operations
if [[ "$file_path" == *".env"* ]]; then
echo '{"decision": "deny", "reason": "Protected file"}' >&2
exit 2
fi
Validation Checklist
Before claiming hook development complete:
Matcher Design:
- Matcher targets specific tool + dangerous operation
- Avoided broad matches like
"*" - Tested to catch intended operations without false positives
Action Configuration:
- Used
prompttype for destructive operations requiring confirmation - Used
commandtype for clear blocking with explanation - Timeout set on prompt hooks (prevents blocking)
Security:
- Destructive operations require explicit confirmation
- Protected files (
.env, credentials) have special handling - Variables properly quoted to prevent injection
Portability:
- Used project-relative paths with
${CLAUDE_PROJECT_DIR} - No hardcoded environment paths
- Works across different team member environments
Team Collaboration Best Practices
Shared vs Personal Hooks
Team-wide hooks (.claude/settings.json):
- Committed to version control
- Enforce project standards across team
- Security policies, quality gates
- Build/test requirements
Personal hooks (.claude/settings.local.json):
- Gitignored (add to
.gitignore) - Personal development preferences
- Local debugging tools
- Custom workflow automation
Hook Independence
Design hooks assuming parallel execution:
- Hooks don't see each other's output
- No ordering guarantees
- Each hook should be independently useful
- Avoid duplicate functionality across team and personal hooks
Best Practices Summary
✅ DO:
- Target specific tool + dangerous args in matchers
- Use
prompttype for destructive operations - Set
timeout: 30on all prompt hooks - Use project-relative paths with
${CLAUDE_PROJECT_DIR} - Quote all variables in bash commands
- Explain clearly what was detected and why
❌ DON'T:
- Use broad matches like
"*"that block everything - Use silent
commandblocks without explanation - Omit timeout values on prompt hooks
- Hardcode paths like
/home/user/ - Leave variables unquoted
- Skip confirmation for destructive operations
Advanced Hooks Best Practices
- Keep hooks independent: Don't rely on execution order
- Use timeouts: Set appropriate limits for each hook type
- Handle errors gracefully: Provide clear error messages
- Document complexity: Explain advanced patterns in project README
- Test thoroughly: Cover edge cases and failure modes
- Monitor performance: Track hook execution time
- Version configuration: Commit hook configs to git
- Provide escape hatches: Allow bypass via flag files when needed
Common Pitfalls to Avoid
❌ Assuming Hook Order
# BAD: Assumes hooks run in specific order
# Hook 1 saves state, Hook 2 reads it
# This can fail because hooks run in parallel!
❌ Long-Running Hooks
# BAD: Hook takes 2 minutes to run
sleep 120
# This will timeout and block the workflow
❌ Uncaught Exceptions
# BAD: Script crashes on unexpected input
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
cat "$file_path" # Fails if file doesn't exist
✅ Proper Error Handling
# GOOD: Handles errors gracefully
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
if [ ! -f "$file_path" ]; then
echo '{"continue": true, "systemMessage": "File not found, skipping check"}' >&2
exit 0
fi
Genetic Code
This component carries essential Seed System principles for context: fork isolation:
<critical_constraint>
Portability invariant: The skill must function without CLAUDE.md, CLAUDE.local.md, or .claude/rules/ dependencies. Core patterns are self-contained in SKILL.md and references/. Optional external tooling (jq, bash) is assumed available in standard environments. Never use relative paths pointing outside the skill itself. When referencing other components, use: "invoke skill-name" or "invoke skill-name and read its file".
Achieve 80-95% autonomy (0-5 AskUserQuestion rounds per session).
Use What-When-Not-Includes format in descriptions (third person).
Progressive disclosure: SKILL.md contains core philosophy; references/ contains detailed content.
Use XML for control (mission_control, critical_constraint), Markdown for data.
</critical_constraint>
Delta Standard: Good Component = Expert Knowledge − What Claude Already Knows
Recognition Questions
| Question | Recognition |
|---|---|
| Would Claude know this without being told? | Delete (zero delta) |
| Can this work standalone? | Fix if no (non-self-sufficient) |
| Did I read the actual file, or just see it in grep? | Verify before claiming |
Validation Checklist
Before claiming hook development complete:
- Matcher targets specific tools
- User communication is clear
- Timeout protection configured
- Paths are project-relative
The Path to High-Quality Hooks
1. Precise Matcher Design
Hooks work reliably when matchers target specific tools rather than broad patterns.
- Target specifically: Match tool name (e.g.,
"Bash"), then filter inside script - Avoid broad matches: Generic
"*"matchers block legitimate operations - Test thoroughly: Verify matchers catch intended operations without false positives
2. Clear User Communication
Hooks succeed when users understand why operations are blocked.
- Prompt type for confirmation: Use
type: "prompt"for destructive operations requiring user consent - Command type for clear blocks: Use
type: "command"with explanation messages - Explain clearly: Describe what was detected and why it matters
3. Timeout Protection
Hooks prevent system blocking when timeout values are properly configured.
- Always set timeouts:
timeout: 30or similar prevents indefinite waiting - Prevent deadlocks: Operations without timeouts can hang the entire system
- Reasonable defaults: 30 seconds works for most confirmation prompts
4. Portability Through Relative Paths
Hooks work across environments when paths are project-relative.
- Use
${CLAUDE_PROJECT_DIR}: Instead of hardcoded paths like/home/user/ - Environment variables: Externalize configuration for different machines
- Team compatibility: Project-relative paths work across different home directories
5. Variable Safety
Hooks prevent injection vulnerabilities when variables are properly quoted.
- Always quote variables:
"$file_path"instead of$file_path - Prevent injection: Unquoted variables with spaces cause security issues
- Bash best practices: Use
[[ ]]for tests and quote all expansions
6. Security-First Design
Hooks protect systems when safety mechanisms are properly implemented.
- Destructive operation confirmation:
rm -rf,sudo, and similar commands require explicit approval - Protected file guards:
.env, credentials, and config files need special handling - Escape hatches: Provide emergency override mechanisms for legitimate operations
<critical_constraint> System Physics:
- Zero external dependencies (portability invariant)
- Hooks require timeout values to prevent blocking operations
- Prompt hooks for user confirmation, command hooks for clear blocking
- Completion claims require verification evidence </critical_constraint>
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?