create-hooks

from glittercowboy/taches-cc-resources

A collection of my favorite custom Claude Code resources to make life easier.

1.2K stars328 forksUpdated Jan 26, 2026
npx skills add https://github.com/glittercowboy/taches-cc-resources --skill create-hooks

SKILL.md

Hooks are event-driven automation for Claude Code that execute shell commands or LLM prompts in response to tool usage, session events, and user interactions. This skill teaches you how to create, configure, and debug hooks for validating commands, automating workflows, injecting context, and implementing custom completion criteria.

Hooks provide programmatic control over Claude's behavior without modifying core code, enabling project-specific automation, safety checks, and workflow customization.

Hooks are shell commands or LLM-evaluated prompts that execute in response to Claude Code events. They operate within an event hierarchy: events (PreToolUse, PostToolUse, Stop, etc.) trigger matchers (tool patterns) which fire hooks (commands or prompts). Hooks can block actions, modify tool inputs, inject context, or simply observe and log Claude's operations.

<quick_start>

  1. Create hooks config file:
    • Project: .claude/hooks.json
    • User: ~/.claude/hooks.json
  2. Choose hook event (when it fires)
  3. Choose hook type (command or prompt)
  4. Configure matcher (which tools trigger it)
  5. Test with claude --debug
**Log all bash commands**:

.claude/hooks.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \\\"No description\\\")\"' >> ~/.claude/bash-log.txt"
          }
        ]
      }
    ]
  }
}

This hook:

  • Fires before (PreToolUse) every Bash tool use
  • Executes a command (not an LLM prompt)
  • Logs command + description to a file

</quick_start>

<hook_types>

EventWhen it firesCan block?
PreToolUseBefore tool executionYes
PostToolUseAfter tool executionNo
UserPromptSubmitUser submits a promptYes
StopClaude attempts to stopYes
SubagentStopSubagent attempts to stopYes
SessionStartSession beginsNo
SessionEndSession endsNo
PreCompactBefore context compactionYes
NotificationClaude needs inputNo

Blocking hooks can return "decision": "block" to prevent the action. See references/hook-types.md for detailed use cases. </hook_types>

<hook_anatomy> <hook_type name="command"> Type: Executes a shell command

Use when:

  • Simple validation (check file exists)
  • Logging (append to file)
  • External tools (formatters, linters)
  • Desktop notifications

Input: JSON via stdin Output: JSON via stdout (optional)

{
  "type": "command",
  "command": "/path/to/script.sh",
  "timeout": 30000
}

</hook_type>

<hook_type name="prompt"> Type: LLM evaluates a prompt

Use when:

  • Complex decision logic
  • Natural language validation
  • Context-aware checks
  • Reasoning required

Input: Prompt with $ARGUMENTS placeholder Output: JSON with decision and reason

{
  "type": "prompt",
  "prompt": "Evaluate if this command is safe: $ARGUMENTS\n\nReturn JSON: {\"decision\": \"approve\" or \"block\", \"reason\": \"explanation\"}"
}

</hook_type> </hook_anatomy>

Matchers filter which tools trigger the hook:
{
  "matcher": "Bash",           // Exact match
  "matcher": "Write|Edit",     // Multiple tools (regex OR)
  "matcher": "mcp__.*",        // All MCP tools
  "matcher": "mcp__memory__.*" // Specific MCP server
}

No matcher: Hook fires for all tools

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [...]  // No matcher - fires on every user prompt
      }
    ]
  }
}

<input_output> Hooks receive JSON via stdin with session info, current directory, and event-specific data. Blocking hooks can return JSON to approve/block actions or modify inputs.

Example output (blocking hooks):

{
  "decision": "approve" | "block",
  "reason": "Why this decision was made"
}

See references/input-output-schemas.md for complete schemas for each hook type. </input_output>

<environment_variables> Available in hook commands:

VariableValue
$CLAUDE_PROJECT_DIRProject root directory
${CLAUDE_PLUGIN_ROOT}Plugin directory (plugin hooks only)
$ARGUMENTSHook input JSON (prompt hooks only)

Example:

{
  "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate.sh"
}

</environment_variables>

<common_patterns> Desktop notification when input needed:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude needs input\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

**Block destru

...

Read full content

Repository Stats

Stars1.2K
Forks328
LicenseMIT License