@polymorphism-tech/morph-spec 3.0.1 → 3.2.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 +561 -63
  2. package/LICENSE +72 -72
  3. package/README.md +275 -79
  4. package/bin/detect-agents.js +3 -1
  5. package/bin/morph-spec.js +60 -1
  6. package/bin/render-template.js +61 -14
  7. package/bin/semantic-detect-agents.js +2 -1
  8. package/bin/{task-manager.js → task-manager.cjs} +113 -8
  9. package/bin/validate-agents-skills.js +10 -4
  10. package/bin/validate-agents.js +4 -3
  11. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
  12. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
  13. package/docs/api/scripts/collapse.js +38 -38
  14. package/docs/api/scripts/commonNav.js +28 -28
  15. package/docs/api/scripts/linenumber.js +25 -25
  16. package/docs/api/scripts/nav.js +12 -12
  17. package/docs/api/scripts/polyfill.js +3 -3
  18. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
  19. package/docs/api/scripts/prettify/lang-css.js +2 -2
  20. package/docs/api/scripts/prettify/prettify.js +28 -28
  21. package/docs/api/scripts/search.js +98 -98
  22. package/docs/api/styles/jsdoc.css +776 -776
  23. package/docs/api/styles/prettify.css +80 -80
  24. package/docs/cli-auto-detection.md +219 -0
  25. package/docs/examples.md +328 -328
  26. package/docs/getting-started.md +3 -3
  27. package/docs/llm-interaction-config.md +735 -0
  28. package/docs/templates.md +418 -418
  29. package/docs/troubleshooting.md +269 -0
  30. package/package.json +7 -3
  31. package/scripts/postinstall.js +132 -132
  32. package/scripts/reorganize-skills.cjs +1 -1
  33. package/scripts/validate-agents-structure.cjs +1 -1
  34. package/scripts/validate-skills.cjs +2 -2
  35. package/src/commands/advance-phase.js +93 -2
  36. package/src/commands/analyze-blazor-concurrency.js +193 -193
  37. package/src/commands/approve.js +221 -0
  38. package/src/commands/capture-pattern.js +121 -0
  39. package/src/commands/create-story.js +5 -2
  40. package/src/commands/deploy.js +780 -780
  41. package/src/commands/detect-agents.js +4 -2
  42. package/src/commands/generate.js +276 -149
  43. package/src/commands/init.js +37 -0
  44. package/src/commands/lint-fluent.js +352 -352
  45. package/src/commands/migrate-state.js +158 -0
  46. package/src/commands/rollback-phase.js +185 -185
  47. package/src/commands/search-patterns.js +126 -0
  48. package/src/commands/session-summary.js +291 -291
  49. package/src/commands/shard-spec.js +224 -224
  50. package/src/commands/spawn-team.js +172 -0
  51. package/src/commands/sprint-status.js +250 -250
  52. package/src/commands/task.js +3 -3
  53. package/src/commands/troubleshoot.js +222 -222
  54. package/src/commands/update.js +36 -0
  55. package/src/commands/upgrade.js +346 -0
  56. package/src/commands/validate-blazor-state.js +210 -210
  57. package/src/commands/validate-blazor.js +156 -156
  58. package/src/commands/validate-css.js +84 -84
  59. package/src/commands/validate-phase.js +221 -221
  60. package/src/generator/.gitkeep +0 -0
  61. package/src/generator/config-generator.js +206 -0
  62. package/src/generator/templates/config.json.template +40 -0
  63. package/src/generator/templates/project.md.template +67 -0
  64. package/src/lib/blazor-concurrency-analyzer.js +288 -288
  65. package/src/lib/blazor-state-validator.js +291 -291
  66. package/src/lib/blazor-validator.js +374 -374
  67. package/src/lib/checkpoint-hooks.js +258 -0
  68. package/src/lib/context-generator.js +7 -4
  69. package/src/lib/css-validator.js +352 -352
  70. package/src/lib/design-system-generator.js +298 -298
  71. package/src/lib/hook-executor.js +2 -1
  72. package/src/lib/learning-system.js +520 -520
  73. package/src/lib/metadata-extractor.js +380 -0
  74. package/src/lib/mockup-generator.js +366 -366
  75. package/src/lib/phase-state-machine.js +214 -0
  76. package/src/lib/stack-resolver.js +148 -0
  77. package/src/lib/standards-context-injector.js +4 -3
  78. package/src/lib/state-manager.js +120 -0
  79. package/src/lib/team-orchestrator.js +2 -1
  80. package/src/lib/template-data-sources.js +325 -0
  81. package/src/lib/troubleshoot-grep.js +204 -194
  82. package/src/lib/troubleshoot-index.js +144 -144
  83. package/src/lib/ui-detector.js +350 -350
  84. package/src/lib/validation-runner.js +2 -1
  85. package/src/lib/validators/architecture-validator.js +387 -387
  86. package/src/lib/validators/content-validator.js +351 -0
  87. package/src/lib/validators/package-validator.js +360 -360
  88. package/src/lib/validators/ui-contrast-validator.js +422 -422
  89. package/src/llm/.gitkeep +0 -0
  90. package/src/llm/analyzer.js +215 -0
  91. package/src/llm/environment-detector.js +43 -0
  92. package/src/llm/few-shot-examples.js +216 -0
  93. package/src/llm/project-config-schema.json +188 -0
  94. package/src/llm/prompt-builder.js +96 -0
  95. package/src/llm/schema-validator.js +121 -0
  96. package/src/orchestrator.js +206 -0
  97. package/src/sanitizer/.gitkeep +0 -0
  98. package/src/sanitizer/context-sanitizer.js +221 -0
  99. package/src/sanitizer/patterns.js +163 -0
  100. package/src/scanner/.gitkeep +0 -0
  101. package/src/scanner/project-scanner.js +242 -0
  102. package/src/types/index.js +477 -0
  103. package/src/ui/.gitkeep +0 -0
  104. package/src/ui/diff-display.js +91 -0
  105. package/src/ui/interactive-wizard.js +96 -0
  106. package/src/ui/user-review.js +211 -0
  107. package/src/ui/wizard-questions.js +190 -0
  108. package/src/utils/file-copier.js +3 -1
  109. package/src/utils/logger.js +32 -32
  110. package/src/utils/version-checker.js +175 -175
  111. package/src/writer/.gitkeep +0 -0
  112. package/src/writer/file-writer.js +86 -0
  113. package/{content → stacks/blazor-azure}/.azure/README.md +2 -2
  114. package/{content → stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +1 -1
  115. package/{content → stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +1 -1
  116. package/{content → stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +1 -1
  117. package/{content → stacks/blazor-azure}/.claude/commands/morph-preflight.md +227 -227
  118. package/{content → stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +122 -122
  119. package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
  120. package/{content → stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
  121. package/{content → stacks/blazor-azure}/.morph/hooks/README.md +12 -12
  122. package/{content → stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
  123. package/{content → stacks/blazor-azure}/.morph/standards/migration-guide.md +2 -2
  124. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +426 -426
  125. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
  126. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
  127. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
  128. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
  129. package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
  130. package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
  131. package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
  132. package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
  133. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
  134. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
  135. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
  136. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
  137. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
  138. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
  139. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
  140. package/stacks/nextjs-supabase/.morph/project.md +168 -0
  141. package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
  142. package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
  143. package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
  144. package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
  145. package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
  146. package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
  147. package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
  148. package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
  149. package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
  150. package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
  151. package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
  152. package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
  153. package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
  154. package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
  155. package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
  156. package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
  157. package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
  158. package/stacks/nextjs-supabase/CLAUDE.md +149 -0
  159. package/stacks/nextjs-supabase/README.md +112 -0
  160. /package/{content → stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +0 -0
  161. /package/{content → stacks/blazor-azure}/.azure/docs/branch-strategy.md +0 -0
  162. /package/{content → stacks/blazor-azure}/.azure/docs/local-development.md +0 -0
  163. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +0 -0
  164. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +0 -0
  165. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +0 -0
  166. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +0 -0
  167. /package/{content → stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
  168. /package/{content → stacks/blazor-azure}/.claude/commands/morph-archive.md +0 -0
  169. /package/{content → stacks/blazor-azure}/.claude/commands/morph-deploy.md +0 -0
  170. /package/{content → stacks/blazor-azure}/.claude/commands/morph-infra.md +0 -0
  171. /package/{content → stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
  172. /package/{content → stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
  173. /package/{content → stacks/blazor-azure}/.claude/settings.local.json +0 -0
  174. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
  175. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
  176. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
  177. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
  178. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
  179. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
  180. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
  181. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
  182. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
  183. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
  184. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
  185. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
  186. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
  187. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -0
  188. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -0
  189. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
  190. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
  191. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
  192. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
  193. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
  194. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
  195. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
  196. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
  197. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
  198. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -0
  199. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
  200. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
  201. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
  202. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
  203. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
  204. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
  205. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
  206. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
  207. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
  208. /package/{content → stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
  209. /package/{content → stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
  210. /package/{content → stacks/blazor-azure}/.morph/.morphversion +0 -0
  211. /package/{content → stacks/blazor-azure}/.morph/archive/.gitkeep +0 -0
  212. /package/{content → stacks/blazor-azure}/.morph/config/agents.json +0 -0
  213. /package/{content → stacks/blazor-azure}/.morph/config/config.template.json +0 -0
  214. /package/{content → stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -0
  215. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
  216. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
  217. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
  218. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
  219. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
  220. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +0 -0
  221. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +0 -0
  222. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +0 -0
  223. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +0 -0
  224. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/README.md +0 -0
  225. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +0 -0
  226. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +0 -0
  227. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +0 -0
  228. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +0 -0
  229. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/README.md +0 -0
  230. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +0 -0
  231. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +0 -0
  232. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +0 -0
  233. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
  234. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
  235. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
  236. /package/{content → stacks/blazor-azure}/.morph/examples/state-v3.json +0 -0
  237. /package/{content → stacks/blazor-azure}/.morph/features/.gitkeep +0 -0
  238. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
  239. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +0 -0
  240. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +0 -0
  241. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +0 -0
  242. /package/{content → stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
  243. /package/{content → stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
  244. /package/{content → stacks/blazor-azure}/.morph/project.md +0 -0
  245. /package/{content → stacks/blazor-azure}/.morph/schemas/agent.schema.json +0 -0
  246. /package/{content → stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
  247. /package/{content → stacks/blazor-azure}/.morph/specs/.gitkeep +0 -0
  248. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
  249. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
  250. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
  251. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
  252. /package/{content → stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
  253. /package/{content → stacks/blazor-azure}/.morph/standards/azure.md +0 -0
  254. /package/{content → stacks/blazor-azure}/.morph/standards/coding.md +0 -0
  255. /package/{content → stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
  256. /package/{content → stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +0 -0
  257. /package/{content → stacks/blazor-azure}/.morph/standards/passkeys-auth.md +0 -0
  258. /package/{content → stacks/blazor-azure}/.morph/standards/vector-search-rag.md +0 -0
  259. /package/{content → stacks/blazor-azure}/.morph/state.json +0 -0
  260. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
  261. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
  262. /package/{content → stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +0 -0
  263. /package/{content → stacks/blazor-azure}/.morph/templates/MudTheme.cs +0 -0
  264. /package/{content → stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
  265. /package/{content → stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
  266. /package/{content → stacks/blazor-azure}/.morph/templates/component.razor +0 -0
  267. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
  268. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
  269. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
  270. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
  271. /package/{content → stacks/blazor-azure}/.morph/templates/contracts.cs +0 -0
  272. /package/{content → stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
  273. /package/{content → stacks/blazor-azure}/.morph/templates/design-system.css +0 -0
  274. /package/{content → stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +0 -0
  275. /package/{content → stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +0 -0
  276. /package/{content → stacks/blazor-azure}/.morph/templates/infra/README.md +0 -0
  277. /package/{content → stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +0 -0
  278. /package/{content → stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +0 -0
  279. /package/{content → stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +0 -0
  280. /package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +0 -0
  281. /package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +0 -0
  282. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +0 -0
  283. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.sh +0 -0
  284. /package/{content → stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +0 -0
  285. /package/{content → stacks/blazor-azure}/.morph/templates/infra/main.bicep +0 -0
  286. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +0 -0
  287. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +0 -0
  288. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +0 -0
  289. /package/{content → stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +0 -0
  290. /package/{content → stacks/blazor-azure}/.morph/templates/infra/storage.bicep +0 -0
  291. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +0 -0
  292. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +0 -0
  293. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +0 -0
  294. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +0 -0
  295. /package/{content → stacks/blazor-azure}/.morph/templates/job.cs +0 -0
  296. /package/{content → stacks/blazor-azure}/.morph/templates/migration.cs +0 -0
  297. /package/{content → stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
  298. /package/{content → stacks/blazor-azure}/.morph/templates/recap.md +0 -0
  299. /package/{content → stacks/blazor-azure}/.morph/templates/repository.cs +0 -0
  300. /package/{content → stacks/blazor-azure}/.morph/templates/saas/subscription.cs +0 -0
  301. /package/{content → stacks/blazor-azure}/.morph/templates/saas/tenant.cs +0 -0
  302. /package/{content → stacks/blazor-azure}/.morph/templates/service.cs +0 -0
  303. /package/{content → stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
  304. /package/{content → stacks/blazor-azure}/.morph/templates/spec.md +0 -0
  305. /package/{content → stacks/blazor-azure}/.morph/templates/sprint-status.yaml +0 -0
  306. /package/{content → stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
  307. /package/{content → stacks/blazor-azure}/.morph/templates/story.md +0 -0
  308. /package/{content → stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
  309. /package/{content → stacks/blazor-azure}/.morph/templates/test.cs +0 -0
  310. /package/{content → stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
  311. /package/{content → stacks/blazor-azure}/.morph/templates/ui-design-system.md +0 -0
  312. /package/{content → stacks/blazor-azure}/.morph/templates/ui-flows.md +0 -0
  313. /package/{content → stacks/blazor-azure}/.morph/templates/ui-mockups.md +0 -0
  314. /package/{content → stacks/blazor-azure}/.morph/test-infra/example.bicep +0 -0
  315. /package/{content → stacks/blazor-azure}/CLAUDE.md +0 -0
  316. /package/{content → stacks/blazor-azure}/README.md +0 -0
@@ -0,0 +1,158 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+
6
+ /**
7
+ * Migrate State Command - Upgrade state.json to v3.0 schema
8
+ *
9
+ * Adds approval gates to existing features
10
+ */
11
+
12
+ const program = new Command();
13
+
14
+ program
15
+ .name('migrate-state')
16
+ .description('Migrate state.json to v3.0 schema (add approval gates)')
17
+ .option('--dry-run', 'Preview changes without writing')
18
+ .option('--force', 'Skip confirmation')
19
+ .action(async (options) => {
20
+ try {
21
+ const statePath = join(process.cwd(), '.morph/state.json');
22
+
23
+ if (!existsSync(statePath)) {
24
+ console.error(chalk.red(`\n❌ No state.json found at ${statePath}`));
25
+ console.log(chalk.yellow('This project may not be initialized with MORPH-SPEC.\n'));
26
+ process.exit(1);
27
+ }
28
+
29
+ // Read current state
30
+ const state = JSON.parse(readFileSync(statePath, 'utf8'));
31
+
32
+ console.log(chalk.cyan('\n🔄 Migrating state.json to v3.0 schema...\n'));
33
+
34
+ // Check if already migrated
35
+ if (state.version === '3.0.0') {
36
+ console.log(chalk.green('✅ State already at v3.0.0 - no migration needed\n'));
37
+ process.exit(0);
38
+ }
39
+
40
+ // Track changes
41
+ let featuresUpdated = 0;
42
+ const changes = [];
43
+
44
+ // Migrate each feature
45
+ Object.entries(state.features || {}).forEach(([featureName, feature]) => {
46
+ // Skip if already has approvalGates
47
+ if (feature.approvalGates) {
48
+ return;
49
+ }
50
+
51
+ // Determine which gates to auto-approve based on current phase
52
+ const currentPhase = feature.phase || 'proposal';
53
+ const approvalGates = {
54
+ proposal: { approved: false, timestamp: null, approvedBy: null },
55
+ uiux: { approved: false, timestamp: null, approvedBy: null },
56
+ design: { approved: false, timestamp: null, approvedBy: null },
57
+ tasks: { approved: false, timestamp: null, approvedBy: null }
58
+ };
59
+
60
+ // Auto-approve past gates
61
+ const phaseOrder = ['proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync', 'archived'];
62
+ const currentPhaseIndex = phaseOrder.indexOf(currentPhase);
63
+
64
+ if (currentPhaseIndex >= phaseOrder.indexOf('proposal')) {
65
+ approvalGates.proposal.approved = true;
66
+ approvalGates.proposal.timestamp = feature.createdAt || new Date().toISOString();
67
+ approvalGates.proposal.approvedBy = 'auto-migration';
68
+ }
69
+
70
+ if (currentPhaseIndex >= phaseOrder.indexOf('design')) {
71
+ approvalGates.design.approved = true;
72
+ approvalGates.design.timestamp = feature.updatedAt || new Date().toISOString();
73
+ approvalGates.design.approvedBy = 'auto-migration';
74
+ }
75
+
76
+ if (currentPhaseIndex >= phaseOrder.indexOf('tasks')) {
77
+ approvalGates.tasks.approved = true;
78
+ approvalGates.tasks.timestamp = feature.updatedAt || new Date().toISOString();
79
+ approvalGates.tasks.approvedBy = 'auto-migration';
80
+ }
81
+
82
+ // Add approval gates to feature
83
+ feature.approvalGates = approvalGates;
84
+
85
+ featuresUpdated++;
86
+ changes.push({
87
+ feature: featureName,
88
+ phase: currentPhase,
89
+ approvedGates: Object.entries(approvalGates)
90
+ .filter(([_, gate]) => gate.approved)
91
+ .map(([name]) => name)
92
+ });
93
+ });
94
+
95
+ // Update state version
96
+ state.version = '3.0.0';
97
+
98
+ // Show changes
99
+ console.log(chalk.bold('📊 Migration Summary:\n'));
100
+ console.log(chalk.cyan(` Features to update: ${featuresUpdated}`));
101
+
102
+ if (changes.length > 0) {
103
+ console.log(chalk.gray('\n Changes:'));
104
+ changes.forEach(change => {
105
+ console.log(chalk.white(` - ${change.feature} (${change.phase})`));
106
+ console.log(chalk.gray(` Auto-approved gates: ${change.approvedGates.join(', ') || 'none'}`));
107
+ });
108
+ }
109
+
110
+ console.log('');
111
+
112
+ // Dry run
113
+ if (options.dryRun) {
114
+ console.log(chalk.yellow('🔍 DRY RUN - No changes written\n'));
115
+ console.log(chalk.gray('Run without --dry-run to apply migration.\n'));
116
+ return;
117
+ }
118
+
119
+ // Confirmation
120
+ if (!options.force) {
121
+ console.log(chalk.yellow('⚠️ This will modify .morph/state.json'));
122
+ console.log(chalk.gray(' A backup will be created at .morph/state.json.backup\n'));
123
+ console.log(chalk.gray(' Run with --force to skip this confirmation, or Ctrl+C to cancel.\n'));
124
+
125
+ // Wait for user confirmation (in CLI context, assume proceed for now)
126
+ // In real implementation, use inquirer for interactive confirmation
127
+ }
128
+
129
+ // Backup original
130
+ const backupPath = `${statePath}.backup`;
131
+ writeFileSync(backupPath, JSON.stringify(state, null, 2));
132
+ console.log(chalk.gray(`📦 Backup created: ${backupPath}\n`));
133
+
134
+ // Write migrated state
135
+ writeFileSync(statePath, JSON.stringify(state, null, 2));
136
+
137
+ console.log(chalk.green('✅ Migration complete!\n'));
138
+ console.log(chalk.bold('Next steps:\n'));
139
+ console.log(chalk.gray('1. Review .morph/config/llm-interaction.json (created on next init)'));
140
+ console.log(chalk.gray('2. Configure approval gates, checkpoints, patterns'));
141
+ console.log(chalk.gray('3. Continue working with v3.0 features\n'));
142
+
143
+ } catch (error) {
144
+ console.error(chalk.red(`\n❌ Migration failed: ${error.message}\n`));
145
+ process.exit(1);
146
+ }
147
+ });
148
+
149
+ // Only parse if run directly (not imported as module)
150
+ if (import.meta.url === `file://${process.argv[1]}`) {
151
+ if (process.argv.length > 2) {
152
+ program.parse(process.argv);
153
+ } else {
154
+ program.help();
155
+ }
156
+ }
157
+
158
+ export default program;
@@ -1,185 +1,185 @@
1
- /**
2
- * MORPH-SPEC Rollback Phase Command
3
- *
4
- * Rolls back a feature to a previous phase, marking outputs as draft.
5
- *
6
- * Usage:
7
- * morph-spec rollback <feature-name> <target-phase>
8
- *
9
- * Example:
10
- * morph-spec rollback scheduled-reports design
11
- */
12
-
13
- import fs from 'fs';
14
- import path from 'path';
15
- import chalk from 'chalk';
16
- import { loadState, saveState, getFeature, updateFeature } from '../lib/state-manager.js';
17
-
18
- // Phase order
19
- const PHASE_ORDER = ['proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];
20
-
21
- /**
22
- * Get phase index
23
- */
24
- function getPhaseIndex(phase) {
25
- return PHASE_ORDER.indexOf(phase);
26
- }
27
-
28
- /**
29
- * Get outputs that should be marked as draft when rolling back
30
- */
31
- function getOutputsToReset(fromPhase, toPhase) {
32
- const fromIndex = getPhaseIndex(fromPhase);
33
- const toIndex = getPhaseIndex(toPhase);
34
-
35
- // Map phases to their outputs
36
- const phaseOutputs = {
37
- 'proposal': ['proposal'],
38
- 'setup': [],
39
- 'uiux': ['uiDesignSystem', 'uiMockups', 'uiComponents', 'uiFlows'],
40
- 'design': ['spec', 'contracts', 'decisions'],
41
- 'clarify': [],
42
- 'tasks': ['tasks'],
43
- 'implement': ['recap'],
44
- 'sync': []
45
- };
46
-
47
- const outputsToReset = [];
48
-
49
- // Collect all outputs from phases after target
50
- for (let i = toIndex + 1; i <= fromIndex; i++) {
51
- const phase = PHASE_ORDER[i];
52
- if (phaseOutputs[phase]) {
53
- outputsToReset.push(...phaseOutputs[phase]);
54
- }
55
- }
56
-
57
- return outputsToReset;
58
- }
59
-
60
- /**
61
- * Main command handler
62
- */
63
- export async function rollbackPhaseCommand(feature, targetPhase, options = {}) {
64
- console.log(chalk.cyan('\n╔════════════════════════════════════════════════╗'));
65
- console.log(chalk.cyan('║ MORPH-SPEC ROLLBACK ║'));
66
- console.log(chalk.cyan('╚════════════════════════════════════════════════╝\n'));
67
-
68
- // Validate target phase
69
- if (!PHASE_ORDER.includes(targetPhase)) {
70
- console.log(chalk.red(`❌ Invalid phase: ${targetPhase}`));
71
- console.log(chalk.gray('\nValid phases:'));
72
- PHASE_ORDER.forEach(p => console.log(chalk.gray(` - ${p}`)));
73
- process.exit(1);
74
- }
75
-
76
- // Get current feature state
77
- let featureState;
78
- try {
79
- featureState = getFeature(feature);
80
- } catch (error) {
81
- console.log(chalk.red(`❌ Feature not found: ${feature}`));
82
- console.log(chalk.gray(' Run: morph-spec state list'));
83
- process.exit(1);
84
- }
85
-
86
- if (!featureState) {
87
- console.log(chalk.red(`❌ Feature not found: ${feature}`));
88
- process.exit(1);
89
- }
90
-
91
- const currentPhase = featureState.phase || 'proposal';
92
- const currentIndex = getPhaseIndex(currentPhase);
93
- const targetIndex = getPhaseIndex(targetPhase);
94
-
95
- // Check if rollback makes sense
96
- if (targetIndex >= currentIndex) {
97
- console.log(chalk.yellow(`⚠️ Cannot rollback: target phase '${targetPhase}' is not before current phase '${currentPhase}'`));
98
- process.exit(1);
99
- }
100
-
101
- // Get outputs to reset
102
- const outputsToReset = getOutputsToReset(currentPhase, targetPhase);
103
-
104
- // Show what will happen
105
- console.log(chalk.gray('Feature:'), feature);
106
- console.log(chalk.gray('Current Phase:'), currentPhase);
107
- console.log(chalk.gray('Target Phase:'), targetPhase);
108
- console.log('');
109
-
110
- if (outputsToReset.length > 0) {
111
- console.log(chalk.yellow('Outputs that will be marked as draft:'));
112
- outputsToReset.forEach(o => {
113
- console.log(chalk.gray(` - ${o}`));
114
- });
115
- console.log('');
116
- }
117
-
118
- // Confirm unless --force
119
- if (!options.force) {
120
- console.log(chalk.yellow('⚠️ This will:'));
121
- console.log(chalk.gray(' 1. Set phase back to: ' + targetPhase));
122
- console.log(chalk.gray(' 2. Reset task progress'));
123
- console.log(chalk.gray(' 3. Mark outputs as not created (files remain on disk)'));
124
- console.log('');
125
- console.log(chalk.gray('Run with --force to confirm.'));
126
- process.exit(1);
127
- }
128
-
129
- // Perform rollback
130
- try {
131
- const state = loadState();
132
-
133
- // Update phase
134
- state.features[feature].phase = targetPhase;
135
- state.features[feature].status = 'in_progress';
136
- state.features[feature].updatedAt = new Date().toISOString();
137
-
138
- // Reset outputs
139
- for (const output of outputsToReset) {
140
- if (state.features[feature].outputs[output]) {
141
- state.features[feature].outputs[output].created = false;
142
- }
143
- }
144
-
145
- // Reset tasks if rolling back before tasks phase
146
- if (targetIndex < getPhaseIndex('tasks')) {
147
- state.features[feature].tasks = {
148
- total: 0,
149
- completed: 0,
150
- inProgress: 0,
151
- pending: 0
152
- };
153
- }
154
-
155
- // Add checkpoint for rollback
156
- state.features[feature].checkpoints = state.features[feature].checkpoints || [];
157
- state.features[feature].checkpoints.push({
158
- timestamp: new Date().toISOString(),
159
- phase: targetPhase,
160
- completedTasks: 0,
161
- note: `Rollback from ${currentPhase} to ${targetPhase}`
162
- });
163
-
164
- // Track skipped phases (if any were skipped)
165
- if (!state.features[feature].skippedPhases) {
166
- state.features[feature].skippedPhases = [];
167
- }
168
-
169
- saveState(state);
170
-
171
- console.log(chalk.green('✅ Rollback completed!'));
172
- console.log('');
173
- console.log(chalk.gray('Current state:'));
174
- console.log(chalk.gray(` Phase: ${targetPhase}`));
175
- console.log(chalk.gray(` Status: in_progress`));
176
- console.log('');
177
- console.log(chalk.cyan('Next steps:'));
178
- console.log(chalk.gray(` 1. Review and update outputs for phase: ${targetPhase}`));
179
- console.log(chalk.gray(` 2. Run: morph-spec session-summary ${feature}`));
180
-
181
- } catch (error) {
182
- console.log(chalk.red(`❌ Rollback failed: ${error.message}`));
183
- process.exit(1);
184
- }
185
- }
1
+ /**
2
+ * MORPH-SPEC Rollback Phase Command
3
+ *
4
+ * Rolls back a feature to a previous phase, marking outputs as draft.
5
+ *
6
+ * Usage:
7
+ * morph-spec rollback <feature-name> <target-phase>
8
+ *
9
+ * Example:
10
+ * morph-spec rollback scheduled-reports design
11
+ */
12
+
13
+ import fs from 'fs';
14
+ import path from 'path';
15
+ import chalk from 'chalk';
16
+ import { loadState, saveState, getFeature, updateFeature } from '../lib/state-manager.js';
17
+
18
+ // Phase order
19
+ const PHASE_ORDER = ['proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];
20
+
21
+ /**
22
+ * Get phase index
23
+ */
24
+ function getPhaseIndex(phase) {
25
+ return PHASE_ORDER.indexOf(phase);
26
+ }
27
+
28
+ /**
29
+ * Get outputs that should be marked as draft when rolling back
30
+ */
31
+ function getOutputsToReset(fromPhase, toPhase) {
32
+ const fromIndex = getPhaseIndex(fromPhase);
33
+ const toIndex = getPhaseIndex(toPhase);
34
+
35
+ // Map phases to their outputs
36
+ const phaseOutputs = {
37
+ 'proposal': ['proposal'],
38
+ 'setup': [],
39
+ 'uiux': ['uiDesignSystem', 'uiMockups', 'uiComponents', 'uiFlows'],
40
+ 'design': ['spec', 'contracts', 'decisions'],
41
+ 'clarify': [],
42
+ 'tasks': ['tasks'],
43
+ 'implement': ['recap'],
44
+ 'sync': []
45
+ };
46
+
47
+ const outputsToReset = [];
48
+
49
+ // Collect all outputs from phases after target
50
+ for (let i = toIndex + 1; i <= fromIndex; i++) {
51
+ const phase = PHASE_ORDER[i];
52
+ if (phaseOutputs[phase]) {
53
+ outputsToReset.push(...phaseOutputs[phase]);
54
+ }
55
+ }
56
+
57
+ return outputsToReset;
58
+ }
59
+
60
+ /**
61
+ * Main command handler
62
+ */
63
+ export async function rollbackPhaseCommand(feature, targetPhase, options = {}) {
64
+ console.log(chalk.cyan('\n╔════════════════════════════════════════════════╗'));
65
+ console.log(chalk.cyan('║ MORPH-SPEC ROLLBACK ║'));
66
+ console.log(chalk.cyan('╚════════════════════════════════════════════════╝\n'));
67
+
68
+ // Validate target phase
69
+ if (!PHASE_ORDER.includes(targetPhase)) {
70
+ console.log(chalk.red(`❌ Invalid phase: ${targetPhase}`));
71
+ console.log(chalk.gray('\nValid phases:'));
72
+ PHASE_ORDER.forEach(p => console.log(chalk.gray(` - ${p}`)));
73
+ process.exit(1);
74
+ }
75
+
76
+ // Get current feature state
77
+ let featureState;
78
+ try {
79
+ featureState = getFeature(feature);
80
+ } catch (error) {
81
+ console.log(chalk.red(`❌ Feature not found: ${feature}`));
82
+ console.log(chalk.gray(' Run: morph-spec state list'));
83
+ process.exit(1);
84
+ }
85
+
86
+ if (!featureState) {
87
+ console.log(chalk.red(`❌ Feature not found: ${feature}`));
88
+ process.exit(1);
89
+ }
90
+
91
+ const currentPhase = featureState.phase || 'proposal';
92
+ const currentIndex = getPhaseIndex(currentPhase);
93
+ const targetIndex = getPhaseIndex(targetPhase);
94
+
95
+ // Check if rollback makes sense
96
+ if (targetIndex >= currentIndex) {
97
+ console.log(chalk.yellow(`⚠️ Cannot rollback: target phase '${targetPhase}' is not before current phase '${currentPhase}'`));
98
+ process.exit(1);
99
+ }
100
+
101
+ // Get outputs to reset
102
+ const outputsToReset = getOutputsToReset(currentPhase, targetPhase);
103
+
104
+ // Show what will happen
105
+ console.log(chalk.gray('Feature:'), feature);
106
+ console.log(chalk.gray('Current Phase:'), currentPhase);
107
+ console.log(chalk.gray('Target Phase:'), targetPhase);
108
+ console.log('');
109
+
110
+ if (outputsToReset.length > 0) {
111
+ console.log(chalk.yellow('Outputs that will be marked as draft:'));
112
+ outputsToReset.forEach(o => {
113
+ console.log(chalk.gray(` - ${o}`));
114
+ });
115
+ console.log('');
116
+ }
117
+
118
+ // Confirm unless --force
119
+ if (!options.force) {
120
+ console.log(chalk.yellow('⚠️ This will:'));
121
+ console.log(chalk.gray(' 1. Set phase back to: ' + targetPhase));
122
+ console.log(chalk.gray(' 2. Reset task progress'));
123
+ console.log(chalk.gray(' 3. Mark outputs as not created (files remain on disk)'));
124
+ console.log('');
125
+ console.log(chalk.gray('Run with --force to confirm.'));
126
+ process.exit(1);
127
+ }
128
+
129
+ // Perform rollback
130
+ try {
131
+ const state = loadState();
132
+
133
+ // Update phase
134
+ state.features[feature].phase = targetPhase;
135
+ state.features[feature].status = 'in_progress';
136
+ state.features[feature].updatedAt = new Date().toISOString();
137
+
138
+ // Reset outputs
139
+ for (const output of outputsToReset) {
140
+ if (state.features[feature].outputs[output]) {
141
+ state.features[feature].outputs[output].created = false;
142
+ }
143
+ }
144
+
145
+ // Reset tasks if rolling back before tasks phase
146
+ if (targetIndex < getPhaseIndex('tasks')) {
147
+ state.features[feature].tasks = {
148
+ total: 0,
149
+ completed: 0,
150
+ inProgress: 0,
151
+ pending: 0
152
+ };
153
+ }
154
+
155
+ // Add checkpoint for rollback
156
+ state.features[feature].checkpoints = state.features[feature].checkpoints || [];
157
+ state.features[feature].checkpoints.push({
158
+ timestamp: new Date().toISOString(),
159
+ phase: targetPhase,
160
+ completedTasks: 0,
161
+ note: `Rollback from ${currentPhase} to ${targetPhase}`
162
+ });
163
+
164
+ // Track skipped phases (if any were skipped)
165
+ if (!state.features[feature].skippedPhases) {
166
+ state.features[feature].skippedPhases = [];
167
+ }
168
+
169
+ saveState(state);
170
+
171
+ console.log(chalk.green('✅ Rollback completed!'));
172
+ console.log('');
173
+ console.log(chalk.gray('Current state:'));
174
+ console.log(chalk.gray(` Phase: ${targetPhase}`));
175
+ console.log(chalk.gray(` Status: in_progress`));
176
+ console.log('');
177
+ console.log(chalk.cyan('Next steps:'));
178
+ console.log(chalk.gray(` 1. Review and update outputs for phase: ${targetPhase}`));
179
+ console.log(chalk.gray(` 2. Run: morph-spec session-summary ${feature}`));
180
+
181
+ } catch (error) {
182
+ console.log(chalk.red(`❌ Rollback failed: ${error.message}`));
183
+ process.exit(1);
184
+ }
185
+ }
@@ -0,0 +1,126 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { readFileSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+
6
+ /**
7
+ * Search Patterns Command - Find relevant patterns
8
+ *
9
+ * Searches patterns-learned.md for keywords
10
+ */
11
+
12
+ const program = new Command();
13
+
14
+ program
15
+ .name('search-patterns')
16
+ .description('Search for patterns by keyword')
17
+ .argument('<keyword>', 'Keyword to search for')
18
+ .option('--category <category>', 'Filter by category')
19
+ .option('--limit <number>', 'Limit number of results', '10')
20
+ .option('--json', 'Output as JSON', false)
21
+ .action(async (keyword, options) => {
22
+ try {
23
+ // Get patterns file path
24
+ const patternsPath = join(process.cwd(), '.morph/memory/patterns-learned.md');
25
+
26
+ if (!existsSync(patternsPath)) {
27
+ console.error(chalk.red(`\n❌ Patterns file not found: ${patternsPath}`));
28
+ console.log(chalk.yellow('No patterns learned yet. Complete some features first!\n'));
29
+ process.exit(1);
30
+ }
31
+
32
+ // Read patterns file
33
+ const content = readFileSync(patternsPath, 'utf8');
34
+
35
+ // Split into pattern sections
36
+ const sections = content.split('---').filter(s => s.trim().length > 0);
37
+
38
+ // Search patterns
39
+ const keywordLower = keyword.toLowerCase();
40
+ const matches = [];
41
+
42
+ sections.forEach(section => {
43
+ if (section.toLowerCase().includes(keywordLower)) {
44
+ // Extract pattern name
45
+ const nameMatch = section.match(/## Pattern: (.+)/);
46
+ const categoryMatch = section.match(/\*\*Category:\*\* (.+)/);
47
+ const sourceMatch = section.match(/\*\*Source:\*\* (.+)/);
48
+
49
+ if (nameMatch) {
50
+ const patternName = nameMatch[1].trim();
51
+ const category = categoryMatch ? categoryMatch[1].trim() : 'Unknown';
52
+ const source = sourceMatch ? sourceMatch[1].trim() : 'Unknown';
53
+
54
+ // Filter by category if specified
55
+ if (options.category && !category.toLowerCase().includes(options.category.toLowerCase())) {
56
+ return;
57
+ }
58
+
59
+ matches.push({
60
+ name: patternName,
61
+ category,
62
+ source,
63
+ content: section.trim(),
64
+ preview: section.substring(0, 300).trim() + '...'
65
+ });
66
+ }
67
+ }
68
+ });
69
+
70
+ // Limit results
71
+ const limit = parseInt(options.limit, 10);
72
+ const limitedMatches = matches.slice(0, limit);
73
+
74
+ if (options.json) {
75
+ // JSON output
76
+ console.log(JSON.stringify({ keyword, matches: limitedMatches, total: matches.length }, null, 2));
77
+ return;
78
+ }
79
+
80
+ // Pretty output
81
+ if (limitedMatches.length === 0) {
82
+ console.log(chalk.yellow(`\n⚠️ No patterns found for keyword: "${keyword}"\n`));
83
+ console.log(chalk.gray('Try a different keyword or broader search term.\n'));
84
+ return;
85
+ }
86
+
87
+ console.log(chalk.bold(`\n🔍 Found ${matches.length} pattern(s) for: "${keyword}"`));
88
+ if (matches.length > limit) {
89
+ console.log(chalk.gray(`Showing first ${limit} results (use --limit to see more)\n`));
90
+ }
91
+ console.log('━'.repeat(60));
92
+
93
+ limitedMatches.forEach((match, index) => {
94
+ console.log(chalk.green(`\n${index + 1}. ${match.name}`));
95
+ console.log(chalk.cyan(` Category: ${match.category}`));
96
+ console.log(chalk.gray(` Source: ${match.source}`));
97
+
98
+ // Show first few lines of the pattern
99
+ const lines = match.content.split('\n').slice(0, 15);
100
+ console.log(chalk.gray('\n ' + lines.join('\n ')));
101
+
102
+ if (match.content.split('\n').length > 15) {
103
+ console.log(chalk.gray(` ... (see full pattern in ${patternsPath})`));
104
+ }
105
+ });
106
+
107
+ console.log('\n' + '━'.repeat(60));
108
+ console.log(chalk.bold('\n💡 Usage:'));
109
+ console.log(chalk.gray(` Edit ${patternsPath} to see full pattern details\n`));
110
+
111
+ } catch (error) {
112
+ console.error(chalk.red(`\n❌ Error searching patterns: ${error.message}\n`));
113
+ process.exit(1);
114
+ }
115
+ });
116
+
117
+ // Only parse if run directly (not imported as module)
118
+ if (import.meta.url === `file://${process.argv[1]}`) {
119
+ if (process.argv.length > 2) {
120
+ program.parse(process.argv);
121
+ } else {
122
+ program.help();
123
+ }
124
+ }
125
+
126
+ export default program;