Repository navigation
Closed
Description
环境 / Environment
- DSH Desktop
0.11.1(Windows 11 家庭版 10.0.26200,AMD64) dshmarket1.66.22(npm latest)- 组件:
resources/app.asar/node_modules/dsh-desktop-market-installer/generations/installer.mjs→verifyGenerationPeers()
现象 / Actual behavior
用插件市场把 dsh-codex-subscription 从 2.6.5 更新到 2.6.9,安装阶段失败。.dsh-market/log.ndjson:
generation-install: hoisted 1 host singletons: @deepseek-ai/dsh-home-paths
generation-install: promoted to dsh-codex-subscription+2.6.9+d5a1264beda5
generation-install: generation peer validation failed:
@earendil-works/pi-ai does not resolve from the generation or installation closure
为什么这是误报 / Why it is a false positive
@earendil-works/pi-ai 是宿主自己就随包分发的:
resources/app.asar/node_modules/@earendil-works/pi-ai→ 版本 0.87.1resources/app.asar/node_modules/@deepseek-ai/dsh-llm-pi-ai/package.json→
"dependencies": { "@earendil-works/pi-ai": "^0.87.1" }
即它是宿主单例@deepseek-ai/dsh-llm-pi-ai(0.2.0-rc.2)的传递依赖。- 运行期也能解析(
resources/host-module-fallback.mjs提供宿主模块兜底)。
版本也完全满足:插件声明的 peer 范围是
"@earendil-works/pi-ai": "0.82.1 || 0.85.1 || 0.87.1 || 1.1.0 || 1.2.0"
0.87.1 命中。而且 2.6.5 → 2.6.9 的 peer 范围只多了一个 || 1.2.0(严格超集),两个版本的 generation pnpm-lock.yaml 除版本号与 integrity 外没有任何语义差异 —— 插件侧没有做错什么。
根因 / Root cause
installer.mjs:
32: const HOST_SINGLETON_PATTERNS = [/^react$/u, /^react-dom$/u, /^@deepseek-ai\//u]
45: function installationClosureDir(dshHome) { return join(dshHome, 'profiles', 'node_modules') }
614: const hostEntry = async (dependency) => {
615: if (!hostRequire || !isHostSingleton(dependency)) return undefined // ← 仅按“包名”放行hostEntry()只认名字(react/react-dom/@deepseek-ai/*)。@earendil-works/pi-ai名字不匹配 →:615直接返回undefined。- 另一条路是安装闭包
$DSH_HOME/profiles/node_modules(:45-47、:628-649)—— 但它在 0.11.1 上根本不存在。0.7.2 时代那里有一批指向应用树的 junction,改成经hostRequire解析之后就不再创建了(见:610-612注释)。 - 于是
:708报出does not resolve from the generation or installation closure。
结论:任何 peer 声明了「宿主自带、但包名不是 @deepseek-ai/*」的库的插件,在干净机器上都无法安装/更新。 现在这个 2.6.5 generation 之所以能用,只是因为它的 node_modules 里恰好被手工放了一份 @earendil-works/pi-ai(并非安装器所为)。
建议修复 / Suggested fix
三选一:
- 放宽 host 解析:对「宿主可解析的 peer」允许经
hostRequire解析,而不只是名字匹配的 singleton。「generation 内不得自带真单例副本」的规则只对真单例保留。 - 扩展 singleton 判定:把
@earendil-works/*这类随宿主分发的包纳入,或直接由宿主入口的依赖闭包计算。 - 恢复安装闭包供给:像 0.7.2 那样在
$DSH_HOME/profiles/node_modules下建立指向应用树的 junction(Plugin market / plugin updates never appear after restart — generation peer validation false-positives freeze the projection #293 的证据第 3 节记录了当时的布局)。
关联 / Related
- Plugin market / plugin updates never appear after restart — generation peer validation false-positives freeze the projection #293(已由 PR AND-400: fix generation peer validation for Desktop links #354 关闭)—— 同一族
verifyGenerationPeers误报 - [Bug] 生成代迁移必败:hoistHostSingletons 会把 @deepseek-ai/ 前缀插件自身的包从生成代删掉(validateGeneration ENOENT) #402(open)——
hoistHostSingletons会删掉@deepseek-ai/前缀插件自身的包
本地绕过 / Local workaround(仅供确认根因,不是修复)
在 $DSH_HOME/profiles/node_modules/@earendil-works/pi-ai 放一份从可用 generation 复制出来的 0.87.1 后,2.6.9 的 peer 校验即通过 —— 正好说明缺的只是「闭包供给」这一环。
Metadata
Metadata
Assignees
Labels
No labels
Activity
yaojin3616 commentedon Oct 21, 2026
关闭说明:重复 Issue,与 #723 内容及标题完全一致。请在 #723 中继续跟踪讨论。