LogoSkills

marionette:sweep

Walk a Widgetbook catalogue or route table; screenshot + interact with each item; flag non-responsive ones.

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/marionette:sweep
Categorycocode-flutter
Complexitymoderate
MCP Serversmarionette

/marionette sweep โ€” ํ™”๋ฉด ์ „์ˆ˜ ์ ๊ฒ€ (ํ•œ ๋ฒˆ์— ์ญ‰ ํ›‘๊ธฐ)#

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

์•ฑ์˜ ํ™”๋ฉด(๋˜๋Š” ๋ถ€ํ’ˆ)๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ž๋™์œผ๋กœ ๋ˆŒ๋Ÿฌ๋ณด๊ณ  ์‚ฌ์ง„์„ ์ฐ์–ด, "๋ˆŒ๋ €๋Š”๋ฐ ์•„๋ฌด ๋ฐ˜์‘ ์—†๋Š”" ๊ฒƒ๋“ค์„ ๊ณจ๋ผ๋‚ด๋Š” ์ผ๊ด„ ์ ๊ฒ€ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋งค์žฅ ์ง์›์ด ์ง„์—ด๋œ ๋ชจ๋“  ์ œํ’ˆ์˜ ๋ฒ„ํŠผ์„ ์ง์ ‘ ๋ˆŒ๋Ÿฌ๋ณด๋ฉฐ "์ด๊ฑด ๊ณ ์žฅ๋‚ฌ๋„ค" ํ•˜๊ณ  ํ‘œ์‹œํ•ด ๋‘๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.

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

  • ํ™”๋ฉด์ด๋‚˜ UI ๋ถ€ํ’ˆ์„ ํ•œ๊บผ๋ฒˆ์— ์ ๊ฒ€ํ•ด ๋ฐ˜์‘ ์—†๋Š”(๊ณ ์žฅ๋‚œ) ๊ณณ์„ ์ฐพ์•„๋‚ด๊ณ  ์‹ถ์„ ๋•Œ
  • ์ƒˆ ๋ฒ„์ „์„ ๋‚ด๋ณด๋‚ด๊ธฐ ์ „, ํšŒ๊ท€ ์ ๊ฒ€(์ด์ „์— ๋ฉ€์ฉกํ•˜๋˜ ๊ฒŒ ๋ง๊ฐ€์ง€์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธ)์ด ํ•„์š”ํ•  ๋•Œ
  • ์ ๊ฒ€ ๋Œ€์ƒ์€ ๋‘ ๊ฐ€์ง€ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค: ๋””์ž์ธ ๋ถ€ํ’ˆ ๋ชจ์Œ(coui) ๋˜๋Š” ์•ฑ์˜ ํ™”๋ฉด ๋ชฉ๋ก(routes).

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

์ ๊ฒ€์ด ๋๋‚˜๋ฉด ๊ฒฐ๊ณผ๋ฌผ์ด ํ•œ ํด๋”(.claude/docs/marionette/<run_id>/)์— ์ •๋ฆฌ๋˜์–ด ๋‚จ์Šต๋‹ˆ๋‹ค:

  • ํ™”๋ฉด ์‚ฌ์ง„ (screens/) โ€” ๊ฐ ํ•ญ๋ชฉ์„ ๋ˆ„๋ฅด๊ธฐ ์ „(_idle.png)๊ณผ ๋ˆ„๋ฅธ ํ›„(_after.png) ์‚ฌ์ง„
  • ๋ˆŒ๋Ÿฌ๋ณธ ์š”์†Œ ๋ชฉ๋ก (interactive/<ํ•ญ๋ชฉ>.json) โ€” ๊ฐ ํ™”๋ฉด์—์„œ ์–ด๋–ค ๋ฒ„ํŠผยท์ž…๋ ฅ์นธ์„ ๊ฑด๋“œ๋ ธ๋Š”์ง€
  • ๋กœ๊ทธ (logs.txt) โ€” ๋„์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋‚œ ๊ฒฝ์šฐ ๊ทธ ํ”์ 
  • ์š”์•ฝ ๋ณด๊ณ ์„œ (summary.md) โ€” ํ•ญ๋ชฉ๋ณ„๋กœ "๋ฐ˜์‘ํ•จ / ๋ฐ˜์‘ ์—†์Œ / ์˜ค๋ฅ˜"๋ฅผ ํ•œ๋ˆˆ์— ๋ณด๋Š” ํ‘œ

