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