Skip to content

[Bug] DSH Desktop 0.11.0:升级后 profile 迁移必然冻结 —— 闭包目录不存在 + 迁移路径未传 dshEntryPath,宿主单例 peer 校验必失败,插件市场无法安装 #654

Open

Description

@rngfbbbffhjgggd-commits

环境

  • DSH Desktop 0.11.0(Windows x64,2026-10-07 15:44 由 0.10.0 覆盖升级;更新来源为「关于 → 选择版本」的 archive feed)
  • 内置内核 @deepseek-ai/dsh 0.2.0-rc.2(从 resources\app.asar 内解析确认,@deepseek-ai/cordis 4.0.4)
  • runtime node v24.17.0;DSH_HOME=C:\Users\<user>\AppData\Roaming\dsh-desktop\harness
  • 升级前的旧内核:0.1.7-rc.2(DSH Desktop 0.10.0)

现象

  1. 升级到 0.11.0 后首次启动,profile(web)迁移失败并整体回滚,日志:
[desktop] generation-install: installing ^0.3.14 into staging
[desktop] generation-install: installed in 2519ms
[desktop] generation-install: promoted to machine-126+dsh-alert-sound+0.3.14+9fc3a4eaee81
[desktop] migration failed, restoring the pre-upgrade profile: @machine-126/dsh-alert-sound failed peer validation: @deepseek-ai/cordis does not resolve from the installation closure; react does not resolve from the installation closure
[desktop] profile maintenance frozen: migration deferred (@machine-126/dsh-alert-sound failed peer validation: @deepseek-ai/cordis does not resolve from the installation closure; react does not resolve from the installation closure)
  1. profiles\web\.generations-deferred.json 被写入(冻结标记)。
  2. 之后在 设置 → 插件市场 安装 dshmarket 失败:
Command failed with exit code 1: pnpm add --workspace-root "dshmarket@^1.65.1"

(pnpm 本身没报错——0.11.0 之前那层 patchedDependencies 补丁文件缺失的问题已另行修复;这次失败是 profile 被冻结、不允许再变更。)

也就是说:迁移失败 → 冻结 → 市场装不了,而迁移失败的原因与 #581 / #293 同族。

本机实测的关键事实

检查项 结果
harness\profiles\node_modules(= installationClosureDir()) 不存在(不是断链,是整个目录没有)
harness\profiles\web\node_modules\react 不存在
resources\app.asar.unpacked\node_modules\@deepseek-ai\ 只有 libreoffice-kit-win32-x64
react / @deepseek-ai/dsh-* / @deepseek-ai/cordis 实际位置 全部在 resources\app.asar 内部(0.11.0 起 JS 依赖收进 asar)

由此:

  1. [Bug] dsh-desktop 0.10.0 覆盖升级后插件市场无法安装/更新任何插件:peer 校验报 "does not resolve from the generation or installation closure" #581 给出的临时解在 0.11.0 上已经失效。[Bug] dsh-desktop 0.10.0 覆盖升级后插件市场无法安装/更新任何插件:peer 校验报 "does not resolve from the generation or installation closure" #581 的做法是把 profiles\node_modules 里 660 条断链重新指向 ${appPath}.unpacked\node_modules;但 0.11.0 的 app.asar.unpacked\node_modules 里已经没有 react、@deepseek-ai/*(只剩原生包),没有可指向的真实路径。
  2. 迁移把它判死,而闭包目录只在迁移成功收尾时由 shared-tree 安装创建(reinstallSharedTree() 在 verifyGenerationPeers 之后才跑),于是形成死循环:
    闭包不存在 → peer 校验失败 → 迁移回滚 → 闭包永远不被创建。

根因(代码级,0.11.0 自带 asar 内)

verifyGenerationPeers() 本身设计了两条路:

// generations/installer.mjs
export async function verifyGenerationPeers(dshHome, generation, options = {}) {
  const hostRequire = options.dshEntryPath ? createRequire(options.dshEntryPath) : undefined
  const hostEntry = async (dependency) => {
    if (!hostRequire || !isHostSingleton(dependency)) return undefined
    ...
  }
  const closure = await realpath(installationClosureDir(dshHome))   // profiles/node_modules
  ...
  if (resolved === undefined) {
    problems.push(isHostSingleton(dependency)
      ? `${prefix}${dependency} does not resolve from the installation closure`   // ← 我们命中的就是这条
      : `${prefix}${dependency} does not resolve from the generation or installation closure`)
  }
  • 「宿主解析」这条后路(createRequire(dshEntryPath),正是为 0.1.7 老 profile 的宿主包准备的)只在市场安装插件那条路径上传了参数:

    const peers = await verifyGenerationPeers(dshHome, generation, { dshEntryPath })   // ✔ 市场路径
  • 而启动迁移路径和两处恢复路径都没传:

    const peers = await verifyGenerationPeers(dshHome, result.generation)     // ✘ 迁移路径
    const peers = await verifyGenerationPeers(dshHome, candidate)             // ✘ 恢复路径 ×2

结果:迁移/恢复时宿主单例(react、@deepseek-ai/*)只能从 profiles\node_modules 解析,而该目录在 0.11.0 的 asar 布局下既不存在、也无法用 junction 指进 asar。任何声明了宿主单例 peer 的插件都会让整个迁移回滚——本机 profile 里这类插件有 5 个(alert-sound 2 个 peer、memos 8 个、auto-review 16 个、genui 19 个、web-mobile 11 个),所以即使逐一摘除也极易连环触发。

为什么“把插件升级到 0.2 适配版”也不一定能解套

核对了 0.2.0-rc.2 内核里 verifyGenerationPeers() 的完整判据后确认:

const optionalPeerOnly =
  Object.hasOwn(peerDependencies, dependency) &&
  peerDependenciesMeta?.[dependency]?.optional === true &&
  !Object.hasOwn(dependencies, dependency)
...
if (optionalPeerOnly && !isHostSingleton(dependency)) continue      // 非宿主单例的 optional peer 才放行
if (resolved === undefined && !optional) {
  problems.push(isHostSingleton(dependency)
    ? `${prefix}${dependency} does not resolve from the installation closure`
    : `${prefix}${dependency} does not resolve from the generation or installation closure`)
}

即:react / react-dom / @deepseek-ai/* 这些宿主单例的 peer,无论是否标 optional,都必须能从闭包解析,否则直接判失败。

同时内核自带文档明确写着:dsh.manifestVersion 与 engines.dsh 仅作声明,"当前安装器和加载器不强制检查 …… 声明范围不会拒绝不兼容的宿主"。所以:

  • 给插件补 engines.dsh / dsh.manifestVersion 不能消除这个报错;
  • 把插件升级到“0.2 适配版”也不能——只要新版本仍然声明 react / @deepseek-ai/* peer(0.2 适配版通常照旧声明),校验依旧要求闭包能解析。

能真正解开死锁的只有两条:(a) 让闭包真的能解析这些宿主单例,(b) 把声明了这类 peer 的插件从 profile 里摘掉。这也是为什么本 issue 主张的修法是“迁移路径补上 dshEntryPath”。

建议修法

  1. 迁移与恢复路径补上 dshEntryPath(与市场路径一致),让宿主单例通过运行中的宿主 entry 解析——这是改动最小、与既有设计一致的修法。
  2. 或者:installationClosureDir() 在 asar 布局下的目标根不能再用盘上链接表达时,改由宿主注入的解析表判定,并在闭包缺失/失效时自动重建,而不是让校验把整个迁移打回。
  3. 附带建议:闭包整体失效时,报错与界面提示应直接指向闭包,而不是像 [Bug] dsh-desktop 0.10.0 覆盖升级后插件市场无法安装/更新任何插件:peer 校验报 "does not resolve from the generation or installation closure" #581 里那样把锅甩给某个恰好必须走闭包的依赖;[Bug] dsh-desktop 0.10.0 覆盖升级后插件市场无法安装/更新任何插件:peer 校验报 "does not resolve from the generation or installation closure" #581 里提到的"请手工重新安装该插件 / 对齐 package.json 与 pnpm-lock.yaml"在本场景是死路。

受影响的插件范围(本机 profile + npm registry 核查)

本机 profile 里会触发该校验、且本次尚未迁移的插件(profiles\node_modules 不存在 → 全部必失败):

插件 本机版本 声明的宿主单例 peer npm 上有 0.2 适配版吗
@machine-126/dsh-alert-sound 0.3.14 react、@deepseek-ai/cordis 有新版本(0.3.16,10-06)但仍声明同样的 peer
@memtensor/memos-local-plugin 2.0.20 8 个(cordis / dsh-agent / dsh-llm / dsh-session / dsh-system-prompt / dsh-timeout / dsh-tools / schemastery) 无:最新 2.0.20 的 peer 明确写 >=0.1.0-rc.5 <0.2.0
dsh-auto-review 0.12.10 16 个 有:0.12.11 起 engines.dsh 含 >=0.2.0-0 <0.3.0(最新 0.12.15)
dsh-more-session-operations 0.3.1(本地 tarball) peer 名为裸 cordis(非宿主单例 → 走“generation or installation closure”分支) 不在 npm 上,无适配版
@dsh-external/dsh-clawd-bridge 0.1.0(本地 link) 无 peer 不在 npm 上;本次迁移已成功
@liustack/modsearch 5.10.6 无 peer 不存在该报错路径
@changfenhuang/dsh-genui / dsh-web-mobile 0.11.3 / 3.0.4(已在 .generations/live,本次跳过) 19 / 11 个 已在新版分支内

(旁证:CLI home ~/.dsh\profiles\node_modules 这棵闭包树同样处于损坏状态——react/react-dom 目录存在但没有 package.json,@deepseek-ai/dsh-client-runtime、@deepseek-ai/dsh-client-ui-slots 缺失。说明“闭包不重建/不修复”不是单一 home 的问题。)

复现要点

  1. Windows 上装 DSH Desktop 0.10.0,profile 里存在声明 react / @deepseek-ai/* peer 的第三方插件(例如 @machine-126/dsh-alert-sound@0.3.14)。
  2. 覆盖升级到 0.11.0(内置内核 0.2.0-rc.2)。
  3. 观察启动日志的 migration failed, restoring the pre-upgrade profile: … does not resolve from the installation closure,以及 profiles\web\.generations-deferred.json。
  4. 再去 设置 → 插件市场 安装 dshmarket,pnpm 阶段成功、随后因冻结失败。

与 #577 / #581 的关系

关联 issue

Activity

  1. rngfbbbffhjgggd-commits commented on Oct 7, 2026

    @rngfbbbffhjgggd-commits
    Author

    补充一次受控实验的结果(同一台机器,Windows x64,0.11.0 + 内核 0.2.0-rc.2),它把本 issue 的结论收紧了:

    我把 profile 里所有声明宿主单例 peer 的插件都从 dependencies 与 dsh.profile.bundles 摘掉(@machine-126/dsh-alert-sound、@memtensor/memos-local-plugin、dsh-auto-review、dsh-more-session-operations),只留下 @dsh-external/dsh-clawd-bridge、@changfenhuang/dsh-genui、dsh-web-mobile、@liustack/modsearch,然后重启。结果:

    [desktop] migration: moving 4 plugin(s) to generations: @dsh-external/dsh-clawd-bridge, @changfenhuang/dsh-genui, dsh-web-mobile, @liustack/modsearch
    [desktop] migration: @dsh-external/dsh-clawd-bridge -> dsh-external+dsh-clawd-bridge+0.1.0+6bc80f2f956b
    [desktop] generation-install: hoisted 1 host singletons: react…
    [desktop] generation-install: generation changfenhuang+dsh-genui+0.11.3+c8c2db603fa2 already exists, reusing
    [desktop] migration failed, restoring the pre-upgrade profile: @changfenhuang/dsh-genui failed peer validation: @deepseek-ai/dsh-agent does not resolve from the installation closure; @deepseek-ai/dsh-client-ui-primitives does not resolve from the installation closure; react does not resolve from the installation closure
    [desktop] profile maintenance frozen: migration deferred (…)
    

    两点关键观察:

    1. 迁移每次都会把所有社区插件重新纳入计划并重新校验,包括 .generations/live 里已经存在的 generation。日志里 genui 明确走了 already exists, reusing,但随后仍然执行 verifyGenerationPeers() 并失败。于是摘插件只是把卡点往后推:本机在摘掉 4 个之后,卡点前移到了 @changfenhuang/dsh-genui(19 个宿主 peer)和 dsh-web-mobile(11 个宿主 peer)——而这两个恰好是不能摘的(genui 提供 DSH 的 UI 组件渲染,web-mobile 是手机访问)。

    2. 因此不存在靠用户删减插件来绕过该缺陷的可行配置:只要 profile 里还剩任何声明 react / @deepseek-ai/* peer 的插件,迁移就不可能完成,闭包目录也就永远不会被创建(它只在迁移成功收尾时创建)。修复必须落在闭包解析上(本 issue 建议的 dshEntryPath,或恢复 [Bug] 0.10.0 稳定版出厂包移除了 healProfilesModuleFallback,profiles\node_modules 遗留 214 个失效链接、47 个包不可用 — 0.10.0 shipped without the profile fallback healer: 214 dead links, 47 packages unavailable #577 里被移除的 healer)。

    顺带一提:摘掉插件之后,日志里出现了 profile inconsistency: dsh-auto-review is installed but declared nowhere in the profile manifest(同类还有 dsh-more-session-operations)——这是删除后的正常残留告警,不影响判断。

    (本次实验的 profile 改动均已备份,可随时还原;如需要我可以提供 package.json 前后对照。)

  2. rngfbbbffhjgggd-commits commented on Oct 9, 2026

    @rngfbbbffhjgggd-commits
    Author

    补充两个代码级的「别走弯路」结论,以及本机当前状态(0.11.0 / 内核 0.2.0-rc.2 / Windows x64,与本 issue 环境一致):

    1. 把 peer 标成 optional 不是绕法。 installer.mjs 对 optional peer 有一条宿主单例例外:

    const optionalPeerOnly = Object.hasOwn(peerDependencies, dependency) &&
      manifest.peerDependenciesMeta?.[dependency]?.optional === true && …
    if (optionalPeerOnly && !isHostSingleton(dependency)) continue

    isHostSingleton() 命中时,即使标了 optional 仍会继续解析并要求成功。所以「请插件作者把 cordis / schemastery 标成 optional」这类建议在本 issue 语境下不成立——不必去麻烦插件作者。

    2. 在 profile 里给插件打 pnpm patch 同样无效。 代际安装是独立 pnpm workspace,只继承两项 profile 设置。generationBuildApprovals() 上方的注释写得很明确:

    No other Profile workspace setting is inherited: patchedDependencies and relative package globs would be invalid inside the immutable staging tree.

    即只继承 allowBuilds(逐条解析)与 autoInstallPeers(正则读取)。改 profile 里 node_modules/<pkg>/package.json 不会进入 staging 那棵不可变的树。

    顺带一刀:autoInstallPeers: true 是唯一能把这三个 peer 装进 staging 从而「过检」的开关,但它是 workspace 级设置,会让所有声明宿主 peer 的插件(dshmarket 同样声明 @deepseek-ai/cordis)都拿到宿主单例的副本,模块双实例风险很大——不建议作为修复方案。

    3. 当前状态数据点(2026-10-09):冻结仍在,且触发点会随生态扩大而增长。本机这次不是升级触发,而是新装了一个普通布局的第三方插件 dsh-context@0.66.1(声明 @deepseek-ai/cordis / dsh-session / schemastery 三个必需宿主 peer):

    [desktop] migration: moving 5 plugin(s) to generations: @dsh-external/dsh-clawd-bridge, dsh-context, @changfenhuang/dsh-genui, dsh-web-mobile, @liustack/modsearch
    [desktop] generation-install: promoted to dsh-context+0.66.1+7d7043b337cf
    [desktop] migration failed, restoring the pre-upgrade profile: dsh-context failed peer validation:
              @deepseek-ai/cordis does not resolve from the installation closure;
              @deepseek-ai/dsh-session does not resolve from the installation closure;
              @deepseek-ai/schemastery does not resolve from the installation closure
    [desktop] profile maintenance frozen: migration deferred (…)
    

    两点含义:

    • (a) 只要 profile 里新出现任何声明宿主 peer 的插件(生态里这类插件是主流,dsh-context 有 1.9k star),就会重新冻结整批——这不是「升级那一次」的问题,而是会随插件安装持续复现;
    • (b) .generations-deferred.json 的 retryAfter 是 6 小时,窗口过后下次启动会重试并再次整批回滚,所以该状态周期性出现(本机 2026-10-07 也有同类残留 .generations-deferred.json.bak-20261007-115944)。

    另附一条可能有用的事实:本机 resources/app.asar 内 @deepseek-ai/dsh 与 dsh-app-boot 均为 0.2.0-rc.2、cordis 4.0.4,而 verifyGenerationPeers 的 hostEntry() 走的是 options.dshEntryPath——也就是说修复所需的宿主入口本来就在 asar 里、可达,只是迁移路径没把 dshEntryPath 传下去,与标题判断一致。


    给生态侧的对照参考:本次触发点 dsh-context 的作者已同步收到提醒(bowenliang123/dsh-context#132,明确「无需改动声明」),以避免排查方向被引到插件侧。若后续还有用户报「装了某插件后市场装不了」,可直接指向本 issue 并复用上面两条「不成立的解法」结论。

  3. bowenliang123 commented on Oct 10, 2026

    @bowenliang123

    @rngfbbbffhjgggd-commits 不要用 AI 乱发 issue,你的提交里面都直接说了不是我插件的原因了,你还给我提 issue 干嘛?

    强烈反对。

  4. rngfbbbffhjgggd-commits commented on Oct 12, 2026

    @rngfbbbffhjgggd-commits
    Author

    同一台机器补充一个 2026-10-12 的数据点(Desktop 仍 0.11.0,内核 @deepseek-ai/dsh 0.2.0-rc.2,
    cordis 4.0.4,DSH_HOME 同本 issue,harness\profiles\node_modules 复核仍不存在)。
    结论:这个冻结的表现形态已经变了,比"推迟 6 小时"更糟。

    1. 现在不只是推迟,而会留下「声明残缺 + 市场显示启用中」的死行

    触发插件是 dsh-context@0.68.0(与 10-09 那条评论里同一个插件,只是又升了版)。这次 Desktop 在启动时
    不再只是回滚,而是把它从 dsh.profile.bundles 里摘掉,同时 package.json 的 dependencies 与
    dsh.desktop.generationProjection 里的记录留着:

    [2026-10-12T02:58:57Z] [desktop] migration deferred before staging: dsh-context has no readable installed package manifest
    [2026-10-12T02:58:57Z] [desktop] profile maintenance frozen: migration deferred (dsh-context has no readable installed package manifest)
    [2026-10-12T02:58:57Z] [desktop] removed unresolvable bundle declaration(s): dsh-context; package files, user patches and plugin data kept, pnpm-lock.yaml dropped for re-resolution
    [2026-10-12T02:58:57Z] [desktop] profile inconsistency: bundle dsh-context is declared but not installed
    

    后果有三条,都是可观测的:

    1. 插件市场仍显示「启用中 / 已是最新」(市场的开关状态没变),但实际没有任何 loader 行 ——
      实时组装结果 profiles\web\cordis.yml 里一行都没有该插件(市场自己的「为什么未生效?」提示指的就是这个);
    2. 迁移此后每次冷启动都以同一理由失败(dsh-context has no readable installed package manifest:
      Desktop 摘掉了 bundle 声明却没清 dependencies,规划阶段读不到它的 profile 副本),
      .generations-deferred.json 的 retryAfter 每次冷启动刷新,等于永久冻结;
    3. 期间插件更新会被 trial 校验判成「the profile will fail to boot」并回滚
      (实测 dsh-web-mobile 3.0.5→3.0.6 被回滚一次,重试才过)。

    即:冻结不只是延迟,它会让一个插件在用户眼里"装着、开着、却是死的",并连带阻塞更新。

    2. 一个可用的用户侧绕法(不改插件、不改 Desktop)

    插件在冻结前已经被 generation-install 成功 promoted 到代际存储,所以包体是完整可用的
    (lib/index.js 106 KB、客户端半边 lib/client.js 396 KB、dsh.bundle.patch 就位;宿主版本
    cordis 4.0.4 / dsh-session 0.2.0-rc.2 / schemastery 3.18.4 均满足其 peer 范围)。
    把它复制到 profile 之外、按 file:// 绝对路径挂载即可(与社区里 memos、wsl-bash 等
    profile 外部插件同款;宿主有运行时兜底解析宿主包 —— 这两个现役插件自身 node_modules 里
    都没有 @deepseek-ai/* 副本,却都 import 宿主包且工作正常):

    # <DSH_HOME>\profiles\web\cordis.patch.yml
    - insert:
        - id: dsh-context
          name: 'file:///C:/Users/<user>/AppData/Roaming/dsh-desktop/harness/dsh-context/node_modules/dsh-context/lib/index.js'

    要点:

    • 包与其唯一的运行时依赖 zod 要同级放好(node_modules/dsh-context + node_modules/zod),
      宿主兜底只覆盖宿主包,普通依赖仍走 Node 解析;
    • 挂载后必须冷启动:实测用 Node 原子替换(临时文件 + rename)写入 patch 文件后宿主零反应
      (cordis.yml 未重生成、harness.log 一行未动)→ 补丁文件的实时监视器不一定吃外部写入,
      改完一律按"下次冷启动生效"处理;
    • 这条路不参与安装期 peer 校验,也不受代际迁移影响,可作为本 issue 修复前的一般性缓解手段;
    • 验收:右侧边栏出现 Context 面板 + 会话里 /context 命令可用(2026-10-12 实测);
    • 残留:市场卡片仍会显示「启用中」、package.json 里的记录仍在(迁移会继续以它为理由冻结)。
      ⚠️ 不建议靠"把该插件从 dependencies 摘掉"来解冻:那等于放行整条代际迁移(本机
      .generations-migrated 至今不存在),迁移会先 snapshotProfile()(把 node_modules /
      package.json / pnpm-lock.yaml 改名成 *.pre-generations)再逐个校验,一旦在后面的插件上失败
      就进入"回滚 + 重试"循环 —— 比现在这种"规划阶段就放弃、什么都不碰"的状态风险大得多。

    3. 复现要素(供定位)

    项 值
    触发插件 dsh-context@0.68.0(peer 依赖宿主单例 @deepseek-ai/cordis / dsh-session / schemastery)
    harness\profiles\node_modules 仍不存在(本 issue 的核心事实,2026-10-12 复核)
    冻结标记 <DSH_HOME>\profiles\web\.generations-deferred.json(protocol: 6,6 小时窗口)
    迁移标记 <DSH_HOME>\profiles\web\.generations-migrated 不存在
    受影响 市场卡片状态失真、插件静默不生效、后续插件更新被 trial 回滚
  5. rngfbbbffhjgggd-commits commented on Oct 13, 2026

    @rngfbbbffhjgggd-commits
    Author

    5. @rngfbbbffhjgggd-commits 不要用 AI 乱发 issue,你的提交里面都直接说了不是我插件的原因了,你还给我提 issue 干嘛?
    强烈反对。

    sorry

  6. rngfbbbffhjgggd-commits commented on Oct 13, 2026

    @rngfbbbffhjgggd-commits
    Author

    补一个 2026-10-13 的数据点:冻结仍在按周期复发,而且卡点已经从 10-09 那条里的 dsh-context 前移到 @changfenhuang/dsh-genui —— 也就是 10-07 那条评论里「摘掉插件只是把卡点往后推」的判断,两周后在同一台机器上被复现。

    环境不变:Windows x64、Desktop 0.11.0、内核 @deepseek-ai/dsh 0.2.0-rc.2、cordis 4.0.4,DSH_HOME 同本 issue。

    冻结标记(今天 15:43 本地时间又写了一次)

    <DSH_HOME>\profiles\web\.generations-deferred.json:

    {
      "protocol": 6,
      "fingerprint": "009e58c093dfa6aab6451fe7bb39a3ab2868caacd2a859de4b2fb43760bec072",
      "reason": "@changfenhuang/dsh-genui failed peer validation: @deepseek-ai/dsh-agent does not resolve from the installation closure; @deepseek-ai/dsh-client-ui-primitives does not resolve from the installation closure; react does not resolve from the installation closure",
      "failedAt": "2026-10-13T07:43:26.879Z",
      "retryAfter": "2026-10-13T13:43:26.879Z"
    }

    复核

    项 值
    harness\profiles\node_modules(installationClosureDir()) 仍不存在
    profiles\web\.generations-migrated 仍不存在
    dsh.profile.bundles 仍列出 @changfenhuang/dsh-genui(0.12.0)
    该插件的代际安装本身 成功:generation-install: installed in 4325ms → promoted to changfenhuang+dsh-genui+0.12.0+ff571db67132,包体完整可用

    也就是说:安装阶段没问题,卡的是迁移阶段对代际产物的宿主 peer 解析 —— 与标题判断一致,且把触发插件从 dsh-context 换成 genui 之后结论完全一样(@deepseek-ai/dsh-agent / dsh-client-ui-primitives / react 三个都「does not resolve from the installation closure」)。

    一点含义

    用「删插件」绕过这条路走不通:能摘的摘掉之后,卡点会前移到摘不掉的插件上(本机 dsh-genui 提供 DSH 的 UI 渲染、dsh-web-mobile 提供手机访问,二者各自还声明着十几个宿主 peer)。10-09 那条里已经列出两条不成立的解法(把 peer 标 optional、在 profile 里打 pnpm patch),本次未再重复验证。

    对修复的要求(与前面一致)

    启动迁移与恢复路径把 dshEntryPath 传给 verifyGenerationPeers();或恢复 #577 里被移除的 healProfilesModuleFallback。判定标准很直接:harness\profiles\node_modules 是否被创建、.generations-migrated 是否落盘。

    在此之前,profile 外部按 file:// 挂载仍是可用的用户侧缓解手段(10-12 那条已给出具体做法)。

  7. EqOSl1me commented on Oct 14, 2026

    @EqOSl1me

    Data point: a second, earlier failure mode in the same freeze — plus a user-side escape that satisfies this issue's acceptance criterion (.generations-migrated on disk).

    On a home created by importing a CLI-managed ~/.dsh (.desktop-install-state.json → "classification": "existing"), the migration in 0.11.1 dies in validateGeneration() before peer validation is reached: the migration list is every profile dependency outside KEEP_IN_SHARED_TREE, and an imported profile carries node-pty — a plain native dependency with no dsh metadata — so it always throws node-pty generation has no readable bundle patch. Passing dshEntryPath to verifyGenerationPeers() (the fix requested here) would not move such a profile past that check; filed separately as #708.

    What did unblock this machine (app closed, full copy of the profile taken first, profile install run with the app's own bundled runtime):

    1. bring dependencies + dsh.profile.bundles down to core (dshmarket, @deepseek-ai/dsh-base, @deepseek-ai/dsh-web-app);
    2. start the app once — it logs migration: no community plugins to move and writes .generations-migrated itself (2026-10-14T13:49:40.905Z);
    3. re-add the plugins.

    After that the migration is skipped for good (isProfileMigrated → noop()), so later marketplace installs activate through the normal launch projection:

    [desktop] migration: no community plugins to move
    [desktop] swept 21 unreferenced plugin generation(s)
    [desktop] projected generations: 3 linked, 0 unlinked
    [desktop] Harness is ready
    

    Marketplace afterwards: 12 plugins installed, dsh-context and dsh-better-sidebar report current == latest, updateAvailable: false, diagnostics findings: 0. Not a fix — a fresh import would be frozen again — but it clears a frozen profile without deleting plugins and without waiting for the retry window.

  8. yaojin3616 commented on Oct 28, 2026

    @yaojin3616
    Contributor

    结合当前主线及正式版 v0.13.0 再次复核:宿主 peer 解析已有后续修复(包括 #744 对应的宿主锚点校验路径),但不能由此认定本 issue 的整个迁移冻结链路已解决。

    尤其是后续反馈涉及的「CLI 导入 home 中普通依赖被当作组合包迁移,因缺少 dsh.bundle.patch 冻结」仍由 尚未合入的 #812 跟踪,正式版不能算已覆盖该路径。

    请在新版验证后反馈:

    1. 当前实际 Desktop/Harness 版本,是否由 CLI home 导入;
    2. 首个迁移失败的包名和最内层错误;
    3. 失败是否仍为宿主 peer/闭包解析,还是 generation has no readable bundle patch;
    4. 一次插件安装/更新并重启后,实际版本是否生效。

    请保留原 Profile 和迁移标记,只提供相关片段并隐去凭据、个人路径与会话内容,不需要先清空配置或删除插件。此 issue 保持打开,等待复测,同时继续跟踪尚未合入的迁移修复。

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