Replies: 1 comment 1 reply
|
在 master(c291e7961)核实:诊断成立,且你提的"建议 C"(提供开关)其实已经存在,只是没文档明示。
建议:认可你的建议 A——Windows 默认走 polling(策略里一处平台判断),同时把 |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
摘要
@deepseek-ai/dsh-skill-filesystem在watch: true(默认)下用 chokidar 以深度 1 监视每个注册的技能根,在 Windows 上会为该目录持有句柄。结果是:注册了技能根的 bundle 插件,在 DSH 运行期间永远无法在插件市场里更新 —— pnpm 落地新版本的最后一步rename <pkg>_tmp_<n> -> <pkg>被 Windows 拒绝。环境
Windows
DSH Desktop 2.0.10 /
@deepseek-ai/dsh0.1.5-rc.2@deepseek-ai/dsh-skill-filesystem0.1.5-rc.2Node v24.18.0 / pnpm 11.8.0
profile
desktop(nodeLinker: hoisted,autoInstallPeers: false)复现
安装
@openviking/dsh-memory-plugin@0.3.0并保持 DSH 运行。更新到 0.3.2:
实际结果
同一进程内改名探测(
插件(同期在线更新均成功) | 子目录 | 包根 -- | -- | -- dsh-context | lib、node_modules 均 OK | ✅ OK dshmarket | client/lib/src 全 OK | ✅ OK @gausszhou/dsh-opencode-session-id | lib OK | ✅ OK @openviking/dsh-memory-plugin | shared OK、servers OK、skills LOCKED | ❌ LOCKEDRename-Item+ 立刻改回):补充:包内新建/删除文件成功、改名
README.md成功、skills/openviking-memory内部改名成功 —— 即锁的粒度是目录句柄,不是「文件被占用」。根因
@openviking/dsh-memory-plugin的skills.mjs注册了包内技能根,且未传watch:该插件由自己的 bundle patch 以默认配置挂载(其
cordis.patch.yml只写name:,无config),用户的 profile patch 也未覆盖,因此走默认值:lib/index.js:37→watch默认truelib/index.js:38→watchUsePolling默认falselib/index.js:372-386→openRootWatcher()用chokidar.watch(mode.anchor, { …, usePolling }),深度 1chokidar 底层
fs.watch()在 Windows 上持有该目录句柄且不带FILE_SHARE_DELETE,于是:skills/本身不可改名(watcher 钉住它)其子项可改名(深度 1)
包里其他目录可改名(无 watcher)
而 pnpm 更新一个包要 rename 的正是该目录的父包目录,故必然 EPERM。这也解释了为什么
dsh-context/dshmarket/dsh-opencode-session-id同期都能在线更新:它们加载后不留任何持续句柄。影响面
不限于 OpenViking:任何在 Windows 上注册文件系统监视根的 bundle 插件都无法在线更新,且用户得到的提示是「检查 profile」,与实际原因无关。
期望
Windows 上更新此类插件应成功,或至少一次性给出可执行指引(完全退出 DSH 后命令行更新 / 停用该插件并重启后再更新)。
不应为了更新而要求用户「停用插件」——这属于平台实现细节泄漏。
建议修复
A(根治,推荐) Windows 上对注册根默认
usePolling: true。fs.watchFile只周期性stat目标路径,不持有目录句柄,因此 rename 不再被拒。现有watchPollIntervalMs(默认 100ms)与watchUsePolling开关使这只是一处策略切换。代价是轮询开销,可配合watchMaxProjects限流。B 改为监视技能根的父目录而非根自身,使技能根可被整体替换。
C 若 A/B 有额外权衡,至少提供可显式
watch: false的途径并写入文档:随发行版发布、运行时不会被磁盘编辑的技能目录(如本 bundle 的skills/)并不需要 watcher。All reactions