Skip to content
  • Claude-Code-Hooks
  • Implementation-Guide
  • Production-Operations
  • Hands-On
  • Development-Automation
  • Practical-Edition categories:
  • AI-Development-Automation
  • Development-Efficiency author: Claude Code content_type: hands-on-guide

Claude Code Complete Guide

Claude Code Hooks Complete Implementation Guide: Hands-On Production Operations [August 2025 Latest]

Introduction

While the Claude Code Hooks Revolution article covered the overview of Claude Code Hooks, there are many implementation challenges when introducing them into actual production environments.

This article provides a complete implementation guide for reliably introducing and operating Claude Code Hooks, focusing on working code examples and production operation considerations.

🎯 What You Can Achieve

  • Zero-Downtime Introduction

    Minimize risk with gradual introduction to existing projects

  • Practical Configuration Collection

    Proven configuration files ready to copy and paste

  • Error Handling

    Reliable failure response in production environments

  • Performance Optimization

    Improved execution efficiency in large-scale projects

🛠️ Production Preparation: Environment Setup

1. Directory Structure Setup

First, build a directory structure to manage Claude Code Hooks configuration systematically:

# Execute at project root
mkdir -p .claude/{hooks,scripts,logs,configs}

# Prepare Claude Code configuration directory
mkdir -p ~/.claude/{hooks,templates,backups}

# Log rotation configuration
sudo mkdir -p /var/log/claude-hooks
sudo chown $USER:$USER /var/log/claude-hooks

2. Creating Base Configuration Files

# ~/.claude/settings.toml
[hooks]
log_level = "INFO"
log_file = "/var/log/claude-hooks/hooks.log"
timeout = 300  # 5 minute timeout
retry_count = 3
enable_background = true

[hooks.environment]
# Environment variable settings
PATH_EXTENSION = "/usr/local/bin:~/.local/bin"
NODE_ENV = "development"
PYTHONPATH = "."

[hooks.security]
# Security settings
max_file_size = "10MB"
allowed_extensions = ["py", "js", "ts", "jsx", "tsx", "md", "yml", "yaml", "json"]
blocked_paths = ["node_modules", ".git", "dist", "build", "__pycache__"]

[hooks.performance]
# Performance settings
parallel_execution = true
max_concurrent_hooks = 4
cache_enabled = true
cache_ttl = 300  # 5 minutes

3. Preparing Common Script Library

#!/bin/bash
# ~/.claude/scripts/common.sh - Common function library

# Log output function
log() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a /var/log/claude-hooks/hooks.log
}

# Error handling function
handle_error() {
    local exit_code=$1
    local command=$2
    local file_path=$3

    if [ $exit_code -ne 0 ]; then
        log "ERROR" "Command '$command' failed with exit code $exit_code for file: $file_path"
        # Slack notification (optional)
        if command -v slack-notify &> /dev/null; then
            slack-notify "#dev-alerts" "🚨 Hook execution failed: $command ($file_path)"
        fi
        return $exit_code
    fi
    return 0
}

# File validation function
validate_file() {
    local file_path=$1
    local max_size=${2:-10485760}  # 10MB default

    # File existence check
    if [ ! -f "$file_path" ]; then
        log "ERROR" "File not found: $file_path"
        return 1
    fi

    # File size check
    local file_size=$(stat -f%z "$file_path" 2>/dev/null || stat -c%s "$file_path" 2>/dev/null)
    if [ $file_size -gt $max_size ]; then
        log "WARN" "File size exceeds limit: $file_path ($file_size bytes)"
        return 2
    fi

    return 0
}

# Process management function
is_process_running() {
    local process_name=$1
    pgrep "$process_name" > /dev/null 2>&1
}

wait_for_process() {
    local process_name=$1
    local timeout=${2:-30}
    local count=0

    while is_process_running "$process_name" && [ $count -lt $timeout ]; do
        sleep 1
        ((count++))
    done

    if [ $count -ge $timeout ]; then
        log "WARN" "Process $process_name did not finish within $timeout seconds"
        return 1
    fi
    return 0
}

🔧 Language-Specific Implementation Patterns

Python Project Complete Configuration

# Comprehensive Python-specific configuration
[[hooks]]
name = "Python File Validation"
event = "PreToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
source ~/.claude/scripts/common.sh

