figma-cache-toolchain 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +201 -170
  2. package/cursor-bootstrap/AGENT-SETUP-PROMPT.md +34 -29
  3. package/cursor-bootstrap/examples/README.md +26 -11
  4. package/cursor-bootstrap/examples/generated-ui-reset.css.template +32 -0
  5. package/cursor-bootstrap/examples/ui-adapter.contract.template.json +90 -0
  6. package/cursor-bootstrap/examples/ui-execution-template.fast.md +11 -0
  7. package/cursor-bootstrap/examples/ui-execution-template.strict.md +13 -0
  8. package/cursor-bootstrap/examples/ui-override.template.json +26 -0
  9. package/cursor-bootstrap/figma-cache.config.example.js +51 -9
  10. package/cursor-bootstrap/managed-files.json +41 -0
  11. package/cursor-bootstrap/rules/02-figma-stack-adapter.mdc +15 -25
  12. package/cursor-bootstrap/rules/03-figma-ui-implementation-hard-constraints.mdc +58 -91
  13. package/cursor-bootstrap/rules/04-ui-baseline-governance.mdc +35 -86
  14. package/cursor-bootstrap/skills/figma-ui-dual-mode-execution/SKILL.md +13 -8
  15. package/figma-cache/adapters/recipes/button.recipe.json +24 -0
  16. package/figma-cache/adapters/recipes/card.recipe.json +24 -0
  17. package/figma-cache/adapters/recipes/checkbox.recipe.json +24 -0
  18. package/figma-cache/adapters/recipes/input.recipe.json +24 -0
  19. package/figma-cache/adapters/recipes/modal.recipe.json +25 -0
  20. package/figma-cache/adapters/recipes/radio.recipe.json +23 -0
  21. package/figma-cache/adapters/recipes/select.recipe.json +24 -0
  22. package/figma-cache/adapters/recipes/table.recipe.json +25 -0
  23. package/figma-cache/adapters/recipes/tabs.recipe.json +24 -0
  24. package/figma-cache/adapters/recipes/tooltip.recipe.json +24 -0
  25. package/figma-cache/docs/README.md +322 -237
  26. package/figma-cache/docs/p0-ui-preflight-handoff.md +207 -0
  27. package/figma-cache/docs/ui-1to1-optimization-roadmap.md +182 -0
  28. package/figma-cache/docs/ui-1to1-report.schema.json +104 -0
  29. package/figma-cache/figma-cache.js +639 -556
  30. package/figma-cache/js/contract-check-cli.js +466 -0
  31. package/figma-cache/js/cursor-bootstrap-cli.js +240 -202
  32. package/figma-cache/js/ui-facts-normalizer.js +233 -0
  33. package/package.json +95 -74
  34. package/scripts/cross-project-e2e.js +453 -0
  35. package/scripts/ui-1to1-audit.js +431 -0
  36. package/scripts/ui-auto-acceptance.js +248 -0
  37. package/scripts/ui-preflight.js +289 -0
  38. package/scripts/ui-profile.js +46 -0
  39. package/scripts/ui-report-aggregate.js +124 -0
  40. package/cursor-bootstrap/skills/ui-baseline-governance/SKILL.md +0 -51
@@ -0,0 +1,13 @@
1
+ # UI 执行模板(strict)
2
+
3
+ 适用:主干发布、关键路径页面、高保真验收。
4
+
5
+ 1. `npm run figma:ui:preflight`
6
+ 2. `npm run figma:ui:audit -- --target=<component-path> --min-score=92`
7
+ 3. `npm run figma:ui:report:aggregate`
8
+ 4. `npm run figma:ui:gate:main`
9
+
10
+ 建议:
11
+ - `FIGMA_UI_PROFILE=strict`
12
+ - preflight warning 视为阻断
13
+ - audit 必须提供 `--target`
@@ -0,0 +1,26 @@
1
+ {
2
+ "version": 1,
3
+ "scope": "node",
4
+ "description": "Node-level override for exceptional visual/interaction differences.",
5
+ "tokenMappings": [
6
+ {
7
+ "id": "node.token.override.example",
8
+ "figmaToken": "Example/Primary",
9
+ "figmaValue": "#305AFE",
10
+ "required": false,
11
+ "projectBinding": {
12
+ "type": "literal",
13
+ "value": "#305AFE",
14
+ "notes": "Only use when this node truly differs from global contract."
15
+ }
16
+ }
17
+ ],
18
+ "stateMappings": {
19
+ "select": {
20
+ "requiredStates": ["default", "expanded", "selected", "unselected"]
21
+ }
22
+ },
23
+ "layoutRules": [],
24
+ "typographyRules": [],
25
+ "interactionRules": []
26
+ }
@@ -1,4 +1,4 @@
1
- /**
1
+ /**
2
2
  * 项目级 Figma 缓存扩展(示例模板,**不绑定任何 UI 框架**)。
3
3
  *
4
4
  * 安装本 npm 包并执行 `npx figma-cache cursor init` 后,项目根会出现 **AGENT-SETUP-PROMPT.md**:
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * 若你已有 `figma-cache.config.js`,可由 Agent 合并而非覆盖。
8
8
  *
9
- * 加载顺序见 `figma-cache/figma-cache.js`:FIGMA_CACHE_PROJECT_CONFIG figma-cache.config.js .figmacacherc.js
9
+ * 加载顺序见 `figma-cache/figma-cache.js`:FIGMA_CACHE_PROJECT_CONFIG -> figma-cache.config.js -> .figmacacherc.js
10
10
  */
