Files
claude-plugins/claude-code/skills/claude-hooks/examples.md
2025-10-28 12:28:48 -05:00

4.4 KiB

Complete Hook Examples

Working hook configurations for common scenarios.

1. Auto-Format on Save

Format files automatically after writing/editing:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "cd $CLAUDE_PROJECT_DIR && npx prettier --write $TOOL_ARGS && exit 0"
          }
        ]
      }
    ]
  }
}

2. Security Validation

Block writes containing secrets:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "if grep -qiE '(password|api[_-]?key|secret|sk-[a-zA-Z0-9]{48})' $TOOL_ARGS 2>/dev/null; then echo 'Error: Possible secret detected' >&2; exit 2; fi; exit 0",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

3. Auto-Git on Changes

Automatically stage and commit changes:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "cd $CLAUDE_PROJECT_DIR && git add $TOOL_ARGS && git commit -m 'Auto-commit: Modified $TOOL_ARGS' && exit 0"
          }
        ]
      }
    ]
  }
}

4. Test Before Commit

Run tests before allowing file writes:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "cd $CLAUDE_PROJECT_DIR && npm test -- --silent || (echo 'Tests failed, cannot save' >&2; exit 2)",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

5. Inject Project Context

Load project info at session start:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "cat << EOF\nProject: MyApp\nEnvironment: Production\nKey Files: src/config.js, .env.example\nCoding Standards: See CONTRIBUTING.md\nEOF"
          }
        ]
      }
    ]
  }
}

6. Log All Activity

Track all tool usage:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date '+%Y-%m-%d %H:%M:%S') - $TOOL_NAME - $TOOL_ARGS\" >> $CLAUDE_PROJECT_DIR/.claude/activity.log && exit 0"
          }
        ]
      }
    ]
  }
}

7. Multiple Hooks Sequence

Format, lint, then stage:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $TOOL_ARGS"
          },
          {
            "type": "command",
            "command": "npx eslint --fix $TOOL_ARGS"
          },
          {
            "type": "command",
            "command": "git add $TOOL_ARGS"
          }
        ]
      }
    ]
  }
}

8. Script-Based Hooks

Call external script for complex logic:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate-write.sh $TOOL_ARGS",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

validate-write.sh:

#!/bin/bash
file=$1

# Check file size
if [ -f "$file" ] && [ $(wc -c < "$file") -gt 1000000 ]; then
    echo "Error: File too large" >&2
    exit 2
fi

# Check for secrets
if grep -qiE '(password|api[_-]?key)' "$file" 2>/dev/null; then
    echo "Error: Possible secret detected" >&2
    exit 2
fi

exit 0

9. Conditional by File Type

Only format JavaScript files:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "if [[ $TOOL_ARGS == *.js ]]; then npm run format $TOOL_ARGS; fi; exit 0"
          }
        ]
      }
    ]
  }
}

10. Desktop Notifications

Alert when Claude needs attention:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude needs attention\" with title \"Claude Code\"' && exit 0"
          }
        ]
      }
    ]
  }
}

For advanced patterns, see patterns.md