--- name: figma-from-code-validate description: Subagent for figma-from-code Phase 5. Validates the completed Figma rebuild by comparing assembled screen frames against app screenshots. Runs fix loops on mismatched screens and produces a structured report. model: claude-sonnet-4-5 --- # Skill: Validate + Fix (Phase 5) Validates the completed Figma rebuild by comparing full-page screen frames against app screenshots. Instead of re-validating every individual component (which already passed during Phase 3's build loop), this phase checks the assembled screens as a whole — verifying that components compose correctly and that nothing was lost during screen assembly. Runs fix loops on mismatched screens and produces a structured report. Runs as a subagent dispatched by the orchestrator. ## When to Use - When `figma-from-code` orchestrator reaches Phase 5 - Standalone to validate assembled screens after a rebuild ## Required Inputs | Input | Description | Source | | ----------------------- | -------------------------------------------------- | ------------------------------------------------------------------- | | `fileKey` | Figma file key | State ledger | | `builtComponents` | Map of `{name: nodeId}` for all built components | `state.json -> builtComponents` | | `figmaNodes` | All page and frame node IDs | `state.json -> figmaNodes` | | `buildOrder` | Tiered component list | `state.json -> buildOrder` | | `devServerUrl` | URL of the running dev server | `state.json → config.devServerUrl` (default `http://localhost:5173`) | | `precaptureScreens` | Screen manifest from Phase 2.5 | `.temp/figma-from-code/precapture-screens.json` | ## Output Files | File | Contents | Consumed by | | ----------------------------------------------- | -------------------------------------------------- | ----------------- | | `.temp/figma-validation/report.md` | Full validation report with per-screen comparisons | User review | | `.temp/figma-from-code/validation-summary.json` | Small summary for the orchestrator | Orchestrator only | ## Workflow > Placeholders like `{devServerUrl}` and `{skillRoot}` resolve from `state.json → config`. ### 1. Validate screens (full-page comparisons only) For each screen built in Phase 4 (read from `.temp/figma-from-code/build-results/screens/`): 1. **Read the screen result** — get the screen's Figma node ID from `build-results/screens/{screenName}.json` 2. **Capture a fresh Figma screenshot** — `get_screenshot(fileKey, screenNodeId)` at `scale: 1` 3. **Compare against the app screenshot** — the pre-captured full-page screenshot from Phase 2.5: ```bash node {skillRoot}/scripts/compare.js \ ".temp/figma-from-code/screenshots/screens/{screenName}/app.png" \ ".temp/figma-validation/screenshots/{screenName}/figma.png" \ ".temp/figma-validation/screenshots/{screenName}/" ``` 4. **Record the verdict** — thresholds: `matchPct ≥ 85%` → match, `70-85%` → minor_diff, `< 70%` → mismatch (screen thresholds are slightly lower than component thresholds because full pages have more variation in dynamic content) **Fix loop for mismatched screens:** For screens with `verdict: "mismatch"` or `"minor_diff"`, run up to 2 fix iterations: - Diagnose from `diff.png` — identify which region/component is off - Apply targeted fix via `use_figma` (adjust instance position, swap variant, fix spacing) - Re-screenshot and re-compare - If after 2 iterations the screen still doesn't pass, record as `partial_match` **Pre-existing screens** (in `state.json → preExistingScreens`) are compared **read-only** — screenshot and record the verdict, but do NOT run the fix loop. Surface mismatches for user review. ### 2. Clean up Components page layout After validation, clean up any misplaced components on the Components page. Subagents sometimes create their own frames instead of using the designated tier frames. ```javascript const componentsPage = figma.root.children.find((p) => p.name.includes('Components')); await figma.setCurrentPageAsync(componentsPage); const tierFrameIds = new Set([ iconsFrameId, tier1FrameId, tier2FrameId, // ... all tier frames from figmaNodes ]); const strayFrames = componentsPage.children.filter((c) => !tierFrameIds.has(c.id)); // For each stray frame, move its children to the correct tier frame // based on which tier the component belongs to (from buildOrder.tiers) // Then delete the empty stray frame // Re-stack all tier frames vertically with 80px gaps const frameOrder = [iconsFrameId, tier1FrameId, tier2FrameId /* ... */]; let yPos = 0; const gap = 80; for (const id of frameOrder) { const frame = figma.getNodeById(id); frame.x = 0; frame.y = yPos; yPos += Math.round(frame.height) + gap; } ``` ### 3. Stop the Playwright server ```bash kill $(cat .temp/figma-from-code/pw-server.pid 2>/dev/null) 2>/dev/null rm -f .temp/figma-from-code/pw-endpoint.txt ``` ### 4. Write validation summary Parse the results and write a concise summary for the orchestrator: ```json { "screensCompared": 8, "match": 6, "minorDiff": 1, "mismatch": 0, "fixedDuringValidation": 1, "averageMatchPct": 89.7, "overallVerdict": "PASS", "preExistingFlagged": [], "screenResults": [ { "name": "CasesPage", "matchPct": 92.1, "verdict": "match" }, { "name": "CreateCasePage", "matchPct": 87.3, "verdict": "match" } ], "reportPath": ".temp/figma-validation/report.md" } ``` Write to `.temp/figma-from-code/validation-summary.json`. **Overall verdict:** `PASS` if >= 75% of compared screens are `match`. Otherwise `FAIL`. ### 5. Report ``` Phase 5 complete: - {screensCompared} screens validated (full-page comparison) - {match} match, {minorDiff} minor diff, {mismatch} mismatch - {fixedDuringValidation} fixed during validation - Average match: {averageMatchPct}% - Overall verdict: {overallVerdict} - Individual components already validated during Phase 3 build loop (not re-checked) ``` ## Skip / Resume Skip if `.temp/figma-from-code/validation-summary.json` exists and `state.json -> phases.phase5` is `complete`. ## Error Handling | Scenario | Action | | --------------------------------- | ---------------------------------------------------------------------------- | | Validator skill fails | Report error; partial results may exist in `.temp/figma-validation/` | | Cleanup `use_figma` fails | Report error; cleanup is non-critical — the components are already validated | | Playwright server already stopped | Ignore the kill failure | | Dev server not running | Halt validation and tell the user to start the dev server |