# 长期计划 v2 — Figma↔Code Bridge（2026-04-29 起）

> **本文件是新真源**，覆盖 [long-term-plan-2026-04-28.md](long-term-plan-2026-04-28.md) v1。
> v1 标 deprecated，仅作历史参考。所有新 Session 应读本文件。

---

## 真实目标

把 TVU Figma 设计系统封装成 **AI 与开发可消费的 Figma↔Code 桥**，达成：

1. **开发者拿到 docs 站即可用** —— 看一页就知道怎么 import / 用哪个 prop / 拿到能跑的最小代码片段
2. **AI 拿到 Figma URL → 自动定位代码并生成 import** —— 通过 Code Connect 官方机制
3. **EP 风格分类** —— 按开发者视角（Basic / Form / Data / Navigation / Feedback / Others / Configuration）而非 Figma 设计师视角组织
4. **每个 code 组件标注 Figma origin** —— 标注来自哪个 Figma node、属性映射可追溯
5. **1:1 视觉还原可验证** —— 视觉回归 baseline 防止漂移

---

## 工作纪律（沿用 v1 + 强化）

1. **No-commit until milestone**：所有 Codex prompt 严禁 `git add` / `git commit`。所有改动累积到 dirty 工作区，最终 M1 一刀 commit。**每一份新写的 prompt 必须包含 "任务 N：⚠️ 不要 commit"**。
2. **Spec 跟现实走**：spec 不预设规则，每条规则必须有真实实现锚点
3. **修复层级判定**：发现要 `:deep()` 时 99% 是组件本体的事
4. **审计与修复分离**：audit prompt 只产报告不动代码；fix prompt 基于报告做修复——不在同一 Codex run 里既 audit 又 fix
5. **样板优先批量靠后**：22 页改造不一刀，先 3 类样板验证再批量

---

## Bridge Layer 架构（v2 新增）

```
┌──────────────────────────────────────────────────────┐
│  Figma 源（设计师组织：—— Other Components 等）     │
└─────────┬────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────┐
│  Normalization Layer（已建大半）                    │
│  • figma-data/normalized/*.json                     │
│  • variables.json / icons normalized                │
└─────────┬────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────┐
│  Code Layer（已建大半，**Class C 待修**）           │
│  • src/canonical/*.vue                              │
│  • src/styles/variables.css                         │
│  • src/icons/*                                      │
│  • src/design-system/translation/*                  │
└─────────┬────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────┐
│  Bridge Layer（**v2 新增 - 几乎空白**）             │
│  • Code Connect .figma.ts（Figma↔Code 硬绑定）      │
│  • Reverse lookup index（node → code）              │
│  • AI manifest（机器可读，AI 直接消费）             │
│  • EP 风格分类                                      │
└─────────┬────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────┐
│  Presentation Layer                                 │
│  • Generated Figma Spec sections（生成不手写）      │
│  • Curated Runtime Docs（API 表 / Try It / Dev Use）│
└──────────────────────────────────────────────────────┘
```

---

## 5 轨道路线图

### T1：Foundation — 让组件本体可信

**为什么先做**：所有下游（generator / Code Connect / 视觉回归）都假设组件本体可信。组件不对，下游全错。Progress 已审出是伪主题；Slider / Rating Figma 数据缺；Tooltip 命名映射未登记。

**拆 2 步**：

#### T1a：audit only

- 写 `figma-sync/audit-component-token-fidelity.mjs`
- 跑一次产报告 `docs/internal/component-token-fidelity-report.md`
- **不修任何代码**
- 覆盖维度（Codex 要求扩展）：
  - theme axis
  - status axis
  - size axis
  - fill / track / text / icon color tokens
  - dimensions（normalized JSON 有明确值的）
- 算法：每组件每 variant tuple，对比 code CSS resolved value vs Figma normalized JSON `fills[*].token` / `fills[*].hex`
- 输出：每组件每 variant 一行，标 ✅ 一致 / ⚠️ 不一致（列差异）/ ❌ 数据缺

