deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:ShanHaiFish/dsh-check-for-updates
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
一个用于检查并安全更新 DSH (DeepSeek Harness) 的 Cordis 插件(静态 bundle 形态)。
① 左下方浮动更新弹窗 —— 首次打开页面自动检查到新版本时,在左下部「设置」按钮上方弹出提示卡片,提供【更新到 {版本}】与【稍后】;点「稍后」后该版本不再重复弹出。v1.13.0 起点击更新为「安排更新」——退出 DSH 后由独立更新器自动完成安装。

② 设置 > 通用 · DSH 更新入口 —— 手动「检查更新 / 测试网络」,展示当前版本与最新版本;有新版本时提供【更新到】按钮(升级完成后重启 DSH 生效)。

在 dsh 进程运行中直接执行 npm install -g 是危险的:Windows 会锁住已被 dsh 加载的
koffi 原生模块(koffi.node),npm 升级时包元数据更新成功、原生二进制却残留旧版,
导致 dsh 下次启动直接报 Mismatched native Koffi modules 崩溃(v1.12.0 及更早版本
的已知问题)。v1.13.0 起,更新流程改为两个阶段:
lib/updater.cjs 模板实例化
(注入目标版本、全局根、本进程 PID 等任务配置)写入临时目录 → 以 detached
子进程启动独立更新器,UI 提示「退出 DSH 后将自动完成安装」。npm install -g @deepseek-ai/dsh@<精确版本> →
做三重校验:npm 退出码、对盘版本(磁盘 package.json 必须等于目标版本)、
koffi 完整性(koffi 主包/平台包声明版本与原生二进制内嵌版本一致)→
koffi 断链时自动按声明版本从 registry tarball(npm pack + 系统 tar)自愈 →
结果写入状态文件,DSH 下次启动时反馈(失败会弹卡片提示重试)。另有防护网:每次「检查更新」时顺带做 koffi 完整性自检(只读文件、无副作用), 发现断链即弹「DSH 安装文件损坏」警告卡,提供【安排修复】一键走上述分离式流程 (repair 模式,仅校验并修复 koffi)。
本仓库同时提供两种形态:
| 形态 | 文件 | 状态 |
|---|---|---|
| 静态 bundle(推荐) | package.json + cordis.patch.yml + lib/ + client/ |
当前维护形态,dsh plugin add 后随 profile 层栈自动加载 |
动态插件(host.js + client.js) |
根目录两个文件 | 遗留,不再维护(v1.10.1 后冻结,仅作历史参考) |
# 从 npm(推荐,已发布到 npmjs;正式环境建议固定版本,例如 @1.13.3):
dsh plugin --profile web add dsh-check-for-updates
# 从 GitHub:
dsh plugin --profile web add github:ShanHaiFish/dsh-check-for-updates
# 本地开发用 file: 指向本仓库(注意路径不能含空格):
dsh plugin --profile web add "file:/absolute/path/to/dsh-check-for-updates"
npmjs: dsh-check-for-updates
Mac/Linux 上若路径含空格或非 ASCII(如本机
...2026-DeepSeekHarness相关\...),建议先 复制到无空格的路径再file:安装。
无硬编码路径:bundle 版 host(lib/index.js)在运行时通过 require.resolve('@deepseek-ai/dsh/package.json')
与 process.execPath 探测 DSH 安装根/版本与 node/npm-cli,不写死任何本机路径,跨机器可用。
客户端:bundle 版在左下部「设置」上方浮动弹窗(首次打开自动检查 + 【更新到】/【稍后】),
通过 POST /dsh-update-check/api 调用 host。
lib/index.js - 主机端(静态 bundle):版本检查、API 路由、koffi 自检、更新任务安排lib/updater.cjs - 分离式更新器模板(阶段二:等待退出 → 安装 → 校验/自愈 → 写状态)lib/launcher.cjs - detached 启动辅助(参数防御性校验)client/client.js - 客户端(静态 bundle):自动检查、更新弹窗、损坏警告卡、设置页「DSH 更新」入口host.js / client.js - 遗留动态形态(v1.10.1 冻结,不再维护)本地验证(无需安装依赖):
# 语法检查
node --check client/client.js
node --check lib/index.js && node --check lib/updater.cjs && node --check lib/launcher.cjs
# 冒烟测试(结构 + 交互契约)
node test/smoke.cjs
node test/interactive.cjs
test/smoke.cjs - 结构冒烟:bundle 插件形态({ name, inject: ['slots'], apply })、
settings.general.item 注册、设置项组件渲染test/interactive.cjs - 交互契约:模拟点击设置项各按钮(检查更新/测试网络/更新到),
验证与 host API(/dsh-update-check/api)契约的完整对齐,含「安排更新」语义与去重键GitHub Actions 云端自动化:
.github/workflows/ci.yml - PR 与 push 到 main 时自动执行上述全部检查,通过才允许合并(发布前把关).github/workflows/release.yaml - *推送 `v标签时自动发布**:校验标签与版本一致 → 先跑测试 → npm publish→ 创建 GitHub Release。需在仓库 Settings → Secrets 配置NPM_TOKEN`
(npmjs access token,publish 权限)发布前测试也可用 GitHub 预发布能力(不污染 npm
latest):发--prereleaseRelease 后, 测试者用dsh plugin --profile web add github:ShanHaiFish/dsh-check-for-updates#<标签>或 tarball URL 安装实测,通过后再升正式标签。
每版发布同步归档至 GitHub Releases, npm 发布记录见 dsh-check-for-updates on npm。
修复(依据 GitHub 发布与 npm registry 快照:0.1.2-rc.1 为当前最高版本,
0.1.2-alpha.5 不是最高):
compareVersions 旧实现从预发布串中抓“第一个数字”
直接比大小(rc.1→1、alpha.5→5),把 0.1.2-alpha.5 误判为高于
0.1.2-rc.1,导致「检查更新」把 Alpha 当成最新版本(README v1.9.0 曾确认
latest 标签滞后、改走全版本集合取最高——但比较器本身的排序是错的)。
现按 semver 规范 §11 完整比较预发布标识符:. 分隔)从左到右比较:数字标识符 < 字母数字标识符;
数字按数值比大小,字母数字按 ASCII 字典序(alpha < beta < rc)-alpha < -alpha.1)+xxx)不参与比较host.js 中同一份比较逻辑同步修复。test/version.cjs 回归测试并接入 CI(ci.yml 与 release.yaml 发布前
测试):覆盖 0.1.2-rc.1 > 0.1.2-alpha.5 与完整预发布排序规则,并用真实 npm
发布集合验证 pickMax 取到 0.1.2-rc.1。自动化发布链路演练:本版本用于端到端验证 GitHub Actions 自动发布流程
(.github/workflows/release.yaml:推送 v* 标签 → 校验 tag/版本一致 → 语法与冒烟
测试 → npm publish → 自动创建 GitHub Release),无功能变更。全部产物由 CI 生成,
发布说明由 GitHub 按提交自动汇总。
修复(依据 bug-report-dsh-check-for-updates-settings-entry-missing.md):
896caaa6)与
v1.13.0 重写(2ea843e)时遗漏了 settings.general.item 注册,用户无法在设置页
手动检查更新/测试网络。现于 client/client.js 导出声明 inject: ['slots'],
经 ctx.slots 注册 UpdateSettingsItem(React 组件,样式沿用 --dsw-alias-*
主题 token),完整对接 v1.13.0 host 契约:get-current-version→{version}),不触发网络动作check-for-updates(当前/最新版本、是否可更新、koffi 断链与
上次更新失败提示)test-network(成功/失败内联反馈)perform-update(v1.13.0「安排」语义:退出 DSH 后自动
完成安装),并把目标版本写入 sessionStorage,与浮动弹卡共用去重键perform-repair修复与更新安全改造(依据 2026-08-24 排查报告):
client/client.js 的模块 factory 之前返回
{ __dshUpdateChecker, recheck } 普通对象,浏览器侧 cordis loader 要求插件形态
(函数或带 apply 方法的对象),导致每个用户安装后启动页必报
Failed to load plugins: invalid plugin, expect function or object with an "apply" method。
现返回 { name, apply },autoCheck() 移入 apply();调试句柄改挂
window.__dshUpdateChecker。功能本身不受影响(副作用在求值期已生效),
但报错必须修复。npm install -g(Windows 下 koffi.node 被锁,npm 部分更新留下"元数据 3.1.6 +
二进制 3.1.5"断链,dsh 重启即崩 Mismatched native Koffi modules)。现在点击
更新只生成独立 updater 脚本并以 detached 子进程启动,等本 DSH 进程退出后
才开始安装(+3s 宽限),UI 话术改为「退出 DSH 后将自动完成安装」。perform-repair API)。上次更新失败的结果也会在下次启动时反馈。修改内容:
check-for-updates(模块级
autoStarted 标志保证每页只检查一次,不随 HMR 重复);自动检查失败不打扰用户。shell.overlay 帧级浮动层,fixed 定位)弹出提示卡片,显示「有新版本可用」
「当前→最新版本」,并提供【更新到 {版本}】主按钮与【稍后】次级按钮。perform-update 做精确版本安装 + 安装后对盘校验,
成功/失败均在弹窗内反馈;成功后自动关闭弹窗。sessionStorage(dsh-updck-dismissed-version),同版本不再弹出;
出现更新版本则重新弹出。updateState.onUpdate 单值回调改为 listeners: Set,
让「设置项」与「弹窗」两个组件同时实时刷新、互不覆盖。updck-curl-*,
避免与先前面动态包已注册的 updck-curl 冲突导致 Host 启动失败;若已有可用提供方则跳过注册。--dsw-alias-* 语义化主题 token(带兜底),随亮/暗色与第三方主题自动适配。说明:新增/改动均在既有 RPC(check-for-updates / perform-update / get-current-version /
test-network)之上完成,无需协议变更。
修改内容:
#007bff/#28a745/#dc3545 等),
全部改用 DSH 语义化主题 token --dsw-alias-*:var(--dsw-alias-button-primary-fill, var(--dsw-alias-brand-primary)),
文字 var(--dsw-alias-label-primary-foreground, var(--dsw-alias-bg-layer-1))state-success-primary;错误:state-error-primary;更新中:state-warn-primaryborder-l1/l2;表面 bg-layer-*/bg-module-platform;文字 label-primary/secondary/tertiaryvar(--a, fallback) 兜底,保证任意主题(含用户安装的主题插件、
亮/暗色)下与整体配色一致。修改内容:
perform-update 用 node + npm-cli.js(不经 cmd shell)执行
npm install -g --prefix <真实全局根> @deepseek-ai/dsh@<精确版本>。--prefix 从运行中的 package.json 程序化推导真实全局根,规避 .npmrc
中 prefix=/home/whaow/.npm-global 被 npm 在 Windows 误解析成不存在的 M:\... 的坑。latest/next 标签,消除歧义。compareVersions(目标, 当前) > 0 才执行;已是最新则 no-op。terminate;失败给出 npm 输出尾部可排查。updating 状态、更新按钮、更新结果信息、可展开的「执行日志」。稳定性保证:精确版本 + 显式程序化 --prefix + 前置守卫 + 安装后校验 + 超时/取消上界 + 不自动重启。
修改内容:
updck-curl):本部署没有内置 fetch 提供方,web.fetch 原本永远报 no usable web provider is registered。插件用 subprocess 启动 curl.exe 抓取 npm registry,注册为 WebFetchProvider,让 web.fetch 真正可用。/latest 标签:npm 的 latest 标签可能滞后(如仍指向 0.1.0-rc.7,而最新发布在 next 标签是 0.1.0-rc.8)。改为读取完整 packument https://registry.npmjs.org/@deepseek-ai/dsh 的 versions,用内置的小型 semver 比较器取实际发布的最高版本。web.search 作为最后兜底。根因回顾:
tool-web 的 fetch: true 只注册模型侧 web_fetch 工具,并不注册 fetch 后端;fetch 后端必须由某插件调用 web.registerFetchProvider 注册——本部署没有,需插件自行提供。/latest 返回的是 latest dist-tag,可能滞后于 next 上的新 rc 版本。当前方案:
fs.resolve/readText 读取本地 @deepseek-ai/dsh/package.jsonweb.search注意事项:
spawn curl(subprocess),安全审查判定为 BLOCK(120/300),需在插件安全白名单放行 updck 家族后运行。web.search(尽力而为)+ 显示错误提示。修改内容:
0.1.0-rc.7C:\Users\whaow\.dsh\profiles\web\cordis.patch.yml 配置,启用 fetch: true(需要重启 dsh 生效)web.fetch 请求 https://registry.npmjs.org/@deepseek-ai/dsh/latest 获取排查过程(已确认的根因):
web.fetch 被 DSH 默认配置 fetch: false 禁用(dsh-base/cordis.patch.yml)web.search 返回的 snippet 全部为空,无法提取版本号require 和 globalThis.fetch,只能使用 Cordis 服务当前方案:
0.1.0-rc.7(升级 DSH 后需手动更新此值)web.fetch 请求 npm registry注意事项:
cordis.patch.yml 中启用 fetch: true 并重启 DSH 后,web.fetch 才可用host.js 中的 CURRENT_VERSION 常量修改内容:
no usable web provider is registered 错误fetch: false,web fetch 功能被禁用web.search() 搜索 npm 包版本信息fs 服务读取本地 package.json 获取当前版本根本原因:
fetch: false,禁用了 web fetch 功能require 或 globalThis.fetchctx.web, ctx.fs)解决方案:
fs.resolve() + fs.readText() 读取本地 @deepseek-ai/dsh/package.jsonweb.search() 搜索 "@deepseek-ai/dsh npm version" 并提取版本号注意事项:
fetch: true修改内容:
no usable web provider is registered 错误web 和 shell 服务的硬依赖(inject)globalThis.fetch 直接发起网络请求(Node.js 18+)fetchUrl() 封装函数修改内容:
getCurrentVersion() 读取本地实际安装版本的 bugshell 服务,通过 node -e 命令读取本地 @deepseek-ai/dsh/package.json 的版本getLatestVersion() 继续从 npm registry 获取最新版本修改内容:
fs 依赖,简化代码修改内容:
web.fetch 错误处理,添加详细日志ctx.fs)初始版本:
⚠️ 以下为遗留动态形态(
host.js/client.js,v1.10.1 冻结)的使用说明,仅作历史参考。 当前推荐使用上文的静态 bundle 安装方式,功能以 bundle 版为准。
host.js 和 client.js 代码复制到 DSH 动态插件定义中cordis_define 定义插件cordis_run 运行插件⚠️ 本节描述遗留动态形态的接口;静态 bundle 版 host 通过
POST /dsh-update-check/api(JSON{method})提供同名方法:check-for-updates/get-current-version/test-network/perform-update(v1.13.0 起返回"已安排"而非同步安装)/perform-repair(v1.13.0 新增)。
host.js)web 服务web.fetch 从 npm registry 获取版本信息check-for-updates - 检查更新get-current-version - 获取当前版本test-network - 测试网络连接client.js)settings.general.item 槽位host.call 调用主机端方法shell.overlay 槽位{
url: 'https://registry.npmjs.org/@deepseek-ai/dsh/latest'
}
注意:不需要 method 和 headers 参数
{
url: string, // 最终URL
statusCode: number, // HTTP状态码(不是 status)
body: { // 是对象,不是字符串
kind: 'html' | 'text',
content: string // 实际内容
},
truncated: boolean
}
插件会在控制台输出详细的调试信息:
web.fetch 的返回结果点击"测试网络"按钮可以:
web.fetch 是否正常工作如果出现错误,插件会显示:
MIT License
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。