Skip to content

fix(settings): 让联动 dsh 插件开关在宿主进程里跟随检测 - #504

Closed
xinspark wants to merge 1 commit into
T-Auto:mainfrom
xinspark:fix/companion-link-detection
Closed

xinspark wants to merge 1 commit into
T-Auto:mainfrom
xinspark:fix/companion-link-detection

Conversation

@xinspark

@xinspark xinspark commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Closes #513

现象

在 main @ 2c0b039 上,「其他 → 联动 dsh 插件」开关(示例插件 dsh-win-pwsh7)存在两条互相独立的问题:

  1. 页面说开、宿主说关:配置页显示联动为开、「隐藏宿主 PowerShell」灰掉,但官方 pwsh 工具仍被 ops_bash 替换,报错原文 dsh-ops <mode> mode replaced the official tool pwsh with ops_bash; … enable Compatibility mode.
  2. 保存一次就写死:没碰过联动的情况下,保存任何其它开关都会把 other.pwsh7Link: true 写进该行配置;此后卸载联动插件也不会回落到关。

详细复现与代码路径见 issue。本文只写改动与验证。

改动

1. 探测改为三条确定性来源(src/settings/companion.ts)

宿主进程里没有 DSH_PROFILE_DIR(启动器只把它注入工具子进程),而调用点传的是 sweep: false,所以旧实现恒返回 undefined。现在按以下顺序解析,命中即返回:

  1. DSH_PROFILE_DIR / DSH_PROFILE(启动器显式给出时优先);
  2. 本包模块路径:<profile>/node_modules/dsh-ops/lib/… 逐级向上取 node_modules——普通安装(registry / file: tarball)走这条;
  3. 挂载本包的 profile:在 DSH_HOME(缺省 ~/.dsh)的 profiles/* 里找 node_modules/dsh-ops,用 realpathSync 与本包根目录比较,相等者即「挂载我的那个 profile」——link: 开发安装走这条;
  4. sweep 仅作兜底,默认关闭。

两处细节:

  • realpathSync 两侧都解析:macOS 的 /var、部分 Linux home 本身就是符号链接,只解析一侧会永远不相等(这轮 CI 第一版正是因为这个红在 macOS)。
  • 比较的是包身份而不是路径前缀:别的 profile 挂的是另一份拷贝时不会误命中,测试里用一个"挂载了别的拷贝"的 profile 反向断言了这一点。

没有改 src/index.ts 的两个调用点(:47 的 effective 与 :57 的 linked):两处都调同一个 companionVersion,修在函数里同时覆盖,避免在两处重复表达同一判据。

2. 保存基线与草稿用同一次检测(src/client/row-schema.ts、src/client/row-form.tsx)

changedFields(draft, raw, options) 新增第三个参数,内部基线改为 readRowValues(raw, options),RowForm 保存时传入 { pwsh7Installed }。效果:

  • 未保存 + 已装:草稿 true、基线 true → 不产生任何操作,继续跟随检测;
  • 用户拨动:与同一基线不同 → 总是写入(开、关都写);
  • 已保存的值:基线取保存值,不会被检测覆盖,也不会每次保存都重写。

3. 拒绝文案指向真实开关(src/publication/replacements.ts)

… or ask the operator to enable Compatibility mode. → … or turn off that replacement in the dsh-ops row settings.,并同步两处提到兼容模式的注释(src/modes/* 现在是上游的兼容 shim,注释跟随上游,不再重复表述)。

4. 双语文档与 CHANGELOG

docs/配置参考.md、docs/configuration-reference.md 在各自新结构里补一段:未保存 = 没碰过、保存其它开关不写死、手动拨动一定落盘、检测在宿主进程里成立。docs/CHANGELOG.md 的 ## [Unreleased] 加中英条目。

验证

构建与静态门

$ node scripts/build.mjs
build: bundled 11 browser modules (71709 bytes)
build: generated PTC declarations for 18 capabilities (113501 bytes)
build: compiled src/ to lib/ and copied 50 assets

$ node scripts/validate-manifest.mjs
validate-manifest: all 83 checks passed

$ node scripts/check-file-size.mjs
check-file-size: 527 code file(s) checked, all at or under 1000 lines (longest: bench/setup/profile.mjs (927))

相关套件

$ node test/run.mjs settings
dsh-ops settings-client: all 3 checks passed
dsh-ops settings-host: all 9 checks passed
dsh-ops settings-rows: all 13 checks passed
dsh-ops settings-runtime: all 11 checks passed
dsh-ops settings-ui: all 18 checks passed
dsh-ops test: 5 suite(s) passed in 4s

$ node test/run.mjs bundle-startup
dsh-ops bundle-startup: all 4 checks passed

新增 6 条断言(settings-rows 13 项、settings-ui 18 项里):

  1. 无环境变量时按模块路径探测到已装联动插件;
  2. link: 安装(junction 指向检出目录)也能探测到挂载它的 profile;
  3. 挂载了别的拷贝的 profile 不会被误判;
  4. 未保存 + 已装时,页面不保存任何操作;改「数据采集」只写 panel.enabled;
  5. 已装时手动关联动 → 写 other.pwsh7Link: false;未装时手动开 → 写 true;
  6. 已保存的值不会被检测覆盖,也不会每次保存重写。

红绿

把第 1、2 处实现回退后:

dsh-ops settings-rows: 3 of 13 check(s) failed
dsh-ops settings-ui: 2 of 18 check(s) failed

恢复后 5 suite(s) passed。

全量

$ node test/run.mjs
dsh-ops test: 2 of 162 suite(s) failed, 56 skipped in 223s

两个失败与本改动无关,且有基线对照:authority 1/12、permissions 3/15,均为临时目录写入 ACCESS_DENIED (os error 5);用 git stash 撤掉本改动后同套件、同数量失败。56 skipped 因缺 build:bash-ipc 与 POSIX-only 套件。

CI

run https://github.com/T-Auto/dsh-ops/actions/runs/41124823561 —— pull_request / success:CI required、node-floor、source-size、tools-trial、workflow-lint、validate-macos-intel、validate-posix(macOS arm64 / Linux x64)、validate-windows (win32-x64) 全 pass;bench-smoke 按设计 skipping。

真机

安装形态 结果
普通安装(profile desktop,file: tarball) 未保存任何配置 → pwsh 工具返回 7.6.9(WindowsApps 版),ops_bash 同时可用;cordis.patch.yml 中 pwsh7Link 出现 0 次
link: 开发安装(profile work-exp) 不设置 DSH_PROFILE_DIR 时探测返回 0.2.4(修复前 undefined)

取舍

  • 没有把 other.pwsh7Link 改成三态枚举:键名与「缺省=跟随检测、布尔=显式」的语义不变,修复只落在「何时写入」上,旧配置无需迁移。
  • 没有改 index.ts 的两个调用点(见上)。
  • 没有动 residentTools、presets 等 0.5.0-alpha3 新结构;本次改动只碰上面 9 个文件。
  • 探测多了一次「列举 profiles」的开销,但只在环境变量与模块路径都落空时发生,且结果有 60s 缓存。

环境

Windows 11 x64,Node v25.2.1,npm 11.6.2;基线上游 main @ 2c0b039;复现环境 DSH 0.2.1-rc.4、dsh-ops@0.5.0-alpha3、dsh-win-pwsh7@0.2.4。

@xinspark xinspark changed the title fix(settings): follow companion detection without writing it fix(settings): keep the dsh-win-pwsh7 link detection-based after a save Oct 30, 2026
@xinspark xinspark changed the title fix(settings): keep the dsh-win-pwsh7 link detection-based after a save fix(settings): keep the dsh-plugin link switch detection-based after a save Oct 30, 2026
@xinspark xinspark changed the title fix(settings): keep the dsh-plugin link switch detection-based after a save 修复(设置)修复联动插件开关选项相关(示例dsh-win-pwsh7)- #504 Oct 30, 2026
@xinspark
xinspark force-pushed the fix/companion-link-detection branch 2 times, most recently from 69d953d to 15ccf0a Compare October 30, 2026 20:07
The link follows detection until the operator sets it, but two defects broke
that promise in the host process and on save.

Detection read only DSH_PROFILE_DIR/DSH_PROFILE. The launcher sets those for
shell calls, not for the host, so companionVersion({ sweep: false }) always
answered "not installed" there: the page showed the link on from the plugin
list while every preset treated it as off and replaced the official pwsh.
Walk up from the loaded package instead, which names the profile that holds
the row, and keep the environment and sweep roots as fallbacks.

changedFields read its baseline without detection while the draft was read
with it, so an unsaved link on an installed companion diffed as false -> true
and any save froze it into an explicit value. Read the baseline with the same
inputs: an untouched link writes nothing, a flipped one always writes.

Also name the row setting instead of the removed Compatibility mode when an
official tool has an OPS replacement.
@xinspark
xinspark force-pushed the fix/companion-link-detection branch from 15ccf0a to cc6086c Compare October 30, 2026 20:20
@xinspark xinspark closed this Oct 30, 2026
@xinspark

Copy link
Copy Markdown
Contributor Author

重新整理后提交:见 issue #513 与新的 PR(措辞更完整,含新主干 2c0b039 的复现证据与真机验证)。本条为清理旧件。

@xinspark xinspark changed the title 修复(设置)修复联动插件开关选项相关(示例dsh-win-pwsh7)- #504 fix(settings): 让联动 dsh 插件开关在宿主进程里跟随检测 Oct 30, 2026
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.

「联动 dsh 插件」开关:宿主进程探测不到已装插件,保存又会把「跟随检测」写成显式值

1 participant