# dsh-alert-sound — Roadmap / 功能计划书 > **核心定位**:让用户在**不盯着 dsh 画面**(在干别的事、切走窗口、全屏等)时,也能通过**声音 / 语音**及时知道 dsh 需要自己——尤其是不想工作被“卡住”。因此本插件的差异化是 **“免注视的声音/语音提醒”**,而非单纯“完成提示音”。 ## 现状 - 5 类提醒:需要审批 / 需要回答 / 输出完成 / 发生错误 + **「卡住」**(实验性,需先开「停滞检测」)。 - 每类:独立启停 + 音色(叮咚/低沉/轻点/警醒/语音/自定义/静音)+ 音量(0–200%)+ 试听。 - 可选**语音朗读**(中/英文随界面语言);**语音失败自动改播提示音**,不会静音。 - **「朗读输出」的语义**:开启后「输出完成」会念出最后一条助手回复(上限 400 字);关闭时只念类型名。**审批 / 提问不受该开关影响**(详情始终会念)。 - 默认对所有会话提醒(可切成「仅当前会话」);后台标签页也能响。 - 其余开关:重复提醒、系统通知、停滞检测、悬浮提示、语音语速、勿扰时段、自定义音色、界面语言、恢复默认设置。 - 设置页在 **侧栏 → 提醒音**;设置存 localStorage(`dsh-alert-sound.v1`,自定义音色 `dsh-alert-sound.custom.v1`)。 - **(main 上已就绪、未发布)UI 改造**:设置页与悬浮提示改用宿主 `ui-primitives`(`Switch` / `Button` / `Toast`)与 `--dsw-*` 主题变量,深浅色 / 高对比主题自动跟随;悬浮提示改为**顶部宿主 Toast**(滑入 + 固定 1 秒淡出,总 3.6 秒);宿主缺该模块时回退为原生控件 + 底部自绘横幅。 ## 已实现(A–I) - **A 播报具体内容**:审批念工具名 + 原因,提问念问题原文,错误念原因;「完成」的正文另需「朗读输出」。 - **B 重复提醒**:审批 / 提问按可配间隔(关 / 10 / 20 / 30 秒)重复到处理为止;错误重复 3 次。 - **C 系统通知**:浏览器 Notification,标签页在后台也会弹。 - **D 朗读输出**:浏览器 `speechSynthesis`;朗读没起来时自动改播该类提示音,保证一定有声音。 - **E 停滞检测**(实验性、默认关):目前按会话 `updatedAt` 判定,**会误报**(见「E+」)。 - **F 自定义音色**:上传音频转 data URL 存 localStorage;每类上限 2MB,**超出配额时写入失败会被静默吞掉**,刷新后该音色消失。 - **G 语速 / 勿扰**:慢 / 标准 / 快;勿扰时段按整点,期间完全不响。 - **H i18n**:界面与语音 zh/en,跟随「界面语言」设置。 - **I 悬浮提示**:默认关(audio-first);现在渲染为宿主 Toast。 ## 未排期 ### K. 语音更自然 / 换声音 - **问题**:浏览器 `speechSynthesis` 只能按语言选,不能选具体音色,中文偏机械。 - **轻(推荐先做)**:`getVoices()` 选音色 + 音调 pitch;纯客户端、成本低。 - **❌ 中方案(Edge TTS)已否决(2026-10-06)**:外部贡献者照它做了一份完整实现([PR #1](https://github.com/Machine-126/dsh-alert-sound/pull/1)),评审后未合并,三条理由: 1. **职责边界** —— 本插件的差异化是"免注视的提醒声音";TTS 引擎选择、音色管理、预取缓存、内部协议维护是另一件事,生态已有专门的 `dsh-plugin-tts`。 2. **隐私承诺** —— 插件与 `SECURITY.md` 都写着"不发起任何网络请求";默认走 Edge 即推翻它。 3. **维护面** —— `Sec-MS-GEC` / UA 版本等是跟着 `edge-tts` 对齐的**未公开内部协议**,上游随时可改,会**无声失灵**。 - **重(不建议放插件)**:本地嗓音克隆需装本地模型,超出浏览器插件范畴。 - **另通路(零开发)**:预录"你的嗓音/角色音"短音频,走**自定义音色**(每次固定句,读不了动态详情)。 ### L. 朗读"挑内容",去掉 markdown 符号 - **问题**:现在把 `assistant-step` 的 text 块原样拼接,`#`、代码、表格、链接、emoji 都会被念出来。 - **轻(推荐先做)**:**去 markdown 符号 + 规则式挑重点**(跳过代码块与元信息,优先读结尾结论);纯客户端、离线、立即见效。 - **中(可选,后期)**:让模型生成一句高信息量摘要再读。 ### E+. 停滞检测换判定信号 - **问题**:现在只看会话的 `updatedAt`,用户在后台 / 离开时会被误判成"卡住",因此只能默认关闭。 - **参考**:社区的 [dsh-stall-guard](https://dshfind.com/zh/plugins/akira399/dsh-stall-guard) 用"**无活动事件 + 无在飞操作**"判定真卡死(`in-flight operations are exempt`),正好补上缺的那半个信号。 - **做法**:改为观察事件流(有没有新事件、有没有 running 的工具调用),而不是只比时间戳;先在真实卡住场景验证,再考虑默认开启。 ## 下一步 按"改动小、收益直接"排序: 1. **K 的轻方案**:加音色选择 + 音调调节(纯客户端)。 2. **L 的轻方案**:朗读前去掉 markdown 符号、跳过代码块。 3. **E+ 的判定改进**:借鉴 stall-guard 的信号,把误报压下去。