AI应用系列 一个简单的Vibe coding的通知系统
本文最后更新于 11 天前,如有失效请评论区留言。

本博客由科研AI Agent实验室BenszResearch强力驱动!如何更快地访问本站?有需要可加电报群获得更多帮助。本博客用什么VPS?创作不易,请支持苯苯!推荐购买本博客的VIP喔,10元/年即可畅享所有VIP专属内容!

VibeNotification 的 GitHub 仓库:

开发和调试不易,希望小伙伴们帮忙给项目点 Star、关注我的帐号呀!感谢感谢!

概览

  • VibeNotification 1.1.0 用 Claude Code 与 Codex 的 Stop hook,专门提醒一次完整主回复真正结束的时刻
  • Codex 的旧 notify 接入已降级为兼容方案;新配置请改用 [[hooks.Stop]]
  • 新增 --doctor 自检、Codex 会话退出 wrapper,以及 macOS 通知 sender 稳定性设置
  • 本文同步了当前配置字段、环境变量、默认值与排错方法

前言

最近在用 Claude Code/Codex 跑长任务时,我希望他们工作时我可以做点别的事;等回复完成后再给个系统提示,我再过去查看结果。在 Play a sound when Codex finishes a prompt / task · Issue #3962 · openai/codex 的启示下,我折腾了个小工具——VibeNotification,能在 Claude Code/Codex 回复完成时弹系统通知+响铃。

这篇文章最初发布时,Codex 还是通过 notify 接入的;不过这套机制在长工具调用里容易把过程事件当作完成事件。现在 VibeNotification 已更新到 1.1.0,推荐用两个 CLI 都支持的 Stop hook,并针对 Claude Code 的工具调用、子代理、后台任务和重复事件做了过滤。下面按新方法重新配置一遍,小伙伴们别再照旧教程抄 notify 啦 (~ ̄▽ ̄)~

image-20251221214216954

它现在是怎么提醒的

VibeNotification 是一个没有第三方 Python 依赖的轻量工具,支持 macOS、Linux、Windows。正常情况下,它在主代理本轮回复真正结束时发送系统通知和提示音;不是每调用一次工具就“滴”一声,也不因为子代理结束而刷屏。

Claude Code 的新版 agentic loop 里,Stop 可能出现在工具调用、子代理或后台任务之间。VibeNotification 会读取 hook 事件中的最终消息或 transcript,跳过仍在工作的中间停止、带 stop_hook_active 的重复链路以及未结束的后台任务;同一条最终回复也只提示一次。Codex 则推荐直接使用主代理 Stop hook,按 thread/turn 做幂等处理。

除了基础通知外,目前还提供交互式配置、音量/音色控制、中文或英文界面、macOS sender 模式,以及 --doctor 本机接入检查。对我来说最实用的还是:开着长任务去忙别的,听到提示再回来验收,终于不用在终端前罚站了,哈哈。

安装与首次自检

💡 需要 Python 3.7 或更高版本

还没有安装 Python 的话,可查看 Python 安装使用指南 或到 Python 官方下载页面 获取安装包。

安装稳定版

大多数小伙伴直接从 PyPI 安装即可:

python -m pip install -U vibe-notification

如果你想跟着源码调试或参与开发,再克隆仓库并以可编辑模式安装:

git clone https://github.com/huangwb8/VibeNotification.git
cd VibeNotification
python -m pip install -e .

虚拟环境不是必须的;介意污染 base 环境的话,可以先创建一个:

python -m venv venv
source venv/bin/activate

Windows PowerShell 则使用:

.\venv\Scripts\Activate.ps1

先发一条测试通知

安装后先别急着改 hook,运行:

python -m vibe_notification --test

预期结果是弹出一条系统通知并播放提示音。没有弹窗时,先看系统是否关闭通知、是否处于专注/勿扰模式;Linux 还要确认桌面环境提供了 notify-send,Ubuntu/Debian 通常可安装 libnotify-bin

sudo apt-get install libnotify-bin

确认测试能工作,再配置 Claude Code 或 Codex,就不会把“hook 没触发”和“系统根本不让弹窗”混在一起排查了。

接入 Claude Code

把下面这段合并进 ~/.claude/settings.jsonhooks 中:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "env VIBE_NOTIFICATION_SENDER_MODE=off python -m vibe_notification"
          }
        ]
      }
    ]
  }
}

如果这个文件已有其他设置或 hook,只合并 Stop 这一项,不要把整个 settings.json 覆盖掉。env VIBE_NOTIFICATION_SENDER_MODE=off 对 macOS 特别有用:它仅关闭通知对 VS Code、Terminal 等宿主 App 的 sender 绑定,让通知通常以 terminal-notifier 的身份显示;并不会关闭系统弹窗。

这里就用 Stop,不要把同一条提醒再挂到 SessionEndSubagentStop。前者是整个会话生命周期事件,后者只代表子代理结束,都不是“这一轮主回复已经可以验收”的可靠信号;VibeNotification 也会默认忽略它们,避免重复提醒。

配置后让 Claude Code 正常完成一次有工具调用的任务。只在最终回复出现时收到一次提醒,说明就接好了。

