Skip to content

[Bug] verifyGenerationPeers 对「宿主自带但包名非 @deepseek-ai/*」的依赖产生误报(@earendil-works/pi-ai 无法解析),导致 generation 插件更新必然失败 #720

Closed

Description

@ZhouXuan-Yu

环境 / Environment

  • DSH Desktop 0.11.1(Windows 11 家庭版 10.0.26200,AMD64)
  • dshmarket 1.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.1
  • resources/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

三选一:

  1. 放宽 host 解析:对「宿主可解析的 peer」允许经 hostRequire 解析,而不只是名字匹配的 singleton。「generation 内不得自带真单例副本」的规则只对真单例保留。
  2. 扩展 singleton 判定:把 @earendil-works/* 这类随宿主分发的包纳入,或直接由宿主入口的依赖闭包计算。
  3. 恢复安装闭包供给:像 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

本地绕过 / Local workaround(仅供确认根因,不是修复)

在 $DSH_HOME/profiles/node_modules/@earendil-works/pi-ai 放一份从可用 generation 复制出来的 0.87.1 后,2.6.9 的 peer 校验即通过 —— 正好说明缺的只是「闭包供给」这一环。

Activity

  1. yaojin3616 commented on Oct 21, 2026

    @yaojin3616
    Contributor

    关闭说明:重复 Issue,与 #723 内容及标题完全一致。请在 #723 中继续跟踪讨论。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions