dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
dsh插件/dsh plugin. //CN: 1. dsh启动时自动检查更新,并提示风险性改动内容。由于dsh预览版的更新常具破坏性,为避免兼容性错误,不提供更新安装功能...... //EN: 1. Perform an immediate update check upon dsh startup. Automatic update installation is not provided to avoid compatibility issues.
dsh_update_check 是一个 dsh 插件,能自动检查 dsharness 官方上游仓库比对差异并提示更新。
connection/reset 时补触发);DSH 更新检查与插件自身检查是两个独立开关。releases/latest API → releases 列表 → tags API,10 秒超时,dsh-v* 前缀的 tag 也能正确解析(semver 风格比较,含 rc/beta 预发布)。package.json 版本与仓库 plugin/package.json 比对(DSH 本身的更新始终由你手动执行,插件只做提示)。$DSH_HOME/update-check.json。locale 服务注册 zh / en 字典,界面跟随当前语言实时切换(横幅、设置页与导航标签);locale 服务不可用时回退内置中文字典。插件以 npm 包 dsh-update-check 提供(plugin/ 目录),挂进宿主 composition,随 DSH 启动自动加载:
安装包:把 plugin/ 目录放入 profile 的 node_modules(Windows 默认 C:\Users\<你>\.dsh\profiles\<profile>\node_modules\dsh-update-check\,含 package.json + lib/);
挂载:编辑该 profile 的 cordis.patch.yml,追加:
- insert:
- id: upd-check
name: 'dsh-update-check'
重启 DSH:生效后无需任何手动加载,插件常驻(更新 DSH 后也不用重装)。
说明:Host 通过宿主
webServer暴露GET /upd-check/api/check(Host 以inject: ['webServer']声明硬依赖,等服务就绪后再注册路由);浏览器端 client bundle(ModuleLoader 格式)经exports["./client"]+package.json dsh.client声明被 dsh 的 client-modules 自动扫描打包,挂载shell.overlay横幅,并在设置区注册独立的「↑ 检查更新」页(settings.section,与「通用设置 / 模型 / 插件」同级,排最后)。
| 半区 | 职责 |
|---|---|
Host 监督者(plugin/lib/index.js) | 进程级基础设施:三级网络回退、设置持久化、HTTP 路由,以及热换入 / 自更新引擎。 |
Host 实现(plugin/lib/impl.js) | 可热插拔的检测逻辑:本机 DSH 版本检测(模块解析 → npm 全局回落,并自报命中渠道)、发布说明分节解析、改动分类、破坏性分级、版本比对;以 API_VERSION / IMPL_CONTRACT 契约与监督者绑定。 |
Client(plugin/lib/client.js) | shell.overlay 顶部横幅 + 设置区独立「↑ 检查更新」页(settings.section);展示更新提醒、破坏性风险详情(含命中关键词片段)、网络错误与热更新按钮。 |
| 通信 | webServer HTTP 路由(/upd-check/api/check、/upd-check/api/settings、/upd-check/api/self-update)+ 同源 fetch |
网络传输三级容错:
web.fetch(若部署挂载了 fetch provider);subprocess 跑 node -(stdin 喂脚本)标准 fetch(自动跟随重定向);github.com 指向 127.0.0.1 并返回自签证书)→ 脚本内用 dns.resolve4 取真实 IP,以 servername/Host 头直连,手动跟随重定向、逐个 IP 重试。插件可以从自己的 GitHub Release 更新自身,且大部分改动无需重启 DSH。
分层与生效边界
| 文件 | 角色 | 生效时机 |
|---|---|---|
lib/impl.js | 检测/解析实现(可热插拔) | 立即——用新的 ?v=<版本> 重新导入并原子换入 |
lib/client.js | 浏览器 UI bundle | 立即——dsh-client-hmr 推送新 rev,页面就地重载该 bundle |
lib/index.js | 监督者:服务、设置、网络、路由 | 下次 DSH 启动(响应里以 restartRequired 标注) |
package.json | 版本标记 | 立即(版本显示) |
监督者刻意不在运行期自我改写:它就是执行更新的那段代码,运行时替换自己等于把脚下地板抽掉。它的改动会落盘并在响应中标注 restartRequired。
更新流程(POST /upd-check/api/self-update,仅手动触发)
releases/latest 取目标 tag(仓库还没有 Release 时回落 contents/plugin/package.json);lib/client.js、lib/impl.js、lib/index.js、package.json);lib/.stage/ —— package.json 形状、client.js 走 node --check 真解析、impl.js 真 import() 并校验契约、index.js 校验关键标记;lib/.bak/<旧版本>_<时间戳>/;rename 原子替换每个文件;impl.js/client.js,继续用内存中的旧引擎);$DSH_HOME/update-check-history.json(成功与失败都记,保留最近 20 条)。第 6 步之前或之中的任何失败都不会动磁盘;第 7 步失败会回滚。响应返回 from/to、hot、clientReloaded、restartRequired、逐文件 changed 标记与备份路径。
接口
| 方法 | 路由 | 作用 |
|---|---|---|
GET | /upd-check/api/self-update | 已装版本、运行中引擎版本/契约、热更新文件集、需重启范围、最近历史 |
POST | /upd-check/api/self-update | {"action":"update"} 执行更新;{"action":"update","force":true} 版本相同时也执行(仍按内容判定差异);{"action":"reload"} 只从磁盘重新导入实现,不下载任何内容 |
发布(热更新的内容来源)
pwsh -NoProfile -File scripts/release.ps1 -Final
以两套契约测试为门禁,抽取 CHANGELOG 中该版本段落作为 Release 说明,然后提交、推送、打 tag,并建立 GitHub Release(全部幂等)。
发布策略:每个版本都打 tag(tag 是自更新抓取内容的锚点),但只有系列最终版本才建 GitHub Release —— 中间版本发 Release 只会让人一头雾水。所以系列开发过程中执行 scripts/release.ps1(只打 tag),定稿时加一次 -Final。插件自更新消费的是 releases/latest,也就是那个最终发布版。
本机
github.com的 git 直连不可用(连接超时 / SSL 校验失败),推送走 Git Data API(scripts/push-via-api.ps1),因此本地与远端的 ref 会内容一致、SHA 分叉,这是预期行为。
| 项目 | 状态 | 说明 |
|---|---|---|
| Windows / macOS / Linux | ✅ | shell 双回退(cmd.exe → sh),node 解析双回退(node → node.exe);无硬编码路径 |
| npm 全局安装的 DSH | ✅ | 本地版本通过 npm ls -g @deepseek-ai/dsh / npm root -g 读取 |
| pnpm / bun / git clone 安装 | ✅ | 本机版本改由 Node 模块解析读取(require.resolve('@deepseek-ai/dsh/package.json'),约 6ms,不起 shell),非 npm 布局同样覆盖;npm ls -g 保留为回落,设置页会显示实际命中的渠道 |
| hosts 劫持(Steamcommunity302 等) | ✅ | 内置 DNS 直连绕过 |
| 未挂载 fetch provider 的部署 | ✅ | node 直连通道兜底 |
| GitHub 匿名 API 限流 | ⚠️ | 60 次/小时/IP;每次页面加载自动检查 1 次,手动检查按需触发,一般足够 |
| DSH 版本适配 | ⚠️ | 插槽名(shell.overlay、settings.section)以 0.1.0-rc.x 实测为准;未来版本若插槽树变化,UI 不挂载但不会崩溃,Host 检查功能不受影响 |
| 破坏性更新判定 | ✅ | semver 判定确定性可靠;发布说明关键词分级(强信号直接判破坏性;弱信号黄色预警并展示完整命中条目供核实) |
| 设置存储 | ✅ | $DSH_HOME/update-check.json(原子写;内容损坏回退默认);三个开关重启后仍生效 |
| 插件热更新 | ✅ | lib/impl.js + lib/client.js 免重启生效;lib/index.js 需下次启动(restartRequired);每次尝试都先校验、再备份、失败回滚 |
| 仓库尚无 Release 时的热更新 | ⚠️ | 自更新以 releases/latest 为内容源;完全没有 Release 时回落默认分支的 contents/plugin/package.json(开发通道)。中间版本只打 tag,见上面的发布策略 |
| 离线时的热更新 | ⚠️ | 需要能连上 GitHub(与检查共用三级回退);下载失败时不写任何文件 |
| 静态插件 | ✅ | 随 DSH 启动自动加载,重启/更新 DSH 后无需重装;Host 无 harness,走 webServer HTTP 接口(同源,仅本机监听) |
C:\Windows\System32\drivers\etc\hosts)是否有 github.com / api.github.com → 127.0.0.1 的劫持行(常见于 Steamcommunity302 等加速工具);有则删除这些行(需管理员),或直接依赖插件内置的 DNS 绕过。也可尝试点「重试」。node_modules/dsh-update-check 存在、cordis.patch.yml 已插入行、重启 DSH;检查 GET /upd-check/api/check 是否返回 JSON。restartRequired:这次发布同时改了 lib/index.js(监督者)。新文件已经落盘,下次 DSH 启动生效;GET /upd-check/api/self-update 可查看运行中的引擎版本。impl-contract-mismatch、remote-client-syntax、http-404),本次尝试记入 $DSH_HOME/update-check-history.json,旧版本备份在 plugin/lib/.bak/ 下。latest 变化)才会再次提醒。rate-limit),不再说成「无法连接 GitHub」;插件自身检测走的是另一个仓库,不受影响。按提示稍后重试即可(/rate_limit 可查重置时间)。plugin/ 目录 = npm 包 dsh-update-check(lib/index.js 监督者 + lib/impl.js 可热插拔实现 + lib/client.js 浏览器 bundle)。node scripts/check-src.js —— 语法与源码契约检查(102 条断言,CI 同样执行);node scripts/check-runtime.mjs —— 运行期契约检查:在临时沙箱里用桩 ctx 装载真实 host 半区并驱动其真实 HTTP handler,覆盖检测载荷、设置读写、引擎契约与热更新全链路(含失败零损伤回滚与两条版本检测渠道),62 条断言,CI 同样执行;node scripts/verify-real-selfupdate.mjs [包目录] —— 可选,需联网:把包复制到临时目录、降到 0.0.1 并制造内容漂移,然后真的从已发布的 GitHub Release 自我更新一次,再断言文件、运行中引擎版本与备份。全程不动源目录;GitHub 不可达时输出 SKIPPED 并以 0 退出。plugin/package.json 并写好 CHANGELOG 段落,然后 pwsh -NoProfile -File scripts/release.ps1(迭代期只打 tag),定稿时加 -Final 发布 Release。lib/index.js 的 IMPL_CONTRACT 与 lib/impl.js 的 API_VERSION;CI 会比对两者是否一致。MIT © nmbzth