hook-audit

from philoserf/claude-code-setup

Comprehensive Claude Code configuration with agents, skills, hooks, and automation

9 stars0 forksUpdated Jan 23, 2026
npx skills add https://github.com/philoserf/claude-code-setup --skill hook-audit

SKILL.md

Reference Files

Advanced hook patterns and best practices:


Hook Audit

Performs comprehensive security and quality audits of Claude Code hooks, ensuring correct JSON handling, exit code semantics, error handling, and performance.

Quick Start

Audit a single hook:

User: "Audit my validate-config.py hook"
Assistant: [Reads hook file, checks patterns, generates report]

Audit all hooks:

User: "Check all my hooks for best practices"
Assistant: [Finds all hooks, analyzes each, generates consolidated report]

Fix specific issues:

User: "My hook is blocking on errors"
Assistant: [Analyzes error handling, suggests fixes]

Hook Audit Checklist

Use this checklist to audit any Claude Code hook:

Critical Requirements

  • Shebang Line: Correct interpreter for hook type (see Shebang Standards below)
    • Python hooks: #!/usr/bin/env python3
    • Bash hooks: #!/bin/bash (NOT #!/usr/bin/env bash or #!/bin/sh)
  • JSON stdin Handling: Safe parsing with try/except and .get() methods
  • Exit Codes: Correct semantics (0=allow, 2=block, never 1)
  • Error Handling: Exit 0 on hook errors (never block on hook failures)
  • Settings.json Registration: Hook is registered with correct matcher and timeout

High Priority

  • Timeout: Configured appropriately for hook type (PreToolUse <500ms, PostToolUse <2s)
  • File Type Validation: Checks file type before processing
  • Error Messages: Clear messages to stderr
  • Performance: Executes within reasonable time

Medium Priority

  • Naming Convention: Uses kebab-case naming
  • Documentation: Header comments explain purpose and usage
  • Pattern Consistency: Follows existing hook patterns
  • Security: No security vulnerabilities or unsafe operations

Audit Workflow

Step 1: Identify Hook Type

Determine the hook type from settings.json registration:

  • PreToolUse: Runs before tool execution, can block operations
  • PostToolUse: Runs after successful tool execution
  • Notification: Runs on specific events (Idle, etc.)
  • SessionStart: Runs once at session start

Hook type determines performance requirements and exit code handling.

Step 2: Read Hook File and Check Syntax

Read the hook file and verify basic syntax:

# For Python hooks
python3 -m py_compile hook-file.py

# For Bash hooks
bash -n hook-file.sh

Check for:

  • Correct shebang line
  • Executable permissions
  • Valid syntax

Step 3: Verify JSON Handling Pattern

For hooks that receive JSON stdin (PreToolUse, PostToolUse), verify safe parsing:

Python Pattern:

try:
    data = json.load(sys.stdin)
    file_path = data.get("tool_input", {}).get("file_path", "")
    content = data.get("tool_input", {}).get("content", "")
except Exception as e:
    print(f"Error: {e}", file=sys.stderr)
    sys.exit(0)  # Don't block on parsing errors

Bash Pattern:

# Read stdin to variable
stdin_data=$(cat)

# Parse specific fields with jq
file_path=$(echo "$stdin_data" | jq -r '.tool_input.file_path // empty')

Critical: Use .get() with defaults, never direct key access.

Step 4: Check Exit Code Usage

Verify exit codes follow correct semantics:

  • Exit 0: Allow operation (or hook encountered error)
  • Exit 2: Block operation (validation failed)
  • Never Exit 1: Reserved, don't use

Pattern to Check:

# Good: Block on validation failure
if errors:
    print(f"Validation errors:", file=sys.stderr)
    sys.exit(2)

# Good: Allow on hook error
except Exception as e:
    print(f"Hook error: {e}", file=sys.stderr)
    sys.exit(0)  # Don't block user

# Bad: Exit 1 or non-zero on errors
sys.exit(1)  # ✗ Wrong, use 0 or 2

For details on exit code patterns, see exit-codes.md.

Step 5: Review Error Handling

Check that hooks degrade gracefully:

  1. Dependency Check: Missing dependencies exit 0 (don't block)
  2. Try/Except: All operations wrapped in try/except
  3. Error Exit: Exceptions exit 0, not 1 or other codes
  4. Clear Messages: Errors printed to stderr with context

Example Pattern:

try:
    import yaml
except ImportError:
    print("Warning: PyYAML not installed, skipping", file=sys.stderr)
    sys.exit(0)  # Don't block user

try:
    # Hook logic here
    ...
except Exception as e:
    print(f"Error in hook: {e}", file=sys.stderr)
    sys.exit(0)  # Don't block user

For error handling patterns, see [error-patterns.md]

...

Read full content

Repository Stats

Stars9
Forks0
LicenseMIT License