@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
|
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 4 (Tasks). Breaks approved spec into bottom-up ord
|
|
|
4
4
|
argument-hint: "[feature-name]"
|
|
5
5
|
user-invocable: false
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
7
|
-
cliVersion: "4.
|
|
7
|
+
cliVersion: "4.11.1"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MORPH Tasks — Phase 4
|
|
@@ -33,8 +33,8 @@ Break the approved specification into executable tasks, define execution order,
|
|
|
33
33
|
| Count similar existing patterns | **Glob** `**/Services/**/*.cs` | — |
|
|
34
34
|
| Look up implementation patterns | **Context7 MCP** `query_docs()` | **WebSearch** |
|
|
35
35
|
| Create GitHub issues from tasks | **GitHub MCP** `create_issue()` | **Bash** `gh issue create ...` |
|
|
36
|
-
| Render tasks template | **Bash** `
|
|
37
|
-
| Update state with task count | **Bash** `
|
|
36
|
+
| Render tasks template | **Bash** `morph-spec template render docs/tasks ...` | — |
|
|
37
|
+
| Update state with task count | **Bash** `morph-spec state set ... tasks.total N` | — |
|
|
38
38
|
|
|
39
39
|
**Phase MCPs:** Context7 (estimate complexity), GitHub (create issues).
|
|
40
40
|
|
|
@@ -54,7 +54,7 @@ Break the approved specification into executable tasks, define execution order,
|
|
|
54
54
|
### 0. Ensure tasks phase
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
|
|
57
|
+
morph-spec state get $ARGUMENTS
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Check the `"phase"` field:
|
|
@@ -62,8 +62,8 @@ Check the `"phase"` field:
|
|
|
62
62
|
**If `"phase": "tasks"`** → correct phase, proceed.
|
|
63
63
|
|
|
64
64
|
**If `"phase": "clarify"`** → run in sequence:
|
|
65
|
-
1. `
|
|
66
|
-
2. `
|
|
65
|
+
1. `morph-spec state mark-output $ARGUMENTS clarifications`
|
|
66
|
+
2. `morph-spec phase advance $ARGUMENTS` (→ tasks)
|
|
67
67
|
|
|
68
68
|
**Any other value** → STOP — inconsistent state, report to user.
|
|
69
69
|
|
|
@@ -71,6 +71,14 @@ Check the `"phase"` field:
|
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
74
|
+
## MANDATORY: Session Tasks
|
|
75
|
+
|
|
76
|
+
> **BEFORE reading any files**, analyze the task breakdown workflow and create session tasks.
|
|
77
|
+
>
|
|
78
|
+
> **Rules:** Minimum 2 tasks, typically 3-4. Mark `in_progress` before starting, `completed` after.
|
|
79
|
+
>
|
|
80
|
+
> **Typical tasks:** spec analysis and task definition, tasks.md generation, state update and approval
|
|
81
|
+
|
|
74
82
|
### 1. Read all prerequisites in PARALLEL
|
|
75
83
|
|
|
76
84
|
```
|
|
@@ -82,25 +90,9 @@ Read: .morph/features/{feature}/1-design/spec.md
|
|
|
82
90
|
+ Read: .morph/config/config.json (→ architecture.style)
|
|
83
91
|
```
|
|
84
92
|
|
|
85
|
-
### 2. Create session tasks for visibility
|
|
86
|
-
|
|
87
|
-
After detecting `activeAgents` from state, create tasks with agent context:
|
|
88
|
-
|
|
89
|
-
```
|
|
90
|
-
TaskCreate: "Analyze spec and define tasks"
|
|
91
|
-
→ description: "Active agents: {activeAgents.join(', ')}"
|
|
92
|
-
→ activeForm: "Analyzing spec"
|
|
93
|
-
TaskCreate: "Generate tasks.md"
|
|
94
|
-
→ description: "Architecture: {config.architecture.style}"
|
|
95
|
-
→ activeForm: "Generating tasks.md"
|
|
96
|
-
TaskCreate: "Phase advance" → activeForm: "Awaiting tasks approval + advancing phase"
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
> **Note:** Individual T001-T00N tasks are created as native tasks during the implementation phase (`phase-implement`). Here we only keep the 3 high-level tasks for this planning session.
|
|
100
|
-
|
|
101
93
|
---
|
|
102
94
|
|
|
103
|
-
###
|
|
95
|
+
### 2. Entry checkpoint — verify prerequisites
|
|
104
96
|
|
|
105
97
|
Before starting the breakdown:
|
|
106
98
|
|
|
@@ -114,8 +106,8 @@ Before starting the breakdown:
|
|
|
114
106
|
If any checkbox is NOT checked → return to corresponding phase and resolve.
|
|
115
107
|
|
|
116
108
|
```bash
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
morph-spec state get $ARGUMENTS
|
|
110
|
+
morph-spec approval-status $ARGUMENTS
|
|
119
111
|
```
|
|
120
112
|
|
|
121
113
|
---
|
|
@@ -245,8 +237,8 @@ If there are Azure resources, add Bicep and migration tasks.
|
|
|
245
237
|
### Step 8: Update State
|
|
246
238
|
|
|
247
239
|
```bash
|
|
248
|
-
|
|
249
|
-
|
|
240
|
+
morph-spec state set $ARGUMENTS tasks.total {N}
|
|
241
|
+
morph-spec state mark-output $ARGUMENTS tasks
|
|
250
242
|
```
|
|
251
243
|
|
|
252
244
|
## Outputs
|
|
@@ -273,8 +265,8 @@ Use `AskUserQuestion` to capture explicit approval before advancing. This gate p
|
|
|
273
265
|
|
|
274
266
|
- **"Approve and implement"** →
|
|
275
267
|
```bash
|
|
276
|
-
|
|
277
|
-
|
|
268
|
+
morph-spec approve $ARGUMENTS tasks
|
|
269
|
+
morph-spec phase advance $ARGUMENTS
|
|
278
270
|
```
|
|
279
271
|
- **"I have feedback" or "Other"** → apply the feedback and repeat this PAUSE
|
|
280
272
|
|
|
@@ -4,7 +4,7 @@ description: MORPH-SPEC Phase 1.5 (UI/UX). Creates design-system.md, mockups.md,
|
|
|
4
4
|
argument-hint: "[feature-name]"
|
|
5
5
|
user-invocable: false
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
7
|
-
cliVersion: "4.
|
|
7
|
+
cliVersion: "4.11.1"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MORPH UI/UX Design - Phase 1.5
|
|
@@ -36,9 +36,9 @@ Conditional phase for features with front-end. Collects UI/UX requirements, gene
|
|
|
36
36
|
| Inspect page structure | **Playwright MCP** `browser_snapshot()` | **WebFetch** + manual parse |
|
|
37
37
|
| Test responsive layout | **Playwright MCP** `browser_resize()` + `browser_take_screenshot()` | Manual testing |
|
|
38
38
|
| External design references | **WebSearch** + **WebFetch** | — |
|
|
39
|
-
| Render UI templates | **Bash** `
|
|
40
|
-
| Generate design system from existing CSS | **Bash** `
|
|
41
|
-
| Update state | **Bash** `
|
|
39
|
+
| Render UI templates | **Bash** `morph-spec template render docs/ui-mockups ...` | — |
|
|
40
|
+
| Generate design system from existing CSS | **Bash** `morph-spec generate design-system --scan` | — |
|
|
41
|
+
| Update state | **Bash** `morph-spec state mark-output ...` | — |
|
|
42
42
|
|
|
43
43
|
**MCPs for this phase:** Playwright (preview, inspection, responsiveness), Context7 (component docs).
|
|
44
44
|
|
|
@@ -54,7 +54,7 @@ Conditional phase for features with front-end. Collects UI/UX requirements, gene
|
|
|
54
54
|
### Step 0: Ensure uiux phase
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
|
|
57
|
+
morph-spec state get $ARGUMENTS
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Check the `"phase"` field in the output:
|
|
@@ -62,7 +62,7 @@ Check the `"phase"` field in the output:
|
|
|
62
62
|
**If `"phase": "uiux"`** → correct phase, proceed.
|
|
63
63
|
|
|
64
64
|
**If `"phase": "setup"`** → execute:
|
|
65
|
-
1. `
|
|
65
|
+
1. `morph-spec phase advance $ARGUMENTS` (→ uiux)
|
|
66
66
|
|
|
67
67
|
**Any other value** → do not proceed — inconsistent state, report to user.
|
|
68
68
|
|
|
@@ -129,12 +129,20 @@ Print: `✓ Design system generated from [N] tokens — .morph/context/design-sy
|
|
|
129
129
|
|
|
130
130
|
> **Design system is mandatory** for UI features. The implementation gate (Phase 5) will block if no design system exists.
|
|
131
131
|
|
|
132
|
+
## MANDATORY: Session Tasks
|
|
133
|
+
|
|
134
|
+
> **BEFORE starting UI/UX work**, analyze the workflow below and create session tasks.
|
|
135
|
+
>
|
|
136
|
+
> **Rules:** Minimum 3 tasks, typically 5-7. Mark `in_progress` before starting, `completed` after.
|
|
137
|
+
>
|
|
138
|
+
> **Typical tasks:** design system check, user input collection, UI library selection, visual mockup, deliverable generation, accessibility validation, approval
|
|
139
|
+
|
|
132
140
|
### Step 1: Detect If Phase Is Needed
|
|
133
141
|
|
|
134
142
|
Check if active agents include `ui-designer`:
|
|
135
143
|
|
|
136
144
|
```bash
|
|
137
|
-
|
|
145
|
+
morph-spec state get $ARGUMENTS
|
|
138
146
|
```
|
|
139
147
|
|
|
140
148
|
If `ui-designer` is NOT in `activeAgents`, skip this phase and continue to Phase 2 (Design).
|
|
@@ -290,7 +298,7 @@ mcp__plugin_playwright_playwright__browser_take_screenshot({}) → save as .morp
|
|
|
290
298
|
|
|
291
299
|
Create the following files in `.morph/features/$ARGUMENTS/`:
|
|
292
300
|
|
|
293
|
-
> **Use templates:** Use `
|
|
301
|
+
> **Use templates:** Use `morph-spec template render` to generate files from templates in `.morph/framework/templates/docs/`. Available templates: `ui-design-system`, `ui-mockups`, `ui-components`, `ui-flows`.
|
|
294
302
|
|
|
295
303
|
#### 4.1. `ui-design-system.md`
|
|
296
304
|
|
|
@@ -367,17 +375,17 @@ Document in UI files:
|
|
|
367
375
|
### Step 6: Update State
|
|
368
376
|
|
|
369
377
|
```bash
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
378
|
+
morph-spec state mark-output $ARGUMENTS ui-design-system
|
|
379
|
+
morph-spec state mark-output $ARGUMENTS ui-mockups
|
|
380
|
+
morph-spec state mark-output $ARGUMENTS ui-components
|
|
381
|
+
morph-spec state mark-output $ARGUMENTS ui-flows
|
|
374
382
|
```
|
|
375
383
|
|
|
376
384
|
> **Format note:** The `mark-output` commands accept BOTH kebab-case (`ui-design-system`)
|
|
377
385
|
> AND camelCase (`uiDesignSystem`). Both formats work equally! Use whichever is more
|
|
378
386
|
> comfortable for you. Examples:
|
|
379
|
-
> - `
|
|
380
|
-
> - `
|
|
387
|
+
> - `morph-spec state mark-output my-feature uiDesignSystem`
|
|
388
|
+
> - `morph-spec state mark-output my-feature ui-design-system`
|
|
381
389
|
|
|
382
390
|
## Generated Outputs
|
|
383
391
|
|
|
@@ -421,8 +429,8 @@ Use `AskUserQuestion` to capture explicit approval before advancing:
|
|
|
421
429
|
|
|
422
430
|
- **"Approve UI/UX"** →
|
|
423
431
|
```bash
|
|
424
|
-
|
|
425
|
-
|
|
432
|
+
morph-spec approve $ARGUMENTS uiux
|
|
433
|
+
morph-spec phase advance $ARGUMENTS
|
|
426
434
|
```
|
|
427
435
|
- **"I have feedback" or "Other"** → apply the received feedback and repeat this PAUSE
|
|
428
436
|
|
|
@@ -4,7 +4,7 @@ description: Guided workflow for mid-implementation scope escalation — analyze
|
|
|
4
4
|
user-invocable: true
|
|
5
5
|
argument-hint: "[feature-name]"
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
7
|
-
cliVersion: "4.
|
|
7
|
+
cliVersion: "4.11.1"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Scope Escalation Workflow
|
|
@@ -57,7 +57,7 @@ Use `AskUserQuestion` to gather the details:
|
|
|
57
57
|
Run dry-run analysis:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
|
|
60
|
+
morph-spec scope escalate <feature> --task <id> --reason "<reason>" --dry-run
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
Read the recommendation output. Additionally:
|
|
@@ -116,17 +116,17 @@ Based on approved action:
|
|
|
116
116
|
|
|
117
117
|
**For expansion (low impact):**
|
|
118
118
|
```bash
|
|
119
|
-
|
|
119
|
+
morph-spec task expand <feature> <task-id> --into "T017a: <title>" "T017b: <title>" ...
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
**For regression (medium/high impact):**
|
|
123
123
|
```bash
|
|
124
|
-
|
|
124
|
+
morph-spec scope escalate <feature> --task <id> --reason "<reason>"
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
Or with target override:
|
|
128
128
|
```bash
|
|
129
|
-
|
|
129
|
+
morph-spec scope escalate <feature> --task <id> --reason "<reason>" --target design
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
### Step 6: GUIDE Next Steps
|
|
@@ -371,7 +371,7 @@ Keywords like: `bicep`, `azure`, `deploy`, `docker`, `kubernetes`, `infrastructu
|
|
|
371
371
|
|
|
372
372
|
```bash
|
|
373
373
|
# When creating a feature
|
|
374
|
-
|
|
374
|
+
morph-spec feature create user-pagination \
|
|
375
375
|
--request "add pagination to users table"
|
|
376
376
|
|
|
377
377
|
# System automatically:
|
|
@@ -385,7 +385,7 @@ npx morph-spec feature create user-pagination \
|
|
|
385
385
|
|
|
386
386
|
```bash
|
|
387
387
|
# Analyze request without creating feature
|
|
388
|
-
|
|
388
|
+
morph-spec detect-workflow "implement complete authentication system"
|
|
389
389
|
|
|
390
390
|
# Output:
|
|
391
391
|
Detected Workflow: full-morph (92% confidence)
|
|
@@ -407,7 +407,7 @@ Alternative Workflows:
|
|
|
407
407
|
### JSON Output (for automation)
|
|
408
408
|
|
|
409
409
|
```bash
|
|
410
|
-
|
|
410
|
+
morph-spec detect-workflow "add pagination" --json
|
|
411
411
|
|
|
412
412
|
# Output:
|
|
413
413
|
{
|
|
@@ -435,17 +435,17 @@ npx morph-spec detect-workflow "add pagination" --json
|
|
|
435
435
|
|
|
436
436
|
```bash
|
|
437
437
|
# Force specific workflow
|
|
438
|
-
|
|
438
|
+
morph-spec state set user-auth workflow full-morph
|
|
439
439
|
|
|
440
440
|
# Re-detect after request changes
|
|
441
|
-
|
|
441
|
+
morph-spec state detect-workflow user-auth \
|
|
442
442
|
"implement basic login only (no OAuth)"
|
|
443
443
|
```
|
|
444
444
|
|
|
445
445
|
### View Current Workflow
|
|
446
446
|
|
|
447
447
|
```bash
|
|
448
|
-
|
|
448
|
+
morph-spec state get user-auth workflow
|
|
449
449
|
|
|
450
450
|
# Output:
|
|
451
451
|
Workflow: standard
|
|
@@ -594,7 +594,7 @@ Create `framework/workflows/docs/my-workflow.md` explaining the workflow.
|
|
|
594
594
|
**3. Test Detection:**
|
|
595
595
|
|
|
596
596
|
```bash
|
|
597
|
-
|
|
597
|
+
morph-spec detect-workflow "request with custom-keyword"
|
|
598
598
|
```
|
|
599
599
|
|
|
600
600
|
### Modifying Existing Workflows
|
|
@@ -675,7 +675,7 @@ Phases: Quick Analysis → Implement
|
|
|
675
675
|
|
|
676
676
|
**User Experience:**
|
|
677
677
|
```bash
|
|
678
|
-
|
|
678
|
+
morph-spec feature create login-typo --request "fix typo in login button"
|
|
679
679
|
|
|
680
680
|
# Output:
|
|
681
681
|
✓ Detected workflow: fast-track
|
|
@@ -683,7 +683,7 @@ npx morph-spec feature create login-typo --request "fix typo in login button"
|
|
|
683
683
|
📝 Write quick analysis (1 paragraph) and implement
|
|
684
684
|
|
|
685
685
|
# User writes quick analysis, then:
|
|
686
|
-
|
|
686
|
+
morph-spec phase advance login-typo
|
|
687
687
|
|
|
688
688
|
# Output:
|
|
689
689
|
⏩ Skipping: setup, uiux, design, clarify, tasks, sync
|
|
@@ -704,7 +704,7 @@ Phases: PROPOSAL → DESIGN → TASKS → IMPLEMENT
|
|
|
704
704
|
|
|
705
705
|
**User Experience:**
|
|
706
706
|
```bash
|
|
707
|
-
|
|
707
|
+
morph-spec feature create user-pagination \
|
|
708
708
|
--request "add pagination to users table"
|
|
709
709
|
|
|
710
710
|
# Output:
|
|
@@ -727,7 +727,7 @@ Phases: ALL (9 phases mandatory)
|
|
|
727
727
|
|
|
728
728
|
**User Experience:**
|
|
729
729
|
```bash
|
|
730
|
-
|
|
730
|
+
morph-spec feature create user-auth \
|
|
731
731
|
--request "implement complete authentication system with OAuth"
|
|
732
732
|
|
|
733
733
|
# Output:
|
|
@@ -750,7 +750,7 @@ Phases: PROTOTYPE ANALYSIS → TASKS → IMPLEMENT
|
|
|
750
750
|
|
|
751
751
|
**User Experience:**
|
|
752
752
|
```bash
|
|
753
|
-
|
|
753
|
+
morph-spec feature create dashboard-screens \
|
|
754
754
|
--request "implement screens from Figma design"
|
|
755
755
|
|
|
756
756
|
# Output:
|
|
@@ -774,7 +774,7 @@ Phases: VISUAL ANALYSIS → DESIGN SYSTEM → IMPLEMENT
|
|
|
774
774
|
|
|
775
775
|
**User Experience:**
|
|
776
776
|
```bash
|
|
777
|
-
|
|
777
|
+
morph-spec feature create dashboard-redesign \
|
|
778
778
|
--request "redesign dashboard to look more modern"
|
|
779
779
|
|
|
780
780
|
# Output:
|
|
@@ -794,13 +794,13 @@ npx morph-spec feature create dashboard-redesign \
|
|
|
794
794
|
|
|
795
795
|
**Solution 1: Provide more context**
|
|
796
796
|
```bash
|
|
797
|
-
|
|
797
|
+
morph-spec feature create simple-fix \
|
|
798
798
|
--request "add pagination (simple, already have paginator component)"
|
|
799
799
|
```
|
|
800
800
|
|
|
801
801
|
**Solution 2: Manual override**
|
|
802
802
|
```bash
|
|
803
|
-
|
|
803
|
+
morph-spec state set my-feature workflow standard
|
|
804
804
|
```
|
|
805
805
|
|
|
806
806
|
**Solution 3: Improve keywords**
|
|
@@ -849,7 +849,7 @@ If this happens often, add keywords to workflow config:
|
|
|
849
849
|
**Alternative:**
|
|
850
850
|
Use `detect-workflow` first to see both options:
|
|
851
851
|
```bash
|
|
852
|
-
|
|
852
|
+
morph-spec detect-workflow "add authentication"
|
|
853
853
|
|
|
854
854
|
# Review both workflows
|
|
855
855
|
# Decide based on:
|
|
@@ -891,13 +891,13 @@ Create `framework/workflows/configs/blazor-standard.json`:
|
|
|
891
891
|
**Solution 1: Force phase**
|
|
892
892
|
```bash
|
|
893
893
|
# Manually go to UIUX phase
|
|
894
|
-
|
|
894
|
+
morph-spec phase set my-feature uiux
|
|
895
895
|
```
|
|
896
896
|
|
|
897
897
|
**Solution 2: Override workflow**
|
|
898
898
|
```bash
|
|
899
899
|
# Use full-morph (includes all phases)
|
|
900
|
-
|
|
900
|
+
morph-spec state set my-feature workflow full-morph
|
|
901
901
|
```
|
|
902
902
|
|
|
903
903
|
**Solution 3: Document in decisions.md**
|
|
@@ -113,7 +113,7 @@ export function loadStandardsForAgent(agentId, projectPath) {
|
|
|
113
113
|
|
|
114
114
|
```bash
|
|
115
115
|
# Standards auto-injected when running detect-agents with --json
|
|
116
|
-
|
|
116
|
+
morph-spec detect-agents --json "create blazor dashboard"
|
|
117
117
|
|
|
118
118
|
# Output includes standardsSummary for each agent:
|
|
119
119
|
{
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
6. Ativar agentes baseado em stack + keywords
|
|
19
19
|
|
|
20
20
|
### FASE 0: PROPOSAL
|
|
21
|
-
1. `
|
|
21
|
+
1. `morph-spec detect "{user-request}"`
|
|
22
22
|
2. Analisar solicitação, identificar stack, estimar complexidade
|
|
23
23
|
3. Gerar proposal.md, registrar agentes no state.json
|
|
24
24
|
- **⛔ PAUSA:** 3 itens (1 ação + 1 pergunta + 1 sugestão)
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
|
|
56
56
|
### FASE 5: IMPLEMENT
|
|
57
57
|
1. Implementar task por task
|
|
58
|
-
2. `
|
|
58
|
+
2. `morph-spec task done {feature} {task-id}` após cada task
|
|
59
59
|
3. Framework gerencia checkpoints automaticamente (a cada 3 tasks)
|
|
60
60
|
4. Gerar recap.md ao final
|
|
61
61
|
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { readFileSync, existsSync } from 'fs';
|
|
20
20
|
import { join, dirname } from 'path';
|
|
21
21
|
import { fileURLToPath } from 'url';
|
|
22
|
-
import { loadState, stateExists } from '../../core/state/state-manager.js';
|
|
22
|
+
import { loadState, stateExists, logDispatch } from '../../core/state/state-manager.js';
|
|
23
23
|
import { buildAgentBriefing, buildValidatorPrompt } from '../../lib/standards/digest-builder.js';
|
|
24
24
|
import { agentIdToSubagentType } from '../../utils/agent-id-mapper.js';
|
|
25
25
|
import { shouldInstall, getProjectTags } from '../../lib/stack-filter.js';
|
|
@@ -434,6 +434,30 @@ export async function dispatchAgentsCommand(featureName, phase, options = {}) {
|
|
|
434
434
|
if (options.mode) dispatchOpts.mode = options.mode;
|
|
435
435
|
const config = await buildDispatchConfig(process.cwd(), featureName, normalizedPhase, dispatchOpts);
|
|
436
436
|
|
|
437
|
+
// Log dispatch to state.json so enforcement gates can verify it happened
|
|
438
|
+
if (config.agents?.length > 0) {
|
|
439
|
+
try {
|
|
440
|
+
logDispatch(featureName, {
|
|
441
|
+
timestamp: new Date().toISOString(),
|
|
442
|
+
phase: normalizedPhase,
|
|
443
|
+
mode: config.mode,
|
|
444
|
+
agents: config.agents.map(a => {
|
|
445
|
+
const groupEntry = Object.entries(config.taskGroups || {}).find(
|
|
446
|
+
([, g]) => g.agentId === a.id
|
|
447
|
+
);
|
|
448
|
+
return {
|
|
449
|
+
id: a.id,
|
|
450
|
+
subagentType: a.subagentType,
|
|
451
|
+
group: a.parallelGroup,
|
|
452
|
+
tasks: groupEntry ? groupEntry[1].tasks : [],
|
|
453
|
+
};
|
|
454
|
+
}),
|
|
455
|
+
});
|
|
456
|
+
} catch {
|
|
457
|
+
// Non-blocking — dispatch output still succeeds even if log fails
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
437
461
|
if (options.table) {
|
|
438
462
|
// Human-readable table format
|
|
439
463
|
console.log(chalk.bold(`\n Dispatch Config — ${featureName} (${normalizedPhase})`));
|
|
@@ -947,13 +947,12 @@ export async function doctorCommand(options = {}) {
|
|
|
947
947
|
logger.dim(' PowerShell (as Administrator):');
|
|
948
948
|
console.log(chalk.gray(` [Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";${prefix}", "User")`));
|
|
949
949
|
logger.blank();
|
|
950
|
-
logger.dim('
|
|
951
|
-
logger.dim(' npx @polymorphism-tech/morph-spec init');
|
|
950
|
+
logger.dim(' Then open a new terminal.');
|
|
952
951
|
logger.blank();
|
|
953
952
|
} else if (!inPath) {
|
|
954
953
|
logger.info('morph-spec not in PATH:');
|
|
955
|
-
logger.dim('
|
|
956
|
-
logger.dim('
|
|
954
|
+
logger.dim(' Open a new terminal — the installer adds npm global to $PROFILE automatically.');
|
|
955
|
+
logger.dim(' If it persists, add manually: npm config get prefix → add to PATH');
|
|
957
956
|
logger.blank();
|
|
958
957
|
}
|
|
959
958
|
}
|
|
@@ -236,7 +236,14 @@ export async function statusCommand(featureName, options = {}) {
|
|
|
236
236
|
process.exit(1);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
let feature;
|
|
240
|
+
try {
|
|
241
|
+
feature = getFeature(featureName);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
console.error(chalk.red(`✗ Error: ${err.message}`));
|
|
244
|
+
console.error(chalk.gray('Run \'morph-spec doctor\' to diagnose or fix your state.json'));
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
240
247
|
if (!feature) {
|
|
241
248
|
console.error(chalk.red(`✗ Error: Feature '${featureName}' not found`));
|
|
242
249
|
console.error(chalk.gray(`Run 'morph-spec state get ${featureName}' to check if feature exists`));
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import chalk from 'chalk';
|
|
14
14
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
15
15
|
import { join } from 'path';
|
|
16
|
-
import { loadState, saveState } from '../../core/state/state-manager.js';
|
|
16
|
+
import { loadState, saveState, derivePhase } from '../../core/state/state-manager.js';
|
|
17
17
|
import { analyzeImpact } from '../../lib/scope/impact-analyzer.js';
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -35,8 +35,10 @@ export async function escalateScope(featureName, options) {
|
|
|
35
35
|
return { success: false, error: `Feature "${featureName}" not found in state.json` };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const featurePath = join(process.cwd(), '.morph', 'features', featureName);
|
|
39
|
+
const currentPhase = feature.phase || derivePhase(featurePath);
|
|
40
|
+
if (currentPhase !== 'implement') {
|
|
41
|
+
return { success: false, error: `Scope escalation only available during implement phase (current: ${currentPhase})` };
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
// Read tasks.md
|
|
@@ -42,6 +42,8 @@ export async function taskDoneCommand(featureName, taskIds, options) {
|
|
|
42
42
|
try {
|
|
43
43
|
const args = ['done', featureName, ...taskIds];
|
|
44
44
|
if (options.skipValidation) args.push('--skip-validation');
|
|
45
|
+
if (options.reason) args.push('--reason', options.reason);
|
|
46
|
+
if (options.note) args.push('--note', options.note);
|
|
45
47
|
if (options.dryRun) args.push('--dry-run');
|
|
46
48
|
await executeTaskManager(args);
|
|
47
49
|
} catch (error) {
|
|
@@ -64,6 +66,58 @@ export async function taskStartCommand(featureName, taskId, options) {
|
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Bulk-start tasks command
|
|
71
|
+
*/
|
|
72
|
+
export async function taskBulkStartCommand(featureName, range, options) {
|
|
73
|
+
try {
|
|
74
|
+
const args = ['bulk-start', featureName];
|
|
75
|
+
if (range) args.push(range);
|
|
76
|
+
if (options.all) args.push('--all');
|
|
77
|
+
if (options.from) args.push('--from', options.from);
|
|
78
|
+
if (options.to) args.push('--to', options.to);
|
|
79
|
+
await executeTaskManager(args);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Bulk-done tasks command
|
|
88
|
+
*/
|
|
89
|
+
export async function taskBulkDoneCommand(featureName, range, options) {
|
|
90
|
+
try {
|
|
91
|
+
const args = ['bulk-done', featureName];
|
|
92
|
+
if (range) args.push(range);
|
|
93
|
+
if (options.all) args.push('--all');
|
|
94
|
+
if (options.from) args.push('--from', options.from);
|
|
95
|
+
if (options.to) args.push('--to', options.to);
|
|
96
|
+
if (options.skipValidation) args.push('--skip-validation');
|
|
97
|
+
if (options.reason) args.push('--reason', options.reason);
|
|
98
|
+
if (options.note) args.push('--note', options.note);
|
|
99
|
+
if (options.dryRun) args.push('--dry-run');
|
|
100
|
+
await executeTaskManager(args);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Annotate a task with a note
|
|
109
|
+
*/
|
|
110
|
+
export async function taskAnnotateCommand(featureName, taskId, text, options) {
|
|
111
|
+
try {
|
|
112
|
+
const args = ['annotate', featureName, taskId, text];
|
|
113
|
+
if (options.type) args.push('--type', options.type);
|
|
114
|
+
await executeTaskManager(args);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
67
121
|
/**
|
|
68
122
|
* Get next task command
|
|
69
123
|
*/
|
|
@@ -70,6 +70,19 @@ const PHASE_OUTPUTS = {
|
|
|
70
70
|
implement: ['spec.md', 'contracts.cs', 'tasks.md']
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Phase-to-folder mapping (filesystem convention)
|
|
75
|
+
*/
|
|
76
|
+
const PHASE_FOLDERS = {
|
|
77
|
+
proposal: '0-proposal',
|
|
78
|
+
uiux: '2-ui',
|
|
79
|
+
design: '1-design',
|
|
80
|
+
clarify: '1-design',
|
|
81
|
+
plan: '3-plan',
|
|
82
|
+
tasks: '4-tasks',
|
|
83
|
+
implement: '5-implement',
|
|
84
|
+
};
|
|
85
|
+
|
|
73
86
|
/**
|
|
74
87
|
* Validate a single output file
|
|
75
88
|
*/
|
|
@@ -254,12 +267,28 @@ export async function validateFeatureCommand(featureName, options = {}) {
|
|
|
254
267
|
process.exit(1);
|
|
255
268
|
}
|
|
256
269
|
} else {
|
|
257
|
-
// Validate all existing outputs
|
|
258
|
-
outputFiles =
|
|
270
|
+
// Validate all existing outputs across all phase folders
|
|
271
|
+
outputFiles = [];
|
|
272
|
+
const entries = fs.readdirSync(featurePath, { withFileTypes: true });
|
|
273
|
+
for (const entry of entries) {
|
|
274
|
+
if (entry.isDirectory()) {
|
|
275
|
+
const subDir = path.join(featurePath, entry.name);
|
|
276
|
+
const files = fs.readdirSync(subDir).filter(f => f.endsWith('.md') || f.endsWith('.cs'));
|
|
277
|
+
outputFiles.push(...files.map(f => ({ file: f, dir: subDir })));
|
|
278
|
+
} else if (entry.name.endsWith('.md') || entry.name.endsWith('.cs')) {
|
|
279
|
+
outputFiles.push({ file: entry.name, dir: featurePath });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
259
282
|
}
|
|
260
283
|
|
|
284
|
+
// Resolve phase folder for path lookup
|
|
285
|
+
const phaseFolder = phase ? PHASE_FOLDERS[phase] : null;
|
|
286
|
+
const searchPath = phaseFolder ? path.join(featurePath, phaseFolder) : featurePath;
|
|
287
|
+
|
|
261
288
|
// Run validation
|
|
262
|
-
const results =
|
|
289
|
+
const results = phase
|
|
290
|
+
? outputFiles.map(file => validateOutput(searchPath, file))
|
|
291
|
+
: outputFiles.map(({ file, dir }) => validateOutput(dir, file));
|
|
263
292
|
const schemaWarnings = crossValidateSchema(featurePath);
|
|
264
293
|
|
|
265
294
|
// Aggregate results
|