@polymorphism-tech/morph-spec 4.10.0 → 4.10.1
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/CLAUDE.md +5 -69
- package/framework/agents/backend/api-designer.md +3 -0
- package/framework/agents/backend/dotnet-senior.md +3 -0
- package/framework/agents/backend/ef-modeler.md +2 -0
- package/framework/agents/backend/hangfire-orchestrator.md +2 -0
- package/framework/agents/backend/ms-agent-expert.md +2 -0
- package/framework/agents/frontend/blazor-builder.md +2 -0
- package/framework/agents/frontend/nextjs-expert.md +2 -0
- package/framework/agents/infrastructure/azure-architect.md +2 -0
- package/framework/agents/infrastructure/azure-deploy-specialist.md +2 -0
- package/framework/agents/infrastructure/bicep-architect.md +2 -0
- package/framework/agents/infrastructure/container-specialist.md +2 -0
- package/framework/agents/infrastructure/devops-engineer.md +3 -0
- package/framework/agents/infrastructure/infra-architect.md +3 -0
- package/framework/agents/integrations/asaas-financial.md +2 -0
- package/framework/agents/integrations/azure-identity.md +2 -0
- package/framework/agents/integrations/clerk-auth.md +3 -0
- package/framework/agents/integrations/hangfire-integration.md +2 -0
- package/framework/agents/integrations/resend-email.md +2 -0
- package/framework/commands/morph-apply.md +151 -161
- package/framework/commands/morph-archive.md +28 -28
- package/framework/commands/morph-infra.md +79 -79
- package/framework/commands/morph-preflight.md +92 -56
- package/framework/commands/morph-proposal.md +94 -70
- package/framework/commands/morph-status.md +31 -31
- package/framework/commands/morph-troubleshoot.md +63 -60
- package/framework/rules/csharp-standards.md +3 -0
- package/framework/rules/frontend-standards.md +2 -0
- package/framework/rules/infrastructure-standards.md +3 -0
- package/framework/rules/morph-workflow.md +57 -2
- package/framework/rules/nextjs-standards.md +2 -0
- package/framework/rules/testing-standards.md +3 -0
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +54 -49
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +42 -19
- package/framework/skills/level-0-meta/morph-code-review/SKILL.md +8 -5
- package/framework/skills/level-0-meta/morph-code-review-nextjs/SKILL.md +7 -5
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +139 -136
- package/framework/skills/level-0-meta/morph-init/SKILL.md +42 -13
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +130 -130
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +95 -87
- package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +24 -0
- package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +42 -41
- package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +22 -11
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +123 -114
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +120 -102
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +206 -214
- package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +38 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +241 -360
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +107 -115
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +135 -135
- package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +14 -0
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +143 -139
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +168 -165
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +57 -8
- package/package.json +3 -3
- package/src/commands/project/doctor.js +7 -2
- package/src/commands/project/update.js +4 -4
- package/src/lib/stack-filter.js +58 -0
- package/src/scripts/setup-infra.js +53 -18
- package/src/utils/agents-installer.js +19 -5
- package/src/utils/claude-md-injector.js +90 -0
- package/src/utils/hooks-installer.js +1 -4
- package/src/utils/skills-installer.js +67 -7
- package/CLAUDE.md +0 -98
- package/framework/memory/patterns-learned.md +0 -766
- package/framework/skills/level-0-meta/morph-terminal-title/SKILL.md +0 -61
- package/framework/skills/level-0-meta/morph-terminal-title/scripts/set_title.sh +0 -65
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: morph:frontend-review
|
|
3
|
-
description:
|
|
4
|
-
mockups),
|
|
5
|
-
breakpoints via Playwright, axe-core a11y
|
|
6
|
-
|
|
3
|
+
description: Complete frontend audit — validates design outputs (design-system, WCAG contrast,
|
|
4
|
+
mockups), static accessibility scan (TSX + Razor), responsive screenshots at 3
|
|
5
|
+
breakpoints via Playwright, axe-core a11y at runtime, and SEO (Next.js metadata). Covers Next.js
|
|
6
|
+
and Blazor. Triggered at end of phase-uiux and post-implementation.
|
|
7
7
|
argument-hint: "[feature-name]"
|
|
8
8
|
user-invocable: true
|
|
9
|
-
allowed-tools: Read, Write, Edit, Bash, Glob, Grep,
|
|
9
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion,
|
|
10
10
|
mcp__playwright__browser_navigate, mcp__playwright__browser_resize,
|
|
11
11
|
mcp__playwright__browser_take_screenshot, mcp__playwright__browser_snapshot,
|
|
12
12
|
mcp__playwright__browser_evaluate, mcp__playwright__browser_console_messages
|
|
13
13
|
cliVersion: "4.8.19"
|
|
14
|
+
stacks:
|
|
15
|
+
- blazor
|
|
16
|
+
- nextjs
|
|
14
17
|
---
|
|
15
18
|
|
|
16
19
|
# Frontend Review
|
|
17
20
|
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
> (
|
|
21
|
+
> Complete frontend audit: design outputs, static + runtime accessibility, responsive
|
|
22
|
+
> screenshots and SEO. Triggered at end of `phase-uiux` (validates design) and post-implementation
|
|
23
|
+
> (validates implemented code).
|
|
21
24
|
|
|
22
|
-
> **
|
|
23
|
-
>
|
|
24
|
-
> `plugin_playwright_playwright`),
|
|
25
|
+
> **Note about MCP:** The `mcp__playwright__` prefix corresponds to the Playwright server name
|
|
26
|
+
> as configured in the project's `settings.json`. If the server has a different name (e.g.,
|
|
27
|
+
> `plugin_playwright_playwright`), adjust the prefix in the calls below.
|
|
25
28
|
|
|
26
29
|
---
|
|
27
30
|
|
|
28
|
-
## Step 0 —
|
|
31
|
+
## Step 0 — Detect Context and Stack
|
|
29
32
|
|
|
30
33
|
```bash
|
|
31
34
|
node .claude/skills/morph-post-implementation/scripts/detect-stack.mjs
|
|
@@ -33,128 +36,128 @@ node .claude/skills/morph-post-implementation/scripts/detect-stack.mjs
|
|
|
33
36
|
|
|
34
37
|
Output JSON: `{ stack: "DOTNET" | "NEXTJS" | "FULLSTACK" | "UNKNOWN", frontendPath, backendPath, startCommand }`
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
Beyond the stack, determine the **context** by examining what exists:
|
|
37
40
|
|
|
38
41
|
```bash
|
|
39
|
-
#
|
|
42
|
+
# Check if design outputs exist
|
|
40
43
|
ls .morph/features/$ARGUMENTS/2-ui/ 2>/dev/null
|
|
41
44
|
|
|
42
|
-
#
|
|
45
|
+
# Check if implemented frontend files exist
|
|
43
46
|
find . -name "*.tsx" -o -name "*.razor" 2>/dev/null | head -5
|
|
44
47
|
```
|
|
45
48
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
+
- If `.morph/features/$ARGUMENTS/2-ui/ui-design-system.md` exists → context includes **design validation**
|
|
50
|
+
- If implemented frontend files exist (`.tsx`, `.razor`) → context includes **implementation validation**
|
|
51
|
+
- Both can coexist
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
Store `stack`, `frontendPath`, `startCommand` and the detected context — all steps depend on them.
|
|
51
54
|
|
|
52
55
|
---
|
|
53
56
|
|
|
54
|
-
## Step 1 —
|
|
57
|
+
## Step 1 — Design Outputs Validation (if context includes design validation)
|
|
55
58
|
|
|
56
59
|
```bash
|
|
57
|
-
npx morph-spec validate-feature $ARGUMENTS
|
|
60
|
+
npx morph-spec validate-feature $ARGUMENTS
|
|
58
61
|
```
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
Verify existence and quality of the 4 mandatory outputs in `.morph/features/$ARGUMENTS/2-ui/`:
|
|
61
64
|
|
|
62
65
|
```
|
|
63
|
-
[ ] ui-design-system.md —
|
|
64
|
-
[ ] ui-mockups.md — wireframes
|
|
65
|
-
[ ] ui-components.md —
|
|
66
|
-
[ ] ui-flows.md —
|
|
67
|
-
[ ]
|
|
68
|
-
[ ]
|
|
69
|
-
[ ]
|
|
66
|
+
[ ] ui-design-system.md — color palette, typography tokens, spacing
|
|
67
|
+
[ ] ui-mockups.md — wireframes with responsive states
|
|
68
|
+
[ ] ui-components.md — technical component specs
|
|
69
|
+
[ ] ui-flows.md — user journeys and edge cases
|
|
70
|
+
[ ] WCAG AA Contrast: primary and text colors ≥ 4.5:1 (check ui-design-system.md)
|
|
71
|
+
[ ] Documented touch targets: ≥ 44x44px for mobile
|
|
72
|
+
[ ] Loading/error/empty states defined in mockups
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
**🚫 BLOCK**
|
|
75
|
+
**🚫 BLOCK** if `validate-feature` fails or mandatory outputs missing.
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
Read `ui-design-system.md` and manually verify that primary and text colors have a contrast ratio
|
|
78
|
+
≥ 4.5:1. Reference tools: WebAIM Contrast Checker (WCAG 2.1 AA criteria).
|
|
76
79
|
|
|
77
80
|
---
|
|
78
81
|
|
|
79
|
-
## Step 2 —
|
|
82
|
+
## Step 2 — Static Accessibility Scan
|
|
80
83
|
|
|
81
84
|
```bash
|
|
82
85
|
node .claude/skills/morph-frontend-review/scripts/scan-accessibility.mjs $frontendPath
|
|
83
86
|
```
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
Blazor (`.razor`).
|
|
88
|
+
The script automatically detects file extensions to determine Next.js (`.tsx`) vs
|
|
89
|
+
Blazor (`.razor`). If `frontendPath` is not defined, the script uses `.` (project root).
|
|
87
90
|
|
|
88
|
-
**Checks
|
|
91
|
+
**Checks implemented:**
|
|
89
92
|
|
|
90
|
-
| ID |
|
|
93
|
+
| ID | Severity | Files | Checks |
|
|
91
94
|
|----|-----------|---------|---------|
|
|
92
|
-
| `IMG_MISSING_ALT` | CRITICAL | .tsx, .razor | `<img`
|
|
93
|
-
| `INPUT_MISSING_LABEL` | HIGH | .tsx, .razor | `<input`/`<InputText`/`<FluentTextField`
|
|
94
|
-
| `HEADING_HIERARCHY` | HIGH | .tsx, .razor |
|
|
95
|
-
| `LINK_NO_TEXT` | HIGH | .tsx, .razor | `<a`
|
|
96
|
-
| `BUTTON_NO_TEXT` | HIGH | .tsx, .razor | `<button`/`<FluentButton`
|
|
97
|
-
| `AUTOPLAY_MEDIA` | MEDIUM | .tsx, .razor | `<video`/`<audio`
|
|
98
|
-
| `FLUENT_CHECKBOX_NO_LABEL` | MEDIUM | .razor | `<FluentCheckbox`
|
|
95
|
+
| `IMG_MISSING_ALT` | CRITICAL | .tsx, .razor | `<img` missing `alt=` attribute |
|
|
96
|
+
| `INPUT_MISSING_LABEL` | HIGH | .tsx, .razor | `<input`/`<InputText`/`<FluentTextField` without `aria-label`, `aria-labelledby`, or associated `<label for=` |
|
|
97
|
+
| `HEADING_HIERARCHY` | HIGH | .tsx, .razor | Heading level skip (H1→H3 skipping H2) |
|
|
98
|
+
| `LINK_NO_TEXT` | HIGH | .tsx, .razor | `<a` empty or with only icon and no `aria-label` |
|
|
99
|
+
| `BUTTON_NO_TEXT` | HIGH | .tsx, .razor | `<button`/`<FluentButton` no text and no `aria-label` |
|
|
100
|
+
| `AUTOPLAY_MEDIA` | MEDIUM | .tsx, .razor | `<video`/`<audio` with `autoPlay` without `muted` |
|
|
101
|
+
| `FLUENT_CHECKBOX_NO_LABEL` | MEDIUM | .razor | `<FluentCheckbox` without `Label=` |
|
|
99
102
|
|
|
100
|
-
**🚫 BLOCK**
|
|
103
|
+
**🚫 BLOCK** if any CRITICAL finding or HIGH count ≥ 3.
|
|
101
104
|
|
|
102
|
-
|
|
105
|
+
Fix all CRITICALs before continuing. For HIGH < 3, record in summary as warnings.
|
|
103
106
|
|
|
104
107
|
---
|
|
105
108
|
|
|
106
|
-
## Step 3 —
|
|
109
|
+
## Step 3 — Frontend Code Scan (if context includes implementation validation)
|
|
107
110
|
|
|
108
|
-
###
|
|
111
|
+
### If NEXTJS or FULLSTACK:
|
|
109
112
|
|
|
110
113
|
```bash
|
|
111
114
|
node .claude/skills/morph-code-review-nextjs/scripts/scan-nextjs.mjs $frontendPath
|
|
112
115
|
```
|
|
113
116
|
|
|
114
|
-
>
|
|
117
|
+
> Skip if already run by `post-implementation` in the same session.
|
|
115
118
|
|
|
116
|
-
**🚫 BLOCK**
|
|
119
|
+
**🚫 BLOCK** if CRITICAL findings found.
|
|
117
120
|
|
|
118
|
-
###
|
|
121
|
+
### If DOTNET or FULLSTACK (Blazor):
|
|
119
122
|
|
|
120
|
-
|
|
123
|
+
Manually verify the main checklist categories for the implemented feature:
|
|
121
124
|
|
|
122
125
|
```
|
|
123
|
-
[ ]
|
|
124
|
-
[ ] EventCallback<T>
|
|
125
|
-
[ ] Dispose
|
|
126
|
-
[ ]
|
|
127
|
-
[ ] StateHasChanged()
|
|
128
|
-
[ ]
|
|
129
|
-
[ ]
|
|
126
|
+
[ ] Blazor components with correctly typed parameters
|
|
127
|
+
[ ] EventCallback<T> for events — no direct Action/Func
|
|
128
|
+
[ ] Dispose implemented where there are subscriptions (IDisposable)
|
|
129
|
+
[ ] No business logic in .razor files (separate into @code or classes)
|
|
130
|
+
[ ] StateHasChanged() called only when necessary
|
|
131
|
+
[ ] Forms with EditForm and DataAnnotationsValidator
|
|
132
|
+
[ ] Required fields with [Required] and defined error messages
|
|
130
133
|
```
|
|
131
134
|
|
|
132
|
-
**🚫 BLOCK**
|
|
135
|
+
**🚫 BLOCK** if any CRITICAL item is found.
|
|
133
136
|
|
|
134
137
|
---
|
|
135
138
|
|
|
136
|
-
## Step 4 — Screenshots
|
|
139
|
+
## Step 4 — Responsive Screenshots (Playwright MCP)
|
|
137
140
|
|
|
138
|
-
### 4a.
|
|
141
|
+
### 4a. Detect Dev Server
|
|
139
142
|
|
|
140
143
|
```bash
|
|
141
144
|
node .claude/skills/morph-post-implementation/scripts/detect-dev-server.mjs "$startCommand"
|
|
142
145
|
```
|
|
143
146
|
|
|
144
|
-
### 4b.
|
|
147
|
+
### 4b. If dev server available (exit 0):
|
|
145
148
|
|
|
146
|
-
|
|
149
|
+
Extract the main feature URLs by reading `spec.md`:
|
|
147
150
|
|
|
148
151
|
```bash
|
|
149
152
|
Read: .morph/features/$ARGUMENTS/1-design/spec.md
|
|
150
153
|
```
|
|
151
154
|
|
|
152
|
-
|
|
155
|
+
For each main page (max 3), capture screenshots at 3 breakpoints:
|
|
153
156
|
|
|
154
157
|
```javascript
|
|
155
158
|
// Mobile (375px)
|
|
156
159
|
await mcp__playwright__browser_resize({ width: 375, height: 812 });
|
|
157
|
-
await mcp__playwright__browser_navigate({ url: '<url
|
|
160
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
158
161
|
await mcp__playwright__browser_take_screenshot({
|
|
159
162
|
type: 'png',
|
|
160
163
|
filename: `.morph/features/${ARGUMENTS}/visual-screenshots/mobile-<page>.png`
|
|
@@ -162,7 +165,7 @@ await mcp__playwright__browser_take_screenshot({
|
|
|
162
165
|
|
|
163
166
|
// Tablet (768px)
|
|
164
167
|
await mcp__playwright__browser_resize({ width: 768, height: 1024 });
|
|
165
|
-
await mcp__playwright__browser_navigate({ url: '<url
|
|
168
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
166
169
|
await mcp__playwright__browser_take_screenshot({
|
|
167
170
|
type: 'png',
|
|
168
171
|
filename: `.morph/features/${ARGUMENTS}/visual-screenshots/tablet-<page>.png`
|
|
@@ -170,45 +173,45 @@ await mcp__playwright__browser_take_screenshot({
|
|
|
170
173
|
|
|
171
174
|
// Desktop (1440px)
|
|
172
175
|
await mcp__playwright__browser_resize({ width: 1440, height: 900 });
|
|
173
|
-
await mcp__playwright__browser_navigate({ url: '<url
|
|
176
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
174
177
|
await mcp__playwright__browser_take_screenshot({
|
|
175
178
|
type: 'png',
|
|
176
179
|
filename: `.morph/features/${ARGUMENTS}/visual-screenshots/desktop-<page>.png`
|
|
177
180
|
});
|
|
178
181
|
```
|
|
179
182
|
|
|
180
|
-
Screenshots
|
|
181
|
-
(
|
|
183
|
+
Screenshots saved to: `.morph/features/$ARGUMENTS/visual-screenshots/`
|
|
184
|
+
(works in both phase `2-ui` and `5-implement`)
|
|
182
185
|
|
|
183
|
-
### 4c.
|
|
186
|
+
### 4c. If dev server NOT available (exit 1):
|
|
184
187
|
|
|
185
|
-
**⚠️
|
|
188
|
+
**⚠️ WARNING: Dev server not found.**
|
|
186
189
|
|
|
187
|
-
|
|
190
|
+
Request explicit user confirmation before skipping screenshots:
|
|
188
191
|
|
|
189
192
|
```
|
|
190
|
-
Dev server
|
|
193
|
+
Dev server not detected. Responsive screenshots via Playwright cannot be captured.
|
|
191
194
|
|
|
192
|
-
|
|
193
|
-
1.
|
|
194
|
-
2.
|
|
195
|
+
Options:
|
|
196
|
+
1. Start the server manually and re-run /morph:frontend-review
|
|
197
|
+
2. Explicitly confirm you want to skip screenshots and why
|
|
195
198
|
|
|
196
|
-
|
|
199
|
+
Cannot proceed to axe-core without dev server.
|
|
197
200
|
```
|
|
198
201
|
|
|
199
|
-
**
|
|
202
|
+
**Wait for response before continuing.**
|
|
200
203
|
|
|
201
204
|
---
|
|
202
205
|
|
|
203
|
-
## Step 5 — axe-core Runtime (Playwright MCP,
|
|
206
|
+
## Step 5 — axe-core Runtime (Playwright MCP, if dev server active)
|
|
204
207
|
|
|
205
|
-
|
|
208
|
+
For each feature page (use the same URLs from Step 4):
|
|
206
209
|
|
|
207
210
|
```javascript
|
|
208
|
-
//
|
|
209
|
-
await mcp__playwright__browser_navigate({ url: '<url
|
|
211
|
+
// Navigate to the page
|
|
212
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
210
213
|
|
|
211
|
-
//
|
|
214
|
+
// Inject axe-core via CDN and run WCAG 2.1 AA scan
|
|
212
215
|
await mcp__playwright__browser_evaluate({
|
|
213
216
|
function: `async () => {
|
|
214
217
|
if (!window.axe) {
|
|
@@ -234,11 +237,11 @@ await mcp__playwright__browser_evaluate({
|
|
|
234
237
|
});
|
|
235
238
|
```
|
|
236
239
|
|
|
237
|
-
|
|
238
|
-
- `critical` / `serious` → **🚫 BLOCK** (
|
|
239
|
-
- `moderate` / `minor` →
|
|
240
|
+
Group violations by impact:
|
|
241
|
+
- `critical` / `serious` → **🚫 BLOCK** (do not create PR)
|
|
242
|
+
- `moderate` / `minor` → report as warnings in summary, non-blocking
|
|
240
243
|
|
|
241
|
-
|
|
244
|
+
Also check for accessibility-related console errors:
|
|
242
245
|
|
|
243
246
|
```javascript
|
|
244
247
|
await mcp__playwright__browser_console_messages({ level: 'error' });
|
|
@@ -248,111 +251,111 @@ await mcp__playwright__browser_console_messages({ level: 'error' });
|
|
|
248
251
|
|
|
249
252
|
## Step 6 — SEO Check (Next.js only)
|
|
250
253
|
|
|
251
|
-
|
|
254
|
+
Scan feature `page.tsx` files to verify metadata:
|
|
252
255
|
|
|
253
256
|
```bash
|
|
254
|
-
#
|
|
257
|
+
# Find feature pages
|
|
255
258
|
find . -name "page.tsx" -path "*$ARGUMENTS*" 2>/dev/null
|
|
256
259
|
|
|
257
|
-
#
|
|
260
|
+
# Check if they have metadata
|
|
258
261
|
grep -l "export const metadata\|export async function generateMetadata" $(find . -name "page.tsx" -path "*$ARGUMENTS*" 2>/dev/null)
|
|
259
262
|
```
|
|
260
263
|
|
|
261
|
-
Checklist
|
|
264
|
+
Checklist per page:
|
|
262
265
|
|
|
263
266
|
```
|
|
264
|
-
[ ] export const metadata
|
|
265
|
-
[ ] og:title
|
|
266
|
-
[ ] og:image
|
|
267
|
-
[ ]
|
|
268
|
-
[ ] robots
|
|
267
|
+
[ ] export const metadata with title and description
|
|
268
|
+
[ ] og:title and og:description (Open Graph)
|
|
269
|
+
[ ] og:image defined (for social sharing)
|
|
270
|
+
[ ] No duplicate titles between pages
|
|
271
|
+
[ ] robots doesn't block public page indexing
|
|
269
272
|
```
|
|
270
273
|
|
|
271
|
-
> SEO
|
|
274
|
+
> SEO doesn't block PR — report as warnings in final summary.
|
|
272
275
|
|
|
273
276
|
---
|
|
274
277
|
|
|
275
|
-
## Step 7 —
|
|
278
|
+
## Step 7 — Responsive Design Checklist
|
|
276
279
|
|
|
277
|
-
|
|
280
|
+
After viewing Step 4 screenshots:
|
|
278
281
|
|
|
279
282
|
```
|
|
280
|
-
[ ] Mobile (375px):
|
|
281
|
-
[ ] Tablet (768px): layout
|
|
282
|
-
[ ] Desktop (1440px):
|
|
283
|
-
[ ]
|
|
284
|
-
[ ]
|
|
283
|
+
[ ] Mobile (375px): no horizontal scroll, buttons ≥ 44px, legible text
|
|
284
|
+
[ ] Tablet (768px): layout adapts (sidebar collapses, grid adjusts columns)
|
|
285
|
+
[ ] Desktop (1440px): uses available space, no stretched content
|
|
286
|
+
[ ] Navigation works on all breakpoints
|
|
287
|
+
[ ] Forms accessible on mobile (visible labels, large enough inputs)
|
|
285
288
|
```
|
|
286
289
|
|
|
287
|
-
|
|
288
|
-
|
|
290
|
+
If screenshots were not captured (dev server unavailable), mark as "unverified" and
|
|
291
|
+
record in summary.
|
|
289
292
|
|
|
290
293
|
---
|
|
291
294
|
|
|
292
|
-
## Step 8 —
|
|
295
|
+
## Step 8 — Summary and Artifacts
|
|
293
296
|
|
|
294
|
-
|
|
297
|
+
Create consolidated summary file:
|
|
295
298
|
|
|
296
299
|
```bash
|
|
297
300
|
mkdir -p ".morph/features/$ARGUMENTS/visual-screenshots"
|
|
298
301
|
```
|
|
299
302
|
|
|
300
|
-
|
|
303
|
+
Save to `.morph/features/$ARGUMENTS/visual-screenshots/morph:frontend-review-summary.md`:
|
|
301
304
|
|
|
302
305
|
```markdown
|
|
303
306
|
# Frontend Review — {feature}
|
|
304
307
|
|
|
305
|
-
**
|
|
306
|
-
**Stack:** {stack
|
|
307
|
-
**
|
|
308
|
+
**Date:** {date}
|
|
309
|
+
**Stack:** {detected stack}
|
|
310
|
+
**Context:** design validation | implementation validation | both
|
|
308
311
|
|
|
309
|
-
##
|
|
312
|
+
## Results
|
|
310
313
|
|
|
311
314
|
### Step 1 — Design Outputs
|
|
312
315
|
- validate-feature: ✅ PASS / 🚫 BLOCK
|
|
313
|
-
- Outputs
|
|
314
|
-
-
|
|
316
|
+
- Outputs verified: ui-design-system.md, ui-mockups.md, ui-components.md, ui-flows.md
|
|
317
|
+
- WCAG Contrast: {result}
|
|
315
318
|
|
|
316
|
-
### Step 2 —
|
|
317
|
-
-
|
|
319
|
+
### Step 2 — Static Accessibility Scan
|
|
320
|
+
- Files scanned: {N}
|
|
318
321
|
- Findings: {total} ({CRITICAL: N, HIGH: N, MEDIUM: N})
|
|
319
322
|
- Status: ✅ PASS / 🚫 BLOCK
|
|
320
323
|
|
|
321
|
-
### Step 3 —
|
|
322
|
-
- Status: ✅ PASS / 🚫 BLOCK / ⏭️
|
|
324
|
+
### Step 3 — Frontend Code Scan
|
|
325
|
+
- Status: ✅ PASS / 🚫 BLOCK / ⏭️ skipped (already run)
|
|
323
326
|
|
|
324
|
-
### Step 4 — Screenshots
|
|
325
|
-
- Mobile (375px): {paths
|
|
326
|
-
- Tablet (768px): {paths
|
|
327
|
-
- Desktop (1440px): {paths
|
|
327
|
+
### Step 4 — Responsive Screenshots
|
|
328
|
+
- Mobile (375px): {paths or "not captured"}
|
|
329
|
+
- Tablet (768px): {paths or "not captured"}
|
|
330
|
+
- Desktop (1440px): {paths or "not captured"}
|
|
328
331
|
|
|
329
332
|
### Step 5 — axe-core Runtime
|
|
330
|
-
-
|
|
333
|
+
- Critical/serious violations: {N} → ✅ / 🚫
|
|
331
334
|
- Warnings (moderate/minor): {N}
|
|
332
335
|
|
|
333
336
|
### Step 6 — SEO (Next.js)
|
|
334
|
-
-
|
|
335
|
-
- Gaps: {
|
|
337
|
+
- Pages with metadata: {N}/{total}
|
|
338
|
+
- Gaps: {list or "none"}
|
|
336
339
|
|
|
337
|
-
## Status
|
|
340
|
+
## Overall Status
|
|
338
341
|
|
|
339
342
|
**{✅ PASS / 🚫 BLOCK}**
|
|
340
343
|
|
|
341
|
-
{
|
|
344
|
+
{If BLOCK: reason(s) listed here}
|
|
342
345
|
```
|
|
343
346
|
|
|
344
347
|
---
|
|
345
348
|
|
|
346
|
-
##
|
|
349
|
+
## Block Summary
|
|
347
350
|
|
|
348
|
-
| Step |
|
|
351
|
+
| Step | Block Condition |
|
|
349
352
|
|------|-------------------|
|
|
350
|
-
| Step 1 | `validate-feature`
|
|
351
|
-
| Step 2 |
|
|
352
|
-
| Step 3 |
|
|
353
|
-
| Step 5 | Dev server
|
|
353
|
+
| Step 1 | `validate-feature` failed or mandatory outputs missing |
|
|
354
|
+
| Step 2 | Any CRITICAL finding or HIGH ≥ 3 in static scan |
|
|
355
|
+
| Step 3 | Any CRITICAL finding in code scan |
|
|
356
|
+
| Step 5 | Dev server active + axe-core violations `critical` or `serious` |
|
|
354
357
|
|
|
355
|
-
**
|
|
358
|
+
**All BLOCKs must be resolved before creating the PR (when run post-implementation).**
|
|
356
359
|
|
|
357
360
|
---
|
|
358
361
|
|
|
@@ -125,13 +125,13 @@ uiLibrary: shadcn | fluent-ui | mudblazor | null
|
|
|
125
125
|
monorepo: true | false
|
|
126
126
|
frontendPath: src/frontend (if monorepo)
|
|
127
127
|
backendPath: src/backend (if monorepo)
|
|
128
|
-
architectureStyle: vertical-slice | null ←
|
|
128
|
+
architectureStyle: vertical-slice | null ← new
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
**VSA detection:** `architectureStyle: "vertical-slice"`
|
|
132
|
-
- `Abstractions/IHandler.cs`
|
|
133
|
-
- `Pipelines/ValidationDecorator.cs`
|
|
134
|
-
- 2+
|
|
131
|
+
**VSA detection:** `architectureStyle: "vertical-slice"` if any of these exist:
|
|
132
|
+
- `Abstractions/IHandler.cs` found by Glob
|
|
133
|
+
- `Pipelines/ValidationDecorator.cs` found by Glob
|
|
134
|
+
- 2+ folders with `Feature` suffix in `Features/` (e.g., `BookFeature`, `OrderFeature`)
|
|
135
135
|
|
|
136
136
|
---
|
|
137
137
|
|
|
@@ -143,9 +143,9 @@ Ask at most 3 questions, only those that apply:
|
|
|
143
143
|
|
|
144
144
|
| # | Question | Condition | Purpose |
|
|
145
145
|
|---|----------|-----------|---------|
|
|
146
|
-
| 1 | *"
|
|
147
|
-
| 2 | *"
|
|
148
|
-
| 3 | *"Supabase Cloud (managed)
|
|
146
|
+
| 1 | *"In one sentence: what is the main purpose of **[ProjectName]**?"* | Always | README.md Overview |
|
|
147
|
+
| 2 | *"Confirmed: frontend at `{frontendPath}`, backend at `{backendPath}`. Correct?"* | Monorepo detected | Validate paths before persisting |
|
|
148
|
+
| 3 | *"Supabase Cloud (managed) or self-hosted?"* | Supabase detected | MCP URL configuration |
|
|
149
149
|
|
|
150
150
|
Do **not** ask about technology already confirmed by file evidence.
|
|
151
151
|
|
|
@@ -200,7 +200,7 @@ Read `.morph/config/config.json` and merge into `project`:
|
|
|
200
200
|
}
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
**
|
|
203
|
+
**If `architectureStyle: "vertical-slice"` was detected in Step 3**, also add:
|
|
204
204
|
|
|
205
205
|
```json
|
|
206
206
|
{
|
|
@@ -210,7 +210,7 @@ Read `.morph/config/config.json` and merge into `project`:
|
|
|
210
210
|
}
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
And inform the user:
|
|
214
214
|
|
|
215
215
|
```
|
|
216
216
|
✓ Detected: Vertical Slice Architecture (IHandler.cs / *Feature folders)
|
|
@@ -218,12 +218,12 @@ E informe o usuário:
|
|
|
218
218
|
→ morph-spec will use vsa-architect + contracts-vsa.cs for features
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
>
|
|
221
|
+
> This key is what activates `vsa-architect` instead of `domain-architect` during `/morph-proposal`.
|
|
222
222
|
|
|
223
|
-
**
|
|
223
|
+
**If the project doesn't exist yet (new VSA project from scratch)**, also inform:
|
|
224
224
|
|
|
225
225
|
```
|
|
226
|
-
|
|
226
|
+
To create a new VSA project:
|
|
227
227
|
dotnet new install https://github.com/polymorphism-tech/Morph_Template_VerticalSliceArchitecture
|
|
228
228
|
dotnet new vsa -n MyProject
|
|
229
229
|
cd MyProject && npx morph-spec init
|
|
@@ -324,6 +324,35 @@ Use `AskUserQuestion` with header `"{MCP} failed"` and these options:
|
|
|
324
324
|
|
|
325
325
|
---
|
|
326
326
|
|
|
327
|
+
## Step 7.7 — Run Doctor
|
|
328
|
+
|
|
329
|
+
After all configuration is complete, run the health check to verify everything is properly installed:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
npx morph-spec doctor
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
This validates: config.json integrity, agents.json presence, hooks installation, skills distribution, required command files, and state.json schema version. Fix any reported issues before proceeding.
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Step 7.8 — Workflow Selection
|
|
340
|
+
|
|
341
|
+
If the project stack suggests a non-standard workflow, ask the user:
|
|
342
|
+
|
|
343
|
+
| Stack | Default Workflow | Alternative |
|
|
344
|
+
|-------|-----------------|-------------|
|
|
345
|
+
| Node.js CLI (no UI) | `nodejs-cli` (skips uiux/clarify/sync) | `standard` |
|
|
346
|
+
| .NET + Blazor | `standard` (all phases) | — |
|
|
347
|
+
| Next.js | `standard` (all phases) | — |
|
|
348
|
+
|
|
349
|
+
For Node.js CLI projects, update config:
|
|
350
|
+
```json
|
|
351
|
+
{ "workflow": "nodejs-cli" }
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
327
356
|
## Step 8 — Final Output
|
|
328
357
|
|
|
329
358
|
Before printing the summary, check `~/.claude/settings.local.json` for `env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`. If set to `"1"`, mark Agent Teams as enabled; otherwise show the warning.
|