dsh-focus-notify
Manifest valid★ 1Focus-aware notifications for DeepSeek Harness: approvals, questions, plan reviews and finished replies appear as one alert only when the conversation window loses focus; background conversations aler
dsh-focus-notify
English | 中文
给 DeepSeek Harness 的通知插件:审批、提问、方案确认、回复完成,统一当成一种提醒推送。规则只有三条。
规则
- 看会话分:当前会话只在窗口失去焦点时弹;其它会话一律弹,DSH 就在前台也弹。
- 看事件分:轮次结束(回复完成)和等你操作(审批 / 方案确认 / 提问)都会弹。
- 回到会话就收掉:你聚焦到某个会话时,它的通知自动消失 —— 点通知进去、切回窗口、手动切到该会话都算。
子代理会话是个例外:它既不是"当前会话"也不提醒,整个不参与(ignoreSubagent,可以关)。
为什么不用「页面可见」判断
macOS 上窗口被别的应用盖住时,document.hidden 仍然是 false —— 只有最小化 / ⌘H 才会变成 true。按「页面可见就不提醒」实现的插件,会把"DSH 被 Edge/QQ 盖住"误判成"用户正看着它",于是你人在别的应用里时,提问和审批的通知被直接丢掉。
这个插件用的是 document.hasFocus():窗口没有键盘焦点就算你不在。当前会话因此只在你真正盯着它时保持安静;反过来,收通知也要手里有焦点才算数 —— 失焦时切会话不会顺手消掉通知,人可能还在别的应用里。
测试状态
只在 DSH Desktop 上实测过。Web 版能不能正常工作未知(代码里按浏览器语义写了 window.focus() 之类的分支,但没人验证过)。
安装
插件管理器
在「设置 → 插件」里安装本包的目录,启用后重启 DSH Desktop。
命令行
# 从 GitHub 安装
dsh plugin --profile desktop add github:sqzw-x/dsh-focus-notify
从本地目录安装(开发时):
dsh plugin --profile desktop add file:/absolute/path/to/dsh-focus-notify
npm 包发布后,可以改用 dsh plugin --profile desktop add dsh-focus-notify。
装完重启 DSH Desktop:客户端 bundle 在页面加载时读取。停用而不卸载:在 profile 的 cordis.patch.yml 里写
- id: dsh-focus-notify
disabled: true
配置
默认值就能用。想改的话,在页面的控制台里:
__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— 导航调用抛错的次数;失败同时会往控制台打一条[dsh-focus-notify] …警告。
每发出一条通知,插件还会在 window 上派发一个 dsh-focus-notify:alert 事件(event.detail 就是那条 alert:kind / sessionId / title / body / tag),想接自己的提醒方式(闪任务栏、换个声音、记日志)从这里挂即可。
| 字段 | 默认 | 说明 |
|---|---|---|
enabled | true | 总开关;关掉后仍然跟踪状态,只是不发通知 |
ignoreSubagent | true | 子代理会话不提醒 |
language | 'auto' | 文案语言:跟随 DSH 界面语言,也可固定 'zh' / 'en' |
sound | false | 通知之外再响一声(WebAudio,需要页面有过交互) |
配置存在 localStorage 的 dshFocusNotify.config。
它怎么工作
两个只读数据源,都是宿主已经发布好的 store:
uiSession.sessionStatus—Map<sessionId, { running, pendingInteraction, completionUnread }>sessions.list— 会话行(标题、origin: 'subagent'、retainedBy.mainView)
由它们派生出两类事件,对应上面第 2 条规则:
- 等你操作:某个会话出现了
pendingInteraction(审批 / 方案确认 / 提问)。按请求key去重,同一个请求只提醒一次。 - 回复完成:某个会话的
running从true落到false,且没有紧接着的等待(停下来等你输入算"等你操作",不算"完成")。
规则判定集中在 src/engine.ts 的 allows() 里,全部是纯逻辑、不碰 DOM,因此可以脱离浏览器单测。点击通知会唤起窗口(桌面端走 dsh://open 深链,浏览器端 window.focus())并切到对应的会话 —— 切会话调的是宿主的 uiWorkspace.openSession(老宿主上是 sessions.open),调用前绑好实例,失败会记进 counters.failed 并告警,不再像 0.2.0 那样被静默吞掉。手动回去的路子(窗口重新获得焦点、手动切会话)和它走同一个收尾:关掉该会话的通知。没回去过的通知不会自己消失,展示时长仍由系统样式决定。
已知限制
- Web 版未验证:只在 DSH Desktop 上实测过,浏览器里的行为(抬窗、通知权限流程)没人验证。
- 切会话依赖宿主的导航服务:
debug().navigation显示none就说明这个宿主既没有uiWorkspace.openSession也没有sessions.open,点击只能抬窗。 - 只在 DSH Web / DSH Desktop 的页面里工作;
dsh-app://页面注册不了 Service Worker,所以没有通知上的按钮(本插件也不需要)。 - "屏幕上的那个对话"由
retainedBy.mainView推导;宿主没有这一信息时,所有会话都按"非当前"处理(也就是都会提醒)。 - 通知的展示样式由系统决定(macOS:系统设置 → 通知 → DeepSeek Harness)。
- 权限被拒绝时不发通知,
__dshFocusNotify.debug().permission会显示denied。 - 完成判定用
running边沿,不用 SDK 的completionUnread:后者是侧栏的未读圆点,上游在主视图持有该会话时、以及running一旦为真时就清掉它 —— 拿它当"回复完成"的信号会让后台会话的完成提醒静默消失。代价是"客户端还没看到running === true就完成的回复"不提醒(例如回复恰好横跨一次页面重载)。 package.json的dsh.compatibility.dshReleases只是信息性声明:DSH 0.2.0-rc.2 里没有代码读它,真正的兼容闸门是peerDependencies里的@deepseek-ai/dsh*(本包声明的@deepseek-ai/cordis不在被检查的前缀里,因此是惰性的,与上游dsh-client-ui-session等包一致)。
开发
需要 Node 22.18+(构建工具链的要求:tsdown ^22.18.0 || ^24.11.0 || >=26.0.0,CI 跑 22/24;产物本身只跑在浏览器里,与 Node 版本无关)。
npm install
npm run build # tsdown → lib/{index,client,engine}.js
npm run typecheck # tsc --noEmit
npm test # 构建 + node --test
lib/client.js 是浏览器产物,包在 window.__ModuleLoader__.load({ id, factory }) 里(与官方 ui-* bundle 同形),包装由 tsdown.config.ts 的 banner/footer 生成。测试分四层:test/engine.test.mjs 打规则表,test/client.test.mjs 把构建产物放进 vm、按真实宿主的样子造服务实例来加载,test/host.test.mjs 把同一个产物当真正的 cordis 插件挂在真 Context 上跑,test/manifest.test.mjs 盯清单与产物契约。上面说的"只在 Desktop 实测过"指的是真实使用,不是这些测试覆盖了什么。
发布
发布走 npm Trusted Publishing(OIDC),CI 不需要长期 NPM_TOKEN。
- 首次发布:npm 上还没有
dsh-focus-notify,先本地npm login后执行npm publish --access public(或临时用一次性 token 在 CI 发),创建包并确定归属。 - 在 npmjs.com 打开该包 → Settings → Trusted publishing,添加 GitHub Actions:
- Organization or user:
sqzw-x - Repository:
dsh-focus-notify - Workflow filename:
publish.yml - Allowed actions: 勾选 npm publish(
npm stage publish默认允许)
- Organization or user:
- 之后打
v*标签即可由.github/workflows/publish.yml经 OIDC 发布;标签版本须与package.json一致。新配置要在 2 天内完成一次成功发布,否则过期;若 0.3.0 已手动发过,先npm version patch到 0.3.1 再打标签(npm version会通过version脚本同步src/version.ts)。 - 验证通过后删掉
NPM_TOKEN,并在包的 Publishing access 里选 “Require two-factor authentication and disallow tokens”。
# 首版已手动发布过时:升到下一个版本并用 CI 验证 trusted publisher
npm version patch && git push --follow-tags
# 之后的版本
git tag "v$(node -pe 'require("./package.json").version')" && git push origin --tags
License
MIT
Comments
Loading…
Similar plugins
by aokamoaki
Conversation-completion notifications for DeepSeek Harness: Windows toast + sound on turn done / error / goal, plus ask & approval alerts - background-only, with a volume-adjustable bell in the conver
★ 1
↓ 197/wk
MIT
JavaScript
Aug 16, 2026
dsh plugin --profile web add dsh-notifyby weekitmo
Completion and status notifications for DeepSeek Harness: desktop alerts, browser-tab unread counts, and sidebar session indicators, with per-event controls.
★ 0
MIT
TypeScript
Sep 8, 2026
dsh plugin --profile web add dsh-notifyby CoachLeong
DeepSeek Harness plugin: desktop notifications when the model starts, finishes, or needs your input (approval / question / plan review).
★ 0
MIT
TypeScript
Aug 16, 2026
dsh plugin --profile web add dsh-notifyWindows toast notifications when a DeepSeek Harness task finishes: the session title, the outcome, and a summary of the final reply, sent once when the agent really stops rather than once per round of
★ 0
dsh plugin --profile web add dsh-notifyby zjbc2000
🔔 Smart session notifications for DeepSeek Harness (DSH): 4 event types (completed/failed/question/permission), ⭐ main-line/side-line alerts, Web Audio sounds, browser notifications
★ 0
MIT
TypeScript
Sep 26, 2026
dsh plugin --profile web add attention-pluginsby pedesdestiny
Browser desktop notifications for DeepSeek Harness (dsh) — get notified when a turn completes or an approval is needed
★ 3
↓ 443/wk
JavaScript
Aug 18, 2026
dsh plugin --profile web add dsh-notify