DeepSeek Harness 插件

hezhongtang/dsh-update-copilot

Star 数 ★ 1 下载量(近 30 天) 1,116 分类 开发与运行时 收录于 2026-08-15 npm dsh-update-copilot

DeepSeek Harness 的更新助手:一次扫描覆盖 DeepSeek Harness 本体和每个 profile 的插件,说清改了什么、风险多大,只更新你确认过的那些。

安装

# npm 包(预构建)

dsh plugin --profile web add dsh-update-copilot

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:hezhongtang/dsh-update-copilot

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

DeepSeek Harness 的更新助手:追踪 dsh 本体、官方 bundle 和所有已装插件——跨全部 profile 按包合并展示;插件更新带预检闸门一键执行,本体代执行更新(始终钉最新健康版本,全套兼容闸门,仅限可写的全局 npm 安装),补丁名体检捕捉被 dsh 升级静默丢弃的配置。

English | 中文

为什么做这个

DSH 迭代很快,插件生态同样如此。每个 profile 通过 pnpm spec 安装插件——npm 版本号、GitHub commit 锁定、本地 link: 目录——每种通道各有各的过期方式。手动检查意味着挨个仓库跑一遍;无脑全自动升级则等于把环境交给第三方代码。

这个插件走中间路线:全部检测、汇总变更、只更新你点过的东西。 更新就是一键——按钮和动作之间没有确认仪式,且只会作用于该包显示出的合格 profile。DSH 本体是带闸门的操作(ADR-0001):在可写的全局 npm 安装上,本体卡片可以在全套兼容闸门之后代执行更新——始终钉到雷达验证过的最新版本(绝不执行 dist-tag 字符串),解析出降级时除非显式 force 否则拒绝。其余安装形态(npx 等)保持「复制命令」行为,且本体绝不参与任何自动更新批次。

功能

