문서 목차
이 페이지에서목차

/cc-pixel-loop:verify — 화면이 디자인대로 나왔는지 "계산으로 대조"

화면이 Figma 시안대로 나왔는지 상태 프레임마다 라이트 · 다크로 결정적 픽셀 비교해 통과 · 실패 · 판정 불가를 정하고, 차이 이미지 · 영역별 보고서 · PR 본문용 요약을 남깁니다(코드 수정 없음). 화면 구현의 완료 판정이나 PR 전 디자인 확인에 쓰세요 — 고치며 맞추려면 /cc-pixel-loop:loop.

항목내용
실행 명령/cc-pixel-loop:verify
분류Flutter
난이도●●○ 보통
MCP 서버figma

한마디로#

디자이너가 그린 화면(Figma)과 앱이 그린 화면을 같은 크기 · 같은 배율로 찍어 프로그램이 점 단위로 비교하고, "같다 · 다르다 · 비교할 수 없다"를 정해 주는 검사기입니다. 코드는 고치지 않고, 어디가 어떻게 다른지 그림과 보고서로 남깁니다.

누가·언제 쓰나요#

  • 디자이너 · 기획자: "지금 앱 화면이 Figma 시안과 정말 같은가?"를 눈대중이 아니라 숫자로 확인하고 싶을 때
  • 개발자: 화면 구현을 끝냈다고 말하기 전, PR 을 올리기 전
  • 한 화면의 상태(기본 · 로딩 · 빈 화면 · 오류)와 밝은 · 어두운 테마를 한 번에 점검할 때

무엇을 해주나요#

  • 상태 프레임마다 밝은 · 어두운 테마로 비교하고, 비교마다 차이를 빨갛게 칠한 이미지(Figma | 앱 | 차이)를 남깁니다
  • 다른 곳마다 "어느 부품의 어디가 어떤 색에서 어떤 색으로" 를 적은 보고서와, PR 본문에 그대로 붙이는 요약표를 남깁니다
  • 비교하지 못한 것(서체가 없다, 시안이 어두운 테마를 그릴 수 없다 …)은 통과로 바꾸지 않고 이유와 함께 남깁니다
  • 차이를 직접 고치지는 않습니다 — 고치는 일은 /cc-pixel-loop:loop 에 넘깁니다

어떻게 쓰나요#

# 화면 레지스트리의 섹션 하나 — 그 섹션의 상태 프레임 전부 × 라이트 · 다크
/cc-pixel-loop:verify --section "https://www.figma.com/design/<key>/<file>?node-id=12-340" --app <앱 경로>

# 섹션 여러 개 + 렌더 테스트가 사는 feature 패키지 지정
/cc-pixel-loop:verify --section <url1>,<url2> --app <앱 경로> --test-package <feature 패키지>

# 라이트만 내는 앱 — 빼는 이유를 함께
/cc-pixel-loop:verify --section <url> --app <앱 경로> --exclude-theme "dark:라이트 전용 제품(DDR-12)"

# 진단 — 이미 찍은 사진 한 장을 프레임 하나와 비교(완료 판정이 아니다)
/cc-pixel-loop:verify --frame <프레임 url> --screenshot <png> --scale 2

안에서 무슨 일이 벌어지나요#

  1. Figma 에서 섹션의 상태 프레임과 그 크기 · 테마 · 서체 · 상태 바를 읽습니다(읽기 전용).
  2. 앱이 그 서체를 갖고 있는지, 앱이 어떤 CoUI 판을 쓰는지 확인합니다.
  3. Figma 에서 프레임을 같은 배율로 내려받습니다. 어두운 테마는 프레임의 임시 복제본을 찍고 바로 지웁니다.
  4. 앱 쪽은 위젯북 상태와 같은 데이터로 같은 크기 · 배율의 사진을 그립니다(기기 없이 테스트로).
  5. 스크립트가 두 사진을 비교해 통과 · 실패 · 판정 불가를 정하고, AI 는 남은 차이를 설명하고 어디서 고칠지 가립니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

절차 · 규칙 · 기본값의 정본은 cc-pixel-loop:visual-verify 스킬이다 — 이 커맨드는 그 스킬을 로드해 순서대로 실행하고 결과를 보고한다.

Parameters#

