@polymorphism-tech/morph-spec 4.9.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/bin/morph-spec.js +30 -0
- package/bin/task-manager.js +34 -22
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +35 -98
- 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/agents.json +37 -7
- package/framework/commands/commit.md +166 -0
- package/framework/commands/morph-apply.md +156 -155
- package/framework/commands/morph-archive.md +33 -27
- package/framework/commands/morph-infra.md +83 -77
- package/framework/commands/morph-preflight.md +97 -55
- package/framework/commands/morph-proposal.md +131 -58
- package/framework/commands/morph-status.md +36 -30
- package/framework/commands/morph-troubleshoot.md +68 -59
- package/framework/hooks/claude-code/notification/approval-reminder.js +3 -2
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +154 -31
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +7 -84
- package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +8 -17
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +16 -3
- package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +4 -3
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +3 -2
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +60 -0
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +55 -2
- package/framework/hooks/claude-code/session-start/post-compact-restore.js +41 -0
- package/framework/hooks/claude-code/stop/validate-completion.js +2 -15
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +23 -5
- package/framework/hooks/shared/compact-restore.js +100 -0
- package/framework/hooks/shared/dispatch-helpers.js +116 -0
- package/framework/hooks/shared/phase-utils.js +9 -5
- package/framework/hooks/shared/state-reader.js +27 -3
- package/framework/phases.json +30 -7
- 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 +143 -86
- package/framework/rules/nextjs-standards.md +2 -0
- package/framework/rules/testing-standards.md +3 -0
- package/framework/skills/level-0-meta/mcp-registry.json +86 -51
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +139 -0
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +42 -19
- package/framework/skills/level-0-meta/{code-review → morph-code-review}/SKILL.md +8 -5
- package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md +8 -6
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +362 -0
- package/framework/skills/level-0-meta/morph-init/SKILL.md +114 -20
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +362 -0
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +95 -87
- package/framework/skills/level-0-meta/{simulation-checklist → morph-simulation-checklist}/SKILL.md +24 -0
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/SKILL.md +43 -43
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/references/tools-per-phase.md +1 -2
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/SKILL.md +23 -12
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/scripts/check-phase-outputs.mjs +2 -2
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +247 -0
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +270 -0
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +499 -0
- 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 +472 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +50 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +45 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +47 -0
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +246 -0
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +238 -0
- 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 +312 -0
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/scripts/validate-tasks.mjs +3 -3
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +324 -0
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +146 -0
- package/framework/standards/integration/mcp/mcp-tools.md +25 -7
- package/framework/templates/docs/onboarding.md +2 -2
- package/package.json +3 -4
- package/src/commands/agents/dispatch-agents.js +50 -3
- package/src/commands/mcp/mcp-setup.js +39 -2
- package/src/commands/phase/phase-reset.js +74 -0
- package/src/commands/project/doctor.js +26 -7
- package/src/commands/project/update.js +4 -4
- package/src/commands/scope/escalate.js +215 -0
- package/src/commands/state/advance-phase.js +27 -53
- package/src/commands/state/state.js +1 -1
- package/src/commands/task/expand.js +100 -0
- package/src/core/paths/output-schema.js +4 -3
- package/src/core/state/phase-state-machine.js +7 -4
- package/src/core/state/state-manager.js +4 -3
- package/src/lib/detectors/claude-config-detector.js +93 -347
- package/src/lib/detectors/design-system-detector.js +189 -189
- package/src/lib/detectors/index.js +155 -57
- package/src/lib/generators/context-generator.js +2 -2
- package/src/lib/installers/mcp-installer.js +37 -5
- package/src/lib/phase-chain/phase-validator.js +22 -16
- package/src/lib/scope/impact-analyzer.js +106 -0
- package/src/lib/stack-filter.js +58 -0
- package/src/lib/tasks/task-parser.js +1 -1
- package/src/lib/validators/shared/emit-validator-dispatch.js +64 -0
- package/src/scripts/setup-infra.js +68 -18
- package/src/utils/agents-installer.js +51 -17
- package/src/utils/claude-md-injector.js +90 -0
- package/src/utils/file-copier.js +0 -1
- package/src/utils/hooks-installer.js +16 -5
- 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/brainstorming/SKILL.md +0 -137
- package/framework/skills/level-0-meta/frontend-review/SKILL.md +0 -359
- package/framework/skills/level-0-meta/post-implementation/SKILL.md +0 -362
- package/framework/skills/level-0-meta/terminal-title/SKILL.md +0 -61
- package/framework/skills/level-0-meta/terminal-title/scripts/set_title.sh +0 -65
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +0 -216
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +0 -252
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +0 -383
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +0 -492
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +0 -195
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +0 -271
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +0 -286
- package/src/commands/project/index.js +0 -8
- package/src/core/index.js +0 -10
- package/src/core/state/index.js +0 -8
- package/src/core/templates/index.js +0 -9
- package/src/core/templates/template-data-sources.js +0 -325
- package/src/core/workflows/index.js +0 -7
- package/src/lib/detectors/config-detector.js +0 -223
- package/src/lib/detectors/standards-generator.js +0 -335
- package/src/lib/detectors/structure-detector.js +0 -275
- package/src/lib/monitor/agent-resolver.js +0 -144
- package/src/lib/monitor/renderer.js +0 -230
- package/src/lib/orchestration/index.js +0 -7
- package/src/lib/orchestration/team-orchestrator.js +0 -404
- package/src/sanitizer/context-sanitizer.js +0 -221
- package/src/sanitizer/patterns.js +0 -163
- package/src/writer/file-writer.js +0 -86
- /package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/references/proposal-example.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-example.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-guidelines.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/scripts/scan-csharp.mjs +0 -0
- /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/references/review-example-nextjs.md +0 -0
- /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/scripts/scan-nextjs.mjs +0 -0
- /package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/scripts/scan-accessibility.mjs +0 -0
- /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-dev-server.mjs +0 -0
- /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-stack.mjs +0 -0
- /package/framework/skills/level-1-workflows/{phase-clarify → morph-phase-clarify}/references/clarifications-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/architecture-analysis-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-authoring-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/recap-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/vsa-implementation-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/task-planning-patterns.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/tasks-example.md +0 -0
|
@@ -7,15 +7,21 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
7
7
|
|
|
8
8
|
# MORPH Checklists
|
|
9
9
|
|
|
10
|
-
Types: `deploy`, `security`, `seo`, `performance`, `accessibility`, `legal-brazil`, `simulation` (
|
|
10
|
+
Types: `deploy`, `security`, `seo`, `performance`, `accessibility`, `legal-brazil`, `simulation` (see skill: `morph:simulation-checklist`)
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
## Deploy
|
|
15
15
|
|
|
16
|
+
### MORPH-SPEC Validation (run first)
|
|
17
|
+
- [ ] `npx morph-spec validate-feature {feature}` — passes with 100% pass rate
|
|
18
|
+
- [ ] `npx morph-spec approval-status {feature}` — all gates approved (design, plan, tasks)
|
|
19
|
+
- [ ] `npx morph-spec state get {feature}` — phase is `implement`, all tasks `done`
|
|
20
|
+
- [ ] Recap generated: `.morph/features/{feature}/5-implement/recap.md` exists
|
|
21
|
+
|
|
16
22
|
### Pre-Deploy
|
|
17
23
|
- [ ] `dotnet build --configuration Release` passes
|
|
18
|
-
- [ ] `dotnet test` passes
|
|
24
|
+
- [ ] `dotnet test` passes (100% pass rate required — zero tolerance)
|
|
19
25
|
- [ ] Migrations applied (`dotnet ef database update`)
|
|
20
26
|
- [ ] Env vars configured (connection strings, API keys, feature flags)
|
|
21
27
|
|
|
@@ -94,28 +100,45 @@ Types: `deploy`, `security`, `seo`, `performance`, `accessibility`, `legal-brazi
|
|
|
94
100
|
- [ ] Alt text on images, captions on videos
|
|
95
101
|
- [ ] Contrast >= 4.5:1 (AA), color not sole indicator
|
|
96
102
|
- [ ] Keyboard navigation works, focus visible
|
|
97
|
-
- [ ] Skip links, `<html lang="
|
|
103
|
+
- [ ] Skip links, `<html lang="...">` with correct locale
|
|
98
104
|
- [ ] Labels on all inputs, clear error messages
|
|
99
105
|
- [ ] Valid HTML, ARIA used correctly
|
|
100
106
|
|
|
101
107
|
---
|
|
102
108
|
|
|
103
|
-
## Legal Brazil (LGPD)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
- [ ]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- [ ] Data
|
|
116
|
-
- [ ]
|
|
117
|
-
- [ ]
|
|
118
|
-
- [ ]
|
|
109
|
+
## Legal Brazil (LGPD — Lei 13.709/2018)
|
|
110
|
+
|
|
111
|
+
The Brazilian General Data Protection Law (LGPD) applies to any application that processes personal data of individuals in Brazil. Non-compliance can result in fines up to 2% of revenue (capped at R$50M per violation) from ANPD (Autoridade Nacional de Protecao de Dados).
|
|
112
|
+
|
|
113
|
+
### Documentation (Art. 9, 23, 41)
|
|
114
|
+
- [ ] Privacy policy published and accessible from every page — must include: categories of data collected, legal basis per category (Art. 7), processing purpose, retention period, DPO (Encarregado) contact name and email
|
|
115
|
+
- [ ] Terms of use covering: service description, user responsibilities, governing forum (Brazilian jurisdiction required)
|
|
116
|
+
- [ ] ROPA (Record of Processing Activities) — internal document mapping data flows per Art. 37
|
|
117
|
+
|
|
118
|
+
### Consent & Data Subject Rights (Art. 7-9, 15-18)
|
|
119
|
+
- [ ] Cookie consent banner with **granular opt-in** (not just "accept all") — separate toggles for analytics, marketing, essential
|
|
120
|
+
- [ ] Explicit consent for marketing communications — checkbox unchecked by default, revocable at any time
|
|
121
|
+
- [ ] Data subject rights page implementing all Art. 18 rights:
|
|
122
|
+
- [ ] Access: user can view all personal data held
|
|
123
|
+
- [ ] Correction: user can update inaccurate data
|
|
124
|
+
- [ ] Deletion: user can request full account/data deletion (Art. 18, IX)
|
|
125
|
+
- [ ] Portability: user can export data in machine-readable format (JSON/CSV)
|
|
126
|
+
- [ ] Opposition: user can object to specific processing
|
|
127
|
+
- [ ] Rights requests processed within 15 days (Art. 19)
|
|
128
|
+
|
|
129
|
+
### Technical Controls (Art. 46-49)
|
|
130
|
+
- [ ] PII encrypted at rest (AES-256) and in transit (TLS 1.2+)
|
|
131
|
+
- [ ] Data minimization: only collect what the legal basis justifies
|
|
132
|
+
- [ ] Defined retention periods per data category — automatic purge after expiry
|
|
133
|
+
- [ ] Anonymization/pseudonymization for analytics and logs
|
|
134
|
+
- [ ] Access logs for all personal data operations (who accessed what, when)
|
|
135
|
+
- [ ] Incident response plan: ANPD notification within **72 hours** of breach (Art. 48), user notification "within reasonable time"
|
|
136
|
+
- [ ] Data Protection Impact Assessment (DPIA/RIPD) for high-risk processing (Art. 5, XVII)
|
|
137
|
+
|
|
138
|
+
### DPO (Encarregado — Art. 41)
|
|
139
|
+
- [ ] DPO designated and publicly identified (name + contact on privacy policy)
|
|
140
|
+
- [ ] DPO contact channel operational (email or form)
|
|
141
|
+
- [ ] DPO handles ANPD communications and data subject requests
|
|
119
142
|
|
|
120
143
|
---
|
|
121
144
|
|
|
@@ -3,6 +3,9 @@ name: morph:code-review
|
|
|
3
3
|
description: .NET/C# code review checklist covering naming conventions, architecture layer integrity, async patterns, logging, error handling, DI lifetimes, and DTO contracts. Use after implementing .NET code, before creating PRs, or when reviewing C# code for compliance with MORPH-SPEC standards.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
+
stacks:
|
|
7
|
+
- dotnet
|
|
8
|
+
- blazor
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
# Code Review Checklist
|
|
@@ -23,12 +26,12 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
23
26
|
git diff --name-only main...HEAD -- "*.cs" | wc -l
|
|
24
27
|
```
|
|
25
28
|
|
|
26
|
-
**
|
|
27
|
-
- 0
|
|
28
|
-
-
|
|
29
|
-
-
|
|
29
|
+
**Skip review if:**
|
|
30
|
+
- 0 `.cs` files changed → no backend code to review
|
|
31
|
+
- Only changes in `*.json`, `*.csproj`, `*.md`, migration files → infrastructure scope
|
|
32
|
+
- `.morph/features/$ARGUMENTS/5-implement/code-review.md` already exists from today → already reviewed
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
If skipping: output `"Skipping code-review: [reason]"` and stop.
|
|
32
35
|
|
|
33
36
|
---
|
|
34
37
|
|
package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md
RENAMED
|
@@ -3,6 +3,8 @@ name: morph:code-review-nextjs
|
|
|
3
3
|
description: Next.js code review checklist covering naming conventions, component architecture (Server vs Client), data fetching patterns, form implementation, state management, TypeScript/Zod discipline, feature boundaries, and testing. Use after implementing Next.js code, before creating PRs, or when reviewing TSX/TS code for compliance with MORPH-SPEC Next.js standards.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
+
stacks:
|
|
7
|
+
- nextjs
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
# Next.js Code Review Checklist
|
|
@@ -17,7 +19,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
17
19
|
> **Ref:** `framework/standards/frontend/nextjs/testing.md`
|
|
18
20
|
> **Example:** `references/review-example-nextjs.md` — filled-in review showing expected finding format.
|
|
19
21
|
> **Script:** `scripts/scan-nextjs.mjs` — automated scan for CRITICAL/HIGH violations before manual review.
|
|
20
|
-
> **Ref:** `.claude/skills/code-review/references/review-guidelines.md` — false-positive rubric, confidence scoring, evidence format.
|
|
22
|
+
> **Ref:** `.claude/skills/morph-code-review/references/review-guidelines.md` — false-positive rubric, confidence scoring, evidence format.
|
|
21
23
|
|
|
22
24
|
---
|
|
23
25
|
|
|
@@ -27,12 +29,12 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
27
29
|
git diff --name-only main...HEAD -- "*.tsx" "*.ts" | wc -l
|
|
28
30
|
```
|
|
29
31
|
|
|
30
|
-
**
|
|
31
|
-
- 0
|
|
32
|
-
-
|
|
33
|
-
-
|
|
32
|
+
**Skip review if:**
|
|
33
|
+
- 0 `.tsx`/`.ts` files changed → no frontend code to review
|
|
34
|
+
- Only changes in `*.json`, `*.md`, config files → infrastructure scope
|
|
35
|
+
- `.morph/features/$ARGUMENTS/5-implement/code-review-nextjs.md` already exists from today → already reviewed
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
If skipping: output `"Skipping code-review-nextjs: [reason]"` and stop.
|
|
36
38
|
|
|
37
39
|
---
|
|
38
40
|
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: morph:frontend-review
|
|
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
|
+
argument-hint: "[feature-name]"
|
|
8
|
+
user-invocable: true
|
|
9
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion,
|
|
10
|
+
mcp__playwright__browser_navigate, mcp__playwright__browser_resize,
|
|
11
|
+
mcp__playwright__browser_take_screenshot, mcp__playwright__browser_snapshot,
|
|
12
|
+
mcp__playwright__browser_evaluate, mcp__playwright__browser_console_messages
|
|
13
|
+
cliVersion: "4.8.19"
|
|
14
|
+
stacks:
|
|
15
|
+
- blazor
|
|
16
|
+
- nextjs
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Frontend Review
|
|
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).
|
|
24
|
+
|
|
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.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Step 0 — Detect Context and Stack
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
node .claude/skills/morph-post-implementation/scripts/detect-stack.mjs
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Output JSON: `{ stack: "DOTNET" | "NEXTJS" | "FULLSTACK" | "UNKNOWN", frontendPath, backendPath, startCommand }`
|
|
38
|
+
|
|
39
|
+
Beyond the stack, determine the **context** by examining what exists:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Check if design outputs exist
|
|
43
|
+
ls .morph/features/$ARGUMENTS/2-ui/ 2>/dev/null
|
|
44
|
+
|
|
45
|
+
# Check if implemented frontend files exist
|
|
46
|
+
find . -name "*.tsx" -o -name "*.razor" 2>/dev/null | head -5
|
|
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
|
|
52
|
+
|
|
53
|
+
Store `stack`, `frontendPath`, `startCommand` and the detected context — all steps depend on them.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 1 — Design Outputs Validation (if context includes design validation)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx morph-spec validate-feature $ARGUMENTS
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Verify existence and quality of the 4 mandatory outputs in `.morph/features/$ARGUMENTS/2-ui/`:
|
|
64
|
+
|
|
65
|
+
```
|
|
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
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**🚫 BLOCK** if `validate-feature` fails or mandatory outputs missing.
|
|
76
|
+
|
|
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).
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Step 2 — Static Accessibility Scan
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
node .claude/skills/morph-frontend-review/scripts/scan-accessibility.mjs $frontendPath
|
|
86
|
+
```
|
|
87
|
+
|
|
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).
|
|
90
|
+
|
|
91
|
+
**Checks implemented:**
|
|
92
|
+
|
|
93
|
+
| ID | Severity | Files | Checks |
|
|
94
|
+
|----|-----------|---------|---------|
|
|
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=` |
|
|
102
|
+
|
|
103
|
+
**🚫 BLOCK** if any CRITICAL finding or HIGH count ≥ 3.
|
|
104
|
+
|
|
105
|
+
Fix all CRITICALs before continuing. For HIGH < 3, record in summary as warnings.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Step 3 — Frontend Code Scan (if context includes implementation validation)
|
|
110
|
+
|
|
111
|
+
### If NEXTJS or FULLSTACK:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
node .claude/skills/morph-code-review-nextjs/scripts/scan-nextjs.mjs $frontendPath
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> Skip if already run by `post-implementation` in the same session.
|
|
118
|
+
|
|
119
|
+
**🚫 BLOCK** if CRITICAL findings found.
|
|
120
|
+
|
|
121
|
+
### If DOTNET or FULLSTACK (Blazor):
|
|
122
|
+
|
|
123
|
+
Manually verify the main checklist categories for the implemented feature:
|
|
124
|
+
|
|
125
|
+
```
|
|
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
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**🚫 BLOCK** if any CRITICAL item is found.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Step 4 — Responsive Screenshots (Playwright MCP)
|
|
140
|
+
|
|
141
|
+
### 4a. Detect Dev Server
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
node .claude/skills/morph-post-implementation/scripts/detect-dev-server.mjs "$startCommand"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 4b. If dev server available (exit 0):
|
|
148
|
+
|
|
149
|
+
Extract the main feature URLs by reading `spec.md`:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
Read: .morph/features/$ARGUMENTS/1-design/spec.md
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For each main page (max 3), capture screenshots at 3 breakpoints:
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
// Mobile (375px)
|
|
159
|
+
await mcp__playwright__browser_resize({ width: 375, height: 812 });
|
|
160
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
161
|
+
await mcp__playwright__browser_take_screenshot({
|
|
162
|
+
type: 'png',
|
|
163
|
+
filename: `.morph/features/${ARGUMENTS}/visual-screenshots/mobile-<page>.png`
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Tablet (768px)
|
|
167
|
+
await mcp__playwright__browser_resize({ width: 768, height: 1024 });
|
|
168
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
169
|
+
await mcp__playwright__browser_take_screenshot({
|
|
170
|
+
type: 'png',
|
|
171
|
+
filename: `.morph/features/${ARGUMENTS}/visual-screenshots/tablet-<page>.png`
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Desktop (1440px)
|
|
175
|
+
await mcp__playwright__browser_resize({ width: 1440, height: 900 });
|
|
176
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
177
|
+
await mcp__playwright__browser_take_screenshot({
|
|
178
|
+
type: 'png',
|
|
179
|
+
filename: `.morph/features/${ARGUMENTS}/visual-screenshots/desktop-<page>.png`
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Screenshots saved to: `.morph/features/$ARGUMENTS/visual-screenshots/`
|
|
184
|
+
(works in both phase `2-ui` and `5-implement`)
|
|
185
|
+
|
|
186
|
+
### 4c. If dev server NOT available (exit 1):
|
|
187
|
+
|
|
188
|
+
**⚠️ WARNING: Dev server not found.**
|
|
189
|
+
|
|
190
|
+
Request explicit user confirmation before skipping screenshots:
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
Dev server not detected. Responsive screenshots via Playwright cannot be captured.
|
|
194
|
+
|
|
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
|
|
198
|
+
|
|
199
|
+
Cannot proceed to axe-core without dev server.
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Wait for response before continuing.**
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Step 5 — axe-core Runtime (Playwright MCP, if dev server active)
|
|
207
|
+
|
|
208
|
+
For each feature page (use the same URLs from Step 4):
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
// Navigate to the page
|
|
212
|
+
await mcp__playwright__browser_navigate({ url: '<feature-url>' });
|
|
213
|
+
|
|
214
|
+
// Inject axe-core via CDN and run WCAG 2.1 AA scan
|
|
215
|
+
await mcp__playwright__browser_evaluate({
|
|
216
|
+
function: `async () => {
|
|
217
|
+
if (!window.axe) {
|
|
218
|
+
await new Promise((resolve, reject) => {
|
|
219
|
+
const s = document.createElement('script');
|
|
220
|
+
s.src = 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.9.1/axe.min.js';
|
|
221
|
+
s.onload = resolve;
|
|
222
|
+
s.onerror = reject;
|
|
223
|
+
document.head.appendChild(s);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
const results = await window.axe.run(document, {
|
|
227
|
+
runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa'] }
|
|
228
|
+
});
|
|
229
|
+
return results.violations.map(v => ({
|
|
230
|
+
id: v.id,
|
|
231
|
+
impact: v.impact,
|
|
232
|
+
description: v.description,
|
|
233
|
+
nodes: v.nodes.length,
|
|
234
|
+
helpUrl: v.helpUrl
|
|
235
|
+
}));
|
|
236
|
+
}`
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Group violations by impact:
|
|
241
|
+
- `critical` / `serious` → **🚫 BLOCK** (do not create PR)
|
|
242
|
+
- `moderate` / `minor` → report as warnings in summary, non-blocking
|
|
243
|
+
|
|
244
|
+
Also check for accessibility-related console errors:
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
await mcp__playwright__browser_console_messages({ level: 'error' });
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Step 6 — SEO Check (Next.js only)
|
|
253
|
+
|
|
254
|
+
Scan feature `page.tsx` files to verify metadata:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Find feature pages
|
|
258
|
+
find . -name "page.tsx" -path "*$ARGUMENTS*" 2>/dev/null
|
|
259
|
+
|
|
260
|
+
# Check if they have metadata
|
|
261
|
+
grep -l "export const metadata\|export async function generateMetadata" $(find . -name "page.tsx" -path "*$ARGUMENTS*" 2>/dev/null)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Checklist per page:
|
|
265
|
+
|
|
266
|
+
```
|
|
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
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
> SEO doesn't block PR — report as warnings in final summary.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Step 7 — Responsive Design Checklist
|
|
279
|
+
|
|
280
|
+
After viewing Step 4 screenshots:
|
|
281
|
+
|
|
282
|
+
```
|
|
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)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
If screenshots were not captured (dev server unavailable), mark as "unverified" and
|
|
291
|
+
record in summary.
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Step 8 — Summary and Artifacts
|
|
296
|
+
|
|
297
|
+
Create consolidated summary file:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
mkdir -p ".morph/features/$ARGUMENTS/visual-screenshots"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Save to `.morph/features/$ARGUMENTS/visual-screenshots/morph:frontend-review-summary.md`:
|
|
304
|
+
|
|
305
|
+
```markdown
|
|
306
|
+
# Frontend Review — {feature}
|
|
307
|
+
|
|
308
|
+
**Date:** {date}
|
|
309
|
+
**Stack:** {detected stack}
|
|
310
|
+
**Context:** design validation | implementation validation | both
|
|
311
|
+
|
|
312
|
+
## Results
|
|
313
|
+
|
|
314
|
+
### Step 1 — Design Outputs
|
|
315
|
+
- validate-feature: ✅ PASS / 🚫 BLOCK
|
|
316
|
+
- Outputs verified: ui-design-system.md, ui-mockups.md, ui-components.md, ui-flows.md
|
|
317
|
+
- WCAG Contrast: {result}
|
|
318
|
+
|
|
319
|
+
### Step 2 — Static Accessibility Scan
|
|
320
|
+
- Files scanned: {N}
|
|
321
|
+
- Findings: {total} ({CRITICAL: N, HIGH: N, MEDIUM: N})
|
|
322
|
+
- Status: ✅ PASS / 🚫 BLOCK
|
|
323
|
+
|
|
324
|
+
### Step 3 — Frontend Code Scan
|
|
325
|
+
- Status: ✅ PASS / 🚫 BLOCK / ⏭️ skipped (already run)
|
|
326
|
+
|
|
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"}
|
|
331
|
+
|
|
332
|
+
### Step 5 — axe-core Runtime
|
|
333
|
+
- Critical/serious violations: {N} → ✅ / 🚫
|
|
334
|
+
- Warnings (moderate/minor): {N}
|
|
335
|
+
|
|
336
|
+
### Step 6 — SEO (Next.js)
|
|
337
|
+
- Pages with metadata: {N}/{total}
|
|
338
|
+
- Gaps: {list or "none"}
|
|
339
|
+
|
|
340
|
+
## Overall Status
|
|
341
|
+
|
|
342
|
+
**{✅ PASS / 🚫 BLOCK}**
|
|
343
|
+
|
|
344
|
+
{If BLOCK: reason(s) listed here}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Block Summary
|
|
350
|
+
|
|
351
|
+
| Step | Block Condition |
|
|
352
|
+
|------|-------------------|
|
|
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` |
|
|
357
|
+
|
|
358
|
+
**All BLOCKs must be resolved before creating the PR (when run post-implementation).**
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
*MORPH-SPEC by Polymorphism Tech*
|