dsh-download-monitor

by keepermttl

1 工作流与自动化github收录于 08-23

DSH Web GUI 下载监控插件: agent 拉起下载后即可离开 ,插件自动监控并在页面右下角以 悬浮窗展示进度;任务 完成 / 停滞 / 失败 时,插件向注册会话发送结构化报告并把 agent 唤醒; 用户可一键停止任务 (不唤醒、留痕); 历史任务留痕 (合并批次、可删可关)。

DSH Web GUI download monitor plugin

安装

dsh plugin --profile web add github:keepermttl/dsh-download-monitor

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗

安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。

README

目录

DSH Web GUI 下载监控插件:agent 拉起下载后即可离开,插件自动监控并在页面右下角以 悬浮窗展示进度;任务完成 / 停滞 / 失败时,插件向注册会话发送结构化报告并把 agent 唤醒; 用户可一键停止任务(不唤醒、留痕);历史任务留痕(合并批次、可删可关)。

特性

  • 注册制监控:agent 把下载任务写进 manifest(~/.dsh/dlmon/tasks.json),插件 host 半区 自动监听;支持三种任务形态:
    • dir:监控目录(对其直接子文件求和算进度),适合 cascette/aria2 这类下载器;
    • process:dir + 进程存活检测(进程退出且未完成 → 失败;停止时直接终止进程);
    • job:DSH 后台任务(browser 半区合并 job 状态显示;完成通知走 DSH 原生机制)。
  • 状态机:pending → running → completed / failed / stalled / stopped;判定依据: 期望字节数、日志完成/错误正则(donePatterns / errorPatterns)、进程存活、 停滞阈值(默认 120 秒无字节增长)。
  • 悬浮窗:shell.overlay 槽位(官方浮动层),右下角,面板与折叠胶囊都可拖拽、 可折叠;「进行中 / 历史」两个分区;每任务显示状态点、进度条、速度、ETA、失败原因; 皮肤全适配(--dsw-* 令牌)。
  • 停止任务:运行/停滞任务行有「停止」(两步确认防误触):process 任务直接终止进程; dir/job 标记停止。停止 = 终态、不生成唤醒报告(并清掉已排队的报告),manifest 写入 stoppedBy: 'user' 标记,agent 可直接看到是用户主动停止。
  • 历史留痕:终态任务(完成/失败/停止)按批次合并记录到 ~/.dsh/dlmon/history.json (同一次 manifest 写入自动成批;batchId 显式成批),每条含简短总结(结果、进度、 来源会话 id、时间);默认保留 20 条(historyCap 可调),可单条删除,可整体关闭 (historyEnabled)。
  • 唤醒闭环:完成/失败/停滞 → host 入队 → 浏览器经 session.prompt 向注册会话发送 【下载监控】 报告 → agent 处理后可 ack(确认后不再重复打扰);每次状态转换只唤醒一次, 会话存储去重、可全局关闭唤醒;prompt 被拒绝(如 sessionId 不存在)会重试并告警,绝不误报已投递。
  • 工作流固化:全局技能 download-monitor(~/.dsh/skills/download-monitor/SKILL.md)—— 所有会话在涉及下载时自动按本协议注册任务、处理唤醒、查询历史。
  • 零框架依赖:不 import 任何 @deepseek-ai/* 值(全部结构类型,dsh-archive-viewer 先例), 不修改 DSH 源码,纯 cordis.patch.yml + profile 挂载。

安装

前置:Node.js ≥ 22、pnpm、dsh CLI(不在 PATH 时用 node --import tsx/esm <deepseek-harness>/apps/cli/src/bin.ts)。

git clone https://github.com/keepermttl/dsh-download-monitor.git
cd dsh-download-monitor
pnpm install
pnpm build

# 安装进 web profile(link: 指向本目录)
dsh plugin --profile web add link:$(pwd)        # POSIX
dsh plugin --profile web add link:E:\path\to\dsh-download-monitor   # Windows

重启 dsh web,浏览器 Ctrl+F5 硬刷新。重启后悬浮窗在右下角出现(有任务时)。

任务注册(manifest 协议)

~/.dsh/dlmon/tasks.json:

{
  "version": 1,
  "tasks": [
    {
      "id": "wow-base",
      "label": "魔兽基础包续传",
      "kind": "process",
      "targetDir": "E:\\WoW_68974\\Data\\data",
      "expectedBytes": 82900000000,
      "pid": 12345,
      "logPath": "C:\\Users\\32701\\AppData\\Local\\Temp\\opencode\\wow_base_watchdog.log",
      "errorPatterns": ["All connection attempts failed", "Traceback"],
      "donePatterns": ["Installing 0 files"],
      "sessionId": "<注册该任务的会话 id>",
      "notify": { "onDone": true, "onProblem": true },
      "ack": false
    }
  ]
}

字段说明:

字段 必填 说明
id / label 是 唯一 id / 显示名
kind 是 dir / process / job
targetDir dir/process 监控目录(直接子文件求和 = 进度)
expectedBytes 否 完成判据之一(字节达标即完成)
pid process 进程存活检测
logPath + errorPatterns / donePatterns 否 日志尾随(最近 64KB)正则;patterns-without-log 会被拒绝
sessionId 是 唤醒目标会话——必须用完整 id(含 session- 前缀,如 session-65d36e62-…),取自 GUI 会话信息或 session.list;裸 uuid 会被 host 拒绝(插件会警告)
notify 否 默认全开
ack 否 agent 处理后置 true,插件停止该任务唤醒

也可经 RPC 注册(浏览器/agent 侧工具):POST /dsh-download-monitor/register,见 src/types.ts 的 wire 契约。

agent 行为协议

  1. 拉起下载(后台 job 或独立进程)→ 写 manifest(sessionId 填当前会话)→ 结束回合;
  2. 收到 【下载监控】 前缀消息 = 插件唤醒:按报告处置(续传/重试/校验/下一阶段);
  3. 处理完后把 manifest 里该任务 ack 置 true(或悬浮窗点「确认」)→ 再次结束回合休息。

悬浮窗操作

  • 胶囊 → 点击展开面板;胶囊与面板头部都可拖拽(位置记忆在 localStorage)。
  • 「进行中」每行:状态点 / 进度条 / 字节 / 速度 / ETA / 失败原因;运行/停滞任务可 「停止」(两步确认:process 直接杀进程,dir/job 仅标记,均不唤醒); 完成/失败任务可点「确认(ack)」。
  • 「历史」分区:按批次合并的终态任务(标签/结果徽标/总结/来源会话/完成时间),可单条删除。
  • 「设置」:唤醒报告总开关、历史留痕开关、历史保留条数(5-200)、停滞阈值、采样间隔 (写回 ~/.dsh/dlmon/state.json)。

agent 使用协议(技能)

全局技能 download-monitor 已注册(~/.dsh/skills/download-monitor/SKILL.md),所有会话在 涉及下载时自动加载。核心:启动下载 → 注册 manifest(sessionId 必须带 session- 前缀; 批量任务同一次写入或显式 batchId)→ 结束回合休息;收到 【下载监控】 唤醒 → 处理并 ack; 用户停止的任务(stoppedBy: 'user')不重启不补报告;查询历史读 history.json。

开发

pnpm typecheck   # tsc --noEmit
pnpm test        # vitest(状态机 / manifest 校验 / 报告文本 / job 合并)
pnpm build       # tsdown:lib/index.js(host)+ lib/client.js(browser)

已知边界(v1)

  • 不自动重启下载器(观察 + 唤醒,决策权留给 agent);
  • job 形态任务:只做状态显示,唤醒走 DSH 原生 job 完成通知;
  • 日志尾随只取最后 64KB,错误正则建议用无锚点的行级表达式;
  • 悬浮窗只对注册了任务时可见;多标签页各自渲染,唤醒按 manifest 的 sessionId 投递。

排障(本机实战教训)

  • dsh plugin add 后启动报 duplicate loader entry id: ui-web-ui-settings: pnpm 重装会把 profile 的 node_modules 重排,file: 链接可能出现新旧两份导致 loader 重复挂载同一 patch。修复:在 profile 目录重跑 pnpm install(或 pnpm add <同款依赖> 触发重解析),再重启。建议在重启前先做预检: node --import tsx/esm <checkout>/apps/cli/src/bin.ts web --port 3099(另一个端口), 确认无 loader 报错且端口监听后再动真身。
  • GUI 进程就是 agent 进程:重启 dsh web 会杀掉当前回合的 agent。脚本 scripts/restart-gui.ps1 用独立进程完成"杀旧起新"(状态写 %TEMP%\dsh-web-restart.status.json), 但保险起见:重启前先告知用户,重启后刷新页面并发消息恢复。
  • 验证 host 半区存活(无需重启、无需浏览器):
    $body = @{ type='client-request'; rpcId='p'; method='snapshot'; payload=@{} } | ConvertTo-Json -Compress
    Invoke-WebRequest -Uri 'http://127.0.0.1:3080/dsh-download-monitor/snapshot' -Method POST `
      -ContentType 'application/json' -Body $body -UseBasicParsing
    
    返回 ok:true 即 host 已挂载(配置与任务清单都在响应里)。

许可

MIT © keepermttl。欢迎使用、修改、引用或收录进自己的插件合集,保留 LICENSE 与出处即可。

原始 README: https://github.com/keepermttl/dsh-download-monitor/blob/main/README.md ↗