DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

printz1 /

printz1/dsh-notify

Verified

DSH Web GUI 通知插件:需要审批 / 模型提问 / 一轮指令结束 / 后台任务结束 / 会话出错时提醒。带完整设置页 —— 场景开关、静音指定会话、免打扰时段、时长下限、提醒节流、系统通知/页面内气泡/提示音三渠道。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@aabcdf67

dsh-notify —— DSH Web 通知

在「需要你介入」或「任务跑完」时提醒你,这样你可以把 DSH 丢在后台去干别的。 提醒方式与时机全部可以在 设置 → 通知 里改,不用碰配置文件。

零第三方依赖、零构建步骤:Host 半侧是一个空的 cordis 插件,全部逻辑都在浏览器半侧。

Desktop / in-page notifications for the DeepSeek Harness (dsh) Web GUI: notify on approval requests, ask_user_question, turn end, background-job end and session errors — with a full settings page (Settings → 通知) for per-scene toggles, per-session mute, quiet hours, minimum duration, throttling, system notification / in-page toast / sound channels. Zero runtime dependencies, no build step.

安装

# 从 GitHub
dsh plugin --profile web add github:printz1/dsh-notify

# 本地开发时(软链,改完文件即时生效)
dsh plugin --profile web add link:/path/to/dsh-notify

装完重启 dsh 后端,然后刷新浏览器页面(客户端 bundle 是页面加载时才拉的)。 自检:node tools/verify-install.mjs 验宿主认不认这个包,node tools/selftest.mjs 验行为。

卸载:dsh plugin --profile web remove dsh-notify,然后重启后端。

装在哪

  • 会话头部右上角:一个铃铛按钮,单击 = 授权 / 一键开关总开关(详细配置在设置页)
  • 设置 → 通知:完整配置面板

触发场景

场景 来源 通知标题 默认
需要你审批 ctx.uiSession.pendingInteractions DSH · 需要你审批 开
模型在等你回答 同上(question / plan-review) DSH · 模型在等你回答 / 计划等你审阅 开
一轮指令结束 api-session/status 由 running 变 idle DSH · 任务已结束 开
后台任务结束 sessions.list 的 jobsBySession 差分 DSH · 后台任务已完成 / 被中断 / 失败 开
会话出错 api-session/error DSH · 任务出错了 开
子会话(subagent)结束 同「一轮指令结束」 DSH · 任务已结束 关

点通知 / 点气泡都会 focus 窗口并切到对应会话。

设置 → 通知(全部开关)

通知方式

项 默认 说明
启用通知 开 总开关,关掉后下面全部不生效
系统通知 开 浏览器 / Windows 通知中心;右侧按钮显示授权状态并可申请权限
页面内气泡 关 DSH 页面右上角弹一条,不依赖浏览器授权;系统通知被拒时的替代方案
提示音 关 两声短促合成音(Web Audio,不引外部音频文件),旁边有「试听」

什么时候提醒

每个场景一个开关,另有三个细分项:

  • 只提醒失败或被中断的(属于「后台任务结束」):后台任务多的时候建议打开,成功的不吵
  • 子会话结束也提醒:默认关 —— 否则 subagent / workflow 每跑完一个子任务都响一次

过滤与勿扰

项 默认 说明
盯屏时也提醒 关 默认:页面在前台且聚焦时静默,免得每轮对话都响一次
免打扰时段 空 如 23:00-08:00(跨天自动识别,可逗号分隔多段),时段内完全不提醒
只提醒运行超过(秒) 0 短任务不打扰;页面加载时已在跑的任务不受此限制
同一会话提醒间隔(秒) 0 只作用于「一轮结束」和「后台任务」;审批 / 提问 / 出错永不节流

静音的会话

  • 「静音此会话」把当前打开的会话加进名单,名单里可逐个「取消静音」
  • 静音的会话完全不提醒,连审批也不提醒 —— 适合你就是要它自己跑完的长任务

诊断

  • 测试系统通知 / 测试气泡 / 测试提示音:改了设置没动静时,先确认渠道通不通
  • 最近通知:最多 50 条,显示时间 + 内容 + 实际生效的渠道(如 [系统+气泡]),刷新页面清空
  • 恢复默认设置:把配置清回出厂值

一个必须先做的动作

浏览器要求「用户手势」才能申请通知权限,所以系统通知第一次要手点一次:

  • 点会话头部右上角的铃铛,或
  • 打开 设置 → 通知,在「系统通知」那一行点 请求权限

如果被拒过:点地址栏左侧的图标 → 网站设置 → 通知 → 允许,再回来点「请求权限」。 http://127.0.0.1:3080 属于安全上下文,通知 API 可用。

不想授权也行:把「页面内气泡」打开即可,它不依赖任何授权。 两个可见渠道都关掉时,会退回闪烁标签页标题(🔔 …),切回标签页自动恢复。

配置存在哪

localStorage 的 dsh-notify:config 一个键(JSON)。不走 DSH 官方设置系统, 因为它的命名空间是白名单制,第三方客户端插件读不到自己的。

0.1.x 的三个旧键(dsh-notify:enabled / :scenes / :notify-when-focused) 在首次加载时自动迁移进新配置,之后不再读取。

想直接改也行(改完刷新页面):

// 例:只在后台提醒,且夜间勿扰
localStorage.setItem('dsh-notify:config', JSON.stringify({
  enabled: true, system: true, toast: false, sound: false,
  scenes: { approval: true, question: true, turnEnd: true, job: true,
            jobFailuresOnly: false, error: true, subagent: false },
  notifyWhenFocused: false, quietHours: '23:00-08:00',
  minDurationSec: 0, throttleSec: 0, mutedSessions: []
}))

