🔔 DSH 主动通知插件(proactive-notify)
一个运行在 DeepSeek Harness(DSH)Web GUI 上的永久组合插件:
当 Agent 遇到权限问题(工具等待审批 / 被沙箱或审批拒绝)或完成任务(每轮处理结束)时,通过浏览器系统通知(Notification API)主动提醒你——即使你在其他网页、其他软件中,也能看到通知弹窗,并自带系统通知音效。
✨ 功能
| 场景 | 通知内容 |
|---|---|
| 工具需要用户审批 | ⚠️ 需要审批:工具「××」正在等待你的授权 |
| 工具被沙箱/审批/权限规则拒绝 | ⚠️ 权限问题:工具「××」执行被拒绝 — 原因 |
| 任务完成(Agent 转为 idle) | ✅ 任务完成:本轮处理已结束 |
- 跨应用可见:通过浏览器 Notification API 弹出系统级通知(Windows 上显示在通知中心,覆盖任何软件)
- 自带系统音效:使用 Windows 系统通知声音,无需额外配置
- 零页面打扰:页面内不显示任何 UI,纯系统级提醒
- 启动即授权:插件加载时自动引导用户授权通知权限
- 永久加载:一次安装,随 DSH 启动自动生效,无需重复安装
📋 前置条件
- DSH Web GUI(组合插件,随 DSH 进程永久加载)
- pnpm(
dsh plugin命令通过它安装插件,装一次即可) - 浏览器:Chrome / Edge(推荐)或 Firefox
- ⚠️ DSH 标签页必须保持打开(后台运行即可),关闭标签页后收不到通知
🚀 安装
一条命令,直接从本 GitHub 仓库安装:
dsh plugin --profile web add "github:DemoJ/proactive-notify#main"
然后重启 DSH(重新运行 dsh web)即可生效。无需手动复制文件、编辑任何配置。
原理:本包在
package.json中声明了"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }。dsh plugin add会用 pnpm 把 GitHub 仓库克隆、打包进 profile 的node_modules,检测到 bundle 声明后自动把它追加到 profile 的dsh.profile.bundles组合层列表;下次启动时组合器自动应用包内的cordis.patch.yml。本插件是纯 JS、无构建步骤的包,安装时不执行任何构建脚本,不会触发 pnpm 的「允许构建」确认 (TS 等需要
prepare构建的插件才会遇到那一步)。
更新
GitHub 方式没有 npm 版本号,「最新版」就是 #main 指向的最新提交。更新到最新:
dsh plugin --profile web update proactive-notify
pnpm 会重新从 main 分支拉取并替换已安装的包,之后重启 dsh web 生效。
若 update 后内容没有变化(可能命中 pnpm 的 git 解析缓存),卸载重装一次即可强制刷新:
dsh plugin --profile web remove proactive-notify
dsh plugin --profile web add "github:DemoJ/proactive-notify#main"
卸载
dsh plugin --profile web remove proactive-notify
卸载后重启 dsh web;bundle 随依赖一起移除,profile 组合层列表会自动同步。
锁定版本(可选)
#main 表示始终跟随 main 分支最新提交。也可以按标签或提交 hash 固定在某个状态:
dsh plugin --profile web add "github:DemoJ/proactive-notify#v1.0.0" # 按标签(需先 git tag 并推送)
dsh plugin --profile web add "github:DemoJ/proactive-notify#11bf8dc" # 按提交 hash
从本地源码安装(开发调试)
改代码后想立刻在本机验证,不用先推 GitHub。在本仓库的上级目录执行(相对路径会锚定到你执行命令时所在的目录):
dsh plugin --profile web add ./proactive-notify
📦 发版方式(维护者)
不需要发布 npm——提交并推送到 GitHub 就等于发版:
git add -A
git commit -m "feat: ..."
git push origin main
已安装的用户随后执行 dsh plugin --profile web update proactive-notify 即可拿到新版。
建议每次顺手递增 package.json 的 version 字段(或直接用 npm version patch,它会自动改号并打 tag),方便用户核对自己装的版本。
🎯 使用
- 首次启动:DSH 启动后,插件会自动弹出确认框请求浏览器通知权限
- 点击"好的,请求权限",浏览器会弹出权限请求,点击 允许
- 之后遇到权限问题或任务完成时,会自动弹出系统通知
⚠️ 注意事项
- 若误点了「拒绝」,请到地址栏左侧站点设置 → 通知 → 允许,刷新页面后插件会重新请求权限
- 系统通知未授权时不会有任何提醒(页面内也没有提示),这是有意为之
- DSH 标签页必须保持打开(后台可用,关闭则收不到通知)
🔧 工作原理
Host 半区(Node 进程内,index.js):
- 监听
tools/result:工具执行失败且错误包含sandbox/permission/denied等关键词 → 推送「权限问题」通知 - 监听
approval/request:工具正在等待用户审批 → 推送「需要审批」通知 - 监听
agent/status:Agent 状态变为idle(本轮处理结束)→ 推送「任务完成」通知 - 通过
webServer服务注册 HTTP 路由GET /api/notify/queue,供 Client 轮询取走通知队列 - 通过
userQuestions服务在插件加载时引导用户授权通知权限
Client 半区(浏览器页面内,client.js):
- 每秒轮询一次
GET /api/notify/queue拉取通知队列 - 调用浏览器
NotificationAPI 弹出系统通知(跨应用可见,自带系统音效) - 收到
permission-request类型时,调用Notification.requestPermission()请求浏览器权限
为什么用 HTTP 轮询而不是动态插件的 harness.handle/host.call?
组合插件没有动态插件的 Package-private RPC 通道,因此改用 webServer 注册 HTTP 路由 + Client fetch() 轮询的方式通信。
📁 文件说明
| 文件 | 说明 |
|---|---|
package.json |
包声明(dsh.bundle 声明 bundle patch 层,dsh.client 标记 Client 半区,exports 声明入口) |
cordis.patch.yml |
bundle patch 层:安装时自动把插件行插入 profile 组合树 |
index.js |
Host 半区:事件监听、通知队列、HTTP 路由、权限引导 |
client.js |
Client 半区:系统通知、队列轮询、权限请求 |
README.md |
本文档 |
LICENSE |
MIT 开源许可 |
📄 License
MIT
No comments yet. Be the first to write one.