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-project-build
3
- description: Translate designs to code (technical phase — benefits from capable models)
3
+ description: Translate designs to code (technical phase — benefits from capable models) — use when: build this, implement, code this up, build me a X, add a X to the app, make the X page
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -70,6 +70,8 @@ Implement designs as production-ready code in the codebase via phased pipeline w
70
70
  <process>
71
71
  ## Step 0: Resolve project and brand
72
72
 
73
+ If `.design/projects/` does not exist: output "No GSP project found. Run `/gsp-start` to begin." and stop.
74
+
73
75
  Resolve project from `.design/projects/` (one → use it, multiple → ask). Set `PROJECT_PATH`.
74
76
 
75
77
  Read `{PROJECT_PATH}/brand.ref` → set `BRAND_PATH`.
@@ -83,7 +85,9 @@ Exception: if `design_scope` is `tokens` in config.json, skip this check (tokens
83
85
 
84
86
  ## Step 1: Load config and check state
85
87
 
86
- Read `{PROJECT_PATH}/config.json` to get `implementation_target`, `design_scope`, `codebase_type`.
88
+ Read `{PROJECT_PATH}/config.json` to get `implementation_target`, `design_scope`, `codebase_type`, `app_path`.
89
+
90
+ Set `APP_PATH` = value of `app_path`. If empty, default to `.` (repo root).
87
91
 
88
92
  ### Branch check
89
93
 
@@ -132,7 +136,7 @@ Read `${CLAUDE_SKILL_DIR}/methodology/gsp-project-builder.md`. Include the full
132
136
  Read these reference files:
133
137
  - `${CLAUDE_SKILL_DIR}/visual-effects.md`
134
138
  - `${CLAUDE_SKILL_DIR}/../gsp-project-design/block-patterns.md`
135
- - `${CLAUDE_SKILL_DIR}/../gsp-brand-guidelines/token-mapping.md`
139
+ - `${CLAUDE_SKILL_DIR}/shadcn-composition.md`
136
140
 
137
141
  Hold their content for inlining into agent prompts in Steps 3, 4.5, 5, 7, and 8.
138
142
 
@@ -149,12 +153,13 @@ Spawn `gsp-project-builder` agent with **execution_mode: foundations**.
149
153
  | `{BRAND_PATH}/patterns/{brand-name}.yml` | Token values only — used with token-mapping.md to generate CSS variables. Do NOT re-read patterns/constraints/effects from here — those are in STYLE.md. |
150
154
  | `{BRAND_PATH}/patterns/STYLE.md` | Design law — philosophy, patterns, constraints, effects, bold bets, implementation hints (if exists; fall back to `{brand-name}.md`) |
151
155
  | `{PROJECT_PATH}/brief/target-adaptations.md` | Component adaptations for target |
152
- | `.design/system/STACK.md` | Stack state |
156
+ | `.design/system/STACK.md` | Stack state (or `.design/system/stacks/{APP_NAME}.md` for monorepos) |
153
157
  | `.design/system/CONVENTIONS.md` | Codebase conventions (if exists) |
154
158
  | `.design/system/COMPONENTS.md` | Existing components (if exists) |
155
- | `{PROJECT_PATH}/config.json` | Tech stack, target |
159
+ | `{PROJECT_PATH}/config.json` | Tech stack, target, `app_path` |
160
+ | `APP_PATH = {APP_PATH}` | Working directory — all file writes and build commands run here |
156
161
  | Build output template (from execution_context) | Build log structure |
157
- | Token mapping ref (loaded in Step 2.6) | Deterministic `.yml` CSS variable mapping per target (shadcn HSL, Tailwind, vanilla). Includes all 26+ shadcn variables, hex→HSL conversion, dark mode, shape/radius derivation. |
162
+ | Token mapping ref (loaded in Step 2.6) | shadcn component composition rules, semantic token usage, `cn()`, `cva`, RSC patterns |
158
163
  | Visual effects, block patterns refs (loaded in Step 2.6) | Design patterns + CSS recipes |
159
164
  | Agent methodology (loaded in Step 2.5) | Builder role, process, quality standards |
160
165
 
@@ -164,7 +169,7 @@ Spawn `gsp-project-builder` agent with **execution_mode: foundations**.
164
169
  >
165
170
  > Build token integration, global styles, and layout primitives ONLY.
166
171
  >
167
- > 1. Integrate design tokens into the codebase using the token-mapping reference: read the `.yml` token values and the token-mapping.md spec, then generate CSS variables per target (shadcn: HSL space-separated in `:root`/`.dark`, Tailwind: custom properties + config extend, vanilla: full custom property system). Map ALL variables — not just colors: background, foreground, card, popover, primary, secondary, muted, accent, destructive, border, input, ring, sidebar-*, chart-1 through chart-5, and --radius.
172
+ > 1. Integrate design tokens into the codebase: run `node bin/theme-css.js {brand-name}.yml --stdout` and paste the OKLCH `:root`/`.dark` output into `globals.css`. For shadcn targets, follow the `@theme inline` pattern from `shadcn-rules.md`. Map ALL variables — background, foreground, card, popover, primary, secondary, muted, accent, destructive, border, input, ring, sidebar-*, chart-1 through chart-5, and --radius.
168
173
  > 2. Create global CSS (resets, base styles, font imports, dark mode setup)
169
174
  > 3. Create root layout with nav shell and footer shell (structure only — no page content)
170
175
  > 4. Create shared utilities (cn helper, theme provider if needed)
@@ -178,14 +183,14 @@ Spawn `gsp-project-builder` agent with **execution_mode: foundations**.
178
183
 
179
184
  ### Checkpoint: Compile check
180
185
 
181
- After the foundations agent completes, run the build command:
186
+ After the foundations agent completes, run the build command in `APP_PATH`:
182
187
 
183
188
  | Stack | Build command |
184
189
  |-------|--------------|
185
- | Next.js | `npx next build` |
186
- | Vite | `npx vite build` |
187
- | TypeScript only | `npx tsc --noEmit` |
188
- | Generic | `npm run build` |
190
+ | Next.js | `cd {APP_PATH} && npx next build` |
191
+ | Vite | `cd {APP_PATH} && npx vite build` |
192
+ | TypeScript only | `cd {APP_PATH} && npx tsc --noEmit` |
193
+ | Generic | `cd {APP_PATH} && npm run build` |
189
194
 
190
195
  **Pass:** Continue to preview verification, then Step 4.
191
196
  **Fail:** Log the error. Do NOT re-spawn the agent. Surface the error to the user and ask how to proceed.
@@ -497,25 +502,13 @@ Invoke `/gsp-phase-transition` with phase `build` and output directory `{PROJECT
497
502
 
498
503
  ## Step 7: Figma fallback
499
504
 
500
- For `implementation_target: figma`, skip the phased pipeline. Spawn a single `gsp-project-builder` agent with execution_mode: `full` and spec-only flag. Builder writes `build/CODE.md` + `build/components/` instead of editing codebase. Then continue from Step 6 (finalize).
501
-
502
- ## Step 8: Revision mode
503
-
504
- For `needs-revision` status, spawn a single `gsp-project-builder` agent with execution_mode: `full` and `review/issues.md` contents. The agent fixes QA issues in the codebase and appends revision sections to BUILD-LOG.md.
505
+ Read `${CLAUDE_SKILL_DIR}/flows/figma.md` for full instructions.
505
506
 
506
- ### Checkpoint: Compile check
507
-
508
- After the revision agent completes, run the build command (same stack table as Step 3 checkpoint).
509
-
510
- **Pass:** Continue to brand feedback check below.
511
- **Fail:** Log the error. Surface to user: "Revision introduced build errors: {error}. Fix before finalizing?"
507
+ For `implementation_target: figma`, skip the phased pipeline. Produce Figma-ready implementation specs instead of editing the codebase. Then continue from Step 6 (finalize).
512
508
 
513
- ### Brand feedback on revisions
514
-
515
- After the revision agent completes, check if any QA fixes changed token-level values (colors, typography, spacing, shadows). If so:
509
+ ## Step 8: Revision mode
516
510
 
517
- 1. Ask: "These revisions changed brand-level values. Update brand patterns so future projects inherit the fix?"
518
- 2. If yes, spawn a background `gsp-brand-engineer` agent with the changed values to update `{BRAND_PATH}/patterns/`.
511
+ Read `${CLAUDE_SKILL_DIR}/flows/revision.md` for full instructions.
519
512
 
520
- Then continue from Step 6 (finalize).
513
+ For `needs-revision` status, fix QA issues from `review/issues.md` via a single revision agent. Then continue from Step 6 (finalize).
521
514
  </process>
@@ -0,0 +1,50 @@
1
+ # Build Flow: Figma Fallback
2
+
3
+ Activated when `implementation_target` is `figma` in `config.json`.
4
+
5
+ ## When this runs
6
+
7
+ When the project's target is Figma (designer handoff), there is no codebase to edit. Instead, the builder produces structured implementation specs that a developer can use to implement in Figma or hand off to their dev team.
8
+
9
+ ## Steps
10
+
11
+ ### 1. Log intent
12
+
13
+ Log: "Figma target — producing implementation specs (no codebase to edit)"
14
+
15
+ ### 2. Spawn spec agent
16
+
17
+ Spawn a single `gsp-project-builder` agent with:
18
+ - `execution_mode: full`
19
+ - `spec_only: true`
20
+ - All design chunks from `{PROJECT_PATH}/design/` inlined
21
+ - Brand system: `{BRAND_PATH}/patterns/STYLE.md` and `{BRAND_PATH}/patterns/{brand-name}.yml`
22
+ - Brief: `{PROJECT_PATH}/brief/target-adaptations.md` and `{PROJECT_PATH}/brief/scope.md`
23
+ - Agent methodology (loaded in Step 2.5 of main flow)
24
+
25
+ Agent instructions:
26
+
27
+ > execution_mode: full
28
+ > spec_only: true
29
+ >
30
+ > Produce Figma-ready implementation specs — no codebase to edit.
31
+ >
32
+ > Output:
33
+ > 1. `{PROJECT_PATH}/build/CODE.md` — component-by-component implementation guide:
34
+ > - For each screen: component tree, token values, interaction states, responsive behavior
35
+ > - For each component: props, variants, accessibility requirements
36
+ > - Token table: all CSS variables with values from the brand `.yml`
37
+ >
38
+ > 2. `{PROJECT_PATH}/build/components/` — one `.md` file per significant custom component:
39
+ > - Structure (HTML/JSX pseudocode)
40
+ > - Variants and states
41
+ > - Token usage (which CSS variables drive which properties)
42
+ > - Accessibility notes (ARIA roles, keyboard, focus)
43
+ >
44
+ > Format specs for developer consumption — be precise about measurements, colors (include both OKLCH and hex), and interaction behavior.
45
+
46
+ ### 3. Finalize
47
+
48
+ After the spec agent completes, continue from Step 6 (Finalize) of the main build flow.
49
+
50
+ `BUILD-LOG.md` in this mode documents spec files produced rather than codebase changes.
@@ -0,0 +1,64 @@
1
+ # Build Flow: Revision Mode
2
+
3
+ Activated when `{PROJECT_PATH}/STATE.md` shows build status `needs-revision`.
4
+
5
+ ## When this runs
6
+
7
+ After `/gsp-project-review` completes and writes `{PROJECT_PATH}/review/issues.md` with QA issues, the next invocation of `/gsp-project-build` enters revision mode automatically.
8
+
9
+ ## Steps
10
+
11
+ ### 1. Read issues
12
+
13
+ Read `{PROJECT_PATH}/review/issues.md`. This file contains QA issues prioritized by severity.
14
+
15
+ Log: "Revision mode — addressing QA issues from review/issues.md"
16
+
17
+ ### 2. Spawn revision agent
18
+
19
+ Spawn a single `gsp-project-builder` agent with:
20
+ - `execution_mode: full`
21
+ - `revision: true`
22
+ - Full content of `review/issues.md` inlined
23
+ - Agent methodology (loaded in Step 2.5 of main flow)
24
+ - Visual effects and block patterns refs (loaded in Step 2.6 of main flow)
25
+
26
+ Agent instructions:
27
+
28
+ > execution_mode: full
29
+ > revision: true
30
+ >
31
+ > Fix the QA issues from review/issues.md in the codebase.
32
+ >
33
+ > 1. Work through issues in priority order (critical → high → medium → low)
34
+ > 2. Read the relevant codebase files before editing — don't guess at existing structure
35
+ > 3. Do NOT modify foundation files unless the QA issue explicitly requires it
36
+ > 4. Do NOT refactor or improve code outside the scope of the listed issues
37
+ > 5. Leave changes unstaged
38
+ >
39
+ > After completing revisions, append a `## Revision` section to `{PROJECT_PATH}/build/BUILD-LOG.md` listing each issue addressed (issue ID, file changed, what was fixed).
40
+
41
+ ### 3. Compile check
42
+
43
+ After the revision agent completes, run the build command:
44
+
45
+ | Stack | Build command |
46
+ |-------|--------------|
47
+ | Next.js | `npx next build` |
48
+ | Vite | `npx vite build` |
49
+ | TypeScript only | `npx tsc --noEmit` |
50
+ | Generic | `npm run build` |
51
+
52
+ **Pass:** Continue to brand feedback check.
53
+ **Fail:** Log the error. Surface to user: "Revision introduced build errors: {error}. Fix before finalizing?"
54
+
55
+ ### 4. Brand feedback on revisions
56
+
57
+ After the revision agent completes, check if any QA fixes changed token-level values (colors, typography, spacing, shadows). If so:
58
+
59
+ 1. Ask: "These revisions changed brand-level values. Update brand patterns so future projects inherit the fix?"
60
+ 2. If yes, spawn a background `gsp-brand-engineer` agent with the changed values to update `{BRAND_PATH}/patterns/`.
61
+
62
+ ### 5. Finalize
63
+
64
+ Continue from Step 6 (Finalize) of the main build flow.
@@ -17,7 +17,7 @@ You are spawned with an `execution_mode` parameter. Follow the mode strictly:
17
17
 
18
18
  ### `foundations`
19
19
  Build token integration, global styles, and layout primitives ONLY. Stop after foundations.
20
- - Design tokens → CSS variables / Tailwind config. Use the **token-mapping.md** reference to map `.yml` values to the correct format per target. For shadcn: convert hex to HSL space-separated channels (e.g., `#1E40AF` → `221 72% 40%`), write ALL variables in `:root` and `.dark` scopes (background, foreground, card, popover, primary, secondary, muted, accent, destructive, border, input, ring, sidebar-*, chart-1 through chart-5, --radius). Write only **global tokens**: brand colors, font families, spacing scale, base radius, base shadows. Do NOT write screen-specific tokens yet.
20
+ - Design tokens → CSS variables / Tailwind config. Run `node bin/theme-css.js <preset.yml> --stdout` to generate a ready-to-paste `:root` and `.dark` block in OKLCH format. If `bin/theme-css.js` is unavailable, convert hex to OKLCH manually. Write ALL variables in `:root` and `.dark` scopes (background, foreground, card, popover, primary, secondary, muted, accent, destructive, border, input, ring, sidebar-*, chart-1 through chart-5, --radius). Write only **global tokens**: brand colors, font families, spacing scale, base radius, base shadows. Do NOT write screen-specific tokens yet.
21
21
  - Global CSS (resets, base styles, dark mode)
22
22
  - Layout components (root layout, nav shell, footer shell)
23
23
  - Shared utilities (cn helper, theme provider)
@@ -125,19 +125,72 @@ These rules are always enforced for shadcn targets. They reflect the official sh
125
125
  - Use full Card composition (`CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`)
126
126
  - `TabsTrigger` must be inside `TabsList`
127
127
  - `Avatar` always needs `AvatarFallback`
128
- - Use `Alert` for callouts, `Badge` for status, `Skeleton` for loading, `Separator` for dividers, `sonner` for toast
128
+ - Use `Alert` for callouts, `Badge` for status, `Skeleton` for loading, `Separator` for dividers, `Empty` for empty states, `sonner` for toast
129
+ - `Button` has no `isPending`/`isLoading` prop — compose with `<Spinner data-icon="inline-start" />` + `disabled`
130
+
131
+ **Forms:**
132
+ - Use `FieldGroup` + `Field` for form layout — never raw `div` with `space-y-*` or `grid gap-*`
133
+ - Option sets (2–7 choices) use `ToggleGroup` + `ToggleGroupItem` — not a loop of `Button` with manual active state
134
+ - Buttons inside inputs use `InputGroup` + `InputGroupAddon` — not `relative` positioning with `absolute` button
135
+ - Use `InputGroupInput` / `InputGroupTextarea` inside `InputGroup` — not raw `Input`/`Textarea`
136
+ - Group related checkboxes/radios with `FieldSet` + `FieldLegend` — not `div` with a heading
137
+ - Field validation: `data-invalid` on `Field`, `aria-invalid` on the control; `data-disabled` on `Field`, `disabled` on the control
138
+
139
+ **base vs radix API (check `base` from `npx shadcn@latest info`):**
140
+ - Custom triggers: `asChild` (radix) vs `render` prop (base)
141
+ - Button as link: `<Button asChild><a>` (radix) vs `<Button render={<a />} nativeButton={false}>` (base)
142
+ - `ToggleGroup`: radix uses `type="single"/"multiple"` + string `defaultValue`; base uses no `type` + array `defaultValue`
143
+ - `Slider`: radix always uses array (`defaultValue={[50]}`); base uses plain number for single thumb
144
+ - `Select`: base requires `items` prop on root; radix uses inline JSX only
129
145
 
130
146
  **Icons:**
131
- - Icons in `Button` use `data-icon` attribute (`data-icon="inline-start"` or `data-icon="inline-end"`)
147
+ - Icons in `Button` use `data-icon` attribute (`data-icon="inline-start"` or `data-icon="inline-end"`) — do NOT add `mr-2`/`ml-2` margin; the component handles spacing via CSS
132
148
  - No sizing classes on icons inside components — components handle icon sizing via CSS
133
149
 
134
150
  **CLI awareness:**
135
151
  - Install components via `npx shadcn@latest add {name}` — never copy/paste from GitHub
136
- - Use `npx shadcn@latest search` to find components before building custom ones
152
+ - Use `npx shadcn@latest search {name}` to find components before building custom ones
153
+ - Use `npx shadcn@latest docs {name}` to get live docs and example URLs before implementing or debugging a component
154
+ - Use `npx shadcn@latest add {name} --dry-run` to preview all affected files before writing
155
+ - Use `npx shadcn@latest add {name} --diff {file}` to preview a specific file's changes before overwriting
137
156
  - After installing components from registries, verify imports match the project's alias config
157
+ - After installing from community registries, check added non-UI files for hardcoded `@/components/ui/...` paths — rewrite to match the project's actual aliases
158
+
159
+ **Charts (Recharts v3):**
160
+ - Color references: `fill="var(--chart-1)"` or `fill="var(--color-chart-1)"` — **no `hsl()` wrapper** (tokens are OKLCH, not HSL channels)
161
+ - `<ChartContainer>` **requires** an explicit height — add `className="min-h-[200px]"` or `aspect-video`; no implicit height is set
162
+ - Add `accessibilityLayer` prop to chart root elements (`<BarChart accessibilityLayer>`)
163
+ - The `layout` prop belongs on the parent chart (`<BarChart layout="vertical">`), not on `<Bar>`
164
+
165
+ **Forms (React Hook Form + Field API):**
166
+ - New projects use the `<Field>/<Controller>` API — not `<FormField>/<FormItem>/<FormControl>/<FormMessage>`:
167
+ ```jsx
168
+ <Controller
169
+ name="email"
170
+ control={form.control}
171
+ render={({ field, fieldState }) => (
172
+ <Field data-invalid={fieldState.invalid}>
173
+ <FieldLabel htmlFor={field.name}>Email</FieldLabel>
174
+ <Input {...field} id={field.name} aria-invalid={fieldState.invalid} />
175
+ {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
176
+ </Field>
177
+ )}
178
+ />
179
+ ```
180
+ - Components: `Field`, `FieldLabel`, `FieldDescription`, `FieldError`, `FieldGroup`, `FieldSet`, `FieldLegend`
181
+ - If the existing project has the old `form.tsx` (with `FormField`/`FormItem`), match its pattern — do not mix APIs
182
+
183
+ **Sidebar:**
184
+ - Set custom sidebar width via inline CSS prop on `<SidebarProvider>`:
185
+ ```jsx
186
+ <SidebarProvider style={{ "--sidebar-width": "20rem" } as React.CSSProperties}>
187
+ ```
188
+ - Do not override `--sidebar-width` in `globals.css` — it belongs on the provider instance
138
189
 
139
190
  Full reference: `references/anti-patterns.md` (available via Read for the complete list with fixes).
140
191
 
192
+ **Theming reference:** when building or fixing themes, read `${CLAUDE_SKILL_DIR}/../../gsp-scaffold/shadcn-theming.md` — full token table, dark mode setup, common theming bugs and fixes.
193
+
141
194
  ## Visual Quality Checklist
142
195
 
143
196
  Every screen must pass these before marking complete. When `STYLE.md` is provided, it overrides these defaults.
@@ -0,0 +1,217 @@
1
+ # shadcn/ui Rules — Tier 2: Component Composition
2
+
3
+ Rules for the build phase. The builder agent reads this to compose shadcn components correctly.
4
+
5
+ ---
6
+
7
+ ## The `cn()` helper
8
+
9
+ All conditional class merging uses `cn()` from `@/lib/utils`:
10
+
11
+ ```ts
12
+ import { cn } from "@/lib/utils"
13
+
14
+ // Correct
15
+ <Button className={cn("mt-4", isActive && "ring-2 ring-ring")} />
16
+
17
+ // Wrong — never string-concatenate classes
18
+ <Button className={"mt-4" + (isActive ? " ring-2 ring-ring" : "")} />
19
+ ```
20
+
21
+ `cn` is `clsx` + `tailwind-merge`. It handles class deduplication and Tailwind conflict resolution automatically.
22
+
23
+ ---
24
+
25
+ ## Semantic color tokens — always use these
26
+
27
+ | Instead of | Use |
28
+ |------------|-----|
29
+ | `bg-white` / `bg-black` | `bg-background` |
30
+ | `text-gray-900` | `text-foreground` |
31
+ | `text-gray-500` | `text-muted-foreground` |
32
+ | `bg-gray-100` | `bg-muted` |
33
+ | `bg-gray-50` | `bg-secondary` |
34
+ | `border-gray-200` | `border-border` |
35
+ | `ring-blue-500` | `ring-ring` |
36
+ | raw hex/rgb | Never — always a token |
37
+
38
+ shadcn components use these tokens internally. Using them in custom code makes dark mode automatic.
39
+
40
+ ---
41
+
42
+ ## Slot pattern (asChild)
43
+
44
+ Use `asChild` to merge props into a child component without an extra DOM node:
45
+
46
+ ```tsx
47
+ // Button as a link
48
+ <Button asChild>
49
+ <Link href="/dashboard">Dashboard</Link>
50
+ </Button>
51
+
52
+ // Never add an <a> inside <Button> without asChild
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Variants with `cva`
58
+
59
+ For custom components that need multiple variants, use `cva` (class-variance-authority):
60
+
61
+ ```tsx
62
+ import { cva, type VariantProps } from "class-variance-authority"
63
+
64
+ const cardVariants = cva(
65
+ "rounded-lg border bg-card text-card-foreground shadow",
66
+ {
67
+ variants: {
68
+ size: {
69
+ sm: "p-4",
70
+ md: "p-6",
71
+ lg: "p-8",
72
+ },
73
+ elevated: {
74
+ true: "shadow-lg",
75
+ false: "shadow-sm",
76
+ },
77
+ },
78
+ defaultVariants: {
79
+ size: "md",
80
+ elevated: false,
81
+ },
82
+ }
83
+ )
84
+
85
+ interface CardProps extends VariantProps<typeof cardVariants> {
86
+ className?: string
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Composing shadcn primitives
93
+
94
+ shadcn components are composed from their sub-parts:
95
+
96
+ ```tsx
97
+ // Card with all sub-parts
98
+ <Card>
99
+ <CardHeader>
100
+ <CardTitle>Title</CardTitle>
101
+ <CardDescription>Subtitle</CardDescription>
102
+ </CardHeader>
103
+ <CardContent>Content here</CardContent>
104
+ <CardFooter>
105
+ <Button>Action</Button>
106
+ </CardFooter>
107
+ </Card>
108
+ ```
109
+
110
+ **Rule:** never nest card-level markup inside `<Card>` without using `CardHeader`/`CardContent`/`CardFooter` — it breaks the spacing contract.
111
+
112
+ ---
113
+
114
+ ## Dialog / Sheet
115
+
116
+ ```tsx
117
+ <Dialog>
118
+ <DialogTrigger asChild>
119
+ <Button>Open</Button>
120
+ </DialogTrigger>
121
+ <DialogContent>
122
+ <DialogHeader>
123
+ <DialogTitle>Title</DialogTitle>
124
+ <DialogDescription>Description</DialogDescription>
125
+ </DialogHeader>
126
+ {/* content */}
127
+ <DialogFooter>
128
+ <Button type="submit">Save</Button>
129
+ </DialogFooter>
130
+ </DialogContent>
131
+ </Dialog>
132
+ ```
133
+
134
+ `DialogDescription` is required for accessibility — the dialog announces it to screen readers. Omitting it triggers a console warning.
135
+
136
+ ---
137
+
138
+ ## Form + react-hook-form
139
+
140
+ shadcn Form wraps react-hook-form. Always use the `<Form>` components for labeled inputs — never raw `<input>`:
141
+
142
+ ```tsx
143
+ <Form {...form}>
144
+ <form onSubmit={form.handleSubmit(onSubmit)}>
145
+ <FormField
146
+ control={form.control}
147
+ name="email"
148
+ render={({ field }) => (
149
+ <FormItem>
150
+ <FormLabel>Email</FormLabel>
151
+ <FormControl>
152
+ <Input placeholder="you@example.com" {...field} />
153
+ </FormControl>
154
+ <FormDescription>We'll never share your email.</FormDescription>
155
+ <FormMessage />
156
+ </FormItem>
157
+ )}
158
+ />
159
+ </form>
160
+ </Form>
161
+ ```
162
+
163
+ `FormMessage` renders validation errors automatically from react-hook-form's state.
164
+
165
+ ---
166
+
167
+ ## Sizing utilities
168
+
169
+ | Instead of | Use |
170
+ |------------|-----|
171
+ | `w-6 h-6` | `size-6` (when width === height) |
172
+ | `space-y-4` | `gap-4` (prefer `flex`/`grid` with `gap`) |
173
+ | `mr-2` on icon | `gap-2` on parent flex container |
174
+
175
+ ---
176
+
177
+ ## Server Components (RSC)
178
+
179
+ Check `isRSC` from `npx shadcn@latest info --json`. If true:
180
+ - shadcn components work as Server Components by default
181
+ - Only add `"use client"` when a component uses `useState`, `useEffect`, event handlers, or browser APIs
182
+ - Prefer `onClick` on leaf elements rather than wrapping entire sections in `"use client"`
183
+
184
+ ```tsx
185
+ // Correct — only the interactive button is a client component
186
+ // page.tsx (Server Component)
187
+ import { SubmitButton } from "./submit-button" // "use client"
188
+
189
+ // Wrong — entire section becomes client component unnecessarily
190
+ "use client"
191
+ export function Section() { ... }
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Icon imports
197
+
198
+ Use the icon library from `shadcn info`:
199
+
200
+ ```tsx
201
+ // lucide-react (default for most styles)
202
+ import { ChevronRight, Settings, User } from "lucide-react"
203
+
204
+ // @tabler/icons-react (some styles)
205
+ import { IconChevronRight, IconSettings } from "@tabler/icons-react"
206
+ ```
207
+
208
+ Never import from both in the same project — check `iconLibrary` once and use it everywhere.
209
+
210
+ ---
211
+
212
+ ## Customization rules
213
+
214
+ 1. **Override via className** — always add `className` on top of the component's defaults, never fork the component file unless strictly necessary
215
+ 2. **CSS variables over arbitrary values** — `text-[#FF0000]` is a code smell; use a token instead
216
+ 3. **Brand effects go in globals.css as utilities** — create `.shadow-brand`, `.glow-accent` etc. as CSS utilities; use them as Tailwind class names
217
+ 4. **Never edit generated component files for visual tweaks** — only edit for structural/API changes. Token changes in globals.css automatically propagate
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-project-critique
3
- description: Critique your designs + accessibility audit (creative phase — benefits from capable models)
3
+ description: Critique designs + accessibility audit (creative phase — benefits from capable models) — use when: review the designs, critique this, check accessibility, what's wrong with, give feedback on
4
4
  user-invocable: true
5
5
  context: fork
6
6
  allowed-tools:
@@ -26,6 +26,8 @@ Critique design quality and audit accessibility compliance.
26
26
  <process>
27
27
  ## Step 0: Resolve project and brand
28
28
 
29
+ If `.design/projects/` does not exist: output "No GSP project found. Run `/gsp-start` to begin." and stop.
30
+
29
31
  Resolve project from `.design/projects/` (one → use it, multiple → ask). Set `PROJECT_PATH`.
30
32
 
31
33
  Read `{PROJECT_PATH}/brand.ref` → set `BRAND_PATH`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-project-design
3
- description: Design screens and interaction flows (creative phase — benefits from capable models)
3
+ description: Design screens and interaction flows (creative phase — benefits from capable models) — use when: design this, mock up, create wireframes, how should X look, lay out the UI for
4
4
  user-invocable: true
5
5
  context: fork
6
6
  allowed-tools:
@@ -32,6 +32,8 @@ Design core UI/UX screens and interaction flows.
32
32
  <process>
33
33
  ## Step 0: Resolve project and brand
34
34
 
35
+ If `.design/projects/` does not exist: output "No GSP project found. Run `/gsp-start` to begin." and stop.
36
+
35
37
  Resolve project from `.design/projects/` (one → use it, multiple → ask). Set `PROJECT_PATH`.
36
38
 
37
39
  Read `{PROJECT_PATH}/brand.ref` → set `BRAND_PATH`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-project-research
3
- description: Research UX patterns and technical approaches
3
+ description: Research UX patterns and technical approaches — use when: research this, look up how X works, find patterns for, what's the best approach for
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -35,6 +35,8 @@ Deep research into UX patterns, competitor experiences, and technical approaches
35
35
  <process>
36
36
  ## Step 0: Resolve project and brand
37
37
 
38
+ If `.design/projects/` does not exist: output "No GSP project found. Run `/gsp-start` to begin." and stop.
39
+
38
40
  Resolve project from `.design/projects/` (one → use it, multiple → ask). Set `PROJECT_PATH`.
39
41
 
40
42
  Read `{PROJECT_PATH}/brand.ref` → set `BRAND_PATH`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-project-review
3
- description: QA review — validate implementation against designs
3
+ description: QA review — validate implementation against designs — use when: review the build, QA this, does it match the designs, check what was built, verify implementation
4
4
  user-invocable: true
5
5
  context: fork
6
6
  allowed-tools:
@@ -32,6 +32,8 @@ QA validate the codebase implementation against design intent.
32
32
  <process>
33
33
  ## Step 0: Resolve project and brand
34
34
 
35
+ If `.design/projects/` does not exist: output "No GSP project found. Run `/gsp-start` to begin." and stop.
36
+
35
37
  Resolve project from `.design/projects/` (one → use it, multiple → ask). Set `PROJECT_PATH`.
36
38
 
37
39
  Read `{PROJECT_PATH}/brand.ref` → set `BRAND_PATH`.
@@ -133,6 +135,13 @@ Update `{PROJECT_PATH}/STATE.md`:
133
135
  - If Pass or Conditional Pass: Set Prettiness Level to 100%
134
136
  - Update `## Screen Build Status` table — set Review Status per screen based on acceptance-report.md findings
135
137
 
138
+ If Pass or Conditional Pass, update `.design/CLAUDE.md` — replace the existing `### {project-name}` entry (written by gsp-project-brief when started) with the completed entry:
139
+
140
+ ```markdown
141
+ ### {project-name} · complete · {DATE}
142
+ brand: {brand-name} · .design/projects/{project-name}/
143
+ ```
144
+
136
145
  ### QA loop — if Fail
137
146
 
138
147
  If verdict is **Fail**: