@polymorphism-tech/morph-spec 4.3.7 → 4.6.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 (394) hide show
  1. package/.morph/.morphversion +3 -3
  2. package/.morph/analytics/threads-log.jsonl +6 -9
  3. package/.morph/config/config.json +2 -3
  4. package/.morph/framework/standards/STANDARDS.json +812 -0
  5. package/.morph/{standards → framework/standards}/ai-agents/team-orchestration.md +3 -3
  6. package/.morph/{standards → framework/standards}/frontend/nextjs/nextjs-patterns.md +17 -0
  7. package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
  8. package/.morph/{templates → framework/templates}/README.md +17 -17
  9. package/.morph/{templates → framework/templates}/REGISTRY.json +48 -233
  10. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
  11. package/.morph/{templates → framework/templates}/context/CONTEXT-FEATURE.md +1 -1
  12. package/.morph/{templates → framework/templates}/context/CONTEXT.md +3 -3
  13. package/.morph/framework/templates/docs/clarifications.md +253 -0
  14. package/.morph/framework/templates/docs/onboarding.md +123 -0
  15. package/.morph/framework/templates/docs/schema-analysis.md +119 -0
  16. package/.morph/{templates → framework/templates}/docs/spec.md +149 -149
  17. package/.morph/framework/templates/docs/ui-components.md +124 -0
  18. package/.morph/framework/templates/docs/ui-design-system.md +76 -0
  19. package/.morph/framework/templates/docs/ui-flows.md +167 -0
  20. package/.morph/framework/templates/docs/ui-mockups.md +98 -0
  21. package/.morph/framework/templates/docs/user-stories.md +34 -0
  22. package/.morph/{templates → framework/templates}/examples/spec-examples.md +1 -1
  23. package/.morph/{templates → framework/templates}/infrastructure/github/README.md +11 -11
  24. package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
  25. package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  26. package/.morph/{templates → framework/templates}/meta-prompts/validators/pre-commit-validator.md +1 -1
  27. package/.morph/logs/tool-failures.log +7 -0
  28. package/.morph/memory/pre-compact-2026-02-23T15-43-03-521Z.json +16 -0
  29. package/.morph/state.json +1 -1
  30. package/CLAUDE.md +77 -155
  31. package/README.md +20 -18
  32. package/bin/detect-agents.js +1 -1
  33. package/bin/morph-spec.js +116 -266
  34. package/bin/task-manager.cjs +2 -2
  35. package/bin/validate.js +1 -1
  36. package/claude-plugin.json +14 -0
  37. package/docs/claude-alignment-report.md +137 -0
  38. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +512 -0
  39. package/docs/plans/2026-02-22-claude-settings.md +515 -0
  40. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +728 -0
  41. package/docs/plans/2026-02-22-morph-spec-next.md +478 -0
  42. package/docs/plans/2026-02-22-native-alignment-design.md +199 -0
  43. package/docs/plans/2026-02-22-native-alignment-impl.md +925 -0
  44. package/docs/plans/2026-02-22-native-enrichment-design.md +244 -0
  45. package/docs/plans/2026-02-22-native-enrichment.md +735 -0
  46. package/framework/CLAUDE.md +77 -0
  47. package/framework/{skills/level-2-domains → agents}/ai-agents/ai-system-architect.md +7 -3
  48. package/framework/{skills/level-2-domains → agents}/architecture/po-pm-advisor.md +7 -1
  49. package/framework/{skills/level-2-domains → agents}/architecture/prompt-engineer.md +7 -1
  50. package/framework/{skills/level-2-domains → agents}/architecture/seo-growth-hacker.md +7 -1
  51. package/framework/{skills/level-2-domains → agents}/architecture/standards-architect.md +10 -6
  52. package/framework/agents/backend/api-designer.md +103 -0
  53. package/framework/{skills/level-2-domains → agents}/backend/dotnet-senior.md +7 -1
  54. package/framework/agents/backend/ef-modeler.md +119 -0
  55. package/framework/{skills/level-2-domains → agents}/backend/hangfire-orchestrator.md +8 -4
  56. package/framework/{skills/level-2-domains → agents}/backend/ms-agent-expert.md +7 -3
  57. package/framework/{skills/level-2-domains → agents}/frontend/blazor-builder.md +7 -3
  58. package/framework/{skills/level-2-domains → agents}/frontend/nextjs-expert.md +7 -3
  59. package/framework/{skills/level-2-domains → agents}/frontend/ui-ux-designer.md +8 -2
  60. package/framework/{skills/level-2-domains → agents}/infrastructure/azure-architect.md +7 -1
  61. package/framework/{skills/level-2-domains → agents}/infrastructure/azure-deploy-specialist.md +7 -1
  62. package/framework/{skills/level-2-domains → agents}/infrastructure/bicep-architect.md +7 -3
  63. package/framework/{skills/level-2-domains → agents}/infrastructure/container-specialist.md +7 -3
  64. package/framework/{skills/level-2-domains → agents}/infrastructure/devops-engineer.md +7 -3
  65. package/framework/{skills/level-2-domains → agents}/integrations/asaas-financial.md +7 -3
  66. package/framework/{skills/level-2-domains → agents}/integrations/azure-identity.md +7 -3
  67. package/framework/{skills/level-2-domains → agents}/integrations/clerk-auth.md +7 -3
  68. package/framework/{skills/level-2-domains/integrations/hangfire-orchestrator.md → agents/integrations/hangfire-integration.md} +7 -1
  69. package/framework/{skills/level-2-domains → agents}/integrations/resend-email.md +7 -3
  70. package/framework/{skills/level-2-domains → agents}/quality/code-analyzer.md +9 -5
  71. package/framework/{skills/level-2-domains → agents}/quality/testing-specialist.md +7 -3
  72. package/framework/commands/morph-apply.md +9 -9
  73. package/framework/commands/morph-archive.md +8 -8
  74. package/framework/commands/morph-infra.md +1 -1
  75. package/framework/commands/morph-proposal.md +9 -9
  76. package/framework/commands/morph-status.md +3 -3
  77. package/framework/commands/morph-troubleshoot.md +1 -1
  78. package/framework/hooks/README.md +201 -282
  79. package/framework/hooks/claude-code/notification/approval-reminder.js +52 -0
  80. package/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
  81. package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
  82. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
  83. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
  84. package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
  85. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
  86. package/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
  87. package/framework/hooks/claude-code/statusline.py +538 -0
  88. package/framework/hooks/claude-code/statusline.sh +7 -0
  89. package/framework/hooks/claude-code/stop/validate-completion.js +88 -0
  90. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
  91. package/framework/hooks/shared/hook-response.js +45 -0
  92. package/framework/hooks/shared/phase-utils.js +129 -0
  93. package/framework/hooks/shared/state-reader.js +138 -0
  94. package/framework/hooks/shared/stdin-reader.js +26 -0
  95. package/framework/phases.json +145 -0
  96. package/framework/rules/csharp-standards.md +10 -0
  97. package/framework/rules/frontend-standards.md +14 -0
  98. package/framework/rules/infrastructure-standards.md +13 -0
  99. package/framework/rules/morph-workflow.md +86 -0
  100. package/framework/rules/testing-standards.md +11 -0
  101. package/framework/skills/README.md +66 -0
  102. package/framework/skills/level-0-meta/brainstorming/SKILL.md +135 -0
  103. package/framework/skills/level-0-meta/brainstorming/references/proposal-example.md +138 -0
  104. package/framework/skills/level-0-meta/{code-review.md → code-review/SKILL.md} +13 -4
  105. package/framework/skills/level-0-meta/code-review/references/review-example.md +164 -0
  106. package/framework/skills/level-0-meta/code-review/scripts/scan-csharp.mjs +121 -0
  107. package/framework/skills/level-0-meta/mcp-registry.json +207 -0
  108. package/framework/skills/level-0-meta/{morph-checklist.md → morph-checklist/SKILL.md} +8 -3
  109. package/framework/skills/{level-1-workflows/morph-replicate.md → level-0-meta/morph-replicate/SKILL.md} +13 -6
  110. package/framework/skills/level-0-meta/{simulation-checklist.md → simulation-checklist/SKILL.md} +9 -4
  111. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +334 -0
  112. package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +147 -0
  113. package/framework/skills/level-0-meta/verification-before-completion/scripts/check-phase-outputs.mjs +110 -0
  114. package/framework/skills/level-1-workflows/{phase-clarify.md → phase-clarify/SKILL.md} +65 -4
  115. package/framework/skills/level-1-workflows/phase-clarify/references/clarifications-example.md +117 -0
  116. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +181 -0
  117. package/framework/skills/level-1-workflows/phase-design/SKILL.md +303 -0
  118. package/framework/skills/level-1-workflows/phase-design/references/spec-example.md +253 -0
  119. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +254 -0
  120. package/framework/skills/level-1-workflows/phase-implement/references/recap-example.md +132 -0
  121. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +171 -0
  122. package/framework/skills/level-1-workflows/{phase-tasks.md → phase-tasks/SKILL.md} +89 -7
  123. package/framework/skills/level-1-workflows/phase-tasks/references/tasks-example.md +231 -0
  124. package/framework/skills/level-1-workflows/phase-tasks/scripts/validate-tasks.mjs +112 -0
  125. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +246 -0
  126. package/framework/standards/STANDARDS.json +812 -0
  127. package/framework/standards/ai-agents/team-orchestration.md +3 -3
  128. package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -0
  129. package/framework/standards/integration/mcp/mcp-tools.md +384 -0
  130. package/framework/templates/README.md +17 -17
  131. package/framework/templates/REGISTRY.json +48 -233
  132. package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
  133. package/framework/templates/context/CONTEXT-FEATURE.md +1 -1
  134. package/framework/templates/context/CONTEXT.md +3 -3
  135. package/framework/templates/docs/clarifications.md +253 -0
  136. package/framework/templates/docs/onboarding.md +123 -0
  137. package/framework/templates/docs/schema-analysis.md +119 -0
  138. package/framework/templates/docs/spec.md +149 -149
  139. package/framework/templates/docs/ui-components.md +124 -0
  140. package/framework/templates/docs/ui-design-system.md +76 -0
  141. package/framework/templates/docs/ui-flows.md +167 -0
  142. package/framework/templates/docs/ui-mockups.md +98 -0
  143. package/framework/templates/docs/user-stories.md +34 -0
  144. package/framework/templates/examples/spec-examples.md +1 -1
  145. package/framework/templates/infrastructure/github/README.md +11 -11
  146. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
  147. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  148. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +1 -1
  149. package/framework/workflows/configs/express.json +45 -0
  150. package/framework/workflows/configs/spec-only.json +43 -0
  151. package/framework/workflows/docs/enforcement-pipeline.md +8 -8
  152. package/framework/workflows/docs/full-morph.md +3 -3
  153. package/package.json +3 -1
  154. package/scripts/generate-refs.js +336 -0
  155. package/scripts/generate-standards-registry.js +44 -0
  156. package/scripts/validate-real.mjs +255 -0
  157. package/src/commands/feature/create-story.js +362 -361
  158. package/src/commands/feature/shard-spec.js +225 -224
  159. package/src/commands/feature/sprint-status.js +1 -1
  160. package/src/commands/generation/generate-onboarding.js +169 -0
  161. package/src/commands/generation/generate.js +2 -2
  162. package/src/commands/mcp/mcp-setup.js +315 -0
  163. package/src/commands/project/changes.js +66 -0
  164. package/src/commands/project/checkpoint.js +209 -0
  165. package/src/commands/project/cost.js +179 -0
  166. package/src/commands/project/diff.js +278 -0
  167. package/src/commands/project/doctor.js +55 -7
  168. package/src/commands/project/init.js +318 -136
  169. package/src/commands/project/revert.js +173 -0
  170. package/src/commands/project/standards.js +80 -0
  171. package/src/commands/project/status.js +376 -0
  172. package/src/commands/project/update-agents.js +23 -0
  173. package/src/commands/project/update.js +60 -88
  174. package/src/commands/state/advance-phase.js +4 -3
  175. package/src/commands/state/state.js +10 -3
  176. package/src/commands/state/validate-phase.js +19 -2
  177. package/src/commands/templates/template-customize.js +4 -4
  178. package/src/commands/templates/template-render.js +1 -1
  179. package/src/commands/templates/template-show.js +1 -1
  180. package/src/commands/validation/validate-feature.js +359 -0
  181. package/src/core/orchestrator.js +3 -38
  182. package/src/core/paths/output-schema.js +135 -0
  183. package/src/core/state/state-manager.js +831 -592
  184. package/src/core/templates/template-registry.js +2 -2
  185. package/src/core/workflows/workflow-detector.js +17 -1
  186. package/src/lib/agents/micro-agent-factory.js +1 -1
  187. package/src/lib/context/context-bundler.js +2 -1
  188. package/src/lib/detectors/claude-config-detector.js +390 -0
  189. package/src/lib/detectors/conversation-analyzer.js +4 -4
  190. package/src/lib/detectors/design-system-detector.js +6 -5
  191. package/src/lib/detectors/standards-generator.js +2 -2
  192. package/src/lib/generators/context-generator.js +539 -538
  193. package/src/lib/generators/recap-generator.js +1 -1
  194. package/src/lib/generators/settings-generator.js +210 -0
  195. package/src/lib/hooks/hook-executor.js +1 -1
  196. package/src/lib/installers/mcp-installer.js +299 -0
  197. package/src/lib/learning/learning-system.js +3 -3
  198. package/src/lib/orchestration/team-orchestrator.js +1 -1
  199. package/src/lib/standards/standards-context-injector.js +7 -7
  200. package/src/lib/threads/thread-coordinator.js +1 -1
  201. package/src/lib/troubleshooting/troubleshoot-grep.js +1 -1
  202. package/src/lib/validators/contracts/contract-compliance-validator.js +274 -273
  203. package/src/lib/validators/design-system/design-system-validator.js +1 -1
  204. package/src/lib/validators/spec-validator.js +258 -258
  205. package/src/lib/validators/validation-runner.js +270 -269
  206. package/src/utils/agents-installer.js +206 -0
  207. package/src/utils/claude-settings-manager.js +258 -0
  208. package/src/utils/file-copier.js +1 -1
  209. package/src/utils/hooks-installer.js +354 -28
  210. package/src/utils/skills-installer.js +118 -0
  211. package/.morph/project/context/README.md +0 -17
  212. package/.morph/project/context/detection-log.md +0 -16
  213. package/.morph/project/standards/inferred.md +0 -59
  214. package/framework/hooks/agent-stop/validate-and-continue.js +0 -96
  215. package/framework/hooks/agent-stop/validate-checkpoints.js +0 -101
  216. package/framework/hooks/agent-stop/validate-tests.js +0 -109
  217. package/framework/hooks/agent-teams/dispatch.js +0 -67
  218. package/framework/hooks/agent-teams/phase-advanced.js +0 -80
  219. package/framework/hooks/agent-teams/task-completed.js +0 -76
  220. package/framework/hooks/agent-teams/teammate-idle.js +0 -70
  221. package/framework/skills/level-1-workflows/phase-design.md +0 -213
  222. package/framework/skills/level-1-workflows/phase-setup.md +0 -106
  223. package/framework/skills/level-1-workflows/phase-uiux.md +0 -169
  224. package/framework/skills/level-2-domains/backend/api-designer.md +0 -59
  225. package/framework/skills/level-2-domains/backend/ef-modeler.md +0 -58
  226. package/framework/skills/level-3-technologies/README.md +0 -7
  227. package/framework/skills/level-4-patterns/README.md +0 -7
  228. package/src/commands/agents/agents-fuse.js +0 -97
  229. package/src/commands/agents/micro-agent.js +0 -112
  230. package/src/commands/agents/spawn-team.js +0 -237
  231. package/src/commands/agents/squad-template.js +0 -146
  232. package/src/commands/analytics/analytics.js +0 -176
  233. package/src/commands/context/context-prime.js +0 -63
  234. package/src/commands/context/core-four.js +0 -54
  235. package/src/commands/generation/generate-context.js +0 -40
  236. package/src/commands/project/detect-agents.js +0 -207
  237. package/src/commands/project/detect-workflow.js +0 -174
  238. package/src/commands/threads/thread-template.js +0 -103
  239. package/src/commands/threads/threads.js +0 -261
  240. package/src/commands/utils/session-summary.js +0 -291
  241. package/src/llm/analyzer.js +0 -215
  242. package/src/llm/few-shot-examples.js +0 -216
  243. package/src/llm/project-config-schema.json +0 -188
  244. package/src/llm/prompt-builder.js +0 -96
  245. /package/.morph/{config → framework}/agents.json +0 -0
  246. /package/.morph/{standards → framework/standards}/ai-agents/blazor-ui.md +0 -0
  247. /package/.morph/{standards → framework/standards}/ai-agents/production.md +0 -0
  248. /package/.morph/{standards → framework/standards}/ai-agents/setup.md +0 -0
  249. /package/.morph/{standards → framework/standards}/ai-agents/workflows.md +0 -0
  250. /package/.morph/{standards → framework/standards}/architecture/ddd/aggregates.md +0 -0
  251. /package/.morph/{standards → framework/standards}/architecture/ddd/entities.md +0 -0
  252. /package/.morph/{standards → framework/standards}/architecture/ddd/value-objects.md +0 -0
  253. /package/.morph/{standards → framework/standards}/backend/api/minimal-api.md +0 -0
  254. /package/.morph/{standards → framework/standards}/backend/api/rest.md +0 -0
  255. /package/.morph/{standards → framework/standards}/backend/api/validation.md +0 -0
  256. /package/.morph/{standards → framework/standards}/backend/authentication/passkeys.md +0 -0
  257. /package/.morph/{standards → framework/standards}/backend/database/ef-core.md +0 -0
  258. /package/.morph/{standards → framework/standards}/backend/database/migrations.md +0 -0
  259. /package/.morph/{standards → framework/standards}/backend/database/postgresql/database.md +0 -0
  260. /package/.morph/{standards → framework/standards}/backend/database/repository-patterns.md +0 -0
  261. /package/.morph/{standards → framework/standards}/backend/database/vector-search-rag.md +0 -0
  262. /package/.morph/{standards → framework/standards}/backend/dotnet/async.md +0 -0
  263. /package/.morph/{standards → framework/standards}/backend/dotnet/core.md +0 -0
  264. /package/.morph/{standards → framework/standards}/backend/dotnet/di.md +0 -0
  265. /package/.morph/{standards → framework/standards}/backend/dotnet/program-cs-checklist.md +0 -0
  266. /package/.morph/{standards → framework/standards}/backend/integrations/asaas/asaas-api.md +0 -0
  267. /package/.morph/{standards → framework/standards}/backend/integrations/clerk/clerk-auth.md +0 -0
  268. /package/.morph/{standards → framework/standards}/backend/integrations/hangfire/hangfire-jobs.md +0 -0
  269. /package/.morph/{standards → framework/standards}/backend/integrations/resend/resend-email.md +0 -0
  270. /package/.morph/{standards → framework/standards}/context/analytics.md +0 -0
  271. /package/.morph/{standards → framework/standards}/context/bundles.md +0 -0
  272. /package/.morph/{standards → framework/standards}/context/priming.md +0 -0
  273. /package/.morph/{standards → framework/standards}/core/architecture.md +0 -0
  274. /package/.morph/{standards → framework/standards}/core/coding.md +0 -0
  275. /package/.morph/{standards → framework/standards}/core/git-branching-strategy.md +0 -0
  276. /package/.morph/{standards → framework/standards}/core/git.md +0 -0
  277. /package/.morph/{standards → framework/standards}/core/testing.md +0 -0
  278. /package/.morph/{standards → framework/standards}/data/nosql/blob-storage.md +0 -0
  279. /package/.morph/{standards → framework/standards}/data/nosql/cache/redis.md +0 -0
  280. /package/.morph/{standards → framework/standards}/data/nosql/cosmos-db.md +0 -0
  281. /package/.morph/{standards → framework/standards}/data/vector-search/azure-ai-search.md +0 -0
  282. /package/.morph/{standards → framework/standards}/data/vector-search/rag-chunking.md +0 -0
  283. /package/.morph/{standards → framework/standards}/frontend/blazor/design-checklist.md +0 -0
  284. /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui-setup.md +0 -0
  285. /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui.md +0 -0
  286. /package/.morph/{standards → framework/standards}/frontend/blazor/html-conversion.md +0 -0
  287. /package/.morph/{standards → framework/standards}/frontend/blazor/lifecycle.md +0 -0
  288. /package/.morph/{standards → framework/standards}/frontend/blazor/pitfalls.md +0 -0
  289. /package/.morph/{standards → framework/standards}/frontend/blazor/state.md +0 -0
  290. /package/.morph/{standards → framework/standards}/frontend/design-system/animations.md +0 -0
  291. /package/.morph/{standards → framework/standards}/frontend/design-system/naming.md +0 -0
  292. /package/.morph/{standards → framework/standards}/infrastructure/azure/azure.md +0 -0
  293. /package/.morph/{standards → framework/standards}/infrastructure/azure/bicep/bicep-patterns.md +0 -0
  294. /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/azure-devops-setup.md +0 -0
  295. /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/local-development.md +0 -0
  296. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/functions.md +0 -0
  297. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/service-bus.md +0 -0
  298. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/storage.md +0 -0
  299. /package/.morph/{standards → framework/standards}/infrastructure/docker/easypanel-deploy.md +0 -0
  300. /package/.morph/{standards → framework/standards}/infrastructure/supabase/mcp-setup.md +0 -0
  301. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-auth.md +0 -0
  302. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-pgvector.md +0 -0
  303. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-rls.md +0 -0
  304. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-storage.md +0 -0
  305. /package/.morph/{standards → framework/standards}/integration/api/graphql.md +0 -0
  306. /package/.morph/{standards → framework/standards}/integration/api/grpc.md +0 -0
  307. /package/.morph/{standards → framework/standards}/integration/api/rest-design.md +0 -0
  308. /package/.morph/{standards → framework/standards}/integration/event-driven/cqrs.md +0 -0
  309. /package/.morph/{standards → framework/standards}/integration/event-driven/event-sourcing.md +0 -0
  310. /package/.morph/{standards → framework/standards}/integration/event-driven/service-bus.md +0 -0
  311. /package/.morph/{standards → framework/standards}/observability/logging.md +0 -0
  312. /package/.morph/{standards → framework/standards}/observability/metrics.md +0 -0
  313. /package/.morph/{standards → framework/standards}/observability/monitoring.md +0 -0
  314. /package/.morph/{standards → framework/standards}/observability/tracing.md +0 -0
  315. /package/.morph/{standards → framework/standards}/workflows/parallel-execution.md +0 -0
  316. /package/.morph/{standards → framework/standards}/workflows/thread-management.md +0 -0
  317. /package/.morph/{templates → framework/templates}/.idea/morph-templates.xml +0 -0
  318. /package/.morph/{templates → framework/templates}/.vscode/morph-templates.code-snippets +0 -0
  319. /package/.morph/{templates → framework/templates}/IDE-SNIPPETS.md +0 -0
  320. /package/.morph/{templates → framework/templates}/code/dotnet/backend/repository.cs +0 -0
  321. /package/.morph/{templates → framework/templates}/code/dotnet/backend/service.cs +0 -0
  322. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Commands.cs +0 -0
  323. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Entities.cs +0 -0
  324. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Queries.cs +0 -0
  325. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/README.md +0 -0
  326. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/api-contracts.cs +0 -0
  327. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/contracts.cs +0 -0
  328. /package/.morph/{templates → framework/templates}/code/dotnet/database/migration.cs +0 -0
  329. /package/.morph/{templates → framework/templates}/code/dotnet/frontend/component.razor +0 -0
  330. /package/.morph/{templates → framework/templates}/code/dotnet/jobs/agent.cs +0 -0
  331. /package/.morph/{templates → framework/templates}/code/dotnet/jobs/job.cs +0 -0
  332. /package/.morph/{templates → framework/templates}/code/dotnet/test.cs +0 -0
  333. /package/.morph/{templates → framework/templates}/code/sql/rls-policy.sql +0 -0
  334. /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.sql +0 -0
  335. /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.template.sql +0 -0
  336. /package/.morph/{templates → framework/templates}/code/typescript/contracts.ts +0 -0
  337. /package/.morph/{templates → framework/templates}/docs/proposal.md +0 -0
  338. /package/.morph/{templates → framework/templates}/examples/design-system-examples.md +0 -0
  339. /package/.morph/{templates → framework/templates}/feature/decisions.md +0 -0
  340. /package/.morph/{templates → framework/templates}/feature/recap.md +0 -0
  341. /package/.morph/{templates → framework/templates}/feature/tasks.md +0 -0
  342. /package/.morph/{templates → framework/templates}/infrastructure/azure/Dockerfile.example +0 -0
  343. /package/.morph/{templates → framework/templates}/infrastructure/azure/README.md +0 -0
  344. /package/.morph/{templates → framework/templates}/infrastructure/azure/app-insights.bicep +0 -0
  345. /package/.morph/{templates → framework/templates}/infrastructure/azure/app-service.bicep +0 -0
  346. /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app-env.bicep +0 -0
  347. /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app.bicep +0 -0
  348. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy-checklist.md +0 -0
  349. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.ps1 +0 -0
  350. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.sh +0 -0
  351. /package/.morph/{templates → framework/templates}/infrastructure/azure/key-vault.bicep +0 -0
  352. /package/.morph/{templates → framework/templates}/infrastructure/azure/main.bicep +0 -0
  353. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.dev.json +0 -0
  354. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.prod.json +0 -0
  355. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.staging.json +0 -0
  356. /package/.morph/{templates → framework/templates}/infrastructure/azure/sql-database.bicep +0 -0
  357. /package/.morph/{templates → framework/templates}/infrastructure/azure/storage.bicep +0 -0
  358. /package/.morph/{templates → framework/templates}/infrastructure/docker/Dockerfile.template +0 -0
  359. /package/.morph/{templates → framework/templates}/infrastructure/docker/docker-compose.template.yml +0 -0
  360. /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-api.dockerfile +0 -0
  361. /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-web.dockerfile +0 -0
  362. /package/.morph/{templates → framework/templates}/infrastructure/docker/easypanel.template.json +0 -0
  363. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -0
  364. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -0
  365. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/health-check/action.yml.hbs +0 -0
  366. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -0
  367. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -0
  368. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -0
  369. /package/.morph/{templates → framework/templates}/integrations/asaas-client.cs +0 -0
  370. /package/.morph/{templates → framework/templates}/integrations/asaas-webhook.cs +0 -0
  371. /package/.morph/{templates → framework/templates}/integrations/azure-identity-config.cs +0 -0
  372. /package/.morph/{templates → framework/templates}/integrations/clerk-config.cs +0 -0
  373. /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-agent.md +0 -0
  374. /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-aggregator.md +0 -0
  375. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-retry.md +0 -0
  376. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-validation.md +0 -0
  377. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-wrapper.md +0 -0
  378. /package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-coordinator.md +0 -0
  379. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/backend-squad.md +0 -0
  380. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/frontend-squad.md +0 -0
  381. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/squad-leader.md +0 -0
  382. /package/.morph/{templates → framework/templates}/meta-prompts/validators/checkpoint-validator.md +0 -0
  383. /package/.morph/{templates → framework/templates}/saas/subscription.cs +0 -0
  384. /package/.morph/{templates → framework/templates}/saas/tenant.cs +0 -0
  385. /package/.morph/{templates → framework/templates}/state.template.json +0 -0
  386. /package/.morph/{templates → framework/templates}/ui/FluentDesignTheme.cs +0 -0
  387. /package/.morph/{templates → framework/templates}/ui/MudTheme.cs +0 -0
  388. /package/.morph/{templates → framework/templates}/ui/design-system.css +0 -0
  389. /package/framework/{skills/level-2-domains → agents}/README.md +0 -0
  390. /package/framework/hooks/{commit-msg → git/commit-msg}/conventional-commits.sh +0 -0
  391. /package/framework/hooks/{pre-commit → git/pre-commit}/agents.sh +0 -0
  392. /package/framework/hooks/{pre-commit → git/pre-commit}/orchestrator.sh +0 -0
  393. /package/framework/hooks/{pre-commit → git/pre-commit}/specs.sh +0 -0
  394. /package/framework/hooks/{pre-push → git/pre-push}/run-tests.sh +0 -0
