Files
gh-resolve-io-prism/skills/hooks-manager/reference/examples.md
2025-11-30 08:51:34 +08:00

649 lines
14 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hook Examples Library
Pre-built hook patterns for common use cases. All examples are production-ready and security-reviewed.
**Configuration Format Note:** All JSON examples below show the complete `hooks.json` structure. For plugin hooks (like PRISM), use `${CLAUDE_PLUGIN_ROOT}` in paths. For user-level hooks, use absolute paths.
## Quick Reference
| Example | Event | Purpose | Language |
|---------|-------|---------|----------|
| [bash-command-logger](#bash-command-logger) | PreToolUse | Log all bash commands | Bash + jq |
| [file-protection](#file-protection) | PreToolUse | Block edits to sensitive files | Python |
| [auto-formatter](#auto-formatter) | PostToolUse | Format code on save | Bash |
| [story-context-enforcer](#story-context-enforcer) | PreToolUse | Ensure PRISM story context | Python |
| [workflow-tracker](#workflow-tracker) | PostToolUse | Track workflow progress | Python |
| [desktop-notifier](#desktop-notifier) | Stop | Desktop notifications | Bash |
| [git-safety-guard](#git-safety-guard) | PreToolUse | Prevent dangerous git ops | Python |
| [test-runner](#test-runner) | PostToolUse | Auto-run tests | Bash |
---
## Logging & Auditing
### bash-command-logger
**Purpose**: Log all bash commands for compliance and debugging
**Event**: PreToolUse
**Matcher**: Bash
**Language**: Bash + jq
**Configuration** (`~/.claude/settings.json` for user-level):
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '\"\(.tool_input.command) - \(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
}
]
}
]
}
}
```
**Features**:
- Logs command and description
- Timestamps automatically (file modification time)
- Non-blocking (exit 0)
- Low overhead
**Dependencies**: `jq`
**Install**:
```
*install-example bash-command-logger
```
---
### file-change-tracker
**Purpose**: Track all file modifications with timestamps
**Event**: PostToolUse
**Matcher**: Edit|Write
**Language**: Python
**Hook Script** (`hooks/file-change-tracker.py`):
```python
#!/usr/bin/env python3
import json
import sys
from datetime import datetime
data = json.load(sys.stdin)
file_path = data.get('tool_input', {}).get('file_path', 'unknown')
timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
with open('.file-changes.log', 'a') as f:
f.write(f"{timestamp} | MODIFIED | {file_path}\n")
print(f"✅ Tracked change: {file_path}")
```
**Configuration** (plugin hooks.json):
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/file-change-tracker.py"
}
]
}
]
}
}
```
---
### workflow-auditor
**Purpose**: Comprehensive workflow event logging
**Event**: Multiple (PreToolUse, PostToolUse, Stop)
**Matcher**: *
**Language**: Python
**Features**:
- Logs all tool usage
- Captures exit codes
- Records execution time
- Creates structured audit trail
**Configuration**:
```json
{
"event": "PostToolUse",
"matcher": "*",
"command": "python hooks/workflow-auditor.py"
}
```
---
## Validation & Safety
### file-protection
**Purpose**: Block edits to sensitive files (.env, package-lock.json, .git/)
**Event**: PreToolUse
**Matcher**: Edit|Write
**Language**: Python
**Hook Script** (`hooks/file-protection.py`):
```python
#!/usr/bin/env python3
import json
import sys
from pathlib import Path
data = json.load(sys.stdin)
file_path = data.get('tool_input', {}).get('file_path', '')
# Protected patterns
protected = [
'.env',
'package-lock.json',
'yarn.lock',
'.git/',
'secrets.json',
'credentials'
]
for pattern in protected:
if pattern in file_path:
print(f"❌ ERROR: Cannot edit protected file: {file_path}", file=sys.stderr)
print(f" Pattern matched: {pattern}", file=sys.stderr)
print(f" Protected files cannot be modified by AI", file=sys.stderr)
sys.exit(2) # Block operation
sys.exit(0) # Allow operation
```
**Configuration**:
```json
{
"event": "PreToolUse",
"matcher": "Edit|Write",
"command": "python hooks/file-protection.py"
}
```
**Customization**: Edit `protected` list to add/remove patterns
---
### git-safety-guard
**Purpose**: Prevent dangerous git operations (force push, hard reset)
**Event**: PreToolUse
**Matcher**: Bash
**Language**: Python
**Hook Script** (`hooks/git-safety-guard.py`):
```python
#!/usr/bin/env python3
import json
import sys
import re
data = json.load(sys.stdin)
command = data.get('tool_input', {}).get('command', '')
# Dangerous git patterns
dangerous = [
(r'git\s+push.*--force', 'Force push'),
(r'git\s+reset.*--hard', 'Hard reset'),
(r'git\s+clean.*-[dfx]', 'Git clean'),
(r'rm\s+-rf\s+\.git', 'Delete .git'),
(r'git\s+rebase.*-i.*main', 'Rebase main branch')
]
for pattern, name in dangerous:
if re.search(pattern, command, re.IGNORECASE):
print(f"❌ ERROR: Dangerous git operation blocked: {name}", file=sys.stderr)
print(f" Command: {command}", file=sys.stderr)
print(f" Reason: High risk of data loss", file=sys.stderr)
print(f" Override: Run manually if absolutely necessary", file=sys.stderr)
sys.exit(2) # Block
sys.exit(0) # Allow
```
**Configuration**:
```json
{
"event": "PreToolUse",
"matcher": "Bash",
"command": "python hooks/git-safety-guard.py"
}
```
---
### syntax-validator
**Purpose**: Validate code syntax before saving
**Event**: PreToolUse
**Matcher**: Edit|Write
**Language**: Python
**Features**:
- Checks Python syntax with `ast.parse()`
- Validates JSON with `json.loads()`
- Checks YAML with `yaml.safe_load()`
- Blocks on syntax errors
**Configuration**:
```json
{
"event": "PreToolUse",
"matcher": "Edit|Write",
"command": "python hooks/syntax-validator.py"
}
```
---
## Automation
### auto-formatter
**Purpose**: Automatically format code on save
**Event**: PostToolUse
**Matcher**: Edit|Write
**Language**: Bash
**Hook Script** (`hooks/auto-formatter.sh`):
```bash
#!/bin/bash
set -euo pipefail
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# Format based on file extension
if [[ "$FILE_PATH" =~ \.ts$ ]] || [[ "$FILE_PATH" =~ \.js$ ]]; then
prettier --write "$FILE_PATH" 2>/dev/null
echo "✅ Formatted TypeScript/JavaScript: $FILE_PATH"
elif [[ "$FILE_PATH" =~ \.py$ ]]; then
black "$FILE_PATH" 2>/dev/null
echo "✅ Formatted Python: $FILE_PATH"
elif [[ "$FILE_PATH" =~ \.go$ ]]; then
gofmt -w "$FILE_PATH" 2>/dev/null
echo "✅ Formatted Go: $FILE_PATH"
fi
exit 0
```
**Configuration**:
```json
{
"event": "PostToolUse",
"matcher": "Edit|Write",
"command": "bash hooks/auto-formatter.sh"
}
```
**Dependencies**: `prettier`, `black`, `gofmt` (based on languages used)
---
### test-runner
**Purpose**: Automatically run tests when code changes
**Event**: PostToolUse
**Matcher**: Edit|Write
**Language**: Bash
**Hook Script** (`hooks/test-runner.sh`):
```bash
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# Only run for source files
if [[ ! "$FILE_PATH" =~ \.(ts|js|py|go)$ ]]; then
exit 0
fi
echo "🧪 Running tests for: $FILE_PATH"
# Run tests based on project type
if [ -f "package.json" ]; then
npm test -- "$FILE_PATH" 2>&1 | tail -20
elif [ -f "pytest.ini" ] || [ -f "setup.py" ]; then
pytest "$FILE_PATH" 2>&1 | tail -20
elif [ -f "go.mod" ]; then
go test ./... 2>&1 | tail -20
fi
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "⚠️ Tests failed - review output above"
else
echo "✅ Tests passed"
fi
exit 0 # Don't block even if tests fail
```
**Configuration**:
```json
{
"event": "PostToolUse",
"matcher": "Edit|Write",
"command": "bash hooks/test-runner.sh"
}
```
---
### auto-commit
**Purpose**: Create automatic backup commits
**Event**: PostToolUse
**Matcher**: Edit|Write
**Language**: Bash
**Hook Script** (`hooks/auto-commit.sh`):
```bash
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# Create backup commit
git add "$FILE_PATH" 2>/dev/null
git commit -m "Auto-backup: $FILE_PATH [Claude Code]" 2>/dev/null
if [ $? -eq 0 ]; then
echo "💾 Auto-commit created for: $FILE_PATH"
else
echo " No changes to commit"
fi
exit 0
```
**Configuration**:
```json
{
"event": "PostToolUse",
"matcher": "Edit|Write",
"command": "bash hooks/auto-commit.sh"
}
```
**⚠️ Warning**: Creates many commits! Consider using only during development.
---
## Notifications
### desktop-notifier
**Purpose**: Send desktop notifications when Claude needs input
**Event**: Stop
**Matcher**: *
**Language**: Bash
**Hook Script** (`hooks/desktop-notifier.sh`):
```bash
#!/bin/bash
# macOS
command -v osascript >/dev/null && osascript -e 'display notification "Claude Code awaiting input" with title "Claude Code"'
# Linux
command -v notify-send >/dev/null && notify-send "Claude Code" "Awaiting your input"
# Windows (requires BurntToast PowerShell module)
command -v powershell.exe >/dev/null && powershell.exe -Command "New-BurntToastNotification -Text 'Claude Code', 'Awaiting your input'"
exit 0
```
**Configuration**:
```json
{
"event": "Stop",
"matcher": "*",
"command": "bash hooks/desktop-notifier.sh"
}
```
**Dependencies**:
- macOS: Built-in `osascript`
- Linux: `notify-send` (libnotify)
- Windows: `BurntToast` PowerShell module
---
### slack-integration
**Purpose**: Send updates to Slack when tasks complete
**Event**: Stop
**Matcher**: *
**Language**: Python
**Hook Script** (`hooks/slack-notifier.py`):
```python
#!/usr/bin/env python3
import json
import sys
import os
import requests
SLACK_WEBHOOK_URL = os.environ.get('SLACK_WEBHOOK_URL')
if not SLACK_WEBHOOK_URL:
sys.exit(0) # Silently skip if not configured
data = json.load(sys.stdin)
message = {
"text": "Claude Code task completed",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "✅ *Claude Code Task Completed*\nReady for your review"
}
}
]
}
try:
response = requests.post(SLACK_WEBHOOK_URL, json=message, timeout=5)
if response.status_code == 200:
print("✅ Slack notification sent")
except Exception as e:
print(f"⚠️ Slack notification failed: {e}", file=sys.stderr)
sys.exit(0)
```
**Configuration**:
```json
{
"event": "Stop",
"matcher": "*",
"command": "python hooks/slack-notifier.py"
}
```
**Setup**:
1. Create Slack webhook: https://api.slack.com/messaging/webhooks
2. Set environment variable: `export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...`
**Dependencies**: `requests` library
---
### completion-notifier
**Purpose**: Play sound when Claude finishes
**Event**: Stop
**Matcher**: *
**Language**: Bash
**Hook Script** (`hooks/completion-notifier.sh`):
```bash
#!/bin/bash
# macOS
command -v afplay >/dev/null && afplay /System/Library/Sounds/Glass.aiff
# Linux
command -v paplay >/dev/null && paplay /usr/share/sounds/freedesktop/stereo/complete.oga
# Cross-platform with ffplay (if installed)
command -v ffplay >/dev/null && ffplay -nodisp -autoexit /path/to/notification.mp3
exit 0
```
**Configuration**:
```json
{
"event": "Stop",
"matcher": "*",
"command": "bash hooks/completion-notifier.sh"
}
```
---
## PRISM-Specific
### story-context-enforcer
**Purpose**: Ensure PRISM workflow commands have active story context
**Event**: PreToolUse
**Matcher**: Bash
**Language**: Python
**Hook Script**: See `hooks/enforce-story-context.py` in PRISM plugin
**Configuration**:
```json
{
"event": "PreToolUse",
"matcher": "Bash",
"command": "python hooks/enforce-story-context.py"
}
```
**Blocks commands**: `*develop-story`, `*review`, `*risk`, `*design`, etc.
**Required**: `.prism-current-story.txt` file with active story path
---
### workflow-tracker
**Purpose**: Track PRISM workflow progress and log events
**Event**: PostToolUse
**Matcher**: Write
**Language**: Python
**Hook Script**: See `hooks/track-current-story.py` in PRISM plugin
**Configuration**:
```json
{
"event": "PostToolUse",
"matcher": "Write",
"command": "python hooks/track-current-story.py"
}
```
**Creates**:
- `.prism-current-story.txt` (active story)
- `.prism-workflow.log` (audit trail)
---
## Installation
### Quick Install
All examples can be installed with:
```
*install-example [example-name]
```
### Manual Installation
1. Copy hook script to `hooks/` directory
2. Make executable: `chmod +x hooks/script.sh`
3. Add configuration to `.claude/settings.json`
4. Test: `*test-hook [hook-name]`
---
## Customization
All examples can be customized by:
1. Editing hook scripts directly
2. Modifying patterns/thresholds
3. Adding additional logic
4. Changing matchers
5. Combining multiple hooks
---
## Dependencies Summary
| Example | Dependencies | Installation |
|---------|--------------|--------------|
| bash-command-logger | jq | `brew install jq` |
| file-protection | Python 3 | Built-in |
| auto-formatter | prettier, black, gofmt | Via package managers |
| test-runner | npm, pytest, go | Project-specific |
| desktop-notifier | OS-specific | Built-in or system package |
| slack-integration | requests | `pip install requests` |
| git-safety-guard | Python 3 | Built-in |
---
## Contributing
Want to add your own example?
1. Create hook script with clear documentation
2. Test thoroughly in safe environment
3. Security review (no credentials, safe operations)
4. Submit via `*export-hooks` and share
---
**Version**: 1.0.0
**Last Updated**: 2025-10-24
**Total Examples**: 13