魔兽争霸语音通知插件让 Claude Code 更有趣
创意开源插件,用《魔兽争霸 3》单位语音作为 Claude Code 的任务通知。兼具娱乐和小幅生产力提升的意义。
创意开源插件,用《魔兽争霸 3》单位语音作为 Claude Code 的任务通知。兼具娱乐和小幅生产力提升的意义。
English | 한국어 | 中文 | 日本語
当你的 AI 编程智能体需要你关注时,播放游戏角色语音并显示可视化覆盖通知——也可以让智能体通过 MCP 自行选择声音。
AI 编程智能体在完成任务或需要权限时不会通知你。你切换到其他标签页,注意力随之转移,然后又浪费 15 分钟才能重新进入状态。peon-ping 用来自 Warcraft、StarCraft、Portal、Zelda 等游戏的角色语音和醒目的屏幕横幅解决了这个问题——支持 Claude Code、Amp、GitHub Copilot、Codex、Cursor、OpenCode、Kilo CLI、Kiro、Kimi Code、Windsurf、Google Antigravity、Rovo Dev CLI、DeepAgents、Qwen Code、iFlow CLI、Trae、Kiro IDE、ECA,以及任何 MCP 客户端。
查看实际效果 → peonping.com
选项 1:Homebrew(推荐)
brew install PeonPing/tap/peon-ping
然后运行 peon-ping-setup 注册钩子并下载声音包。支持 macOS 和 Linux。
选项 2:安装脚本(macOS、Linux、WSL2)
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.sh | bash
⚠️ WSL2 音频说明。peon-ping 在 Windows 端播放音频。首次运行时,它会探测一次你的 Windows 主机(按 Windows 版本缓存结果),以选择最佳播放方式:
在 Windows 10 / Windows 11 24H2 之前的版本中,会直接使用 WPF MediaPlayer——原生支持 MP3 和 WAV,无需额外依赖。
在 Windows 10 / Windows 11 24H2 之前的版本中,会直接使用 WPF MediaPlayer——原生支持 MP3 和 WAV,无需额外依赖。
在 Windows 11 24H2+(内部版本 26100+)中,Microsoft 从操作系统中移除了旧版 Windows Media Player,导致 WPF MediaPlayer 失败(MILAVERR_INVALIDWMPVERSION)。peon-ping 会回退到 System.Media.SoundPlayer,它使用 Win32 PlaySound API,能在所有环境中工作——但只支持 WAV,因此 MP3 声音包需要使用 ffmpeg 进行即时转码:sudo apt update; sudo apt install -y ffmpeg
在 Windows 11 24H2+(内部版本 26100+)中,Microsoft 从操作系统中移除了旧版 Windows Media Player,导致 WPF MediaPlayer 失败(MILAVERR_INVALIDWMPVERSION)。peon-ping 会回退到 System.Media.SoundPlayer,它使用 Win32 PlaySound API,能在所有环境中工作——但只支持 WAV,因此 MP3 声音包需要使用 ffmpeg 进行即时转码:
sudo apt update; sudo apt install -y ffmpeg
你可以通过 PEON_WSL_AUDIO_BACKEND=auto|mediaplayer|soundplayer 覆盖自动检测:
auto(默认)——按上述方式探测并缓存
mediaplayer——强制通过 WSL UNC 路径使用 WPF MediaPlayer(在 24H2+ 上会静默失败)
soundplayer——强制复制到临时文件并使用 SoundPlayer(通用方式,非 WAV 文件需要 ffmpeg)
选项 3:Windows 安装程序
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.ps1" -OutFile ".\install.ps1" -UseBasicParsing
powershell -ExecutionPolicy Bypass -File .\install.ps1
默认安装一组精选的入门声音包。重新运行即可更新,同时保留配置和状态。你也可以在 peonping.com 上以交互方式选择声音包,并获取自定义安装命令。
Windows 安装程序参数:
-All——安装所有可用声音包
-Packs peon,sc_kerrigan,...——仅安装指定声音包
-Lang en,fr,...——仅安装与指定语言匹配的声音包
-Local——将声音包、配置、钩子和技能安装到当前项目的 ./.claude/ 中
-Global——显式执行全局安装(与默认行为相同)
-InitLocalConfig——仅创建 ./.claude/hooks/peon-ping/config.json
-Local 不会安装全局 peon CLI 启动脚本,也不会修改用户的 PATH。钩子会使用绝对路径注册到项目级 ./.claude/settings.json 中,因此从项目内的任何工作目录运行时都能正常工作。
powershell -ExecutionPolicy Bypass -File .\install.ps1 -All
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Packs peon,sc_kerrigan
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Local
powershell -ExecutionPolicy Bypass -File .\install.ps1 -InitLocalConfig
如果在较旧版本的 Windows PowerShell 中,首次下载因 TLS 错误而失败,请在同一会话中运行一次以下命令,然后重试:
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
选项 4:先克隆并检查
git clone https://github.com/PeonPing/peon-ping.git
cd peon-ping
./install.sh
在 Windows PowerShell 中:
git clone https://github.com/PeonPing/peon-ping.git
Set-Location peon-ping
.\install.ps1
选项 5:Nix(macOS、Linux)
无需安装,直接从源代码运行:
nix run github:PeonPing/peon-ping -- status
nix run github:PeonPing/peon-ping -- packs install peon
或者安装到你的 profile:
nix profile install github:PeonPing/peon-ping
开发 shell(bats、shellcheck、nodejs):
nix develop # or use direnv
如需可复现的环境配置,请使用 Home Manager 模块:
# In your home.nix or flake.nix
{ inputs, pkgs, ... }:
let
peonCursorAdapterPath = "${inputs.peon-ping.packages.${pkgs.system}.default}/share/peon-ping/adapters/cursor.sh";
in {
imports = [ inputs.peon-ping.homeManagerModules.default ];
programs.peon-ping = {
enable = true;
package = inputs.peon-ping.packages.${pkgs.system}.default;
claudeCodeIntegration = true;
settings = {
default_pack = "glados";
volume = 0.7;
enabled = true;
desktop_notifications = true;
categories = {
"session.start" = true;
"task.complete" = true;
"task.error" = true;
"input.required" = true;
"resource.limit" = true;
"user.spam" = true;
};
};
# Install packs from og-packs (simple string notation)
# and custom sources (attrset with name + src)
installPacks = [
"peon"
"glados"
"sc_kerrigan"
# Custom pack from GitHub (openpeon.com registry)
{
name = "mr_meeseeks";
src = pkgs.fetchFromGitHub {
owner = "kasperhendriks";
repo = "openpeon-mrmeeseeks";
rev = "main"; # or use a commit hash for reproducibility
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
}
];
enableZshIntegration = true;
};
# Optional extra IDE hooks, like Cursor
home.file.".cursor/hooks.json".text = builtins.toJSON {
version = 1;
hooks = {
afterAgentResponse = [{ command = "bash ${peonCursorAdapterPath} afterAgentResponse"; }];
stop = [{ command = "bash ${peonCursorAdapterPath} stop"; }];
};
};
}
声音包安装:installPacks 选项支持两种格式:
简单字符串(例如 "peon"、"glados")——从 og-packs 仓库获取
自定义来源——包含 name 和 src 字段的属性集,其中 src 可以是任意 Nix 获取器的结果(例如 pkgs.fetchFromGitHub)
对于 openpeon.com 中列出的声音包,请找到其 GitHub 仓库链接并使用 pkgs.fetchFromGitHub:
{
name = "pack_name";
src = pkgs.fetchFromGitHub {
owner = "github-owner";
repo = "repo-name";
rev = "main"; # or a commit hash/tag
sha256 = ""; # Leave empty first, Nix will tell you the correct hash
};
}
Claude Code 钩子:设置 programs.peon-ping.claudeCodeIntegration = true;,即可将 Claude Code 钩子脚本安装到 ~/.claude/hooks/peon-ping/ 下,并把标准的 peon-ping 钩子条目合并到 ~/.claude/settings.json 中。
其他 IDE 钩子:其他 IDE 的适配器仍需主动启用,这样模块就不会覆盖无关的 IDE 设置。peon-ping 在 adapters/ 中提供了 cursor.sh 等适配器脚本,你可以按如下方式接入:
${inputs.peon-ping.packages.${pkgs.system}.default}/share/peon-ping/adapters/$YOUR_IDE.sh EVENT_NAME
参见上面的 Cursor 示例。
此外,它还会在每块屏幕上显示大型覆盖横幅(macOS/WSL/MSYS2),并设置终端标签页标题(● project: done)——即使你正在使用其他应用,也能知道发生了什么。
peon-ping 实现了 Coding Event Sound Pack Specification(CESP)——这是一项开放的编程事件声音标准,任何智能体式 IDE 都可以采用。
需要在会议或结对编程期间将声音和通知静音?有两种选择:
希望自动完成?设置 focus_detect,让 peon-ping 遵循 macOS 的专注模式/勿扰模式。只要启用了专注模式,声音和通知就会静音;关闭后自动恢复。另请参阅 headphones_only 和 meeting_detect。
Windows 说明:Windows 目前支持首批基础控制功能(status、toggle、volume、核心声音包、通知开关、debug、logs、trainer)。setup、rotation、preview 和 mobile 等更高级的命令已作为后续 Windows 功能对齐工作进行跟踪。
peon setup # 交互式配置向导(音量、分类、通知)
peon pause # 静音
peon resume # 取消静音
peon mute # 'pause' 的别名
peon unmute # 'resume' 的别名
peon status # 检查是否已暂停或激活(简洁)
peon status --verbose # 显示完整详情(通知、耳机、IDE 等)
peon volume # 显示当前音量
peon volume 0.7 # 设置音量(0.0–1.0)
peon rotation # 显示当前轮换模式
peon rotation random # 设置轮换模式(random|round-robin|session_override)
peon packs list # 列出已安装的音效包
peon packs list --registry # 浏览注册表中的所有可用包
peon packs community # 列出按信任等级分组的所有注册表包(Windows)
peon packs search <query> # 按名称搜索注册表包(Windows)
peon packs install <p1,p2> # 从注册表安装包
peon packs install --all # 从注册表安装所有包
peon packs install-local <path> # 从本地目录安装包
peon packs use <name> # 切换到特定包(在 Windows 上自动从注册表安装)
peon packs use --install <name> # 切换到包,如需要则从注册表安装
peon packs next # 循环到下一个包
peon packs remove <p1,p2> # 删除特定包
peon packs bind <name> # 将包绑定到当前目录
peon packs bind --pattern <path> # 将包绑定到目录模式,例如 "*/services"
peon packs unbind # 删除当前目录
peon packs bindings # 列出所有已分配的绑定
peon packs ide-bind <ide> <name> # 将包绑定到 IDE id,例如 codex
peon packs ide-unbind <ide> # 删除 IDE 绑定
peon packs ide-bindings # 列出所有基于 IDE 的绑定
peon packs exclude add <path> # 对 glob 或目录禁用声音和通知
peon packs exclude remove <path> # 停止禁用给定路径
peon packs exclude list # 列出被禁用的路径
peon sounds list [pack] # 列出包中的声音,标记已禁用的
peon sounds disable <category> <file> [--pack=<name>] # 在包中禁用单个声音
peon sounds enable <category> <file> [--pack=<name>] # 重新启用之前禁用的声音
peon notifications on # 启用桌面通知
peon notifications off # 禁用桌面通知
peon notifications overlay # 使用大型覆盖层横幅(默认)
peon notifications standard # 使用标准系统通知
peon notifications test # 发送测试通知
peon notifications position [pos] # 获取/设置通知位置(top-left、top-center、top-right、bottom-left、bottom-center、bottom-right)
peon notifications dismiss [N] # 获取/设置自动关闭时间(秒)(0 = 持久)
peon notifications label [text|reset] # 获取/设置通知的项目标签覆盖
peon notifications template [key] [fmt] # 获取/设置/重置消息模板(keys: stop、permission、error、idle、question)
peon preview # 播放 session.start 中的所有声音
peon preview <category> # 播放特定分类中的所有声音
peon preview --list # 列出活跃包中的所有分类
peon mobile ntfy <topic> # 设置手机通知(免费)
peon mobile off # 禁用手机通知
peon mobile test # 发送测试通知
peon debug on # 启用调试日志
peon debug off # 禁用调试日志
peon debug status # 显示调试状态、日志目录、文件计数、总大小
peon logs # 显示今天日志的最后 50 行
peon logs --last N # 显示所有日志文件的最后 N 行
peon logs --session ID # 按会话 ID 过滤今天的日志
peon logs --session ID --all # 在所有日志文件中搜索会话 ID
peon logs --clear # 删除所有日志文件(需确认)
peon relay --daemon # 启动音频中继(用于 SSH)
peon-ping 支持的 CESP 分类:session.start、task.acknowledge、task.complete、task.error、input.required、resource.limit、user.spam。(扩展分类 session.end 和 task.progress 在 CESP 规范中定义,被包清单支持,但当前不由内置钩子事件触发。)
支持 Tab 补全 — 输入 peon packs use <TAB> 可查看可用的包名称。
暂停会立即静音声音和桌面通知。在恢复前持续保持此状态。暂停时,标签页标题仍保持活跃。
配置 peon-ping 的最快方式是交互式向导:
peon setup
它会在一次操作中遍历所有常见设置 — 在任何提示处按 Enter 键可保持当前值:
╔══════════════════════════════════════╗
║ peon-ping setup wizard ║
╚══════════════════════════════════════╝
── 音量 ──
> 音量 (0.0 - 1.0) (0.5):
── 声音分类 ──
> 会话开始 [on/off] (on):
> 任务确认 [on/off] (off):
> 任务完成 [on/off] (on):
> 任务错误 [on/off] (on):
> 需要输入(权限、问题) [on/off] (on):
> 资源限制(上下文压缩) [on/off] (on):
> 用户刷屏(快速提示) [on/off] (on):
── 通知 ──
> 桌面通知 [on/off] (on):
覆盖层主题:
1) Neon (赛博朋克)
2) Glass (半透明)
3) Sakura (樱花)
4) Jarvis (钢铁侠)
> 主题 [neon]:
通知位置:
1) 顶部居中
2) 右上
...
> 位置 [top-center]:
自动关闭:
1) 持久(点击关闭)
2) 3 秒
3) 4 秒
...
> 关闭时间 [4]:
✓ 配置已保存!
音量 — 播放音量(0.0 – 1.0)
声音分类 — 单独启用/禁用每个 CESP 分类(会话开始、任务完成、权限提示、错误等)
桌面通知 — 覆盖层横幅的主开关
覆盖层主题 — 选择视觉风格(neon、glass、sakura、jarvis)
位置 — 通知出现的位置(top-center、top-right 等)
自动关闭 — 通知显示多长时间(0 = 持久,点击关闭)
完成后,向导会打印摘要并将所有内容保存到 ~/.claude/hooks/peon-ping/config.json。你可以随时重新运行 peon setup 来调整设置 — 它总是显示当前值作为默认值。
提示:所有单独的 peon 子命令(peon volume、peon notifications position top-right 等)仍然有效,如果你倾向于脚本化或一次调整一个设置 — 请参阅快速控制部分。
peon-ping 还在 Claude Code 中安装了斜杠命令:
/peon-ping-toggle — 静音/取消静音
/peon-ping-config — 更改任何设置(音量、包、分类等)
/peon-ping-rename <name> — 为此会话指定自定义名称,显示在通知标题和终端标签页标题中(零令牌,钩子拦截);不带参数重置为自动检测
你也可以直接要求 Claude 为你更改设置 — 例如 "enable round-robin pack rotation"、"set volume to 0.3" 或 "add glados to my pack rotation"。无需手动编辑配置文件。
配置位置取决于安装模式:
$CLAUDE_CONFIG_DIR/hooks/peon-ping/config.json(默认 ~/.claude/hooks/peon-ping/config.json)./.claude/hooks/peon-ping/config.json{
"volume": 0.5,
"categories": {
"session.start": true,
"task.acknowledge": true,
"task.complete": true,
"task.error": true,
"input.required": true,
"resource.limit": true,
"user.spam": true
}
}
peon-ping 有三个独立的控制,可混合搭配:
保留声音但禁用桌面弹窗:peon notifications off
保留桌面弹窗但禁用声音:peon pause
启用移动推送但禁用桌面弹窗:设置 desktop_notifications: false 和 mobile_notify.enabled: true
volume:0.0–1.0(足够在办公室安静)
desktop_notifications:true/false — 独立于声音切换桌面通知弹窗(默认:true)。禁用时,声音继续播放但视觉弹窗被禁用。移动通知不受影响。
notification_style:"overlay" 或 "standard"——控制桌面通知的显示方式(默认值:"overlay")overlay:醒目的大型横幅——在 macOS 上使用 JXA Cocoa 浮层,在 WSL/MSYS2 上使用 Windows Forms 弹窗。点击浮层可将焦点切换到终端(支持 Ghostty、Warp、iTerm2、Zed、Terminal.app)。在 iTerm2 上,点击后会聚焦到正确的标签页/窗格/窗口,而不只是应用本身。standard:系统通知——在 macOS 上使用 terminal-notifier / osascript,在 WSL/MSYS2 上使用 Windows toast。安装 terminal-notifier(brew install terminal-notifier)后,点击标准通知可自动将焦点切换到终端(支持 Ghostty、Warp、iTerm2、Zed、Terminal.app)。在原生 Windows 上,点击 toast 通知可将焦点切换到 IDE 或终端窗口(支持 VS Code、Cursor、Windsurf、Windows Terminal、PowerShell)。当打开多个窗口时,通知会通过基于 PID 的进程树匹配,精确定位到触发该事件的窗口。
notification_style:"overlay" 或 "standard"——控制桌面通知的显示方式(默认值:"overlay")
overlay:醒目的大型横幅——在 macOS 上使用 JXA Cocoa 浮层,在 WSL/MSYS2 上使用 Windows Forms 弹窗。点击浮层可将焦点切换到终端(支持 Ghostty、Warp、iTerm2、Zed、Terminal.app)。在 iTerm2 上,点击后会聚焦到正确的标签页/窗格/窗口,而不只是应用本身。
standard:系统通知——在 macOS 上使用 terminal-notifier / osascript,在 WSL/MSYS2 上使用 Windows toast。安装 terminal-notifier(brew install terminal-notifier)后,点击标准通知可自动将焦点切换到终端(支持 Ghostty、Warp、iTerm2、Zed、Terminal.app)。在原生 Windows 上,点击 toast 通知可将焦点切换到 IDE 或终端窗口(支持 VS Code、Cursor、Windsurf、Windows Terminal、PowerShell)。当打开多个窗口时,通知会通过基于 PID 的进程树匹配,精确定位到触发该事件的窗口。
overlay_theme:"jarvis"、"glass"、"sakura",或省略以使用默认浮层——仅限 macOS(默认值:none)jarvis:带有旋转弧线、刻度线和进度环的圆形 HUD glass:带有强调色条、进度线和时间戳的玻璃拟态面板 sakura:带有盆景树和动态樱花花瓣的禅意庭院
overlay_theme:"jarvis"、"glass"、"sakura",或省略以使用默认浮层——仅限 macOS(默认值:none)
jarvis:带有旋转弧线、刻度线和进度环的圆形 HUD
glass:带有强调色条、进度线和时间戳的玻璃拟态面板
sakura:带有盆景树和动态樱花花瓣的禅意庭院
categories:分别开启或关闭各个 CESP 声音类别(例如,使用 "session.start": false 禁用问候音效)
categories:分别开启或关闭各个 CESP 声音类别(例如,使用 "session.start": false 禁用问候音效)
annoyed_threshold / annoyed_window_seconds:在 N 秒内发送多少次提示词会触发 user.spam 彩蛋
annoyed_threshold / annoyed_window_seconds:在 N 秒内发送多少次提示词会触发 user.spam 彩蛋
silent_window_seconds:对耗时短于 N 秒的任务禁用 task.complete 音效和通知。(例如,设为 10,表示仅当任务耗时超过 10 秒时才播放音效)
silent_window_seconds:对耗时短于 N 秒的任务禁用 task.complete 音效和通知。(例如,设为 10,表示仅当任务耗时超过 10 秒时才播放音效)
session_start_cooldown_seconds(数字,默认值:30):当多个工作区同时启动时,对问候音效进行去重(例如,打开包含大量文件夹的 OpenCode 或 Cursor 时)。只有第一个会话启动时会播放问候音效;在此时间窗口内启动的后续会话将保持静音。设为 0 可禁用去重,并始终播放问候音效。
session_start_cooldown_seconds(数字,默认值:30):当多个工作区同时启动时,对问候音效进行去重(例如,打开包含大量文件夹的 OpenCode 或 Cursor 时)。只有第一个会话启动时会播放问候音效;在此时间窗口内启动的后续会话将保持静音。设为 0 可禁用去重,并始终播放问候音效。
suppress_idle_prompt_repeats(布尔值,默认值:true):当终端未获得焦点时,Claude Code 大约每 60 秒会重新触发一次 idle_prompt 通知。peon-ping 会将 idle_prompt 路由到 task.complete,因此当需要输入时,你仍会听到音效——但如果不进行去重,每次提醒时都会重复播放相同音效。当该值为 true 时,如果同一会话的 task.complete 已在 idle_prompt_suppress_window_seconds 时间范围内触发,则会抑制 idle_prompt。设为 false 可恢复周期性提醒。
suppress_idle_prompt_repeats(布尔值,默认值:true):当终端未获得焦点时,Claude Code 大约每 60 秒会重新触发一次 idle_prompt 通知。peon-ping 会将 idle_prompt 路由到 task.complete,因此当需要输入时,你仍会听到音效——但如果不进行去重,每次提醒时都会重复播放相同音效。当该值为 true 时,如果同一会话的 task.complete 已在 idle_prompt_suppress_window_seconds 时间范围内触发,则会抑制 idle_prompt。设为 false 可恢复周期性提醒。
idle_prompt_suppress_window_seconds(数字,默认值:3600):suppress_idle_prompt_repeats 使用的时间窗口。某个会话触发 task.complete 后,该会话后续的 idle_prompt 通知会在指定秒数内保持静音。设为 0 可禁用该时间窗口(效果等同于 suppress_idle_prompt_repeats: false)。
idle_prompt_suppress_window_seconds(数字,默认值:3600):suppress_idle_prompt_repeats 使用的时间窗口。某个会话触发 task.complete 后,该会话后续的 idle_prompt 通知会在指定秒数内保持静音。设为 0 可禁用该时间窗口(效果等同于 suppress_idle_prompt_repeats: false)。
suppress_subagent_complete(布尔值,默认值:false):抑制来自子智能体活动的音效和通知。当 Claude Code 的 Task 工具分派并行子智能体时,每个子智能体都会触发自己的事件:完成时播放完成音效、Bash 命令失败时触发 task.error、请求权限时触发 input.required。将此项设为 true,即可只听到父会话的音效。子智能体内部触发的事件通过 Claude Code 添加到其 hook 载荷中的 agent_id 字段进行检测;独立会话的子智能体(较旧的客户端、其他 IDE)仍会通过 SubagentStart 时间启发式规则进行检测。
suppress_subagent_complete(布尔值,默认值:false):抑制来自子智能体活动的音效和通知。当 Claude Code 的 Task 工具分派并行子智能体时,每个子智能体都会触发自己的事件:完成时播放完成音效、Bash 命令失败时触发 task.error、请求权限时触发 input.required。将此项设为 true,即可只听到父会话的音效。子智能体内部触发的事件通过 Claude Code 添加到其 hook 载荷中的 agent_id 字段进行检测;独立会话的子智能体