dsh-task-notify
已验证dsh-task-notify · v0.2.0 · MIT · Web 界面
DSH task completion system notifications (host-side node-notifier)
安装
dsh plugin add dsh-task-notify 用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。
源码
发布到 npm 但没有公开仓库。安装前请检查包内容。
标签
作者
说明文档
🔔 dsh-task-notify
DSH(DeepSeek Harness)插件:任务完成 · 系统弹窗通知
模型回答完你的请求,系统立即弹出原生通知——切到别的窗口刷剧、写代码时,再也不怕错过 DSH 的完成信号。
系统通知 · 零侵入 · 防打扰 · 可配置
✨ 特性一览
| 特性 | 说明 |
|---|---|
| 🪟 原生系统通知 | host 端 node-notifier:Windows 通知中心 / macOS 通知 / Linux 原生通知 |
| ✅ 准确的完成信号 | 监听 turn/end (completed),只在模型真正回答完时弹;失败/中断不误报 |
| 📝 回复预览 | 通知正文带模型回答的开头文本(长度可配置) |
| 🧘 防打扰设计 | 默认仅在页面不在前台时弹;秒回的小问答不弹;子代理不弹 |
| 🎛️ 7 项可配置 | 设置页「任务通知」区块可视化调整,或 cordis patch 覆盖 |
| 🛡️ 安全 | 全部 API 经 Host 头信任围栏;与 /api 网关同源校验 |
| 📦 一键安装 | dsh plugin add 自动装依赖 + 自动挂载,零配置 |
📦 安装
前置要求
| 要求 | 说明 |
|---|---|
| DSH | 已安装且 dsh web 可正常运行(首次运行会自动初始化 ~/.dsh/profiles/web) |
| Node.js | ≥ 20 |
| pnpm | ≥ 10 |
方式一:npm 安装(推荐)
dsh plugin --profile web add dsh-task-notify
dsh plugin add自动完成三步:① 安装依赖(node-notifier、schemastery自动带上);② 检测dsh.bundle声明自动挂载;③ 无需手动改任何配置。
方式二:本地开发(link)
cd ~/.dsh/profiles/web
pnpm add "dsh-task-notify@link:<插件目录绝对路径>"
卸载
dsh plugin --profile web remove dsh-task-notify
生效
- host 端(监听逻辑)改动 → 重启
dsh web - client 端(设置面板)改动 → 硬刷新浏览器(Ctrl/Cmd+Shift+R)
🚀 快速使用
# 1. 安装
dsh plugin --profile web add dsh-task-notify
# 2. 重启
dsh web --port 8080
# 3. 使用 —— 让 DSH 跑一个任务,完成后系统弹窗:
# 标题:任务完成 · <工作目录名>
# 正文:模型回答的开头 120 字
💡 默认
onlyWhenBlurred: true——页面在前台时不弹(防打扰)。想测试效果,先把 DSH 页面切到后台/最小化再跑任务。
⚙️ 配置
设置页(推荐)
DSH 设置 → 「任务通知」区块,可视化调整全部选项。
cordis patch 覆盖
~/.dsh/profiles/web/cordis.patch.yml:
- id: task-notify
name: 'dsh-task-notify'
config:
enabled: true # 总开关
onlyWhenBlurred: true # 仅页面不在前台时通知
notifyOnError: false # 出错/中断也通知
maxBodyChars: 120 # 正文预览长度(字符)
minTurnMs: 0 # 最短通知时长(毫秒),过滤秒回
sessions: top-level # all | top-level
showCwd: true # 标题显示工作目录名
配置项详解
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled |
boolean | true |
总开关 |
onlyWhenBlurred |
boolean | true |
仅页面不在前台时通知(client 上报可见性) |
notifyOnError |
boolean | false |
error / aborted / max-tokens 结束也通知 |
maxBodyChars |
number | 120 |
正文预览截断长度(0–500) |
minTurnMs |
number | 0 |
回合短于此时长(毫秒)不通知,过滤快速问答 |
sessions |
'all' | 'top-level' |
'top-level' |
top-level 跳过子代理会话 |
showCwd |
boolean | true |
标题附带工作目录名,区分多会话 |
🧠 工作原理
┌─────────────────────────────── DSH 运行时 ───────────────────────────────┐
│ │
│ ┌─────────────────┐ append ┌─────────────────────────────┐ │
│ │ Agent 回合执行 │ ──────────► │ Session 事件日志(持久化) │ │
│ │ turn/end │ │ session/event 事件流 │ │
│ └─────────────────┘ └──────────────┬──────────────┘ │
│ │ ctx.on('session/event') │
│ ┌──────────────────────────────────────────────▼──────────────┐ │
│ │ dsh-task-notify (host 端) │ │
│ │ · turn/end & reason.kind === 'completed' 触发 │ │
│ │ · 过滤:enabled / sessions / onlyWhenBlurred / minTurnMs │ │
│ │ · 提取该回合最后一条 assistant 文本作正文(截断) │ │
│ │ · node-notifier 弹原生系统通知(失败回退 msg.exe) │ │
│ └──────────────────────────────────────────────┬──────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────▼──────────────┐ │
│ │ dsh-task-notify (client 端) │ │
│ │ · 监听 visibilitychange/blur/focus → POST /task-notify/api/ │ │
│ │ visibility 上报页面可见性,供 onlyWhenBlurred 门控 │ │
│ │ · 设置页「任务通知」区块 → /task-notify/api/settings.* 读写 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
完成信号
| 信号 | 事件 | 说明 |
|---|---|---|
| 主信号 | session/event → turn/end |
reason.kind === 'completed' = 模型回答完一轮 |
| 其他 reason | error / aborted / max-tokens / interrupted |
默认不通知;notifyOnError 开启时前三种也通知 |
安全设计
- 所有
/task-notify/api/*路由经过 Host 头信任围栏(loopback /webRuntime.trustedHosts),与/api网关同一套校验 - 插件只读会话日志,不修改任何 DSH 数据
- 通知内容截断(
maxBodyChars),无敏感信息外泄
📁 项目结构
dsh-task-notify/
├── package.json # dsh.client 声明 + 双端 exports + bundle patch
├── cordis.patch.yml # 挂载声明(dsh plugin add 自动识别)
├── tsconfig.json # 开发类型检查
├── tsconfig.build.json # 构建编译(host 端 tsc → lib/)
├── tsdown.config.ts # client bundle 打包(__ModuleLoader__ 格式)
├── README.md
├── DISTRIBUTE.md # 发布与安装指南
└── src/
├── index.ts # host 端:订阅 turn/end → node-notifier 弹窗
├── config.ts # schemastery 配置 schema(7 项)
├── context-types.ts # cordis Context 类型增强
└── client/
└── index.tsx # client 端:设置面板 + 页面可见性上报
🛠️ 开发与构建
pnpm install # 安装依赖
pnpm typecheck # tsc --noEmit 类型检查
pnpm build # tsc(host) + tsdown(client) → lib/
pnpm watch # tsdown --watch(client 热重载)
pnpm pack # 生成可分发 tarball
构建产物
| 产物 | 说明 |
|---|---|
lib/index.js |
host 端(Node,ESM) |
lib/client.js |
client 端 bundle(window.__ModuleLoader__.load 格式,供浏览器加载) |
lib/*.d.ts |
类型声明 |
发布到 npm
# 改 package.json version → 0.1.x
npm publish
❓ 常见问题
装了但设置页没有「任务通知」区块?
硬刷新浏览器(Ctrl/Cmd+Shift+R)。client 端改动不需要重启 DSH。
任务完成了但没弹通知?
按顺序排查:
- 页面是否在前台?默认
onlyWhenBlurred: true,页面可见时故意不弹(防打扰)——切后台再试,或到设置页关掉该项 - 系统通知权限?Windows「设置 → 系统 → 通知」允许来自 PowerShell/终端的通知;macOS「系统设置 → 通知」
- 检查设置页「任务通知」是否启用了总开关
安装时出现 "missing peer @deepseek-ai/*" 警告?
正常现象。@deepseek-ai/* 由 DSH 运行时提供(不在 profile 的 node_modules 里),pnpm 在 profile 层检查不到所以告警,不影响运行——官方 dsh-better-sidebar 安装时同样如此。
Windows 首次弹窗没反应?
node-notifier 在 Windows 走 PowerShell toast 脚本,首次可能被 SmartScreen 拦截,放行一次即可;插件内置回退(msg.exe),实在不行会在会话日志输出 [dsh-task-notify] 警告。
子代理/后台任务完成也会弹吗?
默认不弹(sessions: top-level 跳过 delegationDepth > 0 的子代理会话)。改为 all 则所有会话都通知。
📄 许可证
dsh-task-notify · 让每一次任务完成都不被错过