sync: 设计工具适配层重构 — _d8d/ 抽象接口 + Pencil CLI 适配器 #13

Merged
d8dfun merged 1 commits from sync/d8d-skills-20260409-063203 into master 2026-04-10 06:08:12 +08:00
11 changed files with 579 additions and 25 deletions

View File

@@ -62,6 +62,43 @@
- 关键字段
- 模型间关系
### 3.5 设计文件变更检测(⭐ 设计文件)
扫描项目根目录的设计文件变更。
**先加载适配层文档**
```
Read _d8d/design-tool-adapter/interface.md — 了解 detect 操作
Read _d8d/design-tool-adapter/adapters/pencil.md — 了解具体命令
```
**检测流程**
```
1. 调用 detect(项目根目录)
2. IF found:
a. 对每个设计文件,执行 git log --oneline -3 {file} 获取最近提交
b. 执行 git diff HEAD~1 -- {file} 检测是否有变更
c. 如果发现设计文件有未提交或最近的变更:
→ 标记 design_file_changed: true
→ 记录变更的文件名和变更摘要
d. 调用 extract_structure(设计文件) 获取页面名称列表
3. IF 未找到设计文件: design_file_changed: false
```
**输出写入 iterate-context.md**
```markdown
### 设计文件状态
| 文件 | 大小 | 最近修改 | 变更状态 |
|------|------|---------|---------|
| VividSpark1.2.pen | 988KB | 2026-04-09 | 🆕 新增 |
design_file_changed: true
design_pages: ["Dashboard", "Auth & Pricing", "Pricing Modal", "Publishing Dashboard"]
```
### 4. 技术栈识别
`package.json` 提取:
@@ -98,6 +135,13 @@
- Next.js 16 + App Router
- PostgreSQL 17 + Prisma
- shadcn/ui + Tailwind CSS
### 设计文件状态
| 文件 | 大小 | 最近修改 | 变更状态 |
|------|------|---------|---------|
| VividSpark1.2.pen | 988KB | 2026-04-09 | 🆕 新增 |
design_file_changed: true/false
```
## 判断规则
@@ -116,4 +160,13 @@ IF 有规划文档但无 pipeline-state:
→ 项目类型: planned (已规划未开发)
```
### 设计文件变更提示
```
IF design_file_changed == true:
→ 在 iterate-context.md 中添加提示:
"⚠️ 检测到设计文件有变更。如果用户描述涉及 UI 更新,
建议变更类型分类为 design并通过适配层重新提取设计变量。"
```
将项目类型写入 `iterate-checkpoint.md`

View File

@@ -126,7 +126,8 @@ regression:
→ Phase 5 only: d8d-dev --regression
design:
→ Phase 3: d8d-prototype --incremental
→ Phase 2.5: 设计工具适配层重新提取设计变量(⭐ 如 design_file_changed=true 则必须)
→ Phase 3: d8d-prototype --incremental使用最新设计截图作为基准
→ Phase 4: d8d-dev --story {affected-stories}
→ Phase 5: d8d-dev --regression (可选)
```

View File

@@ -27,6 +27,41 @@ IF NOT has_new_pages AND NOT has_doc_changes → 跳过 Phase 3
## 执行方式
### Step 3.0: 设计文件重新提取(⭐ 如 design_file_changed=true 则必须)
**当 Phase 0 检测到设计文件变更design_file_changed=true必须先更新设计上下文。**
**先加载适配层文档**
```
Read _d8d/design-tool-adapter/interface.md
Read _d8d/design-tool-adapter/adapters/pencil.md
```
```
IF design_file_changed == true:
1. 调用适配层操作重新提取设计文件:
a. extract_structure(设计文件) → 获取最新页面结构
b. extract_tokens(设计文件) → 获取最新设计 Token
2. 更新 UX 设计文档:
- 读取 _bmad-output/planning-artifacts/ux-design-specification.md
- 用新提取的 Token 更新色彩、字体、间距等定义
- 保留文档中的非设计系统内容(交互规范、页面流程等)
- 如果页面结构有变化,更新页面列表
3. 导出设计页面截图:
- 调用 export_screenshots(设计文件, prototype/.pen-references/)
4. 在 iterate-progress.md 记录:
design_re_extracted: true
design_file: "{变更的设计文件}"
updated_tokens: [列出更新的 Token 类别]
ELSE:
跳过此步骤
```
### Step 3.1: 检测原型状态
读取 `prototype/.prototype-state.md` 判断状态:
@@ -116,5 +151,7 @@ phase-03-prototype:
mode: full | [D] | [P] | [A] | first-time
pages_updated: [...] # 更新/新增的页面列表
docs_updated: true | false # 文档中心是否更新
pen_re_extracted: true | false # 设计变量是否通过适配层重新提取
pen_fidelity_score: "85%" # 设计保真度评分(如适用)
reason: "..." # 如果跳过了
```

