@polymorphism-tech/morph-spec 4.11.0 → 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.
Files changed (34) hide show
  1. package/CLAUDE.md +106 -2
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +31 -3
  4. package/bin/task-manager.js +391 -35
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/commands/morph-apply.md +21 -1
  9. package/framework/commands/morph-proposal.md +44 -1
  10. package/framework/hooks/claude-code/post-tool-use/dispatch.js +47 -2
  11. package/framework/hooks/claude-code/session-start/inject-morph-context.js +4 -3
  12. package/framework/hooks/shared/dispatch-helpers.js +14 -0
  13. package/framework/hooks/shared/state-reader.js +7 -3
  14. package/framework/rules/morph-task-tracking.md +49 -0
  15. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +6 -10
  16. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +10 -1
  17. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +1 -1
  18. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +7 -13
  19. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +7 -1
  20. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +9 -12
  21. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +7 -10
  22. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +10 -18
  23. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +9 -1
  24. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  25. package/package.json +1 -1
  26. package/src/commands/agents/dispatch-agents.js +25 -1
  27. package/src/commands/tasks/task.js +54 -0
  28. package/src/lib/build/build-runner.js +99 -0
  29. package/src/lib/checkpoints/checkpoint-hooks.js +110 -0
  30. package/src/lib/generators/recap-generator.js +27 -4
  31. package/src/lib/stack/stack-profile.js +3 -0
  32. package/src/lib/tasks/task-parser.js +23 -9
  33. package/src/utils/file-copier.js +1 -0
  34. package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +0 -7
package/CLAUDE.md CHANGED
@@ -1,3 +1,107 @@
1
- # Project
1
+ # CLAUDE.md
2
2
 
3
- @.claude/CLAUDE.md
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What This Is
6
+
7
+ morph-spec is a spec-driven development framework CLI (`@polymorphism-tech/morph-spec`). It orchestrates AI-first feature development through structured phases with approval gates. This repo is the **framework source code** — not a project that uses morph-spec.
8
+
9
+ ## Build & Test Commands
10
+
11
+ ```bash
12
+ # Run all tests (sequential — required due to process.chdir state)
13
+ npm test
14
+
15
+ # Run a single test file
16
+ node --test test/commands/task-done.test.js
17
+
18
+ # Run tests matching a name pattern
19
+ node --test --test-name-pattern="should advance phase" test/commands/advance-phase.test.js
20
+
21
+ # Coverage
22
+ npm run test:coverage # text + html + lcov
23
+ npm run test:coverage:summary # text-summary only
24
+
25
+ # Generate JSDoc API docs
26
+ npm run docs
27
+
28
+ # Regenerate derived reference files from output-schema.js
29
+ npm run generate
30
+ ```
31
+
32
+ No build step — pure ESM JavaScript, runs directly via Node.js 18+.
33
+
34
+ ## Architecture
35
+
36
+ ### Module Layout
37
+
38
+ - **`bin/morph-spec.js`** — Commander.js CLI entry point. All commands registered here.
39
+ - **`src/commands/`** — CLI command handlers organized by domain (state/, tasks/, agents/, validation/, trust/, etc.)
40
+ - **`src/core/`** — Core domain logic (not CLI-coupled):
41
+ - `state/state-manager.js` — Atomic state I/O with process-ID temp files to prevent race conditions
42
+ - `paths/output-schema.js` — **Single source of truth** for all 15 output types, their filenames, phase directories, and gate associations
43
+ - `templates/` — Handlebars template registry and renderer
44
+ - `workflows/` — Workflow type detector (standard vs nodejs-cli)
45
+ - **`src/lib/`** — Libraries and subsystems:
46
+ - `validators/` — 25+ data-driven validators (architecture, blazor, css, design-system, nextjs, etc.)
47
+ - `generators/` — Code generation (design-system, context, recap, metadata)
48
+ - `trust/trust-manager.js` — 3-level trust model (manual/high/auto)
49
+ - `stack-filter.js` — Stack-aware asset filtering via YAML frontmatter `stacks:` tags
50
+ - `hooks/` — Hook executor
51
+ - `installers/` — Agents, skills, hooks installers for target projects
52
+ - **`src/utils/`** — Shared utilities (logger, banner, file-copier, claude-settings-manager, etc.)
53
+ - **`framework/`** — Metadata installed into target projects (READ-ONLY at runtime):
54
+ - `agents.json` (v4.0.0, 46 agents in 4 tiers)
55
+ - `phases.json` (8 phases + sync)
56
+ - `standards/STANDARDS.json` (86 entries)
57
+ - `hooks/claude-code/` — Hook scripts (10 hooks, fail-open design)
58
+ - `skills/` — Morph skills (level-0-meta + level-1-workflows)
59
+ - `templates/` — Handlebars templates for code generation
60
+
61
+ ### Key Architectural Patterns
62
+
63
+ **Dual-layer phase tracking:** Phase is derived from filesystem (`derivePhase()` scans for highest-numbered phase folder) — state.json only overrides for lightweight phases (setup, clarify, sync).
64
+
65
+ **Output schema as single source of truth:** `src/core/paths/output-schema.js` defines all output types. Run `npm run generate` after modifying it to update derived reference files.
66
+
67
+ **Data-driven validation:** `agents.json` lists validators per agent. The validation runner reads active agents from state and orchestrates only relevant validators.
68
+
69
+ **Fail-open hooks:** All hooks in `framework/hooks/claude-code/` check `stateExists()` first and return `{}` (empty/pass-through) if state is missing or corrupt. Hooks never throw or write state.
70
+
71
+ **Atomic state writes:** `state-manager.js` writes to a process-ID temp file then renames, preventing corruption from concurrent CLI invocations.
72
+
73
+ **Stack-aware filtering:** Assets declare `stacks: ['dotnet', 'blazor']` in YAML frontmatter. `setup-infra.js` reads `config.json → project.stack`, splits into tags, and installs only matching assets. `stacks: ['*']` = universal.
74
+
75
+ ### Phase Sequence
76
+
77
+ ```
78
+ proposal → setup → [uiux] → design → clarify → plan → tasks → implement → [sync]
79
+ ```
80
+
81
+ Phases in brackets are optional. Approval gates exist at: proposal, design, plan, tasks, uiux.
82
+
83
+ ### State Schema (v5.0.0)
84
+
85
+ State lives in `.morph/state.json` in target projects. Phase and outputs are **derived from filesystem**, not stored in state. State tracks: features (status, activeAgents, taskList, trustConfig, metadata), project info, and version.
86
+
87
+ ## Testing Conventions
88
+
89
+ - **Framework:** Node.js native `node:test` — no Jest or Mocha
90
+ - **Concurrency:** Always sequential (`--test-concurrency=1`) — tests use `process.chdir()`
91
+ - **Temp dirs:** Use `createTempDir()` / `cleanupTempDir()` from `test/helpers/test-utils.js` — creates dirs with `morph-test-` prefix
92
+ - **Mock state:** Use `createMockState(overrides)` and `createStateFile(tempDir, state)` from test-utils
93
+ - **Pattern:** Each test creates a temp dir, chdir into it, sets up mock state/filesystem, runs the function, asserts, then restores cwd and cleans up in afterEach
94
+
95
+ ## Code Conventions
96
+
97
+ - **ESM only** — all files use `import`/`export`, package.json has `"type": "module"`
98
+ - **Output type normalization** — `normalizeOutputType()` auto-converts kebab-case to camelCase via regex
99
+ - **Template helpers** — Handlebars v2.0 helpers: pascalCase, camelCase, snakeCase, kebabCase, pluralize, plus comparison/logic helpers
100
+ - **CLI structure** — Commands are thin wrappers that delegate to `src/core/` or `src/lib/` modules. Keep business logic out of command files.
101
+
102
+ ## Framework vs Runtime Distinction
103
+
104
+ - **This repo** (`morph-spec-framework/`) = the CLI tool source code
105
+ - **`framework/`** = files installed into target projects via `morph-spec init`
106
+ - **`framework/CLAUDE.md`** = the CLAUDE.md injected into target projects (not for this repo)
107
+ - When editing `framework/` files, you're changing what gets installed in user projects, not runtime behavior of the CLI itself
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > Spec-driven development framework for multi-stack projects. Turns feature requests into implementation-ready code through structured, AI-orchestrated phases.
4
4
 