11
11
 
12
12
  const fs = require("fs");
@@ -45,6 +45,21 @@ const ADAPTER_DOC_CACHE_REL =
45
45
  const ADAPTER_DOC_WRITE_POLICY =
46
46
  process.env.FIGMA_CACHE_ADAPTER_DOC_WRITE_POLICY || "if-missing";
47
47
 
48
+ /**
49
+ * 全局 UI adapter contract 目标路径(相对项目根)。
50
+ * 该 contract 作为「设计 token/state -> 项目实现」的单一真源。
51
+ */
52
+ const ADAPTER_CONTRACT_REL =
53
+ process.env.FIGMA_CACHE_ADAPTER_CONTRACT ||
54
+ "figma-cache/adapters/ui-adapter.contract.json";
55
+
56
+ /**
57
+ * contract 模板来源(相对项目根,通常来自 cursor-bootstrap)。
58
+ */
59
+ const ADAPTER_CONTRACT_TEMPLATE_REL =
60
+ process.env.FIGMA_CACHE_ADAPTER_CONTRACT_TEMPLATE ||
61
+ "cursor-bootstrap/examples/ui-adapter.contract.template.json";
62
+
48
63
  /**
49
64
  * 人类可读的「流程 / 需求总览」骨架路径(相对项目根)。仅本示例写入;可在业务项目中改路径或删除相关逻辑。
50
65
  * @type {string}
@@ -99,13 +114,14 @@ function writeTextByPolicy(absPath, content) {
99
114
  * @returns {string}
100
115
  */
