$npx -y skills add DNYoussef/context-cascade --skill when-creating-claude-hooks-use-hook-creatorCreate Claude Code hooks with proper schemas, RBAC integration, and performance requirements. Use when implementing PreToolUse, PostToolUse, SessionStart, or any of the 10 hook event types for automation, validation, or security enforcement.
| 1 | # SKILL: Hook Creator |
| 2 | |
| 3 | |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## LIBRARY-FIRST PROTOCOL (MANDATORY) |
| 8 | |
| 9 | **Before writing ANY code, you MUST check:** |
| 10 | |
| 11 | ### Step 1: Library Catalog |
| 12 | - Location: `.claude/library/catalog.json` |
| 13 | - If match >70%: REUSE or ADAPT |
| 14 | |
| 15 | ### Step 2: Patterns Guide |
| 16 | - Location: `.claude/docs/inventories/LIBRARY-PATTERNS-GUIDE.md` |
| 17 | - If pattern exists: FOLLOW documented approach |
| 18 | |
| 19 | ### Step 3: Existing Projects |
| 20 | - Location: `D:\Projects\*` |
| 21 | - If found: EXTRACT and adapt |
| 22 | |
| 23 | ### Decision Matrix |
| 24 | | Match | Action | |
| 25 | |-------|--------| |
| 26 | | Library >90% | REUSE directly | |
| 27 | | Library 70-90% | ADAPT minimally | |
| 28 | | Pattern exists | FOLLOW pattern | |
| 29 | | In project | EXTRACT | |
| 30 | | No match | BUILD (add to library after) | |
| 31 | |
| 32 | --- |
| 33 | |
| 34 | ## Purpose |
| 35 | |
| 36 | Create production-ready Claude Code hooks that integrate with our RBAC security system, |
| 37 | follow official schemas, and meet performance requirements (<20ms for pre-hooks). |
| 38 | |
| 39 | ## When to Use This Skill |
| 40 | |
| 41 | - Creating new automation hooks (pre/post operations) |
| 42 | - Implementing security validation hooks |
| 43 | - Building audit/logging hooks |
| 44 | - Extending the RBAC permission system |
| 45 | - Adding custom session management hooks |
| 46 | |
| 47 | ## 8-Stage Hook Creation Methodology |
| 48 | |
| 49 | ### Stage 1: Hook Type Selection |
| 50 | |
| 51 | Identify which of the 10 hook event types you need: |
| 52 | |
| 53 | | Category | Hook Type | Purpose | |
| 54 | |----------|-----------|---------| |
| 55 | | **Blocking** | UserPromptSubmit | Validate/modify user prompts | |
| 56 | | **Blocking** | SessionStart | Initialize session state | |
| 57 | | **Blocking** | PreToolUse | Validate tool operations | |
| 58 | | **Blocking** | PermissionRequest | Auto-approve/deny permissions | |
| 59 | | **Observational** | PostToolUse | Log tool results | |
| 60 | | **Observational** | Notification | Forward notifications | |
| 61 | | **Observational** | Stop | Cleanup on agent stop | |
| 62 | | **Observational** | SubagentStop | Track subagent completion | |
| 63 | | **Observational** | PreCompact | Preserve context during compaction | |
| 64 | | **Observational** | SessionEnd | Final session cleanup | |
| 65 | |
| 66 | ### Stage 2: Schema Definition |
| 67 | |
| 68 | Define input/output schemas based on hook type. |
| 69 | |
| 70 | **PreToolUse Input**: |
| 71 | ```json |
| 72 | { |
| 73 | "session_id": "string", |
| 74 | "tool_name": "Bash|Read|Write|Edit|...", |
| 75 | "tool_input": { "...tool-specific..." } |
| 76 | } |
| 77 | ``` |
| 78 | |
| 79 | **Blocking Output**: |
| 80 | ```json |
| 81 | { |
| 82 | "continue": true|false, |
| 83 | "decision": "approve|block|modify", |
| 84 | "reason": "string (if blocked)", |
| 85 | "suppressOutput": false, |
| 86 | "updatedInput": { "..." } |
| 87 | } |
| 88 | ``` |
| 89 | |
| 90 | **Non-Blocking Output**: |
| 91 | ```json |
| 92 | { |
| 93 | "suppressOutput": false |
| 94 | } |
| 95 | ``` |
| 96 | |
| 97 | ### Stage 3: Template Selection |
| 98 | |
| 99 | Use our pre-built templates: |
| 100 | |
| 101 | - `pre-hook-template.js` - For blocking hooks (PreToolUse, UserPromptSubmit) |
| 102 | - `post-hook-template.js` - For observational hooks (PostToolUse, SessionEnd) |
| 103 | - `session-hook-template.js` - For session lifecycle hooks |
| 104 | |
| 105 | Generate from templates: |
| 106 | ```bash |
| 107 | node hook-template-generator.js --type pre --name my-validator --event PreToolUse |
| 108 | ``` |
| 109 | |
| 110 | ### Stage 4: Core Logic Implementation |
| 111 | |
| 112 | Implement the hook's core logic: |
| 113 | |
| 114 | ```javascript |
| 115 | #!/usr/bin/env node |
| 116 | const fs = require('fs'); |
| 117 | |
| 118 | // Read input from stdin |
| 119 | const input = JSON.parse(fs.readFileSync(0, 'utf-8')); |
| 120 | |
| 121 | // Your validation/processing logic |
| 122 | function processHook(input) { |
| 123 | // Implement your logic here |
| 124 | return { continue: true, decision: "approve" }; |
| 125 | } |
| 126 | |
| 127 | // Execute and output result |
| 128 | try { |
| 129 | const result = processHook(input); |
| 130 | console.log(JSON.stringify(result)); |
| 131 | } catch (error) { |
| 132 | console.error(`[HOOK ERROR] ${error.message}`); |
| 133 | console.log(JSON.stringify({ continue: true })); // Fail open |
| 134 | process.exit(1); |
| 135 | } |
| 136 | ``` |
| 137 | |
| 138 | ### Stage 5: RBAC Integration |
| 139 | |
| 140 | For security hooks, integrate with our identity system: |
| 141 | |
| 142 | ```javascript |
| 143 | const { validateAgentIdentity, loadAgentIdentityByName } = require('../utils/identity'); |
| 144 | |
| 145 | // Verify agent identity |
| 146 | const identity = loadAgentIdentityByName(input.agent_name); |
| 147 | const validation = validateAgentIdentity(identity); |
| 148 | |
| 149 | if (!validation.valid) { |
| 150 | return { |
| 151 | continue: false, |
| 152 | decision: "block", |
| 153 | reason: `Invalid agent identity: ${validation.errors.join(', ')}` |
| 154 | }; |
| 155 | } |
| 156 | ``` |
| 157 | |
| 158 | ### Stage 6: Performance Optimization |
| 159 | |
| 160 | Meet performance targets: |
| 161 | |
| 162 | | Hook Type | Target | Max | |
| 163 | |-----------|--------|-----| |
| 164 | | Pre-hooks | <20ms | 100ms | |
| 165 | | Post-hooks | <100ms | 1000ms | |
| 166 | |
| 167 | **Optimization Patterns**: |
| 168 | - Cache identity lookups |
| 169 | - Avoid synchronous I/O in hot paths |
| 170 | - Use matchers to filter events |
| 171 | - Batch logging operations |
| 172 | |
| 173 | ### Stage 7: Testing |
| 174 | |
| 175 | Create test scenarios: |
| 176 | |
| 177 | ```javascript |
| 178 | // test-my-hook.js |
| 179 | const testCases = [ |
| 180 | { |
| 181 | name: "Should approve valid operation", |
| 182 | input: { tool_name: "Read", tool_input: { file_path: "/src/app.js" } }, |
| 183 | expectedOutput: { continue: true, decision: "approve" } |
| 184 | }, |
| 185 | { |
| 186 | name: "Should block dangerous command", |
| 187 | input: { tool_name: "B |