get-shit-pretty 0.7.3 → 0.8.2

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 (78) hide show
  1. package/bin/theme-css.js +331 -0
  2. package/gsp/agents/gsp-brand-coherence.md +7 -0
  3. package/gsp/hooks/hooks.json +1 -1
  4. package/gsp/skills/gsp-brand-brief/SKILL.md +50 -5
  5. package/gsp/skills/gsp-brand-guidelines/SKILL.md +51 -31
  6. package/gsp/skills/gsp-brand-guidelines/design-tokens.md +2 -0
  7. package/gsp/skills/gsp-brand-guidelines/guidelines-structure.md +167 -0
  8. package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-coherence.md +86 -0
  9. package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-engineer.md +13 -5
  10. package/gsp/skills/gsp-brand-guidelines/token-mapping.md +16 -319
  11. package/gsp/skills/gsp-brand-identity/SKILL.md +1 -1
  12. package/gsp/skills/gsp-brand-refine/SKILL.md +5 -6
  13. package/gsp/skills/gsp-brand-research/SKILL.md +1 -1
  14. package/gsp/skills/gsp-brand-strategy/SKILL.md +1 -1
  15. package/gsp/skills/gsp-design-system/SKILL.md +1 -1
  16. package/gsp/skills/gsp-doctor/SKILL.md +51 -3
  17. package/gsp/skills/gsp-progress/SKILL.md +1 -1
  18. package/gsp/skills/gsp-project-brief/SKILL.md +40 -6
  19. package/gsp/skills/gsp-project-build/SKILL.md +27 -31
  20. package/gsp/skills/gsp-project-build/flows/figma.md +50 -0
  21. package/gsp/skills/gsp-project-build/flows/revision.md +64 -0
  22. package/gsp/skills/gsp-project-build/methodology/gsp-project-builder.md +84 -1
  23. package/gsp/skills/gsp-project-build/shadcn-composition.md +217 -0
  24. package/gsp/skills/gsp-project-critique/SKILL.md +3 -1
  25. package/gsp/skills/gsp-project-design/SKILL.md +3 -2
  26. package/gsp/skills/gsp-project-design/methodology/gsp-project-designer.md +28 -21
  27. package/gsp/skills/gsp-project-research/SKILL.md +3 -1
  28. package/gsp/skills/gsp-project-review/SKILL.md +10 -1
  29. package/gsp/skills/gsp-scaffold/SKILL.md +67 -11
  30. package/gsp/skills/gsp-scaffold/shadcn-rules.md +433 -0
  31. package/gsp/skills/gsp-scaffold/shadcn-theming.md +310 -0
  32. package/gsp/skills/gsp-start/SKILL.md +18 -2
  33. package/gsp/skills/gsp-style/SKILL.md +1 -1
  34. package/gsp/skills/gsp-style/style-preset-schema.md +59 -14
  35. package/gsp/skills/gsp-style/styles/academia.yml +58 -8
  36. package/gsp/skills/gsp-style/styles/art-deco.yml +39 -7
  37. package/gsp/skills/gsp-style/styles/bauhaus.yml +39 -8
  38. package/gsp/skills/gsp-style/styles/bold-typography.yml +39 -8
  39. package/gsp/skills/gsp-style/styles/botanical.yml +39 -9
  40. package/gsp/skills/gsp-style/styles/claymorphism.yml +39 -9
  41. package/gsp/skills/gsp-style/styles/cyberpunk.yml +39 -7
  42. package/gsp/skills/gsp-style/styles/enterprise.yml +39 -10
  43. package/gsp/skills/gsp-style/styles/flat-design.yml +39 -9
  44. package/gsp/skills/gsp-style/styles/fluent.yml +39 -10
  45. package/gsp/skills/gsp-style/styles/glassmorphism.yml +39 -8
  46. package/gsp/skills/gsp-style/styles/humanist-literary.yml +39 -9
  47. package/gsp/skills/gsp-style/styles/industrial.yml +59 -9
  48. package/gsp/skills/gsp-style/styles/kinetic.yml +32 -7
  49. package/gsp/skills/gsp-style/styles/liquid-glass.yml +59 -9
  50. package/gsp/skills/gsp-style/styles/luxury.yml +59 -9
  51. package/gsp/skills/gsp-style/styles/material.yml +59 -9
  52. package/gsp/skills/gsp-style/styles/maximalism.yml +32 -6
  53. package/gsp/skills/gsp-style/styles/minimal-dark.yml +32 -7
  54. package/gsp/skills/gsp-style/styles/modern-dark.yml +32 -7
  55. package/gsp/skills/gsp-style/styles/monochrome.yml +59 -10
  56. package/gsp/skills/gsp-style/styles/neubrutalism.yml +59 -9
  57. package/gsp/skills/gsp-style/styles/neumorphism.yml +32 -7
  58. package/gsp/skills/gsp-style/styles/newsprint.yml +32 -7
  59. package/gsp/skills/gsp-style/styles/nothing.yml +44 -13
  60. package/gsp/skills/gsp-style/styles/organic.yml +42 -9
  61. package/gsp/skills/gsp-style/styles/playful-geometric.yml +43 -9
  62. package/gsp/skills/gsp-style/styles/professional.yml +41 -10
  63. package/gsp/skills/gsp-style/styles/retro.yml +42 -8
  64. package/gsp/skills/gsp-style/styles/saas.yml +42 -9
  65. package/gsp/skills/gsp-style/styles/sketch.yml +42 -9
  66. package/gsp/skills/gsp-style/styles/swiss-minimalist.yml +41 -10
  67. package/gsp/skills/gsp-style/styles/terminal.yml +42 -8
  68. package/gsp/skills/gsp-style/styles/vaporwave.yml +42 -7
  69. package/gsp/skills/gsp-style/styles/web3.yml +42 -9
  70. package/gsp/templates/branding/brief.md +9 -0
  71. package/gsp/templates/branding/config.json +1 -1
  72. package/gsp/templates/design-claude.md +6 -0
  73. package/gsp/templates/phases/design.md +0 -8
  74. package/gsp/templates/phases/patterns.md +2 -2
  75. package/gsp/templates/projects/config.json +6 -3
  76. package/gsp/templates/projects/state.md +1 -1
  77. package/gsp/templates/system/STACK.md +1 -0
  78. package/package.json +1 -1
