@polymorphism-tech/morph-spec 3.0.0 → 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 (240) hide show
  1. package/CLAUDE.md +68 -400
  2. package/README.md +198 -76
  3. package/bin/detect-agents.js +227 -225
  4. package/bin/morph-spec.js +10 -0
  5. package/bin/render-template.js +303 -302
  6. package/bin/semantic-detect-agents.js +247 -246
  7. package/bin/{task-manager.js → task-manager.cjs} +12 -1
  8. package/bin/validate-agents-skills.js +257 -251
  9. package/bin/validate-agents.js +70 -69
  10. package/bin/validate-phase.js +263 -263
  11. package/docs/getting-started.md +3 -3
  12. package/package.json +3 -4
  13. package/scripts/reorganize-skills.cjs +175 -0
  14. package/scripts/validate-agents-structure.cjs +52 -0
  15. package/scripts/validate-skills.cjs +180 -0
  16. package/src/commands/create-story.js +354 -351
  17. package/src/commands/detect-agents.js +13 -2
  18. package/src/commands/detect.js +104 -104
  19. package/src/commands/state.js +334 -333
  20. package/src/commands/sync.js +167 -167
  21. package/src/commands/task.js +1 -1
  22. package/src/commands/update.js +13 -1
  23. package/src/lib/context-generator.js +7 -4
  24. package/{detectors → src/lib/detectors}/config-detector.js +223 -223
  25. package/{detectors → src/lib/detectors}/conversation-analyzer.js +163 -163
  26. package/{detectors → src/lib/detectors}/index.js +84 -84
  27. package/{detectors → src/lib/detectors}/standards-generator.js +275 -275
  28. package/src/lib/hook-executor.js +2 -1
  29. package/src/lib/stack-resolver.js +148 -0
  30. package/src/lib/standards-context-injector.js +4 -3
  31. package/src/lib/state-manager.js +21 -4
  32. package/src/lib/team-orchestrator.js +2 -1
  33. package/src/lib/troubleshoot-grep.js +13 -3
  34. package/src/lib/validation-runner.js +2 -1
  35. package/src/utils/file-copier.js +3 -1
  36. package/{content → stacks/blazor-azure}/.azure/README.md +293 -293
  37. package/{content → stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +454 -454
  38. package/{content → stacks/blazor-azure}/.azure/docs/branch-strategy.md +398 -398
  39. package/{content → stacks/blazor-azure}/.azure/docs/local-development.md +515 -515
  40. package/{content → stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +34 -34
  41. package/{content → stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +319 -319
  42. package/{content → stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +234 -234
  43. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +75 -75
  44. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +94 -94
  45. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +120 -120
  46. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +90 -90
  47. package/{content → stacks/blazor-azure}/.claude/commands/morph-archive.md +79 -79
  48. package/{content → stacks/blazor-azure}/.claude/commands/morph-deploy.md +529 -529
  49. package/{content → stacks/blazor-azure}/.claude/commands/morph-infra.md +209 -209
  50. package/{content → stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +1 -1
  51. package/{content → stacks/blazor-azure}/.claude/settings.local.json +15 -15
  52. package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
  53. package/{content/.claude/skills/specialists → stacks/blazor-azure/.claude/skills/level-2-domains/architecture}/prompt-engineer.md +189 -189
  54. package/{content/.claude/skills/specialists → stacks/blazor-azure/.claude/skills/level-2-domains/architecture}/seo-growth-hacker.md +320 -320
  55. package/{content/.claude/skills/infra → stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure}/azure-deploy-specialist.md +699 -699
  56. package/{content → stacks/blazor-azure}/.morph/.morphversion +5 -5
  57. package/{content → stacks/blazor-azure}/.morph/archive/.gitkeep +25 -25
  58. package/{content → stacks/blazor-azure}/.morph/config/agents.json +7 -5
  59. package/{content → stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
  60. package/{content → stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
  61. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +241 -241
  62. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +307 -307
  63. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +399 -399
  64. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +168 -168
  65. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/README.md +125 -125
  66. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +358 -358
  67. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +246 -246
  68. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +236 -236
  69. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +150 -150
  70. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/README.md +309 -309
  71. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +433 -433
  72. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +479 -479
  73. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +185 -185
  74. package/{content → stacks/blazor-azure}/.morph/examples/state-v3.json +188 -188
  75. package/{content → stacks/blazor-azure}/.morph/features/.gitkeep +25 -25
  76. package/{content → stacks/blazor-azure}/.morph/hooks/README.md +12 -12
  77. package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +48 -48
  78. package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +49 -49
  79. package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +60 -60
  80. package/{content → stacks/blazor-azure}/.morph/project.md +160 -160
  81. package/{content → stacks/blazor-azure}/.morph/schemas/agent.schema.json +296 -296
  82. package/{content → stacks/blazor-azure}/.morph/specs/.gitkeep +20 -20
  83. package/{content → stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
  84. package/{content → stacks/blazor-azure}/.morph/standards/coding.md +377 -377
  85. package/{content → stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +590 -590
  86. package/{content → stacks/blazor-azure}/.morph/standards/migration-guide.md +514 -514
  87. package/{content → stacks/blazor-azure}/.morph/standards/passkeys-auth.md +423 -423
  88. package/{content → stacks/blazor-azure}/.morph/standards/vector-search-rag.md +536 -536
  89. package/{content → stacks/blazor-azure}/.morph/state.json +17 -17
  90. package/{content → stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +149 -149
  91. package/{content → stacks/blazor-azure}/.morph/templates/MudTheme.cs +281 -281
  92. package/{content → stacks/blazor-azure}/.morph/templates/component.razor +239 -239
  93. package/{content → stacks/blazor-azure}/.morph/templates/contracts.cs +217 -217
  94. package/{content → stacks/blazor-azure}/.morph/templates/design-system.css +226 -226
  95. package/{content → stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +89 -89
  96. package/{content → stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +82 -82
  97. package/{content → stacks/blazor-azure}/.morph/templates/infra/README.md +286 -286
  98. package/{content → stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +63 -63
  99. package/{content → stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +164 -164
  100. package/{content → stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +480 -480
  101. package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +49 -49
  102. package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +156 -156
  103. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +229 -229
  104. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.sh +208 -208
  105. package/{content → stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +91 -91
  106. package/{content → stacks/blazor-azure}/.morph/templates/infra/main.bicep +189 -189
  107. package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +29 -29
  108. package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +29 -29
  109. package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +29 -29
  110. package/{content → stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +103 -103
  111. package/{content → stacks/blazor-azure}/.morph/templates/infra/storage.bicep +106 -106
  112. package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +387 -387
  113. package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +351 -351
  114. package/{content → stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +288 -288
  115. package/{content → stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +258 -258
  116. package/{content → stacks/blazor-azure}/.morph/templates/job.cs +171 -171
  117. package/{content → stacks/blazor-azure}/.morph/templates/migration.cs +83 -83
  118. package/{content → stacks/blazor-azure}/.morph/templates/repository.cs +141 -141
  119. package/{content → stacks/blazor-azure}/.morph/templates/saas/subscription.cs +347 -347
  120. package/{content → stacks/blazor-azure}/.morph/templates/saas/tenant.cs +338 -338
  121. package/{content → stacks/blazor-azure}/.morph/templates/service.cs +139 -139
  122. package/{content → stacks/blazor-azure}/.morph/templates/sprint-status.yaml +68 -68
  123. package/{content → stacks/blazor-azure}/.morph/templates/story.md +143 -143
  124. package/{content → stacks/blazor-azure}/.morph/templates/test.cs +239 -239
  125. package/{content → stacks/blazor-azure}/.morph/templates/ui-design-system.md +286 -286
  126. package/{content → stacks/blazor-azure}/.morph/templates/ui-flows.md +336 -336
  127. package/{content → stacks/blazor-azure}/.morph/templates/ui-mockups.md +133 -133
  128. package/{content → stacks/blazor-azure}/.morph/test-infra/example.bicep +59 -59
  129. package/{content → stacks/blazor-azure}/README.md +79 -79
  130. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
  131. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
  132. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
  133. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
  134. package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
  135. package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
  136. package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
  137. package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
  138. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
  139. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
  140. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
  141. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
  142. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
  143. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
  144. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
  145. package/stacks/nextjs-supabase/.morph/project.md +168 -0
  146. package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
  147. package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
  148. package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
  149. package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
  150. package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
  151. package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
  152. package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
  153. package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
  154. package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
  155. package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
  156. package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
  157. package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
  158. package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
  159. package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
  160. package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
  161. package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
  162. package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
  163. package/stacks/nextjs-supabase/CLAUDE.md +149 -0
  164. package/stacks/nextjs-supabase/README.md +112 -0
  165. /package/{detectors → src/lib/detectors}/structure-detector.js +0 -0
  166. /package/{content → stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
  167. /package/{content → stacks/blazor-azure}/.claude/commands/morph-preflight.md +0 -0
  168. /package/{content → stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
  169. /package/{content → stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
  170. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
  171. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
  172. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
  173. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
  174. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
  175. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
  176. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
  177. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
  178. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
  179. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
  180. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
  181. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
  182. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
  183. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
  184. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
  185. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
  186. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
  187. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
  188. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
  189. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
  190. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
  191. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
  192. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
  193. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
  194. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
  195. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
  196. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
  197. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
  198. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
  199. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
  200. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
  201. /package/{content → stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
  202. /package/{content → stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
  203. /package/{content → stacks/blazor-azure}/.morph/config/config.template.json +0 -0
  204. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
  205. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
  206. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
  207. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
  208. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
  209. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
  210. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
  211. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
  212. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
  213. /package/{content → stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
  214. /package/{content → stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
  215. /package/{content → stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
  216. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
  217. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
  218. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
  219. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
  220. /package/{content → stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
  221. /package/{content → stacks/blazor-azure}/.morph/standards/azure.md +0 -0
  222. /package/{content → stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
  223. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
  224. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
  225. /package/{content → stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
  226. /package/{content → stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
  227. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
  228. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
  229. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
  230. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
  231. /package/{content → stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
  232. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +0 -0
  233. /package/{content → stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
  234. /package/{content → stacks/blazor-azure}/.morph/templates/recap.md +0 -0
  235. /package/{content → stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
  236. /package/{content → stacks/blazor-azure}/.morph/templates/spec.md +0 -0
  237. /package/{content → stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
  238. /package/{content → stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
  239. /package/{content → stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
  240. /package/{content → stacks/blazor-azure}/CLAUDE.md +0 -0
@@ -1,333 +1,334 @@
1
- /**
2
- * MORPH-SPEC State Command
3
- * CLI wrapper for state management operations
4
- */
5
-
6
- import ora from 'ora';
7
- import chalk from 'chalk';
8
- import { logger } from '../utils/logger.js';
9
- import * as StateManager from '../lib/state-manager.js';
10
-
11
- // ============================================================================
12
- // Command Functions
13
- // ============================================================================
14
-
15
- /**
16
- * Main state command router
17
- */
18
- export async function stateCommand(action, args, options) {
19
- switch (action) {
20
- case 'init':
21
- await initCommand(options);
22
- break;
23
-
24
- case 'get':
25
- await getCommand(args[0], options);
26
- break;
27
-
28
- case 'set':
29
- await setCommand(args[0], args[1], args[2], options);
30
- break;
31
-
32
- case 'checkpoint':
33
- await checkpointCommand(args[0], args.slice(1).join(' '), options);
34
- break;
35
-
36
- case 'list':
37
- await listCommand(options);
38
- break;
39
-
40
- case 'add-agent':
41
- await addAgentCommand(args[0], args[1], options);
42
- break;
43
-
44
- case 'remove-agent':
45
- await removeAgentCommand(args[0], args[1], options);
46
- break;
47
-
48
- case 'mark-output':
49
- await markOutputCommand(args[0], args[1], options);
50
- break;
51
-
52
- default:
53
- logger.error(`Unknown action: ${action}`);
54
- logger.blank();
55
- logger.info('Available actions:');
56
- logger.dim(' init, get, set, checkpoint, list, add-agent, remove-agent, mark-output');
57
- logger.blank();
58
- logger.dim('Run "morph-spec state --help" for more information');
59
- process.exit(1);
60
- }
61
- }
62
-
63
- /**
64
- * Initialize state file
65
- */
66
- async function initCommand(options) {
67
- logger.header('Initialize State');
68
- logger.blank();
69
-
70
- try {
71
- if (StateManager.stateExists() && !options.force) {
72
- logger.warn('State file already exists.');
73
- logger.dim(' Use --force to overwrite');
74
- logger.blank();
75
- return;
76
- }
77
-
78
- const spinner = ora('Initializing state.json...').start();
79
-
80
- StateManager.initState({
81
- force: options.force,
82
- projectName: options.project || '{PROJECT_NAME}',
83
- projectType: options.type || 'blazor-server'
84
- });
85
-
86
- spinner.succeed('State initialized!');
87
- logger.blank();
88
- logger.dim(`Location: ${StateManager.getStatePath()}`);
89
- logger.blank();
90
-
91
- } catch (error) {
92
- logger.error(error.message);
93
- process.exit(1);
94
- }
95
- }
96
-
97
- /**
98
- * Get feature state
99
- */
100
- async function getCommand(featureName, options) {
101
- if (!featureName) {
102
- logger.error('Feature name required');
103
- logger.dim(' Usage: morph-spec state get <feature>');
104
- process.exit(1);
105
- }
106
-
107
- try {
108
- const feature = StateManager.getFeature(featureName);
109
-
110
- if (!feature) {
111
- logger.error(`Feature '${featureName}' not found`);
112
- process.exit(1);
113
- }
114
-
115
- if (options.json) {
116
- console.log(JSON.stringify(feature, null, 2));
117
- } else {
118
- logger.header(`Feature: ${featureName}`);
119
- logger.blank();
120
- logger.info(`Status: ${chalk.cyan(feature.status)}`);
121
- logger.info(`Phase: ${chalk.cyan(feature.phase)}`);
122
- logger.info(`Tasks: ${chalk.cyan(`${feature.tasks.completed}/${feature.tasks.total}`)}`);
123
- logger.info(`Agents: ${chalk.cyan(feature.activeAgents.join(', ') || 'None')}`);
124
- logger.blank();
125
- }
126
-
127
- } catch (error) {
128
- logger.error(error.message);
129
- process.exit(1);
130
- }
131
- }
132
-
133
- /**
134
- * Set feature property
135
- */
136
- async function setCommand(featureName, key, value, options) {
137
- if (!featureName || !key || value === undefined) {
138
- logger.error('Missing required arguments');
139
- logger.dim(' Usage: morph-spec state set <feature> <key> <value>');
140
- logger.blank();
141
- logger.dim(' Example: morph-spec state set my-feature phase implement');
142
- process.exit(1);
143
- }
144
-
145
- try {
146
- const spinner = ora('Updating state...').start();
147
-
148
- // Parse value automatically (JSON, number, boolean)
149
- let parsedValue = value;
150
- try {
151
- parsedValue = JSON.parse(value);
152
- } catch {
153
- // Keep as string if not valid JSON
154
- }
155
-
156
- StateManager.updateFeature(featureName, key, parsedValue);
157
-
158
- spinner.succeed(`Updated ${chalk.cyan(featureName)}.${chalk.cyan(key)}`);
159
- logger.blank();
160
- logger.dim(`Value: ${JSON.stringify(parsedValue)}`);
161
- logger.blank();
162
-
163
- } catch (error) {
164
- logger.error(error.message);
165
- process.exit(1);
166
- }
167
- }
168
-
169
- /**
170
- * Add checkpoint
171
- */
172
- async function checkpointCommand(featureName, note, options) {
173
- if (!featureName || !note) {
174
- logger.error('Missing required arguments');
175
- logger.dim(' Usage: morph-spec state checkpoint <feature> "<note>"');
176
- logger.blank();
177
- logger.dim(' Example: morph-spec state checkpoint my-feature "Completed T001-T003"');
178
- process.exit(1);
179
- }
180
-
181
- try {
182
- const spinner = ora('Creating checkpoint...').start();
183
-
184
- const checkpoint = StateManager.addCheckpoint(featureName, note);
185
-
186
- spinner.succeed(`Checkpoint registered for ${chalk.cyan(featureName)}`);
187
- logger.blank();
188
- logger.dim(` ${checkpoint.note}`);
189
- logger.dim(` Phase: ${checkpoint.phase}`);
190
- logger.dim(` Tasks completed: ${checkpoint.completedTasks}`);
191
- logger.blank();
192
-
193
- } catch (error) {
194
- logger.error(error.message);
195
- process.exit(1);
196
- }
197
- }
198
-
199
- /**
200
- * List all features
201
- */
202
- async function listCommand(options) {
203
- logger.header('MORPH-SPEC Project Status');
204
- logger.blank();
205
-
206
- try {
207
- const summary = StateManager.getSummary();
208
- const features = StateManager.listFeatures();
209
-
210
- // Project info
211
- logger.info(`Project: ${chalk.cyan(summary.project.name)}`);
212
- logger.info(`Type: ${chalk.cyan(summary.project.type)}`);
213
- logger.blank();
214
-
215
- if (features.length === 0) {
216
- logger.warn('No features found');
217
- logger.blank();
218
- return;
219
- }
220
-
221
- // Features table
222
- logger.header('Features:');
223
- logger.blank();
224
-
225
- features.forEach(([name, feature]) => {
226
- const statusEmoji = {
227
- draft: '📝',
228
- in_review: '👀',
229
- approved: '✅',
230
- in_progress: '🚧',
231
- done: '✔️',
232
- archived: '📦'
233
- }[feature.status] || '❓';
234
-
235
- const progress = feature.tasks.total > 0
236
- ? `${feature.tasks.completed}/${feature.tasks.total}`
237
- : '0/0';
238
-
239
- logger.info(`${statusEmoji} ${chalk.bold(name)}`);
240
- logger.dim(` Phase: ${feature.phase.padEnd(16)} │ Tasks: ${progress}`);
241
- logger.dim(` Agents: ${feature.activeAgents.slice(0, 5).join(', ') || 'None'}`);
242
- logger.blank();
243
- });
244
-
245
- // Summary
246
- logger.header('Summary:');
247
- logger.info(`Total Features: ${chalk.cyan(summary.metadata.totalFeatures)}`);
248
- logger.info(`Completed: ${chalk.cyan(summary.metadata.completedFeatures)}`);
249
- logger.info(`Estimated Cost: ${chalk.cyan(`$${summary.metadata.totalCostEstimated.toFixed(2)}/month`)}`);
250
- logger.blank();
251
-
252
- } catch (error) {
253
- logger.error(error.message);
254
- process.exit(1);
255
- }
256
- }
257
-
258
- /**
259
- * Add agent to feature
260
- */
261
- async function addAgentCommand(featureName, agentId, options) {
262
- if (!featureName || !agentId) {
263
- logger.error('Missing required arguments');
264
- logger.dim(' Usage: morph-spec state add-agent <feature> <agent-id>');
265
- process.exit(1);
266
- }
267
-
268
- try {
269
- const added = StateManager.addAgent(featureName, agentId);
270
-
271
- if (added) {
272
- logger.success(`Agent '${chalk.cyan(agentId)}' added to ${chalk.cyan(featureName)}`);
273
- } else {
274
- logger.warn(`Agent '${agentId}' already active`);
275
- }
276
- logger.blank();
277
-
278
- } catch (error) {
279
- logger.error(error.message);
280
- process.exit(1);
281
- }
282
- }
283
-
284
- /**
285
- * Remove agent from feature
286
- */
287
- async function removeAgentCommand(featureName, agentId, options) {
288
- if (!featureName || !agentId) {
289
- logger.error('Missing required arguments');
290
- logger.dim(' Usage: morph-spec state remove-agent <feature> <agent-id>');
291
- process.exit(1);
292
- }
293
-
294
- try {
295
- const removed = StateManager.removeAgent(featureName, agentId);
296
-
297
- if (removed) {
298
- logger.success(`Agent '${chalk.cyan(agentId)}' removed from ${chalk.cyan(featureName)}`);
299
- } else {
300
- logger.warn(`Agent '${agentId}' not found`);
301
- }
302
- logger.blank();
303
-
304
- } catch (error) {
305
- logger.error(error.message);
306
- process.exit(1);
307
- }
308
- }
309
-
310
- /**
311
- * Mark output as created
312
- */
313
- async function markOutputCommand(featureName, outputType, options) {
314
- if (!featureName || !outputType) {
315
- logger.error('Missing required arguments');
316
- logger.dim(' Usage: morph-spec state mark-output <feature> <output-type>');
317
- logger.blank();
318
- logger.dim(' Valid types: proposal, spec, contracts, tasks, decisions, recap');
319
- logger.dim(' uiDesignSystem, uiMockups, uiComponents, uiFlows');
320
- process.exit(1);
321
- }
322
-
323
- try {
324
- StateManager.markOutput(featureName, outputType);
325
-
326
- logger.success(`Output '${chalk.cyan(outputType)}' marked as created for ${chalk.cyan(featureName)}`);
327
- logger.blank();
328
-
329
- } catch (error) {
330
- logger.error(error.message);
331
- process.exit(1);
332
- }
333
- }
1
+ /**
2
+ * MORPH-SPEC State Command
3
+ * CLI wrapper for state management operations
4
+ */
5
+
6
+ import ora from 'ora';
7
+ import chalk from 'chalk';
8
+ import { logger } from '../utils/logger.js';
9
+ import * as StateManager from '../lib/state-manager.js';
10
+
11
+ // ============================================================================
12
+ // Command Functions
13
+ // ============================================================================
14
+
15
+ /**
16
+ * Main state command router
17
+ */
18
+ export async function stateCommand(action, args, options) {
19
+ switch (action) {
20
+ case 'init':
21
+ await initCommand(options);
22
+ break;
23
+
24
+ case 'get':
25
+ await getCommand(args[0], options);
26
+ break;
27
+
28
+ case 'set':
29
+ await setCommand(args[0], args[1], args[2], options);
30
+ break;
31
+
32
+ case 'checkpoint':
33
+ await checkpointCommand(args[0], args.slice(1).join(' '), options);
34
+ break;
35
+
36
+ case 'list':
37
+ await listCommand(options);
38
+ break;
39
+
40
+ case 'add-agent':
41
+ await addAgentCommand(args[0], args[1], options);
42
+ break;
43
+
44
+ case 'remove-agent':
45
+ await removeAgentCommand(args[0], args[1], options);
46
+ break;
47
+
48
+ case 'mark-output':
49
+ await markOutputCommand(args[0], args[1], options);
50
+ break;
51
+
52
+ default:
53
+ logger.error(`Unknown action: ${action}`);
54
+ logger.blank();
55
+ logger.info('Available actions:');
56
+ logger.dim(' init, get, set, checkpoint, list, add-agent, remove-agent, mark-output');
57
+ logger.blank();
58
+ logger.dim('Run "morph-spec state --help" for more information');
59
+ process.exit(1);
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Initialize state file
65
+ */
66
+ async function initCommand(options) {
67
+ logger.header('Initialize State');
68
+ logger.blank();
69
+
70
+ try {
71
+ if (StateManager.stateExists() && !options.force) {
72
+ logger.warn('State file already exists.');
73
+ logger.dim(' Use --force to overwrite');
74
+ logger.blank();
75
+ return;
76
+ }
77
+
78
+ const spinner = ora('Initializing state.json...').start();
79
+
80
+ StateManager.initState({
81
+ force: options.force,
82
+ projectName: options.project || '{PROJECT_NAME}',
83
+ projectType: options.type || 'blazor-server'
84
+ });
85
+
86
+ spinner.succeed('State initialized!');
87
+ logger.blank();
88
+ logger.dim(`Location: ${StateManager.getStatePath()}`);
89
+ logger.blank();
90
+
91
+ } catch (error) {
92
+ logger.error(error.message);
93
+ process.exit(1);
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Get feature state
99
+ */
100
+ async function getCommand(featureName, options) {
101
+ if (!featureName) {
102
+ logger.error('Feature name required');
103
+ logger.dim(' Usage: morph-spec state get <feature>');
104
+ process.exit(1);
105
+ }
106
+
107
+ try {
108
+ const feature = StateManager.getFeature(featureName);
109
+
110
+ if (!feature) {
111
+ logger.error(`Feature '${featureName}' not found`);
112
+ process.exit(1);
113
+ }
114
+
115
+ if (options.json) {
116
+ console.log(JSON.stringify(feature, null, 2));
117
+ } else {
118
+ logger.header(`Feature: ${featureName}`);
119
+ logger.blank();
120
+ logger.info(`Status: ${chalk.cyan(feature.status)}`);
121
+ logger.info(`Phase: ${chalk.cyan(feature.phase)}`);
122
+ logger.info(`Tasks: ${chalk.cyan(`${feature.tasks.completed}/${feature.tasks.total}`)}`);
123
+ logger.info(`Agents: ${chalk.cyan(feature.activeAgents.join(', ') || 'None')}`);
124
+ logger.blank();
125
+ }
126
+
127
+ } catch (error) {
128
+ logger.error(error.message);
129
+ process.exit(1);
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Set feature property
135
+ */
136
+ async function setCommand(featureName, key, value, options) {
137
+ if (!featureName || !key || value === undefined) {
138
+ logger.error('Missing required arguments');
139
+ logger.dim(' Usage: morph-spec state set <feature> <key> <value>');
140
+ logger.blank();
141
+ logger.dim(' Example: morph-spec state set my-feature phase implement');
142
+ process.exit(1);
143
+ }
144
+
145
+ try {
146
+ const spinner = ora('Updating state...').start();
147
+
148
+ // Parse value automatically (JSON, number, boolean)
149
+ let parsedValue = value;
150
+ try {
151
+ parsedValue = JSON.parse(value);
152
+ } catch {
153
+ // Keep as string if not valid JSON
154
+ }
155
+
156
+ StateManager.updateFeature(featureName, key, parsedValue);
157
+
158
+ spinner.succeed(`Updated ${chalk.cyan(featureName)}.${chalk.cyan(key)}`);
159
+ logger.blank();
160
+ logger.dim(`Value: ${JSON.stringify(parsedValue)}`);
161
+ logger.blank();
162
+
163
+ } catch (error) {
164
+ logger.error(error.message);
165
+ process.exit(1);
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Add checkpoint
171
+ */
172
+ async function checkpointCommand(featureName, note, options) {
173
+ if (!featureName || !note) {
174
+ logger.error('Missing required arguments');
175
+ logger.dim(' Usage: morph-spec state checkpoint <feature> "<note>"');
176
+ logger.blank();
177
+ logger.dim(' Example: morph-spec state checkpoint my-feature "Completed T001-T003"');
178
+ process.exit(1);
179
+ }
180
+
181
+ try {
182
+ const spinner = ora('Creating checkpoint...').start();
183
+
184
+ const checkpoint = StateManager.addCheckpoint(featureName, note);
185
+
186
+ spinner.succeed(`Checkpoint registered for ${chalk.cyan(featureName)}`);
187
+ logger.blank();
188
+ logger.dim(` ${checkpoint.note}`);
189
+ logger.dim(` Phase: ${checkpoint.phase}`);
190
+ logger.dim(` Tasks completed: ${checkpoint.completedTasks}`);
191
+ logger.blank();
192
+
193
+ } catch (error) {
194
+ logger.error(error.message);
195
+ process.exit(1);
196
+ }
197
+ }
198
+
199
+ /**
200
+ * List all features
201
+ */
202
+ async function listCommand(options) {
203
+ logger.header('MORPH-SPEC Project Status');
204
+ logger.blank();
205
+
206
+ try {
207
+ const summary = StateManager.getSummary();
208
+ const features = StateManager.listFeatures();
209
+
210
+ // Project info
211
+ logger.info(`Project: ${chalk.cyan(summary.project.name)}`);
212
+ logger.info(`Type: ${chalk.cyan(summary.project.type)}`);
213
+ logger.blank();
214
+
215
+ if (features.length === 0) {
216
+ logger.warn('No features found');
217
+ logger.blank();
218
+ return;
219
+ }
220
+
221
+ // Features table
222
+ logger.header('Features:');
223
+ logger.blank();
224
+
225
+ features.forEach(([name, feature]) => {
226
+ const statusEmoji = {
227
+ draft: '📝',
228
+ in_review: '👀',
229
+ approved: '✅',
230
+ in_progress: '🚧',
231
+ done: '✔️',
232
+ archived: '📦'
233
+ }[feature.status] || '❓';
234
+
235
+ const progress = feature.tasks.total > 0
236
+ ? `${feature.tasks.completed}/${feature.tasks.total}`
237
+ : '0/0';
238
+
239
+ logger.info(`${statusEmoji} ${chalk.bold(name)}`);
240
+ logger.dim(` Phase: ${feature.phase.padEnd(16)} │ Tasks: ${progress}`);
241
+ logger.dim(` Agents: ${feature.activeAgents.slice(0, 5).join(', ') || 'None'}`);
242
+ logger.blank();
243
+ });
244
+
245
+ // Summary
246
+ logger.header('Summary:');
247
+ logger.info(`Total Features: ${chalk.cyan(summary.metadata.totalFeatures)}`);
248
+ logger.info(`Completed: ${chalk.cyan(summary.metadata.completedFeatures)}`);
249
+ logger.info(`Estimated Cost: ${chalk.cyan(`$${summary.metadata.totalCostEstimated.toFixed(2)}/month`)}`);
250
+ logger.blank();
251
+
252
+ } catch (error) {
253
+ logger.error(error.message);
254
+ process.exit(1);
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Add agent to feature
260
+ */
261
+ async function addAgentCommand(featureName, agentId, options) {
262
+ if (!featureName || !agentId) {
263
+ logger.error('Missing required arguments');
264
+ logger.dim(' Usage: morph-spec state add-agent <feature> <agent-id>');
265
+ process.exit(1);
266
+ }
267
+
268
+ try {
269
+ const added = StateManager.addAgent(featureName, agentId);
270
+
271
+ if (added) {
272
+ logger.success(`Agent '${chalk.cyan(agentId)}' added to ${chalk.cyan(featureName)}`);
273
+ } else {
274
+ logger.warn(`Agent '${agentId}' already active`);
275
+ }
276
+ logger.blank();
277
+
278
+ } catch (error) {
279
+ logger.error(error.message);
280
+ process.exit(1);
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Remove agent from feature
286
+ */
287
+ async function removeAgentCommand(featureName, agentId, options) {
288
+ if (!featureName || !agentId) {
289
+ logger.error('Missing required arguments');
290
+ logger.dim(' Usage: morph-spec state remove-agent <feature> <agent-id>');
291
+ process.exit(1);
292
+ }
293
+
294
+ try {
295
+ const removed = StateManager.removeAgent(featureName, agentId);
296
+
297
+ if (removed) {
298
+ logger.success(`Agent '${chalk.cyan(agentId)}' removed from ${chalk.cyan(featureName)}`);
299
+ } else {
300
+ logger.warn(`Agent '${agentId}' not found`);
301
+ }
302
+ logger.blank();
303
+
304
+ } catch (error) {
305
+ logger.error(error.message);
306
+ process.exit(1);
307
+ }
308
+ }
309
+
310
+ /**
311
+ * Mark output as created
312
+ */
313
+ async function markOutputCommand(featureName, outputType, options) {
314
+ if (!featureName || !outputType) {
315
+ logger.error('Missing required arguments');
316
+ logger.dim(' Usage: morph-spec state mark-output <feature> <output-type>');
317
+ logger.blank();
318
+ logger.dim(' Valid types: proposal, spec, contracts, tasks, decisions, recap');
319
+ logger.dim(' uiDesignSystem (or ui-design-system), uiMockups (or ui-mockups)');
320
+ logger.dim(' uiComponents (or ui-components), uiFlows (or ui-flows)');
321
+ process.exit(1);
322
+ }
323
+
324
+ try {
325
+ StateManager.markOutput(featureName, outputType);
326
+
327
+ logger.success(`Output '${chalk.cyan(outputType)}' marked as created for ${chalk.cyan(featureName)}`);
328
+ logger.blank();
329
+
330
+ } catch (error) {
331
+ logger.error(error.message);
332
+ process.exit(1);
333
+ }
334
+ }