install
source · Clone the upstream repo
git clone https://github.com/claude-world/director-mode-lite
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/claude-world/director-mode-lite "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/hook-template" ~/.claude/skills/claude-world-director-mode-lite-hook-template && rm -rf "$T"
manifest:
skills/hook-template/SKILL.mdsource content
Hook Template Generator
Generate a hook script and configuration based on requirements.
Usage:
/hook-template [hook-type] [purpose]
Hook Types
| Type | When it Runs | Use Case |
|---|---|---|
| Before a tool runs | Block, validate, add context |
| After a tool completes | Log, notify, react |
| User submits a prompt | Context injection, validation |
| Main agent stopping | Completeness check, continue loops |
| Subagent finishes | Task validation |
| Session begins | Context loading, env setup |
| Session ends | Cleanup, logging |
| Before context compaction | Preserve critical context |
| After compaction completes | Context recovery |
| User is notified | External alerts (Slack, etc.) |
| MCP server requests input | Override elicitation |
| Elicitation result available | Post-process |
Hook Config Fields
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| String | Yes | - | or |
| String | If type=command | - | Shell command to execute |
| String | If type=prompt | - | Natural language prompt for LLM |
| Integer | No | 60s (command), 30s (prompt) | Seconds |
| Boolean | No | false | Run hook only once per session |
Hook Input (stdin JSON)
All hooks receive JSON on stdin with these fields:
{ "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" } }
Process
-
Gather Requirements
- Hook type
- Purpose
- Matcher (for Pre/PostToolUse: 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)
#!/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 fi exit 0 # Allow (no output needed)
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 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