@@ -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`.
@@ -146,7 +148,6 @@ Pass in the agent prompt:
146
148
  The agent writes chunks directly:
147
149
  - `design/screen-{NN}-{name}.md` (one per screen)
148
150
  - `design/shared/` (personas, IA, navigation, micro-interactions, responsive, component-plan)
149
- - `design/preview.html` (self-contained wireframe preview)
150
151
  - `design/INDEX.md`
151
152
  - Updates `{PROJECT_PATH}/exports/INDEX.md` (design section)
152
153
 
@@ -13,21 +13,40 @@ When an **Existing Components** inventory is provided (for `shadcn`, `rn-reusabl
13
13
  <methodology>
14
14
  ## Design Process
15
15
 
16
+ ### Step 0: Internalize brand DNA (BEFORE designing anything)
17
+
18
+ When `STYLE.md` is provided, read it first and extract a working checklist before designing any screen. STYLE.md is your design law — not a reference to consult later, but the lens through which every decision is made.
19
+
20
+ Extract and hold in working memory:
21
+ - **Constraints** → hard boundaries (never/always lists). Violating these is a Critical error.
22
+ - **Patterns** → component composition rules (how to build cards, buttons, inputs, etc.)
23
+ - **Effects vocabulary** → the ONLY interaction techniques you may use. Anything not listed is off-limits.
24
+ - **Bold bets** → brand-specific techniques you MUST actively implement. These are what prevent generic output. If the brand has "purple atmospheric glow" as a bold bet, every relevant screen must show it.
25
+ - **Intensity dials** → calibrate your creativity (variance drives layout, motion drives animation, density drives spacing)
26
+
27
+ Every screen you design must reference specific techniques by name (e.g., "lift-shadow on feature cards", "press-down on CTA", "purple glow behind glass hero") — never generic terms like "use brand styling."
28
+
29
+ ### Steps 1-8: Design with brand DNA active
30
+
16
31
  1. **Define personas** — From BRIEF.md audience, create primary persona with goals and pain points
17
32
  2. **Map information architecture** — Hierarchy, grouping, navigation structure
18
33
  3. **Choose navigation pattern** — Tab bar, sidebar, or custom — justified by use case
19
- 4. **Design 8 core screens** — Each with wireframe description, component usage, interactions, and all states
34
+ 4. **Design core screens** — Each with wireframe description, component usage, interactions, and all states. Apply brand patterns and effects in every screen — not as a separate pass, but as the default visual language.
20
35
  5. **Specify accessibility** — WCAG compliance, VoiceOver order, Dynamic Type behavior
21
- 6. **Define micro-interactions** — Meaningful animations that communicate state changes
36
+ 6. **Define micro-interactions** — Only use techniques from the effects vocabulary. Reference them by name.
22
37
  7. **Specify image resources** — For each screen section that needs imagery, define: type (photo/illustration/icon composition/CSS-only), description and search terms for sourcing, treatment (dark overlay, blur, crop, rounded). Match the brand's imagery style from `imagery-style.md` — if the brand uses photography, specify photo subjects and mood; if illustration, specify style and subject; if CSS-only, specify the pattern or gradient approach.
23
38
  8. **Build component plan** — When existing components inventory is provided, annotate which components to reuse, refactor, or create new