@@ -0,0 +1,315 @@
1
+ /**
2
+ * MCP Setup Command
3
+ *
4
+ * Install and configure MCP servers for morph-spec projects.
5
+ *
6
+ * Usage:
7
+ * morph-spec mcp setup — Interactive wizard showing all MCPs
8
+ * morph-spec mcp setup <name> — Setup a specific MCP
9
+ * morph-spec mcp setup --list — Show MCP install status
10
+ * morph-spec mcp setup --auto — Non-interactive auto-install credential-free MCPs
11
+ */
12
+
13
+ import chalk from 'chalk';
14
+ import inquirer from 'inquirer';
15
+ import ora from 'ora';
16
+ import {
17
+ orchestrateMcpSetup,
18
+ installAutoMcps,
19
+ installMcpWithCredentials,
20
+ generateSetupInstructions,
21
+ formatMcpStatusTable,
22
+ loadMcpRegistry
23
+ } from '../../lib/installers/mcp-installer.js';
24
+ import { detectClaudeConfig } from '../../lib/detectors/claude-config-detector.js';
25
+ import { detectProject } from '../../lib/detectors/index.js';
26
+
27
+ /**
28
+ * Detect the current project's stack
29
+ */
30
+ async function detectStack(targetPath) {
31
+ try {
32
+ const results = await detectProject(targetPath, { conversation: false, generateStandards: false });
33
+ return results.structure?.stack || 'unknown';
34
+ } catch {
35
+ return 'unknown';
36
+ }
37
+ }
38
+
39
+ export async function mcpSetupCommand(name, options) {
40
+ const targetPath = process.cwd();
41
+
42
+ try {
43
+ // Detect current environment
44
+ const stack = await detectStack(targetPath);
45
+ const claudeConfig = await detectClaudeConfig(targetPath);
46
+ const existingMcps = claudeConfig.mcpServers || [];
47
+
48
+ if (options.list) {
49
+ return showStatusList(targetPath, stack, existingMcps);
50
+ }
51
+
52
+ if (options.auto) {
53
+ return autoInstall(targetPath, stack, existingMcps);
54
+ }
55
+
56
+ if (name) {
57
+ return setupSpecificMcp(targetPath, name, stack, existingMcps);
58
+ }
59
+
60
+ // Interactive wizard
61
+ return interactiveWizard(targetPath, stack, existingMcps);
62
+ } catch (err) {
63
+ console.error(chalk.red(`Error: ${err.message}`));
64
+ process.exit(1);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Show MCP status list (--list)
70
+ */
71
+ async function showStatusList(targetPath, stack, existingMcps) {
72
+ const orchestration = orchestrateMcpSetup(targetPath, stack, existingMcps);
73
+ const statusRows = formatMcpStatusTable(orchestration, {});
74
+
75
+ console.log(chalk.cyan('\n MCP Server Status\n'));
76
+ console.log(` Stack: ${chalk.bold(stack)}`);
77
+ console.log(' ' + '─'.repeat(60));
78
+
79
+ const STATUS_ICONS = {
80
+ installed: chalk.green('✓'),
81
+ available: chalk.cyan('○'),
82
+ already_configured: chalk.green('✓'),
83
+ needs_setup: chalk.yellow('⚠'),
84
+ prereq_missing: chalk.red('✗'),
85
+ not_relevant: chalk.gray('─')
86
+ };
87
+
88
+ if (statusRows.length === 0) {
89
+ console.log(chalk.gray('\n No MCPs in registry.\n'));
90
+ return;
91
+ }
92
+
93
+ for (const row of statusRows) {
94
+ const icon = STATUS_ICONS[row.status] || '?';
95
+ const statusLabel = row.status.replace(/_/g, ' ');
96
+ console.log(` ${icon} ${row.name.padEnd(15)} ${statusLabel.padEnd(20)} ${chalk.gray(row.detail)}`);
97
+ }
98
+
99
+ console.log('');
100
+ }
101
+
102
+ /**
103
+ * Auto-install credential-free MCPs (--auto)
104
+ */
105
+ async function autoInstall(targetPath, stack, existingMcps) {
106
+ const orchestration = orchestrateMcpSetup(targetPath, stack, existingMcps, { autoOnly: true });
107
+ const autoNames = Object.keys(orchestration.autoInstallable);
108
+
109
+ if (autoNames.length === 0) {
110
+ console.log(chalk.green('\n ✓ All auto-installable MCPs are already configured.\n'));
111
+ return;
112
+ }
113
+
114
+ const spinner = ora(`Installing ${autoNames.join(', ')}...`).start();
115
+ const result = await installAutoMcps(targetPath, orchestration.autoInstallable);
116
+ spinner.succeed(`Installed ${result.added.length} MCP server(s): ${result.added.join(', ')}`);
117
+
118
+ if (result.skipped.length > 0) {
119
+ console.log(chalk.gray(` Skipped (already configured): ${result.skipped.join(', ')}`));
120
+ }
121
+
122
+ console.log('');
123
+ }
124
+
125
+ /**
126
+ * Setup a specific MCP by name
127
+ */
128
+ async function setupSpecificMcp(targetPath, name, stack, existingMcps) {
129
+ const registry = loadMcpRegistry();
130
+ const mcpEntry = registry.mcps[name];
131
+
132
+ if (!mcpEntry) {
133
+ console.log(chalk.red(`\n Unknown MCP: ${name}`));
134
+ console.log(chalk.gray(` Available: ${Object.keys(registry.mcps).join(', ')}`));
135
+ console.log('');
136
+ return;
137
+ }
138
+
139
+ if (!mcpEntry.install) {
140
+ console.log(chalk.red(`\n MCP "${name}" has no install configuration.\n`));
141
+ return;
142
+ }
143
+
144
+ // Check if already installed
145
+ const isInstalled = existingMcps.some(s => s.name.toLowerCase().includes(name));
146
+ if (isInstalled) {
147
+ const { reconfigure } = await inquirer.prompt([{
148
+ type: 'confirm',
149
+ name: 'reconfigure',
150
+ message: `${name} is already configured. Reconfigure?`,
151
+ default: false
152
+ }]);
153
+ if (!reconfigure) return;
154
+ }
155
+
156
+ // Check prerequisites
157
+ const prereqs = mcpEntry.install.prerequisites || [];
158
+ for (const prereq of prereqs) {
159
+ try {
160
+ const { execSync } = await import('child_process');
161
+ execSync(prereq.checkCommand, { stdio: 'ignore', timeout: 5000 });
162
+ } catch {
163
+ console.log(chalk.red(`\n Missing prerequisite: ${prereq.name}`));
164
+ console.log(chalk.gray(` Install: ${prereq.installUrl}`));
165
+ console.log('');
166
+ return;
167
+ }
168
+ }
169
+
170
+ // Show warnings
171
+ for (const warning of mcpEntry.install.warnings || []) {
172
+ console.log(chalk.yellow(`\n ⚠ ${warning}`));
173
+ }
174
+
175
+ const credentials = mcpEntry.install.credentials || [];
176
+
177
+ // Auto-installable — just install
178
+ if (mcpEntry.install.autoInstall) {
179
+ const spinner = ora(`Installing ${name}...`).start();
180
+ const result = await installAutoMcps(targetPath, { [name]: mcpEntry });
181
+ if (result.added.length > 0) {
182
+ spinner.succeed(`${name} MCP installed`);
183
+ } else {
184
+ spinner.info(`${name} MCP already configured`);
185
+ }
186
+ console.log('');
187
+ return;
188
+ }
189
+
190
+ // Needs credentials
191
+ console.log(chalk.cyan(`\n Setting up ${name} MCP\n`));
192
+ console.log(chalk.gray(` Usage: ${mcpEntry.usage}`));
193
+ console.log('');
194
+
195
+ const { enterCredentials } = await inquirer.prompt([{
196
+ type: 'confirm',
197
+ name: 'enterCredentials',
198
+ message: 'Enter credentials now?',
199
+ default: true
200
+ }]);
201
+
202
+ if (enterCredentials) {
203
+ const credentialValues = {};
204
+ for (const cred of credentials) {
205
+ const { value } = await inquirer.prompt([{
206
+ type: cred.secret ? 'password' : 'input',
207
+ name: 'value',
208
+ message: `${cred.name}:`,
209
+ mask: cred.secret ? '*' : undefined
210
+ }]);
211
+ credentialValues[cred.envVar] = value;
212
+ }
213
+
214
+ const spinner = ora(`Configuring ${name}...`).start();
215
+ await installMcpWithCredentials(targetPath, name, mcpEntry, credentialValues);
216
+ spinner.succeed(`${name} MCP configured`);
217
+ } else {
218
+ // Show config snippet
219
+ const instructions = generateSetupInstructions(name, mcpEntry);
220
+ console.log(chalk.gray('\n Add to .claude/settings.local.json → mcpServers:'));
221
+ console.log(chalk.gray(' ' + '─'.repeat(55)));
222
+ for (const line of instructions.configSnippet.split('\n')) {
223
+ console.log(chalk.gray(` ${line}`));
224
+ }
225
+ console.log(chalk.gray(' ' + '─'.repeat(55)));
226
+
227
+ for (const cred of instructions.credentialUrls) {
228
+ console.log(chalk.gray(` Get ${cred.name}: ${cred.helpUrl}`));
229
+ }
230
+ }
231
+
232
+ console.log('');
233
+ }
234
+
235
+ /**
236
+ * Interactive wizard showing all MCPs
237
+ */
238
+ async function interactiveWizard(targetPath, stack, existingMcps) {
239
+ const orchestration = orchestrateMcpSetup(targetPath, stack, existingMcps);
240
+
241
+ console.log(chalk.cyan('\n MCP Setup Wizard'));
242
+ console.log(chalk.gray(` Stack: ${stack}`));
243
+ console.log('');
244
+
245
+ const autoNames = Object.keys(orchestration.autoInstallable);
246
+ const manualNames = Object.keys(orchestration.needsManualSetup);
247
+ const alreadyNames = Object.keys(orchestration.alreadyInstalled);
248
+
249
+ if (alreadyNames.length > 0) {
250
+ console.log(chalk.green(` Already configured: ${alreadyNames.join(', ')}`));
251
+ }
252
+
253
+ // Auto-install
254
+ if (autoNames.length > 0) {
255
+ const { installAuto } = await inquirer.prompt([{
256
+ type: 'confirm',
257
+ name: 'installAuto',
258
+ message: `Install credential-free MCPs? (${autoNames.join(', ')})`,
259
+ default: true
260
+ }]);
261
+
262
+ if (installAuto) {
263
+ const spinner = ora('Installing...').start();
264
+ const result = await installAutoMcps(targetPath, orchestration.autoInstallable);
265
+ spinner.succeed(`Installed: ${result.added.join(', ')}`);
266
+ }
267
+ }
268
+
269
+ // Credential MCPs
270
+ if (manualNames.length > 0) {
271
+ console.log(chalk.cyan('\n Credential-requiring MCPs:'));
272
+
273
+ for (const name of manualNames) {
274
+ const entry = orchestration.needsManualSetup[name];
275
+
276
+ for (const warning of entry.install.warnings || []) {
277
+ console.log(chalk.yellow(` ⚠ ${warning}`));
278
+ }
279
+
280
+ const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
281
+ const { setupNow } = await inquirer.prompt([{
282
+ type: 'confirm',
283
+ name: 'setupNow',
284
+ message: `Set up ${capitalizedName}? (${entry.usage})`,
285
+ default: false
286
+ }]);
287
+
288
+ if (setupNow) {
289
+ const credentialValues = {};
290
+ for (const cred of entry.install.credentials) {
291
+ const { value } = await inquirer.prompt([{
292
+ type: cred.secret ? 'password' : 'input',
293
+ name: 'value',
294
+ message: `${cred.name}:`,
295
+ mask: cred.secret ? '*' : undefined
296
+ }]);
297
+ credentialValues[cred.envVar] = value;
298
+ }
299
+
300
+ const spinner = ora(`Configuring ${name}...`).start();
301
+ await installMcpWithCredentials(targetPath, name, entry, credentialValues);
302
+ spinner.succeed(`${capitalizedName} configured`);
303
+ } else {
304
+ const instructions = generateSetupInstructions(name, entry);
305
+ console.log(chalk.gray(` Run later: ${instructions.cliCommand}`));
306
+ }
307
+ }
308
+ }
309
+
310
+ if (autoNames.length === 0 && manualNames.length === 0) {
311
+ console.log(chalk.green(' ✓ All relevant MCPs are already configured.\n'));
312
+ } else {
313
+ console.log('');
314
+ }
315
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Changes Command
3
+ *
4
+ * Lists files created/modified by a feature, grouped by phase.
5
+ */
6
+
7
+ import chalk from 'chalk';
8
+ import { logger } from '../../utils/logger.js';
9
+ import { getFileChanges } from '../../core/state/state-manager.js';
10
+
11
+ export async function changesCommand(feature, options = {}) {
12
+ if (!feature) {
13
+ logger.error('Usage: morph-spec changes <feature>');
14
+ process.exit(1);
15
+ }
16
+
17
+ try {
18
+ const grouped = getFileChanges(feature, { groupByPhase: true });
19
+
20
+ if (options.json) {
21
+ console.log(JSON.stringify(grouped, null, 2));
22
+ return;
23
+ }
24
+
25
+ const phases = Object.keys(grouped);
26
+
27
+ if (phases.length === 0) {
28
+ logger.warn(`No file changes tracked for feature '${feature}'.`);
29
+ return;
30
+ }
31
+
32
+ logger.header(`File Changes — ${feature}`);
33
+
34
+ let totalFiles = 0;
35
+
36
+ for (const phase of phases) {
37
+ const changes = grouped[phase];
38
+ totalFiles += changes.length;
39
+
40
+ console.log(chalk.cyan(`\n Phase: ${phase} (${changes.length} files)`));
41
+ console.log(' ' + '─'.repeat(50));
42
+
43
+ for (const change of changes) {
44
+ const actionIcon = {
45
+ created: chalk.green('+'),
46
+ modified: chalk.yellow('~'),
47
+ deleted: chalk.red('-')
48
+ }[change.action] || ' ';
49
+
50
+ const timestamp = change.timestamp
51
+ ? chalk.dim(` (${new Date(change.timestamp).toLocaleDateString()})`)
52
+ : '';
53
+
54
+ console.log(` ${actionIcon} ${change.path}${timestamp}`);
55
+ }
56
+ }
57
+
58
+ logger.blank();
59
+ logger.dim(`Total: ${totalFiles} file(s) across ${phases.length} phase(s)`);
60
+ logger.blank();
61
+
62
+ } catch (error) {
63
+ logger.error(error.message);
64
+ process.exit(1);
65
+ }
66
+ }
@@ -0,0 +1,209 @@
1
+ /**
2
+ * MORPH-SPEC Checkpoint Save/Restore Command
3
+ *
4
+ * Save and restore full context at phase boundaries.
5
+ *
6
+ * Usage:
7
+ * morph-spec checkpoint save <feature-name>
8
+ * morph-spec checkpoint restore <feature-name>
9
+ * morph-spec checkpoint list <feature-name>
10
+ */
11
+
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import chalk from 'chalk';
15
+ import { loadState, saveState, getFeature } from '../../core/state/state-manager.js';
16
+
17
+ /**
18
+ * Get checkpoints directory for a feature
19
+ */
20
+ function getCheckpointsDir(featureName) {
21
+ return path.join(process.cwd(), '.morph/checkpoints', featureName);
22
+ }
23
+
24
+ /**
25
+ * Save checkpoint command
26
+ */
27
+ export async function checkpointSaveCommand(featureName, options = {}) {
28
+ if (!featureName) {
29
+ console.error(chalk.red('Error: Feature name required'));
30
+ process.exit(1);
31
+ }
32
+
33
+ const feature = getFeature(featureName);
34
+ if (!feature) {
35
+ console.error(chalk.red(`Error: Feature '${featureName}' not found`));
36
+ process.exit(1);
37
+ }
38
+
39
+ const outputDir = path.join(process.cwd(), '.morph/features', featureName);
40
+ if (!fs.existsSync(outputDir)) {
41
+ console.error(chalk.red(`Error: No outputs found for '${featureName}'`));
42
+ process.exit(1);
43
+ }
44
+
45
+ // Create checkpoint directory with timestamp
46
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
47
+ const label = options.label || feature.phase;
48
+ const checkpointName = `${label}_${timestamp}`;
49
+ const checkpointDir = path.join(getCheckpointsDir(featureName), checkpointName);
50
+ fs.mkdirSync(checkpointDir, { recursive: true });
51
+
52
+ // Copy all output files
53
+ const files = fs.readdirSync(outputDir);
54
+ let fileCount = 0;
55
+ for (const file of files) {
56
+ const src = path.join(outputDir, file);
57
+ const stat = fs.statSync(src);
58
+ if (stat.isFile()) {
59
+ fs.copyFileSync(src, path.join(checkpointDir, file));
60
+ fileCount++;
61
+ }
62
+ }
63
+
64
+ // Save state snapshot
65
+ const stateSnapshot = {
66
+ feature: { ...feature },
67
+ timestamp: new Date().toISOString(),
68
+ phase: feature.phase,
69
+ label,
70
+ files: files.filter(f => fs.statSync(path.join(outputDir, f)).isFile())
71
+ };
72
+ fs.writeFileSync(
73
+ path.join(checkpointDir, '_checkpoint.json'),
74
+ JSON.stringify(stateSnapshot, null, 2)
75
+ );
76
+
77
+ console.log(chalk.green(`\n✓ Checkpoint saved: ${checkpointName}`));
78
+ console.log(chalk.gray(` Phase: ${feature.phase}`));
79
+ console.log(chalk.gray(` Files: ${fileCount}`));
80
+ console.log(chalk.gray(` Path: ${checkpointDir}\n`));
81
+ }
82
+
83
+ /**
84
+ * Restore checkpoint command
85
+ */
86
+ export async function checkpointRestoreCommand(featureName, checkpointName, options = {}) {
87
+ if (!featureName) {
88
+ console.error(chalk.red('Error: Feature name required'));
89
+ process.exit(1);
90
+ }
91
+
92
+ const checkpointsDir = getCheckpointsDir(featureName);
93
+ if (!fs.existsSync(checkpointsDir)) {
94
+ console.error(chalk.red(`Error: No checkpoints found for '${featureName}'`));
95
+ process.exit(1);
96
+ }
97
+
98
+ // Find checkpoint to restore
99
+ let targetDir;
100
+ if (checkpointName) {
101
+ targetDir = path.join(checkpointsDir, checkpointName);
102
+ if (!fs.existsSync(targetDir)) {
103
+ console.error(chalk.red(`Error: Checkpoint '${checkpointName}' not found`));
104
+ process.exit(1);
105
+ }
106
+ } else {
107
+ // Restore latest
108
+ const checkpoints = fs.readdirSync(checkpointsDir)
109
+ .filter(d => fs.statSync(path.join(checkpointsDir, d)).isDirectory())
110
+ .sort()
111
+ .reverse();
112
+
113
+ if (checkpoints.length === 0) {
114
+ console.error(chalk.red(`Error: No checkpoints found for '${featureName}'`));
115
+ process.exit(1);
116
+ }
117
+
118
+ targetDir = path.join(checkpointsDir, checkpoints[0]);
119
+ checkpointName = checkpoints[0];
120
+ }
121
+
122
+ // Read checkpoint metadata
123
+ const metaPath = path.join(targetDir, '_checkpoint.json');
124
+ if (!fs.existsSync(metaPath)) {
125
+ console.error(chalk.red('Error: Checkpoint metadata not found'));
126
+ process.exit(1);
127
+ }
128
+
129
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
130
+
131
+ // Restore output files
132
+ const outputDir = path.join(process.cwd(), '.morph/features', featureName);
133
+ fs.mkdirSync(outputDir, { recursive: true });
134
+
135
+ const files = fs.readdirSync(targetDir).filter(f => f !== '_checkpoint.json');
136
+ for (const file of files) {
137
+ fs.copyFileSync(path.join(targetDir, file), path.join(outputDir, file));
138
+ }
139
+
140
+ // Restore state
141
+ const state = loadState();
142
+ if (state.features[featureName] && meta.feature) {
143
+ // Preserve some current fields, restore phase and outputs
144
+ state.features[featureName].phase = meta.feature.phase;
145
+ state.features[featureName].outputs = meta.feature.outputs;
146
+ state.features[featureName].tasks = meta.feature.tasks;
147
+ state.features[featureName].approvalGates = meta.feature.approvalGates;
148
+ state.features[featureName].updatedAt = new Date().toISOString();
149
+ saveState(state);
150
+ }
151
+
152
+ console.log(chalk.green(`\n✓ Checkpoint restored: ${checkpointName}`));
153
+ console.log(chalk.gray(` Phase: ${meta.phase}`));
154
+ console.log(chalk.gray(` Files restored: ${files.length}`));
155
+ console.log(chalk.gray(` Original date: ${meta.timestamp}\n`));
156
+ }
157
+
158
+ /**
159
+ * List checkpoints command
160
+ */
161
+ export async function checkpointListCommand(featureName, options = {}) {
162
+ if (!featureName) {
163
+ console.error(chalk.red('Error: Feature name required'));
164
+ process.exit(1);
165
+ }
166
+
167
+ const checkpointsDir = getCheckpointsDir(featureName);
168
+ if (!fs.existsSync(checkpointsDir)) {
169
+ console.log(chalk.gray(`No checkpoints found for '${featureName}'.\n`));
170
+ return;
171
+ }
172
+
173
+ const checkpoints = fs.readdirSync(checkpointsDir)
174
+ .filter(d => fs.statSync(path.join(checkpointsDir, d)).isDirectory())
175
+ .sort()
176
+ .reverse();
177
+
178
+ if (checkpoints.length === 0) {
179
+ console.log(chalk.gray(`No checkpoints found for '${featureName}'.\n`));
180
+ return;
181
+ }
182
+
183
+ // JSON output
184
+ if (options.json) {
185
+ const list = checkpoints.map(cp => {
186
+ const metaPath = path.join(checkpointsDir, cp, '_checkpoint.json');
187
+ const meta = fs.existsSync(metaPath) ? JSON.parse(fs.readFileSync(metaPath, 'utf8')) : {};
188
+ return { name: cp, phase: meta.phase, timestamp: meta.timestamp, files: meta.files?.length || 0 };
189
+ });
190
+ console.log(JSON.stringify({ feature: featureName, checkpoints: list }, null, 2));
191
+ return;
192
+ }
193
+
194
+ // Visual output
195
+ console.log(chalk.cyan(`\nCheckpoints for '${featureName}':\n`));
196
+
197
+ for (const cp of checkpoints) {
198
+ const metaPath = path.join(checkpointsDir, cp, '_checkpoint.json');
199
+ let meta = {};
200
+ if (fs.existsSync(metaPath)) {
201
+ meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
202
+ }
203
+
204
+ const date = meta.timestamp ? new Date(meta.timestamp).toLocaleString() : 'unknown';
205
+ console.log(chalk.white(` ${cp}`));
206
+ console.log(chalk.gray(` Phase: ${meta.phase || 'unknown'} | Files: ${meta.files?.length || '?'} | ${date}`));
207
+ }
208
+ console.log('');
209
+ }