ParameterRequiredDescription
--section✅ (또는 --frame)화면 레지스트리 섹션의 Figma URL(node-id) · use_case designLink 의 프레임 URL(그 섹션 전체를 읽는다). 쉼표로 여럿
--frame❌단건 진단 — 프레임 하나를 --screenshot 한 장과 diff 한다. 그 프레임에 고정한 밝기 하나만, summary 없이 — 완료 판정이 아니다
--app✅ (단건 진단 제외)앱(워크스페이스) 루트 — fonts · coui · literals 가 읽는다
--test-package❌렌더 테스트를 둘 패키지(기본: 섹션의 feature 패키지) — flutter_test_config.dart 의 글꼴 로드를 본다
--source❌render(기본 — 테스트 렌더) · browser(Jaspr) · device(실행 중인 앱 — 게이트의 근거로 쓰지 않음)
--exclude-theme❌'<theme>:<이유>' — 밝기는 늘 라이트 · 다크 둘이고, 빼는 것은 이유와 함께만
--ignore-frame❌'<프레임 id>=<이유>' — 섹션 안의 화면이 아닌 프레임(메모 류). 이름이 「플랫폼-상태」 가 아닌 프레임은 이것 없이는 판정 불가로 남는다
--mask-node❌'<노드 id>=<이유>' — 계속 바뀌는 노드(스피너 · 시계 류)를 가린다
--scale❌비교 배율(기본 Mobile 2 · Web 1)
--tolerance❌pixel=1,color_delta_e=3,text_pixel=2,text_delta_e=10 (기본)
--budget❌ratio=0.002,region=32 (기본)
--screenshot❌이미 찍은 PNG — 캡처를 생략하고 --frame 과만 비교
--base❌literals 기준 ref (기본 origin/main)
--run-id❌기존 실행 폴더로 다시 — Figma 쪽(plan · 내보내기)은 재사용하고 렌더 · 보고서 · 요약은 다시 만든다. 시안을 고쳤으면 새 실행

Phase Flow#

  1. 입력 — figma:figma-use 로드 후 섹션마다 cc-blueprint 의 compare-frames.figma.js → frames-<섹션>.json. Figma 를 읽지 못하면(whoami · get_metadata 실패) 아무것도 비교하지 않고 undetermined:figma-unreadable 로 끝낸다.
  2. 계획 — figma_compare.py plan. 비교가 0 이면 판정 불가로 끝낸다.
  3. 확인 — fonts(빠진 서체 → 판정 불가) · coui(앱의 CoUI 릴리스 · 라이브러리와 달라진 컴포넌트).
  4. Figma 이미지 — download_assets(png, defaultScale) 로 figma/<label>.png. clone:<밝기> 는 dark-frames.figma.js create(MODE = 그 밝기 — Dark · Light) → 받기 → remove(실패해도). unthemable 은 받지 않는다.
  5. 렌더 — --source 에 따라 render/<label>.png. co_golden 캡처는 figma_compare.py ingest 로 옮긴다. Jaspr 는 페이지가 불러온 서체를 읽어 fonts --browser-fonts 로 판정한다.
  6. 비교 — figma_compare.py diff --run --label (비교마다).
  7. 판정 — 실패한 비교의 영역마다 고칠 자리를 judgement.json 에(visual-verify 5절). 이 커맨드는 고치지 않으므로 app · style-slot 영역은 남은 채로 보고된다.
  8. 합계 — literals 뒤 summary --check-issues. summary.md 를 결과 보고에 그대로 싣는다.

Output#

.claude/docs/visual-verify/<run_id>/
├── frames-<섹션>.json · plan.json · nodes/
├── fonts.json · coui.json · literals.json · judgement.json
├── figma/<label>.png · render/<label>.png
├── reports/<label>.report.json · <label>.diff.png
└── summary.json · summary.md
Figma 대조 — fail · 비교 8 · 통과 6 · 실패 1 · 판정 불가 1
| 상품 목록 | Mobile-Default | dark | fail | 0.412% | 96.5 | 3 | 0 |
- 남음 12-345__dark node:12:357 (96.5 px²) — app: 제목 색이 라이트 값으로 남았다
- 사유: fail:diff · undetermined:comparison

상태#

summary.json 의 status 는 pass · fail · undetermined 이고, 이유는 reasons[], 비교마다의 사유는 rows[].status 에 있다(visual-verify §6). 판정 불가는 통과가 아니다 — 부른 쪽(cc-dev:run Step 7.3, /cc-blueprint:build Step 5)은 그것을 실패와 따로, 정지(BLOCKED)나 사람이 확인한 스킵으로 다룬다.

단건 진단(--frame + --screenshot)은 diff 의 결과(pass · fail · undetermined:<사유>)만 보고한다 — 서체 · 덧대기 검사와 다른 밝기가 없으므로 완료 판정에 쓰지 않는다.

  • Skill: cc-pixel-loop:visual-verify — 절차 · 규칙 · 기본값의 정본
  • Edit loop: /cc-pixel-loop:loop
  • Figma 쪽 입력: cc-blueprint 의 references/recipes/compare-frames.figma.js · dark-frames.figma.js

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기