中文EN

dsh-update-checker

dev已测通过npmMIT

DeepSeek Harness 主程序与插件更新管理:对主程序与每个已装插件做 npm/GitHub Release 双源 semver 比对,GUI 横幅按系统语言(中/英)列出可更新项;一键更新——主程序自动备份、完整性校验、失败回滚,插件经临时目录安装不碰其它包;更新后看门狗自动重启服务。「检查更新」设置页提供逐插件版本状态灯、实时更新进度与横幅/通知开关。

下载量 / Downloads
5,648
依赖体积 / node_modules
0.99 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-update-checker

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-update-checker

[English](README.md) | 中文

面向 DeepSeek Harness Web GUI 的常驻 Cordis 插件:自动检查 DeepSeek Harness 主程序与已安装第三方插件的新版本(原独立的 dsh-plugin-checker 已在 v1.1.0 合并进来),向用户提示,并支持一键更新(带成功/失败反馈)。

功能特性

  • 完整更新生命周期 — 检查、备份、更新、回滚、重启,一个插件全部完成。
  • 主程序检查 — 对比已安装的 @deepseek-ai/dsh 与 npm 最新版(全量 packument、稳定版优先、semver 感知)。预发布版本只有在与当前部署同频道时才会安装——跨频道提升(如 rc → alpha)会以 E_PRERELEASE 拒绝,除非显式开启 allowPrerelease,因此绝不会把主框架升进非预期的预发布通道。
  • 第三方插件检查 — 扫描已安装的非官方插件(布局无关,支持 pnpm hoisted 的多位置 node_modules),逐一与 npm/GitHub 双源对比(目标版本取较高者);无发布源的本地工具归入 ignored。同名插件多位置时优先组合所属 profile 的副本(其余记为 copies 供区分),可逐个"不再提醒"排除(excludedPlugins,设置页可一键恢复)。
  • GitHub 更新通道 — 对 GitHub 域使用专用 HTTPS 客户端(兼容本地自签名证书代理;npm registry 仍走严格校验),带重定向跟随、大小上限与超时;codeload tarball 解压前校验构建产物。
  • 界面内横幅 — 跟随 DSH 界面语言(zh/en),显示有更新 / 已是最新 / 失败三种状态,支持"不再提示";更新横幅展示变更说明 brief(vX→vY + 风险等级,有 GitHub release 正文时附更新要点)。
  • 安全的一键更新 — 主程序:dry-run 守卫(只移除更新目标自身传递依赖时放行,只有移除部署根自己声明的包才中止;可用 allowRemove 显式覆盖)→ 快照备份(版本清单 + main-snapshot 里的 @deepseek-ai 整树副本,供离线回滚)→ 布局自适应安装(原位或 -g)→ 安装后回读校验 installed==latest;插件:临时目录安装 + 拷贝、依赖版本核对、npm ≥ 12 自动补 --allow-scripts 构建原生依赖、降级保护(GitHub 探测被限流时不再退回更旧的 npm 版本)与免重命名的原地同步(针对目录被运行中宿主占住的插件)。更新(与回滚)会持久化回 profile 的 package.json + 锁文件(pnpm install --lockfile-only / npm install --package-lock-only),之后的 install 不会再把插件悄悄拉回旧版——不再出现「同一插件反复提醒更新」的死循环。
  • 真回滚 — 主程序 POST /rollback、插件 POST /plugin-rollback;GET /backups.json 列出两者备份。
  • 看门狗重启 — 启动器从当前进程 argv 派生,杀 PID + 端口双保险;恢复确认 = 端口监听 + HTTP 200 探测(GET /restart-status.json)+ 从插件自身路由读回的实例 id,"端口有人应答"不再被当成"新版本已经起来"。
  • 写操作安全 — 所有写路由除 { "confirm": true } 外还要求回环来源(127.0.0.1/::1),局域网客户端无法远程触发更新/重启/回滚。
  • 零配置可移植 — profile 目录 / 组合文件 / 部署根由插件自身安装位置自动推导;状态、备份与日志遵循 DSH_HOME(再退回 ~/.dsh)。任何机器无需改代码。
  • 自挂载(适配 dsh 0.1.6-alpha.2+) — 该版本把 profile 默认解析模式由 "link" 改为 "runtime",于是放在 $DSH_HOME/profiles/node_modules 的第三方插件不再被解析,启动在服务绑定端口之前就以 ERR_MODULE_NOT_FOUND 崩掉。插件现在会在启动时自行重建挂载(ensurePluginMount):为每个 profile 的 node_modules 建一份指向真实包的 junction,并补上各 profile 判定归属所需的 dependencies 声明。幂等、绝不覆盖你刻意设置的规格、绝不删除无法证明是自己副本的目录;mount.json / status.json 可查看状态。

Host 与 Client

  • Host(lib/index.js)— HTTP 路由:status.json(检查)、mount.json(自挂载状态)、suppress、update(支持 dry 预览)、rollback、backups.json、restart、restart-status.json、plugins.json、plugin-update、plugin-rollback、plugin-exclude。
  • Client(lib/client.js)— 在根级 shell.overlay 插槽渲染两个横幅:主程序横幅(更新状态)与插件横幅(可更新插件,支持单个 / 全部更新)。页面加载时各检查一次,之后每 6 小时复查;设置页「检查更新」另提供回滚按钮。

安装与装载

