Releases: Noob-stupid/dsh-plugin-gating-hub
Release list
v0.3.65 - metadata: intranet/offline capability in description + default index sources moved to the new repo name
v0.3.65 — 元数据与默认索引源修正:内网/离线能力写进身份描述 + 索引源改到新仓库名(2026-09-23)
无功能逻辑变更:一处默认配置修正(索引源 URL)+ 身份描述补全。
- 身份描述补上「内网 / 离线」这条硬能力(用户指出:能力早就有,但描述里没人看得出来):
仓库描述、npm description、中英 README 首屏现在都写明——安装源 / 搜索源 / 索引源 / Git 源
四类源全部可自定义,可指向公司内网私有 registry、内网自建索引、file://本地裸仓库,
纯内网或断网环境照样浏览与安装。 - 修默认索引源仍是旧仓库名(
dsh-plugin-hub→dsh-plugin-gating-hub,5 条:jsDelivr
cdn/gcore/fastly、ghproxy、raw)。旧路径在 jsDelivr 上命中旧缓存:实测旧路径拿到的
marketplace/index.json的generatedAt是2026-09-22T15:49Z,新路径与 GitHubmain一致
(2026-09-23T02:01Z,556,993 B)。默认索引源本该始终是最新的那一份。 - 内务:测试文件收进
tests/(根目录 tracked 32 → 13),CI 路径同步;发布物不含tests/。
验证:18 套测试全部 exit 0、零 FAIL;clean-install 发版门槛对已发布 0.3.64 PASS 17/17;
本版相对 0.3.64 的差异 = package.json(版本/描述)+ 5 条索引源 URL + README 文案。
v0.3.64 - metadata: bilingual description/keywords + repository rename
v0.3.64 — 元数据版:npm 描述/关键词中英双语 + repository 指向新仓库名(2026-09-23)
纯元数据与检索可见性改进,不含功能变更(代码与 0.3.63 相同)。
- npm description 改为中英双语,补上用户实际会搜的词:
一键框架升级失败自动回滚/one-click framework upgrade with auto-rollback、
插件升级门控/version gating(此前只有英文one-click framework upgrade,中文用户搜"框架升级/回滚"匹配不到)。 - keywords 扩充到 14 个(npm 搜索按 keywords 加权):
dsh-plugin、dsh-plugins、deepseek-harness、plugin-manager、
plugin-market、plugin-console、marketplace、framework-upgrade、rollback、auto-rollback、插件市场、框架升级、自动回滚。 repository字段改为新仓库名https://github.com/Noob-stupid/dsh-plugin-gating-hub(旧名 301 跳转仍有效;
社区目录站 dsh-plugin.org 会做 repo→npm 反查,旧名可能被判定"信息不一致")。- CI 内务:
npm-check工作流的"某版本是否存在"改为只报告不失败(核查未发布版本属正常中间态,不该刷 failed 通知)。
验证:18 个测试文件全绿;clean-install 发版门槛对 0.3.63 已 PASS 17/17(本版代码与其一致)。
v0.3.63 - fix: release-channel deps rewritten to a non-existent npm version (latent data-consistency bug)
0.3.63 — 修「安装后依赖规格被改写成不存在的 npm 版本」(缺陷②,潜伏性数据一致性缺陷)
本版 = 0.3.62(注入缝
ctx.get修复)+ 缺陷②修复 合并发布。 0.3.62 已提交(c3cd8d8)但发布环节被打断
(未 push / 未打 tag / 未发 Release / npm 上也没有),因此合成一次发布,版本号递增到 0.3.63。如果你在 0.3.59~0.3.61 上装过「只发 GitHub release、没有发 npm」的插件,请务必升级。
① 注入缝改用 ctx.get(即 0.3.62 的内容,随本版一起交付)
channelImpls(ports) 改为优先 ctx.get('installChannels')(Cordis 的正规可选读取,未声明也不抛),
普通对象(测试替身/窄接口)才回退属性访问并 try/catch 兜底 —— 属性式读取未 inject 的名字在真实 cordis ctx
上会同步抛 cannot get property "installChannels" without inject,这正是 0.3.59「每次安装都失败」的根因。
新增 strict-ctx.mjs 严格测试替身(未 inject 的名字只能 ctx.get 读、属性访问抛错并记账本),
test-suite-detect.mjs / test-suite-install.mjs 全程改用,杜绝同类漏网。
② 依赖规格写回:release 来源的包不再被改写成「不存在的 npm 版本号」
现象:release 通道(从 GitHub release 的 tarball 装、npm registry 上并不存在的包)装完后,
<profile>/package.json 里该依赖 specifier 被改写成裸版本号(例 "@dsh-external/dsh-super-injector": "0.3.3"),
而该包 npm view 是 404。现在能跑只因 pnpm-lock.yaml 里还留着 tarball URL 的解析;
一旦 lock 被重建(删 lock、清 node_modules、换机、CI 重装)→ ERR_PNPM_FETCH_404,
而报错指向 npm registry,用户根本联想不到是几周前面板安装改写造成的。装完完全看不出问题。
根因(明确结论:0.3.57 引入的回归):写回者不是 release 通道本身(githubReleaseInstall() 只解压落盘、
从不碰 manifest),而是 0.3.57 新增的 lock 对账 reconcileLockfile()(首次引入提交 962c7e5,
git describe --contains = v0.3.57~1)—— 它对每个漂移包执行 pnpm add <name>@<installed>;
对 registry 上不存在的包,pnpm 见「已装版本满足新 spec」就静默改写成裸版本号
(真 pnpm 10.34.5 实测输出 Already up to date、EXIT=0,面板据此报 lockUpdated=true)。
修法:
- 写回前先探 registry(多镜像 + 超时兜底):这个包的这个版本可解析才写
<name>@<版本>,不误伤正常包; - 查无此包(404)→ 绝不写裸版本号:物化到
<DSH_HOME>/plugin-src/<包名>,specifier 写link:<绝对路径>; - 为什么不用 tarball URL:实测 pnpm 10 对 direct-URL 依赖只在冷缓存真下载时记
integrity,命中缓存重写 lock 时
resolution里没有 integrity →ERR_PNPM_MISSING_TARBALL_INTEGRITY,且 pnpm 会把 lock 文件直接删掉,
形成死循环。link:不经 registry 解析、不经完整性校验,8 个场景实测全通过; - 已污染状态自愈(裸版本号 spec + lock 解析到 URL → 自动规整为
link:); - 顺带修
lockVersionOf():遇specifier:行就break,导致它从未读到version:,对name@https://…
还会截断成http→ 来源钉住的包被判「永久漂移」,每次安装白跑一次pnpm add并给一条假的「没写进 lock」警告。
实测对照(真 pnpm 10.34.5 + 真 corepack,D:\ 临时 profile):
| 步骤 | 修前 | 修后 |
|---|---|---|
| lock 对账后 specifier | 0.3.3(裸版本号,pnpm EXIT=0) |
link:<DSH_HOME>/plugin-src/@dsh-external/dsh-super-injector |
| 删 lock + node_modules 后重装 | ❌ ERR_PNPM_FETCH_404 |
✅ 成功(--frozen-lockfile 亦通过) |
验证:18/18 测试全绿(真实网络,无跳过),新增 17 条缺陷②断言(含 dist-tag 规格护栏、link 链接有效性护栏)。
完整说明见 CHANGELOG.md;实测矩阵与审计清单见 D:\dsh\dsh-plugin-hub-plan\refactor-bugs.zh.md 第 23 节。
v0.3.61 - HOTFIX: installs failed (cannot get property installChannels without inject)
同 v0.3.60 的修复(0.3.60 被 npm 暂存发布流程占用,故改用 0.3.61)。详见 CHANGELOG 的 v0.3.60 一节:注入缝读取未 inject 的 cordis ctx 属性导致每次安装失败,已用 try/catch 兜底。
v0.3.60 - HOTFIX: installs failed with cannot get property installChannels without inject
v0.3.60 — 紧急修复:安装通道注入缝读到了 cordis ctx,导致每一次安装都失败(2026-09-22)
如果你在 0.3.59 上装插件报
cannot get property installChannels without inject,请立刻升级到本版。
- 根因:为单测加的"通道实现注入缝"写成
ports?.installChannels,而生产路径上ports就是 cordis 的ctx代理——
访问未在inject里声明的属性会同步抛错,于是每次安装都在进入通道前就失败(面板显示"操作失败:cannot get property installChannels without inject")。
预览线不受影响,因为它传的是routeDeps()出来的纯对象,所以这个错误只在稳定线(单体版)出现 —— 这正是"越改越坏"的那一处。 - 修复:注入缝的读取改为 try/catch 兜底(读不到就用真实实现),并加注释说明为什么不能直接访问 ctx 属性。
- 测试:18 个测试文件全绿;另核对单体版
channelImpls(ctx)在生产路径下会安全回落到真实实现。
教训(写进代码注释):给测试留的注入缝,绝不能挂在 cordis 的 ctx 代理上——要么走显式参数,要么兜住访问异常。
v0.3.59 - release channel finds the real publishing repo by package name (+ fix 0.3.58 TDZ regression)
v0.3.58 - install channels no longer gated together (git/release/curl get tried)
v0.3.57 — 所有安装通道都对账 lockfile:插件不再被 pnpm 静默还原
v0.3.57 — 所有安装通道都对账 lockfile:装上的插件不再可能被 pnpm 静默还原(2026-09-21)
与 0.3.56 的自更新修复同源。起因是用户实测报告:一键更新/兜底通道只把文件铺进
node_modules、
不写pnpm-lock.yaml,而 profile 依赖由 pnpm 按 lock 管理——之后任何 pnpm 操作(开关插件改
dsh.profile.bundles、dsh plugin add/remove)都可能把包还原成 lock 里的旧版本、甚至当外来物处理。
- 装完必对账:新增
reconcileLockfile(),覆盖所有非 pnpm 通道装出来的包——并行 curl / curl tarball /
GitHub Release / git 装配、套装装配出的普通插件(copyTree)、聚合包补装/对齐的子包:
① 版本与 lock 一致 → 直接返回(不跑 pnpm,零成本);② 有漂移 → 一次pnpm add <包1>@<v1> <包2>@<v2> …
把漂移包全部写进 lock;③ 仍对不上 → 面板如实告警(逐包列出"装了 X/lock 里是 Y")并给出可复制的
dsh plugin --profile <profile> add <包>@<版本>,不再假装成功。 - 安装结果视图新增
lockUpdated/lockVersion/lockNote;客户端在安装成功提示里显著追加⚠️ 警告。 - 与 0.3.56 的自更新修复配套:面板能改的东西,都不会再留下"装上了但不在 lock 里"的静默不一致。
如实说明覆盖边界:技能(~/.dsh/skills)与 agent 预设(~/.dsh/.agent-presets)不由 pnpm 管理,
本就不需要写 lock;受 pnpm 影响的是 node_modules 里的包,本次已全覆盖。
验证:18 个测试文件全绿(新增 4 条离线断言:一次 pnpm add 传数组 spec、对齐后逐包 aligned=true、
对不上逐包说清并给命令、失败包 aligned=false 不谎报)。另做了真 pnpm 实验确认机制:lock 钉 1.2.0 + 手铺
1.3.0 → install / add 另一个包 / install --force 均不覆写(本机 pnpm 11.21.0),
说明"静默不一致"是普遍存在但发作依赖环境的隐患——本版把它从根上消掉。
v0.3.56 — 一键更新写进 lockfile:升级不再被 pnpm 还原
v0.3.56 — 一键更新现在会写进 lockfile:升级不再被 pnpm 还原(2026-09-20)
版本号说明:
0.3.55首次发布时被 npm 的暂存发布流程拦下(409 Cannot publish over previously
staged version),重发改用了0.3.56;随后0.3.55也由该流程自动发布,两者内容相同,
npm 的latest已指向0.3.56。来自用户实测报告(附完整时间线与复现步骤):一键更新把文件铺进
node_modules、没动pnpm-lock.yaml;
而 profile 的依赖由 pnpm 按 lock 管理(dsh plugin本身就是 pnpm 的薄转发器),所以之后任何一次 pnpm 操作
——开关插件(改dsh.profile.bundles)、dsh plugin add/remove——都可能按 lock 重装,把刚升上去的版本
还原成 lock 里钉住的旧版本。用户侧现象:UI 一直提示有新版、点更新显示成功、重启后还是旧版。
- 自更新改为「包管理器优先」:spec 是版本范围 → 先
pnpm update <pkg>(spec 不变、同步把 lock 提到范围内最新);
仍没到最新(超出范围 / spec 是 git·file 来源)→pnpm add <pkg>@<版本>(spec 与 lock 一起改写,并在提示里说明来源切换)。 - 回读核实再报成功:响应新增
method/spec/installedVersion/lockVersion/lockUpdated/lockNote/
command/errors;手铺 tarball 降级为最后兜底,且必然带「此更新未写入 pnpm-lock.yaml,之后任何 pnpm
操作都会还原它」的醒目警告与可复制的dsh plugin --profile <profile> add <包>@<版本>。 - 面板提示同步:
lockUpdated === false时把警告显眼拼进结果提示,不再让人以为升级成功了。 - 附带解决报告里另一处不一致:
package.json的 spec 与 lock 长期不一致,导致「检测更新」一直提示一个
落不了地的版本——走 pnpm 路径后两者同步。
验证:真 pnpm(本机用的是 corepack 里的 pnpm 11.21.0)端到端跑产品自己的 selfUpdateToLatest():
把 fixture profile 里的控制台从 0.3.53 升到 0.3.54 → method=pnpm-update+pnpm-add、lockUpdated=true、
lockVersion=0.3.54;随后再触发重装与 pnpm install --force 强制重链,仍是 0.3.54 且 lock 一致。
如实说明:本地没能复现"被还原"这一步(pnpm 11 对本机手铺的文件在 install/add/--force 下都不覆写),
报告方的证据是其环境里的 lock 重写时间戳与框架备份记录;修复的价值在于让 lock 与安装版本始终一致,
并在此前不可能察觉的兜底路径上给出明确警告。18 个测试文件全绿(含 8 条新断言)。
v0.3.54 — 删除不再谎报 / 装完未重启也能撤 / 失败清场 / 聚合与套装进度
v0.3.54 — 真装真卸演练修出来的一整批(2026-09-20)
全部来自 2026-09-20 的真装真卸演练:拿本机没有的插件真装真卸(普通插件 / bundle 插件 / 无 npm 仓库 /
套装 / 技能 / 聚合仓库 / 仓库落地 / 服务器组件),不是纸面推断。
升级方式:面板里点「更新」,或 dsh plugin --profile <你的profile> add @noob-stupid/dsh-plugin-console@0.3.54。
修了什么
- 删除不再谎报:技能删除 / 残留清理 / 仓库落地删除 / 克隆前清理 / 装包前清旧目录,一律「删完核实再报成功」。
本机实测同一个删除调用在D:\成功、在C:\Users\…\.dsh\…与%TEMP%下会静默落空(不报错、目录还在),
旧版本删完直接回成功 → 你会遇到"技能删了还在""残留清理假装清干净"。现在删不掉就如实报错并给出目录路径。 - 克隆失败说人话:多源重试的失败汇总带上 git 自己说的原因(如
HTTP 502、无法解析主机);半成品目录
清不掉时停止重试并提示"请手动删除该目录",不再只丢给你一句"目录非空"。 - 装完未重启也能撤:
POST /uninstall现在也接受{jobId};/state新增pendingRestart,面板把"已安装但
还没被运行中的 DSH 加载"的插件显示成 「已安装·重启后生效」 行,删除按钮直接撤销这次安装(补丁行 / bundles /
包目录三处各自回读核实,没清干净会如实告警)。 - 失败清场:安装走到"等本地 AI 兜底授权"后取消或超时时,自动清掉本次落盘的包目录与 pnpm
_tmp_半成品,
并在错误里写清「已清理 X / 未能清理(请手动删除:路径)」。 - 聚合安装看得见进度:装多子包聚合仓库时显示「正在装第 i/n 个子包:<名字>」;需要授权本地 AI 兜底时,进度位置
出现带倒计时(剩余 mm:ss)的授权卡(同意 / 取消)——不再对着不动的进度条干等 10 分钟然后失败。套装通道同样
有「clone / 装配 第 i/n 个」进度。 @scope/all也认作聚合包(@dsh-suite/all这类以前命中不了);私有根仓库报错不再借用别人的包名
(以前任何无关仓库报错都让用户去装@linxin666/dsh-web-all)。
验证
- 18 个测试文件全绿(含真装真卸冒烟、路由契约、架构守卫)。
- 真跑演练逐类通过并复原基线:
node_modules逐项一致、cordis.patch.ymlsha 一致、/state条目数一致。 - 已知未在浏览器实测的项:授权卡与倒计时的实际观感(需要人工点一次)。