@polymorphism-tech/morph-spec 4.7.1 → 4.8.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/.morph/analytics/threads-log.jsonl +54 -0
- package/.morph/state.json +198 -0
- package/LICENSE +1 -2
- package/README.md +379 -414
- package/bin/morph-spec.js +57 -403
- package/bin/validate.js +2 -26
- package/claude-plugin.json +2 -2
- package/docs/ARCHITECTURE.md +43 -46
- package/docs/CHEATSHEET.md +203 -221
- package/docs/COMMAND-FLOWS.md +319 -289
- package/docs/QUICKSTART.md +2 -8
- package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +2 -0
- package/docs/plans/2026-02-22-claude-settings.md +2 -0
- package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +2 -0
- package/docs/plans/2026-02-22-morph-spec-next.md +2 -0
- package/docs/plans/2026-02-22-native-alignment-design.md +2 -0
- package/docs/plans/2026-02-22-native-alignment-impl.md +2 -0
- package/docs/plans/2026-02-22-native-enrichment-design.md +2 -0
- package/docs/plans/2026-02-22-native-enrichment.md +2 -0
- package/docs/plans/2026-02-23-ddd-architecture-refactor.md +2 -0
- package/docs/plans/2026-02-23-ddd-nextsteps.md +2 -0
- package/docs/plans/2026-02-23-infra-architect-refactor.md +2 -0
- package/docs/plans/2026-02-23-nextjs-code-review-design.md +2 -1
- package/docs/plans/2026-02-23-nextjs-code-review-impl.md +2 -0
- package/docs/plans/2026-02-23-nextjs-standards-design.md +2 -1
- package/docs/plans/2026-02-23-nextjs-standards-impl.md +2 -0
- package/docs/plans/2026-02-24-cli-radical-simplification.md +592 -0
- package/docs/plans/2026-02-24-framework-failure-points.md +125 -0
- package/docs/plans/2026-02-24-morph-init-design.md +337 -0
- package/docs/plans/2026-02-24-morph-init-impl.md +1269 -0
- package/docs/plans/2026-02-24-tutorial-command-design.md +71 -0
- package/docs/plans/2026-02-24-tutorial-command.md +298 -0
- package/framework/CLAUDE.md +2 -2
- package/framework/commands/morph-proposal.md +3 -3
- package/framework/hooks/README.md +11 -10
- package/framework/hooks/claude-code/notification/approval-reminder.js +2 -0
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +1 -1
- package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +4 -55
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +20 -5
- package/framework/hooks/claude-code/statusline.py +6 -1
- package/framework/hooks/claude-code/stop/validate-completion.js +1 -1
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +1 -1
- package/framework/hooks/dev/check-sync-health.js +117 -0
- package/framework/hooks/dev/guard-version-numbers.js +57 -0
- package/framework/hooks/dev/sync-standards-registry.js +60 -0
- package/framework/hooks/dev/sync-template-registry.js +60 -0
- package/framework/hooks/dev/validate-skill-format.js +70 -0
- package/framework/hooks/dev/validate-standard-format.js +73 -0
- package/framework/hooks/shared/payload-utils.js +39 -0
- package/framework/hooks/shared/state-reader.js +25 -1
- package/framework/rules/morph-workflow.md +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +216 -0
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
- package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +4 -4
- package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +192 -191
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +181 -180
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +339 -338
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +254 -253
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +168 -170
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +284 -283
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +246 -245
- package/framework/templates/examples/design-system-examples.md +1 -1
- package/framework/templates/ui/FluentDesignTheme.cs +1 -1
- package/framework/templates/ui/MudTheme.cs +1 -1
- package/framework/templates/ui/design-system.css +1 -1
- package/package.json +4 -2
- package/scripts/bump-version.js +248 -0
- package/scripts/install-dev-hooks.js +138 -0
- package/src/commands/agents/index.js +1 -2
- package/src/commands/index.js +13 -16
- package/src/commands/project/doctor.js +100 -14
- package/src/commands/project/index.js +7 -10
- package/src/commands/project/init.js +398 -555
- package/src/commands/project/install-plugin-cmd.js +28 -0
- package/src/commands/project/setup-infra-cmd.js +12 -0
- package/src/commands/project/tutorial.js +115 -0
- package/src/commands/project/update.js +22 -37
- package/src/commands/state/approve.js +213 -221
- package/src/commands/state/index.js +0 -1
- package/src/commands/state/state.js +337 -365
- package/src/commands/templates/index.js +0 -4
- package/src/commands/trust/trust.js +1 -93
- package/src/commands/utils/index.js +1 -5
- package/src/commands/validation/index.js +1 -5
- package/src/core/registry/command-registry.js +11 -285
- package/src/core/state/state-manager.js +5 -2
- package/src/lib/detectors/index.js +81 -87
- package/src/lib/detectors/structure-detector.js +275 -273
- package/src/lib/generators/recap-generator.js +232 -225
- package/src/lib/installers/mcp-installer.js +18 -3
- package/src/scripts/global-install.js +34 -0
- package/src/scripts/install-plugin.js +126 -0
- package/src/scripts/setup-infra.js +203 -0
- package/src/utils/agents-installer.js +10 -1
- package/src/utils/hooks-installer.js +70 -17
- package/CLAUDE.md +0 -77
- package/docs/claude-alignment-report.md +0 -137
- package/docs/examples/order-management/contracts.cs +0 -84
- package/docs/examples/order-management/proposal.md +0 -24
- package/docs/examples/order-management/spec.md +0 -162
- package/src/commands/feature/create-story.js +0 -362
- package/src/commands/feature/index.js +0 -6
- package/src/commands/feature/shard-spec.js +0 -225
- package/src/commands/feature/sprint-status.js +0 -250
- package/src/commands/generation/generate-onboarding.js +0 -169
- package/src/commands/generation/generate.js +0 -276
- package/src/commands/generation/index.js +0 -5
- package/src/commands/learning/capture-pattern.js +0 -121
- package/src/commands/learning/index.js +0 -5
- package/src/commands/learning/search-patterns.js +0 -126
- package/src/commands/mcp/mcp.js +0 -102
- package/src/commands/project/changes.js +0 -66
- package/src/commands/project/cost.js +0 -179
- package/src/commands/project/detect.js +0 -114
- package/src/commands/project/diff.js +0 -278
- package/src/commands/project/revert.js +0 -173
- package/src/commands/project/standards.js +0 -80
- package/src/commands/project/sync.js +0 -167
- package/src/commands/project/update-agents.js +0 -23
- package/src/commands/state/rollback-phase.js +0 -185
- package/src/commands/templates/template-customize.js +0 -87
- package/src/commands/templates/template-list.js +0 -114
- package/src/commands/templates/template-show.js +0 -129
- package/src/commands/templates/template-validate.js +0 -91
- package/src/commands/utils/troubleshoot.js +0 -222
- package/src/commands/validation/analyze-blazor-concurrency.js +0 -193
- package/src/commands/validation/lint-fluent.js +0 -352
- package/src/commands/validation/validate-blazor-state.js +0 -210
- package/src/commands/validation/validate-blazor.js +0 -156
- package/src/commands/validation/validate-css.js +0 -84
- package/src/lib/detectors/conversation-analyzer.js +0 -163
- package/src/lib/learning/index.js +0 -7
- package/src/lib/learning/learning-system.js +0 -520
- package/src/lib/troubleshooting/index.js +0 -8
- package/src/lib/troubleshooting/troubleshoot-grep.js +0 -198
- package/src/lib/troubleshooting/troubleshoot-index.js +0 -144
- package/src/llm/environment-detector.js +0 -43
package/docs/COMMAND-FLOWS.md
CHANGED
|
@@ -1,368 +1,398 @@
|
|
|
1
|
-
# morph-spec —
|
|
1
|
+
# morph-spec — Framework Flows
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Authoritative reference for how the framework connects: slash commands → skills → CLI → state manager.
|
|
4
|
+
> Version: 4.8.1
|
|
4
5
|
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
## 1.
|
|
8
|
+
## 1. Mental Model — The 4 Layers
|
|
8
9
|
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
subgraph P1 ["PHASE 1 — SETUP (auto, no gate)"]
|
|
35
|
-
H["Read .morph/context/"] --> I["Confirm detected stack"]
|
|
36
|
-
I --> J["List active agents"]
|
|
37
|
-
J --> J2["state set FEATURE phase setup"]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
J2 --> UICHECK{"uiux-designer\nin activeAgents?"}
|
|
41
|
-
|
|
42
|
-
subgraph P15 ["PHASE 1.5 — UI/UX (conditional)"]
|
|
43
|
-
UICHECK -->|yes| L["Generate wireframes + design system\n(.claude/skills/phase-uiux/SKILL.md)"]
|
|
44
|
-
L --> PAUSEUI(["⏸ GATE — approve UI/UX"])
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
UICHECK -->|no| M
|
|
48
|
-
PAUSEUI -->|approved| M
|
|
49
|
-
|
|
50
|
-
subgraph P2 ["PHASE 2 — DESIGN"]
|
|
51
|
-
M["Generate spec.md\n(.claude/skills/phase-design/SKILL.md)"] --> N["Generate contracts.cs"]
|
|
52
|
-
N --> O["Generate decisions.md with ADRs"]
|
|
53
|
-
O --> P["Estimate costs per resource"]
|
|
54
|
-
P --> Q1["state mark-output FEATURE spec"]
|
|
55
|
-
Q1 --> Q2["state mark-output FEATURE contracts"]
|
|
56
|
-
Q2 --> Q3["state mark-output FEATURE decisions"]
|
|
57
|
-
Q3 --> PAUSE2(["⏸ GATE — approve design"])
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
PAUSE2 -->|approved| R
|
|
61
|
-
|
|
62
|
-
subgraph P3 ["PHASE 3 — CLARIFY"]
|
|
63
|
-
R["Identify ambiguities in spec\n(.claude/skills/phase-clarify/SKILL.md)"] --> S["Generate 3-7 questions"]
|
|
64
|
-
S --> WAIT(["⏳ Waiting for user answers"])
|
|
65
|
-
WAIT -->|answered| T["Update spec with clarifications\nand edge cases"]
|
|
66
|
-
T --> T2["state set FEATURE phase clarify"]
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
T2 --> U
|
|
70
|
-
|
|
71
|
-
subgraph P4 ["PHASE 4 — TASKS"]
|
|
72
|
-
U["Break spec into tasks T001-TXXX\n(.claude/skills/phase-tasks/SKILL.md)"] --> V["Define order and dependencies"]
|
|
73
|
-
V --> W["Checkpoints every 3 tasks"]
|
|
74
|
-
W --> X1["state mark-output FEATURE tasks"]
|
|
75
|
-
X1 --> X2["state set FEATURE tasks.total N"]
|
|
76
|
-
X2 --> PAUSE4(["⏸ GATE — approve tasks"])
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
PAUSE4 -->|approved| END(["✅ Planning complete\nRun /morph-apply FEATURE"])
|
|
10
|
+
```
|
|
11
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
12
|
+
│ USER │
|
|
13
|
+
│ /morph-proposal my-feature (Claude Code slash command) │
|
|
14
|
+
└────────────────────────┬────────────────────────────────────────────┘
|
|
15
|
+
│ invokes Skill tool
|
|
16
|
+
┌────────────────────────▼────────────────────────────────────────────┐
|
|
17
|
+
│ SKILL (.claude/skills/{name}/SKILL.md) │
|
|
18
|
+
│ Claude reads the markdown and follows its instructions. │
|
|
19
|
+
│ Skills chain other skills via "invoke Skill tool with X". │
|
|
20
|
+
│ Skills call CLI via Bash tool: npx morph-spec ... │
|
|
21
|
+
└────────────────────────┬────────────────────────────────────────────┘
|
|
22
|
+
│ Bash: npx morph-spec <command>
|
|
23
|
+
┌────────────────────────▼────────────────────────────────────────────┐
|
|
24
|
+
│ CLI (bin/morph-spec.js → src/commands/**) │
|
|
25
|
+
│ Commander.js routes to command handler functions. │
|
|
26
|
+
│ Handlers call state-manager.js and other lib modules. │
|
|
27
|
+
└────────────────────────┬────────────────────────────────────────────┘
|
|
28
|
+
│ imports
|
|
29
|
+
┌────────────────────────▼────────────────────────────────────────────┐
|
|
30
|
+
│ STATE MANAGER (src/core/state/state-manager.js) │
|
|
31
|
+
│ Single source of truth. Reads/writes .morph/state.json. │
|
|
32
|
+
│ All state mutations go through here — never direct file edits. │
|
|
33
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
80
34
|
```
|
|
81
35
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## 2. /morph-apply
|
|
85
|
-
|
|
86
|
-
```mermaid
|
|
87
|
-
flowchart TD
|
|
88
|
-
START(["/morph-apply FEATURE"]) --> A
|
|
89
|
-
|
|
90
|
-
A["state get FEATURE"] --> B{"All phases\ncomplete?"}
|
|
91
|
-
B -->|no| ERR(["❌ ERROR — phase X not complete\nRun /morph-proposal FEATURE"])
|
|
92
|
-
B -->|yes| C
|
|
93
|
-
|
|
94
|
-
subgraph PREP ["INITIALIZATION"]
|
|
95
|
-
C["Read 1-design/spec.md + 3-tasks/tasks.md + 1-design/contracts.cs"] --> D
|
|
96
|
-
D["Read framework/standards/\n.morph/context/"] --> E1
|
|
97
|
-
E1["state set FEATURE phase implement"] --> E2
|
|
98
|
-
E2["state set FEATURE status in_progress"] --> E3
|
|
99
|
-
E3["state set FEATURE tasks.total N"]
|
|
100
|
-
end
|
|
36
|
+
**Hooks** run as side-effects alongside this chain (see Section 9).
|
|
101
37
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
subgraph LOOP ["LOOP — For each task in order"]
|
|
105
|
-
LOOP_START["Select next task"] --> F
|
|
106
|
-
F["task start FEATURE task-id"] --> F1
|
|
107
|
-
F1["spawn task-manager.cjs start"] --> G
|
|
108
|
-
G["Implement code\nfollowing contracts.cs + standards"] --> H
|
|
109
|
-
H["task done FEATURE task-id"] --> H1
|
|
110
|
-
H1["spawn task-manager.cjs done"] --> VAL_START
|
|
111
|
-
|
|
112
|
-
subgraph VAL ["Automatic validators (hooks)"]
|
|
113
|
-
VAL_START["security-expert\nSQL injection, XSS, hardcoded secrets"] --> V2
|
|
114
|
-
V2["architecture-expert\nIDbContextFactory, async/await, DI order"] --> V3
|
|
115
|
-
V3["packages-validator\nNuGet conflicts, vulnerabilities"] --> V4
|
|
116
|
-
V4["blazor-concurrency-validator\nLifecycle, thread safety"]
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
V4 --> VRESULT{"Validation\npassed?"}
|
|
120
|
-
VRESULT -->|no| FIX["Fix violations\nDO NOT use --skip-validation"] --> H
|
|
121
|
-
VRESULT -->|yes| CHK{"task_count\nmultiple of 3?"}
|
|
122
|
-
CHK -->|yes| CP["state checkpoint FEATURE\nstate list"]
|
|
123
|
-
CHK -->|no| NEXT
|
|
124
|
-
CP --> NEXT{"Next task\nexists?"}
|
|
125
|
-
NEXT -->|yes| LOOP_START
|
|
126
|
-
end
|
|
38
|
+
---
|
|
127
39
|
|
|
128
|
-
|
|
40
|
+
## 2. Slash Command → Skill Map
|
|
129
41
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
42
|
+
| Slash command | Skill invoked | What it covers |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `/morph-proposal {feature}` | Chains: `phase-setup` → `phase-uiux`\* → `phase-design` → `phase-clarify` → `phase-tasks` | Full planning pipeline (phases 1–4) |
|
|
45
|
+
| `/morph-apply {feature}` | `phase-implement` | Implementation (phase 5) |
|
|
46
|
+
| `/morph-status` | No skill — Claude uses `morph-spec status` directly | Feature status dashboard |
|
|
47
|
+
| `/morph-preflight` | No skill — Claude runs validators directly | Pre-deploy validation checks |
|
|
48
|
+
| `/morph-archive {feature}` | No skill — Claude follows CLAUDE.md instructions | Archive completed feature |
|
|
49
|
+
| `/{phase-name} {feature}` | The matching phase skill directly | Run a single phase |
|
|
137
50
|
|
|
138
|
-
|
|
139
|
-
```
|
|
51
|
+
\* `phase-uiux` only if frontend agents are active.
|
|
140
52
|
|
|
141
53
|
---
|
|
142
54
|
|
|
143
|
-
## 3.
|
|
55
|
+
## 3. Skill Invocation Chain
|
|
144
56
|
|
|
145
57
|
```mermaid
|
|
146
58
|
flowchart TD
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
59
|
+
P(["/morph-proposal FEATURE"]) --> SETUP
|
|
60
|
+
|
|
61
|
+
SETUP["Skill: phase-setup\n(Phase 1)"]
|
|
62
|
+
SETUP --> UICHECK{"uiux-designer\nactive?"}
|
|
63
|
+
UICHECK -->|yes| UIUX["Skill: phase-uiux\n(Phase 1.5)"]
|
|
64
|
+
UICHECK -->|no| DESIGN
|
|
65
|
+
UIUX --> DESIGN
|
|
66
|
+
|
|
67
|
+
DESIGN["Skill: phase-design\n(Phase 2)"]
|
|
68
|
+
DESIGN --> CODEBASE["Skill: phase-codebase-analysis\n(sub-phase of Design)"]
|
|
69
|
+
CODEBASE --> DESIGN2["Back in phase-design:\nspec.md + contracts.cs + decisions.md"]
|
|
70
|
+
DESIGN2 --> GATE1(["⏸ Gate: approve design"])
|
|
71
|
+
GATE1 -->|approved| CLARIFY
|
|
72
|
+
|
|
73
|
+
CLARIFY["Skill: phase-clarify\n(Phase 3)"]
|
|
74
|
+
CLARIFY --> TASKS
|
|
75
|
+
|
|
76
|
+
TASKS["Skill: phase-tasks\n(Phase 4)"]
|
|
77
|
+
TASKS --> GATE2(["⏸ Gate: approve tasks"])
|
|
78
|
+
GATE2 --> DONE(["✅ /morph-proposal complete"])
|
|
79
|
+
|
|
80
|
+
A(["/morph-apply FEATURE"]) --> IMPL
|
|
81
|
+
IMPL["Skill: phase-implement\n(Phase 5)"]
|
|
82
|
+
IMPL --> DONE2(["✅ /morph-apply complete"])
|
|
170
83
|
```
|
|
171
84
|
|
|
85
|
+
**How one skill calls another:**
|
|
86
|
+
Skills don't call each other via code. The SKILL.md instructs Claude to `invoke Skill tool with <skill-name>`. Claude executes that as a new Skill tool call. Each skill is a fresh markdown load — they share context only through the conversation and the state.json.
|
|
87
|
+
|
|
172
88
|
---
|
|
173
89
|
|
|
174
|
-
## 4. /morph-
|
|
90
|
+
## 4. /morph-proposal — Detailed Flow
|
|
175
91
|
|
|
176
92
|
```mermaid
|
|
177
93
|
flowchart TD
|
|
178
|
-
START(["/morph-
|
|
94
|
+
START(["/morph-proposal FEATURE"]) --> CHECK
|
|
95
|
+
|
|
96
|
+
CHECK["morph-spec state get FEATURE"] --> EXISTS{"Feature\nexists?"}
|
|
97
|
+
EXISTS -->|yes| RESUME["Resume from current phase"]
|
|
98
|
+
EXISTS -->|no| P0
|
|
99
|
+
|
|
100
|
+
subgraph PHASE0 ["PHASE 0 — PROPOSAL (Claude writes directly)"]
|
|
101
|
+
P0["Write 0-proposal/proposal.md"] --> P0S1
|
|
102
|
+
P0S1["morph-spec state set FEATURE phase proposal"] --> P0S2
|
|
103
|
+
P0S2["morph-spec state set FEATURE status draft"] --> P0S3
|
|
104
|
+
P0S3["morph-spec state mark-output FEATURE proposal"] --> P0S4
|
|
105
|
+
P0S4["morph-spec state add-agent FEATURE agent-id × N"]
|
|
106
|
+
P0S4 --> GATE0(["⏸ GATE — approve proposal\nmorph-spec approve FEATURE proposal"])
|
|
107
|
+
end
|
|
179
108
|
|
|
180
|
-
|
|
181
|
-
B{"All tasks\ncomplete?"} -->|no| ERR(["❌ Feature not ready\nFinish pending tasks first"])
|
|
182
|
-
B -->|yes| C
|
|
109
|
+
GATE0 -->|approved| PHASE1
|
|
183
110
|
|
|
184
|
-
|
|
111
|
+
subgraph PHASE1 ["PHASE 1 — SETUP (Skill: phase-setup)"]
|
|
112
|
+
S1["Read .morph/context/README.md"] --> S2
|
|
113
|
+
S2["Read .morph/framework/agents.json\nMatch keywords → active agents"] --> S3
|
|
114
|
+
S3["morph-spec state set FEATURE phase setup"] --> S4
|
|
115
|
+
S4["morph-spec state set FEATURE status in_progress"]
|
|
116
|
+
end
|
|
185
117
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
118
|
+
S4 --> UICHECK{"uiux-designer\nin activeAgents?"}
|
|
119
|
+
|
|
120
|
+
subgraph PHASE15 ["PHASE 1.5 — UI/UX (Skill: phase-uiux, conditional)"]
|
|
121
|
+
UICHECK -->|yes| U1["Write 2-ui/design-system.md"]
|
|
122
|
+
U1 --> U2["Write 2-ui/mockups.md"]
|
|
123
|
+
U2 --> U3["Write 2-ui/components.md"]
|
|
124
|
+
U3 --> U4["Write 2-ui/flows.md"]
|
|
125
|
+
U4 --> U5["morph-spec state mark-output FEATURE uiDesignSystem"]
|
|
126
|
+
U5 --> U6["morph-spec state mark-output FEATURE uiMockups"]
|
|
127
|
+
U6 --> U7["morph-spec state mark-output FEATURE uiComponents"]
|
|
128
|
+
U7 --> U8["morph-spec state mark-output FEATURE uiFlows"]
|
|
129
|
+
U8 --> GATE15(["⏸ GATE — approve UI/UX\nmorph-spec approve FEATURE uiux"])
|
|
190
130
|
end
|
|
191
131
|
|
|
192
|
-
|
|
132
|
+
UICHECK -->|no| PHASE2
|
|
133
|
+
GATE15 -->|approved| PHASE2
|
|
134
|
+
|
|
135
|
+
subgraph PHASE2 ["PHASE 2 — DESIGN (Skill: phase-design + phase-codebase-analysis)"]
|
|
136
|
+
D0["Skill: phase-codebase-analysis\nRead DB schema via Supabase MCP or Grep"] --> D1
|
|
137
|
+
D1["morph-spec state mark-output FEATURE schema-analysis"] --> D2
|
|
138
|
+
D2["morph-spec template render code/dotnet/contracts/contracts-levelN.cs"] --> D3
|
|
139
|
+
D3["morph-spec template render docs/spec"] --> D4
|
|
140
|
+
D4["morph-spec template render feature/decisions"] --> D5
|
|
141
|
+
D5["morph-spec state set FEATURE phase design"] --> D6
|
|
142
|
+
D6["morph-spec state set FEATURE costs.estimated X.XX"] --> D7
|
|
143
|
+
D7["morph-spec state mark-output FEATURE spec"] --> D8
|
|
144
|
+
D8["morph-spec state mark-output FEATURE contracts"] --> D9
|
|
145
|
+
D9["morph-spec state mark-output FEATURE decisions"]
|
|
146
|
+
D9 --> GATE2(["⏸ GATE — approve design\nmorph-spec approve FEATURE design"])
|
|
147
|
+
end
|
|
193
148
|
|
|
194
|
-
|
|
195
|
-
F --> G
|
|
196
|
-
E -->|no| G
|
|
149
|
+
GATE2 -->|approved| PHASE3
|
|
197
150
|
|
|
198
|
-
subgraph
|
|
199
|
-
|
|
151
|
+
subgraph PHASE3 ["PHASE 3 — CLARIFY (Skill: phase-clarify)"]
|
|
152
|
+
C1["Read 1-design/spec.md\nIdentify 3-7 ambiguities"] --> C2
|
|
153
|
+
C2["Present questions → wait for answers"] --> C3
|
|
154
|
+
C3["Update spec with clarifications"] --> C4
|
|
155
|
+
C4["morph-spec state set FEATURE phase clarify"]
|
|
200
156
|
end
|
|
201
157
|
|
|
202
|
-
|
|
158
|
+
C4 --> PHASE4
|
|
203
159
|
|
|
204
|
-
subgraph
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
160
|
+
subgraph PHASE4 ["PHASE 4 — TASKS (Skill: phase-tasks)"]
|
|
161
|
+
T1["Read spec.md + contracts.cs"] --> T2
|
|
162
|
+
T2["Check domain complexity level\ngrep '## Domain Complexity' spec.md"] --> T3
|
|
163
|
+
T3["Write 3-tasks/tasks.md (T001…TXXX)"] --> T4
|
|
164
|
+
T4["morph-spec state set FEATURE phase tasks"] --> T5
|
|
165
|
+
T5["morph-spec state set FEATURE tasks.total N"] --> T6
|
|
166
|
+
T6["morph-spec state mark-output FEATURE tasks"]
|
|
167
|
+
T6 --> GATE4(["⏸ GATE — approve tasks\nmorph-spec approve FEATURE tasks"])
|
|
208
168
|
end
|
|
209
169
|
|
|
210
|
-
|
|
170
|
+
GATE4 --> END(["✅ Planning complete\nRun /morph-apply FEATURE"])
|
|
211
171
|
```
|
|
212
172
|
|
|
213
173
|
---
|
|
214
174
|
|
|
215
|
-
## 5. /morph-
|
|
175
|
+
## 5. /morph-apply — Detailed Flow
|
|
216
176
|
|
|
217
177
|
```mermaid
|
|
218
178
|
flowchart TD
|
|
219
|
-
START(["/morph-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
ROUTE -->|destroy| DES_1
|
|
228
|
-
|
|
229
|
-
subgraph INIT ["INIT — Initialize IaC"]
|
|
230
|
-
INIT_1["Copy templates from\n.morph/framework/templates/infrastructure/"] --> INIT_2
|
|
231
|
-
INIT_2["Create infra/ structure\nmain.bicep\nparameters.dev.json, parameters.prod.json\nmodules/*.bicep"] --> INIT_3
|
|
232
|
-
INIT_3["Replace placeholders\nAPP_NAME, SUBSCRIPTION_ID\nRESOURCE_GROUP"] --> INIT_4
|
|
233
|
-
INIT_4["Document structure in decisions.md"]
|
|
234
|
-
INIT_4 --> INIT_END(["✅ Done — run /morph-infra validate"])
|
|
179
|
+
START(["/morph-apply FEATURE"]) --> CHECK
|
|
180
|
+
|
|
181
|
+
subgraph INIT ["INITIALIZATION (Skill: phase-implement)"]
|
|
182
|
+
CHECK["morph-spec state get FEATURE"] --> GATES
|
|
183
|
+
GATES["morph-spec approval-status FEATURE\nVerify design + tasks gates passed"] --> READ
|
|
184
|
+
READ["Read 1-design/spec.md\nRead 3-tasks/tasks.md\nRead 1-design/contracts.cs"] --> SETPHASE
|
|
185
|
+
SETPHASE["morph-spec state set FEATURE phase implement"] --> SETSTATUS
|
|
186
|
+
SETSTATUS["morph-spec state set FEATURE status in_progress"]
|
|
235
187
|
end
|
|
236
188
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
189
|
+
SETSTATUS --> GETNEXT
|
|
190
|
+
|
|
191
|
+
subgraph TASKLOOP ["TASK LOOP"]
|
|
192
|
+
GETNEXT["morph-spec task next FEATURE\n(find next pending task)"] --> START_T
|
|
193
|
+
START_T["morph-spec task start FEATURE T00X"] --> IMPL
|
|
194
|
+
IMPL["Implement code\nfollowing contracts.cs + standards\nTDD: write test first"] --> TEST
|
|
195
|
+
TEST["dotnet test / npm test"] --> TESTOK{"Tests\npassed?"}
|
|
196
|
+
TESTOK -->|no| FIX["Fix code"] --> TEST
|
|
197
|
+
TESTOK -->|yes| DONE_T
|
|
198
|
+
DONE_T["morph-spec task done FEATURE T00X"] --> DISPATCH
|
|
199
|
+
DISPATCH["[Hook: dispatch.js fires]\nChecks: completed % 3 === 0?"] --> CHKCHECK{"Auto-checkpoint\nneeded?"}
|
|
200
|
+
CHKCHECK -->|yes| CP["morph-spec checkpoint-save FEATURE\n(auto-triggered by dispatch.js hook)"]
|
|
201
|
+
CP --> MORETASKS
|
|
202
|
+
CHKCHECK -->|no| MORETASKS
|
|
203
|
+
MORETASKS{"More tasks?"}
|
|
204
|
+
MORETASKS -->|yes| GETNEXT
|
|
242
205
|
end
|
|
243
206
|
|
|
244
|
-
|
|
245
|
-
PLAN_1["az account show"] --> PLAN_2{"Authenticated\nto Azure?"}
|
|
246
|
-
PLAN_2 -->|no| PLAN_ERR(["❌ Run az login"])
|
|
247
|
-
PLAN_2 -->|yes| PLAN_3["az deployment group what-if\n--template-file infra/main.bicep\n--parameters parameters.ENV.json"]
|
|
248
|
-
PLAN_3 --> PLAN_4["Display summary:\nCREATE / MODIFY / DELETE\n+ estimated costs"]
|
|
249
|
-
PLAN_4 --> PLAN_PAUSE(["⏸ GATE — wait for approval\nbefore running deploy"])
|
|
250
|
-
end
|
|
207
|
+
MORETASKS -->|no| RECAP
|
|
251
208
|
|
|
252
|
-
subgraph
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
DEP_5["Update documentation\nwith deploy info"]
|
|
258
|
-
DEP_5 --> DEP_END(["✅ Deploy complete"])
|
|
209
|
+
subgraph WRAP ["FINALIZATION"]
|
|
210
|
+
RECAP["morph-spec generate recap FEATURE\n(auto-calls markOutput internally)"] --> VALFEAT
|
|
211
|
+
VALFEAT["morph-spec validate-feature FEATURE --phase implement"] --> SETDONE
|
|
212
|
+
SETDONE["morph-spec state set FEATURE status done"] --> ADVANCE
|
|
213
|
+
ADVANCE["morph-spec phase advance FEATURE"]
|
|
259
214
|
end
|
|
260
215
|
|
|
261
|
-
|
|
262
|
-
DES_1(["⚠️ WARNING: irreversible action"]) --> DES_2
|
|
263
|
-
DES_2["List all resources\nthat will be deleted"] --> DES_3
|
|
264
|
-
DES_3(["⏸ GATE — require explicit confirmation\n'yes, delete'"]) --> DES_4
|
|
265
|
-
DES_4["az group delete --name rg-APP-ENV\n--yes --no-wait"]
|
|
266
|
-
DES_4 --> DES_END(["✅ Resources removed"])
|
|
267
|
-
end
|
|
216
|
+
ADVANCE --> END(["✅ Feature complete"])
|
|
268
217
|
```
|
|
269
218
|
|
|
270
219
|
---
|
|
271
220
|
|
|
272
|
-
## 6. /morph-
|
|
221
|
+
## 6. /morph-status — Flow
|
|
273
222
|
|
|
274
223
|
```mermaid
|
|
275
224
|
flowchart TD
|
|
276
|
-
START(["/morph-
|
|
225
|
+
START(["/morph-status"]) --> A
|
|
226
|
+
A["morph-spec state list\n→ StateManager.getSummary() + listFeatures()\n→ reads .morph/state.json"] --> B
|
|
227
|
+
B["Display: all features, phases, task counts, gates"] --> C
|
|
228
|
+
C{"Specific feature?"}
|
|
229
|
+
C -->|yes| D["morph-spec status FEATURE --verbose\n→ reads state + scans feature directory for output files"]
|
|
230
|
+
C -->|no| E["Suggest next actions"]
|
|
231
|
+
D --> E
|
|
232
|
+
E --> END(["✅ Done"])
|
|
233
|
+
```
|
|
277
234
|
|
|
278
|
-
|
|
279
|
-
C1["Check 1 — Package Conflicts\ndotnet restore --verbosity normal\ngrep NU1605 NU1608"] --> R1{"OK?"}
|
|
280
|
-
R1 -->|✅| C2
|
|
281
|
-
R1 -->|❌| FIX1["Fix: declare Azure.Identity\nwith explicit version in .csproj"] --> C2
|
|
235
|
+
---
|
|
282
236
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
237
|
+
## 7. Skill → CLI Commands Reference
|
|
238
|
+
|
|
239
|
+
### Meta Skills (level-0-meta)
|
|
240
|
+
|
|
241
|
+
| Skill | CLI Commands Called |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `verification-before-completion` | `morph-spec state get {f}` · `morph-spec validate-feature {f} --phase {p}` · `morph-spec status {f} --verbose` · `morph-spec checkpoint-save {f}` · `morph-spec task done {f} T001` |
|
|
244
|
+
| `brainstorming` | `morph-spec state get {f}` · `morph-spec state mark-output {f} proposal` · `morph-spec state mark-output {f} decisions` |
|
|
245
|
+
| `morph-init` | `morph-spec setup-infra` · `morph-spec install-plugin superpowers` · `morph-spec install-plugin context7` |
|
|
246
|
+
| `morph-checklist` | None (pure checklist) |
|
|
247
|
+
| `simulation-checklist` | None (pure checklist) |
|
|
248
|
+
| `code-review` | None (pure checklist) |
|
|
249
|
+
| `code-review-nextjs` | None (pure checklist) |
|
|
250
|
+
| `tool-usage-guide` | None (reference guide) |
|
|
251
|
+
|
|
252
|
+
### Workflow Skills (level-1-workflows)
|
|
253
|
+
|
|
254
|
+
| Skill | CLI Commands Called |
|
|
255
|
+
|---|---|
|
|
256
|
+
| `phase-setup` | `morph-spec state get {f}` · `morph-spec state set {f} phase setup` · `morph-spec state set {f} status in_progress` |
|
|
257
|
+
| `phase-uiux` | `morph-spec state set {f} phase uiux` · `morph-spec state mark-output {f} uiDesignSystem` · `morph-spec state mark-output {f} uiMockups` · `morph-spec state mark-output {f} uiComponents` · `morph-spec state mark-output {f} uiFlows` · `morph-spec approve {f} uiux` |
|
|
258
|
+
| `phase-codebase-analysis` | `morph-spec state mark-output {f} schema-analysis` |
|
|
259
|
+
| `phase-design` | `morph-spec state get {f}` · `morph-spec template render ...` (×3) · `morph-spec state set {f} phase design` · `morph-spec state set {f} costs.estimated N` · `morph-spec state mark-output {f} schema-analysis` · `morph-spec state mark-output {f} spec` · `morph-spec state mark-output {f} contracts` · `morph-spec state mark-output {f} decisions` |
|
|
260
|
+
| `phase-clarify` | `morph-spec state set {f} phase clarify` · `morph-spec state mark-output {f} clarifications` |
|
|
261
|
+
| `phase-tasks` | `morph-spec state get {f}` · `morph-spec state set {f} phase tasks` · `morph-spec state set {f} tasks.total N` · `morph-spec state mark-output {f} tasks` |
|
|
262
|
+
| `phase-implement` | `morph-spec state get {f}` · `morph-spec approval-status {f}` · `morph-spec task next {f}` · `morph-spec task start {f} T00X` · `morph-spec task done {f} T00X` · `morph-spec checkpoint-save {f}` · `morph-spec validate-feature {f} --phase implement` · `morph-spec generate recap {f}` · `morph-spec state set {f} phase implement` · `morph-spec state set {f} status done` · `morph-spec phase advance {f}` |
|
|
286
263
|
|
|
287
|
-
|
|
288
|
-
R3 -->|✅ or N/A| C4
|
|
289
|
-
R3 -->|❌| FIX3["Fix: correct Dockerfile"] --> C4
|
|
264
|
+
---
|
|
290
265
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
266
|
+
## 8. CLI Command → Internal Implementation
|
|
267
|
+
|
|
268
|
+
| CLI Command | Handler | Key State-Manager Calls |
|
|
269
|
+
|---|---|---|
|
|
270
|
+
| `state get {f}` | `src/commands/state/state.js` → `getCommand()` | `StateManager.getFeature(f)` |
|
|
271
|
+
| `state set {f} {key} {value}` | `state.js` → `setCommand()` | `StateManager.updateFeature(f, key, value)` |
|
|
272
|
+
| `state list` | `state.js` → `listCommand()` | `StateManager.getSummary()` · `StateManager.listFeatures()` |
|
|
273
|
+
| `state mark-output {f} {type}` | `state.js` → `markOutputCommand()` | `StateManager.markOutput(f, type)` → normalizes type, sets `outputs.{type}.created = true` |
|
|
274
|
+
| `state add-agent {f} {id}` | `state.js` → `addAgentCommand()` | `StateManager.addAgent(f, id)` → pushes to `activeAgents[]` |
|
|
275
|
+
| `state remove-agent {f} {id}` | `state.js` → `removeAgentCommand()` | `StateManager.removeAgent(f, id)` → filters from `activeAgents[]` |
|
|
276
|
+
| `task start {f} {id}` | `src/commands/tasks/task.js` → `taskStartCommand()` | `StateManager.updateTaskStatus(f, id, 'in_progress')` |
|
|
277
|
+
| `task done {f} {ids...}` | `task.js` → `taskDoneCommand()` | `StateManager.updateTaskStatus(f, id, 'completed')` · increments `tasks.completed` |
|
|
278
|
+
| `task next {f}` | `task.js` → `taskNextCommand()` | `StateManager.getNextTask(f)` → scans `taskList[]` for first pending |
|
|
279
|
+
| `checkpoint-save {f}` | `src/commands/project/checkpoint.js` → `checkpointSaveCommand()` | `StateManager.addCheckpoint(f, note)` → appends to `checkpoints[]` |
|
|
280
|
+
| `checkpoint-restore {f}` | `checkpoint.js` → `checkpointRestoreCommand()` | `StateManager.getCheckpoints(f)` + file restoration |
|
|
281
|
+
| `checkpoint-list {f}` | `checkpoint.js` → `checkpointListCommand()` | `StateManager.getCheckpoints(f)` |
|
|
282
|
+
| `approve {f} {gate}` | `src/commands/state/approve.js` → `approveCommand()` | `StateManager.setApprovalGate(f, gate, true, meta)` |
|
|
283
|
+
| `approval-status {f}` | `approve.js` → `approvalStatusCommand()` | `StateManager.getApprovalGate(f, gate)` × 4 · `StateManager.getApprovalHistory(f)` |
|
|
284
|
+
| `phase advance {f}` | `src/commands/state/advance-phase.js` → `advancePhaseCommand()` | `StateManager.getFeature(f)` · `StateManager.updateFeature(f, 'phase', next)` |
|
|
285
|
+
| `validate-phase {f} {phase}` | `src/commands/state/validate-phase.js` | `StateManager.getFeature(f)` · checks `outputs` + `approvals` |
|
|
286
|
+
| `validate-feature {f}` | `src/commands/validation/validate-feature.js` | `StateManager.getFeature(f)` · `runValidation()` from `validation-runner.js` |
|
|
287
|
+
| `generate recap {f}` | inline in `bin/morph-spec.js` → `generateRecap()` | `StateManager.loadState()` · `StateManager.markOutput(f, 'recap')` *(auto, post-write)* |
|
|
288
|
+
| `template render {id} {out} {vars}` | `src/commands/templates/template-render.js` | None — reads template file, renders Handlebars, writes output |
|
|
289
|
+
| `status {f}` | `src/commands/project/status.js` | `StateManager.getFeature(f)` · scans filesystem for outputs |
|
|
294
290
|
|
|
295
|
-
|
|
296
|
-
R5 -->|✅| C6
|
|
297
|
-
R5 -->|❌| FIX5["Fix: correct Bicep syntax errors"] --> C6
|
|
291
|
+
---
|
|
298
292
|
|
|
299
|
-
|
|
300
|
-
R6 -->|✅| C7
|
|
301
|
-
R6 -->|❌| FIX6["Fix: add KeyVaultUri\nDO NOT gate on IsDevelopment"] --> C7
|
|
293
|
+
## 9. Hook Event Chain
|
|
302
294
|
|
|
303
|
-
|
|
304
|
-
R7 -->|✅| SUM
|
|
305
|
-
R7 -->|⚠️| WARN["Warning: move secrets to Key Vault"] --> SUM
|
|
306
|
-
end
|
|
295
|
+
Hooks are configured in `.claude/settings.local.json`. All fail-open (catch + exit 0).
|
|
307
296
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
297
|
+
```
|
|
298
|
+
SessionStart ──────────────── inject-morph-context.js
|
|
299
|
+
Reads state.json → injects active feature summary
|
|
300
|
+
+ spec.md up to hooks.specInjectionLimit chars (default: 3000)
|
|
301
|
+
|
|
302
|
+
UserPromptSubmit ─────────── enrich-prompt.js
|
|
303
|
+
Scans prompt for feature names, detects intent
|
|
304
|
+
(implement/approve/next-task) → injects hints
|
|
305
|
+
|
|
306
|
+
PreToolUse (Write|Edit) ──┬─ protect-spec-files.js
|
|
307
|
+
│ If gate approved → blocks edits to spec/contracts/tasks
|
|
308
|
+
└─ enforce-phase-writes.js
|
|
309
|
+
If write target is wrong phase folder → blocks
|
|
310
|
+
[permissions.deny in settings.local.json]
|
|
311
|
+
Always blocks: .morph/state.json, .morph/framework/**
|
|
312
|
+
|
|
313
|
+
PostToolUse (Bash) ──────── dispatch.js
|
|
314
|
+
Detects: morph-spec task done {f} {id}
|
|
315
|
+
If completed % 3 === 0 → triggers:
|
|
316
|
+
morph-spec checkpoint-save {f}
|
|
317
|
+
|
|
318
|
+
PostToolUseFailure ──────── handle-tool-failure.js
|
|
319
|
+
Appends JSON to .morph/logs/tool-failures.log
|
|
320
|
+
|
|
321
|
+
Stop ────────────────────── validate-completion.js
|
|
322
|
+
Checks for incomplete tasks, missing outputs,
|
|
323
|
+
pending gates → returns advisory (non-blocking)
|
|
324
|
+
|
|
325
|
+
PreCompact ─────────────── save-morph-context.js
|
|
326
|
+
Snapshots state to .morph/memory/pre-compact-{ts}.json
|
|
327
|
+
|
|
328
|
+
Notification (idle) ─────── approval-reminder.js
|
|
329
|
+
If pending gate → suggests: morph-spec approve {f} {gate}
|
|
312
330
|
```
|
|
313
331
|
|
|
314
332
|
---
|
|
315
333
|
|
|
316
|
-
##
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
334
|
+
## 10. State-Manager Key Methods
|
|
335
|
+
|
|
336
|
+
Located in `src/core/state/state-manager.js`.
|
|
337
|
+
|
|
338
|
+
| Method | Signature | Purpose |
|
|
339
|
+
|---|---|---|
|
|
340
|
+
| `loadState` | `loadState(throwIfMissing?)` | Read `.morph/state.json` → returns parsed object |
|
|
341
|
+
| `saveState` | `saveState(state)` | Write state object to disk |
|
|
342
|
+
| `stateExists` | `stateExists()` | Boolean check for `.morph/state.json` existence |
|
|
343
|
+
| `initState` | `initState(opts)` | Create fresh state.json (v4.0.0 schema) |
|
|
344
|
+
| `getFeature` | `getFeature(name)` | Return single feature object or null |
|
|
345
|
+
| `listFeatures` | `listFeatures()` | Return `[name, feature][]` array |
|
|
346
|
+
| `getSummary` | `getSummary()` | Return project-level metadata (counts, totals) |
|
|
347
|
+
| `updateFeature` | `updateFeature(name, key, value)` | Set `feature[key] = value`, save |
|
|
348
|
+
| `markOutput` | `markOutput(name, type)` | Set `feature.outputs[normalizedType].created = true` |
|
|
349
|
+
| `addAgent` | `addAgent(name, agentId)` | Push to `feature.activeAgents[]` if not present |
|
|
350
|
+
| `removeAgent` | `removeAgent(name, agentId)` | Filter from `feature.activeAgents[]` |
|
|
351
|
+
| `setApprovalGate` | `setApprovalGate(name, gate, approved, meta)` | Set `feature.approvals[gate]` with timestamp + metadata |
|
|
352
|
+
| `getApprovalGate` | `getApprovalGate(name, gate)` | Return gate object or null |
|
|
353
|
+
| `getApprovalHistory` | `getApprovalHistory(name)` | Return `feature.approvalHistory[]` |
|
|
354
|
+
| `addCheckpoint` | `addCheckpoint(name, note)` | Append to `feature.checkpoints[]`, returns checkpoint object |
|
|
355
|
+
| `getCheckpoints` | `getCheckpoints(name)` | Return `feature.checkpoints[]` |
|
|
356
|
+
| `updateTaskStatus` | `updateTaskStatus(name, taskId, status)` | Update task in `taskList[]`, recalculate counters |
|
|
357
|
+
| `getNextTask` | `getNextTask(name)` | Return first task with `status === 'pending'` |
|
|
323
358
|
|
|
324
|
-
|
|
325
|
-
CATS --> END_CATS(["✅ Categories displayed"])
|
|
359
|
+
---
|
|
326
360
|
|
|
327
|
-
|
|
361
|
+
## 11. Agent Detection — How It Actually Works
|
|
328
362
|
|
|
329
|
-
|
|
330
|
-
L1_START["searchIndex(searchTerms, options)"] --> L1A
|
|
331
|
-
L1A["Search JSON database\nof known issues"] --> L1B{"Filter\n--category?"}
|
|
332
|
-
L1B -->|yes| L1C["Filter by category"]
|
|
333
|
-
L1B -->|no| L1D["Match all keywords"]
|
|
334
|
-
L1C --> L1RESULT
|
|
335
|
-
L1D --> L1RESULT["Return matches with score"]
|
|
336
|
-
end
|
|
363
|
+
> `detect-agents` appears in some skill files as `npx morph-spec detect-agents --json`. This CLI command is **not in bin/morph-spec.js** — the source file never made it to the registered CLI.
|
|
337
364
|
|
|
338
|
-
|
|
339
|
-
CHECK1 -->|yes| FORMAT
|
|
365
|
+
The actual flow when agents are needed:
|
|
340
366
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
L2C --> L2D["Merge and limit to 10 results"]
|
|
347
|
-
end
|
|
367
|
+
1. Claude reads `.morph/framework/agents.json` directly (via Read tool)
|
|
368
|
+
2. Claude reads `.morph/framework/standards/STANDARDS.json` for the standards registry
|
|
369
|
+
3. Claude matches the feature description keywords against each agent's `keywords[]` array in agents.json
|
|
370
|
+
4. Matched agents are added to state via `morph-spec state add-agent {f} {agent-id}`
|
|
371
|
+
5. Standards for active agents are loaded from `.morph/framework/standards/{path}` as needed
|
|
348
372
|
|
|
349
|
-
|
|
350
|
-
CHECK2 -->|yes| FORMAT
|
|
373
|
+
---
|
|
351
374
|
|
|
352
|
-
|
|
353
|
-
CHECK2 -->|no| L3_START["WebSearch — external sources"]
|
|
354
|
-
L3_START --> L3A["site:github.com/dotnet/aspnetcore ERROR\nsite:github.com/dotnet/efcore ERROR"]
|
|
355
|
-
L3_START --> L3B["site:stackoverflow.com blazor ERROR\nsite:stackoverflow.com azure ERROR"]
|
|
356
|
-
L3_START --> L3C["site:learn.microsoft.com ERROR\nsite:learn.microsoft.com/azure ERROR"]
|
|
357
|
-
L3A & L3B & L3C --> L3MERGE["Consolidate relevant links"]
|
|
358
|
-
end
|
|
375
|
+
## 12. Data Flow Diagram — A Single Task Cycle
|
|
359
376
|
|
|
360
|
-
|
|
377
|
+
```
|
|
378
|
+
Claude reads: 3-tasks/tasks.md → identifies T003
|
|
379
|
+
CLI: morph-spec task start f T003 → StateManager.updateTaskStatus('f','T003','in_progress')
|
|
380
|
+
.morph/state.json updated
|
|
381
|
+
|
|
382
|
+
Claude writes: src/Services/Foo.cs → [Hook: enforce-phase-writes.js fires]
|
|
383
|
+
Path outside .morph/features/? → passes
|
|
384
|
+
(source files are always allowed)
|
|
385
|
+
|
|
386
|
+
Claude runs: dotnet test → tests pass
|
|
387
|
+
|
|
388
|
+
CLI: morph-spec task done f T003 → StateManager.updateTaskStatus('f','T003','completed')
|
|
389
|
+
tasks.completed incremented
|
|
390
|
+
[Hook: dispatch.js fires on Bash PostToolUse]
|
|
391
|
+
completed=3, 3%3===0 → triggers:
|
|
392
|
+
morph-spec checkpoint-save f
|
|
393
|
+
StateManager.addCheckpoint('f', 'Auto #1 at T003')
|
|
394
|
+
```
|
|
361
395
|
|
|
362
|
-
|
|
363
|
-
FORMAT["formatResult(result, verbose)\nRoot cause + Solution + Fix code"] --> FSUM
|
|
364
|
-
FSUM["formatSummary(stats)\nTotal found per level (L1/L2/L3)"]
|
|
365
|
-
end
|
|
396
|
+
---
|
|
366
397
|
|
|
367
|
-
|
|
368
|
-
```
|
|
398
|
+
*morph-spec v4.8.1 by Polymorphism Tech*
|