该包是一个 profile bundle(其清单声明了 dsh.bundle.patch)。

# 1) 把包放进 $DSH_HOME/profiles/node_modules/,让 profile 能解析到它。
#    ⚠️ 绝不要在 $DSH_HOME/profiles 目录里直接跑 `npm install`——该目录没有
#    package.json,npm 会把整个 node_modules 判为多余并清空(数据丢失)。
#    安全方式 A —— 临时目录安装后只拷贝本包:
npm i dsh-update-checker --prefix <temp-dir> --no-save
cp -r <temp-dir>/node_modules/dsh-update-checker $DSH_HOME/profiles/node_modules/
#    安全方式 B —— 手动拷贝包目录(git clone 或解包 tarball 后整目录拷入)。

# 2) 在 $DSH_HOME/profiles/web/cordis.patch.yml 增加组合行
# $DSH_HOME/profiles/web/cordis.patch.yml
- insert:
    - id: dsh-update-checker
      name: 'dsh-update-checker'

dsh 0.1.6-alpha.2 之后:profile 还必须有自己的一份链接

只做第 1 步已经不够了。0.1.6-alpha.2 把 profile 的默认模块解析模式从 "link" 改成

"runtime",于是 $DSH_HOME/profiles/node_modules 变成 dsh 受管的共享目录,被排除在

Node 原生解析之外——它现在只服务部署依赖闭包与被选中的 bundle 闭包(见

@deepseek-ai/dsh-app-boot 的 PluginPackages / routeScoped),而第三方插件两者都不属于。

结果就是 profile 里那句裸包名 dsh-update-checker 解析不到,启动在 Web 服务绑定端口之前就崩:

ERR_MODULE_NOT_FOUND: Cannot find package 'dsh-update-checker' imported from …\profiles\web\

(这条报错里的 importer 路径是 dsh 改写过的,真实失败基准是 $DSH_HOME/package.json,

不要相信报错里的那个目录。)修法是两件事,缺一不可:

# 2a) 给 profile 的 node_modules 建一份指向真实包的链接(junction,绝不能用副本)
New-Item -ItemType Junction `
  -Path   "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-update-checker" `
  -Target "$env:USERPROFILE\.dsh\profiles\node_modules\dsh-update-checker"

# 2b) 在 profile 清单里声明依赖
#     $DSH_HOME/profiles/web/package.json → "dependencies": { "dsh-update-checker": "^1.6.1" }

必须是 junction 而不是副本:链接的 realpath 必须仍落在 …/profiles/node_modules/…,

否则 pickDshHome 认不出 Harness home,插件的自我定位会漂移(连带把 @deepseek-ai/*

同步写到错误位置)。而依赖声明是 dsh 的 readProfilePlugins 与本插件自己的

findDeclaringProfiles/persistPluginUpdate 判定"这个插件归哪个 profile"的依据——缺了它,

插件会一直把自己报成"需要更新"。

全新安装时第 2 步不是可选项。 解析不到插件的 profile 会在 composeProfile 阶段就崩掉——

在插件被加载之前——所以插件内部任何代码都救不了那一次启动。安装时(或新增第二个 profile 时)

请手工执行 2a 与 2b,profile 即可起来。

首次成功启动之后,挂载由插件自己维护。 自 v1.6.0 起,它会在启动时、每次插件更新后、每次插件

回滚后重跑 ensurePluginMount:为每个 profile 创建或修复链接,为每个 harness profile 写入依赖

声明;幂等,绝不覆盖你刻意设置的 link:/file: 规格,也绝不删除无法证明是自己副本的目录。

因此后续的 dsh 升级、新加 profile(同一台机器)、链接丢失、版本变化都不必再手工编辑。

随时可用 GET /dsh-update-checker/mount.json(只读)查看状态,status.json 里也带 mount 字段;

POST /dsh-update-checker/mount 可强制复查(与其它写路由一样需要 { "confirm": true } + 回环来源)。

然后让 patch HMR 生效(或重启 dsh web)并刷新页面。

图文安装步骤与常见问题:见 [docs/INSTALL.md](docs/INSTALL.md)。

配置与可移植性

所有路径运行时自动检测——没有任何硬编码:

  • 插件 / profile 目录 — 由插件自身安装位置(import.meta.url)推导,并有两处回退:pnpm isolated 布局下插件真实路径位于 node_modules/.pnpm/…,会沿 .pnpm 回到 profile 自己的 node_modules;插件装在 profiles 树之外(npm 全局安装)时,优先用正在运行的 profile($DSH_PROFILE_DIR、profiles/$DSH_PROFILE)。DSH_UC_PROFILE_NODE_MODULES 可完全覆盖该推导结果(v1.7.3,issue #40)。
  • $DSH_HOME — profiles 根目录的父目录(状态文件、备份、重启日志都在这里)。
  • 组合文件 — 以正在运行的 profile 为准:$DSH_PROFILE_DIR/cordis.patch.yml → profiles/$DSH_PROFILE/… → 补丁里声明本插件的 profile → $DSH_HOME/profiles/web/cordis.patch.yml。(v1.6.3;此前无法判定时一律用 web 默认值,宿主跑在别的 profile 时会读错 node_modules——见 issue #31。)
  • 部署根 — 先 junction realpath 解析,再 `D

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:47,最后更新 2026-10-21

链接

GitHub · Homepage · npm

同类插件