🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

升级兼容卫士 zzy6-a/dsh-upgrade-guard

DeepSeek Harness
zzy6-a54 天前有提交已提供中文文档扫描:含敏感能力

宿主升级后自动巡检插件兼容性并修复或回滚

29.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add zzy6-a/dsh-upgrade-guard
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]—
静态安装检查有提示项,装前建议看一眼 README
数据截至 2026/09/25·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 54 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-upgrade-guard(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/21 23:53:39

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 57 处,展示前 55 条)
  • 发起网络请求
    src/client/index.ts:178
    return fetch(API + path, { headers: { 'content-type': 'application/json' }, ...init }).then((response) => response.json())
  • 写入本地文件
    src/hygiene.ts:96
    writeFileSync(paths.profilePatchFile, result.text, 'utf8')
  • 读取本地文件
    src/index.ts:26
    const manifest = JSON.parse(readFileSync(fileURLToPath(new URL('../package.json', import.meta.url)), 'utf8')) as { version?: unknown }
  • 读取本地文件
    src/inventory.ts:63
    return existsSync(join(dir, 'package.json'))
  • 读取本地文件
    src/inventory.ts:71
    return lstatSync(dir).isSymbolicLink() && !existsSync(join(dir, 'package.json'))
  • 读取本地文件
    src/inventory.ts:71
    return lstatSync(dir).isSymbolicLink() && !existsSync(join(dir, 'package.json'))
  • 读取本地文件
    src/inventory.ts:145
    manifest = JSON.parse(readFileSync(join(resolved.dir, 'package.json'), 'utf8')) as Record<string, unknown>
  • 读取本地文件
    src/market.ts:18
    const info = statSync(path)
  • 读取本地文件
    src/market.ts:20
    const text = readFileSync(path).subarray(start).toString('utf8')
  • 读取本地文件
    src/market.ts:33
    ].filter((file) => existsSync(file))
  • 发起网络请求
    src/market.ts:45
    const response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) })
  • 读取本地文件
    src/patch.ts:54
    const existing = files.filter((file) => existsSync(file))
  • 写入本地文件
    src/patch.ts:62
    copyFileSync(file, target)
  • 写入本地文件
    src/patch.ts:106
    writeFileSync(paths.profilePatchFile, next, 'utf8')
  • 写入本地文件
    src/patch.ts:137
    writeFileSync(paths.profilePatchFile, next, 'utf8')
  • 写入本地文件
    src/patch.ts:145
    mkdirSync(paths.backupsDir, { recursive: true })
  • 读取本地文件
    src/patch.ts:149
    try { return readFileSync(paths.profilePatchFile, 'utf8') } catch { return '' }
  • 读取本地文件
    src/paths.ts:39
    const value = JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/paths.ts:163
    if (existsSync(hostDir)) inventory.set('@deepseek-ai/dsh', isDshManifest(hostDir))
  • 读取本地文件
    src/paths.ts:165
    if (existsSync(scopeDir)) {
  • 读取本地文件
    src/paths.ts:179
    return readdirSync(path, { withFileTypes: true })
  • 读取本地文件
    src/probe.ts:58
    for (const variant of variants) if (existsSync(variant)) return variant
  • 发起网络请求
    src/registry.ts:45
    const response = await fetch(url, {
  • 读取本地文件
    src/remediate.ts:43
    const manifest = JSON.parse(readFileSync(join(resolved.dir, 'package.json'), 'utf8')) as { version?: unknown }
  • 读取本地文件
    src/remediate.ts:54
    const manifest = JSON.parse(readFileSync(join(resolved.dir, 'package.json'), 'utf8')) as { scripts?: Record<string, unknown> }
  • 读取本地文件
    src/remediate.ts:237
    if (record.appended === null || record.appended === undefined) return existsSync(paths.profilePatchFile)
  • 读取本地文件
    src/remediate.ts:239
    return readFileSync(paths.profilePatchFile, 'utf8').includes(record.appended)
  • 读取本地文件
    src/remediate.ts:322
    const pid = Number(readFileSync(paths.supervisorPidFile, 'utf8').trim())
  • 读取本地文件
    src/scan.ts:208
    if (roots.some((dir) => existsSync(join(dir, 'package.json')))) {
  • 读取本地文件
    src/scan.ts:267
    if (existsSync(scope)) {
  • 读取本地文件
    src/scan.ts:268
    for (const entry of readdirSync(scope, { withFileTypes: true })) {
  • 读取本地文件
    src/scan.ts:272
    const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as { version?: unknown }
  • 读取本地文件
    src/supervisor-control.ts:50
    const text = readFileSync(file, 'utf8').trim()
  • 读取本地文件
    src/supervisor-control.ts:75
    const logFile = logCandidates.find((file) => existsSync(file)) ?? join(paths.guardDir, 'host.log')
  • 读取本地文件
    src/supervisor-control.ts:104
    const next = readFileSync(source)
  • 读取本地文件
    src/supervisor-control.ts:105
    const prev = existsSync(target) ? readFileSync(target) : null
  • 读取本地文件
    src/supervisor-control.ts:105
    const prev = existsSync(target) ? readFileSync(target) : null
  • 写入本地文件
    src/supervisor-control.ts:106
    if (prev === null || !prev.equals(next)) writeFileSync(target, next)
  • 执行外部命令来自配置/变量
    src/supervisor-control.ts:135
    const child = spawn(process.execPath, [supervisorPath, '--guard-dir', paths.guardDir], {
  • 写入本地文件
    src/supervisor-control.ts:153
    writeFileSync(tmp, JSON.stringify(payload) + '\n', 'utf8')
  • 写入本地文件
    src/supervisor-control.ts:155
    renameSync(tmp, file)
  • 删除本地文件
    src/supervisor-control.ts:158
    try { rmSync(file, { force: true }) } catch { }
  • 写入本地文件
    src/supervisor-control.ts:159
    renameSync(tmp, file)
  • 读取本地文件
    src/supervisor-control.ts:178
    if (!existsSync(paths.incidentsDir)) return []
  • 写入本地文件
    src/supervisor-control.ts:216
    try { writeFileSync(file, JSON.stringify(incident, null, 2) + '\n', 'utf8') } catch { }
  • 读取本地文件
    src/util.ts:5
    if (!existsSync(path)) mkdirSync(path, { recursive: true })
  • 写入本地文件
    src/util.ts:5
    if (!existsSync(path)) mkdirSync(path, { recursive: true })
  • 读取本地文件
    src/util.ts:10
    return JSON.parse(readFileSync(path, 'utf8')) as unknown
  • 读取本地文件
    src/util.ts:18
    const raw = readFileSync(path, 'utf8')
  • 读取本地文件
    src/util.ts:30
    return readFileSync(path, 'utf8')
  • 写入本地文件
    src/util.ts:40
    writeFileSync(tmp, JSON.stringify(value, null, 2) + '\n', 'utf8')
  • 写入本地文件
    src/util.ts:41
    renameSync(tmp, path)
  • 读取本地文件
    src/util.ts:47
    const prev = existsSync(path) ? readFileSync(path, 'utf8') : ''
  • 读取本地文件
    src/util.ts:47
    const prev = existsSync(path) ? readFileSync(path, 'utf8') : ''
  • 写入本地文件
    src/util.ts:48
    writeFileSync(path, prev + line + '\n', 'utf8')
扫描于 2026/11/4(1 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 升级后自动巡检兼容性
  • 修复或禁用插件
  • 启动失败自动回滚

DSH 兼容卫士:宿主升级后自动巡检插件兼容性,支持修复/禁用;宿主启动失败时由宿主外 supervisor 自动救援或回滚到上一个宿主版本。

README

由 DeepSeek 最新模型翻译生成
dsh-upgrade-guard Download license dsh-plugin DeepSeek Harness 兼容卫士。 dsh-upgrade-guard 监视 DSH 宿主版本。升级后首次启动时,它会检查所有已安装插件与新宿主的兼容性,并在你确认后升级、修复、禁用插件,或在必要时回滚到上一个宿主版本——避免一个不兼容的社区插件把整个 harness 留在"起不来"的状态。 DSH 处于开发者预览阶段,破坏性变更会持续发生。这个插件针对的是预期内的失败,而不是边缘情况。 功能 - 升级后自动巡检:宿主版本变化后的首次启动自动触发 - 声明兼容性检查:读取每个已安装插件的 engines.dsh 与 peerDependencies,与解析出的宿主/core 版本比对,沿用生态的方向性策略(低于下限、显式上界 = 风险;隐式 caret 上界 = 警告) - 安装/加载/结构检查:Loader fiber 状态、悬空 junction、core 包遮蔽 - 组合层卫生检查:扫描 cordis.patch.yml 的重复 entry id / 失效 patch 目标,重复项可一键整理(改动前自动备份) - 插件自检 probe:插件可声明 dsh.compat.probe,守卫在隔离子进程里执行并汇总通过/失败
展开完整文档(README 剩余 1 节)
dsh-upgrade-guard

Download
license
dsh-plugin

DeepSeek Harness 兼容卫士。

dsh-upgrade-guard 监视 DSH 宿主版本。升级后首次启动时,它会检查所有已安装插件与新宿主的兼容性,并在你确认后升级、修复、禁用插件,或在必要时回滚到上一个宿主版本——避免一个不兼容的社区插件把整个 harness 留在"起不来"的状态。

DSH 处于开发者预览阶段,破坏性变更会持续发生。这个插件针对的是预期内的失败,而不是边缘情况。

功能

- 升级后自动巡检:宿主版本变化后的首次启动自动触发
- 声明兼容性检查:读取每个已安装插件的 engines.dsh 与 peerDependencies,与解析出的宿主/core 版本比对,沿用生态的方向性策略(低于下限、显式上界 = 风险;隐式 caret 上界 = 警告)
- 安装/加载/结构检查:Loader fiber 状态、悬空 junction、core 包遮蔽
- 组合层卫生检查:扫描 cordis.patch.yml 的重复 entry id / 失效 patch 目标,重复项可一键整理(改动前自动备份)
- 插件自检 probe:插件可声明 dsh.compat.probe,守卫在隔离子进程里执行并汇总通过/失败
- dshmarket 诊断接入:检测到市场插件时自动合并其组合诊断(重复、失效、多版本、peer 不匹配)
- 引导式修复:联网找"与当前宿主兼容的最高版本"(不是盲目 @latest)→ 安装;不行则修复本地安装;再不行则禁用
- 启动失败救援:宿主外 supervisor 在主进程起不来时仍可工作:解析启动日志、禁用故障 entry、重启宿主
- 宿主回滚:禁用仍救不回来时,从快照直接启动上一个宿主版本,无需 sudo/npm
- 手动重启:设置面板 / 弹窗里一键重启 DSH
- 中文界面与通知:巡检结果、事故、操作项展示在设置页与浮层弹窗

工作原理

一个包,三部分:

| 部分 | 位置 | 职责 |
| 宿主插件 | DSH profile bundle | 版本基线、扫描、修复链、HTTP API、settings 命名空间 |
| 客户端 UI | DSH Web 客户端 | 设置页面板、插件卡片、开关、浮层弹窗 |
| Supervisor | 独立 Node 进程 | adopt 宿主、快照宿主版本、崩溃救援、回滚、执行重启 |

运行数据在 ~/.dsh/upgrade-guard/。

组合卫生与插件自检

- 每次巡检会检查 profile 的 cordis.patch.yml:重复的顶层 - id:、dsh --dump-config 报出的失效 patch 目标;面板顶部显示「组合诊断」,有重复项时提供「整理重复项」(保留最后一次,改动前备份)。
- 如果本机装有 dsh-market,守卫会读取它的只读诊断接口并把重复/失效/多版本/peer 不匹配合并进同一块(市场不可用或需要授权时自动跳过,不影响巡检)。
- 插件作者可以声明自检钩子,守卫会在独立 Node 子进程里执行(崩溃/超时不会影响宿主):

{
"dsh": {
"compat": {
"probe": { "file": "./lib/probe.js", "export": "probe", "timeoutMs": 20000 }
}
}
}

// lib/probe.js —— ctx: { hostVersion, profile, dshHome, pluginDir }
export async function probe(ctx) {
const ok = await checkSomethingAgainst(ctx.hostVersion)
return { ok, message: ok ? '正常' : '与当前宿主不兼容的原因' }
}

安装

GitHub Release(当前分发通道)

dsh plugin --profile web add \
https://github.com/zzy6-a/dsh-upgrade-guard/releases/download/v0.2.0/dsh-upgrade-guard-0.2.0.tgz

也可以从 Releases 页面下载 .tgz 后安装本地文件:

dsh plugin --profile web add /path/to/dsh-upgrade-guard-0.2.0.tgz

npm(发布后可用)

dsh plugin --profile web add dsh-upgrade-guard

本地源码(开发)

dsh plugin --profile web add link:/path/to/dsh-upgrade-guard

然后重启一次 DSH(设置 → 升级守卫 → 重启 DSH,或用你的启动器)。之后守卫作为 profile bundle 常驻。

宿主升级后会发什么

1. 对比当前宿主版本与上次记录的版本
2. 审计所有已安装的社区/本地插件
3. 无风险:轻提示"升级后兼容检查通过"
4. 有风险:弹窗列出插件、原因、建议动作
5. 确认后执行修复链,每一步改动前都自动备份:
- 安装与当前宿主兼容的最高版本;否则
- 修复本地安装(pnpm install、有构建脚本则重建);否则
- 在 cordis.patch.yml 写入 disabled 覆盖行(可在面板恢复)
6. 需要重启生效的改动会附一键重启

启动失败救援与回滚如果插件树加载失败,任何宿主内插件都救不了——这时由宿主外 supervisor 兜底:

- 读取最近的启动日志,匹配 failed to apply loader entry ()
- 用 dsh --dump-config(只读)把包名映射成 entry id,备份 patch,写入 disabled: true,重启
- 仍失败或无法归因到插件:从 ~/.dsh/upgrade-guard/host-snapshots// 启动上一个宿主版本,并记录回滚
- 所有动作写入 incidents/,下次成功启动后由插件弹窗展示

快照是宿主目录的完整拷贝(每份约 300MB,保留最近 2 份)。

设置

设置 → 插件 → 插件配置 里的升级守卫卡片:

- 启用升级守卫:软开关;关闭后不自动巡检/提醒,但保留插件、手动检查和 supervisor
- 自动巡检:默认每 5 分钟轻量检查一次
- 当前状态 + 立即检查
- 组合诊断:重复 entry / 失效 patch / 市场诊断摘要;重复项可一键整理
- 卸载升级守卫

cordis.patch.yml 支持组合层默认配置:

- id: dsh-upgrade-guard
config:
autoScanMs: 0 # 自动扫描间隔(毫秒),0 = 仅启动/升级/手动 supervisor: true # 宿主外救援 / 回滚 / 重启 snapshotHost: true # 保留宿主快照用于回滚

HTTP API

仅限本机同源:

- GET /dsh-upgrade-guard/api/state
- POST /dsh-upgrade-guard/api/check
- POST /dsh-upgrade-guard/api/repair { name?, dryRun? }
- POST /dsh-upgrade-guard/api/toggle { name, enabled }
- POST /dsh-upgrade-guard/api/uninstall { name, allowSelf? }
- POST /dsh-upgrade-guard/api/config { enabled?, autoScan? }
- POST /dsh-upgrade-guard/api/patch-fix(整理重复 patch entry,返回备份目录)
- POST /dsh-upgrade-guard/api/restart
- POST /dsh-upgrade-guard/api/alert/ack | alert/ack-all

环境要求

- DSH >= 0.1.5-rc.1
- Node.js >= 22.19
- UI 功能需要 Web profile(其他 profile 仍可执行巡检)

Windows

- 原生 Windows 与 WSL 2 都可用(DSH 官方开发文档两种都支持)
- 守卫只用 Node API;拉起进程加了 windowsHide;Windows 下重启用 taskkill /PID /T /F 杀进程树
- Electron / DSH Desktop 宿主由桌面外壳管理生命周期:守卫跳过 supervisor,重启按钮会提示你使用桌面应用
- Windows 做了代码层兼容,但未做完整实机验证;遇到问题请附 ~/.dsh/upgrade-guard/ 日志提 issue

开发

npm install
npm run typecheck
npm test
npm run build # host: tsc -> lib,client: tsdown -> lib/client.js
npm pack # 产出 dsh-upgrade-guard-.tgz

Supervisor 源码在 scripts/supervisor.mjs,构建时复制进 lib/。

安全与边界

- 守卫会修改文件:cordis.patch.yml,修复过程中会调用包管理器命令;每次写入前都备份到 ~/.dsh/upgrade-guard/backups/
- 不拦截宿主升级,也不修改插件源码;没有兼容版本时只能禁用或回滚
- 未声明兼容信息的插件无法提前判定,只能运行期兜底
- 这是一个独立社区项目,不是 DeepSeek 官方产品

Contributors / 致谢

- zzy6-a — 作者
- DeepSeek V4.1 — 架构设计、实现、测试与发布流程

License

MIT
预览分享卡片长什么样 ↓zzy6-a/dsh-upgrade-guard
分享 · DeepSeek Harness Hub
zzy6-a/dsh-upgrade-guard

宿主升级后自动巡检插件兼容性并修复或回滚

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部