3.6 KiB
3.6 KiB
Hook Development Utility Scripts
These scripts help validate, test, and lint hook implementations before deployment.
validate-hook-schema.sh
Validates hooks.json configuration files for correct structure and common issues.
Usage:
./validate-hook-schema.sh path/to/hooks.json
Checks:
- Valid JSON syntax
- Required fields present
- Valid hook event names
- Proper hook types (command/prompt)
- Timeout values in valid ranges
- Hardcoded path detection
- Prompt hook event compatibility
Example:
cd my-plugin
./validate-hook-schema.sh hooks/hooks.json
test-hook.sh
Tests individual hook scripts with sample input before deploying to Claude Code.
Usage:
./test-hook.sh [options] <hook-script> <test-input.json>
Options:
-v, --verbose- Show detailed execution information-t, --timeout N- Set timeout in seconds (default: 60)--create-sample <event-type>- Generate sample test input
Example:
# Create sample test input
./test-hook.sh --create-sample PreToolUse > test-input.json
# Test a hook script
./test-hook.sh my-hook.sh test-input.json
# Test with verbose output and custom timeout
./test-hook.sh -v -t 30 my-hook.sh test-input.json
Features:
- Sets up proper environment variables (CLAUDE_PROJECT_DIR, CLAUDE_PLUGIN_ROOT)
- Measures execution time
- Validates output JSON
- Shows exit codes and their meanings
- Captures environment file output
hook-linter.sh
Checks hook scripts for common issues and best practices violations.
Usage:
./hook-linter.sh <hook-script.sh> [hook-script2.sh ...]
Checks:
- Shebang presence
set -euo pipefailusage- Stdin input reading
- Proper error handling
- Variable quoting (injection prevention)
- Exit code usage
- Hardcoded paths
- Long-running code detection
- Error output to stderr
- Input validation
Example:
# Lint single script
./hook-linter.sh ../examples/validate-write.sh
# Lint multiple scripts
./hook-linter.sh ../examples/*.sh
Typical Workflow
-
Write your hook script
vim my-plugin/scripts/my-hook.sh -
Lint the script
./hook-linter.sh my-plugin/scripts/my-hook.sh -
Create test input
./test-hook.sh --create-sample PreToolUse > test-input.json # Edit test-input.json as needed -
Test the hook
./test-hook.sh -v my-plugin/scripts/my-hook.sh test-input.json -
Add to hooks.json
# Edit my-plugin/hooks/hooks.json -
Validate configuration
./validate-hook-schema.sh my-plugin/hooks/hooks.json -
Test in Claude Code
claude --debug
Tips
- Always test hooks before deploying to avoid breaking user workflows
- Use verbose mode (
-v) to debug hook behavior - Check the linter output for security and best practice issues
- Validate hooks.json after any changes
- Create different test inputs for various scenarios (safe operations, dangerous operations, edge cases)
Common Issues
Hook doesn't execute
Check:
- Script has shebang (
#!/bin/bash) - Script is executable (
chmod +x) - Path in hooks.json is correct (use
${CLAUDE_PLUGIN_ROOT})
Hook times out
- Reduce timeout in hooks.json
- Optimize hook script performance
- Remove long-running operations
Hook fails silently
- Check exit codes (should be 0 or 2)
- Ensure errors go to stderr (
>&2) - Validate JSON output structure
Injection vulnerabilities
- Always quote variables:
"$variable" - Use
set -euo pipefail - Validate all input fields
- Run the linter to catch issues