figma-cache-toolchain 2.0.1 → 2.0.3

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.
package/README.md CHANGED
@@ -32,9 +32,9 @@ npx figma-cache cursor init
32
32
 
33
33
  该命令会:
34
34
 
35
- - 默认覆盖写入最新 `.cursor/rules/`、`.cursor/skills/` 模板
35
+ - 默认安全模式:保留已有 `.cursor/rules/`、`.cursor/skills/`,仅补缺失文件
36
36
  - 新增通用规则:`.cursor/rules/00-output-token-budget.mdc`(全任务低 token 输出基线)
37
- - 若需保留已存在模板,可使用 `npx figma-cache cursor init --force`(跳过同名覆盖)
37
+ - 若需覆盖现有模板,可使用 `npx figma-cache cursor init --overwrite`
38
38
  - 确保根目录存在 `figma-cache.config.js`
39
39
  - 刷新根目录 `AGENT-SETUP-PROMPT.md`
40
40
  - 同步刷新 `figma-cache/docs/colleague-guide-zh.md`
@@ -1,60 +1,43 @@
1
- # Figma Cache:请 Agent 一次性完成项目适配
2
-
3
- > **给 Cursor Agent 的指令**:你正在操作的是**用户业务项目**的根目录。以下文件应已存在(由 `npx figma-cache cursor init` 从 npm 包 **`{{NPM_PACKAGE_NAME}}`** 复制到当前仓库根):
4
- > - `.cursor/rules/01-figma-cache-core.mdc`
5
- > - `.cursor/rules/00-output-token-budget.mdc`(通用低 token 输出基线)
6
- > - `.cursor/rules/02-figma-stack-adapter.mdc`(**占位**,任务完成后需删除)
7
- > - `.cursor/rules/figma-local-cache-first.mdc`(可选保留)
8
- > - `.cursor/skills/figma-mcp-local-cache/SKILL.md`
9
- > - `figma-cache.config.js`(示例 `postEnsure`:目录级 adapter hint + 可选 `docs/figma-flow-readme.md`)
10
- > - (兼容旧项目)`figma-cache.config.example.js` 可能存在;仅当内容被用户自定义且无法安全迁移时保留
11
-
12
- ## 你必须完成的任务(按顺序执行,尽量少问用户)
13
-
14
- 1. **读取工程事实**
15
- 阅读 `package.json` 及存在的构建配置(如 `vite.config.*`、`vue.config.js`、`next.config.*`、`tsconfig.json` 等),**自行推断** UI 技术栈(框架、组件库、样式方案、状态管理若有则记录)。仅在关键信息完全无法从仓库推断时,再向用户提一个极简问题。
16
-
17
- 2. **检查并合并 `figma-cache.config.js`**
18
- - 若根目录**不存在** `figma-cache.config.js`:基于当前文件创建完整配置,并实现与栈匹配的 `hooks.postEnsure`。
19
- - 若**已存在** `figma-cache.config.js`:**合并**而非盲目覆盖——保留用户已有非 figma-cache 字段,仅补充或调整 `hooks.postEnsure` 及与 figma-cache 相关的导出;冲突时以「不破坏用户现有逻辑」优先并注释说明。
20
- - 默认建议:`FIGMA_CACHE_ADAPTER_DOC_MODE=cache-root`(目录级单文件,减少重复);仅在团队明确需要节点文档时改为 `node`。
21
-
22
- 3. **清理 legacy example(若安全)**
23
- 若根目录存在 `figma-cache.config.example.js` 且其内容与 `figma-cache.config.js` 等价(或为未改动模板),请删除该 example 文件,避免后续协作混淆。
24
-
25
- 4. **生成栈专属 Adapter 规则**
26
- 新建 **`.cursor/rules/02-figma-<栈简名>-adapter.mdc`**(`alwaysApply: false`)。内容须与 **`01-figma-cache-core.mdc`** 边界一致:只约束「在通用缓存可读之后如何写业务 UI」;**禁止**要求在 `meta.json` / `raw.json` / `spec.md` 中写入框架专有实现。
27
-
28
- 5. **删除占位规则**
29
- 确认第 4 步文件已写入且无语法问题后,**删除** `.cursor/rules/02-figma-stack-adapter.mdc`。若用户在 Cursor 设置里固定引用了该文件名,请在汇报中提示用户改为引用新的 `02-figma-<栈>-adapter.mdc`。
30
-
31
- 6. **补全 npm scripts(若缺失)**
32
- 若 `package.json` 中没有任何 `figma:cache:*` 脚本,请追加一组,命令使用 **`npx figma-cache`** **`figma-cache`**(与项目是否已安装本包、以及 `node_modules/.bin` 是否可用一致即可,优先 `npx figma-cache` 以减少环境差异)。至少包含:`init`、`config`、`validate`、`ensure`、`get`(名称与 `figma-cache --help` 或包内 **`figma-cache/docs/README.md`** 中 scripts 示例一致即可)。
33
-
34
- 7. **收尾**
35
- - 用简短列表向用户汇报:新建/修改/删除了哪些路径。
36
- - 若项目根**尚无** `figma-cache/index.json`,提示用户执行:`npm run figma:cache:init`(若已加 script)或 `npx figma-cache init`(与 `cursor init` 不同,用于创建空索引与缓存目录)。
37
- - 提示用户在本项目根执行:`npm run figma:cache:validate`(若已加 script)或 `npx figma-cache validate`。
38
- - 说明:后续 Figma 相关对话将主要由 **01 Core + 新 Adapter + Skill** 驱动。
39
- - **可选**:若项目已通过 `cursor init` 同步 `figma-cache/docs/colleague-guide-zh.md`,提示团队默认只使用 **§5.1「最推荐主提示词」**,只有特殊诉求再追加 **§5.2** 的一句附加要求。
40
-
41
- ## 输出与 token 约束(强制)
42
- - 默认“只要结果”:不输出思考过程,不粘贴 MCP 长回包。
43
- - 执行 Figma MCP 后,用户可见回复只保留:缓存状态、调用次数、产物路径、校验结论、失败修复动作。
44
- - 除非用户明确要求,禁止在 chat 中贴出 `get_design_context` 全文;原始内容仅保存到 `mcp-raw/*`。
45
-
46
- ## 硬约束(违反则视为未完成)
47
-
48
- - **不要**修改 `node_modules/{{NPM_PACKAGE_NAME}}/` 下已发布包内文件(应无此必要)。
49
- - **不要**修改 `figma-cache/figma-cache.js` 或破坏 Core「框架中立」语义。
50
- - **不要**把业务路由名、具体组件库 API 写进 `figma-cache/files/**` 下的 `meta.json` / `raw.json` / `spec.md`。
51
-
52
- ## 可选参考(仅在用户需要 Vue2+Vuetify2 时)
53
-
54
- 包内附带参考文本(**不在 init 时复制到 .cursor**):
55
- `node_modules/{{NPM_PACKAGE_NAME}}/cursor-bootstrap/examples/vue2-vuetify2-adapter.reference.mdc`
56
- 若用户明确要求该栈,可读入后改写为第 4 步的 Adapter 规则内容。
57
-
58
- ---
59
-
60
- **开始执行:**读完本文件后立刻按上述顺序操作仓库文件,直至全部完成。
1
+ # Figma Cache:请 Agent 一次性完成项目适配(精简)
2
+
3
+ > 前提:你在用户业务项目根目录;以下模板来自 `{{NPM_PACKAGE_NAME}}`。
4
+
5
+ ## 必做(按序)
6
+ 1. 读取项目栈事实(package.json + 构建配置)。
7
+ 2. 合并/创建 `figma-cache.config.js`(不破坏用户已有逻辑)。
8
+ 3. 生成 `.cursor/rules/02-figma-<stack>-adapter.mdc`。
9
+ 4. 验证新 adapter 可用(语法 + 最小执行验证)。
10
+ 5. 补全 `figma:cache:*` scripts(缺失时)。
11
+
12
+ ## 老项目 UI 基线(默认 B0)
13
+ 1. 复制模板:
14
+ `node_modules/{{NPM_PACKAGE_NAME}}/cursor-bootstrap/examples/generated-ui-reset.css.template`
15
+ -> 项目 `src/styles/generated-ui-reset.css`
16
+ 2. 在入口(如 `src/main.ts`)单次引入。
17
+ 3. 后续生成组件根节点统一加:`generate-ui-reset`。
18
+ 4. 若用户要求更强控制,再升级 B1/B2。
19
+
20
+ ## 生成完成后清理临时模板文件(强制)
21
+ - 删除 `.cursor/rules/02-figma-stack-adapter.mdc`
22
+ - 删除 `AGENT-SETUP-PROMPT.md`
23
+
24
+ ## 规则优先级
25
+ - 缓存层:`01-figma-cache-core.mdc`
26
+ - UI 实现:`03-figma-ui-implementation-hard-constraints.mdc`
27
+ - 基线治理:`04-ui-baseline-governance.mdc`
28
+ - 输出约束:`00-output-token-budget.mdc`
29
+
30
+ ## UI 标签口径
31
+ - 默认优先 `div/span/img`
32
+ - 默认禁用 `p/ul/li/ol/h1-h6`(除非用户明确要求)
33
+ - `input/select/textarea/a` 可直接使用
34
+ - 原生 `button` 默认禁用(封装或 UI 库按钮除外)
35
+ - `role/aria-*` 默认不强制
36
+ - `data-node-id/data-name` 默认不输出(调试模式除外)
37
+
38
+ ## 输出约束
39
+ - 结果优先,不贴 MCP 长原文。
40
+ - 仅输出:结论、关键改动、验证结果、下一步。
41
+
42
+ ---
43
+ 开始执行:直接落文件并完成验证。
@@ -1,11 +1,15 @@
1
- # 栈相关参考(不随 `cursor init` 复制)
1
+ # 栈相关参考(不随 `cursor init` 复制)
2
2
 
