Visual Verify#
한마디로#
실제로 돌아가는 앱 화면을 사진으로 찍어, 디자이너가 만든 설계도(Figma)와 "다른 그림 찾기"처럼 비교해 주는 도구입니다. 사람이 눈으로 일일이 대조하지 않아도, 위치·색상·글자 모양이 설계와 얼마나 어긋나는지 자동으로 정리해 줍니다. 코드를 직접 고치지는 않고, "맞다/틀리다"만 확인해 주는 검사관 역할입니다.
무엇을·언제#
-
무엇을 해 주나요
- 지금 실행 중인 앱 화면을 사진(스크린샷)으로 찍습니다.
- 그 사진을 디자인 원본(Figma)과 비교해, 어긋난 부분을 보고서로 정리합니다.
- 기본 모드에서는 코드나 화면을 절대 건드리지 않습니다(읽기 전용 검사).
-
언제 쓰면 좋나요
- "이 화면이 디자인이랑 똑같이 나왔는지만 확인하고 싶다. 고치지는 마라."
- "버튼 위치를 고쳤다는데, 정말 제대로 반영됐는지 확인해 줘."
- 여러 화면을 한꺼번에 점검하고 싶을 때(예: 합치기 전 마지막 검사).
-
언제 쓰면 안 되나요
- 어긋난 부분을 직접 고쳐 주길 원할 때는 이 도구가 아니라
cc-pixel-loop:pixel-loop를 씁니다(이건 검사만 합니다).
- 어긋난 부분을 직접 고쳐 주길 원할 때는 이 도구가 아니라
핵심 용어#
| 용어 | 쉬운 설명 |
|---|---|
| Figma | 디자이너가 화면 모양을 그려 둔 설계도(원본 디자인). 비교의 기준이 됩니다. |
| 스크린샷(Screenshot) | 지금 화면을 그대로 찍은 사진. |
| Marionette | 실행 중인 앱에 연결해 화면을 대신 찍어 주는 자동 촬영 도구. |
| 핫 리로드(Hot reload) | 앱을 껐다 켜지 않고, 살짝 바꾼 내용을 즉시 화면에 반영하는 기능. |
| 위젯 트리(Widget tree) | 화면이 어떤 부품들로 어떻게 쌓여 있는지 보여 주는 구조도. |
| diff(차이 보고서) | 설계도와 실제 화면이 어디서, 얼마나 다른지 정리한 결과물. |
| 레이아웃/타이포그래피 | 각각 화면 배치(요소 위치·크기)와 글자 모양(폰트·글씨 스타일)을 뜻합니다. |
| FAB | 화면 위에 떠 있는 동그란 주요 버튼(예: 글쓰기 버튼). |
| regression(회귀 점검) | 여러 화면을 한 번에 돌려보며, 예전엔 멀쩡했던 곳이 망가지지 않았는지 확인하는 점검. |
| MCP | Claude가 외부 도구(촬영기, 디자인 원본 등)와 연결해 일을 시키는 통로. |
Runtime-only verification companion to the pixel-perfect loop. Sits next to the other inspectors (nav,
bloc, ui, …) and uses the same conventions, but adds a Figma-aware visual diff on top of widget-tree introspection.
Scope and Capabilities#
| Capability | MCP | Notes |
|---|---|---|
| Screenshot of current screen | marionette |
Running debug app on a device, emulator, or desktop window (VM Service). |
| Widget tree snapshot | flutter-inspector |
Existing ui_get_widget_tree tool. |
| Design source-of-truth | figma |
Resolves the target frame and its computed styles. |
| Hot reload before capture | dart |
Optional — for "fix this one token then re-verify" flow. |
| Structured diff | agent | Combines layout / color / typography deltas into a YAML report. |
Modes#
| Mode | Behavior |
|---|---|
verify (default) | Capture → Compare → write a report. Read-only. |
verify-after-reload |
dart.hotReload() → Capture → Compare. Use after a single-line tweak. |
regression |
Capture multiple labelled routes (
--routes=/home,/settings
) and compare each against its Figma counterpart.
|
When to invoke#
- "Does this screen match the design? I don't want it to edit anything."
- "Confirm the FAB position fix landed."
- "Pre-merge visual check on these three routes."
When not to invoke#
- You want the agent to fix the deltas → use
cc-pixel-loop:pixel-loopinstead. -
Flutter web target → use
cc-jaspr-web, or the Playwright fallback incc-flutter:figma:analyze. - Release build → Marionette and Dart MCP both need a VM Service; release builds don't expose one.
Prerequisites#
Same as the other inspectors plus the Marionette and Figma MCPs:
flutter run --enable-vm-service \
--host-vmservice-port=8182 \
--dds-port=8181 \
--disable-service-auth-codes \
--print-dtd
The --print-dtd addition exposes the Dart Tooling Daemon URI so Dart MCP can drive hot reload when
verify-after-reload is requested. The same run's VM Service URI (ws://127.0.0.1:8182/ws, given the ports above) is what Marionette's
connect takes.
Output#
.claude/docs/pixel-loop/verify/ < run_id > /
├── before.png # only for verify-after-reload
├── after.png
├── widget_tree.json
├── design.json
└── diff.yaml
Related#
cc-inspector:flutter-inspector— master runtime inspector.cc-pixel-loop:pixel-loop— full edit-and-verify loop (design-conformance layer).cc-marionette:marionette— CoUI-aware widget-tree automation (in-process layer).cc-mcp-toolkit:mcp-toolkit— dynamic in-app tools for domain state (internal layer).cc-jaspr-web:jaspr-web— Jaspr DOM + Flutter Web embed verification (Web layer).cc-flutter:figma:analyze— upstream Figma analysis pipeline.