24
- 9. **Apply brand visual DNA** — When `STYLE.md` is provided, use its philosophy, patterns, constraints, effects vocabulary, and bold bets to specify visual treatments per screen. STYLE.md is your design law:
25
- - **Patterns** component composition rules (how to build cards, buttons, inputs, etc.)
26
- - **Constraints** → hard boundaries (never/always lists — do not violate these)
27
- - **Effects** interaction vocabulary (only use techniques from the allowed list)
28
- - **Bold Bets** brand-specific techniques to actively implement (prevents generic output)
29
- - **Intensity dials** calibrate your creativity (variance drives layout, motion drives animation, density drives spacing)
30
- In screen chunks, reference specific techniques by name (e.g., "lift-shadow on feature cards", "press-down on CTA") not generic terms like "use brand styling"
39
+
40
+ ### Step 9: Brand fidelity self-check
41
+
42
+ Before writing INDEX.md, verify your output against STYLE.md:
43
+ - [ ] Every constraint respected (check the never/always lists)
44
+ - [ ] Every bold bet appears in at least one screen (list which screen for each)
45
+ - [ ] Effects vocabulary is the only source of interaction techniques used
46
+ - [ ] Intensity dials match — variance, motion, density are calibrated correctly
47
+ - [ ] No generic visual treatments — every surface, shadow, glow, gradient references a named brand technique
48
+
49
+ If any bold bet is missing from all screens, go back and add it. Bold bets are the brand's differentiation — skipping them produces generic output.
31
50
 
32
51
  ## Style Feedback Detection
33
52
 
@@ -111,18 +130,6 @@ Write to `design/shared/` (~50-100 lines each):
111
130
 
112
131
  Shared chunks link to related shared chunks and relevant screen chunks.
113
132
 
114
- ### `design/preview.html`
115
-
116
- After writing all screen chunks, generate a self-contained HTML preview file:
117
- - Single HTML file with embedded CSS (no external dependencies)
118
- - One section per screen showing a wireframe-level layout visualization
119
- - Use simple boxes, text labels, and semantic structure to represent each screen's layout
120
- - Include navigation between screens
121
- - Use the brand's color tokens (from the brand `.yml`) for accents if available, otherwise use neutral grays
122
- - Responsive — preview itself adapts to viewport width
123
- - Add a table of contents sidebar listing all screens
124
- - Keep it minimal — this is a wireframe preview, not a polished mockup
125
-
126
133
  ### `INDEX.md`
127
134
 
128
135
  After writing all chunks, write `INDEX.md` in the design directory:
@@ -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**:
@@ -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` |
47
72
 
48
- Read `.design/system/STACK.md` if it exists — check what's already set up.
73
+ 3. **Gate on divergence:**
74
+ - If any divergence found, surface it clearly:
75
+ ```
76
+ ⚠️ Stack compliance — divergence detected
49
77
 
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).
78
+ STACK.md declares: aliases.components = @/components/ui
79
+ Live codebase has: aliases.components = ~/components/ui
80
+
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)
86
+
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:
@@ -184,6 +221,21 @@ Clear any build cache first (`rm -rf .next` for Next.js), then run the build com
184
221
  - After fix attempt, clear cache and re-run build once
185
222
  - **Second failure:** Log the error and stop. Do not loop.
186
223
 
224
+ ## Step 5.5: Capture project context (shadcn targets)
225
+
226
+ If `implementation_target` is `shadcn`, run `cd {APP_PATH} && npx shadcn@latest info --json` and capture the output. This provides:
227
+ - `aliases` — the actual alias prefix for imports (`@/`, `~/`)
228
+ - `tailwindVersion` — `"v4"` (uses `@theme inline`) vs `"v3"` (uses `tailwind.config.js`)
229
+ - `tailwindCssFile` — the global CSS file where custom properties go
230
+ - `style` — component visual treatment (nova, vega, etc.)
231
+ - `base` — primitive library (radix or base)
232
+ - `iconLibrary` — determines icon imports (lucide-react, @tabler/icons-react, etc.)
233
+ - `resolvedPaths` — exact file-system destinations for components, utils, hooks
234
+ - `framework` — routing and file conventions (Next.js App Router, Vite SPA, etc.)
235
+ - `isRSC` — whether "use client" directives are needed
236
+
237
+ Include this JSON in the scaffold log under a `## Project Context` section so the foundations agent can reference it.
238
+
187
239
  ## Step 6: Write scaffold log
188
240
 
189
241
  Write `{PROJECT_PATH}/build/SCAFFOLD-LOG.md`:
@@ -191,7 +243,7 @@ Write `{PROJECT_PATH}/build/SCAFFOLD-LOG.md`:
191
243
  ```markdown
192
244
  # Scaffold Log
193
245
 
194
- > Phase: build (scaffold) | Project: {name} | Generated: {DATE}
246
+ > Phase: build (scaffold) | Project: {name} | App: {APP_PATH} | Generated: {DATE}
195
247
 
196
248
  ## Stack
197
249
 
@@ -225,6 +277,10 @@ Write `{PROJECT_PATH}/build/SCAFFOLD-LOG.md`:
225
277
  - **Result:** {pass / fail}
226
278
  - **Output:** {first/last lines if relevant}
227
279
 
280
+ ## Project Context
281
+
282
+ {If shadcn target: JSON output from `npx shadcn@latest info --json`. Otherwise: "N/A — non-shadcn target"}
283
+
228
284
  ## Issues
229
285
 
230
286
  {Any problems encountered and how they were resolved, or "None"}