@polymorphism-tech/morph-spec 4.10.10 → 4.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +106 -2
- package/README.md +5 -11
- package/bin/morph-spec.js +30 -2
- package/bin/task-manager.js +394 -38
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +2 -8
- package/framework/agents/frontend/css-specialist.md +1 -1
- package/framework/agents/infrastructure/azure-deploy-specialist.md +4 -4
- package/framework/commands/morph-apply.md +39 -19
- package/framework/commands/morph-preflight.md +3 -3
- package/framework/commands/morph-proposal.md +59 -16
- package/framework/commands/morph-status.md +3 -3
- package/framework/commands/morph-troubleshoot.md +1 -1
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +47 -2
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +2 -2
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +5 -4
- package/framework/hooks/claude-code/teammate-idle/teammate-idle.js +3 -3
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +2 -2
- package/framework/hooks/git/pre-commit/agents.sh +1 -1
- package/framework/hooks/shared/dispatch-helpers.js +14 -0
- package/framework/hooks/shared/state-reader.js +7 -3
- package/framework/rules/morph-task-tracking.md +49 -0
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +14 -18
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +3 -3
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +11 -11
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +3 -3
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +1 -1
- package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +4 -4
- package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +25 -25
- package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +8 -8
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +16 -7
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +4 -4
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +29 -35
- package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +35 -29
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -4
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -20
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +23 -26
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +21 -29
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +24 -16
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +5 -5
- package/framework/workflows/README.md +18 -18
- package/framework/workflows/docs/enforcement-pipeline.md +1 -1
- package/framework/workflows/docs/full-morph.md +2 -2
- package/package.json +1 -1
- package/src/commands/agents/dispatch-agents.js +25 -1
- package/src/commands/project/doctor.js +3 -4
- package/src/commands/project/status.js +8 -1
- package/src/commands/scope/escalate.js +5 -3
- package/src/commands/tasks/task.js +54 -0
- package/src/commands/validation/validate-feature.js +32 -3
- package/src/lib/build/build-runner.js +99 -0
- package/src/lib/checkpoints/checkpoint-hooks.js +110 -0
- package/src/lib/generators/recap-generator.js +27 -4
- package/src/lib/stack/stack-profile.js +3 -0
- package/src/lib/tasks/task-parser.js +23 -9
- package/src/scripts/global-install.js +57 -3
- package/src/utils/file-copier.js +1 -0
- package/src/utils/version-checker.js +1 -7
- package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +0 -7
package/docs/QUICKSTART.md
CHANGED
|
@@ -6,13 +6,7 @@
|
|
|
6
6
|
npm install -g @polymorphism-tech/morph-spec
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npx @polymorphism-tech/morph-spec init
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
> **Windows / nvm-windows:** Global installs may not appear on PATH. Use `npx` or add the npm prefix to PATH manually: `npm config get prefix`, then add `{prefix}` to your PATH.
|
|
9
|
+
> The installer automatically configures your PowerShell PATH on Windows. If `morph-spec` is not found, open a new terminal window.
|
|
16
10
|
|
|
17
11
|
---
|
|
18
12
|
|
|
@@ -203,4 +197,4 @@ morph-spec doctor
|
|
|
203
197
|
|
|
204
198
|
---
|
|
205
199
|
|
|
206
|
-
*morph-spec v4.
|
|
200
|
+
*morph-spec v4.11.1 by Polymorphism Tech*
|
|
@@ -67,7 +67,7 @@ When reviewing CSS:
|
|
|
67
67
|
|
|
68
68
|
If project already has CSS variables, scan them:
|
|
69
69
|
```bash
|
|
70
|
-
|
|
70
|
+
morph-spec generate design-system --scan
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
This extracts existing `:root { --var: value }` declarations and populates design-system.md.
|
|
@@ -220,7 +220,7 @@ Por favor, forneca os valores abaixo. Serao armazenados de forma segura.
|
|
|
220
220
|
|
|
221
221
|
```bash
|
|
222
222
|
# Validar custos antes de deploy
|
|
223
|
-
|
|
223
|
+
morph-spec cost infra/main.bicep --verbose
|
|
224
224
|
|
|
225
225
|
# Se custo > limite configurado:
|
|
226
226
|
# 1. PARAR deployment
|
|
@@ -563,7 +563,7 @@ Para uso em pipelines Azure DevOps:
|
|
|
563
563
|
|
|
564
564
|
```bash
|
|
565
565
|
# Uso automatico (sem pausas interativas)
|
|
566
|
-
|
|
566
|
+
morph-spec deploy prod --auto \
|
|
567
567
|
--sql-password "$(SQL_PASSWORD)" \
|
|
568
568
|
--tenant-id "$(TENANT_ID)" \
|
|
569
569
|
--client-secret "$(CLIENT_SECRET)" \
|
|
@@ -622,7 +622,7 @@ stages:
|
|
|
622
622
|
deploy:
|
|
623
623
|
steps:
|
|
624
624
|
- script: |
|
|
625
|
-
|
|
625
|
+
morph-spec deploy dev --auto \
|
|
626
626
|
--sql-password "$(SqlPassword)" \
|
|
627
627
|
--skip-confirmation
|
|
628
628
|
displayName: 'Deploy to Dev'
|
|
@@ -638,7 +638,7 @@ stages:
|
|
|
638
638
|
deploy:
|
|
639
639
|
steps:
|
|
640
640
|
- script: |
|
|
641
|
-
|
|
641
|
+
morph-spec deploy prod --auto \
|
|
642
642
|
--sql-password "$(SqlPasswordProd)" \
|
|
643
643
|
--skip-confirmation
|
|
644
644
|
displayName: 'Deploy to Prod'
|
|
@@ -23,10 +23,10 @@ Implement the feature by executing its task breakdown, tracking progress through
|
|
|
23
23
|
|--------|------|-------------|
|
|
24
24
|
| Read spec, tasks, contracts | **Read** all outputs | — |
|
|
25
25
|
| Detect architecture style | **Bash** `cat .morph/config/config.json \| grep architecture` | — |
|
|
26
|
-
| Agent dispatch config | **Bash** `
|
|
26
|
+
| Agent dispatch config | **Bash** `morph-spec dispatch-agents $ARGUMENTS implement` | — |
|
|
27
27
|
| Parallel task execution | **Agent** subagent per task group | Sequential fallback |
|
|
28
28
|
| Look up implementation patterns | **Context7 MCP** `query_docs()` | **WebSearch** |
|
|
29
|
-
| Track progress | **Bash** `
|
|
29
|
+
| Track progress | **Bash** `morph-spec state get $ARGUMENTS` | — |
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
@@ -37,9 +37,9 @@ Before writing any code, verify all prior phases are complete. This gate prevent
|
|
|
37
37
|
### 1. Check state and approvals
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
morph-spec state get $ARGUMENTS
|
|
41
|
+
morph-spec approval-status $ARGUMENTS
|
|
42
|
+
morph-spec validate-feature $ARGUMENTS
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
**All three must pass.** If any fails:
|
|
@@ -87,13 +87,13 @@ cat .morph/config/config.json | grep -A3 '"architecture"'
|
|
|
87
87
|
### 4. Get agent dispatch config
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
|
|
90
|
+
morph-spec dispatch-agents $ARGUMENTS implement --table
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
This shows which agents are active for implementation and how tasks can be grouped. If agent teams are enabled and tasks have no dependencies between groups, consider dispatching parallel agents:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
|
|
96
|
+
morph-spec dispatch-agents $ARGUMENTS implement
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
The JSON output includes `shouldDispatch`, `agents[]`, and `taskGroups` for multi-agent coordination.
|
|
@@ -105,15 +105,27 @@ The JSON output includes `shouldDispatch`, `agents[]`, and `taskGroups` for mult
|
|
|
105
105
|
### Step 1: Advance to implement phase
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
|
|
108
|
+
morph-spec phase advance $ARGUMENTS
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
This validates phase eligibility and emits a SKILL DISPATCH block listing required skills for implementation (verification-before-completion, morph-checklist, etc.).
|
|
112
112
|
|
|
113
|
+
### Step 1.5: Create pipeline visibility task
|
|
114
|
+
|
|
115
|
+
> **MANDATORY** — Create umbrella task for implementation tracking.
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
TaskCreate: "Implement: {feature-name}"
|
|
119
|
+
→ description: "Execute T001-T00N from tasks.md with checkpoints"
|
|
120
|
+
→ activeForm: "Implementing feature"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Mark as `in_progress`. After all tasks complete (Step 5), mark as `completed`.
|
|
124
|
+
|
|
113
125
|
### Step 2: Initialize state tracking
|
|
114
126
|
|
|
115
127
|
```bash
|
|
116
|
-
|
|
128
|
+
morph-spec state set $ARGUMENTS tasks.total {N}
|
|
117
129
|
```
|
|
118
130
|
|
|
119
131
|
Where `{N}` is the number of tasks in tasks.md (e.g., 6 for T001-T006).
|
|
@@ -124,7 +136,7 @@ For each task in the breakdown, follow this cycle:
|
|
|
124
136
|
|
|
125
137
|
```bash
|
|
126
138
|
# 1. Start the task (activates task-tracking guard)
|
|
127
|
-
|
|
139
|
+
morph-spec task start $ARGUMENTS {task-id}
|
|
128
140
|
|
|
129
141
|
# 2. Implement the task
|
|
130
142
|
# - Follow spec.md and contracts
|
|
@@ -136,7 +148,7 @@ npx morph-spec task start $ARGUMENTS {task-id}
|
|
|
136
148
|
# matches the spec and contracts before marking done
|
|
137
149
|
|
|
138
150
|
# 4. Complete the task (triggers Tier-4 validators automatically)
|
|
139
|
-
|
|
151
|
+
morph-spec task done $ARGUMENTS {task-id}
|
|
140
152
|
```
|
|
141
153
|
|
|
142
154
|
**If validation fails on `task done`:**
|
|
@@ -145,6 +157,13 @@ npx morph-spec task done $ARGUMENTS {task-id}
|
|
|
145
157
|
- Re-run `task done` — do NOT use `--skip-validation` unless the user explicitly authorizes it
|
|
146
158
|
- After 3 consecutive failures, escalate to the user
|
|
147
159
|
|
|
160
|
+
**`--skip-validation` budget system:**
|
|
161
|
+
- Budget-limited: `min(5, ceil(totalTasks × 0.20))` — e.g., 5 tasks → 1 skip, 32 tasks → 5 skips
|
|
162
|
+
- Requires `--reason <text>` (minimum 5 characters) for audit trail
|
|
163
|
+
- Skipped tasks don't count as `passed` in validationHistory → degrades pass rate
|
|
164
|
+
- Usage: `morph-spec task done feat T001 --skip-validation --reason "CSS-only change, no logic"`
|
|
165
|
+
- When budget is exhausted, all remaining tasks must pass Tier-4 validation
|
|
166
|
+
|
|
148
167
|
**Parallel execution (agent teams):**
|
|
149
168
|
If `dispatch-agents` identified parallelizable task groups and agent teams are enabled, dispatch independent tasks to separate agents. Each agent still calls `task start` and `task done` for its assigned task.
|
|
150
169
|
|
|
@@ -153,8 +172,8 @@ If `dispatch-agents` identified parallelizable task groups and agent teams are e
|
|
|
153
172
|
After every 3 completed tasks, save a checkpoint:
|
|
154
173
|
|
|
155
174
|
```bash
|
|
156
|
-
|
|
157
|
-
|
|
175
|
+
morph-spec checkpoint-save $ARGUMENTS "after-T003"
|
|
176
|
+
morph-spec state get $ARGUMENTS
|
|
158
177
|
```
|
|
159
178
|
|
|
160
179
|
Checkpoints validate architecture compliance, check package versions, scan for security issues, and save a restorable snapshot. The cadence is every 3 tasks — for 6 tasks: checkpoint after T003 and T006. For 10 tasks: after T003, T006, T009, and at completion.
|
|
@@ -162,7 +181,7 @@ Checkpoints validate architecture compliance, check package versions, scan for s
|
|
|
162
181
|
After each checkpoint, check progress:
|
|
163
182
|
|
|
164
183
|
```bash
|
|
165
|
-
|
|
184
|
+
morph-spec state list
|
|
166
185
|
```
|
|
167
186
|
|
|
168
187
|
### Step 5: Finalize implementation
|
|
@@ -171,16 +190,16 @@ After all tasks are complete:
|
|
|
171
190
|
|
|
172
191
|
```bash
|
|
173
192
|
# Final validation
|
|
174
|
-
|
|
193
|
+
morph-spec validate-feature $ARGUMENTS
|
|
175
194
|
|
|
176
195
|
# Generate recap (auto-marks 'recap' output in state)
|
|
177
|
-
|
|
196
|
+
morph-spec generate recap $ARGUMENTS
|
|
178
197
|
|
|
179
198
|
# Verify final state
|
|
180
|
-
|
|
199
|
+
morph-spec state get $ARGUMENTS
|
|
181
200
|
|
|
182
201
|
# Advance to next phase
|
|
183
|
-
|
|
202
|
+
morph-spec phase advance $ARGUMENTS
|
|
184
203
|
```
|
|
185
204
|
|
|
186
205
|
### Step 6: Post-implementation review
|
|
@@ -212,7 +231,8 @@ Next: {next-task-id} — {next-task-title}
|
|
|
212
231
|
|
|
213
232
|
- Using `state set phase` instead of `phase advance` — phase advance validates eligibility first
|
|
214
233
|
- Skipping `task start` before implementing — the task-tracking guard will warn
|
|
215
|
-
- Using `--skip-validation` without user authorization
|
|
234
|
+
- Using `--skip-validation` without user authorization or without `--reason`
|
|
235
|
+
- Exhausting `--skip-validation` budget on trivial tasks — reserve for genuine emergencies
|
|
216
236
|
- Implementing without reading spec.md and contracts first
|
|
217
237
|
- Writing code before `phase advance` to implement — the hook will block writes
|
|
218
238
|
- Skipping checkpoints — they catch integration issues early
|
|
@@ -26,9 +26,9 @@ These checks verify that the morph-spec workflow is complete for the feature bei
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
# Verify implementation is complete
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
morph-spec state get {feature}
|
|
30
|
+
morph-spec approval-status {feature}
|
|
31
|
+
morph-spec validate-feature {feature}
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
| Check | Command | Pass Criteria |
|
|
@@ -15,10 +15,10 @@ Guide a feature through the full planning pipeline (proposal through tasks) with
|
|
|
15
15
|
Check if the feature already has state:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
18
|
+
morph-spec state get {feature-name}
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
- **Exists:** Read the current phase and resume from where it stopped (skip completed phases)
|
|
21
|
+
- **Exists:** Read the current phase and resume from where it stopped (skip completed phases). Create pipeline master tasks (Step 6) and mark already-completed phases as `completed`.
|
|
22
22
|
- **Does not exist:** Start from scratch (PHASE 0)
|
|
23
23
|
|
|
24
24
|
---
|
|
@@ -40,7 +40,7 @@ Read `framework/agents.json` (or `.morph/framework/agents.json` in client projec
|
|
|
40
40
|
|
|
41
41
|
Register each selected agent:
|
|
42
42
|
```bash
|
|
43
|
-
|
|
43
|
+
morph-spec state add-agent {feature-name} {agent-id}
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
### Step 3: Determine if UI/UX phase is needed
|
|
@@ -70,11 +70,40 @@ Fill every section of the template. In particular:
|
|
|
70
70
|
### Step 5: Register state
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
morph-spec state init {feature-name}
|
|
74
|
+
morph-spec state set {feature-name} status draft
|
|
75
|
+
morph-spec state mark-output {feature-name} proposal
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
### Step 6: Create pipeline master tasks
|
|
79
|
+
|
|
80
|
+
> **MANDATORY** — Create one native task per pipeline phase for progress visibility.
|
|
81
|
+
> These are high-level tasks — one per phase, not per workflow step.
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
TaskCreate: "Phase 0: Proposal" → description: "Define feature scope and approach" → activeForm: "Proposal"
|
|
85
|
+
TaskCreate: "Phase 1: Setup" → description: "Load context, detect agents, confirm stack" → activeForm: "Setup"
|
|
86
|
+
TaskCreate: "Phase 2: Design" → description: "Schema analysis, spec, contracts, decisions" → activeForm: "Design"
|
|
87
|
+
TaskCreate: "Phase 3: Clarify" → description: "Resolve ambiguities and edge cases" → activeForm: "Clarify"
|
|
88
|
+
TaskCreate: "Phase 4: Plan" → description: "Implementation plan with TDD and file paths" → activeForm: "Plan"
|
|
89
|
+
TaskCreate: "Phase 5: Tasks" → description: "Break spec into T001-T00N with dependencies" → activeForm: "Tasks"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If `ui-designer` is among the activated agents, also create:
|
|
93
|
+
```
|
|
94
|
+
TaskCreate: "Phase 1.5: UI/UX" → description: "Design system, mockups, components, flows" → activeForm: "UI/UX"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Wire dependencies (addBlockedBy) matching the phase sequence:
|
|
98
|
+
- Setup ← Proposal
|
|
99
|
+
- UI/UX (if created) ← Setup
|
|
100
|
+
- Design ← UI/UX (or Setup if no UI/UX)
|
|
101
|
+
- Clarify ← Design
|
|
102
|
+
- Plan ← Clarify
|
|
103
|
+
- Tasks ← Plan
|
|
104
|
+
|
|
105
|
+
Mark "Phase 0: Proposal" as `in_progress` immediately.
|
|
106
|
+
|
|
78
107
|
### MANDATORY PAUSE
|
|
79
108
|
|
|
80
109
|
Use `AskUserQuestion` to present the approval gate with these elements:
|
|
@@ -88,8 +117,8 @@ Options: Approve proposal / Request changes / Reject
|
|
|
88
117
|
|
|
89
118
|
After approval:
|
|
90
119
|
```bash
|
|
91
|
-
|
|
92
|
-
|
|
120
|
+
morph-spec approve {feature-name} proposal
|
|
121
|
+
morph-spec phase advance {feature-name}
|
|
93
122
|
```
|
|
94
123
|
|
|
95
124
|
---
|
|
@@ -100,6 +129,8 @@ Invoke the `morph-phase-setup` skill.
|
|
|
100
129
|
|
|
101
130
|
Summary: load project context, confirm stack, list active agents, update state.
|
|
102
131
|
|
|
132
|
+
> **Task lifecycle:** `TaskUpdate` the "Phase 0: Proposal" task → `completed`. `TaskUpdate` the "Phase 1: Setup" task → `in_progress`.
|
|
133
|
+
|
|
103
134
|
**No pause here.** Continue automatically to the next phase.
|
|
104
135
|
|
|
105
136
|
---
|
|
@@ -110,16 +141,20 @@ Check if `ui-designer` is in `activeAgents`:
|
|
|
110
141
|
- **Yes:** Invoke the `morph-phase-uiux` skill. **MANDATORY PAUSE** after generating UI deliverables.
|
|
111
142
|
- **No:** Skip to PHASE 2.
|
|
112
143
|
|
|
144
|
+
> **Task lifecycle:** `TaskUpdate` the "Phase 1: Setup" task → `completed`. `TaskUpdate` the "Phase 1.5: UI/UX" task → `in_progress` (if UI/UX), or the "Phase 2: Design" task → `in_progress` (if skipping UI/UX).
|
|
145
|
+
|
|
113
146
|
After approval:
|
|
114
147
|
```bash
|
|
115
|
-
|
|
116
|
-
|
|
148
|
+
morph-spec approve {feature-name} uiux
|
|
149
|
+
morph-spec phase advance {feature-name}
|
|
117
150
|
```
|
|
118
151
|
|
|
119
152
|
---
|
|
120
153
|
|
|
121
154
|
## 5. PHASE 2: DESIGN
|
|
122
155
|
|
|
156
|
+
> **Task lifecycle:** `TaskUpdate` the completing phase task (UI/UX or Setup) → `completed`. `TaskUpdate` the "Phase 2: Design" task → `in_progress`.
|
|
157
|
+
|
|
123
158
|
Invoke the `morph-phase-design` skill.
|
|
124
159
|
|
|
125
160
|
Summary: generate spec.md, contracts.cs (or contracts-vsa.cs for VSA), decisions.md with ADRs.
|
|
@@ -130,14 +165,16 @@ Present: spec, contracts, decisions, effort estimate. Use `AskUserQuestion` with
|
|
|
130
165
|
|
|
131
166
|
After approval:
|
|
132
167
|
```bash
|
|
133
|
-
|
|
134
|
-
|
|
168
|
+
morph-spec approve {feature-name} design
|
|
169
|
+
morph-spec phase advance {feature-name}
|
|
135
170
|
```
|
|
136
171
|
|
|
137
172
|
---
|
|
138
173
|
|
|
139
174
|
## 6. PHASE 3: CLARIFY (interactive)
|
|
140
175
|
|
|
176
|
+
> **Task lifecycle:** `TaskUpdate` the "Phase 2: Design" task → `completed`. `TaskUpdate` the "Phase 3: Clarify" task → `in_progress`.
|
|
177
|
+
|
|
141
178
|
Invoke the `morph-phase-clarify` skill.
|
|
142
179
|
|
|
143
180
|
Summary: identify ambiguities in spec.md, generate 3-7 targeted questions (building on the questions seeded in the proposal), wait for user answers, update spec with clarifications and edge cases.
|
|
@@ -148,6 +185,8 @@ Summary: identify ambiguities in spec.md, generate 3-7 targeted questions (build
|
|
|
148
185
|
|
|
149
186
|
## 7. PHASE 4: PLAN
|
|
150
187
|
|
|
188
|
+
> **Task lifecycle:** `TaskUpdate` the "Phase 3: Clarify" task → `completed`. `TaskUpdate` the "Phase 4: Plan" task → `in_progress`.
|
|
189
|
+
|
|
151
190
|
Invoke the `morph-phase-plan` skill.
|
|
152
191
|
|
|
153
192
|
Summary: generate a detailed implementation plan with exact file paths, TDD structure, and context-aware execution strategy.
|
|
@@ -158,14 +197,16 @@ Present: implementation plan with recommended strategy. Use `AskUserQuestion` wi
|
|
|
158
197
|
|
|
159
198
|
After approval:
|
|
160
199
|
```bash
|
|
161
|
-
|
|
162
|
-
|
|
200
|
+
morph-spec approve {feature-name} plan
|
|
201
|
+
morph-spec phase advance {feature-name}
|
|
163
202
|
```
|
|
164
203
|
|
|
165
204
|
---
|
|
166
205
|
|
|
167
206
|
## 8. PHASE 5: TASKS
|
|
168
207
|
|
|
208
|
+
> **Task lifecycle:** `TaskUpdate` the "Phase 4: Plan" task → `completed`. `TaskUpdate` the "Phase 5: Tasks" task → `in_progress`.
|
|
209
|
+
|
|
169
210
|
Invoke the `morph-phase-tasks` skill.
|
|
170
211
|
|
|
171
212
|
Summary: break spec into tasks T001-TXXX with dependencies, checkpoints, estimates.
|
|
@@ -176,14 +217,16 @@ Present: task breakdown, execution order, total estimate. Use `AskUserQuestion`
|
|
|
176
217
|
|
|
177
218
|
After approval:
|
|
178
219
|
```bash
|
|
179
|
-
|
|
180
|
-
|
|
220
|
+
morph-spec approve {feature-name} tasks
|
|
221
|
+
morph-spec phase advance {feature-name}
|
|
181
222
|
```
|
|
182
223
|
|
|
183
224
|
---
|
|
184
225
|
|
|
185
226
|
## 9. Planning Complete
|
|
186
227
|
|
|
228
|
+
> **Task lifecycle:** `TaskUpdate` the "Phase 5: Tasks" task → `completed`.
|
|
229
|
+
|
|
187
230
|
After task approval:
|
|
188
231
|
|
|
189
232
|
```
|
|
@@ -13,7 +13,7 @@ Show the current MORPH project status and features in development.
|
|
|
13
13
|
**ALWAYS** use the state-manager CLI to get status:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
morph-spec state list
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
This command automatically shows:
|
|
@@ -35,7 +35,7 @@ This command automatically shows:
|
|
|
35
35
|
To get detailed JSON for a feature:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
|
|
38
|
+
morph-spec state get {feature-name}
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
### 3. Archived Features
|
|
@@ -51,7 +51,7 @@ Check `.morph/specs/` for consolidated specs.
|
|
|
51
51
|
|
|
52
52
|
## Output
|
|
53
53
|
|
|
54
|
-
The `
|
|
54
|
+
The `morph-spec state list` command automatically generates a formatted dashboard:
|
|
55
55
|
|
|
56
56
|
```
|
|
57
57
|
╔════════════════════════════════════════════════════════════════╗
|
|
@@ -72,7 +72,7 @@ site:learn.microsoft.com/azure {error}
|
|
|
72
72
|
**WebSearch usage example:**
|
|
73
73
|
|
|
74
74
|
If the user asks about a SignalR error:
|
|
75
|
-
1. First: `
|
|
75
|
+
1. First: `morph-spec troubleshoot SignalR connection`
|
|
76
76
|
2. If not found: WebSearch with `site:github.com/dotnet/aspnetcore SignalR connection closed`
|
|
77
77
|
3. Return formatted relevant links
|
|
78
78
|
|
|
@@ -27,7 +27,7 @@ import { readStdin } from '../../shared/stdin-reader.js';
|
|
|
27
27
|
import { stateExists, getFeature, getFeaturePhase } from '../../shared/state-reader.js';
|
|
28
28
|
import { pass, injectContext } from '../../shared/hook-response.js';
|
|
29
29
|
import { logHookActivity } from '../../shared/activity-logger.js';
|
|
30
|
-
import { extractValidationDispatch, formatValidatorInstruction, getToolOutput, parseTaskDoneCommand, parsePhaseAdvanceCommand } from '../../shared/dispatch-helpers.js';
|
|
30
|
+
import { extractValidationDispatch, formatValidatorInstruction, getToolOutput, parseTaskDoneCommand, parsePhaseAdvanceCommand, parseDispatchAgentsCommand } from '../../shared/dispatch-helpers.js';
|
|
31
31
|
|
|
32
32
|
try {
|
|
33
33
|
if (!stateExists()) pass();
|
|
@@ -73,8 +73,21 @@ async function dispatch(command, payload) {
|
|
|
73
73
|
const validatorText = await buildValidatorDispatchContext(featureName, payload);
|
|
74
74
|
if (validatorText) {
|
|
75
75
|
if (skipValidation) {
|
|
76
|
+
// Include budget info when available
|
|
77
|
+
let budgetInfo = '';
|
|
78
|
+
try {
|
|
79
|
+
const feature = getFeature(featureName);
|
|
80
|
+
if (feature) {
|
|
81
|
+
const total = feature.tasks?.total || 0;
|
|
82
|
+
const budget = total === 0 ? 1 : Math.max(1, Math.min(5, Math.ceil(total * 0.2)));
|
|
83
|
+
const used = (feature.skipValidationLog || []).length;
|
|
84
|
+
budgetInfo = ` (budget: ${used}/${budget})`;
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
// Non-blocking
|
|
88
|
+
}
|
|
76
89
|
contextParts.push(
|
|
77
|
-
|
|
90
|
+
`⏩ DEFERRED TO CHECKPOINT — validators skipped on this task${budgetInfo} but MUST run at next checkpoint:\n\n` +
|
|
78
91
|
validatorText
|
|
79
92
|
);
|
|
80
93
|
dispatchResult = 'task_done_deferred_validators';
|
|
@@ -107,6 +120,23 @@ async function dispatch(command, payload) {
|
|
|
107
120
|
const validatorText = await buildValidatorDispatchContext(featureName, payload);
|
|
108
121
|
if (validatorText) contextParts.push(validatorText);
|
|
109
122
|
|
|
123
|
+
// Mandatory dispatch instruction when advancing to implement phase
|
|
124
|
+
try {
|
|
125
|
+
const advancedPhase = getFeaturePhase(featureName);
|
|
126
|
+
if (advancedPhase === 'implement') {
|
|
127
|
+
contextParts.push(
|
|
128
|
+
'🔧 MANDATORY AGENT DISPATCH\n' +
|
|
129
|
+
'════════════════════════════════════════\n' +
|
|
130
|
+
`Run this command BEFORE starting any task:\n\n` +
|
|
131
|
+
` morph-spec dispatch-agents ${featureName} implement\n\n` +
|
|
132
|
+
`Task start will be BLOCKED until dispatch is recorded.\n` +
|
|
133
|
+
`Use the dispatch output to determine execution mode (single/subagents/agent-teams).`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
} catch {
|
|
137
|
+
// Non-blocking
|
|
138
|
+
}
|
|
139
|
+
|
|
110
140
|
logHookActivity('phase-dispatch', 'PostToolUse',
|
|
111
141
|
validatorText ? 'phase_advance_with_validators' : 'phase_chain');
|
|
112
142
|
|
|
@@ -116,6 +146,21 @@ async function dispatch(command, payload) {
|
|
|
116
146
|
pass();
|
|
117
147
|
}
|
|
118
148
|
|
|
149
|
+
// morph-spec dispatch-agents <feature> <phase>
|
|
150
|
+
const dispatchParsed = parseDispatchAgentsCommand(command);
|
|
151
|
+
if (dispatchParsed) {
|
|
152
|
+
const { featureName: dispFeature, phase: dispPhase } = dispatchParsed;
|
|
153
|
+
if (dispPhase === 'implement') {
|
|
154
|
+
injectContext(
|
|
155
|
+
`✓ Agent dispatch recorded for '${dispFeature}' (implement phase).\n` +
|
|
156
|
+
`You may now start tasks with: morph-spec task start ${dispFeature} <taskId>\n` +
|
|
157
|
+
`Use the dispatch config above to assign tasks to the correct typed agents.`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
logHookActivity('phase-dispatch', 'PostToolUse', 'dispatch_agents_confirmed');
|
|
161
|
+
pass();
|
|
162
|
+
}
|
|
163
|
+
|
|
119
164
|
// morph-spec approve <feature> <gate>
|
|
120
165
|
const approveMatch = command.match(/morph-spec\s+approve\s+(\S+)\s+(\S+)/);
|
|
121
166
|
if (approveMatch) {
|
|
@@ -50,8 +50,8 @@ try {
|
|
|
50
50
|
approve(
|
|
51
51
|
`[morph-spec] WARNING: No active task tracking detected during implement phase.\n` +
|
|
52
52
|
`Before writing code, start a task:\n` +
|
|
53
|
-
`
|
|
54
|
-
`
|
|
53
|
+
` morph-spec task next ${name} # see what's next\n` +
|
|
54
|
+
` morph-spec task start ${name} <id> # mark it in progress\n` +
|
|
55
55
|
`Task tracking ensures validators run, checkpoints fire, and progress is recorded.`
|
|
56
56
|
);
|
|
57
57
|
} catch {
|
|
@@ -125,10 +125,11 @@ try {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// Task tracking guidance for work phases
|
|
128
|
-
if (['design', 'tasks', 'implement'].includes(phase)) {
|
|
128
|
+
if (['proposal', 'setup', 'uiux', 'design', 'clarify', 'plan', 'tasks', 'implement'].includes(phase)) {
|
|
129
129
|
lines.push('');
|
|
130
|
-
lines.push('
|
|
131
|
-
lines.push('
|
|
130
|
+
lines.push('⚠️ MANDATORY: Create session tasks (TaskCreate) BEFORE starting phase work.');
|
|
131
|
+
lines.push(' Analyze the phase workflow and create tasks reflecting your planned actions.');
|
|
132
|
+
lines.push(' Mark each in_progress → completed as you go. See phase skill for guidance.');
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
// Trust level visibility — warn when low trust may block approval gates
|
|
@@ -140,7 +141,7 @@ try {
|
|
|
140
141
|
if (trustLevel !== 'high' && trustLevel !== 'maximum') {
|
|
141
142
|
lines.push('');
|
|
142
143
|
lines.push(`⚠ Trust level: ${trustLevel} — approval gates require manual approval`);
|
|
143
|
-
lines.push(` To auto-approve:
|
|
144
|
+
lines.push(` To auto-approve: morph-spec trust set ${name} high`);
|
|
144
145
|
}
|
|
145
146
|
if (!workflow && config?.workflowDetection?.confidence === 0) {
|
|
146
147
|
lines.push('');
|
|
@@ -51,7 +51,7 @@ try {
|
|
|
51
51
|
|
|
52
52
|
try {
|
|
53
53
|
output = execSync(
|
|
54
|
-
`
|
|
54
|
+
`morph-spec validate-feature "${featureName}" --phase implement --quiet`,
|
|
55
55
|
{
|
|
56
56
|
cwd: process.cwd(),
|
|
57
57
|
encoding: 'utf-8',
|
|
@@ -71,9 +71,9 @@ try {
|
|
|
71
71
|
const feedback = [
|
|
72
72
|
'MORPH-SPEC validation found issues — please fix before going idle:',
|
|
73
73
|
'',
|
|
74
|
-
output.trim() || 'Run `
|
|
74
|
+
output.trim() || 'Run `morph-spec validate-feature to see details.',
|
|
75
75
|
'',
|
|
76
|
-
`Run:
|
|
76
|
+
`Run: morph-spec validate-feature ${featureName} --phase implement`,
|
|
77
77
|
].join('\n');
|
|
78
78
|
|
|
79
79
|
// Claude Code reads additionalContext from stdout for exit code 2
|
|
@@ -72,8 +72,8 @@ try {
|
|
|
72
72
|
context.push(
|
|
73
73
|
`[morph-spec] REMINDER: No task is currently in_progress for '${name}'.` +
|
|
74
74
|
` Start a task before coding:\n` +
|
|
75
|
-
`
|
|
76
|
-
`
|
|
75
|
+
` morph-spec task next ${name} # see what's next\n` +
|
|
76
|
+
` morph-spec task start ${name} <id> # mark it in progress`
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -10,7 +10,7 @@ if git diff --cached --name-only | grep -q 'agents\.json$'; then
|
|
|
10
10
|
echo "Detected changes to agents.json"
|
|
11
11
|
|
|
12
12
|
# Run validator
|
|
13
|
-
if !
|
|
13
|
+
if ! morph-spec validate-agents-skills; then
|
|
14
14
|
echo ""
|
|
15
15
|
echo "❌ COMMIT BLOCKED: agents.json validation failed"
|
|
16
16
|
echo " Fix errors above before committing"
|
|
@@ -98,6 +98,20 @@ export function parsePhaseAdvanceCommand(command) {
|
|
|
98
98
|
return { featureName: match[1] };
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Parse `morph-spec dispatch-agents <feature> <phase>` from a bash command string.
|
|
103
|
+
* Returns { featureName, phase } or null if the command doesn't match.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} command
|
|
106
|
+
* @returns {{ featureName: string, phase: string } | null}
|
|
107
|
+
*/
|
|
108
|
+
export function parseDispatchAgentsCommand(command) {
|
|
109
|
+
if (!command || typeof command !== 'string') return null;
|
|
110
|
+
const match = command.match(/morph-spec\s+dispatch-agents\s+(\S+)\s+(\S+)/);
|
|
111
|
+
if (!match) return null;
|
|
112
|
+
return { featureName: match[1], phase: match[2] };
|
|
113
|
+
}
|
|
114
|
+
|
|
101
115
|
/**
|
|
102
116
|
* Extract the tool result string from a PostToolUse hook payload.
|
|
103
117
|
* Handles multiple possible formats.
|
|
@@ -142,7 +142,9 @@ export function getFeaturePhase(featureName, projectPath) {
|
|
|
142
142
|
*/
|
|
143
143
|
export function isGateApproved(featureName, gate, projectPath) {
|
|
144
144
|
const feature = getFeature(featureName, projectPath);
|
|
145
|
-
|
|
145
|
+
// Support both field names: 'approvals' (v5 state) and 'approvalGates' (legacy)
|
|
146
|
+
const gates = feature?.approvals || feature?.approvalGates;
|
|
147
|
+
return gates?.[gate]?.approved === true;
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
/**
|
|
@@ -153,9 +155,11 @@ export function isGateApproved(featureName, gate, projectPath) {
|
|
|
153
155
|
*/
|
|
154
156
|
export function getPendingGates(featureName, projectPath) {
|
|
155
157
|
const feature = getFeature(featureName, projectPath);
|
|
156
|
-
|
|
158
|
+
// Support both field names: 'approvals' (v5 state) and 'approvalGates' (legacy)
|
|
159
|
+
const gates = feature?.approvals || feature?.approvalGates;
|
|
160
|
+
if (!gates) return [];
|
|
157
161
|
|
|
158
|
-
return Object.entries(
|
|
162
|
+
return Object.entries(gates)
|
|
159
163
|
.filter(([, gate]) => !gate.approved)
|
|
160
164
|
.map(([name]) => name);
|
|
161
165
|
}
|