ginskill-init 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +77 -0
  2. package/agents/developer.md +56 -0
  3. package/agents/frontend-design.md +69 -0
  4. package/agents/mobile-reviewer.md +36 -0
  5. package/agents/review-code.md +49 -0
  6. package/agents/security-scanner.md +50 -0
  7. package/agents/tester.md +72 -0
  8. package/bin/cli.js +226 -0
  9. package/package.json +20 -0
  10. package/skills/ai-asset-generator/SKILL.md +255 -0
  11. package/skills/ai-asset-generator/docs/gen-image.md +274 -0
  12. package/skills/ai-asset-generator/docs/genvideo.md +341 -0
  13. package/skills/ai-asset-generator/docs/remove-background.md +19 -0
  14. package/skills/ai-asset-generator/generate-credit-assets.mjs +180 -0
  15. package/skills/ai-asset-generator/generate-ginbrowser-assets.mjs +242 -0
  16. package/skills/ai-asset-generator/generate-sty-icon.mjs +149 -0
  17. package/skills/ai-asset-generator/lib/bg-remove.mjs +34 -0
  18. package/skills/ai-asset-generator/lib/env.mjs +38 -0
  19. package/skills/ai-asset-generator/lib/kie-client.mjs +88 -0
  20. package/skills/ai-asset-generator/scripts/scaffold-generator.mjs +203 -0
  21. package/skills/ai-build-ai/SKILL.md +124 -0
  22. package/skills/ai-build-ai/docs/agent-teams.md +293 -0
  23. package/skills/ai-build-ai/docs/checkpointing.md +161 -0
  24. package/skills/ai-build-ai/docs/create-agent.md +399 -0
  25. package/skills/ai-build-ai/docs/create-mcp.md +395 -0
  26. package/skills/ai-build-ai/docs/create-skill.md +299 -0
  27. package/skills/ai-build-ai/docs/headless-mode.md +614 -0
  28. package/skills/ai-build-ai/docs/hooks.md +578 -0
  29. package/skills/ai-build-ai/docs/memory-claude-md.md +375 -0
  30. package/skills/ai-build-ai/docs/output-styles.md +208 -0
  31. package/skills/ai-build-ai/docs/overview.md +162 -0
  32. package/skills/ai-build-ai/docs/permissions.md +391 -0
  33. package/skills/ai-build-ai/docs/plugins.md +396 -0
  34. package/skills/ai-build-ai/docs/sandbox.md +262 -0
  35. package/skills/ai-build-ai/scripts/load-tutorial.sh +54 -0
  36. package/skills/icon-generator/SKILL.md +270 -0
  37. package/skills/mobile-app-review/SKILL.md +321 -0
  38. package/skills/mobile-app-review/references/apple-review.md +132 -0
  39. package/skills/mobile-app-review/references/google-play-review.md +203 -0
  40. package/skills/mongodb/SKILL.md +667 -0
  41. package/skills/mongodb/references/mongoose-patterns.md +368 -0
  42. package/skills/nestjs-architecture/SKILL.md +1086 -0
  43. package/skills/nestjs-architecture/references/advanced-patterns.md +590 -0
  44. package/skills/performance/SKILL.md +509 -0
  45. package/skills/react-fsd-architecture/SKILL.md +693 -0
  46. package/skills/react-fsd-architecture/references/fsd-patterns.md +747 -0
  47. package/skills/react-query/SKILL.md +685 -0
  48. package/skills/react-query/references/query-patterns.md +365 -0
  49. package/skills/review-code/SKILL.md +321 -0
  50. package/skills/review-code/references/clean-code-principles.md +395 -0
  51. package/skills/review-code/references/frontend-patterns.md +136 -0
  52. package/skills/review-code/references/nestjs-patterns.md +184 -0
  53. package/skills/review-code/scripts/check-module.sh +201 -0
  54. package/skills/review-code/scripts/deep-scan.sh +604 -0
  55. package/skills/review-code/scripts/dep-check.sh +522 -0
  56. package/skills/review-code/scripts/detect-duplicates.sh +466 -0
  57. package/skills/review-code/scripts/format-check.sh +577 -0
  58. package/skills/review-code/scripts/run-review.sh +167 -0
  59. package/skills/review-code/scripts/scan-codebase.sh +152 -0
  60. package/skills/security-scanner/SKILL.md +327 -0
  61. package/skills/security-scanner/references/nestjs-security.md +260 -0
  62. package/skills/security-scanner/references/nextjs-security.md +201 -0
  63. package/skills/security-scanner/references/react-native-security.md +199 -0
  64. package/skills/security-scanner/scripts/security-scan.sh +478 -0
  65. package/skills/ui-ux-pro-max/SKILL.md +377 -0
  66. package/skills/ui-ux-pro-max/data/charts.csv +26 -0
  67. package/skills/ui-ux-pro-max/data/colors.csv +97 -0
  68. package/skills/ui-ux-pro-max/data/icons.csv +101 -0
  69. package/skills/ui-ux-pro-max/data/landing.csv +31 -0
  70. package/skills/ui-ux-pro-max/data/products.csv +97 -0
  71. package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  72. package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  73. package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  74. package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  75. package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  76. package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  77. package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  78. package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  79. package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  80. package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  81. package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  82. package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  83. package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  84. package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  85. package/skills/ui-ux-pro-max/data/styles.csv +68 -0
  86. package/skills/ui-ux-pro-max/data/typography.csv +58 -0
  87. package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  88. package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  89. package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  90. package/skills/ui-ux-pro-max/scripts/core.py +253 -0
  91. package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  92. package/skills/ui-ux-pro-max/scripts/search.py +114 -0