5
5
  **Package:** `@polymorphism-tech/morph-spec`
6
- **Version:** 4.11.0
6
+ **Version:** 4.11.1
7
7
  **Requires:** Node.js 18+, Claude Code
8
8
 
9
9
  ---
@@ -370,4 +370,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
370
370
 
371
371
  ---
372
372
 
373
- *morph-spec v4.11.0 by [Polymorphism Tech](https://polymorphism.tech)*
373
+ *morph-spec v4.11.1 by [Polymorphism Tech](https://polymorphism.tech)*
package/bin/morph-spec.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { program } from 'commander';
4
4
  import chalk from 'chalk';
@@ -38,7 +38,7 @@ import {
38
38
  } from '../src/commands/agents/manage-agents.js';
39
39
 
40
40
  // Task commands
41
- import { taskDoneCommand, taskStartCommand, taskNextCommand } from '../src/commands/tasks/task.js';
41
+ import { taskDoneCommand, taskStartCommand, taskNextCommand, taskBulkStartCommand, taskBulkDoneCommand, taskAnnotateCommand } from '../src/commands/tasks/task.js';
42
42
 
43
43
  // Scope escalation commands
44
44
  import { scopeEscalateCommand } from '../src/commands/scope/escalate.js';
@@ -153,7 +153,9 @@ const taskCommand = program
153
153
  taskCommand
154
154
  .command('done <feature> <task-ids...>')
155
155
  .description('Mark tasks as completed (runs validation first)')
156
- .option('--skip-validation', 'Skip code validation (not recommended)')
156
+ .option('--note <text>', 'Add a deviation note explaining why task was done differently than planned')
157
+ .option('--skip-validation', 'Skip code validation (budget-limited, requires --reason)')
158
+ .option('--reason <text>', 'Reason for skipping validation (required with --skip-validation)')
157
159
  .option('--dry-run', 'Show validation results without marking tasks as complete')
158
160
  .action((feature, taskIds, options) => taskDoneCommand(feature, taskIds, options));
159
161
 
@@ -173,6 +175,32 @@ taskCommand
173
175
  .option('--into <subtasks...>', 'Sub-task definitions ("T017a: Title")')
174
176
  .action((feature, taskId, options) => taskExpandCommand(feature, taskId, options));
175
177
 
178
+ taskCommand
179
+ .command('bulk-start <feature> [range]')
180
+ .description('Start multiple tasks at once (mark as in_progress)')
181
+ .option('--all', 'Start all pending tasks with met dependencies')
182
+ .option('--from <id>', 'Start of task range (e.g. T007)')
183
+ .option('--to <id>', 'End of task range (e.g. T014)')
184
+ .action((feature, range, options) => taskBulkStartCommand(feature, range, options));
185
+
186
+ taskCommand
187
+ .command('bulk-done <feature> [range]')
188
+ .description('Complete multiple tasks with a single validation pass')
189
+ .option('--all', 'Complete all non-completed tasks')
190
+ .option('--from <id>', 'Start of task range (e.g. T007)')
191
+ .option('--to <id>', 'End of task range (e.g. T014)')
192
+ .option('--note <text>', 'Add a deviation note explaining why tasks were done differently than planned')
193
+ .option('--skip-validation', 'Skip code validation (budget-limited, requires --reason)')
194
+ .option('--reason <text>', 'Reason for skipping validation (required with --skip-validation)')
195
+ .option('--dry-run', 'Show validation results without marking tasks as complete')
196
+ .action((feature, range, options) => taskBulkDoneCommand(feature, range, options));
197
+
198
+ taskCommand
199
+ .command('annotate <feature> <task-id> <text>')
200
+ .description('Add a note to a task (deviation, context, or blocker resolution)')
201
+ .option('--type <type>', 'Note type: deviation | context | blocker-resolved', 'deviation')
202
+ .action((feature, taskId, text, options) => taskAnnotateCommand(feature, taskId, text, options));
203
+
176
204
  // Generation commands
177
205
  const generateCommand = program
178
206
  .command('generate')