@polymorphism-tech/morph-spec 4.7.2 → 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 (342) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +379 -414
  3. package/bin/morph-spec.js +57 -394
  4. package/bin/validate.js +2 -26
  5. package/claude-plugin.json +2 -2
  6. package/docs/CHEATSHEET.md +203 -221
  7. package/docs/QUICKSTART.md +2 -8
  8. package/framework/CLAUDE.md +1 -1
  9. package/framework/commands/morph-proposal.md +3 -3
  10. package/framework/hooks/README.md +2 -5
  11. package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +4 -55
  12. package/framework/hooks/claude-code/session-start/inject-morph-context.js +20 -5
  13. package/framework/hooks/claude-code/statusline.py +6 -1
  14. package/framework/hooks/dev/check-sync-health.js +117 -0
  15. package/framework/hooks/dev/guard-version-numbers.js +57 -0
  16. package/framework/hooks/dev/sync-standards-registry.js +60 -0
  17. package/framework/hooks/dev/sync-template-registry.js +60 -0
  18. package/framework/hooks/dev/validate-skill-format.js +70 -0
  19. package/framework/hooks/dev/validate-standard-format.js +73 -0
  20. package/framework/hooks/shared/payload-utils.js +39 -0
  21. package/framework/hooks/shared/state-reader.js +25 -1
  22. package/framework/rules/morph-workflow.md +1 -1
  23. package/framework/skills/level-0-meta/morph-init/SKILL.md +216 -0
  24. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
  25. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +4 -4
  26. package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
  27. package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +192 -191
  28. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +181 -180
  29. package/framework/skills/level-1-workflows/phase-design/SKILL.md +339 -338
  30. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +254 -253
  31. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +168 -170
  32. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +284 -283
  33. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +246 -245
  34. package/framework/templates/examples/design-system-examples.md +1 -1
  35. package/framework/templates/ui/FluentDesignTheme.cs +1 -1
  36. package/framework/templates/ui/MudTheme.cs +1 -1
  37. package/framework/templates/ui/design-system.css +1 -1
  38. package/package.json +7 -5
  39. package/src/commands/agents/index.js +1 -2
  40. package/src/commands/index.js +13 -16
  41. package/src/commands/project/doctor.js +100 -14
  42. package/src/commands/project/index.js +7 -10
  43. package/src/commands/project/init.js +398 -528
  44. package/src/commands/project/install-plugin-cmd.js +28 -0
  45. package/src/commands/project/setup-infra-cmd.js +12 -0
  46. package/src/commands/project/tutorial.js +115 -0
  47. package/src/commands/state/approve.js +213 -221
  48. package/src/commands/state/index.js +0 -1
  49. package/src/commands/state/state.js +337 -365
  50. package/src/commands/templates/index.js +0 -4
  51. package/src/commands/trust/trust.js +1 -93
  52. package/src/commands/utils/index.js +1 -5
  53. package/src/commands/validation/index.js +1 -5
  54. package/src/core/registry/command-registry.js +11 -285
  55. package/src/core/state/state-manager.js +5 -2
  56. package/src/lib/detectors/index.js +81 -87
  57. package/src/lib/detectors/structure-detector.js +275 -273
  58. package/src/lib/generators/recap-generator.js +232 -225
  59. package/src/scripts/global-install.js +34 -0
  60. package/src/scripts/install-plugin.js +126 -0
  61. package/src/scripts/setup-infra.js +203 -0
  62. package/src/utils/agents-installer.js +10 -1
  63. package/src/utils/hooks-installer.js +66 -3
  64. package/.morph/.morphversion +0 -5
  65. package/.morph/analytics/threads-log.jsonl +0 -5
  66. package/.morph/config/config.json +0 -8
  67. package/.morph/framework/agents.json +0 -1815
  68. package/.morph/framework/hooks/README.md +0 -205
  69. package/.morph/framework/hooks/claude-code/notification/approval-reminder.js +0 -54
  70. package/.morph/framework/hooks/claude-code/post-tool-use/dispatch.js +0 -83
  71. package/.morph/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +0 -42
  72. package/.morph/framework/hooks/claude-code/pre-compact/save-morph-context.js +0 -61
  73. package/.morph/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +0 -71
  74. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +0 -58
  75. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +0 -64
  76. package/.morph/framework/hooks/claude-code/session-start/inject-morph-context.js +0 -94
  77. package/.morph/framework/hooks/claude-code/statusline.py +0 -538
  78. package/.morph/framework/hooks/claude-code/statusline.sh +0 -7
  79. package/.morph/framework/hooks/claude-code/stop/validate-completion.js +0 -88
  80. package/.morph/framework/hooks/claude-code/user-prompt/enrich-prompt.js +0 -91
  81. package/.morph/framework/hooks/git/commit-msg/conventional-commits.sh +0 -33
  82. package/.morph/framework/hooks/git/pre-commit/agents.sh +0 -25
  83. package/.morph/framework/hooks/git/pre-commit/orchestrator.sh +0 -64
  84. package/.morph/framework/hooks/git/pre-commit/specs.sh +0 -50
  85. package/.morph/framework/hooks/git/pre-push/run-tests.sh +0 -44
  86. package/.morph/framework/hooks/shared/hook-response.js +0 -45
  87. package/.morph/framework/hooks/shared/phase-utils.js +0 -129
  88. package/.morph/framework/hooks/shared/state-reader.js +0 -138
  89. package/.morph/framework/hooks/shared/stdin-reader.js +0 -26
  90. package/.morph/framework/standards/STANDARDS.json +0 -933
  91. package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
  92. package/.morph/framework/standards/ai-agents/production.md +0 -415
  93. package/.morph/framework/standards/ai-agents/setup.md +0 -418
  94. package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
  95. package/.morph/framework/standards/ai-agents/workflows.md +0 -354
  96. package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
  97. package/.morph/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  98. package/.morph/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  99. package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
  100. package/.morph/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  101. package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
  102. package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
  103. package/.morph/framework/standards/backend/api/rest.md +0 -492
  104. package/.morph/framework/standards/backend/api/validation.md +0 -88
  105. package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
  106. package/.morph/framework/standards/backend/database/ef-core.md +0 -199
  107. package/.morph/framework/standards/backend/database/migrations.md +0 -393
  108. package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
  109. package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
  110. package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
  111. package/.morph/framework/standards/backend/dotnet/async.md +0 -366
  112. package/.morph/framework/standards/backend/dotnet/core.md +0 -117
  113. package/.morph/framework/standards/backend/dotnet/di.md +0 -439
  114. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  115. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
  116. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
  117. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
  118. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
  119. package/.morph/framework/standards/context/analytics.md +0 -96
  120. package/.morph/framework/standards/context/bundles.md +0 -110
  121. package/.morph/framework/standards/context/priming.md +0 -78
  122. package/.morph/framework/standards/core/architecture.md +0 -185
  123. package/.morph/framework/standards/core/coding.md +0 -214
  124. package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
  125. package/.morph/framework/standards/core/git.md +0 -185
  126. package/.morph/framework/standards/core/testing.md +0 -295
  127. package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
  128. package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
  129. package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
  130. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  131. package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
  132. package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
  133. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  134. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  135. package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
  136. package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
  137. package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
  138. package/.morph/framework/standards/frontend/blazor/state.md +0 -191
  139. package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
  140. package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
  141. package/.morph/framework/standards/frontend/nextjs/app-router.md +0 -123
  142. package/.morph/framework/standards/frontend/nextjs/components.md +0 -132
  143. package/.morph/framework/standards/frontend/nextjs/data-fetching.md +0 -126
  144. package/.morph/framework/standards/frontend/nextjs/forms.md +0 -128
  145. package/.morph/framework/standards/frontend/nextjs/naming-conventions.md +0 -67
  146. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -215
  147. package/.morph/framework/standards/frontend/nextjs/project-structure.md +0 -102
  148. package/.morph/framework/standards/frontend/nextjs/state-management.md +0 -72
  149. package/.morph/framework/standards/frontend/nextjs/testing.md +0 -111
  150. package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
  151. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  152. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  153. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  154. package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
  155. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  156. package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
  157. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
  158. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
  159. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  160. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  161. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  162. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
  163. package/.morph/framework/standards/integration/api/graphql.md +0 -91
  164. package/.morph/framework/standards/integration/api/grpc.md +0 -114
  165. package/.morph/framework/standards/integration/api/rest-design.md +0 -95
  166. package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
  167. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  168. package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
  169. package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
  170. package/.morph/framework/standards/observability/logging.md +0 -131
  171. package/.morph/framework/standards/observability/metrics.md +0 -121
  172. package/.morph/framework/standards/observability/monitoring.md +0 -114
  173. package/.morph/framework/standards/observability/tracing.md +0 -132
  174. package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
  175. package/.morph/framework/standards/workflows/thread-management.md +0 -113
  176. package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
  177. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  178. package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
  179. package/.morph/framework/templates/README.md +0 -814
  180. package/.morph/framework/templates/REGISTRY.json +0 -1888
  181. package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
  182. package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
  183. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  184. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  185. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  186. package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
  187. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  188. package/.morph/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  189. package/.morph/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  190. package/.morph/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  191. package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
  192. package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
  193. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
  194. package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
  195. package/.morph/framework/templates/code/dotnet/test.cs +0 -239
  196. package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
  197. package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
  198. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
  199. package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
  200. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
  201. package/.morph/framework/templates/context/CONTEXT.md +0 -181
  202. package/.morph/framework/templates/docs/clarifications.md +0 -253
  203. package/.morph/framework/templates/docs/onboarding.md +0 -123
  204. package/.morph/framework/templates/docs/proposal.md +0 -182
  205. package/.morph/framework/templates/docs/schema-analysis.md +0 -119
  206. package/.morph/framework/templates/docs/spec.md +0 -198
  207. package/.morph/framework/templates/docs/ui-components.md +0 -124
  208. package/.morph/framework/templates/docs/ui-design-system.md +0 -76
  209. package/.morph/framework/templates/docs/ui-flows.md +0 -167
  210. package/.morph/framework/templates/docs/ui-mockups.md +0 -98
  211. package/.morph/framework/templates/docs/user-stories.md +0 -34
  212. package/.morph/framework/templates/examples/design-system-examples.md +0 -357
  213. package/.morph/framework/templates/examples/spec-examples.md +0 -90
  214. package/.morph/framework/templates/feature/decisions.md +0 -187
  215. package/.morph/framework/templates/feature/recap.md +0 -146
  216. package/.morph/framework/templates/feature/tasks.md +0 -199
  217. package/.morph/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +0 -43
  218. package/.morph/framework/templates/frontend/nextjs/client-component.tsx.hbs +0 -26
  219. package/.morph/framework/templates/frontend/nextjs/env.mjs.hbs +0 -32
  220. package/.morph/framework/templates/frontend/nextjs/feature-form.tsx.hbs +0 -56
  221. package/.morph/framework/templates/frontend/nextjs/page.tsx.hbs +0 -22
  222. package/.morph/framework/templates/frontend/nextjs/tsconfig.json.hbs +0 -26
  223. package/.morph/framework/templates/frontend/nextjs/use-feature.ts.hbs +0 -54
  224. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  225. package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
  226. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  227. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  228. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  229. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  230. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  231. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  232. package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
  233. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  234. package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
  235. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  236. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  237. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  238. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  239. package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
  240. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
  241. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
  242. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
  243. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
  244. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
  245. package/.morph/framework/templates/infrastructure/github/README.md +0 -593
  246. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  247. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
  248. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
  249. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  250. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
  251. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
  252. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
  253. package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
  254. package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
  255. package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
  256. package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
  257. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
  258. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
  259. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  260. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  261. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  262. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  263. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  264. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
  265. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
  266. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
  267. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
  268. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
  269. package/.morph/framework/templates/project-structure/dotnet-ddd.md +0 -70
  270. package/.morph/framework/templates/saas/subscription.cs +0 -347
  271. package/.morph/framework/templates/saas/tenant.cs +0 -338
  272. package/.morph/framework/templates/state.template.json +0 -17
  273. package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
  274. package/.morph/framework/templates/ui/MudTheme.cs +0 -281
  275. package/.morph/framework/templates/ui/design-system.css +0 -226
  276. package/.morph/logs/tool-failures.log +0 -17
  277. package/.morph/memory/pre-compact-2026-02-24T17-43-30-049Z.json +0 -16
  278. package/.morph/plans/eager-watching-bunny.md +0 -105
  279. package/.morph/plans/temporal-seeking-nebula.md +0 -45
  280. package/.morph/state.json +0 -48
  281. package/CLAUDE.md +0 -77
  282. package/docs/ARCHITECTURE.md +0 -331
  283. package/docs/COMMAND-FLOWS.md +0 -368
  284. package/docs/claude-alignment-report.md +0 -137
  285. package/docs/examples/order-management/contracts.cs +0 -84
  286. package/docs/examples/order-management/proposal.md +0 -24
  287. package/docs/examples/order-management/spec.md +0 -162
  288. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -512
  289. package/docs/plans/2026-02-22-claude-settings.md +0 -515
  290. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -728
  291. package/docs/plans/2026-02-22-morph-spec-next.md +0 -478
  292. package/docs/plans/2026-02-22-native-alignment-design.md +0 -199
  293. package/docs/plans/2026-02-22-native-alignment-impl.md +0 -925
  294. package/docs/plans/2026-02-22-native-enrichment-design.md +0 -244
  295. package/docs/plans/2026-02-22-native-enrichment.md +0 -735
  296. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1153
  297. package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -682
  298. package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -437
  299. package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -156
  300. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1254
  301. package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -149
  302. package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1846
  303. package/scripts/generate-refs.js +0 -336
  304. package/scripts/generate-standards-registry.js +0 -44
  305. package/scripts/scan-nextjs.mjs +0 -169
  306. package/scripts/validate-real.mjs +0 -255
  307. package/src/commands/feature/create-story.js +0 -362
  308. package/src/commands/feature/index.js +0 -6
  309. package/src/commands/feature/shard-spec.js +0 -225
  310. package/src/commands/feature/sprint-status.js +0 -250
  311. package/src/commands/generation/generate-onboarding.js +0 -169
  312. package/src/commands/generation/generate.js +0 -276
  313. package/src/commands/generation/index.js +0 -5
  314. package/src/commands/learning/capture-pattern.js +0 -121
  315. package/src/commands/learning/index.js +0 -5
  316. package/src/commands/learning/search-patterns.js +0 -126
  317. package/src/commands/mcp/mcp.js +0 -102
  318. package/src/commands/project/changes.js +0 -66
  319. package/src/commands/project/cost.js +0 -179
  320. package/src/commands/project/diff.js +0 -278
  321. package/src/commands/project/revert.js +0 -173
  322. package/src/commands/project/standards.js +0 -80
  323. package/src/commands/project/sync.js +0 -167
  324. package/src/commands/project/update-agents.js +0 -23
  325. package/src/commands/state/rollback-phase.js +0 -185
  326. package/src/commands/templates/template-customize.js +0 -87
  327. package/src/commands/templates/template-list.js +0 -114
  328. package/src/commands/templates/template-show.js +0 -129
  329. package/src/commands/templates/template-validate.js +0 -91
  330. package/src/commands/utils/troubleshoot.js +0 -222
  331. package/src/commands/validation/analyze-blazor-concurrency.js +0 -193
  332. package/src/commands/validation/lint-fluent.js +0 -352
  333. package/src/commands/validation/validate-blazor-state.js +0 -210
  334. package/src/commands/validation/validate-blazor.js +0 -156
  335. package/src/commands/validation/validate-css.js +0 -84
  336. package/src/lib/detectors/conversation-analyzer.js +0 -163
  337. package/src/lib/learning/index.js +0 -7
  338. package/src/lib/learning/learning-system.js +0 -520
  339. package/src/lib/troubleshooting/index.js +0 -8
  340. package/src/lib/troubleshooting/troubleshoot-grep.js +0 -198
  341. package/src/lib/troubleshooting/troubleshoot-index.js +0 -144
  342. package/src/llm/environment-detector.js +0 -43
@@ -1,925 +0,0 @@
1
- # Native Alignment Implementation Plan
2
-
3
- > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
-
5
- **Goal:** Align MORPH-SPEC with Claude Code's native platform patterns across 6 areas: skills format, rules as @-imports, CLAUDE.md consolidation, test file policy, standards additions, and state.json simplification.
6
-
7
- **Architecture:** Non-breaking changes first (Tasks 1-5), state.json simplification last (Tasks 6-8). All 614 existing tests must pass at each commit. Each task is independently testable.
8
-
9
- **Tech Stack:** Node.js ESM, `node:test`, `node:fs`, `node:path`. Run tests with `npm test`. Single test file: `node --test test/path/to/file.test.js`.
10
-
11
- ---
12
-
13
- ## Task 1: Fix Skills File Format (flat → subdirectory/SKILL.md)
14
-
15
- **Files:**
16
- - Modify: `src/utils/skills-installer.js`
17
- - Modify: `test/utils/skills-installer.test.js`
18
-
19
- **Context:** Claude Code's native skill format is `.claude/skills/<name>/SKILL.md`, not `.claude/skills/<name>.md`. Flat files prevent frontmatter features (allowed-tools, argument-hint) from working. Current code in `installSkillsFromDir()` does `copyFileSync(srcPath, join(destDir, entry))` — we change it to `mkdir(join(destDir, skillName))` + `copyFile(srcPath, join(destDir, skillName, 'SKILL.md'))`.
20
-
21
- **Step 1: Update skills-installer.js**
22
-
23
- Replace the body of `installSkillsFromDir` in `src/utils/skills-installer.js`:
24
-
25
- ```javascript
26
- function installSkillsFromDir(srcDir, destDir) {
27
- const entries = readdirSync(srcDir);
28
- for (const entry of entries) {
29
- const srcPath = join(srcDir, entry);
30
- const stat = statSync(srcPath);
31
-
32
- if (stat.isDirectory()) {
33
- installSkillsFromDir(srcPath, destDir);
34
- } else if (entry.endsWith('.md') && entry !== 'README.md') {
35
- const skillName = entry.slice(0, -3); // strip .md
36
- const skillDir = join(destDir, skillName);
37
- mkdirSync(skillDir, { recursive: true });
38
- copyFileSync(srcPath, join(skillDir, 'SKILL.md'));
39
- }
40
- }
41
- }
42
- ```
43
-
44
- Also add `mkdirSync` to the imports at line 11:
45
- ```javascript
46
- import { mkdirSync, copyFileSync, existsSync, readdirSync, statSync } from 'fs';
47
- ```
48
- (mkdirSync is already imported — verify it's there, add if missing)
49
-
50
- **Step 2: Run single test file to verify it fails**
51
-
52
- ```bash
53
- node --test test/utils/skills-installer.test.js
54
- ```
55
-
56
- Expected: FAIL — assertions check for `.md` filenames like `morph-checklist.md` which no longer exist.
57
-
58
- **Step 3: Update skills-installer.test.js**
59
-
60
- Replace the entire test file content:
61
-
62
- ```javascript
63
- /**
64
- * Tests for src/utils/skills-installer.js
65
- */
66
-
67
- import { test, describe, before, after } from 'node:test';
68
- import assert from 'node:assert/strict';
69
- import { mkdtemp, rm, readdir, stat } from 'node:fs/promises';
70
- import { join } from 'path';
71
- import { tmpdir } from 'os';
72
- import { installSkills } from '../../src/utils/skills-installer.js';
73
-
74
- describe('installSkills', () => {
75
- let tmpDir;
76
-
77
- before(async () => {
78
- tmpDir = await mkdtemp(join(tmpdir(), 'morph-skills-'));
79
- });
80
-
81
- after(async () => {
82
- await rm(tmpDir, { recursive: true, force: true });
83
- });
84
-
85
- test('creates .claude/skills/ directory', async () => {
86
- await installSkills(tmpDir);
87
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
88
- assert.ok(entries.length > 0, 'should have skill directories installed');
89
- });
90
-
91
- test('installs skills as subdirectories (not flat .md files)', async () => {
92
- await installSkills(tmpDir);
93
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
94
- // All entries should be directories, not .md files
95
- for (const entry of entries) {
96
- assert.ok(!entry.endsWith('.md'), `${entry} should be a directory, not a flat .md file`);
97
- }
98
- });
99
-
100
- test('each skill directory contains SKILL.md', async () => {
101
- await installSkills(tmpDir);
102
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
103
- for (const entry of entries) {
104
- const skillMd = join(tmpDir, '.claude', 'skills', entry, 'SKILL.md');
105
- const s = await stat(skillMd).catch(() => null);
106
- assert.ok(s?.isFile(), `${entry}/SKILL.md should exist and be a file`);
107
- }
108
- });
109
-
110
- test('installs level-0-meta skills (morph-checklist, code-review)', async () => {
111
- await installSkills(tmpDir);
112
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
113
- assert.ok(entries.includes('morph-checklist'), 'morph-checklist/ directory should be installed');
114
- assert.ok(entries.includes('code-review'), 'code-review/ directory should be installed');
115
- });
116
-
117
- test('installs level-1-workflows skills (phase-design, phase-implement)', async () => {
118
- await installSkills(tmpDir);
119
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
120
- assert.ok(entries.includes('phase-design'), 'phase-design/ directory should be installed');
121
- assert.ok(entries.includes('phase-implement'), 'phase-implement/ directory should be installed');
122
- });
123
-
124
- test('does not install README.md files as skills', async () => {
125
- await installSkills(tmpDir);
126
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
127
- assert.ok(!entries.includes('README'), 'README should not be installed as a skill');
128
- assert.ok(!entries.includes('README.md'), 'README.md should not appear in skills dir');
129
- });
130
-
131
- test('installs at least 10 skills total', async () => {
132
- await installSkills(tmpDir);
133
- const entries = await readdir(join(tmpDir, '.claude', 'skills'));
134
- assert.ok(entries.length >= 10, `should install at least 10 skills, got ${entries.length}`);
135
- });
136
-
137
- test('is idempotent — running twice produces same directory count', async () => {
138
- await installSkills(tmpDir);
139
- const firstCount = (await readdir(join(tmpDir, '.claude', 'skills'))).length;
140
- await installSkills(tmpDir);
141
- const secondCount = (await readdir(join(tmpDir, '.claude', 'skills'))).length;
142
- assert.strictEqual(firstCount, secondCount, 'directory count should not change on second run');
143
- });
144
- });
145
- ```
146
-
147
- **Step 4: Run test to verify it passes**
148
-
149
- ```bash
150
- node --test test/utils/skills-installer.test.js
151
- ```
152
-
153
- Expected: all 8 tests PASS.
154
-
155
- **Step 5: Run full suite**
156
-
157
- ```bash
158
- npm test
159
- ```
160
-
161
- Expected: 614+ tests pass, 0 fail.
162
-
163
- **Step 6: Commit**
164
-
165
- ```bash
166
- git add src/utils/skills-installer.js test/utils/skills-installer.test.js
167
- git commit -m "feat(skills): install as subdirectory/SKILL.md — native Claude Code format"
168
- ```
169
-
170
- ---
171
-
172
- ## Task 2: Rules as Dynamic @-imports
173
-
174
- **Files:**
175
- - Modify: `framework/rules/csharp-standards.md`
176
- - Modify: `framework/rules/frontend-standards.md`
177
- - Modify: `framework/rules/testing-standards.md`
178
- - Modify: `framework/rules/infrastructure-standards.md`
179
-
180
- **Context:** Rules currently contain static copies of standards content. Replacing with @-imports makes them always current. The @-import paths use `.morph/framework/standards/` because rules are installed into user projects where that path is valid after `morph-spec init`. `morph-workflow.md` is NOT changed here — it has its own content (not a standards file).
181
-
182
- No code changes — only markdown content changes. No tests needed (framework content files have no unit tests).
183
-
184
- **Step 1: Replace csharp-standards.md body**
185
-
186
- Replace everything after the frontmatter (after line 5 `---`) in `framework/rules/csharp-standards.md` with:
187
-
188
- ```markdown
189
- ---
190
- paths:
191
- - "**/*.cs"
192
- - "**/*.csproj"
193
- ---
194
-
195
- # C# and .NET Standards
196
-
197
- @.morph/framework/standards/core/coding.md
198
- @.morph/framework/standards/backend/dotnet.md
199
- ```
200
-
201
- > **Note:** Verify the exact filenames exist in `framework/standards/core/` and `framework/standards/backend/`. Run `ls framework/standards/core/` and `ls framework/standards/backend/` first. Use the actual filenames found.
202
-
203
- **Step 2: Replace frontend-standards.md body**
204
-
205
- ```markdown
206
- ---
207
- paths:
208
- - "**/*.razor"
209
- - "**/*.tsx"
210
- - "**/*.ts"
211
- - "**/*.css"
212
- - "**/*.scss"
213
- ---
214
-
215
- # Frontend Standards
216
-
217
- @.morph/framework/standards/frontend/blazor.md
218
- @.morph/framework/standards/frontend/nextjs.md
219
- @.morph/framework/standards/frontend/css.md
220
- ```
221
-
222
- > Same note: verify filenames first with `ls framework/standards/frontend/`.
223
-
224
- **Step 3: Replace testing-standards.md body**
225
-
226
- ```markdown
227
- ---
228
- paths:
229
- - "tests/**"
230
- - "**/*.test.*"
231
- - "**/*.spec.*"
232
- - "**/*Tests.cs"
233
- ---
234
-
235
- # Testing Standards
236
-
237
- @.morph/framework/standards/core/testing.md
238
- ```
239
-
240
- **Step 4: Replace infrastructure-standards.md body**
241
-
242
- ```markdown
243
- ---
244
- paths:
245
- - "**/*.bicep"
246
- - "**/Dockerfile"
247
- - "**/docker-compose*.yml"
248
- - "**/pipelines/**"
249
- - "**/.github/workflows/**"
250
- ---
251
-
252
- # Infrastructure Standards
253
-
254
- @.morph/framework/standards/infrastructure/azure.md
255
- @.morph/framework/standards/infrastructure/docker.md
256
- ```
257
-
258
- **Step 5: Verify actual standard filenames before writing**
259
-
260
- ```bash
261
- ls framework/standards/core/
262
- ls framework/standards/backend/
263
- ls framework/standards/frontend/
264
- ls framework/standards/infrastructure/
265
- ```
266
-
267
- Adjust @-import paths above to match actual filenames.
268
-
269
- **Step 6: Run full suite (no tests for framework content, but verify nothing broke)**
270
-
271
- ```bash
272
- npm test
273
- ```
274
-
275
- Expected: same pass count as before.
276
-
277
- **Step 7: Commit**
278
-
279
- ```bash
280
- git add framework/rules/csharp-standards.md framework/rules/frontend-standards.md framework/rules/testing-standards.md framework/rules/infrastructure-standards.md
281
- git commit -m "feat(rules): replace static content with @-imports from framework/standards"
282
- ```
283
-
284
- ---
285
-
286
- ## Task 3: CLAUDE.md Consolidation
287
-
288
- **Files:**
289
- - Modify: `framework/CLAUDE.md` — merge both files into one
290
- - Delete: `framework/CLAUDE_runtime.md`
291
- - Modify: `src/commands/project/init.js` — change CLAUDE_runtime.md → CLAUDE.md as source
292
- - Modify: `src/commands/project/update.js` — same
293
- - Modify: `test/commands/init.test.js` — update source file reference
294
- - Modify: `test/commands/update.test.js` — update source file reference
295
-
296
- **Context:** `init.js` copies `framework/CLAUDE_runtime.md` → `.claude/CLAUDE.md` in user projects. After this task, it copies `framework/CLAUDE.md` instead. The merged file has all content from both plus MCP deferred mode note.
297
-
298
- **Step 1: Find the CLAUDE_runtime.md copy line in init.js**
299
-
300
- ```bash
301
- grep -n "CLAUDE_runtime" src/commands/project/init.js
302
- grep -n "CLAUDE_runtime" src/commands/project/update.js
303
- ```
304
-
305
- Note the exact line numbers.
306
-
307
- **Step 2: Write new merged framework/CLAUDE.md**
308
-
309
- Replace the entire content of `framework/CLAUDE.md`:
310
-
311
- ```markdown
312
- # MORPH-SPEC Runtime Instructions
313
-
314
- > by Polymorphism Tech — Spec-driven development for .NET/Blazor/Next.js/Azure
315
-
316
- ---
317
-
318
- ## Project Context
319
-
320
- @.morph/context/README.md
321
-
322
- ---
323
-
324
- ## Critical Rules
325
-
326
- **NEVER:**
327
- - Skip to code without a specification
328
- - Implement without design approval
329
- - Ignore standards in `.morph/framework/standards/`
330
- - Create infrastructure manually
331
- - Generate code without defined contracts
332
-
333
- **ALWAYS:**
334
- - Follow the mandatory phases
335
- - Generate outputs in `.morph/features/{feature}/`
336
- - Document decisions in `decisions.md`
337
- - Checkpoint every 3 implemented tasks
338
- - Use Infrastructure as Code
339
-
340
- ---
341
-
342
- ## Quick Reference
343
-
344
- | Command | Purpose |
345
- |---------|---------|
346
- | `/morph-proposal {feature}` | Full spec pipeline (phases 1–4, pauses for approval) |
347
- | `/morph-apply {feature}` | Implement feature (phase 5) |
348
- | `/morph-status` | Feature status dashboard |
349
- | `/morph-preflight` | Pre-implementation validation |
350
-
351
- ---
352
-
353
- ## State & Outputs
354
-
355
- | Path | Notes |
356
- |------|-------|
357
- | `.morph/state.json` | **READ-ONLY** — use `morph-spec` CLI to update |
358
- | `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
359
- | `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
360
- | `.morph/config/config.json` | Project configuration (editable) |
361
-
362
- ---
363
-
364
- ## Phase Sequence
365
-
366
- ```
367
- proposal → setup → [uiux] → design → clarify → tasks → implement → [sync]
368
- ```
369
-
370
- Use `morph-spec state show {feature}` to see current phase and pending approval gates.
371
-
372
- ---
373
-
374
- ## Agents
375
-
376
- Tier-1 and tier-2 MORPH agents are available as native subagents in `.claude/agents/`.
377
- They can be invoked directly by Claude Code during multi-agent workflows.
378
-
379
- ---
380
-
381
- ## Context Window Tip
382
-
383
- When using 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to `.claude/settings.json`.
384
- MCP tools load on-demand instead of all at startup — keeps context clean for actual work.
385
-
386
- ---
387
-
388
- *MORPH-SPEC v4.5.0 by Polymorphism Tech*
389
- ```
390
-
391
- **Step 3: Update init.js source reference**
392
-
393
- Find the line that copies CLAUDE_runtime.md and change it to CLAUDE.md. It will look something like:
394
-
395
- ```javascript
396
- // BEFORE (find exact line with grep result from Step 1):
397
- await copyFile(join(frameworkDir, 'CLAUDE_runtime.md'), join(projectDir, '.claude', 'CLAUDE.md'));
398
-
399
- // AFTER:
400
- await copyFile(join(frameworkDir, 'CLAUDE.md'), join(projectDir, '.claude', 'CLAUDE.md'));
401
- ```
402
-
403
- **Step 4: Update update.js source reference**
404
-
405
- Same change in `src/commands/project/update.js`.
406
-
407
- **Step 5: Run test files to find failing assertions**
408
-
409
- ```bash
410
- node --test test/commands/init.test.js
411
- node --test test/commands/update.test.js
412
- ```
413
-
414
- Find any assertions referencing `CLAUDE_runtime.md` and change them to `CLAUDE.md`.
415
-
416
- **Step 6: Delete framework/CLAUDE_runtime.md**
417
-
418
- ```bash
419
- git rm framework/CLAUDE_runtime.md
420
- ```
421
-
422
- **Step 7: Run full suite**
423
-
424
- ```bash
425
- npm test
426
- ```
427
-
428
- Expected: same pass count, 0 fail.
429
-
430
- **Step 8: Commit**
431
-
432
- ```bash
433
- git add framework/CLAUDE.md src/commands/project/init.js src/commands/project/update.js test/commands/init.test.js test/commands/update.test.js
434
- git commit -m "feat(claude-md): merge CLAUDE.md + CLAUDE_runtime.md into single unified file"
435
- ```
436
-
437
- ---
438
-
439
- ## Task 4: Test File Policy in morph-workflow.md
440
-
441
- **Files:**
442
- - Modify: `framework/rules/morph-workflow.md`
443
-
444
- **Context:** No hook — behavioral guidance only. Add "Test File Policy" section at the end of the file (before the final `*MORPH-SPEC by Polymorphism Tech*` footer). No tests needed.
445
-
446
- **Step 1: Add section to framework/rules/morph-workflow.md**
447
-
448
- Append before the final footer line:
449
-
450
- ```markdown
451
- ---
452
-
453
- ## Test File Policy
454
-
455
- When a test fails, always follow this order:
456
-
457
- 1. **Analyze first** — determine if the IMPLEMENTATION is wrong or the TEST SPEC is wrong
458
- 2. **Fix implementation first** — the test is the spec; trust it by default
459
- 3. **Only modify a test file if the test expectation itself is incorrect** — wrong expected value, wrong behavior modeled
460
- 4. **Before modifying any test file, explain WHY the test spec is wrong** — what the correct behavior is and why the test doesn't model it
461
-
462
- Do not modify test files to make a failing test pass when the implementation is the actual problem.
463
-
464
- ---
465
- ```
466
-
467
- **Step 2: Run full suite**
468
-
469
- ```bash
470
- npm test
471
- ```
472
-
473
- Expected: same pass count.
474
-
475
- **Step 3: Commit**
476
-
477
- ```bash
478
- git add framework/rules/morph-workflow.md
479
- git commit -m "feat(rules): add Test File Policy to morph-workflow rule"
480
- ```
481
-
482
- ---
483
-
484
- ## Task 5: Standards and Templates Additions
485
-
486
- **Files:**
487
- - Modify: `framework/rules/frontend-standards.md` — note: already updated in Task 2 with @-imports, so also update the source standard file
488
- - Create: `framework/templates/docs/user-stories.md`
489
-
490
- **Context:** TypeScript strict mode guidance goes into the actual standards file (which the rule now @-imports). User stories template is a new Handlebars template.
491
-
492
- **Step 1: Check if TypeScript strict is already in frontend standards**
493
-
494
- ```bash
495
- grep -r "strict" framework/standards/frontend/
496
- ```
497
-
498
- If not present, add to the appropriate standards file (e.g., `framework/standards/frontend/typescript.md` or whatever file exists):
499
-
500
- ```markdown
501
- ## TypeScript Strict Mode (Required)
502
-
503
- Always enable `"strict": true` in `tsconfig.json`. This is non-negotiable for
504
- agent-assisted development because agents rely on compiler errors to self-correct.
505
- Without strict mode, type/null errors only surface at runtime where agents cannot observe them.
506
-
507
- ```json
508
- {
509
- "compilerOptions": {
510
- "strict": true,
511
- "noUncheckedIndexedAccess": true
512
- }
513
- }
514
- ```
515
-
516
- Strict mode enables: `strictNullChecks`, `noImplicitAny`, `strictFunctionTypes`, `strictPropertyInitialization`.
517
- ```
518
-
519
- **Step 2: Create framework/templates/docs/user-stories.md**
520
-
521
- ```markdown
522
- # User Stories: {{featureName}}
523
-
524
- > Generated: {{date}} | Feature: {{featureName}} | Status: Draft
525
-
526
- ---
527
-
528
- ## Story 1: [Actor] [Action]
529
-
530
- **Feature:** {{featureName}}
531
- **Priority:** High / Medium / Low
532
-
533
- ### Optimal Path
534
- 1. [Step 1]
535
- 2. [Step 2]
536
- 3. [Step 3 — success state]
537
-
538
- ### Edge Cases
539
- - [Edge case] → [Expected behavior]
540
- - [Error condition] → [Expected error handling]
541
-
542
- ### Acceptance Criteria
543
- - [ ] [Measurable criterion 1]
544
- - [ ] [Measurable criterion 2]
545
- - [ ] Edge: [edge case criterion]
546
-
547
- ---
548
-
549
- ## Story 2: [Actor] [Action]
550
-
551
- [Repeat structure above]
552
-
553
- ---
554
-
555
- *Generated by MORPH-SPEC — complete before implementation begins*
556
- ```
557
-
558
- **Step 3: Run full suite**
559
-
560
- ```bash
561
- npm test
562
- ```
563
-
564
- Expected: same pass count.
565
-
566
- **Step 4: Commit**
567
-
568
- ```bash
569
- git add framework/standards/ framework/templates/docs/user-stories.md
570
- git commit -m "feat(standards): add TypeScript strict mode requirement; add user-stories template"
571
- ```
572
-
573
- ---
574
-
575
- ## Task 6: Remove `outputs` and `phase` from state-manager.js
576
-
577
- **Files:**
578
- - Modify: `src/core/state/state-manager.js`
579
- - Modify: `test/lib/state-manager.test.js`
580
-
581
- **Context:** `ensureFeature()` at line 191 sets `outputs: getAllOutputPaths(featureName)` and `phase: "proposal"`. Remove both fields. Add two new exported helper functions: `derivePhase(featurePath)` and `deriveOutputs(featureName)`. Add v4→v5 migration in `loadState()`.
582
-
583
- **Step 1: Add helper functions to state-manager.js**
584
-
585
- Add these two new exported functions after the existing `getStatePath()` function (around line 25):
586
-
587
- ```javascript
588
- /**
589
- * Derive current phase from filesystem — checks for phase folders in descending order.
590
- * Returns the phase corresponding to the highest-numbered folder present.
591
- *
592
- * @param {string} featurePath - Absolute path to .morph/features/{feature}/
593
- * @returns {string} Phase name: 'implement' | 'tasks' | 'uiux' | 'design' | 'proposal' | 'setup'
594
- */
595
- export function derivePhase(featurePath) {
596
- const phaseMap = [
597
- ['4-implement', 'implement'],
598
- ['3-tasks', 'tasks'],
599
- ['2-ui', 'uiux'],
600
- ['1-design', 'design'],
601
- ['0-proposal', 'proposal'],
602
- ];
603
- for (const [folder, phase] of phaseMap) {
604
- if (existsSync(join(featurePath, folder))) return phase;
605
- }
606
- return 'setup';
607
- }
608
-
609
- /**
610
- * Derive output existence from filesystem — checks if each output file exists at its expected path.
611
- * Returns an object matching the old outputs shape for backwards-compatible display.
612
- *
613
- * @param {string} featureName - Feature name
614
- * @param {string} [baseDir] - Project base dir (defaults to cwd)
615
- * @returns {Object} Map of outputType → { created: boolean, path: string }
616
- */
617
- export function deriveOutputs(featureName, baseDir = process.cwd()) {
618
- const outputPaths = getAllOutputPaths(featureName);
619
- const result = {};
620
- for (const [type, { path: relPath }] of Object.entries(outputPaths)) {
621
- const absPath = join(baseDir, relPath);
622
- result[type] = { created: existsSync(absPath), path: relPath };
623
- }
624
- return result;
625
- }
626
- ```
627
-
628
- **Step 2: Remove `outputs` and `phase` from ensureFeature()**
629
-
630
- In `ensureFeature()` (around line 191), change:
631
-
632
- ```javascript
633
- // REMOVE these two lines:
634
- phase: "proposal",
635
- outputs: getAllOutputPaths(featureName),
636
- ```
637
-
638
- The feature object after the change should NOT have `phase` or `outputs` keys.
639
-
640
- **Step 3: Add v4→v5 migration in loadState()**
641
-
642
- In `loadState()`, after the existing v3→v4 migration block (around line 65), add:
643
-
644
- ```javascript
645
- // Migrate v4.x → v5.0.0: remove outputs and phase (now derived from filesystem)
646
- if (state.version && state.version.startsWith('4.')) {
647
- state.version = '5.0.0';
648
- for (const feature of Object.values(state.features || {})) {
649
- delete feature.outputs;
650
- delete feature.phase;
651
- }
652
- writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
653
- }
654
- ```
655
-
656
- **Step 4: Update initState() version string**
657
-
658
- Change `version: "4.0.0"` to `version: "5.0.0"` in `initState()`.
659
-
660
- **Step 5: Run state-manager tests to find failures**
661
-
662
- ```bash
663
- node --test test/lib/state-manager.test.js
664
- ```
665
-
666
- Find tests that assert on `feature.phase` or `feature.outputs` and update them:
667
- - Tests asserting `feature.phase === 'design'` → remove or replace with `derivePhase()` call
668
- - Tests asserting `feature.outputs.spec.created` → remove or replace with `deriveOutputs()` call
669
- - Tests asserting `state.version === '4.0.0'` → change to `'5.0.0'`
670
-
671
- **Step 6: Add new tests for derivePhase and deriveOutputs**
672
-
673
- In `test/lib/state-manager.test.js`, add:
674
-
675
- ```javascript
676
- import { derivePhase, deriveOutputs } from '../../src/core/state/state-manager.js';
677
- import { mkdirSync } from 'fs';
678
-
679
- describe('derivePhase', () => {
680
- test('returns setup when no phase folders exist', () => {
681
- const dir = createTempDir();
682
- assert.strictEqual(derivePhase(join(dir, '.morph', 'features', 'f')), 'setup');
683
- cleanupTempDir(dir);
684
- });
685
-
686
- test('returns proposal when 0-proposal/ exists', () => {
687
- const dir = createTempDir();
688
- const featurePath = join(dir, '.morph', 'features', 'f');
689
- mkdirSync(join(featurePath, '0-proposal'), { recursive: true });
690
- assert.strictEqual(derivePhase(featurePath), 'proposal');
691
- cleanupTempDir(dir);
692
- });
693
-
694
- test('returns tasks when 3-tasks/ is highest folder', () => {
695
- const dir = createTempDir();
696
- const featurePath = join(dir, '.morph', 'features', 'f');
697
- mkdirSync(join(featurePath, '0-proposal'), { recursive: true });
698
- mkdirSync(join(featurePath, '1-design'), { recursive: true });
699
- mkdirSync(join(featurePath, '3-tasks'), { recursive: true });
700
- assert.strictEqual(derivePhase(featurePath), 'tasks');
701
- cleanupTempDir(dir);
702
- });
703
-
704
- test('returns implement when 4-implement/ exists', () => {
705
- const dir = createTempDir();
706
- const featurePath = join(dir, '.morph', 'features', 'f');
707
- mkdirSync(join(featurePath, '4-implement'), { recursive: true });
708
- assert.strictEqual(derivePhase(featurePath), 'implement');
709
- cleanupTempDir(dir);
710
- });
711
- });
712
-
713
- describe('state migration v4 → v5', () => {
714
- test('removes outputs and phase from v4 state on load', () => {
715
- const dir = createTempDir();
716
- process.chdir(dir);
717
- // Write a v4.0.0 state with outputs and phase
718
- const v4State = {
719
- version: '4.0.0',
720
- project: { name: 'Test' },
721
- features: {
722
- 'my-feature': {
723
- phase: 'design',
724
- outputs: { spec: { created: true, path: 'some/path' } },
725
- workflow: 'standard'
726
- }
727
- }
728
- };
729
- mkdirSync(join(dir, '.morph'), { recursive: true });
730
- writeFileSync(join(dir, '.morph', 'state.json'), JSON.stringify(v4State), 'utf8');
731
-
732
- const state = loadState();
733
- assert.strictEqual(state.version, '5.0.0');
734
- assert.strictEqual(state.features['my-feature'].phase, undefined);
735
- assert.strictEqual(state.features['my-feature'].outputs, undefined);
736
- assert.strictEqual(state.features['my-feature'].workflow, 'standard'); // kept
737
-
738
- process.chdir(originalCwd);
739
- cleanupTempDir(dir);
740
- });
741
- });
742
- ```
743
-
744
- **Step 7: Run full suite**
745
-
746
- ```bash
747
- npm test
748
- ```
749
-
750
- Expected: 614+ tests pass, 0 fail.
751
-
752
- **Step 8: Commit**
753
-
754
- ```bash
755
- git add src/core/state/state-manager.js test/lib/state-manager.test.js
756
- git commit -m "feat(state): remove outputs+phase fields; derive from filesystem at runtime"
757
- ```
758
-
759
- ---
760
-
761
- ## Task 7: Delete track-output-creation hook + unregister it
762
-
763
- **Files:**
764
- - Delete: `framework/hooks/claude-code/post-tool-use/track-output-creation.js`
765
- - Modify: `src/utils/hooks-installer.js` — remove PostToolUse/Write entry for track-output-creation
766
- - Delete: `test/hooks/track-output-creation.test.js`
767
- - Modify: `test/hooks/hooks-installer.test.js` — verify hook no longer registered
768
-
769
- **Context:** `track-output-creation.js` existed solely to mark `outputs.{type}.created = true` in state.json. With `outputs` removed from state.json (Task 6), this hook has no purpose.
770
-
771
- **Step 1: Remove the PostToolUse/Write hook entry from hooks-installer.js**
772
-
773
- In `src/utils/hooks-installer.js`, find and delete the entire block (around lines 92-100):
774
-
775
- ```javascript
776
- // DELETE this entire block:
777
- // === PostToolUse: Write ===
778
- {
779
- event: 'PostToolUse',
780
- matcher: 'Write',
781
- hooks: [{
782
- type: 'command',
783
- command: 'node framework/hooks/claude-code/post-tool-use/track-output-creation.js'
784
- }]
785
- },
786
- ```
787
-
788
- **Step 2: Delete the hook file**
789
-
790
- ```bash
791
- git rm framework/hooks/claude-code/post-tool-use/track-output-creation.js
792
- git rm test/hooks/track-output-creation.test.js
793
- ```
794
-
795
- **Step 3: Update hooks-installer.test.js**
796
-
797
- Find any test that asserts `PostToolUse` is installed with `track-output-creation` and either remove it or change it to assert the hook is NOT registered. Add:
798
-
799
- ```javascript
800
- test('does NOT register track-output-creation hook (removed in v5)', async () => {
801
- await installClaudeHooks(tempDir);
802
- const settings = readSettings();
803
- const postToolUseHooks = settings.hooks?.PostToolUse ?? [];
804
- const commands = postToolUseHooks.flatMap(h => h.hooks ?? []).map(h => h.command ?? '');
805
- assert.ok(
806
- !commands.some(c => c.includes('track-output-creation')),
807
- 'track-output-creation should not be registered'
808
- );
809
- });
810
- ```
811
-
812
- **Step 4: Run hooks tests**
813
-
814
- ```bash
815
- node --test test/hooks/hooks-installer.test.js
816
- ```
817
-
818
- Expected: all pass.
819
-
820
- **Step 5: Run full suite**
821
-
822
- ```bash
823
- npm test
824
- ```
825
-
826
- Expected: test count slightly lower (track-output-creation.test.js removed), 0 fail.
827
-
828
- **Step 6: Commit**
829
-
830
- ```bash
831
- git add src/utils/hooks-installer.js test/hooks/hooks-installer.test.js
832
- git commit -m "feat(hooks): remove track-output-creation — outputs now derived from filesystem"
833
- ```
834
-
835
- ---
836
-
837
- ## Task 8: Update status command + version bump
838
-
839
- **Files:**
840
- - Modify: `src/commands/project/status.js` — use derivePhase/deriveOutputs
841
- - Modify: `test/commands/status.test.js` — update assertions
842
- - Modify: `package.json` — version 4.4.0 → 4.5.0
843
-
844
- **Context:** `morph-spec status <feature>` currently reads `feature.phase` and `feature.outputs` from state.json. After Task 6 these fields don't exist. Update status to call `derivePhase()` and `deriveOutputs()` instead.
845
-
846
- **Step 1: Find where status.js reads phase and outputs**
847
-
848
- ```bash
849
- grep -n "\.phase\|\.outputs" src/commands/project/status.js
850
- ```
851
-
852
- **Step 2: Update status.js to use derive helpers**
853
-
854
- Import and use the new helpers:
855
-
856
- ```javascript
857
- import { loadState, derivePhase, deriveOutputs } from '../../core/state/state-manager.js';
858
- import { join } from 'path';
859
-
860
- // Where phase was read:
861
- // BEFORE: const phase = feature.phase;
862
- // AFTER:
863
- const featurePath = join(process.cwd(), '.morph', 'features', featureName);
864
- const phase = derivePhase(featurePath);
865
-
866
- // Where outputs were read:
867
- // BEFORE: const outputs = feature.outputs;
868
- // AFTER:
869
- const outputs = deriveOutputs(featureName);
870
- ```
871
-
872
- **Step 3: Run status tests**
873
-
874
- ```bash
875
- node --test test/commands/status.test.js
876
- ```
877
-
878
- Fix any failing assertions — they'll be about phase values or outputs shape. The shape of `deriveOutputs()` return value matches the old `feature.outputs` shape (`{ type: { created: boolean, path: string } }`), so display logic should need minimal changes.
879
-
880
- **Step 4: Bump version in package.json**
881
-
882
- Change `"version": "4.4.0"` to `"version": "4.5.0"`.
883
-
884
- **Step 5: Update version reference in framework/CLAUDE.md footer**
885
-
886
- Change `*MORPH-SPEC v4.4.0 by Polymorphism Tech*` to `*MORPH-SPEC v4.5.0 by Polymorphism Tech*`.
887
- (This file was already rewritten in Task 3 with v4.5.0, so just verify it's correct.)
888
-
889
- **Step 6: Run full suite — final verification**
890
-
891
- ```bash
892
- npm test
893
- ```
894
-
895
- Expected: all tests pass, 0 fail. Count may differ from original (some tests removed, some added).
896
-
897
- **Step 7: Final commit**
898
-
899
- ```bash
900
- git add src/commands/project/status.js test/commands/status.test.js package.json framework/CLAUDE.md
901
- git commit -m "feat(status): derive phase+outputs from filesystem; bump version to 4.5.0"
902
- ```
903
-
904
- ---
905
-
906
- ## Final Verification
907
-
908
- After all 8 tasks:
909
-
910
- ```bash
911
- npm test
912
- git log --oneline -8
913
- ```
914
-
915
- Expected log:
916
- ```
917
- feat(status): derive phase+outputs from filesystem; bump version to 4.5.0
918
- feat(hooks): remove track-output-creation — outputs now derived from filesystem
919
- feat(state): remove outputs+phase fields; derive from filesystem at runtime
920
- feat(standards): add TypeScript strict mode requirement; add user-stories template
921
- feat(rules): add Test File Policy to morph-workflow rule
922
- feat(claude-md): merge CLAUDE.md + CLAUDE_runtime.md into single unified file
923
- feat(rules): replace static content with @-imports from framework/standards
924
- feat(skills): install as subdirectory/SKILL.md — native Claude Code format
925
- ```