dx-figma-verify
Compare a generated prototype with the Figma reference screenshot in a browser, fix gaps, write a report. Use after /dx-figma-prototype. Not for components on AEM (aem-fe-verify) or pre-PR checks (dx-step-verify).
- License 许可
- MIT
- 最近更新
- 2026-11-11
- Stars
- ★ 7
- Forks
- 3
01 前言 Front Matter
- name
- dx-figma-verify
- metadata
- { "version": "2.28.0", "category": "design-to-code", "mcp-server": "playwright" }
- description
- Compare a generated prototype with the Figma reference screenshot in a browser, fix gaps, write a report. Use after /dx-figma-prototype. Not for components on AEM (aem-fe-verify) or pre-PR checks (dx-step-verify).
- allowed-tools
- [ "read", "edit", "search", "write", "agent", "figma/*", "playwright/*" ]
- argument-hint
- <ADO Work Item ID (optional — uses most recent if omitted)>
- compatibility
- Requires Playwright MCP (playwright) and a generated prototype from /dx-figma-prototype with figma-reference.png from /dx-figma-extract.
02 资源文件 1
- 参考文档references/acceptance-checklist.md2.4 KB
03 SKILL.md 正文
You visually verify a generated HTML/CSS prototype against the original Figma design screenshot. You open the prototype in Chrome, take a screenshot, compare both images side by side using multimodal vision, and fix any visual gaps — up to 2 iterations.
Use ultrathink for visual comparison — identifying layout, spacing, and color differences between two screenshots requires careful analysis.
1. Locate the Spec Directory
SPEC_DIR=$(bash .ai/lib/dx-common.sh find-spec-dir $ARGUMENTS)
If the script exits with error, ask the user for the work item ID.
2. Check Prerequisites
Verify required files exist:
$SPEC_DIR/prototype/index.html— if missing: printprototype/index.html not found — run /dx-figma-prototype firstand STOP.- Read
$SPEC_DIR/figma-extract.md— extract the node name, Figma URL, and Viewports field for the report header.
Detect viewport mode:
- Check the
**Viewports:**field infigma-extract.md - If
singleor field absent → single-viewport mode. Requireprototype/figma-reference.png. - If multi-viewport (e.g.,
2 — desktop (1440px), mobile (375px)) → multi-viewport mode. Requireprototype/figma-reference-desktop.png(and any other listed viewport files). Also acceptfigma-reference.pngas fallback for desktop.
Set verify_viewports list:
- Single:
[{ name: "default", reference: "figma-reference.png" }] - Multi:
[{ name: "desktop", reference: "figma-reference-desktop.png", width: 1440 }, { name: "mobile", reference: "figma-reference-mobile.png", width: 375 }](parsed from figma-extract.md)
Run Steps 3–7 once per viewport. For multi-viewport, iterate through each viewport sequentially — resize Chrome, screenshot, compare, fix. Aggregate all gaps into a single figma-gaps.md.
3. Match Viewport to Figma Reference Size
The prototype screenshot MUST match the Figma reference width exactly — otherwise the visual comparison is meaningless (e.g., 390px mobile design vs 1000px desktop screenshot).
Step 3a. Get the Figma reference image dimensions. Use one of these methods:
-
From figma-extract.md — check for explicit width in the
**Viewports:**field (e.g.,mobile (375px),desktop (1440px)). This is the most reliable source. -
Via bash — read image dimensions directly:
file <absolute-path-to-figma-reference.png>This outputs dimensions like
PNG image data, 390 x 844. Parse the width. -
Via browser_evaluate — load the image in a blank page (before navigating to prototype):
mcp__plugin_dx-aem_playwright__browser_navigate url: "about:blank"mcp__plugin_dx-aem_playwright__browser_evaluate expression: | (() => { return new Promise((resolve) => { const img = new Image(); img.onload = () => resolve({ width: img.naturalWidth, height: img.naturalHeight }); img.onerror = () => resolve({ error: 'failed to load image' }); img.src = 'file://<absolute-path-to-figma-reference.png>'; }); })()
If none of these methods return a width, fall back to 1440x900.
Step 3b. Resize Chrome to match the Figma reference width:
mcp__plugin_dx-aem_playwright__browser_resize
width: <figma-reference-width>
height: <figma-reference-height or 900>
Step 3c. Verify the resize took effect:
mcp__plugin_dx-aem_playwright__browser_evaluate
expression: "(() => ({ width: window.innerWidth, height: window.innerHeight }))()"
If window.innerWidth does not match the target width, retry the resize once. If still wrong, log a warning: ⚠️ Chrome viewport is <actual>px, expected <target>px. Screenshot may not match Figma reference dimensions.
CRITICAL: This resize MUST happen BEFORE navigating to the prototype (Step 4). The prototype screenshot must be taken at the same width as the Figma reference. A 390px Figma mobile design compared against a 1000px screenshot will produce false gaps everywhere.
4. Open Prototype in Chrome
Navigate to the prototype HTML file:
mcp__plugin_dx-aem_playwright__browser_navigate
url: "file://<absolute-path-to-SPEC_DIR>/prototype/index.html"
Wait for the page to load:
mcp__plugin_dx-aem_playwright__browser_wait_for
text: "</html>"
timeout: 10000
If the prototype has a side-by-side comparison container (Figma reference panel), hide it so only the component renders:
mcp__plugin_dx-aem_playwright__browser_evaluate
expression: |
(() => {
// Hide any Figma reference comparison panel
const panels = document.querySelectorAll('[class*="reference"], [class*="comparison"], [class*="figma-ref"], [class*="side-by-side"]');
panels.forEach(el => el.style.display = 'none');
// Also hide any img pointing to figma-reference
document.querySelectorAll('img[src*="figma-reference"]').forEach(el => el.style.display = 'none');
return { hiddenPanels: panels.length };
})()
5. Take Prototype Screenshot
mcp__plugin_dx-aem_playwright__browser_take_screenshot
Save the screenshot with viewport-aware naming:
- Single viewport:
$SPEC_DIR/prototype/prototype-screenshot.png - Multi-viewport:
$SPEC_DIR/prototype/prototype-screenshot-<viewport.name>.png(e.g.,prototype-screenshot-desktop.png,prototype-screenshot-mobile.png)
If Playwright returns the screenshot as a displayed image rather than a file path, note the output for visual comparison in the next step.
6. Visual Comparison
Read both images and compare them:
- Read the Figma reference for this viewport (
figma-reference.pngorfigma-reference-<viewport.name>.png) - Read the prototype screenshot for this viewport (
prototype-screenshot.pngorprototype-screenshot-<viewport.name>.png)
Compare across these categories:
| Category | What to check |
|---|---|
| Layout | Flex/grid direction, alignment, element ordering, overall structure |
| Typography | Font sizes, weights, line heights, text alignment, letter spacing |
| Colors | Background colors, text colors, border colors, accent colors |
| Spacing | Margins, paddings, gaps between elements |
| Missing elements | Buttons, icons, dividers, labels, images present in Figma but absent in prototype |
| Extra elements | Anything in prototype not in the Figma design |
≈ Tolerance: If figma-extract.md contains a ## Dynamic Content Elements table, read it before comparing. Properties marked ≈ in the extract are content-dependent — allow reasonable deviation for these (e.g., ≈32px padding could be 28-36px without being flagged). Only flag ≈ values as gaps if the deviation is clearly wrong (>30% off or visually broken).
For each gap found, record:
- Category (from table above)
- Description of the difference
- Severity:
major(structural/layout wrong, missing element) orminor(spacing off, color slightly different) - Whether the property is ≈ (content-dependent) — if so, note the tolerance
If no gaps found: Skip to Step 8.
7. Fix Loop (max 2 iterations)
For each iteration:
7a. Apply Fixes
Edit the prototype files directly based on the gaps found:
- CSS fixes (colors, spacing, typography, sizing): Edit
prototype/styles.css - HTML fixes (missing elements, wrong structure, extra elements): Edit
prototype/index.html - JS fixes (interactive behavior): Edit
prototype/script.jsif it exists
Make targeted, surgical edits — do not regenerate the entire file. Fix one gap at a time.
7b. Re-screenshot
Reload the page in Chrome:
mcp__plugin_dx-aem_playwright__browser_navigate
url: "file://<absolute-path-to-SPEC_DIR>/prototype/index.html"
Hide the comparison panel again (Step 4 script), then take a new screenshot. Overwrite prototype-screenshot.png.
7c. Re-compare
Read the new screenshot and compare again against the Figma reference for this viewport. Update the gap list:
- Mark fixed gaps as
fixed - Note any remaining gaps
- Note any new gaps introduced by fixes
7d. Loop Control
- If all gaps are fixed or only minor gaps remain → break
- If iteration count reaches 2 → break (diminishing returns)
- Otherwise → continue to next iteration
8. Write figma-gaps.md
After all viewports have been verified, write a single $SPEC_DIR/figma-gaps.md.
Read .ai/templates/spec/figma-gaps.md.template and follow that structure exactly. The template uses HTML comments as authoring instructions — follow them but do not include them in the output. Key rules:
- Overall result is the worst result across all viewports (e.g., desktop PASS + mobile NEEDS ATTENTION → overall NEEDS ATTENTION)
- Include one per-viewport section for each verified viewport (or one "Default" section for single-viewport)
- Visual Acceptance Checklist is mandatory — generate binary pass/fail assertions per viewport with concrete values (hex colors, pixel sizes). See
references/acceptance-checklist.mdfor assertion format rules. - Mark
[x]for assertions verified during comparison,[ ]for unverified or manual-check items - Use ≈ prefix for assertions about content-dependent properties (from figma-extract.md's Dynamic Content Elements table)
9. Present Summary
## Prototype verification complete
**Result:** <PASS | PASS WITH MINOR GAPS | NEEDS ATTENTION>
**Viewports:** <list with per-viewport results, e.g. "desktop: PASS, mobile: PASS WITH MINOR GAPS">
- Gaps found: <total count>
- Fixed: <count> in <N> iterations
- Remaining: <count> (<severity breakdown>)
- Acceptance checklist: <count> assertions (<count> verified, <count> to check manually)
- Report: figma-gaps.md
<if PASS>
### Prototype matches Figma reference. Ready for `/dx-plan`.
</if>
<if PASS WITH MINOR GAPS>
### Minor differences remain — acceptable for implementation. Ready for `/dx-plan`.
</if>
<if NEEDS ATTENTION>
### Major gaps remain after 2 fix rounds. Review figma-gaps.md and consider re-running `/dx-figma-prototype`.
</if>
Result Classification
| Result | Criteria |
|---|---|
| PASS | 0 remaining gaps |
| PASS WITH MINOR GAPS | Only minor remaining gaps (no major) |
| NEEDS ATTENTION | 1+ major remaining gaps after max iterations |
Error Handling
- Playwright MCP not available: Print
⚠️ Playwright MCP not available — cannot verify prototype visually. Ensure the playwright server is enabled and Chromium is installed (npx playwright install chromium).and STOP. - File URL blocked by Chrome: Some Chrome configs block
file://URLs. Print instructions:Try: open -a "Google Chrome" --args --allow-file-access-from-filesand retry. - Screenshot fails: Continue with whatever was captured. If no screenshot at all, fall back to structural HTML comparison (read the HTML source and compare element structure against figma-extract.md).
- Resize fails: Proceed with default viewport. Note the mismatch in the report.
Rules
- Real screenshots only — always use Playwright, never "mentally compare"
- Match viewport — resize Chrome to Figma reference dimensions before screenshotting
- Surgical fixes — edit specific CSS properties/HTML elements, don't regenerate files
- 2 iterations max — stop after 2 fix rounds regardless of remaining gaps
- Separate images — compare prototype screenshot vs Figma reference as two independent images
- Classify severity — major (structural) vs minor (cosmetic) determines the result
- Idempotent — re-running overwrites prototype-screenshot.png and figma-gaps.md
04 同仓库更多 Skills
dx-hub-status
Show hub dispatch status — which repos are running, done, blocked or failed. Use for 'hub status', 'what's running'.
dx-hub-init
Initialize a hub directory for multi-repo orchestration. Discovers sibling repos, merges configs, validates CLI compatibility. Use when setting up hub mode for the first time. Trigger on "init hub", "set up hub", "multi-repo setup".
dx-hub-dispatch
Dispatch a ticket to several repos — open an independent Claude session per repo in VS Code terminals. Use for 'hub dispatch', 'work on ticket across repos'.
dx-hub-config
View and edit hub configuration — add repos, adjust terminal delay. Use to manage hub settings. Trigger on "hub config", "add repo to hub", "terminal delay".
dx-discover-repos
Resolve which repos a work item touches (explicit directive → simple block → cross-repo table → LLM). Used by the KAI-HUB router to fan an agent out across repos; 'which repos'.
dx-upgrade
Upgrade a consumer project to the installed plugin versions — run dx-doctor, fix stale and missing files, list manual actions. Use after upgrading plugins.