peon-ping
May 29, 2026 · View on GitHub
当你的 AI 编程助手需要关注时,播放游戏角色语音 + 显示视觉覆盖通知 — 或通过 MCP 让 AI 自行选择音效。
AI 编程助手完成任务或需要权限时不会通知你。你切换标签页、失去焦点,然后浪费 15 分钟重新进入状态。peon-ping 通过魔兽争霸、星际争霸、传送门、塞尔达等游戏的角色语音和醒目的屏幕横幅来解决这个问题 — 支持 Claude Code、Amp、Gemini CLI、GitHub Copilot、Codex、Cursor、OpenCode、Kilo CLI、Kiro、Kimi Code、Windsurf、Google Antigravity、Rovo Dev CLI、DeepAgents 及任何 MCP 客户端.
查看演示 → peonping.com
安装
方式一:Homebrew(推荐)
brew install PeonPing/tap/peon-ping
然后运行 peon-ping-setup 注册钩子并下载语音包。支持 macOS 和 Linux。
方式二:安装脚本(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 11 24H2+(构建号 26100+)上,微软已从系统中移除了旧版 Windows Media Player,WPF MediaPlayer 会失败(
MILAVERR_INVALIDWMPVERSION)。peon-ping 会回退到System.Media.SoundPlayer,它使用 Win32PlaySoundAPI,到处都能工作 — 但仅支持 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)
方式三:Windows 安装
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.ps1" -UseBasicParsing | Invoke-Expression
默认安装 5 个精选语音包(魔兽、星际、传送门)。重新运行可更新,同时保留配置和状态。你也可以在 peonping.com 交互式选择语音包 获取自定义安装命令。
实用安装参数:
--all— 安装所有可用语音包--packs=peon,sc_kerrigan,...— 仅安装指定语音包--local— 将语音包、配置和钩子安装到当前项目的./.claude/目录--global— 显式全局安装(与默认相同)--init-local-config— 仅创建./.claude/hooks/peon-ping/config.json
--local 不会修改你的 shell rc 文件(不注入全局 peon 别名/补全)。钩子注册到项目级 ./.claude/settings.json 并使用绝对路径,因此在项目内的任何工作目录下都能工作。
示例:
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.sh | bash -s -- --all
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.sh | bash -s -- --packs=peon,sc_kerrigan
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.sh | bash -s -- --local
如果已存在全局安装,你又安装了本地版本(或反之),安装程序会提示你移除现有的以避免冲突。
方式四:克隆后检查
git clone https://github.com/PeonPing/peon-ping.git
cd peon-ping
./install.sh
方式五: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 # 或使用 direnv
Home Manager 模块(声明式配置)
如需可复现的设置,使用 Home Manager 模块:
# 在你的 home.nix 或 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;
};
};
# 从 og-packs 安装语音包(简单字符串格式)
# 以及自定义来源(带 name + src 的属性集)
installPacks = [
"peon"
"glados"
"sc_kerrigan"
# 来自 GitHub 的自定义语音包(openpeon.com 注册表)
{
name = "mr_meeseeks";
src = pkgs.fetchFromGitHub {
owner = "kasperhendriks";
repo = "openpeon-mrmeeseeks";
rev = "main"; # 或使用 commit hash 以确保可复现
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
}
];
enableZshIntegration = true;
};
# 可选的额外 IDE 钩子(如 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 fetcher 结果(如pkgs.fetchFromGitHub)
在 openpeon.com 上列出的语音包,找到 GitHub 仓库链接并使用 pkgs.fetchFromGitHub:
{
name = "pack_name";
src = pkgs.fetchFromGitHub {
owner = "github-owner";
repo = "repo-name";
rev = "main"; # 或 commit hash/tag
sha256 = ""; # 先留空,Nix 会告诉你正确的 hash
};
}
Claude Code 钩子:设置 programs.peon-ping.claudeCodeIntegration = true; 即可将 Claude Code 钩子脚本安装到 ~/.claude/hooks/peon-ping/,并把标准的 peon-ping 钩子条目合并进 ~/.claude/settings.json。
其他 IDE 钩子:为避免覆盖与 peon-ping 无关的 IDE 设置,其他 IDE 的钩子仍然是可选的。peon-ping 在 adapters/ 下提供如 cursor.sh 之类的适配器脚本,你可以这样接入:
${inputs.peon-ping.packages.${pkgs.system}.default}/share/peon-ping/adapters/$YOUR_IDE.sh EVENT_NAME
参见上方 Cursor 示例。
你会听到什么
| 事件 | CESP 分类 | 示例 |
|---|---|---|
| 会话开始 | session.start | "Ready to work!", "Something need doing?" |
| 任务完成 | task.complete | "Work complete.", "Work, work." |
| 代理确认任务 | task.acknowledge | "I can do that.", "Be happy to.", "Okie dokie." (默认禁用) |
| 需要权限 | input.required | "Hmm?", "What you want?", "Yes?" |
| 工具或命令错误 | task.error | "Me not that kind of orc!", "Ugh." |
| 速率或 token 限制 | resource.limit | "Why not?" |
| 快速提示(10秒内3次以上) | user.spam | "Whaaat?", "Me busy, leave me alone!", "No time for play." |
此外,还会在每个屏幕上显示大型覆盖横幅(macOS/WSL/MSYS2)和终端标签页标题(● 项目: 完成)——即使你在其他应用中,也能立即知道任务完成。
peon-ping 实现了 编码事件语音包规范(CESP) — 这是一个任何代理式 IDE 都可以采用的编码事件声音开放标准。
快捷控制
开会或结对编程时需要静音?两种方式:
| 方式 | 命令 | 适用场景 |
|---|---|---|
| 斜杠命令 | /peon-ping-toggle | 在 Claude Code 中工作时 |
| CLI | peon toggle | 从任意终端标签页 |
其他 CLI 命令:
peon pause # 静音
peon mute # 'pause' 的别名
peon volume # 查看当前音量
peon volume 0.7 # 设置音量(0.0–1.0)
peon rotation # 查看当前轮换模式
peon rotation random # 设置轮换模式(random|round-robin|session_override)
peon resume # 取消静音
peon unmute # 'resume' 的别名
peon status # 查看暂停或活动状态(简洁模式)
peon status --verbose # 显示完整详情(通知、耳机、IDE 等)
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 标识,例如 codex
peon packs ide-unbind <ide> # 移除 IDE 绑定
peon packs ide-bindings # 列出所有 IDE 绑定
peon packs exclude add <path> # 为 glob 或目录跳过 path_rules
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] # 获取/设置/重置消息模板(键: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/devcontainer)
peon relay --stop # 停止后台中继
peon preview 支持的 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 在 Claude Code 中安装以下斜杠命令:
/peon-ping-toggle— 静音/取消静音/peon-ping-config— 更改任意设置(音量、语音包、分类等)/peon-ping-rename <名称>— 为当前会话设置自定义名称,显示在通知标题和终端标签标题中(零 token 消耗,由钩子拦截处理);不带参数则重置为自动检测
你也可以直接让 Claude 帮你修改设置 — 例如"启用轮换语音包"、"将音量设为 0.3"或"添加 glados 到我的语音包轮换"。无需手动编辑配置文件。
配置位置取决于安装模式:
- 全局安装:
$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 有三个独立的控制开关,可以混合使用:
| 配置键 | 控制项 | 影响声音 | 影响桌面弹窗 | 影响手机推送 |
|---|---|---|---|---|
enabled | 主音频开关 | ✅ 是 | ❌ 否 | ❌ 否 |
desktop_notifications | 桌面弹窗横幅 | ❌ 否 | ✅ 是 | ❌ 否 |
mobile_notify.enabled | 手机推送通知 | ❌ 否 | ❌ 否 | ✅ 是 |
这意味着您可以:
-
保留声音但禁用桌面弹窗:
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)后,点击通知可自动聚焦终端。在原生 Windows 上,点击 toast 通知可聚焦 IDE 或终端窗口(支持 VS Code、Cursor、Windsurf、Windows Terminal、PowerShell)。当打开多个窗口时,通知会通过基于 PID 的进程树匹配精确定位到触发事件的窗口。
-
overlay_theme:
"jarvis"、"glass"、"sakura",或留空使用默认覆盖层 — 仅 macOS(默认:无)- jarvis:圆形 HUD,带旋转弧线、刻度和进度环
- glass:毛玻璃风格面板,带强调色条、进度线和时间戳
- sakura:禅意花园,带盆景树和动态樱花花瓣
- wsl_toast:
true/false— 在 WSL 上使用原生 Windows toast 通知代替 Windows Forms 弹窗。Toast 不会抢占焦点并出现在操作中心。(默认:true)
-
categories:单独开关 CESP 声音分类(例如
"session.start": false禁用问候声音) -
annoyed_threshold / annoyed_window_seconds:在 N 秒内多少次提示触发
user.spam彩蛋 -
silent_window_seconds:对于短于 N 秒的任务,抑制
task.complete声音和通知。(例如10表示只播放超过 10 秒的任务声音) -
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时,如果同一会话已在idle_prompt_suppress_window_seconds窗口内触发过task.complete,则抑制此次idle_prompt。设为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):当子 Agent 会话结束时,抑制task.complete声音和通知。当 Claude Code 的 Task 工具并行派发多个子 Agent 时,每个子 Agent 完成都会触发一次提示音——将此选项设为true,则只播放父会话的完成提示音。 -
default_pack:当没有更具体的规则时使用的备选语音包(默认:
"peon")。取代旧的active_pack键——现有配置在peon update时自动迁移。 -
path_rules:
{ "pattern": "...", "pack": "..." }对象数组。根据工作目录使用通配符匹配(*、?)为会话分配语音包。第一个匹配规则生效,优先级高于pack_rotation和default_pack,但低于session_override分配。 -
exclude_dirs:glob 或目录模式数组。如果当前工作目录匹配其中一项,所有声音和通知都会被静音(钩子日志记录
suppressed=True reason=excluded_dir pattern=<匹配项>)。纯目录路径也会匹配其所有子目录,所以"~/conductor/workspaces"会让整棵目录树都保持静默。适用于后台代理(如CodexBar/ClaudeProbe)、临时目录或不希望发出声音的工作区。 -
ide_rules:
{ "ide": "...", "pack": "..." }对象数组。在path_rules之后、轮换与默认包之前按 IDE/source 指定语音包。第一个匹配规则生效。常见 id:claude、codex、cursor、opencode、kilo、kiro、gemini、copilot、windsurf、kimi、antigravity、amp、deepagents、openclaw、rovodev。 -
pack_rotation:语音包名称数组(例如
["peon", "sc_kerrigan", "peasant"])。用于pack_rotation_mode为random或round-robin时。留空[]则仅使用default_pack(或path_rules/ide_rules)。 -
pack_rotation_mode:
"random"(默认)、"round-robin"或"session_override"。使用random/round-robin时,每个会话从pack_rotation中选择一个语音包。使用session_override时,/peon-ping-use <pack>命令为每个会话分配语音包。无效或缺失的语音包会按层级回退。("agentskill"作为"session_override"的旧别名仍被接受。) -
session_ttl_days(数字,默认:7):使超过 N 天的陈旧每会话语音包分配过期。防止使用
session_override模式时.state.json无限增长。 -
headphones_only(布尔值,默认:
false):仅在检测到耳机或外部音频设备时播放声音。启用后,如果内置扬声器是活动输出,声音将被静音 — 适用于开放式办公室。使用peon status查看状态。支持 macOS(通过system_profiler)和 Linux(通过 PipeWirewpctl或 PulseAudiopactl)。 -
suppress_sound_when_tab_focused(布尔值,默认:
false):当生成钩子事件的终端标签页处于当前活动/聚焦状态时,跳过声音播放。声音仍会在后台标签页中播放,提醒您其他地方发生了事件。桌面和移动通知不受影响。适用于只想在未查看的标签页中听到音频提示的用户。仅支持 macOS(使用osascript检查最前端应用和 iTerm2 标签页焦点)。 -
meeting_detect:检测麦克风是否正在使用中,并在麦克风使用期间临时抑制音频播放。通知仍会正常显示。
-
notification_position(字符串,默认:
"top-center"):覆盖通知在屏幕上的显示位置。选项:"top-left"、"top-center"、"top-right"、"bottom-left"、"bottom-center"、"bottom-right"。 -
notification_dismiss_seconds(数字,默认:
4):覆盖通知在 N 秒后自动消失。设为0则通知持续显示,需点击关闭。 -
CLAUDE_SESSION_NAME环境变量:在启动claude前设置,为会话指定自定义名称。同时显示在桌面通知标题和终端标签标题中,优先级高于所有配置项。示例:CLAUDE_SESSION_NAME="Auth Refactor" claude或先export CLAUDE_SESSION_NAME="功能: Auth"再claude。 -
notification_title_override(字符串,默认:
""):覆盖通知标题中显示的项目名称。为空时自动检测:/peon-ping-rename>CLAUDE_SESSION_NAME>.peon-label>notification_title_script>project_name_map> git 仓库名 > 文件夹名。 -
notification_title_marker(字符串,默认:
"●"):通知标题和终端标签标题前显示的字符。设为""可禁用。例如:"🔔"。 -
notification_title_script(字符串,默认:
""):在事件触发时运行的 Shell 命令,用于动态计算项目名称。可用环境变量:PEON_SESSION_ID、PEON_CWD、PEON_HOOK_EVENT、PEON_SESSION_NAME。使用标准输出(去除首尾空白,最多 50 字符);非零退出码则继续查找下一层级。示例:"basename $PEON_CWD"。 -
project_name_map(对象,默认:
{}):将目录路径映射为通知中的自定义项目标签。键为路径模式,值为显示名称。 -
notification_templates(对象,默认:
{}):自定义通知事件的消息格式。键为事件类型(stop、permission、error、idle、question),值为支持变量替换的模板字符串。可用变量:{project}、{summary}、{tool_name}、{status}、{event}。
语音包选择层级
peon-ping 通过 6 层层级结构确定使用哪个语音包。第一个产生有效已安装语音包的层级生效:
| 优先级 | 层级 | 来源 | 设置方式 |
|---|---|---|---|
| 1(最高) | session_override | 每会话分配 | /peon-ping-use <pack> 技能或 MCP |
| 2 | path_rules | 工作目录的通配符匹配 | peon packs bind 或配置中的 path_rules |
| 3 | ide_rules | IDE/source 匹配 | peon packs ide-bind 或配置中的 ide_rules |
| 4 | pack_rotation | 从列表中随机或轮换 | 配置中的 pack_rotation 数组 + pack_rotation_mode |
| 5 | default_pack | 静态回退 | peon packs use <name> 或配置中的 default_pack |
| 6(最低) | 硬编码 | 内置默认 | "peon" |
如果某层级引用的语音包未安装,则回退到下一层级。
如果 exclude_dirs 命中当前工作目录,则本次调用被完全静音 —— 不播放声音、不发送通知。
按项目分配语音包(path_rules)
根据目录路径为不同项目分配不同的语音包。可以使用 CLI 或直接编辑 config.json。
CLI(推荐):
peon packs bind glados # 将 glados 绑定到当前目录
peon packs bind sc_kerrigan --pattern "*/services/*" # 绑定到通配符模式
peon packs bind duke_nukem --install # 绑定并在需要时从注册表安装
peon packs unbind # 移除当前目录的绑定
peon packs unbind --pattern "*/services/*" # 移除特定模式的绑定
peon packs bindings # 列出所有绑定
手动配置:
"path_rules": [
{ "pattern": "*/work/client-a/*", "pack": "glados" },
{ "pattern": "*/personal/*", "pack": "peon" },
{ "pattern": "*/services/*", "pack": "sc_kerrigan" }
]
规则使用通配符匹配(*、?)。第一个匹配规则生效。路径规则优先级高于 pack_rotation 和 default_pack,但低于 session_override 分配。
按 IDE 分配语音包(ide_rules)
当某个路径本身很嘈杂、或者多个工具共用同一目录时,可以让语音包跟着 IDE/source 走。
CLI(推荐):
peon packs ide-bind codex glados # 为 Codex 会话使用 glados
peon packs ide-bind claude peon # 为 Claude Code 使用 peon
peon packs ide-unbind codex # 移除一个 IDE 规则
peon packs ide-bindings # 列出 IDE 规则和最近检测到的 IDE
手动配置:
"ide_rules": [
{ "ide": "codex", "pack": "glados" },
{ "ide": "claude", "pack": "peon" }
]
ide_rules 在 path_rules 之后执行。
常见用例
保留声音但禁用弹窗
想要语音反馈但不想要视觉干扰?
peon notifications off
这会保持所有声音类别的播放,同时禁用桌面通知横幅。手机通知(如果已配置)继续工作。
您也可以使用别名:
peon popups off
静音模式但保留通知
想要视觉提醒但不要音频?
peon pause # 或在配置中设置 "enabled": false
当 desktop_notifications: true 时,您将收到弹窗但没有声音。
完全静音
禁用所有功能:
peon pause
peon notifications off
peon mobile off
Peon 教练
你的苦工也是你的私人教练。内置帕维尔风格(Pavel-style)每日锻炼模式 — 那个告诉你"work work"的兽人现在会叫你趴下做二十个俯卧撑。
快速开始
peon trainer on # 启用教练模式
peon trainer goal 200 # 设置每日目标(默认:300/300)
# ... 写一段时间代码,苦工每约 20 分钟唠叨你一次 ...
peon trainer log 25 pushups # 记录你的运动次数
peon trainer log 30 squats
peon trainer status # 查看进度
工作原理
教练提醒基于你的编程会话运行。当你开始新会话时,苦工会立即鼓励你在写任何代码之前先做俯卧撑。然后在活跃编程期间每约 20 分钟,你会听到苦工喊你做更多次。无需后台守护进程。使用 peon trainer log 记录你的次数,进度在午夜自动重置。
命令
| 命令 | 描述 |
|---|---|
peon trainer on | 启用教练模式 |
peon trainer off | 禁用教练模式 |
peon trainer status | 显示今日进度 |
peon trainer log <n> <exercise> | 记录次数(例如 log 25 pushups) |
peon trainer goal <n> | 设置所有运动的统一每日目标 |
peon trainer goal <exercise> <n> | 设置单项运动的统一每日目标 |
peon trainer goal <exercise> <day> <n> | 设置特定日期的目标(mon、tue 等) |
peon trainer goal <day> <n> | 设置某天所有运动的目标 |
日程表与统一目标
运动可以设置统一每日目标(每天相同)或按日日程表(不同日期不同目标)。两者互斥:
- 设置统一目标会移除该运动的所有日程安排
- 设置特定日期目标会移除该运动的统一目标
日期使用缩写:mon、tue、wed、thu、fri、sat、sun
peon trainer goal pushups 300 # 每天 300 俯卧撑(统一目标)
peon trainer goal pushups mon 400 # 覆盖:周一 400(创建日程表)
peon trainer goal squats sun 0 # 周日深蹲休息
peon trainer goal fri 150 # 周五所有运动轻松日
在休息日(目标=0),提醒会被跳过,状态显示 [REST DAY]。如果你愿意,仍然可以在休息日记录运动次数。
Claude Code 技能
在 Claude Code 中,你可以不用离开对话就记录次数:
/peon-ping-log 25 pushups
/peon-ping-log 30 squats
自定义语音
将你自己的音频文件放入 ~/.claude/hooks/peon-ping/trainer/sounds/:
trainer/sounds/session_start/ # 会话问候("Pushups first, code second! Zug zug!")
trainer/sounds/remind/ # 提醒语音("Something need doing? YES. PUSHUPS.")
trainer/sounds/log/ # 确认语音("Work work! Muscles getting bigger maybe!")
trainer/sounds/complete/ # 庆祝语音("Zug zug! Human finish all reps!")
trainer/sounds/slacking/ # 失望语音("Peon very disappointed.")
更新 trainer/manifest.json 来注册你的声音文件。
MCP 服务器
peon-ping 包含一个 MCP(模型上下文协议)服务器,任何兼容 MCP 的 AI 代理都可以通过工具调用直接播放声音,无需钩子。
核心区别:由代理选择声音。代理不再在每个事件上自动播放固定声音,而是直接调用 play_sound 指定想要的声音——构建失败时用 duke_nukem/SonOfABitch,读取文件时用 sc_kerrigan/IReadYou。
设置
在 MCP 客户端配置中添加(Claude Desktop、Cursor 等):
{
"mcpServers": {
"peon-ping": {
"command": "node",
"args": ["/path/to/peon-ping/mcp/peon-mcp.js"]
}
}
}
通过 Homebrew 安装时路径为 $(brew --prefix peon-ping)/libexec/mcp/peon-mcp.js。完整设置说明见 mcp/README.md。
可用功能
| 功能 | 说明 |
|---|---|
play_sound | 按键名播放一个或多个声音(如 duke_nukem/SonOfABitch、peon/PeonReady1) |
peon-ping://catalog | 以 MCP 资源形式获取完整语音包目录——客户端预取一次,无需重复工具调用 |
peon-ping://pack/{name} | 获取指定语音包的详细信息和可用声音键名 |
需要 Node.js 18+。由 @tag-assistant 贡献。
多 IDE 支持
peon-ping 适用于任何支持钩子的代理式 IDE。适配器将 IDE 特定事件转换为 CESP 标准。
| IDE | 状态 | 设置 |
|---|---|---|
| Claude Code | 内置 | curl | bash 安装会自动处理 |
| Amp | 适配器 | bash adapters/amp.sh / powershell adapters/amp.ps1(设置) |
| Gemini CLI | 适配器 | 添加指向 adapters/gemini.sh(Windows 用 .ps1)的钩子(设置) |
| GitHub Copilot CLI | 内置(自动检测) | 当 ~/.copilot 存在时,install.sh / install.ps1 自动在 ~/.copilot/hooks/peon-ping.json 注册钩子。也可通过 adapters/copilot.sh / .ps1 进行逐仓库手动配置(设置) |
| OpenAI Codex | 适配器 | 先安装 peon-ping 运行时,然后在 ~/.codex/config.toml 中添加指向 adapters/codex.sh(或 .ps1)的 notify 条目(设置) |
| Cursor | 内置 | curl | bash、peon-ping-setup 或 Windows install.ps1 自动检测并注册钩子。在 Windows 上,请在 设置 → 功能 → 第三方技能 中启用,以便 Cursor 加载 ~/.claude/settings.json 以播放 SessionStart/Stop 音效。 |
| OpenCode | 适配器 | bash adapters/opencode.sh / powershell adapters/opencode.ps1(设置) |
| Kilo CLI | 适配器 | bash adapters/kilo.sh / powershell adapters/kilo.ps1(设置) |
| Kiro | 适配器 | 添加指向 adapters/kiro.sh(或 .ps1)的钩子条目(设置) |
| Windsurf | 适配器 | 添加指向 adapters/windsurf.sh(或 .ps1)的钩子条目(设置) |
| Google Antigravity | 适配器 | bash adapters/antigravity.sh / powershell adapters/antigravity.ps1。无头 / macOS LaunchAgent 场景可用 bash adapters/antigravity-py.sh --install(基于 Python watchdog 的 25 秒空闲阈值守护进程,需要 pip3 install watchdog)。 |
| Kimi Code | 适配器 | bash adapters/kimi.sh --install / powershell adapters/kimi.ps1 -Install(设置) |
| OpenClaw | 适配器 | 调用 adapters/openclaw.sh <event>(或 openclaw.ps1),支持所有 CESP 分类和原生 Claude Code 事件名 |
| Rovo Dev CLI | 适配器 | 如果 ~/.rovodev 存在,install.sh 会自动注册,或手动添加钩子到 ~/.rovodev/config.yml(设置) |
| DeepAgents | 适配器 | bash adapters/deepagents.sh / powershell adapters/deepagents.ps1(设置) |
| oh-my-pi (omp) | 适配器 | bash adapters/omp.sh(设置) |
Windows: 所有适配器都有原生 PowerShell(
.ps1)版本。Windows 安装程序(install.ps1)会将其复制到~/.claude/hooks/peon-ping/adapters/。文件系统监视器(Amp、Antigravity、Kimi)使用 .NETFileSystemWatcher而非 fswatch/inotifywait — 无需额外依赖。
OpenAI Codex 设置
Codex 支持使用适配器,不会由 peon-ping-setup 自动注册。
Codex 适配器要求 peon-ping 运行时位于 ~/.claude/hooks/peon-ping/,即使你只使用 Codex 而不使用 Claude Code。
设置步骤:
-
先安装 peon-ping 运行时:
bash "$(brew --prefix peon-ping)"/libexec/install.sh --no-rc或使用标准安装器:
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.sh | bash -s -- --no-rc -
添加以下内容到
~/.codex/config.toml:notify = ["bash", "~/.claude/hooks/peon-ping/adapters/codex.sh"] -
重启 Codex。
如果通过 Homebrew 安装,运行时文件在 ~/.claude/hooks/peon-ping/ 下管理,Codex 适配器将 Codex notify 事件转发到该共享运行时。
Amp 设置
Amp(Sourcegraph)的文件系统监视适配器。Amp 不像 Claude Code 那样提供事件钩子,因此该适配器监视 Amp 的线程文件并检测代理何时完成回合。
设置步骤:
-
确保已安装 peon-ping(
curl -fsSL https://peonping.com/install | bash) -
安装
fswatch(macOS)或inotify-tools(Linux):brew install fswatch # macOS sudo apt install inotify-tools # Linux -
启动监视器:
bash ~/.claude/hooks/peon-ping/adapters/amp.sh # 前台运行 bash ~/.claude/hooks/peon-ping/adapters/amp.sh & # 后台运行
事件映射:
- 新线程文件创建 → 问候音效("Ready to work?"、"Yes?")
- 线程文件停止更新 + 代理完成回合 → 完成音效("Work, work."、"Job's done!")
工作原理:
适配器监视 ~/.local/share/amp/threads/ 目录的 JSON 文件变化。当线程文件停止更新(1 秒空闲超时)且最后一条消息来自助手的文本内容(非待处理的工具调用)时,发出 Stop 事件 — 表示代理已完成,正在等待你的输入。
环境变量:
| 变量 | 默认值 | 说明 |
|---|---|---|
AMP_DATA_DIR | ~/.local/share/amp | Amp 数据目录 |
AMP_THREADS_DIR | $AMP_DATA_DIR/threads | 要监视的线程目录 |
AMP_IDLE_SECONDS | 1 | 停止变化后等待多少秒发出 Stop 事件 |
AMP_STOP_COOLDOWN | 10 | 每个线程 Stop 事件之间的最小间隔秒数 |
GitHub Copilot CLI 设置
GitHub Copilot CLI 原生集成,完全符合 CESP v1.0 规范。
推荐:用户级(全局)配置 —— 无需逐仓库设置。
每当 ~/.copilot/ 目录存在时,install.sh 和 install.ps1 会自动在 ~/.copilot/hooks/peon-ping.json 注册 Copilot CLI 钩子。如果你在安装 peon-ping 之后才安装了 Copilot CLI,请重新运行安装脚本。该配置使用 PascalCase 事件名称,这会让 Copilot CLI 直接发送与 VS Code 兼容的(snake_case)负载,正是 peon.sh / peon.ps1 原生读取的格式 —— 不需要逐仓库适配器。
全局注册的钩子:
| 事件 | 分类 | 触发条件 |
|---|---|---|
SessionStart | session.start | 启动 copilot(问候) |
SessionEnd | (当前静音) | 退出 CLI |
UserPromptSubmit | user.spam(3+ 次快速提示后) | 每次提交提示 |
Stop(即 agentStop) | task.complete | Agent 完成一个回合(5 秒去抖) |
Notification | input.required(elicitation) | 空闲、elicitation 对话框、权限弹出 |
PermissionRequest | input.required | 工具权限请求 |
PreToolUse | input.required(仅匹配危险模式时) | 每次工具调用前 |
PostToolUseFailure | task.error | 工具失败 |
PreCompact | resource.limit | 上下文压缩开始 |
postToolUse 未被注册:peon 没有 PostToolUse 处理程序,将其路由到 Stop 会淹没去抖窗口,吞掉真正的 Stop 事件。
前置条件(Windows): Copilot CLI 钩子需要 PowerShell 7+(pwsh 在 PATH 中)以及宽松的执行策略:
winget install Microsoft.PowerShell
powershell -NoProfile -Command "Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force"
替代方案:使用适配器进行逐仓库配置。
如果你想要将 Copilot CLI 钩子提交到特定仓库(例如团队工作流),请使用 .github/hooks/hooks.json 配合 adapters/copilot.sh(Windows 上为 .ps1)转换器:
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "command",
"bash": "bash ~/.claude/hooks/peon-ping/adapters/copilot.sh sessionStart",
"powershell": "powershell -NoProfile -File %USERPROFILE%\\.claude\\hooks\\peon-ping\\adapters\\copilot.ps1 sessionStart"
}
],
"agentStop": [
{
"type": "command",
"bash": "bash ~/.claude/hooks/peon-ping/adapters/copilot.sh agentStop",
"powershell": "powershell -NoProfile -File %USERPROFILE%\\.claude\\hooks\\peon-ping\\adapters\\copilot.ps1 agentStop"
}
],
"postToolUseFailure": [
{
"type": "command",
"bash": "bash ~/.claude/hooks/peon-ping/adapters/copilot.sh postToolUseFailure",
"powershell": "powershell -NoProfile -File %USERPROFILE%\\.claude\\hooks\\peon-ping\\adapters\\copilot.ps1 postToolUseFailure"
}
],
"notification": [
{
"type": "command",
"bash": "bash ~/.claude/hooks/peon-ping/adapters/copilot.sh notification",
"powershell": "powershell -NoProfile -File %USERPROFILE%\\.claude\\hooks\\peon-ping\\adapters\\copilot.ps1 notification"
}
]
}
}
可按上表添加其他事件。适配器将 Copilot CLI 的 camelCase 负载(sessionId、toolName、stopReason 等)转换为 peon.sh / peon.ps1 读取的 snake_case 形式(session_id、tool_name、stop_reason)。
功能:
- 音频播放 通过
afplay(macOS)、pw-play/paplay/ffplay(Linux)、MediaPlayer/SoundPlayer(Windows)—— 与 shell 钩子相同的优先级链 - CESP 事件映射 —— Copilot CLI 钩子映射到标准 CESP 分类(
session.start、task.complete、task.error、input.required、user.spam、resource.limit) - 桌面通知 —— 默认使用大型覆盖横幅,或标准通知
- 垃圾信息检测 —— 检测 10 秒内 3 次以上快速提示,触发
user.spam语音 - 去抖 ——
Stop事件在 5 秒窗口内被抑制,防止链式工具调用产生的垃圾消息
OpenCode 设置
OpenCode 的原生 TypeScript 插件,完全符合 CESP v1.0 规范。
快速安装:
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/adapters/opencode.sh | bash
安装程序将 peon-ping.ts 复制到 ~/.config/opencode/plugins/ 并在 ~/.config/opencode/peon-ping/config.json 创建配置。语音包存储在共享 CESP 路径(~/.openpeon/packs/)。
功能:
- 声音播放 — 通过
afplay(macOS)、pw-play/paplay/ffplay(Linux)— 与 shell 钩子相同的优先级链 - CESP 事件映射 —
session.created/session.idle/session.error/permission.asked/ 快速提示检测都映射到标准 CESP 分类 - 桌面通知 — 通过
terminal-notifier提供丰富通知(副标题、按项目分组),回退到osascript。仅在终端未获得焦点时触发 - 终端焦点检测 — 通过 AppleScript 检测你的终端应用(Terminal、iTerm2、Warp、Alacritty、kitty、WezTerm、ghostty、Hyper)是否在最前端
- 标签页标题 — 更新终端标签页显示任务状态(
● 项目: 工作中.../✓ 项目: 完成/✗ 项目: 错误) - 语音包切换 — 从配置读取
default_pack(旧版配置中回退到active_pack),运行时加载语音包的openpeon.json清单。path_rules可根据工作目录覆盖语音包。 - 不重复逻辑 — 避免每个分类连续播放相同声音
- 刷屏检测 — 检测 10 秒内 3 次以上快速提示,触发
user.spam语音
🖼️ 截图:带有自定义苦工图标的桌面通知
提示: 安装
terminal-notifier(brew install terminal-notifier)以获得更丰富的通知(支持副标题和分组)。
🎨 可选:自定义苦工图标用于通知
默认情况下,terminal-notifier 显示通用终端图标。包含的脚本使用 macOS 内置工具(sips + iconutil)将其替换为苦工图标 — 无需额外依赖。
bash <(curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/adapters/opencode/setup-icon.sh)
或本地安装(Homebrew / git clone):
bash ~/.claude/hooks/peon-ping/adapters/opencode/setup-icon.sh
脚本会自动查找苦工图标(Homebrew libexec、OpenCode 配置或 Claude 钩子目录),生成正确的 .icns,备份原始 Terminal.icns 并替换。brew upgrade terminal-notifier 后需重新运行。
未来: 当 jamf/Notifier 发布到 Homebrew(#32)时,插件将迁移到它 — Notifier 内置
--rebrand支持,无需修改图标。
Kilo CLI 设置
Kilo CLI 的原生 TypeScript 插件,完全符合 CESP v1.0 规范。Kilo CLI 是 OpenCode 的分支,使用相同的插件系统 — 此安装程序下载 OpenCode 插件并为 Kilo 打补丁。
快速安装:
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/adapters/kilo.sh | bash
安装程序将 peon-ping.ts 复制到 ~/.config/kilo/plugins/ 并在 ~/.config/kilo/peon-ping/config.json 创建配置。语音包存储在共享 CESP 路径(~/.openpeon/packs/)。
功能: 与 OpenCode 适配器相同 — 声音播放、CESP 事件映射、桌面通知、终端焦点检测、标签页标题、语音包切换、不重复逻辑和刷屏检测。
Gemini CLI 设置
Gemini CLI 的 shell 适配器,完全符合 CESP v1.0 规范。
设置步骤:
-
确保已安装 peon-ping(
curl -fsSL https://peonping.com/install | bash) -
在
~/.gemini/settings.json中添加以下钩子:{ "hooks": { "SessionStart": [ { "matcher": "startup", "hooks": [ { "name": "peon-start", "type": "command", "command": "bash ~/.claude/hooks/peon-ping/adapters/gemini.sh SessionStart" } ] } ], "AfterAgent": [ { "matcher": "*", "hooks": [ { "name": "peon-after-agent", "type": "command", "command": "bash ~/.claude/hooks/peon-ping/adapters/gemini.sh AfterAgent" } ] } ], "AfterTool": [ { "matcher": "*", "hooks": [ { "name": "peon-after-tool", "type": "command", "command": "bash ~/.claude/hooks/peon-ping/adapters/gemini.sh AfterTool" } ] } ], "Notification": [ { "matcher": "*", "hooks": [ { "name": "peon-notification", "type": "command", "command": "bash ~/.claude/hooks/peon-ping/adapters/gemini.sh Notification" } ] } ] } }
事件映射:
SessionStart(startup)→ 问候音效("准备好了吗?"、"是的?")AfterAgent→ 任务完成音效("干活,干活。"、"完成了!")AfterTool(成功)→ 任务完成音效;(失败)→ 错误音效("我做不到。")Notification→ 系统通知
Windsurf 设置
添加到 ~/.codeium/windsurf/hooks.json(用户级)或 .windsurf/hooks.json(工作区级):
{
"hooks": {
"post_cascade_response": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/windsurf.sh post_cascade_response", "show_output": false }
],
"pre_user_prompt": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/windsurf.sh pre_user_prompt", "show_output": false }
],
"post_write_code": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/windsurf.sh post_write_code", "show_output": false }
],
"post_run_command": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/windsurf.sh post_run_command", "show_output": false }
]
}
}
Kiro 设置
创建 ~/.kiro/agents/peon-ping.json:
{
"hooks": {
"agentSpawn": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/kiro.sh" }
],
"userPromptSubmit": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/kiro.sh" }
],
"stop": [
{ "command": "bash ~/.claude/hooks/peon-ping/adapters/kiro.sh" }
]
}
}
preToolUse/postToolUse 被有意排除 — 它们会在每次工具调用时触发,会非常嘈杂。
Rovo Dev CLI 设置
Rovo Dev CLI(Atlassian)的 shell 适配器,完全符合 CESP v1.0 规范。
自动设置:
如果运行 install.sh 或 peon-ping-setup 时 ~/.rovodev/config.yml 存在,事件钩子会自动注册。
手动设置:
-
确保已安装 peon-ping(
curl -fsSL https://peonping.com/install | bash) -
添加到
~/.rovodev/config.yml:eventHooks: events: - name: on_complete commands: - command: bash ~/.claude/hooks/peon-ping/adapters/rovodev.sh on_complete - name: on_error commands: - command: bash ~/.claude/hooks/peon-ping/adapters/rovodev.sh on_error - name: on_tool_permission commands: - command: bash ~/.claude/hooks/peon-ping/adapters/rovodev.sh on_tool_permission -
重启 Rovo Dev CLI 以使钩子生效。
事件映射:
on_complete→ 完成音效("Work, work."、"Job's done!")on_error→ 错误音效("I can't do that."、"Son of a bitch!")on_tool_permission→ 权限提示音效("Something need doing?"、"Hmm?")
功能:
- 声音播放 通过
afplay(macOS)、pw-play/paplay/ffplay(Linux)— 与 shell 钩子相同的优先级链 - CESP 事件映射 — Rovo Dev 事件映射到标准 CESP 分类(
task.complete、task.error、input.required) - 桌面通知 — 默认大型覆盖横幅,或标准通知
- 防抖 — 抑制快速完成产生的重复声音
Kimi Code 设置
Kimi Code CLI(MoonshotAI)的文件系统监视适配器。Kimi Code 将 Wire Mode 事件写入 ~/.kimi/sessions/ — 该适配器作为后台守护进程监视这些文件并将事件转换为 CESP 格式。
# 安装(启动后台守护进程)
bash ~/.claude/hooks/peon-ping/adapters/kimi.sh --install
# 查看状态 / 停止
bash ~/.claude/hooks/peon-ping/adapters/kimi.sh --status
bash ~/.claude/hooks/peon-ping/adapters/kimi.sh --uninstall
macOS 需要 fswatch(brew install fswatch),Linux 需要 inotifywait(apt install inotify-tools)。curl | bash 安装器会自动检测 Kimi Code 并启动守护进程。
macOS 上 --install 会注册 LaunchAgent(~/Library/LaunchAgents/com.peonping.kimi-adapter.plist),监听器会在登录时自动启动并在崩溃时自动重启 — 重启后无需重新运行 --install。设置 KIMI_NO_LAUNCHD=1 可回退到 nohup+pidfile(例如用于测试)。Linux 始终使用 nohup+pidfile。
仅 Kimi 安装(无需 Claude):
如果你没有 Claude Code,只想给 Kimi 装 peon-ping,使用 --kimi:
curl -fsSL peonping.com/install | bash -s -- --kimi
文件会安装到 ~/.kimi/hooks/peon-ping/ 而不是 ~/.claude/hooks/peon-ping/,也不会创建 ~/.claude/ 目录。安装器还会自动检测:在仅有 ~/.kimi/ 但没有 ~/.claude/ 的机器上,无参数运行安装器会自动进入 --kimi 模式。监视守护进程会在安装时启动,并通过 LaunchAgent 在每次登录时重新启动。
与 Claude 安装共享语音包:
如果 ~/.claude/hooks/peon-ping/packs/ 已存在并包含语音包,--kimi 安装会将 ~/.kimi/hooks/peon-ping/packs 软链接到它,而不是重新下载。一次下载即可服务两个 IDE,从任一侧执行 peon packs install <name> 都会更新共享的包集。状态、配置和静音切换在每个安装中保持独立。传递 --no-shared-packs(或 --packs= / --all)以下载独立副本。
事件映射:
- 新会话 → 问候音效("Ready to work?"、"Yes?")
- Agent 完成回合 → 完成音效("Work, work."、"Job's done!")
- 上下文压缩 → Token 限制音效
- 子 Agent 启动 → 子 Agent 跟踪
oh-my-pi (omp) 设置
oh-my-pi(omp)的原生 TypeScript 扩展,完全符合 CESP v1.0 规范。订阅 omp 的 ExtensionAPI 生命周期事件,并通过 peon.sh 路由,让 omp 用户享受 peon-ping 的所有功能:语音包、桌面通知、训练提醒、移动推送、SSH/devcontainer 中继及标签页标题更新。
快速安装:
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/adapters/omp.sh | bash
安装程序将 peon-ping.ts 和 package.json 复制到 ~/.omp/agent/extensions/peon-ping/。之后重启 omp。
事件映射:
| omp 事件 | peon-ping 事件 |
|---|---|
session_start | SessionStart |
turn_start | UserPromptSubmit |
turn_end | Stop |
tool_result with isError: true | PostToolUseFailure |
auto_compaction_start | PreCompact |
session_shutdown | SessionEnd |
卸载:
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/adapters/omp.sh | bash -s -- --uninstall
远程开发(SSH / Devcontainers / Codespaces)
在远程服务器或容器中编码?peon-ping 自动检测 SSH 会话、devcontainers 和 Codespaces,然后通过本地机器上运行的轻量级中继路由音频和通知。
SSH 设置
-
在本地机器上,启动中继:
peon relay --daemon -
带端口转发的 SSH:
ssh -R 19998:localhost:19998 your-server -
在远程安装 peon-ping — 它会自动检测 SSH 会话并通过转发端口将音频请求发送回本地中继。
就这样。声音在你的笔记本电脑上播放,而不是远程服务器。
Devcontainers / Codespaces
无需端口转发 — peon-ping 自动检测 REMOTE_CONTAINERS 和 CODESPACES 环境变量并将音频路由到 host.docker.internal:19998。只需在主机上运行 peon relay --daemon。
中继命令
peon relay # 前台启动中继
peon relay --daemon # 后台启动
peon relay --stop # 停止后台中继
peon relay --status # 检查中继是否运行
peon relay --port=12345 # 自定义端口(默认:19998)
peon relay --bind=0.0.0.0 # 监听所有接口(安全性较低)
环境变量:PEON_RELAY_PORT、PEON_RELAY_HOST、PEON_RELAY_BIND。
如果 peon-ping 检测到 SSH 或容器会话但无法连接中继,它会在 SessionStart 时打印设置说明。
基于分类的 API(用于轻量级远程钩子)
中继支持在服务器端处理声音选择的基于分类的端点。这对于未安装 peon-ping 的远程机器很有用 — 远程钩子只需发送分类名称,中继从活动语音包中随机选择声音。
端点:
| 端点 | 描述 |
|---|---|
GET /health | 健康检查(返回 "OK") |
GET /play?file=<path> | 播放指定声音文件(旧版) |
GET /play?category=<cat> | 播放分类中的随机声音(推荐) |
POST /notify | 发送桌面通知 |
远程钩子示例(scripts/remote-hook.sh):
#!/bin/bash
RELAY_URL="${PEON_RELAY_URL:-http://127.0.0.1:19998}"
EVENT=$(cat | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('hook_event_name',''))" 2>/dev/null)
case "$EVENT" in
SessionStart) CATEGORY="session.start" ;;
Stop) CATEGORY="task.complete" ;;
PermissionRequest) CATEGORY="input.required" ;;
*) exit 0 ;;
esac
curl -sf "${RELAY_URL}/play?category=${CATEGORY}" >/dev/null 2>&1 &
将其复制到远程机器并在 ~/.claude/settings.json 中注册:
{
"hooks": {
"SessionStart": [{"command": "bash /path/to/remote-hook.sh"}],
"Stop": [{"command": "bash /path/to/remote-hook.sh"}],
"PermissionRequest": [{"command": "bash /path/to/remote-hook.sh"}]
}
}
中继从本地机器的 config.json 读取活动语音包和音量,加载语音包清单,并选择随机声音(避免重复)。
手机通知
当任务完成或需要关注时在手机上收到推送通知 — 当你离开桌面时很有用。
快速开始(ntfy.sh — 免费,无需账户)
- 在手机上安装 ntfy 应用
- 在应用中订阅一个唯一主题(例如
my-peon-notifications) - 运行:
peon mobile ntfy my-peon-notifications
peon mobile pushover <user_key> <app_token>
peon mobile telegram <bot_token> <chat_id>
手机命令
peon mobile on # 启用手机通知
peon mobile off # 禁用手机通知
peon mobile status # 显示当前配置
peon mobile test # 发送测试通知
手机通知在每个事件时都会触发,无论窗口焦点 — 它们独立于桌面通知和声音。
语音包
160 多个语音包,涵盖魔兽争霸、星际争霸、红色警戒、传送门、塞尔达、Dota 2、绝地潜兵2、上古卷轴等。默认安装包含 5 个精选语音包:
| 语音包 | 角色 | 声音 |
|---|---|---|
peon(默认) | 兽人苦工(魔兽争霸 III) | "Ready to work?", "Work, work.", "Okie dokie." |
peasant | 人类农民(魔兽争霸 III) | "Yes, milord?", "Job's done!", "Ready, sir." |
sc_kerrigan | 莎拉·凯瑞甘(星际争霸) | "I gotcha", "What now?", "Easily amused, huh?" |
sc_battlecruiser | 战列巡航舰(星际争霸) | "Battlecruiser operational", "Make it happen", "Engage" |
glados | GLaDOS(传送门) | "Oh, it's you.", "You monster.", "Your entire team is dead." |
浏览所有语音包并试听 → openpeon.com/packs
使用 --all 安装全部,或随时切换语音包:
peon packs use glados # 切换到指定语音包
peon packs next # 切换到下一个语音包
peon packs list # 列出所有已安装语音包
peon packs list --registry # 浏览所有可用语音包
peon packs install glados,murloc # 安装指定语音包
peon packs install --all # 安装注册表中所有语音包
想添加自己的语音包?参见 openpeon.com/create 完整指南 或 CONTRIBUTING.md。
调试
当声音不播放或通知未出现时,结构化调试日志可帮助你精确追踪钩子调用期间发生的事情。
启用调试日志
peon debug on # 启用 — 日志写入 ~/.claude/hooks/peon-ping/logs/
peon debug off # 禁用
peon debug status # 显示状态、日志目录、文件数和总大小
你也可以通过设置环境变量 PEON_DEBUG=1 在单次调用中启用调试日志,而无需更改配置。
查看日志
peon logs # 今天日志的最后 50 行
peon logs --last 100 # 所有日志文件的最后 100 行
peon logs --session <ID> # 按会话 ID 过滤今天的日志
peon logs --session <ID> --all # 搜索所有日志文件中的会话 ID
peon logs --clear # 删除所有日志文件(需确认)
日志格式
每行日志是一条结构化的 key=value 记录:
2026-03-26T14:32:01.042 [config] inv=a3f1 loaded=/path/to/config.json volume=0.5 pack=peon enabled=True
2026-03-26T14:32:01.045 [event] inv=a3f1 hook_event=Stop cesp=task.complete session=abc123
2026-03-26T14:32:01.048 [sound] inv=a3f1 file=work-work.wav label="Work, work." category=task.complete
2026-03-26T14:32:01.120 [play] inv=a3f1 player=afplay file=work-work.wav
2026-03-26T14:32:01.125 [notify] inv=a3f1 title="peon: done" body="Work, work."
- inv -- 唯一的 4 字符调用 ID,链接单次钩子调用的所有阶段
- 阶段:
[config]、[event]、[sound]、[play]、[notify]-- 每个代表钩子管道中的一个阶段 - 包含空格或特殊字符的值会加引号
常见故障示例
| 症状 | 在日志中查找 |
|---|---|
| 没有声音播放 | [event] 行显示 exit=early(分类被禁用、已暂停或去抖动) |
| 错误的语音包 | [config] 行显示意外的 pack= 值 -- 检查 path_rules 或轮换设置 |
| 缺少声音文件 | [sound] 行显示 error= 和文件路径 |
| 通知缺失 | [notify] 行不存在 -- 检查配置中的 desktop_notifications |
配置键
| 键 | 默认值 | 说明 |
|---|---|---|
debug | false | 启用结构化调试日志 |
debug_retention_days | 7 | 自动清理超过 N 天的日志 |
日志存储在 ~/.claude/hooks/peon-ping/logs/peon-ping-YYYY-MM-DD.log(每天一个文件)。旧日志会在新一天的日志创建时根据 debug_retention_days 自动清理。
卸载
macOS/Linux:
bash "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/hooks/peon-ping/uninstall.sh # 全局
bash .claude/hooks/peon-ping/uninstall.sh # 项目本地
Windows (PowerShell):
# 标准卸载(删除声音前会提示)
powershell -File "$env:USERPROFILE\.claude\hooks\peon-ping\uninstall.ps1"
# 保留语音包(移除其他所有内容)
powershell -File "$env:USERPROFILE\.claude\hooks\peon-ping\uninstall.ps1" -KeepSounds
系统要求
- macOS —
afplay(内置),AppleScript 用于通知 - Linux — 以下之一:
pw-play、paplay、ffplay、mpv、play(SoX)或aplay;notify-send用于通知 - Windows — 原生 PowerShell 带
MediaPlayer和 WinForms(无需 WSL),或 WSL2 - MSYS2 / Git Bash —
python3、cygpath(内置);音频通过ffplay/mpv/play或 PowerShell 回退 - 所有平台 —
python3(原生 Windows 不需要) - SSH/远程 — 远程主机上需要
curl - IDE — 支持钩子的 Claude Code(或通过适配器的任何支持的 IDE)
工作原理
peon.sh 是一个为 SessionStart、SessionEnd、SubagentStart、UserPromptSubmit、Stop、Notification、PermissionRequest、PostToolUseFailure 和 PreCompact 事件注册的 Claude Code 钩子。在每个事件:
- 事件映射 — 嵌入的 Python 块将钩子事件映射到 CESP 声音分类(
session.start、task.complete、input.required等) - 声音选择 — 从活动语音包清单中随机选择一个语音,避免重复
- 音频播放 — 通过
afplay(macOS)、PowerShellMediaPlayer(WSL2/MSYS2 回退)或pw-play/paplay/ffplay/mpv/aplay(Linux/MSYS2)异步播放声音 - 通知 — 更新终端标签页标题,如果终端未获得焦点则发送桌面通知
- 远程路由 — 在 SSH 会话、devcontainers 和 Codespaces 中,音频和通知请求通过 HTTP 转发到本地机器上的中继服务器
语音包在安装时从 OpenPeon 注册表下载。官方语音包托管在 PeonPing/og-packs。声音文件归各自发行商(Blizzard、Valve、EA 等)所有,根据合理使用原则分发用于个人通知目的。
链接
- @peonping on X — 更新和公告
- peonping.com — 主页
- openpeon.com — CESP 规范、语音包浏览器、集成指南、创建指南
- OpenPeon 注册表 — 语音包注册表(GitHub Pages)
- og-packs — 官方语音包
- peon-pet — macOS 桌面宠物(兽人精灵,响应钩子事件)
- 许可证 (MIT)
支持项目
- Venmo: @garysheng
- 社区代币(DYOR / 仅供娱乐):有人在 Base 上创建了 $PEON 代币 — 我们接收交易手续费,帮助资助开发。
0xf4ba744229afb64e2571eef89aacec2f524e8ba3