dsh-focus-notify:按窗口焦点区分的 DSH 统一通知

前言

在 DeepSeek Harness(DSH)里跑多会话、多智能体时,审批、提问、方案确认和回复完成往往分散在不同事件里。若通知策略只按「页面是否可见」判断,在 macOS 上窗口被其他应用盖住时,document.hidden 仍可能为 false,容易误判为「用户正在看 DSH」,从而漏掉需要你操作的提醒。

下面介绍社区插件 dsh-focus-notify(维护者 sqzw-x):把上述几类事件统一成一种桌面提醒,并按窗口键盘焦点和当前会话决定何时弹出。分类为客户端插件;仓库在 GitHub 上约 1 star。本文事实以 仓库 README 为准。

这是什么

dsh-focus-notify 是跑在 DSH Web / DSH Desktop 页面内的 Cordis 通知插件。它不替代 DSH 自身的交互 UI,而是在宿主已暴露的会话状态上监听「等你操作」与「回复完成」,在规则允许时调用系统通知;你回到对应会话或窗口重新获得焦点时,该会话的通知会被收掉。

许可证为 MIT;当前资料中的包版本为 0.3.1。README 写明:只在 DSH Desktop 上实测过,Web 版能否正常工作未知。

三条提醒规则

插件 README 把行为浓缩为三条规则,理解安装后的表现以此为准。

  1. 看会话分:屏幕上当前主视图持有的会话,仅在窗口失去键盘焦点时弹通知;其它会话在 DSH 处于前台时也会弹。
  2. 看事件分:轮次结束(回复完成),以及等待你操作(审批 / 方案确认 / 提问),都会触发提醒;同一类「等你操作」请求按 key 去重,只提醒一次。
  3. 回到会话就收掉:聚焦到某个会话时,该会话的通知自动消失——点通知进入、窗口重新获得焦点、或手动切换到该会话,收尾逻辑一致。

子代理会话默认不参与:ignoreSubagent 默认为 true,子代理既不是「当前会话」也不提醒。

为什么用 document.hasFocus() 而不是「页面可见」

macOS 上窗口被 Edge、QQ 等盖住时,页面往往仍「可见」。本插件用 document.hasFocus():窗口没有键盘焦点即视为你不盯着 DSH。因此当前会话只有在你真正看着它时保持安静;失焦时仅切换会话不会顺带消掉通知,避免你仍在别的应用里时误清提醒。

核心能力与数据来源

插件不自己猜会话状态,而是订阅宿主已发布的 store:

  • uiSession.sessionStatus:Map<sessionId, { running, pendingInteraction, completionUnread }>
  • sessions.list:会话标题、origin: 'subagent'、retainedBy.mainView 等

由此派生两类事件:

  • 等你操作:某会话出现 pendingInteraction。
  • 回复完成:某会话 running 从 true 变为 false,且没有紧接着的等待(停下来等你输入算「等你操作」,不算「完成」)。

规则判定集中在 src/engine.ts 的 allows(),为纯逻辑、可单测。点击通知会尝试唤起窗口(桌面端 dsh://open 深链,浏览器端 window.focus()),并调用宿主的 uiWorkspace.openSession(旧宿主为 sessions.open);失败会记入 counters.failed 并在控制台打出 [dsh-focus-notify] 警告。

每发出一条通知,还会在 window 上派发 dsh-focus-notify:alert 事件(event.detail 含 kind / sessionId / title / body / tag),便于自定义闪任务栏、换声音或记日志。

安装与启用

DSH 生态里插件可通过社区目录或 GitHub 安装;装完后客户端 bundle 在页面加载时读取,需要重启 DSH Desktop。

插件管理器

在「设置 → 插件」里安装本包目录,启用后重启 DSH Desktop。

命令行

从 GitHub 安装:

dsh plugin --profile desktop add github:sqzw-x/dsh-focus-notify

npm 包发布后,可改用:

dsh plugin --profile desktop add dsh-focus-notify

若只想停用而不卸载,可在 profile 的 cordis.patch.yml 中写:

- id: dsh-focus-notify
  disabled: true

package.json 中声明的 DSH 引擎范围为 >=0.2.0-rc.2 <0.2.1-0 || >=0.2.1-rc.2 <0.3.0-0;实际兼容以 peerDependencies 里的 @deepseek-ai/dsh* 为准。

配置与调试

默认配置即可使用。需要时在页面控制台调用:

__dshFocusNotify.configure({ sound: true })   // 打开提示音
__dshFocusNotify.configure({ enabled: false }) // 暂时全关
__dshFocusNotify.debug()                       // 当前会话、未送达等待、计数器、权限、焦点、导航路径
__dshFocusNotify.test()                        // 绕过规则立刻发一条,验证通道
__dshFocusNotify.open('session-id')            // 按 id 切会话,验证点击路径

debug() 里 navigation 表示点击通知时用哪个服务切会话(uiWorkspace.openSession / sessions.open / none);counters.failed 为导航失败次数。

字段 默认 说明
enabled true 总开关;关闭后仍跟踪状态,不发通知
ignoreSubagent true 子代理会话不提醒
language 'auto' 文案语言,可固定 'zh' / 'en'
sound false 通知外再响一声(WebAudio,需页面有过交互)

配置持久化在 localStorage 的 dshFocusNotify.config。

适用场景与注意

适合谁:经常在 DSH Desktop 开多个会话、需要审批或确认方案、又不想被「页面可见」误判漏通知的开发者。后台会话的完成与待办希望统一推到系统通知栏时,也适合启用。

使用前请知悉:

  • 插件在当前 DSH 进程/页面内运行,安装前请自行查看 源码 与 MIT 许可证。
  • Web 版未验证;通知样式由系统决定(macOS 可在系统设置 → 通知 → DeepSeek Harness 调整)。
  • 权限被拒绝时不发通知,debug().permission 为 denied。
  • 宿主无 retainedBy.mainView 时,所有会话按「非当前」处理,都会提醒。
  • 完成判定用 running 边沿,不用 SDK 的 completionUnread;极短窗口内「客户端尚未看到 running 为 true 就完成」的回复可能不提醒(例如横跨页面重载)。
  • dsh-app:// 页面无法注册 Service Worker,通知上无额外按钮(本插件不依赖按钮)。

社区插件目录 SkillHub 条目 与 GitHub 仓库相互独立,均非 DeepSeek / 幻方官方应用商店。

结尾

dsh-focus-notify 把审批、提问、方案确认和回复完成收成同一种提醒,并用窗口焦点区分「当前会话安静、其它会话随时可弹」,子代理默认静音。若你主要在 DSH Desktop 多会话协作,可按上文命令安装、用 test() 与 debug() 验证通道与导航,再按需打开 sound 或监听 dsh-focus-notify:alert。

  • 目录页:https://www.skillhub.cn/plugins/sqzw-x/dsh-focus-notify
  • GitHub:https://github.com/sqzw-x/dsh-focus-notify
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