dsh-notify-desktop
Windows native toast notifications for DSH desktop sessions: turn ends, approvals, questions and a reminder for an unanswered wait — each with its own sound and popup text (up to three named templates per situation), three delivery modes, previews, and imported custom sounds. Clicking a toast raises
Install
dsh plugin --profile web add dsh-notify-desktop
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-notify-desktop
 · [English](README.md) · 中文
给 DSH 桌面端 加 Windows 原生通知:会话跑完、出错、或停下来等你确认时弹一条系统通知,并播放为这种情况挑好的音效、
显示为这种情况写好的文字;点通知把 DSH 窗口拉回前台。
<img src="https://raw.githubusercontent.com/paleech0/dsh-notify-desktop/main/docs/images/settings-zh.png" width="620" alt="卡一「桌面通知」:右上角语言切换、总开关、发送测试通知与通知形式">
0.2.3 更新
- 没装 ffmpeg 不再一头雾水:导入非
.wav音效而本机没有ffmpeg时,设置页「自定义音效」里会出现黄色提示,
说明原因和安装方法;点「预览效果」也会直接告诉你,而不是静默无声。装好 ffmpeg 回到设置页即可生效,不用重启。
- 兼容性:在 DSH 桌面端 0.2.2-rc.1 实测通过(插件加载、会话投影、宿主 Toast、诊断与文本模板路由);
声明范围不变(>=0.2.0-rc.2 <0.3.0-0)。
它能给你什么
- 该提醒时提醒 —— 回合结束(正常完成 / 出错 / 被中止 / 被阻塞 / Token 上限)、等待审批、等待回答、计划评审,
以及等待过久时的一条催办。
- 你在看就不吵 —— DSH 窗口有焦点时一律不弹;同一件事只弹一次(3 秒去重)。
- 每种情况一套音效和文字 —— 九个情况(五个结束原因、三种等待、一个催办)各自挑音效、各自选弹窗文本;
每个情况可以保存最多 3 套自定义文本,每行都能先点「预览效果」看/听。
- 中英双语 —— 插件界面和弹窗文本可以单独切到中文或 English,也可以跟随 DSH 的界面语言。
- 通知形式三选一 —— 通知 + 提示音 / 仅通知(静音弹窗)/ 仅提示音(只出声,不弹窗)。
- 可以用自己的音效和文字 —— 音效来源三类:Windows 音效、随插件发布的作者音效([sounds/](sounds/))、你导入的文件;
文字支持名称、标题、正文和占位符,保存在本机 JSON 里,改名/删除都走二次确认。
- 不会一直响 —— 文件类音效最长 8 秒;关掉总开关、切到「仅通知」、或切回 DSH 窗口,正在响的立刻停。
- 点击回前台 —— 通知只把窗口拉回前台,刻意不跳转会话(更可预测)。
环境要求:Windows + DSH 桌面端(profile desktop),运行时 0.2.x。ffmpeg 可选(仅用于把非 .wav 的自定义音效转码),
放在 PATH 里即可。
安装
从 npm 安装
& "<DSH 桌面端安装目录>\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add dsh-notify-desktop
然后重启 DSH 桌面端,打开 设置 → 通知(窗口有焦点时按 Ctrl+,)。
从本地仓库安装
1. 把本仓库 clone 到一个固定目录(profile 以链接方式指向它,之后别挪动)。
2. 用桌面端自带 CLI 注册:
& "<DSH 桌面端安装目录>\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add "link:<本仓库路径>"
3. 重启 DSH 桌面端,然后打开 设置 → 通知(窗口有焦点时按 Ctrl+,)。
设置项
设置页的「通知」段现在共三张卡。偏好存在渲染层 localStorage,文字和音效文件存在本机磁盘,改完立即生效。
卡一「桌面通知」—— 要不要发、怎么发:
控件 · 作用
启用通知 · 总开关;关掉后不再弹窗也不出声。交付相关的控件全部变灰(已选内容保留):通知形式、各情况的音效/文本选择、预览、催办分钟数、下面的情况开关;只有「自定义音效」「自定义文本」仍可编辑
发送测试通知 · 就在总开关下方;固定用默认音效(Windows 通知)+ 弹窗,不受通知形式和下面任何设置影响,用于检测配置是否正常
通知形式 · 三选一:通知 + 提示音(默认)/ 仅通知(只弹窗)/ 仅提示音(只出声,不弹窗)
语言 · 卡片右上角:自动(跟随 DSH 的语言)/ 中文 / English。切换只改插件自己的界面文案与弹窗文本,DSH 其余界面不受影响
<img src="https://raw.githubusercontent.com/paleech0/dsh-notify-desktop/main/docs/images/settings-zh.png" width="620" alt="卡一「桌面通知」:右上角语言切换、总开关、发送测试通知与通知形式">
点「发送测试通知」弹出的系统通知长这样:
<img src="https://raw.githubusercontent.com/paleech0/dsh-notify-desktop/main/docs/images/toast-zh.png" width="460" alt="测试通知:DeepSeek Harness · 测试通知 · 看到这条通知,说明弹窗与默认提示音均正常">
卡二「选择接收以下哪种情况的通知」—— 哪些情况要提醒:
分组 · 开关
会话结束 · 正常完成 / 出错 / 被中止 / 被阻塞 / 达到 Token 上限(每行附一句例子)
等待你确认 · 等待审批 / 等待回答 / 等待计划评审(每行附一句例子)
<img src="https://raw.githubusercontent.com/paleech0/dsh-notify-desktop/main/docs/images/settings-situations-zh.png" width="620" alt="卡二「选择接收以下哪种情况的通知」:会话结束与等待你确认两组开关">
卡三「通知自定义」—— 每个情况的声音和文字:
控件 · 作用
情况行 · 只列出你在卡二勾选的情况(勾选变化实时增减)。每行 = 情况名 + 音效选择器 + 文本选择器 + 「预览效果」
预览效果 · 用该情况当前选中的文本(默认文本按示例值渲染)和音效,按当前通知形式弹/响
音效选择器 · 两级:先选来源(Windows / 作者 / 自定义),再选具体音效
文本选择器 · 两级:默认(内置文案)或自定义(该情况保存的文本,按名称列出)
自定义音效(可收起) · 添加 / 列出 / 删除你的音效文件;「转换缓存」占用与清理也在里面
自定义文本(可收起) · 按情况管理已保存文本:每个情况最多 3 套,每套有名称、标题、正文,带「编辑」和红色「删除」(删除有二次确认)
勾选情况后,下面的「通知自定义」会实时出现对应行;取消勾选只是隐藏,已配的音效和文本都保留,重新勾选回来还在。
<img src="https://raw.githubusercontent.com/paleech0/dsh-notify-desktop/main/docs/images/settings-customize-zh.png" width="620" alt="卡三「通知自定义」:每个情况的音效、文本、预览与两个折叠库">
音效
三个分区。 每个音效选择器都是两级:先选来源,再选该来源下的具体音效。
- Windows 音效 —— 内置 20 个:5 个通知事件 + 系统媒体库(
chimes、ding、tada、Windows Error、
Critical Stop、Alarm0x、Ring0x 等)。
- 作者音效 —— 本仓库 [
sounds/](sounds/) 里的 4 个.wav。往那个文件夹再丢文件就等于加音效,不用改代码。 - 自定义音效 —— 你自己导入的。
用自己的文件。 点「添加音效…」会把文件复制到 %LOCALAPPDATA%\dsh-notify\custom,所以原文件之后移动或删除都不影响。
支持 .wav、.mp3、.m4a、.aac、.wma、.flac、.ogg、.opus。删除自定义音效会先弹行内确认。
其他格式要先装 ffmpeg。 插件用 Windows 的 SoundPlayer 发音,它只认 wav;mp3、m4a、flac 这些格式得先用
ffmpeg 转成 wav 才能播。没装也不会坏:.wav 和随插件发布的音效照常可用,其他格式保持静音,设置页「自定义音效」
里会出现一行黄色提示,写清楚缺什么、怎么装。
装法任选一种(Win10/11 自带 winget,最省事):
winget install Gyan.FFmpeg # 推荐 choco install ffmpeg # 已装 Chocolatey scoop install ffmpeg # 已装 Scoop
也可以从 ffmpeg.org 或 gyan.dev 下载构建包,
把里面的 ffmpeg.exe 放进任意一个 PATH 目录。装好后回到设置页就能用,不用重启 DSH。
转码只在该格式第一次播放时发生,实测 5 秒~5 分钟的音频都是 0.1~0.3 秒,之后的播放直接用缓存。缓存是未压缩的 wav,
体积约 10 MB/分钟,所以建议用短音效;占用的空间在设置页「自定义音效 → 转换缓存」里可以看到并一键清理(只删缓存,不动音效本体)。
声音什么时候停。 .wav 直接播放;其他格式首次播放时用 PATH 上的 ffmpeg 转码一次,占用计入「自定义音效」里的
「转换缓存」(在那里查看与清理)。文件类音效最长 8 秒;总开关关掉、切到「仅通知」,或窗口重获焦点时,正在响的立刻停。
没有 ffmpeg 时,wav 与随插件发布的音效照常可用,诊断接口会显示 media.ffmpeg: null。
为什么需要自定义音效。 Toast 只能引用 5 个 ms-winsoundevent 值,而在 Windows 11 上它们只对应 4 个彼此很像的
「叮」—— Notification.IM 与 Notification.SMS 甚至是同一个文件。想让不同情况真的听得出差别,只能由宿主自己播放音频。
弹窗文本
每个情况一套文字。 真实通知的标题和正文来自该情况当前选中的文本:
- 默认文本 —— 内置的
{工作区} · {状态}/{内容},不需要配置。 - 自定义文本 —— 在该情况行里选择,或在卡三的「自定义文本」里新建/编辑。每个情况最多保存 3 套。
编辑器。 名称(最多 24 字)、标题(120 字)、正文(300 字);占位符 {工作区} {状态} {内容} {分钟}
可点击插入,编辑器里会实时渲染一行预览。长度上限与 Windows Toast 的截断一致。
测试与预览。 卡一的「发送测试通知」永远是固定文案 + 系统默认音效;卡三的「预览效果」才用该情况真正的文本和音效
(跟随当前通知形式)。默认文本的 {内容} 为空时整条正文回退到该情况的内置提示句。
存在哪里。 文本内容保存在 %LOCALAPPDATA%\dsh-notify\templates\templates.json(和自定义音效同一个 dsh-notify 目录),
按情况分组、每个情况最多 3 套;写入走临时文件 + rename,损坏时按空库处理不会崩。设置里只存"当前用哪一套"的 id;
模板被删掉时该情况自动回退默认文本。手动编辑这个文件后需要重启桌面端(客户端启动时加载一次)。
兼容性
实测版本 · DSH 桌面端 0.2.2-rc.1:插件加载、会话投影、宿主 Toast、诊断与文本模板路由,以及设置页的中英切换实测通过([证据](docs/acceptance/2026-11-06-bilingual-ui.md));更早的 0.2.1-rc.5(Toast 身份自适应)与 rc.3 / rc.2 / 0.2.0-rc.2 记录见 docs/acceptance/
声明范围 · >=0.2.0-rc.2 <0.3.0-0(semver 加载闸门)—— 表示加载器会放行从 0.2.0-rc.2 起的整条 0.2 线(含预发布);**只有上表实测版本经过验证,范围
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::7,最后更新 2026-11-06