Design System Component Usage Audit
Find where the codebase hand-codes UI that the project's own design-system components already provide, and where those components are used with manual styling that a variant should own. Report findings; optionally autofix the mechanical ones. $ARGUMENTS
Parameters
scan-path (optional) — root to audit. Default: repo src/ (or repo root if no src/).
autofix — autofix/autofix=true forces the fix phase ON; autofix=false forces OFF; omitted → report only.
Core Principle
Trust the component's built-in props (variants, sizes, icon slotting) instead of re-applying styles by hand. When a recurring visual need has no variant (e.g. an always-purple button), add a variant to the component or componentize the pattern, keeping every styled native element attached to the component it belongs to.
Workflow
Step 1: Inventory the design system FIRST
Discovery is generalized — no config assumed. Auto-detect, then read real APIs.
- Locate the components folder(s). Spawn an
Explore sub-agent (breadth: medium, no model param) to glob common roots under the scan path — **/lib/components/**, **/components/**, **/ui/** — and return the component folder paths. Strong signals: a directory of single-purpose folders each with a .svelte/.tsx + an index.ts + a variants file.
- Detect the stack. Check
package.json and imports for bits-ui, shadcn, radix-ui, cva, tailwind-variants (tv). If the project is shadcn-svelte / Bits UI, treat rules-per-project/shadcn-svelte.md as the canonical anti-pattern source and feed its rules to the audit agents.
- Read each base component's real prop API. Open variant definitions (
*_variants.ts, cva()/tv() configs, prop/type declarations) to learn actual variant/intent/size values and icon-slot conventions. Read prop names from the source rather than assuming them.
- Build the inventory — for each component: name, import path, available variants/sizes, and which native element(s) it replaces (
button→Button, input→Input, calendar/date field→date picker, etc.).
- Record the exclusion set — the component-implementation folder(s) themselves, plus generated/vendored files. These are always excluded from audit targets.
The inventory string seeds every sub-agent prompt — agents must audit against the components that actually exist, not a generic list.
Step 2: Fan-out audit (parallel sub-agents)
See ../shared/EXPLORATION.md for delegation policy. Spawn Explore sub-agents in parallel (breadth: medium), roughly one per base component or component group (per user preference), each given: the inventory, the exclusion set, and one axis checklist from CHECKLISTS.md. For large component sets, run the agents run_in_background: true and process findings as each returns.
Audit axes (see CHECKLISTS.md for the concrete patterns per axis):
- A — Native element → component: raw
<button>, <input>, <select>, <textarea>, <hr>, animate-pulse divs, styled spans, callout divs that should be the design-system component.
- B — Improper variant/prop usage: manual classes that duplicate or override a variant (
<Button class="rounded-lg">, color overrides defeating intent/variant), wrong variant, missing size="icon", manual icon sizing.
- C — Componentize / add-variant: repeated detached-style patterns (the "always purple button") → add a variant to the component or extract a component. Each finding is tagged C-clear (mechanical, auto-fixable) or C-judgment (debatable abstraction, recommendation only).
- D — Hardcoded theme-color bypass: inline/hardcoded colors (
#hex, oklch(...), bg-gray-*, bg-white, text-black) bypassing semantic theme tokens.
Every finding must be { axis, file, line, current code, suggested fix, confidence }.
Step 3: Consolidate & report
- Merge findings, dedupe by
file:line, drop anything inside the exclusion set, and apply the skip list (see below).
- All four axes are actionable. Split C into C-clear (unambiguous: map a one-off onto an existing primitive, or add a well-defined variant + migrate call-sites preserving public API) and C-judgment (the proposed abstraction is debatable — leave as a recommendation).
- Write
COMPONENT-AUDIT.md only if findings exist; otherwise report a clean result in conversation.
Report shape:
## Native element → component (A)
- `path:line` — current → suggested fix
## Improper variant/prop usage (B)
- `path:line` — current → suggested fix
## Componentize / add-variant recommendations (C)
- pattern (N occurrences) — proposed variant/component + call-sites
## Hardcoded theme-color bypass (D)
- `path:line` — current → suggested fix
Reconcile every raw finding into the report exactly once or record its exclusion or skip reason.
Step 4: Autofix phase (conditional)
Run only when autofix is ON and actionable findings exist. Apply A, B, D, and C-clear. Leave C-judgment as recommendations in the report — those are debatable abstractions for the user to decide.
- Pre-analyze each fix — resolve exact file path, current code, and the precise change (the executor applies; it does not diagnose). For a C-clear variant addition, specify both the edit to the component's variants file and every call-site migration.
- Spawn
mp-executor sub-agent with the concrete per-finding instructions plus the requirement to fix only in-scope findings and preserve each component's public API when refactoring internals.
- After the executor completes, re-read the changed files on disk (a concurrent rebase/hook can silently revert edits — verify the final on-disk state directly, rather than trusting an earlier diff), then run the project's typecheck (
npm run check/pnpm check/tsc). Distinguish pre-existing errors from new ones, and account for every actionable finding as applied or with a recorded reason.
- In the output, list any new component variants added so the user can review the design changes.
Skip list
- Semantically-correct hardcoded colors (e.g.
text-white on a filled primary button, decorative brand colors).
- The component-implementation folder(s) and generated/vendored files.
- Native elements with no design-system equivalent in the inventory.
Output
Stack: [shadcn-svelte | Bits UI | custom | ...]
Components folder: [path]
Inventory: [N components]
Findings:
- A native→component: [N]
- B improper variant: [N]
- C recommendations: [N]
- D color bypass: [N]
Report: [COMPONENT-AUDIT.md | none]
Autofix: [applied A/B/D/C-clear: N | report only | not requested]
New variants added: [list | none]
Typecheck: [clean | N new errors | not run]
1---2name: components-audit3description: Audits design-system component usage, flagging native elements, wrong variants, missed componentization opportunities, and hardcoded colors that bypass theme tokens.4---56# Design System Component Usage Audit78Find where the codebase hand-codes UI that the project's own design-system components already provide, and where those components are used with manual styling that a variant should own. Report findings; optionally autofix the mechanical ones. $ARGUMENTS910## Parameters1112- `scan-path` (optional) — root to audit. Default: repo `src/` (or repo root if no `src/`).13- `autofix` — `autofix`/`autofix=true` forces the fix phase ON; `autofix=false` forces OFF; omitted → report only.1415## Core Principle1617Trust the component's built-in props (variants, sizes, icon slotting) instead of re-applying styles by hand. When a recurring visual need has no variant (e.g. an always-purple button), **add a variant to the component** or **componentize the pattern**, keeping every styled native element attached to the component it belongs to.1819## Workflow2021### Step 1: Inventory the design system FIRST2223Discovery is generalized — no config assumed. Auto-detect, then read real APIs.24251. **Locate the components folder(s).** Spawn an `Explore` sub-agent (breadth: medium, no `model` param) to glob common roots under the scan path — `**/lib/components/**`, `**/components/**`, `**/ui/**` — and return the component folder paths. Strong signals: a directory of single-purpose folders each with a `.svelte`/`.tsx` + an `index.ts` + a variants file.262. **Detect the stack.** Check `package.json` and imports for `bits-ui`, `shadcn`, `radix-ui`, `cva`, `tailwind-variants` (`tv`). If the project is **shadcn-svelte / Bits UI**, treat `rules-per-project/shadcn-svelte.md` as the canonical anti-pattern source and feed its rules to the audit agents.273. **Read each base component's real prop API.** Open variant definitions (`*_variants.ts`, `cva()`/`tv()` configs, prop/type declarations) to learn actual `variant`/`intent`/`size` values and icon-slot conventions. Read prop names from the source rather than assuming them.284. **Build the inventory** — for each component: name, import path, available variants/sizes, and which native element(s) it replaces (`button`→`Button`, `input`→`Input`, calendar/date field→date picker, etc.).295. **Record the exclusion set** — the component-implementation folder(s) themselves, plus generated/vendored files. These are always excluded from audit targets.3031The inventory string seeds every sub-agent prompt — agents must audit against the components that actually exist, not a generic list.3233### Step 2: Fan-out audit (parallel sub-agents)3435See `../shared/EXPLORATION.md` for delegation policy. Spawn `Explore` sub-agents in parallel (breadth: medium), **roughly one per base component or component group** (per user preference), each given: the inventory, the exclusion set, and one axis checklist from [CHECKLISTS.md](CHECKLISTS.md). For large component sets, run the agents `run_in_background: true` and process findings as each returns.3637Audit axes (see [CHECKLISTS.md](CHECKLISTS.md) for the concrete patterns per axis):3839- **A — Native element → component**: raw `<button>`, `<input>`, `<select>`, `<textarea>`, `<hr>`, `animate-pulse` divs, styled spans, callout divs that should be the design-system component.40- **B — Improper variant/prop usage**: manual classes that duplicate or override a variant (`<Button class="rounded-lg">`, color overrides defeating `intent`/`variant`), wrong variant, missing `size="icon"`, manual icon sizing.41- **C — Componentize / add-variant**: repeated detached-style patterns (the "always purple button") → add a variant to the component or extract a component. Each finding is tagged **C-clear** (mechanical, auto-fixable) or **C-judgment** (debatable abstraction, recommendation only).42- **D — Hardcoded theme-color bypass**: inline/hardcoded colors (`#hex`, `oklch(...)`, `bg-gray-*`, `bg-white`, `text-black`) bypassing semantic theme tokens.4344Every finding must be `{ axis, file, line, current code, suggested fix, confidence }`.4546### Step 3: Consolidate & report47481. Merge findings, dedupe by `file:line`, drop anything inside the exclusion set, and apply the skip list (see below).492. All four axes are actionable. Split C into **C-clear** (unambiguous: map a one-off onto an existing primitive, or add a well-defined variant + migrate call-sites preserving public API) and **C-judgment** (the proposed abstraction is debatable — leave as a recommendation).503. Write `COMPONENT-AUDIT.md` only if findings exist; otherwise report a clean result in conversation.5152Report shape:5354```markdown55## Native element → component (A)56- `path:line` — current → suggested fix5758## Improper variant/prop usage (B)59- `path:line` — current → suggested fix6061## Componentize / add-variant recommendations (C)62- pattern (N occurrences) — proposed variant/component + call-sites6364## Hardcoded theme-color bypass (D)65- `path:line` — current → suggested fix66```6768Reconcile every raw finding into the report exactly once or record its exclusion or skip reason.6970### Step 4: Autofix phase (conditional)7172Run only when `autofix` is ON and actionable findings exist. Apply **A, B, D, and C-clear**. Leave **C-judgment** as recommendations in the report — those are debatable abstractions for the user to decide.73741. **Pre-analyze each fix** — resolve exact file path, current code, and the precise change (the executor applies; it does not diagnose). For a C-clear variant addition, specify both the edit to the component's variants file and every call-site migration.752. Spawn `mp-executor` sub-agent with the concrete per-finding instructions plus the requirement to fix only in-scope findings and preserve each component's public API when refactoring internals.763. After the executor completes, **re-read the changed files on disk** (a concurrent rebase/hook can silently revert edits — verify the final on-disk state directly, rather than trusting an earlier diff), then run the project's typecheck (`npm run check`/`pnpm check`/`tsc`). Distinguish pre-existing errors from new ones, and account for every actionable finding as applied or with a recorded reason.774. In the output, list any new component variants added so the user can review the design changes.7879### Skip list8081- Semantically-correct hardcoded colors (e.g. `text-white` on a filled primary button, decorative brand colors).82- The component-implementation folder(s) and generated/vendored files.83- Native elements with no design-system equivalent in the inventory.8485## Output8687```markdown88Stack: [shadcn-svelte | Bits UI | custom | ...]89Components folder: [path]90Inventory: [N components]9192Findings:93- A native→component: [N]94- B improper variant: [N]95- C recommendations: [N]96- D color bypass: [N]9798Report: [COMPONENT-AUDIT.md | none]99Autofix: [applied A/B/D/C-clear: N | report only | not requested]100New variants added: [list | none]101Typecheck: [clean | N new errors | not run]102```