Skip to content

fix: 适配 DSH 0.2.0(语义 token 全覆盖 + 构建期兼容性守卫) - #20

Merged
MangMax merged 2 commits into
mainfrom
fix/dsh-0.2.0-compat
Oct 6, 2026
Merged

MangMax merged 2 commits into
mainfrom
fix/dsh-0.2.0-compat

Conversation

@MangMax

@MangMax MangMax commented Oct 6, 2026

Copy link
Copy Markdown
Owner

背景

用户实际运行的 DSH 是 0.2.0-rc.2(dsh CLI 与桌面版一致),而插件的开发依赖与 token 清单仍停留在 0.1.5 时代。核对真实运行时后,发现两个不会报错、只会静默失效的缺陷。

修复的缺陷

1. --dsw-alias-state-idle-primary 从未被覆盖

DSH 0.2.0 的官方 token 目录(dsh-client-ui-theme 的 BUILTIN_INSPECT_TOKENS)有 14 个核心 token,插件 CORE_TOKEN_NAMES 只有 13 个,缺的正是 --dsw-alias-state-idle-primary。

该 token 由 StateDot[data-state='idle'] 消费。后果:工具调用的 idle 状态点恒为 DSH 原生灰,切换主题不生效。

2. UI 语义 token 覆盖率仅 73.3%(63/86)

DSH 各 UI 包 CSS 实际消费 86 个语义 --dsw-* token,插件只覆盖 63 个。未覆盖的在主题化后会露出 DSH 原生色:diff 高亮、菜单、开关滑块、链接、Toast 文字、turn 触发器、shimmer 等。

现补齐 24 个 token 至 86/86 全覆盖。派生沿用相邻 token 的既有做法,从各调色板自身 core 色推导,而非只写死默认值 —— 因此 DEFAULT_PALETTE、DEFAULT_THEME 与 6 个内置调色板均完整覆盖全部 118 个 token,无 undefined。

防止再次漂移(本次核心增量)

这类缺陷的共同点是静默:token 名写错、上游新增 token、peer 区间过窄,都不会让构建失败。因此新增两道构建期守卫,数据源一律是用户实际在跑的真实 DSH 运行时(自动定位全局 dsh 安装),而不是仓库里可能落后的 devDependencies:

脚本 接入 校验内容
scripts/check-dsh-compat.mjs pnpm check 核心 token 集合 vs 官方目录;UI 语义 token 覆盖率;peerDependencies 区间 vs 实际 DSH 版本
scripts/e2e-dsh-runtime.mjs pnpm test 主题服务 API、官方 token 目录、覆盖层 token 名有效性、connection.fetch.register 字段、locale 服务面、seed word 导出符号、客户端产物 require 面

其中 peer 区间判定自实现了 caret 语义,严格复刻 DSH 门禁的 semver.satisfies(v, range, { includePrerelease: true }),并带自检确保 ^0.2.0 会正确拒绝 0.3.0(手写 semver 最易犯的错)。

其他改动

  • 依赖:5 个 @deepseek-ai/dsh-client-* 此前只声明在 peerDependencies,靠 pnpm autoInstallPeers 隐式装入 0.1.5-rc.3。现显式声明为 devDependencies 并升至 ^0.2.0-rc.2。
  • peer 区间不变:^0.1.5-rc.1 || ^0.2.0-rc.1 经核验在 DSH 门禁的 includePrerelease 语义下接受 0.1.5-rc.2 一直到 0.2.1-alpha.1,无需修改。
  • README 单一真相来源:npm 包内 README 此前在 install.sh 里内联硬编码,与根 README 各写各的(已出现措辞漂移)。现改为从根 README 的 <!-- npm-readme:start/end --> 区间生成,兼容性事实由 package.json 的 peerDependencies + dshCompat 程序化产出;组装时逐行核对根 README,不一致直接失败。

验证

pnpm verify 全绿:

  • 构建 ✔ / check-vs-keys ✔ / check-locales ✔(中英 168 键对齐)
  • DSH 兼容性检查全 ✔:核心 token 14/14、UI 语义 token 86/86、peer 区间 ✔、caret 上界自检 ✔
  • 52 项导入端到端(真实 Tokyo Night VSIX,含冷缓存)✔
  • 31 项真运行时契约 ✔
  • bash scripts/install.sh --pack-only ✔,包内 peerDependencies 与根 deep equal

另做了反向验证:篡改根 README 的版本行后 install.sh --pack-only 确实 exit 1 并给出「期望包含」指引,证明漂移守卫真的会拦。

DSH 0.2.0 引入了新的语义 token,且插件的核心 token 清单与上游权威目录
发生了静默漂移 —— 两者都不会报错,只会让部分界面不跟随主题。

## 修复的缺陷

1. **`--dsw-alias-state-idle-primary` 从未被覆盖**
   DSH 0.2.0 的官方 token 目录(`BUILTIN_INSPECT_TOKENS`)有 14 个核心
   token,插件 `CORE_TOKEN_NAMES` 只有 13 个。后果:`StateDot` 的 idle
   状态(`state-idle-primary`)恒为 DSH 原生灰,切主题不生效。

2. **UI 语义 token 覆盖率仅 73.3%(63/86)**
   DSH 各 UI 包 CSS 实际消费 86 个语义 `--dsw-*` token,插件只覆盖 63 个。
   未覆盖的在主题化后会露出 DSH 原生色(diff 高亮、菜单、开关滑块、
   链接、Toast 文字、turn 触发器、shimmer 等)。

   现补齐 24 个 token 至 **86/86 全覆盖**。派生采用与相邻 token 一致的
   方式从各调色板自身 core 色推导,不只依赖硬编码默认值 —— 因此
   DEFAULT_PALETTE、DEFAULT_THEME 与 6 个内置调色板均完整覆盖
   全部 118 个 token,无 undefined。

## 防止再次漂移(本次的核心增量)

新增两道**构建期**守卫,数据源都是用户实际在跑的真实 DSH 运行时
(自动定位全局 dsh 安装),而非仓库里可能落后的 devDependencies:

- `scripts/check-dsh-compat.mjs`(接入 `pnpm check`)
  · 核心 token 集合 vs 官方 `BUILTIN_INSPECT_TOKENS`
  · UI 包实际消费的语义 token 覆盖率
  · `peerDependencies` 区间 vs 实际 DSH 版本
    (自实现 caret 语义,严格复刻 DSH 门禁的
     `semver.satisfies(..., { includePrerelease: true })`,
     并带自检确保 `^0.2.0` 正确拒绝 0.3.0)

- `scripts/e2e-dsh-runtime.mjs`(接入 `pnpm test`)
  拿真实 DSH 包的 .d.ts / client.js / CSS 校验契约面:
  主题服务 API、官方 token 目录、覆盖层 token 名有效性、
  `connection.fetch.register` 字段、locale 服务面、
  seed word 导出符号、客户端产物 require 面。

## 其他

- devDependencies 的 5 个 `@deepseek-ai/dsh-client-*` 显式声明并升至
  `^0.2.0-rc.2`(此前仅存在于 peerDependencies,靠 pnpm
  `autoInstallPeers` 隐式装入 0.1.5-rc.3)。
- `peerDependencies` 区间保持 `^0.1.5-rc.1 || ^0.2.0-rc.1` —— 经核验
  该区间在 DSH 门禁的 `includePrerelease` 语义下接受
  0.1.5-rc.2 一直到 0.2.1-alpha.1,不需要改。
- npm 包内 README previously 在 install.sh 里内联硬编码,与根 README
  各写各的。现改为从根 README 的 `<!-- npm-readme:start/end -->`
  区间生成,兼容性事实由 `package.json` 的 `peerDependencies` +
  `dshCompat` 程序化产出;组装时逐行核对根 README,不一致直接失败。

验证:`pnpm verify` 全绿(构建 + 源码检查 + 产物检查 +
52 项导入端到端 + 31 项真运行时契约)。
CI 上只装了 5 个 dsh-client-* 包(没有 dsh-web-frontend、
dsh-client-ui-chat 等),而 `--dsw-alias-separator-primary` 仅被
dsh-client-ui-chat 引用 —— 于是「无臆造 token 名」这项在 CI 上
把「引用它的包没装」误判成了「插件写了个不存在的名字」,PR 门禁变红。

改为:先把扫描面登记成 SCAN_SURFACE,并计算本机实际在场数量;
- 扫描面完整(本机全局 DSH 运行时)→ 维持硬校验,臆造名仍然失败
- 扫描面不全(CI 只装 5 个包)→ 降级为提示,不判失败

这样既不会把环境缺包误报成代码缺陷,也没有削弱守卫:已验证在完整
运行时下注入一个错字 token 名仍会硬失败(exit 1)。
@MangMax
MangMax merged commit ed3c781 into main Oct 6, 2026
1 check passed
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