Haoxiang-Fant/dsh-task-notice ↗★ 0
dsh-task-notice
DeepSeek Harness 插件:代理任务完工通知(弹窗提示任务完成与本次 Token 消耗)+ 按 API Key 的 Token 消耗统计(缓存输入/缓外输入/输出,1年/6个月/3个月/1个月/15天/1周/24小时/自定义时间范围查询)+ 安全启动(版本兼容与插件冲突检测,冲突或版本不兼容时自动取消插件运行;模块解析失败等异常同样只会停用本插件,保证 DSH 正常启动)。
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:Haoxiang-Fant/dsh-task-notice说明文档
阅读完整 README ↗安装(路径无空格限制) 下载文件后使用
dsh plugin --profile web add "文件路径"
> `dsh plugin add` 会先 `pnpm add` 安装依赖,再把声明了 `dsh.bundle.patch` 的包加入 `dsh.profile.bundles` 层栈。完成后重启 `dsh web` 生效(该 profile 的 `patchReload` 为 live,但依赖变更需要重启)。
>
> 直接用 `dsh plugin add ` 也可以安装(插件会安全降级为停用状态而不是拖垮 DSH),但要用完整功能请用上面的 tarball 方式。
卸载:
```sh
dsh plugin --profile web remove dsh-task-notice
使用
完工通知
- 每个顶层会话(非 subagent)完成一轮任务时,浏览器端收到通知帧后在 Web 界面右上角弹出 toast,并按配置经 Web Notifications API 发送 Windows 系统通知(桌面右下角横幅 + 操作中心);内容为本轮消耗(缓存输入 / 缓外输入 / 输出 / 合计)。
- 目标(goal)完成时同样触发系统通知与网页弹窗,显示该目标自创建以来的总消耗。
- 系统通知由浏览器 Web Notifications API发出(不再依赖宿主 PowerShell):需先在插件设置页点击「授权并开启」(浏览器要求用户手势授权;GUI 需运行在 HTTPS 或 localhost 安全上下文)。开启后,Edge/Chrome 会调用 Windows Notification Platform API,把通知交给 Windows 操作中心统一管理与显示——桌面右下角弹出横幅、存入操作中心;点击通知浏览器自动聚焦回本页面。
- 发送时机可选:默认「仅页面后台时发送」(正在看本页时只显示页内弹窗,切走/最小化后才发系统通知);也可取消该选项,让每次完成都发系统通知。
- 网页弹窗自动消失(默认 15 秒,可配),也可手动关闭;页面隐藏期间弹窗挂起,回到页面后继续计时。
消耗统计
打开 设置(Settings)→ 任务通知与消耗,即可:
- 选择时间范围:24小时 / 1周 / 15天 / 1个月 / 3个月 / 6个月 / 1年 / 自定义(自定义支持起止日期时间)。
- 查看汇总卡片(总消耗、调用次数、缓存输入、缓外输入、输出)。
- 查看按 Key 的表:每个 API Key 一行,列出调用次数、缓存输入、缓外输入、输出与合计;展开可看按模型明细。
- 查看按模型消耗总览:跨全部 Key 聚合每个模型(提供商 · 型号)的调用次数与各类 tokens 消耗,一眼看出不同模型的用量。
口径:缓存输入 =
cacheReadTokens(命中缓存);缓外输入 =inputTokens(未命中缓存);输出 =outputTokens。消耗按每次模型调用的 provider 上报 usage 记账,并按请求所用凭证(如DEEPSEEK_API_KEY)归集。
插件配置
打开 设置 → 任务通知与消耗 页,底部即可调整:
| 字段 | 说明 | 默认 |
|---|---|---|
| 插件总开关 | 关闭后停止通知与记账 | 开 |
| 每轮任务弹窗 | 每完成一轮任务即弹窗 | 开 |
| 目标完成弹窗 | 目标(goal)完成时弹窗 | 开 |
| 弹窗时长(秒) | 弹窗自动消失秒数(3–120,滑块) | 15 |
| 浏览器系统通知 | 经 Web Notifications API 发送系统通知(需页面授权;Edge 横幅 + 操作中心) | 开 |
| 仅后台时发送 | 页面在前台时只显示页内弹窗,切到后台/最小化后才发系统通知 | 开 |
| 账本保留天数 | 消耗账本保留天数(1–3650,滑块) | 365 |
另可在 profile 的 loader 行(cordis.patch.yml 或市场安装补丁)通过 config: 提供安全启动参数:
| 字段 | 说明 | 默认 |
|---|---|---|
| requiredDshVersion | 安全启动要求的最低 DSH 版本 | >=0.1.0-rc.5 |
| conflictingPlugins | 视为冲突的插件名列表(命中即停用本插件) | [] |
安全启动
启动时依次检测,任一失败即取消插件运行(前端设置页会显示原因):
- 版本兼容:找不到
@deepseek-ai/dsh宿主包,或版本不满足requiredDshVersion(默认>=0.1.0-rc.5)。 - 冲突插件:loader 条目中出现
conflictingPlugins中声明的插件名。 - 重复挂载:
dsh-task-notice被挂载了多次(如同时出现在cordis.patch.yml与dsh.profile.bundles)。 - 命名空间占用:其他插件已占用
taskNoticeTypert 服务命名空间。
取消运行后插件只注册 taskNotice.getHealth 查询,不做任何计费/折叠/通知工作;DSH 正常启动。
数据存储
- 账本:
$DSH_HOME/storages/task-notice/usage.json(追加式,原子写,按保留天数裁剪)。 - 配置覆盖:
$DSH_HOME/storages/task-notice/config.json(由设置页写入)。
开发
lib/
index.js 宿主插件入口(name / apply + 安全启动门,零顶层外部 import)
safe-start.js 版本与冲突检测(findDshHostInfo / checkSafeStart)
semver.js 内置最小 semver 范围匹配(无外部依赖)
store.js 消耗账本(usage.json,原子写、保留裁剪)
accounting.js llm/stream 瀑布捕获(usage 块 → 记账)
fold.js 会话日志折叠(turn/end、goal/change → 通知帧)
notify.js 通知枢纽(推送队列 + 流订阅)
keys.js provider → 凭证引用(API Key)解析
service.js taskNotice RPC 服务(getHealth/getConfig/updateConfig/getUsageStats/subscribeNotifications)
typert.host.js 手动注册的 Typert 清单工厂(zod v4 编解码,守卫式动态 import)
client.js 浏览器端(完工弹窗 + 消耗统计/配置设置页)
cordis.patch.yml 本包的 profile 层补丁(挂载一行)
依赖纪律(安全启动的根基):宿主入口零顶层外部 import(只 import Node 内建模块与自身模块);运行期可用的服务(session/settings/credentials/typert/loader/llm)一律经 ctx 访问;唯一的外部包 zod(Typert 编解码强制要求)在 apply() 内用 try/catch 包裹的动态 import 加载。这样即使依赖解析失败(如 Windows link: 安装的 junction realpath 陷阱),也只让本插件停用,DSH 照常启动——从结构上杜绝了社区插件「不存在的命名导出在模块求值期抛 SyntaxError 导致整个 dsh 无法启动」的灾难。
使用
完工通知
- 每个顶层会话(非 subagent)完成一轮任务时,浏览器端收到通知帧后在 Web 界面右上角弹出 toast,并按配置经 Web Notifications API 发送 Windows 系统通知(桌面右下角横幅 + 操作中心);内容为本轮消耗(缓存输入 / 缓外输入 / 输出 / 合计)。
- 目标(goal)完成时同样触发系统通知与网页弹窗,显示该目标自创建以来的总消耗。
- 系统通知由浏览器 Web Notifications API发出(不再依赖宿主 PowerShell):需先在插件设置页点击「授权并开启」(浏览器要求用户手势授权;GUI 需运行在 HTTPS 或 localhost 安全上下文)。开启后,Edge/Chrome 会调用 Windows Notification Platform API,把通知交给 Windows 操作中心统一管理与显示——桌面右下角弹出横幅、存入操作中心;点击通知浏览器自动聚焦回本页面。
- 发送时机可选:默认「仅页面后台时发送」(正在看本页时只显示页内弹窗,切走/最小化后才发系统通知);也可取消该选项,让每次完成都发系统通知。
- 网页弹窗自动消失(默认 15 秒,可配),也可手动关闭;页面隐藏期间弹窗挂起,回到页面后继续计时。
消耗统计
打开 设置(Settings)→ 任务通知与消耗,即可:
- 选择时间范围:24小时 / 1周 / 15天 / 1个月 / 3个月 / 6个月 / 1年 / 自定义(自定义支持起止日期时间)。
- 查看汇总卡片(总消耗、调用次数、缓存输入、缓外输入、输出)。
- 查看按 Key 的表:每个 API Key 一行,列出调用次数、缓存输入、缓外输入、输出与合计;展开可看按模型明细。
- 查看按模型消耗总览:跨全部 Key 聚合每个模型(提供商 · 型号)的调用次数与各类 tokens 消耗,一眼看出不同模型的用量。
口径:缓存输入 =
cacheReadTokens(命中缓存);缓外输入 =inputTokens(未命中缓存);输出 =outputTokens。消耗按每次模型调用的 provider 上报 usage 记账,并按请求所用凭证(如DEEPSEEK_API_KEY)归集。
插件配置
打开 设置 → 任务通知与消耗 页,底部即可调整:
| 字段 | 说明 | 默认 |
|---|---|---|
| 插件总开关 | 关闭后停止通知与记账 | 开 |
| 每轮任务弹窗 | 每完成一轮任务即弹窗 | 开 |
| 目标完成弹窗 | 目标(goal)完成时弹窗 | 开 |
| 弹窗时长(秒) | 弹窗自动消失秒数(3–120,滑块) | 15 |
| 浏览器系统通知 | 经 Web Notifications API 发送系统通知(需页面授权;Edge 横幅 + 操作中心) | 开 |
| 仅后台时发送 | 页面在前台时只显示页内弹窗,切到后台/最小化后才发系统通知 | 开 |
| 账本保留天数 | 消耗账本保留天数(1–3650,滑块) | 365 |
另可在 profile 的 loader 行(cordis.patch.yml 或市场安装补丁)通过 config: 提供安全启动参数:
| 字段 | 说明 | 默认 |
|---|---|---|
| requiredDshVersion | 安全启动要求的最低 DSH 版本 | >=0.1.0-rc.5 |
| conflictingPlugins | 视为冲突的插件名列表(命中即停用本插件) | [] |
插件配置
打开 设置 → 任务通知与消耗 页,底部即可调整:
| 字段 | 说明 | 默认 |
|---|---|---|
| 插件总开关 | 关闭后停止通知与记账 | 开 |
| 每轮任务弹窗 | 每完成一轮任务即弹窗 | 开 |
| 目标完成弹窗 | 目标(goal)完成时弹窗 | 开 |
| 弹窗时长(秒) | 弹窗自动消失秒数(3–120,滑块) | 15 |
| 浏览器系统通知 | 经 Web Notifications API 发送系统通知(需页面授权;Edge 横幅 + 操作中心) | 开 |
| 仅后台时发送 | 页面在前台时只显示页内弹窗,切到后台/最小化后才发系统通知 | 开 |
| 账本保留天数 | 消耗账本保留天数(1–3650,滑块) | 365 |
另可在 profile 的 loader 行(cordis.patch.yml 或市场安装补丁)通过 config: 提供安全启动参数:
| 字段 | 说明 | 默认 |
|---|---|---|
| requiredDshVersion | 安全启动要求的最低 DSH 版本 | >=0.1.0-rc.5 |
| conflictingPlugins | 视为冲突的插件名列表(命中即停用本插件) | [] |