get-shit-pretty 0.7.4 → 0.8.3

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.
Files changed (79) hide show
  1. package/README.md +21 -14
  2. package/bin/install.js +10 -10
  3. package/bin/theme-css.js +331 -0
  4. package/gsp/agents/gsp-brand-coherence.md +7 -0
  5. package/gsp/skills/get-shit-pretty/SKILL.md +3 -1
  6. package/gsp/skills/gsp-brand-brief/SKILL.md +50 -5
  7. package/gsp/skills/gsp-brand-guidelines/SKILL.md +51 -31
  8. package/gsp/skills/gsp-brand-guidelines/design-tokens.md +2 -0
  9. package/gsp/skills/gsp-brand-guidelines/guidelines-structure.md +167 -0
  10. package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-coherence.md +86 -0
  11. package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-engineer.md +13 -5
  12. package/gsp/skills/gsp-brand-guidelines/token-mapping.md +16 -319
  13. package/gsp/skills/gsp-brand-identity/SKILL.md +1 -1
  14. package/gsp/skills/gsp-brand-refine/SKILL.md +5 -6
  15. package/gsp/skills/gsp-brand-research/SKILL.md +1 -1
  16. package/gsp/skills/gsp-brand-strategy/SKILL.md +1 -1
  17. package/gsp/skills/gsp-design-system/SKILL.md +1 -1
  18. package/gsp/skills/gsp-doctor/SKILL.md +54 -6
  19. package/gsp/skills/gsp-progress/SKILL.md +1 -1
  20. package/gsp/skills/gsp-project-brief/SKILL.md +40 -6
  21. package/gsp/skills/gsp-project-build/SKILL.md +22 -29
  22. package/gsp/skills/gsp-project-build/flows/figma.md +50 -0
  23. package/gsp/skills/gsp-project-build/flows/revision.md +64 -0
  24. package/gsp/skills/gsp-project-build/methodology/gsp-project-builder.md +57 -4
  25. package/gsp/skills/gsp-project-build/shadcn-composition.md +217 -0
  26. package/gsp/skills/gsp-project-critique/SKILL.md +3 -1
  27. package/gsp/skills/gsp-project-design/SKILL.md +3 -1
  28. package/gsp/skills/gsp-project-research/SKILL.md +3 -1
  29. package/gsp/skills/gsp-project-review/SKILL.md +10 -1
  30. package/gsp/skills/gsp-scaffold/SKILL.md +49 -12
  31. package/gsp/skills/gsp-scaffold/shadcn-rules.md +433 -0
  32. package/gsp/skills/gsp-scaffold/shadcn-theming.md +310 -0
  33. package/gsp/skills/gsp-start/SKILL.md +18 -2
  34. package/gsp/skills/gsp-style/SKILL.md +1 -1
  35. package/gsp/skills/gsp-style/style-preset-schema.md +59 -14
  36. package/gsp/skills/gsp-style/styles/academia.yml +58 -8
  37. package/gsp/skills/gsp-style/styles/art-deco.yml +39 -7
  38. package/gsp/skills/gsp-style/styles/bauhaus.yml +39 -8
  39. package/gsp/skills/gsp-style/styles/bold-typography.yml +39 -8
  40. package/gsp/skills/gsp-style/styles/botanical.yml +39 -9
  41. package/gsp/skills/gsp-style/styles/claymorphism.yml +39 -9
  42. package/gsp/skills/gsp-style/styles/cyberpunk.yml +39 -7
  43. package/gsp/skills/gsp-style/styles/enterprise.yml +39 -10
  44. package/gsp/skills/gsp-style/styles/flat-design.yml +39 -9
  45. package/gsp/skills/gsp-style/styles/fluent.yml +39 -10
  46. package/gsp/skills/gsp-style/styles/glassmorphism.yml +39 -8
  47. package/gsp/skills/gsp-style/styles/humanist-literary.yml +39 -9
  48. package/gsp/skills/gsp-style/styles/industrial.yml +59 -9
  49. package/gsp/skills/gsp-style/styles/kinetic.yml +32 -7
  50. package/gsp/skills/gsp-style/styles/liquid-glass.yml +59 -9
  51. package/gsp/skills/gsp-style/styles/luxury.yml +59 -9
  52. package/gsp/skills/gsp-style/styles/material.yml +59 -9
  53. package/gsp/skills/gsp-style/styles/maximalism.yml +32 -6
  54. package/gsp/skills/gsp-style/styles/minimal-dark.yml +32 -7
  55. package/gsp/skills/gsp-style/styles/modern-dark.yml +32 -7
  56. package/gsp/skills/gsp-style/styles/monochrome.yml +59 -10
  57. package/gsp/skills/gsp-style/styles/neubrutalism.yml +59 -9
  58. package/gsp/skills/gsp-style/styles/neumorphism.yml +32 -7
  59. package/gsp/skills/gsp-style/styles/newsprint.yml +32 -7
  60. package/gsp/skills/gsp-style/styles/nothing.yml +44 -13
  61. package/gsp/skills/gsp-style/styles/organic.yml +42 -9
  62. package/gsp/skills/gsp-style/styles/playful-geometric.yml +43 -9
  63. package/gsp/skills/gsp-style/styles/professional.yml +41 -10
  64. package/gsp/skills/gsp-style/styles/retro.yml +42 -8
  65. package/gsp/skills/gsp-style/styles/saas.yml +42 -9
  66. package/gsp/skills/gsp-style/styles/sketch.yml +42 -9
  67. package/gsp/skills/gsp-style/styles/swiss-minimalist.yml +41 -10
  68. package/gsp/skills/gsp-style/styles/terminal.yml +42 -8
  69. package/gsp/skills/gsp-style/styles/vaporwave.yml +42 -7
  70. package/gsp/skills/gsp-style/styles/web3.yml +42 -9
  71. package/gsp/skills/gsp-update/SKILL.md +9 -6
  72. package/gsp/templates/branding/brief.md +9 -0
  73. package/gsp/templates/branding/config.json +1 -1
  74. package/gsp/templates/design-claude.md +6 -0
  75. package/gsp/templates/phases/patterns.md +2 -2
  76. package/gsp/templates/projects/config.json +6 -3
  77. package/gsp/templates/projects/state.md +1 -1
  78. package/gsp/templates/system/STACK.md +1 -0
  79. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-scaffold
3
- description: Deterministic stack setup — install deps, create configs, verify build compiles
3
+ description: Set up the tech stack — install deps, configs, verify build — use when: set up the stack, install shadcn, init the project, scaffold, set up Tailwind
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -40,20 +40,57 @@ Read `{PROJECT_PATH}/config.json` to get:
40
40
  - `preferences.implementation_target` (shadcn, rn-reusables, existing, code)
41
41
  - `preferences.tech_stack` (Next.js + Tailwind + shadcn/ui, etc.)
42
42
  - `preferences.codebase_type` (greenfield, existing)
43
+ - `preferences.app_path` (relative path from repo root to the target app, e.g. `apps/web`)
44
+ - `preferences.repo_type` (`single` or `monorepo`)
45
+
46
+ Set `APP_PATH` = value of `app_path`. If empty, default to `.` (repo root).
47
+ Derive `APP_NAME` = last segment of `APP_PATH` (e.g. `apps/web` → `web`, `.` → `root`).
43
48
 
44
49
  If `implementation_target` is `figma` or `skip`, log "⚠️ No scaffold needed for target: {target}" and exit.
45
50
 
46
- ## Step 2: Read stack state
51
+ ## Step 2: Read stack state + compliance gate
52
+
53
+ Read `.design/system/stacks/{APP_NAME}.md` if it exists — this is the per-app stack file for monorepos. Fall back to `.design/system/STACK.md` for legacy single-app setups (or when `APP_NAME` is `root` and the legacy file exists).
54
+
55
+ ### If stack file exists (existing or returning project)
56
+
57
+ This workspace has a declared stack for this app. Enforce compliance before touching anything.
58
+
59
+ 1. **Read the live stack** from `components.json` (if present) and `package.json` inside `APP_PATH`:
60
+ - `cd {APP_PATH} && npx shadcn@latest info --json` (if shadcn target) → captures `aliases`, `tailwindVersion`, `style`, `base`, `iconLibrary`
61
+ - `cd {APP_PATH} && node -e "console.log(require('tailwindcss/package.json').version)"` → actual Tailwind version
62
+
63
+ 2. **Compare against STACK.md** — flag any of these divergences:
64
+
65
+ | What to check | STACK.md field | Live source |
66
+ |---|---|---|
67
+ | Framework | `## Tech Stack → Framework` | `package.json` dependencies |
68
+ | Tailwind version | `## Tech Stack → Styling` | Installed `tailwindcss` version |
69
+ | shadcn alias | `## Key Paths → Components` | `shadcn info` → `aliases.components` |
70
+ | shadcn style | (if recorded) | `shadcn info` → `style` |
71
+ | Icon library | (if recorded) | `shadcn info` → `iconLibrary` |
72
+
73
+ 3. **Gate on divergence:**
74
+ - If any divergence found, surface it clearly:
75
+ ```
76
+ ⚠️ Stack compliance — divergence detected
77
+
78
+ STACK.md declares: aliases.components = @/components/ui
79
+ Live codebase has: aliases.components = ~/components/ui
47
80
 
48
- Read `.design/system/STACK.md` if it exists check what's already set up.
81
+ Proceeding will write files to the wrong paths.
82
+ ```
83
+ - Use `AskUserQuestion`: "Stack divergence detected. Proceed anyway (may break imports), or stop to fix STACK.md first?"
84
+ - **Stop** → exit; user fixes `STACK.md` and re-runs
85
+ - **Proceed anyway** → log divergence in scaffold log, continue with live values (not STACK.md)
49
86
 
50
- If STACK.md indicates the stack is already initialized (has framework, CSS, component library entries), log existing state and skip to Step 4 (component installs).
87
+ 4. If the stack file indicates the stack is already initialized (has framework, CSS, component library entries) **and no divergence found**, log existing state and skip to Step 4 (component installs).
51
88
 
52
89
  ## Step 3: Initialize stack
53
90
 
54
91
  Based on `tech_stack` and `implementation_target`, run the appropriate setup.
55
92
 
56
- **Important:** Always check if config files already exist before overwriting. Only create what's missing.
93
+ **Important:** All shell commands in this step run in the `APP_PATH` working directory (`cd {APP_PATH} && ...`). Always check if config files already exist before overwriting. Only create what's missing.
57
94
 
58
95
  ### Next.js + shadcn (greenfield)
59
96
 
@@ -165,14 +202,14 @@ Run additional dependency installs (`npm install ...`) separately from component
165
202
 
166
203
  ## Step 5: Verify build
167
204
 
168
- Clear any build cache first (`rm -rf .next` for Next.js), then run the build command:
205
+ Clear any build cache first (`cd {APP_PATH} && rm -rf .next` for Next.js), then run the build command in `APP_PATH`:
169
206
 
170
207
  | Stack | Build command |
171
208
  |-------|--------------|
172
- | Next.js | `npx next build` |
173
- | Vite | `npx vite build` |
174
- | TypeScript only | `npx tsc --noEmit` |
175
- | Generic | `npm run build` |
209
+ | Next.js | `cd {APP_PATH} && npx next build` |
210
+ | Vite | `cd {APP_PATH} && npx vite build` |
211
+ | TypeScript only | `cd {APP_PATH} && npx tsc --noEmit` |
212
+ | Generic | `cd {APP_PATH} && npm run build` |
176
213
 
177
214
  - **Success:** Log "Build compiles cleanly"
178
215
  - **Failure:** Log the error output. Attempt to fix common issues:
@@ -186,7 +223,7 @@ Clear any build cache first (`rm -rf .next` for Next.js), then run the build com
186
223
 
187
224
  ## Step 5.5: Capture project context (shadcn targets)
188
225
 
189
- If `implementation_target` is `shadcn`, run `npx shadcn@latest info --json` and capture the output. This provides:
226
+ If `implementation_target` is `shadcn`, run `cd {APP_PATH} && npx shadcn@latest info --json` and capture the output. This provides:
190
227
  - `aliases` — the actual alias prefix for imports (`@/`, `~/`)
191
228
  - `tailwindVersion` — `"v4"` (uses `@theme inline`) vs `"v3"` (uses `tailwind.config.js`)
192
229
  - `tailwindCssFile` — the global CSS file where custom properties go
@@ -206,7 +243,7 @@ Write `{PROJECT_PATH}/build/SCAFFOLD-LOG.md`:
206
243
  ```markdown
207
244
  # Scaffold Log
208
245
 
209
- > Phase: build (scaffold) | Project: {name} | Generated: {DATE}
246
+ > Phase: build (scaffold) | Project: {name} | App: {APP_PATH} | Generated: {DATE}
210
247
 
211
248
  ## Stack
212
249
 
@@ -0,0 +1,433 @@
1
+ # shadcn/ui Rules — Tier 1: Install & Config
2
+
3
+ Rules for the scaffold phase. The foundations agent reads this to set up a correct shadcn/ui installation.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npx shadcn@latest init -d
11
+ ```
12
+
13
+ The `-d` flag uses defaults — it forces **Next.js + nova preset**. For other frameworks (Vite, React Router, Remix) or to pick a different preset, omit `-d` and answer the prompts, or use the `-t` / `-p` flags:
14
+
15
+ ```bash
16
+ npx shadcn@latest init -t vite # scaffold for Vite
17
+ npx shadcn@latest init -t next -p lyra # Next.js with lyra preset
18
+ npx shadcn@latest init --monorepo # monorepo scaffold (prompts for framework)
19
+ npx shadcn@latest init -t next --monorepo # Next.js monorepo
20
+ npx shadcn@latest init # interactive — choose framework + style
21
+ ```
22
+
23
+ Templates: `next`, `vite`, `start`, `react-router`, `astro` (all support `--monorepo`), `laravel` (no monorepo).
24
+
25
+ After init, capture project context:
26
+
27
+ ```bash
28
+ npx shadcn@latest info --json
29
+ ```
30
+
31
+ Key fields from the JSON:
32
+
33
+ | Field | Use |
34
+ |-------|-----|
35
+ | `aliases` | Import prefix (`@/`, `~/`) — use consistently in all generated code |
36
+ | `tailwindVersion` | `"v4"` uses `@theme inline`; `"v3"` uses `tailwind.config.js` |
37
+ | `tailwindCssFile` | Where CSS custom properties go — write tokens here |
38
+ | `style` | Component visual treatment (`new-york`, `base-nova`, etc.) — do NOT assume `default` (deprecated) |
39
+ | `iconLibrary` | `lucide-react` or `@tabler/icons-react` — use the right import |
40
+ | `resolvedPaths` | Exact destinations for components, utils, hooks |
41
+ | `isRSC` | Whether `"use client"` directives are needed |
42
+
43
+ ---
44
+
45
+ ## globals.css pattern
46
+
47
+ ### Tailwind v4
48
+
49
+ ```css
50
+ @import "tailwindcss";
51
+ @import "shadcn/tailwind.css";
52
+
53
+ @custom-variant dark (&:is(.dark *));
54
+
55
+ @theme inline {
56
+ --color-background: var(--background);
57
+ --color-foreground: var(--foreground);
58
+ --color-card: var(--card);
59
+ --color-card-foreground: var(--card-foreground);
60
+ --color-popover: var(--popover);
61
+ --color-popover-foreground: var(--popover-foreground);
62
+ --color-primary: var(--primary);
63
+ --color-primary-foreground: var(--primary-foreground);
64
+ --color-secondary: var(--secondary);
65
+ --color-secondary-foreground: var(--secondary-foreground);
66
+ --color-muted: var(--muted);
67
+ --color-muted-foreground: var(--muted-foreground);
68
+ --color-accent: var(--accent);
69
+ --color-accent-foreground: var(--accent-foreground);
70
+ --color-destructive: var(--destructive);
71
+ --color-border: var(--border);
72
+ --color-input: var(--input);
73
+ --color-ring: var(--ring);
74
+ --color-chart-1: var(--chart-1);
75
+ --color-chart-2: var(--chart-2);
76
+ --color-chart-3: var(--chart-3);
77
+ --color-chart-4: var(--chart-4);
78
+ --color-chart-5: var(--chart-5);
79
+ --color-sidebar: var(--sidebar);
80
+ --color-sidebar-foreground: var(--sidebar-foreground);
81
+ --color-sidebar-primary: var(--sidebar-primary);
82
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
83
+ --color-sidebar-accent: var(--sidebar-accent);
84
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
85
+ --color-sidebar-border: var(--sidebar-border);
86
+ --color-sidebar-ring: var(--sidebar-ring);
87
+ --radius-sm: calc(var(--radius) * 0.6);
88
+ --radius-md: calc(var(--radius) * 0.8);
89
+ --radius-lg: var(--radius);
90
+ --radius-xl: calc(var(--radius) * 1.4);
91
+ --radius-2xl: calc(var(--radius) * 1.8);
92
+ --radius-3xl: calc(var(--radius) * 2.2);
93
+ --radius-4xl: calc(var(--radius) * 2.6);
94
+ }
95
+
96
+ :root {
97
+ /* Insert OKLCH custom properties from bin/theme-css.js output here */
98
+ }
99
+
100
+ .dark {
101
+ /* Insert .dark overrides from bin/theme-css.js output here */
102
+ }
103
+
104
+ @layer base {
105
+ * {
106
+ @apply border-border outline-ring/50;
107
+ }
108
+ body {
109
+ @apply bg-background text-foreground;
110
+ }
111
+ button:not(:disabled), [role="button"]:not(:disabled) {
112
+ cursor: pointer;
113
+ }
114
+ }
115
+ ```
116
+
117
+ **Note:** `shadcn/tailwind.css` ships with the shadcn CLI — no separate npm install needed. Do **not** use `tw-animate-css`; that's a different package with different animation primitives.
118
+
119
+ ### Google Fonts (optional)
120
+
121
+ If the preset uses a Google Font (check `typography.font-family-primary`), add the import **before** the Tailwind import:
122
+
123
+ ```css
124
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
125
+ @import "tailwindcss";
126
+ @import "shadcn/tailwind.css";
127
+ ```
128
+
129
+ Then set font vars with literal values in `@theme inline` (not `var()` self-references):
130
+
131
+ ```css
132
+ @theme inline {
133
+ /* … existing color/radius vars … */
134
+ --font-sans: "Inter", sans-serif;
135
+ --font-mono: "JetBrains Mono", monospace;
136
+ }
137
+ ```
138
+
139
+ `bin/theme-css.js` emits `--font-sans` / `--font-mono` / `--font-display` from the preset's `typography` block — paste those values (not the var declarations) into `@theme inline`.
140
+
141
+ ### Tailwind v3
142
+
143
+ ```css
144
+ @tailwind base;
145
+ @tailwind components;
146
+ @tailwind utilities;
147
+
148
+ @layer base {
149
+ :root {
150
+ /* Insert HSL custom properties here */
151
+ }
152
+ .dark {
153
+ /* Insert .dark overrides here */
154
+ }
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Token injection
161
+
162
+ **Order matters** — run component installs first, then overwrite tokens. This prevents `shadcn add` from appending its own `cssVars` after your custom OKLCH values.
163
+
164
+ **Step 1 — Install all components first:**
165
+
166
+ ```bash
167
+ npx shadcn@latest add button card dialog popover select tooltip ...
168
+ ```
169
+
170
+ **Step 2 — Generate and inject brand tokens:**
171
+
172
+ ```bash
173
+ node bin/theme-css.js .design/branding/{brand}/patterns/{brand}.yml --stdout
174
+ ```
175
+
176
+ Paste the `:root { }` and `.dark { }` output into `globals.css`, replacing any `:root`/`.dark` blocks the shadcn CLI wrote. The `@theme inline` block stays untouched — it only contains `var()` aliases and radius/font values, not actual color values.
177
+
178
+ **Format:** OKLCH (`oklch(L C H)`). shadcn/ui v2+ accepts OKLCH natively. No `hsl()` wrapper needed.
179
+
180
+ ---
181
+
182
+ ## Project context
183
+
184
+ Always run this first — it tells you exactly what the project has:
185
+
186
+ ```bash
187
+ npx shadcn@latest info --json
188
+ ```
189
+
190
+ Key fields to check before writing any code:
191
+
192
+ | Field | Use |
193
+ |-------|-----|
194
+ | `base` | `"radix"` or `"base"` — determines component APIs (asChild vs render, ToggleGroup type prop, Slider value shape, etc.) |
195
+ | `tailwindVersion` | `"v4"` uses `@theme inline`; `"v3"` uses `tailwind.config.js` |
196
+ | `tailwindCssFile` | The exact CSS file to edit — never create a new one |
197
+ | `iconLibrary` | `lucide-react` or `@tabler/icons-react` — never assume lucide |
198
+ | `aliases` | Import prefix — use consistently, never relative paths to UI files |
199
+ | `isRSC` | When `true`, components with hooks/event handlers need `"use client"` |
200
+ | `packageManager` | Use for non-shadcn dep installs (`pnpm add date-fns` vs `npm install date-fns`) |
201
+
202
+ ---
203
+
204
+ ## Presets
205
+
206
+ Three formats for `--preset`:
207
+
208
+ ```bash
209
+ npx shadcn@latest init --preset nova # named preset
210
+ npx shadcn@latest init --preset a2r6bw # opaque code from ui.shadcn.com
211
+ npx shadcn@latest init --preset "https://..." # full URL
212
+ ```
213
+
214
+ **Never decode or fetch preset codes manually.** They are opaque — pass them directly to the CLI.
215
+
216
+ ### Applying a preset to an existing project
217
+
218
+ ```bash
219
+ npx shadcn@latest apply --preset a2r6bw # overwrite all detected component files
220
+ npx shadcn@latest apply a2r6bw # shorthand
221
+ ```
222
+
223
+ ### Switching presets
224
+
225
+ Ask the user which strategy before running:
226
+
227
+ | Strategy | Command | When |
228
+ |----------|---------|------|
229
+ | **Overwrite** | `npx shadcn@latest apply --preset <code>` | User hasn't customized components |
230
+ | **Merge** | `npx shadcn@latest init --preset <code> --force --no-reinstall`, then smart merge per component | User has customized components |
231
+ | **Skip** | `npx shadcn@latest init --preset <code> --force --no-reinstall` | Update config/CSS only, leave components |
232
+
233
+ Named presets: `nova`, `vega`, `maia`, `lyra`, `mira`, `luma`
234
+
235
+ ---
236
+
237
+ ## Component install
238
+
239
+ ```bash
240
+ # Install individual components
241
+ npx shadcn@latest add button card input
242
+
243
+ # Install all at once (preferred — from install-manifest.md)
244
+ npx shadcn@latest add button card dialog popover select tooltip ...
245
+
246
+ # Preview all files that would be written (no changes)
247
+ npx shadcn@latest add button --dry-run
248
+
249
+ # Preview diff for a specific file before updating
250
+ npx shadcn@latest add button --diff button.tsx
251
+
252
+ # Preview CSS changes
253
+ npx shadcn@latest add button --diff globals.css
254
+
255
+ # View component source without installing
256
+ npx shadcn@latest add button --view button.tsx
257
+
258
+ # Overwrite existing files
259
+ npx shadcn@latest add button --overwrite
260
+
261
+ # Install from a community registry
262
+ npx shadcn@latest add @shadcnblocks/sidebar-07
263
+ ```
264
+
265
+ **Always use `--dry-run` or `--diff` before overwriting existing components.** Never fetch raw component source from GitHub — the CLI handles registry resolution, paths, and CSS diffing.
266
+
267
+ ### Get component docs before building or fixing
268
+
269
+ ```bash
270
+ npx shadcn@latest docs button dialog select
271
+ ```
272
+
273
+ Returns live documentation and example URLs. Fetch those URLs to get the actual API and usage patterns. Run this before implementing or debugging any component.
274
+
275
+ ### Before building a custom component
276
+
277
+ Run `npx shadcn@latest search {name}` — a registry version may already exist:
278
+
279
+ ```bash
280
+ npx shadcn@latest search sidebar
281
+ npx shadcn@latest search @tailark -q "stats"
282
+ ```
283
+
284
+ ### Post-install import check (community registries)
285
+
286
+ After installing from a community registry (e.g. `@bundui`, `@magicui`, `@shadcnblocks`), check added non-UI files for hardcoded import paths like `@/components/ui/...`. These may not match the project's actual aliases. Use `npx shadcn@latest info` to get the correct `ui` alias and rewrite imports accordingly. The CLI rewrites its own UI files — third-party files may use default paths.
287
+
288
+ ### Registry gate
289
+
290
+ When the user asks to add a block or component without specifying a registry, ask which registry to use. Never default to one silently. When the user specifies a registry, always use exactly that one.
291
+
292
+ **If a batch install fails:** parse the error, remove the failing component(s), retry with the rest. Log failures.
293
+
294
+ **`registryDependencies` are installed automatically** — complex components pull their own deps in one step.
295
+
296
+ Known registry gaps:
297
+ - `visually-hidden` — implement as a simple CSS utility instead
298
+
299
+ ---
300
+
301
+ ## Blocks
302
+
303
+ Blocks are pre-built page sections — install them the same way as components:
304
+
305
+ ```bash
306
+ npx shadcn@latest add sidebar-07 # install a specific block
307
+ npx shadcn@latest add sidebar-07 --diff # preview changes before installing
308
+ npx shadcn@latest add sidebar-07 --overwrite # force overwrite existing files
309
+ ```
310
+
311
+ **Always check for a block before building from scratch.** Run `npx shadcn@latest search {name}` first.
312
+
313
+ ### Block categories
314
+
315
+ | Category | Slugs | Page target |
316
+ |----------|-------|-------------|
317
+ | Sidebar | `sidebar-01` … `sidebar-16` | `app/dashboard/page.tsx` |
318
+ | Login | `login-01` … `login-05` | `app/login/page.tsx` |
319
+ | Signup | `signup-01` … `signup-05` | `app/signup/page.tsx` |
320
+
321
+ Each block installs two things: a **page.tsx** at the fixed route above, and one or more component files. The page path is fixed — the agent cannot change it without manual refactoring.
322
+
323
+ ### Sidebar blocks (01–16)
324
+
325
+ All 16 sidebar blocks share the same structural shell:
326
+
327
+ ```tsx
328
+ <SidebarProvider style={{ "--sidebar-width": "19rem" } as React.CSSProperties}>
329
+ <AppSidebar />
330
+ <SidebarInset>
331
+ <header>
332
+ <SidebarTrigger />
333
+ <Breadcrumb />
334
+ </header>
335
+ {/* page content */}
336
+ </SidebarInset>
337
+ </SidebarProvider>
338
+ ```
339
+
340
+ Key props:
341
+ - `collapsible` — `"icon"` | `"offcanvas"` | `"none"`
342
+ - `variant` — default | `"inset"` | `"floating"`
343
+ - `useSidebar()` hook — exposes `isMobile` for responsive dropdown positioning
344
+ - `--sidebar-width` goes on `<SidebarProvider>` as an inline style, **not** in global CSS
345
+
346
+ `registryDependencies` (sidebar, breadcrumb, card, etc.) install automatically with the block.
347
+
348
+ ### Login blocks (01–05)
349
+
350
+ UI-only. What agents must add manually:
351
+ - Form handling (`react-hook-form` + `zod` + server actions)
352
+ - OAuth provider wiring — buttons render as plain `<Button variant="outline">` shells
353
+ - Error states and redirect logic
354
+
355
+ The blocks use the `field` primitive (`<Field>`, `<FieldLabel>`, `<FieldGroup>`, `<FieldDescription>`) — **not** a plain `<label>`. See the Form Field API section in builder rules.
356
+
357
+ ### Signup blocks (01–05)
358
+
359
+ Parallel structure to login blocks — same UI-only caveat. Add form handling and validation.
360
+
361
+ ### Community registries
362
+
363
+ ```bash
364
+ # Search community registries
365
+ npx shadcn@latest search dashboard
366
+
367
+ # Install from a community registry
368
+ npx shadcn@latest add @shadcnblocks/dashboard
369
+
370
+ # Preview registry item before installing
371
+ npx shadcn@latest add @shadcnblocks/dashboard --diff
372
+ ```
373
+
374
+ 148 community registries are available via `@namespace/item` syntax. Always check with `--diff` before installing community items — they may conflict with existing components.
375
+
376
+ ---
377
+
378
+ ## base vs radix
379
+
380
+ Check `base` from `npx shadcn@latest info` before writing any component code. The two primitives have different APIs:
381
+
382
+ | Area | radix | base |
383
+ |------|-------|------|
384
+ | Custom trigger | `asChild` prop | `render` prop |
385
+ | Button as link | `<Button asChild><a>` | `<Button render={<a />} nativeButton={false}>` |
386
+ | Select items | Inline JSX only | Requires `items` prop on root + JSX |
387
+ | Select placeholder | `<SelectValue placeholder="…">` | `{ value: null }` item in items array |
388
+ | ToggleGroup single | `type="single"` + string `defaultValue` | No `type` prop + array `defaultValue` |
389
+ | ToggleGroup multi | `type="multiple"` | `multiple` boolean prop |
390
+ | Slider | Array always (`defaultValue={[50]}`) | Plain number for single thumb (`defaultValue={50}`) |
391
+ | Accordion | `type="single"/"multiple"` + `collapsible` + string `defaultValue` | `multiple` boolean + array `defaultValue` |
392
+
393
+ **Trigger composition:**
394
+
395
+ ```tsx
396
+ // radix
397
+ <DialogTrigger asChild>
398
+ <Button>Open</Button>
399
+ </DialogTrigger>
400
+
401
+ // base
402
+ <DialogTrigger render={<Button />}>Open</DialogTrigger>
403
+ ```
404
+
405
+ For full API differences with code examples, read `${CLAUDE_SKILL_DIR}/shadcn-theming.md` or run `npx shadcn@latest docs <component>`.
406
+
407
+ ---
408
+
409
+ ## Critical rules
410
+
411
+ 1. **Never overwrite components.json** — shadcn init writes it; subsequent adds read it. The `style`, `tailwind.baseColor`, and `tailwind.cssVariables` fields are immutable after init — changing them requires deleting all installed components and reinstalling
412
+ 2. **Check for existing files before overwriting** — `globals.css` may already have Tailwind imports
413
+ 3. **Tailwind v4 source scoping** — if the repo has non-source files with CSS class names (`.design/`, `gsp/`), add `source("../")` to the `@import "tailwindcss"` line to limit scanning
414
+ 4. **Import alias consistency** — all generated code must use the alias from `shadcn info` (`@/` or `~/`), never relative paths to component files
415
+ 5. **Never hardcode colors** — use `bg-primary`, `text-muted-foreground`, `border-border`, etc. — never `bg-blue-500`
416
+ 6. **Install components before writing tokens** — run `shadcn add` first; then overwrite `:root`/`.dark` with `bin/theme-css.js` output. Reversing this order risks shadcn appending its own vars after yours
417
+
418
+ ---
419
+
420
+ ## Dark mode setup
421
+
422
+ shadcn uses class-based dark mode. In `tailwind.config.js` (v3):
423
+
424
+ ```js
425
+ module.exports = {
426
+ darkMode: ["class"],
427
+ // ...
428
+ }
429
+ ```
430
+
431
+ In v4 with `@custom-variant dark` — no config needed; the variant is declared in CSS.
432
+
433
+ The root layout needs a `ThemeProvider` if the project requires user-togglable dark mode. For dark-by-default or light-only, skip the provider and set the class on `<html>` directly.