LogoSkills

pixel-loop:compare

One-shot visual + structural diff between an existing screenshot and a Figma node (no code changes).

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/pixel-loop:compare
Categorycocode-flutter
Complexitymoderate
MCP Serversfigma

/pixel-loop compare โ€” ๋””์ž์ธ vs ์‹ค์ œ ํ™”๋ฉด "๋‹ค๋ฅธ ์  ์ฐพ๊ธฐ"#

ํ•œ๋งˆ๋””๋กœ#

๋””์ž์ธ ์‹œ์•ˆ(Figma)๊ณผ ์‹ค์ œ๋กœ ๋งŒ๋“  ํ™”๋ฉด(์Šคํฌ๋ฆฐ์ƒท)์„ ๋‚˜๋ž€ํžˆ ๊ฒน์ณ ๋†“๊ณ  "์–ด๋””๊ฐ€ ๋‹ค๋ฅธ์ง€" ์ฐพ์•„์ฃผ๋Š” ๊ฒ€์‚ฌ๊ธฐ์ž…๋‹ˆ๋‹ค. ํ‹€๋ฆฐ ๊ทธ๋ฆผ ์ฐพ๊ธฐ์ฒ˜๋Ÿผ, ๋ฒ„ํŠผ ์œ„์น˜๊ฐ€ 8px ๋‚ด๋ ค๊ฐ”๋‹ค๊ฑฐ๋‚˜ ๊ธ€์”จ ๊ตต๊ธฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค๊ฑฐ๋‚˜ ํ•˜๋Š” ์ฐจ์ด๋ฅผ ๊ณจ๋ผ๋ƒ…๋‹ˆ๋‹ค. ๋‹จ, ๊ณ ์น˜์ง€๋Š” ์•Š๊ณ  ๋ณด๊ณ ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ฐ€ยท์–ธ์ œ ์“ฐ๋‚˜์š”#

  • ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋‚˜ ๋””์ž์ธ QA๋ฅผ ํ•  ๋•Œ โ€” "์‹œ์•ˆ๋Œ€๋กœ ์ž˜ ๋‚˜์™”๋‚˜?"๋ฅผ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • ์ง์ ‘ ํ™”๋ฉด์„ ์ˆ˜์ •ํ•˜๋Š” ์ž‘์—…๊นŒ์ง€๋Š” ํ•„์š” ์—†๊ณ , ์ฐจ์ด๋งŒ ์ ๊ฒ€(์ฝ๊ธฐ ์ „์šฉ) ํ•˜๊ณ  ์‹ถ์„ ๋•Œ

๋ฌด์—‡์„ ํ•ด์ฃผ๋‚˜์š”#

๊ฒ€์‚ฌ ๊ฒฐ๊ณผ๋ฅผ ๋‘ ๊ฐ€์ง€ ํ˜•ํƒœ๋กœ ๋‚จ๊ฒจ ์ค๋‹ˆ๋‹ค.

  • ๊ตฌ์กฐํ™”๋œ ๋ฆฌํฌํŠธ ํŒŒ์ผ โ€” .claude/docs/pixel-loop/compare_<์‹œ๊ฐ>.yaml (์š”์†Œ๋ณ„๋กœ ๋ฌด์—‡์ด ์–ผ๋งˆ๋‚˜ ๋‹ค๋ฅธ์ง€ ๊ธฐ๋ก)
  • ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ์š”์•ฝ โ€” ์ผ์น˜ํ•œ ํ•ญ๋ชฉ / ์–ด๊ธ‹๋‚œ ํ•ญ๋ชฉ / ํ—ˆ์šฉ ์˜ค์ฐจ ์•ˆ์— ๋“  ํ•ญ๋ชฉ์˜ ๊ฐœ์ˆ˜

์˜ˆ๋ฅผ ๋“ค์–ด "PrimaryButton์ด ์‹œ์•ˆ๋ณด๋‹ค 8px ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ(์ฃผ์š” ๋ฌธ์ œ)", "TitleText ๊ธ€์”จ ๊ตต๊ธฐ๊ฐ€ 600์ด์–ด์•ผ ํ•˜๋Š”๋ฐ 500์ž„(์‚ฌ์†Œํ•œ ๋ฌธ์ œ)" ์ฒ˜๋Ÿผ ์ฝ• ์ง‘์–ด ์•Œ๋ ค ์ค๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ์“ฐ๋‚˜์š”#

# ๊ธฐ๋ณธ ์‚ฌ์šฉ (์‹œ์•ˆ URL + ๋น„๊ตํ•  ์Šคํฌ๋ฆฐ์ƒท)
/pixel-loop compare --figma  " < Figma ํ”„๋ ˆ์ž„ URL(node-id ํฌํ•จ) > "   --screenshot  " < PNG ๊ฒฝ๋กœ > " 

 # ํ—ˆ์šฉ ์˜ค์ฐจ๋ฅผ ์ง์ ‘ ์ง€์ • (์ด ์ •๋„ ์ฐจ์ด๋Š” ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๋ด„)