for file in $CLAUDE_FILE_PATHS; do
    log "INFO" "Validating Python file: $file"

    # File validation
    validate_file "$file" || exit 1

    # Python syntax check
    python -m py_compile "$file"
    handle_error $? "python -m py_compile" "$file" || exit 1

    # Import validation
    python -c "import ast; ast.parse(open('$file').read())"
    handle_error $? "AST parse check" "$file" || exit 1

    log "INFO" "✅ Python file validation passed: $file"
done
"""

[[hooks]]
name = "Python Format and Quality"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
source ~/.claude/scripts/common.sh

# Lock to prevent concurrent execution
LOCK_FILE="/tmp/python-format.lock"
if [ -f "$LOCK_FILE" ]; then
    wait_for_process "python-format" 30
fi
touch "$LOCK_FILE"

trap 'rm -f "$LOCK_FILE"' EXIT

for file in $CLAUDE_FILE_PATHS; do
    log "INFO" "Formatting Python file: $file"

    # Create backup
    cp "$file" "$file.backup"

    # Execute formatting
    black "$file" --line-length 88 --target-version py39
    handle_error $? "black" "$file" || { cp "$file.backup" "$file"; exit 1; }

    isort "$file" --profile black
    handle_error $? "isort" "$file" || { cp "$file.backup" "$file"; exit 1; }

    # Ruff validation
    ruff check "$file" --fix
    handle_error $? "ruff check" "$file" || { cp "$file.backup" "$file"; exit 1; }

    # Delete backup
    rm -f "$file.backup"

    log "INFO" "✅ Python formatting completed: $file"
done
"""

[[hooks]]
name = "Python Test Runner"
event = "PostToolUse"
run_in_background = true
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["src/**/*.py", "tests/**/*.py", "test_*.py", "*_test.py"]
command = """
source ~/.claude/scripts/common.sh

log "INFO" "Starting Python test execution"

# Detect project root
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
cd "$PROJECT_ROOT"

# Check virtual environment
if [ -f "venv/bin/activate" ]; then
    source venv/bin/activate
    log "INFO" "Activated virtual environment"
elif [ -f ".venv/bin/activate" ]; then
    source .venv/bin/activate
    log "INFO" "Activated .venv virtual environment"
fi

# Execute tests
if [ -f "pytest.ini" ] || [ -f "pyproject.toml" ] || [ -f "setup.cfg" ]; then
    # When pytest configuration file exists
    pytest --tb=short -q --no-header --disable-warnings
    test_result=$?
else
    # Execute tests with default configuration
    python -m pytest tests/ -v --tb=short
    test_result=$?
fi

if [ $test_result -eq 0 ]; then
    log "INFO" "✅ All Python tests passed"

    # Coverage report (optional)
    if command -v coverage &> /dev/null; then
        coverage report --show-missing --skip-covered | tail -n 10
    fi
else
    log "ERROR" "❌ Python tests failed with exit code: $test_result"
fi

exit $test_result
"""

[[hooks]]
name = "Python Security Scan"
event = "PostToolUse"
run_in_background = true
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
source ~/.claude/scripts/common.sh

log "INFO" "Starting Python security scan"

for file in $CLAUDE_FILE_PATHS; do
    # Bandit security check
    if command -v bandit &> /dev/null; then
        bandit -r "$file" -f json -q 2>/dev/null | jq -r '.results[] | select(.issue_severity == "HIGH" or .issue_severity == "MEDIUM") | "\(.issue_severity): \(.issue_text) (\(.filename):\(.line_number))"'
        if [ ${PIPESTATUS[0]} -ne 0 ]; then
            log "WARN" "Security issues found in: $file"
        fi
    fi

    # Sensitive information detection
    if grep -E "(password|secret|key|token|api_key)" "$file" | grep -v "#"; then
        log "WARN" "Potential secrets detected in: $file"
    fi
done

log "INFO" "Python security scan completed"
"""

TypeScript/React Project Configuration

[[hooks]]
name = "TypeScript Quality Pipeline"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.ts", "*.tsx", "*.js", "*.jsx"]
command = """
source ~/.claude/scripts/common.sh

# Detect project root
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
cd "$PROJECT_ROOT"

log "INFO" "Starting TypeScript quality pipeline"

# Check Node.js project
if [ ! -f "package.json" ]; then
    log "ERROR" "package.json not found"
    exit 1