3
- 本目录存放 **可选** 的完整 Adapter 示例,供人工或 Agent 对照;**通用默认**请使用 `cursor init` 生成的 `02-figma-stack-adapter.mdc` 与根目录 `figma-cache.config.js`。
3
+ 本目录存放可选参考与模板文件:
4
4
 
5
5
  | 文件 | 说明 |
6
- |------|------|
7
- | `vue2-vuetify2-adapter.reference.mdc` | 历史 Vue 2 + Vuetify 2 表现层规则全文,可复制为 `.cursor/rules/02-figma-vuetify2-adapter.mdc` 并按项目改名 |
8
-
9
- 将参考规则复制进 `.cursor/rules/` 后,建议同步 `figma-cache.config.js` 的 adapter 提示策略:默认使用 `FIGMA_CACHE_ADAPTER_DOC_MODE=cache-root`(目录级单文件),仅在明确需要节点文档时改为 `node`。
6
+ |---|---|
7
+ | `vue2-vuetify2-adapter.reference.mdc` | 历史 Vue2 + Vuetify2 参考规则 |
8
+ | `generated-ui-reset.css.template` | 老项目 B0 局部 reset 模板(推荐默认) |
10
9
 
10
+ ## B0 推荐用法(目标业务项目)
11
+ 1. 复制模板到项目:`src/styles/generated-ui-reset.css`
12
+ 2. 在入口(如 `src/main.ts`)引入一次
13
+ 3. 生成组件根节点加 `generate-ui-reset`
11
14
 
