roast-my-design-system 9.0.6 → 9.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,120 +2,99 @@
2
2
 
3
3
  # roast-my-design-system
4
4
 
5
- [![npm](https://img.shields.io/npm/v/roast-my-design-system?color=2dd4bf&label=npm)](https://www.npmjs.com/package/roast-my-design-system) [![downloads](https://img.shields.io/npm/dm/roast-my-design-system?color=2dd4bf&label=downloads)](https://www.npmjs.com/package/roast-my-design-system) [![Socket](https://badge.socket.dev/npm/package/roast-my-design-system)](https://socket.dev/npm/package/roast-my-design-system) [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE) [![zero dependencies](https://img.shields.io/badge/dependencies-0-2dd4bf)](https://www.npmjs.com/package/roast-my-design-system?activeTab=dependencies) [![no telemetry](https://img.shields.io/badge/no-telemetry-2dd4bf)](https://github.com/gregkozakiewicz/roast-my-design-system#what-makes-the-numbers-trustworthy)
5
+ [![npm](https://img.shields.io/npm/v/roast-my-design-system?color=2dd4bf&label=npm)](https://www.npmjs.com/package/roast-my-design-system) [![Socket](https://badge.socket.dev/npm/package/roast-my-design-system)](https://socket.dev/npm/package/roast-my-design-system) [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE) [![zero dependencies](https://img.shields.io/badge/dependencies-0-2dd4bf)](https://www.npmjs.com/package/roast-my-design-system?activeTab=dependencies) [![no telemetry](https://img.shields.io/badge/no-telemetry-2dd4bf)](#what-makes-the-numbers-trustworthy)
6
6
 
7
7
  [![MCP verified in Claude Code](https://img.shields.io/badge/MCP_verified-Claude_Code-2dd4bf)](#live-answers-over-mcp) [![MCP verified in Cursor](https://img.shields.io/badge/MCP_verified-Cursor-2dd4bf)](#live-answers-over-mcp) [![MCP verified in Windsurf / Devin Desktop](https://img.shields.io/badge/MCP_verified-Windsurf_%2F_Devin_Desktop-2dd4bf)](#live-answers-over-mcp)
8
8
 
9
- ## Your AI can write the UI. This makes sure it writes *your* UI.
9
+ ## Find where your AI agent will invent UI.
10
10
 
11
- A free CLI tool, and a Claude Code plugin with two skills, a bundled local MCP server and an edit hook, that roasts your repo's design system with real data, reviews what you change against it, and generates the rules that keep your AI agent on-system.
11
+ Your AI can write the UI. This makes sure it writes *your* UI.
12
12
 
13
- > **New in 9.0: the spacing count means what its label says, and the ruler is rebuilt.** Inside a style object every length used to count as an off-scale spacing value: a width, a font size, a shadow's offsets. Only padding, margin, gap and position count now, the same set the CSS rule reads. Because the benchmark was built on the old count, every yardstick is rebuilt on the same 34 repos, 10 reputable systems and 6 kit slices. Fleet medians are now 118 colours, 21 greys, 23 off-scale spacing values, 21 duplicated components, 51 inline style blocks, 77 bracket values, 8 near-identical pairs and 5 `!important`. Spacing moved down everywhere (33 to 23 on the fleet, 29 to 14 on shadcn repos, 97 to 75 on Ant Design); colours, greys and near pairs moved by one to three from counting fixes shipped since the last rebuild. Two of the eleven examples change score: Adobe Spectrum 72 to 66, Unleash 64 to 60. Take a fresh scan before you compare.
13
+ An agent builds UI the way a new hire does on their first day: it looks around the repo and copies what it finds. We measured that on 10 real products, 259 agent sessions, with and without this tool. On everyday work the agent reused the components and tokens that were there and stayed on-system. It went off-system in the places where the repo had no answer to copy. A chart, in a codebase with no chart palette. A theme, where nobody had named the surfaces. And it filled each gap the way the repo's own code did: by hand.
14
14
 
15
- > **New in 8.0: support for the four big component kits.**
16
- >
17
- > If your product is built on MUI, Mantine, Chakra UI or Ant Design, roast now reads it as such. It finds your theme in the repo, counts how often your components read it, and measures the two things that drift: colours and spacing written onto components when the theme already has a value.
18
- >
19
- > - **The kit's own code is not counted.** Nor are chart colours, colour pickers, artwork, editor themes or fallbacks.
20
- > - **Your own layer counts as the kit.** Metabase wraps Mantine and imports the wrapper in 2,469 files. The old reading covered 14% of the product.
21
- > - **A repo belongs to the kit it uses most,** shadcn included.
22
- > - **You are compared with products on the same kit:** 19 MUI, 19 Mantine, 16 Chakra and 16 Ant Design, 70 in all. Each target comes from the tidiest third of its group.
23
- > - **The fix prompts speak your kit:** MUI's `sx`, Mantine's props, Chakra's space steps, Ant Design's `theme.useToken()`.
24
- >
25
- > Repos that used to fall through now read properly. Open-Assistant scored a false 100 and now scores 75 as a Chakra product. InvenTree and the APISIX dashboard got no score at all and now score 75 and 84.
15
+ ```bash
16
+ npx roast-my-design-system@latest
17
+ ```
26
18
 
27
- > **Also in 8.0: eleven counting fixes.**
28
- >
29
- > The benchmark is rebuilt on them, so every score moves. Take a fresh one before you compare.
30
- >
31
- > - **One colour written two ways is one colour.** It was counted twice and reported as a near-identical pair.
32
- > - **A fallback inside `var(--x, #fefefe)` reads the theme.** It is no longer a stray colour. Primer goes from 308 colours to 8.
33
- > - **Stylesheets you did not write are left out.** So are apps you have replaced, such as a `web-old` folder. The report lists everything left out, with file counts.
34
- > - **Fix prompts start from a product file,** not from your docs site.
35
- >
36
- > Fleet medians then: 115 colours, 23 greys, 33 off-scale spacing values, 21 duplicated components, 51 inline style blocks, 77 bracket values, 7 near-identical pairs and 5 `!important`. (9.0 moved them; see the note above.)
19
+ Run it at the root of a UI repo. About a second later a self-contained HTML report opens. No account, no network, no telemetry, nothing in your repo is changed.
37
20
 
38
- > **New in 7.10: a fifth profile, `tailwind`, with its own benchmark.** A repo that uses Tailwind v4 and defines at least 3 colours of its own in an `@theme` block is read as a Tailwind repo. It gets one extra check: Tailwind palette classes such as `text-gray-500` written where the theme has a colour of that kind, per 100 files. A Tailwind name given a different colour counts as the repo's own. Tailwind repos are compared with a group of 11 Tailwind repos, and the target is 3 per 100 files (median 10). Three scores that were too high now show no score or a lower one: better-auth (100, its interface is in skipped folders), strapi (75, its colours are in an installed package) and supabase (100, now 28). Files that import an email kit are skipped as emails wherever they are. Svelte, Vue and Tailwind v3 configs are not read as Tailwind yet. `summary.json` gains `kind: "tailwind"` and a `tailwind` block, and `score` can be `null`.
21
+ **Current release: 9.0.** What changed in each version is in [CHANGELOG.md](CHANGELOG.md).
39
22
 
40
- > **New in 7.7: four repo profiles, and the fourth is `registry`.** The scanner decides once what kind of repo it is reading, `product`, `library`, `shadcn` or `registry`, and every count, ideal and benchmark line reads that decision. `registry` is new: a repo that publishes a shadcn registry (a `registry.json` with typed items, or a route that builds one from a packages folder) is counted on what it publishes and nothing else. The docs site, demos and examples are kept out and named in the header with file counts; the same components kept in several variants count once; a name repeated only inside published blocks is the range, not a duplicate; published components are the project's own work, with no installed-code exemption. Published themes get their own tile: every shadcn colour variable present for light and for dark, ideal 0. For a registry that publishes themes and no code, that check is the score. Covers shadcn's own source (84), magicui (69), kibo-ui (78) and tweakcn (100, 36 themes, all complete). No other kind of repo moves. `summary.json`: `kind: "registry"` with a `registry` block (`publishes`, `counted`, `showcase`, `variantsDropped`, `themes`); tiles gain `themesIncomplete` on registries.
23
+ ### The mess an agent adds is a map of the gaps in your system
41
24
 
42
- Run it on your codebase and get, in about a second:
25
+ An agent copies what it finds. Where the repo has no answer, it makes one up, and the next agent copies that. This tool draws the map before the gap becomes a layer: it finds the places with no answer, measures the mess already there, writes the rules that keep the agent on-system, and puts a check inside the agent's editor that runs whether or not the agent thinks to ask.
43
26
 
44
- - **A health score you can defend in a meeting.** It measures how safely an AI agent can build new UI on this repo without going off-system. Everything else on the report is receipts for humans. 0 to 100, deterministic, and benchmarked against 3 yardsticks: Ideal Design System norms, 34 scanned public repos and 10 reputable design systems (Primer, Polaris, Carbon, shadcn/ui…).
45
- - **Per-package scores for monorepos.** One blended number hides which package is the problem: `packages/ui` scores 80 while `apps/web` scores 40, and now you can see it.
46
- - **Reads React and web components alike.** Stencil, Lit and custom elements are detected by tag registration and counted by kebab tag. Libraries get composition maps, not adoption accusations. Earned token namespaces are named in the header. Anything the scan can not read is declared "not measured" instead of scored.
47
- - **The receipts behind it.** Every colour and its near-identical twin. Every spacing value, typeface, duplicated or never-imported component, inline style and !important. All with real file paths, in one self-contained HTML report you can open, Slack or email.
48
- - **The first fixes ranked by payoff, each with its prompt.** A "Where to start" list derived from your own numbers. Every move carries a copy button with a ready-made fix prompt for your agent: the finding, the files, the expected payoff, and rules that respect deliberate craft. Fix, re-run the scan, press the next button.
49
- - **Where agents will invent.** The places where the repo has no answer yet, so the next piece of UI, human or agent, will make one up. Today that is one gap, found by measuring 164 agent sessions on real products: charts that paint their series colours by hand in a repo with no chart palette. The section names the files and the one move that closes it.
50
- - **Rules that stop the mess coming back.** A generated `design-system-rules.md` with canonical components, your token file, and known duplicates to avoid, so your AI agent follows your system instead of guessing at it. `--apply` injects them into every agent file you have: Claude, Cursor, GitHub Copilot, and Windsurf. Every scan also checks the rules you already have for stale references: paths that no longer exist, components named canonical that nothing imports anymore. And the agent card states which tools can actually read the rules you have (Claude Code, Codex, Cursor), with the one-line fix where a door is missing.
27
+ **A script does the counting. Claude writes the explanation.** Every number in the report comes from a deterministic read of your files, the same numbers every run. Where an AI reads the scan for you, its text is labelled as written by AI and kept apart from the measurements.
51
28
 
52
- ## Why this exists
29
+ ## What you get
53
30
 
54
- Your AI agent (Claude, Cursor, Copilot) builds UI by copying what is already in your repo. We measured it: 164 agent sessions on 10 real products, with and without this tool. On everyday work the agent reused the components and tokens it found and stayed on-system. It went off-system where the design system had no answer, a chart with no palette or a whole new theme, and it filled the gap the way the repo's own code did: by hand. So the mess an agent adds is a map of the gaps in your system. This tool measures the mess, names the gaps, and puts the check inside the agent's editor, so it runs whether or not the agent thinks to ask.
31
+ **The gaps, named.** A "Where agents will invent" section lists the places where the repo has no answer yet, with the files that prove each one and the single move that closes it. Today it knows one gap for certain, because the agent runs found it: charts that paint their series colours by hand in a repo with no chart palette. Across 126 public repos, 43 look like that. The list grows only when a gap has been measured, never guessed.
55
32
 
56
- ## Live examples
33
+ **A health score you can defend in a meeting.** 0 to 100, the same number every run, measured against 3 yardsticks: the ideal norms of a design system, the median of 34 scanned public products, and 10 reputable systems (Primer, Polaris, Carbon, shadcn/ui and others). Monorepos get a score per package, so `packages/ui` at 80 stops hiding `apps/web` at 40.
57
34
 
58
- The same eleven reports the landing page shows, hosted exactly as the tool generates them: self-contained HTML, every number deterministic, every path real. Four kits, a fresh install, a registry, Stencil, Lit and plain React.
35
+ **The receipts behind it.** Every colour and its near-identical twin. Every off-scale spacing value, typeface, duplicated or never-imported component, inline style block and `!important`, each with a real file path. One HTML file you can open, Slack or email.
59
36
 
60
- - **[npx shadcn create, fresh](https://gregkozakiewicz.github.io/roast-my-design-system/examples/shadcn-create-fresh.html)** (factory install, all 61 components): read as a fresh install: "the score is the kit's, not yours"; 13 colours, every theme variable in place, shadcn's own 24 bracket values named and not counted. No score: a fresh install is the kit's, not yours.
61
- - **[Unleash](https://gregkozakiewicz.github.io/roast-my-design-system/examples/unleash-mui.html)** (MUI): read as an MUI product: 1,109 files import the kit and the theme is read 6,166 times; 4 colours and 2 spacings per 100 kit files are written onto components. Score 60.
62
- - **[Metabase](https://gregkozakiewicz.github.io/roast-my-design-system/examples/metabase-mantine.html)** (Mantine): its own wrapper over Mantine counts as the kit, so 2,679 files are read instead of 392; nothing written onto components, 2 spacings per 100 kit files. Score 47.
63
- - **[SigNoz](https://gregkozakiewicz.github.io/roast-my-design-system/examples/signoz-antd.html)** (Ant Design): read as an Ant Design product: 2 colours and 7 spacings per 100 kit files written in style objects where a token exists. Score 51.
64
- - **[Apache Airflow](https://gregkozakiewicz.github.io/roast-my-design-system/examples/airflow-chakra.html)** (Chakra UI): read as a Chakra product: no colours written onto components, 4 spacings per 100 kit files as pixel strings where a space step exists. Score 43.
65
- - **[vercel/ai-chatbot](https://gregkozakiewicz.github.io/roast-my-design-system/examples/vercel-ai-chatbot.html)** (shadcn install): 74 values like [13px] written outside the Tailwind scale, and 66 palette colours per 100 files where a theme variable exists; Claude's notes embedded. Score 80.
66
- - **[excalidraw/excalidraw](https://gregkozakiewicz.github.io/roast-my-design-system/examples/excalidraw-excalidraw.html)**: 78 off-scale spacing values and 90 !important declarations. Score 55.
67
- - **[dubinc/dub](https://gregkozakiewicz.github.io/roast-my-design-system/examples/dubinc-dub.html)**: 622 arbitrary bracket values and 22 duplicated components. Score 20.
68
- - **[telekom/scale](https://gregkozakiewicz.github.io/roast-my-design-system/examples/telekom-scale.html)** (Stencil): 95 Stencil components read by tag; 66 spacing values outside the scale where about 12 would do; Claude's notes embedded. Score 55.
69
- - **[magicuidesign/magicui](https://gregkozakiewicz.github.io/roast-my-design-system/examples/magicui.html)** (registry): read as a shadcn registry and counted on the components it publishes: 52 off-theme colours per 100 files in the code it ships, its docs site kept out and named. Score 78.
70
- - **[adobe/spectrum-web-components](https://gregkozakiewicz.github.io/roast-my-design-system/examples/adobe-spectrum.html)** (Lit): hardcoded colours sitting beside 744 colour tokens, and 37 !important declarations. Score 66.
37
+ **The first fixes, ranked by payoff.** A "Where to start" list derived from your own numbers. Each move has a copy button with a ready-made fix prompt for your agent: the finding, the files, the expected payoff, and rules that respect deliberate craft. Fix, rescan, press the next button.
71
38
 
72
- ## Every command
39
+ **Rules that stop the mess coming back.** A generated `design-system-rules.md` with the canonical components, your token file and the known duplicates to avoid. `--apply` writes it into every agent file you have: Claude, Cursor, GitHub Copilot and Windsurf. Every scan also checks the rules you already have for stale references, and says which of your tools can actually read them.
73
40
 
74
- One scan powers all of it; the flags decide what lands on disk. Combine freely.
41
+ ## Three ways to use it
75
42
 
76
- ### Run it yourself
43
+ ### 1. Roast the repo
77
44
 
78
- Type these in a terminal and you get a result.
45
+ The scan and the report. The full flag list is under [Every command](#every-command).
79
46
 
80
- | Command                                                         | What you get |
81
- |---|---|
82
- | <code>npx&nbsp;roast-my-design-system@latest</code> | The scan and `design-system-roast.html`, opened in your browser |
83
- | <code>...&nbsp;&lt;path&gt;</code> | Scan a different repo than the current directory |
84
- | `... --apply` | The generated agent rules injected straight into every agent file you have: `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.cursor/rules/`, `.windsurfrules` and `.github/copilot-instructions.md`, inside a marked block. Re-running replaces only that block, never your own text. Windsurf and Copilot get a compact variant sized for their limits |
85
- | `... --rules` | The same rules written to `design-system-rules.md` instead, for pasting by hand |
86
- | `... --card` | `roast-card.svg`: a shareable 1200x630 card with the score and worst findings. Pure SVG, embeds in a README |
87
- | `... --sarif` | `design-system-roast.sarif` for GitHub code scanning: upload it in CI and findings appear in the Security tab, annotated on files |
88
- | `... --check` | The working tree's changed files checked against the design system, in the terminal. Exits 1 on findings, so it slots into scripts |
89
- | `/roast-my-design-system:review` (in Claude Code) | The same check in chat, from the plugin's second skill: each changed file's findings with the fix named, then the fixes applied and the check re-run |
90
- | <code>...&nbsp;--exclude&nbsp;lab/</code> | Leave a folder out of the scan (repeat the flag or comma-separate). Or list folders in a `.roastignore` file at the repo root. Either way the report says so in the header; see [Scoping the scan](#scoping-the-scan) |
91
- | `... --json` | The scan summary as JSON on stdout, for scripts and pipelines. Includes `schemaVersion`, the benchmark used, and every metric as a number, so two scans can be compared |
92
- | <code>...&nbsp;--by&nbsp;"Dwayne&nbsp;Hicks"</code> | Puts a name in the report header, for when you ran it for someone else |
93
- | <code>...&nbsp;--theme&nbsp;light</code>&nbsp;/ <code>--out&nbsp;&lt;file&gt;</code>&nbsp;/ <code>--no-open</code>&nbsp;/ <code>--open</code> | Light report, custom report path, never open the browser, always open it |
47
+ ```bash
48
+ npx roast-my-design-system@latest
49
+ ```
94
50
 
95
- ### For your agent
51
+ ### 2. Put the system inside the agent
96
52
 
97
- These need an agent.
53
+ The same engine as a local MCP server. Five read-only tools the agent calls while it writes UI, from "is there a Button already?" to "review my changes". The Claude Code plugin bundles it; any other client registers one command. See [Live answers over MCP](#live-answers-over-mcp).
98
54
 
99
- | Command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | What you get |
100
- |---|---|
101
- | <code>...&nbsp;--notes&nbsp;&lt;file.md&gt;</code> | The agent's read of this scan, embedded in the report as **"What the numbers mean"**: which findings matter, which good numbers are accidents, what to fix first. Labelled as written by AI and kept apart from the measured numbers. The Claude Code skill writes and passes it automatically; the flag is here so any agent can |
102
- | <code>...&nbsp;--section&nbsp;"Title"&nbsp;&lt;file.md&gt;</code> | A further agent-written chapter after the notes, same styling, same label, sub-headings allowed. Repeatable, so analysis that outgrows the notes still lives inside the report instead of a hand-built page |
103
- | `... --hook` | The check the Claude Code plugin runs after every edit, for hand-installed setups: reads the hook event on stdin, checks the one file that changed, prints only the findings the edit added as JSON. Always exits 0 |
104
- | `... --mcp` | The scan as a local MCP server: 5 tools your agent calls while writing UI, from "is there a Button already?" to "review my changes", plus the `roast-fix` prompt that serves the top fix from a fresh scan. See [Live answers over MCP](#live-answers-over-mcp) |
105
- | <code>/roast-my-design-system</code> (in&nbsp;Claude&nbsp;Code) | The full experience: the roast in chat *and* embedded in the report as "What the numbers mean", the rules offer, and the fix loop with Claude on your own numbers |
55
+ ```bash
56
+ claude mcp add roast -- npx roast-my-design-system@latest --mcp
57
+ ```
58
+
59
+ ### 3. Check what the agent changed
60
+
61
+ Three doors to the same check. `--check` reads your git diff in the terminal and exits 1 on findings, so it slots into a script. The plugin's `review` skill does it in chat. And the plugin's edit hook runs it after every file the agent edits, writes or produces with a shell command, handing back only the findings that edit added. The agent does not have to remember to ask.
62
+
63
+ ```bash
64
+ npx roast-my-design-system@latest --check
65
+ ```
66
+
67
+ For pull requests there is a sister package, [guard-my-design-system](https://github.com/gregkozakiewicz/guard-my-design-system): a GitHub Action that runs the same rules on the diff and fails the check when new mess arrives.
106
68
 
107
- Not to be confused with each other: **"Why this matters"** is generic, ships with the tool and reads the same in every report. **"What the numbers mean"** is your agent's read of your repo, and only appears when an agent passed it.
69
+ ## What the agent runs showed
108
70
 
109
- **One scan writes rules for every agent: Claude, Cursor, GitHub Copilot, and Windsurf.** Every scan also checks the agent rules you already have and flags stale references, no flag needed.
71
+ We ran Claude Code headless on 10 public products (cal.com, Dub, Metabase, Plausible, SigNoz, trigger.dev and four more), pinned to one commit each, and counted the design-system findings each session added, by this tool's own rules. 259 sessions, Sonnet 5 and Haiku 4.5, September 2026.
110
72
 
111
- ## Example use cases
73
+ Routine work did not drift, with or without help: 7 findings without this tool and 9 with it, over 80 sessions of moving panels and building dashboards. Invention drifted, and in the shape the repo already had. Three numbers:
112
74
 
113
- - **Pre-refactor audit.** Run `/roast-my-design-system` before a design-system cleanup to get the measured baseline: every colour, spacing value, duplicated component and inline style, with real file paths.
114
- - **Diagnosing almost-right AI output.** When Claude keeps generating UI that looks slightly off, the report shows which duplicated components and stray values it is imitating, and where the canonical ones live.
115
- - **Making the case without a meeting.** Drop the self-contained HTML report in Slack: a health score and 3 benchmarks (ideal norms, the median of 112 scanned repos, 10 reputable systems) argue for the design system for you.
116
- - **The fix loop.** Hand the report back to Claude as the punch list and work through the Where to start section, file by file.
75
+ - **28 to 2.** Findings a Christmas theme added across 10 products, without and with this tool. The agent called the MCP tools in every theme session.
76
+ - **42 in 16 runs, to 3 in 51.** Haiku 4.5 asked for a chart, a status colour, an empty state and a new component, without the tool and with the edit hook on.
77
+ - **10 in 20 runs, to 0 in 20.** Sonnet 5 asked for a chart, without and with the plugin installed. It called no tool and the hook never had to speak: the rules in its context were enough.
117
78
 
118
- The full report for vercel/ai-chatbot, top to bottom, including "What the numbers mean", Claude's read of the scan, embedded right under the verdict:
79
+ The agent does not always call a tool when it should: Sonnet in about one session in 3, Haiku never. A check on every edit does not have that problem. Nothing was rendered, so zero findings means on-system by these rules, a floor rather than a design review. Method, tables and limits are in the research write-up, which will be published separately.
80
+
81
+ ## Live examples
82
+
83
+ Eleven reports, hosted exactly as the tool writes them: self-contained HTML, every number deterministic, every path real. Four kits, a fresh install, a registry, Stencil, Lit and plain React.
84
+
85
+ - **[npx shadcn create, fresh](https://gregkozakiewicz.github.io/roast-my-design-system/examples/shadcn-create-fresh.html)** (factory install, all 61 components): read as a fresh install, "the score is the kit's, not yours"; 13 colours, every theme variable in place, shadcn's own 24 bracket values named and not counted. No score.
86
+ - **[Unleash](https://gregkozakiewicz.github.io/roast-my-design-system/examples/unleash-mui.html)** (MUI): 1,109 files import the kit and the theme is read 6,166 times; 4 colours and 2 spacings per 100 kit files are written onto components. Score 60.
87
+ - **[Metabase](https://gregkozakiewicz.github.io/roast-my-design-system/examples/metabase-mantine.html)** (Mantine): its own wrapper over Mantine counts as the kit, so 2,679 files are read instead of 392; nothing written onto components, 2 spacings per 100 kit files. Score 47.
88
+ - **[SigNoz](https://gregkozakiewicz.github.io/roast-my-design-system/examples/signoz-antd.html)** (Ant Design): 2 colours and 7 spacings per 100 kit files written in style objects where a token exists. Score 51.
89
+ - **[Apache Airflow](https://gregkozakiewicz.github.io/roast-my-design-system/examples/airflow-chakra.html)** (Chakra UI): no colours written onto components, 4 spacings per 100 kit files as pixel strings where a space step exists. Score 43.
90
+ - **[vercel/ai-chatbot](https://gregkozakiewicz.github.io/roast-my-design-system/examples/vercel-ai-chatbot.html)** (shadcn install): 74 values like [13px] written outside the Tailwind scale, and 66 palette colours per 100 files where a theme variable exists; Claude's notes embedded. Score 80.
91
+ - **[excalidraw/excalidraw](https://gregkozakiewicz.github.io/roast-my-design-system/examples/excalidraw-excalidraw.html)**: 78 off-scale spacing values and 90 !important declarations. Score 55.
92
+ - **[dubinc/dub](https://gregkozakiewicz.github.io/roast-my-design-system/examples/dubinc-dub.html)**: 622 arbitrary bracket values, 22 duplicated components, and the chart-palette gap named. Score 20.
93
+ - **[telekom/scale](https://gregkozakiewicz.github.io/roast-my-design-system/examples/telekom-scale.html)** (Stencil): 95 Stencil components read by tag; 66 spacing values outside the scale where about 12 would do; Claude's notes embedded. Score 55.
94
+ - **[magicuidesign/magicui](https://gregkozakiewicz.github.io/roast-my-design-system/examples/magicui.html)** (registry): counted on the components it publishes, 52 off-theme colours per 100 files in the code it ships, its docs site kept out and named. Score 78.
95
+ - **[adobe/spectrum-web-components](https://gregkozakiewicz.github.io/roast-my-design-system/examples/adobe-spectrum.html)** (Lit): hardcoded colours sitting beside 744 colour tokens, and 37 !important declarations. Score 66.
96
+
97
+ The full report for vercel/ai-chatbot, top to bottom, with "What the numbers mean", Claude's read of the scan, under the verdict:
119
98
 
120
99
  ![The full diagnosis report for vercel/ai-chatbot in dark mode: a fixed side panel with the health score and what it measures, the stack, how the repo was read as a shadcn install, an index of every section and what is not the team's and not counted; then the summary, the What the numbers mean analysis written by Claude, priced Where to start moves each with its copy-the-fix-prompt button, the wrapped present with the agent rules, an agent trap callout, 3-yardstick tiles including the 2 shadcn tiles, the adoption map treemap, palette forensics, the shadcn theme variable by variable, spacing receipts, typography specimens, offenders, duplicates, and the component usage ledger](assets/report-full-dark.png?v=9.0.6)
121
100
 
@@ -123,6 +102,16 @@ The same report in light mode (one file, built-in toggle):
123
102
 
124
103
  ![The diagnosis report in light mode](assets/report-light-hero.png?v=9.0.6)
125
104
 
105
+ ## What makes the numbers trustworthy
106
+
107
+ - **Deterministic.** A zero-dependency Node script reads every file, about a second on a normal repo, and returns the same numbers every run.
108
+ - **Read-only, no network, no telemetry.** Nothing in your repo is modified and nothing about your code leaves your machine. The suite fails if package.json ever declares a dependency.
109
+ - **Honest gaps and exclusions.** What the scan cannot read says "not measured" and drops out of the score. Test files, stories, docs sites, artwork and email templates are left out, and your own exclusions are printed in the report header with file counts.
110
+ - **A real benchmark.** 112 public React repos scanned; a core fleet of 34 sets the medians, the rest feed the kit profiles so a shadcn repo is compared with shadcn repos. Ten reputable systems (Primer, Polaris, Carbon, GOV.UK and others) are the second yardstick. The builder is in `tools/benchmark/`, so the ruler can be checked.
111
+ - **Importable scoring.** `scoreHarvest(harvest)` returns the score and metrics as plain data; the report and a CI check get the same numbers.
112
+
113
+ The longer version, with what each exclusion covers, how a scan is scoped and what the plugin runs on your machine, is in [docs/reference.md](docs/reference.md).
114
+
126
115
  ## What it works on
127
116
 
128
117
  **Supported**
@@ -133,45 +122,47 @@ The same report in light mode (one file, built-in toggle):
133
122
  - 5 kit profiles: Tailwind theme, MUI, Mantine, Chakra, Ant Design.
134
123
  - Any styling on top: Tailwind, styled-components, Emotion, Sass, Less, vanilla-extract, Stitches, CVA, CSS Modules.
135
124
 
136
- **Recognised, not supported yet but on the roadmap**
125
+ **Recognised, not supported yet**
137
126
 
138
127
  - Vue, Angular and Svelte: named in the header, colours and spacing still counted, but components are not measured and the report says so.
139
128
  - HeroUI, NextUI, Radix Themes, Fluent UI, React Bootstrap and Grommet: named in the header, no kit rules.
140
129
 
141
- ## What makes the numbers trustworthy
142
-
143
- - **Deterministic scanner, not AI sampling.** A zero-dependency Node script reads *every* file (about a second on a normal repo, a few on a large monorepo) and returns the same numbers every run. Claude narrates; it never counts.
144
- - **Read-only.** Nothing in your repo is modified. The only outputs are a temp JSON and the HTML report.
145
- - **No network, no telemetry.** Everything runs locally. Nothing about your code leaves your machine. Dependency scanners such as Socket may flag URL strings in this package; they are product links and format identifiers written into generated reports, never fetched.
146
- - **Zero dependencies, enforced by the test suite.** The package installs nothing but itself. That is a tested promise rather than a habit: the suite fails if package.json ever declares a dependency. The exact file list npm ships is a photographed contract too, so nothing can stow away in a release.
147
- - **Honest gaps.** When a repo's components register in a pattern the scan can not read, the component tiles say "not measured" and drop out of the score. A zero the scanner never earned is presented as blindness, not discipline.
148
- - **Honest exclusions.** Test files, Storybook stories, docs sites, example apps, SVG artwork, and email templates (which *must* inline styles) are excluded, so you can't discredit the numbers on a technicality. Your own exclusions (`.roastignore`, `--exclude`) are printed in the report header with file counts, so a scoped scan can never pass itself off as the whole repo.
149
- - **Intent-aware counting (v3).** Runtime-computed inline styles, compound-component APIs and wrapper components are not crimes and are not counted as ones. Token-led repos are judged on their hardcoded strays, not their token architecture. Repeated arbitrary values are read as decisions without names, not drift.
150
- - **The scoring code can be imported.** `scoreHarvest(harvest)` in `diagnose/score.mjs` returns the score, the nine tile results and the metrics as plain data. The report uses the same function. A CI check gets the same numbers as the page, and every `summary.json` records its schema version and the benchmark used.
151
- - **A real benchmark.** The "Avg Design System" yardstick comes from scanning 112 public React repos. A core fleet of 34 (cal.com, excalidraw, supabase, grafana, twenty, dub, langfuse…) sets the medians for ordinary product repos: 118 colours, 21 greys, 23 off-scale spacing values, 21 duplicated components, 51 inline style blocks, 77 arbitrary Tailwind values. The other 78 were scanned for the kit profiles, so a repo built on shadcn, Tailwind, MUI, Mantine, Chakra or Ant Design is compared with repos built the same way. The builder and the repo list are in `tools/benchmark/`, so the ruler can be checked, not just quoted.
152
- - **A second yardstick: reputable systems.** Curated, scoped scans of 10 well-known design systems (shadcn/ui, Primer, Polaris, Carbon, Material UI, Chakra, Ant Design, GOV.UK, Spectrum, Cloudscape) show what disciplined looks like at scale.
130
+ ## Every command
153
131
 
154
- ## Scoping the scan
132
+ One scan powers all of it; the flags decide what lands on disk. Combine freely.
155
133
 
156
- Some repos host more than one visual world on purpose: the product plus a marketing site, a playground, a batch of experiments. Blending them produces a score that describes none of them. Scope the scan to the design system you are actually judging:
134
+ ### Run it yourself
157
135
 
158
- ```bash
159
- npx roast-my-design-system@latest --exclude lab/ --exclude playground/
160
- ```
136
+ | Command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | What you get |
137
+ |---|---|
138
+ | <code>npx&nbsp;roast-my-design-system@latest</code> | The scan and `design-system-roast.html`, opened in your browser |
139
+ | <code>...&nbsp;&lt;path&gt;</code> | Scan a different repo than the current directory |
140
+ | `... --apply` | The generated agent rules injected into every agent file you have: `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.cursor/rules/`, `.windsurfrules` and `.github/copilot-instructions.md`, inside a marked block. Re-running replaces only that block, never your own text. |
141
+ | `... --rules` | The same rules written to `design-system-rules.md` instead, for pasting by hand |
142
+ | `... --card` | `roast-card.svg`: a shareable 1200x630 card with the score and worst findings. Pure SVG, embeds in a README |
143
+ | `... --sarif` | `design-system-roast.sarif` for GitHub code scanning: upload it in CI and findings appear in the Security tab, annotated on files |
144
+ | `... --check` | The working tree's changed files checked against the design system, in the terminal. Exits 1 on findings, so it slots into scripts |
145
+ | `/roast-my-design-system:review` (in Claude Code) | The same check in chat, from the plugin's second skill: each changed file's findings with the fix named, then the fixes applied and the check re-run |
146
+ | <code>...&nbsp;--exclude&nbsp;lab/</code> | Leave a folder out of the scan (repeat the flag or comma-separate). Or list folders in a `.roastignore` file at the repo root. Either way the report says so in the header |
147
+ | `... --json` | The scan summary as JSON on stdout, for scripts and pipelines. Includes `schemaVersion`, the benchmark used, and every metric as a number, so two scans can be compared |
148
+ | <code>...&nbsp;--by&nbsp;"Dwayne&nbsp;Hicks"</code> | Puts a name in the report header, for when you ran it for someone else |
149
+ | <code>...&nbsp;--theme&nbsp;light</code>&nbsp;/ <code>--out&nbsp;&lt;file&gt;</code>&nbsp;/ <code>--no-open</code>&nbsp;/ <code>--open</code> | Light report, custom report path, never open the browser, always open it |
161
150
 
162
- Or make it permanent with a `.roastignore` file at the repo root, one repo-relative folder per line:
151
+ ### For your agent
163
152
 
164
- ```
165
- # separate visual worlds, not the product's design system
166
- lab/
167
- playground/
168
- ```
153
+ | Command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | What you get |
154
+ |---|---|
155
+ | <code>...&nbsp;--notes&nbsp;&lt;file.md&gt;</code> | The agent's read of this scan, embedded in the report as **"What the numbers mean"**: which findings matter, which good numbers are accidents, what to fix first. Labelled as written by AI and kept apart from the measured numbers. The Claude Code skill writes and passes it automatically; the flag is here so any agent can |
156
+ | <code>...&nbsp;--section&nbsp;"Title"&nbsp;&lt;file.md&gt;</code> | A further agent-written chapter after the notes, same styling, same label, sub-headings allowed. Repeatable |
157
+ | `... --hook` | The check the Claude Code plugin runs after every edit, for hand-installed setups: reads the hook event on stdin, checks the file that changed, prints only the findings the edit added as JSON. Always exits 0 |
158
+ | `... --mcp` | The scan as a local MCP server: 5 tools your agent calls while writing UI, plus the `roast-fix` prompt that serves the top fix from a fresh scan. See [Live answers over MCP](#live-answers-over-mcp) |
159
+ | <code>/roast-my-design-system</code> (in&nbsp;Claude&nbsp;Code) | The full experience: the roast in chat *and* embedded in the report as "What the numbers mean", the rules offer, and the fix loop with Claude on your own numbers |
169
160
 
170
- Both routes merge, and both are loud on purpose. The harvest JSON records every active pattern and how many files it removed. The report prints a line in the header ("2 folders excluded by .roastignore (lab/, playground/) · 946 files kept out of this scan"). You can narrow the question, but the report always says which question was asked, so a scoped score can't be quietly gamed. There is no negation and no glob syntax: plain folder prefixes, nothing clever.
161
+ **"Why this matters"** is generic, ships with the tool and reads the same in every report. **"What the numbers mean"** is your agent's read of your repo, and only appears when an agent passed it.
171
162
 
172
163
  ## Live answers over MCP
173
164
 
174
- The report and the rules file describe the repo as it was at scan time. `--mcp` keeps the same engine running while your agent works, so questions get answered from the code as it is right now, and mistakes get caught before they land:
165
+ The report and the rules file describe the repo as it was at scan time. `--mcp` keeps the same engine running while your agent works, so questions get answered from the code as it is right now, and mistakes get caught before they land.
175
166
 
176
167
  | Tool | The question it answers |
177
168
  |---|---|
@@ -183,78 +174,45 @@ The report and the rules file describe the repo as it was at scan time. `--mcp`
183
174
 
184
175
  The loop: context before building, find while building, validate before saving, review before finishing.
185
176
 
186
- Charts get their own rule, because a chart needs several colours that differ from each other and most design systems never name them. In a repo that keeps a chart palette (its own `--chart-*` or `--series-*` tokens, a `chartColors` entry in the theme, or shadcn's `--chart-1` to `--chart-5` when a chart actually reads them), a colour written by hand in a chart file is a finding that names the palette. In a repo that has charts but no palette, a new chart that paints by hand gets one warning that names the existing chart doing the same and asks for the palette once. The first chart in a repo gets one warning asking for a name. The report never counted chart colours; the live checks now agree with it.
187
-
188
- The server reads the repo the way the report does. On a product built on MUI, Mantine, Chakra UI or Ant Design, the context names the theme file and the kit's own way of reading it, `roast_find_token` answers in spacing steps (`12px` is `p: 3` on a 4px MUI theme), and `roast_validate` and `roast_review` flag a colour or a pixel size written onto a kit component where the theme has a value. On a Tailwind theme or a shadcn repo they flag a palette class such as `text-gray-500` or `ring-green-500` where the theme names a colour of that kind.
189
-
190
- ### What a session looks like
191
-
192
- A real exchange against [Unleash](https://github.com/Unleash/unleash), an MUI product that scores 60/100. The agent was asked to add a small usage hint to a feature page. Every answer is the server's own text, unedited.
193
-
194
- Before writing anything, the agent calls `roast_get_context`:
177
+ One real exchange, against [Unleash](https://github.com/Unleash/unleash), an MUI product at 60/100. The agent has a grey in hand and a padding in mind:
195
178
 
196
179
  ```
197
- KIT: MUI (1109 files import it, the theme is read 6162x). A colour, a spacing step or a radius is decided in frontend/src/themes/dark-theme.ts. On a component, read it: sx paths (color: 'text.secondary', p: 2) or theme.palette / theme.spacing() in styled().
198
- 43 colours are already written onto components (#6c65e5, #f1f0fc, #302e42); do not add one.
199
- USE THESE, DO NOT REBUILD THEM:
200
- <Dialogue> from frontend/src/component/common/Dialogue/Dialogue.tsx (97x)
201
- <TextCell> from frontend/src/component/common/Table/cells/TextCell/TextCell.tsx (96x)
202
- <PageContent> from frontend/src/component/common/PageContent/PageContent.tsx (84x)
203
- DUPLICATES, DO NOT MAKE IT WORSE:
204
- <StyledSuccessIcon> exists in 6 places; match what the surrounding code imports, never create another.
205
- SPACING: Use spacing steps (p: 2), not pixels. 17 pixel sizes are already written onto components; do not add one.
206
- TYPE: Sen. No new typefaces, no hand-declared font stacks.
207
- Before finishing: call roast_validate on what you wrote, then roast_review.
208
- ```
180
+ roast_find_token #6b7280
181
+ → Nearest token: #607d8b, 11 channel steps from #6b7280. Unless the difference is a deliberate decision, use the token.
209
182
 
210
- It has a grey in hand and a padding in mind, so `roast_find_token` twice:
183
+ roast_validate (first draft)
184
+ → ✕ L5 Colour #6b7280 written onto an MUI component, and the theme has no such colour.
185
+ Fix: Add it to the theme once (frontend/src/themes/dark-theme.ts), then read it there: color: 'text.secondary' in sx.
186
+ ✕ L5 Pixel size p: 12px on an MUI component.
187
+ Fix: 12px is between steps 1 (8px) and 2 (16px). Keep it with a comment, or use the nearest step in sx.
211
188
 
212
- ```
213
- #6b7280 → Nearest token: #607d8b, 11 channel steps from #6b7280. Unless the difference is a deliberate decision, use the token.
214
- 12px → 12px is between steps 1 (8px) and 2 (16px) on the default theme. If the design needs 12px exactly, keep it with a comment; otherwise use the nearest step in sx.
189
+ roast_validate (second draft: color: 'text.secondary', p: 1.5)
190
+ → No measured violations found. Checked: hardcoded colours vs the token set, near-identical colour twins, off-scale spacing …
215
191
  ```
216
192
 
217
- It writes a first draft anyway and runs `roast_validate` before saving:
193
+ Four calls, under 800 tokens, and the new component reads the theme instead of adding colour number 44.
218
194
 
219
- ```
220
- 2 findings:
221
- ✕ L5 Colour #6b7280 written onto an MUI component, and the theme has no such colour.
222
- Fix: Add it to the theme once (frontend/src/themes/dark-theme.ts), then read it there. On an MUI component, point at it: color: 'text.secondary' in sx, or theme.palette.primary.main in a styled() call.
223
- ✕ L5 Pixel size p: 12px on an MUI component.
224
- Fix: 12px is between steps 1 (8px) and 2 (16px) on the default theme. If the design needs 12px exactly, keep it with a comment; otherwise use the nearest step in sx.
225
- ```
195
+ Charts get their own rule, because a chart needs several colours that differ from each other and most design systems never name them. Where a repo keeps a chart palette, a colour written by hand in a chart file is a finding that names the palette. Where a repo has charts but no palette, a new chart that paints by hand gets one warning that names the existing chart doing the same and asks for the palette once. That warning is the gap report, live.
226
196
 
227
- Second draft: `color: 'text.secondary'`, `p: 1.5`, the radius read from the theme. `roast_validate` again:
197
+ The server reads the repo the way the report does. On a product built on MUI, Mantine, Chakra UI or Ant Design, the context names the theme file and the kit's own way of reading it, `roast_find_token` answers in spacing steps, and the checks flag a colour or a pixel size written onto a kit component where the theme has a value. On a Tailwind theme or a shadcn repo they flag a palette class such as `text-gray-500` where the theme names a colour of that kind.
228
198
 
229
- ```
230
- No measured violations found. Checked: hardcoded colours vs the token set, near-identical colour twins, off-scale spacing, off-scale radii, font sizes and shadows, typefaces outside the system, arbitrary bracket values, static inline style blocks, !important, duplicate component definitions, new colour tokens that twin an existing token, imports of a duplicate the canonical copy replaces, chart colours against the chart palette, colours and pixel sizes written onto kit components where the theme has a value.
231
- ```
199
+ The `roast-fix` prompt serves the top Where-to-start move from a fresh scan, byte-identical to the report's copy buttons. In Claude Code type `/mcp__roast__roast-fix`, add a number to jump the queue. Fix it, ask again, and the next move has risen to the top: the scan is the progress bar.
232
200
 
233
- Four calls, under 800 tokens in total, and the new component reads the theme instead of adding colour number 44. `roast_review` then checks the whole diff the same way before the agent says it is done.
234
-
235
- When the goal is fixing the system rather than building on it, the `roast-fix` prompt serves the top Where-to-start move from a fresh scan. It is a ready-made fix prompt, byte-identical to the report's copy buttons. Fix it, ask again, and the next move has risen to the top: the scan is the progress bar. Pass `move: 2` to jump the queue.
236
-
237
- To use it in Claude Code, type `/mcp__roast__roast-fix` in the chat. MCP prompts appear as slash commands, named after whatever you registered the server as, and the `/` autocomplete menu lists them too. Add the move number to jump the queue: `/mcp__roast__roast-fix 2`. Other clients list server prompts in their own prompt picker; wherever `roast-build-ui` and `roast-review-ui` show up, `roast-fix` sits beside them.
238
-
239
- **Installed the Claude Code plugin?** The server is already there: the plugin bundles it, so the five tools appear as soon as the plugin is enabled. Nothing to add.
240
-
241
- Otherwise, add it to Claude Code by hand:
201
+ **Installed the Claude Code plugin?** The server is already there. Otherwise:
242
202
 
243
203
  ```bash
244
204
  claude mcp add roast -- npx roast-my-design-system@latest --mcp
245
205
  ```
246
206
 
247
- **Verified in Claude Code, Cursor, and Windsurf (now Devin Desktop).** Each was tested end to end: server connected, all 5 tools listed, real answers in the editor's own chat. Same promise as the scan: local, read-only, one scan at startup, no port, no account, nothing about your code leaves your machine. A clean answer reads "no measured violations found" with the list of checks attached, because a scanner can only certify what it can count.
207
+ **Verified in Claude Code, Cursor and Windsurf (now Devin Desktop).** Each was tested end to end: server connected, all 5 tools listed, real answers in the editor's own chat. Local, read-only, one scan at startup, no port, no account.
248
208
 
249
- **Cursor**: put this in `.cursor/mcp.json` inside the project (the project, not your home directory, so the scan sees one repo, not your whole disk):
209
+ **Cursor**: put this in `.cursor/mcp.json` inside the project (the project, so the scan sees one repo, not your whole disk), then enable `roast` under Settings → Tools & MCP the first time:
250
210
 
251
211
  ```json
252
212
  { "mcpServers": { "roast": { "command": "npx", "args": ["roast-my-design-system", "--mcp"] } } }
253
213
  ```
254
214
 
255
- Cursor holds workspace servers at arm's length until you approve them: open Settings → Tools & MCP and enable `roast` the first time. The first start takes a few seconds while npx fetches the package; Cursor retries on its own.
256
-
257
- **Windsurf (Devin Desktop)**: its MCP config is global (`~/.codeium/windsurf/mcp_config.json`), so name the project folder in the entry to keep the scan scoped to one repo:
215
+ **Windsurf (Devin Desktop)**: its MCP config is global (`~/.codeium/windsurf/mcp_config.json`), so name the project folder to keep the scan scoped to one repo:
258
216
 
259
217
  ```json
260
218
  { "mcpServers": { "roast": { "command": "npx", "args": ["roast-my-design-system", "--mcp", "/path/to/your/repo"] } } }
@@ -264,7 +222,7 @@ Any other MCP client can register the same stdio command.
264
222
 
265
223
  ## In CI
266
224
 
267
- The scanner already speaks SARIF, so wiring it into GitHub code scanning is 6 lines. Findings appear in the Security tab, annotated on the files themselves:
225
+ The scanner speaks SARIF, so wiring it into GitHub code scanning is 6 lines. Findings appear in the Security tab, annotated on the files themselves:
268
226
 
269
227
  ```yaml
270
228
  - uses: actions/checkout@v5
@@ -274,16 +232,16 @@ The scanner already speaks SARIF, so wiring it into GitHub code scanning is 6 li
274
232
  sarif_file: design-system-roast.sarif
275
233
  ```
276
234
 
235
+ To fail a pull request on new mess only, use [guard-my-design-system](https://github.com/gregkozakiewicz/guard-my-design-system).
236
+
277
237
  ## Install
278
238
 
279
- **No install, no Claude needed. Just try it:**
239
+ **No install, no Claude needed:**
280
240
 
281
241
  ```bash
282
242
  npx roast-my-design-system@latest
283
243
  ```
284
244
 
285
- Run it inside any repo. Same scanner, same report, straight from npm. The Claude Code skill below adds the conversation on top: the roast in chat, then a punch list you can actually work through with Claude.
286
-
287
245
  **Claude Code (recommended):**
288
246
 
289
247
  ```bash
@@ -291,18 +249,16 @@ Run it inside any repo. Same scanner, same report, straight from npm. The Claude
291
249
  /plugin install roast-my-design-system@roast-my-design-system
292
250
  ```
293
251
 
294
- What it installs: two skills, one local MCP server and one edit hook, nothing else. **roast** (`/roast-my-design-system`, or "roast my design system") scans the whole repo and writes the report with Claude's read of the numbers inside it, then walks the fixes with you. **review** (`/roast-my-design-system:review`, or "review my UI changes") checks only what changed, in about a second. The bundled server gives your agent five read-only tools while it writes UI. The hook runs after every file the agent edits and hands back the findings that edit added, so the check happens whether or not the agent thought to ask; a file with nothing new gets no message. Local, no network, no telemetry.
295
-
296
- If those commands error, your Claude Code is likely older than the plugin marketplace feature. Update Claude Code and retry, or use the manual route below: it works everywhere and installs the same skill.
252
+ What it installs: two skills, one local MCP server and one edit hook, nothing else. **roast** (`/roast-my-design-system`, or "roast my design system") scans the whole repo, writes the report with Claude's read of the numbers inside it, then walks the fixes with you. **review** (`/roast-my-design-system:review`, or "review my UI changes") checks only what changed, in about a second. The hook runs after every file the agent edits and hands back the findings that edit added; a file with nothing new gets no message.
297
253
 
298
- **Manual (Claude Code, any version):**
254
+ If those commands error, your Claude Code is older than the plugin marketplace. Update it, or use the manual route:
299
255
 
300
256
  ```bash
301
257
  git clone https://github.com/gregkozakiewicz/roast-my-design-system.git
302
258
  cp -r roast-my-design-system/skills/roast-my-design-system roast-my-design-system/skills/review ~/.claude/skills/
303
259
  ```
304
260
 
305
- (Use `.claude/skills/` inside a repo instead to share it with your team. The `review` skill needs the `roast-my-design-system` folder beside it; it runs the engine from there.)
261
+ (Use `.claude/skills/` inside a repo to share it with your team. The `review` skill needs the `roast-my-design-system` folder beside it.)
306
262
 
307
263
  **OpenAI Codex CLI** (same SKILL.md, same folder):
308
264
 
@@ -311,9 +267,9 @@ git clone https://github.com/gregkozakiewicz/roast-my-design-system.git
311
267
  cp -r roast-my-design-system/skills/roast-my-design-system ~/.codex/skills/
312
268
  ```
313
269
 
314
- Invoke with `$roast-my-design-system` (or let Codex auto-match it). Use `.codex/skills/` inside a repo to share with your team.
270
+ Invoke with `$roast-my-design-system`. Use `.codex/skills/` inside a repo to share with your team.
315
271
 
316
- **`npx skills`:** `npx skills add gregkozakiewicz/roast-my-design-system` works for agents that read `~/.agents/skills/`. Claude Code currently reads `~/.claude/skills/`, so prefer one of the routes above.
272
+ **`npx skills`:** `npx skills add gregkozakiewicz/roast-my-design-system` works for agents that read `~/.agents/skills/`. Claude Code reads `~/.claude/skills/`, so prefer one of the routes above.
317
273
 
318
274
  Requires Node 18+.
319
275
 
@@ -325,7 +281,7 @@ Open Claude Code in the repo you want roasted and type:
325
281
  /roast-my-design-system
326
282
  ```
327
283
 
328
- And once you have a design system worth protecting, the second skill checks only what you changed, in about a second:
284
+ Once you have a design system worth protecting, the second skill checks only what you changed:
329
285
 
330
286
  ```
331
287
  /roast-my-design-system:review
@@ -333,22 +289,20 @@ And once you have a design system worth protecting, the second skill checks only
333
289
 
334
290
  It runs the same check as `--check` on the files in your git diff and lists each finding with its fix, in the kit's own vocabulary on a MUI, Mantine, Chakra, Ant Design or Tailwind-theme repo. No score, no report: the small check for Tuesday afternoons. Claude also picks it up from plain words such as "review my UI changes" or "did I break the design system".
335
291
 
336
- You get the roast in chat plus `design-system-roast.html` at your repo root: a self-contained page (open it, Slack it, email it, no external requests) with:
292
+ You get the roast in chat plus `design-system-roast.html` at your repo root, a self-contained page with:
337
293
 
338
294
  - a **health score** computed from how your numbers sit against the ideal
339
- - **"What the numbers mean"**: Claude's read of your scan. Which findings actually matter, which good numbers are accidents, what to fix first. It is embedded in the same file you'll forward, labelled as written by Claude and kept apart from the measured numbers. The score alone can flatter; this section is what keeps a shared 85/100 honest
340
- - stat tiles comparing you to all 3 yardsticks: Ideal, the benchmark median (112 scanned repos), and the reputable systems
295
+ - **"What the numbers mean"**: Claude's read of your scan, embedded in the file you'll forward, labelled as written by Claude and kept apart from the measured numbers. The score alone can flatter; this section keeps a shared 85/100 honest
296
+ - stat tiles comparing you to all 3 yardsticks
341
297
  - a **light/dark theme toggle** in one file
342
298
  - the usage-weighted palette bar, the grey ramp, the off-scale spacing receipts, the duplicate-component receipts with clickable file paths, and the worst-offenders ledger
343
299
  - a **Where to start** close: up to 3 moves derived from your repo's own numbers, each with a file-path receipt
344
300
  - a **Where agents will invent** list: the gaps where the repo has no answer yet, with the files that prove each one and the move that closes it
345
- - a **present** 🎁 below it: you sat through the roast, so `design-system-rules.md` is wrapped inside the report itself. Unwrap, then copy or download the agent rules generated from your scan.
346
-
347
- After the roast, the skill also offers to write `design-system-rules.md` to disk and merge it into your CLAUDE.md, `.cursor/rules` or AGENTS.md.
301
+ - a **present** 🎁 below it: `design-system-rules.md` wrapped inside the report. Unwrap, then copy or download the agent rules generated from your scan
348
302
 
349
- ### Three prompts to try
303
+ After the roast, the skill offers to write `design-system-rules.md` to disk and merge it into your CLAUDE.md, `.cursor/rules` or AGENTS.md.
350
304
 
351
- Type any of these in Claude Code, inside the repo:
305
+ ### Four prompts to try
352
306
 
353
307
  ```
354
308
  Roast my design system.
@@ -358,7 +312,7 @@ Roast my design system.
358
312
  How bad is my CSS? Scan this repo and show me the receipts.
359
313
  ```
360
314
 
361
- With the MCP server connected (see [Live answers over MCP](#live-answers-over-mcp)):
315
+ With the MCP server connected:
362
316
 
363
317
  ```
364
318
  Is there already a Button component in this repo, and which one should I use?
@@ -372,28 +326,19 @@ Review my UI changes against the design system.
372
326
 
373
327
  ## Troubleshooting
374
328
 
375
- - **"Command not found" or the plugin will not install.** Update Claude Code; the plugin marketplace needs a recent version. The manual install above works on any version.
329
+ - **"Command not found" or the plugin will not install.** Update Claude Code; the plugin marketplace needs a recent version. The manual install works on any version.
376
330
  - **"Nothing to roast" or a near-empty report.** The scan found almost no colours or spacing. The styling probably lives in another repo, a CDN or an installed package. Run it from the repo that holds the styles.
377
- - **A score that looks wrong.** Check the header of the report: it names how the repo was read (product, library, shadcn, a kit, a Tailwind theme) and every folder that was left out. Scope the scan with a `.roastignore` file or `--exclude` if a playground or an old app is blurring the numbers.
331
+ - **A score that looks wrong.** Check the report header: it names how the repo was read (product, library, shadcn, a kit, a Tailwind theme) and every folder that was left out. Scope the scan with `.roastignore` or `--exclude` if a playground or an old app is blurring the numbers.
378
332
  - **The report did not open.** It is written to `design-system-roast.html` at the repo root. Open it in any browser; it needs no server and makes no requests.
379
- - **The MCP server does not appear.** Restart the client after adding it. In Claude Code, `claude mcp list` shows whether it connected. Everything it needs is Node 18 or newer.
333
+ - **The MCP server does not appear.** Restart the client after adding it. In Claude Code, `claude mcp list` shows whether it connected. It needs Node 18 or newer.
380
334
 
381
335
  ## Support
382
336
 
383
337
  Bugs and questions go to [GitHub Issues](https://github.com/gregkozakiewicz/roast-my-design-system/issues). Everything else reaches Greg through [gregkozakiewicz.com](https://gregkozakiewicz.com). Security problems: see [SECURITY.md](SECURITY.md).
384
338
 
385
- ## For reviewers
386
-
387
- What runs on a user's machine, and what does not, in one place.
388
-
389
- - **The plugin runs three things, all from its own folder.** Two skills, which run `node` on scripts inside the plugin; one local MCP server, started with `node` on a script inside the plugin; and one edit hook, which runs the bundled CLI on the file that changed. Nothing is downloaded at install or run time, nothing is fetched from the network, and nothing leaves the machine. There is no telemetry and no credential is read.
390
- - **The rest of the repository is tooling and documentation, never run by the plugin.** `.github/workflows` publishes a tagged version to npm and the MCP registry from GitHub, with no stored secrets; the release script that cuts the tag lives outside this repository; `tools/benchmark` rebuilds the benchmark from public repos; `tests` is the snapshot suite; `docs` is the landing page and the hosted example reports; `assets` holds the README screenshots, the logo and the icon. A scanner reading the whole folder sees these too. None of them is reachable from a skill, the server or the hook.
391
- - **`npx roast-my-design-system@latest` appears in the documentation only.** It is how people run the scanner without the plugin. The plugin itself never calls a package launcher.
392
- - **Images.** The PNGs are the two README screenshots, the logo marks, and the seven link-preview cards the hosted example pages reference. No code opens them.
393
-
394
339
  ## Privacy
395
340
 
396
- The tool reads the repository you point it at and writes its output next to it. It makes no network requests, collects no data, and has no telemetry. The MCP server answers from the same local scan and never leaves the machine. Nothing about your code, your prompts or your conversation is sent to anyone, including the author.
341
+ The tool reads the repository you point it at and writes its output next to it. It makes no network requests, collects no data, and has no telemetry. The MCP server answers from the same local scan. Nothing about your code, your prompts or your conversation is sent to anyone, including the author.
397
342
 
398
343
  ## What it measures
399
344
 
@@ -411,7 +356,7 @@ The tool reads the repository you point it at and writes its output next to it.
411
356
  | !important declarations | 0 | 5 | 3 |
412
357
  | Components never imported | 0 | 0 | 0 |
413
358
 
414
- Yes, the median repo is already a mess. That's the point.
359
+ Yes, the median repo is already a mess. That is the point. An agent arriving in it will copy the mess faithfully and, where the mess runs out, add some of its own.
415
360
 
416
361
  **Your AI can write the UI. This makes sure it writes *your* UI.**
417
362
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roast-my-design-system",
3
- "version": "9.0.6",
3
+ "version": "9.0.7",
4
4
  "mcpName": "io.github.gregkozakiewicz/roast-my-design-system",
5
5
  "description": "Your AI can write the UI. This makes sure it writes your UI. A deterministic scanner scores your design system 0-100 against 112 public repos, reads React and web components (Stencil, Lit), hands you a copy-paste fix prompt for each top finding, writes rules for Claude, Cursor, Copilot and Windsurf with --apply, and runs as a local MCP server with --mcp.",
6
6
  "keywords": [
@@ -1,7 +1,7 @@
1
1
  // Single version constant for the engine — imported by diagnose (report
2
2
  // footer) and rules (generated-by line). This is the bump spot that used to
3
3
  // live as a const inside diagnose/index.mjs.
4
- export const VERSION = '9.0.6';
4
+ export const VERSION = '9.0.7';
5
5
  // The shape of harvest.json and summary.json. Bumped only when a field is
6
6
  // renamed, removed or changes meaning; a new field is not a new schema. A
7
7
  // tool comparing two scans compares like with like by this number, not by VERSION.