Skip to content

refactor(design-system): DS-8 统一 Desktop 设计数值的生产来源 - #4268

Merged
kirozeng merged 3 commits into
makecindy:mainfrom
kirozeng:ds/8-desktop-token-source
Sep 11, 2026
Merged

kirozeng merged 3 commits into
makecindy:mainfrom
kirozeng:ds/8-desktop-token-source

Conversation

@kirozeng

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

把 Desktop 已接管的静态设计数值集中到 packages/design-tokens/src 的 DTCG 源,由锁定的 Terrazzo 2.7.1 生成到真实消费者。以后改源并生成即可同步颜色、内置主题和通用基础样式;本次保留现有界面数值与运行行为。

522/541 个注册项、11 个内置主题覆盖、通用字号/行高/字体/字重、间距、圆角、Input 尺寸、动效、shared 默认字号和窗口背板已接管。旧手写第二来源同批退出,19 个原位保留项及运行期边界逐项见 packages/design-tokens/README.md 和 desktop-bindings.json。

变更类型

  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护

范围

  • 关联需求:DS-8,承接已合并的 DS-7 ci(design-system): DS-7 启用成熟范围的设计检查 #4215;提交基线 88632bdda96d8531aa854114cfc6731df439b45c。
  • 包含:DTCG → Terrazzo → 18 个生产/规范输出;颜色和内置主题在原文件明确标记区生成;生成新鲜度、独立基础值冻结、主题兼容、effort 初始化及 inventory 守卫。
  • 包含审查修复:恢复主题设计依据;补回系统等宽默认字体与 JetBrains Mono 可选预设说明(F2);撤掉原有依赖链的 lightningcss 1.32→1.33 被动漂移(F4)。新 Terrazzo/Vite 8 链需要的 1.33 保留,既有 packages/snapshots 条目不变。
  • 不包含:DS-9—12、Mobile 实现/原生输入、账号或权限流程、用户配置含义、协议/数据迁移、动态配色/插值、Diff 算法和图表命中裁决。
  • 用户可见变化:无有意视觉变化。旧 ID、注册顺序、alias 符号关系、历史 HSL/格式、null 回退和用户 radius 保留。
  • Breaking change:无。运行时不依赖整个 Token 包;用户主题只沿用原加载路径,不改写磁盘。
  • 按批准的完整 DS-8 范围交付一张 PR;不按 800 行或生成物体积拆分。用户明确豁免本次本地双审;已有 Claude Opus 5 / high 独立首轮与修复复核,首轮 5 个 P1 全部关闭。此后 F2/F4 和更新 main 的增量由 Codex 自审,不冒称独立复核覆盖最终 SHA。

UI 变化

  • 引用的设计规范:docs/design-rules/DESIGN.md §3 排版与缩放、§5 圆角、§10 主题/alias 与双模式、§14.4 动效、§15 保护皮肤、§16.1 登录色;docs/design-rules/design-governance.md §2/§4/§6 单源、兼容和证据合同。
  • 不涉及新的视觉/交互/文案设计:实际样式接线改为生成子集,保留原值。541 项活注册表冻结件及 11 主题独立预期未改;HSL 不按同名 hex 重算,alias 不展开成固定色。
  • macOS arm64 真实隔离 Electron Global 已采集 Light/Dark 及 14/24 字号截图,截图未入 Git。完整证据位于唯一执行计划同目录的 附件/DS-8/submit-e2e/;GitHub 图片附件仍待人工上传,不将本地路径冒充公开附件。

怎么验证的

自动验证

VITE_CINDY_AUTH_REGION=global pnpm test:unit:related
  退出0:lockfile 触发完整 unit 调度,28 workspace通过,6个既有notApplicable;runner 529通过/1个既有skip。
pnpm --filter desktop run --if-present typecheck
pnpm --filter @cindy/design-tokens run --if-present typecheck
pnpm --filter mobile run --if-present typecheck
pnpm --filter @cindy/design-tokens check:generated
pnpm check:design-inventory
pnpm check:design-colors --base-ref 88632bdda96d8531aa854114cfc6731df439b45c --worktree
pnpm check:endpoints
pnpm check:i18n
pnpm check:brand-terminology
pnpm check:i18n-glossary
pnpm --filter desktop db:validate
pnpm ci:scheduler-guard
pnpm --filter mobile test:scope
pnpm --filter desktop exec tsc --project ../../scripts/device-link/tsconfig.json
pnpm test:device-link
pnpm install --frozen-lockfile --ignore-scripts

以上命令全部退出0。

生产生成不读取 fixture;18 输出新鲜度和 LF、独立冻结预期、真实源改动与生成物劣化负例均有保护。库存 49 surface,生成 CSS 进入原 5 个 globals 消费 surface;颜色门禁不扩豁免。Device Link 真实 loopback WebSocket 集成 9/9 通过。

真实 Electron E2E:submit-e2e/run-e2e.cjs 退出 0,5 组场景全过、20 格控件矩阵通过、4 窗口原始 hash/主题/root/body 样式逐项恢复。覆盖当前 Providers/Storage/Tools/Usage、两表单与普通确认、9 类媒体菜单、订阅/价格、图表/滑杆、1600 行真实 Worker Diff、完整复制、Light/Dark/主题覆盖并存、字号放大/compact/状态。之前的 Diff 采证脚本只等待 250ms,本轮等待虚拟列表行高测量并仍断言真实末尾标记,四格均通过;生产 Diff 未改。

手工验证

Codex 已自审完整候选 diff,并核对真实测试版 source MATCH / ready;可撤销改风格演练已完成且恢复,交付无演练值。E2E 使用真实客户端生产组件和受控内存样本,未执行真实账号保存/解绑/删除或存储清理。系统剪贴板写入仅在测试中拦截并恢复。

未执行的验证

最终用户/设计师人工验收、真实多账号登录/切换与订阅远端联调、Windows/Linux 实机、原生 IME/200% 缩放/拖窗、字典浮窗与插件独立宿主完整操作仍未测。未单独运行 pnpm test:all 或完整 CI 平台矩阵;本地全量 unit 不等于这些验收。交付 commit dbeb18d280b169a1d813460fa7b59e5b430826ac,云端 CI 结果待 PR 运行。旧轮 Opus 隔离树缺原生产物导致的全量失败不计为通过,以本轮完整主工作树结果为准。

风险

风险分类

  • 跨平台差异
  • 其他:生成链、CSS 加载/覆盖顺序和构建依赖

影响与回滚

  • 影响范围:Desktop 静态设计值和构建期生成。主要风险是 alias、格式/单位、初始化顺序及 Windows LF;活注册表/主题冻结、真实 cn()/字号行为、effort 两种导入顺序和输出 LF 守卫保护上述边界。没有修改权限、凭证、迁移、配置语义或 Mobile 原生依赖。
  • 回滚:整体 revert 本 PR 的源、输出、消费引用及过渡测试合同;不单独删生成输出,不重写用户主题或偏好。下游若已依赖新源,按依赖顺序回退。
  • SC-01—07、09—12 按声明工程范围完成;SC-08 代表真实场景通过,平台/真实业务/人工待项保留。G1—G4 不提前宣称全完成,下一批不自动启动。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s)
  • UI 改动已注明设计规范章节
  • 未提交凭证、令牌、授权文件或截图
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

@kirozeng
kirozeng requested a review from a team as a code owner September 10, 2026 18:27
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-10T23:40:57.073177Z 96ab73a New commits
🔒 Security Review ✅ Completed 2026-09-10T23:41:48.245520Z 96ab73a New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 将 Desktop 已接管的设计值迁移到 DTCG 单一来源,并通过锁定的 Terrazzo 生成颜色注册、内置主题、基础 CSS、Tailwind 映射、共享默认值和设计文档。

  • 保留现有主题 ID、注册顺序、alias、格式及运行时字体缩放边界。
  • 新增生成新鲜度、基础值冻结、主题兼容、初始化顺序和设计库存守卫。
  • 发现一处生成器校验缺口:基础数值 token 若携带 symbolic CSS alias,可能静默生成 NaN。

Confidence Score: 4/5

此 PR 整体可合并,但建议补上基础数值 token 携带 symbolic alias 时的生成校验,避免后续源变更静默产出 NaN。

当前提交的生成结果与既有值和运行行为一致,主题、字体、CSS 加载及依赖兼容未发现实际回归;唯一问题是生成器对一种现实的后续 token 元数据变更缺少防护。

Files Needing Attention: packages/design-tokens/src/generate.ts, packages/design-tokens/src/production.ts

Important Files Changed

