@polymorphism-tech/morph-spec 4.8.6 → 4.8.8
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 +22 -1
- package/bin/task-manager.cjs +120 -16
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/agents.json +1854 -1815
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +141 -23
- package/framework/hooks/claude-code/statusline.py +304 -280
- package/framework/hooks/claude-code/statusline.sh +6 -2
- package/framework/hooks/claude-code/stop/validate-completion.js +70 -23
- package/framework/hooks/dev/guard-version-numbers.js +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +44 -6
- package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +67 -16
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +77 -7
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +114 -50
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +139 -1
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +29 -6
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +4 -3
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +1 -1
- package/framework/standards/STANDARDS.json +944 -933
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +429 -0
- package/framework/templates/REGISTRY.json +1909 -1888
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +282 -0
- package/package.json +1 -1
- package/src/commands/agents/dispatch-agents.js +430 -0
- package/src/commands/agents/index.js +2 -1
- package/src/commands/project/doctor.js +137 -2
- package/src/commands/state/state.js +20 -4
- package/src/commands/templates/generate-contracts.js +445 -0
- package/src/commands/templates/index.js +1 -0
- package/src/lib/validators/validation-runner.js +19 -7
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# morph-spec statusline — installed globally to ~/.claude/statusline.sh
|
|
3
3
|
# Claude Code invokes this with JSON via stdin after each response.
|
|
4
|
-
# Requires: Python 3 available as `python3` on PATH.
|
|
4
|
+
# Requires: Python 3 available as `python3` or `python` on PATH.
|
|
5
5
|
|
|
6
6
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
-
python3
|
|
7
|
+
if command -v python3 &>/dev/null; then
|
|
8
|
+
python3 "${SCRIPT_DIR}/statusline.py" 2>/dev/null || true
|
|
9
|
+
elif command -v python &>/dev/null; then
|
|
10
|
+
python "${SCRIPT_DIR}/statusline.py" 2>/dev/null || true
|
|
11
|
+
fi
|
|
@@ -1,23 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Stop Hook: Validate Completion
|
|
4
|
+
* Stop Hook: Validate Completion + Phase Transition Alerts
|
|
5
5
|
*
|
|
6
6
|
* Event: Stop
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* 1. Detects transitions into the `implement` phase and recommends /compact
|
|
9
|
+
* before starting — ensures Claude has a clean context for writing code.
|
|
10
|
+
* 2. Checks for incomplete work (tasks, missing outputs, pending gates).
|
|
11
|
+
*
|
|
12
|
+
* Phase transition tracking: stores last-seen phase per feature in
|
|
13
|
+
* .morph/memory/phase-watch.json so the alert fires exactly once,
|
|
14
|
+
* the first Stop after the transition occurs.
|
|
12
15
|
*
|
|
13
16
|
* Uses stop_hook_active env check to prevent infinite loops.
|
|
14
17
|
*
|
|
15
18
|
* Fail-open: exits 0 on any error.
|
|
16
19
|
*/
|
|
17
20
|
|
|
18
|
-
import {
|
|
21
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
22
|
+
import { join } from 'path';
|
|
23
|
+
import {
|
|
24
|
+
stateExists, getActiveFeature, getMissingOutputs, derivePhaseForFeature,
|
|
25
|
+
} from '../../shared/state-reader.js';
|
|
19
26
|
import { injectContext, pass } from '../../shared/hook-response.js';
|
|
20
27
|
|
|
28
|
+
// Phases where compaction is strongly recommended before starting
|
|
29
|
+
const COMPACT_TRIGGER_PHASES = new Set(['implement']);
|
|
30
|
+
|
|
31
|
+
// Phases where compaction is suggested when arriving from a heavy spec phase
|
|
32
|
+
const HEAVY_SOURCE_PHASES = new Set(['tasks', 'design', 'clarify', 'uiux']);
|
|
33
|
+
|
|
21
34
|
try {
|
|
22
35
|
// Prevent infinite loop
|
|
23
36
|
if (process.env.MORPH_STOP_HOOK_ACTIVE === '1') pass();
|
|
@@ -28,10 +41,48 @@ try {
|
|
|
28
41
|
if (!active) pass();
|
|
29
42
|
|
|
30
43
|
const { name, feature } = active;
|
|
44
|
+
const cwd = process.cwd();
|
|
31
45
|
const warnings = [];
|
|
32
46
|
|
|
33
|
-
//
|
|
34
|
-
|
|
47
|
+
// ── Phase transition detection ────────────────────────────────────────────
|
|
48
|
+
const currentPhase = feature.phase || derivePhaseForFeature(name, cwd);
|
|
49
|
+
|
|
50
|
+
const watchPath = join(cwd, '.morph', 'memory', 'phase-watch.json');
|
|
51
|
+
let phaseWatch = {};
|
|
52
|
+
try {
|
|
53
|
+
if (existsSync(watchPath)) phaseWatch = JSON.parse(readFileSync(watchPath, 'utf-8'));
|
|
54
|
+
} catch { /* corrupt file — start fresh */ }
|
|
55
|
+
|
|
56
|
+
const lastPhase = phaseWatch[name];
|
|
57
|
+
|
|
58
|
+
// Update stored phase (always, so the alert only fires once per transition)
|
|
59
|
+
try {
|
|
60
|
+
phaseWatch[name] = currentPhase;
|
|
61
|
+
writeFileSync(watchPath, JSON.stringify(phaseWatch, null, 2), 'utf-8');
|
|
62
|
+
} catch { /* non-blocking */ }
|
|
63
|
+
|
|
64
|
+
// Alert when entering implement from a heavy spec phase
|
|
65
|
+
const isPhaseTransition = lastPhase && lastPhase !== currentPhase;
|
|
66
|
+
const enteringImplement = COMPACT_TRIGGER_PHASES.has(currentPhase);
|
|
67
|
+
const comingFromHeavyPhase = HEAVY_SOURCE_PHASES.has(lastPhase);
|
|
68
|
+
|
|
69
|
+
if (isPhaseTransition && enteringImplement && comingFromHeavyPhase) {
|
|
70
|
+
warnings.push(
|
|
71
|
+
`⚡ Phase advanced: ${lastPhase} → implement`,
|
|
72
|
+
``,
|
|
73
|
+
`💡 Recommended before starting implementation:`,
|
|
74
|
+
` Run /compact to free up context — the spec, design and task files`,
|
|
75
|
+
` loaded during planning take significant space. A compact now gives`,
|
|
76
|
+
` Claude a clean slate focused on writing code.`,
|
|
77
|
+
``,
|
|
78
|
+
` After /compact, resume with: morph-spec task next ${name}`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ── Incomplete work checks ────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
// Incomplete tasks during implement phase
|
|
85
|
+
if (currentPhase === 'implement' && feature.tasks) {
|
|
35
86
|
const remaining = (feature.tasks.total || 0) - (feature.tasks.completed || 0);
|
|
36
87
|
if (remaining > 0) {
|
|
37
88
|
warnings.push(`${remaining} task(s) remaining for feature '${name}'`);
|
|
@@ -41,11 +92,11 @@ try {
|
|
|
41
92
|
}
|
|
42
93
|
}
|
|
43
94
|
|
|
44
|
-
//
|
|
45
|
-
if (['proposal', 'design', 'clarify', 'tasks', 'uiux'].includes(
|
|
95
|
+
// Missing outputs in spec phases
|
|
96
|
+
if (['proposal', 'design', 'clarify', 'tasks', 'uiux'].includes(currentPhase)) {
|
|
46
97
|
const missing = getMissingOutputs(name);
|
|
47
98
|
if (missing.length > 0) {
|
|
48
|
-
warnings.push(`Missing outputs for '${name}' (${
|
|
99
|
+
warnings.push(`Missing outputs for '${name}' (${currentPhase} phase):`);
|
|
49
100
|
for (const output of missing.slice(0, 5)) {
|
|
50
101
|
warnings.push(` - ${output.type}: ${output.path}`);
|
|
51
102
|
}
|
|
@@ -55,34 +106,30 @@ try {
|
|
|
55
106
|
}
|
|
56
107
|
}
|
|
57
108
|
|
|
58
|
-
//
|
|
109
|
+
// Pending approval gates
|
|
59
110
|
if (feature.approvalGates) {
|
|
60
111
|
const pendingGates = Object.entries(feature.approvalGates)
|
|
61
112
|
.filter(([, gate]) => !gate.approved && !gate.timestamp)
|
|
62
|
-
.map(([
|
|
113
|
+
.map(([gateName]) => gateName);
|
|
63
114
|
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const gatePhaseMap = { proposal: 'proposal', uiux: 'uiux', design: 'design', tasks: 'tasks' };
|
|
67
|
-
return gatePhaseMap[gate] !== undefined;
|
|
68
|
-
});
|
|
115
|
+
const gatePhaseMap = { proposal: 'proposal', uiux: 'uiux', design: 'design', tasks: 'tasks' };
|
|
116
|
+
const relevant = pendingGates.filter(gate => gatePhaseMap[gate] !== undefined);
|
|
69
117
|
|
|
70
|
-
if (
|
|
71
|
-
warnings.push(`Pending approvals: ${
|
|
118
|
+
if (relevant.length > 0) {
|
|
119
|
+
warnings.push(`Pending approvals: ${relevant.join(', ')}`);
|
|
72
120
|
}
|
|
73
121
|
}
|
|
74
122
|
|
|
75
123
|
if (warnings.length === 0) pass();
|
|
76
124
|
|
|
77
125
|
const message = [
|
|
78
|
-
'MORPH-SPEC:
|
|
126
|
+
'MORPH-SPEC:',
|
|
79
127
|
...warnings.map(w => ` ${w}`),
|
|
80
128
|
'',
|
|
81
|
-
|
|
129
|
+
`Status: morph-spec status ${name}`,
|
|
82
130
|
].join('\n');
|
|
83
131
|
|
|
84
132
|
injectContext(message);
|
|
85
133
|
} catch {
|
|
86
|
-
// Fail-open
|
|
87
134
|
process.exit(0);
|
|
88
135
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Scope: Framework codebase only (dev hook)
|
|
8
8
|
*
|
|
9
9
|
* Blocks Write/Edit to files that contain hardcoded version patterns
|
|
10
|
-
* like "MORPH-SPEC v4.8.
|
|
10
|
+
* like "MORPH-SPEC v4.8.8". Version should only be in package.json.
|
|
11
11
|
*
|
|
12
12
|
* Checked extensions: .md, .cs, .css, .js (covers templates + source)
|
|
13
13
|
* Exceptions: CHANGELOG.md, node_modules/, test/, package.json, package-lock.json
|
|
@@ -111,6 +111,9 @@ Gather evidence to build a stack map. Run these in parallel:
|
|
|
111
111
|
| `Glob` | `database/migrations/**` | Supabase local dev |
|
|
112
112
|
| `Glob` | `supabase/**` | Supabase project config |
|
|
113
113
|
| `Glob` | `**/*.razor` | Blazor |
|
|
114
|
+
| `Glob` | `**/Abstractions/IHandler.cs` | VSA pattern (KanaiyaKatarmal) |
|
|
115
|
+
| `Glob` | `**/Pipelines/ValidationDecorator.cs` | VSA pipeline |
|
|
116
|
+
| `Glob` | `**/Features/**/*Feature` | VSA feature folder suffix |
|
|
114
117
|
| `Read` | `.env.example` | Env vars reveal integrations |
|
|
115
118
|
| `Read` | `README.md` | Existing project description |
|
|
116
119
|
| `Grep` | `@supabase/supabase-js` | Supabase dep in any package.json |
|
|
@@ -120,14 +123,20 @@ Gather evidence to build a stack map. Run these in parallel:
|
|
|
120
123
|
Read each found `package.json` for dependency names. Build an **evidence map**:
|
|
121
124
|
|
|
122
125
|
```
|
|
123
|
-
stack:
|
|
124
|
-
integrations:
|
|
125
|
-
uiLibrary:
|
|
126
|
-
monorepo:
|
|
127
|
-
frontendPath:
|
|
128
|
-
backendPath:
|
|
126
|
+
stack: [nextjs, dotnet, ...]
|
|
127
|
+
integrations: [supabase, docker, clerk, ...]
|
|
128
|
+
uiLibrary: shadcn | fluent-ui | mudblazor | null
|
|
129
|
+
monorepo: true | false
|
|
130
|
+
frontendPath: src/frontend (if monorepo)
|
|
131
|
+
backendPath: src/backend (if monorepo)
|
|
132
|
+
architectureStyle: vertical-slice | null ← novo
|
|
129
133
|
```
|
|
130
134
|
|
|
135
|
+
**VSA detection:** `architectureStyle: "vertical-slice"` se qualquer um destes existir:
|
|
136
|
+
- `Abstractions/IHandler.cs` encontrado pelo Glob
|
|
137
|
+
- `Pipelines/ValidationDecorator.cs` encontrado pelo Glob
|
|
138
|
+
- 2+ pastas com sufixo `Feature` em `Features/` (ex: `BookFeature`, `OrderFeature`)
|
|
139
|
+
|
|
131
140
|
---
|
|
132
141
|
|
|
133
142
|
## Step 4 — Ask Targeted Questions
|
|
@@ -195,6 +204,35 @@ Read `.morph/config/config.json` and merge into `project`:
|
|
|
195
204
|
}
|
|
196
205
|
```
|
|
197
206
|
|
|
207
|
+
**Se `architectureStyle: "vertical-slice"` foi detectado no Step 3**, adicione também:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"architecture": {
|
|
212
|
+
"style": "vertical-slice"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
E informe o usuário:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
✓ Detected: Vertical Slice Architecture (IHandler.cs / *Feature folders)
|
|
221
|
+
→ config.json: architecture.style = "vertical-slice"
|
|
222
|
+
→ morph-spec will use vsa-architect + contracts-vsa.cs for features
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
> Esta key é o que ativa o `vsa-architect` em vez do `domain-architect` durante `/morph-proposal`.
|
|
226
|
+
|
|
227
|
+
**Se o projeto ainda não existe (novo projeto VSA do zero)**, informe também:
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
Para criar um novo projeto VSA:
|
|
231
|
+
dotnet new install https://github.com/polymorphism-tech/Morph_Template_VerticalSliceArchitecture
|
|
232
|
+
dotnet new vsa -n MyProject
|
|
233
|
+
cd MyProject && npx morph-spec init
|
|
234
|
+
```
|
|
235
|
+
|
|
198
236
|
---
|
|
199
237
|
|
|
200
238
|
## Step 7 — Configure MCPs
|
|
@@ -34,18 +34,52 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
34
34
|
└──┬──────────────┬────────┘
|
|
35
35
|
│ YES │ NO
|
|
36
36
|
▼ ▼
|
|
37
|
-
Use MCP tool
|
|
38
|
-
(+ fallback) │ Does it
|
|
39
|
-
│
|
|
40
|
-
│
|
|
41
|
-
│
|
|
42
|
-
|
|
43
|
-
│ YES
|
|
44
|
-
▼
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
Use MCP tool ┌──────────────────────────────┐
|
|
38
|
+
(+ fallback) │ Does it involve MULTIPLE │
|
|
39
|
+
│ independent specialist tasks │
|
|
40
|
+
│ (domain analysis + schema, │
|
|
41
|
+
│ backend + frontend tasks)? │
|
|
42
|
+
└──┬───────────────┬───────────┘
|
|
43
|
+
│ YES │ NO
|
|
44
|
+
▼ ▼
|
|
45
|
+
Dispatch parallel ┌──────────────────┐
|
|
46
|
+
Task subagents │ Does it require │
|
|
47
|
+
(see below) │ MULTI-STEP │
|
|
48
|
+
│ exploration of │
|
|
49
|
+
│ many files? │
|
|
50
|
+
└──┬──────────┬─────┘
|
|
51
|
+
│ YES │ NO
|
|
52
|
+
▼ ▼
|
|
53
|
+
Use Task Do it
|
|
54
|
+
(subagent) directly
|
|
47
55
|
```
|
|
48
56
|
|
|
57
|
+
### When to use Task subagents for agent dispatch
|
|
58
|
+
|
|
59
|
+
Dispatch specialist agents as **Task subagents** when ALL conditions are met:
|
|
60
|
+
- Phase is `design`, `tasks`, or `implement`
|
|
61
|
+
- Feature has **2+ active specialist agents** (check `activeAgents` in state.json)
|
|
62
|
+
- Work can be divided into **independent parallel tasks** with clear outputs
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Feature with multiple active agents?
|
|
66
|
+
│
|
|
67
|
+
├─ design phase → Dispatch domain-architect (complexity analysis)
|
|
68
|
+
│ + tech leads (spec validation) — in PARALLEL
|
|
69
|
+
│
|
|
70
|
+
├─ tasks phase → Dispatch per-domain task planners (if spec has 50+ reqs
|
|
71
|
+
│ OR 3+ independent domains detected)
|
|
72
|
+
│
|
|
73
|
+
└─ implement phase → Dispatch per-domain implementers when tasks.total ≥ 6
|
|
74
|
+
AND feature spans multiple domains (backend + frontend,
|
|
75
|
+
or backend + infra, etc.)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Key principle (from real-world usage):** Define subagents by **TASK**, not by **ROLE**.
|
|
79
|
+
- ✅ "Analyze this proposal for DDD complexity and return level + blueprint" (task)
|
|
80
|
+
- ✅ "Implement backend tasks T001-T005 for feature X" (task)
|
|
81
|
+
- ❌ "Be a domain architect" (vague role assignment — poor results)
|
|
82
|
+
|
|
49
83
|
---
|
|
50
84
|
|
|
51
85
|
## Tools Per Phase
|
|
@@ -80,18 +114,19 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
80
114
|
| Action | Tool | Why |
|
|
81
115
|
|--------|------|-----|
|
|
82
116
|
| Verify feature state | **Bash** `npx morph-spec state get {feature}` | CLI command |
|
|
83
|
-
| Detect agents + standards | **Read** `.morph/framework/agents.json` → match keywords → **Bash** `npx morph-spec state add-agent {f} {id}` per match |
|
|
117
|
+
| Detect agents + standards | **Read** `.morph/framework/agents.json` → match keywords → **Bash** `npx morph-spec state add-agent {f} {id}` per match | Keyword matching is fast inline |
|
|
84
118
|
| Read project context | **Read** `.morph/context/README.md` | Single file |
|
|
85
119
|
| Read config | **Read** `.morph/config.json` | Single file |
|
|
86
120
|
| Scan project structure | **Glob** `src/**/*.{ts,tsx,cs}` | Understand codebase layout |
|
|
87
121
|
| Get repo metadata | **GitHub MCP** `get_repo()` | Structured repo info (if MCP available) |
|
|
122
|
+
| Get dispatch config for next phases | **Bash** `npx morph-spec dispatch-agents {feature} design` | Shows which agents will be dispatched in design phase |
|
|
88
123
|
| Update state | **Bash** `npx morph-spec state set ...` | CLI command |
|
|
89
124
|
|
|
90
125
|
**MCPs used:** GitHub (optional — for repo metadata).
|
|
91
126
|
|
|
92
127
|
**Anti-patterns:**
|
|
93
128
|
- ❌ Calling `detect-agents` CLI (it doesn't exist — read `.morph/framework/agents.json` directly)
|
|
94
|
-
- ❌ Task agent to detect project stack (
|
|
129
|
+
- ❌ Task agent to detect project stack inline (keyword matching is fast enough directly)
|
|
95
130
|
- ❌ WebSearch for project info (it's local, use Read/Glob)
|
|
96
131
|
|
|
97
132
|
---
|
|
@@ -132,6 +167,9 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
132
167
|
| Action | Tool | Why |
|
|
133
168
|
|--------|------|-----|
|
|
134
169
|
| Read proposal + UI specs | **Read** output files | Single known files |
|
|
170
|
+
| **Get dispatch config** | **Bash** `npx morph-spec dispatch-agents {feature} design` | Which agents to spawn + their task prompts |
|
|
171
|
+
| **Dispatch domain-architect** (parallel) | **Task** subagent with prompt from dispatch config | Analyze DDD complexity independently |
|
|
172
|
+
| **Dispatch tech leads** (parallel) | **Task** subagents (dotnet-senior, nextjs-expert, etc.) | Validate architecture independently |
|
|
135
173
|
| Get database schema | **Supabase MCP** `list_tables()`, `get_table_schema()` | **PREFERRED** — real schema data |
|
|
136
174
|
| Get table relationships | **Supabase MCP** `get_relationships()` | Real FK/constraint data |
|
|
137
175
|
| Get RLS policies | **Supabase MCP** `query()` with pg_policies | Security analysis |
|
|
@@ -149,11 +187,14 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
149
187
|
|
|
150
188
|
**MCPs used:** Supabase (schema analysis), Context7 (library research), GitHub (code search).
|
|
151
189
|
|
|
190
|
+
**Parallel dispatch opportunity:** Domain complexity analysis (domain-architect) and schema analysis (phase-codebase-analysis) are **independent** — run them as parallel Task subagents to cut design phase time.
|
|
191
|
+
|
|
152
192
|
**Anti-patterns:**
|
|
153
193
|
- ❌ Guessing field names without checking schema (use MCP or Grep first!)
|
|
154
|
-
- ❌ Task agent to read a single spec file (
|
|
194
|
+
- ❌ Task agent to read a single spec file (use Read directly)
|
|
155
195
|
- ❌ WebSearch for database schema (use Supabase MCP or code analysis)
|
|
156
196
|
- ❌ Manually writing contracts-level{N}.cs from scratch (use template render)
|
|
197
|
+
- ❌ Running domain analysis and schema analysis sequentially (they're independent — run in parallel)
|
|
157
198
|
|
|
158
199
|
---
|
|
159
200
|
|
|
@@ -189,8 +230,10 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
189
230
|
| Action | Tool | Why |
|
|
190
231
|
|--------|------|-----|
|
|
191
232
|
| Read spec + contracts + decisions | **Read** all output files | Full context needed |
|
|
233
|
+
| **Get dispatch config** | **Bash** `npx morph-spec dispatch-agents {feature} tasks` | Which domain experts to consult |
|
|
192
234
|
| Analyze implementation complexity | **Grep** patterns in existing code | Estimate effort from codebase size |
|
|
193
235
|
| Count existing similar patterns | **Glob** `**/Services/**/*.cs` | Understand scope |
|
|
236
|
+
| **Dispatch domain experts** (when spec is complex) | **Task** subagents per domain | Parallel per-domain task planning |
|
|
194
237
|
| Look up implementation patterns | **Context7 MCP** `query_docs()` | Estimate task complexity accurately |
|
|
195
238
|
| Create GitHub issues from tasks | **GitHub MCP** `create_issue()` | Sync tasks to project management |
|
|
196
239
|
| **Fallback:** Create issues via CLI | **Bash** `gh issue create ...` | When no GitHub MCP |
|
|
@@ -200,8 +243,9 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
200
243
|
**MCPs used:** Context7 (complexity estimation), GitHub (issue creation).
|
|
201
244
|
|
|
202
245
|
**Anti-patterns:**
|
|
203
|
-
- ❌ Task agent to break down a simple spec (do it directly
|
|
204
|
-
- ✅ Task agent for complex specs
|
|
246
|
+
- ❌ Task agent to break down a simple 1-domain spec (do it directly)
|
|
247
|
+
- ✅ Task agent for complex multi-domain specs (backend + frontend + infra = 3 independent planners)
|
|
248
|
+
- ✅ Task agent when spec has 20+ requirements across multiple bounded contexts
|
|
205
249
|
- ❌ Manually writing tasks.json without reading all outputs first
|
|
206
250
|
|
|
207
251
|
---
|
|
@@ -213,6 +257,8 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
213
257
|
| Action | Tool | Why |
|
|
214
258
|
|--------|------|-----|
|
|
215
259
|
| Read task details | **Read** tasks.json, spec.md, contracts.cs | Implementation reference |
|
|
260
|
+
| **Check parallelization viability** | **Bash** `npx morph-spec dispatch-agents {feature} implement` | Whether to dispatch parallel implementers |
|
|
261
|
+
| **Dispatch per-domain implementers** (when viable) | **Task** subagents — one per domain group | Backend tasks + frontend tasks run in parallel |
|
|
216
262
|
| Create new files | **Write** new source files | New entities, services, pages |
|
|
217
263
|
| Modify existing files | **Edit** existing source files | Add features to existing code |
|
|
218
264
|
| Look up API during coding | **Context7 MCP** `query_docs()` | Accurate library usage |
|
|
@@ -228,17 +274,22 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
228
274
|
| Smoke test feature no browser | **Playwright MCP** `browser_navigate()` + `browser_snapshot()` | Manual testing |
|
|
229
275
|
| Verificar erros de console | **Playwright MCP** `browser_console_messages()` | Browser DevTools |
|
|
230
276
|
| Screenshot para recap.md | **Playwright MCP** `browser_take_screenshot()` | Manual screenshot |
|
|
231
|
-
| Multi-file refactoring | **Task** (subagent) | Complex parallel changes |
|
|
232
277
|
| Update state | **Bash** `npx morph-spec state set ...` | CLI command |
|
|
233
278
|
|
|
234
279
|
**MCPs used:** Supabase (migrations, RLS), Context7 (API lookup), GitHub (PRs), Playwright (smoke test, verification).
|
|
235
280
|
|
|
281
|
+
**Parallel dispatch threshold:**
|
|
282
|
+
- `tasks.total ≥ 6` AND feature spans 2+ domains (e.g. `dotnet-senior` + `nextjs-expert`) → dispatch parallel implementers
|
|
283
|
+
- Each subagent gets its own task group (backend T001-T005, frontend T006-T009) with isolated file scope
|
|
284
|
+
|
|
236
285
|
**Anti-patterns:**
|
|
237
286
|
- ❌ Task agent for a single file edit (use Edit directly)
|
|
238
287
|
- ✅ Task agent for implementing a full service layer across 5+ files
|
|
288
|
+
- ✅ Task agent for each domain group when feature has 6+ tasks across multiple domains
|
|
239
289
|
- ❌ Bash `cat` to create files (use Write tool)
|
|
240
290
|
- ❌ Bash `sed` to modify code (use Edit tool)
|
|
241
291
|
- ❌ Implementing without reading contracts.cs first (contracts are the source of truth)
|
|
292
|
+
- ❌ Implementing backend and frontend tasks sequentially when they have no cross-dependencies
|
|
242
293
|
|
|
243
294
|
---
|
|
244
295
|
|
|
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 3 (Clarify). Reviews spec.md for ambiguities, gene
|
|
|
4
4
|
argument-hint: "[feature-name]"
|
|
5
5
|
user-invocable: false
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
7
|
-
cliVersion: "4.8.
|
|
7
|
+
cliVersion: "4.8.8"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MORPH Clarify - FASE 3
|
|
@@ -3,7 +3,7 @@ name: phase-codebase-analysis
|
|
|
3
3
|
description: MORPH-SPEC Design sub-phase that analyzes existing codebase and database schema, producing schema-analysis.md with real column names, types, relationships, and field mismatches. Use at the start of Design phase before generating contracts.cs to prevent incorrect field names or types.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
-
cliVersion: "4.8.
|
|
6
|
+
cliVersion: "4.8.8"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# MORPH Codebase Analysis - Sub-fase de DESIGN
|
|
@@ -44,15 +44,33 @@ Automatiza a análise de código existente para gerar `schema-analysis.md` com d
|
|
|
44
44
|
|
|
45
45
|
### Passo 1: Detectar Método de Análise
|
|
46
46
|
|
|
47
|
+
**IMPORTANTE (Problem 8 fix):** Não assuma que o MCP está disponível e acessível.
|
|
48
|
+
Verifique primeiro com uma chamada de teste antes de tentar usá-lo.
|
|
49
|
+
|
|
47
50
|
```
|
|
48
|
-
SE MCP Supabase
|
|
49
|
-
|
|
50
|
-
SE
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
1. SE MCP Supabase configurado no settings.json:
|
|
52
|
+
→ Tentar mcp__supabase__list_tables() com timeout implícito
|
|
53
|
+
→ SE retornar dados válidos (array de tabelas com conteúdo):
|
|
54
|
+
→ Usar Método A (MCP direto)
|
|
55
|
+
→ SE retornar erro, timeout, array vazio, ou dados inacessíveis:
|
|
56
|
+
→ Logar: "MCP Supabase configurado mas inacessível (CloudSQL? Auth? Permissões?)"
|
|
57
|
+
→ Usar Método B (análise estática de código)
|
|
58
|
+
|
|
59
|
+
2. SE MCP Database (outro) configurado:
|
|
60
|
+
→ Testar conectividade com query trivial antes de usar
|
|
61
|
+
→ SE OK: Usar Método A adaptado
|
|
62
|
+
→ SE falhar: Usar Método B
|
|
63
|
+
|
|
64
|
+
3. SE nenhum MCP disponível:
|
|
65
|
+
→ Usar Método B (análise estática de código)
|
|
54
66
|
```
|
|
55
67
|
|
|
68
|
+
**Sinais de MCP inacessível:**
|
|
69
|
+
- Resposta vazia ou `[]` em `list_tables()`
|
|
70
|
+
- Erro de autenticação / permissão negada
|
|
71
|
+
- Schema retornado não bate com o código (ex: tabelas existem no código mas não no MCP)
|
|
72
|
+
- Projeto usa banco diferente do Supabase (CloudSQL, RDS, Azure SQL, etc.)
|
|
73
|
+
|
|
56
74
|
### Passo 2A: Método MCP (Preferencial)
|
|
57
75
|
|
|
58
76
|
**Ferramentas:** Supabase MCP
|
|
@@ -128,6 +146,58 @@ Não use Task subagent quando:
|
|
|
128
146
|
- Projeto tem < 10 arquivos de query (Read direto é mais rápido)
|
|
129
147
|
- Padrão de acesso a dados é uniforme (só Supabase OU só EF Core)
|
|
130
148
|
|
|
149
|
+
### Passo 2B-Formato: Formato Padronizado para Análise Estática
|
|
150
|
+
|
|
151
|
+
**IMPORTANTE (Problem 10 fix):** Quando usar Método B (análise estática), **sempre use o template oficial**.
|
|
152
|
+
Isso garante que `contracts.cs` pode ser gerado mecanicamente, sem interpretação manual.
|
|
153
|
+
|
|
154
|
+
O template está em `framework/templates/docs/schema-analysis.md`. Use-o via:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npx morph-spec template render docs/schema-analysis \
|
|
158
|
+
.morph/features/{feature}/1-design/schema-analysis.md \
|
|
159
|
+
'{
|
|
160
|
+
"FEATURE_NAME": "{feature}",
|
|
161
|
+
"FEATURE_NAME_TITLE": "{Feature Display Name}",
|
|
162
|
+
"DATE": "YYYY-MM-DD",
|
|
163
|
+
"AUTHOR": "Claude Code (Sonnet 4.6)",
|
|
164
|
+
"method": "Static Code Analysis",
|
|
165
|
+
"mcpUsed": "No",
|
|
166
|
+
"tableCount": N,
|
|
167
|
+
"fileCount": N,
|
|
168
|
+
"tables": [
|
|
169
|
+
{
|
|
170
|
+
"name": "table_name",
|
|
171
|
+
"codeSource": "path/to/file.ts",
|
|
172
|
+
"columns": [
|
|
173
|
+
{ "name": "column_name", "type": "string", "nullable": false, "notes": "from SELECT query" }
|
|
174
|
+
],
|
|
175
|
+
"relationships": [{ "description": "belongs to users via user_id" }],
|
|
176
|
+
"indexes": [{ "description": "idx_leads_created_at (created_at DESC)" }]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
"fieldMismatches": [
|
|
180
|
+
{ "description": "Code uses user.name but DB column is users.fullname" }
|
|
181
|
+
],
|
|
182
|
+
"typeMismatches": [],
|
|
183
|
+
"relationshipIssues": [],
|
|
184
|
+
"dtoRecommendations": [
|
|
185
|
+
{
|
|
186
|
+
"tableName": "leads",
|
|
187
|
+
"dtoName": "LeadDto",
|
|
188
|
+
"fields": [
|
|
189
|
+
{ "type": "Guid", "name": "Id", "nullable": false, "comment": "PK" },
|
|
190
|
+
{ "type": "string", "name": "FullName", "nullable": false, "comment": "leads.fullname" }
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
}'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Se o template render não estiver disponível**, use **Write** tool para criar o arquivo diretamente
|
|
198
|
+
seguindo a estrutura acima. O formato das tabelas e mismatches é OBRIGATÓRIO — sem formato padrão
|
|
199
|
+
não é possível gerar contracts.cs mecanicamente.
|
|
200
|
+
|
|
131
201
|
### Passo 3: Mapear Inconsistências
|
|
132
202
|
|
|
133
203
|
Crie um mapa de:
|