Lwc-LiuWenCheng
dsh-session-notify
DSH 浏览器通知及系统通知插件
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 14, 2026
- Updated
- Aug 14, 2026
Introduction
dsh-session-notify · 会话通知中心
DeepSeek Harness (DSH) 动态 Cordis 插件:把所有需要人工干预的事件——审批请求、提问确认、目标受阻、消息推送、任务完成、错误失败——接入浏览器系统通知与应用内 toast,点击通知直接跳转到对应会话,并可在设置页配置每个分类的通知级别。
特性
- 🧩 纯动态插件:Host + Client 双半体,无需修改 DSH 部署源码即可加载
- 📬 覆盖全部人工干预事件(7 分类 / 11 事件源,见 docs/EVENTS.md):
- 审批请求(
approval/request) - 提问确认(
ask_user_question工具调用) - 目标受阻 / 暂停(
goal/changed) - 消息推送(子代理报告等,
agent/inbox/inserted) - 任务完成(子代理 / 工作流子任务 / 后台任务)
- 错误失败(会话出错 / 子代理出错 / 工作流失败 / 后台任务失败)
- 开始执行(默认关闭,防打扰)
- 审批请求(
- 🔔 双通道提醒:浏览器
NotificationAPI 系统通知 + 右上角 toast 栈 - 🖱️ 点击跳转:通知点击后聚焦窗口并
sessions.open(sessionId)打开对应会话 - ⚙️ 设置页配置:每个分类独立级别(关闭 / 应用内提示 / 系统通知)、总开关、聚焦抑制、权限状态、测试通知
- ⚡ 近实时推送:Client→Host 长轮询(空队列挂起 15s),无轮询风暴
- 🧹 事件源过滤:Host 侧按配置在源头过滤,关闭的分类零负载
架构总览
┌─────────────── Host(Node 进程) ───────────────┐ ┌──────────── Client(浏览器页面) ────────────┐
│ │ │ │
│ DSH 事件(11 个源) │ │ ┌─ 长轮询 ntf/poll(挂起≤15s)──────────┐ │
│ ├ approval/request ──┐ │ │ │ │ │
│ ├ tools/pre-execute ─┤ │ │ │ ┌─ 系统通知 Notification ──┐ │
│ ├ goal/changed ──────┼─► 按配置过滤 ─► 队列 ──┼──►┼──►│ └ 点击 → 跳转会话 ────────┘ │
│ ├ agent/inbox/… ─────┤ │ │ │ ┌─ toast 栈(shell.overlay)┐ │
│ ├ subagent/* ────────┤ │ │ │ └ 点击 → 跳转会话 ──────────┘ │
│ ├ workflow/* ────────┤ │ │ │ │
│ ├ agent/error ───────┤ │ │ └─ 设置页(settings.section) │
│ ├ agent/status ──────┤ │ │ │ │
│ └ jobs.onJobDone ────┘ │ │ └─ ntf/config 同步配置 ────────────────┘
│ ntf/state · ntf/config │ │ │
│ ntf/poll · ntf/test (harness.handle RPC) │ └───────────────────────────────────────────────┘
└────────────────────────────────────────────────┘
详细设计见 docs/ARCHITECTURE.md,事件源字段级说明见 docs/EVENTS.md。
快速开始
方式 A:作为动态插件加载(推荐,无需改部署)
-
构建可粘贴的单文件函数体:
npm run build:dynamic # 生成 dynamic/host.body.js 与 dynamic/client.body.js -
在 DSH 会话中,把
dynamic/host.body.js的内容作为code.host、dynamic/client.body.js的内容作为code.client调用cordis_define,再cordis_run激活。 -
首次使用:打开 设置 → 通知,点击「请求通知权限」并允许浏览器权限; 可点「发送测试通知」验证链路。
动态插件是会话级、进程内的:停止/更新即移除全部副作用;配置随插件生命周期存在, 刷新页面后回退到默认配置(需要持久化可自行接入
settings服务,见 docs/ARCHITECTURE.md)。
方式 B:作为静态插件安装到本地 DSH 部署(常驻、所有会话可用)
-
构建静态产物(
lib/index.jsHost 插件 +lib/client.js客户端 bundle):npm run build:static npm pack # 生成 dsh-session-notify-<version>.tgz -
停止 dsh 进程后,运行一键安装脚本(会重建依赖树、安装包、登记 bundle):
powershell -ExecutionPolicy Bypass -File scripts\install-local.ps1 -
重新启动
dsh web,刷新页面。启动后 host 组合加载session-notify插件行 (全进程事件作用域),页面出现通知 UI(toast + 设置页 + 系统通知)。
卸载:
dsh plugin --profile web remove dsh-session-notify(或从profiles/web/package.json的dependencies与dsh.profile.bundles移除)。 详见 docs/PACKAGING.md。
方式 C:作为 npm 包分发
见 docs/PACKAGING.md(npm pack、发布流程、CI)。
配置项(设置页)
原则:只有需要用户操作的事项才默认通知(审批 / 提问确认 / 目标受阻); 其余为信息性分类,默认全部关闭,可在设置页按需开启。
| 分类 | 默认级别 | 事件源 |
|---|---|---|
| 审批请求 approval | 系统通知 | approval/request |
| 提问确认 question | 系统通知 | ask_user_question 工具调用 |
| 目标受阻 goal | 系统通知 | goal/changed(block / pause) |
| 消息推送 message | 关闭 | agent/inbox/inserted(子代理报告等,信息性) |
| 任务完成 task | 关闭 | subagent/end / workflow/agent-end / jobs.onJobDone(信息性) |
| 错误失败 error | 关闭 | agent/error / workflow/end / 子代理与后台任务失败(信息性) |
| 开始执行 start | 关闭 | agent/status / subagent/start(信息性) |
级别语义:
- 关闭:完全不提醒,且 Host 源头过滤(零负载)
- 应用内提示:右上角 toast,点击跳转会话,8s 自动消失
- 系统通知:应用内提示 + 浏览器系统通知;点击聚焦窗口并跳转会话
其他选项:总开关、页面聚焦时抑制系统通知(system 级别聚焦时只弹 toast)、
标签页失焦时自动切换为系统通知(默认开启:离开页面后,任意已启用级别
app/system 的通知都自动以系统通知呈现,确保收到提醒)、
仅推送其他会话的通知(默认开启:正在查看的会话已看到内容,不再提醒;
其余会话的通知照常推送——由 Client 通过 useSessions.current 实时上报当前会话,
Host 在源头过滤,属于当前会话的通知直接不入队)。
开发
npm run build:dynamic # 从 src/ 生成 dynamic/*.body.js(含语法校验)
npm test # 运行 config 单元测试(node:test)
npm run check # 构建 + 测试
项目结构
dsh-session-notify/
├── src/
│ ├── config.js # 共享配置与纯函数(分类/级别/默认值/归一化)—— 单一事实来源
│ ├── host.js # Host 半体:事件监听 → 过滤 → 队列 → RPC
│ └── client.js # Client 半体:长轮询 → 通知 UI → 设置页
├── dynamic/ # 构建产物:可直接粘贴 cordis_define 的函数体(勿手改)
├── scripts/
│ └── build-dynamic.mjs
├── tests/
│ └── config.test.mjs
├── docs/
│ ├── ARCHITECTURE.md
│ ├── EVENTS.md
│ └── PACKAGING.md
├── .github/workflows/ci.yml
├── package.json
└── LICENSE
⚠️
dynamic/*.body.js由构建脚本生成:修改配置/代码请改src/,再运行npm run build:dynamic。
已知边界
- 动态插件接收当前会话作用域内的事件(审批、状态等按 agent 作用域分发;子代理通过 委托载体到达父会话作用域),跨会话的事件不会收到——这是 DSH 动态插件的作用域约束。
- 浏览器系统通知依赖
NotificationAPI 与用户授权;不支持时自动降级为应用内提示。 - 通知正文中的会话标题来自
sessionQuery.readTitle,取不到时降级为通用文案。