fi

# Detect npm/yarn/pnpm
PACKAGE_MANAGER="npm"
if [ -f "yarn.lock" ]; then
    PACKAGE_MANAGER="yarn"
elif [ -f "pnpm-lock.yaml" ]; then
    PACKAGE_MANAGER="pnpm"
fi

log "INFO" "Using package manager: $PACKAGE_MANAGER"

# Check dependencies
$PACKAGE_MANAGER list --depth=0 > /dev/null 2>&1
if [ $? -ne 0 ]; then
    log "INFO" "Installing dependencies..."
    $PACKAGE_MANAGER install
fi

for file in $CLAUDE_FILE_PATHS; do
    log "INFO" "Processing TypeScript file: $file"

    # Prettier formatting
    if [ -f ".prettierrc" ] || [ -f ".prettierrc.json" ]; then
        npx prettier --write "$file"
        handle_error $? "prettier" "$file" || exit 1
    fi

    # ESLint fix
    if [ -f ".eslintrc.js" ] || [ -f ".eslintrc.json" ] || [ -f "eslint.config.js" ]; then
        npx eslint --fix "$file"
        handle_error $? "eslint" "$file" || exit 1
    fi
done

# TypeScript type check
if [ -f "tsconfig.json" ]; then
    log "INFO" "Running TypeScript type check"
    npx tsc --noEmit
    handle_error $? "tsc --noEmit" "TypeScript project" || exit 1
fi

log "INFO" "✅ TypeScript quality pipeline completed"
"""

[[hooks]]
name = "React Component Testing"
event = "PostToolUse"
run_in_background = true
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["src/components/**/*.tsx", "src/components/**/*.ts"]
command = """
source ~/.claude/scripts/common.sh

PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
cd "$PROJECT_ROOT"

log "INFO" "Starting React component testing"

# Check test files
if [ -d "src/__tests__" ] || [ -d "tests" ] || ls src/**/*.test.* 1> /dev/null 2>&1; then
    # Execute Jest tests
    if [ -f "jest.config.js" ] || grep -q "jest" package.json; then
        npm test -- --watchAll=false --passWithNoTests
        test_result=$?
    else
        log "WARN" "No Jest configuration found"
        test_result=0
    fi

    if [ $test_result -eq 0 ]; then
        log "INFO" "✅ React component tests passed"
    else
        log "ERROR" "❌ React component tests failed"
    fi
else
    log "INFO" "No tests found, skipping test execution"
    test_result=0
fi

# Storybook build test (optional)
if [ -f ".storybook/main.js" ] || [ -f ".storybook/main.ts" ]; then
    log "INFO" "Testing Storybook build"
    npm run build-storybook > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        log "INFO" "✅ Storybook build successful"
    else
        log "WARN" "Storybook build issues detected"
    fi
fi

exit $test_result
"""

🛡️ Security and Production Environment Protection

Production Environment Protection Configuration

[[hooks]]
name = "Production Environment Protection"
event = "PreToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["prod/**", "production/**", "*.prod.*", "docker-compose.prod.yml", "k8s/prod/**"]
command = """
source ~/.claude/scripts/common.sh

log "WARN" "🛡️ Production file modification detected!"

# Check current branch
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
log "INFO" "Current branch: $CURRENT_BRANCH"

# Restrict production file editing on main/master branch
if [[ "$CURRENT_BRANCH" == "main" ]] || [[ "$CURRENT_BRANCH" == "master" ]]; then
    log "ERROR" "Direct modification of production files on main/master branch is prohibited!"
    echo "Please create a feature branch for production changes."
    exit 1
fi

# Interactive confirmation (auto-skip in CI environment)
if [ -z "$CI" ] && [ -z "$GITHUB_ACTIONS" ]; then
    echo "You are about to modify production files:"
    for file in $CLAUDE_FILE_PATHS; do
        echo "  - $file"
    done
    echo ""
    read -p "Are you absolutely sure you want to proceed? Type 'CONFIRM' to continue: " confirmation

    if [ "$confirmation" != "CONFIRM" ]; then
        log "INFO" "Operation cancelled by user"
        exit 1
    fi
fi

# Create backup
BACKUP_DIR="~/.claude/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

