dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Universal notification plugin for DeepSeek Harness: in-app toasts, native Windows toasts, one-click approval from the action center
DeepSeek Harness 通用通知插件 — 新会话 / 待审批 / 任务完成 / 任务中断,一个都不错过。
| 🔔 应用内通知 焦点在 DSH 时,右上角弹出 Telegram 风格 Toast 并播放提示音 | 🪟 Windows 原生通知 焦点离开 DSH 时,由系统通知中心弹出并发出提示音(PowerShell + WinRT,无需管理员) | 🍎 macOS 原生通知 焦点离开 DSH 时,由 macOS 通知中心弹出(osascript,零依赖) |
| 🎛️ 设置面板 Web UI 设置 → 通知:总开关、通道开关、场景开关 | 📋 通知日志 记录内容 + 本地时区时间(如 GMT+8),最多 100 条 | 🚀 重启不刷屏 首次加载仅播种基线,历史状态不会重复补通知 |
| 🤖 子代理静音 子代理会话不产生「新会话」「任务完成」通知,fan-out 工作流不会刷屏 | 📉 任务订阅有界 只订阅可能还有任务在跑的会话,不给全部历史会话开流 | ⚖️ 按需降级 可选服务缺失时只关掉对应功能,插件本身永远能加载 |
原生通知只负责提醒,不做点击回调 / 一键审批 / 带回前台(已移除 wscript + VBS 激活链路,避免被 360 等安全软件误报为木马)。待审批请回到 DSH 界面,在应用内通知或审批面板中处理。
# 在项目目录下打包
pnpm pack --pack-destination ..
# 安装到 DSH profile(新版桌面端是 desktop,旧版 Web 是 web)
dsh plugin --profile desktop add having5548-dsh-notify-0.6.0.tgz
安装完成后重启 DSH Web GUI 生效(重启会中断当前会话,请先保存手头任务)。
| 场景 | 触发方式 | 通知内容 |
|---|---|---|
| 新会话 | 会话列表出现非空会话 / 空白会话发出首条消息(子代理会话除外) | DSH-<项目名> · 新会话已创建 |
| 待审批 | ctx.uiSession.sessionStatus 里该会话的 pendingInteraction.kind === 'approval' | 应用内通知含 批准 / 拒绝 按钮 |
| 待回答 / 计划审阅 | 同上,kind 为 'question' / 'plan-review' | 「查看」按钮,点击回到会话 |
| 任务完成 | 服务端 turn/end reason=completed(子代理会话除外) | 任务完成 |
| 任务中断 / 失败 | 服务端 turn/end reason=aborted/error/interrupted | 任务被中断 / 任务失败 |
| 后台任务 | ctx.jobs 名册里该任务转为 completed/killed/failed | 后台任务完成 / 被中断 / 失败 |
插件在 DSH Web UI 设置 → 通知 注册管理页:
2026-08-23 22:45:01 GMT+8),最多 100 条,可清空Config schema 声明,客户端经 ctx.configForms.get('dsh-notify') 读写,与 Web UI 其他设置一致Windows.UI.Notifications)<audio src="ms-winsoundevent:Notification.Default"> 负责,后台也能听到;关闭「提示音」时写 <audio silent="true">osascript 调 display notification,走 macOS 通知中心,零第三方依赖sound name "default" 触发;关闭「提示音」时省略该子句(不写就是静音)DSH-<项目名>,正文 = 事件内容;点击通知不会跳转(如需图标 / 跳转可后续接入 terminal-notifier)flowchart LR
A[DSH 服务端<br/>session/event] -->|SSE /dsh-notify/events<br/>turn/end| B[Web/WebView2 客户端]
P[ctx.uiSession.sessionStatus] -->|待审批 / 待回答 / 计划审阅| B
J[ctx.jobs] -->|后台任务| B
L[ctx.sessions.list] -->|新会话| B
B -->|焦点在内| C[应用内 Toast + 页面内提示音]
B -->|焦点在外| D[POST /dsh-notify/native]
D -->|Windows| E[dsh-toast.ps1 弹原生 Toast + 系统提示音]
D -->|macOS| F[osascript 弹原生通知 + 系统提示音]
要点:
win32 → PowerShell WinRT Toast;darwin → osascript;其他平台跳过<audio> 发声;焦点在外时页面不再发声,改由系统通知发声(Windows 的 toast 里写显式 <audio>,macOS 用 sound name "default")。之所以不两边都响,是为了避免同一条通知响两次
turn/end;待审批 / 待回答 / 计划审阅由客户端直接从 ctx.uiSession.sessionStatus 读取——那是官方审批面板与侧边栏角标用的同一个事实源,服务端再广播一份只会造成一次审批弹两条通知sessions / slots 放进 inject,其余服务(configForms / uiSession / jobs / locale)一律惰性解析:DSH 小版本升级常会改名或移除客户端服务,硬依赖会让整个插件停在 pending、连通知都发不出来。宁可少一个功能,也不能整个插件不加载PendingApproval.answer('allowed-once' | 'rejected'),不需要先打开会话;待办在别处被应答或取消后,对应 Toast 会自动撤掉SessionSummary.origin、服务端 session.header.origin 均为 'subagent'),它们的每一轮都会 turn/end——一次 fan-out 工作流能刷出几十条通知。服务端在广播前就拦掉,「新会话」「任务完成」两侧也各自过滤。审批 / 待回答不过滤:漏掉一次授权的代价远大于多一条通知ctx.jobs.watchRows),每个订阅在服务端是一条常开的 job.list 流。插件只订阅「可能还有任务在跑」的会话:当前会话、正在运行的会话、12 小时内活跃过的会话、以及名册里当前仍有任务的会话,其余不订阅tag 去重,避免重复通知dsh-notify/
├─ lib/index.js # 服务端:路由 + SSE + 会话事件监听 + 跨平台原生通知触发
├─ lib/client.js # 客户端:应用内 Toast + 音频 + 焦点检测 + 审批应答 + 设置页
├─ scripts/dsh-toast.ps1 # Windows 原生 Toast(PowerShell + WinRT,纯通知无激活)
├─ assets/notify.wav # 自带提示音(合成,无版权)
├─ assets/dsh-notify.ico # 通知图标(合成,无版权)
├─ tools/generate-audio.mjs # 重新生成提示音
├─ tools/generate-icon.mjs # 重新生成图标
├─ tools/smoke-client.mjs # 客户端接线回归测试(打桩跑,无需浏览器)
├─ cordis.patch.yml # DSH bundle patch
└─ package.json
# 客户端接线回归测试(DSH 升级后必跑)
node tools/smoke-client.mjs
# 重新生成提示音 / 图标
node tools/generate-audio.mjs
node tools/generate-icon.mjs
# 语法自检
node --check lib/index.js
node --check lib/client.js
# 打包
pnpm pack --pack-destination ..
DSH 升级后请务必跑一遍
tools/smoke-client.mjs。 DSH 小版本之间会改名或移除客户端服务 (0.1.5 → 0.1.7 就删掉了settingsScope、把uiSession.pendingInteractions并进了sessionStatus、把jobsBySession搬到了ctx.jobs)。插件的inject里只要有一个服务 不存在,cordis 就会让它在pending里一直等——插件完全不加载,而且没有任何报错。
MIT © dsh-notify by having5548