@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 +2 -2
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +57 -9
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +49 -16
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/lib/detectors/design-system-detector.js +73 -31
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.
|
|
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.
|
|
379
|
+
*morph-spec v4.10.9 by [Polymorphism Tech](https://polymorphism.tech)*
|
package/claude-plugin.json
CHANGED
package/docs/CHEATSHEET.md
CHANGED
package/docs/QUICKSTART.md
CHANGED
|
@@ -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
|
|
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
|
|
165
|
+
→ Skip steps 4.5.1–4.5.2. Print: `✓ Design system found — .morph/context/design-system.md`
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
### 4.5.1 — ALWAYS scan for existing CSS tokens
|
|
168
168
|
|
|
169
|
-
|
|
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.
|
|
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.
|
|
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
|
|
224
|
-
| Color chosen | Replace `--color-primary: #TODO` with a reasonable hex for that color family
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
7
|
+
cliVersion: "4.10.9"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MORPH Design — Phase 2
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
73
|
+
### Step 0.5: Check Design System
|
|
74
74
|
|
|
75
|
-
**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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.
|
|
7
|
+
cliVersion: "4.10.9"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Scope Escalation Workflow
|
package/package.json
CHANGED
|
@@ -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:
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|