From design-skills
Design-system inspector and /preview page builder for React and Next.js projects. Scans the real codebase to extract CSS variables, discover components, detect the framework, and build a polished /preview route — all without hallucinating colors, tokens, or component APIs. Use this skill whenever the user asks to build a UI preview, component catalog, design-system audit, or /preview page. Also triggers on requests to extract design tokens, audit styles, catalog components, update an existing preview, or any mention of "capy". Subcommands: /capy (or /capy preview), /capy design-system, /capy update.
How this skill is triggered — by the user, by Claude, or both
Slash command
/design-skills:design-system-extractorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Capy scans a React/Next.js repository and produces two things: a machine-readable design-system
Capy scans a React/Next.js repository and produces two things: a machine-readable design-system
artifact (.capy/design-system.json) and a polished /preview route that showcases the app's
real colors, typography, components, and icons. Every value comes from the actual codebase — nothing
is invented.
| Invocation | Action |
|---|---|
/capy or /capy preview | Full scan + build the /preview page (default) |
/capy design-system | Scan + write .capy/design-system.json only |
/capy update | Detect changes since last snapshot, refresh design system, update preview incrementally |
Read package.json at the project root. Parse its dependencies and devDependencies.
Detection rules (evaluate in order, stop at first match):
next in deps AND directory src/app/ exists → Next.js App Router
app-routersrc/app/preview/page.tsxnext in deps AND directory app/ exists → Next.js App Router
app/preview/page.tsxnext in deps AND directory src/pages/ exists → Next.js Pages Router
pages-routersrc/pages/preview.tsxnext in deps AND directory pages/ exists → Next.js Pages Router
pages/preview.tsxreact AND react-router-dom in deps → React Router
react-routersrc/routes/preview.tsxreact only (no router) → React without router
Package manager: Check the packageManager field in package.json. If it starts with pnpm → pnpm, yarn → yarn, bun → bun, otherwise default to npm.
Store these results as the "framework info" for all subsequent phases.
Glob for **/*.{ts,tsx,js,jsx}. Exclude these patterns:
**/*.test.*, **/*.spec.*, **/*.stories.*, **/*.story.***/node_modules/**, **/.next/**, **/dist/**, **/build/****/coverage/**, **/.git/**, **/.capy/**, **/preview/**Scan the source file list for routing marker filenames:
layout.tsx, layout.ts, layout.jsx, layout.js, page.tsx, page.ts, page.jsx, page.js_app.tsx, _app.ts, _app.jsx, _app.js, _document.tsx, _document.ts+page.svelte, +layout.svelteCollect the parent directory of each marker file. Then deduplicate to root-most directories — if both src/app and src/app/blog appear, keep only src/app (any directory that is a prefix of another is sufficient).
Only examine .tsx and .jsx files (plain .ts/.js are utilities/hooks, not components).
For each .tsx/.jsx file:
layout, page, loading, error, not-found, template, default, route, middleware, _app, _document, _errorexport\s+(?:default\s+)?(?:function|const|class)\s+[A-Z][A-Za-z0-9_]*
Deduplicate to root-most directories (same algorithm as 2b).
Glob for **/*.{css,scss,sass,less}. Exclude **/node_modules/**, **/.next/**, **/dist/**, **/build/**, **/.capy/**, **/coverage/**. Also filter out any file whose path contains /preview/.
After discovery, briefly report to the user:
For each style file discovered in Phase 2d, read the file and extract CSS custom properties using this regex:
--([A-Za-z0-9-_]+)\s*:\s*([^;}{]+);
Categorize each variable by its name:
| Category | Name matches (case-insensitive) |
|---|---|
color | color, bg, text, border, surface, accent, primary, secondary, foreground |
typography | font, type, text, leading, tracking, heading, body |
layout | gap, radius, shadow, size, width, height |
other | Everything else |
Note: text matches both color and typography — but since color is checked first, variables with text in the name will be categorized as color. This matches the original Capy behavior.
Record each variable as: { name, value, category, file, line }.
For each component directory from Phase 2c, glob for **/*.{tsx,jsx,ts,js} inside that directory. Exclude test files, stories, node_modules, dist, build, preview, and coverage.
For each file, extract PascalCase exports using these four regex patterns:
export\s+function\s+([A-Z][A-Za-z0-9_]*)
export\s+const\s+([A-Z][A-Za-z0-9_]*)
export\s+class\s+([A-Z][A-Za-z0-9_]*)
export\s+default\s+function\s+([A-Z][A-Za-z0-9_]*)
Classify the component kind by its file path:
/features/ → "feature"/ui/ → "primitive"/components/ → "component""unknown"The first export found becomes the component's display name. If no exports are found, use the filename (without extension) as a fallback.
Group discovered components by their parent directory. For each directory, list up to 5 component names. If more than 5, add "and N more". Example:
src/components/ui/: Button, Card, Input, Badge, Avatar and 3 more.
Write .capy/design-system.json with this exact structure:
{
"artifact": {
"generatedAt": "<ISO timestamp>",
"mode": "build",
"artifactPath": ".capy/design-system.json",
"changedFiles": []
},
"repo": {
"framework": "<framework kind>",
"routingStyle": "<routing style>",
"previewRoute": "/preview",
"previewEntryFile": "<detected entry file>",
"packageManager": "<detected package manager>"
},
"scan": {
"componentDirs": ["<dirs>"],
"pageDirs": ["<dirs>"],
"styleFiles": ["<files>"],
"uiDirs": ["<dirs>"],
"discoveredFamilies": ["<family summary strings>"]
},
"tokens": {
"cssVariables": [
{ "name": "--example", "value": "#fff", "category": "color", "file": "src/styles/globals.css", "line": 12 }
],
"themeSourceFiles": ["<style files>"]
},
"components": {
"count": 0,
"items": [
{ "name": "Button", "path": "src/ui/button.tsx", "exports": ["Button"], "kind": "primitive" }
]
}
}
Use the Write tool to create the .capy/ directory and file. This completes the /capy design-system subcommand.
This phase only runs for /capy preview (or bare /capy). Read references/design-guidance.md before starting this phase — it contains the full visual specification.
Step 1 — Read app shell and routing entry points. Based on the routing style:
layout.tsx and page.tsx in each page directory_app.tsx in each page directorylayout.tsx, page.tsx, and _app.tsxThis tells you the project's visual language — what providers wrap the app, what global styles are applied, what layout structure exists.
Step 2 — Read global styles and theme sources. Read up to 8 of the style files from Phase 2d. Extract real colors, typography scales, spacing tokens, and theme conventions. Everything in the preview must come from what you find here — never invent values.
Step 3 — Discover components in component directories.
Read files in the component/UI directories. For each component with a PascalCase export, note its name, path, props (if readable from the file), and kind. If no component directories were found, check these fallback locations: src/components, components, src/ui, ui, src/features, features.
Step 4 — Trace real usage paths. For each discovered component, search the page directories for import statements that reference it. This validates that the component is actually used in the app (not just exported). Only showcase components with confirmed real usage in the preview. If a component has no usage, note it but don't fabricate example code.
Step 5 — Implement the preview route.
Create the preview entry file (the path from Phase 1). Follow the design guidance in references/design-guidance.md precisely. The page should:
These are critical. The preview page must:
.capy/ and the preview entry file path to .gitignore (append if not already present)/preview in their dev server)/capy update)This phase runs only for /capy update.
Look for .capy/preview-state.json. This file stores SHA-1 hashes of all tracked source files from the last run.
If no snapshot exists: Create a baseline by hashing all source files (**/*.{ts,tsx,js,jsx,css,scss,sass,less,vue,svelte}, excluding node_modules/.next/dist/build/coverage/.git/.capy). Write the snapshot to .capy/preview-state.json. Tell the user: "No prior snapshot found — created a baseline. The next /capy update will detect changes from this point."
If a snapshot exists: Read the previous snapshot. Build a new snapshot of current file hashes. Compare:
Collect all changed file paths.
Re-run Phases 2–5 with mode: "update" and the changedFiles list populated.
Follow the update strategy:
git diff or ask the user what changedWrite the current file hashes to .capy/preview-state.json, replacing the old snapshot.
| Purpose | Pattern | Excludes |
|---|---|---|
| Source files | **/*.{ts,tsx,js,jsx} | test, spec, stories, story, node_modules, .next, dist, build, coverage, .git, .capy, preview |
| Style files | **/*.{css,scss,sass,less} | node_modules, .next, dist, build, .capy, coverage; also filter /preview/ paths |
| Components in dirs | <dir>/**/*.{tsx,jsx,ts,js} | test, spec, stories, story, node_modules, .next, dist, build, coverage, .git, .capy, preview |
| Snapshot tracking | **/*.{ts,tsx,js,jsx,css,scss,sass,less,vue,svelte} | node_modules, .next, dist, build, coverage, .git, .capy |
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub githubanant/skills --plugin design-skills