Claude
Skills
Sign in
Back

hooks-system

Included with Lifetime
$97 forever

Comprehensive lifecycle hook patterns for Claude Code workflows. Use when configuring PreToolUse, PostToolUse, UserPromptSubmit, Stop, or SubagentStop hooks. Covers hook matchers, command hooks, prompt hooks, validation, metrics, auto-formatting, and security patterns. Trigger keywords - "hooks", "PreToolUse", "PostToolUse", "lifecycle", "tool matcher", "hook template", "auto-format", "security hook", "validation hook".

AI AgentsorchestrationhookslifecyclePreToolUsePostToolUseUserPromptSubmitvalidationsecurity

What this skill does


# Hooks System

**Version:** 1.0.0
**Purpose:** Lifecycle hook patterns for validation, automation, security, and metrics in Claude Code workflows
**Status:** Production Ready

## Overview

Hooks are lifecycle callbacks that execute at specific points in the Claude Code workflow. They enable:
- **Validation** (block dangerous operations before execution)
- **Automation** (auto-format code after file changes)
- **Security** (enforce safety policies on commands and tools)
- **Metrics** (track tool usage, performance, costs)
- **Quality Control** (run tests after implementation changes)
- **Context Injection** (load project-specific context at session start)

Hooks transform Claude Code from a reactive assistant into a **proactive, policy-enforced development environment**.

---

## Hook Types Reference

Claude Code provides 7 hook types that fire at different lifecycle stages:

| Hook Type | When It Fires | Receives | Can Modify | Use Cases |
|-----------|---------------|----------|------------|-----------|
| **PreToolUse** | Before tool execution | Tool name, input | Tool input, can block | Validation, security checks, permission gates |
| **PostToolUse** | After tool completion | Tool name, input, output | Nothing (read-only) | Auto-format, metrics, notifications |
| **UserPromptSubmit** | User submits prompt | Prompt text | Nothing (read-only) | Complexity analysis, model routing, context injection |
| **SessionStart** | Session begins | Session metadata | Nothing (read-only) | Load project context, initialize environment |
| **Stop** | Main session stops | Session metadata | Nothing (read-only) | Completion validation, cleanup, final reports |
| **SubagentStop** | Sub-agent (Task) completes | Task metadata, output | Nothing (read-only) | Task metrics, result validation |
| **Notification** | System notification | Notification data | Nothing (read-only) | Alert logging, external integrations |
| **PermissionRequest** | Tool needs permission | Tool name, action | Nothing (read-only) | Custom approval workflows |

**Key Concepts:**

- **PreToolUse**: Only hook that can **block or modify** execution
- **PostToolUse**: Cannot modify output, but can trigger follow-up actions
- **Matcher**: Regex pattern to filter which tools trigger the hook
- **Hooks Array**: Commands to execute when hook fires (can run multiple)

---

## Hook Configuration in settings.json

Hooks are configured in `.claude/settings.json` under the `"hooks"` key:

### Basic Structure

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^(Write|Edit)$",
        "hooks": ["echo 'File change detected'"]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "^(Write|Edit)$",
        "hooks": ["bun run format"]
      }
    ]
  }
}
```

### Configuration Properties

**matcher** (required):
- Regex pattern to match tool names
- Uses JavaScript regex syntax
- Examples:
  - `"^Write$"` - Matches only Write tool
  - `"^(Write|Edit)$"` - Matches Write or Edit
  - `".*"` - Matches all tools (use sparingly)
  - `"^Bash$"` - Matches Bash tool

**hooks** (required):
- Array of commands to execute
- Commands run sequentially
- Can be shell commands or custom scripts
- Each command runs in its own shell context

**continueOnError** (optional, default: true):
- `true`: Continue workflow if hook fails
- `false`: Stop workflow on hook failure
- Use `false` for critical validation hooks

**timeout** (optional, default: 30000ms):
- Maximum execution time for hook command
- In milliseconds (30000 = 30 seconds)
- Hook is killed if timeout exceeded

### Advanced Configuration Example

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^Write$",
        "hooks": [
          "node scripts/validate-file.js",
          "node scripts/check-secrets.js"
        ],
        "continueOnError": false,
        "timeout": 10000
      }
    ],
    "PostToolUse": [
      {
        "matcher": "^(Write|Edit)$",
        "hooks": ["bun run format", "bun run lint --fix"],
        "continueOnError": true,
        "timeout": 60000
      }
    ],
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": ["node scripts/analyze-complexity.js"]
      }
    ]
  }
}
```