**产出**：
- 1 个新 audit 脚本
- 1 份全库 component-token 一致性报告

#### T1b：fix C 类组件

基于 T1a 报告写 fix prompt，分组件单独修：

- Progress：CSS 改成消费 Figma token（不再用 `--bg-layer3` / `--line-divider-light` 自创 mapping）
- Slider / Rating：补 figma-data pipeline 提取缺失的 fills
- Tooltip：在 [prop-aliases.md](../../src/design-system/translation/prop-aliases.md) 登记 `darkTheme[on|off] ↔ theme[dark|light]` 映射

**产出**：组件本体修正 diff（dirty 工作区）

---

### T1c：Extract Pipeline Schema 升级（依赖 T1b 完成，T2 启动前完成）

**为什么独立成轨道**：T1b 是修组件本体（改 `src/`）；T1c 是修数据管道（改 `figma-sync/` + 真源翻译层）。混在一起会让 commit 历史和回顾混乱。

**为什么先做**：[figma-sync/extract.mjs](../../figma-sync/extract.mjs) `extractNodeFrame()` 只抽 COMPONENT / COMPONENT_SET 顶层 fills/strokes/text，子节点只收 `vectorNodeIds`（用于 icon detection），不抽子节点 paint。后果：

- 8 组件 171 条 figma-data-missing（[component-token-fidelity-report.md](component-token-fidelity-report.md) Summary）：Progress 32 / FormItem 26 / Rating 20 / Switch 14 / Notification 10 / TopBar 9 / StepItem 9 / Slider 8 / Checkbox+Input 7
- 实证：Slider / Rating 顶层 fill = `[{opacity: 0, hex: #000000}]`（透明占位），track / handle / star 视觉数据全在子节点
- T2 generator 无法 1:1 还原 Slider track / Rating star / Progress fill bar 等子节点视觉
- T4a Code Connect 绑定到不存在的子节点 = 假桥

**两轮做**（按 T1a fix v2 经验，schema 决策类升级必须分轮）：

#### T1c Round 1：plan only

prompt：[`t1c-extract-recurse-children-round1-plan-only.prompt.md`](_prompts/t1c-extract-recurse-children-round1-plan-only.prompt.md)

executor 产出：
- `docs/internal/_plans/t1c-extract-recurse-plan.md` — 10 节实现计划（含 schema 设计 / 受影响组件清单 / 算法 / 缓存设计 / 下游消费契约 / 边界 case / 自验数字 / 工程量分解）
- `src/design-system/translation/figma-extract-rules.draft.md` — 真源 schema 草稿 + 5 实例（Slider / Rating / Progress / Notification / Switch）

#### T1c Round 2：implementation

按 plan owner 复审通过的 plan + 定稿 schema 改：

- `figma-sync/extract.mjs` — 加 `extractChildrenByRules()` 递归 + 读 `figma-extract-rules.md`
- `figma-sync/normalize-component-tokens.mjs` — 消费 `extractedChildren` + 保留 child role / nodePath 字段
- `figma-sync/audit-component-token-fidelity.mjs` — figma-data-missing 触发逻辑升级（line 1530-1560）
- 加 raw Figma response 缓存（`figma-data/raw-cache/figma-file-response.json`，进 .gitignore），让后续改 extract 规则不用反复网络调 API
- 跑 `pnpm sync:figma-library --with-extract`（**安全模式，dry-run cleanup**）拉新数据
- 重跑 audit，验证 figma-data-missing 降幅
- Round 2 完成后把 `figma-extract-rules.draft.md` 定稿为 `figma-extract-rules.md`，更新 [AGENTS.md](../../AGENTS.md) 必读链路第 4 段（translation/ 从 4 文件 → 5 文件）

**产出**：
- 升级后的 extract pipeline + `figma-extract-rules.md` 真源
- figma-data-missing 从 171 降到接近 0
- 解锁 T2 generator 的 1:1 还原可行性 + T4a Code Connect 绑定可信度

---

### T2：Docs Generator + Page Refactor（依赖 T1 完成）

