原因: huashu-design 是纯设计 skill,加实施模式会导致人格冲突、 SKILL.md 膨胀、约束倒灌。design-handoff 已有 SPEC+截图+Token 映射, 直接在当前会话实施代码更自然。
245 lines
7.4 KiB
Markdown
245 lines
7.4 KiB
Markdown
---
|
||
name: design-handoff
|
||
description: 设计交付编排器 — 调用 huashu-design 设计原型、解析生成 SPEC,再由本 skill 根据 SPEC 实施代码,覆盖从需求到实现的完整流程
|
||
---
|
||
|
||
# 设计交付编排器 (design-handoff)
|
||
|
||
编排从需求到代码实现的完整流程:
|
||
1. 调用 huashu-design 设计 HTML 原型
|
||
2. 解析原型生成 SPEC.md + 截图 + Token 映射
|
||
3. 根据 SPEC 直接实施代码(不调用 huashu-design)
|
||
|
||
## 触发词
|
||
|
||
- `design-handoff`
|
||
- `设计交付`
|
||
- `handoff`
|
||
- `设计并实现`
|
||
- `从设计到代码`
|
||
|
||
---
|
||
|
||
## 输入模式
|
||
|
||
### 模式 A:从需求开始(完整流程)
|
||
|
||
用户提供功能需求描述(无 HTML 文件),skill 执行 7 步完整流程。
|
||
|
||
**输入示例:**
|
||
```
|
||
/design-handoff 患者端家庭档案管理页面,包含家庭成员列表、添加/编辑/删除操作
|
||
```
|
||
|
||
### 模式 B:从原型开始(仅解析+实施)
|
||
|
||
用户提供已有 HTML 原型文件路径,跳过 Step 0,从 Step 1 开始。
|
||
|
||
**输入示例:**
|
||
```
|
||
/design-handoff docs/design/mp-13-family-profile.html
|
||
```
|
||
|
||
---
|
||
|
||
## 核心流程(7 步)
|
||
|
||
### Step 0: 设计原型(仅模式 A)
|
||
|
||
调用 huashu-design 生成 HTML 原型:
|
||
|
||
```
|
||
Skill("huashu-design", "设计 {用户需求描述}。要求:1) 使用 HMS 设计系统 Token(const T = {...})2) 包含 IosFrame 设备框 3) 每个页面用 .screen-wrap 包裹 4) 输出到 docs/design/ 目录")
|
||
```
|
||
|
||
**关键要求传递给 huashu-design:**
|
||
- 使用项目 Token 系统(`const T = { pri: ..., bg: ..., r: ... }`)
|
||
- 每个页面/状态用 `.screen-wrap` 包裹并配中文 label
|
||
- 使用 `IosFrame` 组件呈现
|
||
- 输出为单文件 HTML,保存到 `docs/design/mp-{编号}-{名称}.html`
|
||
|
||
**完成后获得:** HTML 原型文件路径,进入 Step 1。
|
||
|
||
### Step 1: 解析 HTML 原型
|
||
|
||
调用 `scripts/parse-prototype.mjs` 解析 HTML 文件:
|
||
|
||
```bash
|
||
node .claude/skills/design-handoff/scripts/parse-prototype.mjs <html文件路径>
|
||
```
|
||
|
||
**输出(stdout JSON):**
|
||
- `tokens`: T 对象所有键值对(如 `{"T.pri": "#C4623A", ...}`)
|
||
- `inlineStyles`: 内联样式值收集(按 CSS 属性分组)
|
||
- `screens`: 每个屏幕的标签和组件名
|
||
- `components`: 所有组件函数定义列表
|
||
- `variant`: `"patient"` 或 `"doctor"`(根据 T.pri 值自动检测)
|
||
|
||
**若脚本不存在:** LLM 自行解析 HTML,提取 T 对象和 DOM 结构。
|
||
|
||
### Step 2: 截图
|
||
|
||
调用 `scripts/extract-screenshots.mjs` 生成截图:
|
||
|
||
```bash
|
||
node .claude/skills/design-handoff/scripts/extract-screenshots.mjs <html文件路径> <输出目录>
|
||
```
|
||
|
||
**输出:** PNG 文件到输出目录,文件名由中文标签自动翻译为英文。
|
||
|
||
**若脚本不存在:** 指导用户手动截图,保存到 `docs/design/{原型名}/screenshots/`。
|
||
|
||
### Step 3: Token 匹配
|
||
|
||
调用 `scripts/match-tokens.mjs` 进行三层 Token 匹配:
|
||
|
||
```bash
|
||
node .claude/skills/design-handoff/scripts/parse-prototype.mjs <html> > /tmp/parse-result.json
|
||
node .claude/skills/design-handoff/scripts/match-tokens.mjs /tmp/parse-result.json .design/tokens.yml
|
||
```
|
||
|
||
**三层匹配算法:**
|
||
1. **别名直查** — 在 `aliases.prototype_keys` 中查找已确认映射(支持值条件匹配,区分 patient/doctor variant)
|
||
2. **值精确匹配** — 按 CSS 属性上下文消歧(borderRadius→radius, fontSize→typography)
|
||
3. **色彩模糊匹配** — RGB 欧几里得距离 < 30 视为近似
|
||
|
||
**若脚本不存在:** LLM 自行读取 tokens.yml 执行匹配。
|
||
|
||
### Step 4: 组件映射推断
|
||
|
||
读取 `defaults/components.yml`,按 DOM 特征推断组件映射。
|
||
|
||
### Step 5: 交互推断
|
||
|
||
调用 `scripts/infer-interactions.mjs` 推断交互行为:
|
||
|
||
```bash
|
||
node .claude/skills/design-handoff/scripts/infer-interactions.mjs <html文件路径> .claude/skills/design-handoff/rules/interaction-rules.yml
|
||
```
|
||
|
||
### Step 6: 组装 SPEC.md
|
||
|
||
将前 5 步数据组装为 SPEC.md,输出到 `docs/design/{原型名}/SPEC.md`。
|
||
|
||
### Step 7: 实施代码
|
||
|
||
根据 Step 1-6 产出的 SPEC.md、截图和 Token 映射,**在当前会话中直接实施代码**。
|
||
|
||
**实施流程:**
|
||
|
||
1. **读取 SPEC.md** — 获取 Token 映射、组件清单、交互行为、未匹配项
|
||
2. **读取截图** — 对照截图确认视觉还原度
|
||
3. **创建/修改文件** — 在 `apps/miniprogram/src/pages/` 下实现 Taro 页面
|
||
4. **验证** — `pnpm build` 编译通过 + 长者模式适配
|
||
|
||
**实施规则:**
|
||
|
||
- 样式使用 `var(--tk-*)` CSS 变量,不硬编码数值
|
||
- 使用组件库已有组件(ContentCard, PrimaryButton, SectionTitle 等),参见 `defaults/components.yml`
|
||
- 交互行为按 SPEC.md 第 4 节实现
|
||
- 遵循 CLAUDE.md 中的小程序代码规范
|
||
- 长者模式:字号 ≥ 22px,间距按 elder 值
|
||
- 未匹配的 Token 需与用户确认后再补充到 `.design/tokens.yml`
|
||
- 新建组件时遵循 `feedback-component-consistency` 原则:不适配则新建,不外部覆盖
|
||
|
||
---
|
||
|
||
## 前置检查
|
||
|
||
执行任何步骤前,必须完成以下检查:
|
||
|
||
### 1. 输入验证
|
||
|
||
**模式 A(从需求开始):** 无需输入文件验证,直接进入 Step 0。
|
||
|
||
**模式 B(从原型开始):** 确认输入文件为 huashu-design 产物:
|
||
- 文件为 `.html` 格式
|
||
- 包含 React + Babel 的 script 标签
|
||
- 包含 Token 定义块(`const T = {`)
|
||
|
||
### 2. Token 配置文件初始化
|
||
|
||
检查 `.design/tokens.yml` 是否存在:
|
||
- **存在** → 直接使用
|
||
- **不存在** → 从 `defaults/tokens.yml` 复制
|
||
|
||
---
|
||
|
||
## 输出目录结构
|
||
|
||
```
|
||
docs/design/
|
||
mp-00-visitor.html # 原始原型(Step 0 产物或已有文件)
|
||
mp-00-visitor/ # 交付包目录
|
||
├── SPEC.md # 设计规格文档(Step 6 产物)
|
||
├── screenshots/ # 截图目录(Step 2 产物)
|
||
│ ├── home.png
|
||
│ └── profile.png
|
||
├── tokens.json # Token 匹配结果(Step 3 产物)
|
||
└── META.yml # 元数据
|
||
```
|
||
|
||
### META.yml 格式
|
||
|
||
```yaml
|
||
prototype: {原型文件名}
|
||
source: {HTML文件路径}
|
||
variant: patient | doctor
|
||
generated_at: {ISO 8601}
|
||
tokens:
|
||
matched: {数}
|
||
unmatched: {数}
|
||
components:
|
||
total: {数}
|
||
mapped: {数}
|
||
new: {数}
|
||
interactions: {数}
|
||
```
|
||
|
||
---
|
||
|
||
## 终端输出
|
||
|
||
完成全部步骤后:
|
||
|
||
```
|
||
============================================================
|
||
设计交付完成: {原型名}
|
||
输出目录: docs/design/{原型名}/
|
||
模式: {完整流程 | 仅解析}
|
||
Variant: {patient | doctor}
|
||
Token 匹配: {matched}/{total} ({unmatched} 未匹配)
|
||
组件: {total} ({new} 需新建)
|
||
交互: {数} 项
|
||
下一步: 根据 SPEC 实施代码(Step 7)
|
||
============================================================
|
||
```
|
||
|
||
---
|
||
|
||
## 待确认项交互
|
||
|
||
完成 Step 1-6 后,若有 `pending` 或 `unmatched` Token,需与用户交互确认后再进入 Step 7。
|
||
|
||
---
|
||
|
||
## 脚本说明
|
||
|
||
| 脚本 | 用途 |
|
||
|------|------|
|
||
| `scripts/parse-prototype.mjs` | 解析 HTML 原型为结构化 JSON |
|
||
| `scripts/extract-screenshots.mjs` | Playwright 截图(裁掉设备框) |
|
||
| `scripts/match-tokens.mjs` | 三层 Token 匹配 |
|
||
| `scripts/infer-interactions.mjs` | 交互行为推断 |
|
||
|
||
**降级策略:** 每个脚本缺失时,LLM 自行执行对应步骤。
|
||
|
||
## 模板与规则
|
||
|
||
| 文件 | 用途 |
|
||
|------|------|
|
||
| `templates/spec-template.md` | SPEC.md 模板 |
|
||
| `defaults/tokens.yml` | Token 注册表 + 别名映射 |
|
||
| `defaults/components.yml` | 组件映射规则 |
|
||
| `rules/interaction-rules.yml` | 交互推断规则 |
|