File size: 3,677 Bytes
7f0ec95 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | # 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:**
```bash
./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:**
```bash
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:**
```bash
./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:**
```bash
# 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:**
```bash
./hook-linter.sh <hook-script.sh> [hook-script2.sh ...]
```
**Checks:**
- Shebang presence
- `set -euo pipefail` usage
- 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:**
```bash
# Lint single script
./hook-linter.sh ../examples/validate-write.sh
# Lint multiple scripts
./hook-linter.sh ../examples/*.sh
```
## Typical Workflow
1. **Write your hook script**
```bash
vim my-plugin/scripts/my-hook.sh
```
2. **Lint the script**
```bash
./hook-linter.sh my-plugin/scripts/my-hook.sh
```
3. **Create test input**
```bash
./test-hook.sh --create-sample PreToolUse > test-input.json
# Edit test-input.json as needed
```
4. **Test the hook**
```bash
./test-hook.sh -v my-plugin/scripts/my-hook.sh test-input.json
```
5. **Add to hooks.json**
```bash
# Edit my-plugin/hooks/hooks.json
```
6. **Validate configuration**
```bash
./validate-hook-schema.sh my-plugin/hooks/hooks.json
```
7. **Test in Claude Code**
```bash
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
|