@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.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/claude-plugin.json +1 -1
  3. package/docs/CHEATSHEET.md +1 -1
  4. package/docs/QUICKSTART.md +1 -1
  5. package/framework/hooks/dev/guard-version-numbers.js +1 -1
  6. package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +1 -1
  7. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +1 -1
  8. package/framework/skills/level-1-workflows/phase-design/SKILL.md +1 -1
  9. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +1 -1
  10. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +1 -1
  11. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +1 -1
  12. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +1 -1
  13. package/package.json +4 -4
  14. package/.morph/analytics/threads-log.jsonl +0 -54
  15. package/.morph/state.json +0 -198
  16. package/docs/ARCHITECTURE.md +0 -328
  17. package/docs/COMMAND-FLOWS.md +0 -398
  18. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -514
  19. package/docs/plans/2026-02-22-claude-settings.md +0 -517
  20. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -730
  21. package/docs/plans/2026-02-22-morph-spec-next.md +0 -480
  22. package/docs/plans/2026-02-22-native-alignment-design.md +0 -201
  23. package/docs/plans/2026-02-22-native-alignment-impl.md +0 -927
  24. package/docs/plans/2026-02-22-native-enrichment-design.md +0 -246
  25. package/docs/plans/2026-02-22-native-enrichment.md +0 -737
  26. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1155
  27. package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -684
  28. package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -439
  29. package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -157
  30. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1256
  31. package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -150
  32. package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1848
  33. package/docs/plans/2026-02-24-cli-radical-simplification.md +0 -592
  34. package/docs/plans/2026-02-24-framework-failure-points.md +0 -125
  35. package/docs/plans/2026-02-24-morph-init-design.md +0 -337
  36. package/docs/plans/2026-02-24-morph-init-impl.md +0 -1269
  37. package/docs/plans/2026-02-24-tutorial-command-design.md +0 -71
  38. package/docs/plans/2026-02-24-tutorial-command.md +0 -298
  39. package/scripts/bump-version.js +0 -248
  40. package/scripts/generate-refs.js +0 -336
  41. package/scripts/generate-standards-registry.js +0 -44
  42. package/scripts/install-dev-hooks.js +0 -138
  43. package/scripts/scan-nextjs.mjs +0 -169
  44. package/scripts/validate-real.mjs +0 -255
@@ -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*