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,329 +1,26 @@
1
- # Token Mapping Reference
1
+ # Token Mapping → bin/theme-css.js
2
2
 
3
- Deterministic mapping from GSP style preset `.yml` tokens to target CSS variable systems. The builder reads the `.yml` and generates the right output for the detected stack — no separate `tokens.json` or `token-mapping.md` needed.
3
+ > **Superseded in v0.8.0.** The static mapping table has been replaced by a deterministic script.
4
4
 
5
- ## Source: `.yml` Token Structure
5
+ GSP presets use shadcn/ui-native token names directly. The `.yml` token keys match shadcn CSS variable names 1:1 — no translation layer is needed.
6
6
 
7
- Every preset (and every brand `.yml`) has this structure:
7
+ ## Generating CSS from a preset
8
8
 
9
- ```yaml
10
- tokens:
11
- color:
12
- primary: "#hex" # Brand primary
13
- secondary: "#hex" # Brand secondary
14
- accent: "#hex" # Brand accent
15
- background: "#hex" # Page background
16
- surface: "#hex" # Card/panel fill
17
- on-primary: "#hex" # Text on primary
18
- on-background: "#hex" # Text on background
19
- error: "#hex"
20
- success: "#hex"
21
- warning: "#hex"
22
- info: "#hex"
23
- muted: "#hex" # Subtle text, borders (optional)
24
-
25
- typography:
26
- font-family-primary: "stack"
27
- font-family-mono: "stack"
28
- font-family-display: "stack" # optional
29
- font-family-secondary: "stack" # optional
30
- font-weight-heading: N
31
- font-weight-body: N
32
- font-size-base: "Npx"
33
- line-height-base: N
34
-
35
- shape:
36
- border-radius-sm: "Npx"
37
- border-radius-md: "Npx"
38
- border-radius-lg: "Npx"
39
- border-width: "Npx"
40
- border-color: "#hex"
41
-
42
- elevation:
43
- shadow-sm: "css-shadow"
44
- shadow-md: "css-shadow"
45
- shadow-lg: "css-shadow"
46
- shadow-xl: "css-shadow"
47
-
48
- spacing:
49
- base: N
50
- scale: [N, N, ...]
51
-
52
- motion:
53
- duration-fast: "Nms"
54
- duration-normal: "Nms"
55
- easing: "css-easing"
56
-
57
- dark_mode:
58
- color:
59
- background: "#hex"
60
- surface: "#hex"
61
- on-background: "#hex"
62
- border-color: "#hex" # optional
63
- muted: "#hex" # optional
64
- ```
65
-
66
- ---
67
-
68
- ## Target: shadcn/ui
69
-
70
- shadcn uses HSL CSS variables in `:root` and `.dark`. The mapping is deterministic — every `.yml` token has exactly one shadcn variable.
71
-
72
- ### Color mapping
73
-
74
- | `.yml` token | shadcn CSS variable | Notes |
75
- |---|---|---|
76
- | `color.background` | `--background` | Page background |
77
- | `color.on-background` | `--foreground` | Primary text |
78
- | `color.surface` | `--card` | Card background |
79
- | `color.on-background` | `--card-foreground` | Card text (same as foreground) |
80
- | `color.surface` | `--popover` | Popover bg (same as card) |
81
- | `color.on-background` | `--popover-foreground` | Popover text |
82
- | `color.primary` | `--primary` | Primary actions |
83
- | `color.on-primary` | `--primary-foreground` | Text on primary |
84
- | `color.secondary` | `--secondary` | Secondary actions |
85
- | `color.on-primary` | `--secondary-foreground` | Text on secondary (derive from contrast) |
86
- | `color.muted` | `--muted` | Muted backgrounds |
87
- | `color.muted` | `--muted-foreground` | Muted text (use muted or derive darker) |
88
- | `color.accent` | `--accent` | Accent highlights |
89
- | `color.on-primary` | `--accent-foreground` | Text on accent (derive from contrast) |
90
- | `color.error` | `--destructive` | Destructive actions |
91
- | `color.on-primary` | `--destructive-foreground` | Text on destructive |
92
- | `shape.border-color` | `--border` | Default borders |
93
- | `shape.border-color` | `--input` | Input borders |
94
- | `color.primary` | `--ring` | Focus ring |
95
- | `color.surface` | `--sidebar-background` | Sidebar bg |
96
- | `color.on-background` | `--sidebar-foreground` | Sidebar text |
97
- | `color.primary` | `--sidebar-primary` | Sidebar active |
98
- | `color.on-primary` | `--sidebar-primary-foreground` | Sidebar active text |
99
- | `color.accent` | `--sidebar-accent` | Sidebar accent |
100
- | `color.on-background` | `--sidebar-accent-foreground` | Sidebar accent text |
101
- | `shape.border-color` | `--sidebar-border` | Sidebar borders |
102
- | `color.primary` | `--sidebar-ring` | Sidebar focus ring |
103
- | | `--chart-1` through `--chart-5` | Derive from primary, secondary, accent, info, success |
104
-
105
- ### Shape mapping
106
-
107
- | `.yml` token | shadcn CSS variable |
108
- |---|---|
109
- | `shape.border-radius-lg` | `--radius` |
110
-
111
- shadcn derives `--radius` down: `calc(var(--radius) - 2px)` for md, `calc(var(--radius) - 4px)` for sm.
112
-
113
- ### Typography
114
-
115
- shadcn doesn't use CSS variables for fonts — set in `tailwind.config` `fontFamily` extend:
116
-
117
- ```js
118
- fontFamily: {
119
- sans: [/* from typography.font-family-primary */],
120
- mono: [/* from typography.font-family-mono */],
121
- }
122
- ```
123
-
124
- ### Dark mode
125
-
126
- | `.yml` dark_mode token | shadcn CSS variable (`.dark` scope) |
127
- |---|---|
128
- | `dark_mode.color.background` | `--background` |
129
- | `dark_mode.color.on-background` | `--foreground` |
130
- | `dark_mode.color.surface` | `--card`, `--popover` |
131
- | `dark_mode.color.border-color` | `--border`, `--input` |
132
- | `dark_mode.color.muted` | `--muted`, `--muted-foreground` |
133
-
134
- Tokens not listed in `dark_mode` inherit their light-mode value.
135
-
136
- ### Color format conversion
137
-
138
- shadcn expects HSL channel values (no `hsl()` wrapper): `210 40% 98%`
139
-
140
- **Conversion:** hex → HSL → extract H S% L% as space-separated string.
141
-
142
- ```
143
- #1E40AF → hsl(221, 72%, 40%) → "221 72% 40%"
9
+ ```bash
10
+ node bin/theme-css.js gsp/skills/gsp-style/styles/professional.yml --stdout
144
11
  ```
145
12
 
146
- ### Complete output example
147
-
148
- Given `professional.yml`:
149
-
150
- ```css
151
- @layer base {
152
- :root {
153
- --background: 0 0% 100%;
154
- --foreground: 222 47% 11%;
155
- --card: 210 40% 98%;
156
- --card-foreground: 222 47% 11%;
157
- --popover: 210 40% 98%;
158
- --popover-foreground: 222 47% 11%;
159
- --primary: 221 72% 40%;
160
- --primary-foreground: 0 0% 100%;
161
- --secondary: 215 16% 47%;
162
- --secondary-foreground: 0 0% 100%;
163
- --muted: 213 27% 84%;
164
- --muted-foreground: 215 16% 47%;
165
- --accent: 199 89% 48%;
166
- --accent-foreground: 0 0% 100%;
167
- --destructive: 0 72% 51%;
168
- --destructive-foreground: 0 0% 100%;
169
- --border: 214 32% 91%;
170
- --input: 214 32% 91%;
171
- --ring: 221 72% 40%;
172
- --radius: 0.75rem;
173
- --chart-1: 221 72% 40%;
174
- --chart-2: 215 16% 47%;
175
- --chart-3: 199 89% 48%;
176
- --chart-4: 217 91% 60%;
177
- --chart-5: 142 71% 45%;
178
- }
179
-
180
- .dark {
181
- --background: 222 47% 11%;
182
- --foreground: 210 40% 96%;
183
- --card: 217 33% 17%;
184
- --card-foreground: 210 40% 96%;
185
- --popover: 217 33% 17%;
186
- --popover-foreground: 210 40% 96%;
187
- --border: 217 19% 27%;
188
- --input: 217 19% 27%;
189
- --muted: 215 20% 65%;
190
- --muted-foreground: 215 20% 65%;
191
- }
192
- }
193
- ```
194
-
195
- ---
196
-
197
- ## Target: Tailwind (no component library)
198
-
199
- For codebases using Tailwind without shadcn, map directly to `tailwind.config` `extend`:
200
-
201
- ```js
202
- theme: {
203
- extend: {
204
- colors: {
205
- primary: "var(--color-primary)",
206
- secondary: "var(--color-secondary)",
207
- accent: "var(--color-accent)",
208
- background: "var(--color-background)",
209
- surface: "var(--color-surface)",
210
- foreground: "var(--color-foreground)",
211
- muted: "var(--color-muted)",
212
- error: "var(--color-error)",
213
- success: "var(--color-success)",
214
- warning: "var(--color-warning)",
215
- },
216
- fontFamily: {
217
- sans: [/* typography.font-family-primary */],
218
- mono: [/* typography.font-family-mono */],
219
- },
220
- borderRadius: {
221
- sm: "var(--radius-sm)",
222
- md: "var(--radius-md)",
223
- lg: "var(--radius-lg)",
224
- },
225
- boxShadow: {
226
- sm: "var(--shadow-sm)",
227
- md: "var(--shadow-md)",
228
- lg: "var(--shadow-lg)",
229
- xl: "var(--shadow-xl)",
230
- },
231
- }
232
- }
233
- ```
234
-
235
- CSS variables use hex directly (no HSL conversion needed):
236
-
237
- ```css
238
- :root {
239
- --color-primary: #1E40AF;
240
- --color-secondary: #475569;
241
- --color-background: #FFFFFF;
242
- --color-surface: #F8FAFC;
243
- --color-foreground: #0F172A;
244
- --color-muted: #94A3B8;
245
- --radius-sm: 6px;
246
- --radius-md: 8px;
247
- --radius-lg: 12px;
248
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
249
- --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
250
- }
251
- ```
252
-
253
- ---
254
-
255
- ## Target: Vanilla CSS
256
-
257
- For non-Tailwind codebases, generate a CSS custom property system with semantic class recipes:
258
-
259
- ```css
260
- :root {
261
- /* Brand */
262
- --color-primary: #1E40AF;
263
- --color-secondary: #475569;
264
- --color-accent: #0EA5E9;
265
- --color-bg: #FFFFFF;
266
- --color-surface: #F8FAFC;
267
- --color-text: #0F172A;
268
- --color-muted: #94A3B8;
269
- --color-border: #E2E8F0;
270
-
271
- /* Semantic */
272
- --color-error: #DC2626;
273
- --color-success: #16A34A;
274
- --color-warning: #D97706;
275
-
276
- /* Shape */
277
- --radius-sm: 6px;
278
- --radius-md: 8px;
279
- --radius-lg: 12px;
280
- --border-width: 1px;
281
-
282
- /* Elevation */
283
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
284
- --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
285
-
286
- /* Spacing */
287
- --space-1: 4px;
288
- --space-2: 8px;
289
- --space-3: 12px;
290
- --space-4: 16px;
291
- --space-6: 24px;
292
- --space-8: 32px;
293
- --space-12: 48px;
294
- --space-16: 64px;
295
-
296
- /* Motion */
297
- --duration-fast: 150ms;
298
- --duration-normal: 250ms;
299
- --easing: cubic-bezier(0.4, 0, 0.2, 1);
300
-
301
- /* Typography */
302
- --font-sans: Inter, system-ui, sans-serif;
303
- --font-mono: SF Mono, Menlo, monospace;
304
- --font-weight-heading: 600;
305
- --font-weight-body: 400;
306
- --font-size-base: 16px;
307
- --line-height-base: 1.6;
308
- }
309
- ```
310
-
311
- ---
312
-
313
- ## Layered resolution
314
-
315
- The builder resolves tokens in this order (last wins):
13
+ Output is `:root { }` + `.dark { }` blocks ready to paste into `globals.css`.
316
14
 
317
- 1. **Preset `.yml`** — base tokens from the style preset (e.g., `professional.yml`)
318
- 2. **Brand `.yml`** — overrides from branding process (e.g., `acme.yml` with `style_base: professional`)
319
- 3. **Dark mode** — `dark_mode.color.*` overrides for `.dark` scope
15
+ ## How it works
320
16
 
321
- If only a preset exists (quick project), step 2 is skipped. The builder generates CSS from whatever `.yml` it receives.
17
+ - Hex `#RRGGBB` values converted to OKLCH (full color math: sRGB linear XYZ OKLab OKLCh)
18
+ - Values containing `oklch(` → passed through as-is (handles alpha variants)
19
+ - All other values (font stacks, shadows, etc.) → passed through verbatim
20
+ - `--radius` derived from `shape.border-radius-lg`
21
+ - `--chart-1` through `--chart-5` derived from palette colors
22
+ - Sidebar vars written from explicit `color.sidebar-*` tokens in the `.yml`
322
23
 