์ด ๋„๊ตฌ๋Š” ๋ฌธ์ œ๋ฅผ ์ฐพ์•„ ์ฆ๊ฑฐ๋ฅผ ๋‚จ๊ธฐ๊ธฐ๋งŒ ํ•  ๋ฟ, ์ง์ ‘ ๊ณ ์น˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐœ๊ฒฌ๋œ ๋ฌธ์ œ๋Š” ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ์ด์Šˆ๋กœ ๋“ฑ๋กํ•ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

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

# ๋””์ž์ธ ๋ถ€ํ’ˆ ๋ชจ์Œ(coui)์„ ์ ๊ฒ€ํ•˜๋˜, ์ฒ˜์Œ์—” 20๊ฐœ๋งŒ (์‹œํ—˜ ์‚ผ์•„)
/marionette sweep --catalogue=coui --limit=20 --output=.claude/docs/marionette/coui-v2.3/
  • --catalogue (ํ•„์ˆ˜): ๋ฌด์—‡์„ ์ ๊ฒ€ํ• ์ง€. coui(๋””์ž์ธ ๋ถ€ํ’ˆ) / routes(์•ฑ ํ™”๋ฉด ๋ชฉ๋ก) / ์ง์ ‘ ๋งŒ๋“  ๋ชฉ๋ก ํŒŒ์ผ(YAML) ์ค‘ ํ•˜๋‚˜
  • --limit (์„ ํƒ): ํ•œ ๋ฒˆ์— ์ ๊ฒ€ํ•  ๊ฐœ์ˆ˜ ์ œํ•œ. ์ฒ˜์Œ ์‹œํ—˜ ์‚ผ์•„ ๋Œ๋ฆด ๋•Œ ์œ ์šฉ
  • --output (์„ ํƒ): ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•  ํด๋” ์œ„์น˜
  • --actions (์„ ํƒ): ๋ถ€ํ’ˆ ์ข…๋ฅ˜๋ณ„ ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๋•Œ

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

