钩子

通过响应生命周期事件来自定义Claude Code行为

什么是钩子?

钩子是响应Claude Code中特定事件而执行的JavaScript函数。它们允许您自定义行为、执行策略、集成外部工具和自动化工作流。

事件驱动

自动响应特定的生命周期事件

完全可自定义

编写JavaScript来自定义任何行为

策略执行

执行团队标准和安全策略

外部集成

连接到外部服务和工具

可用的钩子事件

PreToolUse

在Claude使用任何工具之前触发。验证、修改或阻止工具使用。

使用场景:安全验证、文件保护

PostToolUse

工具完成后触发。处理结果、触发通知或记录操作。

使用场景:自动格式化、日志记录、指标

UserPromptSubmit

用户提交提示时触发。修改提示、添加上下文或触发工作流。

使用场景:上下文注入、提示增强

Notification

Claude发送通知时触发。自定义通知行为。

使用场景:自定义警报、团队通知

SessionStart

Claude会话开始时触发。初始化资源或加载上下文。

使用场景:会话设置、环境检查

SessionEnd

会话结束时触发。清理资源或保存会话数据。

使用场景:清理、分析、会话报告
NEW

Setup

通过 --init、--init-only 或 --maintenance 标志触发。适用于仓库设置和维护任务。

使用场景:环境设置、依赖检查、项目初始化
NEW

SubagentStop

子代理完成工作时触发。处理结果或触发后续操作。

使用场景:结果处理、任务链接、通知
NEW

SubagentStart

子代理即将启动时触发。监控子代理启动或注入上下文。

使用场景:子代理监控、日志记录、上下文注入
NEW

PermissionRequest

请求权限时触发。自动批准/拒绝或记录权限请求。

使用场景:自动批准、权限记录、安全审计
NEW

PreCompact

上下文压缩发生前触发。在上下文被压缩之前保存重要信息。

使用场景:上下文保存、重要数据备份
NEW FEATURE

基于提示的钩子

在钩子中使用LLM驱动的决策。无需编写JavaScript逻辑,而是用自然语言描述您想要的内容。

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "type": "prompt",
        "matcher": { "tool": "Write" },
        "prompt": "Review this file write operation. Check if it follows 
                   our coding standards. Respond with 'allow' or 'deny' 
                   and explain why."
      }
    ]
  }
}

何时使用

  • +难以用代码编写的复杂决策逻辑
  • +代码审查和质量检查
  • +上下文感知验证

响应格式

{
  "decision": "allow" | "deny" | "skip",
  "reason": "Optional explanation",
  "modifiedInput": { /* optional */ }
}

实践示例

编辑后自动格式化代码

在Claude编辑文件后自动运行Prettier

hooks/post-tool-use.js
// Auto-format files after Edit tool
export async function postToolUse({ tool, result }) {
  if (tool.name === 'Edit' && result.success) {
    const { execSync } = require('child_process');
    try {
      execSync(`prettier --write "${tool.params.file_path}"`);
      console.log('✓ Formatted', tool.params.file_path);
    } catch (error) {
      console.error('Format failed:', error.message);
    }
  }
}

保护敏感文件

防止Claude编辑关键配置文件

hooks/pre-tool-use.js
// Protect sensitive files
export async function preToolUse({ tool }) {
  const protectedFiles = [
    '.env',
    'credentials.json',
    'package-lock.json'
  ];

  if (['Edit', 'Write'].includes(tool.name)) {
    const filePath = tool.params.file_path;
    if (protectedFiles.some(f => filePath.includes(f))) {
      return {
        allow: false,
        reason: `Cannot modify protected file: ${filePath}`
      };
    }
  }

  return { allow: true };
}

发送Slack通知

部署发生时通知团队

hooks/post-tool-use.js
// Notify team on deployment
export async function postToolUse({ tool, result }) {
  if (tool.name === 'Bash' &&
      tool.params.command.includes('deploy')) {
    const webhook = process.env.SLACK_WEBHOOK;
    await fetch(webhook, {
      method: 'POST',
      body: JSON.stringify({
        text: `🚀 Deployment completed!
Success: ${result.success}
Command: ${tool.params.command}`
      })
    });
  }
}

安全注意事项

钩子执行任意JavaScript代码。遵循以下安全最佳实践:

永远不要在钩子文件中存储密钥 - 使用环境变量

在执行外部命令之前验证所有输入

在使用来自外部源的钩子之前先审查它们

使用try-catch块优雅地处理错误

最佳实践

1

保持钩子简单

每个钩子应该只做好一件事。复杂的逻辑会降低Claude的速度。

2

优雅地处理错误

始终使用try-catch块并提供有意义的错误消息。

3

使用Async/Await

钩子支持用于外部API调用和文件操作的异步函数。

4

测试您的钩子

在部署之前彻底测试钩子,以避免中断工作流。

准备自定义您的工作流了吗?

开始创建钩子来自动化您的团队工作流并执行您的开发标准