323
- ## When to generate extended files
24
+ ## Token structure
324
25
 
325
- | Scenario | Files produced |
326
- |----------|---------------|
327
- | Quick project (`/gsp-style`) | Preset `.yml` (base) → CSS vars generated at build time |
328
- | Full branding (customized) | Brand `.yml` (inherits preset) + `STYLE.md` |
329
- | Full branding (unchanged from preset) | Only `STYLE.md` (brand `.yml` not needed if identical to preset) |
26
+ See `${CLAUDE_SKILL_DIR}/../gsp-style/style-preset-schema.md` for the full `.yml` schema — all shadcn variables are first-class token keys.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-brand-identity
3
- description: Create your visual identity — logo, color, typography (creative phase — benefits from capable models)
3
+ description: Create visual identity — logo, color, typography (creative phase — benefits from capable models) — use when: design the logo, pick colors, choose fonts, create the visual identity
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-brand-refine
3
- description: Targeted brand adjustments mid-project — tweak colors, typography, or spacing without re-running the full branding diamond
3
+ description: Adjust brand mid-project — use when: tweak the colors, change the font, adjust spacing, the brand feels off, refine the brand
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -82,14 +82,13 @@ Show a clear before/after for each affected token:
82
82
 
83
83
  ─── Proposed Changes ─────────────────