**为什么不一刀做完 22 页**：22 页同时改造容易出现新脏数据。先 3 类样板跑通再批量。

#### T2 样板阶段（3 类样板）

> ⚠️ **2026-04-30 修正**：原 v2 plan 选 Progress / Notification / Select 作样板，但 Progress + Notification 在 figma-data-missing 8 组件清单里（依赖 T1c PAUSED）。T2 generator 渲染它们的 Figma Members 段视觉会不完整。修正为下面 3 个**已被 spike 验证 + figma-data 干净**的组件，避免 T1c 阻塞。

挑 3 个代表性组件做 refactor 样板：

- **Badge**：Color × Tag × Type 三 axis 视觉 primitive 类（已 spike 验证 1:1，commit b9e5ac3）
- **Tooltip**：darkTheme × pointing × content 三 axis hover 反馈类（已 spike 验证 rule #6 通用机制 PASS）
- **Select**：darkTheme on/off 表单类（canonical SelectBoxLine / SelectBoxFilled，figma-data 干净）

**原 Progress / Notification 改造延后**到 T1c 恢复后单独跑（与剩余 6 个 figma-data-missing 组件页一并处理）。

每类样板包含：
- 写 `figma-sync/generate-docs-figma-spec.mjs`（增量实现，先支持这 3 类）
- 生成 `figma-data/normalized/docs-figma-members/<X>.ts`
- 写 `<FigmaMembersGrid>` Vue 组件（`playground/docs/components/FigmaMembersGrid.vue`）
- 改造 BadgePage / TooltipPage / SelectPage 用 generator + grid
- 跑 4 个 page-level audit 验证：
  - α: theme isolation（页面只渲染当前站点 theme 的 variant）
  - β: figma axis coverage（渲染的 prop 值必须在 Figma axis 里）
  - γ: runtime fabrication（Figma Members 段不能混 runtime-only demo）
  - δ: token purity（CSS 禁 hex/rgb literal）

#### T2 批量阶段（剩 19 页）

样板 3 页验证 OK 后，再批量改造剩 19 页。审 batch diff 确认不破样板范式。

**产出**：22 页 Figma Members 段全部从 generator 来，禁手写

---

### T3：EP 风格分类（与 T2 并行，独立轨道）

**为什么并行**：只动 navigation + 元数据，不碰页面内容。零冲突。

- 重组 [playground/docs/navigation.ts](../../playground/docs/navigation.ts) 为 EP 7 大类：

| 类 | 组件 |
|---|---|
| Basic | Button / Icon |
| Form | Input / InputNumber / Select / DateTime / Checkbox / Radio / Switch / Slider / Rating / FormItem |
| Data | Table / Pagination |
| Navigation | Breadcrumb / Steps / Tabs / TopBar |
| Feedback | Notification / Tooltip / Progress / PromptMessage |
| Others | Badge |
| Configuration | (站点 theme switcher 等基础设施页) |

- 22 页头加 Figma source 元数据（`figmaPage` / `figmaNodeId`），建立 EP 类 → Figma 来源映射

**产出**：新导航结构 + 22 页元数据

---

### T4：Bridge Layer — Code Connect + AI manifest（依赖 T1+T2 稳定）

**为什么等**：Code Connect 一旦绑定，错误的页面/组件会被固化为"正式桥"。T1+T2 不稳就上 T4 = 把脏数据合法化。

#### T4a：Code Connect .figma.ts 文件

每个 canonical 组件生成 `<X>.figma.ts`：

```ts
import figma from '@figma/code-connect'
import Progress from './Progress.vue'

figma.connect(Progress, 'https://figma.com/.../node-id=4915-7287', {
  props: {
    theme: figma.enum('theme', { dark: 'dark', light: 'light' }),
    status: figma.enum('status', { ... }),
    size: figma.enum('size', { ... }),
  },
  example: ({ theme, status, size }) => `<Progress theme="${theme}" status="${status}" size="${size}" :value="60" />`,
})
```

#### T4b：AI manifest