---

## Ready-To-Use Hook Templates

### Template 1: File Protection Hook

**Purpose:** Block writes to sensitive files (secrets, credentials, config)

**Hook Type:** PreToolUse

**Matcher:** `"^(Write|Edit)$"`

**Configuration:**

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^(Write|Edit)$",
        "hooks": ["node scripts/protect-files.js"],
        "continueOnError": false,
        "timeout": 5000
      }
    ]
  }
}
```

**Script: scripts/protect-files.js**

```javascript
#!/usr/bin/env node

const PROTECTED_PATTERNS = [
  /\.env$/,
  /\.env\./,
  /credentials\.json$/,
  /secrets\.yaml$/,
  /id_rsa$/,
  /\.pem$/,
  /\.key$/
];

const args = process.argv.slice(2);
const filePath = args[0] || '';

const isProtected = PROTECTED_PATTERNS.some(pattern => pattern.test(filePath));

if (isProtected) {
  console.error(`❌ BLOCKED: Cannot modify protected file: ${filePath}`);
  process.exit(1);
}

console.log(`✅ File write allowed: ${filePath}`);
process.exit(0);
```

**When to Use:**
- Protecting credentials and secrets
- Preventing accidental config file modifications
- Enforcing file-level permissions in team workflows

---

### Template 2: Auto-Format Hook

**Purpose:** Automatically format code after file changes

**Hook Type:** PostToolUse

**Matcher:** `"^(Write|Edit)$"`

**Configuration:**

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "^(Write|Edit)$",
        "hooks": [
          "bun run format",
          "bun run lint --fix"
        ],
        "continueOnError": true,
        "timeout": 60000
      }
    ]
  }
}
```

**package.json Scripts:**

```json
{
  "scripts": {
    "format": "prettier --write .",
    "lint": "eslint . --ext .ts,.tsx,.js,.jsx"
  }
}
```

**When to Use:**
- Maintaining consistent code style
- Automatic linting and formatting
- Reducing manual formatting overhead
- Enforcing team style guidelines

**Benefits:**
- Every file change is auto-formatted
- No manual "run prettier" steps needed
- Consistent style across all changes
- Catches lint errors immediately

---

### Template 3: Security Command Blocker

**Purpose:** Block dangerous bash commands (rm -rf /, force push, etc.)

**Hook Type:** PreToolUse

**Matcher:** `"^Bash$"`

**Configuration:**

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^Bash$",
        "hooks": ["node scripts/security-check.js"],
        "continueOnError": false,
        "timeout": 5000
      }
    ]
  }
}
```

**Script: scripts/security-check.js**

```javascript
#!/usr/bin/env node

const DANGEROUS_COMMANDS = [
  /rm\s+-rf\s+\//,           // rm -rf /
  /rm\s+-rf\s+~\//,          // rm -rf ~/
  /git\s+push\s+.*--force/,   // git push --force
  /git\s+reset\s+--hard/,     // git reset --hard (main/master)
  /chmod\s+777/,              // chmod 777
  /sudo\s+rm/,                // sudo rm
  /:\(\)\{\s*:\|:&\s*\};:/,   // fork bomb
  /dd\s+if=.*of=\/dev\//,     // dd to device
  /mkfs/,                     // format filesystem
  />\s*\/dev\/sd/             // redirect to disk
];

const args = process.argv.slice(2);
const command = args.join(' ');

const isDangerous = DANGEROUS_COMMANDS.some(pattern => pattern.test(command));

if (isDangerous) {
  console.error(`❌ BLOCKED: Dangerous command detected: ${command}`);
  console.error('This command could cause data loss or system damage.');
  process.exit(1);
}

console.log(`✅ Command allowed: ${command}`);
process.exit(0);
```

**When to Use:**
- Production environments
- Shared development machines
- Preventing accidental destructive commands
- Enforcing security policies

**Protected Against:**
- Recursive deletion of root or home directories
- Force pushing to protected branches
- Destructive git operations
- System-level permission 

Related in AI Agents