@@ -0,0 +1,578 @@
1
+ # Tutorial: Hooks
2
+
3
+ Hooks are shell commands, HTTP endpoints, or LLM prompts that fire automatically at specific lifecycle points in Claude Code. They give you **deterministic control** — certain actions always happen regardless of what Claude decides to do.
4
+
5
+ Use hooks to: auto-format files after edits, block dangerous commands, inject context after compaction, send notifications, audit tool use, enforce project rules.
6
+
7
+ ---
8
+
9
+ ## Step 1: The Hooks Lifecycle
10
+
11
+ All 16 hook events in order:
12
+
13
+ | Event | When it fires | Can block? |
14
+ |-------|--------------|-----------|
15
+ | `SessionStart` | Session begins or resumes | No (but can inject context) |
16
+ | `UserPromptSubmit` | You submit a prompt, before Claude processes | No (but can inject context) |
17
+ | `PreToolUse` | Before any tool executes | **Yes** |
18
+ | `PermissionRequest` | When a permission dialog appears | **Yes** |
19
+ | `PostToolUse` | After a tool succeeds | No (but can block continuation) |
20
+ | `PostToolUseFailure` | After a tool fails | No |
21
+ | `Notification` | Claude needs your attention | No |
22
+ | `SubagentStart` | A subagent is spawned | No |
23
+ | `SubagentStop` | A subagent finishes | No |
24
+ | `Stop` | Claude finishes responding | No (but can keep Claude working) |
25
+ | `TeammateIdle` | Agent team teammate goes idle | **Yes** (send feedback) |
26
+ | `TaskCompleted` | A task marked as completed | **Yes** (block completion) |
27
+ | `ConfigChange` | A settings/skills file changes live | **Yes** |
28
+ | `WorktreeCreate` | A worktree is being created | Replaces default behavior |
29
+ | `WorktreeRemove` | A worktree is being removed | Replaces default behavior |
30
+ | `PreCompact` | Before context compaction | No |
31
+ | `SessionEnd` | Session terminates | No |
32
+
33
+ ---
34
+
35
+ ## Step 2: Where to Configure Hooks
36
+
37
+ Hooks live in settings JSON files:
38
+
39
+ ```
40
+ ~/.claude/settings.json ← All your projects (personal)
41
+ .claude/settings.json ← This project only (commit to git)
42
+ .claude/settings.local.json ← This project, not committed
43
+ plugin/hooks/hooks.json ← Bundled with a plugin
44
+ skill/agent frontmatter ← Active only while component runs
45
+ ```
46
+
47
+ Basic structure:
48
+
49
+ ```json
50
+ {
51
+ "hooks": {
52
+ "PostToolUse": [
53
+ {
54
+ "matcher": "Edit|Write",
55
+ "hooks": [
56
+ {
57
+ "type": "command",
58
+ "command": "npx prettier --write $(jq -r '.tool_input.file_path')"
59
+ }
60
+ ]
61
+ }
62
+ ]
63
+ }
64
+ }
65
+ ```
66
+
67
+ You can also manage hooks interactively: run `/hooks` inside Claude Code.
68
+
69
+ ---
70
+
71
+ ## Step 3: Hook Types
72
+
73
+ ### Type 1: `command` (most common)
74
+
75
+ Runs a shell command. Receives event data as JSON on stdin.
76
+
77
+ ```json
78
+ {
79
+ "type": "command",
80
+ "command": "./scripts/my-hook.sh",
81
+ "timeout": 30
82
+ }
83
+ ```
84
+
85
+ ### Type 2: `http`
86
+
87
+ POSTs event JSON to an HTTP endpoint. Response body uses same JSON format as command output.
88
+
89
+ ```json
90
+ {
91
+ "type": "http",
92
+ "url": "https://my-server.com/hooks/tool-use",
93
+ "headers": {
94
+ "Authorization": "Bearer $MY_TOKEN"
95
+ },
96
+ "allowedEnvVars": ["MY_TOKEN"]
97
+ }
98
+ ```
99
+
100
+ Header values support `$VAR` interpolation — only vars listed in `allowedEnvVars` are expanded.
101
+
102
+ ### Type 3: `prompt` (LLM-based judgment)
103
+
104
+ Sends your prompt + event data to Claude Haiku for a yes/no decision. Returns `{"ok": true}` or `{"ok": false, "reason": "..."}`.
105
+
106
+ ```json
107
+ {
108
+ "type": "prompt",
109
+ "prompt": "Check if all requested tasks are complete. If any remain, respond with {\"ok\": false, \"reason\": \"what remains\"}.",
110
+ "model": "haiku"
111
+ }
112
+ ```
113
+
114
+ Use prompt hooks when you need judgment rather than deterministic rules.
115
+
116
+ ### Type 4: `agent` (multi-step verification)
117
+
118
+ Spawns a subagent that can use tools (read files, run commands) to verify conditions, then returns `{"ok": true/false}`.
119
+
120
+ ```json
121
+ {
122
+ "type": "agent",
123
+ "prompt": "Run the test suite. If any tests fail, return {\"ok\": false, \"reason\": \"list of failing tests\"}.",
124
+ "timeout": 120
125
+ }
126
+ ```
127
+
128
+ Use agent hooks when verification requires inspecting actual code/files.
129
+
130
+ ---
131
+
132
+ ## Step 4: Exit Codes and Output
133
+
134
+ For `command` hooks, communication is via stdin/stdout/stderr + exit codes:
135
+
136
+ | Exit Code | Meaning |
137
+ |-----------|---------|
138
+ | `0` | Allow the action. Stdout is added to Claude's context (for SessionStart/UserPromptSubmit hooks). |
139
+ | `2` | **Block** the action. Stderr content is shown to Claude as feedback. |
140
+ | Other | Allow the action. Stderr is logged but NOT shown to Claude. |
141
+
142
+ ```bash
143
+ #!/bin/bash
144
+ INPUT=$(cat) # Read JSON event from stdin
145
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
146
+
147
+ if echo "$COMMAND" | grep -q "rm -rf"; then
148
+ echo "Blocked: destructive command not allowed" >&2
149
+ exit 2 # Block
150
+ fi
151
+
152
+ exit 0 # Allow
153
+ ```
154
+
155
+ ### Structured JSON output (instead of exit codes)
156
+
157
+ For more control, exit 0 and print JSON to stdout:
158
+
159
+ ```json
160
+ {
161
+ "hookSpecificOutput": {
162
+ "hookEventName": "PreToolUse",
163
+ "permissionDecision": "deny",
164
+ "permissionDecisionReason": "Use rg instead of grep for performance"
165
+ }
166
+ }
167
+ ```
168
+
169
+ **Permission decisions** (PreToolUse only):
170
+ - `"allow"` — proceed without showing permission prompt
171
+ - `"deny"` — cancel tool call, send reason to Claude
172
+ - `"ask"` — show normal permission prompt to user
173
+
174
+ **Block continuation** (PostToolUse/Stop):
175
+ ```json
176
+ { "decision": "block", "reason": "Tests are still failing" }
177
+ ```
178
+
179
+ **Inject context** (UserPromptSubmit):
180
+ ```json
181
+ { "additionalContext": "Remember: we're in a migration sprint, don't change DB schemas." }
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Step 5: Matcher Patterns
187
+
188
+ The `matcher` field is a **regex** that filters when hooks fire. Omit or set to `""` or `"*"` to match everything.
189
+
190
+ | Event | Matcher filters on |
191
+ |-------|--------------------|
192
+ | `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest` | Tool name |
193
+ | `SessionStart` | How session started: `startup` \| `resume` \| `clear` \| `compact` |
194
+ | `SessionEnd` | Why session ended: `clear` \| `logout` \| `prompt_input_exit` \| `other` |
195
+ | `Notification` | Type: `permission_prompt` \| `idle_prompt` \| `auth_success` |
196
+ | `SubagentStart`, `SubagentStop` | Agent type name |
197
+ | `PreCompact` | Trigger: `manual` \| `auto` |
198
+ | `ConfigChange` | Source: `user_settings` \| `project_settings` \| `local_settings` \| `skills` |
199
+ | `UserPromptSubmit`, `Stop`, `TeammateIdle`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove` | No matcher — always fires |
200
+
201
+ Matcher is a regex, so:
202
+ - `"Edit|Write"` — matches either Edit or Write tool
203
+ - `"Notebook.*"` — matches any Notebook tool
204
+ - `"mcp__github__.*"` — matches all GitHub MCP tools
205
+ - `"mcp__.*__write.*"` — matches any MCP write tool across servers
206
+
207
+ ---
208
+
209
+ ## Step 6: JSON Input Schemas
210
+
211
+ Every hook receives a JSON object on stdin. Common fields across all events:
212
+
213
+ ```json
214
+ {
215
+ "session_id": "abc123",
216
+ "cwd": "/Users/abc/project",
217
+ "hook_event_name": "PreToolUse"
218
+ }
219
+ ```
220
+
221
+ **PreToolUse / PostToolUse / PermissionRequest:**
222
+ ```json
223
+ {
224
+ "tool_name": "Bash",
225
+ "tool_input": {
226
+ "command": "npm test"
227
+ }
228
+ }
229
+ ```
230
+
231
+ **For Edit/Write tools:**
232
+ ```json
233
+ {
234
+ "tool_name": "Edit",
235
+ "tool_input": {
236
+ "file_path": "/path/to/file.ts",
237
+ "old_string": "...",
238
+ "new_string": "..."
239
+ }
240
+ }
241
+ ```
242
+
243
+ **UserPromptSubmit:**
244
+ ```json
245
+ {
246
+ "prompt": "user's message text here"
247
+ }
248
+ ```
249
+
250
+ **SessionStart:**
251
+ ```json
252
+ {
253
+ "source": "startup"
254
+ }
255
+ ```
256
+
257
+ **Stop:**
258
+ ```json
259
+ {
260
+ "stop_hook_active": false
261
+ }
262
+ ```
263
+
264
+ **ConfigChange:**
265
+ ```json
266
+ {
267
+ "source": "project_settings",
268
+ "file_path": "/path/to/.claude/settings.json"
269
+ }
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Step 7: Common Hook Recipes
275
+
276
+ ### Auto-format after edits
277
+
278
+ ```json
279
+ {
280
+ "hooks": {
281
+ "PostToolUse": [{
282
+ "matcher": "Edit|Write",
283
+ "hooks": [{
284
+ "type": "command",
285
+ "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write 2>/dev/null || true"
286
+ }]
287
+ }]
288
+ }
289
+ }
290
+ ```
291
+
292
+ ### Desktop notification when Claude needs input
293
+
294
+ ```json
295
+ {
296
+ "hooks": {
297
+ "Notification": [{
298
+ "matcher": "",
299
+ "hooks": [{
300
+ "type": "command",
301
+ "command": "osascript -e 'display notification \"Claude needs your attention\" with title \"Claude Code\"'"
302
+ }]
303
+ }]
304
+ }
305
+ }
306
+ ```
307
+
308
+ ### Block edits to protected files
309
+
310
+ **`.claude/hooks/protect-files.sh`:**
311
+ ```bash
312
+ #!/bin/bash
313
+ INPUT=$(cat)
314
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
315
+ PROTECTED=(".env" "package-lock.json" ".git/")
316
+ for pattern in "${PROTECTED[@]}"; do
317
+ if [[ "$FILE" == *"$pattern"* ]]; then
318
+ echo "Blocked: $FILE matches protected pattern '$pattern'" >&2
319
+ exit 2
320
+ fi
321
+ done
322
+ exit 0
323
+ ```
324
+
325
+ **`.claude/settings.json`:**
326
+ ```json
327
+ {
328
+ "hooks": {
329
+ "PreToolUse": [{
330
+ "matcher": "Edit|Write",
331
+ "hooks": [{
332
+ "type": "command",
333
+ "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
334
+ }]
335
+ }]
336
+ }
337
+ }
338
+ ```
339
+
340
+ ### Re-inject context after compaction
341
+
342
+ ```json
343
+ {
344
+ "hooks": {
345
+ "SessionStart": [{
346
+ "matcher": "compact",
347
+ "hooks": [{
348
+ "type": "command",
349
+ "command": "echo 'Reminder: use Bun not npm. Current sprint: auth refactor. Run bun test before commits.'"
350
+ }]
351
+ }]
352
+ }
353
+ }
354
+ ```
355
+
356
+ ### Log all bash commands
357
+
358
+ ```json
359
+ {
360
+ "hooks": {
361
+ "PostToolUse": [{
362
+ "matcher": "Bash",
363
+ "hooks": [{
364
+ "type": "command",
365
+ "command": "jq -r '[now|todate, .tool_input.command] | @tsv' >> ~/.claude/bash-log.tsv"
366
+ }]
367
+ }]
368
+ }
369
+ }
370
+ ```
371
+
372
+ ### Keep Claude working until tests pass (Stop hook)
373
+
374
+ ```json
375
+ {
376
+ "hooks": {
377
+ "Stop": [{
378
+ "hooks": [{
379
+ "type": "agent",
380
+ "prompt": "Run `npm test` and check the output. If any tests fail, respond with {\"ok\": false, \"reason\": \"X tests failing: [test names]\"}. If all tests pass or there are no tests, respond with {\"ok\": true}.",
381
+ "timeout": 120
382
+ }]
383
+ }]
384
+ }
385
+ }
386
+ ```
387
+
388
+ ### Validate only READ-only SQL (PreToolUse + hook)
389
+
390
+ **`.claude/hooks/validate-readonly-sql.sh`:**
391
+ ```bash
392
+ #!/bin/bash
393
+ INPUT=$(cat)
394
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
395
+ if echo "$CMD" | grep -iE '\b(INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|TRUNCATE|REPLACE|MERGE)\b' > /dev/null 2>&1; then
396
+ echo "Blocked: only SELECT queries are allowed in this context" >&2
397
+ exit 2
398
+ fi
399
+ exit 0
400
+ ```
401
+
402
+ ### Audit config changes
403
+
404
+ ```json
405
+ {
406
+ "hooks": {
407
+ "ConfigChange": [{
408
+ "matcher": "",
409
+ "hooks": [{
410
+ "type": "command",
411
+ "command": "jq -c '{ts: now|todate, source: .source, file: .file_path}' >> ~/claude-config-audit.log"
412
+ }]
413
+ }]
414
+ }
415
+ }
416
+ ```
417
+
418
+ ### Stop hook infinite loop prevention
419
+
420
+ Stop hooks can re-trigger themselves. Always check `stop_hook_active`:
421
+
422
+ ```bash
423
+ #!/bin/bash
424
+ INPUT=$(cat)
425
+ # If already triggered once, let Claude stop
426
+ if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
427
+ exit 0
428
+ fi
429
+ # Your check logic here
430
+ # ...
431
+ exit 2 # Keep Claude working
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Step 8: Hooks in Skills and Agents
437
+
438
+ Define hooks scoped to a skill's or agent's active lifetime in the frontmatter:
439
+
440
+ **In a skill's SKILL.md:**
441
+ ```yaml
442
+ ---
443
+ name: safe-reviewer
444
+ allowed-tools: Read, Grep
445
+ hooks:
446
+ PostToolUse:
447
+ - matcher: "Bash"
448
+ hooks:
449
+ - type: command
450
+ command: "echo 'Bash used by skill' >> /tmp/skill-log.txt"
451
+ ---
452
+ ```
453
+
454
+ **In an agent's .md file:**
455
+ ```yaml
456
+ ---
457
+ name: db-agent
458
+ hooks:
459
+ PreToolUse:
460
+ - matcher: "Bash"
461
+ hooks:
462
+ - type: command
463
+ command: ".claude/hooks/validate-sql.sh"
464
+ Stop:
465
+ - hooks:
466
+ - type: command
467
+ command: "./scripts/cleanup.sh"
468
+ ---
469
+ ```
470
+
471
+ `Stop` hooks in skill/agent frontmatter automatically become `SubagentStop` events at runtime.
472
+
473
+ ---
474
+
475
+ ## Step 9: Troubleshooting
476
+
477
+ **Hook not firing:**
478
+ - Run `/hooks` and confirm it's listed under the correct event
479
+ - Check matcher regex is correct (case-sensitive)
480
+ - `PermissionRequest` hooks don't fire in headless mode (`-p`) — use `PreToolUse` instead
481
+
482
+ **Hook errors in output:**
483
+ - Test manually: `echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh`
484
+ - Make scripts executable: `chmod +x ./my-hook.sh`
485
+ - Use absolute paths or `$CLAUDE_PROJECT_DIR` to reference scripts
486
+ - Install `jq` if missing: `brew install jq`
487
+
488
+ **Stop hook loops forever:**
489
+ ```bash
490
+ # Add this at the top of your stop hook script:
491
+ INPUT=$(cat)
492
+ if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
493
+ exit 0
494
+ fi
495
+ ```
496
+
497
+ **JSON output ignored:**
498
+ - Don't mix: if you exit 2, JSON is ignored. For JSON output, exit 0.
499
+ - Profile echo statements can corrupt JSON: wrap them in `if [[ $- == *i* ]]; then`.
500
+
501
+ **Debug all hook execution:**
502
+ - Press `Ctrl+O` to toggle verbose mode — shows hook output in transcript
503
+ - Or run `claude --debug` for full hook execution details
504
+
505
+ ---
506
+
507
+ ## Step 10: Notification Hook Matchers
508
+
509
+ The `Notification` event supports specific matchers to target different notification types:
510
+
511
+ | Matcher | Fires when |
512
+ |---------|-----------|
513
+ | `permission_prompt` | Claude needs approval for a tool (permission dialog appearing) |
514
+ | `idle_prompt` | Claude has finished responding and is waiting for your input |
515
+ | `auth_success` | Authentication / OAuth flow completes |
516
+ | `elicitation_dialog` | Claude is asking you a question (AskUserQuestion tool) |
517
+ | `""` (empty) | All notification types |
518
+
519
+ **Example: different sounds for different notifications:**
520
+
521
+ ```json
522
+ {
523
+ "hooks": {
524
+ "Notification": [
525
+ {
526
+ "matcher": "permission_prompt",
527
+ "hooks": [{
528
+ "type": "command",
529
+ "command": "afplay /System/Library/Sounds/Ping.aiff"
530
+ }]
531
+ },
532
+ {
533
+ "matcher": "idle_prompt",
534
+ "hooks": [{
535
+ "type": "command",
536
+ "command": "afplay /System/Library/Sounds/Glass.aiff"
537
+ }]
538
+ }
539
+ ]
540
+ }
541
+ }
542
+ ```
543
+
544
+ ---
545
+
546
+ ## Step 11: Managed Settings for Hooks
547
+
548
+ For enterprise / team deployments, these settings control hooks at the org level (set in managed policy files):
549
+
550
+ | Setting | Effect |
551
+ |---------|--------|
552
+ | `allowManagedHooksOnly: true` | Blocks user/project/plugin hooks — only managed hooks run |
553
+ | `allowedHttpHookUrls: ["https://hooks.company.com/*"]` | HTTP hooks can only call these URLs (wildcard supported) |
554
+ | `allowedHttpHookUrls: []` | Block all HTTP hook calls |
555
+ | `httpHookAllowedEnvVars: ["MY_TOKEN"]` | Env vars HTTP hooks can interpolate (intersection with hook's own `allowedEnvVars`) |
556
+
557
+ **Example managed settings file:**
558
+
559
+ ```json
560
+ {
561
+ "allowManagedHooksOnly": true,
562
+ "allowedHttpHookUrls": [
563
+ "https://hooks.company.com/*",
564
+ "https://audit.internal.company.com/claude"
565
+ ],
566
+ "httpHookAllowedEnvVars": ["AUDIT_TOKEN", "TEAM_ID"]
567
+ }
568
+ ```
569
+
570
+ When `allowedHttpHookUrls` is `undefined` (not set), there are no URL restrictions. When set to `[]`, all HTTP hooks are blocked.
571
+
572
+ ---
573
+
574
+ ## Environment Variables Available in Hooks
575
+
576
+ - `$CLAUDE_PROJECT_DIR` — absolute path to the project root
577
+ - `$CLAUDE_SESSION_ID` — current session ID
578
+ - `$MY_VAR` — any env var listed in `allowedEnvVars` (HTTP hooks only)