Skip to content

fix: pin the profile's pnpm store, and restyle the update card - #148

Merged
yaojin3616 merged 2 commits into
mainfrom
fix/profile-store-and-update-card
Aug 22, 2026
Merged

fix: pin the profile's pnpm store, and restyle the update card#148
yaojin3616 merged 2 commits into
mainfrom
fix/profile-store-and-update-card

Conversation

@yaojin3616

@yaojin3616 yaojin3616 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

接在 #147 之后,同一轮排查里剩下的两件事及后续修复。

一、固定 profile 的 pnpm store(P0)

一个 profile 的 node_modules 如果是从某个 store 链过来的,而 pnpm 下次不会再选中那个 store,整个插件系统就被从外面锁死:ERR_PNPM_UNEXPECTED_STORE 拒绝的不只是安装,卸载、更新、修复一并拒绝,而用户看到的只有一句"未能修改插件配置"。

实际发生的情形:某个 profile 内部有一个 487 MB 的 store(<profile>/.pnpm-store/v10),.modules.yaml 记着它,但 .npmrc 没有 store-dir——于是 pnpm 默认去用 ~/Library/pnpm/store/v10,两边对不上。结果是一个会导致启动失败的插件没法从界面卸载,必须手工改配置才能救回来。

修法:启动路径在任何 pnpm 运行之前,把 pnpm 自己记录过的 store 写进 profile 的 .npmrc

  • 只写既成事实:值来自 node_modules/.modules.yamlstoreDir,不是替用户挑一个 store;从没装过东西的 profile 没有可写的东西。
  • 已经一致时不重写文件,不会每次启动都动它。
  • 写不进去(只读等)时,把真相报进日志,而不是让下一次操作以那句笼统的失败收场。

时序上放在 runtime.stop() 之后、repairProfilePackages() 之前——修复本身也要跑 pnpm。

二、更新卡片样式

第二行是新的:第一行说发生了什么,第二行说这对用户意味着什么,版本号落在第二行(版本号回答"哪一个",不回答"现在怎样")。图标变成承载状态的圆形徽章,卡片上只有被接受的那个动作是实心按钮,其余是间距。

按钮的文案和行为没变——同意更新、跳过此版本、重新启动并安装。

三、补全 dsh 补丁依赖并完善插件卸载恢复降级

  1. 补全 dsh-desktop-hmr-fallback 依赖声明:在 patches/@deepseek-ai+dsh+0.1.1-rc.1.patch 中声明该依赖,使全新 profile 启动时 healProfilesModuleFallback 正确软链该包,解决 CI Windows 冒烟测试失败问题。
  2. 卸载失败自动降级重置:主进程恢复弹窗点击"移除插件"时,若常规 pnpm 移除因依赖冲突/损坏报错,自动降级调用 resetPluginProfile 进行安全清理(清理 package.jsoncordis.patch.ymlnode_modules/<pkg>packages/<pkg> 及脏 lockfile),避免卸载失败死锁。

验证

  • npm run typecheck 通过;npm test 40 文件 271 测试全绿。
  • CI Windows / macOS 打包冒烟测试重新触发运行中。

Two unrelated things this branch already touches.

A profile whose node_modules was linked from a store pnpm would not choose
again is locked shut: ERR_PNPM_UNEXPECTED_STORE refuses installs, uninstalls,
updates and repairs alike, and all the user sees is "unable to change
plugins". One profile reached that state with a 487 MB store inside itself
and nothing pinning it, so removing a plugin that broke startup was
impossible from the UI. The launch path now writes the store pnpm recorded
into the profile's .npmrc before anything runs pnpm — stating a fact that
already holds rather than choosing a new store — and reports the mismatch
when it cannot.

The update card grew a second line: what happened on the first, what it
means on the second, with the version where a version belongs. The icon
became a badge that carries the state, the accepted action is the only
filled control on the card, and the rest is spacing. Wording and buttons are
unchanged in substance — accept, skip, restart.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant