Claude Code钩子机制解析:如何为AI编程助手添加个性化事件通知
事件钩子(Event Hooks)是现代软件开发中实现可扩展性的核心机制,它允许开发者在应用程序的关键生命周期节点注入自定义逻辑。其原理是通过预定义的接口或配置文件,在特定事件发生时触发外部脚本或函数,实现功能的动态扩展。这一技术价值在于能以非侵入式的方式增强软件能力,提升开发体验和自动化水平。在AI编程助手等工具中,钩子机制常用于定制化通知、日志记录、流程自动化等场景。本文以Claude Cod
1. 项目概述:当Claude Code遇上斯蒂芬·库里
如果你和我一样,是个既写代码又看NBA的开发者,那你肯定懂那种感觉:深夜调试,对着终端里滚动的日志,世界安静得只剩下键盘声。这时候,要是能有个激情四射的解说员在旁边喊两嗓子,该多带劲? elizabethsiegle/claudecode-curry 这个项目,就把这个有点“中二”但极其有趣的幻想变成了现实。它的核心很简单: 让你在本地使用 Claude Code(Anthropic公司推出的AI编程助手)的每一个关键操作,都触发一段由NBA巨星斯蒂芬·库里“配音”的 macOS 通知和音效 。
想象一下,当你向Claude提交一个复杂的编程问题时,通知中心弹出“🏀 Chef Curry cooking!”。当Claude开始执行一个Bash命令时,耳边响起“💨 Fast Break!”的提示音。甚至当Claude请求文件权限,或者一个会话结束时,还会自动在浏览器里打开库里那些经典绝杀球的YouTube集锦。这个项目通过一系列精巧的钩子(Hooks),无缝嵌入了Claude Code的工作流,把枯燥的AI交互过程,变成了一场充满仪式感和趣味性的“篮球比赛直播”。
它非常适合那些 长期使用Claude Code进行开发、希望为重复性工作增添一点乐趣和个性化反馈的macOS用户 。无论是独立开发者,还是团队里想搞点新花样的技术爱好者,这个工具都能让你在“人机协作”的日常中,会心一笑。接下来,我就带你彻底拆解这个项目,从原理、安装、配置到深度定制,让你不仅能用起来,更能理解它背后的每一个齿轮是如何咬合的。
2. 核心原理与架构拆解
这个项目的巧妙之处在于,它没有修改Claude Code这个闭源商业软件的一行代码,而是利用了其提供给用户的 配置扩展能力 。理解这一点,是玩转这个项目乃至探索更多自定义可能性的关键。
2.1 Claude Code的钩子(Hooks)机制
Claude Code作为一个本地AI编程助手,其设计哲学之一就是可扩展性。它在用户的家目录( ~/.claude/ )下维护了一个核心配置文件: settings.json 。这个文件不仅存储了你的API密钥、主题偏好等设置,更重要的是,它定义了一系列 事件钩子(Event Hooks) 。
你可以把这些钩子理解为Claude Code生命周期中的一个个“事件触发器”。例如:
UserPromptSubmit: 当你按下回车键,向Claude发送一个问题或指令时触发。PreToolUse: 在Claude准备调用一个工具(如写文件、运行Bash命令、读取文件、搜索网页)之前触发。Notification: 当Claude需要向你请求权限(如文件访问)或发出一般性通知时触发。Stop: 当Claude Code会话结束时触发。
项目的核心脚本 install.py 所做的工作,就是 向这个 settings.json 文件中的对应钩子,注入调用我们自定义脚本 curry_alerts.py 的命令 。这样一来,每当Claude Code内部发生这些事件,它就会自动执行我们写的Python脚本。
2.2 进程分离与无阻塞设计
一个优秀的钩子脚本必须遵守一个铁律: 绝不能阻塞主进程 。想象一下,如果每次Claude要执行命令前,都得等我们的脚本播完一段3秒的音频、再弹出通知,那用户体验将是灾难性的。
curry_alerts.py 脚本通过Python的 os.fork() 或 subprocess.Popen 结合 detach 参数(具体实现取决于代码)完美解决了这个问题。其工作流程如下:
- 事件触发 :Claude Code调用钩子,执行类似
python3 /path/to/curry_alerts.py PreToolUse的命令,并将当前工具上下文(如工具类型、文件路径)通过标准输入(stdin)传递给脚本。 - 快速分叉 :脚本主进程立即创建一个子进程,并将所有实际工作(选消息、播声音、发通知、开网页)交给子进程。
- 立即退出 :主进程在创建子进程后立刻退出,并向Claude Code返回“成功”信号。Claude Code几乎感知不到延迟。
- 后台执行 :子进程在完全独立的后台运行,执行所有“花里胡哨”的操作,即使它运行了5秒钟,也完全不影响Claude Code继续它的核心工作。
这种“发射后不管”的设计,是此类增强工具能否实用的关键。
2.3 系统资源调用链
脚本的后台工作主要依赖macOS的原生能力:
- 通知(Notification) : 通过
osascript命令调用macOS的AppleScript接口,这是在macOS上弹出系统通知最稳定、兼容性最好的方式。 - 音频播放(Audio) : 通过
afplay命令直接播放MP3或AIFF音频文件。这是一个轻量级的命令行音频播放工具,无需复杂的音频库依赖。 - 浏览器打开(Browser) : 通过
webbrowser模块(Python标准库)或open命令(在shell中),使用系统默认浏览器打开指定的YouTube URL。
整个架构可以概括为: 配置注入 -> 事件捕获 -> 进程分离 -> 资源调用 。清晰的分层使得每一部分都可以独立修改和调试。
3. 详细安装与配置指南
了解了原理,动手安装就变得非常直观。整个过程就像在搭积木,每一步都有明确的目的。
3.1 环境准备与前置检查
在运行任何安装命令之前,请先确认你的环境符合要求:
- 操作系统 :必须是macOS。因为项目重度依赖
osascript和afplay这两个macOS特有的命令行工具。在Linux或Windows上无法运行。 - Python版本 :确保已安装Python 3.10或更高版本。在终端输入
python3 --version检查。建议使用Homebrew安装或维护Python环境,以避免系统Python的权限问题。 - Claude Code :显然,你需要先安装并至少成功运行过一次Claude Code桌面应用。这会确保
~/.claude/目录和settings.json文件被正确创建。 - Git :用于克隆项目仓库。通常macOS已自带,可通过
git --version检查。
注意 :建议在安装前,备份你的
~/.claude/settings.json文件。虽然安装脚本理论上只会追加内容,但备份是一个好习惯。执行cp ~/.claude/settings.json ~/.claude/settings.json.backup即可。
3.2 全局安装(监控所有项目)
这是最常用、最“沉浸式”的安装方式。安装后,无论你在哪个文件夹、哪个项目里使用Claude Code,库里教练的解说都会如约而至。
# 1. 克隆项目到本地,你可以放在任何你喜欢的位置,比如家目录下的Developer文件夹
git clone https://github.com/elizabethsiegle/claudecode-curry
cd claudecode-curry
# 2. 执行全局安装脚本
python3 install.py
安装脚本 install.py 会执行以下关键操作:
- 读取当前配置 :首先加载你现有的
~/.claude/settings.json。 - 备份原配置 :在修改前,可能会在临时位置或同目录下创建一个备份文件。
- 注入钩子 :在配置文件的相应节点(通常是
hooks或eventHandlers字段下),添加调用curry_alerts.py的命令行指令。指令中会包含当前脚本的绝对路径,确保Claude Code能找到它。 - 写入配置 :将修改后的配置写回原文件。
- 权限设置 :确保
curry_alerts.py和install.py具有可执行权限(chmod +x)。
安装完成后, 完全重启你的Claude Code应用 。这是必须的步骤,因为Claude Code通常只在启动时读取一次配置文件。重启后,你的“库里解说席”就正式上线了。
3.3 项目级安装(精准控制)
如果你只想在特定的项目中使用这个趣味功能,而在其他严肃或保密项目中保持安静,可以使用项目级安装模式。
# 进入你希望启用此功能的项目根目录
cd /path/to/your/fun-project
# 从项目仓库目录执行项目级安装命令
python3 /path/to/claudecode-curry/install.py --project
这个 --project 参数会让安装脚本的行为发生根本变化:
- 作用域 :它不会修改全局的
~/.claude/settings.json,而是在 当前项目目录 下寻找或创建一个Claude Code的本地配置文件(可能是.claude.json或类似名称)。 - 优先级 :Claude Code在运行时,会优先读取项目目录下的本地配置,再与全局配置合并。本地配置中的钩子会覆盖全局的同名钩子。
- 灵活性 :这为你提供了极大的灵活性。你可以为不同的项目配置不同的提示音、消息甚至触发概率。例如,在一个游戏开发项目里,你可以把提示音换成游戏音效;在一个数据分析项目里,可以把消息改成更“极客”的风格。
实操心得 :我强烈建议先进行全局安装,体验完整功能。熟悉之后,再在某些需要专注的项目中使用
--uninstall全局卸载,然后针对性地进行项目级安装。这样你能更好地控制“噪音”水平。
3.4 验证安装是否成功
安装并重启Claude Code后,如何验证钩子已生效?
- 直接检查配置文件 :打开
~/.claude/settings.json(如果是项目级安装,则检查项目目录下的配置文件),搜索“curry_alerts”或“install.py”中添加的命令行片段。如果能找到,说明注入成功。 - 触发测试 :在Claude Code中执行一个最基础的操作,比如问它一个简单问题(触发
UserPromptSubmit)。如果安装成功,你应该会立即在屏幕右上角看到macOS通知,并听到一个简短的篮球音效(如果默认配置了声音)。 - 监听进程 :打开“活动监视器”,在Claude Code运行期间,当你触发事件时,应该能看到短暂的
python3进程出现又消失,这就是我们的后台脚本在工作。
如果没有任何反应,请按以下步骤排查:
- 确认Claude Code已完全重启(最好彻底退出再从程序坞启动)。
- 检查终端中安装脚本是否有报错信息。
- 检查macOS的“通知中心”设置,确保Claude Code应用有发送通知的权限(系统偏好设置 -> 通知与焦点 -> Claude)。
- 尝试在终端中手动运行一下脚本:
cd /path/to/claudecode-curry && python3 curry_alerts.py UserPromptSubmit,看是否有错误输出。
4. 事件系统与个性化定制详解
项目默认的配置已经充满了趣味性,但真正的乐趣在于按照你自己的喜好进行深度定制。所有配置都集中在项目根目录下的 curry.config.json 文件中。
4.1 理解配置结构
curry.config.json 是一个JSON文件,其顶层结构是一个对象,键名对应Claude Code的各个事件(Event),值则是该事件的配置对象。
{
"UserPromptSubmit": { ... },
"PreToolUse": { ... },
"Notification": { ... },
"Stop": { ... }
}
每个事件的配置对象都支持以下字段(所有字段都是可选的,除了 messages ):
enabled: (布尔值) 默认为true。设为false可以完全禁用该事件的任何提醒。title: (字符串) 显示在macOS通知顶部的标题。默认已经配置了有趣的篮球相关emoji和文字。messages: (字符串数组) 必填项 。这是一个消息池,每次事件触发时,脚本会从中随机选取一条显示在通知的主体部分。这是创造多样性和惊喜的关键。sound: (字符串) 音频文件的路径。播放的提示音。可以是项目sounds/目录下的相对路径,也可以是macOS系统音效的绝对路径。video_url: (字符串) 一个URL地址。当事件触发时,会在默认浏览器中打开此链接。主要用于播放库里经典镜头的YouTube视频。probability: (浮点数) 介于 0.0 到 1.0 之间。表示该事件触发提醒的概率。1.0表示100%触发,0.5表示50%几率,0.0则等同于enabled: false。
4.2 默认事件解析与场景
让我们看看默认配置是如何营造“比赛氛围”的:
| 事件 | 触发时机 | 默认标题 | 设计意图与场景联想 |
|---|---|---|---|
UserPromptSubmit |
用户提交问题/指令 | 🏀 Chef Curry | 你(用户)是教练,发出了战术指令。“Chef Curry cooking”是库里进球后解说常喊的,寓意Claude开始“烹饪”解决方案。 |
PreToolUse (Write/Edit) |
Claude准备写/编辑文件 | 🎯 Pulling Up | 库里在Logo区超远三分“Pull Up”的经典动作。比喻Claude准备“出手”修改代码,精准命中需求。 |
PreToolUse (Bash) |
Claude准备运行Shell命令 | 💨 Fast Break | 篮球快攻。比喻Claude快速执行一系列命令,干净利落。 |
PreToolUse (Read/Glob/Grep) |
Claude准备读取/搜索文件 | 📼 Scouting | 球探看录像。概率设为40%,因为读取操作频繁,全提示会太吵。比喻Claude在“侦查”你的代码库。 |
PreToolUse (Web) |
Claude准备进行网络搜索 | 🔭 Googling | 拿着望远镜搜索。概率50%。比喻Claude在广阔互联网上寻找信息。 |
Notification (permission) |
Claude请求用户权限 | ⏱️ TIMEOUT | 比赛暂停。100%触发并打开“Night Night”绝杀视频,增加了请求权限时的戏剧性和趣味性,提醒你“比赛暂停,需要你的裁决”。 |
Notification (general) |
Claude其他一般通知 | 📣 Hey | 简单提醒。 |
Stop |
Claude会话结束 | 🙏 Night Night | 库里著名的“晚安”庆祝动作。100%触发并打开“Bang Bang”经典镜头集锦,为一次编程会话画上完美的、有仪式感的句号。 |
4.3 高级定制实战
现在,我们来动手打造属于自己的版本。
1. 更换音效库: 项目自带的音效在 sounds/ 目录下。你可以轻松替换它们。
- 来源:可以从无版权音效网站(如 freesound.org)下载简短的篮球音效,如哨声、运球声、进球刷网声、观众欢呼声。
- 格式:确保转换为
.mp3或.aiff格式,macOS的afplay支持良好。 - 配置:在
curry.config.json中,将对应事件的sound字段改为"sounds/你的音效文件名.mp3"。
示例:为代码编写成功添加庆祝音效 假设你下载了一个“crowd-cheer.mp3”放在sounds文件夹里。你可以修改 PreToolUse 中针对“Write”工具的配置,或者新增一个 PostToolUse 事件(如果项目后续支持)的配置。
2. 个性化消息池: messages 数组是你的创意舞台。你可以加入任何你喜欢的库里名言、篮球术语或者符合你个人风格的话。
"UserPromptSubmit": {
"messages": [
"战术板画起来!",
"教练,接下来怎么打?",
"把球给我,我来搞定。",
"Threeeeee-pointer! (指解决难题)",
"看好了,我只演示一次。"
]
}
3. 活用概率控制“噪音”: 这是保持工具长期可用的关键。如果你觉得文件读取(Read/Glob/Grep)的提示太频繁,可以把概率从0.4调到0.1或0.05。对于你非常关注的事件(如运行Bash命令),可以保持1.0。
4. 链接自定义视频: video_url 不一定非得是库里的视频。你可以链接到:
- 一个激励你编程的音乐视频。
- 一个搞笑的GIF图页面(虽然浏览器可能不会自动播放GIF)。
- 你自己团队庆祝项目上线的视频。 例如,在
Stop事件中,你可以把它改成你们团队完成一个Sprint后的庆祝视频链接。
5. 使用运行时占位符: 消息字符串支持 {tool} 和 {message} 占位符。 {tool} 会被替换为工具类型(如“Bash”、“WriteFile”), {message} 会被替换为Claude通知的原始内容(如果有的话)。这能让提醒更具上下文感。
"Notification": {
"messages": ["裁判查看回放中: {message}"]
}
注意事项 :修改
curry.config.json后, 不需要重启Claude Code 。因为配置是每次事件触发时由curry_alerts.py脚本动态读取的。这是非常人性化的设计,让你可以实时调整体验。
5. 故障排除与常见问题实录
即使设计再精巧,在实际使用中也可能遇到一些小问题。下面是我在体验过程中遇到的情况和解决方案。
5.1 问题:安装后没有任何通知弹出
可能原因及排查步骤:
- Claude Code未重启 :这是最常见的原因。修改了
settings.json后,必须完全退出并重启Claude Code桌面应用。 - macOS通知权限未开启 :前往“系统设置” -> “通知”,找到“Claude”应用,确保“允许通知”是打开的。同时检查是否被设为了“专注模式”过滤。
- 脚本路径错误 :
install.py在注入命令时使用的是绝对路径。如果你移动了claudecode-curry项目文件夹,钩子命令中的路径就会失效。需要重新运行安装脚本。 - Python环境问题 :在终端中手动测试脚本:
cd /path/to/claudecode-curry && /usr/bin/python3 curry_alerts.py UserPromptSubmit。如果报错“ModuleNotFoundError”,可能是脚本依赖了未安装的第三方库。但原项目应该只用了标准库。确保你用的是python3。 - 配置文件冲突 :如果你同时进行了全局安装和项目级安装,可能会产生冲突。检查当前工作目录下是否有
.claude.json等本地配置文件,它可能会覆盖全局设置。
5.2 问题:有通知弹出,但没有声音
可能原因及排查步骤:
- 系统音量或静音 :检查macOS的系统音量,以及是否按了静音键。
- 音效文件路径错误 :检查
curry.config.json中sound字段指向的文件是否存在。相对路径是相对于curry_alerts.py脚本所在目录的。 - 音频文件格式问题 :
afplay主要支持.mp3,.aiff,.wav等常见格式。确保你的音频文件没有损坏,可以尝试用afplay sounds/your_sound.mp3命令在终端直接播放测试。 - 播放被中断 :由于脚本是后台运行并立即退出的,如果音频文件较长,可能会在播放完前被终止。默认配置中的音效都很短(1-2秒),以避免此问题。
5.3 问题:通知有延迟,或感觉Claude变卡了
可能原因及排查步骤:
- 概率设置过高 :如果几乎所有事件的
probability都设为1.0,且频繁触发(如Read操作),后台会瞬间产生大量Python进程。虽然每个都很快退出,但创建进程本身有开销。 建议 :将频繁但非核心的事件(如Read,Glob)概率调低至0.2以下。 - 视频自动打开 :
video_url设置为一个非常长的YouTube视频,且每次触发都打开新标签页,会导致浏览器卡顿并分散注意力。 建议 :只为最重要的事件(如Stop)设置视频链接,或者将其移除。 - 系统资源占用 :在低配Mac上,同时运行Claude Code(本身是Electron应用,占用不低)、浏览器、终端以及多个后台脚本,可能导致卡顿。这是硬件限制。
5.4 问题:如何为特定工具类型定制不同提示?
默认配置已经对 PreToolUse 事件根据工具类型做了区分(Write, Bash, Read等)。这是通过在 curry_alerts.py 脚本中解析Claude Code通过stdin传递的上下文信息实现的。 如果你想进一步定制,例如为“写测试文件”和“写源代码文件”设置不同提示,目前的配置粒度可能不够。这需要修改 curry_alerts.py 脚本本身,去解析更详细的工具参数(如文件路径)。对于大多数用户,默认的按工具大类区分已经足够。
5.5 问题:卸载不干净或想暂时关闭
完全卸载:
cd /path/to/claudecode-curry
python3 install.py --uninstall
这个命令会从 ~/.claude/settings.json 中移除所有本项目注入的钩子命令。
临时关闭:
- 全局关闭 :编辑
curry.config.json,将所有事件的enabled设为false。 - 选择性关闭 :只将你觉得吵闹的事件的
enabled设为false或大幅调低probability。 - 使用专注模式 :利用macOS的“专注模式”(如工作模式),设置该模式下屏蔽Claude的所有通知。
踩坑记录 :我曾遇到一个奇怪的问题,安装后只有部分事件触发。后来发现是因为我手动编辑过
settings.json,格式有些不规范(多了个逗号)。install.py脚本在修改时可能没有正确处理,导致JSON格式损坏,使得部分钩子失效。 教训 :尽量不要手动编辑settings.json,如果必须,请使用JSON验证工具检查格式。出问题时,用备份文件恢复,然后重新安装。
6. 扩展思路与进阶玩法
这个项目不仅是一个玩具,它更是一个展示“如何优雅地扩展AI辅助工具”的绝佳范例。理解了它的原理后,你可以脑洞大开,创造出属于自己的版本。
1. 主题切换:从篮球到其他领域
- 星球大战版 :把库里换成尤达大师或黑武士的音效和名言。“Use the Force, write the code.”,工具调用时播放光剑挥舞声。
- 科幻版 :使用《星际迷航》或《黑客帝国》的语音和音效。“Captain, the code is being analyzed.”,权限请求时播放红色警报。
- 简约禅意版 :去掉所有音效和视频,只保留极其简洁、平静的文字通知,如“思考中...”、“执行中...”、“完成。”,适合追求极简和专注的环境。
2. 功能增强:超越通知
- 日志记录 :修改
curry_alerts.py,在触发事件时将时间、事件类型、工具上下文追加到一个本地日志文件中。这可以帮助你事后分析你和Claude的协作模式,比如你最常用哪些工具。 - 效率统计 :在
Stop事件中,脚本可以计算本次会话的时长、触发的工具次数,并生成一个简单的效率报告,通过通知显示出来。 - 与外部系统联动 :当Claude完成一个复杂任务(如
Stop事件)时,脚本可以调用一个Webhook,通知你的Slack频道“今日AI编程任务已完成”,甚至触发一个CI/CD流程。
3. 移植与适配
- 其他AI助手 :虽然项目是为Claude Code设计的,但思路可以复制。观察其他本地AI编程助手(如Cursor、Windsurf)是否也提供类似的钩子或插件接口。它们的配置方式可能不同,但“事件监听 -> 触发动作”的核心模式是相通的。
- 跨平台挑战 :如果想移植到Windows或Linux,需要替换
osascript(通知)和afplay(音频)的实现。- 通知 :Linux可以使用
notify-send命令,Windows可以使用plyer库或win10toast库。 - 音频 :可以使用跨平台的Python库如
playsound或pygame.mixer。
- 通知 :Linux可以使用
这个项目的魅力在于它用一个轻巧、非侵入的方式,在严肃的生产力工具中注入了个性化和乐趣。它提醒我们,开发者体验(DX)同样重要,一点小小的创意和仪式感,就能让日复一日的编码工作变得生动起来。
更多推荐



所有评论(0)