/pixel-loop compare --figma  " ... "   --screenshot  " ... "   --tolerance pixel=1,color_delta_e=2

# ๋ฆฌํฌํŠธ๋ฅผ ์ €์žฅํ•  ์œ„์น˜๋ฅผ ์ง์ ‘ ์ง€์ •
/pixel-loop compare --figma  " ... "   --screenshot  " ... "   --output  " .claude/docs/pixel-loop/my_report.yaml "
  • --figma (ํ•„์ˆ˜): ๋น„๊ตํ•  ๋””์ž์ธ ์‹œ์•ˆ์˜ Figma ํ”„๋ ˆ์ž„ ์ฃผ์†Œ (node-id ํฌํ•จ)
  • --screenshot (ํ•„์ˆ˜): ๋น„๊ตํ•  ์‹ค์ œ ํ™”๋ฉด PNG ๊ฒฝ๋กœ (์ ˆ๋Œ€๊ฒฝ๋กœ ๋˜๋Š” .claude/docs/ ์•„๋ž˜)
  • --tolerance (์„ ํƒ): ํ”ฝ์…€ยท์ƒ‰์ƒ ํ—ˆ์šฉ ์˜ค์ฐจ. ๊ธฐ๋ณธ๊ฐ’์€ pixel=1,color_delta_e=2
  • --output (์„ ํƒ): ๋ฆฌํฌํŠธ ์ €์žฅ ์œ„์น˜. ๊ธฐ๋ณธ๊ฐ’์€ .claude/docs/pixel-loop/compare_<์‹œ๊ฐ>.yaml

์•ˆ์—์„œ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋‚˜์š”#

  1. Figma์—์„œ ๋น„๊ต ๋Œ€์ƒ ๋””์ž์ธ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  2. ์‹œ์•ˆ ๊ธฐ์ค€์œผ๋กœ "์ด๋ ‡๊ฒŒ ๋‚˜์™€์•ผ ํ•œ๋‹ค"๋Š” ๋ ˆ์ด์•„์›ƒยท๊ธ€๊ผดยท์ƒ‰์ƒ ๊ธฐ์ค€ํ‘œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  3. ์‹ค์ œ ์Šคํฌ๋ฆฐ์ƒท์„ ๋ถˆ๋Ÿฌ์™€, ์š”์†Œ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ์œ„์น˜ยทํฌ๊ธฐ๋ฅผ ๊ธฐ์ค€ํ‘œ์™€ ๋Œ€์กฐํ•ฉ๋‹ˆ๋‹ค.
  4. ์ฐจ์ด์ ์„ ์ •๋ฆฌํ•œ YAML ๋ฆฌํฌํŠธ์™€ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ์š”์•ฝ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ์ฐจ์ด๋ฅผ ์ง์ ‘ ๊ณ ์ณ ์ฃผ๊ธธ ์›ํ•œ๋‹ค๋ฉด /pixel-loop loop --mode=repair๋ฅผ, ๋น„๊ต ์ „์— ์ƒˆ ์Šคํฌ๋ฆฐ์ƒท๋ถ€ํ„ฐ ์ฐ์–ด์•ผ ํ•œ๋‹ค๋ฉด /pixel-loop capture๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.


โš™๏ธ ์ƒ์„ธ ์˜ต์…˜ยท์‹คํ–‰ ๋ช…์„ธ (๊ฐœ๋ฐœ์ž / AI ์—์ด์ „ํŠธ์šฉ)

Parameters#

ParameterRequiredDescription
--figmaโœ…Figma frame URL (with node-id)
--screenshotโœ…Path to a PNG (absolute, or under .claude/docs/)
--toleranceโŒpixel=N,color_delta_e=N (default pixel=1,color_delta_e=2)
--outputโŒWhere to write the diff report (default .claude/docs/pixel-loop/compare_<ts>.yaml)

Behavior#

  1. Resolve Figma node via figma.getNode.
  2. Build the expected layout/typography/color spec.
  3. Load the screenshot, do per-element diff (using the design spec for element bounding boxes).
  4. Write a structured YAML report and a human-readable summary.

Output Schema#

file: .claude/docs/pixel-loop/compare_ < ts > .yaml
summary:
  matched: 27
  mismatched: 3
  within_tolerance: 1
diff:
  - element: PrimaryButton
    kind: layout
    expected: { x: 24, y: 312, width: 327, height: 48 }
    actual:   { x: 24, y: 320, width: 327, height: 48 }
    delta:    { y: +8 }
    severity: major
  - element: TitleText
    kind: typography
    expected: { weight: 600, size: 22 }
    actual:   { weight: 500, size: 22 }
    severity: minor

When Not to Use#

  • Use /pixel-loop loop --mode=repair instead if you want the agent to actually fix the deltas.
  • Use /pixel-loop capture if you need a fresh screenshot before diffing.