get-shit-pretty 0.7.4 → 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.
- package/bin/theme-css.js +331 -0
- package/gsp/agents/gsp-brand-coherence.md +7 -0
- package/gsp/skills/gsp-brand-brief/SKILL.md +50 -5
- package/gsp/skills/gsp-brand-guidelines/SKILL.md +51 -31
- package/gsp/skills/gsp-brand-guidelines/design-tokens.md +2 -0
- package/gsp/skills/gsp-brand-guidelines/guidelines-structure.md +167 -0
- package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-coherence.md +86 -0
- package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-engineer.md +13 -5
- package/gsp/skills/gsp-brand-guidelines/token-mapping.md +16 -319
- package/gsp/skills/gsp-brand-identity/SKILL.md +1 -1
- package/gsp/skills/gsp-brand-refine/SKILL.md +5 -6
- package/gsp/skills/gsp-brand-research/SKILL.md +1 -1
- package/gsp/skills/gsp-brand-strategy/SKILL.md +1 -1
- package/gsp/skills/gsp-design-system/SKILL.md +1 -1
- package/gsp/skills/gsp-doctor/SKILL.md +51 -3
- package/gsp/skills/gsp-progress/SKILL.md +1 -1
- package/gsp/skills/gsp-project-brief/SKILL.md +40 -6
- package/gsp/skills/gsp-project-build/SKILL.md +22 -29
- package/gsp/skills/gsp-project-build/flows/figma.md +50 -0
- package/gsp/skills/gsp-project-build/flows/revision.md +64 -0
- package/gsp/skills/gsp-project-build/methodology/gsp-project-builder.md +57 -4
- package/gsp/skills/gsp-project-build/shadcn-composition.md +217 -0
- package/gsp/skills/gsp-project-critique/SKILL.md +3 -1
- package/gsp/skills/gsp-project-design/SKILL.md +3 -1
- package/gsp/skills/gsp-project-research/SKILL.md +3 -1
- package/gsp/skills/gsp-project-review/SKILL.md +10 -1
- package/gsp/skills/gsp-scaffold/SKILL.md +49 -12
- package/gsp/skills/gsp-scaffold/shadcn-rules.md +433 -0
- package/gsp/skills/gsp-scaffold/shadcn-theming.md +310 -0
- package/gsp/skills/gsp-start/SKILL.md +18 -2
- package/gsp/skills/gsp-style/SKILL.md +1 -1
- package/gsp/skills/gsp-style/style-preset-schema.md +59 -14
- package/gsp/skills/gsp-style/styles/academia.yml +58 -8
- package/gsp/skills/gsp-style/styles/art-deco.yml +39 -7
- package/gsp/skills/gsp-style/styles/bauhaus.yml +39 -8
- package/gsp/skills/gsp-style/styles/bold-typography.yml +39 -8
- package/gsp/skills/gsp-style/styles/botanical.yml +39 -9
- package/gsp/skills/gsp-style/styles/claymorphism.yml +39 -9
- package/gsp/skills/gsp-style/styles/cyberpunk.yml +39 -7
- package/gsp/skills/gsp-style/styles/enterprise.yml +39 -10
- package/gsp/skills/gsp-style/styles/flat-design.yml +39 -9
- package/gsp/skills/gsp-style/styles/fluent.yml +39 -10
- package/gsp/skills/gsp-style/styles/glassmorphism.yml +39 -8
- package/gsp/skills/gsp-style/styles/humanist-literary.yml +39 -9
- package/gsp/skills/gsp-style/styles/industrial.yml +59 -9
- package/gsp/skills/gsp-style/styles/kinetic.yml +32 -7
- package/gsp/skills/gsp-style/styles/liquid-glass.yml +59 -9
- package/gsp/skills/gsp-style/styles/luxury.yml +59 -9
- package/gsp/skills/gsp-style/styles/material.yml +59 -9
- package/gsp/skills/gsp-style/styles/maximalism.yml +32 -6
- package/gsp/skills/gsp-style/styles/minimal-dark.yml +32 -7
- package/gsp/skills/gsp-style/styles/modern-dark.yml +32 -7
- package/gsp/skills/gsp-style/styles/monochrome.yml +59 -10
- package/gsp/skills/gsp-style/styles/neubrutalism.yml +59 -9
- package/gsp/skills/gsp-style/styles/neumorphism.yml +32 -7
- package/gsp/skills/gsp-style/styles/newsprint.yml +32 -7
- package/gsp/skills/gsp-style/styles/nothing.yml +44 -13
- package/gsp/skills/gsp-style/styles/organic.yml +42 -9
- package/gsp/skills/gsp-style/styles/playful-geometric.yml +43 -9
- package/gsp/skills/gsp-style/styles/professional.yml +41 -10
- package/gsp/skills/gsp-style/styles/retro.yml +42 -8
- package/gsp/skills/gsp-style/styles/saas.yml +42 -9
- package/gsp/skills/gsp-style/styles/sketch.yml +42 -9
- package/gsp/skills/gsp-style/styles/swiss-minimalist.yml +41 -10
- package/gsp/skills/gsp-style/styles/terminal.yml +42 -8
- package/gsp/skills/gsp-style/styles/vaporwave.yml +42 -7
- package/gsp/skills/gsp-style/styles/web3.yml +42 -9
- package/gsp/templates/branding/brief.md +9 -0
- package/gsp/templates/branding/config.json +1 -1
- package/gsp/templates/design-claude.md +6 -0
- package/gsp/templates/phases/patterns.md +2 -2
- package/gsp/templates/projects/config.json +6 -3
- package/gsp/templates/projects/state.md +1 -1
- package/gsp/templates/system/STACK.md +1 -0
- 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
|
|
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**:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-scaffold
|
|
3
|
-
description:
|
|
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
|
-
|
|
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
|
|
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
|
|