Passer au contenu principal
Z

dsh-approval-voice

ziye1208/dsh-approval-voice

Joue un carillon et une alerte vocale en chinois lorsqu'une fenêtre d'approbation, de question ou de revue de plan apparaît dans l'interface web DSH, pour ne jamais manquer une demande.

Installer

dsh plugin --profile web add github:ziye1208/dsh-approval-voice

README

dsh-approval-voice(审批语音提示)

DSH Web GUI 插件:当需要你审批或回答的弹窗(沙箱权限升级审批、ask_user_question 提问、计划审批等)出现时,自动播放提示音并用语音播报,避免漏看。

工作原理

插件有两条检测路径,两条路径统一使用会话作用域的事件标识 (session:<sessionId>:<kind>:<key>),因此不会重复提醒:

  1. 全局待处理交互源(首选):订阅 DSH 客户端的全局待处理交互快照,按 Map<sessionId, {kind, key}> 感知所有会话的 approval / question / plan-review —— 包括没有开在任何标签页里的会话。两种客户端核心形状都支持(resolveGlobalSource() 自动适配):
    • 网页版 dsh 0.1.5-rc.3:ctx.uiSession.pendingInteractions (即侧边栏「等待审批」所用的 root hook sessionPendingInteraction);
    • 桌面端 dsh-desktop 0.2.0-rc.2:没有 pendingInteractions,改用 ctx.uiSession.sessionStatus(Map<sessionId, {running, pendingInteraction, completionUnread}>, 取其中的 pendingInteraction),这正是桌面端侧边栏「等待审批」用的源。
  2. DOM 标记(兜底):仅在两个源都取不到时(更老的 DSH)才使用,监听当前视图渲染出来的卡片:
标记对应界面
data-approval-key沙箱权限升级等审批(ApprovalPanel)
data-question-key提问 / 选择题(QuestionComposer)
data-plan-review-key计划审批(PlanReviewPanel)

命中时按配置播放升调提示音(Web Audio,C5-E5-G5)和/或语音播报(SpeechSynthesis,中文语音)。每个请求只提醒一次。

安装

方式一:npm(推荐,已发布到 npmjs)

dsh plugin --profile web add dsh-approval-voice

方式二:GitHub(备选)

dsh plugin --profile web add github:ZIye1208/dsh-approval-voice

安装后重启 dsh web 服务,刷新页面即可生效。

本地开发安装(改代码即时生效):

dsh plugin --profile web add link:C:\path\to\dsh-approval-voice

使用

  • 默认开启「提示音 + 语音播报」,且默认对所有会话提醒(多会话 / 单页签切换会话 / 多标签页都能听到任何会话的审批、提问、计划审批)。
  • 设置入口:设置 → 常规 → 审批语音提示,可配置:
    • 总开关;
    • 提醒方式:仅提示音 / 仅语音播报 / 提示音 + 语音播报;
    • 音量;
    • 提醒范围:所有会话(默认,覆盖所有会话,含没开在任何标签页里的会话)或 仅当前会话(只在当前标签页响应本页显示的会话);
    • 提示音文件:选择本地音频文件(mp3/wav/ogg 等,≤2MB)替换内置提示音;点「恢复默认」回到内置提示音。超限或保存失败时面板会直接报错,不会"看着像存住了"。
  • 试听按钮:按当前设置播放一次(含自定义提示音)。
  • 控制台调试:window.__approvalVoice.get() / set({...}) / test() / pending() / global() / alertedCount() / soundBytes() / currentSessionId() / tabId。 set({...}) 返回 { ok, error, config }:ok:false 表示没存住(已回滚内存配置),别忽略它。
  • 配置保存在浏览器 localStorage(键 dsh.approvalVoice.v1),同一浏览器所有标签页共享。

多会话提醒原理

DSH Web GUI 里每个会话可能是一个独立标签页,也可能只是同一页签侧边栏里的一条。插件按以下方式让任一会话的审批都能被听到:

  • 每个页签订阅 DSH 客户端的全局待处理交互源(网页版 ctx.uiSession.pendingInteractions、 桌面端 ctx.uiSession.sessionStatus),因此任何会话(哪怕没开在任何页签里、只在侧边栏显示 「等待审批」)出现审批 / 提问 / 计划审批时,每个页签都会感知到;两个源都取不到时才退回监听本页 DOM 里的卡片。
  • 事件标识是会话作用域的(session:<sessionId>:<kind>:<key>),配合 BroadcastChannel (并写入 localStorage 作为兜底)在全浏览器内一次提醒只响一次:优先由当前聚焦的标签页 播放(声音最可靠),若没有任何聚焦标签页,则由最先到时的后台标签页兜底播放。
  • 若抢到播放权的页签实际没能出声(浏览器拒绝自动播放且音频未解锁),它会释放 claim 并广播 bell-failed,请已解锁音频的其它页签补响一次。
  • 仅当前会话 模式不广播,只在本地为本页正在显示的那个会话出声。

注意事项

  • 语音播报依赖系统安装的中文 TTS 语音;找不到中文语音时自动退化为仅提示音(避免用英文语音念中文)。
  • 浏览器自动播放策略:首次点击/按键后音频才解锁;设置在自定义提示音且未起播时会自动回退内置提示音, 并把失败原因打到 console.warn(不再静默无声)。
  • 自定义提示音以 data URL 存入 localStorage(≤2MB 二进制,编码成 base64 后约 1.33 倍), 请选择短促音频;跨标签页共享。提示音单独占一个 key,不跟开关/音量挤在一起 —— 这样拖动音量滑块不会每次都重写几 MB 的数据。老版本留下的提示音会在首次启动时自动搬过去。
  • 保存失败不会静默:浏览器存储配额不足(数据 URL 太大、或同源其它插件把 localStorage 占满)时, 面板会显示红色错误行、失败原因写进 console.warn,并且配置回滚到上一个值 —— 绝不会出现"面板显示已自定义、刷新后提示音消失"。遇到这种提示就换更短的音频(建议 1MB 以内), 或清理浏览器数据后重试。
  • 若所有 DSH 标签页都在后台且使用「仅语音播报」,浏览器可能限制后台标签页的语音合成(提示音不受影响)。
  • 卸载:dsh plugin --profile web remove dsh-approval-voice,重启服务即可。

文件结构

dsh-approval-voice/
├── package.json            # dsh.bundle + dsh.client 声明(免构建)
├── cordis.patch.yml        # 插件名册插入行
├── lib/index.js            # 宿主侧空插件(浏览器专用插件无需宿主行为)
├── lib/client.js           # 浏览器端实现(模块加载器格式,纯 JS)
├── test-global-scope.mjs   # 回归测试:直接加载真实 lib/client.js 的假浏览器测试
└── test-cross-tab.mjs      # 旧版跨标签页协调逻辑复刻测试

Plugins associés