🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

分因提示音 3332210/dsh-notify-cues

DeepSeek Harness
333221032 天前有提交已提供中文文档扫描:含敏感能力

按任务结束原因播放不同提示音,不再误报完成

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

该插件未发布到 npm,按作者文档从 GitHub 源安装即可(静态检查只覆盖 npm 路径,不代表插件不可用)。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add 3332210/dsh-notify-cues
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · other
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-notify-cues(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 17:40:09

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 9 处,展示前 9 条)
  • 读取本地文件
    lib/index.js:249
    return mergeConfig(DEFAULT_CONFIG, JSON.parse(readFileSync(configPath(), 'utf8')))
  • 写入本地文件
    lib/index.js:259
    mkdirSync(dirname(target), { recursive: true })
  • 写入本地文件
    lib/index.js:260
    writeFileSync(tmp, JSON.stringify(cfg, null, 2), 'utf8')
  • 写入本地文件
    lib/index.js:261
    renameSync(tmp, target)
  • 读取本地文件
    lib/index.js:363
    if (existsSync(candidate)) return candidate
  • 发起网络请求
    lib/client.js:50
    fetch(PRESENCE_URL, {
  • 发起网络请求
    lib/client.js:193
    fetch(CONFIG_URL, { cache: "no-store" })
  • 发起网络请求
    lib/client.js:204
    return fetch(CONFIG_URL, {
  • 发起网络请求
    lib/client.js:226
    fetch(TEST_URL + "?scene=" + encodeURIComponent(scene), { cache: "no-store" })
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 按结束原因区分提示音
  • 完成中断出错不同音
  • 避免误报完成

为 DeepSeek Harness 按原因区分 Windows 通知——完成、中断、出错各有不同提示音

README

由 DeepSeek 最新模型翻译生成
dsh-notify-cues 给 DeepSeek Harness 的 Windows 通知插件:按「这一轮为什么结束」区分提示音 —— 完成、被你中断、出错、额度耗尽各有各的声音,而不是把所有停止都报成「任务完成」。 纯 PowerShell 实现:不需要 .NET 桌面运行时,不需要任何音频素材文件,六种音色全部现场合成。 设置 → 通知 解决的问题 市面上给 DSH 做的 Windows 通知插件,判定「完成」用的都是 agent/status → idle。可这个条件在任务正常跑完时成立,在你按下停止时同样成立。所以你亲手中断一个任务,它会欢快地弹「任务完成」。 而真正的原因一直都记在会话日志里 —— DSH 自己写进去的: this.session.append("turn/end", { turn, reason: turnEnds }) reason.kind 来自 TurnEndReasonMap,被取消时还带一层嵌套原因: type TurnEndReason = 'completed' | 'aborted' | 'error' | 'max-tokens' | 'interrupted' | 'blocked' | 'forked'
展开完整文档(README 剩余 1 节)
dsh-notify-cues

给 DeepSeek Harness 的 Windows 通知插件:按「这一轮为什么结束」区分提示音 —— 完成、被你中断、出错、额度耗尽各有各的声音,而不是把所有停止都报成「任务完成」。

纯 PowerShell 实现:不需要 .NET 桌面运行时,不需要任何音频素材文件,六种音色全部现场合成。

设置 → 通知

解决的问题

市面上给 DSH 做的 Windows 通知插件,判定「完成」用的都是 agent/status → idle。可这个条件在任务正常跑完时成立,在你按下停止时同样成立。所以你亲手中断一个任务,它会欢快地弹「任务完成」。

而真正的原因一直都记在会话日志里 —— DSH 自己写进去的:

this.session.append("turn/end", { turn, reason: turnEnds })

reason.kind 来自 TurnEndReasonMap,被取消时还带一层嵌套原因:

type TurnEndReason = 'completed' | 'aborted' | 'error' | 'max-tokens'
| 'interrupted' | 'blocked' | 'forked'
type TurnEndCancelCause = AgentCancelCause | { kind: 'legacy' }
type AgentCancelCause = { kind: 'user' } | { kind: 'parent' }
| { kind: 'hook'; reason: string } | { kind: 'disposed' }

你按下停止就是 { kind: 'aborted', reason: { kind: 'user' } }。信息一直在,只是没人接。本插件把它接上了。

六种情形,六种提示音

| 情形 | 判据 | 默认音色 | 听感 |
| 任务完成 | completed | completed | D5→A5 上行双音 |
| 被中断 | aborted + reason.kind === 'user' | interrupted | A5→A4 下行短音 |
| 出错 | error | error | 低沉不谐和音 |
| 达到输出上限 | max-tokens | maxTokens | 三声急促高音 |
| 被阻止 | blocked,或 aborted + reason.kind === 'hook' | blocked | 平音双击 |
| 需要你操作 | approval/asked、ask_user_question | attention | E5-G5-B5 上行琶音 |

aborted 的另外两种原因 —— parent(父 agent 取消了子会话)和 disposed(会话销毁)—— 刻意静默,那是生命周期噪音,不是你的事。TurnEndReasonMap 官方标注为可被其它包扩展,所以遇到不认识的 kind 一律静默,而不是瞎猜一个音。

任务栏:QQ/微信那套行为

先闪几下抓注意力,然后停动画但让任务栏图标保持高亮,直到你切回来。

| flashAfter | 行为 |
| holdUntilFocused(默认) | 闪 3 次 → 保持高亮直到你点它 |
| stop | 闪 3 次就结束 |
| keepFlashing | 一直闪到你切回来 |

Windows 从不闪前台窗口,所以你已经盯着 DSH 时这一套都不会触发。

设置页

注册进 DSH 自己的设置对话框(通过官方 settings.section 插槽),不是自建弹窗:

分场景提示音

- 总开关 · 任务栏闪烁 · 系统通知弹窗 —— 三个独立开关
- 闪烁次数、节奏、以及闪完之后的行为
- 「正在看的那个会话跑完时不出声」—— 见下
- 音量
- 六种情形各自:开关 + 音效下拉 + ▶ 试听

每个改动即时落盘,不用改代码、不用重启。

「静默」指的是你正在看的那个会话,不是「页面在前台」

判据不是「只要页面在前台就全静默」。客户端会实时上报主视图正在显示哪个会话,宿主只在这个完成的会话就是你正在读的那一个时才静默:

| 你的状态 | 哪个会话跑完 | 结果 |
| 正在读会话 A | 会话 A | 安静 |
| 正在读会话 A | 会话 B | 提醒 |
| 在设置页里调配置 | 任意会话 | 提醒 |
| 切到别的程序 | 任意会话 | 提醒 |
| 提问 / 审批到达 | — | 始终提醒 |

漏掉一次提示音比多响一次更糟,所以上报链路是失效即放行:浏览器从没上报过,通知照常响。

安装

需要 Windows 10/11。

装进 profile

1. 把插件放进你的 profile $dest = Join-Path $env:USERPROFILE '.dsh\profiles\<profile>\node_modules\dsh-notify-cues' New-Item -ItemType Directory -Force -Path $dest | Out-Null Copy-Item package.json, cordis.patch.yml, lib -Destination $dest -Recurse -Force

2. 打印第 3 步要用的加载说明符 name 必须是 file:// URL:Cordis loader 把这个值交给裸 import(name),传文件系统路径会失败(ERR_UNSUPPORTED_ESM_URL_SCHEME)。
node -e "console.log(require('node:url').pathToFileURL(process.argv[1]).href)" "$dest\lib\index.js"
把下面这段追加到 ~/.dsh/profiles/<profile>/cordis.patch.yml,name 用上一步打印出来的 URL:

- insert:
- id: dsh-notify-cues
name: 'file:///.../node_modules/dsh-notify-cues/lib/index.js'
inject: ['subprocess', 'webServer']
config:
notifications: true

然后完整重启 DeepSeek Harness,打开 设置 → 通知。

本地开发挂载

如果你的 profile 不是桌面应用独占的,可以直接挂载 checkout 并享受热重载:

dsh --profile <profile> --patch /path/to/dev.patch.yml web

dev.patch.yml 里的 name 是 REPLACE/WITH 占位符,需要先填。被桌面应用独占的 profile 会被拒绝启动(profile "X" is managed exclusively by the Electron application),那种情况请走上面的安装方式。

配置

配置文件在 ~/.dsh/dsh-notify-cues.json,可以在设置页改,也可以手改。每次通知都重新读取,所以手改立刻生效。

| 字段 | 默认 | 含义 |
| notifications | true | 总开关:不出声、不弹通知、不闪任务栏 |
| flash | true | 任务栏闪烁 |
| flashCount | 3 | 开场闪几次 |
| flashTimeout | 500 | 每闪一下的间隔毫秒数 |
| flashAfter | holdUntilFocused | stop · holdUntilFocused · keepFlashing |
| toast | true | 系统通知弹窗 |
| volume | 1 | 提示音音量,0.1–1.0 |
| quietOnForeground | true | 只静默你正在读的那一个会话 |
| alwaysNotifyAttention | true | 提问与审批不受上面那条限制 |
| dedupMs | 1500 | 同情形去重窗口 |
| per.<情形>.enabled | true | 单个情形开关 |
| per.<情形>.toast | true | 单个情形是否弹通知 |
| per.<情形>.sound | 同情形名 | 音色名、ding、none,或 .wav 路径 |

情形键名:completed、interrupted、error、max-tokens、blocked、attention。

HTTP 接口

仅接受同源请求(校验 Sec-Fetch-Site,跨站返回 403)。

| 端点 | 方法 | 用途 |
| /dsh-notify-cues/config | GET/POST | 读取 / 局部更新配置 |
| /dsh-notify-cues/presence | GET/POST | 浏览器状态:{visible, focused, viewedSessionId} |
| /dsh-notify-cues/test?scene=<情形> | GET | 立刻发一条该情形的真实通知 |
| /dsh-notify-cues/keys | GET | 情形名与音色名清单 |

两个刻意的设计决定

去重按 (会话, 情形) 计时,不按会话。 早期实现用的是会话级窗口,测试立刻抓到一个真 bug —— 审批提示之后紧接着报错,错误通知会被 1.5 秒窗口吞掉,真实故障被静默。现在只有「同一情形的重复触发」会被压掉。

回答完问题后抑制紧随其后的「完成」音,但绝不影响出错和中断。 你回答提问后回合恢复,最终以 completed 结束;你刚点完就叮一声「完成」是纯噪音。但如果那一轮接下来报错或被中断,那是真新闻,照响。

测试

node test/run.mjs # 逻辑单测
node test/client-contract.mjs lib/client.js # 浏览器 bundle 契约
node test/manifest.mjs package.json # manifest 对已装 harness
node test/patch-shape.mjs cordis.patch.yml dev.patch.yml
node test/patch-loadable.mjs dev.patch.yml
node test/sim-append.mjs # profile 补丁仍合法

test/run.mjs 是自建的进程内 runner,不用 node --test:DSH 的文件沙箱禁止命名管道,而内置 runner 正是用管道 spawn 子进程的。

依赖本机 harness 安装(app.asar)的检查,在没有安装时会报 skipped 而不是失败。用 DSH_ASAR=/path/to/app.asar 可以指向别处的安装。

逻辑套件覆盖:情形映射(取消原因的全部五个成员)、门控规则、配置读写、参数构造,以及通过假 ctx 的端到端分发 —— 其中有若干条专门钉住「中断绝不能报成完成」。

已知限制

- 仅 Windows。 通知器调用 WinRT toast 和 FlashWindowEx。
- 第一次弹 toast 会注册 AppUserModelID。 非打包进程没有 package identity,Windows 会直接丢弃 toast(0x80073D54),必须先有 AUMID 注册表项和开始菜单快捷方式。插件会建一个专用的 DeepSeek Harness Notifications.lnk —— 刻意不叫 DeepSeek Harness.lnk,那个属于桌面客户端安装程序。
- 通知里不能直接作答。 ask_user_question 只弹普通 toast 加闪烁,回答仍在 DSH 界面里完成。那个交互式下拉菜单正是需要 .NET 的部分,本插件刻意避开。
- 任务栏「保持高亮」依赖 FLASHW_TIMERNOFG,这个标志不带动画。Windows 11 不再暴露旧的 WS_EX_FLASHING 位,所以这一点没法用程序断言,是在一台机器上肉眼确认的。如果你的机器上并不保持,改用 keepFlashing 或 stop。
- 开发针对 DSH 0.2.0-rc.2。同生态的一个更早的插件提到 0.1.0-rc.6 根本不发 turn/end,在那个版本上只有前台启发式规则能工作。

目录结构

dsh-notify-cues/
├── lib/
│ ├── index.js # 宿主:turn/end 判定、门控、配置与状态上报 API │ ├── client.js # 浏览器:设置分区 + 状态上报 │ └── notify.ps1 # 音色合成、WinRT toast、任务栏闪烁 ├── cordis.patch.yml # 作为包安装时的 bundle 补丁 ├── dev.patch.yml # 热重载挂载(需填 name 占位符) ├── docs/ │ ├── DSH-API-CONTRACTS.md # 已核实的 DSH 0.2.0-rc.2 插件契约 │ ├── assets/ # README 截图 │ ├── asar.cjs # 读取 app.asar 的辅助工具 │ └── probe-asar.mjs # 对 app.asar 的内存全文检索 └── test/ # 见「测试」

docs/DSH-API-CONTRACTS.md 是一份契约参考,逐条带行号引用,覆盖本插件依赖的每一个接口:session/event 回调签名、turn/end 完整类型树、插槽 API(哪种 kind 需要哪个必填项、inject 如何变成 props)、webServer 路由契约、宿主插件导出形态。想扩展这个插件时,比重新反查省事得多。

致谢

写这个插件之前读了同生态的两个插件,它们各自已经解决过本插件必须解决的一些问题:

- dsh-notify-win —— WinRT toast 的构造方式、AppUserModelID 自注册那一套(以及为什么快捷方式名字不能和安装程序的撞车)、EnumWindows + FlashWindowEx 的用法。
- aokamoaki/dsh-notify —— 分场景音型的设计,以及「需要你操作」必须绕过前台静默这个判断。

两者都不是依赖,也没有复制代码;是作为先行者参考了源码与文档。

许可

MIT,见 LICENSE。
预览分享卡片长什么样 ↓3332210/dsh-notify-cues
分享 · DeepSeek Harness Hub
3332210/dsh-notify-cues

按任务结束原因播放不同提示音,不再误报完成

这是你的仓库?认领条目

回到顶部