View File

@@ -8,7 +8,7 @@
## 执行序列
### 1.1 检查可复用的现有素材
### 1.1 检查可复用的现有素材 + .pen 设计文件提取
在开始生成之前,**先检查项目中是否有客户/设计师提供的现有页面或设计素材**
@@ -21,25 +21,78 @@
- 提取现有页面的设计 token颜色、字体、间距作为新页面的基础
- 确保复用页面与新页面的设计风格一致
#### 1.1.1 设计文件检测与提取(⭐ 高保真关键步骤)
如果项目根目录存在设计文件(如 `*.pen`**必须**通过设计工具适配层提取精确设计信息,作为原型生成的视觉基准。
**先加载适配层文档**
```
Read _d8d/design-tool-adapter/interface.md — 了解可用操作
Read _d8d/design-tool-adapter/adapters/pencil.md — 了解具体命令(如使用 Pencil
```
**执行流程**
```
1. 调用 detect(项目根目录)
2. IF found:
a. 调用 extract_structure(设计文件) → 获取页面名称和组件层级
b. 调用 extract_tokens(设计文件) → 获取精确的颜色、字体、间距 Token
c. 调用 export_screenshots(设计文件, prototype/.pen-references/) → 导出页面截图
3. IF 未找到设计文件: 跳过此步骤
```
**提取内容写入状态文件**
```yaml
design_file:
tool: "pencil"
file: "VividSpark1.2.pen"
pages:
- name: "Dashboard"
id: "2dEtF"
screenshot: ".pen-references/dashboard.png"
- name: "Auth & Pricing"
id: "Er7uX"
screenshot: ".pen-references/auth-pricing.png"
variables:
colors: { background: "#0a0a0f", foreground: "#ffffff", ... }
fonts: { family: "Inter", sizes: [...] }
spacing: { unit: "4px", scale: [...] }
```
**为什么这一步至关重要**
- 设计文件包含精确的像素级设计信息(间距、圆角、阴影)
- 仅靠 UX 文档的文字描述无法还原这些细节
- 导出的截图作为 step-02 生成 HTML 时的视觉参考
- step-07 验证时用于对比原型与原始设计的保真度
### 1.2 读取项目设计系统(⚠️ 最高优先级)
**必须先读取项目的设计系统文档,项目设计系统优先级高于一切默认值。**
#### 设计系统发现顺序(按优先级)
1. **项目 UX 设计文**(最高优先级)
1. **设计文**(最高优先级,精确值
- 通过 1.1.1 步骤 detect() 检测到的设计文件
- 提取的精确 Token 和截图
- **如果存在,设计 Token 必须以设计文件提取值为准**
- UX 文档和设计文件 Token 冲突时,以设计文件为准
2. **项目 UX 设计文档**
- 路径: `_bmad-output/planning-artifacts/*ux*.md``docs/*ux*.md`
- 提取: CSS 变量、色彩系统、字体系统、组件样式、页面布局规范
- 如果存在,**必须使用其中定义的所有设计 Token**
- 如果存在,**必须使用其中定义的所有设计 Token**.pen 不存在的部分)
2. **项目 CLAUDE.md 中的设计规范**
3. **项目 CLAUDE.md 中的设计规范**
- 查找 CLAUDE.md 中的"设计风格"、"色彩规范"等章节
3. **DESIGN.md 或类似设计系统文件**
4. **DESIGN.md 或类似设计系统文件**
- 路径: `DESIGN.md``docs/DESIGN.md``design-system.md`
4. **references/design-patterns.md**(兜底默认值)
- 仅在前者均不存在时使用
5. **references/design-patterns.md**(兜底默认值)
- 仅在前者均不存在时使用
- 使用时需告知用户:"未找到项目设计系统文档,使用默认配色方案"
#### Token 提取清单
@@ -120,8 +173,10 @@ prototype-v2/screenshots/
- [ ] 方案文档已读取和分析
- [ ] 设计系统已提取(或确认使用默认值)
- [ ] 设计文件已检测和提取(如存在,通过适配层)
- [ ] 设计文件页面截图已导出到 prototype/.pen-references/(如存在)
- [ ] 页面清单已生成(前台+后台)
- [ ] 状态文件已写入页面清单
- [ ] 状态文件已写入页面清单(含 pen_design 部分,如适用)
- [ ] 状态文件 current_step 已更新为 step-02
**完成后,加载 `steps/step-02-generate-pages.md` 继续执行。**

View File

@@ -150,6 +150,46 @@ actual_image_source: prototype/screenshots/actual.png
prompt: 对比参考设计与实际实现指出差异和问题
```
### 7.5.1 设计保真度验证(⭐ 如有设计文件则强制执行)
**当 step-01 在状态文件中生成了 `design_file` 部分时,本步骤不可跳过。**
**先加载适配层文档**
```
Read _d8d/design-tool-adapter/interface.md — 了解 compare_visuals 操作
Read _d8d/design-tool-adapter/adapters/pencil.md — 了解具体命令
```
**目标**:将生成的原型页面截图与设计文件导出的原始截图进行对比,检测保真度差距。
**执行流程**
```
1. 读取 .prototype-state.md 中的 design_file 部分
2. IF design_file 存在:
a. 对 design_file.pages 中的每个页面:
- 找到对应的原型截图prototype/screenshots/
- 读取设计文件参考截图prototype/.pen-references/ 或等效目录)
- 调用 compare_visuals(设计截图, 原型截图)
b. 汇总所有页面的对比结果
3. IF 发现 🔴 关键差异:
→ 输出修复建议(精确到 CSS 属性级别)
→ 建议重新生成该页面的 HTML
4. 记录到验证报告的「设计保真度」部分
```
**差异分类标准**
| 级别 | 描述 | 示例 | 处理 |
|------|------|------|------|
| 🔴 关键 | 布局结构不一致 | 导航栏位置错误、缺少侧边栏 | 必须修复 |
| 🟡 中等 | 视觉明显不同但不影响功能 | 配色偏差、间距不一致 | 建议修复 |
| 🟢 次要 | 细微差别 | 字号差 1px、阴影深度微差 | 可接受 |
### 7.6 验证检查清单
#### 链接验证
@@ -192,6 +232,13 @@ prompt: 对比参考设计与实际实现,指出差异和问题
- [ ] 交互流程正确
- [ ] 与需求文档描述一致
#### 设计保真度验证 ⭐(如有设计文件则强制)
- [ ] 设计文件参考截图已加载
- [ ] 每个原型页面已与对应设计页面对比
- [ ] 关键差异(🔴)已记录并修复
- [ ] 中等差异(🟡)已记录并有处理决定
- [ ] 保真度评分已记录0-100%
### 7.7 生成验证报告
```markdown
@@ -233,6 +280,16 @@ prompt: 对比参考设计与实际实现,指出差异和问题
## 问题列表
1. [问题描述] → [改进建议]
## 设计保真度 ⭐(如有设计文件)
### 保真度总评: X%
| 页面 | 设计文件截图 | 原型截图 | 保真度 | 🔴 关键 | 🟡 中等 | 🟢 次要 |
|------|------------|---------|--------|--------|--------|--------|
| Dashboard | .pen-references/dashboard.png | screenshots/dashboard.png | 85% | 0 | 2 | 3 |
| Login | .pen-references/auth.png | screenshots/login.png | 92% | 0 | 1 | 2 |
### 关键差异修复建议
1. [差异描述] → [具体 CSS/HTML 修复建议]
```
### 7.8 最终状态更新
@@ -245,6 +302,7 @@ prompt: 对比参考设计与实际实现,指出差异和问题
- [ ] 所有页面已截图
- [ ] **所有文档内容已验证加载成功**
- [ ] 设计保真度验证完成(如适用,含截图对比)
- [ ] 链接验证通过
- [ ] 平铺布局验证通过
- [ ] 样式分析完成

View File

@@ -25,11 +25,12 @@
## 3. 设计文件检测
1. Glob 项目根目录 `*.pen`
**先加载适配层**`Read _d8d/design-tool-adapter/interface.md``adapters/pencil.md`
1. 调用 `detect(项目根目录)` 检测设计文件
2. 如果找到:
- 使`mcp__pencil__snapshot_layout` 读取顶层结构maxDepth=0
- 使`mcp__pencil__batch_get` 提取页面名称readDepth=0
- 使用 `mcp__pencil__get_variables` 提取设计系统变量
- `extract_structure(设计文件)` 提取页面名称和组件层级
- `extract_tokens(设计文件)` 提取设计系统变量
- 构建设计上下文摘要
3. 如果未找到:记录 `design_file: null`

View File

@@ -147,9 +147,9 @@ Glob {planning_artifacts}/*ux*.md
2. 产品简报(完整内容)
3. 设计文件详细上下文(从 pipeline-context.md 获取设计系统变量、页面布局)
如果 .pen 文件存在,额外提取
- 使`mcp__pencil__get_variables` 获取设计 token
- 使`mcp__pencil__batch_get` 获取关键页面的布局结构
如果设计文件存在(从 pipeline-context.md 检测),通过适配层额外提取(参见 `_d8d/design-tool-adapter/`
- `extract_tokens(设计文件)` 获取设计 token
- `extract_structure(设计文件)` 获取关键页面的布局结构
### 2.3.3 调用子技能

View File

@@ -231,11 +231,10 @@ phases:
### Scanning (phase-00)
```
1. Glob 项目根目录 *.pen
2. 如找到:使mcp__pencil__snapshot_layout 读取顶层结构
3. 使mcp__pencil__batch_get 提取页面名称和组件层级
4. 使用 mcp__pencil__get_variables 提取设计系统变量
5. 存储摘要到 pipeline-context.md
1. 调用 detect(项目根目录) 检测设计文件(参见 _d8d/design-tool-adapter/
2. 如找到:extract_structure() 提取页面结构和组件层级
3. extract_tokens() 提取设计系统变量
4. 存储摘要到 pipeline-context.md
```
### Context Per Sub-Skill

View File

@@ -7,7 +7,9 @@ description: '将项目中 .claude/skills/ 下所有 d8d-* 技能目录d8d-de
将项目 `.claude/skills/` 下所有 `d8d-*` 目录与 `https://gitea.d8d.fun/d8dfun/bmad-method-template` 双向同步。
同步范围:所有匹配 `d8d-*/` 的技能目录(包括 d8d-dev、d8d-requirements、d8d-prototype、d8d-skills-sync 自身等)
同步范围:
1. 所有匹配 `d8d-*/` 的技能目录(包括 d8d-dev、d8d-requirements、d8d-prototype、d8d-skills-sync 自身等)
2. `_d8d/` 共享资源目录(设计工具适配层等)
## 配置
@@ -15,7 +17,7 @@ description: '将项目中 .claude/skills/ 下所有 d8d-* 技能目录d8d-de
TEMPLATE_REPO_URL: https://gitea.d8d.fun/d8dfun/bmad-method-template.git
TEMPLATE_REPO_API: https://gitea.d8d.fun/api/v1/repos/d8dfun/bmad-method-template
LOCAL_CLONE_PATH: /tmp/bmad-method-template
SYNC_PATTERNS: .claude/skills/d8d-*/
SYNC_PATTERNS: .claude/skills/d8d-*/ _d8d/
```
Gitea 认证信息从项目 git remote URL 提取oauth2 token 在 remote URL 中)。
@@ -49,6 +51,13 @@ for skill_dir in $PROJECT_ROOT/.claude/skills/d8d-*/; do
fi
done
# _d8d 共享资源目录差异
if [ -d $PROJECT_ROOT/_d8d ] && [ -d /tmp/bmad-method-template/_d8d ]; then
diff -rq $PROJECT_ROOT/_d8d/ /tmp/bmad-method-template/_d8d/ 2>/dev/null || true
elif [ -d $PROJECT_ROOT/_d8d ]; then
echo " NEW in project: _d8d/"
fi
echo "=== B) 模板有而项目无(需先拉到项目)==="
for skill_dir in /tmp/bmad-method-template/.claude/skills/d8d-*/; do
skill=$(basename $skill_dir)
@@ -58,6 +67,11 @@ for skill_dir in /tmp/bmad-method-template/.claude/skills/d8d-*/; do
echo " NEW in template: $skill/"
fi
done
# _d8d 模板独有
if [ -d /tmp/bmad-method-template/_d8d ] && [ ! -d $PROJECT_ROOT/_d8d ]; then
echo " NEW in template: _d8d/"
fi
```
如果 A 和 B 都为空 → 告知用户"已是最新,无需同步"。
@@ -81,7 +95,7 @@ done
3. 拉取完成后提交:
```bash
git add .claude/skills/d8d-*/ && git commit -m "chore(skill): 从模板拉取更新 — {摘要}"
git add .claude/skills/d8d-*/ _d8d/ _d8d/ && git commit -m "chore(skill): 从模板拉取更新 — {摘要}"
git push
```
@@ -99,12 +113,18 @@ for skill_dir in $PROJECT_ROOT/.claude/skills/d8d-*/; do
mkdir -p .claude/skills/$skill/
cp -r $skill_dir* .claude/skills/$skill/
done
# 同步 _d8d 共享资源目录
if [ -d $PROJECT_ROOT/_d8d ]; then
mkdir -p _d8d/
cp -r $PROJECT_ROOT/_d8d/* _d8d/
fi
```
### Step 4: 提交
```bash
git add .claude/skills/d8d-*/
git add .claude/skills/d8d-*/ _d8d/
git diff --cached --stat # 确认只有项目独有的变更
git commit -m "sync: {简要描述变更内容}"
```

View File

@@ -0,0 +1,167 @@
# Pencil CLI 适配器
> 实现 `_d8d/design-tool-adapter/interface.md` 定义的 5 个操作。
> **环境要求**`pencil` CLI 已安装(`npm install -g @pencil.dev/cli`),无桌面环境依赖。
## 前置检查
```bash
pencil --version # 确认 >= 0.2.4
pencil status # 确认已认证
```
## 操作实现
### 1. detect(root_dir)
```bash
find {root_dir} -maxdepth 1 -name "*.pen" -type f
```
对找到的每个 .pen 文件,获取文件信息:
```bash
stat --format="%s %y" {file}.pen
```
返回:
```yaml
found: true
files:
- path: "{root_dir}/VividSpark1.2.pen"
size: "988KB"
modified: "2026-04-09"
tool_type: "pencil"
```
### 2. extract_structure(file)
使用 `pencil interactive` 模式提取结构:
```bash
pencil interactive --in {file}.pen <<'EOF'
snapshot_layout({"maxDepth": 1})
EOF
```
再提取页面详情:
```bash
pencil interactive --in {file}.pen <<'EOF'
batch_get({"readDepth": 0})
EOF
```
**解析输出**:从 JSON 输出中提取:
- 顶层 frame 节点作为页面(`type: "frame"`, 无父节点)
- 可复用组件列表(`reusable_components` 数组)
返回:
```yaml
pages:
- id: "{node_id}"
name: "{node_name}"
type: "frame"
components:
- name: "{component_name}"
instances: {count}
```
**注意**interactive 模式的输出可能很大(几百 KB建议保存到文件后分段读取
```bash
pencil interactive --in {file}.pen <<'EOF' > /tmp/pencil-structure.json
snapshot_layout({"maxDepth": 1})
EOF
```
### 3. extract_tokens(file)
```bash
pencil interactive --in {file}.pen <<'EOF' > /tmp/pencil-tokens.json
get_variables({})
EOF
```
**解析输出**:从 `get_variables` 返回的 JSON 中提取:
- `$--background`, `$--foreground`, `$--primary` 等颜色变量
- 字体 family 和 size
- 其他 CSS 变量
**注意变量引用格式**.pen 文件中变量用 `$--name` 格式,但有些文件可能有转义问题(`\\$--name`)。解析时需要处理两种格式。
返回格式见 `interface.md` extract_tokens 部分。
### 4. export_screenshots(file, output_dir, pages)
**导出全部页面**
```bash
pencil --in {file}.pen --out {output_dir}/full-export.png
```
**导出特定页面**(使用 interactive 模式的 export_nodes
```bash
pencil interactive --in {file}.pen <<'EOF'
export_nodes({"nodeIds": ["page_id_1", "page_id_2"], "format": "png", "outputDir": "{output_dir}"})
EOF
```
或逐页面导出:
```bash
pencil --in {file}.pen --out {output_dir}/dashboard.png --node-id 2dEtF
```
**确保输出目录存在**
```bash
mkdir -p {output_dir}
```
返回:
```yaml
screenshots:
- page_id: "{id}"
page_name: "{name}"
path: "{output_dir}/{name}.png"
```
### 5. compare_visuals(img_a, img_b)
使用 ZAI MCP 的 ui_diff_check 工具(非 Pencil MCP在服务器上可用
```
mcp__zai-mcp-server__ui_diff_check
expected_image_source: {img_a}
actual_image_source: {img_b}
prompt: "严格对比原始设计与实现。重点检查:
1. 布局结构(导航栏、侧边栏、内容区域位置)
2. 配色方案(背景色、文字色、强调色)
3. 组件间距和比例
4. 字体大小和粗细
5. 圆角、阴影等细节
按严重程度分类:🔴 critical / 🟡 moderate / 🟢 minor"
```
解析 MCP 返回结果,映射到接口格式:
```yaml
score: "85%"
differences:
- level: "critical" | "moderate" | "minor"
category: "layout" | "color" | "spacing" | "typography" | "component"
description: "{从 MCP 结果中提取}"
suggestion: "{从 MCP 结果中提取}"
```
## 已知问题
1. **大文件处理**`get_editor_state` 输出可达 638KB+,必须保存到文件后分段读取
2. **变量转义**:部分 .pen 文件变量引用使用 `\\$--name` 而非 `$--name`,解析时需兼容
3. **interactive 模式输入**:需要通过 heredoc 或管道传入 JSON 命令
4. **导出限制**CLI 导出可能不支持所有节点类型fallback 到全页面导出

View File

@@ -0,0 +1,163 @@
# 设计工具适配层 — 接口定义
> 本文件定义设计工具的抽象接口。具体实现见 `adapters/{tool}.md`。
> 当前可用适配器:`pencil.md`Pencil CLI
## 前置条件
使用前需确认目标工具已安装且可用:
```
pencil --version # 或其他工具的版本命令
```
## 操作接口
### 1. detect(root_dir)
**用途**:检测项目根目录中是否存在设计文件。
| 参数 | 类型 | 说明 |
|------|------|------|
| root_dir | string | 项目根目录绝对路径 |
**返回**
```yaml
found: true | false
files:
- path: "VividSpark1.2.pen"
size: "988KB"
modified: "2026-04-09"
tool_type: "pencil" | "figma" | null
```
### 2. extract_structure(file)
**用途**:提取设计文件的页面结构和组件层级。
| 参数 | 类型 | 说明 |
|------|------|------|
| file | string | 设计文件绝对路径 |
**返回**
```yaml
pages:
- id: "2dEtF"
name: "Dashboard"
type: "frame"
- id: "Er7uX"
name: "Auth & Pricing"
type: "frame"
components:
- name: "Button"
instances: 12
- name: "Card"
instances: 8
```
### 3. extract_tokens(file)
**用途**提取设计文件的样式变量Token
| 参数 | 类型 | 说明 |
|------|------|------|
| file | string | 设计文件绝对路径 |
**返回**
```yaml
colors:
background: "#0a0a0f"
foreground: "#ffffff"
primary: "#ff6b2b"
card: "#141420"
border: "#2a2a3a"
muted_foreground: "#8888a0"
fonts:
family: "Inter"
sizes: [12, 14, 16, 18, 20, 24, 32, 48]
weights: [400, 500, 600, 700]
spacing:
unit: "4"
scale: [4, 8, 12, 16, 20, 24, 32, 48, 64]
radii:
sm: "4"
md: "8"
lg: "12"
xl: "16"
full: "9999"
shadows:
sm: "0 1px 2px rgba(0,0,0,0.3)"
md: "0 4px 8px rgba(0,0,0,0.4)"
lg: "0 8px 16px rgba(0,0,0,0.5)"
```
### 4. export_screenshots(file, output_dir, pages)
**用途**:导出设计文件中指定页面的截图。
| 参数 | 类型 | 说明 |
|------|------|------|
| file | string | 设计文件绝对路径 |
| output_dir | string | 截图输出目录 |
| pages | string[] | 可选,指定导出的页面 ID。为空则导出所有顶层页面 |
**返回**
```yaml
screenshots:
- page_id: "2dEtF"
page_name: "Dashboard"
path: "{output_dir}/dashboard.png"
width: 1440
height: 900
- page_id: "Er7uX"
page_name: "Auth & Pricing"
path: "{output_dir}/auth-pricing.png"
```
### 5. compare_visuals(img_a, img_b)
**用途**:对比两张截图的视觉差异。
| 参数 | 类型 | 说明 |
|------|------|------|
| img_a | string | 参考截图路径(设计文件导出) |
| img_b | string | 实际截图路径(原型或实现) |
**返回**
```yaml
score: "85%"
differences:
- level: "critical" | "moderate" | "minor"
category: "layout" | "color" | "spacing" | "typography" | "component"
description: "导航栏位置不一致"
suggestion: "调整导航栏为固定顶部"
```
## 使用模式
在 d8d 技能步骤文件中引用本接口:
```markdown
#### 设计文件操作
加载 `_d8d/design-tool-adapter/interface.md` 了解可用操作。
加载 `_d8d/design-tool-adapter/adapters/pencil.md` 了解具体命令。
1. 调用 detect(项目根目录) 检测设计文件
2. IF found: 调用 extract_structure() + extract_tokens() 提取设计信息
3. 调用 export_screenshots() 导出页面截图
4. 调用 compare_visuals() 对比设计 vs 实现
```
## 适配器实现指南
新增适配器(如 Figma只需在 `adapters/` 下创建 `{tool}.md`,实现上述 5 个操作。每个操作需包含:
- 具体的命令或 API 调用
- 输入参数映射
- 输出格式转换(需匹配本接口定义的返回格式)
- 环境要求和前置条件