接入 Codex

新版 Codex 请在 ~/.codex/config.toml 中添加主代理 Stop hook:

[[hooks.Stop]]

[[hooks.Stop.hooks]]
type = "command"
command = "python3 -m vibe_notification"
timeout = 30

⚠️ Codex 必须先审核并信任这个 Hook,否则不会执行! 保存 config.toml 后,请完全重启 Codex,在 Codex CLI 中输入 /hooks,找到刚添加的 Stop hook,完成 Review/Trust。仅仅保证 TOML 语法正确、--doctor 能识别配置还不够;未通过审核的非托管 command hook 会被 Codex 跳过,因此 VibeNotification 无法生效。以后只要修改了 command 等 Hook 定义,Codex 会按新哈希将它重新标记为待审核,也必须再次进入 /hooks 完成 Review/Trust。

它的含义是:本轮主代理停止输出时调用 VibeNotification。注意,这不等于整个 Codex 会话退出;你继续在同一个会话里追问,下一次主回复完成还会再提醒一次。

旧版教程里的:

notify = ["python3", "-m", "vibe_notification"]

现在不再推荐。旧 notifyagent-turn-complete 负载没有消息阶段,长任务中无法稳定分辨过程消息和最终答复;1.1.0 起 VibeNotification 会默认静默跳过它。请删除旧 notify,只保留上面的 Stop hook,避免同一个任务从两条通道重复进入。

如果你的 Codex 太旧、确实不支持 hooks,才可以临时恢复兼容模式:

notify = ["env", "VIBE_ALLOW_LEGACY_CODEX_NOTIFY=1", "python3", "-m", "vibe_notification"]

不过它仍可能把长时间工具调用之间的过程 turn 误判为完成,不建议作为日常配置。必要时可用 VIBE_DEBOUNCE_COOLDOWN=30 调整兼容模式的静默秒数。

只想在 Codex 整个会话退出时提醒

如果你要的是“我退出 Codex 后再提醒一次”,别用 Stop hook,直接用内置 wrapper 启动:

python -m vibe_notification --wrap-codex

平时带给 Codex 的参数也能原样透传:

python -m vibe_notification --wrap-codex -- -C /path/to/project

嫌长的话,往 ~/.zshrc~/.bashrc 加一个别名:

alias codexn='python3 -m vibe_notification --wrap-codex --'

重新打开终端或执行 source ~/.zshrc 后,用 codexn 启动就行。这样只会在 Codex 进程真正结束时通知一次。

配置通知行为

交互式配置与优先级

默认配置文件是 ~/.config/vibe-notification/config.json。不想手改 JSON 的话,运行:

python -m vibe_notification --config

向导会让你选择中文或英文,并可以依次设置声音、系统通知、日志级别、通知超时、音色和音量;按 Enter 保留当前值,按 Esc 退出。

声音、弹窗和日志级别的优先级是:命令行参数 > 环境变量 > config.json > 内置默认值。音量、音色、语言和 sender mode 没有对应的 CLI 参数,所以环境变量优先于配置文件。下面是当前可用的配置示例:

{
  "enable_sound": true,
  "enable_notification": true,
  "notification_timeout": 10000,
  "sound_type": "Glass",
  "sound_volume": 0.1,
  "log_level": "INFO",
  "detect_conversation_end": true,
  "language": "zh",
  "macos_sender_mode": "auto"
}

其中 notification_timeout 目前还是保留字段,macOS、Linux、Windows 的系统通知后端不保证按这个毫秒数自动收起;实际停留时间主要由系统通知样式、通知中心和专注模式决定。detect_conversation_end 建议保持 true

常用临时设置

想只对一条 hook 命令生效,就把环境变量写在命令前面。比如 Codex 的 command 可以这样改:

# 只弹窗,不响铃
command = "env VIBE_NOTIFICATION_SOUND=0 python3 -m vibe_notification"

# 只响铃,不弹窗
command = "env VIBE_NOTIFICATION_NOTIFY=0 python3 -m vibe_notification"

# 低音量的 Ping
command = "env VIBE_NOTIFICATION_SOUND_VOLUME=0.2 VIBE_NOTIFICATION_SOUND_TYPE=Ping python3 -m vibe_notification"

# 排错时输出更详细的日志
command = "env VIBE_NOTIFICATION_LOG_LEVEL=DEBUG python3 -m vibe_notification"

Claude Code 也是同样思路,把 command 改为:

"command": "env VIBE_NOTIFICATION_SOUND=0 VIBE_NOTIFICATION_SENDER_MODE=off python -m vibe_notification"

常用变量有这些:

变量 可用值 用途
VIBE_NOTIFICATION_SOUND 0 临时关闭提示音
VIBE_NOTIFICATION_NOTIFY 0 临时关闭系统弹窗
VIBE_NOTIFICATION_SOUND_VOLUME 0.01.0 覆盖音量,超出范围会自动截断
VIBE_NOTIFICATION_SOUND_TYPE Glass、Ping、Pop、Tink、Basso 覆盖提示音类型
VIBE_NOTIFICATION_LOG_LEVEL DEBUG、INFO、WARNING、ERROR 覆盖日志级别
VIBE_NOTIFICATION_LANGUAGE zh、en 覆盖界面语言
VIBE_NOTIFICATION_SENDER_MODE auto、off、force 控制 macOS sender 绑定

音色以 macOS 的 GlassPingPopTinkBasso 为准;Linux 会调用系统默认音频后端,Windows 会映射到相近的系统音。测试某一种声音,直接这样跑:

VIBE_NOTIFICATION_SOUND_TYPE=Ping python -m vibe_notification --test
VIBE_NOTIFICATION_SOUND_VOLUME=0.3 python -m vibe_notification --test

macOS 没有横幅怎么办

macOS 下,通知“进了通知中心却没有横幅”常常不是程序没执行,而是 sender 绑定到了 VS Code、Terminal 等宿主 App 后,被那个 App 自己的通知策略或专注模式压住了。先运行:

VIBE_NOTIFICATION_SENDER_MODE=off python -m vibe_notification --test

若这样能显示,就把 VIBE_NOTIFICATION_SENDER_MODE=off 固定到 Claude Code/Codex 的 hook 命令里。接着到“系统设置 > 通知”检查当前生效的应用是否允许通知、样式是否设为横幅/提醒,并确认没有开启专注模式。off 只是不用宿主 App 作为 sender,绝对不是禁用通知;真正关闭弹窗用的是 VIBE_NOTIFICATION_NOTIFY=0

验证与排错

最省事的总检查是:

python -m vibe_notification --doctor

它会检查 Claude Code、Codex、项目安装情况和本机通知后端,能很快看出是不是还残留旧 notify、没配置 Stop hook,或者系统缺少通知能力。需要看更详细的运行信息时,再用:

python -m vibe_notification --log-level DEBUG --test

如果 --test 正常,但实际任务没有提醒,按下面的思路看就好:Claude Code 检查 ~/.claude/settings.json 是否为合法 JSON、Stop 是否写在 hooks 里;Codex 除了检查 ~/.codex/config.toml 是否只有推荐的 [[hooks.Stop]]、没有同时残留旧 notify,还必须在重启后输入 /hooks,确认该 Hook 已完成 Review/Trust。没有通过审核时,即使配置语法完全正确,Codex 也不会执行 Hook。如果测试本身都没有弹窗或声音,优先检查系统通知权限、专注模式、静音状态和 Python 是否指向安装了 VibeNotification 的环境。

FAQ

为什么 Codex 配了旧 notify 却没有提示?

这是 1.1.0 的有意调整。旧事件无法可靠辨别最终答复,默认静默跳过是为了避免长任务中途把你叫回来。请迁移到 Stop hook;只有旧 Codex 无法升级时才设置 VIBE_ALLOW_LEGACY_CODEX_NOTIFY=1,并接受它仍可能误报的限制。

为什么 Claude Code 有工具调用时没有连续响?

这是正常的。新版 Claude Code 会在 agentic loop 中多次触发 Stop,VibeNotification 会跳过工具调用中间状态、子代理、后台任务和重复事件,只保留本轮主回复真正结束时的一次提醒。

--test 能响,实际 hook 却不响?

测试命令只验证本机的通知链路;hook 还需要确认配置文件的位置、JSON/TOML 语法,以及 hook 命令中使用的 python/python3 是否就是安装本工具的解释器。对于 Codex,还要重启后进入 /hooks 完成 Review/Trust;这是必需步骤,未审核的 Hook 不会运行。虚拟环境用户尤其要留意这一点。

Linux 没有弹窗怎么办?

确认桌面会话可用且存在 notify-send。Ubuntu/Debian 可安装 libnotify-bin;声音部分还依赖 paplayaplay 等系统音频命令。--doctor 可以先帮助定位缺哪一环。

小结

现在这套通知系统的重点已经不是“收到一个事件就响”,而是尽量只在 Claude Code 或 Codex 的主回复真正结束时叫你回来。安装后先用 --test 验证系统通知,再分别把 Claude Code 和 Codex 接到 Stop hook;若只关心整个 Codex 会话结束,则用 --wrap-codex 启动。音量、音色和 macOS sender 都能按习惯微调。这样跑长任务时就可以放心切去做别的事,听到提示再回来验收结果,舒服多了 (~ ̄▽ ̄)~ 有问题的小伙伴欢迎到 GitHub 仓库 提 Issue 或 PR,博客评论区留言也没问题!

---------------
完结,撒花!如果您点一下广告,可以养活苯苯😍😍😍


感谢OhMyGPT的友情赞助 (ฅ´ω`ฅ) 本博客基于m2w创作。版权声明:除特殊说明,博客文章均为Bensz原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。VIP内容严禁转载!由于可能会成为AI模型(如chatGPT)的训练样本,本博客禁止将AI自动生成内容作为文章上传(特别声明时除外)。如有需要,请至学习地图系统学习本博客的教程。加Telegram群可获得更多帮助喔! | 博客订阅:RSS | 广告招租请留言 | 博客VPS | 致谢渺软公益CDN |
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