15
+ 说明:B0 仅做局部基线,不污染全局;B1/B2 见 `04-ui-baseline-governance.mdc`。
@@ -0,0 +1,32 @@
1
+ /* Generated UI local reset (scoped) */
2
+
3
+ :where(.generate-ui-reset),
4
+ :where(.generate-ui-reset *) {
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ :where(.generate-ui-reset img),
9
+ :where(.generate-ui-reset svg),
10
+ :where(.generate-ui-reset video),
11
+ :where(.generate-ui-reset canvas) {
12
+ display: block;
13
+ max-width: 100%;
14
+ }
15
+
16
+ :where(.generate-ui-reset input),
17
+ :where(.generate-ui-reset select),
18
+ :where(.generate-ui-reset textarea),
19
+ :where(.generate-ui-reset button),
20
+ :where(.generate-ui-reset a) {
21
+ font: inherit;
22
+ color: inherit;
23
+ letter-spacing: inherit;
24
+ }
25
+
26
+ /* Optional strict mode for high-fidelity pages only */
27
+ :where(.generate-ui-reset--strict input),
28
+ :where(.generate-ui-reset--strict select),
29
+ :where(.generate-ui-reset--strict textarea) {
30
+ margin: 0;
31
+ border-radius: 0;
32
+ }
@@ -0,0 +1,80 @@
1
+ # UI 1:1 实现前预检模板
2
+
3
+ > 用途:在“开始写组件前”完成事实快照、状态对照与预检,降低返工。
4
+ > 适用:Figma 缓存驱动实现(任意 nodeId)。
5
+
6
+ ## 0. 基本信息
7
+
8
+ - fileKey:
9
+ - nodeId:
10
+ - cachePath:
11
+ - 实现目标页面/组件路径:
12
+ - 执行模式(短流程 / 严格流程):
13
+
14
+ ## 1. 设计值快照(Design Facts)
15
+
16
+ ### 1.1 结构与尺寸
17
+
18
+ - 根容器(宽/高/圆角/边框/背景):
19
+ - 关键子容器尺寸:
20
+ - 宽度策略(固定 / 自适应,仅可选一):
21
+ - 对齐策略(左/右/居中):
22
+
23
+ ### 1.2 文案
24
+
25
+ - 标签文本:
26
+ - 值文本:
27
+ - 选项文本:
28
+
29
+ ### 1.3 Token
30
+
31
+ - 字体(size/line-height/weight/letter-spacing):
32
+ - 主文本色:
33
+ - 次文本色:
34
+ - 背景色:
35
+ - 边框色:
36
+ - 状态色(hover/focus/selected):
37
+
38
+ ### 1.4 交互与语义
39
+
40
+ - 交互触发(click/esc/outside/keyboard):
41
+ - 语义角色(combobox/listbox/option 等):
42
+ - 禁止项(本任务):
43
+
44
+ ## 2. 状态对照表(必须填写)
45
+
46
+ | 状态 | 背景 | 边框 | 文本 | 图标 | 数据状态 | 是否实现 |
47
+ | --- | --- | --- | --- | --- | --- | --- |
48
+ | default | | | | | | [ ] |
49
+ | hover | | | | | | [ ] |
50
+ | focus | | | | | | [ ] |
51
+ | active | | | | | | [ ] |
52
+ | expanded | | | | | | [ ] |
53
+ | selected | | | | | | [ ] |
54
+ | unselected | | | | | | [ ] |
55
+ | disabled(若存在) | | | | | | [ ] |
56
+
57
+ ## 3. 1:1 预检清单(实现前)
58
+
59
+ - [ ] 已读取 `spec.md` / `raw.json` / `state-map.md` / `mcp-raw-get-design-context.txt`
60
+ - [ ] 冲突裁决规则确认:`mcp-raw-get-design-context.txt` 优先
61
+ - [ ] 全组件盒模型策略一致(建议 `box-border`)
62
+ - [ ] 文本溢出策略明确(`min-w-0` + `truncate` 或等效)
63
+ - [ ] 弹层锚定触发器(非页面硬编码定位)
64
+ - [ ] 图标策略确认(项目图标库优先;兜底 `inline svg`)
65
+ - [ ] 禁止使用 Figma 临时远程资产 URL 作为运行时图标
66
+ - [ ] 禁止无意义标签嵌套
67
+ - [ ] 默认无横向滚动
68
+
69
+ ## 4. 实现后验收(最小)
70
+
71
+ - [ ] 改动文件 lint 通过
72
+ - [ ] 关键状态可见且可切换(至少 default/expanded/selected/unselected)
73
+ - [ ] 关键视觉项(尺寸/对齐/图标居中)通过
74
+ - [ ] 输出“设计值 -> 代码映射”
75
+
76
+ ## 5. 失败反馈(固定三段)
77
+
78
+ 1. 失败原因
79
+ 2. 定位信息(文件/字段/样式项)
80
+ 3. 修复动作
@@ -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
+ - 若用户明确要求保留任务书或占位模板,可不删除,并在汇报中说明原因。
@@ -0,0 +1,58 @@
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. 修复动作
@@ -0,0 +1,35 @@
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 + 可视验证
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: figma-ui-dual-mode-execution
3
+ description: 仅用 nodeId 或 Figma 链接触发 UI 实现,支持 L0/L1/L2 压缩级别,并内置基线判型与 B0/B1/B2 选择。
4
+ ---
5
+
6
+ # Figma UI Dual Mode Execution(分级)
7
+
8
+ ## 执行步骤(固定)
9
+ 1. 规范化 nodeId 并命中缓存目录。
10
+ 2. 读取 `spec/raw/state-map/design-context`。
11
+ 3. 选择压缩级别:L0/L1/L2(默认 L1)。
12
+ 4. 输出事实对齐清单并实现挂载。
13
+ 5. lint 验证并输出映射结论。
14
+
15
+ ## 压缩级别
16
+ - L0:高保真严格流程(预检文档 + 完整状态)。
17
+ - L1:标准流程(精简清单 + 核心状态)。
18
+ - L2:快速看效果(先静态后补交互)。
19
+
20
+ ## 基线治理(并入)
21
+ - 项目判型:新项目 / 老项目 / 不确定(不确定按老项目)。
22
+ - 基线级别:B0/B1/B2(老项目默认 B0)。
23
+ - B0(默认):
24
+ - 复制模板到 `src/styles/generated-ui-reset.css`
25
+ - 入口单次引入
26
+ - 生成组件根节点加 `generate-ui-reset`
27
+ - B1:仅新页面/模块范围启用作用域基线。
28
+ - B2:全局基线,仅新项目或明确授权。
29
+ - 若与规则冲突,以 `.cursor/rules/04-ui-baseline-governance.mdc` 为准。
30
+
31
+ ## 标签口径
32
+ - 默认 `div/span/img`
33
+ - 默认禁 `p/ul/li/ol/h1-h6`
34
+ - `input/select/textarea/a` 允许
35
+ - 原生 `button` 默认禁用(封装/UI 库按钮除外)
36
+ - `role/aria-*` 默认不强制
37
+ - `data-node-id/data-name` 默认不输出
@@ -134,7 +134,7 @@ npm run figma:cache:init
134
134
  - **项目根**仍需:`figma-cache.config.js`、`.cursor/` 规则与 Skill、`AGENT-SETUP-PROMPT.md`(或由等价流程生成)。
135
135
  - Vue2+Vuetify2 参考 Adapter:`cursor-bootstrap/examples/vue2-vuetify2-adapter.reference.mdc`(npm 安装时在 `node_modules/.../cursor-bootstrap/examples/`)。
136
136
 
137
- 说明:Cursor **不会**在 `npm install` 时写入 `.cursor/`;`npx figma-cache cursor init` 负责从包内复制模板。`cursor init` 默认**覆盖**同名模板为最新版本(`--force` 可改为保留已有模板并跳过覆盖);并会下发通用低 token 规则 `00-output-token-budget.mdc`;**`AGENT-SETUP-PROMPT.md` 每次 `cursor init` 均刷新**。
137
+ 说明:Cursor **不会**在 `npm install` 时写入 `.cursor/`;`npx figma-cache cursor init` 负责从包内复制模板。`cursor init` 默认**保留**同名模板(安全模式);使用 `--overwrite` 可覆盖为最新版本;并会下发通用低 token 规则 `00-output-token-budget.mdc`;**`AGENT-SETUP-PROMPT.md` 每次 `cursor init` 均刷新**。
138
138
 
139
139
  ## package.json scripts 示例
140
140
 
@@ -353,7 +353,7 @@ function run() {
353
353
  console.log(` ${ex} flow show --flow=<flowId>`);
354
354
  console.log(` ${ex} flow mermaid --flow=<flowId>`);
355
355
  console.log(
356
- `${ex} cursor init [--force] # default: overwrite .cursor templates with latest bootstrap; --force keeps existing templates (skip overwrite)`,
356
+ `${ex} cursor init [--overwrite] [--force] # default safe mode; --overwrite forces replacement; --force keeps legacy behavior (no overwrite)`,
357
357
  );
358
358
  process.exit(1);
359
359
  }
@@ -362,12 +362,18 @@ function run() {
362
362
  const sub = args[0];
363
363
  if (sub !== "init") {
364
364
  console.error(
365
- "Usage: figma-cache cursor init [--force] # default overwrite; --force keeps existing templates",
365
+ "Usage: figma-cache cursor init [--overwrite] [--force] # --overwrite replaces existing templates; --force keeps legacy no-overwrite behavior",
366
366
  );
367
367
  process.exit(1);
368
368
  }
369
- const force = args.includes("--force");
370
- copyCursorBootstrap(force, {
369
+ const hasOverwrite = args.includes("--overwrite");
370
+ const hasForce = args.includes("--force");
371
+ if (hasOverwrite && hasForce) {
372
+ console.error("Do not use --overwrite and --force together. Choose one mode.");
373
+ process.exit(1);
374
+ }
375
+ const overwrite = hasOverwrite;
376
+ copyCursorBootstrap({ overwrite, legacyForce: hasForce }, {
371
377
  fs,
372
378
  path,
373
379
  ROOT,
@@ -1,186 +1,218 @@
1
- /* eslint-disable no-console */
2
-
3
- function readUtf8IfExists(fs, absPath) {
4
- if (!fs.existsSync(absPath)) {
5
- return "";
6
- }
7
- return fs.readFileSync(absPath, "utf8");
8
- }
9
-
10
- function copyCursorBootstrap(force, deps) {
11
- const {
12
- fs,
13
- path,
14
- ROOT,
15
- CACHE_DIR,
16
- CURSOR_BOOTSTRAP_DIR,
17
- normalizeSlash,
18
- readSelfNpmPackageName,
19
- packageDir,
20
- } = deps;
21
-
22
- const pairs = [
23
- {
24
- from: path.join("rules", "00-output-token-budget.mdc"),
25
- to: path.join(".cursor", "rules", "00-output-token-budget.mdc"),
26
- },
27
- {
28
- from: path.join("rules", "01-figma-cache-core.mdc"),
29
- to: path.join(".cursor", "rules", "01-figma-cache-core.mdc"),
30
- },
31
- {
32
- from: path.join("rules", "02-figma-stack-adapter.mdc"),
33
- to: path.join(".cursor", "rules", "02-figma-stack-adapter.mdc"),
34
- },
35
- {
36
- from: path.join("rules", "figma-local-cache-first.mdc"),
37
- to: path.join(".cursor", "rules", "figma-local-cache-first.mdc"),
38
- },
39
- {
40
- from: path.join("skills", "figma-mcp-local-cache", "SKILL.md"),
41
- to: path.join(".cursor", "skills", "figma-mcp-local-cache", "SKILL.md"),
42
- },
43
- ];
44
-
45
- if (!fs.existsSync(CURSOR_BOOTSTRAP_DIR)) {
46
- console.error(
47
- `[figma-cache] cursor-bootstrap not found at ${normalizeSlash(CURSOR_BOOTSTRAP_DIR)} (broken package install?)`
48
- );
49
- process.exit(1);
50
- }
51
-
52
- const overwrite = !force;
53
- let copied = 0;
54
- let skipped = 0;
55
- pairs.forEach(({ from: relFrom, to: relTo }) => {
56
- const absFrom = path.join(CURSOR_BOOTSTRAP_DIR, relFrom);
57
- const absTo = path.join(ROOT, relTo);
58
- if (!fs.existsSync(absFrom)) {
59
- console.error(`[figma-cache] missing template file: ${normalizeSlash(absFrom)}`);
60
- process.exit(1);
61
- }
62
- fs.mkdirSync(path.dirname(absTo), { recursive: true });
63
- if (fs.existsSync(absTo) && !overwrite) {
64
- skipped += 1;
65
- return;
66
- }
67
- fs.copyFileSync(absFrom, absTo);
68
- copied += 1;
69
- });
70
-
71
- const configTemplatePath = path.join(CURSOR_BOOTSTRAP_DIR, "figma-cache.config.example.js");
72
- const projectConfigPath = path.join(ROOT, "figma-cache.config.js");
73
- const legacyExamplePath = path.join(ROOT, "figma-cache.config.example.js");
74
-
75
- if (!fs.existsSync(configTemplatePath)) {
76
- console.error(`[figma-cache] missing template file: ${normalizeSlash(configTemplatePath)}`);
77
- process.exit(1);
78
- }
79
-
80
- const hadProjectConfig = fs.existsSync(projectConfigPath);
81
- const hadLegacyExample = fs.existsSync(legacyExamplePath);
82
- const configTemplateBody = fs.readFileSync(configTemplatePath, "utf8");
83
-
84
- let configAction = "skipped";
85
- let configSource = "existing";
86
- if (hadProjectConfig && !force) {
87
- configAction = "skipped";
88
- configSource = "existing";
89
- } else if (!hadProjectConfig && hadLegacyExample && !force) {
90
- fs.copyFileSync(legacyExamplePath, projectConfigPath);
91
- configAction = "created";
92
- configSource = "legacy-example";
93
- } else {
94
- fs.writeFileSync(projectConfigPath, configTemplateBody, "utf8");
95
- configAction = hadProjectConfig ? "overwritten" : "created";
96
- configSource = "template";
97
- }
98
-
99
- let legacyExampleStatus = "not-found";
100
- if (fs.existsSync(legacyExamplePath)) {
101
- const legacyBody = readUtf8IfExists(fs, legacyExamplePath);
102
- const projectBody = readUtf8IfExists(fs, projectConfigPath);
103
- const sameAsTemplate = legacyBody === configTemplateBody;
104
- const sameAsProject = projectBody && legacyBody === projectBody;
105
- if (sameAsTemplate || sameAsProject) {
106
- fs.unlinkSync(legacyExamplePath);
107
- legacyExampleStatus = "deleted";
108
- } else {
109
- legacyExampleStatus = "kept-customized";
110
- }
111
- }
112
-
113
- const agentSrc = path.join(CURSOR_BOOTSTRAP_DIR, "AGENT-SETUP-PROMPT.md");
114
- const agentDest = path.join(ROOT, "AGENT-SETUP-PROMPT.md");
115
- if (!fs.existsSync(agentSrc)) {
116
- console.error(`[figma-cache] missing ${normalizeSlash(agentSrc)}`);
117
- process.exit(1);
118
- }
119
-
120
- let agentBody = fs.readFileSync(agentSrc, "utf8");
121
- const npmPkg = readSelfNpmPackageName();
122
- agentBody = agentBody.replace(/\{\{NPM_PACKAGE_NAME\}\}/g, npmPkg);
123
- fs.writeFileSync(agentDest, agentBody, "utf8");
124
-
125
- const colleagueSrc = path.join(packageDir, "docs", "colleague-guide-zh.md");
126
- const colleagueDest = path.join(CACHE_DIR, "docs", "colleague-guide-zh.md");
127
- if (!fs.existsSync(colleagueSrc)) {
128
- console.error(`[figma-cache] missing ${normalizeSlash(colleagueSrc)} (broken package install?)`);
129
- process.exit(1);
130
- }
131
- const colleagueSameFile = path.resolve(colleagueSrc) === path.resolve(colleagueDest);
132
- if (!colleagueSameFile) {
133
- fs.mkdirSync(path.dirname(colleagueDest), { recursive: true });
134
- fs.copyFileSync(colleagueSrc, colleagueDest);
135
- }
136
-
137
- console.log(
138
- JSON.stringify(
139
- {
140
- ok: true,
141
- root: normalizeSlash(ROOT),
142
- copied,
143
- skipped,
144
- force: !!force,
145
- overwriteByDefault: overwrite,
146
- hint: skipped
147
- ? "Some template files were skipped (--force means keep existing files)."
148
- : overwrite
149
- ? "Done. Existing .cursor templates were overwritten by latest bootstrap."
150
- : "Done.",
151
- configFile: normalizeSlash(projectConfigPath),
152
- configAction,
153
- configSource,
154
- legacyExampleFile: normalizeSlash(legacyExamplePath),
155
- legacyExampleStatus,
156
- agentPromptFile: normalizeSlash(agentDest),
157
- colleagueGuideFile: normalizeSlash(colleagueDest),
158
- colleagueGuideSynced: !colleagueSameFile,
159
- colleagueGuideNote: colleagueSameFile
160
- ? "colleague-guide-zh.md already at package path (toolchain dev tree); no copy."
161
- : "colleague-guide-zh.md refreshed under FIGMA_CACHE_DIR/docs (default figma-cache/docs/).",
162
- agentPromptNote:
163
- "AGENT-SETUP-PROMPT.md is refreshed every run. Next: @ it in Cursor; after Agent finishes, run npm run figma:cache:init (or npx figma-cache init if scripts are missing).",
164
- npmPackageName: npmPkg,
165
- },
166
- null,
167
- 2
168
- )
169
- );
170
- console.log(
171
- "\n" +
172
- "================================================================\n" +
173
- "下一步(请按顺序):\n" +
174
- "1) 在 Cursor 对话中输入 @AGENT-SETUP-PROMPT.md,并说明「按该文档执行」\n" +
175
- " (每次 cursor init 都会刷新该文件;无需再整篇粘贴。)\n" +
176
- "2) 待 Agent 完成后,在项目根初始化本地缓存索引:\n" +
177
- " npm run figma:cache:init\n" +
178
- " 若尚未补全 npm scripts,请改用:npx figma-cache init\n" +
179
- "================================================================\n"
180
- );
181
- }
182
-
183
- module.exports = {
184
- copyCursorBootstrap,
185
- };
186
-
1
+ /* eslint-disable no-console */
2
+
3
+ function readUtf8IfExists(fs, absPath) {
4
+ if (!fs.existsSync(absPath)) {
5
+ return "";
6
+ }
7
+ return fs.readFileSync(absPath, "utf8");
8
+ }
9
+
10
+ function loadManagedManifest({ fs, path, CURSOR_BOOTSTRAP_DIR, normalizeSlash }) {
11
+ const manifestPath = path.join(CURSOR_BOOTSTRAP_DIR, "managed-files.json");
12
+ if (!fs.existsSync(manifestPath)) {
13
+ console.error(`[figma-cache] missing managed files manifest: ${normalizeSlash(manifestPath)}`);
14
+ process.exit(1);
15
+ }
16
+
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
20
+ } catch (error) {
21
+ console.error(`[figma-cache] invalid managed files manifest: ${error.message}`);
22
+ process.exit(1);
23
+ }
24
+
25
+ const { managedFiles, retiredFiles } = parsed || {};
26
+ if (!Array.isArray(managedFiles) || managedFiles.length === 0) {
27
+ console.error("[figma-cache] managed-files.json must contain non-empty managedFiles");
28
+ process.exit(1);
29
+ }
30
+
31
+ const pairs = managedFiles.map((item, index) => {
32
+ if (!item || typeof item.from !== "string" || typeof item.to !== "string") {
33
+ console.error(`[figma-cache] invalid managedFiles[${index}] item`);
34
+ process.exit(1);
35
+ }
36
+ return {
37
+ from: item.from,
38
+ to: item.to,
39
+ };
40
+ });
41
+
42
+ const retired = Array.isArray(retiredFiles)
43
+ ? retiredFiles.filter((item) => typeof item === "string" && item.trim())
44
+ : [];
45
+
46
+ return { pairs, retired };
47
+ }
48
+
49
+ function copyCursorBootstrap(options, deps) {
50
+ const {
51
+ fs,
52
+ path,
53
+ ROOT,
54
+ CACHE_DIR,
55
+ CURSOR_BOOTSTRAP_DIR,
56
+ normalizeSlash,
57
+ readSelfNpmPackageName,
58
+ packageDir,
59
+ } = deps;
60
+ const {
61
+ overwrite = false,
62
+ legacyForce = false,
63
+ } = options || {};
64
+
65
+ const { pairs, retired } = loadManagedManifest({ fs, path, CURSOR_BOOTSTRAP_DIR, normalizeSlash });
66
+
67
+ if (!fs.existsSync(CURSOR_BOOTSTRAP_DIR)) {
68
+ console.error(
69
+ `[figma-cache] cursor-bootstrap not found at ${normalizeSlash(CURSOR_BOOTSTRAP_DIR)} (broken package install?)`
70
+ );
71
+ process.exit(1);
72
+ }
73
+
74
+ let copied = 0;
75
+ let skipped = 0;
76
+ pairs.forEach(({ from: relFrom, to: relTo }) => {
77
+ const absFrom = path.join(CURSOR_BOOTSTRAP_DIR, relFrom);
78
+ const absTo = path.join(ROOT, relTo);
79
+ if (!fs.existsSync(absFrom)) {
80
+ console.error(`[figma-cache] missing template file: ${normalizeSlash(absFrom)}`);
81
+ process.exit(1);
82
+ }
83
+ fs.mkdirSync(path.dirname(absTo), { recursive: true });
84
+ if (fs.existsSync(absTo) && !overwrite) {
85
+ skipped += 1;
86
+ return;
87
+ }
88
+ fs.copyFileSync(absFrom, absTo);
89
+ copied += 1;
90
+ });
91
+
92
+ const retiredDeleted = retired
93
+ .map((relPath) => {
94
+ const abs = path.join(ROOT, relPath);
95
+ if (!fs.existsSync(abs)) {
96
+ return null;
97
+ }
98
+ fs.unlinkSync(abs);
99
+ return normalizeSlash(relPath);
100
+ })
101
+ .filter(Boolean);
102
+
103
+ const configTemplatePath = path.join(CURSOR_BOOTSTRAP_DIR, "figma-cache.config.example.js");
104
+ const projectConfigPath = path.join(ROOT, "figma-cache.config.js");
105
+ const legacyExamplePath = path.join(ROOT, "figma-cache.config.example.js");
106
+
107
+ if (!fs.existsSync(configTemplatePath)) {
108
+ console.error(`[figma-cache] missing template file: ${normalizeSlash(configTemplatePath)}`);
109
+ process.exit(1);
110
+ }
111
+
112
+ const hadProjectConfig = fs.existsSync(projectConfigPath);
113
+ const hadLegacyExample = fs.existsSync(legacyExamplePath);
114
+ const configTemplateBody = fs.readFileSync(configTemplatePath, "utf8");
115
+
116
+ let configAction = "skipped";
117
+ let configSource = "existing";
118
+ if (hadProjectConfig && !overwrite) {
119
+ configAction = "skipped";
120
+ configSource = "existing";
121
+ } else if (!hadProjectConfig && hadLegacyExample && !overwrite) {
122
+ fs.copyFileSync(legacyExamplePath, projectConfigPath);
123
+ configAction = "created";
124
+ configSource = "legacy-example";
125
+ } else {
126
+ fs.writeFileSync(projectConfigPath, configTemplateBody, "utf8");
127
+ configAction = hadProjectConfig ? "overwritten" : "created";
128
+ configSource = "template";
129
+ }
130
+
131
+ let legacyExampleStatus = "not-found";
132
+ if (fs.existsSync(legacyExamplePath)) {
133
+ const legacyBody = readUtf8IfExists(fs, legacyExamplePath);
134
+ const projectBody = readUtf8IfExists(fs, projectConfigPath);
135
+ const sameAsTemplate = legacyBody === configTemplateBody;
136
+ const sameAsProject = projectBody && legacyBody === projectBody;
137
+ if (sameAsTemplate || sameAsProject) {
138
+ fs.unlinkSync(legacyExamplePath);
139
+ legacyExampleStatus = "deleted";
140
+ } else {
141
+ legacyExampleStatus = "kept-customized";
142
+ }
143
+ }
144
+
145
+ const agentSrc = path.join(CURSOR_BOOTSTRAP_DIR, "AGENT-SETUP-PROMPT.md");
146
+ const agentDest = path.join(ROOT, "AGENT-SETUP-PROMPT.md");
147
+ if (!fs.existsSync(agentSrc)) {
148
+ console.error(`[figma-cache] missing ${normalizeSlash(agentSrc)}`);
149
+ process.exit(1);
150
+ }
151
+
152
+ let agentBody = fs.readFileSync(agentSrc, "utf8");
153
+ const npmPkg = readSelfNpmPackageName();
154
+ agentBody = agentBody.replace(/\{\{NPM_PACKAGE_NAME\}\}/g, npmPkg);
155
+ fs.writeFileSync(agentDest, agentBody, "utf8");
156
+
157
+ const colleagueSrc = path.join(packageDir, "docs", "colleague-guide-zh.md");
158
+ const colleagueDest = path.join(CACHE_DIR, "docs", "colleague-guide-zh.md");
159
+ if (!fs.existsSync(colleagueSrc)) {
160
+ console.error(`[figma-cache] missing ${normalizeSlash(colleagueSrc)} (broken package install?)`);
161
+ process.exit(1);
162
+ }
163
+ const colleagueSameFile = path.resolve(colleagueSrc) === path.resolve(colleagueDest);
164
+ if (!colleagueSameFile) {
165
+ fs.mkdirSync(path.dirname(colleagueDest), { recursive: true });
166
+ fs.copyFileSync(colleagueSrc, colleagueDest);
167
+ }
168
+
169
+ console.log(
170
+ JSON.stringify(
171
+ {
172
+ ok: true,
173
+ root: normalizeSlash(ROOT),
174
+ copied,
175
+ skipped,
176
+ overwrite,
177
+ legacyForce,
178
+ retiredDeleted,
179
+ hint: skipped
180
+ ? "Some template files were skipped (default safe mode keeps existing files)."
181
+ : overwrite
182
+ ? "Done. Existing .cursor templates were overwritten by latest bootstrap."
183
+ : "Done.",
184
+ configFile: normalizeSlash(projectConfigPath),
185
+ configAction,
186
+ configSource,
187
+ legacyExampleFile: normalizeSlash(legacyExamplePath),
188
+ legacyExampleStatus,
189
+ agentPromptFile: normalizeSlash(agentDest),
190
+ colleagueGuideFile: normalizeSlash(colleagueDest),
191
+ colleagueGuideSynced: !colleagueSameFile,
192
+ colleagueGuideNote: colleagueSameFile
193
+ ? "colleague-guide-zh.md already at package path (toolchain dev tree); no copy."
194
+ : "colleague-guide-zh.md refreshed under FIGMA_CACHE_DIR/docs (default figma-cache/docs/).",
195
+ agentPromptNote:
196
+ "AGENT-SETUP-PROMPT.md is refreshed every run. Next: @ it in Cursor; after Agent finishes, run npm run figma:cache:init (or npx figma-cache init if scripts are missing).",
197
+ npmPackageName: npmPkg,
198
+ },
199
+ null,
200
+ 2
201
+ )
202
+ );
203
+ console.log(
204
+ "\n" +
205
+ "================================================================\n" +
206
+ "下一步(请按顺序):\n" +
207
+ "1) 在 Cursor 对话中输入 @AGENT-SETUP-PROMPT.md,并说明「按该文档执行」\n" +
208
+ " (每次 cursor init 都会刷新该文件;无需再整篇粘贴。)\n" +
209
+ "2) 待 Agent 完成后,在项目根初始化本地缓存索引:\n" +
210
+ " npm run figma:cache:init\n" +
211
+ " 若尚未补全 npm scripts,请改用:npx figma-cache init\n" +
212
+ "================================================================\n"
213
+ );
214
+ }
215
+
216
+ module.exports = {
217
+ copyCursorBootstrap,
218
+ };
package/package.json CHANGED
@@ -1,74 +1,75 @@
1
- {
2
- "name": "figma-cache-toolchain",
3
- "version": "2.0.1",
4
- "description": "Figma link normalization, local cache index, validation, and Node CLI (framework-agnostic core).",
5
- "homepage": "https://github.com/907086379/figma-cache-toolchain#readme",
6
- "keywords": [
7
- "figma",
8
- "cache",
9
- "cli",
10
- "design-tokens",
11
- "mcp"
12
- ],
13
- "license": "MIT",
14
- "engines": {
15
- "node": ">=16.20.0"
16
- },
17
- "bin": {
18
- "figma-cache": "bin/figma-cache.js"
19
- },
20
- "files": [
21
- "LICENSE",
22
- "bin",
23
- "cursor-bootstrap",
24
- "figma-cache/figma-cache.js",
25
- "figma-cache/js/flow-cli.js",
26
- "figma-cache/js/validate-cli.js",
27
- "figma-cache/js/budget-cli.js",
28
- "figma-cache/js/index-store.js",
29
- "figma-cache/js/cursor-bootstrap-cli.js",
30
- "figma-cache/js/entry-files.js",
31
- "figma-cache/js/backfill-cli.js",
32
- "figma-cache/js/project-config.js",
33
- "figma-cache/js/upsert-core.js",
34
- "figma-cache/docs/*.md"
35
- ],
36
- "publishConfig": {
37
- "registry": "https://registry.npmjs.org/"
38
- },
39
- "scripts": {
40
- "test": "npm run cursor:shadow:check && npm run docs:encoding:check && node tests/rules-guard.js && node tests/smoke.js",
41
- "prepack": "npm run cursor:shadow:check && npm run docs:encoding:check && node bin/figma-cache.js validate",
42
- "figma:cache:normalize": "node bin/figma-cache.js normalize",
43
- "figma:cache:get": "node bin/figma-cache.js get",
44
- "figma:cache:upsert": "node bin/figma-cache.js upsert",
45
- "figma:cache:ensure": "node bin/figma-cache.js ensure",
46
- "figma:cache:validate": "node bin/figma-cache.js validate",
47
- "figma:cache:stale": "node bin/figma-cache.js stale",
48
- "figma:cache:budget": "node bin/figma-cache.js budget --mcp-only",
49
- "figma:cache:backfill": "node bin/figma-cache.js backfill",
50
- "figma:cache:init": "node bin/figma-cache.js init",
51
- "figma:cache:config": "node bin/figma-cache.js config",
52
- "figma:cache:flow:init": "node bin/figma-cache.js flow init",
53
- "figma:cache:flow:add-node": "node bin/figma-cache.js flow add-node",
54
- "figma:cache:flow:link": "node bin/figma-cache.js flow link",
55
- "figma:cache:flow:chain": "node bin/figma-cache.js flow chain",
56
- "figma:cache:flow:show": "node bin/figma-cache.js flow show",
57
- "figma:cache:flow:mermaid": "node bin/figma-cache.js flow mermaid",
58
- "figma:cache:cursor:init": "node bin/figma-cache.js cursor init",
59
- "cursor:shadow:sync": "node scripts/sync-cursor-shadow.js",
60
- "cursor:shadow:check": "node scripts/check-cursor-shadow.js",
61
- "docs:encoding:check": "node scripts/check-doc-encoding.js",
62
- "figma:cache:mobile:spec": "node scripts/mobile/generate-mobile-spec.js"
63
- },
64
- "volta": {
65
- "node": "16.20.2"
66
- },
67
- "repository": {
68
- "type": "git",
69
- "url": "git+https://github.com/907086379/figma-cache-toolchain.git"
70
- },
71
- "bugs": {
72
- "url": "https://github.com/907086379/figma-cache-toolchain/issues"
73
- }
74
- }
1
+ {
2
+ "name": "figma-cache-toolchain",
3
+ "version": "2.0.3",
4
+ "description": "Figma link normalization, local cache index, validation, and Node CLI (framework-agnostic core).",
5
+ "homepage": "https://github.com/907086379/figma-cache-toolchain#readme",
6
+ "keywords": [
7
+ "figma",
8
+ "cache",
9
+ "cli",
10
+ "design-tokens",
11
+ "mcp"
12
+ ],
13
+ "license": "MIT",
14
+ "engines": {
15
+ "node": ">=16.20.0"
16
+ },
17
+ "bin": {
18
+ "figma-cache": "bin/figma-cache.js"
19
+ },
20
+ "files": [
21
+ "LICENSE",
22
+ "bin",
23
+ "cursor-bootstrap",
24
+ "figma-cache/figma-cache.js",
25
+ "figma-cache/js/flow-cli.js",
26
+ "figma-cache/js/validate-cli.js",
27
+ "figma-cache/js/budget-cli.js",
28
+ "figma-cache/js/index-store.js",
29
+ "figma-cache/js/cursor-bootstrap-cli.js",
30
+ "figma-cache/js/entry-files.js",
31
+ "figma-cache/js/backfill-cli.js",
32
+ "figma-cache/js/project-config.js",
33
+ "figma-cache/js/upsert-core.js",
34
+ "figma-cache/docs/*.md"
35
+ ],
36
+ "publishConfig": {
37
+ "registry": "https://registry.npmjs.org/"
38
+ },
39
+ "scripts": {
40
+ "test": "npm run cursor:shadow:check && npm run docs:encoding:check && node tests/rules-guard.js && node tests/smoke.js",
41
+ "prepack": "npm run cursor:shadow:check && npm run docs:encoding:check && node bin/figma-cache.js validate",
42
+ "figma:cache:normalize": "node bin/figma-cache.js normalize",
43
+ "figma:cache:get": "node bin/figma-cache.js get",
44
+ "figma:cache:upsert": "node bin/figma-cache.js upsert",
45
+ "figma:cache:ensure": "node bin/figma-cache.js ensure",
46
+ "figma:cache:validate": "node bin/figma-cache.js validate",
47
+ "figma:cache:stale": "node bin/figma-cache.js stale",
48
+ "figma:cache:budget": "node bin/figma-cache.js budget --mcp-only",
49
+ "figma:cache:backfill": "node bin/figma-cache.js backfill",
50
+ "figma:cache:init": "node bin/figma-cache.js init",
51
+ "figma:cache:config": "node bin/figma-cache.js config",
52
+ "figma:cache:flow:init": "node bin/figma-cache.js flow init",
53
+ "figma:cache:flow:add-node": "node bin/figma-cache.js flow add-node",
54
+ "figma:cache:flow:link": "node bin/figma-cache.js flow link",
55
+ "figma:cache:flow:chain": "node bin/figma-cache.js flow chain",
56
+ "figma:cache:flow:show": "node bin/figma-cache.js flow show",
57
+ "figma:cache:flow:mermaid": "node bin/figma-cache.js flow mermaid",
58
+ "figma:cache:cursor:init": "node bin/figma-cache.js cursor init",
59
+ "cursor:shadow:sync": "node scripts/sync-cursor-shadow.js",
60
+ "cursor:shadow:check": "node scripts/check-cursor-shadow.js",
61
+ "docs:encoding:check": "node scripts/check-doc-encoding.js",
62
+ "figma:cache:mobile:spec": "node scripts/mobile/generate-mobile-spec.js",
63
+ "figma:ui:gate": "npm run figma:cache:validate && npm run cursor:shadow:check && npm test"
64
+ },
65
+ "volta": {
66
+ "node": "16.20.2"
67
+ },
68
+ "repository": {
69
+ "type": "git",
70
+ "url": "git+https://github.com/907086379/figma-cache-toolchain.git"
71
+ },
72
+ "bugs": {
73
+ "url": "https://github.com/907086379/figma-cache-toolchain/issues"
74
+ }
75
+ }