@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
@@ -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
+ }