Filename Overview
packages/design-tokens/src/generate.ts 新增生产生成编排及 18 个输出;基础数值映射对 symbolic alias 缺少安全转换或拒绝。
packages/design-tokens/src/production.ts 新增绑定、类型、alias、格式及生成区域校验,整体防护完整,但像素映射校验未覆盖 token 自身的 cssAlias。
packages/design-tokens/src/desktop-bindings.json 集中声明 Desktop 默认色、主题覆盖、基础值、文档和窗口背板的生产绑定。
apps/desktop/src/renderer/themes/colors.ts 将已建模颜色默认值切换到生成常量,同时保留注册顺序和明确保留项。
apps/desktop/src/renderer/styles/generated/tokens.css 在 base layer 中提供字体、字号、动效、间距、圆角、Input 和额度条的静态默认值。
apps/desktop/tailwind.config.ts Tailwind 字号、间距、圆角、字重和动效映射改由生成区域维护。
apps/desktop/src/renderer/hooks/useFontSettings.ts 运行时字体缩放改为消费生成映射,现有缩放和覆盖行为保持不变。
pnpm-lock.yaml 锁定 Terrazzo 2.7.1 及其构建期依赖,Node 要求与仓库支持基线一致。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[DTCG reference tokens] --> D[Terrazzo 2.7.1]
  B[Semantic/component/theme tokens] --> D
  C[desktop-bindings.json] --> D
  D --> E[colors.ts 与内置主题]
  D --> F[tokens.css 与 token-mappings.ts]
  D --> G[tailwind.config.ts]
  D --> H[共享 appearance 与窗口背板]
  D --> I[DESIGN.md 规范区域]
  F --> J[Desktop renderer]
  E --> J
  G --> J
Loading
Prompt To Fix All With AI
### Issue 1
packages/design-tokens/src/generate.ts:66
**符号别名会生成 NaN**

当 `numeric`、`text`、`lineHeight` 或 `defaults` 中的基础 token 增加合法的 `cssAlias` 时,`formatToken()` 会返回 `var(--...)`,而这里会继续对它执行 `Number.parseFloat`。结果是生成器把 `NaN` 静默写入 `token-mappings.ts` 或 `appearance-tokens.ts`,后续字体与行高计算可能失效。建议在生成数值前拒绝这类符号别名,或直接从解析后的 px dimension 读取数值,并补充对应的负例测试。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "refactor(design-system): DS-8 统一 Desktop..." | Re-trigger Greptile

Comment thread packages/design-tokens/src/generate.ts
@MagicLizi MagicLizi added status:ci-failed CI 失败(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:new-dependency 新增第三方依赖(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示) labels Sep 10, 2026
- validateProduction 对 numeric/text/lineHeight/defaults 四族运行期像素
  绑定新增校验:绑定 token 自身携带合法 cssAlias 时直接拒绝。此前
  formatToken() 会输出 var(--…),generate.ts 的 Number.parseFloat 把它
  静默变成 NaN 写入 token-mappings.ts / appearance-tokens.ts(JSON
  序列化后成 null),字体与行高的运行期缩放随之失效。补 numeric 与
  defaults 两条负例,分别钉住 token-mappings 与 appearance-tokens
  两条输出链。
- 修复 Windows unit tests 红:两处测试断言用 '/themes/colors.ts' 后缀
  匹配 buildProductionFiles 的输出路径,Windows 上 path.join 返回 '\'
  分隔符导致匹配失败。按跨平台路径宪法改为 path.join 构造期望路径后
  全等比较。

Signed-off-by: Kirozeng <kirozeng@gmail.com>
@kirozeng

kirozeng commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor Author

跟进本轮反馈,commit 4f2964bc2,两处改动。

1. 符号别名生成 NaN(review P2)——已修,改为生成前拒绝

反馈属实。numeric / text / lineHeight / defaults 四族的绑定 token 若带上合法 cssAlias,formatToken() 会返回 var(--…),generate.ts 里对它执行 Number.parseFloat 会得到 NaN 并静默写进生成物(经 JSON.stringify 后在文件里呈现为 null),字体与行高的运行期缩放会拿到坏值。

修法:在 production.ts 的运行期像素绑定校验里 fail-closed——绑定 token 自身携带 cssAlias 就抛 Runtime pixel binding cannot use a CSS alias,生成在写盘前中止。按建议补了负例测试(production.test.ts),numeric 与 defaults 各一条,分别钉住 token-mappings.ts 和 appearance-tokens.ts 两条输出链。

证据:

  • 端到端复现:在临时仓库副本里给 semantic.foundations.text-13 加合法 cssAlias 后跑 buildProductionFiles——修复前生成成功,UI_TEXT_TOKEN_SIZES["13"] 变成 null;修复后直接中止,报 Runtime pixel binding cannot use a CSS alias: semantic.foundations.text-13。
  • pnpm --filter @cindy/design-tokens test 47/47 通过;check:generated 通过,现有生成物字节不变。

2. Windows unit tests 红——已修

根因是本 PR 自己的两条测试:用 path.endsWith('themes/colors.ts') 匹配 buildProductionFiles 的输出路径,Windows 上 path.join 返回 \ 分隔符,后缀匹配不上——一条假红加一条 TypeError。已按 docs/dev-rules/engineering-conventions.md 的「路径断言跨平台宪法」改为用 path.join 构造期望路径后全等比较,并用 path.win32 验证了旧行为确实匹配失败、新行为成立。等 Windows 分片复跑确认转绿。

另外说明:Linux unit tests (1/2) 的红是 ERR_PNPM_ENOENT ... rename ... esbuild 的依赖安装竞态,与本 PR 改动无关;verify 和 Windows unit tests 两个无分片 job 是分片汇总门,分片绿了会跟着绿。

本地验证:pnpm test:unit:related 全绿;@cindy/design-tokens typecheck 通过;DCO 已签(对 merge-base..HEAD 校验通过)。

dispatch:03ebedd0b69bef62

@MagicLizi MagicLizi added status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) and removed status:ci-failed CI 失败(review-pr 自动维护,仅展示) labels Sep 10, 2026
@kirozeng

