@polymorphism-tech/morph-spec 4.10.8 → 4.10.9

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > Spec-driven development framework for multi-stack projects. Turns feature requests into implementation-ready code through structured, AI-orchestrated phases.
4
4
 
5
5
  **Package:** `@polymorphism-tech/morph-spec`
6
- **Version:** 4.10.8
6
+ **Version:** 4.10.9
7
7
  **Requires:** Node.js 18+, Claude Code
8
8
 
9
9
  ---
@@ -376,4 +376,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
376
376
 
377
377
  ---
378
378
 
379
- *morph-spec v4.10.8 by [Polymorphism Tech](https://polymorphism.tech)*
379
+ *morph-spec v4.10.9 by [Polymorphism Tech](https://polymorphism.tech)*
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morph-spec",
3
- "version": "4.10.8",
3
+ "version": "4.10.9",
4
4
  "displayName": "MORPH-SPEC Framework",
5
5
  "description": "Spec-driven development with 38 agents and 8-phase workflow for .NET/Blazor/Next.js/Azure",
6
6
  "publisher": "polymorphism-tech",
@@ -198,4 +198,4 @@ These files are never edited directly. Use CLI commands or `morph-spec update` i
198
198
 
199
199
  ---
200
200
 
201
- *morph-spec v4.10.8 by Polymorphism Tech*
201
+ *morph-spec v4.10.9 by Polymorphism Tech*
@@ -203,4 +203,4 @@ morph-spec doctor
203
203
 
204
204
  ---
205
205
 
206
- *morph-spec v4.10.8 by Polymorphism Tech*
206
+ *morph-spec v4.10.9 by Polymorphism Tech*
@@ -155,24 +155,70 @@ Do **not** ask about technology already confirmed by file evidence.
155
155
 
156
156
  ## Step 4.5 — Scaffold Design System
157
157
 
158
- Check if the project already has a design system file:
158
+ ### 4.5.0 — Check if DS already exists
159
159
 
160
160
  ```
161
161
  Read: .morph/context/design-system.md
162
162
  ```
163
163
 
164
164
  **If the file EXISTS with non-TODO content in the Aesthetic Direction section:**
165
- → Skip this step. Print: `✓ Design system found — .morph/context/design-system.md`
165
+ → Skip steps 4.5.1–4.5.2. Print: `✓ Design system found — .morph/context/design-system.md`
166
166
 
167
- **If the file does NOT EXIST or is empty:**
167
+ ### 4.5.1 — ALWAYS scan for existing CSS tokens
168
168
 
169
- 1. **Copy the template:**
169
+ Search for existing CSS custom properties across the project's frontend directories.
170
+
171
+ Glob these patterns (exclude `node_modules/`, `.next/`, `dist/`, `build/`):
172
+ ```
173
+ wwwroot/**/*.css
174
+ wwwroot/**/*.scss
175
+ styles/**/*.css
176
+ src/styles/**/*.css
177
+ src/**/*.css
178
+ src/**/*.scss
179
+ src/**/*.module.css
180
+ public/**/*.css
181
+ ```
182
+
183
+ For each CSS/SCSS file found, Grep for `:root {` blocks containing `--` custom properties.
184
+
185
+ Track:
186
+ - `cssTokensFound` (bool)
187
+ - `tokenCount` (int — total number of `--variable` lines found)
188
+ - `sourceFiles` (array of file paths that had tokens)
189
+
190
+ ### 4.5.2 — Decision tree
191
+
192
+ **Case A: CSS tokens found (existing project)**
193
+
194
+ 1. Create `.morph/context/design-system.md` from scanned tokens:
195
+ - `## Color Tokens` → `:root { }` block with all found color variables (preserve exact variable names from CSS)
196
+ - `## Typography` → found font-family values (map to `--font-display` / `--font-body` by variable name heuristic)
197
+ - `## Spacing Tokens` → found spacing variables
198
+ - `## Aesthetic Direction` → `#TODO` (requires user judgment — fill in during `/morph-phase-uiux`)
199
+ - `## Changelog` → `- [today's date] [morph-init] Auto-generated from CSS scan ([N] tokens from [files])`
200
+
201
+ 2. Skip the `AskUserQuestion` for direction/brand color — the project has established colors
202
+
203
+ 3. Print:
204
+ ```
205
+ ✓ Design system scaffolded from existing CSS
206
+ Source: [file list]
207
+ Tokens: [N] colors, [M] font families, [K] spacing values
208
+ Note: Aesthetic Direction is TODO — fill in during /morph-phase-uiux
209
+ ```
210
+
211
+ 4. Continue to Step 5.
212
+
213
+ **Case B: No CSS tokens found (greenfield project)**
214
+
215
+ 1. Copy the template:
170
216
  ```bash
171
217
  cp .morph/framework/templates/context/design-system.md .morph/context/design-system.md
172
218
  ```
173
219
  *(The template is at `framework/templates/context/design-system.md` in the installed framework)*
174
220
 
175
- 2. **Ask 3 quick questions** using `AskUserQuestion`:
221
+ 2. Ask 3 quick questions using `AskUserQuestion`:
176
222
 
177
223
  ```json
178
224
  {
@@ -216,15 +262,15 @@ Read: .morph/context/design-system.md
216
262
  }
217
263
  ```
218
264
 
219
- 4. **Fill in the design-system.md** with user responses:
265
+ 4. Fill in the design-system.md with user responses:
220
266
 
221
267
  | User answered | What to update |
222
268
  |--------------|----------------|
223
- | Direction chosen | Replace `[Minimal Refined / Editorial / ...]` with chosen direction. Update Font Pair with the correct fonts from this mapping: Minimal Refined → Cormorant Garamond + DM Sans; Editorial → Playfair Display + Source Sans 3; Soft Professional → Nunito + Inter; Industrial → JetBrains Mono + IBM Plex Sans; Modern Luxury → Bodoni Moda + Sora |
224
- | Color chosen | Replace `--color-primary: #TODO` with a reasonable hex for that color family (deep blue → #1e3a5f, rich green → #065f46, warm orange → #c2410c, purple → #6d28d9, black → #0a0a0a). Add a note: "Adjust exact values to match your brand" |
269
+ | Direction chosen | Replace `[Minimal Refined / Editorial / ...]` with chosen direction. Update Font Pair with the correct fonts: Minimal Refined → Cormorant Garamond + DM Sans; Editorial → Playfair Display + Source Sans 3; Soft Professional → Nunito + Inter; Industrial → JetBrains Mono + IBM Plex Sans; Modern Luxury → Bodoni Moda + Sora |
270
+ | Color chosen | Replace `--color-primary: #TODO` with a reasonable hex for that color family: deep blue → #1e3a5f, rich green → #065f46, warm orange → #c2410c, purple → #6d28d9, black → #0a0a0a. Add note: "Adjust exact values to match your brand" |
225
271
  | "Skip for now" | Leave all TODOs in place |
226
272
 
227
- 5. **Update the Changelog** in design-system.md:
273
+ 5. Update the Changelog in design-system.md:
228
274
  Add entry: `- [today's date] [morph-init] Initial scaffold from morph-init`
229
275
 
230
276
  6. Print confirmation:
@@ -234,6 +280,8 @@ Read: .morph/context/design-system.md
234
280
  Edit to refine exact token values before the UI/UX phase.
235
281
  ```
236
282
 
283
+ 7. Continue to Step 5.
284
+
237
285
  ---
238
286
 
239
287
  ## Step 5 — Generate `context/README.md`
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 3 (Clarify). Iterative clarification loop driven b
4
4
  argument-hint: "[feature-name]"
5
5
  user-invocable: false
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # MORPH Clarify — Phase 3
@@ -3,7 +3,7 @@ name: morph-phase-codebase-analysis
3
3
  description: MORPH-SPEC Design sub-phase that analyzes existing codebase and database schema, producing schema-analysis.md with real column names, types, relationships, and field mismatches. Use at the start of Design phase before generating contracts.cs to prevent incorrect field names or types.
4
4
  user-invocable: false
5
5
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
6
- cliVersion: "4.10.8"
6
+ cliVersion: "4.10.9"
7
7
  ---
8
8
 
9
9
  # MORPH Codebase Analysis - Design Sub-phase
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 2 (Design). Schema-first interactive design: reads
4
4
  argument-hint: "[feature-name]"
5
5
  user-invocable: false
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Agent
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # MORPH Design — Phase 2
@@ -5,7 +5,7 @@ argument-hint: "[feature-name]"
5
5
  context: fork
6
6
  agent: general-purpose
7
7
  user-invocable: false
8
- cliVersion: "4.10.8"
8
+ cliVersion: "4.10.9"
9
9
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Agent
10
10
  ---
11
11
 
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 4 (Plan). Generates a detailed implementation plan
4
4
  argument-hint: "[feature-name]"
5
5
  user-invocable: false
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # MORPH Plan — Phase 4
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 1 (Setup). Reads project context, detects tech sta
4
4
  argument-hint: "[feature-name]"
5
5
  user-invocable: false
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # MORPH Setup — Phase 1
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 4 (Tasks). Breaks approved spec into bottom-up ord
4
4
  argument-hint: "[feature-name]"
5
5
  user-invocable: false
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # MORPH Tasks — Phase 4
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 1.5 (UI/UX). Creates design-system.md, mockups.md,
4
4
  argument-hint: "[feature-name]"
5
5
  user-invocable: false
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # MORPH UI/UX Design - Phase 1.5
@@ -70,31 +70,64 @@ Check the `"phase"` field in the output:
70
70
 
71
71
  ---
72
72
 
73
- ### Step 0.5: Check Design System Exists
73
+ ### Step 0.5: Check Design System
74
74
 
75
- **CRITICAL:** Before starting UI/UX phase, check if a design system exists:
75
+ **This step is MANDATORY and must always run before Step 1.**
76
+
77
+ #### Step 0.5.1 — Scan frontend for CSS tokens (ALWAYS)
78
+
79
+ Search for existing CSS custom properties in the project's frontend directories.
80
+
81
+ Glob these patterns (exclude `node_modules/`, `.next/`, `dist/`, `build/`):
82
+ ```
83
+ wwwroot/**/*.css
84
+ wwwroot/**/*.scss
85
+ styles/**/*.css
86
+ src/styles/**/*.css
87
+ src/**/*.css
88
+ src/**/*.scss
89
+ src/**/*.module.css
90
+ public/**/*.css
91
+ ```
92
+
93
+ For each CSS/SCSS file found, Grep for `:root {` blocks containing `--` custom properties.
94
+
95
+ Classify found tokens:
96
+ - **Colors**: lines with `--color-*`, or any `--*` containing `#hex` / `rgb(...)`
97
+ - **Fonts**: `--font-*` or `font-family:` declarations
98
+ - **Spacing**: `--space-*`, `--gap-*`, `--size-*` with rem/px values
99
+
100
+ Track: `cssTokensFound` (bool), token counts by category, source file list.
101
+
102
+ #### Step 0.5.2 — Check if design-system.md exists
76
103
 
77
104
  ```
78
105
  Read: .morph/context/design-system.md
79
106
  ```
80
107
 
81
- If the file doesn't exist (design system not found):
108
+ Track: `dsExists` (bool).
109
+
110
+ #### Step 0.5.3 — Decision tree (4 cases)
111
+
112
+ | Case | Condition | Action |
113
+ |------|-----------|--------|
114
+ | **A** | `dsExists` AND `cssTokensFound` | Cross-check DS vs scanned tokens. If >2 colors diverge, flag misalignment and ask user if they want to update DS with `AskUserQuestion`. Proceed to Step 1. |
115
+ | **B** | `dsExists` AND NOT `cssTokensFound` | Print: `✓ Design system found (no CSS tokens to cross-check)`. Proceed to Step 1. |
116
+ | **C** | NOT `dsExists` AND `cssTokensFound` | Auto-generate `.morph/context/design-system.md` from scanned tokens (see Case C detail below). Proceed to Step 1. |
117
+ | **D** | NOT `dsExists` AND NOT `cssTokensFound` | Greenfield project. Ask user for aesthetic direction + brand color using `AskUserQuestion` (same options as morph-init). Scaffold from template. Proceed to Step 1. |
82
118
 
83
- 1. **Option A - Automatic scaffold:**
84
- - The system will automatically create a design system when advancing to implementation
85
- - You can generate manually now: `npx morph-spec generate design-system`
119
+ **Case C — auto-generate from scanned tokens:**
86
120
 
87
- 2. **Option B - Create manually:**
88
- - Create `.morph/context/design-system.md` (project-level, shared)
89
- - Or `.morph/features/$ARGUMENTS/2-ui/design-system.md` (feature-specific)
121
+ Create `.morph/context/design-system.md` with these sections populated from scan results:
122
+ - `## Color Tokens` → `:root { }` block with all found color variables (preserve exact variable names)
123
+ - `## Typography` → found font-family values (map by variable name heuristic: `--font-display` vs `--font-body`)
124
+ - `## Spacing Tokens` → found spacing variables
125
+ - `## Aesthetic Direction` → `#TODO` (requires user judgment, fill in manually)
126
+ - `## Changelog` → `- [today's date] [morph-phase-uiux] Auto-generated from CSS scan ([N] tokens from [files])`
90
127
 
91
- 3. **Option C - Scan existing CSS:**
92
- - If the project already has CSS with variables: `npx morph-spec generate design-system --scan`
128
+ Print: `✓ Design system generated from [N] tokens — .morph/context/design-system.md`
93
129
 
94
- **IMPORTANT:**
95
- - Design system is **mandatory** for UI features
96
- - Automatic gate will block implementation (Phase 5) if design system doesn't exist
97
- - Better to create now to ensure visual consistency
130
+ > **Design system is mandatory** for UI features. The implementation gate (Phase 5) will block if no design system exists.
98
131
 
99
132
  ### Step 1: Detect If Phase Is Needed
100
133
 
@@ -4,7 +4,7 @@ description: Guided workflow for mid-implementation scope escalation — analyze
4
4
  user-invocable: true
5
5
  argument-hint: "[feature-name]"
6
6
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
7
- cliVersion: "4.10.8"
7
+ cliVersion: "4.10.9"
8
8
  ---
9
9
 
10
10
  # Scope Escalation Workflow
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "4.10.8",
3
+ "version": "4.10.9",
4
4
  "description": "MORPH-SPEC: AI-First development framework with validation pipeline and multi-stack support",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -7,9 +7,42 @@
7
7
  * @module design-system-detector
8
8
  */
9
9
 
10
- import { existsSync, readFileSync } from 'fs';
10
+ import { existsSync, readFileSync, readdirSync } from 'fs';
11
11
  import { join } from 'path';
12
12
 
13
+ const SKIP_DIRS = new Set(['node_modules', '.git', '.morph', 'dist', 'build', '.next', 'obj', 'bin', '.vs']);
14
+ const CSS_SCAN_MAX_DEPTH = 6;
15
+
16
+ /**
17
+ * Recursively walk a directory collecting files with given extensions.
18
+ * @param {string} dir - Directory to walk
19
+ * @param {string[]} extensions - File extensions to collect (e.g. ['.css', '.scss'])
20
+ * @param {string[]} files - Accumulator array (mutated in-place)
21
+ * @param {number} depth - Current recursion depth
22
+ * @param {number} maxDepth - Maximum recursion depth
23
+ */
24
+ function walkDirForCss(dir, extensions, files, depth, maxDepth) {
25
+ if (depth > maxDepth) return;
26
+ let entries;
27
+ try {
28
+ entries = readdirSync(dir, { withFileTypes: true });
29
+ } catch {
30
+ return;
31
+ }
32
+ for (const entry of entries) {
33
+ if (entry.isDirectory()) {
34
+ if (!SKIP_DIRS.has(entry.name)) {
35
+ walkDirForCss(join(dir, entry.name), extensions, files, depth + 1, maxDepth);
36
+ }
37
+ } else if (entry.isFile()) {
38
+ const lower = entry.name.toLowerCase();
39
+ if (extensions.some(ext => lower.endsWith(ext))) {
40
+ files.push(join(dir, entry.name));
41
+ }
42
+ }
43
+ }
44
+ }
45
+
13
46
  /**
14
47
  * Detect design system for project or feature
15
48
  * @param {string} projectPath - Root path of the project
@@ -70,37 +103,46 @@ export function detectDesignSystem(projectPath, featureName = null) {
70
103
  };
71
104
  }
72
105
 
73
- // Priority 4: Check common CSS locations for design system variables
74
- const commonCssLocations = [
75
- 'wwwroot/css/site.css',
76
- 'wwwroot/css/app.css',
77
- 'styles/globals.css',
78
- 'src/styles/globals.css'
79
- ];
80
-
81
- for (const cssPath of commonCssLocations) {
82
- const fullPath = join(projectPath, cssPath);
83
- if (existsSync(fullPath)) {
84
- // Check if file contains design system variables (CSS custom properties)
85
- try {
86
- const content = readFileSync(fullPath, 'utf8');
87
-
88
- // Look for CSS custom properties that indicate a design system
89
- // Match :root { ... --variable ... } (with newlines)
90
- const hasDesignTokens = /:root\s*\{[\s\S]*?--/.test(content);
91
-
92
- if (hasDesignTokens) {
93
- return {
94
- hasDesignSystem: true,
95
- path: fullPath,
96
- isProjectLevel: true,
97
- isFeatureLevel: false,
98
- source: 'existing-css-variables'
99
- };
100
- }
101
- } catch {
102
- // Continue checking other locations
106
+ // Priority 4: Recursively scan frontend root directories for CSS/SCSS with design tokens
107
+ const frontendRoots = ['wwwroot', 'styles', 'src/styles', 'src', 'public'];
108
+ const extensions = ['.css', '.scss'];
109
+ const collected = [];
110
+
111
+ for (const root of frontendRoots) {
112
+ const rootPath = join(projectPath, root);
113
+ if (existsSync(rootPath)) {
114
+ walkDirForCss(rootPath, extensions, collected, 0, CSS_SCAN_MAX_DEPTH);
115
+ }
116
+ }
117
+
118
+ // Deduplicate by resolved path
119
+ const seen = new Set();
120
+ const cssFiles = [];
121
+ for (const file of collected) {
122
+ if (!seen.has(file)) {
123
+ seen.add(file);
124
+ cssFiles.push(file);
125
+ }
126
+ }
127
+
128
+ // Sort for deterministic first-match across platforms
129
+ cssFiles.sort();
130
+
131
+ for (const cssFile of cssFiles) {
132
+ try {
133
+ const content = readFileSync(cssFile, 'utf8');
134
+ const hasDesignTokens = /:root\s*\{[\s\S]*?--/.test(content);
135
+ if (hasDesignTokens) {
136
+ return {
137
+ hasDesignSystem: true,
138
+ path: cssFile,
139
+ isProjectLevel: true,
140
+ isFeatureLevel: false,
141
+ source: 'existing-css-variables'
142
+ };
103
143
  }
144
+ } catch {
145
+ // Continue checking other files
104
146
  }
105
147
  }
106
148