Repository navigation
[BUG] 插件管理器裸包名安装受 pnpm 11 minimumReleaseAge 默认值影响:新版本发布 24 小时内静默降级到上一版并被判不兼容 #9178
Replies: 1 comment
|
机制、时间线、peer 范围我都核过了,你的判断基本全对,而且我用 pnpm 实测复现了你缺的那一环。补一处更准的根因表述,再指出一个可直接提的上游改进点。 1. 我实测复现了关键分歧:
|
|
机制、时间线、peer 范围我都核过了,你的判断基本全对,而且我用 pnpm 实测复现了你缺的那一环。补一处更准的根因表述,再指出一个可直接提的上游改进点。 1. 我实测复现了关键分歧:
|
Uh oh!
There was an error while loading. Please reload this page.
桌面端插件管理器:裸包名安装会被 pnpm 11 的 24 小时发布时长隔离静默降级到旧版本,随后被兼容性检查拒绝
环境
app.asar版本文件44.0.00.2.0-rc.2(@deepseek-ai/dsh-base/dsh-tools/dsh-web-app/dsh-app-boot均为该版本)desktop(%USERPROFILE%\.dsh\profiles\desktop)11.7.0(profile 内.modules.yaml的packageManager)registry.npmmirror.com(registry.npmjs.org的dist-tags完全相同)dsh-drawai(标准 DSH bundle 插件,dsh.bundle.patch)摘要
在「插件 → 添加插件」中用裸包名(不带版本号)安装插件时,如果该插件的最新版本发布时间不足 24 小时,插件管理器会解析到一个更旧的版本;而该旧版本往往已经不兼容当前 DSH 运行时,于是安装被"兼容性检查"拒绝并整体回滚。
dsh-drawai就是一个确定性复现的例子:包名裸装 → 解析到0.1.1→ 报"不兼容 dsh 0.2.0-rc.2"→ 回滚。而实际上0.2.1完全兼容,只是"太新"被隔离策略挡住了。根因是 pnpm 11 的供应链默认设置
minimumReleaseAge=1440分钟(24 小时),不是 DSH 自己的配置——但在当前安装流程里,这个降级既没有被告知,也不会被兼容性约束纠正,最终以一条误导性的错误信息呈现给用户。复现步骤
0.2.0-rc.2),确保目标插件最新版本发布于 24 小时以内。dsh-drawai,回车 / 点「安装」。本例三次操作的实际结果:
dsh-drawai+ dsh-drawai ^0.1.1dsh-drawai+ dsh-drawai ^0.1.1dsh-drawai@0.2.1+ dsh-drawai 0.2.1预期行为 / 实际行为
预期:安装可用的最新版本;若最新版本因某种原因不可用,明确说明原因,并且不要解析到一个与当前运行时已知不兼容的版本。
实际:
关键证据
1) 版本与发布时间(
registry.npmjs.org/npmmirror一致)两源的
/latest端点当时与事后都返回0.2.1。元数据本身没有问题。2) 兼容性(
peerDependencies["@deepseek-ai/dsh-tools"])3) 插件管理器日志(原文)
第一次尝试(失败):
第三次尝试(指定版本,成功)—— 日志里藏着根因:
minimumReleaseAgeExclude这个提示是 pnpm 自己打印的,说明当时确实有发布时长隔离在生效。安装后 profile 的pnpm-workspace.yaml被追加:4) 对照实验(决定性)
在一个全新的空项目里用全局 pnpm 11.21.0、npmmirror 源、全新 store/cache 执行裸包名安装:
执行时间约 22:35,此时
0.2.1只有 45 分钟大、0.2.0已 24 小时 07 分。安装的是 0.2.0 而不是最新的 0.2.1 —— 证明隔离策略与 DSH 无关,任何 pnpm 11 环境都会这样解析。该实验同时把阈值夹定在
(23h54m, 24h07m],与官方文档的1440分钟完全吻合。5) 官方文档(根因确认)
pnpm 官方《缓解供应链攻击》:
来源:https://pnpm.io/zh/supply-chain-security
(pnpm 11 的"延迟依赖更新"是有意为之的安全特性,不是 bug。问题在于它与插件安装流程的交互。)
根因
时间窗口: 一个插件每发布一个新版本,接下来的 24 小时内,裸包名安装都会解析到上一版。对于像
dsh-drawai这样每个版本都会调整peerDependencies范围的插件,上一版往往正好不兼容 —— 于是这 24 小时内该插件无法用裸包名安装,任何用户都会撞上一条吓人的"可能崩溃/丢数据"提示。本例的具体窗口:
0.2.0发布于 10-07 22:28,直到 10-08 22:28 才满 24 小时;在此之前裸装一律解析到0.1.1并被拒绝。这也解释了为什么 22:12 和 22:22 两次尝试必然失败(只差 16 分钟和 6 分钟),而 22:30 指定版本后立即成功。影响与危害
dsh-drawai@0.1.1授予精确版本豁免」——而0.1.1是因为隔离策略才被选中的降级产物,本身确实不兼容。用户照着做等于主动接受崩溃/数据损坏风险,而这个风险完全是流程造成的假象。这是本报告最重要的一点。pnpm-workspace.yaml(minimumReleaseAgeExclude),等于对该包静默削弱了这道安全防线。用户不知道自己的安全设置被改动了;在minimumReleaseAgeStrict未开启时不会有任何确认。建议修复(按优先级)
版本选择要同时满足"发布时长"与"运行时兼容"两个约束。
解析候选版本时,若最新版被发布时长隔离挡住,应继续向下找一个与当前 DSH 运行时兼容的版本;找不到就明确报"最新兼容版本 X 因发布不足 24 小时暂不可安装",而不是塞一个已知不兼容的版本进去。
重写这条错误信息。 当被拒绝的版本是隔离策略造成的降级产物时,应当:
0.2.1)及可一键执行的安装方式(包名@0.2.1);不要在用户无感的情况下改动供应链设置。 安装流程若需要写
minimumReleaseAgeExclude,应当在安装结果里明确列出,或默认开启minimumReleaseAgeStrict让用户确认。把
minimumReleaseAge纳入插件安装策略的一部分。 建议为插件安装显式声明策略(例如安装页面显示"新版本发布满 24 小时后可自动获取"),让行为可预期而不是隐式继承 pnpm 默认值。已验证的绕过方式
dsh-drawai@0.2.1minimumReleaseAgeExclude并安装;由于 0.2.1 本身兼容,兼容性校验通过github:owner/repo形式minimumReleaseAge只作用于注册源版本)附:其他观察(非阻塞)
Packages: -27再重建,失败时由 DSH 整体还原node_modules。还原是正确的(事后核对:profile 内应有的 26 个包一个不缺),但一次失败尝试要动 27 个包的链接,代价偏大。dsh-drawai)本身没有问题:包完整(cordis.patch.yml+ 预构建lib/)、无安装期脚本、peerDependencies声明正确,最新版与0.2.0-rc.2兼容。本报告针对的是安装流程,不是插件。报告整理者:DSH 会话内 AI 助手;证据来自本机
%USERPROFILE%\.dsh\profiles\desktop\.plugin-manager\logs\、pnpm 元数据缓存、注册源响应与一次对照实验,另引用了 pnpm 官方文档。All reactions