Codex声音提醒配置日志

By Dean

背景

今天希望让 Codex 在两类场景里播放声音提醒,而不是只发文字消息:

  • 任务完成、准备回复最终结果时
  • 需要用户手动授权、登录、确认或执行外部操作时

最开始直接尝试过 afplaysayafplay /System/Library/Sounds/Glass.aiff 返回 AudioQueueStart failed (-66680),说明当前沙箱环境无法直接启动音频队列。后来在沙箱外授权执行 say 后,声音可以正常播放,因此最终选择使用 macOS 自带的 say 命令作为提醒方式。

全局授权

Codex 的全局规则文件是:

/Users/ira/.codex/rules/default.rules

其中已经包含:

prefix_rule(pattern=["say"], decision="allow")

这表示之后 Codex 可以直接执行下面的提醒命令,不用每次都重新请求命令执行权限:

say "任务完成了"
say "需要你授权"

为什么不用 Skill

一开始考虑过创建一个 skill,但后来确认 skill 不适合这个需求。skill 只有在任务语义触发时才会被加载,而“任务完成时提醒我”和“需要授权时提醒我”是跨所有会话的全局行为,不是某一类具体任务。

如果新会话没有触发这个 skill,就无法保证声音提醒规则生效。更合适的方式是使用 Codex 的全局 hooks。

参考思路

参考文章:Self-updating agent skills

这篇文章的思路是:把需要跨会话稳定执行的行为放到 agent 或 host 生命周期机制里,而不是依赖模型在上下文里“记得”。结合当前 Codex CLI 的功能检查,确认当前版本中 hooks stable true,因此采用 ~/.codex/hooks.json

声音提醒脚本

创建脚本:

/Users/ira/.codex/hooks/sound-notify/notify.sh

内容:

#!/usr/bin/env bash
set -euo pipefail

message="${1:-Codex needs your attention}"
/usr/bin/say "$message"

并添加可执行权限:

chmod +x /Users/ira/.codex/hooks/sound-notify/notify.sh

Hooks 配置

创建或更新:

/Users/ira/.codex/hooks.json

内容:

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "/Users/ira/.codex/hooks/sound-notify/notify.sh \"Codex needs your approval\"",
            "timeout": 10
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/Users/ira/.codex/hooks/sound-notify/notify.sh \"Codex task complete\"",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

PermissionRequest 用于需要用户授权时播放 Codex needs your approvalStop 用于 Codex 停止本轮工作、准备返回结果时播放 Codex task complete

验证

验证 JSON 格式:

jq . /Users/ira/.codex/hooks.json

验证脚本可以独立播放声音:

/Users/ira/.codex/hooks/sound-notify/notify.sh "Codex sound hook test"

额外验证:

say "配置完成了"

声音可以正常播放。

注意事项

  • 新会话通常会读取 ~/.codex/hooks.json
  • 如果旧会话没有立即生效,重开会话或重启 Codex app 后再试。
  • Stop 事件可能会在每轮回复结束时触发,不只是在长任务完全结束时触发。
  • PermissionRequest 是否在所有授权场景都触发,取决于当前 Codex 版本的 hook 事件实现。

当前结论

使用全局 hooks 比 skill 更适合这个需求。目前配置目标是:所有会话任务完成时自动发声提醒,所有会话需要用户授权时自动发声提醒,并使用已验证可播放的 macOS say 命令。