SuperAPI AI Directory

figma-verify

Frontend & websites

View repository

Updated 10-15 17:26

About this skill

/figma-verify — Figma vs local alignment and ship gate

The final gate for UI / copy PRs before mark ready-for-review, merge, production deploy; Step 4.5 uses the built-in /goal evaluator to run the visual gate (see that step for details).

When to use / when not to use

✅ Use:

  • PRs that touch visual tokens / copy / icons / spacing / layout
  • ticket / PR description contains a Figma link
  • code contains "placeholder" "temp" "follow-up" "reuse XX" disclaimers
  • final check before mark ready-for-review / merge / deploy

❌ Don't use:

  • pure backend / pure logic PRs with zero visual/copy changes
  • design system explicitly states "engineering may adjust X scope on their own"
  • Bug fixes (z-index, layout overlap) that aren't design parameter changes, but should still be noted in the PR for designers to see

Step 1: Get the Figma node-id

Find it in the ticket / PR / Slack thread figma.com/design/<fileKey>/...?node-id=<id>:

https://figma.com/design/I8foiMEfn9ngF44UGEIrUL/...?node-id=18374-19281
                         └── fileKey ─────┘                 └─ nodeId (- → :) ─┘
                                                              => "18374:19281"

Without a node-id, do not touch UI / copy.

Step 2: Use Figma MCP to fetch the real specs (four calls in parallel)

mcp__figma__get_design_context({ nodeId, fileKey })   // Tailwind code + token names
mcp__figma__get_variable_defs({ nodeId, fileKey })    // token → hex map
mcp__figma__get_screenshot({ nodeId, fileKey })       // 視覺 reference(Step 4.5 用)
mcp__figma__get_metadata({ nodeId, fileKey })         // 結構 + x/y/w/h

Not authorized → first run mcp__figma__authenticate or ask the user to run the OAuth flow.

Step 3:fallback — Playwright MCP headed + logged-in Figma session

When Figma MCP is unavailable:

  • must be headed(Figma SPA + CSR + bot detection; headless gets stuck on the login page)
  • must already be logged into a Figma session(headless default session is not logged in)
  • must not use WebFetch(figma.com is on the webfetch-blocklist)
  • Open the page → browser_resize ≥1600×1000 → browser_take_screenshot fullPage:true → measure distances / grab token names

Step 4: List the "Figma → code" mapping table and align each item

Property Figma spec Code field Match?
bg token Color/Success/L-06 (#eaf5f4) bg-(--Color-Success-L-06) ✅
label text 待曝光 label: "待曝光" ✅

Any ❌ must be handled — no "ship first, wait for follow-up".

Step 4.5:/goal built-in Haiku evaluator runs the visual gate

after the token / copy table passescannot ship directly. Even with correct token names, visual rendering may differ (font weight fallback, icon size, spacing rendered with 1px diff). This step turns "fix until visually consistent" into an automatically re-running gate.

4.5a — Surface both screenshots into the transcript

/goal evaluator is a small fast model (defaults to Haiku), but itcannot call tools, and only reads existing transcript content. The main turn must first paste both the Figma and local images into the conversation:

mcp__figma__get_screenshot({ nodeId, fileKey })
mcp__playwright__browser_take_screenshot({ fullPage: true })  // 已 resize ≥1600×1000

Once both images are in the transcript, the Haiku evaluator can directly do a "pure visual comparison".

4.5b — Issue /goal to start the visual gate

/goal Figma screenshot 與 local headed screenshot 視覺一致
      (font weight / spacing / color 無肉眼可辨偏差),
      且 Step 4 的「Figma → 程式碼」對齊表全部 ✅
      OR stop after 5 turns
  • Inconsistent → evaluator returns a reason (e.g., "Figma looks bolder vs local looks thinner"), automatically starting the next round of fixes
  • Consistent → automatically clears the goal, proceeds to Step 5

4.5c — 3-column diagnostic table (each round of the evaluator's reason is the "visual findings" column; organize into the table below and paste into the PR description)

Model Visual findings (evaluator reason) Inferred root cause (main turn diagnose)
haiku(/goal evaluator, purely visual comparison of 2 screenshots) Visual difference is obvious, Figma is too bold vs local is too thin weight setting error (inferred) + font fallback

Any row ❌ → must not proceed to Step 5. Produce the table in one shot via /goal, and organize the evaluator reason; use explicit Agent(model="haiku") subagent(/goal only when Haiku tool calls or multi-way parallelism are needed (the evaluator itself is already Haiku, so opening it again is reinventing the wheel).

Step 5: The final alignment before ship

before ready-for-review / merge / production deploy — open Figma literal values against git diff, and check off each item.

Legitimate options when it truly cannot wait

The designer "really" hasn't given the spec yet (extremely rare):

  1. split the PR: ship only backend logic / status mapping / route gate,do not ship visuals/copy
  2. TODO constants + lint gate:const TODO_TOKEN = "TODO_DESIGN_TOKEN_AWAITING_SPEC"; + lint rule blocking the production build
  3. block on designer: write "block on designer spec, do not merge" in the PR description + do not click ready-for-review
  4. dev-only flag: gate visuals/copy by environment; do not display at all in production

❌ Forbidden: self-chosen token / self-written copy merged to main → production. "Reuse the same status type", "placeholder", "fix later"cannot be used as免责 terms。

Audit grep recipe

# 找 placeholder / follow-up disclaimer(PR 內最可疑訊號)
grep -rnE "placeholder|TODO|待\s*designer|follow-up|沿用.*配色|借\s+.*token" \
  features/ components/ src/ --include="*.tsx" --include="*.ts" \
  | grep -vE "node_modules|\.test\."

# 找 PR description 自承 placeholder
gh pr view <num> --json body | grep -iE "placeholder|follow-up|沿用|借"

See Also

Design basis

  • /goal the evaluator defaults to Haiku: official text "the conversation so far are sent to your configured small fast model, which defaults to Haiku"
  • Designer spec must not be unilaterally modified: self-chosen token / self-written copy = unilateral edit, regardless of whether the placeholder marking is clear
  • Token names matching ≠ visual matching: font weight fallback, font loading failure, and platform rendering differences can make token-correct code still look different from Figma — the visual gate must be run