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

插件更新中心 darkings/dsh-plugin-update-center

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

集中检查并排队更新插件,支持快照回滚与残留清理

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add darkings/dsh-plugin-update-center
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →

可信度证据

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

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

可执行外部命令读写/删除本地文件
查看扫描证据(共 27 处,展示前 27 条)
  • 写入本地文件
    lib/backup.js:45
    await mkdir(dir, { recursive: true })
  • 读取本地文件
    lib/backup.js:49
    if (!existsSync(source)) continue
  • 读取本地文件
    lib/backup.js:53
    const manifest = JSON.parse(await readFile(join(profileDir, 'package.json'), 'utf8'))
  • 写入本地文件
    lib/backup.js:54
    await writeFile(join(dir, 'meta.json'), JSON.stringify({
  • 读取本地文件
    lib/backup.js:68
    const entries = (await readdir(snapshots, { withFileTypes: true }).catch(() => []))
  • 删除本地文件递归
    lib/backup.js:73
    await rm(join(snapshots, old), { recursive: true, force: true }).catch(() => {})
  • 写入本地文件
    lib/backup.js:80
    await mkdir(root, { recursive: true })
  • 写入本地文件
    lib/backup.js:81
    await writeFile(join(root, 'history.jsonl'), JSON.stringify({ at: clock(), ...entry }) + '\n', { flag: 'a' })
  • 读取本地文件
    lib/engine.js:147
    return JSON.parse(await readFile(path, 'utf8'))
  • 读取本地文件
    lib/engine.js:269
    if (entry !== null && !existsSync(join(dir, entry))) return { ok: false, reason: 'entry-missing' }
  • 读取本地文件
    lib/engine.js:271
    if (typeof patch === 'string' && !existsSync(join(dir, patch))) return { ok: false, reason: 'patch-missing' }
  • 读取本地文件
    lib/residue.js:55
    if (existsSync(join(profileDir, 'node_modules', root, MANIFEST_FILE))) continue
  • 读取本地文件
    lib/residue.js:66
    if (!existsSync(path)) continue
  • 读取本地文件
    lib/residue.js:83
    manifest = JSON.parse(await readFile(join(profileDir, MANIFEST_FILE), 'utf8'))
  • 读取本地文件
    lib/residue.js:115
    patchText = await readFile(join(profileDir, PATCH_FILE), 'utf8')
  • 写入本地文件
    lib/residue.js:184
    await writeFile(temporary, text, 'utf8')
  • 写入本地文件
    lib/residue.js:185
    await rename(temporary, path)
  • 读取本地文件
    lib/residue.js:205
    const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
  • 读取本地文件
    lib/residue.js:225
    const original = await readFile(patchPath, 'utf8')
  • 读取本地文件
    repair.mjs:46
    if (!existsSync(join(profileDir, 'package.json'))) fail('profile not found: ' + profileDir)
  • 读取本地文件
    repair.mjs:49
    const entries = await readdir(snapshotsRoot, { withFileTypes: true }).catch(() => [])
  • 读取本地文件
    repair.mjs:58
    meta = JSON.parse(await readFile(join(snapshotsRoot, name, 'meta.json'), 'utf8'))
  • 写入本地文件
    repair.mjs:81
    await mkdir(brokenDir, { recursive: true })
  • 读取本地文件
    repair.mjs:85
    if (!existsSync(source)) continue
  • 读取本地文件
    repair.mjs:94
    if (!existsSync(source)) continue
  • 读取本地文件
    repair.mjs:112
    return candidates.find((candidate) => existsSync(candidate))
  • 执行外部命令固定命令
    repair.mjs:123
    const result = spawnSync('cmd.exe', ['/d', '/s', '/c', `"${dsh}" plugin --profile ${profile} install`], {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

尊重 DSH 原始风格的插件更新插件:侧边栏检查/排队更新、快照回滚、卸载残留清理

README

由 DeepSeek 最新模型翻译生成
dsh-plugin-update-center 尊重 DSH 原始风格的插件更新插件:检查 profile 里已安装插件的 npm 新版本,在侧边栏集中、可排队地更新,并用进度条显示进度;带快照回滚、安装后校验、卸载残留清理和离线恢复。 GitHub: https://github.com/darkings/dsh-plugin-update-center · npm: https://www.npmjs.com/package/dsh-plugin-update-center 它只更新 npm registry 来源的 profile 插件。DSH 自带插件、github: / git: / file: / link: / workspace: 安装的插件、以及 DSH 本体更新都不在这里处理。 界面 - 入口:侧边栏底部登录名右侧,与 DSH 自己的更新提示并排(同一个 triggerRow,插件更新 chip 在账号按钮之后、DSH 更新 chip 之前)。 - 该位置没有官方 list 插槽,所以用 shell.overlay + React portal 把 chip 挂进账号行;chip 的高度、字号、品牌色 tint 与 DSH 的 DesktopUpdateIndicator 一致。
展开完整文档(README 剩余 1 节)
dsh-plugin-update-center

尊重 DSH 原始风格的插件更新插件:检查 profile 里已安装插件的 npm 新版本,在侧边栏集中、可排队地更新,并用进度条显示进度;带快照回滚、安装后校验、卸载残留清理和离线恢复。

GitHub: https://github.com/darkings/dsh-plugin-update-center · npm: https://www.npmjs.com/package/dsh-plugin-update-center

它只更新 npm registry 来源的 profile 插件。DSH 自带插件、github: / git: / file: / link: / workspace: 安装的插件、以及 DSH 本体更新都不在这里处理。

界面

- 入口:侧边栏底部登录名右侧,与 DSH 自己的更新提示并排(同一个 triggerRow,插件更新 chip 在账号按钮之后、DSH 更新 chip 之前)。
- 该位置没有官方 list 插槽,所以用 shell.overlay + React portal 把 chip 挂进账号行;chip 的高度、字号、品牌色 tint 与 DSH 的 DesktopUpdateIndicator 一致。
- 更新 chip:下载图标;没有可更新插件时不显示;有更新时显示数量;排队时显示时钟图标;更新中显示旋转图标和 n/total。
- 残留 chip:垃圾桶图标 + 警告色(与更新 chip 的下载图标和品牌色明确区分);发现卸载残留时出现,点击打开残留窗口。
- 点击更新 chip 打开 DSH 原生风格的弹窗:勾选要更新的插件,点「更新 N 个插件」。
- 有任务在运行时,按钮变成「任务完成后自动更新」;点击进入队列,任务全部结束并静默后自动开始。
- 更新开始后弹窗切换为进度视图:总进度条、当前插件、每个插件的状态(等待 / 核对版本 / 移除旧版 / 安装新版 / 已更新 / 待重启 / 失败)。
- 全部完成后统一提示:需要重启就只提示重启;否则需要刷新页面就自动刷新(3 秒倒计时,可取消)。
- 不需要时可以关闭弹窗、让任务在后台继续;完成后再打开查看结果。

检查逻辑

1. 读取 pluginManager.listBundles(),只保留 installed 且 availability === "profile"、可移除、无错误的 bundle。
2. 解析依赖来源,只接受 name@版本/范围 形式的 npm registry 安装;其余来源跳过。
3. 查询 registry.npmjs.org(失败时回退 registry.npmmirror.com):
- dist-tags.latest
- 对应版本的 manifest
4. 过滤:稳定版(非预发布)、未 deprecated、带 dsh.bundle、sha512 integrity 合法、engines.dsh / engines.node 兼容当前 DSH。
5. 最新版严格大于已装版本时才显示为可更新。

检查结果在 Host 内存中缓存 30 分钟;页面刷新不会重复请求,弹窗里的「重新检查」会强制刷新。

更新逻辑

当前 DSH 的 pluginManager 没有 updateBundle,所以单个插件按官方插件页同样的方式更新:

removeBundle(name)
installBundle(${name}@${latest}, { enabled: 原状态, saveExact: true, registry, requestId })

- 安装失败:自动装回旧版本,记录失败并停止后续插件。
- 更新前再次核对版本与 integrity,防止检查后发布变化。
- 保留插件原来的启用/停用状态。
- 有任务正在运行或已有更新任务时不会直接更新;可以选择「任务完成后自动更新」进入队列。
- 不自动重启 DSH,也不更新 DSH 本体。DSH 本体有更新(available/downloading/installing/ready)时禁止插件更新。

进度条口径:由于官方 API 不暴露 pnpm 的字节级下载进度,进度按「已完成插件数 + 当前阶段权重」推进(核对 5% → 移除 35% → 安装 65% → 完成 100%),而不是按下载百分比。

排队与生效

- 有任务(对话 turn 或后台 job)时,点击「更新」会返回 busy-session;弹窗显示「任务完成后自动更新」,点击后进入 Host 侧队列。
- 队列等待所有任务空闲,再静默 10 秒,然后 5 秒倒计时开始;倒计时内来新任务会退回等待。
- 每个插件开始前再查一次任务;运行中来新 conversation,当前插件安装完后暂停,任务结束再恢复。
- 队列在页面刷新/关闭后保留(Host 内存);Host 重启后不自动续跑。
- 全部完成后聚合:任意 restart-required → 只提示重启;否则任意成功插件带 dsh.client → 自动刷新页面(3 秒倒计时可取消);都没有 → 不提示。
- 启动层客户端插件更新按「需要重启」处理,避免只刷新后启动层失败。

DSH 本体更新

- 客户端订阅 dshDesktop.updates(protocolVersion === 1),把阶段同步给 Host。
- available / downloading / verifying / installing / ready 阶段禁止开始插件更新,队列也会停住等待。
- DSH 更新后第一次启动,会按新运行版本重新检查插件兼容性;不兼容的插件不会被自动更新。

卸载残留

- 只做检测和提示,不接管官方卸载。
- 检测三类:dsh.profile.bundles 里悬空的插件选择;cordis.patch.yml 里引用不存在包的 name: 行;与悬空包同名的 $DSH_HOME 数据目录。
- 残留 chip 使用垃圾桶图标和警告色,与更新 chip 区分;点击打开窗口查看明细。
- 底部「清理」会删除悬空的 bundle 选择和失效的补丁条目(先自动快照、原子写回;补丁只移除引用失效包的整段条目,其余行原样保留);数据目录只报告,不自动删除。
- 若卸载后 DSH 打不开:先用错误对话框的「禁用第三方插件」,再运行 repair.cmd 恢复卸载前快照。

防砖与恢复

DSH 对缺失/损坏的 bundle 是宽容的:Loader 会跳过并打印 warning,应用仍能启动。真正会让应用打不开的是另外三类问题,本插件针对它们做了防护:
1. 启动层插件互相依赖断裂(例如 dsh-thought-buddy 等待 dsh-loader 提供的 dshLoaderUi):web boot 要求 immediate 客户端插件全部激活,一个 pending 就会让窗口打不开。插件会读取已安装 manifest 的 dsh.client.immediately 和 dsh.client.inject,把「启动关键」和「被其他插件注入」的更新标记出来,默认不勾选,并在勾选时给出警告。
2. 安装成功但落盘不完整:更新后逐一校验 listBundles 的 installed/version/enabled/error、Host 行的 fiberPhase、node_modules/<pkg> 的 package.json、入口文件和 bundle patch 文件;任何一项不通过就自动回滚旧版本。
3. 硬崩溃/断电导致 profile 文件残留:每批更新开始前把 package.json、pnpm-lock.yaml、pnpm-workspace.yaml、cordis.patch.yml、cordis.yml 复制到 $DSH_HOME/plugin-updates/snapshots/<timestamp>/;快照失败则拒绝开始更新。更新前的旧版本 manifest 也会先确认可下载,否则拒绝更新(保证回滚目标存在)。

DSH 打不开时

1. 先点错误对话框里的 「禁用第三方插件、备份 profile patch 并重启」(DSH 自带的安全模式)。
2. 仍不行就运行本仓库的 repair.cmd(双击即可): repair.cmd --list repair.cmd # 恢复最新快照并重装依赖 repair.cmd --snapshot <目录名> # 指定快照 repair.cmd --no-install # 只恢复文件

它会把当前损坏文件另存到 $DSH_HOME/plugin-updates/broken-/,再恢复快照并执行 dsh plugin --profile desktop install。
3. 没有任何快照时,可用 dsh --profile rescue --from-default-profile web 启动一个干净 profile 排查,或手动编辑 profiles/desktop/package.json 移除可疑依赖。

建议的使用方式

- 一次只更新一个「启动关键 / 被依赖」插件,更新完立即重启验证;普通插件可以批量。
- 更新后先重启一次确认能打开,再继续下一批。
- 出现 fatal uncaught exception(如共享依赖里的 undici/openai)时,先 repair.cmd 回到更新前,再单独排查该插件,不要连续重试。

安装

npm 包:dsh-plugin-update-center

通过 dsh CLI 安装到 desktop profile
dsh plugin --profile desktop add dsh-plugin-update-center

也可以在 DSH 的「插件 → 添加插件」里输入 dsh-plugin-update-center。

本地开发安装(链接当前 checkout):

plugin_manager install_bundle C:\Users\Jie\Projects\dsh-plugins\dsh-plugin-update-center

本地目录安装会链接当前 checkout;改完代码后刷新页面即可看到客户端改动,Host 半由 HMR 重载。

测试

npm test

覆盖:版本比较与 engines 范围、更新计划筛选、remove → install → 回滚顺序、发布变化中止、队列空闲等待/取消、重启优先于刷新、残留扫描与安全清理、HTTP 路由的鉴权头/请求体/错误码、registry 回退与范围检查。

文件

| 文件 | 作用 |
| index.js | Host 入口:注册 POST /api/dsh-plugin-update-center |
| lib/engine.js | 检查、计划、串行更新、队列等待、快照前校验、安装后验证、回滚、进度状态 |
| lib/backup.js | profile 快照、保留策略、更新历史 |
| lib/residue.js | 卸载残留扫描(悬空选择/补丁引用/数据目录)与安全清理 |
| lib/registry.js | npm registry 读取与回退 |
| lib/versions.js | 无依赖的 semver 比较与范围判断 |
| lib/http.js | 同源 POST 路由与有界请求体 |
| client.js | 登录名右侧 chip、排队/生效提示、残留窗口、进度条 |
| repair.mjs / repair.cmd | DSH 打不开时的离线恢复脚本 |
| locale/.json | 插件管理页显示标题与描述 |

已知限制

- 账号行没有官方 list 插槽,chip 依赖两个稳定锚点:账号按钮的 data-signed-out 与 SettingsRoot 的 _triggerRow class 后缀。DSH 大版本改这两处 DOM 时 chip 会暂时不显示,需要同步调整 useAccountRowHost。
- 新装插件或更新插件后,Web 页面需要刷新一次才能加载新的 Client 模块;Host 半会由 HMR 重载。
- 更新是「先卸后装」,异常时依赖回滚;请避免在 DSH 正在执行任务时更新。
- 只处理顶层 profile 依赖;Suite 类组合包的子插件需要按组合包本身的更新方式处理。
- 队列只存在 Host 内存:页面刷新/关闭不影响,Host 重启后队列丢失,不会自动续跑。
- DSH 本体更新门控依赖桌面 preload 的 dshDesktop.updates;浏览器模式无法感知,只能按运行版本重查。
- 残留清理只删悬空的 bundle 选择;cordis.patch.yml 的失效引用与数据目录需要手动处理。
预览分享卡片长什么样 ↓darkings/dsh-plugin-update-center
分享 · DeepSeek Harness Hub
darkings/dsh-plugin-update-center

集中检查并排队更新插件,支持快照回滚与残留清理

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