101
116
  function buildCacheRootHint(ctx) {
102
- return `# Figma 缓存 UI 实现(目录级提示)
117
+ return `# Figma 缓存 -> UI 实现(目录级提示)
103
118
 
104
119
  本文件由示例 \`postEnsure\` 生成,默认放在 **figma-cache 目录级**,用于避免“每个节点重复生成同一提示”。
105
120
 
106
121
  - **默认来源优先级**:先用 \`raw.json\` / \`spec.md\` / \`meta.json\` / \`state-map.md\`,仅在缺口或冲突时再读 \`mcp-raw/*\`
107
122
  - **证据约束**:同一设计事实只保留一个主证据来源,避免重复引用
108
123
  - **命中检查**:先查本地缓存命中与字段覆盖,再决定是否需要 MCP 补齐
124
+ - **全局映射契约**:先读取 \`${ADAPTER_CONTRACT_REL}\`,将 token/state 映射到项目实现;未映射项禁止猜测
109
125
 
110
126
  可选模式(环境变量):
111
127
  - \`FIGMA_CACHE_ADAPTER_DOC_MODE=cache-root\`(默认)
@@ -122,7 +138,7 @@ function buildCacheRootHint(ctx) {
122
138
  */
123
139
  function buildNodeHint(ctx) {
124
140
  const nodeLabel = ctx.nodeId == null ? "" : String(ctx.nodeId);
125
- return `# Figma 缓存 UI 实现(节点提示)
141
+ return `# Figma 缓存 -> UI 实现(节点提示)
126
142
 
127
143
  本文件由示例 \`postEnsure\` 生成。若你希望减少重复,可改用目录级模式:\`FIGMA_CACHE_ADAPTER_DOC_MODE=cache-root\`。
128
144
 
@@ -130,6 +146,7 @@ function buildNodeHint(ctx) {
130
146
  - cacheKey: \`${ctx.cacheKey}\`
131
147
  - fileKey: \`${ctx.fileKey}\`
132
148
  - nodeId: \`${nodeLabel}\`
149
+ - 全局映射契约:\`${ADAPTER_CONTRACT_REL}\`
133
150
 
134
151
  **流程 / 交互总览(可选)**:若使用本示例默认钩子,项目根下另有 **\`${FLOW_README_REL}\`**,随每次 \`ensure\` 追加节点小节,便于与 \`index.json\` 里的 \`flows\` 互补(人读 md,机读索引)。
135
152
  `;
@@ -155,6 +172,26 @@ function writeAdapterHint(ctx) {
155
172
  writeTextByPolicy(cacheRootTarget, buildCacheRootHint(ctx));
156
173
  }
157
174
 
175
+ /**
176
+ * 保证项目存在全局 adapter contract(单一真源)。
177
+ * 默认仅在缺失时写入,避免覆盖项目已定制内容。
178
+ * @param {object} ctx
179
+ */
180
+ function ensureAdapterContract(ctx) {
181
+ const targetAbs = path.resolve(ctx.root, ADAPTER_CONTRACT_REL);
182
+ if (fs.existsSync(targetAbs)) {
183
+ return;
184
+ }
185
+
186
+ const templateAbs = path.resolve(ctx.root, ADAPTER_CONTRACT_TEMPLATE_REL);
187
+ if (!fs.existsSync(templateAbs)) {
188
+ return;
189
+ }
190
+
191
+ fs.mkdirSync(path.dirname(targetAbs), { recursive: true });
192
+ fs.copyFileSync(templateAbs, targetAbs);
193
+ }
194
+
158
195
  /**
159
196
  * 在单文件里维护「已缓存节点」登记(按 cacheKey 幂等追加),与 index.json / flows 互补:适合评审与新人阅读。
160
197
  * @param {object} ctx
@@ -164,13 +201,13 @@ function appendFlowReadmeRegistry(ctx) {
164
201
  const marker = `<!-- cache-node:${ctx.cacheKey} -->`;
165
202
  const specRel = normalizePosixPath(path.relative(ctx.root, path.resolve(ctx.root, ctx.paths.spec)));
166
203
  const metaRel = normalizePosixPath(path.relative(ctx.root, path.resolve(ctx.root, ctx.paths.meta)));
167
- const completeness = Array.isArray(ctx.completeness) && ctx.completeness.length ? ctx.completeness.join(", ") : "";
204
+ const completeness = Array.isArray(ctx.completeness) && ctx.completeness.length ? ctx.completeness.join(", ") : "-";
168
205
  const block =
169
206
  `\n${marker}\n` +
170
207
  `### \`${ctx.cacheKey}\`\n\n` +
171
- `- **Figma**: ${ctx.url || ""}\n` +
172
- `- **syncedAt**: ${ctx.syncedAt || ""}\n` +
173
- `- **source**: ${ctx.source || ""}\n` +
208
+ `- **Figma**: ${ctx.url || "-"}\n` +
209
+ `- **syncedAt**: ${ctx.syncedAt || "-"}\n` +
210
+ `- **source**: ${ctx.source || "-"}\n` +
174
211
  `- **completeness**: ${completeness}\n` +
175
212
  `- **spec**: \`${specRel}\` · **meta**: \`${metaRel}\`\n` +
176
213
  `- **提示**: 像素级还原以 \`spec.md\` / \`raw.json\` 为准;用户路径请维护 \`flows\` 后把 \`npm run figma:cache:flow mermaid\` 输出贴到下方「流程总览」。\n`;
@@ -219,16 +256,21 @@ module.exports = {
219
256
  ADAPTER_DOC_MODE,
220
257
  ADAPTER_DOC_CACHE_REL,
221
258
  ADAPTER_DOC_WRITE_POLICY,
259
+ ADAPTER_CONTRACT_REL,
260
+ ADAPTER_CONTRACT_TEMPLATE_REL,
222
261
  FLOW_README_REL,
223
262
  appendFlowReadmeRegistry,
263
+ ensureAdapterContract,
224
264
 
225
265
  hooks: {
226
266
  /**
227
- * 默认实现:目录级 adapter 提示(避免节点重复)+ 项目根下「流程/需求」总览骨架(单文件、幂等追加节点块)。
267
+ * 默认实现:目录级 adapter 提示(避免节点重复)+ 全局 adapter contract(缺失时自动落地)
268
+ * + 项目根下「流程/需求」总览骨架(单文件、幂等追加节点块)。
228
269
  * 用 Agent 生成业务方案后,可整体替换本模块逻辑。
229
270
  */
230
271
  postEnsure(ctx) {
231
272
  try {
273
+ ensureAdapterContract(ctx);
232
274
  writeAdapterHint(ctx);
233
275
  appendFlowReadmeRegistry(ctx);
234
276
  } catch (err) {
@@ -0,0 +1,41 @@
1
+ {
2
+ "managedFiles": [
3
+ {
4
+ "from": "rules/00-output-token-budget.mdc",
5
+ "to": ".cursor/rules/00-output-token-budget.mdc"
6
+ },
7
+ {
8
+ "from": "rules/01-figma-cache-core.mdc",
9
+ "to": ".cursor/rules/01-figma-cache-core.mdc"
10
+ },
11
+ {
12
+ "from": "rules/02-figma-stack-adapter.mdc",
13
+ "to": ".cursor/rules/02-figma-stack-adapter.mdc"
14
+ },
15
+ {
16
+ "from": "rules/03-figma-ui-implementation-hard-constraints.mdc",
17
+ "to": ".cursor/rules/03-figma-ui-implementation-hard-constraints.mdc"
18
+ },
19
+ {
20
+ "from": "rules/04-ui-baseline-governance.mdc",
21
+ "to": ".cursor/rules/04-ui-baseline-governance.mdc"
22
+ },
23
+ {
24
+ "from": "rules/figma-local-cache-first.mdc",
25
+ "to": ".cursor/rules/figma-local-cache-first.mdc"
26
+ },
27
+ {
28
+ "from": "skills/figma-mcp-local-cache/SKILL.md",
29
+ "to": ".cursor/skills/figma-mcp-local-cache/SKILL.md"
30
+ },
31
+ {
32
+ "from": "skills/figma-ui-dual-mode-execution/SKILL.md",
33
+ "to": ".cursor/skills/figma-ui-dual-mode-execution/SKILL.md"
34
+ }
35
+ ],
36
+ "retiredFiles": [
37
+ ".cursor/skills/ui-baseline-governance/SKILL.md",
38
+ ".cursor/rules/04-command-execution-anti-regression.mdc",
39
+ ".cursor/rules/commit-conventions.mdc"
40
+ ]
41
+ }
@@ -1,32 +1,22 @@
1
- ---
2
- description: 栈占位:由 Agent 按项目 UI 技术栈生成 02-figma-<stack>-adapter.mdc 后再实现业务 UI(本文件可删除或 alwaysApply 保持 false)
1
+ ---
2
+ description: 栈占位模板(仅生成期使用):生成完成后删除本文件与 AGENT-SETUP-PROMPT.md
3
3
  alwaysApply: false
4
4
  ---
5
5
 
6
- # Figma UI Stack Adapter(占位)
7
-
8
- 本文件是 **通用脚手架**,不绑定 Vue / React / 任何组件库。若你已有具体栈的 Adapter 规则(例如 `02-figma-vuetify2-adapter.mdc`、`02-figma-react-mui-adapter.mdc`),可将本文件删除,或在 Cursor 设置中不再引用本文件。
9
-
10
- ## 第一步:用 Agent 生成栈专属规则
11
-
12
- 在项目根执行 `npx figma-cache cursor init` 后,打开 **`AGENT-SETUP-PROMPT.md`**,在 Cursor 里 **`@AGENT-SETUP-PROMPT.md`** 或整篇粘贴给 Agent,让其按文档顺序执行(含推断栈、生成配置、删除本占位文件)。若你更习惯手写,也可自行新建 `02-figma-<栈>-adapter.mdc` 与 `figma-cache.config.js`,再删除本文件。
13
-
14
- 生成后,**01-figma-cache-core** 仍只负责缓存与校验;**表现层**仅由你的 `02-figma-*-adapter` 约束。
15
-
16
- ## 与 01 的固定边界
17
-
18
- - **单一事实来源**:实现 UI 时只从 `raw.json`、`spec.md`、`state-map.md`、`meta.json` 取数;不在这些通用文件里写入框架专有代码或路由名。
19
- - **仅当任务包含「写/改业务 UI」且缓存可读**时,才应用具体栈的 Adapter;纯缓存维护、只跑 CLI,不触发表现层规则。
20
-
21
- ## React 直复用(选用规则)
6
+ # Figma -> UI Stack Adapter(占位模板)
22
7
 
23
- 仅当 Agent 识别目标项目为 **React 栈**(如 React + Tailwind / React + CSS Modules / React + styled-system)时启用:
8
+ 本文件仅用于生成阶段引导,非长期规则。
24
9
 
25
- - 优先复用节点目录下 `mcp-raw-get-design-context.txt` 的 React 参考代码作为起稿。
26
- - 在此基础上仅做必要微调:项目 token 映射、组件替换、状态/交互逻辑、数据绑定、可访问性与响应式。
27
- - 若项目非 React 栈,禁止直接复用该 React 代码,应按目标栈 Adapter 规则转换实现。
28
- - 复用时优先保持结构与视觉一致性;改动应聚焦“接入项目规范”而非重写布局。
10
+ ## 生成流程(强制)
11
+ 1. 基于项目栈生成 `.cursor/rules/02-figma-<stack>-adapter.mdc`。
12
+ 2. 验证新 adapter 可用(语法 + 最小执行验证)。
13
+ 3. 删除临时模板文件:
14
+ - `.cursor/rules/02-figma-stack-adapter.mdc`
15
+ - `AGENT-SETUP-PROMPT.md`
29
16
 
30
- ## 参考实现(非默认)
17
+ ## 边界
18
+ - `01-figma-cache-core` 仅负责缓存与校验。
19
+ - 业务 UI 实现约束由新生成的 `02-figma-<stack>-adapter.mdc` + `03/04` 规则承接。
31
20
 
32
- 安装本包后,示例路径为 **`node_modules/figma-cache-toolchain/cursor-bootstrap/examples/vue2-vuetify2-adapter.reference.mdc`**(Vue 2 + Vuetify 2 全文参考),需时由 Agent 读入并改写为你的 `.cursor/rules/02-figma-...`。
21
+ ## 说明
22
+ - 若用户明确要求保留任务书或占位模板,可不删除,并在汇报中说明原因。
@@ -1,91 +1,58 @@
1
- ---
2
- description: Figma 缓存驱动的 UI 实现硬约束(严格 1:1)
3
- alwaysApply: true
4
- ---
5
-
6
- # Figma UI 实现硬约束(Hard Mode)
7
-
8
- 边界:本规则仅约束业务 UI 实现阶段(已具备可读缓存数据后),不负责 MCP 拉取与缓存写入。
9
-
10
- ## 0. 目标(强制)
11
-
12
- - 首版必须 1:1 还原缓存事实。
13
- - 禁止“贴近”“近似”“经验值补全”。
14
- - 若信息冲突或不足,先停下澄清,不得猜测实现。
15
-
16
- ## 1. 首版必读数据源(强制)
17
-
18
- 实现前必须读取并建立事实对齐清单,缺一不可:
19
-
20
- 1. `spec.md`
21
- 2. `raw.json`
22
- 3. `state-map.md`
23
- 4. `mcp-raw-get-design-context.txt`(首版强制必读)
24
-
25
- 补充说明:
26
-
27
- - `mcp-raw-manifest.json` 用于确认证据完整性与来源一致性。
28
- - `mcp-raw-get-variable-defs.txt` 用于 token 变量补充。
29
-
30
- ## 2. 数据职责与裁决顺序(强制)
31
-
32
- - `spec.md`:结构化布局/文案/token 概览。
33
- - `raw.json`:覆盖度与完整性约束。
34
- - `state-map.md`:状态与交互映射。
35
- - `mcp-raw-get-design-context.txt`:首版视觉与结构落地的一手细节依据。
36
-
37
- 当 `spec.md` / `raw.json` / `state-map.md` 信息抽象、缺失、或相互冲突时:
38
-
39
- - 必须回到 `mcp-raw-get-design-context.txt` 裁决。
40
- - 仍无法裁决时,必须停止实现并向用户确认。
41
- - 禁止凭经验补齐。
42
-
43
- ## 3. 视觉 1:1 规则(强制)
44
-
45
- - 颜色:必须使用缓存 token 或明确值,禁止近似替换。
46
- - 文本:字号/字重/行高/字距逐项对齐,禁止“近似 class”替代。
47
- - 几何:圆角/边框/背景/间距逐项对齐,不做推测。
48
- - 盒模型:统一 `box-border`(或等效策略)并保持全组件一致。
49
- - 状态切换不得引发布局占位变化(避免抖动/超宽/变窄)。
50
-
51
- ## 4. 标签与语义规则(强制)
52
-
53
- - 布局与展示优先使用安全标签:`div` / `span` / `p` / `img`。
54
- - 不禁用功能标签(如 `button` / `input` / `select` / `ul` / `li`),但使用时必须:
55
- - 明确其语义必要性,或来自本地封装组件复用。
56
- - 完整接管默认样式(基础态 + hover/focus/active/selected)。
57
- - 保证视觉结果与设计事实 1:1,不受浏览器默认样式干扰。
58
- - 禁止“为了方便”滥用功能标签。
59
-
60
- ## 5. 结构与尺寸一致性(强制)
61
-
62
- - 首版必须先确定单一宽度策略(固定值或自适应),同组件内不得混用。
63
- - 左右对齐策略必须统一;同类块(如双下拉)必须同构实现。
64
- - 默认禁止横向滚动;非设计明确要求不得出现横向滚动条。
65
- - 文本溢出必须显式处理(如 `min-w-0` + `truncate`)。
66
-
67
- ## 6. 状态与交互还原(强制)
68
-
69
- - 必须覆盖缓存声明状态:`default / expanded / selected / unselected`(若存在)。
70
- - 每个状态必须映射背景/边框/文本/图标样式。
71
- - 交互行为(展开、收起、选择、Esc、outside click)按缓存或用户要求实现。
72
- - 禁止新增未请求交互;禁止删除已声明交互。
73
-
74
- ## 7. 执行节奏(强制)
75
-
76
- - 每轮只允许改一个维度:结构 / 颜色 / 尺寸 / 交互。
77
- - 禁止“顺手”捆绑多维改动,除非用户明确要求整包改。
78
- - 变更后必须做改动文件 lint 校验。
79
-
80
- ## 8. 失败判定(任一命中即失败)
81
-
82
- - 未读取 `mcp-raw-get-design-context.txt` 就开始实现。
83
- - 使用“近似值”替代缓存明确值。
84
- - 状态样式未完整覆盖或与缓存定义不一致。
85
- - 出现横向滚动、尺寸漂移、对齐不一致且无设计依据。
86
-
87
- ## 9. 失败反馈格式(固定)
88
-
89
- 1. 失败原因(违反哪条硬约束)
90
- 2. 定位信息(文件 + 样式/结构项)
91
- 3. 修复动作(如何回到 1:1)
1
+ ---
2
+ description: Figma 缓存驱动 UI 实现硬约束(统一版:含一次性交付与证据映射)
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Figma UI 实现硬约束(统一版)
7
+
8
+ 边界:仅约束缓存可读后的业务 UI 实现,不负责 MCP 拉取。
9
+
10
+ ## 0) 压缩级别(先选)
11
+ - L0 严格:高保真/复杂交互/历史漂移(完整对齐 + 全状态 + 强校验)。
12
+ - L1 标准(默认):精简事实清单 + 核心状态 + lint。
13
+ - L2 快速:仅“先看效果”场景,先静态后补交互。
14
+
15
+ ## 1) 首版必读(强制)
16
+ - `spec.md` / `raw.json` / `state-map.md` / `mcp-raw-get-design-context.txt`
17
+
18
+ ## 2) 裁决顺序(强制)
19
+ - 信息冲突:回到 `mcp-raw-get-design-context.txt`。
20
+ - 仍无法裁决:先问用户,禁止猜测。
21
+
22
+ ## 3) 视觉与布局(强制)
23
+ - 颜色/字体/几何/间距使用明确值,不用近似值。
24
+ - 默认 `box-border`,文本溢出显式处理。
25
+ - 禁止无依据横向滚动与布局抖动。
26
+
27
+ ## 4) 标签与控件(最新口径)
28
+ - 默认优先:`div` / `span` / `img`。
29
+ - 默认禁用:`p` / `ul` / `li` / `ol` / `h1-h6`(除非用户明确要求)。
30
+ - 可直接使用:`input` / `select` / `textarea` / `a`。
31
+ - 原生 `button` 默认禁用;仅封装按钮或 UI 库按钮可用。
32
+ - `role` / `aria-*` 默认不强制。
33
+
34
+ ## 5) 元数据策略
35
+ - `data-node-id` / `data-name` 默认不输出到最终业务代码。
36
+ - 仅在调试映射模式下临时保留。
37
+
38
+ ## 6) 状态与交互(强制)
39
+ - 覆盖缓存声明状态(至少 `default / expanded / selected / unselected`,若存在)。
40
+ - 仅实现缓存声明或用户要求交互,不私增。
41
+
42
+ ## 7) 一次性交付判定(强制)
43
+ - 信息充分(结构/文案/token/状态交互无关键缺口)时:必须一次性完成结构、样式、状态、基础响应式与可访问性,并同轮完成至少一项核心校验。
44
+ - 信息不足时:必须一次性列出“缺失字段 + 影响范围 + 最小补充需求”,并标注“受限还原”。
45
+
46
+ ## 8) 证据映射(强制)
47
+ - 交付说明至少覆盖:布局结构、核心文案、主要颜色/字体 token、状态/交互判断。
48
+ - 每项实现事实必须给一个主来源(`raw.json/spec.md/state-map.md/mcp-raw-get-design-context.txt`)。
49
+ - 若引用 `mcp-raw`,仅用于补缺口/消歧,不重复主来源事实。
50
+ - 若 `raw/spec` 与 `mcp-raw` 冲突,先报告冲突再给采用依据。
51
+
52
+ ## 9) 验收与失败反馈
53
+ - 每轮至少执行改动文件 lint。
54
+ - 声称“1:1 完成”前,至少补一项构建/类型/核心测试。
55
+ - 失败反馈固定三段:
56
+ 1. 失败原因
57
+ 2. 定位信息(文件 + 项)
58
+ 3. 修复动作
@@ -1,86 +1,35 @@
1
- ---
2
- description: UI 全局基线治理(新项目与老项目双轨),并约束组件生成行为
3
- alwaysApply: false
4
- ---
5
-
6
- # UI Baseline Governance(生成约束)
7
-
8
- 边界:本规则只约束“全局样式基线与组件生成策略”,不替代 `01-figma-cache-core.mdc` 与具体栈 Adapter。
9
-
10
- ## 0. 目标(强制)
11
-
12
- - 在不破坏现有页面的前提下,建立可复用的 UI 默认基线。
13
- - 将“新项目一次性定标”与“老项目渐进治理”统一到同一执行模型。
14
- - 将基线策略约束到 Agent 的组件生成行为,降低返工。
15
-
16
- ## 1. 双轨策略(强制)
17
-
18
- ### 1.0 项目类型判定(机械启发式,强制先判再改)
19
-
20
- > 目的:减少主观判断;**拿不准时一律按老项目**(安全默认)。
21
-
22
- 在动手改全局样式前,Agent 必须完成一次快速扫描并输出「判定结论 + 命中证据(路径或计数)」。
23
-
24
- **老项目(走 §1.2 分层分批)**,满足**任一**即判定为老项目:
25
-
26
- - **存量页面信号**:`src/`(无 `src` 则看项目约定的主源码根)下 `*.vue` / `*.tsx` / `*.jsx` 文件数 **≥ 40**。
27
- - **已有全局 reset / normalize**:入口或样式目录存在或引入命中以下之一(文件名或 import 字符串):`normalize`、`reset`、`preflight`、`@unocss/reset`、`sanitize`。
28
- - **已接入成熟 UI 框架**:`package.json` 的 `dependencies` 命中其一:`element-plus`、`ant-design-vue`、`vuetify`、`naive-ui`、`@mui/material`、`@chakra-ui/react` 等。
29
- - **全局样式覆盖风险**:根样式或全局入口中存在通配选择器(如 `* {`、`html, body` 大包)、或抽样可见大量 `!important` 与深度选择器混用(仅作辅助信号,命中则偏老项目)。
30
-
31
- **新项目(可走 §1.1 一次性全局基线)**,需**同时**满足:
32
-
33
- - 上述「老项目」四条**均未**命中。
34
- - `*.vue` / `*.tsx` / `*.jsx` 计数 **< 15**(或主业务目录下可数的页面级组件极少)。
35
-
36
- **不确定**:凡计数落在 **15~39** 之间、或仅有弱信号时,**按老项目处理**,仅允许局部基线或单模块试点,禁止首轮全量全局 reset。
37
-
38
- ### 1.1 新项目(无历史负担)
39
-
40
- - 可一次性启用全局基线(推荐)。
41
- - 首版建议最小集合:
42
- - `box-sizing: border-box`(含 `*::before/*::after`)
43
- - 常见标签 margin/padding reset
44
- - 媒体元素 `display:block` 与 `max-width:100%`
45
- - 统一字体基线(family/size/line-height)
46
- - 焦点可见策略(`focus-visible`)
47
-
48
- ### 1.2 老项目(已有线上页面)
49
-
50
- - 禁止直接全量覆盖全局 reset。
51
- - 采用“分层 + 分阶段 + 可回滚”:
52
- 1. 新增 `baseline layer`(仅声明基线,不改业务样式)。
53
- 2. 先对“新页面/新组件”生效(范围隔离或入口分批)。
54
- 3. 用视觉回归与缺陷工单推进存量页迁移。
55
- 4. 每轮迁移可独立回滚。
56
-
57
- ## 2. 生成时行为约束(强制)
58
-
59
- - 未显式声明前,生成组件默认假设 `border-box`。
60
- - 在 `flex` 文本容器中必须显式处理溢出:`min-w-0` + `truncate`(或等效策略)。
61
- - 弹层/下拉必须“锚定触发器”,禁止页面坐标硬定位。
62
- - 图标优先复用项目图标系统;若缺失,用本地 `inline svg`,禁止运行时依赖 Figma 临时资产 URL。
63
- - 默认覆盖 `default/hover/focus/active/selected/disabled`(按设计需求裁剪)。
64
- - 禁止为“临时对齐”引入无意义嵌套;结构必须最小可读。
65
-
66
- ## 3. 老项目安全闸(强制)
67
-
68
- - 当检测到项目未完成 reset 或存在历史样式冲突:
69
- - 先输出“风险清单”(组件、影响面、回滚点)再改。
70
- - 优先局部基线(页面容器或组件命名空间)而非全局覆盖。
71
- - 不得在同一轮同时做“全局 reset + 大规模业务重构”。
72
-
73
- ## 4. 验证与验收(强制)
74
-
75
- - 每次变更后至少执行:改动文件 lint + 关键页面可视化验证。
76
- - 验收输出必须包含:
77
- 1. 本轮基线策略(新项目全局/老项目分层)
78
- 2. 影响范围
79
- 3. 回滚方式
80
- 4. 与组件生成约束的一致性说明
81
-
82
- ## 5. 失败反馈格式(固定)
83
-
84
- 1. 失败原因(违反哪条基线或安全闸)
85
- 2. 定位信息(文件 + 规则项)
86
- 3. 修复动作(分阶段方案与回滚点)
1
+ ---
2
+ description: UI 基线治理(分级精简版:判型、局部基线、验证回滚)
3
+ alwaysApply: false
4
+ ---
5
+
6
+ # UI Baseline Governance(分级)
7
+
8
+ ## 0) 项目判型
9
+ - 老项目:命中任一(页面多 / 已有 reset / UI 框架 / 全局样式风险)。
10
+ - 新项目:均不命中且页面少。
11
+ - 不确定:按老项目。
12
+
13
+ ## 1) 策略
14
+ - 新项目:可一次性全局基线。
15
+ - 老项目:局部基线优先,分层分批,可回滚。
16
+
17
+ ## 2) 基线实施级别(按效果选)
18
+ - B0 保守(老项目默认):
19
+ - 复制模板 `node_modules/{{NPM_PACKAGE_NAME}}/cursor-bootstrap/examples/generated-ui-reset.css.template`
20
+ -> 项目 `src/styles/generated-ui-reset.css`。
21
+ - 在入口(如 `src/main.ts`)单次引入。
22
+ - 生成组件根节点统一加 `generate-ui-reset`。
23
+ - B1 中等:页面级作用域基线(新页面/新模块)。
24
+ - B2 激进:全局基线(仅新项目或明确授权)。
25
+
26
+ ## 3) 最小联动约束
27
+ - 默认 `box-border`。
28
+ - 弹层锚定触发器。
29
+ - 图标优先项目图标系统,兜底 `inline svg`。
30
+
31
+ ## 4) 验收输出
32
+ 1. 判型结论 + 证据
33
+ 2. 本轮级别(B0/B1/B2)
34
+ 3. 影响范围 + 回滚方式
35
+ 4. lint + 可视验证
@@ -23,19 +23,23 @@ description: 仅用 nodeId(如 9277-28772)或 Figma 链接触发 UI 实现
23
23
  - `raw.json`
24
24
  - `state-map.md`
25
25
  - `mcp-raw-get-design-context.txt`
26
- 4. 模式选择:
26
+ 4. 读取全局 adapter contract(新增强制项):
27
+ - 默认路径:`figma-cache/adapters/ui-adapter.contract.json`
28
+ - 目标:把 token/state 从设计事实映射到项目实现(变量/class/主题 token)
29
+ 5. 模式选择:
27
30
  - 默认短流程;
28
31
  - 命中任一升级条件(老项目/全局样式改动/复杂状态/历史漂移问题/信息冲突)-> 切严格流程。
29
- 5. 预检文档策略(降噪):
32
+ 6. 预检文档策略(降噪):
30
33
  - 默认短流程:可跳过完整预检文档,仅输出精简事实清单。
31
34
  - 严格流程:必须基于 `cursor-bootstrap/examples/ui-1to1-preflight.template.md` 生成并填写“预检文档”(可落到项目 `figma-cache/docs/` 或节点目录旁),至少完成:设计值快照、状态对照表、1:1 预检清单。
32
- 6. 先输出“事实对齐清单”,再实现组件与挂载。
33
- 7. 改动后执行 lint,并输出映射与验证结论。
35
+ 7. 先输出“事实对齐清单”,再实现组件与挂载。
36
+ 8. 改动后执行 lint,并输出映射与验证结论。
34
37
 
35
38
  ## 关键硬约束
36
39
 
37
40
  - 冲突裁决顺序:`mcp-raw-get-design-context.txt` 优先。
38
41
  - 禁止猜测设计值;无法裁决必须先提问。
42
+ - 对 token/state 未命中 adapter contract 的项,必须先补 mapping 或向用户确认,禁止凭经验填色。
39
43
  - 禁止使用 Figma 临时远程资产 URL 作为运行时图标。
40
44
  - 图标优先项目图标系统;无则 `inline svg`。
41
45
  - 默认按 `border-box` 思维实现;弹层必须锚定触发器。
@@ -44,7 +48,8 @@ description: 仅用 nodeId(如 9277-28772)或 Figma 链接触发 UI 实现
44
48
 
45
49
  1. 缓存定位结果(命中节点目录)
46
50
  2. 事实对齐清单(结构/文案/token/状态/交互)
47
- 3. 变更文件列表
48
- 4. 关键设计值 -> 代码映射
49
- 5. lint/验证结果
50
- 6. 未决问题(如有)
51
+ 3. adapter contract 命中结果(命中项 / 缺失项)
52
+ 4. 变更文件列表
53
+ 5. 关键设计值 -> 代码映射
54
+ 6. lint/验证结果
55
+ 7. 未决问题(如有)
@@ -0,0 +1,24 @@
1
+ {
2
+ "id": "button",
3
+ "description": "Generic clickable button recipe",
4
+ "structureTemplate": [
5
+ "button-shell",
6
+ "label",
7
+ "leading-icon",
8
+ "trailing-icon"
9
+ ],
10
+ "stateMachine": {
11
+ "requiredStates": ["default", "hover", "active", "disabled"],
12
+ "optionalStates": ["loading", "focus-visible"]
13
+ },
14
+ "tokenPriority": [
15
+ "background",
16
+ "text",
17
+ "icon",
18
+ "border"
19
+ ],
20
+ "pitfalls": [
21
+ "Do not lose disabled contrast",
22
+ "Do not collapse hover and active states"
23
+ ]
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "id": "card",
3
+ "description": "Generic card recipe for content containers",
4
+ "structureTemplate": [
5
+ "card-shell",
6
+ "header",
7
+ "body",
8
+ "footer"
9
+ ],
10
+ "stateMachine": {
11
+ "requiredStates": ["default"],
12
+ "optionalStates": ["hover", "selected", "disabled"]
13
+ },
14
+ "tokenPriority": [
15
+ "surface",
16
+ "border",
17
+ "title-text",
18
+ "body-text"
19
+ ],
20
+ "pitfalls": [
21
+ "Do not remove spacing hierarchy between header/body/footer",
22
+ "Do not flatten card elevation when hover state exists"
23
+ ]
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "id": "checkbox",
3
+ "description": "Generic checkbox recipe for multi-select controls",
4
+ "structureTemplate": [
5
+ "control",
6
+ "check-indicator",
7
+ "label",
8
+ "helper-text"
9
+ ],
10
+ "stateMachine": {
11
+ "requiredStates": ["unchecked", "checked", "disabled"],
12
+ "optionalStates": ["indeterminate", "error"]
13
+ },
14
+ "tokenPriority": [
15
+ "control-bg",
16
+ "control-border",
17
+ "icon",
18
+ "label-text"
19
+ ],
20
+ "pitfalls": [
21
+ "Do not skip indeterminate style if design includes partial selection",
22
+ "Do not hide disabled state contrast"
23
+ ]
24
+ }