非法值会被规整(布尔回落默认、数字夹紧到 0..86400、静音名单只留字符串),不必担心写坏。

目录结构

dsh-notify/
├─ package.json          # dsh.bundle.patch + dsh.client 双面声明
├─ cordis.patch.yml      # 插入一行 `name: dsh-notify` 到 web profile 的插件树
├─ lib/index.js          # Host 半侧:空的 apply()(合法插件入口,零副作用)
├─ lib/client.js         # 浏览器半侧:全部逻辑(通知链路 + 头部按钮 + 设置面板)
├─ tools/selftest.mjs       # 行为自检:假 DOM/假 ctx 里跑 122 项断言
├─ tools/verify-install.mjs # 安装自检:宿主认不认这个客户端包(30 项)
└─ README.md

三条硬性约束(改坏了会静默不加载)

  1. cordis.patch.yml 里那行的 name 必须是裸包名(dsh-notify)。客户端模块扫描用 exactPackageSpecifier(),带子路径的三段写法直接返回 undefined。
  2. lib/client.js 里 window.__ModuleLoader__.load({ id }) 的 id 必须与包名逐字相同 —— 引导图里的 entry id 就是包名。
  3. dsh.client.inject 留空。它声明的是模块图依赖(本插件要 require 哪些 DSH 客户端包), 本插件只 require('react');remote / sessions / uiSession / slots 全走 cordis 服务注入(exports.inject),cordis 会让插件在依赖服务就绪前停在 PENDING, 所以不需要也不应该在 dsh.client.inject 里列 @deepseek-ai/dsh-client-ui-slots 这类不是 Loader 行的包。

为什么铃铛挂在会话头部而不是侧栏

会话头部右上从右到左是 headerCorner(single,已被 sidebar-right 占用)→ headerUtilities(list,现有 open-in-app order -10、session-log-download order 0) → headerActions(在标题旁)。本插件挂 headerUtilities、取 order: 10 排到最右。

早先挂在侧栏底部的 sidebar.footer.action:那是个不换行的横向 flex 行,而重启后端 (width: calc(100% + 8px))和 cordis 面板(width: 100%)各自声明满宽,第三个成员必然 被挤出侧栏右边缘裁掉 —— 这就是「太靠右、看不清」的根因。已弃用该位置。

为什么设置面板用 settings.section

settings.section 是 list 槽(root 作用域),每个条目就是设置弹窗左侧的一页 (现有 general 0 / models 10 / plugins 15 / agent-presets 20),本插件取 30 排在最后, 注册项 label: '通知' 就是导航文字。面板里的开关/输入框直接用 DSH 的 CSS 变量手写, 不依赖 @deepseek-ai/dsh-client-ui-primitives(该包没有独立类型,属未公开内部)。

自检

两个脚本,各管一段,都不用开浏览器:

1. 行为自检

node tools/selftest.mjs

在 Node 里用假的 window / document / Notification / AudioContext + 假的 client ctx 真跑 lib/client.js,122 项断言覆盖:五个通知场景与子会话过滤、渠道三选与兜底、 免打扰时段、时长下限、节流、静音会话、前台静音、总开关、场景开关、旧配置迁移、 设置面板(注册项/分组/11 个开关/文本数字输入/静音名单/恢复默认/诊断按钮/日志)、 头部按钮(槽位/order/尺寸/SVG/状态)、单个订阅抛错不影响其它场景。

2. 安装自检

node tools/verify-install.mjs

客户端包被宿主忽略时不会报错,只是页面上什么都不出现 —— 所以单独验这一条链路: 裸包名判定(含「带子路径会被静默忽略」的对照)、dsh.client 声明过宿主的校验、 exports["./client"] 能解析到真实文件、bundle 自报 id 与行名逐字一致、 Host 半侧导出 apply() 且零 import、bundle 能在无 DOM 环境执行并导出 apply/inject。 最后直接 import 宿主的 stripClientSuffix / orderByModuleGraph 真货做交叉验证。

宿主的校验函数是逐字抄过来的,宿主升级后这里不会自动跟 —— 所以那两条真导入的交叉验证 是关键:它们会跟着宿主一起变。30 项全绿只说明「宿主会认这个包」,不代表页面渲染正常。

排错

现象 原因 / 处理
头部没有铃铛按钮 后端没重启;或没打开任何会话(该槽位是会话级作用域);或 dsh --profile web --dump-config | grep -A1 'id: notify' 里没有这一行
设置里没有「通知」页 后端没重启;或客户端 bundle 没重新拉取(必须刷新页面)
有按钮但从不弹 没点过授权;或页面正前台聚焦(见「盯屏时也提醒」);或总开关关了;或该会话被静音;或落在免打扰时段
系统通知通不了 设置 → 通知 看「系统通知」那行的状态;被拒就去站点设置放开;实在不行改用「页面内气泡」
想确认它加载了 浏览器控制台看 window.__DSH_BOOT__ 里有没有 dsh-notify 行;或看「最近通知」有没有记录
改代码后没变化 软链是实时的,但需要重启后端 + 刷新页面;node --check lib/client.js 先确认语法

卸载

dsh plugin --profile web remove dsh-notify

然后重启后端。localStorage 里的 dsh-notify:* 可自行清掉。

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit aabcdf67b612

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout