桌面通知 · dsh-desktop-notify
Harness 停下来等你时,弹一条系统通知。 工具授权确认、提问 / 计划评审、任务完成 —— 不用一直盯着界面,点通知直接回到那张待处理卡片。
1. 它解决了什么问题
DeepSeek Harness 在三种时刻必须等你动手:工具越权需要授权确认、模型向你提问或提交计划待确认、以及一轮任务跑完。你不在界面跟前时,对话就一直挂着;靠"盯着页面"既不现实,也违背了把活交给 Agent 的初衷。
本插件把这三种时刻转成系统级通知(Windows 上就是系统 toast,由浏览器的 Notification API 发出),让你在别的窗口干活时也能第一时间知道。
┌──────────────────────── DeepSeek Harness ────────────────────────┐
│ │
│ 工具需要授权 ─┐ │
│ 向你提问 ─┼─▶ pendingInteraction ──▶ uiSession.sessionStatus │
│ 任务完成 ─┘ (官方状态源,只读观测) │ │
│ │ subscribe │
│ ▼ │
│ dsh-desktop-notify │
│ │ │
└────────────────────────────────────────────────────────┼──────────┘
▼
浏览器 Notification API
│
▼
Windows 系统通知(toast)+ 点击回前台
关键点:只读观测,不接管任何链路。官方的审批面板、提问输入框照常工作,插件只是在它们旁边"看了一眼状态"。
2. 功能特性
- ✅ 三类提醒:工具授权确认(
approval)、向你提问与计划评审(question/plan-review)、任务完成(会话由运行转为空闲) - ✅ 系统级通知:由浏览器发出(Windows 显示为系统 toast),无需宿主进程、无需常驻后台程序
- ✅ 点击直达:点通知把窗口拉到前台,并自动滚动到那张待处理的授权 / 提问卡片
- ✅ 失焦补发:你正盯着界面时不打扰;一旦你切走(窗口失焦),会把刚才压下的那条补发出来
- ✅ 子代理降噪:完成提醒只针对宿主会话列表里你跟踪的会话,子代理跑完不弹
- ✅ 去重与自清理:同一请求只通知一次;你在界面上回答后,对应通知自动关闭
- ✅ 不占侧边栏:只在「设置」里新增一节,侧边栏零占用
- ✅ 四项开关 + 本地持久化:存浏览器
localStorage,不上传任何数据 - ✅ 零依赖:无宿主服务、无外部 npm 依赖、不读取会话日志、不注册任何 HTTP 路由
3. 目录结构
dsh-desktop-notify/
├── README.md # 中文主文档(本文件)
├── README.en.md # 英文完整版(结构平行)
├── LICENSE # MIT
├── .gitignore # 忽略密钥 / 产物 / 编辑器噪音
├── package.json # 包定义:dsh.bundle.patch + dsh.client(platform: web)
├── cordis.patch.yml # bundle 补丁:把插件行插入 web profile 组合
└── lib/
├── index.js # 宿主半部:刻意惰性的空实现(见第 10 节)
└── client.js # 浏览器半部:状态观测 + 通知 + 设置页
无构建步骤:浏览器半部就是 window.__ModuleLoader__.load() 形式的 classic script,由宿主按请求直接提供。
4. 快速开始
dsh plugin --profile web add github:AFAP/dsh-desktop-notify
装完刷新页面即可生效,不需要重启 dsh web。然后:
- 打开「设置」→ 左侧「桌面通知」
- 点「开启权限」,在浏览器弹窗里允许通知
- 点「发送测试通知」验证通道
升级:
dsh plugin --profile web update dsh-desktop-notify
卸载:
dsh plugin --profile web remove dsh-desktop-notify
从源码目录安装(开发 / 预览用)
dsh plugin --profile web add link:D:\path\to\dsh-desktop-notify
验证是否加载成功
设置面板左侧出现「桌面通知」一节(排在「通用」之后、「模型」之前);侧边栏不新增任何按钮。
5. 使用说明
5.1 什么时候会提醒
| 触发时机 | 通知标题 | 通知正文 |
|---|---|---|
| 工具需要授权确认 | 需要授权确认 | 请求原因(如"写入被沙箱拒绝"),无原因时显示"工具 X 请求越权执行";附会话标题 |
| 模型提问 / 提交计划 | 有问题等你回答 / 计划待你确认 | 问题原文(计划评审显示固定文案);附会话标题 |
| 任务完成(会话转空闲) | 任务已完成 | 会话标题 |
5.2 通知里的行为
- 点击通知:窗口置前 + 滚动到对应卡片(授权卡片、问题输入框),随后通知自动关闭。
- 回答后:你在界面上点掉授权 / 回答完问题,对应通知会自动关闭,不会留下过期的提醒。
- 同一条请求:只通知一次;重复出现的同一请求不会反复弹。
5.3 前台抑制与失焦补发
默认开启「仅在 DSH 不在前台时提醒」:当你正看着 DSH 界面(页面可见且窗口有焦点)时不打扰;而当你切走 / 最小化时,会把刚才压下的那条补发出来。这样既不会在你眼前重复提示,也不会因为你转身走开而漏掉。
5.4 待处理计数
设置页里有一行状态:有待处理的授权 / 提问时显示 ● 当前有 N 个请求在等你处理;没有时显示"当前没有等待你操作的请求"。这是唯一需要主动查看的地方(侧边栏不占位)。
6. 配置项
全部为布尔开关,存在浏览器 localStorage 的 dsh-desktop-notify:settings 键下(不同浏览器各自独立,不上传)。
| 键 | 默认值 | 说明 |
|---|---|---|
approval |
true |
工具需要授权确认时提醒 |
question |
true |
需要你回答问题 / 确认计划时提醒 |
completion |
true |
任务完成(会话转空闲)时提醒;仅针对宿主会话列表里跟踪的会话 |
backgroundOnly |
true |
仅在 DSH 不在前台时提醒;关闭后你盯着界面时也会弹 |
通知权限本身不是本插件的配置项,由浏览器按站点授权管理;被拒绝后需在地址栏的站点设置里改回允许(见第 7 节)。
7. 排错
| 现象 | 排查方向 |
|---|---|
| 完全收不到通知 | 设置 → 桌面通知里看权限状态:未授权 就点「开启权限」;已被浏览器拒绝 需在地址栏左侧站点设置把「通知」改为允许后刷新 |
| 权限正常但仍无通知 | 系统「专注助手 / 勿扰模式」会拦截 toast,在系统设置里放行浏览器通知;也确认「发送测试通知」是否有效 |
| 界面里明明有待处理却不弹 | 默认「仅在 DSH 不在前台时提醒」:你正看着界面时被有意抑制;切走窗口即会补发,或关掉该开关 |
| 设置里找不到「桌面通知」一节 | 插件未加载:确认 dsh plugin --profile web list 里有它,并刷新页面(Ctrl+Shift+R) |
| 提示「当前环境不支持」 | 页面不是安全上下文(非 https / 非 127.0.0.1 / localhost),浏览器不提供 Notification API |
| 提醒太吵 | 按需关掉 completion(任务完成)或 question,或保持「仅前台之外提醒」 |
| 点了通知没跳到卡片 | 该卡片属于另一个会话:先在会话列表切到对应会话,再点通知 |
| 子代理跑完也弹「任务已完成」 | 不应发生:完成提醒已按宿主会话列表过滤,如复现请带截图提 Issue |
8. 安全与合规(务必阅读)
- 不读数据、不写数据、不发请求:宿主半部(
lib/index.js)是刻意惰性的空实现 —— 不注册路由、不读会话日志、不发网络请求;浏览器半部只读官方已推送到页面的状态源。 - 唯一权限是浏览器通知权限:可随时在站点设置里撤销,撤销后插件静默失效,不报错、不影响 DSH。
- 通知正文可能出现在锁屏 / 通知中心:内容包含工具名、请求原因、会话标题。共享屏幕、录屏或投屏时请注意这一点;敏感项目里可关闭对应开关。
- 无凭证、无密钥:仓库不含任何令牌、密钥、内网地址与本机绝对路径(文档里的路径一律用
D:\path\to\...、$DSH_HOME之类的占位符)。 - 设置只存本机浏览器:
localStorage不随会话或账号同步,插件不上传任何偏好数据。 - 发现问题请开 Issue;涉及安全细节请使用仓库的 Security Advisory 私下报告,不要在公开 Issue 里贴敏感信息。
9. FAQ
Q:能不能只提醒授权,不要"任务完成"? A:可以,设置里关掉「任务完成时」即可;三项开关互相独立。
Q:能不能不用浏览器通知,走系统原生 toast(如 PowerShell)? A:当前版本只走浏览器 Notification API —— 它同样在 Windows 上显示为系统 toast,且点通知能把窗口拉到前台、自动滚到卡片;宿主端方案无法可靠地把浏览器窗口带到前台,且需要每次启动一个外部进程。
Q:为什么侧边栏没有入口? A:本插件只承载"注意力状态",没有常驻操作。设置里一节 + 待处理计数已经够用,不占侧边栏空间。
Q:标签页关了还会提醒吗? A:不会。通知由页面发出,页面关掉时也没有 UI 能回答授权,请求会以拒绝方式关闭。
Q:多个浏览器都开着会重复提醒吗?
A:每个页面各自判定并弹各自的系统通知;设置(localStorage)按浏览器独立。
Q:会不会影响 DSH 本身的审批流程? A:不会。插件不注册审批应答者,只观测官方状态源,官方面板的允许 / 拒绝链路完全不受影响。
10. 开发与实现
10.1 模块分层
| 文件 | 职责 |
|---|---|
lib/index.js |
宿主半部:刻意惰性(只导出空的 apply),让插件行能被 cordis 正常加载;不提供服务、不需要配置 |
lib/client.js |
浏览器半部:注册语言字典、订阅状态源、弹通知、贡献设置页 |
cordis.patch.yml |
bundle 补丁:把 desktop-notify 行插入 web profile 组合(无 inject、无 config) |
10.2 为什么不挂 approval/request 瀑布
ctx.remote.$on("approval/request", (req, next) => ...) 看起来是最自然的接缝,但它是错的:
官方面板(@deepseek-ai/dsh-client-ui-approval)在启动时注册了自己的 waterfall 监听器,并且故意 hold 住整条瀑布直到用户点击(它 await pending.result)。因此任何后注册的监听器 —— 也就是所有外部插件 —— 在面板持有的请求上永远轮不到执行;$on 也没有 prepend 选项,靠加载顺序修不好。
10.3 实际做法:观测官方状态源
ctx.uiSession.sessionStatus // HostObservable: { getSnapshot, subscribe }
└─ Map<SessionId, { running, pendingInteraction, completionUnread }>
pendingInteraction.kind直接区分approval/question/plan-review,并带toolName/reason/questions,三类事件一次覆盖;- 读状态与监听器顺序无关、不参与回答链路,因此做到零侵入;
- 与瀑布解耦后,"前台抑制 + 失焦补发" 这类策略才有地方落地。
10.4 界面席位
通过 settings.section 贡献一个设置页(order: 5,排在「通用」之后、「模型」之前 —— 它是普通偏好,不是插件管理页)。侧边栏不新增任何按钮。
10.5 构建与发布
无构建步骤(纯 JS classic script bundle),因此不配置 GitHub Actions:dsh plugin add <repo> 直接按 package.json 的 exports["./client"] 提供浏览器半部。改动按 Conventional Commits 提交,发版打 SemVer tag。
10.6 本地预览与自检
- 手工验证:
link:安装后刷新页面,用「发送测试通知」+ 触发一次真实授权确认。 - 主题样式自检:用真实 DSW 主题令牌渲染浅色 / 深色两态,确认卡片与开关不透明、可读(本插件不使用半透明浮层令牌)。
11. 兼容性
需要 DeepSeek Harness 0.1.7-alpha.1 或更高。插件依赖的契约:
| 契约 | 用途 |
|---|---|
ctx.uiSession.sessionStatus(HostObservable) |
待处理请求与运行状态 |
pendingInteraction.kind:approval / question / plan-review |
区分三类提醒 |
settings.section 插槽 |
设置页席位 |
主题令牌 --dsw-alias-bg-layer-2 / --dsw-alias-bg-skeleton 等 |
设置页样式 |
仅浏览器端(dsh.client.platform = web):无宿主依赖、无外部 npm 依赖。
12. 相关文档
- DeepSeek Harness:https://github.com/deepseek-ai/deepseek-harness
- 同作者插件参考(同样的双语 + 最小集风格):https://github.com/AFAP/dsh-token-usage
- GitHub Actions / README 官方说明:https://docs.github.com/zh/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes
13. License
MIT © contributors · 见 LICENSE
免责声明:本插件只是把 DSH 已有的待处理状态转成系统通知,不改变任何审批结果。系统「专注助手 / 勿扰模式」、浏览器权限策略、页面未打开等情况都可能导致通知不出现,请勿把关键审批流程完全依赖通知;因通知缺失造成的任何后果由使用者自行承担。
No comments yet. Be the first to write one.