@polymorphism-tech/morph-spec 4.12.0 → 4.14.0

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 (316) hide show
  1. package/CLAUDE.md +7 -7
  2. package/README.md +28 -34
  3. package/bin/morph-spec.js +41 -24
  4. package/bin/task-manager.js +962 -1341
  5. package/bin/validate.js +1 -1
  6. package/claude-plugin.json +1 -1
  7. package/docs/CHEATSHEET.md +14 -16
  8. package/docs/QUICKSTART.md +15 -15
  9. package/framework/CLAUDE.md +5 -2
  10. package/framework/agents/README.md +3 -4
  11. package/framework/agents/ai-agents/ai-system-architect.md +6 -10
  12. package/framework/agents/architecture/seo-growth-hacker.md +166 -326
  13. package/framework/agents/architecture/standards-architect.md +21 -31
  14. package/framework/agents/backend/dotnet-senior.md +160 -86
  15. package/framework/agents/backend/ef-modeler.md +2 -6
  16. package/framework/agents/backend/hangfire-orchestrator.md +8 -9
  17. package/framework/agents/backend/ms-agent-expert.md +1 -1
  18. package/framework/agents/frontend/nextjs-expert.md +198 -133
  19. package/framework/agents/frontend/ui-ux-designer.md +226 -267
  20. package/framework/agents/infrastructure/infra-architect.md +191 -27
  21. package/framework/agents/integrations/clerk-auth.md +19 -26
  22. package/framework/agents/integrations/hangfire-integration.md +1 -4
  23. package/framework/agents.json +1084 -2278
  24. package/framework/commands/morph-apply.md +4 -6
  25. package/framework/commands/morph-preflight.md +192 -269
  26. package/framework/commands/morph-proposal.md +210 -238
  27. package/framework/commands/morph-status.md +72 -92
  28. package/framework/commands/morph-troubleshoot.md +6 -13
  29. package/framework/hooks/README.md +1 -6
  30. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +4 -6
  31. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
  32. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
  33. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
  34. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
  35. package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
  36. package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
  37. package/framework/hooks/claude-code/statusline.py +4 -5
  38. package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
  39. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
  40. package/framework/hooks/shared/compact-restore.js +28 -5
  41. package/framework/hooks/shared/phase-utils.js +4 -8
  42. package/framework/hooks/shared/state-reader.js +34 -3
  43. package/framework/phases.json +162 -200
  44. package/framework/rules/ai-agents-standards.md +15 -0
  45. package/framework/rules/asaas-standards.md +13 -0
  46. package/framework/rules/clerk-standards.md +13 -0
  47. package/framework/rules/csharp-standards.md +8 -4
  48. package/framework/rules/data-standards.md +18 -0
  49. package/framework/rules/dotnet-templates.md +87 -0
  50. package/framework/rules/frontend-standards.md +13 -13
  51. package/framework/rules/hangfire-standards.md +13 -0
  52. package/framework/rules/infrastructure-standards.md +27 -16
  53. package/framework/rules/morph-workflow.md +73 -13
  54. package/framework/rules/nextjs-standards.md +1 -0
  55. package/framework/rules/nextjs-templates.md +40 -0
  56. package/framework/rules/resend-standards.md +12 -0
  57. package/framework/rules/supabase-standards.md +29 -0
  58. package/framework/skills/README.md +6 -8
  59. package/framework/skills/level-0-meta/mcp-registry.json +21 -99
  60. package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
  61. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
  62. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  63. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
  64. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
  65. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
  66. package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
  67. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
  68. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
  69. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
  70. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
  71. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
  72. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
  73. package/framework/skills/level-1-workflows/README.md +1 -1
  74. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
  75. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +57 -123
  76. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
  77. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
  78. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
  79. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +1 -1
  80. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
  81. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
  82. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
  83. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
  84. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
  85. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +143 -172
  86. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
  87. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +57 -77
  88. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  89. package/framework/squad-templates/backend-only.json +6 -6
  90. package/framework/squad-templates/frontend-only.json +17 -8
  91. package/framework/squad-templates/full-stack.json +29 -24
  92. package/framework/standards/STANDARDS.json +1021 -2369
  93. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
  94. package/framework/standards/backend/dotnet/result-pattern.md +213 -0
  95. package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
  96. package/framework/standards/backend/dotnet/scrutor.md +158 -0
  97. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
  98. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
  99. package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
  100. package/framework/standards/integration/mcp/mcp-tools.md +91 -77
  101. package/framework/templates/IDE-SNIPPETS.md +2 -6
  102. package/framework/templates/README.md +709 -814
  103. package/framework/templates/REGISTRY.json +223 -762
  104. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
  105. package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
  106. package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
  107. package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
  108. package/framework/templates/code/dotnet/backend/repository.cs +148 -141
  109. package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
  110. package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
  111. package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
  112. package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
  113. package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
  114. package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
  115. package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
  116. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
  117. package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
  118. package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
  119. package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
  120. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
  121. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
  122. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
  123. package/framework/templates/code/dotnet/jobs/job.cs +21 -17
  124. package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
  125. package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
  126. package/framework/templates/code/dotnet/test.cs +192 -106
  127. package/framework/templates/context/ARCHITECTURE.md +89 -0
  128. package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
  129. package/framework/templates/context/CONTEXT.md +180 -181
  130. package/framework/templates/context/design-system.md +1 -5
  131. package/framework/templates/docs/onboarding.md +2 -3
  132. package/framework/templates/docs/proposal.md +171 -182
  133. package/framework/templates/docs/spec.md +1 -3
  134. package/framework/templates/docs/ui-components.md +0 -72
  135. package/framework/templates/examples/design-system-examples.md +4 -4
  136. package/framework/templates/feature/decisions.md +0 -66
  137. package/framework/templates/feature/recap.md +1 -2
  138. package/framework/templates/infrastructure/github/README.md +56 -593
  139. package/framework/templates/integrations/clerk-config.cs +0 -41
  140. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  141. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
  142. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
  143. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
  144. package/framework/templates/project/validate.js +2 -4
  145. package/framework/templates/ui/design-system.css +1 -1
  146. package/framework/workflows/README.md +8 -8
  147. package/framework/workflows/configs/fast-track.json +51 -0
  148. package/framework/workflows/configs/full.json +68 -0
  149. package/framework/workflows/configs/standard.json +7 -3
  150. package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
  151. package/framework/workflows/docs/enforcement-pipeline.md +18 -19
  152. package/framework/workflows/docs/full-morph.md +69 -76
  153. package/framework/workflows/docs/standard.md +49 -44
  154. package/framework/workflows/docs/ui-refresh.md +1 -1
  155. package/package.json +3 -3
  156. package/src/commands/agents/dispatch-agents.js +55 -116
  157. package/src/commands/context/context-refresh.js +79 -0
  158. package/src/commands/phase/phase-reset.js +1 -1
  159. package/src/commands/project/doctor.js +10 -32
  160. package/src/commands/project/init.js +12 -0
  161. package/src/commands/project/status.js +6 -12
  162. package/src/commands/scaffold/scaffold.js +131 -0
  163. package/src/commands/scope/escalate.js +1 -1
  164. package/src/commands/state/advance-phase.js +15 -29
  165. package/src/commands/state/state.js +20 -5
  166. package/src/commands/tasks/task.js +0 -30
  167. package/src/commands/validation/validate-feature.js +3 -10
  168. package/src/core/paths/output-schema.js +12 -13
  169. package/src/core/state/phase-state-machine.js +211 -217
  170. package/src/core/state/state-manager.js +9 -9
  171. package/src/lib/agents/agents-manager.js +2 -2
  172. package/src/lib/agents/output-collector.js +1 -2
  173. package/src/lib/detectors/design-system-detector.js +4 -4
  174. package/src/lib/detectors/index.js +1 -11
  175. package/src/lib/generators/architecture-scanner.js +640 -0
  176. package/src/lib/generators/context-generator.js +3 -3
  177. package/src/lib/generators/design-system-generator.js +508 -587
  178. package/src/lib/generators/index.js +12 -10
  179. package/src/lib/generators/metadata-extractor.js +386 -387
  180. package/src/lib/generators/recap-generator.js +4 -4
  181. package/src/lib/generators/scaffold-generator.js +317 -0
  182. package/src/lib/generators/settings-generator.js +0 -1
  183. package/src/lib/phase-chain/phase-validator.js +64 -42
  184. package/src/lib/stack/stack-profile.js +2 -2
  185. package/src/lib/standards/digest-builder.js +72 -285
  186. package/src/lib/tasks/task-parser.js +11 -5
  187. package/src/lib/validators/architecture/architecture-validator.js +259 -387
  188. package/src/lib/validators/content/content-validator.js +287 -287
  189. package/src/lib/validators/css/css-validator.js +340 -352
  190. package/src/lib/validators/packages/package-validator.js +347 -360
  191. package/src/lib/validators/shared/issue-counter.js +14 -18
  192. package/src/lib/validators/validation-runner.js +3 -19
  193. package/src/scripts/setup-infra.js +1 -1
  194. package/src/utils/agents-installer.js +61 -10
  195. package/src/utils/file-copier.js +1 -0
  196. package/src/utils/hooks-installer.js +11 -19
  197. package/src/utils/skills-installer.js +178 -178
  198. package/framework/agents/architecture/prompt-engineer.md +0 -195
  199. package/framework/agents/backend/api-designer.md +0 -106
  200. package/framework/agents/frontend/blazor-builder.md +0 -229
  201. package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
  202. package/framework/agents/infrastructure/azure-architect.md +0 -150
  203. package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
  204. package/framework/agents/infrastructure/bicep-architect.md +0 -132
  205. package/framework/agents/infrastructure/container-specialist.md +0 -137
  206. package/framework/agents/infrastructure/devops-engineer.md +0 -126
  207. package/framework/agents/integrations/azure-identity.md +0 -148
  208. package/framework/agents/quality/code-analyzer.md +0 -239
  209. package/framework/agents/quality/testing-specialist.md +0 -130
  210. package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
  211. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
  212. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
  213. package/framework/index/troubleshooting-index.json +0 -184
  214. package/framework/rules/testing-standards.md +0 -14
  215. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
  216. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
  217. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
  218. package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
  219. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
  220. package/framework/standards/ai-agents/blazor-ui.md +0 -364
  221. package/framework/standards/architecture/ddd/aggregates.md +0 -120
  222. package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  223. package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  224. package/framework/standards/architecture/ddd/entities.md +0 -99
  225. package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  226. package/framework/standards/architecture/ddd/value-objects.md +0 -124
  227. package/framework/standards/backend/api/minimal-api.md +0 -494
  228. package/framework/standards/backend/api/rest.md +0 -492
  229. package/framework/standards/backend/authentication/passkeys.md +0 -428
  230. package/framework/standards/backend/database/ef-core.md +0 -199
  231. package/framework/standards/backend/database/migrations.md +0 -393
  232. package/framework/standards/backend/database/repository-patterns.md +0 -528
  233. package/framework/standards/backend/dotnet/async.md +0 -366
  234. package/framework/standards/backend/dotnet/core.md +0 -117
  235. package/framework/standards/backend/dotnet/di.md +0 -439
  236. package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  237. package/framework/standards/context/analytics.md +0 -96
  238. package/framework/standards/context/bundles.md +0 -110
  239. package/framework/standards/context/priming.md +0 -78
  240. package/framework/standards/core/architecture.md +0 -185
  241. package/framework/standards/core/coding.md +0 -214
  242. package/framework/standards/core/git-branching-strategy.md +0 -403
  243. package/framework/standards/core/git.md +0 -185
  244. package/framework/standards/core/testing.md +0 -295
  245. package/framework/standards/data/nosql/blob-storage.md +0 -102
  246. package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  247. package/framework/standards/frontend/blazor/design-checklist.md +0 -222
  248. package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  249. package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  250. package/framework/standards/frontend/blazor/html-conversion.md +0 -184
  251. package/framework/standards/frontend/blazor/lifecycle.md +0 -195
  252. package/framework/standards/frontend/blazor/pitfalls.md +0 -198
  253. package/framework/standards/frontend/blazor/state.md +0 -191
  254. package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -266
  255. package/framework/standards/frontend/design-system/design-trends.md +0 -171
  256. package/framework/standards/infrastructure/azure/azure.md +0 -624
  257. package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  258. package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  259. package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  260. package/framework/standards/infrastructure/azure/services/functions.md +0 -486
  261. package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  262. package/framework/standards/infrastructure/azure/services/storage.md +0 -407
  263. package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
  264. package/framework/standards/integration/api/graphql.md +0 -91
  265. package/framework/standards/integration/api/grpc.md +0 -114
  266. package/framework/standards/integration/api/rest-design.md +0 -95
  267. package/framework/standards/integration/event-driven/cqrs.md +0 -101
  268. package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  269. package/framework/standards/integration/event-driven/service-bus.md +0 -95
  270. package/framework/standards/observability/logging.md +0 -131
  271. package/framework/standards/observability/metrics.md +0 -121
  272. package/framework/standards/observability/monitoring.md +0 -114
  273. package/framework/standards/observability/tracing.md +0 -132
  274. package/framework/standards/workflows/parallel-execution.md +0 -112
  275. package/framework/standards/workflows/thread-management.md +0 -113
  276. package/framework/templates/code/dotnet/backend/service.cs +0 -139
  277. package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  278. package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  279. package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  280. package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  281. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  282. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  283. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  284. package/framework/templates/code/dotnet/frontend/component.razor +0 -239
  285. package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  286. package/framework/templates/infrastructure/azure/README.md +0 -286
  287. package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  288. package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  289. package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  290. package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  291. package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  292. package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  293. package/framework/templates/infrastructure/azure/deploy.sh +0 -208
  294. package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  295. package/framework/templates/infrastructure/azure/main.bicep +0 -189
  296. package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  297. package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  298. package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  299. package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  300. package/framework/templates/infrastructure/azure/storage.bicep +0 -106
  301. package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  302. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  303. package/framework/templates/integrations/azure-identity-config.cs +0 -288
  304. package/framework/templates/project-structure/dotnet-ddd.md +0 -70
  305. package/framework/templates/saas/subscription.cs +0 -347
  306. package/framework/templates/saas/tenant.cs +0 -338
  307. package/framework/templates/ui/FluentDesignTheme.cs +0 -149
  308. package/framework/templates/ui/MudTheme.cs +0 -281
  309. package/framework/workflows/configs/nodejs-cli.json +0 -40
  310. package/src/commands/standards/context-budget.js +0 -89
  311. package/src/lib/standards/index.js +0 -7
  312. package/src/lib/standards/standards-context-injector.js +0 -302
  313. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
  314. package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
  315. package/src/lib/validators/blazor/blazor-validator.js +0 -369
  316. package/src/lib/validators/blazor/index.js +0 -9
@@ -1,217 +1,211 @@
1
- /**
2
- * Phase State Machine - Enforces valid phase transitions
3
- *
4
- * Prevents invalid workflow jumps and ensures sequential phase progression.
5
- * Based on the MORPH 5-phase workflow.
6
- */
7
-
8
- /**
9
- * Valid phase transitions map
10
- * Each phase can only transition to specific next phases
11
- */
12
- const VALID_TRANSITIONS = {
13
- 'proposal': ['setup'],
14
- 'setup': ['uiux', 'design'], // Can skip UI/UX if no frontend
15
- 'uiux': ['design'],
16
- 'design': ['clarify'],
17
- 'clarify': ['plan'],
18
- 'plan': ['tasks'],
19
- 'tasks': ['implement'],
20
- 'implement': ['sync', 'archived'], // Can skip sync
21
- 'sync': ['archived']
22
- };
23
-
24
- /**
25
- * Phase display names for error messages
26
- */
27
- const PHASE_NAMES = {
28
- 'proposal': 'Proposal (Phase 0)',
29
- 'setup': 'Setup (Phase 1)',
30
- 'uiux': 'UI/UX Design (Phase 1.5)',
31
- 'design': 'Design (Phase 2)',
32
- 'clarify': 'Clarify (Phase 3)',
33
- 'plan': 'Plan (Phase 4)',
34
- 'tasks': 'Tasks (Phase 5)',
35
- 'implement': 'Implement (Phase 6)',
36
- 'sync': 'Sync (Phase 7)',
37
- 'archived': 'Archived'
38
- };
39
-
40
- /**
41
- * Optional phases that can be skipped
42
- */
43
- const OPTIONAL_PHASES = ['uiux', 'sync'];
44
-
45
- /**
46
- * Validate if a phase transition is allowed
47
- * @param {string} fromPhase - Current phase
48
- * @param {string} toPhase - Target phase
49
- * @returns {boolean} True if transition is valid
50
- */
51
- export function isValidTransition(fromPhase, toPhase) {
52
- if (!fromPhase || !toPhase) {
53
- return false;
54
- }
55
-
56
- const validNextPhases = VALID_TRANSITIONS[fromPhase];
57
- return validNextPhases ? validNextPhases.includes(toPhase) : false;
58
- }
59
-
60
- /**
61
- * Get list of valid next phases for a given phase
62
- * @param {string} currentPhase - Current phase
63
- * @returns {string[]} Array of valid next phase names
64
- */
65
- export function getValidNextPhases(currentPhase) {
66
- return VALID_TRANSITIONS[currentPhase] || [];
67
- }
68
-
69
- /**
70
- * Get display name for a phase
71
- * @param {string} phase - Phase identifier
72
- * @returns {string} Human-readable phase name
73
- */
74
- export function getPhaseDisplayName(phase) {
75
- return PHASE_NAMES[phase] || phase;
76
- }
77
-
78
- /**
79
- * Check if a phase is optional
80
- * @param {string} phase - Phase identifier
81
- * @returns {boolean} True if phase is optional
82
- */
83
- export function isOptionalPhase(phase) {
84
- return OPTIONAL_PHASES.includes(phase);
85
- }
86
-
87
- /**
88
- * Validate transition and throw error if invalid
89
- * @param {string} fromPhase - Current phase
90
- * @param {string} toPhase - Target phase
91
- * @throws {Error} If transition is invalid
92
- */
93
- export function validateTransition(fromPhase, toPhase) {
94
- if (!fromPhase) {
95
- throw new Error('Current phase is undefined. Cannot validate transition.');
96
- }
97
-
98
- if (!toPhase) {
99
- throw new Error('Target phase is undefined. Cannot validate transition.');
100
- }
101
-
102
- if (!isValidTransition(fromPhase, toPhase)) {
103
- const validPhases = getValidNextPhases(fromPhase);
104
- const fromDisplay = getPhaseDisplayName(fromPhase);
105
- const toDisplay = getPhaseDisplayName(toPhase);
106
-
107
- throw new Error(
108
- `Invalid phase transition: ${fromDisplay} → ${toDisplay}\n\n` +
109
- `Valid next phases from ${fromDisplay}:\n` +
110
- validPhases.map(p => ` • ${getPhaseDisplayName(p)}`).join('\n') +
111
- '\n\n' +
112
- 'You cannot skip phases in the MORPH workflow.\n' +
113
- 'To override this check, use the --force flag (not recommended).'
114
- );
115
- }
116
- }
117
-
118
- /**
119
- * Get the sequential order of phases
120
- * @returns {string[]} Ordered list of phases
121
- */
122
- export function getPhaseSequence() {
123
- return [
124
- 'proposal',
125
- 'setup',
126
- 'uiux', // optional
127
- 'design',
128
- 'clarify',
129
- 'plan',
130
- 'tasks',
131
- 'implement',
132
- 'sync', // optional
133
- 'archived'
134
- ];
135
- }
136
-
137
- /**
138
- * Get phase order index (for comparison)
139
- * @param {string} phase - Phase identifier
140
- * @returns {number} Index in sequence (-1 if not found)
141
- */
142
- export function getPhaseOrder(phase) {
143
- return getPhaseSequence().indexOf(phase);
144
- }
145
-
146
- /**
147
- * Check if target phase is ahead of current phase
148
- * @param {string} currentPhase - Current phase
149
- * @param {string} targetPhase - Target phase
150
- * @returns {boolean} True if target is ahead
151
- */
152
- export function isPhaseAhead(currentPhase, targetPhase) {
153
- return getPhaseOrder(targetPhase) > getPhaseOrder(currentPhase);
154
- }
155
-
156
- /**
157
- * Check if target phase is behind current phase (rollback scenario)
158
- * @param {string} currentPhase - Current phase
159
- * @param {string} targetPhase - Target phase
160
- * @returns {boolean} True if target is behind
161
- */
162
- export function isPhaseRollback(currentPhase, targetPhase) {
163
- return getPhaseOrder(targetPhase) < getPhaseOrder(currentPhase);
164
- }
165
-
166
- /**
167
- * Get all skipped phases between two phases
168
- * @param {string} fromPhase - Starting phase
169
- * @param {string} toPhase - Ending phase
170
- * @returns {string[]} Array of skipped phases
171
- */
172
- export function getSkippedPhases(fromPhase, toPhase) {
173
- const sequence = getPhaseSequence();
174
- const fromIndex = sequence.indexOf(fromPhase);
175
- const toIndex = sequence.indexOf(toPhase);
176
-
177
- if (fromIndex === -1 || toIndex === -1 || toIndex <= fromIndex) {
178
- return [];
179
- }
180
-
181
- return sequence.slice(fromIndex + 1, toIndex);
182
- }
183
-
184
- /**
185
- * Validate that no required phases were skipped
186
- * @param {string} fromPhase - Starting phase
187
- * @param {string} toPhase - Ending phase
188
- * @throws {Error} If required phases were skipped
189
- */
190
- export function validateNoRequiredPhasesSkipped(fromPhase, toPhase) {
191
- const skipped = getSkippedPhases(fromPhase, toPhase);
192
- const requiredSkipped = skipped.filter(p => !isOptionalPhase(p));
193
-
194
- if (requiredSkipped.length > 0) {
195
- throw new Error(
196
- `Cannot skip required phases:\n` +
197
- requiredSkipped.map(p => ` • ${getPhaseDisplayName(p)}`).join('\n') +
198
- '\n\nYou must complete each required phase in sequence.'
199
- );
200
- }
201
- }
202
-
203
- /**
204
- * Get comprehensive phase information
205
- * @param {string} phase - Phase identifier
206
- * @returns {Object} Phase metadata
207
- */
208
- export function getPhaseInfo(phase) {
209
- return {
210
- id: phase,
211
- displayName: getPhaseDisplayName(phase),
212
- order: getPhaseOrder(phase),
213
- isOptional: isOptionalPhase(phase),
214
- validNextPhases: getValidNextPhases(phase),
215
- canTransitionTo: (targetPhase) => isValidTransition(phase, targetPhase)
216
- };
217
- }
1
+ /**
2
+ * Phase State Machine - Enforces valid phase transitions
3
+ *
4
+ * Prevents invalid workflow jumps and ensures sequential phase progression.
5
+ * Based on the MORPH 5-phase workflow.
6
+ */
7
+
8
+ /**
9
+ * Valid phase transitions map
10
+ * Each phase can only transition to specific next phases
11
+ */
12
+ const VALID_TRANSITIONS = {
13
+ 'proposal': ['uiux', 'design'], // Can skip UI/UX if no frontend
14
+ 'uiux': ['design'],
15
+ 'design': ['plan'],
16
+ 'plan': ['tasks'],
17
+ 'tasks': ['implement'],
18
+ 'implement': ['sync', 'archived'], // Can skip sync
19
+ 'sync': ['archived']
20
+ };
21
+
22
+ /**
23
+ * Phase display names for error messages
24
+ */
25
+ const PHASE_NAMES = {
26
+ 'proposal': 'Proposal (Phase 0)',
27
+ 'uiux': 'UI/UX Design (Phase 1)',
28
+ 'design': 'Design (Phase 2)',
29
+ 'plan': 'Plan (Phase 3)',
30
+ 'tasks': 'Tasks (Phase 4)',
31
+ 'implement': 'Implement (Phase 5)',
32
+ 'sync': 'Sync (Phase 6)',
33
+ 'archived': 'Archived'
34
+ };
35
+
36
+ /**
37
+ * Optional phases that can be skipped
38
+ */
39
+ const OPTIONAL_PHASES = ['uiux', 'sync'];
40
+
41
+ /**
42
+ * Validate if a phase transition is allowed
43
+ * @param {string} fromPhase - Current phase
44
+ * @param {string} toPhase - Target phase
45
+ * @returns {boolean} True if transition is valid
46
+ */
47
+ export function isValidTransition(fromPhase, toPhase) {
48
+ if (!fromPhase || !toPhase) {
49
+ return false;
50
+ }
51
+
52
+ const validNextPhases = VALID_TRANSITIONS[fromPhase];
53
+ return validNextPhases ? validNextPhases.includes(toPhase) : false;
54
+ }
55
+
56
+ /**
57
+ * Get list of valid next phases for a given phase
58
+ * @param {string} currentPhase - Current phase
59
+ * @returns {string[]} Array of valid next phase names
60
+ */
61
+ export function getValidNextPhases(currentPhase) {
62
+ return VALID_TRANSITIONS[currentPhase] || [];
63
+ }
64
+
65
+ /**
66
+ * Get display name for a phase
67
+ * @param {string} phase - Phase identifier
68
+ * @returns {string} Human-readable phase name
69
+ */
70
+ export function getPhaseDisplayName(phase) {
71
+ return PHASE_NAMES[phase] || phase;
72
+ }
73
+
74
+ /**
75
+ * Check if a phase is optional
76
+ * @param {string} phase - Phase identifier
77
+ * @returns {boolean} True if phase is optional
78
+ */
79
+ export function isOptionalPhase(phase) {
80
+ return OPTIONAL_PHASES.includes(phase);
81
+ }
82
+
83
+ /**
84
+ * Validate transition and throw error if invalid
85
+ * @param {string} fromPhase - Current phase
86
+ * @param {string} toPhase - Target phase
87
+ * @throws {Error} If transition is invalid
88
+ */
89
+ export function validateTransition(fromPhase, toPhase) {
90
+ if (!fromPhase) {
91
+ throw new Error('Current phase is undefined. Cannot validate transition.');
92
+ }
93
+
94
+ if (!toPhase) {
95
+ throw new Error('Target phase is undefined. Cannot validate transition.');
96
+ }
97
+
98
+ if (!isValidTransition(fromPhase, toPhase)) {
99
+ const validPhases = getValidNextPhases(fromPhase);
100
+ const fromDisplay = getPhaseDisplayName(fromPhase);
101
+ const toDisplay = getPhaseDisplayName(toPhase);
102
+
103
+ throw new Error(
104
+ `Invalid phase transition: ${fromDisplay} → ${toDisplay}\n\n` +
105
+ `Valid next phases from ${fromDisplay}:\n` +
106
+ validPhases.map(p => ` • ${getPhaseDisplayName(p)}`).join('\n') +
107
+ '\n\n' +
108
+ 'You cannot skip phases in the MORPH workflow.\n' +
109
+ 'To override this check, use the --force flag (not recommended).'
110
+ );
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Get the sequential order of phases
116
+ * @returns {string[]} Ordered list of phases
117
+ */
118
+ export function getPhaseSequence() {
119
+ return [
120
+ 'proposal',
121
+ 'uiux', // optional
122
+ 'design',
123
+ 'plan',
124
+ 'tasks',
125
+ 'implement',
126
+ 'sync', // optional
127
+ 'archived'
128
+ ];
129
+ }
130
+
131
+ /**
132
+ * Get phase order index (for comparison)
133
+ * @param {string} phase - Phase identifier
134
+ * @returns {number} Index in sequence (-1 if not found)
135
+ */
136
+ export function getPhaseOrder(phase) {
137
+ return getPhaseSequence().indexOf(phase);
138
+ }
139
+
140
+ /**
141
+ * Check if target phase is ahead of current phase
142
+ * @param {string} currentPhase - Current phase
143
+ * @param {string} targetPhase - Target phase
144
+ * @returns {boolean} True if target is ahead
145
+ */
146
+ export function isPhaseAhead(currentPhase, targetPhase) {
147
+ return getPhaseOrder(targetPhase) > getPhaseOrder(currentPhase);
148
+ }
149
+
150
+ /**
151
+ * Check if target phase is behind current phase (rollback scenario)
152
+ * @param {string} currentPhase - Current phase
153
+ * @param {string} targetPhase - Target phase
154
+ * @returns {boolean} True if target is behind
155
+ */
156
+ export function isPhaseRollback(currentPhase, targetPhase) {
157
+ return getPhaseOrder(targetPhase) < getPhaseOrder(currentPhase);
158
+ }
159
+
160
+ /**
161
+ * Get all skipped phases between two phases
162
+ * @param {string} fromPhase - Starting phase
163
+ * @param {string} toPhase - Ending phase
164
+ * @returns {string[]} Array of skipped phases
165
+ */
166
+ export function getSkippedPhases(fromPhase, toPhase) {
167
+ const sequence = getPhaseSequence();
168
+ const fromIndex = sequence.indexOf(fromPhase);
169
+ const toIndex = sequence.indexOf(toPhase);
170
+
171
+ if (fromIndex === -1 || toIndex === -1 || toIndex <= fromIndex) {
172
+ return [];
173
+ }
174
+
175
+ return sequence.slice(fromIndex + 1, toIndex);
176
+ }
177
+
178
+ /**
179
+ * Validate that no required phases were skipped
180
+ * @param {string} fromPhase - Starting phase
181
+ * @param {string} toPhase - Ending phase
182
+ * @throws {Error} If required phases were skipped
183
+ */
184
+ export function validateNoRequiredPhasesSkipped(fromPhase, toPhase) {
185
+ const skipped = getSkippedPhases(fromPhase, toPhase);
186
+ const requiredSkipped = skipped.filter(p => !isOptionalPhase(p));
187
+
188
+ if (requiredSkipped.length > 0) {
189
+ throw new Error(
190
+ `Cannot skip required phases:\n` +
191
+ requiredSkipped.map(p => ` • ${getPhaseDisplayName(p)}`).join('\n') +
192
+ '\n\nYou must complete each required phase in sequence.'
193
+ );
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Get comprehensive phase information
199
+ * @param {string} phase - Phase identifier
200
+ * @returns {Object} Phase metadata
201
+ */
202
+ export function getPhaseInfo(phase) {
203
+ return {
204
+ id: phase,
205
+ displayName: getPhaseDisplayName(phase),
206
+ order: getPhaseOrder(phase),
207
+ isOptional: isOptionalPhase(phase),
208
+ validNextPhases: getValidNextPhases(phase),
209
+ canTransitionTo: (targetPhase) => isValidTransition(phase, targetPhase)
210
+ };
211
+ }
@@ -27,21 +27,21 @@ export function getStatePath() {
27
27
  * Returns the phase corresponding to the highest-numbered folder present.
28
28
  *
29
29
  * @param {string} featurePath - Absolute path to .morph/features/{feature}/
30
- * @returns {string} Phase name: 'implement' | 'tasks' | 'plan' | 'uiux' | 'design' | 'proposal' | 'setup'
30
+ * @returns {string} Phase name: 'implement' | 'tasks' | 'plan' | 'uiux' | 'design' | 'proposal'
31
31
  */
32
32
  export function derivePhase(featurePath) {
33
33
  const phaseMap = [
34
34
  ['5-implement', 'implement'],
35
35
  ['4-tasks', 'tasks'],
36
36
  ['3-plan', 'plan'],
37
- ['2-ui', 'uiux'],
38
- ['1-design', 'design'],
37
+ ['2-design', 'design'],
38
+ ['1-ui', 'uiux'],
39
39
  ['0-proposal', 'proposal'],
40
40
  ];
41
41
  for (const [folder, phase] of phaseMap) {
42
42
  if (existsSync(join(featurePath, folder))) return phase;
43
43
  }
44
- return 'setup';
44
+ return 'proposal';
45
45
  }
46
46
 
47
47
  /**
@@ -168,11 +168,11 @@ export function saveState(state) {
168
168
  * @param {Object} options - Options
169
169
  * @param {boolean} options.force - Overwrite existing file
170
170
  * @param {string} options.projectName - Project name
171
- * @param {string} options.projectType - Project type (e.g., 'blazor-server')
171
+ * @param {string} options.projectType - Project type (e.g., 'dotnet-nextjs')
172
172
  * @returns {Object} Initial state
173
173
  */
174
174
  export function initState(options = {}) {
175
- const { force = false, projectName = '{PROJECT_NAME}', projectType = 'blazor-server' } = options;
175
+ const { force = false, projectName = '{PROJECT_NAME}', projectType = 'dotnet-nextjs' } = options;
176
176
 
177
177
  if (stateExists() && !force) {
178
178
  throw new Error('State file already exists. Use force=true to overwrite.');
@@ -362,7 +362,7 @@ export async function addCheckpoint(featureName, note) {
362
362
  passed: true,
363
363
  checkpointNum: feature.checkpoints.length + 1,
364
364
  timestamp: new Date().toISOString(),
365
- phase: feature.phase || 'setup',
365
+ phase: feature.phase || 'proposal',
366
366
  results: [],
367
367
  summary: {
368
368
  note: note,
@@ -617,7 +617,7 @@ export async function trackFileChange(featureName, filePath, action, phase) {
617
617
  state.features[featureName].fileChanges.push({
618
618
  path: filePath,
619
619
  action,
620
- phase: phase || state.features[featureName].phase || 'setup',
620
+ phase: phase || state.features[featureName].phase || 'proposal',
621
621
  timestamp: new Date().toISOString()
622
622
  });
623
623
 
@@ -783,7 +783,7 @@ export function isPendingApproval(featureName) {
783
783
  return false;
784
784
  }
785
785
 
786
- const currentPhase = feature.phase || 'setup';
786
+ const currentPhase = feature.phase || 'proposal';
787
787
 
788
788
  // Check if current phase has an approval gate
789
789
  const phaseGateMap = {
@@ -16,8 +16,8 @@ import { dirname } from 'node:path';
16
16
 
17
17
  /** Known valid phases for active_phases validation */
18
18
  export const KNOWN_PHASES = [
19
- 'proposal', 'setup', 'uiux', 'design',
20
- 'clarify', 'plan', 'tasks', 'implement',
19
+ 'proposal', 'uiux', 'design',
20
+ 'plan', 'tasks', 'implement', 'sync',
21
21
  ];
22
22
 
23
23
  /** Tier labels for display and validation */
@@ -19,7 +19,6 @@ export const SOURCE_WEIGHTS = {
19
19
  contracts: 1.0,
20
20
  contractsTs: 1.0,
21
21
  contractsVsa: 1.0,
22
- clarifications: 1.0,
23
22
  decisions: 1.0,
24
23
  plan: 1.2,
25
24
  tasks: 1.3,
@@ -31,7 +30,7 @@ export const SOURCE_WEIGHTS = {
31
30
  };
32
31
 
33
32
  /** Phase order for sorting collected outputs */
34
- const PHASE_ORDER = ['proposal', 'uiux', 'design', 'clarify', 'plan', 'tasks', 'implement'];
33
+ const PHASE_ORDER = ['proposal', 'uiux', 'design', 'plan', 'tasks', 'implement'];
35
34
 
36
35
  /**
37
36
  * Collect all existing phase output files for a feature.
@@ -64,7 +64,7 @@ export function detectDesignSystem(projectPath, featureName = null) {
64
64
  projectPath,
65
65
  '.morph/features',
66
66
  featureName,
67
- '2-ui',
67
+ '1-ui',
68
68
  'design-system.md'
69
69
  );
70
70
 
@@ -179,7 +179,7 @@ export function hasUIAgentsActive(projectPath, featureName) {
179
179
  }
180
180
 
181
181
  // UI design agents that require a design system before implement phase.
182
- // Implementation-only agents (blazor-builder, nextjs-expert, css-specialist)
182
+ // Implementation-only agents (nextjs-expert, css-specialist)
183
183
  // build from existing designs and do NOT trigger this gate.
184
184
  const uiAgents = [
185
185
  'ui-designer',
@@ -208,10 +208,10 @@ export function getRecommendedLocations(projectPath) {
208
208
  projectType = config.project?.type || 'unknown';
209
209
  }
210
210
 
211
- // Default locations (Blazor)
211
+ // Default locations
212
212
  const locations = {
213
213
  markdown: '.morph/context/design-system.md',
214
- css: 'wwwroot/css/design-system.css',
214
+ css: 'public/design-system.css',
215
215
  description: 'Project-level design system (shared across features)'
216
216
  };
217
217
 
@@ -68,10 +68,6 @@ export function detectProject(targetPath, opts = {}) {
68
68
  // UI library detection
69
69
  if (existsSync(join(targetPath, 'components.json')) || existsSync(join(targetPath, structure.frontendPath || '.', 'components.json')) || depNames.includes('@shadcn/ui')) {
70
70
  structure.uiLibrary = 'shadcn';
71
- } else if (depNames.some(d => d.includes('mudblazor'))) {
72
- structure.uiLibrary = 'mudblazor';
73
- } else if (depNames.some(d => d.includes('fluent'))) {
74
- structure.uiLibrary = 'fluent-ui';
75
71
  }
76
72
 
77
73
  // Integrations
@@ -93,16 +89,12 @@ export function detectProject(targetPath, opts = {}) {
93
89
 
94
90
  // ── .csproj detection ──────────────────────────────────────────────────
95
91
  let hasDotnet = false;
96
- let hasBlazer = false;
97
92
  const csprojLocations = ['.', 'src', 'src/Api', 'src/Web', 'src/backend'];
98
93
 
99
94
  function checkCsproj(filePath) {
100
95
  hasDotnet = true;
101
96
  try {
102
97
  const content = readFileSync(filePath, 'utf8');
103
- if (content.includes('Microsoft.AspNetCore.Components') || content.includes('Blazor')) {
104
- hasBlazer = true;
105
- }
106
98
  if (content.includes('Hangfire')) {
107
99
  if (!structure.integrations.includes('hangfire')) structure.integrations.push('hangfire');
108
100
  }
@@ -128,13 +120,11 @@ export function detectProject(targetPath, opts = {}) {
128
120
  } catch { /* ignore */ }
129
121
  }
130
122
 
131
- // Determine stack: monorepo (nextjs+dotnet), blazor, dotnet, or keep frontend stack
123
+ // Determine stack: monorepo (nextjs+dotnet), dotnet, or keep frontend stack
132
124
  if (hasDotnet) {
133
125
  if (structure.stack === 'nextjs' || structure.stack === 'react' || structure.stack === 'vue') {
134
126
  // Monorepo: frontend + .NET backend
135
127
  structure.stack = `${structure.stack}+dotnet`;
136
- } else if (hasBlazer) {
137
- structure.stack = 'blazor';
138
128
  } else if (structure.stack === 'unknown') {
139
129
  structure.stack = 'dotnet';
140
130
  }