Hook template
Generate hook script from template. Use when adding a new hook, wiring a PreToolUse/PostToolUse/Stop/Notification hook, or scaffolding hook config for settings.json.From its SKILL.md
npx -y skills add claude-world/director-mode-lite --skill hook-templateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- runs commandsInstructs the agent to run 2 commands, including `chmod +x` and 1 more.
SKILL.md
6.1 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it
Hook Template Generator
Generate a hook script and configuration based on requirements.
Usage: /hook-template [hook-event] [purpose]
Hook Events
Claude Code defines 30 hook events. The common ones, grouped:
| Group | Events |
|---|---|
| Lifecycle | SessionStart, SessionEnd, Setup |
| Prompt | UserPromptSubmit, UserPromptExpansion |
| Tool | PreToolUse, PostToolUse, PostToolUseFailure, PostToolBatch |
| Permission | PermissionRequest, PermissionDenied |
| Subagent | SubagentStart, SubagentStop |
| Stop | Stop, StopFailure |
| Task | TaskCreated, TaskCompleted |
| Compaction | PreCompact, PostCompact |
| Notification | Notification, MessageDisplay |
| MCP elicitation | Elicitation, ElicitationResult |
| Environment | ConfigChange, CwdChanged, FileChanged, InstructionsLoaded, WorktreeCreate, WorktreeRemove, TeammateIdle |
That is all 30 events. See the official Claude Code hooks docs for the full list and each event's payload. The templates below cover the practical 90%.
Hook Config Fields
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
type | String | No | command | command, prompt, http, mcp_tool, or agent |
command | String | If type=command | - | Shell command to execute |
prompt | String | If type=prompt | - | Natural language prompt evaluated by an LLM |
matcher | String | No | - | For tool events: tool name, regex, or * |
timeout | Integer | No | 60 | Seconds, per hook |
once | Boolean | No | false | Run hook only once per session |
if | String | No | - | Conditional guard for the hook |
statusMessage | String | No | - | Message shown while the hook runs |
type: command (default) and type: prompt (LLM-evaluated) cover most needs.
The http, mcp_tool, and agent entry types also exist for calling an
endpoint, invoking an MCP tool, or dispatching a subagent.
Hook Input (stdin JSON)
All hooks receive JSON on stdin. The event name is in hook_event_name:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.txt",
"cwd": "/current/working/dir",
"permission_mode": "ask",
"hook_event_name": "PreToolUse",
"tool_name": "Write",
"tool_input": { "file_path": "/path/to/file" }
}
Decision output cheatsheet
- PreToolUse: return
hookSpecificOutput.permissionDecisionofallow,deny, orask. Exit code 2 with a stderr message is the shorthand fordeny. The legacy top-level{"decision": "approve" | "block"}is still accepted. - Stop / SubagentStop: to continue the loop, return
{"decision": "block", "reason": "<next prompt>"}— the key isreason. - Silent success is exit
0with no output.
Process
-
Gather Requirements
- Hook event
- Purpose
- Matcher (for tool events: tool name, regex, or
*)
-
Generate Script at
.claude/hooks/[name].sh -
Update settings.json with hook config
-
Make Executable:
chmod +x -
Validate with
/hooks-check
Templates
PreToolUse (Blocker, exit-code shorthand)
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# Block edits to specific files
if [[ "$FILE" == *"package-lock.json"* ]]; then
echo "BLOCKED: Do not edit lockfiles directly" >&2
exit 2 # exit 2 = deny for PreToolUse
fi
exit 0 # Allow (no output needed)
PreToolUse (Deny via JSON permissionDecision)
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE" == *"package-lock.json"* ]]; then
jq -n '{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Do not edit lockfiles directly"
}
}'
exit 0
fi
# permissionDecision may be "allow", "deny", or "ask"
exit 0
PreToolUse (Context Adding)
#!/bin/bash
cat > /dev/null # Consume stdin
INFO="This file requires careful review"
jq -n --arg ctx "$INFO" '{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": $ctx
}
}'
exit 0
PostToolUse (Logger)
#!/bin/bash
INPUT=$(cat)
# Process and log... (no stdout needed)
exit 0
Stop (Auto-Loop)
#!/bin/bash
CHECKPOINT=".auto-loop/checkpoint.json"
if [[ ! -f "$CHECKPOINT" ]]; then
exit 0 # Allow stop
fi
# Block stop to continue loop — key is "reason", used as the next prompt
jq -n --arg reason "Continuing iteration" \
'{"decision": "block", "reason": $reason}'
exit 0
SessionStart (Context Load)
#!/bin/bash
cat > /dev/null
echo "Loading project context..." >&2
exit 0
Prompt Hook (LLM-based)
Instead of a bash script, use type: "prompt" in settings.json:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "prompt",
"prompt": "Review the work done. Return 'approve' if complete, or 'block' with reason.",
"timeout": 30
}
]
}
]
}
}
Settings.json Format
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate.sh",
"timeout": 60
}
]
}
],
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/load-context.sh",
"once": true
}
]
}
]
}
}
Example
/hook-template PreToolUse "block edits to package-lock.json"
Creates:
- .claude/hooks/protect-lockfile.sh
- Updates .claude/settings.json
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most project setup skills give in ~1.6k tokens
Counted across 1,553 of the 3,091 authors here whose files we hold, read 2026-09-06
- Write the configuration filein 36 of 1553
- Create the directory structurein 35 of 1553, across 33 files
- Verify the setupin 31 of 1553, across 28 files
- Run the setup scriptin 30 of 1553, across 29 files
- Pre-determine the required sample sizein 29 of 1553, across 12 files
- Check if the configuration already existsin 29 of 1553
- Document every testin 26 of 1553, across 10 files
- Start with a hypothesisin 26 of 1553, across 11 files
- Ask one question at a timein 22 of 1553
- Test a single variable per testin 21 of 1553, across 9 files
- Read product marketing context before asking questionsin 19 of 1553, across 8 files
- Do not peek and stop earlyin 18 of 1553, across 7 files
Said here and by no other author read
- Gather hook event and purpose requirements
- Generate script at specified path
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.