@amsterdamdatalabs/enact-extensions 0.1.0 → 0.1.3
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.
- package/README.md +96 -21
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +171 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +402 -49
- package/dist/install.js.map +1 -1
- package/dist/internal/codex.d.ts.map +1 -1
- package/dist/internal/codex.js +7 -1
- package/dist/internal/codex.js.map +1 -1
- package/dist/internal/platform.d.ts +8 -0
- package/dist/internal/platform.d.ts.map +1 -1
- package/dist/internal/platform.js +46 -2
- package/dist/internal/platform.js.map +1 -1
- package/dist/provision.d.ts +30 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +202 -0
- package/dist/provision.js.map +1 -0
- package/dist/validate/index.d.ts +44 -0
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +157 -0
- package/dist/validate/index.js.map +1 -1
- package/extensions/cmux/.agents/plugin.json +37 -0
- package/extensions/cmux/skills/cmux/SKILL.md +82 -0
- package/extensions/cmux/skills/cmux/agents/openai.yaml +4 -0
- package/extensions/cmux/skills/cmux/references/handles-and-identify.md +35 -0
- package/extensions/cmux/skills/cmux/references/panes-surfaces.md +37 -0
- package/extensions/cmux/skills/cmux/references/trigger-flash-and-health.md +23 -0
- package/extensions/cmux/skills/cmux/references/windows-workspaces.md +31 -0
- package/extensions/cmux/skills/cmux-vm-monitor/SKILL.md +122 -0
- package/extensions/cmux/skills/cmux-vm-monitor/agents/openai.yaml +4 -0
- package/extensions/cmux/skills/cmux-vm-monitor/references/cmux-commands.md +66 -0
- package/extensions/cmux/skills/cmux-vm-monitor/scripts/codex_vm_monitor.sh +45 -0
- package/extensions/cmux/skills/cmux-workspace/SKILL.md +93 -0
- package/extensions/dev-state/.agents/plugin.json +35 -0
- package/extensions/dev-state/skills/dev-state-plan-graduation/SKILL.md +194 -0
- package/extensions/dev-state/skills/dev-state-plan-graduation/agents/openai.yaml +4 -0
- package/extensions/dev-state/skills/dev-state-plan-graduation/references/reference.md +130 -0
- package/extensions/devops/.agents/plugin.json +36 -0
- package/extensions/devops/skills/azure-devops-cli/SKILL.md +431 -0
- package/extensions/devops/skills/azure-devops-cli/agents/openai.yaml +4 -0
- package/extensions/devops/skills/ci-pipeline-strategy/SKILL.md +217 -0
- package/extensions/devops/skills/ci-pipeline-strategy/agents/openai.yaml +4 -0
- package/extensions/enact-context/.agents/plugin.json +40 -0
- package/extensions/enact-context/.mcp.json +8 -0
- package/extensions/enact-context/README.md +25 -0
- package/extensions/enact-context/assets/icon.png +0 -0
- package/extensions/enact-context/assets/logo.png +0 -0
- package/extensions/enact-context/hooks/hooks.json +115 -0
- package/extensions/enact-context/skills/enact-context/SKILL.md +149 -0
- package/extensions/enact-context/skills/enact-context/scripts/install.sh +69 -0
- package/extensions/enact-factory/.agents/plugin.json +42 -0
- package/extensions/enact-factory/.mcp.json +8 -0
- package/extensions/enact-factory/assets/icon.png +0 -0
- package/extensions/enact-factory/assets/logo.png +0 -0
- package/extensions/enact-factory/hooks/user-prompt-submit.mjs +67 -0
- package/extensions/enact-factory/skills/testing-strategy/SKILL.md +167 -0
- package/extensions/enact-factory/skills/workitem-triage/SKILL.md +22 -0
- package/extensions/enact-operator/.agents/plugin.json +57 -0
- package/extensions/enact-operator/.app.json +3 -0
- package/extensions/enact-operator/.mcp.json +10 -0
- package/extensions/enact-operator/_taxonomy.md +86 -0
- package/extensions/enact-operator/agents/README.md +5 -0
- package/extensions/enact-operator/agents/architect.toml +25 -0
- package/extensions/enact-operator/agents/code-reviewer.toml +24 -0
- package/extensions/enact-operator/agents/critic.toml +30 -0
- package/extensions/enact-operator/agents/executor.toml +24 -0
- package/extensions/enact-operator/agents/explore.toml +23 -0
- package/extensions/enact-operator/agents/planner.toml +24 -0
- package/extensions/enact-operator/agents/verifier.toml +24 -0
- package/extensions/enact-operator/assets/icon.png +0 -0
- package/extensions/enact-operator/assets/logo.png +0 -0
- package/extensions/enact-operator/commands/doctor.md +39 -0
- package/extensions/enact-operator/commands/setup.md +51 -0
- package/extensions/enact-operator/hooks/hooks.json +146 -0
- package/extensions/enact-operator/skills/_variants.md +44 -0
- package/extensions/enact-operator/skills/ai-slop-cleaner/SKILL.md +50 -0
- package/extensions/enact-operator/skills/analyze/SKILL.md +91 -0
- package/extensions/enact-operator/skills/ask/SKILL.md +47 -0
- package/extensions/enact-operator/skills/autopilot/SKILL.md +170 -0
- package/extensions/enact-operator/skills/autoresearch-goal/SKILL.md +79 -0
- package/extensions/enact-operator/skills/cancel/SKILL.md +99 -0
- package/extensions/enact-operator/skills/configure-notifications/SKILL.md +77 -0
- package/extensions/enact-operator/skills/deep-interview/SKILL.md +80 -0
- package/extensions/enact-operator/skills/doctor/SKILL.md +48 -0
- package/extensions/enact-operator/skills/hud/SKILL.md +49 -0
- package/extensions/enact-operator/skills/hyperplan/SKILL.md +47 -0
- package/extensions/enact-operator/skills/plan/SKILL.md +78 -0
- package/extensions/enact-operator/skills/ralph/SKILL.md +201 -0
- package/extensions/enact-operator/skills/ralph/gemini.md +18 -0
- package/extensions/enact-operator/skills/ralplan/SKILL.md +151 -0
- package/extensions/enact-operator/skills/remove-deadcode/SKILL.md +45 -0
- package/extensions/enact-operator/skills/research/SKILL.md +74 -0
- package/extensions/enact-operator/skills/review/SKILL.md +58 -0
- package/extensions/enact-operator/skills/security-research/SKILL.md +54 -0
- package/extensions/enact-operator/skills/setup/SKILL.md +91 -0
- package/extensions/enact-operator/skills/setup/scripts/install.sh +50 -0
- package/extensions/enact-operator/skills/skill/SKILL.md +82 -0
- package/extensions/enact-operator/skills/tdd/SKILL.md +59 -0
- package/extensions/enact-operator/skills/team/SKILL.md +199 -0
- package/extensions/enact-operator/skills/trace/SKILL.md +41 -0
- package/extensions/enact-operator/skills/ultragoal/SKILL.md +99 -0
- package/extensions/enact-operator/skills/ultraqa/SKILL.md +113 -0
- package/extensions/enact-operator/skills/ultrawork/SKILL.md +145 -0
- package/extensions/enact-operator/skills/ultrawork/planner.md +28 -0
- package/extensions/enact-operator/skills/wiki/SKILL.md +41 -0
- package/extensions/enact-operator/skills/work-with-workitem/SKILL.md +51 -0
- package/extensions/enact-wiki/.agents/plugin.json +42 -0
- package/extensions/enact-wiki/.mcp.json +15 -0
- package/extensions/enact-wiki/README.md +44 -0
- package/extensions/enact-wiki/assets/icon.png +0 -0
- package/extensions/enact-wiki/assets/logo.png +0 -0
- package/extensions/enact-wiki/skills/document-parser/SKILL.md +17 -0
- package/extensions/enact-wiki/skills/document-parser/scripts/parse.sh +60 -0
- package/extensions/enact-wiki/skills/document-parser/skill.json +9 -0
- package/extensions/enact-wiki/skills/enact-wiki/SKILL.md +30 -0
- package/extensions/enact-wiki/skills/enact-wiki/references/ingest.md +62 -0
- package/extensions/enact-wiki/skills/enact-wiki/references/manage.md +34 -0
- package/extensions/enact-wiki/skills/enact-wiki/references/query.md +59 -0
- package/extensions/enact-wiki/skills/search-lab/SKILL.md +57 -0
- package/extensions/enact-wiki/skills/search-lab/scripts/analyze.ts +23 -0
- package/{plugins/net-revenue-management/.codex-plugin → extensions/net-revenue-management/.agents}/plugin.json +10 -6
- package/extensions/plugin-dev/.agents/plugin.json +42 -0
- package/extensions/plugin-dev/.mcp.json +3 -0
- package/extensions/plugin-dev/agents/agent-creator.md +199 -0
- package/extensions/plugin-dev/agents/plugin-validator.md +91 -0
- package/extensions/plugin-dev/agents/skill-reviewer.md +212 -0
- package/extensions/plugin-dev/commands/_archive/create-marketplace.md +427 -0
- package/extensions/plugin-dev/commands/_archive/plugin-dev-guide.md +12 -0
- package/extensions/plugin-dev/commands/create-plugin.md +498 -0
- package/extensions/plugin-dev/commands/start.md +81 -0
- package/extensions/plugin-dev/hooks/hooks.json +3 -0
- package/extensions/plugin-dev/skills/agent-development/SKILL.md +641 -0
- package/extensions/plugin-dev/skills/agent-development/examples/agent-creation-prompt.md +250 -0
- package/extensions/plugin-dev/skills/agent-development/examples/complete-agent-examples.md +461 -0
- package/extensions/plugin-dev/skills/agent-development/references/advanced-agent-fields.md +246 -0
- package/extensions/plugin-dev/skills/agent-development/references/agent-creation-system-prompt.md +216 -0
- package/extensions/plugin-dev/skills/agent-development/references/permission-modes-rules.md +226 -0
- package/extensions/plugin-dev/skills/agent-development/references/system-prompt-design.md +464 -0
- package/extensions/plugin-dev/skills/agent-development/references/triggering-examples.md +474 -0
- package/extensions/plugin-dev/skills/agent-development/scripts/create-agent-skeleton.sh +176 -0
- package/extensions/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh +227 -0
- package/extensions/plugin-dev/skills/agent-development/scripts/validate-agent.sh +227 -0
- package/extensions/plugin-dev/skills/command-development/SKILL.md +763 -0
- package/extensions/plugin-dev/skills/command-development/examples/plugin-commands.md +612 -0
- package/extensions/plugin-dev/skills/command-development/examples/simple-commands.md +527 -0
- package/extensions/plugin-dev/skills/command-development/references/advanced-workflows.md +762 -0
- package/extensions/plugin-dev/skills/command-development/references/documentation-patterns.md +769 -0
- package/extensions/plugin-dev/skills/command-development/references/frontmatter-reference.md +508 -0
- package/extensions/plugin-dev/skills/command-development/references/interactive-commands.md +966 -0
- package/extensions/plugin-dev/skills/command-development/references/marketplace-considerations.md +943 -0
- package/extensions/plugin-dev/skills/command-development/references/plugin-features-reference.md +637 -0
- package/extensions/plugin-dev/skills/command-development/references/plugin-integration.md +191 -0
- package/extensions/plugin-dev/skills/command-development/references/skill-tool.md +447 -0
- package/extensions/plugin-dev/skills/command-development/references/testing-strategies.md +723 -0
- package/extensions/plugin-dev/skills/command-development/scripts/check-frontmatter.sh +234 -0
- package/extensions/plugin-dev/skills/command-development/scripts/validate-command.sh +160 -0
- package/extensions/plugin-dev/skills/hook-development/SKILL.md +861 -0
- package/extensions/plugin-dev/skills/hook-development/examples/load-context.sh +55 -0
- package/extensions/plugin-dev/skills/hook-development/examples/validate-bash.sh +57 -0
- package/extensions/plugin-dev/skills/hook-development/examples/validate-write.sh +48 -0
- package/extensions/plugin-dev/skills/hook-development/references/advanced.md +871 -0
- package/extensions/plugin-dev/skills/hook-development/references/hook-input-schemas.md +145 -0
- package/extensions/plugin-dev/skills/hook-development/references/migration.md +392 -0
- package/extensions/plugin-dev/skills/hook-development/references/patterns.md +430 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/README.md +181 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/hook-linter.sh +153 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/test-hook.sh +276 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
- package/extensions/plugin-dev/skills/mcp-integration/SKILL.md +775 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/http-server.json +20 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/sse-server.json +19 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/stdio-server.json +38 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/ws-server.json +26 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/authentication.md +601 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/server-discovery.md +190 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/server-types.md +572 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/tool-usage.md +623 -0
- package/extensions/plugin-dev/skills/plugin-dev-guide/SKILL.md +222 -0
- package/extensions/plugin-dev/skills/plugin-structure/SKILL.md +705 -0
- package/extensions/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md +774 -0
- package/extensions/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md +83 -0
- package/extensions/plugin-dev/skills/plugin-structure/examples/standard-plugin.md +611 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/advanced-topics.md +289 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/component-patterns.md +592 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/github-actions.md +233 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/headless-ci-mode.md +193 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/manifest-reference.md +625 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/output-styles.md +116 -0
- package/extensions/plugin-dev/skills/skill-development/SKILL.md +564 -0
- package/extensions/plugin-dev/skills/skill-development/examples/complete-skill.md +465 -0
- package/extensions/plugin-dev/skills/skill-development/examples/frontmatter-templates.md +167 -0
- package/extensions/plugin-dev/skills/skill-development/examples/minimal-skill.md +111 -0
- package/extensions/plugin-dev/skills/skill-development/references/advanced-frontmatter.md +225 -0
- package/extensions/plugin-dev/skills/skill-development/references/commands-vs-skills.md +39 -0
- package/extensions/plugin-dev/skills/skill-development/references/skill-creation-workflow.md +379 -0
- package/extensions/plugin-dev/skills/skill-development/references/skill-creator-original.md +210 -0
- package/package.json +8 -11
- package/scripts/enact-extensions.mjs +823 -21
- package/scripts/hooks/session-start-drift-check.mjs +58 -0
- package/scripts/lib/build-index.mjs +50 -0
- package/scripts/lib/bundle-hash.mjs +137 -0
- package/scripts/lib/hooks.mjs +741 -0
- package/scripts/lib/ledger.mjs +163 -0
- package/scripts/lib/list-bundles.mjs +70 -0
- package/scripts/lib/outdated.mjs +144 -0
- package/scripts/lib/provision-mcp.mjs +16 -0
- package/scripts/lib/resolve-bundle.mjs +121 -0
- package/scripts/lib/run-install.mjs +402 -38
- package/scripts/lib/run-prune.mjs +73 -0
- package/scripts/lib/run-sync.mjs +9 -1
- package/scripts/lib/run-uninstall.mjs +244 -0
- package/scripts/lib/run-update.mjs +152 -0
- package/scripts/lib/run-validate.mjs +21 -18
- package/scripts/lib/serve.mjs +472 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/setup-enact-context.sh +2 -2
- package/scripts/version-bump.sh +463 -0
- package/spec/codex.json +1 -11
- package/spec/index.json +59 -0
- package/web/assets/README.md +111 -0
- package/web/assets/logo-full.png +0 -0
- package/web/assets/logo-slim.png +0 -0
- package/web/assets/tokens/base.css +45 -0
- package/web/assets/tokens/colors.css +248 -0
- package/web/assets/tokens/effects.css +24 -0
- package/web/assets/tokens/fonts.css +8 -0
- package/web/assets/tokens/index.css +18 -0
- package/web/assets/tokens/spacing.css +50 -0
- package/web/index.html +1188 -0
- package/.agents/plugins/marketplace.json +0 -20
- package/catalog/enact-context.json +0 -9
- package/catalog/enact-factory.json +0 -7
- package/catalog/enact-operator.json +0 -7
- package/catalog/enact-wiki.json +0 -7
- package/catalog/net-revenue-management.json +0 -8
- package/scripts/rename-supervisor-to-operator.pl +0 -66
- package/scripts/sync-manifests.mjs +0 -23
- package/scripts/validate-catalog.mjs +0 -37
- package/scripts/validate-plugin.mjs +0 -10
- /package/{plugins → extensions}/net-revenue-management/.mcp.json +0 -0
- /package/{plugins → extensions}/net-revenue-management/skills/net-revenue-risks/SKILL.md +0 -0
- /package/{plugins → extensions}/net-revenue-management/skills/net-revenue-scenario/SKILL.md +0 -0
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
# Advanced Hook Use Cases
|
|
2
|
+
|
|
3
|
+
This reference covers advanced hook patterns and techniques for sophisticated automation workflows.
|
|
4
|
+
|
|
5
|
+
## Multi-Stage Validation
|
|
6
|
+
|
|
7
|
+
Combine command and prompt hooks for layered validation:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"PreToolUse": [
|
|
12
|
+
{
|
|
13
|
+
"matcher": "Bash",
|
|
14
|
+
"hooks": [
|
|
15
|
+
{
|
|
16
|
+
"type": "command",
|
|
17
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/quick-check.sh",
|
|
18
|
+
"timeout": 5
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "prompt",
|
|
22
|
+
"prompt": "Deep analysis of bash command: $TOOL_INPUT",
|
|
23
|
+
"timeout": 15
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Use case:** Fast deterministic checks followed by intelligent analysis
|
|
32
|
+
|
|
33
|
+
**Example quick-check.sh:**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
#!/bin/bash
|
|
37
|
+
input=$(cat)
|
|
38
|
+
command=$(echo "$input" | jq -r '.tool_input.command')
|
|
39
|
+
|
|
40
|
+
# Immediate approval for safe commands
|
|
41
|
+
if [[ "$command" =~ ^(ls|pwd|echo|date|whoami)$ ]]; then
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Let prompt hook handle complex cases
|
|
46
|
+
exit 0
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The command hook quickly approves obviously safe commands, while the prompt hook analyzes everything else.
|
|
50
|
+
|
|
51
|
+
## Conditional Hook Execution
|
|
52
|
+
|
|
53
|
+
Execute hooks based on environment or context:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
#!/bin/bash
|
|
57
|
+
# Only run in CI environment
|
|
58
|
+
if [ -z "$CI" ]; then
|
|
59
|
+
echo '{"continue": true}' # Skip in non-CI
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Run validation logic in CI
|
|
64
|
+
input=$(cat)
|
|
65
|
+
# ... validation code ...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Use cases:**
|
|
69
|
+
|
|
70
|
+
- Different behavior in CI vs local development
|
|
71
|
+
- Project-specific validation
|
|
72
|
+
- User-specific rules
|
|
73
|
+
|
|
74
|
+
**Example: Skip certain checks for trusted users:**
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
#!/bin/bash
|
|
78
|
+
# Skip detailed checks for admin users
|
|
79
|
+
if [ "$USER" = "admin" ]; then
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Full validation for other users
|
|
84
|
+
input=$(cat)
|
|
85
|
+
# ... validation code ...
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Hook Chaining via State
|
|
89
|
+
|
|
90
|
+
Share state between hooks using temporary files:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Hook 1: Analyze and save state
|
|
94
|
+
#!/bin/bash
|
|
95
|
+
input=$(cat)
|
|
96
|
+
command=$(echo "$input" | jq -r '.tool_input.command')
|
|
97
|
+
|
|
98
|
+
# Analyze command
|
|
99
|
+
risk_level=$(calculate_risk "$command")
|
|
100
|
+
echo "$risk_level" > /tmp/hook-state-$$
|
|
101
|
+
|
|
102
|
+
exit 0
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Hook 2: Use saved state
|
|
107
|
+
#!/bin/bash
|
|
108
|
+
risk_level=$(cat /tmp/hook-state-$$ 2>/dev/null || echo "unknown")
|
|
109
|
+
|
|
110
|
+
if [ "$risk_level" = "high" ]; then
|
|
111
|
+
echo "High risk operation detected" >&2
|
|
112
|
+
exit 2
|
|
113
|
+
fi
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Important:** This only works for sequential hook events (e.g., PreToolUse then PostToolUse), not parallel hooks.
|
|
117
|
+
|
|
118
|
+
## Dynamic Hook Configuration
|
|
119
|
+
|
|
120
|
+
Modify hook behavior based on project configuration:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
#!/bin/bash
|
|
124
|
+
cd "$CLAUDE_PROJECT_DIR" || exit 1
|
|
125
|
+
|
|
126
|
+
# Read project-specific config
|
|
127
|
+
if [ -f ".claude-hooks-config.json" ]; then
|
|
128
|
+
strict_mode=$(jq -r '.strict_mode' .claude-hooks-config.json)
|
|
129
|
+
|
|
130
|
+
if [ "$strict_mode" = "true" ]; then
|
|
131
|
+
# Apply strict validation
|
|
132
|
+
# ...
|
|
133
|
+
else
|
|
134
|
+
# Apply lenient validation
|
|
135
|
+
# ...
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Example .claude-hooks-config.json:**
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"strict_mode": true,
|
|
145
|
+
"allowed_commands": ["ls", "pwd", "grep"],
|
|
146
|
+
"forbidden_paths": ["/etc", "/sys"]
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Context-Aware Prompt Hooks
|
|
151
|
+
|
|
152
|
+
Use transcript and session context for intelligent decisions:
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"Stop": [
|
|
157
|
+
{
|
|
158
|
+
"matcher": "*",
|
|
159
|
+
"hooks": [
|
|
160
|
+
{
|
|
161
|
+
"type": "prompt",
|
|
162
|
+
"prompt": "Review the full transcript at $TRANSCRIPT_PATH. Check: 1) Were tests run after code changes? 2) Did the build succeed? 3) Were all user questions answered? 4) Is there any unfinished work? Return 'approve' only if everything is complete."
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The LLM can read the transcript file and make context-aware decisions.
|
|
171
|
+
|
|
172
|
+
**Response format:** Agent hooks use the same response schema as prompt hooks:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{ "ok": true, "reason": "Explanation of decision" }
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Agent hooks can also use tool access for multi-turn verification (up to 50 turns). Default timeout: 60 seconds.
|
|
179
|
+
|
|
180
|
+
## Performance Optimization
|
|
181
|
+
|
|
182
|
+
### Caching Validation Results
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
#!/bin/bash
|
|
186
|
+
input=$(cat)
|
|
187
|
+
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
|
|
188
|
+
cache_key=$(echo -n "$file_path" | md5sum | cut -d' ' -f1)
|
|
189
|
+
cache_file="/tmp/hook-cache-$cache_key"
|
|
190
|
+
|
|
191
|
+
# Check cache
|
|
192
|
+
if [ -f "$cache_file" ]; then
|
|
193
|
+
cache_age=$(($(date +%s) - $(stat -f%m "$cache_file" 2>/dev/null || stat -c%Y "$cache_file")))
|
|
194
|
+
if [ "$cache_age" -lt 300 ]; then # 5 minute cache
|
|
195
|
+
cat "$cache_file"
|
|
196
|
+
exit 0
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# Perform validation
|
|
201
|
+
result='{"decision": "approve"}'
|
|
202
|
+
|
|
203
|
+
# Cache result
|
|
204
|
+
echo "$result" > "$cache_file"
|
|
205
|
+
echo "$result"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Parallel Execution Optimization
|
|
209
|
+
|
|
210
|
+
Since hooks run in parallel, design them to be independent:
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"PreToolUse": [
|
|
215
|
+
{
|
|
216
|
+
"matcher": "Write",
|
|
217
|
+
"hooks": [
|
|
218
|
+
{
|
|
219
|
+
"type": "command",
|
|
220
|
+
"command": "bash check-size.sh", // Independent
|
|
221
|
+
"timeout": 2
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"type": "command",
|
|
225
|
+
"command": "bash check-path.sh", // Independent
|
|
226
|
+
"timeout": 2
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"type": "prompt",
|
|
230
|
+
"prompt": "Check content safety", // Independent
|
|
231
|
+
"timeout": 10
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
All three hooks run simultaneously, reducing total latency.
|
|
240
|
+
|
|
241
|
+
## Cross-Event Workflows
|
|
242
|
+
|
|
243
|
+
Coordinate hooks across different events:
|
|
244
|
+
|
|
245
|
+
**SessionStart - Set up tracking:**
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
#!/bin/bash
|
|
249
|
+
# Initialize session tracking
|
|
250
|
+
echo "0" > /tmp/test-count-$$
|
|
251
|
+
echo "0" > /tmp/build-count-$$
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**PostToolUse - Track events:**
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
#!/bin/bash
|
|
258
|
+
input=$(cat)
|
|
259
|
+
tool_name=$(echo "$input" | jq -r '.tool_name')
|
|
260
|
+
|
|
261
|
+
if [ "$tool_name" = "Bash" ]; then
|
|
262
|
+
command=$(echo "$input" | jq -r '.tool_result')
|
|
263
|
+
if [[ "$command" == *"test"* ]]; then
|
|
264
|
+
count=$(cat /tmp/test-count-$$ 2>/dev/null || echo "0")
|
|
265
|
+
echo $((count + 1)) > /tmp/test-count-$$
|
|
266
|
+
fi
|
|
267
|
+
fi
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Stop - Verify based on tracking:**
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
#!/bin/bash
|
|
274
|
+
test_count=$(cat /tmp/test-count-$$ 2>/dev/null || echo "0")
|
|
275
|
+
|
|
276
|
+
if [ "$test_count" -eq 0 ]; then
|
|
277
|
+
echo '{"decision": "block", "reason": "No tests were run"}' >&2
|
|
278
|
+
exit 2
|
|
279
|
+
fi
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Integration with External Systems
|
|
283
|
+
|
|
284
|
+
### Slack Notifications
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
#!/bin/bash
|
|
288
|
+
input=$(cat)
|
|
289
|
+
tool_name=$(echo "$input" | jq -r '.tool_name')
|
|
290
|
+
decision="blocked"
|
|
291
|
+
|
|
292
|
+
# Send notification to Slack
|
|
293
|
+
curl -X POST "$SLACK_WEBHOOK" \
|
|
294
|
+
-H 'Content-Type: application/json' \
|
|
295
|
+
-d "{\"text\": \"Hook ${decision} ${tool_name} operation\"}" \
|
|
296
|
+
2>/dev/null
|
|
297
|
+
|
|
298
|
+
echo '{"decision": "deny"}' >&2
|
|
299
|
+
exit 2
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Database Logging
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
#!/bin/bash
|
|
306
|
+
input=$(cat)
|
|
307
|
+
|
|
308
|
+
# Log to database
|
|
309
|
+
psql "$DATABASE_URL" -c "INSERT INTO hook_logs (event, data) VALUES ('PreToolUse', '$input')" \
|
|
310
|
+
2>/dev/null
|
|
311
|
+
|
|
312
|
+
exit 0
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Metrics Collection
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
#!/bin/bash
|
|
319
|
+
input=$(cat)
|
|
320
|
+
tool_name=$(echo "$input" | jq -r '.tool_name')
|
|
321
|
+
|
|
322
|
+
# Send metrics to monitoring system
|
|
323
|
+
echo "hook.pretooluse.${tool_name}:1|c" | nc -u -w1 statsd.local 8125
|
|
324
|
+
|
|
325
|
+
exit 0
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Security Patterns
|
|
329
|
+
|
|
330
|
+
### Rate Limiting
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
#!/bin/bash
|
|
334
|
+
input=$(cat)
|
|
335
|
+
command=$(echo "$input" | jq -r '.tool_input.command')
|
|
336
|
+
|
|
337
|
+
# Track command frequency
|
|
338
|
+
rate_file="/tmp/hook-rate-$$"
|
|
339
|
+
current_minute=$(date +%Y%m%d%H%M)
|
|
340
|
+
|
|
341
|
+
if [ -f "$rate_file" ]; then
|
|
342
|
+
last_minute=$(head -1 "$rate_file")
|
|
343
|
+
count=$(tail -1 "$rate_file")
|
|
344
|
+
|
|
345
|
+
if [ "$current_minute" = "$last_minute" ]; then
|
|
346
|
+
if [ "$count" -gt 10 ]; then
|
|
347
|
+
echo '{"decision": "deny", "reason": "Rate limit exceeded"}' >&2
|
|
348
|
+
exit 2
|
|
349
|
+
fi
|
|
350
|
+
count=$((count + 1))
|
|
351
|
+
else
|
|
352
|
+
count=1
|
|
353
|
+
fi
|
|
354
|
+
else
|
|
355
|
+
count=1
|
|
356
|
+
fi
|
|
357
|
+
|
|
358
|
+
echo "$current_minute" > "$rate_file"
|
|
359
|
+
echo "$count" >> "$rate_file"
|
|
360
|
+
|
|
361
|
+
exit 0
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Audit Logging
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
#!/bin/bash
|
|
368
|
+
input=$(cat)
|
|
369
|
+
tool_name=$(echo "$input" | jq -r '.tool_name')
|
|
370
|
+
timestamp=$(date -Iseconds)
|
|
371
|
+
|
|
372
|
+
# Append to audit log
|
|
373
|
+
echo "$timestamp | $USER | $tool_name | $input" >> ~/.claude/audit.log
|
|
374
|
+
|
|
375
|
+
exit 0
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Secret Detection
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
#!/bin/bash
|
|
382
|
+
input=$(cat)
|
|
383
|
+
content=$(echo "$input" | jq -r '.tool_input.content')
|
|
384
|
+
|
|
385
|
+
# Check for common secret patterns
|
|
386
|
+
if echo "$content" | grep -qE "(api[_-]?key|password|secret|token).{0,20}['\"]?[A-Za-z0-9]{20,}"; then
|
|
387
|
+
echo '{"decision": "deny", "reason": "Potential secret detected in content"}' >&2
|
|
388
|
+
exit 2
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
exit 0
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Testing Advanced Hooks
|
|
395
|
+
|
|
396
|
+
### Unit Testing Hook Scripts
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
# test-hook.sh
|
|
400
|
+
#!/bin/bash
|
|
401
|
+
|
|
402
|
+
# Test 1: Approve safe command
|
|
403
|
+
result=$(echo '{"tool_input": {"command": "ls"}}' | bash validate-bash.sh)
|
|
404
|
+
if [ $? -eq 0 ]; then
|
|
405
|
+
echo "✓ Test 1 passed"
|
|
406
|
+
else
|
|
407
|
+
echo "✗ Test 1 failed"
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
# Test 2: Block dangerous command
|
|
411
|
+
result=$(echo '{"tool_input": {"command": "rm -rf /"}}' | bash validate-bash.sh)
|
|
412
|
+
if [ $? -eq 2 ]; then
|
|
413
|
+
echo "✓ Test 2 passed"
|
|
414
|
+
else
|
|
415
|
+
echo "✗ Test 2 failed"
|
|
416
|
+
fi
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Integration Testing
|
|
420
|
+
|
|
421
|
+
Create test scenarios that exercise the full hook workflow:
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
# integration-test.sh
|
|
425
|
+
#!/bin/bash
|
|
426
|
+
|
|
427
|
+
# Set up test environment
|
|
428
|
+
export CLAUDE_PROJECT_DIR="/tmp/test-project"
|
|
429
|
+
export CLAUDE_PLUGIN_ROOT="$(pwd)"
|
|
430
|
+
mkdir -p "$CLAUDE_PROJECT_DIR"
|
|
431
|
+
|
|
432
|
+
# Test SessionStart hook
|
|
433
|
+
echo '{}' | bash hooks/session-start.sh
|
|
434
|
+
if [ -f "/tmp/session-initialized" ]; then
|
|
435
|
+
echo "✓ SessionStart hook works"
|
|
436
|
+
else
|
|
437
|
+
echo "✗ SessionStart hook failed"
|
|
438
|
+
fi
|
|
439
|
+
|
|
440
|
+
# Clean up
|
|
441
|
+
rm -rf "$CLAUDE_PROJECT_DIR"
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Best Practices for Advanced Hooks
|
|
445
|
+
|
|
446
|
+
1. **Keep hooks independent**: Don't rely on execution order
|
|
447
|
+
2. **Use timeouts**: Set appropriate limits for each hook type
|
|
448
|
+
3. **Handle errors gracefully**: Provide clear error messages
|
|
449
|
+
4. **Document complexity**: Explain advanced patterns in README
|
|
450
|
+
5. **Test thoroughly**: Cover edge cases and failure modes
|
|
451
|
+
6. **Monitor performance**: Track hook execution time
|
|
452
|
+
7. **Version configuration**: Use version control for hook configs
|
|
453
|
+
8. **Provide escape hatches**: Allow users to bypass hooks when needed
|
|
454
|
+
|
|
455
|
+
## Common Pitfalls
|
|
456
|
+
|
|
457
|
+
### ❌ Assuming Hook Order
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
# BAD: Assumes hooks run in specific order
|
|
461
|
+
# Hook 1 saves state, Hook 2 reads it
|
|
462
|
+
# This can fail because hooks run in parallel!
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### ❌ Long-Running Hooks
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
# BAD: Hook takes 2 minutes to run
|
|
469
|
+
sleep 120
|
|
470
|
+
# This will timeout and block the workflow
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### ❌ Uncaught Exceptions
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
# BAD: Script crashes on unexpected input
|
|
477
|
+
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
|
|
478
|
+
cat "$file_path" # Fails if file doesn't exist
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### ✅ Proper Error Handling
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
# GOOD: Handles errors gracefully
|
|
485
|
+
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
|
|
486
|
+
if [ ! -f "$file_path" ]; then
|
|
487
|
+
echo '{"continue": true, "systemMessage": "File not found, skipping check"}' >&2
|
|
488
|
+
exit 0
|
|
489
|
+
fi
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Scoped Hooks in Skill/Agent Frontmatter
|
|
493
|
+
|
|
494
|
+
Hooks can be defined directly in skill or agent YAML frontmatter, scoping them to activate only when that component is in use.
|
|
495
|
+
|
|
496
|
+
### Concept
|
|
497
|
+
|
|
498
|
+
Unlike `hooks.json` (global, always active when plugin enabled) or settings hooks (user-level), scoped hooks are lifecycle-bound to a specific skill or agent. They activate when the component loads and deactivate when it completes.
|
|
499
|
+
|
|
500
|
+
### Format
|
|
501
|
+
|
|
502
|
+
The `hooks` field in frontmatter uses the same event/matcher/hook structure as `hooks.json`:
|
|
503
|
+
|
|
504
|
+
```yaml
|
|
505
|
+
---
|
|
506
|
+
name: secure-writer
|
|
507
|
+
description: Write files with safety validation...
|
|
508
|
+
hooks:
|
|
509
|
+
PreToolUse:
|
|
510
|
+
- matcher: Write
|
|
511
|
+
hooks:
|
|
512
|
+
- type: command
|
|
513
|
+
command: "${CLAUDE_PLUGIN_ROOT}/scripts/validate-write.sh"
|
|
514
|
+
timeout: 10
|
|
515
|
+
PostToolUse:
|
|
516
|
+
- matcher: Write
|
|
517
|
+
hooks:
|
|
518
|
+
- type: command
|
|
519
|
+
command: "${CLAUDE_PLUGIN_ROOT}/scripts/post-write-check.sh"
|
|
520
|
+
---
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Supported Events
|
|
524
|
+
|
|
525
|
+
Only a subset of hook events apply in frontmatter scope:
|
|
526
|
+
|
|
527
|
+
| Event | Purpose in Frontmatter |
|
|
528
|
+
| ------------- | -------------------------------------------------------------------------------------------------- |
|
|
529
|
+
| `PreToolUse` | Validate or block tool calls during skill execution |
|
|
530
|
+
| `PostToolUse` | Run checks after tool execution during skill use |
|
|
531
|
+
| `Stop` | Verify completion criteria before skill/agent finishes (auto-converted to SubagentStop for agents) |
|
|
532
|
+
|
|
533
|
+
Session-level events (`SessionStart`, `UserPromptSubmit`, `Notification`, etc.) don't apply — they operate at a different lifecycle scope.
|
|
534
|
+
|
|
535
|
+
### Comparison with hooks.json
|
|
536
|
+
|
|
537
|
+
| Aspect | `hooks.json` | Frontmatter `hooks` |
|
|
538
|
+
| -------------- | ------------------------------------------ | --------------------------------------------------- |
|
|
539
|
+
| Scope | Global (always active when plugin enabled) | Component-specific (active only during use) |
|
|
540
|
+
| Events | All 11+ hook events | PreToolUse, PostToolUse, Stop |
|
|
541
|
+
| Location | `hooks/hooks.json` file | YAML frontmatter in SKILL.md or agent .md |
|
|
542
|
+
| Merge behavior | Merges with user/project hooks | Merges with global hooks during component lifecycle |
|
|
543
|
+
|
|
544
|
+
### Use Cases
|
|
545
|
+
|
|
546
|
+
- **Skill-specific validation:** A "database writer" skill that validates SQL before execution
|
|
547
|
+
- **Restricted workflows:** A "deploy" skill that checks branch and test status before allowing Bash commands
|
|
548
|
+
- **Quality gates:** A "code generator" skill that runs linting after every Write operation
|
|
549
|
+
- **Agent safety:** An autonomous agent that validates all Bash commands before execution
|
|
550
|
+
|
|
551
|
+
### Both Hook Types Work
|
|
552
|
+
|
|
553
|
+
**Command hook** (deterministic script execution):
|
|
554
|
+
|
|
555
|
+
```yaml
|
|
556
|
+
hooks:
|
|
557
|
+
PreToolUse:
|
|
558
|
+
- matcher: Bash
|
|
559
|
+
hooks:
|
|
560
|
+
- type: command
|
|
561
|
+
command: "${CLAUDE_PLUGIN_ROOT}/scripts/check-safety.sh"
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
**Prompt hook** (LLM evaluation):
|
|
565
|
+
|
|
566
|
+
```yaml
|
|
567
|
+
hooks:
|
|
568
|
+
Stop:
|
|
569
|
+
- hooks:
|
|
570
|
+
- type: prompt
|
|
571
|
+
prompt: 'Verify all generated code has tests. Return {"decision": "stop"} if satisfied or {"decision": "continue", "reason": "missing tests"} if not.'
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
## Agent Hook Type
|
|
575
|
+
|
|
576
|
+
The `agent` hook type spawns a subagent for complex, multi-step verification workflows that require tool access.
|
|
577
|
+
|
|
578
|
+
### Concept
|
|
579
|
+
|
|
580
|
+
While `command` hooks execute bash scripts and `prompt` hooks evaluate a single LLM prompt, `agent` hooks create a full subagent that can use tools (Read, Bash, Grep, etc.) to perform thorough verification. This is the most powerful but most expensive hook type.
|
|
581
|
+
|
|
582
|
+
### Configuration
|
|
583
|
+
|
|
584
|
+
```json
|
|
585
|
+
{
|
|
586
|
+
"type": "agent",
|
|
587
|
+
"prompt": "Verify that all generated code has tests and passes linting. Check each modified file.",
|
|
588
|
+
"timeout": 120
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### Supported Events
|
|
593
|
+
|
|
594
|
+
Agent hooks are supported on **Stop** and **SubagentStop** events only. They aren't suitable for PreToolUse (too slow) or session-level events.
|
|
595
|
+
|
|
596
|
+
### When to Use Agent Hooks
|
|
597
|
+
|
|
598
|
+
| Hook Type | Speed | Capability | Best For |
|
|
599
|
+
| --------- | --------------- | --------------------- | --------------------------------------------- |
|
|
600
|
+
| `command` | Fast (~1-5s) | Bash scripts only | Deterministic checks, file validation |
|
|
601
|
+
| `prompt` | Medium (~5-15s) | Single LLM evaluation | Context-aware decisions, flexible logic |
|
|
602
|
+
| `agent` | Slow (~30-120s) | Multi-step with tools | Comprehensive verification, multi-file checks |
|
|
603
|
+
|
|
604
|
+
Use agent hooks when:
|
|
605
|
+
|
|
606
|
+
- Verification requires reading multiple files
|
|
607
|
+
- You need to run commands and analyze their output
|
|
608
|
+
- Single-prompt evaluation is insufficient
|
|
609
|
+
- Completion criteria are complex and multi-faceted
|
|
610
|
+
|
|
611
|
+
### Example: Comprehensive Completion Check
|
|
612
|
+
|
|
613
|
+
```json
|
|
614
|
+
{
|
|
615
|
+
"Stop": [
|
|
616
|
+
{
|
|
617
|
+
"matcher": "*",
|
|
618
|
+
"hooks": [
|
|
619
|
+
{
|
|
620
|
+
"type": "agent",
|
|
621
|
+
"prompt": "Before approving task completion, verify: 1) All modified files have corresponding tests, 2) Tests pass (run them), 3) No linting errors exist. Report findings and return approve/block decision.",
|
|
622
|
+
"timeout": 120
|
|
623
|
+
}
|
|
624
|
+
]
|
|
625
|
+
}
|
|
626
|
+
]
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
The agent will autonomously read files, run tests, check linting, and make a comprehensive decision about whether to allow the main agent to stop.
|
|
631
|
+
|
|
632
|
+
## Handler Configuration Fields
|
|
633
|
+
|
|
634
|
+
Beyond `type`, `command`/`prompt`, and `timeout`, hook handlers support additional fields:
|
|
635
|
+
|
|
636
|
+
### once
|
|
637
|
+
|
|
638
|
+
```json
|
|
639
|
+
{
|
|
640
|
+
"type": "command",
|
|
641
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/init.sh",
|
|
642
|
+
"once": true
|
|
643
|
+
}
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
When `true`, the hook runs only once per session and is then auto-removed. Useful for one-time initialization hooks in scoped contexts (skills/agents).
|
|
647
|
+
|
|
648
|
+
### statusMessage
|
|
649
|
+
|
|
650
|
+
```json
|
|
651
|
+
{
|
|
652
|
+
"type": "command",
|
|
653
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
|
|
654
|
+
"statusMessage": "Validating file write..."
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
Display text shown in the UI while the hook is executing. Helps users understand what's happening during longer hook operations.
|
|
659
|
+
|
|
660
|
+
## Event-Specific Matchers
|
|
661
|
+
|
|
662
|
+
Some hook events support matcher values beyond tool names:
|
|
663
|
+
|
|
664
|
+
| Event | Matcher Values |
|
|
665
|
+
| ------------- | ------------------------------------------------------------------------------ |
|
|
666
|
+
| SessionStart | `startup`, `resume`, `clear`, `compact` |
|
|
667
|
+
| SessionEnd | `clear`, `logout`, `prompt_input_exit`, `bypass_permissions_disabled`, `other` |
|
|
668
|
+
| Notification | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog` |
|
|
669
|
+
| PreCompact | `manual`, `auto` |
|
|
670
|
+
| SubagentStart | Agent type name (e.g., `Bash`, `Explore`, `Plan`, or custom agent names) |
|
|
671
|
+
| SubagentStop | Agent type name (same as SubagentStart) |
|
|
672
|
+
| PreToolUse | Tool name (exact, regex, or `*` wildcard) |
|
|
673
|
+
|
|
674
|
+
## Decision Control Output Schemas
|
|
675
|
+
|
|
676
|
+
Different hook events support different output formats for controlling Claude's behavior.
|
|
677
|
+
|
|
678
|
+
### PreToolUse Decision Control
|
|
679
|
+
|
|
680
|
+
```json
|
|
681
|
+
{
|
|
682
|
+
"hookSpecificOutput": {
|
|
683
|
+
"hookEventName": "PreToolUse",
|
|
684
|
+
"permissionDecision": "allow|deny|ask",
|
|
685
|
+
"permissionDecisionReason": "Explanation",
|
|
686
|
+
"updatedInput": { "field": "modified_value" },
|
|
687
|
+
"additionalContext": "Extra context for Claude"
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
- `permissionDecision`: `allow` (proceed), `deny` (block), `ask` (prompt user)
|
|
693
|
+
- `updatedInput`: Optionally modify tool parameters before execution
|
|
694
|
+
- `additionalContext`: Injected into Claude's context
|
|
695
|
+
|
|
696
|
+
### PermissionRequest Decision Control
|
|
697
|
+
|
|
698
|
+
```json
|
|
699
|
+
{
|
|
700
|
+
"hookSpecificOutput": {
|
|
701
|
+
"hookEventName": "PermissionRequest",
|
|
702
|
+
"decision": {
|
|
703
|
+
"behavior": "allow|deny",
|
|
704
|
+
"updatedInput": {},
|
|
705
|
+
"updatedPermissions": {},
|
|
706
|
+
"message": "Reason for denial",
|
|
707
|
+
"interrupt": false
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
- `behavior`: `allow` or `deny`
|
|
714
|
+
- `updatedInput`: Modified tool parameters (only with `allow`)
|
|
715
|
+
- `updatedPermissions`: Permission changes (only with `allow`)
|
|
716
|
+
- `message`: Shown to user (only with `deny`)
|
|
717
|
+
- `interrupt`: If true with `deny`, stops the current operation
|
|
718
|
+
|
|
719
|
+
### PostToolUse / Stop / UserPromptSubmit Decision Control
|
|
720
|
+
|
|
721
|
+
These events share a simpler top-level schema:
|
|
722
|
+
|
|
723
|
+
```json
|
|
724
|
+
{
|
|
725
|
+
"decision": "block",
|
|
726
|
+
"reason": "Explanation of why the action is blocked"
|
|
727
|
+
}
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
- `decision`: Set to `"block"` to prevent the action (stopping, prompt processing, etc.)
|
|
731
|
+
- `reason`: Required when blocking; fed back to Claude or shown to user
|
|
732
|
+
|
|
733
|
+
PostToolUse specifically supports an additional field for replacing MCP tool output:
|
|
734
|
+
|
|
735
|
+
```json
|
|
736
|
+
{
|
|
737
|
+
"updatedMCPToolOutput": "Replacement output for MCP tool response"
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
This allows hooks to replace what Claude sees as the MCP tool response before processing. Only applies to MCP tools in PostToolUse events.
|
|
742
|
+
|
|
743
|
+
### PostToolUseFailure Decision Control
|
|
744
|
+
|
|
745
|
+
PostToolUseFailure supports providing additional context to help Claude handle the failure:
|
|
746
|
+
|
|
747
|
+
```json
|
|
748
|
+
{
|
|
749
|
+
"additionalContext": "Extra context to help Claude handle the failure"
|
|
750
|
+
}
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### TeammateIdle and TaskCompleted
|
|
754
|
+
|
|
755
|
+
These events use **exit codes only** for decision control (no JSON output):
|
|
756
|
+
|
|
757
|
+
- Exit code `0`: Allow (teammate goes idle / task marked complete)
|
|
758
|
+
- Exit code `2`: Block — stderr is fed back to the teammate/model as feedback
|
|
759
|
+
|
|
760
|
+
### Common Output Fields (All Hooks)
|
|
761
|
+
|
|
762
|
+
These fields can be included in any hook's JSON output:
|
|
763
|
+
|
|
764
|
+
```json
|
|
765
|
+
{
|
|
766
|
+
"continue": true,
|
|
767
|
+
"stopReason": "Critical error, halting all processing",
|
|
768
|
+
"suppressOutput": false,
|
|
769
|
+
"systemMessage": "Warning message for the user"
|
|
770
|
+
}
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
- `continue`: If `false`, halts all processing (default: `true`)
|
|
774
|
+
- `stopReason`: Message when `continue` is `false`
|
|
775
|
+
- `suppressOutput`: Hide hook output from transcript (default: `false`)
|
|
776
|
+
- `systemMessage`: Warning/info message shown to the user
|
|
777
|
+
|
|
778
|
+
## TeammateIdle and TaskCompleted Events
|
|
779
|
+
|
|
780
|
+
These events support quality gates in agent team workflows.
|
|
781
|
+
|
|
782
|
+
### TeammateIdle
|
|
783
|
+
|
|
784
|
+
Fires when a teammate is about to go idle (stop processing). Use to keep teammates working or validate their output.
|
|
785
|
+
|
|
786
|
+
**Input schema:**
|
|
787
|
+
|
|
788
|
+
```json
|
|
789
|
+
{
|
|
790
|
+
"session_id": "...",
|
|
791
|
+
"teammate_name": "researcher",
|
|
792
|
+
"team_name": "my-project"
|
|
793
|
+
}
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
**Example hook:**
|
|
797
|
+
|
|
798
|
+
```json
|
|
799
|
+
{
|
|
800
|
+
"TeammateIdle": [
|
|
801
|
+
{
|
|
802
|
+
"matcher": "*",
|
|
803
|
+
"hooks": [
|
|
804
|
+
{
|
|
805
|
+
"type": "command",
|
|
806
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/check-teammate.sh"
|
|
807
|
+
}
|
|
808
|
+
]
|
|
809
|
+
}
|
|
810
|
+
]
|
|
811
|
+
}
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
### TaskCompleted
|
|
815
|
+
|
|
816
|
+
Fires when a task is marked complete. Use to verify task quality before accepting completion.
|
|
817
|
+
|
|
818
|
+
**Input schema:**
|
|
819
|
+
|
|
820
|
+
```json
|
|
821
|
+
{
|
|
822
|
+
"session_id": "...",
|
|
823
|
+
"task_id": "123",
|
|
824
|
+
"task_subject": "Implement feature X",
|
|
825
|
+
"task_description": "...",
|
|
826
|
+
"teammate_name": "implementer",
|
|
827
|
+
"team_name": "my-project"
|
|
828
|
+
}
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
**Example hook:**
|
|
832
|
+
|
|
833
|
+
```json
|
|
834
|
+
{
|
|
835
|
+
"TaskCompleted": [
|
|
836
|
+
{
|
|
837
|
+
"matcher": "*",
|
|
838
|
+
"hooks": [
|
|
839
|
+
{
|
|
840
|
+
"type": "command",
|
|
841
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/verify-task.sh"
|
|
842
|
+
}
|
|
843
|
+
]
|
|
844
|
+
}
|
|
845
|
+
]
|
|
846
|
+
}
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
## Async Hooks
|
|
850
|
+
|
|
851
|
+
Command hooks can run asynchronously in the background without blocking the main flow:
|
|
852
|
+
|
|
853
|
+
```json
|
|
854
|
+
{
|
|
855
|
+
"type": "command",
|
|
856
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/log-event.sh",
|
|
857
|
+
"async": true
|
|
858
|
+
}
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
**Key constraints:**
|
|
862
|
+
|
|
863
|
+
- Only available on `type: "command"` hooks (not prompt or agent)
|
|
864
|
+
- Cannot block or control behavior — the action proceeds immediately
|
|
865
|
+
- Response fields (`decision`, `hookSpecificOutput`) have no effect
|
|
866
|
+
- Useful for logging, metrics collection, and fire-and-forget notifications
|
|
867
|
+
- Uses the same `timeout` field (default: 600 seconds)
|
|
868
|
+
|
|
869
|
+
## Conclusion
|
|
870
|
+
|
|
871
|
+
Advanced hook patterns enable sophisticated automation while maintaining reliability and performance. Use these techniques when basic hooks are insufficient, but always prioritize simplicity and maintainability.
|