`dist/ai-manifest.json`（npm 发布时附带）：

```json
{
  "components": [
    {
      "name": "Progress",
      "figmaNodeId": "4915:7287",
      "figmaUrl": "https://figma.com/...",
      "vueImport": "import { Progress } from '@tvu/design-system'",
      "props": [...],
      "events": [...],
      "slots": [...],
      "examples": [...]
    }
  ],
  "tokens": { ... },
  "icons": { ... }
}
```

#### T4c：反向索引

`figma-data/normalized/figma-to-code-index.json`：

```json
{
  "4915:7287": {
    "codeComponent": "Progress",
    "filePath": "src/canonical/Progress.vue",
    "docsPage": "playground/docs/pages/ProgressPage.vue",
    "props": { "theme": "...", "status": "...", "size": "..." }
  }
}
```

**产出**：3 类 Bridge artifact，让 AI 工具直接消费

---

### T5：Visual Regression Baseline（长期，可在 M1 后启动）

- Playwright 跑每个 docs page 每个 demo
- baseline PNG 入 git
- PR diff 超过阈值 fail

**为什么留到最后**：搭建 4-6 小时，T1-T4 落地后跑一次截图作 baseline，从此免维护。

---

## 执行顺序总览

```
[串行]
T1a  audit-component-token-fidelity（audit only）
   ↓
T1b  修 C 类组件（Progress / Slider / Rating / Tooltip alias）
   ↓
T1c  Extract Pipeline 升级（递归子节点 + figma-extract-rules.md 真源）
   ↓
[T2 与 T3 并行]
T2 样板  generator + grid + 改 3 个样板页 + 4 page audit
   ↓
T2 批量  剩 19 页改造
   |
T3       EP 导航重组 + 22 页元数据
   ↓
[串行]
T4a  Code Connect .figma.ts
T4b  AI manifest
T4c  反向索引
   ↓
[里程碑]
M1 一刀 commit（包含 T1-T4 累积全部 dirty + 用户 WIP + spec 重写版）
   ↓
[长期]
T5 视觉回归 baseline
```

---

## Codex prompt 数量预估

| 阶段 | prompt 数 |
|---|---:|
| T1a audit | 1 |
| T1b fix（按组件拆，3-4 个） | 3-4 |
| T1c extract pipeline（Round 1 plan-only + Round 2 implementation） | 2 |
| T2 样板（generator + grid + 3 页） | 1-2 |
| T2 批量 | 1 |
| T3 navigation | 1 |
| T4a Code Connect | 1 |
| T4b manifest | 1 |
| T4c 反向索引 | 1 |
| **总计** | **12-14** |

每个 prompt 全 no-commit。

---

## 之前工作的最终归类

| 工作 | 状态 | 在 v2 框架里 |
|---|---|---|
| 翻译层（6.1/6.2/6.3） | ✅ 已 commit | Code Layer 资产，保留 |
| Phase 6.3.5 反向 audit | ✅ 已 commit | 数据资产，保留 |
| D1 API 三表（commit 9fa1882） | ✅ 已 commit | Curated Runtime Docs Layer，保留 |
| Phase A 22 页 baseline | untracked | 数据资产，T2 批量阶段输入 |
| Component theme audit (2026-04-29) | untracked | T1 输入 |
| 595 行 DX parity spec | untracked | T2 完成后**部分重写**作为最终 spec |
| D2 prompt（未 fire） | untracked | **降级**——原意"Try It demo"会在 T2 Curated 层落实，prompt 文件保留作历史参考 |
| D3 / D4 / 6.3.5d 等 prompt | untracked / 未写 | D3/D4 不再需要；6.3.5d 独立任务，M1 后再做 |
| 用户 8 个 dirty WIP（FormItem/Steps/PromptMessage） | dirty | T1b 期间审 diff，决定是否合并 |

---

## 当前进度（2026-04-29 上午）

