@polymorphism-tech/morph-spec 4.8.18 → 4.9.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 +98 -0
- package/README.md +2 -2
- package/bin/morph-spec.js +15 -56
- package/bin/task-manager.js +115 -14
- 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 +21 -0
- package/framework/agents.json +758 -164
- package/framework/hooks/claude-code/post-tool-use/context-refresh.js +1 -1
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +2 -2
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +155 -0
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +1 -1
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +71 -2
- package/framework/hooks/claude-code/statusline.py +76 -30
- 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/phase-utils.js +3 -0
- 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 +2 -2
- package/framework/hooks/shared/worktree-helpers.js +53 -0
- package/framework/phases.json +40 -8
- package/framework/skills/level-0-meta/brainstorming/SKILL.md +1 -1
- package/framework/skills/level-0-meta/code-review/SKILL.md +1 -1
- package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +163 -163
- package/framework/skills/level-0-meta/frontend-review/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/morph-init/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +1 -1
- package/framework/skills/level-0-meta/post-implementation/SKILL.md +59 -12
- package/framework/skills/level-0-meta/simulation-checklist/SKILL.md +1 -1
- package/framework/skills/level-0-meta/terminal-title/SKILL.md +1 -1
- package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +1 -1
- package/framework/skills/level-0-meta/tool-usage-guide/references/tools-per-phase.md +6 -5
- package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +215 -189
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +251 -251
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +382 -365
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +492 -450
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +194 -190
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +270 -270
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +285 -285
- package/framework/standards/STANDARDS.json +640 -88
- package/framework/standards/infrastructure/vercel/vercel-database.md +106 -0
- package/framework/templates/REGISTRY.json +1825 -1909
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
- package/framework/templates/docs/onboarding.md +1 -5
- package/framework/workflows/configs/nodejs-cli.json +40 -0
- package/package.json +2 -6
- package/src/commands/agents/dispatch-agents.js +55 -4
- package/src/commands/project/doctor.js +16 -47
- 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/state/advance-phase.js +120 -30
- 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/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 +15 -0
- package/src/core/state/state-manager.js +28 -54
- package/src/core/workflows/workflow-detector.js +9 -87
- package/src/lib/phase-chain/phase-validator.js +330 -0
- package/src/lib/stack/stack-profile.js +88 -0
- package/src/lib/tasks/task-classifier.js +16 -0
- package/src/lib/tasks/test-runner.js +77 -0
- package/src/lib/trust/trust-manager.js +32 -144
- package/src/lib/validators/spec-validator.js +58 -4
- package/src/lib/validators/validation-runner.js +23 -11
- package/src/scripts/setup-infra.js +240 -224
- package/src/utils/agents-installer.js +2 -2
- package/src/utils/banner.js +1 -1
- package/src/utils/claude-settings-manager.js +1 -1
- package/src/utils/file-copier.js +1 -0
- package/src/utils/hooks-installer.js +258 -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/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/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/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/templates/template-validator.js +0 -296
- 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/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/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/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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale Task Reset — shared hook utility
|
|
3
|
+
*
|
|
4
|
+
* Detects tasks stuck in `in_progress` for longer than STALE_MS and resets
|
|
5
|
+
* them to `pending`. Works for both v2 (tasks is array) and v3 (taskList)
|
|
6
|
+
* state formats. Pure function: mutates state in-place, returns reset log.
|
|
7
|
+
*
|
|
8
|
+
* Stale threshold: 1 hour (hardcoded — not user-configurable)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const STALE_MS = 60 * 60 * 1000; // 1 hour
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Determine if a task is stale (in_progress for longer than STALE_MS).
|
|
15
|
+
* @param {Object} task
|
|
16
|
+
* @param {number} [now] - timestamp for testability (defaults to Date.now())
|
|
17
|
+
* @returns {boolean}
|
|
18
|
+
*/
|
|
19
|
+
export function isStaleTask(task, now = Date.now()) {
|
|
20
|
+
if (task.status !== 'in_progress') return false;
|
|
21
|
+
if (!task.startedAt) return true; // missing timestamp → treat as stale
|
|
22
|
+
return now - new Date(task.startedAt).getTime() > STALE_MS;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Reset all stale in_progress tasks across all features in state.
|
|
27
|
+
* Mutates state in-place. Returns log of reset task identifiers.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} state - Full state object (state.features)
|
|
30
|
+
* @param {number} [now] - Timestamp for testability
|
|
31
|
+
* @returns {string[]} resetLog — entries like "feature-name/T008"
|
|
32
|
+
*/
|
|
33
|
+
export function resetStaleTasks(state, now = Date.now()) {
|
|
34
|
+
const resetLog = [];
|
|
35
|
+
|
|
36
|
+
for (const [featureName, feature] of Object.entries(state.features || {})) {
|
|
37
|
+
// Resolve task list for both v2 (array) and v3 (taskList) formats
|
|
38
|
+
const isV2 = Array.isArray(feature.tasks);
|
|
39
|
+
const list = isV2 ? feature.tasks : (feature.taskList || []);
|
|
40
|
+
|
|
41
|
+
for (const task of list) {
|
|
42
|
+
if (isStaleTask(task, now)) {
|
|
43
|
+
task.status = 'pending';
|
|
44
|
+
delete task.startedAt;
|
|
45
|
+
resetLog.push(`${featureName}/${task.id ?? '(unknown)'}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Re-sync counters (v3 only — v2 tasks IS the list, no separate counters)
|
|
50
|
+
if (!isV2 && feature.tasks) {
|
|
51
|
+
feature.tasks.inProgress = list.filter(t => t.status === 'in_progress').length;
|
|
52
|
+
feature.tasks.pending = list.filter(t => t.status === 'pending').length;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return resetLog;
|
|
57
|
+
}
|
|
@@ -74,7 +74,7 @@ export function getFeature(featureName, projectPath) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
* Derive phase from filesystem (
|
|
77
|
+
* Derive phase from filesystem (phase deleted from state).
|
|
78
78
|
* Checks for phase folders in descending order, returns highest present.
|
|
79
79
|
* @param {string} featureName
|
|
80
80
|
* @param {string} [projectPath]
|
|
@@ -98,7 +98,7 @@ export function derivePhaseForFeature(featureName, projectPath) {
|
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* Get the current phase of a feature.
|
|
101
|
-
* Falls back to filesystem derivation when phase is not in state
|
|
101
|
+
* Falls back to filesystem derivation when phase is not in state.
|
|
102
102
|
* @param {string} featureName
|
|
103
103
|
* @param {string} [projectPath]
|
|
104
104
|
* @returns {string|null}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for worktree-related hook logic.
|
|
3
|
+
* Pure functions — no side effects, easy to test.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parse JSON output from `morph-spec worktree setup`.
|
|
8
|
+
* Finds the last line starting with '{' to skip chalk-colored output.
|
|
9
|
+
* @param {string} stdout - Raw stdout from the command
|
|
10
|
+
* @returns {Object|null}
|
|
11
|
+
*/
|
|
12
|
+
export function parseWorktreeResult(stdout) {
|
|
13
|
+
if (!stdout || typeof stdout !== 'string') return null;
|
|
14
|
+
try {
|
|
15
|
+
const trimmed = stdout.trim();
|
|
16
|
+
if (!trimmed) return null;
|
|
17
|
+
const lines = trimmed.split('\n');
|
|
18
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
19
|
+
const line = lines[i].trim();
|
|
20
|
+
if (line.startsWith('{')) {
|
|
21
|
+
return JSON.parse(line);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build context line(s) to inject based on worktree setup result.
|
|
32
|
+
* @param {Object|null} result - Parsed result from parseWorktreeResult
|
|
33
|
+
* @returns {string} Context lines to inject, or '' to skip injection
|
|
34
|
+
*/
|
|
35
|
+
export function buildWorktreeContextLine(result) {
|
|
36
|
+
if (!result) return '';
|
|
37
|
+
if (result.error) return '';
|
|
38
|
+
|
|
39
|
+
if (result.created) {
|
|
40
|
+
return `🪴 Worktree created: Working in .worktrees/${result.feature || ''} on branch ${result.branch}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (result.alreadyExists) {
|
|
44
|
+
return [
|
|
45
|
+
`⚠️ Existing worktree found for feature '${result.feature}': ${result.path} (branch: ${result.branch})`,
|
|
46
|
+
` Use AskUserQuestion to ask: "resume existing worktree or start fresh (--fresh)?"`,
|
|
47
|
+
` • Resume: continue in existing worktree (no change)`,
|
|
48
|
+
` • Fresh: run \`morph-spec worktree setup ${result.feature} --fresh\``
|
|
49
|
+
].join('\n');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return '';
|
|
53
|
+
}
|
package/framework/phases.json
CHANGED
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
"pausePoints": [
|
|
18
18
|
{ "id": "proposal", "label": "Approve Proposal" }
|
|
19
19
|
],
|
|
20
|
-
"agentTiers": [1]
|
|
20
|
+
"agentTiers": [1],
|
|
21
|
+
"requiredSkills": [
|
|
22
|
+
{ "trigger": "beforePhaseStart", "skill": "morph:brainstorming" }
|
|
23
|
+
]
|
|
21
24
|
},
|
|
22
25
|
"setup": {
|
|
23
26
|
"id": "setup",
|
|
@@ -33,7 +36,8 @@
|
|
|
33
36
|
"optionalOutputs": [],
|
|
34
37
|
"recommendedMCPs": ["github"],
|
|
35
38
|
"pausePoints": [],
|
|
36
|
-
"agentTiers": [1, 2]
|
|
39
|
+
"agentTiers": [1, 2],
|
|
40
|
+
"requiredSkills": []
|
|
37
41
|
},
|
|
38
42
|
"uiux": {
|
|
39
43
|
"id": "uiux",
|
|
@@ -52,7 +56,12 @@
|
|
|
52
56
|
"pausePoints": [
|
|
53
57
|
{ "id": "uiux", "label": "Approve UI/UX Design" }
|
|
54
58
|
],
|
|
55
|
-
"agentTiers": [1, 2, 3]
|
|
59
|
+
"agentTiers": [1, 2, 3],
|
|
60
|
+
"requiredSkills": [
|
|
61
|
+
{ "trigger": "beforeArchitecturalDecision", "skill": "morph:brainstorming" },
|
|
62
|
+
{ "trigger": "onHTMLPrototypeAvailable", "skill": "morph:replicate" },
|
|
63
|
+
{ "trigger": "beforePhaseComplete", "skill": "morph:frontend-review" }
|
|
64
|
+
]
|
|
56
65
|
},
|
|
57
66
|
"design": {
|
|
58
67
|
"id": "design",
|
|
@@ -71,7 +80,13 @@
|
|
|
71
80
|
"pausePoints": [
|
|
72
81
|
{ "id": "design", "label": "Approve Design Spec" }
|
|
73
82
|
],
|
|
74
|
-
"agentTiers": [1, 2, 3, 4]
|
|
83
|
+
"agentTiers": [1, 2, 3, 4],
|
|
84
|
+
"requiredSkills": [
|
|
85
|
+
{ "trigger": "beforePhaseStart", "skill": "morph:phase-codebase-analysis" },
|
|
86
|
+
{ "trigger": "beforeArchitecturalDecision", "skill": "morph:brainstorming" },
|
|
87
|
+
{ "trigger": "onExternalServiceIntegration", "skill": "morph:simulation-checklist" },
|
|
88
|
+
{ "trigger": "beforePhaseComplete", "skill": "morph:verification-before-completion" }
|
|
89
|
+
]
|
|
75
90
|
},
|
|
76
91
|
"clarify": {
|
|
77
92
|
"id": "clarify",
|
|
@@ -87,7 +102,10 @@
|
|
|
87
102
|
"optionalOutputs": [],
|
|
88
103
|
"recommendedMCPs": ["context7", "github"],
|
|
89
104
|
"pausePoints": [],
|
|
90
|
-
"agentTiers": [1, 2]
|
|
105
|
+
"agentTiers": [1, 2],
|
|
106
|
+
"requiredSkills": [
|
|
107
|
+
{ "trigger": "beforePhaseComplete", "skill": "morph:verification-before-completion" }
|
|
108
|
+
]
|
|
91
109
|
},
|
|
92
110
|
"tasks": {
|
|
93
111
|
"id": "tasks",
|
|
@@ -105,7 +123,12 @@
|
|
|
105
123
|
"pausePoints": [
|
|
106
124
|
{ "id": "tasks", "label": "Approve Task List" }
|
|
107
125
|
],
|
|
108
|
-
"agentTiers": [1, 2, 3]
|
|
126
|
+
"agentTiers": [1, 2, 3],
|
|
127
|
+
"requiredSkills": [
|
|
128
|
+
{ "trigger": "beforePhaseStart", "skill": "superpowers:writing-plans" },
|
|
129
|
+
{ "trigger": "onParallelTasksIdentified", "skill": "superpowers:dispatching-parallel-agents" },
|
|
130
|
+
{ "trigger": "beforePhaseComplete", "skill": "morph:verification-before-completion" }
|
|
131
|
+
]
|
|
109
132
|
},
|
|
110
133
|
"implement": {
|
|
111
134
|
"id": "implement",
|
|
@@ -122,7 +145,15 @@
|
|
|
122
145
|
"optionalOutputs": [],
|
|
123
146
|
"recommendedMCPs": ["supabase", "context7", "playwright", "github", "docker", "azure"],
|
|
124
147
|
"pausePoints": [],
|
|
125
|
-
"agentTiers": [1, 2, 3, 4]
|
|
148
|
+
"agentTiers": [1, 2, 3, 4],
|
|
149
|
+
"requiredSkills": [
|
|
150
|
+
{ "trigger": "beforeEachTask", "skill": "superpowers:test-driven-development" },
|
|
151
|
+
{ "trigger": "beforeTaskDone", "skill": "morph:verification-before-completion" },
|
|
152
|
+
{ "trigger": "onBugOrUnexpected", "skill": "superpowers:systematic-debugging" },
|
|
153
|
+
{ "trigger": "afterAllTasks", "skill": "morph:post-implementation" },
|
|
154
|
+
{ "trigger": "afterAllTasks", "skill": "superpowers:requesting-code-review" },
|
|
155
|
+
{ "trigger": "beforePR", "skill": "morph:checklist" }
|
|
156
|
+
]
|
|
126
157
|
},
|
|
127
158
|
"sync": {
|
|
128
159
|
"id": "sync",
|
|
@@ -139,7 +170,8 @@
|
|
|
139
170
|
"optionalOutputs": [],
|
|
140
171
|
"recommendedMCPs": [],
|
|
141
172
|
"pausePoints": [],
|
|
142
|
-
"agentTiers": [1]
|
|
173
|
+
"agentTiers": [1],
|
|
174
|
+
"requiredSkills": []
|
|
143
175
|
}
|
|
144
176
|
}
|
|
145
177
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: brainstorming
|
|
2
|
+
name: morph:brainstorming
|
|
3
3
|
description: Morph-spec-aware brainstorming that loads project context, explores multiple design approaches, asks clarifying questions, and produces proposal.md or decisions.md. Use before designing a feature, when facing architectural decisions with multiple valid approaches, or when a feature needs requirements exploration before committing to a direction.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
argument-hint: "[feature-name or topic]"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: code-review
|
|
2
|
+
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
|
|
@@ -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/4-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
|
+
---
|
|
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/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/4-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
|
|
@@ -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
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: morph
|
|
2
|
+
name: morph:checklist
|
|
3
3
|
description: Pre-deploy, security, SEO, performance, accessibility, and LGPD compliance checklists for MORPH-SPEC projects. Use before deploying to production, during security audits, when optimizing for SEO or performance, or when validating Brazilian LGPD data protection compliance.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
@@ -7,7 +7,7 @@ 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` (ver skill: `simulation-checklist`)
|
|
10
|
+
Types: `deploy`, `security`, `seo`, `performance`, `accessibility`, `legal-brazil`, `simulation` (ver skill: `morph:simulation-checklist`)
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|