for file in $CLAUDE_FILE_PATHS; do
    if [ -f "$file" ]; then
        cp "$file" "$BACKUP_DIR/$(basename $file)"
        log "INFO" "Backup created: $BACKUP_DIR/$(basename $file)"
    fi
done

log "INFO" "Production modification approved - backup created in $BACKUP_DIR"
"""

[[hooks]]
name = "Secret Detection and Prevention"
event = "PreToolUse"
[hooks.matcher]
tool_name = "edit_file"
command = """
source ~/.claude/scripts/common.sh

log "INFO" "🔒 Running secret detection scan"

for file in $CLAUDE_FILE_PATHS; do
    if [ ! -f "$file" ]; then
        continue
    fi

    # Common secret pattern detection
    SECRETS_FOUND=false

    # API key detection
    if grep -E "(api_key|apikey|api-key)[\s]*=[\s]*['\"][^'\"]{20,}['\"]" "$file"; then
        log "ERROR" "API key detected in: $file"
        SECRETS_FOUND=true
    fi

    # Password detection
    if grep -E "(password|passwd|pwd)[\s]*=[\s]*['\"][^'\"]{8,}['\"]" "$file"; then
        log "ERROR" "Password detected in: $file"
        SECRETS_FOUND=true
    fi

    # Token detection
    if grep -E "(token|secret|key)[\s]*=[\s]*['\"][a-zA-Z0-9+/]{20,}['\"]" "$file"; then
        log "ERROR" "Token/Secret detected in: $file"
        SECRETS_FOUND=true
    fi

    # AWS credential detection
    if grep -E "AKIA[0-9A-Z]{16}" "$file"; then
        log "ERROR" "AWS Access Key detected in: $file"
        SECRETS_FOUND=true
    fi

    # GitHub Token detection
    if grep -E "ghp_[0-9a-zA-Z]{36}" "$file"; then
        log "ERROR" "GitHub Token detected in: $file"
        SECRETS_FOUND=true
    fi

    if [ "$SECRETS_FOUND" = true ]; then
        echo ""
        echo "🚨 SECURITY ALERT: Potential secrets detected!"
        echo "Please remove sensitive information before proceeding."
        echo ""
        echo "Consider using:"
        echo "  - Environment variables"
        echo "  - Secret management tools (AWS Secrets Manager, HashiCorp Vault)"
        echo "  - .env files (with .gitignore)"
        echo ""
        exit 1
    fi
done

log "INFO" "✅ No secrets detected"
"""

📊 Performance Optimization and Monitoring

Execution Time Monitoring and Bottleneck Detection

[[hooks]]
name = "Performance Monitor"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
command = """
source ~/.claude/scripts/common.sh

# Performance log directory
PERF_LOG_DIR="/var/log/claude-hooks/performance"
mkdir -p "$PERF_LOG_DIR"

# Start execution time measurement
START_TIME=$(date +%s.%N)

log "INFO" "📊 Performance monitoring started"

# Process at hook execution completion
END_TIME=$(date +%s.%N)
EXECUTION_TIME=$(echo "$END_TIME - $START_TIME" | bc)

# Record performance data
echo "$(date '+%Y-%m-%d %H:%M:%S'),$EXECUTION_TIME,$CLAUDE_TOOL_NAME,$CLAUDE_FILE_PATHS" >> "$PERF_LOG_DIR/execution_times.csv"

# Threshold check (warning if over 5 seconds)
THRESHOLD=5.0
if (( $(echo "$EXECUTION_TIME > $THRESHOLD" | bc -l) )); then
    log "WARN" "⚠️ Hook execution exceeded threshold: ${EXECUTION_TIME}s > ${THRESHOLD}s"

    # Performance detail log
    {
        echo "=== Performance Analysis ==="
        echo "Hook: $CLAUDE_TOOL_NAME"
        echo "Files: $CLAUDE_FILE_PATHS"
        echo "Execution Time: ${EXECUTION_TIME}s"
        echo "Timestamp: $(date)"
        echo "System Load: $(uptime)"
        echo "Memory Usage: $(free -h | grep Mem)"
        echo "================================"
    } >> "$PERF_LOG_DIR/slow_executions.log"
fi

log "INFO" "✅ Performance monitoring completed (${EXECUTION_TIME}s)"
"""

[[hooks]]
name = "Resource Usage Monitor"
event = "Notification"
command = """
source ~/.claude/scripts/common.sh

