Skip to content
cccskills
FreePublished on GitHub

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.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md6.1 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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:

GroupEvents
LifecycleSessionStart, SessionEnd, Setup
PromptUserPromptSubmit, UserPromptExpansion
ToolPreToolUse, PostToolUse, PostToolUseFailure, PostToolBatch
PermissionPermissionRequest, PermissionDenied
SubagentSubagentStart, SubagentStop
StopStop, StopFailure
TaskTaskCreated, TaskCompleted
CompactionPreCompact, PostCompact
NotificationNotification, MessageDisplay
MCP elicitationElicitation, ElicitationResult
EnvironmentConfigChange, 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

FieldTypeRequiredDefaultNotes
typeStringNocommandcommand, prompt, http, mcp_tool, or agent
commandStringIf type=command-Shell command to execute
promptStringIf type=prompt-Natural language prompt evaluated by an LLM
matcherStringNo-For tool events: tool name, regex, or *
timeoutIntegerNo60Seconds, per hook
onceBooleanNofalseRun hook only once per session
ifStringNo-Conditional guard for the hook
statusMessageStringNo-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.permissionDecision of allow, deny, or ask. Exit code 2 with a stderr message is the shorthand for deny. The legacy top-level {"decision": "approve" | "block"} is still accepted.
  • Stop / SubagentStop: to continue the loop, return {"decision": "block", "reason": "<next prompt>"} — the key is reason.
  • Silent success is exit 0 with no output.

Process

  1. Gather Requirements

    • Hook event
    • Purpose
    • Matcher (for tool events: tool name, regex, or *)
  2. Generate Script at .claude/hooks/[name].sh

  3. Update settings.json with hook config

  4. Make Executable: chmod +x

  5. 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

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Validate custom agent file format and structure. Use after creating or editing an agent, before committing agent changes, or when an agent fails to load.

The English summary is being prepared. Showing the original description.

claude-world/director-mode-lite80Updated Aug 31, 2026

Generate custom agent from template. Use when creating a new subagent from scratch, or scaffolding an agent file with correct frontmatter.

The English summary is being prepared. Showing the original description.

claude-world/director-mode-lite80Updated Aug 31, 2026

agents

Free

List all available agents (core, expert, self-evolving). Use when the user asks what agents are available or runs /agents.

The English summary is being prepared. Showing the original description.

claude-world/director-mode-lite80Updated Aug 31, 2026

TDD-based autonomous development loop with checkpoint recovery and observability changelog

The English summary is being prepared. Showing the original description.

claude-world/director-mode-lite80Updated Aug 31, 2026

View and manage the runtime changelog for observability

The English summary is being prepared. Showing the original description.

claude-world/director-mode-lite80Updated Aug 31, 2026

Track development session events in a daily markdown changelog, including file changes, test results, and key decisions.

The English summary is being prepared. Showing the original description.

claude-world/director-mode-lite80Updated Aug 31, 2026

See all skills by claude-world

Report a problem with this skill