Claude Code Plugins

Community-maintained marketplace

Feedback

claude-code-hooks

@filipexyz/plugins
0
0

Implement Claude Code hooks for deterministic control over agent behavior. Use when creating custom hooks for notifications, auto-formatting, logging, feedback, permissions, or lifecycle events.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name claude-code-hooks
description Implement Claude Code hooks for deterministic control over agent behavior. Use when creating custom hooks for notifications, auto-formatting, logging, feedback, permissions, or lifecycle events.

Claude Code Hooks

Hooks are shell commands that execute at specific points in Claude Code's lifecycle, providing deterministic control over behavior.

Hook Events

Event When it runs Can block?
PreToolUse Before tool execution Yes
PermissionRequest When permission dialog shown Yes
PostToolUse After tool completes Feedback only
UserPromptSubmit When user submits prompt Yes
Notification When notification sent No
Stop When agent finishes Can continue
SubagentStop When subagent finishes Can continue
PreCompact Before compact operation No
SessionStart Session starts/resumes No
SessionEnd Session ends No

Configuration

Hooks are defined in settings files:

  • ~/.claude/settings.json - User settings (all projects)
  • .claude/settings.json - Project settings
  • .claude/settings.local.json - Local settings (not committed)

Basic Structure

{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command",
            "command": "your-command-here",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

Matcher patterns:

  • Exact match: Write, Bash, Read
  • Regex: Edit|Write, Notebook.*, mcp__memory__.*
  • Match all: * or ""

Hook Input

Hooks receive JSON via stdin:

{
  "session_id": "abc123",
  "transcript_path": "/path/to/transcript.jsonl",
  "cwd": "/current/directory",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse",
  "tool_name": "Write",
  "tool_input": { "file_path": "/path/to/file", "content": "..." },
  "tool_use_id": "toolu_01ABC..."
}

Hook Output

Exit Codes

  • 0: Success (stdout shown in verbose mode)
  • 2: Blocking error (stderr fed back to Claude)
  • Other: Non-blocking error (stderr shown in verbose mode)

JSON Output (exit code 0)

{
  "decision": "block",
  "reason": "Explanation for Claude",
  "continue": true,
  "stopReason": "Message when continue=false",
  "systemMessage": "Warning for user"
}

Quick Examples

Log Bash Commands

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

Auto-Format on Save

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "jq -r '.tool_input.file_path' | xargs -I{} sh -c 'echo \"{}\" | grep -q \"\\.ts$\" && npx prettier --write \"{}\"'"
        }]
      }
    ]
  }
}

Block Sensitive Files

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "jq -e '.tool_input.file_path | test(\"\\\\.env|secrets|credentials\")' > /dev/null && echo 'Cannot modify sensitive files' >&2 && exit 2 || exit 0"
        }]
      }
    ]
  }
}

Environment Variables

  • CLAUDE_PROJECT_DIR - Absolute path to project root
  • CLAUDE_PLUGIN_ROOT - Plugin directory (for plugin hooks)
  • CLAUDE_ENV_FILE - File to persist env vars (SessionStart only)
  • CLAUDE_CODE_REMOTE - "true" if running in remote/web environment

References