# System resource monitoring
CPU_USAGE=$(top -l1 | grep "CPU usage" | awk '{print $3}' | sed 's/%//' 2>/dev/null || echo "0")
MEMORY_USAGE=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}' 2>/dev/null || echo "0")
DISK_USAGE=$(df -h . | tail -1 | awk '{print $5}' | sed 's/%//' 2>/dev/null || echo "0")

log "INFO" "💻 System Resources - CPU: ${CPU_USAGE}%, Memory: ${MEMORY_USAGE}%, Disk: ${DISK_USAGE}%"

# High usage alert
if (( $(echo "$CPU_USAGE > 80" | bc -l 2>/dev/null || echo "0") )); then
    log "WARN" "High CPU usage detected: ${CPU_USAGE}%"
fi

if (( $(echo "$MEMORY_USAGE > 85" | bc -l 2>/dev/null || echo "0") )); then
    log "WARN" "High memory usage detected: ${MEMORY_USAGE}%"
fi

if (( $(echo "$DISK_USAGE > 90" | bc -l 2>/dev/null || echo "0") )); then
    log "WARN" "High disk usage detected: ${DISK_USAGE}%"
fi
"""

🚨 Troubleshooting and Incident Response

Common Issues and Solutions

1. When Hooks Execution Hangs

#!/bin/bash
# ~/.claude/scripts/hook-watchdog.sh

# Detection and termination of hung Hook processes
find_hung_processes() {
    local max_runtime=600  # 10 minutes
    local current_time=$(date +%s)

    ps -eo pid,etime,comm,args | grep claude | while read pid etime comm args; do
        # Convert execution time to seconds
        if [[ $etime =~ ([0-9]+):([0-9]+) ]]; then
            local minutes=${BASH_REMATCH[1]}
            local seconds=${BASH_REMATCH[2]}
            local total_seconds=$((minutes * 60 + seconds))

            if [ $total_seconds -gt $max_runtime ]; then
                echo "Terminating hung process: $pid ($etime)"
                kill -TERM $pid
                sleep 5
                kill -KILL $pid 2>/dev/null
            fi
        fi
    done
}

# Cron job for periodic execution
# */5 * * * * /home/user/.claude/scripts/hook-watchdog.sh
find_hung_processes

2. Resolving Race Conditions in Parallel Execution

[[hooks]]
name = "Mutex Protected Operation"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["package.json", "requirements.txt", "Cargo.toml"]
command = """
source ~/.claude/scripts/common.sh

# Mutex lock implementation
LOCK_FILE="/tmp/claude-dependency-update.lock"
LOCK_TIMEOUT=300  # 5 minutes

acquire_lock() {
    local timeout_count=0
    while [ -f "$LOCK_FILE" ] && [ $timeout_count -lt $LOCK_TIMEOUT ]; do
        sleep 1
        ((timeout_count++))
        if [ $((timeout_count % 30)) -eq 0 ]; then
            log "INFO" "Waiting for lock... (${timeout_count}s)"
        fi
    done

    if [ $timeout_count -ge $LOCK_TIMEOUT ]; then
        log "ERROR" "Lock acquisition timeout"
        return 1
    fi

    echo $$ > "$LOCK_FILE"
    return 0
}

release_lock() {
    rm -f "$LOCK_FILE"
}

# Cleanup with trap
trap 'release_lock' EXIT

if acquire_lock; then
    log "INFO" "Lock acquired, proceeding with operation"

    # Dependency update process
    for file in $CLAUDE_FILE_PATHS; do
        case "$file" in
            "package.json")
                npm audit fix
                npm update
                ;;
            "requirements.txt")
                pip install -r requirements.txt --upgrade
                ;;
            "Cargo.toml")
                cargo update
                ;;
        esac
    done

    log "INFO" "Dependency update completed"
else
    log "ERROR" "Failed to acquire lock"
    exit 1
fi
"""

3. Error Recovery and Rollback Functionality

[[hooks]]
name = "Auto Rollback on Error"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py", "*.js", "*.ts"]
command = """
source ~/.claude/scripts/common.sh

# Create backup directory
BACKUP_DIR="/tmp/claude-backup-$(date +%s)"
mkdir -p "$BACKUP_DIR"

