@polymorphism-tech/morph-spec 4.8.19 → 4.10.0
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/CLAUDE.md +21 -0
- package/README.md +2 -2
- package/bin/morph-spec.js +44 -55
- package/bin/task-manager.js +133 -20
- package/bin/validate.js +67 -33
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +201 -203
- package/docs/QUICKSTART.md +2 -2
- package/framework/CLAUDE.md +99 -77
- package/framework/agents.json +734 -182
- package/framework/commands/commit.md +166 -0
- package/framework/commands/morph-apply.md +13 -2
- package/framework/commands/morph-archive.md +8 -2
- package/framework/commands/morph-infra.md +6 -0
- package/framework/commands/morph-preflight.md +6 -0
- package/framework/commands/morph-proposal.md +56 -7
- package/framework/commands/morph-status.md +6 -0
- package/framework/commands/morph-troubleshoot.md +6 -0
- package/framework/hooks/claude-code/notification/approval-reminder.js +3 -2
- package/framework/hooks/claude-code/post-tool-use/context-refresh.js +1 -1
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +155 -32
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +78 -0
- 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 +4 -3
- 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 +124 -2
- package/framework/hooks/claude-code/session-start/post-compact-restore.js +41 -0
- package/framework/hooks/claude-code/statusline.py +76 -30
- 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/claude-code/user-prompt/set-terminal-title.js +14 -6
- package/framework/hooks/shared/activity-logger.js +0 -24
- 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 +12 -5
- package/framework/hooks/shared/skill-reminder-helpers.js +79 -0
- package/framework/hooks/shared/stale-task-reset.js +57 -0
- package/framework/hooks/shared/state-reader.js +29 -5
- package/framework/hooks/shared/worktree-helpers.js +53 -0
- package/framework/phases.json +69 -14
- package/framework/rules/morph-workflow.md +88 -86
- package/framework/skills/level-0-meta/mcp-registry.json +86 -51
- package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/SKILL.md +14 -17
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{code-review → morph-code-review}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md +163 -163
- package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/SKILL.md +9 -9
- package/framework/skills/level-0-meta/morph-init/SKILL.md +77 -12
- package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/SKILL.md +62 -15
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +1 -1
- package/framework/skills/level-0-meta/{simulation-checklist → morph-simulation-checklist}/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{terminal-title → morph-terminal-title}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/SKILL.md +3 -4
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/references/tools-per-phase.md +7 -7
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/SKILL.md +2 -2
- 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 +238 -0
- package/framework/skills/level-1-workflows/{phase-codebase-analysis → morph-phase-codebase-analysis}/SKILL.md +3 -3
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +507 -0
- package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/SKILL.md +168 -27
- 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 +254 -0
- package/framework/skills/level-1-workflows/{phase-setup → morph-phase-setup}/SKILL.md +50 -3
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/SKILL.md +48 -11
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/scripts/validate-tasks.mjs +3 -3
- package/framework/skills/level-1-workflows/{phase-uiux → morph-phase-uiux}/SKILL.md +46 -11
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +97 -0
- package/framework/standards/STANDARDS.json +640 -88
- package/framework/standards/infrastructure/vercel/vercel-database.md +106 -0
- package/framework/standards/integration/mcp/mcp-tools.md +25 -7
- package/framework/templates/REGISTRY.json +1825 -1909
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
- package/framework/templates/docs/onboarding.md +3 -7
- package/package.json +2 -7
- package/src/commands/agents/dispatch-agents.js +104 -6
- package/src/commands/mcp/mcp-setup.js +39 -2
- package/src/commands/phase/phase-reset.js +74 -0
- package/src/commands/project/doctor.js +34 -51
- package/src/commands/project/init.js +1 -1
- package/src/commands/project/status.js +2 -2
- package/src/commands/project/update.js +381 -365
- package/src/commands/project/worktree.js +154 -0
- package/src/commands/scope/escalate.js +215 -0
- package/src/commands/state/advance-phase.js +132 -68
- package/src/commands/state/approve.js +2 -2
- package/src/commands/state/index.js +7 -8
- package/src/commands/state/phase-runner.js +1 -1
- package/src/commands/state/state.js +61 -6
- package/src/commands/task/expand.js +100 -0
- package/src/commands/tasks/task.js +78 -99
- package/src/commands/templates/template-render.js +93 -173
- package/src/commands/trust/trust.js +26 -21
- package/src/core/paths/output-schema.js +19 -3
- package/src/core/state/phase-state-machine.js +7 -4
- package/src/core/state/state-manager.js +32 -57
- package/src/core/workflows/workflow-detector.js +9 -87
- 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 +336 -0
- package/src/lib/scope/impact-analyzer.js +106 -0
- package/src/lib/stack/stack-profile.js +88 -0
- package/src/lib/tasks/task-classifier.js +16 -0
- package/src/lib/tasks/task-parser.js +1 -1
- package/src/lib/tasks/test-runner.js +77 -0
- package/src/lib/trust/trust-manager.js +32 -144
- package/src/lib/validators/shared/emit-validator-dispatch.js +64 -0
- package/src/lib/validators/spec-validator.js +58 -4
- package/src/lib/validators/validation-runner.js +23 -11
- package/src/scripts/setup-infra.js +255 -224
- package/src/utils/agents-installer.js +34 -14
- package/src/utils/banner.js +1 -1
- package/src/utils/claude-settings-manager.js +1 -1
- package/src/utils/file-copier.js +1 -1
- package/src/utils/hooks-installer.js +272 -8
- package/framework/hooks/dev/check-sync-health.js +0 -117
- package/framework/hooks/dev/guard-version-numbers.js +0 -57
- package/framework/hooks/dev/sync-standards-registry.js +0 -60
- package/framework/hooks/dev/sync-template-registry.js +0 -60
- package/framework/hooks/dev/validate-skill-format.js +0 -70
- package/framework/hooks/dev/validate-standard-format.js +0 -73
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +0 -190
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +0 -366
- package/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
- package/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
- package/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
- package/framework/workflows/configs/design-impl.json +0 -49
- package/framework/workflows/configs/express.json +0 -45
- package/framework/workflows/configs/fast-track.json +0 -42
- package/framework/workflows/configs/full-morph.json +0 -79
- package/framework/workflows/configs/fusion.json +0 -39
- package/framework/workflows/configs/long-running.json +0 -33
- package/framework/workflows/configs/spec-only.json +0 -43
- package/framework/workflows/configs/ui-refresh.json +0 -49
- package/framework/workflows/configs/zero-touch.json +0 -82
- package/src/commands/project/index.js +0 -8
- package/src/commands/project/monitor.js +0 -295
- package/src/commands/project/tutorial.js +0 -115
- package/src/commands/state/validate-phase.js +0 -238
- package/src/commands/templates/generate-contracts.js +0 -445
- package/src/core/index.js +0 -10
- package/src/core/orchestrator.js +0 -171
- package/src/core/registry/command-registry.js +0 -28
- package/src/core/registry/index.js +0 -8
- package/src/core/registry/validator-registry.js +0 -204
- 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/templates/template-validator.js +0 -296
- package/src/core/workflows/index.js +0 -7
- package/src/generator/config-generator.js +0 -206
- package/src/generator/templates/config.json.template +0 -40
- package/src/generator/templates/project.md.template +0 -67
- package/src/lib/agents/micro-agent-factory.js +0 -161
- package/src/lib/analysis/complexity-analyzer.js +0 -441
- package/src/lib/analysis/index.js +0 -7
- package/src/lib/analytics/analytics-engine.js +0 -345
- package/src/lib/checkpoints/checkpoint-hooks.js +0 -298
- package/src/lib/checkpoints/index.js +0 -7
- package/src/lib/context/context-bundler.js +0 -241
- package/src/lib/context/context-optimizer.js +0 -212
- package/src/lib/context/context-tracker.js +0 -273
- package/src/lib/context/core-four-tracker.js +0 -201
- package/src/lib/context/mcp-optimizer.js +0 -200
- 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/execution/fusion-executor.js +0 -304
- package/src/lib/execution/parallel-executor.js +0 -270
- package/src/lib/hooks/stop-hook-executor.js +0 -286
- package/src/lib/hops/hop-composer.js +0 -221
- 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/lib/phase-chain/eligibility-checker.js +0 -243
- package/src/lib/threads/thread-coordinator.js +0 -238
- package/src/lib/threads/thread-manager.js +0 -317
- package/src/lib/tracking/artifact-trail.js +0 -202
- package/src/sanitizer/context-sanitizer.js +0 -221
- package/src/sanitizer/patterns.js +0 -163
- package/src/scanner/project-scanner.js +0 -242
- package/src/ui/diff-display.js +0 -91
- package/src/ui/interactive-wizard.js +0 -96
- package/src/ui/user-review.js +0 -211
- package/src/ui/wizard-questions.js +0 -188
- package/src/utils/color-utils.js +0 -70
- package/src/utils/process-handler.js +0 -97
- 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-0-meta/{terminal-title → morph-terminal-title}/scripts/set_title.sh +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
package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md
RENAMED
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: code-review-nextjs
|
|
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
|
-
user-invocable: true
|
|
5
|
-
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Next.js Code Review Checklist
|
|
9
|
-
|
|
10
|
-
> Comprehensive checklist for Next.js code review: naming, component architecture, data fetching, forms, state, TypeScript, structure, and testing.
|
|
11
|
-
> **Ref:** `framework/standards/frontend/nextjs/naming-conventions.md`
|
|
12
|
-
> **Ref:** `framework/standards/frontend/nextjs/app-router.md`
|
|
13
|
-
> **Ref:** `framework/standards/frontend/nextjs/components.md`
|
|
14
|
-
> **Ref:** `framework/standards/frontend/nextjs/data-fetching.md`
|
|
15
|
-
> **Ref:** `framework/standards/frontend/nextjs/forms.md`
|
|
16
|
-
> **Ref:** `framework/standards/frontend/nextjs/state-management.md`
|
|
17
|
-
> **Ref:** `framework/standards/frontend/nextjs/testing.md`
|
|
18
|
-
> **Example:** `references/review-example-nextjs.md` — filled-in review showing expected finding format.
|
|
19
|
-
> **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.
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Step 0 — Eligibility Check
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
git diff --name-only main...HEAD -- "*.tsx" "*.ts" | wc -l
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
**Pular revisão se:**
|
|
31
|
-
- 0 arquivos `.tsx`/`.ts` alterados → sem código frontend para revisar
|
|
32
|
-
- Apenas mudanças em `*.json`, `*.md`, arquivos de config → escopo de infra
|
|
33
|
-
- Já existe `.morph/features/$ARGUMENTS/
|
|
34
|
-
|
|
35
|
-
Se skip: output `"Skipping code-review-nextjs: [motivo]"` e parar.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Step 1 — Run automated scan first
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
node scripts/scan-nextjs.mjs src/
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Review and address CRITICAL findings before proceeding with the manual checklist below. Warnings can be addressed during review.
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## Naming & Style (ref: naming-conventions.md)
|
|
50
|
-
|
|
51
|
-
- [ ] `[CRITICAL]` File names use kebab-case (`user-card.tsx`, NOT `UserCard.tsx`)
|
|
52
|
-
- [ ] `[HIGH]` Components exported as named exports (`export function UserCard`, NOT `export default function UserCard`)
|
|
53
|
-
- [ ] `[HIGH]` Hook files named `use-{action}.ts` and export `use{Action}()`
|
|
54
|
-
- [ ] `[HIGH]` Schema files named `{feature}.schemas.ts` with Zod exports
|
|
55
|
-
- [ ] `[HIGH]` Type files named `{feature}.types.ts` with `z.infer<>` derived types
|
|
56
|
-
- [ ] `[MEDIUM]` No abbreviations in public API names (`repository` not `repo`)
|
|
57
|
-
- [ ] `[MEDIUM]` Feature folder uses kebab-case (`features/user-management/`, NOT `features/userManagement/`)
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Component Architecture (ref: app-router.md, components.md)
|
|
62
|
-
|
|
63
|
-
### Server vs Client Discipline
|
|
64
|
-
- [ ] `[CRITICAL]` `'use client'` only on components that use hooks or event handlers
|
|
65
|
-
- [ ] `[CRITICAL]` No `useEffect(() => { fetch(...) }, [])` for data fetching — use Server Components or TanStack Query
|
|
66
|
-
- [ ] `[HIGH]` Server Components used for initial page data (no `'use client'` on page files)
|
|
67
|
-
- [ ] `[HIGH]` `loading.tsx`, `error.tsx` co-located with every `page.tsx`
|
|
68
|
-
- [ ] `[HIGH]` No business logic in `app/` route files — import from `features/`
|
|
69
|
-
|
|
70
|
-
### Three-Tier Hierarchy
|
|
71
|
-
- [ ] `[CRITICAL]` No edits to `components/ui/` files — shadcn primitives are never modified
|
|
72
|
-
- [ ] `[HIGH]` `components/` (Tier 2) has no imports from `features/` — no domain knowledge
|
|
73
|
-
- [ ] `[HIGH]` Feature components (`features/*/components/`) do not import from other features
|
|
74
|
-
- [ ] `[MEDIUM]` Feature cross-dependencies extracted to `components/` or `lib/`
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Data Fetching (ref: data-fetching.md)
|
|
79
|
-
|
|
80
|
-
- [ ] `[CRITICAL]` No `useEffect` + `useState` pattern for API data — use `useQuery`
|
|
81
|
-
- [ ] `[HIGH]` TanStack Query v5 syntax: `useQuery({ queryKey: [...], queryFn: async () => {} })`
|
|
82
|
-
- [ ] `[HIGH]` Query key factory pattern used (`userKeys.lists()`, NOT hardcoded `['users']`)
|
|
83
|
-
- [ ] `[HIGH]` `useMutation` used for POST/PUT/DELETE — not inline `fetch` in handlers
|
|
84
|
-
- [ ] `[HIGH]` API responses validated with Zod before use
|
|
85
|
-
- [ ] `[MEDIUM]` `onSuccess` in `useMutation` invalidates relevant query keys
|
|
86
|
-
- [ ] `[MEDIUM]` `QueryClientProvider` wraps app in `app/layout.tsx`, not per-component
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Forms (ref: forms.md)
|
|
91
|
-
|
|
92
|
-
- [ ] `[CRITICAL]` Zod schema defined BEFORE TypeScript type — type derived with `z.infer<>`
|
|
93
|
-
- [ ] `[HIGH]` `useForm` uses `zodResolver(schema)` — NOT manual validation
|
|
94
|
-
- [ ] `[HIGH]` shadcn `<Form>`, `<FormField>`, `<FormItem>`, `<FormLabel>`, `<FormControl>`, `<FormMessage>` used
|
|
95
|
-
- [ ] `[HIGH]` Form submission uses `useMutation` — NOT direct `fetch` in `onSubmit`
|
|
96
|
-
- [ ] `[MEDIUM]` `isPending` used for loading state — NOT `isLoading` (v5 renamed)
|
|
97
|
-
- [ ] `[MEDIUM]` Root-level errors displayed: `form.formState.errors.root`
|
|
98
|
-
- [ ] `[MEDIUM]` No `useState` for individual form fields — react-hook-form handles this
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## State Management (ref: state-management.md)
|
|
103
|
-
|
|
104
|
-
- [ ] `[HIGH]` No Zustand/Redux installed without documented justification
|
|
105
|
-
- [ ] `[HIGH]` No React Context used for server state (API data) — use TanStack Query
|
|
106
|
-
- [ ] `[MEDIUM]` Local UI state (open/closed, selected) in `useState` — not global store
|
|
107
|
-
- [ ] `[MEDIUM]` Context only for truly global UI: theme, auth user, locale
|
|
108
|
-
- [ ] `[LOW]` No prop drilling beyond 3 levels — consider Context or co-location
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## TypeScript Discipline
|
|
113
|
-
|
|
114
|
-
- [ ] `[CRITICAL]` No `any` type — use `unknown` and narrow, or fix the actual type
|
|
115
|
-
- [ ] `[HIGH]` Types derived from Zod schemas (`type User = z.infer<typeof userSchema>`)
|
|
116
|
-
- [ ] `[HIGH]` No duplicate type definitions — if the server returns it, define it once with Zod
|
|
117
|
-
- [ ] `[MEDIUM]` API response types come from the shared schema, not manually written
|
|
118
|
-
- [ ] `[MEDIUM]` `noUncheckedIndexedAccess` respected — array accesses use optional chaining
|
|
119
|
-
- [ ] `[LOW]` No type assertions (`as User`) without validation
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Feature Structure (ref: project-structure.md)
|
|
124
|
-
|
|
125
|
-
- [ ] `[HIGH]` Feature exposes public API via `features/{name}/index.ts` — no deep path imports
|
|
126
|
-
- [ ] `[HIGH]` Consumers import from index: `from '@/features/users'` NOT `from '@/features/users/components/user-list'`
|
|
127
|
-
- [ ] `[MEDIUM]` New features create: `components/`, `hooks/`, `types/` subdirectories
|
|
128
|
-
- [ ] `[MEDIUM]` TanStack Query hooks in `features/{name}/hooks/` — NOT co-located with components
|
|
129
|
-
- [ ] `[MEDIUM]` Zod schemas in `features/{name}/types/{name}.schemas.ts`
|
|
130
|
-
- [ ] `[LOW]` Feature index only exports what external consumers actually need (no over-exposure)
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## Testing (ref: testing.md)
|
|
135
|
-
|
|
136
|
-
- [ ] `[HIGH]` Test files co-located with source (`user-card.test.tsx` next to `user-card.tsx`)
|
|
137
|
-
- [ ] `[HIGH]` `@testing-library/user-event` used — NOT `fireEvent`
|
|
138
|
-
- [ ] `[HIGH]` API calls mocked with MSW — NOT `jest.mock('fetch')` or `global.fetch = jest.fn()`
|
|
139
|
-
- [ ] `[MEDIUM]` Hook tests use `QueryClientWrapper` helper with `retry: false`
|
|
140
|
-
- [ ] `[MEDIUM]` Tests cover happy path + one error path per component
|
|
141
|
-
- [ ] `[LOW]` No snapshot tests — use `expect(screen.getByText(...))`
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## Quick Pre-Merge Checklist
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
[ ] node scripts/scan-nextjs.mjs src/ — 0 CRITICAL findings
|
|
149
|
-
[ ] File names are kebab-case (UserCard.tsx → user-card.tsx)
|
|
150
|
-
[ ] 'use client' only on interactive components (hooks or event handlers)
|
|
151
|
-
[ ] No useEffect for data fetching — Server Component or useQuery
|
|
152
|
-
[ ] Zod schema defined first, type derived with z.infer<>
|
|
153
|
-
[ ] zodResolver connected to useForm, useMutation for submit
|
|
154
|
-
[ ] Query key factory used (userKeys.lists() not ['users'])
|
|
155
|
-
[ ] Feature public API via features/{name}/index.ts
|
|
156
|
-
[ ] components/ui/ files untouched (shadcn CLI only)
|
|
157
|
-
[ ] Tests: userEvent not fireEvent, MSW not mock fetch
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
*Covers: naming-conventions.md + app-router.md + components.md + data-fetching.md + forms.md + state-management.md + testing.md + project-structure.md*
|
|
163
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
1
|
+
---
|
|
2
|
+
name: morph:code-review-nextjs
|
|
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
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js Code Review Checklist
|
|
9
|
+
|
|
10
|
+
> Comprehensive checklist for Next.js code review: naming, component architecture, data fetching, forms, state, TypeScript, structure, and testing.
|
|
11
|
+
> **Ref:** `framework/standards/frontend/nextjs/naming-conventions.md`
|
|
12
|
+
> **Ref:** `framework/standards/frontend/nextjs/app-router.md`
|
|
13
|
+
> **Ref:** `framework/standards/frontend/nextjs/components.md`
|
|
14
|
+
> **Ref:** `framework/standards/frontend/nextjs/data-fetching.md`
|
|
15
|
+
> **Ref:** `framework/standards/frontend/nextjs/forms.md`
|
|
16
|
+
> **Ref:** `framework/standards/frontend/nextjs/state-management.md`
|
|
17
|
+
> **Ref:** `framework/standards/frontend/nextjs/testing.md`
|
|
18
|
+
> **Example:** `references/review-example-nextjs.md` — filled-in review showing expected finding format.
|
|
19
|
+
> **Script:** `scripts/scan-nextjs.mjs` — automated scan for CRITICAL/HIGH violations before manual review.
|
|
20
|
+
> **Ref:** `.claude/skills/morph-code-review/references/review-guidelines.md` — false-positive rubric, confidence scoring, evidence format.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 0 — Eligibility Check
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git diff --name-only main...HEAD -- "*.tsx" "*.ts" | wc -l
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Pular revisão se:**
|
|
31
|
+
- 0 arquivos `.tsx`/`.ts` alterados → sem código frontend para revisar
|
|
32
|
+
- Apenas mudanças em `*.json`, `*.md`, arquivos de config → escopo de infra
|
|
33
|
+
- Já existe `.morph/features/$ARGUMENTS/5-implement/code-review-nextjs.md` criado hoje → já revisado
|
|
34
|
+
|
|
35
|
+
Se skip: output `"Skipping code-review-nextjs: [motivo]"` e parar.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Step 1 — Run automated scan first
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
node scripts/scan-nextjs.mjs src/
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Review and address CRITICAL findings before proceeding with the manual checklist below. Warnings can be addressed during review.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Naming & Style (ref: naming-conventions.md)
|
|
50
|
+
|
|
51
|
+
- [ ] `[CRITICAL]` File names use kebab-case (`user-card.tsx`, NOT `UserCard.tsx`)
|
|
52
|
+
- [ ] `[HIGH]` Components exported as named exports (`export function UserCard`, NOT `export default function UserCard`)
|
|
53
|
+
- [ ] `[HIGH]` Hook files named `use-{action}.ts` and export `use{Action}()`
|
|
54
|
+
- [ ] `[HIGH]` Schema files named `{feature}.schemas.ts` with Zod exports
|
|
55
|
+
- [ ] `[HIGH]` Type files named `{feature}.types.ts` with `z.infer<>` derived types
|
|
56
|
+
- [ ] `[MEDIUM]` No abbreviations in public API names (`repository` not `repo`)
|
|
57
|
+
- [ ] `[MEDIUM]` Feature folder uses kebab-case (`features/user-management/`, NOT `features/userManagement/`)
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Component Architecture (ref: app-router.md, components.md)
|
|
62
|
+
|
|
63
|
+
### Server vs Client Discipline
|
|
64
|
+
- [ ] `[CRITICAL]` `'use client'` only on components that use hooks or event handlers
|
|
65
|
+
- [ ] `[CRITICAL]` No `useEffect(() => { fetch(...) }, [])` for data fetching — use Server Components or TanStack Query
|
|
66
|
+
- [ ] `[HIGH]` Server Components used for initial page data (no `'use client'` on page files)
|
|
67
|
+
- [ ] `[HIGH]` `loading.tsx`, `error.tsx` co-located with every `page.tsx`
|
|
68
|
+
- [ ] `[HIGH]` No business logic in `app/` route files — import from `features/`
|
|
69
|
+
|
|
70
|
+
### Three-Tier Hierarchy
|
|
71
|
+
- [ ] `[CRITICAL]` No edits to `components/ui/` files — shadcn primitives are never modified
|
|
72
|
+
- [ ] `[HIGH]` `components/` (Tier 2) has no imports from `features/` — no domain knowledge
|
|
73
|
+
- [ ] `[HIGH]` Feature components (`features/*/components/`) do not import from other features
|
|
74
|
+
- [ ] `[MEDIUM]` Feature cross-dependencies extracted to `components/` or `lib/`
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Data Fetching (ref: data-fetching.md)
|
|
79
|
+
|
|
80
|
+
- [ ] `[CRITICAL]` No `useEffect` + `useState` pattern for API data — use `useQuery`
|
|
81
|
+
- [ ] `[HIGH]` TanStack Query v5 syntax: `useQuery({ queryKey: [...], queryFn: async () => {} })`
|
|
82
|
+
- [ ] `[HIGH]` Query key factory pattern used (`userKeys.lists()`, NOT hardcoded `['users']`)
|
|
83
|
+
- [ ] `[HIGH]` `useMutation` used for POST/PUT/DELETE — not inline `fetch` in handlers
|
|
84
|
+
- [ ] `[HIGH]` API responses validated with Zod before use
|
|
85
|
+
- [ ] `[MEDIUM]` `onSuccess` in `useMutation` invalidates relevant query keys
|
|
86
|
+
- [ ] `[MEDIUM]` `QueryClientProvider` wraps app in `app/layout.tsx`, not per-component
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Forms (ref: forms.md)
|
|
91
|
+
|
|
92
|
+
- [ ] `[CRITICAL]` Zod schema defined BEFORE TypeScript type — type derived with `z.infer<>`
|
|
93
|
+
- [ ] `[HIGH]` `useForm` uses `zodResolver(schema)` — NOT manual validation
|
|
94
|
+
- [ ] `[HIGH]` shadcn `<Form>`, `<FormField>`, `<FormItem>`, `<FormLabel>`, `<FormControl>`, `<FormMessage>` used
|
|
95
|
+
- [ ] `[HIGH]` Form submission uses `useMutation` — NOT direct `fetch` in `onSubmit`
|
|
96
|
+
- [ ] `[MEDIUM]` `isPending` used for loading state — NOT `isLoading` (v5 renamed)
|
|
97
|
+
- [ ] `[MEDIUM]` Root-level errors displayed: `form.formState.errors.root`
|
|
98
|
+
- [ ] `[MEDIUM]` No `useState` for individual form fields — react-hook-form handles this
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## State Management (ref: state-management.md)
|
|
103
|
+
|
|
104
|
+
- [ ] `[HIGH]` No Zustand/Redux installed without documented justification
|
|
105
|
+
- [ ] `[HIGH]` No React Context used for server state (API data) — use TanStack Query
|
|
106
|
+
- [ ] `[MEDIUM]` Local UI state (open/closed, selected) in `useState` — not global store
|
|
107
|
+
- [ ] `[MEDIUM]` Context only for truly global UI: theme, auth user, locale
|
|
108
|
+
- [ ] `[LOW]` No prop drilling beyond 3 levels — consider Context or co-location
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## TypeScript Discipline
|
|
113
|
+
|
|
114
|
+
- [ ] `[CRITICAL]` No `any` type — use `unknown` and narrow, or fix the actual type
|
|
115
|
+
- [ ] `[HIGH]` Types derived from Zod schemas (`type User = z.infer<typeof userSchema>`)
|
|
116
|
+
- [ ] `[HIGH]` No duplicate type definitions — if the server returns it, define it once with Zod
|
|
117
|
+
- [ ] `[MEDIUM]` API response types come from the shared schema, not manually written
|
|
118
|
+
- [ ] `[MEDIUM]` `noUncheckedIndexedAccess` respected — array accesses use optional chaining
|
|
119
|
+
- [ ] `[LOW]` No type assertions (`as User`) without validation
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Feature Structure (ref: project-structure.md)
|
|
124
|
+
|
|
125
|
+
- [ ] `[HIGH]` Feature exposes public API via `features/{name}/index.ts` — no deep path imports
|
|
126
|
+
- [ ] `[HIGH]` Consumers import from index: `from '@/features/users'` NOT `from '@/features/users/components/user-list'`
|
|
127
|
+
- [ ] `[MEDIUM]` New features create: `components/`, `hooks/`, `types/` subdirectories
|
|
128
|
+
- [ ] `[MEDIUM]` TanStack Query hooks in `features/{name}/hooks/` — NOT co-located with components
|
|
129
|
+
- [ ] `[MEDIUM]` Zod schemas in `features/{name}/types/{name}.schemas.ts`
|
|
130
|
+
- [ ] `[LOW]` Feature index only exports what external consumers actually need (no over-exposure)
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Testing (ref: testing.md)
|
|
135
|
+
|
|
136
|
+
- [ ] `[HIGH]` Test files co-located with source (`user-card.test.tsx` next to `user-card.tsx`)
|
|
137
|
+
- [ ] `[HIGH]` `@testing-library/user-event` used — NOT `fireEvent`
|
|
138
|
+
- [ ] `[HIGH]` API calls mocked with MSW — NOT `jest.mock('fetch')` or `global.fetch = jest.fn()`
|
|
139
|
+
- [ ] `[MEDIUM]` Hook tests use `QueryClientWrapper` helper with `retry: false`
|
|
140
|
+
- [ ] `[MEDIUM]` Tests cover happy path + one error path per component
|
|
141
|
+
- [ ] `[LOW]` No snapshot tests — use `expect(screen.getByText(...))`
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Quick Pre-Merge Checklist
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
[ ] node scripts/scan-nextjs.mjs src/ — 0 CRITICAL findings
|
|
149
|
+
[ ] File names are kebab-case (UserCard.tsx → user-card.tsx)
|
|
150
|
+
[ ] 'use client' only on interactive components (hooks or event handlers)
|
|
151
|
+
[ ] No useEffect for data fetching — Server Component or useQuery
|
|
152
|
+
[ ] Zod schema defined first, type derived with z.infer<>
|
|
153
|
+
[ ] zodResolver connected to useForm, useMutation for submit
|
|
154
|
+
[ ] Query key factory used (userKeys.lists() not ['users'])
|
|
155
|
+
[ ] Feature public API via features/{name}/index.ts
|
|
156
|
+
[ ] components/ui/ files untouched (shadcn CLI only)
|
|
157
|
+
[ ] Tests: userEvent not fireEvent, MSW not mock fetch
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
*Covers: naming-conventions.md + app-router.md + components.md + data-fetching.md + forms.md + state-management.md + testing.md + project-structure.md*
|
|
163
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: frontend-review
|
|
2
|
+
name: morph:frontend-review
|
|
3
3
|
description: Auditoria completa do frontend — valida design outputs (design-system, contraste WCAG,
|
|
4
4
|
mockups), scan estático de acessibilidade (TSX + Razor), screenshots responsivos em 3
|
|
5
5
|
breakpoints via Playwright, axe-core a11y em runtime, e SEO (Next.js metadata). Cobre Next.js
|
|
@@ -10,7 +10,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep,
|
|
|
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
|
-
cliVersion: "4.8.
|
|
13
|
+
cliVersion: "4.8.19"
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Frontend Review
|
|
@@ -28,7 +28,7 @@ cliVersion: "4.8.14"
|
|
|
28
28
|
## Step 0 — Detectar Contexto e Stack
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
node .claude/skills/post-implementation/scripts/detect-stack.mjs
|
|
31
|
+
node .claude/skills/morph-post-implementation/scripts/detect-stack.mjs
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
Output JSON: `{ stack: "DOTNET" | "NEXTJS" | "FULLSTACK" | "UNKNOWN", frontendPath, backendPath, startCommand }`
|
|
@@ -79,7 +79,7 @@ contraste ≥ 4.5:1. Ferramentas de referência: WebAIM Contrast Checker (crité
|
|
|
79
79
|
## Step 2 — Scan Estático de Acessibilidade
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
node .claude/skills/frontend-review/scripts/scan-accessibility.mjs $frontendPath
|
|
82
|
+
node .claude/skills/morph-frontend-review/scripts/scan-accessibility.mjs $frontendPath
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
O script detecta automaticamente a extensão dos arquivos para determinar Next.js (`.tsx`) vs
|
|
@@ -108,7 +108,7 @@ Corrija todos os CRITICALs antes de continuar. Para HIGH < 3, registre no resumo
|
|
|
108
108
|
### Se NEXTJS ou FULLSTACK:
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
-
node .claude/skills/code-review-nextjs/scripts/scan-nextjs.mjs $frontendPath
|
|
111
|
+
node .claude/skills/morph-code-review-nextjs/scripts/scan-nextjs.mjs $frontendPath
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
> Pular se já executado pelo `post-implementation` na mesma sessão.
|
|
@@ -138,7 +138,7 @@ Verificar manualmente as categorias principais do checklist para o feature imple
|
|
|
138
138
|
### 4a. Detectar Dev Server
|
|
139
139
|
|
|
140
140
|
```bash
|
|
141
|
-
node .claude/skills/post-implementation/scripts/detect-dev-server.mjs "$startCommand"
|
|
141
|
+
node .claude/skills/morph-post-implementation/scripts/detect-dev-server.mjs "$startCommand"
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
### 4b. Se dev server disponível (exit 0):
|
|
@@ -178,7 +178,7 @@ await mcp__playwright__browser_take_screenshot({
|
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
Screenshots salvos em: `.morph/features/$ARGUMENTS/visual-screenshots/`
|
|
181
|
-
(funciona tanto na fase `2-ui` quanto na `
|
|
181
|
+
(funciona tanto na fase `2-ui` quanto na `5-implement`)
|
|
182
182
|
|
|
183
183
|
### 4c. Se dev server NÃO disponível (exit 1):
|
|
184
184
|
|
|
@@ -190,7 +190,7 @@ Solicite confirmação explícita ao usuário antes de pular os screenshots:
|
|
|
190
190
|
Dev server não detectado. Screenshots responsivos via Playwright não podem ser capturados.
|
|
191
191
|
|
|
192
192
|
Opções:
|
|
193
|
-
1. Inicie manualmente o servidor e re-execute /frontend-review
|
|
193
|
+
1. Inicie manualmente o servidor e re-execute /morph:frontend-review
|
|
194
194
|
2. Confirme explicitamente que deseja pular os screenshots e por quê
|
|
195
195
|
|
|
196
196
|
Não é possível prosseguir para axe-core sem dev server.
|
|
@@ -297,7 +297,7 @@ Criar arquivo de resumo consolidado:
|
|
|
297
297
|
mkdir -p ".morph/features/$ARGUMENTS/visual-screenshots"
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
Salvar em `.morph/features/$ARGUMENTS/visual-screenshots/frontend-review-summary.md`:
|
|
300
|
+
Salvar em `.morph/features/$ARGUMENTS/visual-screenshots/morph:frontend-review-summary.md`:
|
|
301
301
|
|
|
302
302
|
```markdown
|
|
303
303
|
# Frontend Review — {feature}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: morph
|
|
2
|
+
name: morph:init
|
|
3
3
|
description: >
|
|
4
4
|
LLM-powered project initialization. Installs morph-spec infrastructure if
|
|
5
5
|
needed, auto-installs required plugins (superpowers, context7), analyzes any
|
|
6
6
|
project structure intelligently, generates rich context/README.md and
|
|
7
7
|
config.json, and configures MCPs. Use once per project after installing
|
|
8
|
-
@polymorphism-tech/morph-spec. Re-run with /morph
|
|
8
|
+
@polymorphism-tech/morph-spec. Re-run with /morph:init refresh to update
|
|
9
9
|
context as the project evolves.
|
|
10
10
|
argument-hint: "[refresh]"
|
|
11
11
|
user-invocable: true
|
|
@@ -15,7 +15,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
15
15
|
# morph-init — LLM-Powered Project Initialization
|
|
16
16
|
|
|
17
17
|
> Run once after `npm install @polymorphism-tech/morph-spec`.
|
|
18
|
-
> Re-run as `/morph
|
|
18
|
+
> Re-run as `/morph:init refresh` when your project evolves.
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -55,7 +55,7 @@ claude plugin install superpowers@claude-plugins-official
|
|
|
55
55
|
claude plugin install context7@claude-plugins-official
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
**If the command succeeds:** `✓ {plugin} installed. Restart Claude Code after /morph
|
|
58
|
+
**If the command succeeds:** `✓ {plugin} installed. Restart Claude Code after /morph:init completes.`
|
|
59
59
|
|
|
60
60
|
**If the command fails:** Show this and **STOP** — do not continue:
|
|
61
61
|
|
|
@@ -63,7 +63,7 @@ claude plugin install context7@claude-plugins-official
|
|
|
63
63
|
Plugin {plugin} could not be installed automatically.
|
|
64
64
|
Run manually and restart Claude Code:
|
|
65
65
|
claude plugin install {plugin}
|
|
66
|
-
Then re-run /morph
|
|
66
|
+
Then re-run /morph:init.
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
Both `superpowers` and `context7` are required. Do not continue if either is missing.
|
|
@@ -236,17 +236,43 @@ Para criar um novo projeto VSA:
|
|
|
236
236
|
For each detected integration with an available MCP:
|
|
237
237
|
|
|
238
238
|
**Supabase detected:**
|
|
239
|
-
> *"Configure Supabase MCP
|
|
240
|
-
- YES →
|
|
239
|
+
> *"Configure Supabase MCP? Uses OAuth — no credentials needed."*
|
|
240
|
+
- YES → write remote config to `.claude/settings.local.json`:
|
|
241
|
+
```json
|
|
242
|
+
"supabase": { "type": "http", "url": "https://mcp.supabase.com/mcp" }
|
|
243
|
+
```
|
|
241
244
|
- NO → show snippet + `npx morph-spec mcp setup supabase`
|
|
242
245
|
|
|
243
246
|
**GitHub:**
|
|
244
|
-
> *"Configure GitHub MCP?
|
|
245
|
-
- YES
|
|
247
|
+
> *"Configure GitHub MCP? Requires Docker + a `GITHUB_PERSONAL_ACCESS_TOKEN`."*
|
|
248
|
+
- YES → collect token → write Docker config:
|
|
249
|
+
```json
|
|
250
|
+
"github": {
|
|
251
|
+
"command": "docker",
|
|
252
|
+
"args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"],
|
|
253
|
+
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "<token>" }
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
- NO → show snippet + `npx morph-spec mcp setup github`
|
|
246
257
|
|
|
247
|
-
|
|
258
|
+
**Vercel detected** (vercel.json exists OR stack is nextjs):
|
|
259
|
+
> *"Configure Vercel MCP? Uses OAuth — no credentials needed."*
|
|
260
|
+
- YES → write remote config:
|
|
261
|
+
```json
|
|
262
|
+
"vercel": { "type": "http", "url": "https://mcp.vercel.com" }
|
|
263
|
+
```
|
|
264
|
+
- NO → show snippet + `npx morph-spec mcp setup vercel`
|
|
265
|
+
|
|
266
|
+
Only offer Docker, Azure if explicitly detected in `.env.example`.
|
|
248
267
|
|
|
249
|
-
> **Format
|
|
268
|
+
> **Format rules for MCP configs:**
|
|
269
|
+
>
|
|
270
|
+
> **Remote MCPs** (Supabase, Vercel) — no credentials, OAuth-based:
|
|
271
|
+
> ```json
|
|
272
|
+
> "mcp-name": { "type": "http", "url": "https://mcp.example.com" }
|
|
273
|
+
> ```
|
|
274
|
+
>
|
|
275
|
+
> **Stdio MCPs** (Context7, Playwright) — local process with `cmd /c` on Windows:
|
|
250
276
|
> ```json
|
|
251
277
|
> "mcp-name": {
|
|
252
278
|
> "command": "cmd",
|
|
@@ -254,11 +280,50 @@ Only offer Figma, Docker, Azure if explicitly detected in `.env.example`.
|
|
|
254
280
|
> "env": { "KEY": "VALUE" }
|
|
255
281
|
> }
|
|
256
282
|
> ```
|
|
283
|
+
>
|
|
284
|
+
> **Docker MCPs** (GitHub) — Docker container:
|
|
285
|
+
> ```json
|
|
286
|
+
> "mcp-name": {
|
|
287
|
+
> "command": "docker",
|
|
288
|
+
> "args": ["run", "-i", "--rm", "-e", "TOKEN_VAR", "ghcr.io/org/image"],
|
|
289
|
+
> "env": { "TOKEN_VAR": "<value>" }
|
|
290
|
+
> }
|
|
291
|
+
> ```
|
|
292
|
+
>
|
|
257
293
|
> **Never** use `"command": "cmd /c"` (space-separated string) — that is invalid and will fail.
|
|
258
294
|
> **Never** use `"command": "npx"` directly — it also fails on Windows without `cmd`.
|
|
259
295
|
|
|
260
296
|
---
|
|
261
297
|
|
|
298
|
+
## Step 7.5 — Validate MCP Connections
|
|
299
|
+
|
|
300
|
+
For each MCP configured in Step 7, run a health check to verify it actually works.
|
|
301
|
+
|
|
302
|
+
**Read the registry:** `framework/skills/level-0-meta/mcp-registry.json` → for each configured MCP, get its `healthCheck` object.
|
|
303
|
+
|
|
304
|
+
**For each configured MCP:**
|
|
305
|
+
|
|
306
|
+
1. **Find available tool:** Search your available tools for one matching `healthCheck.toolPattern` (substring match — e.g., tool name contains "context7")
|
|
307
|
+
2. **If tool found → execute the test call:** Follow `healthCheck.testCall` using `healthCheck.testParams`
|
|
308
|
+
3. **Evaluate result:**
|
|
309
|
+
|
|
310
|
+
| Result | Action |
|
|
311
|
+
|--------|--------|
|
|
312
|
+
| **Success** (matches `healthCheck.successIndicator`) | Print `✓ {MCP} — connection verified` |
|
|
313
|
+
| **Tool not found** (no tool matching `toolPattern`) | Print `○ {MCP} — needs restart to activate` (MCP configured but tools not yet loaded) |
|
|
314
|
+
| **Error** (tool found but call fails) | → **AskUserQuestion** (see below) |
|
|
315
|
+
|
|
316
|
+
**On error — ask user with 3 options:**
|
|
317
|
+
|
|
318
|
+
Use `AskUserQuestion` with header `"{MCP} failed"` and these options:
|
|
319
|
+
- **Reconfigure credentials** — Loop back to Step 7 for this specific MCP. Maximum 2 retries per MCP. After 2 failures, force option 2.
|
|
320
|
+
- **Continue without {MCP}** — Show the `fallback` field from the registry (e.g., "WebSearch + WebFetch for library documentation") and proceed.
|
|
321
|
+
- **Stop init** — Abort initialization. User must fix MCP configuration manually and re-run `/morph:init`.
|
|
322
|
+
|
|
323
|
+
**Retry tracking:** Keep a counter per MCP. On the 2nd failure for the same MCP, skip the "Reconfigure" option and only offer "Continue without" or "Stop".
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
262
327
|
## Step 8 — Final Output
|
|
263
328
|
|
|
264
329
|
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.
|
|
@@ -271,7 +336,7 @@ Before printing the summary, check `~/.claude/settings.local.json` for `env.CLAU
|
|
|
271
336
|
✓ config.json updated
|
|
272
337
|
Stack: [stack] | Architecture: [architecture]
|
|
273
338
|
Integrations: [list]
|
|
274
|
-
✓ MCPs: [configured list]
|
|
339
|
+
✓ MCPs: [configured list] ([N verified] / [M needs restart] / [K failed])
|
|
275
340
|
|
|
276
341
|
[If CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1":]
|
|
277
342
|
✓ Agent Teams: enabled
|