- ✅ 11 组件 theme 审计完成（[component-theme-implementation-audit-2026-04-29.md](component-theme-implementation-audit-2026-04-29.md)）
- ✅ v2 计划落地（本文件）
- ⏳ 待写 T1a prompt（下一步）

---

## 当前进度（2026-04-29 下午 — 拐点）

- ✅ T1a fix v2 三轮完成（commit ccf48a0 / 8d12abf / f5941f2）
- ✅ T1b 2/3 完成（Progress 自创 dark/light 删除 + Tooltip darkTheme alias 登记）；Slider / Rating 待 T1c
- ✅ T1c Round 1 plan + schema 草稿产出（dirty：[t1c-extract-recurse-plan.md](_plans/t1c-extract-recurse-plan.md) + [figma-extract-rules.draft.md](../../src/design-system/translation/figma-extract-rules.draft.md)）
- ⏸️ **T1c PAUSED** —— 用户元层面疑问"项目目标越来越远"，决策暂停 T1c Round 2 implementation
- ▶️ **T4-spike 启动** —— 跳转到 Bridge Layer 做 Badge vertical slice，验证 "AI 拿 Figma URL → 1:1 还原 Vue 代码" 端到端是否跑通
- 拐点决策：spike 跑通 → 重估 T1c 必要性（可能 component-by-component 跳过 8 个 figma-data-missing 组件，先在 13 个干净组件上做 T4，再回头补 T1c）

---

## 当前进度（2026-04-30 — T4-spike 收口 + 路径再调整）

- ✅ T4-spike 完成（commit b9e5ac3）：Badge vertical slice 端到端 Figma URL → 1:1 Vue 代码验证 PASS（Claude + Codex 双 AI 工具）
- ✅ Badge canonical/legacy 双源处置：legacy 加 LEGACY 警告 + divergences.md "Code 端双源" 段登记
- ✅ AGENTS.md 硬规则 #6 加："AI 工具从 Figma URL 生成代码必须用 src/canonical/* 作为 SoT"——Tooltip 二轮测试已证 rule #6 通用机制对 wrapper 组件有效（Claude 显式引用 #6 by number）
- 🔍 **关键发现：Code Connect publish 需 Organization / Enterprise seat**——用户当前 Pro plan，`figma connect publish` 不可达
- 🚫 **T4 batch DEFERRED until Org plan upgrade**：写 20 个 .figma.ts 在 Pro plan 上主要是 Org-tier 投机价值；项目目标"AI 拿 URL → 1:1"已通过 rule #6 + canonical SoT 拿到
- ▶️ **下一阶段：T3 先 → T2 后（修正为串行）** —— 单 executor 模式下并行无意义；T3 nav 不依赖任何数据，先跑 1-2h 小赢；T2 样板换 3 个 figma-data 干净组件（Badge / Tooltip / Select），避开 figma-data-missing 雷
  - **T2 样板修正**：原 Progress / Notification / Select → **Badge / Tooltip / Select**。Progress + Notification 改造延后到 T1c 恢复后处理
  - 项目级约束登记：[AGENTS.md "项目约束" 段](../../AGENTS.md) Pro plan 限制（跨工具有效）

### Pro tier Bridge 状态总结

| 项目目标 | Pro 可达？ | 当前 |
|---|---|---|
| AI 拿 Figma URL → 1:1 还原 Vue | ✅ | ✅ rule #6 + canonical + divergences |
| 多 AI 工具收敛到 canonical SoT | ✅ | ✅ rule #6 + Badge legacy header |
| Figma 改 → 找受影响代码 | ✅（现有 `pnpm sync:figma-library` audit） | ✅ |
| `figma connect publish` + DevMode 显代码片段 | ❌（需 Org/Ent） | 已 DEFERRED |

---

## 用户回到下次 Session 时优先看

1. 本文件（方向）
2. [component-theme-implementation-audit-2026-04-29.md](component-theme-implementation-audit-2026-04-29.md)（数据基础）
3. T1a prompt（要 fire 的下一刀）

如果方向偏了告诉 Claude；如果 OK，把 T1a prompt 路径粘给 Codex 触发。
