@polymorphism-tech/morph-spec 2.3.0 → 2.4.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 (251) hide show
  1. package/CLAUDE.md +314 -1730
  2. package/LICENSE +72 -72
  3. package/README.md +515 -516
  4. package/bin/detect-agents.js +225 -225
  5. package/bin/morph-spec.js +358 -294
  6. package/bin/render-template.js +302 -302
  7. package/bin/semantic-detect-agents.js +246 -246
  8. package/bin/task-manager.js +429 -368
  9. package/bin/validate-agents-skills.js +251 -251
  10. package/bin/validate-agents.js +69 -69
  11. package/bin/validate-phase.js +263 -263
  12. package/bin/validate.js +369 -268
  13. package/content/.azure/README.md +293 -293
  14. package/content/.azure/docs/azure-devops-setup.md +454 -454
  15. package/content/.azure/docs/branch-strategy.md +398 -398
  16. package/content/.azure/docs/local-development.md +515 -515
  17. package/content/.azure/pipelines/pipeline-variables.yml +34 -34
  18. package/content/.azure/pipelines/prod-pipeline.yml +319 -319
  19. package/content/.azure/pipelines/staging-pipeline.yml +234 -234
  20. package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
  21. package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
  22. package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
  23. package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
  24. package/content/.claude/commands/morph-apply.md +221 -158
  25. package/content/.claude/commands/morph-archive.md +79 -79
  26. package/content/.claude/commands/morph-infra.md +209 -209
  27. package/content/.claude/commands/morph-preflight.md +227 -0
  28. package/content/.claude/commands/morph-proposal.md +122 -101
  29. package/content/.claude/commands/morph-status.md +86 -86
  30. package/content/.claude/commands/morph-troubleshoot.md +122 -0
  31. package/content/.claude/settings.local.json +15 -15
  32. package/content/.claude/skills/checklists/code-review.md +226 -0
  33. package/content/.claude/skills/checklists/morph-checklist.md +117 -0
  34. package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
  35. package/content/.claude/skills/infra/bicep-architect.md +126 -419
  36. package/content/.claude/skills/infra/container-specialist.md +131 -437
  37. package/content/.claude/skills/infra/devops-engineer.md +119 -405
  38. package/content/.claude/skills/integrations/asaas-financial.md +130 -333
  39. package/content/.claude/skills/integrations/azure-identity.md +142 -309
  40. package/content/.claude/skills/integrations/clerk-auth.md +108 -290
  41. package/content/.claude/skills/integrations/resend-email.md +119 -0
  42. package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
  43. package/content/.claude/skills/specialists/azure-architect.md +142 -142
  44. package/content/.claude/skills/specialists/code-analyzer.md +235 -0
  45. package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
  46. package/content/.claude/skills/specialists/ef-modeler.md +113 -211
  47. package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -255
  48. package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
  49. package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
  50. package/content/.claude/skills/specialists/standards-architect.md +156 -78
  51. package/content/.claude/skills/specialists/testing-specialist.md +126 -0
  52. package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1100
  53. package/content/.claude/skills/stacks/dotnet-blazor.md +210 -606
  54. package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
  55. package/content/.claude/skills/workflows/morph-replicate.md +213 -0
  56. package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
  57. package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
  58. package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
  59. package/content/.claude/skills/workflows/phase-tasks.md +164 -0
  60. package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
  61. package/content/.morph/.morphversion +5 -5
  62. package/content/.morph/archive/.gitkeep +25 -25
  63. package/content/.morph/config/agents.json +378 -242
  64. package/content/.morph/config/config.template.json +89 -108
  65. package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
  66. package/content/.morph/docs/workflows/design-impl.md +37 -0
  67. package/content/.morph/docs/workflows/fast-track.md +29 -0
  68. package/content/.morph/docs/workflows/full-morph.md +76 -0
  69. package/content/.morph/docs/workflows/standard.md +44 -0
  70. package/content/.morph/docs/workflows/ui-refresh.md +39 -0
  71. package/content/.morph/examples/api-nextjs/README.md +241 -241
  72. package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
  73. package/content/.morph/examples/api-nextjs/spec.md +399 -399
  74. package/content/.morph/examples/api-nextjs/tasks.md +168 -168
  75. package/content/.morph/examples/micro-saas/README.md +125 -125
  76. package/content/.morph/examples/micro-saas/contracts.cs +358 -358
  77. package/content/.morph/examples/micro-saas/decisions.md +246 -246
  78. package/content/.morph/examples/micro-saas/spec.md +236 -236
  79. package/content/.morph/examples/micro-saas/tasks.md +150 -150
  80. package/content/.morph/examples/multi-agent/README.md +309 -309
  81. package/content/.morph/examples/multi-agent/contracts.cs +433 -433
  82. package/content/.morph/examples/multi-agent/spec.md +479 -479
  83. package/content/.morph/examples/multi-agent/tasks.md +185 -185
  84. package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
  85. package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
  86. package/content/.morph/examples/scheduled-reports/spec.md +267 -0
  87. package/content/.morph/examples/state-v3.json +188 -188
  88. package/content/.morph/features/.gitkeep +25 -25
  89. package/content/.morph/hooks/README.md +190 -239
  90. package/content/.morph/hooks/pre-commit-agents.sh +24 -24
  91. package/content/.morph/hooks/pre-commit-all.sh +48 -48
  92. package/content/.morph/hooks/pre-commit-specs.sh +49 -49
  93. package/content/.morph/hooks/pre-commit-tests.sh +60 -60
  94. package/content/.morph/project.md +160 -160
  95. package/content/.morph/schemas/agent.schema.json +296 -296
  96. package/content/.morph/schemas/tasks.schema.json +220 -0
  97. package/content/.morph/specs/.gitkeep +20 -20
  98. package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
  99. package/content/.morph/standards/agent-framework-production.md +410 -0
  100. package/content/.morph/standards/agent-framework-setup.md +413 -453
  101. package/content/.morph/standards/agent-framework-workflows.md +349 -0
  102. package/content/.morph/standards/architecture.md +325 -325
  103. package/content/.morph/standards/azure.md +605 -379
  104. package/content/.morph/standards/coding.md +377 -377
  105. package/content/.morph/standards/dotnet10-migration.md +520 -494
  106. package/content/.morph/standards/fluent-ui-setup.md +590 -590
  107. package/content/.morph/standards/migration-guide.md +514 -514
  108. package/content/.morph/standards/passkeys-auth.md +423 -423
  109. package/content/.morph/standards/vector-search-rag.md +536 -536
  110. package/content/.morph/state.json +17 -17
  111. package/content/.morph/templates/FluentDesignTheme.cs +149 -149
  112. package/content/.morph/templates/MudTheme.cs +281 -281
  113. package/content/.morph/templates/agent.cs +163 -172
  114. package/content/.morph/templates/clarify-questions.md +159 -0
  115. package/content/.morph/templates/component.razor +239 -239
  116. package/content/.morph/templates/contracts/Commands.cs +74 -0
  117. package/content/.morph/templates/contracts/Entities.cs +25 -0
  118. package/content/.morph/templates/contracts/Queries.cs +74 -0
  119. package/content/.morph/templates/contracts/README.md +74 -0
  120. package/content/.morph/templates/contracts.cs +217 -217
  121. package/content/.morph/templates/decisions.md +123 -106
  122. package/content/.morph/templates/design-system.css +226 -226
  123. package/content/.morph/templates/infra/.dockerignore.example +89 -89
  124. package/content/.morph/templates/infra/Dockerfile.example +82 -82
  125. package/content/.morph/templates/infra/README.md +286 -286
  126. package/content/.morph/templates/infra/app-insights.bicep +63 -63
  127. package/content/.morph/templates/infra/app-service.bicep +164 -164
  128. package/content/.morph/templates/infra/container-app-env.bicep +49 -49
  129. package/content/.morph/templates/infra/container-app.bicep +156 -156
  130. package/content/.morph/templates/infra/deploy-checklist.md +426 -0
  131. package/content/.morph/templates/infra/deploy.ps1 +229 -229
  132. package/content/.morph/templates/infra/deploy.sh +208 -208
  133. package/content/.morph/templates/infra/key-vault.bicep +91 -91
  134. package/content/.morph/templates/infra/main.bicep +189 -189
  135. package/content/.morph/templates/infra/parameters.dev.json +29 -29
  136. package/content/.morph/templates/infra/parameters.prod.json +29 -29
  137. package/content/.morph/templates/infra/parameters.staging.json +29 -29
  138. package/content/.morph/templates/infra/sql-database.bicep +103 -103
  139. package/content/.morph/templates/infra/storage.bicep +106 -106
  140. package/content/.morph/templates/integrations/asaas-client.cs +387 -387
  141. package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
  142. package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
  143. package/content/.morph/templates/integrations/clerk-config.cs +258 -258
  144. package/content/.morph/templates/job.cs +171 -171
  145. package/content/.morph/templates/migration.cs +83 -83
  146. package/content/.morph/templates/proposal.md +141 -155
  147. package/content/.morph/templates/recap.md +94 -105
  148. package/content/.morph/templates/repository.cs +141 -141
  149. package/content/.morph/templates/saas/subscription.cs +347 -347
  150. package/content/.morph/templates/saas/tenant.cs +338 -338
  151. package/content/.morph/templates/service.cs +139 -139
  152. package/content/.morph/templates/simulation.md +353 -0
  153. package/content/.morph/templates/spec.md +149 -148
  154. package/content/.morph/templates/sprint-status.yaml +68 -68
  155. package/content/.morph/templates/state.template.json +222 -222
  156. package/content/.morph/templates/story.md +143 -143
  157. package/content/.morph/templates/tasks.md +257 -235
  158. package/content/.morph/templates/test.cs +239 -239
  159. package/content/.morph/templates/ui-components.md +362 -276
  160. package/content/.morph/templates/ui-design-system.md +286 -286
  161. package/content/.morph/templates/ui-flows.md +336 -336
  162. package/content/.morph/templates/ui-mockups.md +133 -133
  163. package/content/.morph/test-infra/example.bicep +59 -59
  164. package/content/CLAUDE.md +150 -442
  165. package/content/README.md +79 -79
  166. package/detectors/config-detector.js +223 -223
  167. package/detectors/conversation-analyzer.js +163 -163
  168. package/detectors/index.js +84 -84
  169. package/detectors/standards-generator.js +275 -275
  170. package/detectors/structure-detector.js +245 -250
  171. package/docs/README.md +144 -149
  172. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
  173. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
  174. package/docs/api/scripts/collapse.js +38 -38
  175. package/docs/api/scripts/commonNav.js +28 -28
  176. package/docs/api/scripts/linenumber.js +25 -25
  177. package/docs/api/scripts/nav.js +12 -12
  178. package/docs/api/scripts/polyfill.js +3 -3
  179. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
  180. package/docs/api/scripts/prettify/lang-css.js +2 -2
  181. package/docs/api/scripts/prettify/prettify.js +28 -28
  182. package/docs/api/scripts/search.js +98 -98
  183. package/docs/api/styles/jsdoc.css +776 -776
  184. package/docs/api/styles/prettify.css +80 -80
  185. package/docs/examples.md +328 -328
  186. package/docs/getting-started.md +301 -302
  187. package/docs/installation.md +361 -361
  188. package/docs/templates.md +418 -418
  189. package/docs/validation-checklist.md +265 -266
  190. package/package.json +80 -80
  191. package/scripts/postinstall.js +132 -132
  192. package/src/commands/advance-phase.js +183 -0
  193. package/src/commands/analyze-blazor-concurrency.js +193 -0
  194. package/src/commands/create-story.js +351 -351
  195. package/src/commands/detect-agents.js +139 -0
  196. package/src/commands/detect.js +104 -104
  197. package/src/commands/doctor.js +356 -280
  198. package/src/commands/generate.js +149 -149
  199. package/src/commands/init.js +258 -245
  200. package/src/commands/lint-fluent.js +352 -0
  201. package/src/commands/rollback-phase.js +185 -0
  202. package/src/commands/session-summary.js +291 -0
  203. package/src/commands/shard-spec.js +224 -224
  204. package/src/commands/sprint-status.js +250 -250
  205. package/src/commands/state.js +333 -333
  206. package/src/commands/sync.js +167 -167
  207. package/src/commands/task.js +78 -75
  208. package/src/commands/troubleshoot.js +222 -0
  209. package/src/commands/update.js +192 -159
  210. package/src/commands/validate-blazor-state.js +210 -0
  211. package/src/commands/validate-blazor.js +156 -0
  212. package/src/commands/validate-css.js +84 -0
  213. package/src/commands/validate-phase.js +221 -0
  214. package/src/lib/blazor-concurrency-analyzer.js +288 -0
  215. package/src/lib/blazor-state-validator.js +291 -0
  216. package/src/lib/blazor-validator.js +374 -0
  217. package/src/lib/complexity-analyzer.js +441 -292
  218. package/src/lib/continuous-validator.js +421 -440
  219. package/src/lib/css-validator.js +352 -0
  220. package/src/lib/decision-constraint-loader.js +109 -0
  221. package/src/lib/design-system-generator.js +298 -298
  222. package/src/lib/learning-system.js +520 -520
  223. package/src/lib/mockup-generator.js +366 -366
  224. package/src/lib/recap-generator.js +205 -0
  225. package/src/lib/state-manager.js +397 -340
  226. package/src/lib/troubleshoot-grep.js +194 -0
  227. package/src/lib/troubleshoot-index.js +144 -0
  228. package/src/lib/ui-detector.js +350 -350
  229. package/src/lib/validation-runner.js +231 -0
  230. package/src/lib/validators/architecture-validator.js +387 -387
  231. package/src/lib/validators/contract-compliance-validator.js +273 -0
  232. package/src/lib/validators/package-validator.js +360 -360
  233. package/src/lib/validators/ui-contrast-validator.js +422 -422
  234. package/src/utils/file-copier.js +179 -139
  235. package/src/utils/logger.js +32 -32
  236. package/src/utils/version-checker.js +175 -175
  237. package/content/.claude/commands/morph-costs.md +0 -206
  238. package/content/.claude/commands/morph-tasks.md +0 -319
  239. package/content/.claude/skills/specialists/cost-guardian.md +0 -110
  240. package/content/.claude/skills/stacks/shopify.md +0 -445
  241. package/content/.morph/config/azure-pricing.json +0 -70
  242. package/content/.morph/config/azure-pricing.schema.json +0 -50
  243. package/content/.morph/hooks/pre-commit-costs.sh +0 -91
  244. package/docs/api/cost-calculator.js.html +0 -513
  245. package/docs/api/design-system-generator.js.html +0 -382
  246. package/docs/api/global.html +0 -5263
  247. package/docs/api/index.html +0 -96
  248. package/docs/api/state-manager.js.html +0 -423
  249. package/src/commands/cost.js +0 -181
  250. package/src/commands/update-pricing.js +0 -206
  251. package/src/lib/cost-calculator.js +0 -429
package/bin/morph-spec.js CHANGED
@@ -1,294 +1,358 @@
1
- #!/usr/bin/env node
2
-
3
- import { program } from 'commander';
4
- import chalk from 'chalk';
5
- import { fileURLToPath } from 'url';
6
- import { dirname, join } from 'path';
7
- import { readFileSync } from 'fs';
8
-
9
- import { initCommand } from '../src/commands/init.js';
10
- import { updateCommand } from '../src/commands/update.js';
11
- import { doctorCommand } from '../src/commands/doctor.js';
12
- import { detectCommand } from '../src/commands/detect.js';
13
- import { syncCommand } from '../src/commands/sync.js';
14
- import { createStoryCommand } from '../src/commands/create-story.js';
15
- import { shardSpecCommand } from '../src/commands/shard-spec.js';
16
- import { sprintStatusCommand } from '../src/commands/sprint-status.js';
17
- import { stateCommand } from '../src/commands/state.js';
18
- import { taskDoneCommand, taskStartCommand, taskNextCommand } from '../src/commands/task.js';
19
- import { costCommand } from '../src/commands/cost.js';
20
- import { generateDesignSystemCommand } from '../src/commands/generate.js';
21
- import { updateResourcePricing, showPricing, validatePricing } from '../src/commands/update-pricing.js';
22
- import { validateCommand } from './validate.js';
23
- import { LearningSystem } from '../src/lib/learning-system.js';
24
-
25
- const __dirname = dirname(fileURLToPath(import.meta.url));
26
- const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
27
-
28
- const banner = chalk.cyan(`
29
- ███╗ ███╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗
30
- ████╗ ████║██╔═══██╗██╔══██╗██╔══██╗██║ ██║
31
- ██╔████╔██║██║ ██║██████╔╝██████╔╝███████║
32
- ██║╚██╔╝██║██║ ██║██╔══██╗██╔═══╝ ██╔══██║
33
- ██║ ╚═╝ ██║╚██████╔╝██║ ██║██║ ██║ ██║
34
- ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝
35
-
36
- Methodical Orchestration for Reliable Production-ready SPEC-driven development
37
- by Polymorphism Tech | v${pkg.version}
38
- `);
39
-
40
- program
41
- .name('morph-spec')
42
- .description('MORPH-SPEC Framework CLI')
43
- .version(pkg.version)
44
- .addHelpText('beforeAll', banner);
45
-
46
- program
47
- .command('init')
48
- .description('Initialize MORPH-SPEC in current directory')
49
- .option('-f, --force', 'Overwrite existing MORPH installation')
50
- .option('-p, --path <path>', 'Target path (default: current directory)')
51
- .action(initCommand);
52
-
53
- program
54
- .command('update')
55
- .description('Update MORPH templates and standards to latest version')
56
- .option('--templates', 'Update only templates')
57
- .option('--standards', 'Update only standards')
58
- .action(updateCommand);
59
-
60
- program
61
- .command('doctor')
62
- .description('Check MORPH installation health')
63
- .action(doctorCommand);
64
-
65
- program
66
- .command('detect')
67
- .description('Detect project stack, architecture, and patterns')
68
- .option('-p, --path <path>', 'Project path (default: current directory)')
69
- .option('-v, --verbose', 'Show detailed detection results')
70
- .option('--no-save', 'Do not save results to .morph/project/')
71
- .action(detectCommand);
72
-
73
- program
74
- .command('sync')
75
- .description('Sync standards from feature decisions')
76
- .option('-p, --path <path>', 'Project path (default: current directory)')
77
- .option('--dry-run', 'Show what would be synced without updating files')
78
- .action(syncCommand);
79
-
80
- // Story-driven development commands
81
- const storyCommand = program
82
- .command('story')
83
- .description('Story-driven development commands');
84
-
85
- storyCommand
86
- .command('create <feature> <story-id>')
87
- .description('Create a new story with auto-injected Dev Notes')
88
- .option('--title <title>', 'Story title')
89
- .option('--epic <epic>', 'Epic name')
90
- .option('--context <context>', 'Story context')
91
- .option('--tasks <tasks>', 'Comma-separated tasks')
92
- .option('--dry-run', 'Preview without writing file')
93
- .action(createStoryCommand);
94
-
95
- storyCommand
96
- .command('shard <feature>')
97
- .description('Shard spec.md into manageable chunks (90% token savings)')
98
- .option('--dry-run', 'Preview shards without writing files')
99
- .option('--verbose', 'Show detailed shard info')
100
- .action(shardSpecCommand);
101
-
102
- storyCommand
103
- .command('status <feature> [action] [story-id]')
104
- .description('Manage sprint status (show | start | qa | done | next)')
105
- .action(sprintStatusCommand);
106
-
107
- // State management commands
108
- program
109
- .command('state <action> [args...]')
110
- .description('Manage state.json (init | get | set | checkpoint | list | add-agent | remove-agent | mark-output)')
111
- .option('--force', 'Force overwrite (init command)')
112
- .option('--project <name>', 'Project name (init command)')
113
- .option('--type <type>', 'Project type (init command)')
114
- .option('--json', 'Output as JSON (get command)')
115
- .action((action, args, options) => stateCommand(action, args, options));
116
-
117
- // Task management commands (MORPH-SPEC 3.0)
118
- const taskCommand = program
119
- .command('task')
120
- .description('Manage feature tasks (done | start | next)');
121
-
122
- taskCommand
123
- .command('done <feature> <task-ids...>')
124
- .description('Mark tasks as completed')
125
- .action((feature, taskIds, options) => taskDoneCommand(feature, taskIds, options));
126
-
127
- taskCommand
128
- .command('start <feature> <task-id>')
129
- .description('Start a task (mark as in_progress)')
130
- .action((feature, taskId, options) => taskStartCommand(feature, taskId, options));
131
-
132
- taskCommand
133
- .command('next <feature>')
134
- .description('Show next suggested task')
135
- .action((feature, options) => taskNextCommand(feature, options));
136
-
137
- // Cost calculation command
138
- program
139
- .command('cost <bicep-files>')
140
- .description('Calculate Azure infrastructure costs from Bicep files')
141
- .option('--config <path>', 'Custom config path')
142
- .option('--verbose', 'Show detailed breakdown')
143
- .option('--json', 'Output as JSON')
144
- .option('--strict', 'Exit with error if cost exceeds ADR threshold')
145
- .action(costCommand);
146
-
147
- // Pricing management commands
148
- const pricingCommand = program
149
- .command('pricing')
150
- .description('Manage Azure pricing table');
151
-
152
- pricingCommand
153
- .command('show [resource-type]')
154
- .description('Show current pricing (all or specific resource type)')
155
- .option('--json', 'Output as JSON')
156
- .action((resourceType, options) => showPricing({ resourceType, format: options.json ? 'json' : 'table' }));
157
-
158
- pricingCommand
159
- .command('update <resource-type> <sku> <price>')
160
- .description('Update pricing for a specific SKU')
161
- .option('--dry-run', 'Preview without saving')
162
- .option('--no-validate', 'Skip validation')
163
- .action((resourceType, sku, price, options) =>
164
- updateResourcePricing({
165
- resourceType,
166
- sku,
167
- price: parseFloat(price),
168
- dryRun: options.dryRun,
169
- validate: options.validate !== false
170
- })
171
- );
172
-
173
- pricingCommand
174
- .command('validate')
175
- .description('Validate pricing file against JSON schema')
176
- .action(validatePricing);
177
-
178
- // Generation commands
179
- const generateCommand = program
180
- .command('generate')
181
- .description('Generate code from templates');
182
-
183
- generateCommand
184
- .command('design-system <ui-design-system-md>')
185
- .description('Generate CSS + theme files from ui-design-system.md')
186
- .option('--fluent', 'Generate only Fluent UI theme')
187
- .option('--mud', 'Generate only MudBlazor theme')
188
- .option('--both', 'Generate both themes (default)')
189
- .option('--namespace <ns>', 'C# namespace (default: YourProject.Themes)')
190
- .option('--css-output <path>', 'CSS output path (default: wwwroot/css/design-system.css)')
191
- .option('--fluent-output <path>', 'Fluent theme output path (default: Themes/FluentDesignTheme.cs)')
192
- .option('--mud-output <path>', 'MudBlazor theme output path (default: Themes/MudDesignTheme.cs)')
193
- .option('--dry-run', 'Preview without writing files')
194
- .action(generateDesignSystemCommand);
195
-
196
- // Validation commands (Sprint 4: Continuous Validation)
197
- program
198
- .command('validate [validator]')
199
- .description('Run project validations (all | packages | architecture | contrast)')
200
- .option('-v, --verbose', 'Show detailed output')
201
- .option('--auto-fix, --fix', 'Auto-fix issues where possible')
202
- .option('--no-fail', 'Don\'t exit with error code')
203
- .option('-i, --insights', 'Show learning insights')
204
- .option('--wcag-aaa', 'Use WCAG AAA standard (stricter)')
205
- .action((validator, options) => {
206
- const args = validator ? [validator] : ['all'];
207
- if (options.verbose) args.push('--verbose');
208
- if (options.autoFix) args.push('--auto-fix');
209
- if (options.noFail) args.push('--no-fail');
210
- if (options.insights) args.push('--insights');
211
- if (options.wcagAaa) args.push('--wcag-aaa');
212
- validateCommand(args);
213
- });
214
-
215
- // Learning commands (Sprint 4: Learning System)
216
- const learnCommand = program
217
- .command('learn')
218
- .description('AI learning system commands');
219
-
220
- learnCommand
221
- .command('analyze')
222
- .description('Learn from project history (decisions.md files)')
223
- .option('-v, --verbose', 'Show detailed learning progress')
224
- .action(async (options) => {
225
- const learner = new LearningSystem('.');
226
- await learner.learnFromProject();
227
-
228
- if (options.verbose) {
229
- learner.formatInsights();
230
- }
231
- });
232
-
233
- learnCommand
234
- .command('insights')
235
- .description('Show AI insights and patterns')
236
- .option('--json', 'Output as JSON')
237
- .action((options) => {
238
- const learner = new LearningSystem('.');
239
-
240
- if (options.json) {
241
- console.log(JSON.stringify(learner.getInsightsSummary(), null, 2));
242
- } else {
243
- learner.formatInsights();
244
- }
245
- });
246
-
247
- learnCommand
248
- .command('suggest [category]')
249
- .description('Get AI suggestions for a category (uiLibrary | architecture | infrastructure | authentication | stateManagement | testing)')
250
- .option('--json', 'Output as JSON')
251
- .action((category, options) => {
252
- const learner = new LearningSystem('.');
253
-
254
- if (category) {
255
- const suggestion = learner.getSuggestion(category);
256
- if (options.json) {
257
- console.log(JSON.stringify(suggestion, null, 2));
258
- } else {
259
- console.log(chalk.cyan(`\n💡 Suggestion for ${category}:\n`));
260
- if (suggestion.confidence === 'none') {
261
- console.log(chalk.yellow(` ${suggestion.reason}`));
262
- } else {
263
- console.log(chalk.white(` → ${suggestion.suggestion} (${suggestion.percentage}% confidence)`));
264
- console.log(chalk.gray(` ${suggestion.reason}`));
265
- }
266
- console.log('');
267
- }
268
- } else {
269
- const suggestions = learner.getAllSuggestions();
270
- if (options.json) {
271
- console.log(JSON.stringify(suggestions, null, 2));
272
- } else {
273
- learner.formatSuggestions(suggestions);
274
- }
275
- }
276
- });
277
-
278
- learnCommand
279
- .command('reset')
280
- .description('Reset knowledge base (clear all learned patterns)')
281
- .option('--force', 'Skip confirmation')
282
- .action((options) => {
283
- if (!options.force) {
284
- console.log(chalk.yellow('\n⚠️ This will delete all learned patterns and preferences.'));
285
- console.log(chalk.gray(' Run with --force to confirm.\n'));
286
- process.exit(1);
287
- }
288
-
289
- const learner = new LearningSystem('.');
290
- learner.reset();
291
- console.log(chalk.green('\n✅ Knowledge base reset\n'));
292
- });
293
-
294
- program.parse();
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from 'commander';
4
+ import chalk from 'chalk';
5
+ import { fileURLToPath } from 'url';
6
+ import { dirname, join } from 'path';
7
+ import { readFileSync } from 'fs';
8
+
9
+ import { initCommand } from '../src/commands/init.js';
10
+ import { updateCommand } from '../src/commands/update.js';
11
+ import { doctorCommand } from '../src/commands/doctor.js';
12
+ import { detectCommand } from '../src/commands/detect.js';
13
+ import { detectAgentsCommand } from '../src/commands/detect-agents.js';
14
+ import { syncCommand } from '../src/commands/sync.js';
15
+ import { createStoryCommand } from '../src/commands/create-story.js';
16
+ import { shardSpecCommand } from '../src/commands/shard-spec.js';
17
+ import { sprintStatusCommand } from '../src/commands/sprint-status.js';
18
+ import { stateCommand } from '../src/commands/state.js';
19
+ import { taskDoneCommand, taskStartCommand, taskNextCommand } from '../src/commands/task.js';
20
+ import { generateDesignSystemCommand } from '../src/commands/generate.js';
21
+ import { validateCommand } from './validate.js';
22
+ import { validateBlazorCommand } from '../src/commands/validate-blazor.js';
23
+ import { lintFluentCommand } from '../src/commands/lint-fluent.js';
24
+ import { analyzeBlazorConcurrencyCommand } from '../src/commands/analyze-blazor-concurrency.js';
25
+ import { validateBlazorStateCommand } from '../src/commands/validate-blazor-state.js';
26
+ import { validateCssCommand } from '../src/commands/validate-css.js';
27
+ import { LearningSystem } from '../src/lib/learning-system.js';
28
+ import troubleshootCommand from '../src/commands/troubleshoot.js';
29
+ import { validatePhaseCommand } from '../src/commands/validate-phase.js';
30
+ import { sessionSummaryCommand } from '../src/commands/session-summary.js';
31
+ import { rollbackPhaseCommand } from '../src/commands/rollback-phase.js';
32
+ import { advancePhaseCommand } from '../src/commands/advance-phase.js';
33
+
34
+ const __dirname = dirname(fileURLToPath(import.meta.url));
35
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
36
+
37
+ const banner = chalk.cyan(`
38
+ ███╗ ███╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗
39
+ ████╗ ████║██╔═══██╗██╔══██╗██╔══██╗██║ ██║
40
+ ██╔████╔██║██║ ██║██████╔╝██████╔╝███████║
41
+ ██║╚██╔╝██║██║ ██║██╔══██╗██╔═══╝ ██╔══██║
42
+ ██║ ╚═╝ ██║╚██████╔╝██║ ██║██║ ██║ ██║
43
+ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝
44
+
45
+ Methodical Orchestration for Reliable Production-ready SPEC-driven development
46
+ by Polymorphism Tech | v${pkg.version}
47
+ `);
48
+
49
+ program
50
+ .name('morph-spec')
51
+ .description('MORPH-SPEC Framework CLI')
52
+ .version(pkg.version)
53
+ .addHelpText('beforeAll', banner);
54
+
55
+ program
56
+ .command('init')
57
+ .description('Initialize MORPH-SPEC in current directory')
58
+ .option('-f, --force', 'Overwrite existing MORPH installation')
59
+ .option('-p, --path <path>', 'Target path (default: current directory)')
60
+ .action(initCommand);
61
+
62
+ program
63
+ .command('update')
64
+ .description('Update MORPH templates and standards to latest version')
65
+ .option('--templates', 'Update only templates')
66
+ .option('--standards', 'Update only standards')
67
+ .action(updateCommand);
68
+
69
+ program
70
+ .command('doctor')
71
+ .description('Check MORPH installation health')
72
+ .action(doctorCommand);
73
+
74
+ program
75
+ .command('detect')
76
+ .description('Detect project stack, architecture, and patterns')
77
+ .option('-p, --path <path>', 'Project path (default: current directory)')
78
+ .option('-v, --verbose', 'Show detailed detection results')
79
+ .option('--no-save', 'Do not save results to .morph/project/')
80
+ .action(detectCommand);
81
+
82
+ program
83
+ .command('detect-agents <input...>')
84
+ .description('Detect which agents to activate based on keywords in user input')
85
+ .option('-v, --verbose', 'Show detailed detection results')
86
+ .option('-j, --json', 'Output full result as JSON')
87
+ .option('-i, --ids-only', 'Output only agent IDs (one per line)')
88
+ .action(detectAgentsCommand);
89
+
90
+ program
91
+ .command('sync')
92
+ .description('Sync standards from feature decisions')
93
+ .option('-p, --path <path>', 'Project path (default: current directory)')
94
+ .option('--dry-run', 'Show what would be synced without updating files')
95
+ .action(syncCommand);
96
+
97
+ // Story-driven development commands
98
+ const storyCommand = program
99
+ .command('story')
100
+ .description('Story-driven development commands');
101
+
102
+ storyCommand
103
+ .command('create <feature> <story-id>')
104
+ .description('Create a new story with auto-injected Dev Notes')
105
+ .option('--title <title>', 'Story title')
106
+ .option('--epic <epic>', 'Epic name')
107
+ .option('--context <context>', 'Story context')
108
+ .option('--tasks <tasks>', 'Comma-separated tasks')
109
+ .option('--dry-run', 'Preview without writing file')
110
+ .action(createStoryCommand);
111
+
112
+ storyCommand
113
+ .command('shard <feature>')
114
+ .description('Shard spec.md into manageable chunks (90% token savings)')
115
+ .option('--dry-run', 'Preview shards without writing files')
116
+ .option('--verbose', 'Show detailed shard info')
117
+ .action(shardSpecCommand);
118
+
119
+ storyCommand
120
+ .command('status <feature> [action] [story-id]')
121
+ .description('Manage sprint status (show | start | qa | done | next)')
122
+ .action(sprintStatusCommand);
123
+
124
+ // State management commands
125
+ program
126
+ .command('state <action> [args...]')
127
+ .description('Manage state.json (init | get | set | checkpoint | list | add-agent | remove-agent | mark-output)')
128
+ .option('--force', 'Force overwrite (init command)')
129
+ .option('--project <name>', 'Project name (init command)')
130
+ .option('--type <type>', 'Project type (init command)')
131
+ .option('--json', 'Output as JSON (get command)')
132
+ .action((action, args, options) => stateCommand(action, args, options));
133
+
134
+ // Task management commands (MORPH-SPEC 3.0)
135
+ const taskCommand = program
136
+ .command('task')
137
+ .description('Manage feature tasks (done | start | next)');
138
+
139
+ taskCommand
140
+ .command('done <feature> <task-ids...>')
141
+ .description('Mark tasks as completed (runs validation first)')
142
+ .option('--skip-validation', 'Skip code validation (not recommended)')
143
+ .action((feature, taskIds, options) => taskDoneCommand(feature, taskIds, options));
144
+
145
+ taskCommand
146
+ .command('start <feature> <task-id>')
147
+ .description('Start a task (mark as in_progress)')
148
+ .action((feature, taskId, options) => taskStartCommand(feature, taskId, options));
149
+
150
+ taskCommand
151
+ .command('next <feature>')
152
+ .description('Show next suggested task')
153
+ .action((feature, options) => taskNextCommand(feature, options));
154
+
155
+ // Generation commands
156
+ const generateCommand = program
157
+ .command('generate')
158
+ .description('Generate code from templates');
159
+
160
+ generateCommand
161
+ .command('design-system <ui-design-system-md>')
162
+ .description('Generate CSS + theme files from ui-design-system.md')
163
+ .option('--fluent', 'Generate only Fluent UI theme')
164
+ .option('--mud', 'Generate only MudBlazor theme')
165
+ .option('--both', 'Generate both themes (default)')
166
+ .option('--namespace <ns>', 'C# namespace (default: YourProject.Themes)')
167
+ .option('--css-output <path>', 'CSS output path (default: wwwroot/css/design-system.css)')
168
+ .option('--fluent-output <path>', 'Fluent theme output path (default: Themes/FluentDesignTheme.cs)')
169
+ .option('--mud-output <path>', 'MudBlazor theme output path (default: Themes/MudDesignTheme.cs)')
170
+ .option('--dry-run', 'Preview without writing files')
171
+ .action(generateDesignSystemCommand);
172
+
173
+ generateCommand
174
+ .command('recap <feature>')
175
+ .description('Auto-generate recap.md from project data (state, validation, contracts)')
176
+ .option('--quiet', 'Suppress output')
177
+ .action(async (feature, options) => {
178
+ const { generateRecap } = await import('../src/lib/recap-generator.js');
179
+ await generateRecap('.', feature, options);
180
+ });
181
+
182
+ // Validation commands (Sprint 4: Continuous Validation)
183
+ program
184
+ .command('validate [validator]')
185
+ .description('Run project validations (all | packages | architecture | contrast)')
186
+ .option('-v, --verbose', 'Show detailed output')
187
+ .option('--auto-fix, --fix', 'Auto-fix issues where possible')
188
+ .option('--no-fail', 'Don\'t exit with error code')
189
+ .option('-i, --insights', 'Show learning insights')
190
+ .option('--wcag-aaa', 'Use WCAG AAA standard (stricter)')
191
+ .action((validator, options) => {
192
+ const args = validator ? [validator] : ['all'];
193
+ if (options.verbose) args.push('--verbose');
194
+ if (options.autoFix) args.push('--auto-fix');
195
+ if (options.noFail) args.push('--no-fail');
196
+ if (options.insights) args.push('--insights');
197
+ if (options.wcagAaa) args.push('--wcag-aaa');
198
+ validateCommand(args);
199
+ });
200
+
201
+ // Fluent UI Blazor validation commands
202
+ program
203
+ .command('validate-blazor [path]')
204
+ .description('Validate Fluent UI Blazor patterns and icons')
205
+ .option('-v, --verbose', 'Show detailed output')
206
+ .option('--fix', 'Auto-fix issues where possible')
207
+ .action(validateBlazorCommand);
208
+
209
+ program
210
+ .command('lint-fluent [path]')
211
+ .description('Lint Fluent UI patterns for common issues')
212
+ .option('-v, --verbose', 'Show detailed output')
213
+ .action(lintFluentCommand);
214
+
215
+ program
216
+ .command('analyze-blazor-concurrency [path]')
217
+ .description('Analyze Blazor Server code for DbContext concurrency issues')
218
+ .option('-v, --verbose', 'Show detailed output')
219
+ .action(analyzeBlazorConcurrencyCommand);
220
+
221
+ program
222
+ .command('validate-blazor-state [path]')
223
+ .description('Validate Blazor Server session state patterns')
224
+ .option('-v, --verbose', 'Show detailed output')
225
+ .action(validateBlazorStateCommand);
226
+
227
+ program
228
+ .command('validate-css [path]')
229
+ .description('Validate CSS classes used in Razor files exist in CSS files')
230
+ .option('-v, --verbose', 'Show detailed output')
231
+ .option('--generate-stub', 'Generate a CSS stub file with missing classes')
232
+ .option('--include-utilities', 'Include utility classes (Tailwind, Bootstrap) in validation')
233
+ .action(validateCssCommand);
234
+
235
+ // Learning commands (Sprint 4: Learning System)
236
+ const learnCommand = program
237
+ .command('learn')
238
+ .description('AI learning system commands');
239
+
240
+ learnCommand
241
+ .command('analyze')
242
+ .description('Learn from project history (decisions.md files)')
243
+ .option('-v, --verbose', 'Show detailed learning progress')
244
+ .action(async (options) => {
245
+ const learner = new LearningSystem('.');
246
+ await learner.learnFromProject();
247
+
248
+ if (options.verbose) {
249
+ learner.formatInsights();
250
+ }
251
+ });
252
+
253
+ learnCommand
254
+ .command('insights')
255
+ .description('Show AI insights and patterns')
256
+ .option('--json', 'Output as JSON')
257
+ .action((options) => {
258
+ const learner = new LearningSystem('.');
259
+
260
+ if (options.json) {
261
+ console.log(JSON.stringify(learner.getInsightsSummary(), null, 2));
262
+ } else {
263
+ learner.formatInsights();
264
+ }
265
+ });
266
+
267
+ learnCommand
268
+ .command('suggest [category]')
269
+ .description('Get AI suggestions for a category (uiLibrary | architecture | infrastructure | authentication | stateManagement | testing)')
270
+ .option('--json', 'Output as JSON')
271
+ .action((category, options) => {
272
+ const learner = new LearningSystem('.');
273
+
274
+ if (category) {
275
+ const suggestion = learner.getSuggestion(category);
276
+ if (options.json) {
277
+ console.log(JSON.stringify(suggestion, null, 2));
278
+ } else {
279
+ console.log(chalk.cyan(`\n💡 Suggestion for ${category}:\n`));
280
+ if (suggestion.confidence === 'none') {
281
+ console.log(chalk.yellow(` ${suggestion.reason}`));
282
+ } else {
283
+ console.log(chalk.white(` → ${suggestion.suggestion} (${suggestion.percentage}% confidence)`));
284
+ console.log(chalk.gray(` ${suggestion.reason}`));
285
+ }
286
+ console.log('');
287
+ }
288
+ } else {
289
+ const suggestions = learner.getAllSuggestions();
290
+ if (options.json) {
291
+ console.log(JSON.stringify(suggestions, null, 2));
292
+ } else {
293
+ learner.formatSuggestions(suggestions);
294
+ }
295
+ }
296
+ });
297
+
298
+ learnCommand
299
+ .command('reset')
300
+ .description('Reset knowledge base (clear all learned patterns)')
301
+ .option('--force', 'Skip confirmation')
302
+ .action((options) => {
303
+ if (!options.force) {
304
+ console.log(chalk.yellow('\n⚠️ This will delete all learned patterns and preferences.'));
305
+ console.log(chalk.gray(' Run with --force to confirm.\n'));
306
+ process.exit(1);
307
+ }
308
+
309
+ const learner = new LearningSystem('.');
310
+ learner.reset();
311
+ console.log(chalk.green('\n✅ Knowledge base reset\n'));
312
+ });
313
+
314
+ // Troubleshooting command
315
+ program
316
+ .command('troubleshoot <keywords...>')
317
+ .alias('ts')
318
+ .description('Search troubleshooting solutions for common errors')
319
+ .option('--category <cat>', 'Filter by category (blazor, efcore, azure, auth, deploy)')
320
+ .option('-v, --verbose', 'Show full solution content')
321
+ .option('--list-categories', 'List available categories')
322
+ .action(troubleshootCommand);
323
+
324
+ // Phase management commands
325
+ const phaseCommand = program
326
+ .command('phase')
327
+ .description('Phase management (advance | validate)');
328
+
329
+ phaseCommand
330
+ .command('advance <feature>')
331
+ .description('Validate current phase and advance to next')
332
+ .option('--skip-optional', 'Skip optional phases (uiux, sync)')
333
+ .action((feature, options) => advancePhaseCommand(feature, options));
334
+
335
+ // Phase validation command (also available as standalone)
336
+ program
337
+ .command('validate-phase <feature> <phase>')
338
+ .description('Validate prerequisites before advancing to a phase')
339
+ .option('-v, --verbose', 'Show detailed output')
340
+ .action(validatePhaseCommand);
341
+
342
+ // Session summary command
343
+ program
344
+ .command('session-summary <feature>')
345
+ .alias('summary')
346
+ .description('Show summary of current session (phases, decisions, progress)')
347
+ .option('--json', 'Output as JSON')
348
+ .action(sessionSummaryCommand);
349
+
350
+ // Rollback phase command
351
+ program
352
+ .command('rollback <feature> <phase>')
353
+ .description('Rollback feature to a previous phase (marks outputs as draft)')
354
+ .option('--force', 'Skip confirmation')
355
+ .option('-v, --verbose', 'Show detailed output')
356
+ .action(rollbackPhaseCommand);
357
+
358
+ program.parse();