@polymorphism-tech/morph-spec 4.8.1 → 4.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/hooks/dev/guard-version-numbers.js +1 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +1 -1
- package/package.json +4 -4
- package/.morph/analytics/threads-log.jsonl +0 -54
- package/.morph/state.json +0 -198
- package/docs/ARCHITECTURE.md +0 -328
- package/docs/COMMAND-FLOWS.md +0 -398
- package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -514
- package/docs/plans/2026-02-22-claude-settings.md +0 -517
- package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -730
- package/docs/plans/2026-02-22-morph-spec-next.md +0 -480
- package/docs/plans/2026-02-22-native-alignment-design.md +0 -201
- package/docs/plans/2026-02-22-native-alignment-impl.md +0 -927
- package/docs/plans/2026-02-22-native-enrichment-design.md +0 -246
- package/docs/plans/2026-02-22-native-enrichment.md +0 -737
- package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1155
- package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -684
- package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -439
- package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -157
- package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1256
- package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -150
- package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1848
- package/docs/plans/2026-02-24-cli-radical-simplification.md +0 -592
- package/docs/plans/2026-02-24-framework-failure-points.md +0 -125
- package/docs/plans/2026-02-24-morph-init-design.md +0 -337
- package/docs/plans/2026-02-24-morph-init-impl.md +0 -1269
- package/docs/plans/2026-02-24-tutorial-command-design.md +0 -71
- package/docs/plans/2026-02-24-tutorial-command.md +0 -298
- package/scripts/bump-version.js +0 -248
- package/scripts/generate-refs.js +0 -336
- package/scripts/generate-standards-registry.js +0 -44
- package/scripts/install-dev-hooks.js +0 -138
- package/scripts/scan-nextjs.mjs +0 -169
- package/scripts/validate-real.mjs +0 -255
package/docs/COMMAND-FLOWS.md
DELETED
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
# morph-spec — Framework Flows
|
|
2
|
-
|
|
3
|
-
> Authoritative reference for how the framework connects: slash commands → skills → CLI → state manager.
|
|
4
|
-
> Version: 4.8.1
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 1. Mental Model — The 4 Layers
|
|
9
|
-
|
|
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
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
**Hooks** run as side-effects alongside this chain (see Section 9).
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## 2. Slash Command → Skill Map
|
|
41
|
-
|
|
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 |
|
|
50
|
-
|
|
51
|
-
\* `phase-uiux` only if frontend agents are active.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## 3. Skill Invocation Chain
|
|
56
|
-
|
|
57
|
-
```mermaid
|
|
58
|
-
flowchart TD
|
|
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"])
|
|
83
|
-
```
|
|
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
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## 4. /morph-proposal — Detailed Flow
|
|
91
|
-
|
|
92
|
-
```mermaid
|
|
93
|
-
flowchart TD
|
|
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
|
|
108
|
-
|
|
109
|
-
GATE0 -->|approved| PHASE1
|
|
110
|
-
|
|
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
|
|
117
|
-
|
|
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"])
|
|
130
|
-
end
|
|
131
|
-
|
|
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
|
|
148
|
-
|
|
149
|
-
GATE2 -->|approved| PHASE3
|
|
150
|
-
|
|
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"]
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
C4 --> PHASE4
|
|
159
|
-
|
|
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"])
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
GATE4 --> END(["✅ Planning complete\nRun /morph-apply FEATURE"])
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## 5. /morph-apply — Detailed Flow
|
|
176
|
-
|
|
177
|
-
```mermaid
|
|
178
|
-
flowchart TD
|
|
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"]
|
|
187
|
-
end
|
|
188
|
-
|
|
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
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
MORETASKS -->|no| RECAP
|
|
208
|
-
|
|
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"]
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
ADVANCE --> END(["✅ Feature complete"])
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## 6. /morph-status — Flow
|
|
222
|
-
|
|
223
|
-
```mermaid
|
|
224
|
-
flowchart TD
|
|
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
|
-
```
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
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}` |
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
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 |
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## 9. Hook Event Chain
|
|
294
|
-
|
|
295
|
-
Hooks are configured in `.claude/settings.local.json`. All fail-open (catch + exit 0).
|
|
296
|
-
|
|
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}
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
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'` |
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## 11. Agent Detection — How It Actually Works
|
|
362
|
-
|
|
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.
|
|
364
|
-
|
|
365
|
-
The actual flow when agents are needed:
|
|
366
|
-
|
|
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
|
|
372
|
-
|
|
373
|
-
---
|
|
374
|
-
|
|
375
|
-
## 12. Data Flow Diagram — A Single Task Cycle
|
|
376
|
-
|
|
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
|
-
```
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
*morph-spec v4.8.1 by Polymorphism Tech*
|