HO

Lifecycle hook management for Claude Code. Enables custom validation and security policies for agent workflows.

Install

mkdir -p .claude/skills/hooks-system && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6522" && unzip -o skill.zip -d .claude/skills/hooks-system && rm skill.zip

Installs to .claude/skills/hooks-system

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

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".
423 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Intercepts and validates tool inputs before execution
  • Triggers automated post-processing after tool output
  • Tracks execution metrics for performance monitoring
  • Injects custom startup context and security policies

How it works

Registers callback functions at specific lifecycle events within the agent execution loop to monitor or modify tool behavior.

Inputs & outputs

You give it
Hook configuration definition and trigger event
You get back
Automated callback execution and state validation status

When to use hooks-system

  • Set up a security validation hook
  • Configure auto-formatting after tool execution
  • Track agent performance metrics
  • Inject project context at startup

About this skill

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 TypeWhen It FiresReceivesCan ModifyUse Cases
PreToolUseBefore tool executionTool name, inputTool input, can blockValidation, security checks, permission gates
PostToolUseAfter tool completionTool name, input, outputNothing (read-only)Auto-format, metrics, notifications
UserPromptSubmitUser submits promptPrompt textNothing (read-only)Complexity analysis, model routing, context injection
SessionStartSession beginsSession metadataNothing (read-only)Load project context, initialize environment
StopMain session stopsSession metadataNothing (read-only)Completion validation, cleanup, final reports
SubagentStopSub-agent (Task) completesTask metadata, outputNothing (read-only)Task metrics, result validation
NotificationSystem notificationNotification dataNothing (read-only)Alert logging, external integrations
PermissionRequestTool needs permissionTool name, actionNothing (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

{
  "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

{
  "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:

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

Script: scripts/protect-files.js

#!/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:

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

package.json Scripts:

{
  "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:

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

Script: scripts/security-check.js

#!/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:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": ".*",
        "hooks": ["node scripts/analyze-complexity.js"]
      }
    ]
  }
}

Script: scripts/analyze-complexity.js

#!/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
};

fs.appendFileSync('.claude/complexity-log.json', JSON.stringify(logEntry) + '\n');

console.log(`Complexity Score: ${score} - Recommended: ${recommendation}`);
process.exit(0);

When to Use:

  • Cost optimization (use cheaper models for simple tasks)
  • Automatic model routing based on task complexity
  • Performance tracking (are prompts getting more complex?)
  • Budget management (track usage patterns)

Template 5: Metrics


Content truncated.

When not to use it

  • Simple, one-off scripts where overhead is unnecessary
  • When external dependencies for hook management are prohibited

Prerequisites

Claude Code workflow environment

Limitations

  • Misconfiguration can lead to blocked operations or infinite loops
  • Read-only hooks cannot modify output, limiting corrective actions

How it compares

Embeds policy enforcement directly into the workflow lifecycle rather than relying on manual checks.

Compared to similar skills

hooks-system side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
hooks-system (this skill)16moReviewAdvanced
moai-workflow-loop12moNo flagsAdvanced
yes05moReviewIntermediate
fix-dependabot-alerts186moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by MadAppGang

View all by MadAppGang

claudish-usage

MadAppGang

CRITICAL - Guide for using Claudish CLI ONLY through sub-agents to run Claude Code with any AI model (OpenRouter, Gemini, OpenAI, local models). NEVER run Claudish directly in main context unless user explicitly requests it. Use when user mentions external AI models, Claudish, OpenRouter, Gemini, OpenAI, Ollama, or alternative models. Includes mandatory sub-agent delegation patterns, agent selection guide, file-based instructions, and strict rules to prevent context window pollution.

442

golang-performance

MadAppGang

Use when profiling Go applications (pprof), running benchmarks, optimizing memory/CPU usage, or debugging performance bottlenecks in production Go code.

47

golang

MadAppGang

Use when building Go backend services, implementing goroutines/channels, handling errors idiomatically, writing tests with testify, or following Go best practices for APIs/CLI tools.

313

schemas

MadAppGang

YAML frontmatter schemas for Claude Code agents and commands. Use when creating or validating agent/command files.

34

external-model-selection

MadAppGang

Choose optimal external AI models for code analysis, bug investigation, and architectural decisions. Use when consulting multiple LLMs via claudish, comparing model perspectives, or investigating complex Go/LSP/transpiler issues. Provides empirically validated model rankings (91/100 for MiniMax M2, 83/100 for Grok Code Fast) and proven consultation strategies based on real-world testing.

218

adr-documentation

MadAppGang

Architecture Decision Records (ADR) documentation practice. Use when documenting architectural decisions, recording technical trade-offs, creating decision logs, or establishing architectural patterns. Trigger keywords - "ADR", "architecture decision", "decision record", "trade-offs", "architectural decision", "decision log".

12

You might also like

moai-workflow-loop

modu-ai

Ralph Engine - Automated feedback loop with LSP diagnostics and AST-grep integration for continuous code quality improvement. Use when implementing error-driven development, automated fixing, or continuous quality validation workflows.

10

yes

sstklen

Use when any task involves modifying files, configs, databases, or deployments. Use when debugging hits 2+ failures. Use when about to guess or assume without evidence ('probably', 'might be', 'I think', 'should be'). Use when deflecting to user ('please check...', 'you should manually...', 'you may

00

fix-dependabot-alerts

microsoft

Fix Dependabot security alerts by updating vulnerable npm dependencies. Use when the user mentions "dependabot", "security alerts", "vulnerability", "CVE", or wants to update packages with security issues.

1872

prowler-compliance-review

prowler-cloud

Reviews Pull Requests that add or modify compliance frameworks. Trigger: When reviewing PRs with compliance framework changes, CIS/NIST/PCI-DSS additions, or compliance JSON files.

01

semgrep-rule-variant-creator

trailofbits

Creates language variants of existing Semgrep rules. Use when porting a Semgrep rule to specified target languages. Takes an existing rule and target languages as input, produces independent rule+test directories for each language.

10

resolve-conflicts

antinomyhq

Use this skill immediately when the user mentions merge conflicts that need to be resolved. Do not attempt to resolve conflicts directly - invoke this skill first. This skill specializes in providing a structured framework for merging imports, tests, lock files (regeneration), configuration files, and handling deleted-but-modified files with backup and analysis.

81334

Search skills

Search the agent skills registry