- name
- hooks-system
- description
- 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".
- version
- 0.1.0
- tags
- ["orchestration","hooks","lifecycle","PreToolUse","PostToolUse","UserPromptSubmit","validation","security"]
- keywords
- ["hooks","lifecycle","pre-tool","post-tool","user-prompt","session-start","stop","subagent","notification","permission","validation","auto-format","security","metrics"]
- plugin
- multimodel
- updated
- 2026-01-28T00:00:00.000Z
# 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 changes
- Fork bombs and other malicious commands
---
### Template 4: Task Complexity Analyzer
**Purpose:** Analyze prompt complexity and suggest appropriate model tier
**Hook Type:** UserPromptSubmit
**Matcher:** `".*"` (all prompts)
**Configuration:**
```json
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": ".*",
"hooks": ["node scripts/analyze-complexity.js"]
}
]
}
}
```
**Script: scripts/analyze-complexity.js**
```javascript
#!/usr/bin/env node
const fs = require('fs');
const args = process.argv.slice(2);
const prompt = args.join(' ');
// Complexity scoring
let score = 0;
// Length-based scoring
if (prompt.length > 500) score += 2;
if (prompt.length > 1000) score += 3;
// Keyword-based scoring
const complexKeywords = [
'implement', 'refactor', 'architect', 'design',
'optimize', 'performance', 'security', 'scale'
];
const simpleKeywords = ['fix', 'update', 'change', 'modify'];
complexKeywords.forEach(keyword => {
if (prompt.toLowerCase().includes(keyword)) score += 2;
});
simpleKeywords.forEach(keyword => {
if (prompt.toLowerCase().includes(keyword)) score -= 1;
});
// Determine recommended model
let recommendation;
if (score >= 5) {
recommendation = 'Claude Opus 4.5 (complex task)';
} else if (score >= 2) {
recommendation = 'Claude Sonnet 4.5 (medium task)';
} else {
recommendation = 'Claude Haiku 3.5 (simple task)';
}
// Log recommendation
const logEntry = {
timestamp: new Date().toISOString(),
prompt: prompt.substring(0, 100),
score,
recommendation
};
عرض على GitHub