跳过主要内容
本页提供按技能水平组织的完整、可用于生产环境的 hook 示例。每个示例都包含完整的工作代码、详细解释以及何时使用每种模式的指导。

如何使用这些示例

每个示例的设计目标是
  • 可复制粘贴:直接使用或作为起点
  • 教育性:通过逐步增加的复杂性学习 hook 概念
  • 实用性:解决实际的开发工作流挑战
根据您的经验水平选择示例,并逐步学习更高级的模式。

初级示例

非常适合 hook 入门。这些示例展示了具有简单逻辑的核心概念。

1. 项目类型检测

Hook: TaskStart
#!/usr/bin/env bash
# Project Type Detection Hook
# 
# Overview: Automatically detects project type at task start and injects relevant
# coding standards and best practices into the AI context. This helps Cline understand
# your project structure and apply appropriate conventions from the beginning.
#
# Demonstrates: Basic hook input/output, file system checks, conditional logic,
# and context injection to guide AI behavior.

input=$(cat)

# Read basic JSON structure and detect project type
context=""

# Check for different project indicators
if [[ -f "package.json" ]]; then
  if grep -q "react" package.json; then
    context="PROJECT_TYPE: React application detected. Follow component-based architecture and use functional components."
  elif grep -q "express" package.json; then
    context="PROJECT_TYPE: Express.js API detected. Follow RESTful patterns and proper middleware structure."
  else
    context="PROJECT_TYPE: Node.js project detected. Use proper npm scripts and dependency management."
  fi
elif [[ -f "requirements.txt" ]] || [[ -f "pyproject.toml" ]]; then
  context="PROJECT_TYPE: Python project detected. Follow PEP 8 standards and use virtual environments."
elif [[ -f "Cargo.toml" ]]; then
  context="PROJECT_TYPE: Rust project detected. Follow Rust conventions and use proper error handling."
elif [[ -f "go.mod" ]]; then
  context="PROJECT_TYPE: Go project detected. Follow Go conventions and use proper package structure."
fi

# Return the context to guide Cline's behavior
if [[ -n "$context" ]]; then
  jq -n --arg ctx "$context" '{"cancel": false, "contextModification": $ctx}'
else
  echo '{"cancel": false}'
fi
核心概念
  • 使用 input=$(cat) 读取 hook 输入
  • 使用文件系统检查检测项目类型
  • 返回上下文以影响 AI 行为
  • 使用 jq 进行基本 JSON 输出

2. 文件扩展名验证器

Hook: PreToolUse
#!/usr/bin/env bash
# File Extension Validator Hook
#
# Overview: Enforces TypeScript file extensions in TypeScript projects by blocking
# creation of .js and .jsx files. This prevents common mistakes where developers
# accidentally create JavaScript files when they should be using TypeScript.
#
# Demonstrates: PreToolUse blocking, parameter extraction, conditional validation,
# and providing clear error messages to guide users toward correct file extensions.

input=$(cat)

# Extract tool information
tool_name=$(echo "$input" | jq -r '.preToolUse.toolName')

# Only process file creation tools
if [[ "$tool_name" != "write_to_file" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Check if this is a TypeScript project
if [[ ! -f "tsconfig.json" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Get the file path from tool parameters
file_path=$(echo "$input" | jq -r '.preToolUse.parameters.path // empty')

if [[ -z "$file_path" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Block .js files in TypeScript projects
if [[ "$file_path" == *.js ]]; then
  echo '{"cancel": true, "errorMessage": "JavaScript files (.js) are not allowed in TypeScript projects. Use .ts extension instead."}'
  exit 0
fi

# Block .jsx files, suggest .tsx
if [[ "$file_path" == *.jsx ]]; then
  echo '{"cancel": true, "errorMessage": "JSX files (.jsx) are not allowed in TypeScript projects. Use .tsx extension instead."}'
  exit 0
fi

# Everything is OK
echo '{"cancel": false}'
核心概念
  • 提取工具名称和参数
  • 基于项目状态的条件逻辑
  • 使用 "cancel": true 阻止操作
  • 提供有帮助的错误消息

3. 基本性能监视器

Hook: PostToolUse
#!/usr/bin/env bash
# Basic Performance Monitor Hook
#
# Overview: Monitors tool execution times and logs operations that exceed a 3-second
# threshold. This helps identify performance bottlenecks and provides feedback to
# users about system resource issues that may be slowing down Cline's operations.
#
# Demonstrates: PostToolUse hook usage, arithmetic operations in bash, simple file
# logging, and conditional context injection based on performance metrics.

input=$(cat)

# Extract performance information
tool_name=$(echo "$input" | jq -r '.postToolUse.toolName')
execution_time=$(echo "$input" | jq -r '.postToolUse.executionTimeMs // 0')
success=$(echo "$input" | jq -r '.postToolUse.success')

# Log slow operations (threshold: 3 seconds)
if (( execution_time > 3000 )); then
  # Create simple log directory
  mkdir -p "$HOME/.cline_logs"
  
  # Log the slow operation
  echo "$(date -Iseconds): SLOW OPERATION - $tool_name took ${execution_time}ms" >> "$HOME/.cline_logs/performance.log"
  
  # Provide feedback to user
  context="PERFORMANCE: Operation $tool_name took ${execution_time}ms. Consider checking system resources if this happens frequently."
  jq -n --arg ctx "$context" '{"cancel": false, "contextModification": $ctx}'
else
  echo '{"cancel": false}'
fi
核心概念
  • 处理工具执行后的结果
  • bash 中的基本算术运算
  • 简单的文件日志记录
  • 条件上下文注入

中级示例

这些示例演示了更高级的概念,包括外部工具集成、模式匹配和结构化日志记录。

4. 使用 Linting 进行代码质量检查

Hook: PreToolUse
#!/usr/bin/env bash
# Code Quality Linting Hook
#
# Overview: Integrates ESLint and Flake8 to enforce code quality standards before
# files are written. Blocks file creation if linting errors are detected, ensuring
# all code meets quality standards. Supports TypeScript, JavaScript, and Python files.
#
# Demonstrates: External tool integration, temporary file handling, regex pattern
# matching, and comprehensive error reporting with actionable feedback.

input=$(cat)

tool_name=$(echo "$input" | jq -r '.preToolUse.toolName')

# Only lint file write operations
if [[ "$tool_name" != "write_to_file" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

file_path=$(echo "$input" | jq -r '.preToolUse.parameters.path // empty')

# Skip non-code files
if [[ ! "$file_path" =~ \.(ts|tsx|js|jsx|py|rs)$ ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Get file content from the tool parameters  
content=$(echo "$input" | jq -r '.preToolUse.parameters.content // empty')

if [[ -z "$content" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Create temporary file for linting
temp_file=$(mktemp)
echo "$content" > "$temp_file"

# Run appropriate linter based on file extension
lint_errors=""
if [[ "$file_path" =~ \.(ts|tsx)$ ]] && command -v eslint > /dev/null; then
  lint_output=$(eslint "$temp_file" --format=json 2>/dev/null || true)
  if [[ "$lint_output" != "[]" ]] && [[ -n "$lint_output" ]]; then
    error_count=$(echo "$lint_output" | jq '.[0].errorCount // 0')
    if (( error_count > 0 )); then
      messages=$(echo "$lint_output" | jq -r '.[0].messages[] | "\(.line):\(.column) \(.message)"')
      lint_errors="ESLint errors found:\n$messages"
    fi
  fi
elif [[ "$file_path" =~ \.py$ ]] && command -v flake8 > /dev/null; then
  lint_output=$(flake8 "$temp_file" 2>/dev/null || true)
  if [[ -n "$lint_output" ]]; then
    lint_errors="Flake8 errors found:\n$lint_output"
  fi
fi

# Cleanup
rm -f "$temp_file"

# Block if linting errors found
if [[ -n "$lint_errors" ]]; then
  error_message="Code quality check failed. Please fix these issues:\n\n$lint_errors"
  jq -n --arg msg "$error_message" '{"cancel": true, "errorMessage": $msg}'
else
  echo '{"cancel": false}'
fi
核心概念
  • 临时文件创建和清理
  • 外部工具集成 (eslint, flake8)
  • 使用正则表达式进行复杂模式匹配
  • 结构化错误报告

5. 安全扫描器

Hook: PreToolUse
#!/usr/bin/env bash
# Security Scanner Hook
#
# Overview: Scans file content for hardcoded secrets (API keys, tokens, passwords)
# before files are written. Blocks creation of files containing secrets except in
# safe locations like .env.example files or documentation, preventing credential leaks.
#
# Demonstrates: Pattern matching with regex arrays, file path exception handling,
# security-focused validation, and clear user guidance in error messages.

input=$(cat)

tool_name=$(echo "$input" | jq -r '.preToolUse.toolName')

# Only check file operations
if [[ "$tool_name" != "write_to_file" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

content=$(echo "$input" | jq -r '.preToolUse.parameters.content // empty')
file_path=$(echo "$input" | jq -r '.preToolUse.parameters.path // empty')

# Skip if no content
if [[ -z "$content" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Define secret patterns (simplified for readability)
secrets_found=""

# Check for API keys
if echo "$content" | grep -qi "api[_-]*key.*[=:].*['\"][a-z0-9_-]{10,}['\"]"; then
  secrets_found+="- API key pattern detected\n"
fi

# Check for tokens
if echo "$content" | grep -qi "token.*[=:].*['\"][a-z0-9_-]{10,}['\"]"; then
  secrets_found+="- Token pattern detected\n"
fi

# Check for passwords
if echo "$content" | grep -qi "password.*[=:].*['\"][^'\"]{8,}['\"]"; then
  secrets_found+="- Password pattern detected\n"
fi

# Allow secrets in safe files
safe_patterns=("\.env\.example$" "\.env\.template$" "/docs/" "\.md$")
is_safe_file=false
for safe_pattern in "${safe_patterns[@]}"; do
  if [[ "$file_path" =~ $safe_pattern ]]; then
    is_safe_file=true
    break
  fi
done

if [[ -n "$secrets_found" ]] && [[ "$is_safe_file" == false ]]; then
  error_message="🔒 SECURITY ALERT: Potential secrets detected in $file_path

$secrets_found
Please use environment variables or a secrets management service instead."

  jq -n --arg msg "$error_message" '{"cancel": true, "errorMessage": $msg}'
else
  echo '{"cancel": false}'
fi
核心概念
  • 模式数组和迭代
  • 文件路径异常处理
  • 以安全为重点的验证
  • 错误消息中的清晰用户指导

6. Git 工作流助手

Hook: PostToolUse
#!/usr/bin/env bash
# Git Workflow Assistant Hook
#
# Overview: Analyzes file modifications and provides intelligent git workflow suggestions
# based on file types and current branch. Encourages best practices like feature branches
# for components and test branches for test files, with actionable git commands.
#
# Demonstrates: Git integration, branch analysis, file path pattern matching, and
# contextual suggestions to guide users toward better git practices.

input=$(cat)

tool_name=$(echo "$input" | jq -r '.postToolUse.toolName')
success=$(echo "$input" | jq -r '.postToolUse.success')

# Only process successful file modifications
if [[ "$success" != "true" ]] || [[ "$tool_name" != "write_to_file" && "$tool_name" != "replace_in_file" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
  echo '{"cancel": false}'
  exit 0
fi

file_path=$(echo "$input" | jq -r '.postToolUse.parameters.path // empty')
current_branch=$(git branch --show-current 2>/dev/null || echo "main")

# Analyze file type and suggest appropriate branch naming
context=""
if [[ "$file_path" == *"component"* ]] && [[ "$current_branch" == "main" || "$current_branch" == "master" ]]; then
  component_name=$(basename "$file_path" .tsx .ts .jsx .js)
  context="GIT_WORKFLOW: Consider creating a feature branch: git checkout -b feature/add-${component_name,,}-component"
elif [[ "$file_path" == *"test"* ]] || [[ "$file_path" == *"spec"* ]]; then
  if [[ "$current_branch" == "main" || "$current_branch" == "master" ]]; then
    context="GIT_WORKFLOW: Consider creating a test branch: git checkout -b test/add-tests-$(basename "$(dirname "$file_path")")"
  fi
fi

# Add staging guidance
if [[ -n "$context" ]]; then
  context="$context After completing changes, use 'git add $file_path' to stage for commit."
else
  context="GIT_WORKFLOW: File modified: $file_path. Use 'git add $file_path' when ready to commit."
fi

jq -n --arg ctx "$context" '{"cancel": false, "contextModification": $ctx}'
核心概念
  • Git 仓库检测
  • 分支分析和建议
  • 用于上下文的文件路径分析
  • 可操作的用户指导

高级示例

这些示例展示了复杂的模式,包括外部集成、异步处理和复杂的状态管理。

7. 综合任务生命周期管理器

Hook: TaskComplete
#!/usr/bin/env bash
# Comprehensive Task Lifecycle Manager Hook
#
# Overview: Tracks task completions by generating detailed markdown reports with
# workspace information and git state, and optionally sends webhook notifications
# to external systems. Perfect for enterprise environments requiring audit trails.
#
# Demonstrates: Complex data extraction, structured report generation, markdown
# heredocs, asynchronous webhook notifications, and robust error handling.

input=$(cat)

# Extract task metadata using proper API field paths
task_id=$(echo "$input" | jq -r '.taskId')
ulid=$(echo "$input" | jq -r '.taskComplete.taskMetadata.ulid // "unknown"')
completion_time=$(echo "$input" | jq -r '.timestamp')

# Create completion report directory with error handling
reports_dir="$HOME/.cline_reports"
if [[ ! -d "$(dirname "$reports_dir")" ]]; then
  echo '{"cancel": false, "errorMessage": "Cannot access home directory"}' 
  exit 0
fi
mkdir -p "$reports_dir" || exit 0

# Generate safe, unique report filename
safe_task_id=$(echo "$task_id" | tr -cd '[:alnum:]_-' | head -c 50)
report_file="$reports_dir/completion_$(date +%Y%m%d_%H%M%S)_${safe_task_id}.md"

# Collect comprehensive workspace information
git_branch=$(git branch --show-current 2>/dev/null || echo "No git repository")
git_status_count=$(git status --porcelain 2>/dev/null | wc -l || echo "0")
project_name=$(basename "$PWD")

# Generate detailed completion report
cat > "$report_file" << EOF
# Cline Task Completion Report

**Task ID:** $task_id  
**ULID:** $ulid  
**Completed:** $(date -Iseconds)  
**Completion Time:** $completion_time

## Workspace Information
- **Project:** $project_name
- **Git Branch:** $git_branch
- **Modified Files:** $git_status_count

## Completion Status
✅ Task completed successfully

## Next Steps
- Review changes made during this task
- Consider committing changes if appropriate  
- Run tests to verify functionality
EOF

# Send webhook notification if configured
webhook_url="${COMPLETION_WEBHOOK_URL:-}"
if [[ -n "$webhook_url" ]]; then
  payload=$(jq -n \
    --arg task_id "$task_id" \
    --arg ulid "$ulid" \
    --arg workspace "$project_name" \
    --arg timestamp "$completion_time" \
    '{
      event: "task_completed",
      task_id: $task_id,
      ulid: $ulid,
      workspace: $workspace,
      timestamp: $timestamp
    }')
  
  # Send notification in background with timeout
  (curl -X POST \
    -H "Content-Type: application/json" \
    -d "$payload" \
    "$webhook_url" \
    --max-time 5 \
    --silent > /dev/null 2>&1) &
fi

context="TASK_COMPLETED: ✅ Task $task_id finished successfully. Report saved to: $(basename "$report_file")"
jq -n --arg ctx "$context" '{"cancel": false, "contextModification": $ctx}'
核心概念
  • 复杂的数据提取和验证
  • 结构化报告生成
  • 异步 webhook 通知
  • 错误处理和资源管理

8. 智能用户输入增强器

Hook: UserPromptSubmit
#!/usr/bin/env bash
# Intelligent User Input Enhancer Hook
#
# Overview: Analyzes user prompts to detect potentially harmful commands, logs user
# activity for analytics, and intelligently injects project and git context based on
# prompt keywords. Provides safety guards while enhancing AI responses with relevant context.
#
# Demonstrates: UserPromptSubmit hook usage, multi-pattern safety validation, intelligent
# context detection from prompts, structured JSON logging, and dynamic suggestion generation.

input=$(cat)

user_prompt=$(echo "$input" | jq -r '.userPromptSubmit.prompt')
task_id=$(echo "$input" | jq -r '.taskId')
user_id=$(echo "$input" | jq -r '.userId')

# Log user activity for analytics
activity_log="$HOME/.cline_user_activity/$(date +%Y-%m-%d).log"
mkdir -p "$(dirname "$activity_log")"

activity_entry=$(jq -n \
  --arg timestamp "$(date -Iseconds)" \
  --arg task_id "$task_id" \
  --arg user_id "$user_id" \
  --arg prompt_length "${#user_prompt}" \
  '{
    timestamp: $timestamp,
    task_id: $task_id,
    user_id: $user_id,
    prompt_length: ($prompt_length | tonumber),
    workspace: env.PWD
  }')

echo "$activity_entry" >> "$activity_log"

context_modifications=""
cancel_request=false

# Safety validation
harmful_patterns=("rm -rf" "delete.*all" "format.*drive" "sudo.*passwd")
for pattern in "${harmful_patterns[@]}"; do
  if echo "$user_prompt" | grep -qi "$pattern"; then
    cancel_request=true
    error_message="🚨 SAFETY ALERT: Potentially harmful command detected. Please review your request."
    break
  fi
done

# Intelligent context enhancement
if [[ "$cancel_request" == false ]]; then
  # Detect project context
  if echo "$user_prompt" | grep -qi "file\|directory\|folder"; then
    if [[ -f "package.json" ]]; then
      project_name=$(jq -r '.name // "unknown"' package.json 2>/dev/null)
      context_modifications+="PROJECT_CONTEXT: Working in Node.js project '$project_name'. "
    elif [[ -f "requirements.txt" ]]; then
      context_modifications+="PROJECT_CONTEXT: Working in Python project. "
    fi
  fi
  
  # Git context enhancement
  if echo "$user_prompt" | grep -qi "git\|commit\|branch" && git rev-parse --git-dir > /dev/null 2>&1; then
    current_branch=$(git branch --show-current 2>/dev/null)
    uncommitted=$(git status --porcelain | wc -l)
    context_modifications+="GIT_CONTEXT: On branch '$current_branch' with $uncommitted uncommitted changes. "
  fi
  
  # Tool suggestions
  if echo "$user_prompt" | grep -qi "search.*code\|find.*function"; then
    context_modifications+="SUGGESTION: Consider using search_files tool for code exploration. "
  fi
fi

# Return response
if [[ "$cancel_request" == true ]]; then
  jq -n --arg msg "$error_message" '{"cancel": true, "errorMessage": $msg}'
else
  if [[ -n "$context_modifications" ]]; then
    jq -n --arg ctx "$context_modifications" '{"cancel": false, "contextModification": $ctx}'
  else
    echo '{"cancel": false}'
  fi
fi
核心概念
  • 用户交互分析和日志记录
  • 多模式安全验证
  • 智能上下文检测
  • 动态建议生成

9. 多服务集成中心

Hook: PostToolUse
#!/usr/bin/env bash
# Multi-Service Integration Hub Hook
#
# Overview: Detects file modifications by type (dependencies, CI/CD, frontend, backend, tests)
# and sends asynchronous webhook notifications to multiple external services like Slack and
# CI/CD systems. Enables seamless integration of Cline operations into enterprise workflows.
#
# Demonstrates: Advanced pattern matching with associative arrays, multi-service webhook
# orchestration, asynchronous background processing, and enterprise notification patterns.

input=$(cat)

tool_name=$(echo "$input" | jq -r '.postToolUse.toolName')
success=$(echo "$input" | jq -r '.postToolUse.success')
file_path=$(echo "$input" | jq -r '.postToolUse.parameters.path // empty')

# Only process successful file operations
if [[ "$success" != "true" ]] || [[ "$tool_name" != "write_to_file" && "$tool_name" != "replace_in_file" ]]; then
  echo '{"cancel": false}'
  exit 0
fi

# Define workflow triggers
declare -A triggers=(
  ["package\\.json|yarn\\.lock"]="dependencies"
  ["\\.github/workflows/"]="ci_cd"
  ["src/.*component"]="frontend"
  ["api/.*\\.(ts|js)"]="backend"
  [".*\\.(test|spec)\\."]="testing"
)

# Determine triggered workflows
triggered_workflows=""
for pattern in "${!triggers[@]}"; do
  if [[ "$file_path" =~ $pattern ]]; then
    workflow_type="${triggers[$pattern]}"
    triggered_workflows+="$workflow_type "
  fi
done

context="WORKFLOW: File modified: $file_path"

if [[ -n "$triggered_workflows" ]]; then
  # Slack notification (async)
  slack_webhook="${SLACK_WEBHOOK_URL:-}"
  if [[ -n "$slack_webhook" ]]; then
    slack_payload=$(jq -n \
      --arg file "$file_path" \
      --arg workflows "$triggered_workflows" \
      --arg workspace "$(basename "$PWD")" \
      '{
        text: ("🔧 Cline modified `" + $file + "` in " + $workspace),
        color: "good",
        fields: [{
          title: "Triggered Workflows",
          value: $workflows,
          short: true
        }]
      }')
    
    (curl -X POST -H "Content-Type: application/json" -d "$slack_payload" "$slack_webhook" --max-time 5 --silent > /dev/null 2>&1) &
  fi

  # CI/CD webhook (async)  
  ci_webhook="${CI_WEBHOOK_URL:-}"
  if [[ -n "$ci_webhook" ]]; then
    ci_payload=$(jq -n \
      --arg file "$file_path" \
      --arg workflows "$triggered_workflows" \
      '{
        event: "file_modified",
        file_path: $file,
        workflows: ($workflows | split(" "))
      }')
    
    (curl -X POST -H "Content-Type: application/json" -d "$ci_payload" "$ci_webhook" --max-time 5 --silent > /dev/null 2>&1) &
  fi

  context+=" Triggered workflows: $triggered_workflows. Notifications sent to configured services."
fi

jq -n --arg ctx "$context" '{"cancel": false, "contextModification": $ctx}'
核心概念
  • 多服务集成模式
  • 异步 webhook 协调
  • 复杂工作流检测
  • 企业通知系统

使用技巧

运行多个 Hook

您可以通过为每种 hook 类型创建单独的文件来同时使用多个 hook
# Create hooks directory
mkdir -p .clinerules/hooks

# Create multiple hooks
touch .clinerules/hooks/PreToolUse
touch .clinerules/hooks/PostToolUse
touch .clinerules/hooks/TaskStart

# Make them executable
chmod +x .clinerules/hooks/*

环境配置

为外部集成设置环境变量
# Add to your .bashrc or .zshrc
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export JIRA_URL="https://yourcompany.atlassian.net"
export JIRA_USER="[email protected]"
export JIRA_TOKEN="your-api-token"
export CI_WEBHOOK_URL="https://your-ci-system.com/hooks/cline"

测试 Hook

通过模拟输入手动测试 hook
# Test a PreToolUse hook
echo '{
  "clineVersion": "1.0.0",
  "hookName": "PreToolUse",
  "timestamp": "2024-01-01T12:00:00Z",
  "taskId": "test",
  "workspaceRoots": ["/path/to/workspace"],
  "userId": "test-user",
  "preToolUse": {
    "toolName": "write_to_file",
    "parameters": {
      "path": "test.js",
      "content": "console.log(\"test\");"
    }
  }
}' | .clinerules/hooks/PreToolUse
这些示例为在您的开发工作流中实施 hook 提供了坚实的基础。根据您的具体需求、工具和集成进行自定义。