# 03 · 数据契约 > 所有内容(页面端 + MCP 端)共享的同一份数据结构的定义。 > 这是"一份数据,两个出口"原则的技术落地:结构定死,内容的存放位置随阶段演进。 --- ## 1. 总原则 1. **单一事实来源**:流程内容只维护一份,页面端与 MCP 端消费同一份数据 2. **原型阶段固化**:内容硬编码为 JS 数据模块(Node 可直接 import),不过度设计存储层 3. **结构先行**:本文件定义的字段结构是稳定的;内容(各阶段的文本)可随时改 4. **未来外置化**:当"改内容要动代码"成为负担时,改为 JSON/YAML 加载——契约不变,只换存储介质 --- ## 2. 模式(Mode) ```jsonc { "id": "wpf", // 唯一标识,MCP 参数用 "name": "WPF 启发流", "description": "面向 .NET WPF 桌面应用,适合工业/管理类桌面软件", "techStack": [".NET", "XAML", "MVVM"], "status": "primary", // primary(首发)/ planned(规划中) "stageOverrides": {}, // 模式对通用阶段的差异覆盖(见 §3.3) "notes": "设计稿窗口尺寸 = 目标 WPF 窗口尺寸" } ``` 四种模式:`wpf`(首发)、`vue`、`react`、`generic`(通用)。 --- ## 3. 阶段约束包(StageContract) MCP 核心工具的核心返回物。每个模式的每个阶段一个。 ### 3.1 字段定义 | 字段 | 类型 | 说明 | |---|---|---| | `id` | string | 阶段标识:`blueprint` / `explore` / `tokens` / `components` / `main` / `spec` / `checkup` / `mapping` / `handoff` | | `modeId` | string | 所属模式 | | `number` | number | 阶段序号 0-8 | | `name` | string | 阶段名 | | `goal` | string | 一句话目标 | | `deliverables` | object[] | 产物清单:`{ name, path?, description }` | | `exitCriteria` | string[] | 出口条件(怎么算做完) | | `dependencies` | object[] | 前置依赖:`{ stageId, deliverable, hint }`——用于提示进展 | | `rules` | string[] | 本阶段的硬规则(如"不许魔法数字") | | `guidance` | string[] | AI 引导用户的步骤要点(AI 读给用户) | | `aiPromptTemplate` | string | 可复制的提示词模板(人发给 AI 编码助手用) | | `pitfalls` | string[] | 常见坑 | | `revisionImpact` | string[] | 回退影响面:改本阶段产物后需复查什么 | | `humanCheckpoint` | string | 人确认点的描述 | | `capabilities` | string[] | 引用能力包 id(如 `design-toolkit`),无则空 | | `environment` | object[] | 本阶段环境要求(透传自能力包,见 §5) | ### 3.2 完整示例(WPF 模式 · 阶段 2 定令牌) ```jsonc { "id": "tokens", "modeId": "wpf", "number": 2, "name": "定令牌", "goal": "把选定风格固化为唯一取值来源(设计令牌)", "deliverables": [ { "name": "tokens.css", "path": "design/tokens.css", "description": "颜色/圆角/间距/字号/尺寸基准,每个值有语义化名字" }, { "name": "WPF 资源字典", "path": "design/tokens.xaml", "description": "ResourceDictionary 版本(SolidColorBrush/CornerRadius/Thickness)" } ], "exitCriteria": [ "每个值都有语义化名字", "后续任何文件不许出现魔法数字和手写色值" ], "dependencies": [ { "stageId": "explore", "deliverable": "选定风格方向", "hint": "若尚未选定视觉方向,先回阶段 1 完成风格探索" } ], "rules": [ "令牌与组件必须分文件(换皮只改令牌)", "名字描述用途而非长相(--color-danger 而非 --color-red)" ], "guidance": [ "把选定方向交给 AI,要求输出令牌文件", "要求按类别分组、每个变量带用途注释", "与用户逐组过一遍(色彩组/间距组/…)" ], "aiPromptTemplate": "(此处为可复制的提示词模板正文,见流程模型文档)", "pitfalls": [ "令牌数量过多或过少", "名字无语义", "与组件样式混在一个文件" ], "revisionImpact": [ "改 tokens.css → app.css 需核对引用", "所有 fig*.html 需复查视觉" ], "humanCheckpoint": "颜色/尺寸过目一遍,视觉方向确认无误", "capabilities": [], "environment": [] } ``` ### 3.3 模式差异(stageOverrides) 通用阶段内容在模式层可被覆盖:`tokens` 阶段的 `aiPromptTemplate`、`deliverables` 在 WPF 模式下带 XAML 术语与资源字典产物;Vue 模式则带 CSS 变量与 SFC 术语。覆盖策略:**字段级覆盖**(只写要改的字段,其余继承通用版)。 **数组合并语义**:覆盖是字段级浅合并——数组字段(如 `deliverables` / `rules` / `guidance` / `exitCriteria` 等)为**整体替换**而非逐项合并。模式覆盖中定义的数组将完全取代通用版同名字段,因此必须包含该字段的完整内容。 --- ## 4. 能力包(CapabilityPack) 工具链能力的分组单元。原型阶段唯一的包是 `design-toolkit`。 ```jsonc { "id": "design-toolkit", "name": "设计工具链", "description": "跨模式共享的设计工程脚本:体检与出图", "scripts": [ { "file": "check-layout.js", "purpose": "设计稿体检:溢出/越界/文字出框", "usage": "node check-layout.js ", "pass": "输出 vOverflow / hOverflow / textLeak 三类均为 []" }, { "file": "export-png.py", "purpose": "HTML → PNG 出图(无头浏览器截图)", "usage": "python export-png.py [fig1]", "pass": "PNG 生成且尺寸正确" } ], "requirements": [ /* 见 §5 */ ] } ``` **定位说明**:能力包是**跨模式共享**的(操作对象是 HTML 与浏览器,与目标框架无关);WPF 模式不是它的专属消费者。 --- ## 5. 环境要求(EnvRequirement) ```jsonc { "name": "Node.js", "minVersion": "22.4", "optional": false, "why": "check-layout.js 依赖全局 WebSocket(Node 22.4+ 默认可用)", "check": "node --version", "install": "https://nodejs.org 或 winget install OpenJS.NodeJS" } ``` | 字段 | 说明 | |---|---| | `name` / `minVersion` | 组件与最低版本 | | `optional` | 可选依赖缺失时只降级部分能力(如 Pillow 缺失只影响裁剪) | | `why` | 为什么需要——同时写给人和 AI 看 | | `check` | AI 执行的探测命令 | | `install` | AI 执行安装时的依据 | **行为约定**:阶段约束包返回时,`environment` 字段透传所引用能力包的环境要求;AI 负责检查、与用户确认、安装、复检(工具不执行任何系统操作)。 --- ## 6. 演进路线 | 阶段 | 存储方式 | 触发条件 | |---|---|---| | 现在(原型) | 硬编码 JS 数据模块 | — | | 后续 | JSON/YAML 外置加载 | 内容修改频繁到"改文案要动代码"成为负担时 | | 更远 | 数据与执行分离(MCP 只读数据) | 出现多消费者(页面端独立发布等)需求时 | **契约(本文件)在以上演进中保持不变**——它是接口,存储是实现。