๋ชฉ๋ก์— ์žˆ๋Š” ๊ฐ ํ•ญ๋ชฉ๋งˆ๋‹ค ์•„๋ž˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค:

  1. ํ•ด๋‹น ํ•ญ๋ชฉ(ํ™”๋ฉดยท๋ถ€ํ’ˆ)์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ฑด๋“œ๋ฆฌ๊ธฐ ์ „ ๋ชจ์Šต์„ ์‚ฌ์ง„์œผ๋กœ ์ฐ์–ด ๋‘ก๋‹ˆ๋‹ค (_idle.png).
  3. ๊ทธ ํ™”๋ฉด์—์„œ ๋ˆ„๋ฅผ ์ˆ˜ ์žˆ๋Š” ์š”์†Œ๋“ค์„ ๋ชจ๋‘ ์ฐพ์•„๋ƒ…๋‹ˆ๋‹ค.
  4. ๋ฒ„ํŠผ์€ ๋ˆ„๋ฅด๊ณ , ์ž…๋ ฅ์นธ์—” ๊ธ€์ž๋ฅผ ๋„ฃ๊ณ , ์Šค์œ„์น˜๋Š” ์ผœ๋Š” ์‹์œผ๋กœ ์ข…๋ฅ˜์— ๋งž๋Š” ๋™์ž‘์„ ํ•œ ๋ฒˆ์”ฉ ํ•ด๋ด…๋‹ˆ๋‹ค.
  5. ๊ฑด๋“œ๋ฆฐ ๋’ค ๋ชจ์Šต์„ ๋‹ค์‹œ ์‚ฌ์ง„์œผ๋กœ ์ฐ์Šต๋‹ˆ๋‹ค (_after.png).
  6. ๋‘ ์‚ฌ์ง„์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค โ€” ๋˜‘๊ฐ™์œผ๋ฉด "๋ฐ˜์‘ ์—†์Œ"์œผ๋กœ ํ‘œ์‹œ, ๋‹ฌ๋ผ์ง€๋ฉด "์ •์ƒ", ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ์œผ๋ฉด ๋กœ๊ทธ๋ฅผ ํ•จ๊ป˜ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ๊ฒ€์€ ํ•œ ๋ฒˆ์— ์ญ‰ ํ›‘๊ณ  ๋์ž…๋‹ˆ๋‹ค(๋ฐ˜๋ณตํ•˜๋ฉฐ ๊ณ ์น˜์ง€ ์•Š์Œ). ๊ฒฐ๊ณผ ํ‘œ๋ฅผ ๋ณด๊ณ  ์–ด๋””๊ฐ€ ๋ฌธ์ œ์ธ์ง€ ํŒŒ์•…ํ•˜๋Š” ์šฉ๋„์˜ˆ์š”.


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

Parameters#

ParameterRequiredDescriptionDefault
--catalogueโœ…coui (Widgetbook), routes (app router table), or a path to a YAML manifestโ€”
--limitโŒCap on items processed (useful for first dry-run)unlimited
--outputโŒOutput dir.claude/docs/marionette/<ts>/
--actionsโŒOverride default smoke actions per type (YAML inline)sensible defaults

Default Smoke Actions per Type#

TypeAction
PrimaryButton / SecondaryButton / otherstap
Input / Textareaenter_text("marionette-test")
Toggle / Switch / Checkboxtap (flip)
Slidertap mid-track
TabItemtap
AccordionItemtap (expand)

Loop#

For each catalogue item:

  1. Navigate to the item (tap on Widgetbook sidebar entry OR GoRouter.go(route)).
  2. take_screenshots โ†’ screens/<item>_idle.png.
  3. get_interactive_elements โ†’ interactive/<item>.json.
  4. For each element, run the type's smoke action.
  5. take_screenshots โ†’ screens/<item>_after.png.
  6. Diff the two screenshots:
    • identical โ†’ flag as "non-responsive" in summary.md.
    • changed โ†’ record as "interactive".
    • threw โ†’ collect get_logs excerpt around the timestamp.

Output#

.claude/docs/marionette/ < run_id > /
โ”œโ”€โ”€ interactive/
โ”‚   โ””โ”€โ”€  < item > .json
โ”œโ”€โ”€ screens/
โ”‚   โ”œโ”€โ”€  < item > _idle.png
โ”‚   โ””โ”€โ”€  < item > _after.png
โ”œโ”€โ”€ logs.txt
โ””โ”€โ”€ summary.md            # table of items ร— actions ร— result

Convergence#

The sweep is one-shot โ€” no iteration. It produces evidence, not fixes. Use this output to open ZenHub issues; see cc-code-quality:bug-report for the next step.

Example#

/marionette sweep --catalogue=coui --limit=20 --output=.claude/docs/marionette/coui-v2.3/
[1/20] PrimaryButton โ†’ idle.png + after.png + 4 interactive elements
[2/20] SecondaryButton โ†’ idle.png + after.png + 4 interactive elements
...
[20/20] Toggle โ†’ idle.png + after.png + 2 interactive elements

Non-responsive: 1 (LinkButton.disabled โ€” expected, see ADR-12)
Threw: 0
Report: .claude/docs/marionette/coui-v2.3/summary.md