84
84
 
85
- color.brand.accent
85
+ color.accent
86
86
  before: #B8860B
87
87
  after: #E8A317
88
88
  change: increased chroma
89
89
 
90
90
  Cascade:
91
- color.semantic.link → #E8A317
92
- color.semantic.focus-ring → #E8A317
91
+ color.ring → #E8A317 (shares accent as focus ring)
93
92
 
94
93
  Contrast: accent on white 3.2:1 → 2.8:1 ⚠️ below AA
95
94
  accent on dark 8.4:1 → 9.2:1 ✓
@@ -133,8 +132,8 @@ Append to `{BRAND_PATH}/REFINE-LOG.md`:
133
132
 
134
133
  | Token | Before | After |
135
134
  |-------|--------|-------|
136
- | color.brand.accent | #B8860B | #E8A317 |
137
- | color.semantic.link | #B8860B | #E8A317 |
135
+ | color.accent | #B8860B | #E8A317 |
136
+ | color.ring | #B8860B | #E8A317 |
138
137
  ```
139
138
 
140
139
  Display summary:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-brand-research
3
- description: Research your market and competitors
3
+ description: Research market and competitors — use when: research competitors, who else is doing this, market analysis, what do competitors look like
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-brand-strategy
3
- description: Define positioning, voice, and messaging (creative phase — benefits from capable models)
3
+ description: Define positioning, voice, and messaging (creative phase — benefits from capable models) — use when: define our positioning, brand strategy, what's our voice, how do we talk to customers
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-design-system
3
- description: Scan and document the existing design system state
3
+ description: Scan and document the existing design system — use when: scan the codebase, document what components exist, what's already built, inventory the design system
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-doctor
3
- description: Check project health
3
+ description: Check project health — use when: something's broken, check the project, is everything set up right, health check, what's the status of my GSP setup
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -87,6 +87,9 @@ Check each exists:
87
87
  - All present → PASS
88
88
  - Core files missing → FAIL: list which are missing, suggest `/gsp-start`
89
89
 
90
+ **Monorepo app_path check:**
91
+ - If `repo_type` is `monorepo` (in config.json) and `app_path` is empty → WARN: "Project has no `app_path` set. Run `/gsp-project-brief` to assign a target app."
92
+
90
93
  **Design system check:**
91
94
  - If `.design/system/` directory exists, verify at least `STACK.md` is present → PASS
92
95
  - If `.design/system/` is missing and codebase is not greenfield → WARN: "Design system scan missing. Run `/gsp-design-system` to scan."
@@ -242,12 +245,12 @@ Glob for all SKILL.md files in the skills directory (`{runtime-dir}/skills/*/SKI
242
245
  **Check I2: Skill directories are complete (not just SKILL.md)**
243
246
  For each gsp-* skill directory, check if `SKILL.md` references sibling files via `${CLAUDE_SKILL_DIR}/` paths (e.g. `styles/INDEX.yml`). If it does, verify those files/dirs exist in the installed skill directory.
244
247
  - All referenced siblings present → PASS
245
- - Missing siblings → FAIL: "Skill {name} references {path} but it's missing. Re-run the installer: `npx get-shit-pretty`"
248
+ - Missing siblings → FAIL: "Skill {name} references {path} but it's missing. Re-run the installer: `pnpm dlx get-shit-pretty` (or `bunx get-shit-pretty`)"
246
249
 
247
250
  **Check I3: Bundle directories accessible**
248
251
  Check that the runtime bundle directories exist (`{runtime-dir}/templates/`, `{runtime-dir}/references/`). Skills reference these via `${CLAUDE_SKILL_DIR}/../../`.
249
252
  - All present → PASS
250
- - Missing → FAIL: "Bundle directory {dir} missing. Re-run the installer: `npx get-shit-pretty`"
253
+ - Missing → FAIL: "Bundle directory {dir} missing. Re-run the installer: `pnpm dlx get-shit-pretty` (or `bunx get-shit-pretty`)"
251
254
 
252
255
  **Check I4: VERSION file present**
253
256
  Check `{runtime-dir}/VERSION` exists and contains a valid semver string.
@@ -259,9 +262,47 @@ Check `{runtime-dir}/VERSION` exists and contains a valid semver string.
259
262
  Check if `~/.claude/skills/` contains `gsp-*` directories when running from a local install. These cause duplicates between global and local.
260
263
  - Run: `ls ~/.claude/skills/ | grep '^gsp-'`
261
264
  - No matches → PASS
262
- - Matches found → FAIL: "Found {N} stale GSP skills in ~/.claude/skills/. Fix: run `npx get-shit-pretty --claude --local` to reinstall (the installer cleans stale globals automatically), or manually remove: `rm -rf ~/.claude/skills/gsp-*`"
265
+ - Matches found → FAIL: "Found {N} stale GSP skills in ~/.claude/skills/. Fix: run `pnpm dlx get-shit-pretty --claude --local` (or `bunx get-shit-pretty --claude --local`) to reinstall (the installer cleans stale globals automatically), or manually remove: `rm -rf ~/.claude/skills/gsp-*`"
266
+
267
+ ### Stack Compliance Checks (shadcn targets)
268
+
269
+ Only run these checks when `.design/system/STACK.md` exists and at least one project has `implementation_target: shadcn`.
270
+
271
+ > **Monorepo note:** For monorepos, each project's S-checks run in its declared `app_path`. Read `config.json` → `preferences.app_path` before running commands. If `app_path` is empty, run in repo root.
272
+
273
+ **Check S1: Alias drift**
274
+
275
+ Read `config.json` → `preferences.app_path`. Set `APP_PATH` (default `.` if empty).
276
+
277
+ Run `cd {APP_PATH} && npx shadcn@latest info --json` and extract `aliases.components`. Compare to `## Key Paths → Components` in STACK.md.
278
+
279
+ If mismatch → FAIL: "shadcn alias drift — STACK.md declares `{declared}` but live config has `{live}`. Imports will break. Fix by updating `components.json` or `STACK.md`."
280
+
281
+ **Check S2: Tailwind version drift**
282
+
283
+ Run `cd {APP_PATH} && node -e "console.log(require('tailwindcss/package.json').version)"`. Compare major version to `## Tech Stack → Styling` in STACK.md.
284
+
285
+ If major version differs → FAIL: "Tailwind version drift — STACK.md declares `{declared}` but `{live}` is installed. Run `/gsp-scaffold` to realign or update STACK.md."
286
+
287
+ **Check S3: Icon library drift**
288
+
289
+ Read `components.json` → `iconLibrary`. Compare to icon library recorded in STACK.md (if present).
290
+
291
+ If mismatch → WARN: "Icon library drift — STACK.md declares `{declared}` but `components.json` says `{live}`. Agents may import from the wrong package."
292
+
293
+ **Check S4: Token presence in globals.css**
294
+
295
+ Find the global CSS file (from `cd {APP_PATH} && npx shadcn@latest info --json` → `tailwindCssFile`, or glob for `globals.css` inside `APP_PATH`). Check it contains `--background`, `--foreground`, `--primary` CSS custom properties.
296
+
297
+ If missing → WARN: "CSS custom properties not found in `{file}`. Token integration may be incomplete. Run `/gsp-project-build` foundations phase to regenerate."
298
+
299
+ **Check S5: Tailwind v4 source scoping (if Tailwind v4)**
300
+
301
+ If Tailwind v4 detected, check `globals.css` for `@import "tailwindcss"`. If present without `source(...)` modifier, and the repo contains non-source directories with Tailwind class names (like `.design/`) → WARN: "Tailwind v4 source not scoped. Add `source(\"../\")` to avoid scanning `.design/` spec files."
302
+
303
+ All S checks pass → single PASS line: "S1-S5. Stack compliance .......... PASS"
304
+
263
305
 
264
- ### Cross-Instance Checks
265
306
 
266
307
  **Check X1: Multiple projects, same brand**
267
308
  If multiple projects reference the same brand, and brand has changed since any project consumed it → WARN with list of affected projects.
@@ -314,7 +355,14 @@ Overall Health: {SCORE}/100 {emoji}
314
355
  ✅ I4. VERSION file ............ PASS
315
356
  ✅ I5. No duplicate skills ..... PASS
316
357
 
317
- ─── Cross-Instance ────────────────────
358
+ ─── Stack Compliance (shadcn) ────────
359
+ ✅ S1. Alias ....................... PASS
360
+ ✅ S2. Tailwind version ........... PASS
361
+ ✅ S3. Icon library ............... PASS
362
+ ✅ S4. CSS custom properties ....... PASS
363
+ ✅ S5. Source scoping .............. PASS
364
+
365
+ ─── Cross-Instance ────────────────────
318
366
  ✅ X1. Brand Consistency ...... PASS
319
367
 
320
368
  ─── Issues Found ──────────────────────
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-progress
3
- description: How pretty are we?
3
+ description: Show pipeline progress dashboard — use when: where are we, what's done, show progress, how far along, what phase are we on
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gsp-project-brief
3
- description: Scope what you're building
3
+ description: Scope a feature or flow — use when: scope this, define what we're building, plan the project, what should we build, write a brief
4
4
  user-invocable: true
5
5
  allowed-tools:
6
6
  - Read
@@ -31,6 +31,8 @@ Scope the project and plan adaptations from the brand system.
31
31
  <process>
32
32
  ## Step 0: Resolve project and brand
33
33
 
34
+ If `.design/projects/` does not exist: output "No GSP project found. Run `/gsp-start` to begin." and stop.
35
+
34
36
  Resolve project from `.design/projects/` (one → use it, multiple → ask). Set `PROJECT_PATH`.
35
37
 
36
38
  Read `{PROJECT_PATH}/brand.ref` → set `BRAND_PATH`. If brand.ref doesn't exist, tell the user to run `/gsp-start`.
@@ -49,16 +51,41 @@ Also read the brand `.yml` preset from `{BRAND_PATH}/patterns/`.
49
51
 
50
52
  Read:
51
53
  - `{PROJECT_PATH}/BRIEF.md` — what we're building, platforms, tech stack
52
- - `{PROJECT_PATH}/config.json` — get `implementation_target`, `design_scope`, `codebase_type`
54
+ - `{PROJECT_PATH}/config.json` — get `implementation_target`, `design_scope`, `codebase_type`, `app_path`, `repo_type`
55
+
56
+ After reading config, check if `app_path` is empty. If empty AND (`repo_type` is `monorepo` OR multiple `package.json` files are found at `apps/*/package.json` or `packages/*/package.json`), set flag `NEEDS_APP_SELECTION = true`.
53
57
 
54
58
  ### Codebase context
55
59
 
56
60
  Read `.design/system/STACK.md` and `.design/system/COMPONENTS.md` (if exist) — existing tech stack, components, architecture.
57
61
 
62
+ **Stack inheritance (existing codebases):** If `STACK.md` exists and the project `config.json` has empty or generic values for `tech_stack`, `implementation_target`, or `codebase_type`, inherit them from `STACK.md` directly — do not ask the user questions the stack already answers. Update `config.json` with the inherited values before proceeding.
63
+
64
+ The global stack is the compliance baseline. Every project in this workspace must target it. If the user's brief describes a different stack than what `STACK.md` declares (e.g., "I want to use Radix directly" when `STACK.md` says `shadcn/ui`), surface the conflict: "⚠️ Your brief mentions {X}, but the workspace stack is {Y} per STACK.md. Proceed with the workspace stack, or update STACK.md first?"
65
+
58
66
  Read `.design/CHANGELOG.md` — quick history of what prior projects built.
59
67
  For projects with overlapping scope, read their `codebase/MANIFEST.md` for detail.
60
68
  Glob `.design/projects/*/STATE.md` — detect active sibling projects.
61
69
 
70
+ ## Step 1.3: App targeting
71
+
72
+ Run when `NEEDS_APP_SELECTION = true`.
73
+
74
+ 1. Glob for `apps/*/package.json` and `packages/*/package.json` to find all app packages.
75
+ 2. Read each package.json to extract `name` and the primary framework dependency (Next.js, Vite, React Native, etc.).
76
+ 3. Build an app list, e.g.:
77
+ ```
78
+ apps/web → my-app-web (Next.js)
79
+ apps/mobile → my-app-mobile (Expo / React Native)
80
+ packages/ui → my-app-ui (Vite)
81
+ ```
82
+ 4. Use `AskUserQuestion`: "Which app does this project target?" with one option per detected app (showing path + framework) plus **Whole repo (no specific app)**.
83
+ 5. Based on the user's choice:
84
+ - If an app was selected: set `app_path` to the chosen path (e.g. `apps/web`) and `repo_type` to `monorepo`
85
+ - If "Whole repo" was selected: set `app_path` to `""` and `repo_type` to `monorepo`
86
+ 6. Write the updated `app_path` and `repo_type` back to `{PROJECT_PATH}/config.json`.
87
+ 7. Derive `APP_NAME` = last segment of `app_path` (e.g. `apps/web` → `web`, empty → `root`). Note that the per-app stack file will live at `.design/system/stacks/{APP_NAME}.md`.
88
+
62
89
  ## Step 1.5: Scope check
63
90
 
64
91
  **If `design_scope` is `tokens`:**
@@ -69,10 +96,10 @@ Glob `.design/projects/*/STATE.md` — detect active sibling projects.
69
96
 
70
97
  ## Step 1.7: Issue framing
71
98
 
72
- Suggest to the user:
73
- "Consider framing this project as a bounded issue (or set of issues) and a PR. Smaller scope = higher quality. What's the tightest version of this that ships?"
74
-
75
- If the project scope feels large, suggest breaking it into multiple bounded issues — each one a focused deliverable that can be reviewed independently.
99
+ Ask the user (via `AskUserQuestion`): "Is this project linked to a GitHub issue?"
100
+ - **Yes paste the issue URL** → read the issue number from the URL, write `git.issue` to `{PROJECT_PATH}/config.json` and populate the `| Issue |` row in STATE.md. Also read the issue title/body via `gh issue view {number} --json title,body,labels` and use that content to pre-populate scope context (saves the user from re-describing what the issue already states).
101
+ - **No — describe it** → continue with manual brief as before
102
+ - **Skip** continue without issue link
76
103
 
77
104
  ## Step 2: Scope the project
78
105
 
@@ -157,6 +184,13 @@ Update `{PROJECT_PATH}/STATE.md`:
157
184
  - Set Phase 1 (Brief) status to `complete`
158
185
  - Record completion date
159
186
 
187
+ Write/update `.design/CLAUDE.md` — register the project as started. If the file doesn't exist, read the template from `${CLAUDE_SKILL_DIR}/../../templates/design-claude.md` first. Append under `## Projects`:
188
+
189
+ ```markdown
190
+ ### {project-name} · in progress · {DATE}
191
+ brand: {brand-name} · next: gsp-project-research · .design/projects/{project-name}/
192
+ ```
193
+
160
194
  ## Step 5: Phase transition output
161
195
 
162
196
  Invoke `/gsp-phase-transition` with phase `brief` and output directory `{PROJECT_PATH}/brief/`.