@polymorphism-tech/morph-spec 3.0.1 → 3.1.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 (273) hide show
  1. package/CLAUDE.md +52 -88
  2. package/LICENSE +72 -72
  3. package/README.md +198 -76
  4. package/bin/detect-agents.js +3 -1
  5. package/bin/morph-spec.js +10 -0
  6. package/bin/render-template.js +5 -4
  7. package/bin/semantic-detect-agents.js +2 -1
  8. package/bin/{task-manager.js → task-manager.cjs} +12 -1
  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/examples.md +328 -328
  25. package/docs/getting-started.md +3 -3
  26. package/docs/templates.md +418 -418
  27. package/package.json +3 -3
  28. package/scripts/postinstall.js +132 -132
  29. package/scripts/reorganize-skills.cjs +1 -1
  30. package/scripts/validate-agents-structure.cjs +1 -1
  31. package/scripts/validate-skills.cjs +2 -2
  32. package/src/commands/analyze-blazor-concurrency.js +193 -193
  33. package/src/commands/create-story.js +5 -2
  34. package/src/commands/deploy.js +780 -780
  35. package/src/commands/detect-agents.js +4 -2
  36. package/src/commands/generate.js +149 -149
  37. package/src/commands/lint-fluent.js +352 -352
  38. package/src/commands/rollback-phase.js +185 -185
  39. package/src/commands/session-summary.js +291 -291
  40. package/src/commands/shard-spec.js +224 -224
  41. package/src/commands/sprint-status.js +250 -250
  42. package/src/commands/task.js +1 -1
  43. package/src/commands/troubleshoot.js +222 -222
  44. package/src/commands/validate-blazor-state.js +210 -210
  45. package/src/commands/validate-blazor.js +156 -156
  46. package/src/commands/validate-css.js +84 -84
  47. package/src/commands/validate-phase.js +221 -221
  48. package/src/lib/blazor-concurrency-analyzer.js +288 -288
  49. package/src/lib/blazor-state-validator.js +291 -291
  50. package/src/lib/blazor-validator.js +374 -374
  51. package/src/lib/context-generator.js +7 -4
  52. package/src/lib/css-validator.js +352 -352
  53. package/src/lib/design-system-generator.js +298 -298
  54. package/src/lib/hook-executor.js +2 -1
  55. package/src/lib/learning-system.js +520 -520
  56. package/src/lib/mockup-generator.js +366 -366
  57. package/src/lib/stack-resolver.js +148 -0
  58. package/src/lib/standards-context-injector.js +4 -3
  59. package/src/lib/team-orchestrator.js +2 -1
  60. package/src/lib/troubleshoot-grep.js +204 -194
  61. package/src/lib/troubleshoot-index.js +144 -144
  62. package/src/lib/ui-detector.js +350 -350
  63. package/src/lib/validation-runner.js +2 -1
  64. package/src/lib/validators/architecture-validator.js +387 -387
  65. package/src/lib/validators/package-validator.js +360 -360
  66. package/src/lib/validators/ui-contrast-validator.js +422 -422
  67. package/src/utils/file-copier.js +3 -1
  68. package/src/utils/logger.js +32 -32
  69. package/src/utils/version-checker.js +175 -175
  70. package/{content → stacks/blazor-azure}/.azure/README.md +2 -2
  71. package/{content → stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +1 -1
  72. package/{content → stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +1 -1
  73. package/{content → stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +1 -1
  74. package/{content → stacks/blazor-azure}/.claude/commands/morph-preflight.md +227 -227
  75. package/{content → stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +122 -122
  76. package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
  77. package/{content → stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
  78. package/{content → stacks/blazor-azure}/.morph/hooks/README.md +12 -12
  79. package/{content → stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
  80. package/{content → stacks/blazor-azure}/.morph/standards/migration-guide.md +2 -2
  81. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +426 -426
  82. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
  83. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
  84. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
  85. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
  86. package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
  87. package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
  88. package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
  89. package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
  90. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
  91. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
  92. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
  93. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
  94. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
  95. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
  96. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
  97. package/stacks/nextjs-supabase/.morph/project.md +168 -0
  98. package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
  99. package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
  100. package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
  101. package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
  102. package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
  103. package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
  104. package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
  105. package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
  106. package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
  107. package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
  108. package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
  109. package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
  110. package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
  111. package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
  112. package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
  113. package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
  114. package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
  115. package/stacks/nextjs-supabase/CLAUDE.md +149 -0
  116. package/stacks/nextjs-supabase/README.md +112 -0
  117. /package/{content → stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +0 -0
  118. /package/{content → stacks/blazor-azure}/.azure/docs/branch-strategy.md +0 -0
  119. /package/{content → stacks/blazor-azure}/.azure/docs/local-development.md +0 -0
  120. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +0 -0
  121. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +0 -0
  122. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +0 -0
  123. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +0 -0
  124. /package/{content → stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
  125. /package/{content → stacks/blazor-azure}/.claude/commands/morph-archive.md +0 -0
  126. /package/{content → stacks/blazor-azure}/.claude/commands/morph-deploy.md +0 -0
  127. /package/{content → stacks/blazor-azure}/.claude/commands/morph-infra.md +0 -0
  128. /package/{content → stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
  129. /package/{content → stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
  130. /package/{content → stacks/blazor-azure}/.claude/settings.local.json +0 -0
  131. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
  132. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
  133. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
  134. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
  135. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
  136. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
  137. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
  138. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
  139. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
  140. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
  141. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
  142. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
  143. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
  144. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -0
  145. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -0
  146. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
  147. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
  148. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
  149. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
  150. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
  151. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
  152. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
  153. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
  154. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
  155. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -0
  156. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
  157. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
  158. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
  159. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
  160. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
  161. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
  162. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
  163. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
  164. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
  165. /package/{content → stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
  166. /package/{content → stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
  167. /package/{content → stacks/blazor-azure}/.morph/.morphversion +0 -0
  168. /package/{content → stacks/blazor-azure}/.morph/archive/.gitkeep +0 -0
  169. /package/{content → stacks/blazor-azure}/.morph/config/agents.json +0 -0
  170. /package/{content → stacks/blazor-azure}/.morph/config/config.template.json +0 -0
  171. /package/{content → stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -0
  172. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
  173. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
  174. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
  175. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
  176. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
  177. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +0 -0
  178. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +0 -0
  179. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +0 -0
  180. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +0 -0
  181. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/README.md +0 -0
  182. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +0 -0
  183. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +0 -0
  184. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +0 -0
  185. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +0 -0
  186. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/README.md +0 -0
  187. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +0 -0
  188. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +0 -0
  189. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +0 -0
  190. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
  191. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
  192. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
  193. /package/{content → stacks/blazor-azure}/.morph/examples/state-v3.json +0 -0
  194. /package/{content → stacks/blazor-azure}/.morph/features/.gitkeep +0 -0
  195. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
  196. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +0 -0
  197. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +0 -0
  198. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +0 -0
  199. /package/{content → stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
  200. /package/{content → stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
  201. /package/{content → stacks/blazor-azure}/.morph/project.md +0 -0
  202. /package/{content → stacks/blazor-azure}/.morph/schemas/agent.schema.json +0 -0
  203. /package/{content → stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
  204. /package/{content → stacks/blazor-azure}/.morph/specs/.gitkeep +0 -0
  205. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
  206. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
  207. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
  208. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
  209. /package/{content → stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
  210. /package/{content → stacks/blazor-azure}/.morph/standards/azure.md +0 -0
  211. /package/{content → stacks/blazor-azure}/.morph/standards/coding.md +0 -0
  212. /package/{content → stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
  213. /package/{content → stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +0 -0
  214. /package/{content → stacks/blazor-azure}/.morph/standards/passkeys-auth.md +0 -0
  215. /package/{content → stacks/blazor-azure}/.morph/standards/vector-search-rag.md +0 -0
  216. /package/{content → stacks/blazor-azure}/.morph/state.json +0 -0
  217. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
  218. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
  219. /package/{content → stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +0 -0
  220. /package/{content → stacks/blazor-azure}/.morph/templates/MudTheme.cs +0 -0
  221. /package/{content → stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
  222. /package/{content → stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
  223. /package/{content → stacks/blazor-azure}/.morph/templates/component.razor +0 -0
  224. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
  225. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
  226. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
  227. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
  228. /package/{content → stacks/blazor-azure}/.morph/templates/contracts.cs +0 -0
  229. /package/{content → stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
  230. /package/{content → stacks/blazor-azure}/.morph/templates/design-system.css +0 -0
  231. /package/{content → stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +0 -0
  232. /package/{content → stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +0 -0
  233. /package/{content → stacks/blazor-azure}/.morph/templates/infra/README.md +0 -0
  234. /package/{content → stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +0 -0
  235. /package/{content → stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +0 -0
  236. /package/{content → stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +0 -0
  237. /package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +0 -0
  238. /package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +0 -0
  239. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +0 -0
  240. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.sh +0 -0
  241. /package/{content → stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +0 -0
  242. /package/{content → stacks/blazor-azure}/.morph/templates/infra/main.bicep +0 -0
  243. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +0 -0
  244. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +0 -0
  245. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +0 -0
  246. /package/{content → stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +0 -0
  247. /package/{content → stacks/blazor-azure}/.morph/templates/infra/storage.bicep +0 -0
  248. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +0 -0
  249. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +0 -0
  250. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +0 -0
  251. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +0 -0
  252. /package/{content → stacks/blazor-azure}/.morph/templates/job.cs +0 -0
  253. /package/{content → stacks/blazor-azure}/.morph/templates/migration.cs +0 -0
  254. /package/{content → stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
  255. /package/{content → stacks/blazor-azure}/.morph/templates/recap.md +0 -0
  256. /package/{content → stacks/blazor-azure}/.morph/templates/repository.cs +0 -0
  257. /package/{content → stacks/blazor-azure}/.morph/templates/saas/subscription.cs +0 -0
  258. /package/{content → stacks/blazor-azure}/.morph/templates/saas/tenant.cs +0 -0
  259. /package/{content → stacks/blazor-azure}/.morph/templates/service.cs +0 -0
  260. /package/{content → stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
  261. /package/{content → stacks/blazor-azure}/.morph/templates/spec.md +0 -0
  262. /package/{content → stacks/blazor-azure}/.morph/templates/sprint-status.yaml +0 -0
  263. /package/{content → stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
  264. /package/{content → stacks/blazor-azure}/.morph/templates/story.md +0 -0
  265. /package/{content → stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
  266. /package/{content → stacks/blazor-azure}/.morph/templates/test.cs +0 -0
  267. /package/{content → stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
  268. /package/{content → stacks/blazor-azure}/.morph/templates/ui-design-system.md +0 -0
  269. /package/{content → stacks/blazor-azure}/.morph/templates/ui-flows.md +0 -0
  270. /package/{content → stacks/blazor-azure}/.morph/templates/ui-mockups.md +0 -0
  271. /package/{content → stacks/blazor-azure}/.morph/test-infra/example.bicep +0 -0
  272. /package/{content → stacks/blazor-azure}/CLAUDE.md +0 -0
  273. /package/{content → stacks/blazor-azure}/README.md +0 -0
@@ -1,291 +1,291 @@
1
- /**
2
- * MORPH-SPEC Session Summary Command
3
- *
4
- * Shows a comprehensive summary of the current session including:
5
- * - Phases completed
6
- * - Decisions taken
7
- * - Progress on tasks
8
- * - Next steps
9
- *
10
- * Usage:
11
- * morph-spec session-summary <feature-name>
12
- * morph-spec summary <feature-name>
13
- */
14
-
15
- import fs from 'fs';
16
- import path from 'path';
17
- import chalk from 'chalk';
18
- import { loadState, getFeature } from '../lib/state-manager.js';
19
-
20
- // Phase order for display
21
- const PHASE_ORDER = [
22
- { key: 'proposal', name: 'FASE 0: PROPOSAL', emoji: '📝' },
23
- { key: 'setup', name: 'FASE 1: SETUP', emoji: '⚙️' },
24
- { key: 'uiux', name: 'FASE 1.5: UI/UX', emoji: '🎨', optional: true },
25
- { key: 'design', name: 'FASE 2: DESIGN', emoji: '📐' },
26
- { key: 'clarify', name: 'FASE 3: CLARIFY', emoji: '❓' },
27
- { key: 'tasks', name: 'FASE 4: TASKS', emoji: '📋' },
28
- { key: 'implement', name: 'FASE 5: IMPLEMENT', emoji: '🔨' },
29
- { key: 'sync', name: 'FASE 6: SYNC', emoji: '🔄', optional: true }
30
- ];
31
-
32
- /**
33
- * Get phase index for comparison
34
- */
35
- function getPhaseIndex(phaseKey) {
36
- return PHASE_ORDER.findIndex(p => p.key === phaseKey);
37
- }
38
-
39
- /**
40
- * Read decisions from decisions.md
41
- */
42
- function readDecisions(featurePath) {
43
- const decisionsPath = path.join(featurePath, 'decisions.md');
44
- if (!fs.existsSync(decisionsPath)) return [];
45
-
46
- try {
47
- const content = fs.readFileSync(decisionsPath, 'utf-8');
48
- const decisions = [];
49
-
50
- // Parse ADR sections
51
- const adrMatches = content.matchAll(/##\s+ADR[- ]?\d*:?\s*(.+?)(?=\n##|\n$|$)/gis);
52
- for (const match of adrMatches) {
53
- const title = match[1].split('\n')[0].trim();
54
- decisions.push(title);
55
- }
56
-
57
- // Also parse simple decisions format
58
- const simpleMatches = content.matchAll(/[-*]\s+\*\*(.+?)\*\*:\s*(.+)/g);
59
- for (const match of simpleMatches) {
60
- decisions.push(`${match[1]}: ${match[2]}`);
61
- }
62
-
63
- return decisions.slice(0, 10); // Limit to 10
64
- } catch {
65
- return [];
66
- }
67
- }
68
-
69
- /**
70
- * Check which outputs exist
71
- */
72
- function checkOutputs(featurePath) {
73
- const outputs = [
74
- { file: 'proposal.md', name: 'Proposal' },
75
- { file: 'spec.md', name: 'Spec' },
76
- { file: 'contracts.cs', name: 'Contracts' },
77
- { file: 'ui-design-system.md', name: 'UI Design System' },
78
- { file: 'ui-mockups.md', name: 'UI Mockups' },
79
- { file: 'ui-components.md', name: 'UI Components' },
80
- { file: 'ui-flows.md', name: 'UI Flows' },
81
- { file: 'decisions.md', name: 'Decisions' },
82
- { file: 'recap.md', name: 'Recap' }
83
- ];
84
-
85
- return outputs.map(o => ({
86
- ...o,
87
- exists: fs.existsSync(path.join(featurePath, o.file))
88
- }));
89
- }
90
-
91
- /**
92
- * Generate progress bar
93
- */
94
- function progressBar(completed, total, width = 30) {
95
- if (total === 0) return chalk.gray('[' + '░'.repeat(width) + '] 0%');
96
-
97
- const percentage = Math.round((completed / total) * 100);
98
- const filled = Math.round((completed / total) * width);
99
- const empty = width - filled;
100
-
101
- const bar = '█'.repeat(filled) + '░'.repeat(empty);
102
- const color = percentage === 100 ? chalk.green : percentage > 50 ? chalk.yellow : chalk.cyan;
103
-
104
- return color(`[${bar}] ${percentage}%`);
105
- }
106
-
107
- /**
108
- * Get next steps suggestions
109
- */
110
- function getNextSteps(feature, currentPhaseIndex) {
111
- const steps = [];
112
-
113
- if (!feature) {
114
- steps.push('Run: morph-spec state set <feature> phase proposal');
115
- return steps;
116
- }
117
-
118
- const nextPhase = PHASE_ORDER[currentPhaseIndex + 1];
119
-
120
- if (feature.tasks?.total > 0 && feature.tasks?.completed < feature.tasks?.total) {
121
- steps.push(`Continue implementing tasks (${feature.tasks.completed}/${feature.tasks.total} done)`);
122
- }
123
-
124
- if (nextPhase) {
125
- steps.push(`Advance to ${nextPhase.name}`);
126
- }
127
-
128
- if (feature.phase === 'implement' && feature.tasks?.completed === feature.tasks?.total) {
129
- steps.push('Generate recap.md');
130
- steps.push('Consider running FASE 6: SYNC to promote decisions');
131
- }
132
-
133
- return steps;
134
- }
135
-
136
- /**
137
- * Main command handler
138
- */
139
- export async function sessionSummaryCommand(featureName, options = {}) {
140
- const featurePath = path.join(process.cwd(), '.morph/project/outputs', featureName);
141
-
142
- // Header
143
- console.log(chalk.cyan('\n╔════════════════════════════════════════════════════════════╗'));
144
- console.log(chalk.cyan(`║ 📊 SESSION SUMMARY: ${featureName.padEnd(35)}║`));
145
- console.log(chalk.cyan('╚════════════════════════════════════════════════════════════╝\n'));
146
-
147
- // Get feature from state
148
- let feature = null;
149
- try {
150
- feature = getFeature(featureName);
151
- } catch {
152
- // State may not exist
153
- }
154
-
155
- // JSON output mode
156
- if (options.json) {
157
- const outputs = checkOutputs(featurePath);
158
- const decisions = readDecisions(featurePath);
159
- const summary = {
160
- feature: featureName,
161
- status: feature?.status || 'unknown',
162
- phase: feature?.phase || 'unknown',
163
- workflow: feature?.workflow || 'auto',
164
- agents: feature?.activeAgents || [],
165
- tasks: feature?.tasks || { total: 0, completed: 0 },
166
- checkpoints: feature?.checkpoints || [],
167
- outputs: outputs.filter(o => o.exists).map(o => o.name),
168
- decisions,
169
- skippedPhases: feature?.skippedPhases || []
170
- };
171
- console.log(JSON.stringify(summary, null, 2));
172
- return;
173
- }
174
-
175
- // Check if feature directory exists
176
- if (!fs.existsSync(featurePath)) {
177
- console.log(chalk.yellow(' ⚠️ Feature directory not found'));
178
- console.log(chalk.gray(` Expected: ${featurePath}\n`));
179
-
180
- if (feature) {
181
- console.log(chalk.gray(' State exists but no outputs directory.'));
182
- console.log(chalk.gray(` Phase: ${feature.phase}`));
183
- }
184
- return;
185
- }
186
-
187
- // Current Status
188
- const currentPhaseIndex = feature ? getPhaseIndex(feature.phase) : -1;
189
-
190
- console.log(chalk.bold('📌 Current Status'));
191
- console.log(chalk.gray('─'.repeat(50)));
192
- console.log(` Phase: ${chalk.cyan(feature?.phase || 'unknown')}`);
193
- console.log(` Status: ${chalk.cyan(feature?.status || 'unknown')}`);
194
- console.log(` Workflow: ${chalk.cyan(feature?.workflow || 'auto')}`);
195
- console.log('');
196
-
197
- // Phases Progress
198
- console.log(chalk.bold('🔄 Phases Progress'));
199
- console.log(chalk.gray('─'.repeat(50)));
200
-
201
- for (let i = 0; i < PHASE_ORDER.length; i++) {
202
- const phase = PHASE_ORDER[i];
203
- let status;
204
- let color;
205
-
206
- const isSkipped = feature?.skippedPhases?.includes(phase.key);
207
-
208
- if (isSkipped) {
209
- status = 'SKIP';
210
- color = chalk.gray;
211
- } else if (i < currentPhaseIndex) {
212
- status = '✓';
213
- color = chalk.green;
214
- } else if (i === currentPhaseIndex) {
215
- status = '▸';
216
- color = chalk.cyan;
217
- } else {
218
- status = ' ';
219
- color = chalk.gray;
220
- }
221
-
222
- const optionalTag = phase.optional ? chalk.gray(' (optional)') : '';
223
- console.log(` ${color(status)} ${phase.emoji} ${color(phase.name)}${optionalTag}`);
224
- }
225
- console.log('');
226
-
227
- // Tasks Progress
228
- if (feature?.tasks && feature.tasks.total > 0) {
229
- console.log(chalk.bold('📋 Tasks Progress'));
230
- console.log(chalk.gray('─'.repeat(50)));
231
- console.log(` ${progressBar(feature.tasks.completed, feature.tasks.total)}`);
232
- console.log(` ${chalk.gray(`${feature.tasks.completed}/${feature.tasks.total} tasks completed`)}`);
233
- console.log('');
234
- }
235
-
236
- // Active Agents
237
- if (feature?.activeAgents && feature.activeAgents.length > 0) {
238
- console.log(chalk.bold('🤖 Active Agents'));
239
- console.log(chalk.gray('─'.repeat(50)));
240
- feature.activeAgents.forEach(agent => {
241
- console.log(` • ${chalk.cyan(agent)}`);
242
- });
243
- console.log('');
244
- }
245
-
246
- // Outputs
247
- const outputs = checkOutputs(featurePath);
248
- const createdOutputs = outputs.filter(o => o.exists);
249
-
250
- if (createdOutputs.length > 0) {
251
- console.log(chalk.bold('📄 Outputs Created'));
252
- console.log(chalk.gray('─'.repeat(50)));
253
- createdOutputs.forEach(o => {
254
- console.log(` ${chalk.green('✓')} ${o.name}`);
255
- });
256
- console.log('');
257
- }
258
-
259
- // Decisions Taken
260
- const decisions = readDecisions(featurePath);
261
- if (decisions.length > 0) {
262
- console.log(chalk.bold('🎯 Decisions Taken'));
263
- console.log(chalk.gray('─'.repeat(50)));
264
- decisions.forEach(d => {
265
- console.log(` • ${chalk.white(d)}`);
266
- });
267
- console.log('');
268
- }
269
-
270
- // Checkpoints
271
- if (feature?.checkpoints && feature.checkpoints.length > 0) {
272
- console.log(chalk.bold('🏁 Checkpoints'));
273
- console.log(chalk.gray('─'.repeat(50)));
274
- feature.checkpoints.slice(-5).forEach(cp => {
275
- const date = new Date(cp.timestamp).toLocaleString();
276
- console.log(` ${chalk.gray(date)} - ${cp.note}`);
277
- });
278
- console.log('');
279
- }
280
-
281
- // Next Steps
282
- const nextSteps = getNextSteps(feature, currentPhaseIndex);
283
- if (nextSteps.length > 0) {
284
- console.log(chalk.bold('➡️ Next Steps'));
285
- console.log(chalk.gray('─'.repeat(50)));
286
- nextSteps.forEach((step, i) => {
287
- console.log(` ${i + 1}. ${chalk.yellow(step)}`);
288
- });
289
- console.log('');
290
- }
291
- }
1
+ /**
2
+ * MORPH-SPEC Session Summary Command
3
+ *
4
+ * Shows a comprehensive summary of the current session including:
5
+ * - Phases completed
6
+ * - Decisions taken
7
+ * - Progress on tasks
8
+ * - Next steps
9
+ *
10
+ * Usage:
11
+ * morph-spec session-summary <feature-name>
12
+ * morph-spec summary <feature-name>
13
+ */
14
+
15
+ import fs from 'fs';
16
+ import path from 'path';
17
+ import chalk from 'chalk';
18
+ import { loadState, getFeature } from '../lib/state-manager.js';
19
+
20
+ // Phase order for display
21
+ const PHASE_ORDER = [
22
+ { key: 'proposal', name: 'FASE 0: PROPOSAL', emoji: '📝' },
23
+ { key: 'setup', name: 'FASE 1: SETUP', emoji: '⚙️' },
24
+ { key: 'uiux', name: 'FASE 1.5: UI/UX', emoji: '🎨', optional: true },
25
+ { key: 'design', name: 'FASE 2: DESIGN', emoji: '📐' },
26
+ { key: 'clarify', name: 'FASE 3: CLARIFY', emoji: '❓' },
27
+ { key: 'tasks', name: 'FASE 4: TASKS', emoji: '📋' },
28
+ { key: 'implement', name: 'FASE 5: IMPLEMENT', emoji: '🔨' },
29
+ { key: 'sync', name: 'FASE 6: SYNC', emoji: '🔄', optional: true }
30
+ ];
31
+
32
+ /**
33
+ * Get phase index for comparison
34
+ */
35
+ function getPhaseIndex(phaseKey) {
36
+ return PHASE_ORDER.findIndex(p => p.key === phaseKey);
37
+ }
38
+
39
+ /**
40
+ * Read decisions from decisions.md
41
+ */
42
+ function readDecisions(featurePath) {
43
+ const decisionsPath = path.join(featurePath, 'decisions.md');
44
+ if (!fs.existsSync(decisionsPath)) return [];
45
+
46
+ try {
47
+ const content = fs.readFileSync(decisionsPath, 'utf-8');
48
+ const decisions = [];
49
+
50
+ // Parse ADR sections
51
+ const adrMatches = content.matchAll(/##\s+ADR[- ]?\d*:?\s*(.+?)(?=\n##|\n$|$)/gis);
52
+ for (const match of adrMatches) {
53
+ const title = match[1].split('\n')[0].trim();
54
+ decisions.push(title);
55
+ }
56
+
57
+ // Also parse simple decisions format
58
+ const simpleMatches = content.matchAll(/[-*]\s+\*\*(.+?)\*\*:\s*(.+)/g);
59
+ for (const match of simpleMatches) {
60
+ decisions.push(`${match[1]}: ${match[2]}`);
61
+ }
62
+
63
+ return decisions.slice(0, 10); // Limit to 10
64
+ } catch {
65
+ return [];
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Check which outputs exist
71
+ */
72
+ function checkOutputs(featurePath) {
73
+ const outputs = [
74
+ { file: 'proposal.md', name: 'Proposal' },
75
+ { file: 'spec.md', name: 'Spec' },
76
+ { file: 'contracts.cs', name: 'Contracts' },
77
+ { file: 'ui-design-system.md', name: 'UI Design System' },
78
+ { file: 'ui-mockups.md', name: 'UI Mockups' },
79
+ { file: 'ui-components.md', name: 'UI Components' },
80
+ { file: 'ui-flows.md', name: 'UI Flows' },
81
+ { file: 'decisions.md', name: 'Decisions' },
82
+ { file: 'recap.md', name: 'Recap' }
83
+ ];
84
+
85
+ return outputs.map(o => ({
86
+ ...o,
87
+ exists: fs.existsSync(path.join(featurePath, o.file))
88
+ }));
89
+ }
90
+
91
+ /**
92
+ * Generate progress bar
93
+ */
94
+ function progressBar(completed, total, width = 30) {
95
+ if (total === 0) return chalk.gray('[' + '░'.repeat(width) + '] 0%');
96
+
97
+ const percentage = Math.round((completed / total) * 100);
98
+ const filled = Math.round((completed / total) * width);
99
+ const empty = width - filled;
100
+
101
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
102
+ const color = percentage === 100 ? chalk.green : percentage > 50 ? chalk.yellow : chalk.cyan;
103
+
104
+ return color(`[${bar}] ${percentage}%`);
105
+ }
106
+
107
+ /**
108
+ * Get next steps suggestions
109
+ */
110
+ function getNextSteps(feature, currentPhaseIndex) {
111
+ const steps = [];
112
+
113
+ if (!feature) {
114
+ steps.push('Run: morph-spec state set <feature> phase proposal');
115
+ return steps;
116
+ }
117
+
118
+ const nextPhase = PHASE_ORDER[currentPhaseIndex + 1];
119
+
120
+ if (feature.tasks?.total > 0 && feature.tasks?.completed < feature.tasks?.total) {
121
+ steps.push(`Continue implementing tasks (${feature.tasks.completed}/${feature.tasks.total} done)`);
122
+ }
123
+
124
+ if (nextPhase) {
125
+ steps.push(`Advance to ${nextPhase.name}`);
126
+ }
127
+
128
+ if (feature.phase === 'implement' && feature.tasks?.completed === feature.tasks?.total) {
129
+ steps.push('Generate recap.md');
130
+ steps.push('Consider running FASE 6: SYNC to promote decisions');
131
+ }
132
+
133
+ return steps;
134
+ }
135
+
136
+ /**
137
+ * Main command handler
138
+ */
139
+ export async function sessionSummaryCommand(featureName, options = {}) {
140
+ const featurePath = path.join(process.cwd(), '.morph/project/outputs', featureName);
141
+
142
+ // Header
143
+ console.log(chalk.cyan('\n╔════════════════════════════════════════════════════════════╗'));
144
+ console.log(chalk.cyan(`║ 📊 SESSION SUMMARY: ${featureName.padEnd(35)}║`));
145
+ console.log(chalk.cyan('╚════════════════════════════════════════════════════════════╝\n'));
146
+
147
+ // Get feature from state
148
+ let feature = null;
149
+ try {
150
+ feature = getFeature(featureName);
151
+ } catch {
152
+ // State may not exist
153
+ }
154
+
155
+ // JSON output mode
156
+ if (options.json) {
157
+ const outputs = checkOutputs(featurePath);
158
+ const decisions = readDecisions(featurePath);
159
+ const summary = {
160
+ feature: featureName,
161
+ status: feature?.status || 'unknown',
162
+ phase: feature?.phase || 'unknown',
163
+ workflow: feature?.workflow || 'auto',
164
+ agents: feature?.activeAgents || [],
165
+ tasks: feature?.tasks || { total: 0, completed: 0 },
166
+ checkpoints: feature?.checkpoints || [],
167
+ outputs: outputs.filter(o => o.exists).map(o => o.name),
168
+ decisions,
169
+ skippedPhases: feature?.skippedPhases || []
170
+ };
171
+ console.log(JSON.stringify(summary, null, 2));
172
+ return;
173
+ }
174
+
175
+ // Check if feature directory exists
176
+ if (!fs.existsSync(featurePath)) {
177
+ console.log(chalk.yellow(' ⚠️ Feature directory not found'));
178
+ console.log(chalk.gray(` Expected: ${featurePath}\n`));
179
+
180
+ if (feature) {
181
+ console.log(chalk.gray(' State exists but no outputs directory.'));
182
+ console.log(chalk.gray(` Phase: ${feature.phase}`));
183
+ }
184
+ return;
185
+ }
186
+
187
+ // Current Status
188
+ const currentPhaseIndex = feature ? getPhaseIndex(feature.phase) : -1;
189
+
190
+ console.log(chalk.bold('📌 Current Status'));
191
+ console.log(chalk.gray('─'.repeat(50)));
192
+ console.log(` Phase: ${chalk.cyan(feature?.phase || 'unknown')}`);
193
+ console.log(` Status: ${chalk.cyan(feature?.status || 'unknown')}`);
194
+ console.log(` Workflow: ${chalk.cyan(feature?.workflow || 'auto')}`);
195
+ console.log('');
196
+
197
+ // Phases Progress
198
+ console.log(chalk.bold('🔄 Phases Progress'));
199
+ console.log(chalk.gray('─'.repeat(50)));
200
+
201
+ for (let i = 0; i < PHASE_ORDER.length; i++) {
202
+ const phase = PHASE_ORDER[i];
203
+ let status;
204
+ let color;
205
+
206
+ const isSkipped = feature?.skippedPhases?.includes(phase.key);
207
+
208
+ if (isSkipped) {
209
+ status = 'SKIP';
210
+ color = chalk.gray;
211
+ } else if (i < currentPhaseIndex) {
212
+ status = '✓';
213
+ color = chalk.green;
214
+ } else if (i === currentPhaseIndex) {
215
+ status = '▸';
216
+ color = chalk.cyan;
217
+ } else {
218
+ status = ' ';
219
+ color = chalk.gray;
220
+ }
221
+
222
+ const optionalTag = phase.optional ? chalk.gray(' (optional)') : '';
223
+ console.log(` ${color(status)} ${phase.emoji} ${color(phase.name)}${optionalTag}`);
224
+ }
225
+ console.log('');
226
+
227
+ // Tasks Progress
228
+ if (feature?.tasks && feature.tasks.total > 0) {
229
+ console.log(chalk.bold('📋 Tasks Progress'));
230
+ console.log(chalk.gray('─'.repeat(50)));
231
+ console.log(` ${progressBar(feature.tasks.completed, feature.tasks.total)}`);
232
+ console.log(` ${chalk.gray(`${feature.tasks.completed}/${feature.tasks.total} tasks completed`)}`);
233
+ console.log('');
234
+ }
235
+
236
+ // Active Agents
237
+ if (feature?.activeAgents && feature.activeAgents.length > 0) {
238
+ console.log(chalk.bold('🤖 Active Agents'));
239
+ console.log(chalk.gray('─'.repeat(50)));
240
+ feature.activeAgents.forEach(agent => {
241
+ console.log(` • ${chalk.cyan(agent)}`);
242
+ });
243
+ console.log('');
244
+ }
245
+
246
+ // Outputs
247
+ const outputs = checkOutputs(featurePath);
248
+ const createdOutputs = outputs.filter(o => o.exists);
249
+
250
+ if (createdOutputs.length > 0) {
251
+ console.log(chalk.bold('📄 Outputs Created'));
252
+ console.log(chalk.gray('─'.repeat(50)));
253
+ createdOutputs.forEach(o => {
254
+ console.log(` ${chalk.green('✓')} ${o.name}`);
255
+ });
256
+ console.log('');
257
+ }
258
+
259
+ // Decisions Taken
260
+ const decisions = readDecisions(featurePath);
261
+ if (decisions.length > 0) {
262
+ console.log(chalk.bold('🎯 Decisions Taken'));
263
+ console.log(chalk.gray('─'.repeat(50)));
264
+ decisions.forEach(d => {
265
+ console.log(` • ${chalk.white(d)}`);
266
+ });
267
+ console.log('');
268
+ }
269
+
270
+ // Checkpoints
271
+ if (feature?.checkpoints && feature.checkpoints.length > 0) {
272
+ console.log(chalk.bold('🏁 Checkpoints'));
273
+ console.log(chalk.gray('─'.repeat(50)));
274
+ feature.checkpoints.slice(-5).forEach(cp => {
275
+ const date = new Date(cp.timestamp).toLocaleString();
276
+ console.log(` ${chalk.gray(date)} - ${cp.note}`);
277
+ });
278
+ console.log('');
279
+ }
280
+
281
+ // Next Steps
282
+ const nextSteps = getNextSteps(feature, currentPhaseIndex);
283
+ if (nextSteps.length > 0) {
284
+ console.log(chalk.bold('➡️ Next Steps'));
285
+ console.log(chalk.gray('─'.repeat(50)));
286
+ nextSteps.forEach((step, i) => {
287
+ console.log(` ${i + 1}. ${chalk.yellow(step)}`);
288
+ });
289
+ console.log('');
290
+ }
291
+ }