Copy link
Copy Markdown
Contributor Author

已核实本轮 CI 信号,无需代码改动。

触发的是「required context 在当前 head 上缺席: Windows unit tests」——当时 Windows 两个分片还在跑(汇总 check 要等两个分片结束才出现),不是真红灯,本轮没有可修的东西。

现在 4f2964bc2 上 10 个 check 全绿:

  • Windows unit tests (1/2) ✅ / (2/2) ✅ / 汇总 Windows unit tests ✅——上一轮修的 Windows 路径断言已实跑通过
  • Linux unit tests (1/2)(2/2) ✅、verify ✅、verify-checks ✅、check:pr-design-basis ✅、Desktop Git integration ✅、DCO ✅

dispatch:e068e2a063aacc59

@MagicLizi MagicLizi added status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) and removed status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) labels Sep 10, 2026
解决 docs/design-rules/design-inventory.md 的合并冲突:该文件 GENERATED
区块由生成器维护,冲突行(desktop.settings 行组件计数)取合并树重新生成
——main 侧 makecindy#4246 新增组件已计入(732 → 733),人工区保留。其余 70 个
文件自动合并无冲突。

Signed-off-by: Kirozeng <kirozeng@gmail.com>
@kirozeng

Copy link
Copy Markdown
Contributor Author

跟进本轮 conflict 信号:main 前进导致 PR 冲突,已用 merge 解决,commit 96ab73a82。

冲突面核实:PR 与 main 的改动交集只有 docs/design-rules/design-inventory.md 一个文件,其余 70 个文件全部自动合并。main 侧对该文件的改动只是 desktop.settings 行的组件计数 732 → 733(#4246 新增组件)。

解法:该文件的 GENERATED 区块由 scripts/design-inventory.mjs 维护,冲突行取合并树重新生成(pnpm design:inventory)——settings 行计数为 733,与 main 侧意图一致;人工区原样保留。未用 force-push(merge commit,不改写已有提交)。

验证:

  • pnpm check:design-inventory ✅ GENERATED 区块最新(49 个 surface)
  • pnpm test:unit:related 全绿(57 workspace PASS)
  • desktop / responses-chat-bridge / anthropic-responses-bridge / model-providers / maker-core / design-tokens typecheck 全过
  • design-tokens check:generated ✅(DS-8 生成物不受 merge 影响)
  • GitHub 现报 mergeable: MERGEABLE(mergeStateStatus BLOCKED 只是新 head 的 CI 还在跑)

dispatch:e068e2a063aacc59

@MagicLizi MagicLizi added status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) and removed status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) labels Sep 10, 2026
@kirozeng

Copy link
Copy Markdown
Contributor Author

已核实本轮 CI 信号,无需代码改动。

信号是「required context 在当前 head 上缺席: Windows unit tests」——触发时(约 23:40)merge commit 96ab73a82 的 Windows 两个分片刚开始跑(23:35 起),汇总 check 要等两个分片结束才出现,不是真红灯。本会话等到出结果再收口,未提前吞掉任何可能的失败。

现在 96ab73a82 上 10 个 check 全绿:

  • Windows unit tests (1/2) ✅ / (2/2) ✅ / 汇总 Windows unit tests ✅
  • Linux unit tests (1/2)(2/2) ✅、verify ✅、verify-checks ✅、check:pr-design-basis ✅、Desktop Git integration ✅、DCO ✅

PR 保持 mergeable: MERGEABLE(上一轮 merge 解决冲突后无回归)。

dispatch:6b12f6402c9667fc

@MagicLizi MagicLizi removed the status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) label Sep 11, 2026
@kirozeng
kirozeng merged commit 2e74488 into makecindy:main Sep 11, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:new-dependency 新增第三方依赖(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants