Back to home@dp419936514

dsh-plugin-updater

Safe one-click plugin updater for DeepSeek Harness (dsh): backup, verified update with real boot smoke test, auto-rollback, and a launch-aware restart button. 深度求索 Harness 插件安全一键更新器

Stars
0
Language
JavaScript
Created
Sep 9, 2026
Updated
Sep 9, 2026
GitHub repo

Introduction

dsh-plugin-updater

dsh platform license version

DeepSeek Harness(dsh)插件安全一键更新器:清单、备份、经过验证的更新、失败自动回滚、手动回滚,以及一个懂你启动方式的重启按钮。

目标只有一个 —— 更新永远不把 dsh 搞坏。做不到"更新后一定能启动"的更新,会被自动回滚到更新前。

screenshot

为什么需要它

dsh 的插件是 profile 目录里的 pnpm 依赖,组合成 dsh.profile.bundles 层叠。直接 pnpm up --latest(或某些市场类插件的"一键更新")有几个经典翻车点:

翻车点本插件的对策
pnpm 中途失败,profile 半残更新前先备份 package.json / pnpm-lock.yaml / pnpm-workspace.yaml / cordis.patch.yml 四件套
更新后从不验证,重启才发现起不来更新后 dsh --dump-config 组合校验 + 在临时端口真实启动一次,看到 dsh web: 才算通过(约 1–2 秒)
只跑 pnpm 不做 bundles 对账,新版插件丢了 dsh.bundle 声明复刻 dsh plugin 官方 reconcile 规则,层列表与实际安装同步
校验失败没有退路任何一步失败 → 自动还原备份 → pnpm install --frozen-lockfile → 再校验 → 报告"已回滚"
--latest 把精确锁定改写pnpm add name@版本 分组执行,精确锁定走 --save-exact 保持锁定风格;锁定插件默认不勾选
动了不该动的核心包只更新第三方依赖;内置 @deepseek-ai/* bundle 不是依赖,天然不受影响

pipeline

功能特性

  • 插件清单 — 插件名、当前版本、可升级版本、已锁定(精确版本)/已弃用/本地依赖 徽章,一键刷新(pnpm outdated)。
  • 两种更新模式升级到最新版(默认)与 仅范围内(不改版本约束);跨大版本时给出醒目提示。
  • 一键更新所选 — 勾选、二次确认、实时进度日志、逐插件 旧 → 新 结果汇报。
  • 自动回滚 + 手动回滚 — 失败自动还原;设置页里任选一个历史备份回滚(保留最近 10 份),回滚同样经过校验。
  • 懂启动方式的重启按钮 — 自动检测 dsh 的启动方式:
    • systemd 用户服务(如 dsh-web.service)→ systemctl --user restart,由 systemd 监护停止与拉起,无端口竞态;
    • 前台 / nohup / tmux 启动 → 分离的重新拉起器:等旧进程优雅退出后,以相同 argv / cwd / env 重新执行;
    • 重启期间页面断连属预期,服务恢复后设置页自动刷新
  • 操作历史 — 每次更新/回滚的结果落在 <profile>/.dsh-plugin-updater/history.jsonl,设置页可见。
  • 命令行恢复通道 — dsh 起不来时 bin/dpu.mjs 照常可用。

安装

以 web profile 为例(dsh ≥ 0.1.0-rc.5,Node ≥ 20):

# 方式一:直接从 GitHub 安装
dsh plugin --profile web add github:dp419936514/dsh-plugin-updater

# 方式二:clone 后以本地路径安装(便于自行修改)
git clone https://github.com/dp419936514/dsh-plugin-updater ~/.dsh/plugins/dsh-plugin-updater
dsh plugin --profile web add ~/.dsh/plugins/dsh-plugin-updater

重启 dsh web 后,设置页出现「插件更新」分区。卸载:dsh plugin --profile web remove dsh-plugin-updater

方式二以 link: 依赖安装,改源码后重跑一次 add(或在该 profile 目录 pnpm install)并重启即可生效;从 GitHub 更新本插件自身:重跑方式一的 add 命令。

使用

设置页

设置 → 插件更新:

  1. 打开即自动读取清单;也可点右上「刷新清单」;
  2. 勾选要更新的插件(精确锁定的默认不勾,标 已锁定),选模式;
  3. 「一键更新所选」→ 二次确认 → 看进度日志(pnpm 输出、组合校验、启动冒烟逐条可见);
  4. 成功后点「重启 dsh」生效;失败则已自动回滚,日志里写明原因;
  5. 需要时在回滚区选任意备份一键回滚。

命令行(dsh 起不来时的恢复通道)

cd ~/.dsh/plugins/dsh-plugin-updater   # 或 clone 目录
node bin/dpu.mjs check                  # 清单与可更新项(默认 profile 自动检测)
node bin/dpu.mjs update --yes           # 升级所有可升级插件(精确锁定的跳过)
node bin/dpu.mjs update --targets dsh-cost-meter --yes   # 只更一个(含锁定插件)
node bin/dpu.mjs rollback               # 回滚到最新备份
node bin/dpu.mjs backups                # 备份列表与操作历史
node bin/dpu.mjs restart [--unit dsh-web.service] --yes  # 重启 systemd 用户服务

行配置(可选)

在 profile 的 cordis.patch.yml 里覆盖:

- id: plugin-updater
  config:
    profile: web         # 管理哪个 profile(默认自动检测本插件所在 profile)
    bootVerify: true     # 更新后是否真实启动冒烟(默认开;关掉只剩组合校验)

环境变量:DPU_RESTART_MODE=self|systemdDPU_RESTART_UNIT=<name> 可强制重启方式。

工作原理

lib/engine.js   纯 Node 管线:清单/备份/分组 pnpm add/bundles 对账/双重校验/回滚/历史
lib/index.js    宿主半:webServer 前缀路由 /plugin-updater/api(loopback+同源栏,与 /api 网关同款)
lib/client.js   浏览器半:lazy-CJS 工厂格式,注册「插件更新」设置分区
bin/dpu.mjs     CLI 恢复通道

校验两段式:--dump-config 抓组合层错误(缺包/坏 patch/配置 schema);--port 0 --no-open 冒烟抓激活错误(行未激活、服务冲突、client bundle 缺失);非 web profile(静默启动)则用"存活即通过"的探活窗口。

FAQ

Q: 和直接 pnpm up --latest 有什么本质区别? A: 备份、锁定风格保持、bundles 对账、双重校验、失败自动回滚。pnpm up 只负责把文件改掉,后面的五件事它都不做 —— 而翻车恰恰都在这五件里。

Q: 更新过程中途断电/被杀怎么办? A: 备份目录(<profile>/.dsh-plugin-updater/backups/<时间戳>/)里躺着四件套,node bin/dpu.mjs rollback 一条命令还原 + 冻结锁重装 + 校验。

Q: 为什么更新完要重启? A: 运行中的 dsh 已把旧版本加载进内存;新版在重启后生效。设置页的「重启 dsh」按钮会按检测到的启动方式(systemd / 自重启)替你完成。

English

A safe one-click plugin updater for DeepSeek Harness (dsh) profiles. Before touching anything it backs up the four files an update can affect; after updating it reconciles dsh.profile.bundles exactly like dsh plugin does, then verifies the profile twice — once via --dump-config composition, once by really booting it on an ephemeral port and watching for the dsh web: URL line. Any failure triggers automatic rollback (restore + frozen-lockfile reinstall + re-verification). Exact version pins are preserved (--save-exact), pinned plugins are opt-in, in-box @deepseek-ai/* bundles are never touched. Ships a settings-section UI, a launch-context-aware restart button (systemd user unit or detached self-relaunch), and a CLI (bin/dpu.mjs) usable as a recovery channel when a profile no longer boots.

License

MIT