🔭 全量雷达 一次扫描覆盖 dsh 本体 + 官方 bundle(dsh-base、dsh-web-app)+ 所有 profile 的插件依赖
🔄 双通道 npm registry 版本(完整 semver 比较,含 prerelease)+ git 上游(pinned commit vs HEAD)。link:/file: 本地目录只列出、不探测、不管理
🤖 Agent 工具 update_copilot_scan / update_copilot_preflight / update_copilot_update / update_copilot_core——对 Agent 说一句「有没有更新」,得到有数据支撑的回答;扫描按包合并(一个包一行),自动推断的挂载关系只用于展示;官方包跟随 harness 安装(本体更新走 update_copilot_core),每个直接依赖仍按自身更新策略处理。profile 参数在 preflight/update 上可选:不传时 preflight 逐个评估所有装有该包的 profile,update 也只在那些合格 profile 中执行
🖥 Web 界面 设置旁的侧栏入口(徽章在挂载时补齐、启动扫描后刷新)打开紧凑雷达弹窗,旁边就是**「⚡ 一键更新」快捷按钮**——不必打开任何视图,点击即按序更新所有落后且可自动更新的插件(运行中显示 n/m 进度并禁用,完成显示 ✓/✗ 反馈,失败或需重启时自动打开弹窗看明细)。弹窗承载完整雷达,共用同一折叠布局——「DeepSeek Harness 本体」卡片默认收起,插件拆成「可更新」「已最新」两组(已最新默认折叠、点击展开),自动推断的挂载关系始终跟随父行。插件跨 profile 合并成一行(每个已在的 profile 的当前 → 最新版本内联列出),挂载的包可在父行下展开披露,同时保留独立归属和更新操作——子项「更新」只更新子项,父项普通「更新」只更新父项,「更新 bundle」只处理过期且合格的目标(父项过期先更新父项,再按每条关系的 profile 范围更新过期的挂载子项)。点一次「更新」只在该包明确列出的合格 profile 中执行,工具栏「一键更新全部」按序跑完所有合格的落后包(在弹窗内勾选「点击按钮时自动更新」后,点侧栏按钮一发现有落后插件就自动开始这一轮,dsh 本体绝不参与这一自动批次)。所有变更操作共用一个 UI 操作锁;更新或刷新状态未结束时禁止刷新。更新过程通过 SSE 实时推送进度(解析依赖 / 下载中 / 重试中阶段),直接渲染成每行进度条;更新从不静默——无论这轮更新由谁发起(自动更新、一键更新快捷键、Agent 工具、另一个标签页),运行期间侧栏按钮的徽章会变成跳动的「更新中」圆点,弹窗常驻「正在更新:包名(profile)…」横幅(含当前阶段 / 百分比),所有更新按钮同步禁用,更新一结束列表自动刷新;无论这轮更新由谁发起,雷达里匹配的那一行都会内联同一根实时进度条(发起行走 SSE 流,其余座位经 2 秒轮询镜像),新一轮更新开始时该行残留的上一次结果自动清除——后台静默更新不会再和前台点击撞出「更新中」报错
🛡 更新护栏 同源 POST + 显式 confirm、严格目标 allowlist、单并发锁、5 分钟超时;预检硬拦截门拒绝目标 dsh 确实会弄坏的更新(缺失 named export),显式 force 才可越过;npm/github 通道只走官方 dsh plugin CLI,link:/file: 本地目录与官方 @deepseek-ai/* 包一律拒绝——本地检出请在它自己的仓库里更新;空包 dist-tag / husk 发布(无入口、无 dsh.bundle、tarball 极小)在解析目标版本时直接跳过并拒绝安装
🩹 补丁名体检 dsh 的补丁装载器对 cordis.patch.yml 每条记录做严格名校验,钉住的包名不存在时整条静默跳过(含 config)——0.1.7-rc.2 把 dsh-llm-deepseek 改名为 dsh-llm-deepseek-api-key,用户自定义模型列表无声失效,唯一信号是一行 stderr。雷达现在把每个 profile 的补丁文件对照装载器全部解析来源(依赖树、声明的 bundles、两层 node_modules、bundle 补丁行)做体检,钉住已消失名字的条目以横幅呈现,附修复方式与逐 profile 验证命令(`dsh --profile --dump-config 2>&1 >/dev/null
🧯 Host 导出检查 扫描第三方插件对 @deepseek-ai/* 的 named import,对照当前(以及本体有新版本时的目标)DSH host 包实际导出。peer 范围拦不住「范围合法、导出没了」——这种错误会在启动时整棵插件树挂掉。雷达本体卡片和插件行给出提醒,并附带可复制的 cordis.patch.yml 禁用片段与 dsh plugin remove 命令。DSH 已经起不来时,不经过 dsh web,直接跑 node …/dsh-update-copilot/lib/cli.js
🚦 peer 范围预检预警 对每个插件声明的 @deepseek-ai/* peerDependencies,用含 prerelease 规则的 semver 对照运行中 dsh(以及本体落后时的升级目标)——^0.1.0-rc.8 对 0.1.2-rc.1 这种版本号里看不出来的坑会被点亮。预警以行徽标呈现、随更新结果返回;无法解析的范围保持沉默,预检自身的任何故障都不会阻断扫描或更新。Release 说明与提交里的破坏性变更标记同样被扫描,并入预检预警。
🧭 升级卡 corridor + 分层预检 预检输出对齐社区三层失败签名(link-time / mount-time / run-time,外加 storage / peer / breaking-card):layerFindings 携带 action level、证据与修复建议。跨 host 版本会先走 oh-my-dsh 升级卡 corridor——缺边即停(没有 curated 卡的 hop 不会假装安全);session 格式 V2→V3→V4 只向前迁移,跳变要求先快照。已知 run-time 契约坑(prepareCall、Session.events、registerContinuableSetup 等)做静态能力风险提示。
🩹 更新后连带体检 更新成功后重新体检 profile 的全部插件成员,而不只是被更新的包——pnpm 会整树重写共享依赖,没被动过的兄弟插件也可能被连累。新增的 broken/missing 行会出现在更新结果里,并标注为连带损坏。
↩️ 更新历史与回滚 每次变更前,更新助手把已装版本、spec、pinned commit 和 bundle patch 原文快照进 $DSH_HOME 下自己的历史目录(每包保留 10 份,尽力而为)。回滚 = 以旧 target 走现有带确认的更新流程——行上有两段式回滚按钮。离线 CLI 可列出快照与手工回滚命令:node …/lib/cli.js history [profile] [package]。
🌐 完整双语 所有面向用户的文案——弹窗、徽章、更新错误——跟随界面语言(中/英);Agent 工具路径保留稳定英文标识

安装

# 从 npm 安装(推荐)
dsh plugin --profile web add dsh-update-copilot

# 或者直接从 GitHub 仓库安装
dsh plugin --profile web add github:hezhongtang/dsh-update-copilot

重启 dsh web,点击侧栏设置旁的**「更新助手」**入口。其他 profile 用法相同(--profile <name>)。

使用

问你的 Agent

「帮我看看插件有没有更新」

Agent 会调用 update_copilot_scan,对落后项跑 update_copilot_preflight、先呈现风险,然后等你拍板。更新工具在没有 confirm: true 时直接拒绝执行。

或者用弹窗

设置旁的侧栏按钮打开紧凑雷达弹窗(ESC 或点击遮罩关闭)。按钮右侧的**「⚡ 一键更新」**在点击时直接开跑(不经过弹窗):按序更新所有落后且可自动更新的插件,运行中按钮显示 n/m 进度、徽章变跳动圆点,完成短暂显示 ✓/✗ 后恢复;失败或需重启时自动打开弹窗展示明细。在弹窗内勾选「点击按钮时自动更新」后,点侧栏按钮还会在发现有落后插件时立即自动开始「一键更新全部」,进度直接显示在弹窗里。

更新过程全程可见:无论由谁发起——侧栏自动更新、你点的行内更新、Agent 工具(update_copilot_update)、另一个浏览器标签页——弹窗没开时,侧栏按钮的徽章会变成跳动的圆点(悬停提示正在更新的包名);弹窗打开时,顶部常驻一条「正在更新:包名(profile)…」横幅,跟随服务端实时阶段(解析依赖 / 下载中 / 重试中)与百分比。横幅出现期间所有变更操作(行内「更新」、「更新 bundle」、「一键更新全部」)都会禁用,避免后台更新与前台的点击抢同一把锁而撞出「正在更新中,请稍候」的报错。批量跑序(「一键更新全部」「更新 bundle」)行内直接呈现队列状态:正在执行的那行显示「更新中…」与实时进度条,还没轮到的那行按钮变成**「待更新」**(悬停提示当前项完成后自动开始),已跑过的行则保持原样,避免把旧扫描的「可更新」误读成未开始;更新结束后列表自动刷新出新版本。

弹窗即完整雷达:本体卡片的**单一「更新本体」操作(始终取雷达验证过的最新版、绝不执行 dist-tag 字符串;在可写的全局 npm 安装上,两步确认按钮代跑带闸门的 npm install -g 并报告重启要求与回滚命令——npx 等其余形态仅展示命令)、全部已装插件跨 profile 合并成一行(每个 profile 的当前 → 最新版本内联展示)、可展开的挂载关系,以及每行一个一键「更新」按钮。子项行的「更新」只作用于子项,父项普通「更新」只作用于父项;「更新 bundle」跳过当前目标,在父项符合条件且过期时先运行父项,再按每条关系的 profile 范围依次运行过期的已选挂载子项,并报告进度与结果。每个包都带明确的合格 profile,不会按同名依赖盲目更新全部 profile。工具栏的「一键更新全部」**仍是独立的全局操作,按序跑合格的落后包。更新过程由 SSE 实时推送到每行进度条。更新完成后,结果报告 dsh 重启要求,弹窗显示重启横幅。

Agent 工具一览

工具 读/写 用途
update_copilot_scan 读 全量扫描:核心 + 所有 profile,按包合并(10 分钟缓存,force 强制刷新)
update_copilot_update 写 执行一次已确认的更新——不传 profile 时只在该包明确列出的合格 profile 中执行;npm/github 通道走官方 dsh plugin CLI(瞬时失败自动重试——最多 3 次、指数退避加全抖动;版本不存在、鉴权被拒等确定性错误快速失败)。link:/file: 本地目录不由助手管理,请在它自己的 checkout 内更新。target 可回滚到确切的旧版本;force: true 覆盖预检硬拦截(仅在用户明确同意后传入)
update_copilot_preflight 读 一个包的门检决策,不触发任何变更:按 profile 给出 ok / warning / blocked,附拦截证据(目标 dsh 缺失的导出)、peer 范围预警、release notes 与 commits 的破坏性变更信号
update_copilot_core 写 执行已确认的 DSH 本体更新。始终以最新健康发布版为目标,先解析成具体版本(绝不执行 dist-tag 字符串),解析出降级时无 force 拒绝。执行前过全套闸门:升级卡片走廊、session 格式存储边界、跨全部 profile 的逐插件导出证据;force 仅在用户同意后覆盖,证据保留在结果里。只在可写的全局 npm 安装上执行——npx / 不可溯源的启动会返回手工命令。结果必带 requiresRestart 与回滚命令

工作原理

每个依赖 spec 先分类到通道,每个通道有自己的比较方式。扫描结果按包跨 profile 合并:同一个包装在 web / headless / desktop,就只出现一行,携带每个 profile 的通道与版本,以及明确的合格更新 profile。每个 profile 内,活动 bundle 的包内 patch 若挂载至少两个生产依赖,会展示仅用于呈现的挂载关系;多个父包声明同一子项时,先选已验证子项更多的父包,再按包名确定归属。挂载关系不转移更新归属,每个直接依赖仍按自身策略更新;bundle 更新沿用所选关系的 profile 范围。link: 与 file: 本地依赖保持本地;官方 @deepseek-ai/* 包只报告,不能独立更新。

什么才算一行插件: profile manifest 里 dsh.profile.bundles 声明的包(宿主真正加载的那份清单),外加所有 link: / file: 本地开发检出——尚未激活也保持可见,外加活动 bundle 的已验证 patch 挂载子项——宿主正是通过 patch 的 insert 记录加载这些插件。manifest 里的其它普通依赖(顺手装进来的 CLI、服务端运行时等)不是 dsh 插件,也不会渲染成插件行;否则同一个 GitHub 仓库的真插件旁边会多出一个幽灵更新按钮。manifest 没有 bundle 清单时回退为展示全部依赖。

通道 spec 示例 当前版本 最新版本
npm ^0.1.4 已装 package.json 的版本 registry 全量文档中的最新版
github github:owner/repo#sha pnpm-lock.yaml 锁定的 commit GitHub API 查询的上游 HEAD
linked link:../my-plugin 已装 package.json 版本 —(不探测;在其自身仓库内管理)

npm 通道刻意不信任 latest dist-tag:monorepo 子包的这个 tag 常年滞后,会把实际比 tag 更新的安装误报为落后。版本比较采用完整 semver 优先级(含 prerelease),因此 0.1.0-rc.6 > 0.1.0-rc.5、1.0.0 > 1.0.0-rc.1 都成立。

更新通过严格校验的路径执行,绝不拼接 shell:npm/github 通道走 dsh plugin --profile <p> add <target>——和人手动输入的是同一条路径——目标字符串经过 allowlist 校验;link:/file: 本地目录绝不触碰。DSH 本体走独立的带闸门执行器:目标先解析成具体的钉定版本(绝不执行 tag 字符串),安装形态必须是可写的全局 npm 安装,且闸门——走廊、存储边界、跨全部 profile 的逐插件导出证据——通过后才 spawn npm install -g @deepseek-ai/dsh@<版本>;闸门同时产出咨询级预警(补丁钉住的名字目标版本不再发布),升级成功后逐 profile 的 post-flight --dump-config 探测把新装载器的跳过行并入同一组预警;运行中的进程永远不会是被更新的那个,因此变更必然报告重启要求与回滚命令。瞬时失败自动重试:最多共 3 次,间隔采用指数退避 + 全抖动(基准 1s、上限 8s),避免一批更新在网络恢复瞬间同时扎堆重试;确定性错误——包或版本不存在(E404、ETARGET)、鉴权被拒(E401/403)——跳过剩余次数快速失败。子项、父项和 bundle 操作都只按包行里明确列出的合格 profile 执行;「一键更新全部」仍是独立的全局操作,绝不因同名依赖而更新全部 profile。

DSH 起不来时

第三方插件若 import { 某个已删除的名字 } from '@deepseek-ai/…',loader 会让整棵 plugin tree 失败,更新助手的 Web 界面也出不来。这时在任意能跑 Node 的 shell 里:

node ~/.dsh/profiles/web/node_modules/dsh-update-copilot/lib/cli.js
# 本地 link 安装:
node /path/to/dsh-update-copilot/lib/cli.js

只对照当前磁盘上的 DSH(不查 npm、不预演目标版本),因此 DSH 起不来时也能跑。已不兼容时退出码为 1,并打印禁用 / 卸载命令。要从一次失败的更新中恢复,用 history 子命令列出更新前快照与手工回滚命令:

node ~/.dsh/profiles/web/node_modules/dsh-update-copilot/lib/cli.js history          # 所有 profile
node …/lib/cli.js history web my-plugin                                              # 单个包

安全性

  • 变更路由有两个:POST /dsh-update-copilot/update(插件)与 POST /dsh-update-copilot/update-core(带闸门的本体更新):强制同源且校验实际传输协议,必须显式 confirm: true,不信任转发协议请求头。TLS 终止代理可设置其公开 HTTP(S) origin 至 DSH_UPDATE_COPILOT_PUBLIC_ORIGIN;请求必须精确匹配,配置无效时拒绝所有请求。
  • 官方 @deepseek-ai/* 包和 dsh 本体绝不自动更新;本体只在显式确认的动作下执行,且仅限可写的全局 npm 安装。
  • 所有上游查询均为只读(registry.npmjs.org、api.github.com、git ls-remote)且带硬超时;单项查询失败只降级该项,不影响整体扫描。

限制

  • 每次有变更的更新都需要重启 dsh 才生效:结果返回 requiresRestart: true,弹窗显示重启提示。不做进程内热重载。
  • link:/file: 本地目录在雷达中列出但绝不探测、绝不更新:请在它自己的仓库内管理(git pull)。
  • GitHub API 未认证时限流 60 次/小时——破坏性变更信号会优雅降级为无信号。
  • 裸 git+https:// spec 只报告、不提供比较通道。
  • Host 导出检查是静态 named import:动态 import()、运行时才碰到的 API、以及 import * as ns 不会标出来。官方 @deepseek-ai/* 包不扫。目标版本只 pack 与 DSH 同版本线的 @deepseek-ai/dsh-*;pack 失败或独立版本的包(cordis、schemastery)跳过,不报假不兼容。
  • peer 范围检查覆盖常见范围写法(caret、tilde、区间、并集、通配、精确)并遵循 node-semver 的 prerelease 规则;生僻写法按「无法评估」保持沉默。历史快照尽力而为——目录不可写时只是没有回滚建议,更新本身绝不会被阻断。

参与贡献

欢迎提 Issue 和 PR:hezhongtang/dsh-update-copilot。代码库刻意保持小巧、零依赖——host 是纯 ESM,浏览器端是手写 CJS bundle,无需搭建任何构建环境。

许可

MIT © 2026 hezhongtang

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。