# Backup function
create_backup() {
    local file=$1
    local backup_file="$BACKUP_DIR/$(basename $file).backup"
    cp "$file" "$backup_file"
    echo "$backup_file"
}

# Rollback function
rollback_files() {
    log "WARN" "Rolling back changes due to error"
    for backup_file in "$BACKUP_DIR"/*.backup; do
        if [ -f "$backup_file" ]; then
            original_file=$(basename "$backup_file" .backup)
            # Identify original file location
            find . -name "$original_file" -exec cp "$backup_file" {} \;
            log "INFO" "Rolled back: $original_file"
        fi
    done
}

# Set error trap
trap 'rollback_files; exit 1' ERR

# Start processing
for file in $CLAUDE_FILE_PATHS; do
    log "INFO" "Processing file: $file"

    # Create backup
    backup_file=$(create_backup "$file")
    log "INFO" "Backup created: $backup_file"

    # Actual processing (example: formatting)
    case "${file##*.}" in
        "py")
            black "$file" || { log "ERROR" "Black formatting failed"; exit 1; }
            ;;
        "js"|"ts")
            prettier --write "$file" || { log "ERROR" "Prettier formatting failed"; exit 1; }
            ;;
    esac

    # Delete backup on successful processing
    rm -f "$backup_file"
done

# Delete backup directory when all processing completes
rmdir "$BACKUP_DIR" 2>/dev/null || true

log "INFO" "✅ All files processed successfully"
"""

📈 Enterprise Implementation Case Studies and Best Practices

Configuration Management for Large Teams

#!/bin/bash
# Team shared configuration setup script

# Enterprise Claude Hooks configuration management
setup_enterprise_hooks() {
    local team_config_repo="https://github.com/your-company/claude-hooks-config.git"
    local config_dir="$HOME/.claude"

    echo "Setting up enterprise Claude Hooks configuration..."

    # Backup existing configuration
    if [ -d "$config_dir" ]; then
        mv "$config_dir" "$config_dir.backup.$(date +%s)"
    fi

    # Clone team configuration
    git clone "$team_config_repo" "$config_dir"

    # Apply environment-specific configuration
    local env=${1:-development}
    if [ -f "$config_dir/environments/$env.toml" ]; then
        cp "$config_dir/environments/$env.toml" "$config_dir/settings.toml"
        echo "Applied $env environment configuration"
    fi

    # Set execution permissions for team-specific scripts
    chmod +x "$config_dir/scripts/"*.sh

    # Prepare log directory
    sudo mkdir -p /var/log/claude-hooks
    sudo chown $USER:$USER /var/log/claude-hooks

    echo "✅ Enterprise Claude Hooks setup completed"
}

# Usage example
# ./setup-enterprise-hooks.sh production
setup_enterprise_hooks "$1"

CI/CD Integration Example

# .github/workflows/claude-hooks-ci.yml
name: Claude Hooks CI Integration

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  claude-hooks-validation:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Claude Code
      run: |
        curl -fsSL https://claude.ai/install.sh | sh
        echo "$HOME/.local/bin" >> $GITHUB_PATH

    - name: Install Dependencies
      run: |
        # Python dependencies
        if [ -f requirements.txt ]; then
          pip install -r requirements.txt
        fi

        # Node.js dependencies
        if [ -f package.json ]; then
          npm ci
        fi

    - name: Setup Claude Hooks
      env:
        CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }}
      run: |
        mkdir -p ~/.claude
        cp .github/claude-hooks/ci-settings.toml ~/.claude/settings.toml
        cp -r .github/claude-hooks/scripts ~/.claude/
        chmod +x ~/.claude/scripts/*.sh

    - name: Run Code Quality Checks
      run: |
        # Simulate hooks execution
        for file in $(git diff --name-only HEAD~1 HEAD | grep -E '\.(py|js|ts)$'); do
          if [ -f "$file" ]; then
            echo "Simulating hooks for: $file"

            # Python processing
            if [[ "$file" == *.py ]]; then
              black --check "$file"
              ruff check "$file"
              python -m py_compile "$file"
            fi

            # JavaScript/TypeScript processing
            if [[ "$file" =~ \.(js|ts|tsx)$ ]]; then
              npx prettier --check "$file"
              npx eslint "$file"
            fi
          fi
        done

    - name: Run Tests
      run: |
        # Python tests
        if [ -f pytest.ini ] || [ -f pyproject.toml ]; then
          pytest --tb=short
        fi

        # Node.js tests
        if [ -f package.json ] && grep -q '"test"' package.json; then
          npm test
        fi

    - name: Performance Report
      run: |
        echo "## Claude Hooks Performance Report" >> $GITHUB_STEP_SUMMARY
        echo "| Check | Status | Duration |" >> $GITHUB_STEP_SUMMARY
        echo "|-------|--------|----------|" >> $GITHUB_STEP_SUMMARY
        echo "| Code Format | ✅ | 2.3s |" >> $GITHUB_STEP_SUMMARY
        echo "| Tests | ✅ | 15.7s |" >> $GITHUB_STEP_SUMMARY
        echo "| Security Scan | ✅ | 4.1s |" >> $GITHUB_STEP_SUMMARY

🔧 Advanced Customization

Project-Specific AI Learning Functionality

[[hooks]]
name = "AI-Powered Code Analysis"
event = "PostToolUse"
run_in_background = true
[hooks.matcher]
tool_name = "edit_file"
command = """
source ~/.claude/scripts/common.sh

PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
ANALYSIS_DIR="$PROJECT_ROOT/.claude/analysis"
mkdir -p "$ANALYSIS_DIR"

log "INFO" "🤖 Starting AI-powered code analysis"

# Code pattern learning
for file in $CLAUDE_FILE_PATHS; do
    if [ ! -f "$file" ]; then
        continue
    fi

    # File type detection
    file_type="${file##*.}"

    # Code complexity analysis
    case "$file_type" in
        "py")
            if command -v radon &> /dev/null; then
                complexity=$(radon cc "$file" -a 2>/dev/null | tail -1 | awk '{print $NF}' | tr -d '()')
                echo "$(date '+%Y-%m-%d %H:%M:%S'),$file,python,$complexity" >> "$ANALYSIS_DIR/complexity.csv"
            fi
            ;;
        "js"|"ts")
            if command -v eslint &> /dev/null; then
                complexity=$(npx eslint "$file" --format json 2>/dev/null | jq '.[].messages | length' || echo "0")
                echo "$(date '+%Y-%m-%d %H:%M:%S'),$file,javascript,$complexity" >> "$ANALYSIS_DIR/complexity.csv"
            fi
            ;;
    esac

    # Record change pattern
    git log -n 5 --oneline "$file" > "$ANALYSIS_DIR/$(basename $file).history" 2>/dev/null
done

# Generate weekly learning summary
if [ $(date +%w) -eq 1 ]; then  # Monday
    log "INFO" "📊 Generating weekly learning summary"

    {
        echo "# Weekly Code Analysis Summary - $(date '+%Y-%m-%d')"
        echo ""
        echo "## Complexity Trends"
        tail -n 50 "$ANALYSIS_DIR/complexity.csv" | awk -F',' '
        {
            sum += $4
            count++
        }
        END {
            if (count > 0) {
                avg = sum / count
                print "Average complexity: " avg
                if (avg > 10) print "⚠️ High complexity detected - consider refactoring"
                else print "✅ Complexity within acceptable range"
            }
        }'

        echo ""
        echo "## Most Modified Files"
        find "$ANALYSIS_DIR" -name "*.history" -exec wc -l {} + | sort -nr | head -5

    } > "$ANALYSIS_DIR/weekly-summary.md"
fi

log "INFO" "✅ AI code analysis completed"
"""

Summary

Implementing Claude Code Hooks in production environments goes beyond simple configuration file creation, requiring robust error handling, performance monitoring, and security assurance.

By utilizing the configuration examples and scripts introduced in this guide, you can achieve:

  • Gradual Introduction: Progressive automation that minimizes risk
  • Incident Response: Rapid recovery and root cause analysis when issues occur
  • Team Operations: Unified development environment for large organizations
  • Continuous Improvement: Automatic optimization with AI assistance

These implementations enable Claude Code Hooks to function as a true development productivity enhancement tool.

Next Steps

  • Review basic concepts in the morning article
  • Begin test introduction in small projects
  • Customize team configuration files
  • Implement CI/CD environment integration

Production Introduction Considerations

Before production deployment, ensure thorough testing in development and staging environments. PreToolUse hooks in particular require careful configuration as they may block operations.