@polymorphism-tech/morph-spec 1.0.4 → 2.0.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 (152) hide show
  1. package/CLAUDE.md +1381 -0
  2. package/LICENSE +72 -0
  3. package/README.md +89 -6
  4. package/bin/detect-agents.js +225 -0
  5. package/bin/morph-spec.js +120 -0
  6. package/bin/render-template.js +302 -0
  7. package/bin/semantic-detect-agents.js +246 -0
  8. package/bin/validate-agents-skills.js +239 -0
  9. package/bin/validate-agents.js +69 -0
  10. package/bin/validate-phase.js +263 -0
  11. package/content/.azure/README.md +293 -0
  12. package/content/.azure/docs/azure-devops-setup.md +454 -0
  13. package/content/.azure/docs/branch-strategy.md +398 -0
  14. package/content/.azure/docs/local-development.md +515 -0
  15. package/content/.azure/pipelines/pipeline-variables.yml +34 -0
  16. package/content/.azure/pipelines/prod-pipeline.yml +319 -0
  17. package/content/.azure/pipelines/staging-pipeline.yml +234 -0
  18. package/content/.azure/pipelines/templates/build-dotnet.yml +75 -0
  19. package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -0
  20. package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -0
  21. package/content/.azure/pipelines/templates/infra-deploy.yml +90 -0
  22. package/content/.claude/commands/morph-apply.md +118 -26
  23. package/content/.claude/commands/morph-archive.md +9 -9
  24. package/content/.claude/commands/morph-clarify.md +184 -0
  25. package/content/.claude/commands/morph-design.md +275 -0
  26. package/content/.claude/commands/morph-proposal.md +56 -15
  27. package/content/.claude/commands/morph-setup.md +100 -0
  28. package/content/.claude/commands/morph-status.md +47 -32
  29. package/content/.claude/commands/morph-tasks.md +319 -0
  30. package/content/.claude/commands/morph-uiux.md +211 -0
  31. package/content/.claude/skills/specialists/ai-system-architect.md +604 -0
  32. package/content/.claude/skills/specialists/ms-agent-expert.md +143 -89
  33. package/content/.claude/skills/specialists/ui-ux-designer.md +744 -9
  34. package/content/.claude/skills/stacks/dotnet-blazor.md +244 -8
  35. package/content/.claude/skills/stacks/dotnet-nextjs.md +2 -2
  36. package/content/.morph/.morphversion +5 -0
  37. package/content/.morph/config/agents.json +101 -8
  38. package/content/.morph/config/azure-pricing.json +70 -0
  39. package/content/.morph/config/azure-pricing.schema.json +50 -0
  40. package/content/.morph/config/config.template.json +15 -3
  41. package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -0
  42. package/content/.morph/hooks/README.md +239 -0
  43. package/content/.morph/hooks/pre-commit-agents.sh +24 -0
  44. package/content/.morph/hooks/pre-commit-all.sh +48 -0
  45. package/content/.morph/hooks/pre-commit-costs.sh +91 -0
  46. package/content/.morph/hooks/pre-commit-specs.sh +49 -0
  47. package/content/.morph/hooks/pre-commit-tests.sh +60 -0
  48. package/content/.morph/project.md +5 -4
  49. package/content/.morph/schemas/agent.schema.json +296 -0
  50. package/content/.morph/standards/agent-framework-setup.md +453 -0
  51. package/content/.morph/standards/architecture.md +142 -7
  52. package/content/.morph/standards/azure.md +218 -23
  53. package/content/.morph/standards/coding.md +47 -12
  54. package/content/.morph/standards/dotnet10-migration.md +494 -0
  55. package/content/.morph/standards/fluent-ui-setup.md +590 -0
  56. package/content/.morph/standards/migration-guide.md +514 -0
  57. package/content/.morph/standards/passkeys-auth.md +423 -0
  58. package/content/.morph/standards/vector-search-rag.md +536 -0
  59. package/content/.morph/state.json +18 -0
  60. package/content/.morph/templates/FluentDesignTheme.cs +149 -0
  61. package/content/.morph/templates/MudTheme.cs +281 -0
  62. package/content/.morph/templates/contracts.cs +55 -55
  63. package/content/.morph/templates/decisions.md +4 -4
  64. package/content/.morph/templates/design-system.css +226 -0
  65. package/content/.morph/templates/infra/.dockerignore.example +89 -0
  66. package/content/.morph/templates/infra/Dockerfile.example +82 -0
  67. package/content/.morph/templates/infra/README.md +286 -0
  68. package/content/.morph/templates/infra/app-service.bicep +164 -0
  69. package/content/.morph/templates/infra/deploy.ps1 +229 -0
  70. package/content/.morph/templates/infra/deploy.sh +208 -0
  71. package/content/.morph/templates/infra/main.bicep +41 -7
  72. package/content/.morph/templates/infra/parameters.dev.json +6 -0
  73. package/content/.morph/templates/infra/parameters.prod.json +6 -0
  74. package/content/.morph/templates/infra/parameters.staging.json +29 -0
  75. package/content/.morph/templates/proposal.md +3 -3
  76. package/content/.morph/templates/recap.md +3 -3
  77. package/content/.morph/templates/spec.md +9 -8
  78. package/content/.morph/templates/sprint-status.yaml +68 -0
  79. package/content/.morph/templates/state.template.json +222 -0
  80. package/content/.morph/templates/story.md +143 -0
  81. package/content/.morph/templates/tasks.md +1 -1
  82. package/content/.morph/templates/ui-components.md +276 -0
  83. package/content/.morph/templates/ui-design-system.md +286 -0
  84. package/content/.morph/templates/ui-flows.md +336 -0
  85. package/content/.morph/templates/ui-mockups.md +133 -0
  86. package/content/.morph/test-infra/example.bicep +59 -0
  87. package/content/CLAUDE.md +124 -0
  88. package/content/README.md +79 -0
  89. package/detectors/config-detector.js +223 -0
  90. package/detectors/conversation-analyzer.js +163 -0
  91. package/detectors/index.js +84 -0
  92. package/detectors/standards-generator.js +275 -0
  93. package/detectors/structure-detector.js +221 -0
  94. package/docs/README.md +149 -0
  95. package/docs/api/cost-calculator.js.html +513 -0
  96. package/docs/api/design-system-generator.js.html +382 -0
  97. package/docs/api/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  98. package/docs/api/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  99. package/docs/api/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  100. package/docs/api/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  101. package/docs/api/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  102. package/docs/api/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  103. package/docs/api/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  104. package/docs/api/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  105. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  106. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  107. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  108. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  109. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  110. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  111. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  112. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  113. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  114. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  115. package/docs/api/global.html +5263 -0
  116. package/docs/api/index.html +96 -0
  117. package/docs/api/scripts/collapse.js +39 -0
  118. package/docs/api/scripts/commonNav.js +28 -0
  119. package/docs/api/scripts/linenumber.js +25 -0
  120. package/docs/api/scripts/nav.js +12 -0
  121. package/docs/api/scripts/polyfill.js +4 -0
  122. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
  123. package/docs/api/scripts/prettify/lang-css.js +2 -0
  124. package/docs/api/scripts/prettify/prettify.js +28 -0
  125. package/docs/api/scripts/search.js +99 -0
  126. package/docs/api/state-manager.js.html +423 -0
  127. package/docs/api/styles/jsdoc.css +776 -0
  128. package/docs/api/styles/prettify.css +80 -0
  129. package/docs/examples.md +328 -0
  130. package/docs/getting-started.md +302 -0
  131. package/docs/installation.md +361 -0
  132. package/docs/templates.md +418 -0
  133. package/docs/validation-checklist.md +266 -0
  134. package/package.json +39 -12
  135. package/src/commands/cost.js +181 -0
  136. package/src/commands/create-story.js +283 -0
  137. package/src/commands/detect.js +104 -0
  138. package/src/commands/doctor.js +67 -0
  139. package/src/commands/generate.js +149 -0
  140. package/src/commands/init.js +69 -45
  141. package/src/commands/shard-spec.js +224 -0
  142. package/src/commands/sprint-status.js +250 -0
  143. package/src/commands/state.js +333 -0
  144. package/src/commands/sync.js +167 -0
  145. package/src/commands/update-pricing.js +206 -0
  146. package/src/commands/update.js +88 -13
  147. package/src/lib/complexity-analyzer.js +292 -0
  148. package/src/lib/cost-calculator.js +429 -0
  149. package/src/lib/design-system-generator.js +298 -0
  150. package/src/lib/state-manager.js +340 -0
  151. package/src/utils/file-copier.js +59 -0
  152. package/src/utils/version-checker.js +175 -0
package/LICENSE ADDED
@@ -0,0 +1,72 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2024-2025 Polymorphism Tech
4
+ All rights reserved.
5
+
6
+ MORPH-SPEC Framework - Proprietary Software License
7
+
8
+ 1. GRANT OF LICENSE
9
+
10
+ Subject to the terms and conditions of this License, Polymorphism Tech ("Licensor")
11
+ grants you a limited, non-exclusive, non-transferable license to:
12
+
13
+ a) Install and use the MORPH-SPEC CLI tool for personal or commercial projects
14
+ b) Use the generated templates and code in your own projects
15
+ c) Modify generated code for your specific use cases
16
+
17
+ 2. RESTRICTIONS
18
+
19
+ You may NOT:
20
+
21
+ a) Redistribute, sell, lease, or sublicense the MORPH-SPEC framework itself
22
+ b) Modify, decompile, reverse engineer, or create derivative works of the framework
23
+ c) Remove or modify any copyright notices or proprietary markings
24
+ d) Use the framework to create competing products or services
25
+ e) Publicly fork or redistribute the source code
26
+ f) Share access credentials to private repositories
27
+
28
+ 3. OWNERSHIP
29
+
30
+ The MORPH-SPEC framework, including all code, documentation, templates, and
31
+ associated materials, remains the exclusive property of Polymorphism Tech.
32
+
33
+ 4. GENERATED CODE
34
+
35
+ Code and projects generated using MORPH-SPEC are yours to use, modify, and
36
+ distribute as you see fit, including commercial use.
37
+
38
+ 5. SUPPORT AND UPDATES
39
+
40
+ - CLI tool updates are provided via npm registry
41
+ - Support is available at: support@polymorphism.tech
42
+ - Documentation updates are included with each release
43
+
44
+ 6. WARRANTY DISCLAIMER
45
+
46
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
49
+
50
+ 7. LIMITATION OF LIABILITY
51
+
52
+ IN NO EVENT SHALL POLYMORPHISM TECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55
+ SOFTWARE.
56
+
57
+ 8. TERMINATION
58
+
59
+ This license is effective until terminated. Your rights under this license will
60
+ terminate automatically without notice if you fail to comply with any term of
61
+ this license.
62
+
63
+ 9. CONTACT
64
+
65
+ For licensing inquiries, custom licenses, or commercial support:
66
+ Email: contact@polymorphism.com.br
67
+ Website: https://polymorphism.com.br
68
+
69
+ ---
70
+
71
+ MORPH-SPEC v2.0.0
72
+ by Polymorphism Tech
package/README.md CHANGED
@@ -19,6 +19,13 @@
19
19
  <a href="docs/">Documentação</a>
20
20
  </p>
21
21
 
22
+ <p align="center">
23
+ <strong>📚 Guias de Uso:</strong>
24
+ <a href="QUICKSTART.md">Quick Start</a> •
25
+ <a href="CHEATSHEET.md">Cheat Sheet</a> •
26
+ <a href="docs/README.md">API Docs</a>
27
+ </p>
28
+
22
29
  ---
23
30
 
24
31
  ## O que é MORPH-SPEC?
@@ -86,8 +93,10 @@ npx @polymorphism-tech/morph-spec init
86
93
  |---------|-----------|
87
94
  | `morph-spec init` | Inicializa MORPH no diretório atual |
88
95
  | `morph-spec init --force` | Sobrescreve instalação existente |
89
- | `morph-spec update` | Atualiza templates e standards |
90
- | `morph-spec doctor` | Verifica saúde da instalação |
96
+ | `morph-spec update` | Atualiza projeto para versão mais recente |
97
+ | `morph-spec update --templates` | Atualiza apenas templates |
98
+ | `morph-spec update --standards` | Atualiza apenas standards |
99
+ | `morph-spec doctor` | Verifica saúde e versões da instalação |
91
100
 
92
101
  ### Verificar Instalação
93
102
 
@@ -95,6 +104,11 @@ npx @polymorphism-tech/morph-spec init
95
104
  morph-spec doctor
96
105
  ```
97
106
 
107
+ O comando `doctor` verifica:
108
+ - ✓ Versão do CLI (se está atualizada)
109
+ - ✓ Versão do MORPH no projeto
110
+ - ✓ Estrutura de arquivos e configurações
111
+
98
112
  Ou abra seu projeto no Claude Code e execute:
99
113
  ```
100
114
  /morph-status
@@ -102,6 +116,48 @@ Ou abra seu projeto no Claude Code e execute:
102
116
 
103
117
  ---
104
118
 
119
+ ## Mantendo Atualizado
120
+
121
+ ### 1. Verificar se há atualizações
122
+
123
+ ```bash
124
+ morph-spec doctor
125
+ ```
126
+
127
+ Isso mostrará se há versões mais recentes disponíveis.
128
+
129
+ ### 2. Atualizar para a versão mais recente
130
+
131
+ **Instalação Global:**
132
+ ```bash
133
+ # Primeiro, atualize o CLI
134
+ npm install -g @polymorphism-tech/morph-spec@latest
135
+
136
+ # Depois, atualize seu projeto
137
+ cd /caminho/do/seu/projeto
138
+ morph-spec update
139
+ ```
140
+
141
+ **Usando npx (Recomendado - sempre pega a versão mais recente):**
142
+ ```bash
143
+ cd /caminho/do/seu/projeto
144
+ npx @polymorphism-tech/morph-spec@latest update
145
+ ```
146
+
147
+ ### 3. O que é atualizado?
148
+
149
+ O comando `update` sincroniza:
150
+ - ✅ Templates (`.morph/templates/`)
151
+ - ✅ Standards (`.morph/standards/`)
152
+ - ✅ Agentes (`.morph/config/agents.json`)
153
+ - ✅ Comandos Claude (`.claude/commands/`)
154
+ - ✅ Skills (`.claude/skills/`)
155
+ - ✅ Instruções (CLAUDE.md)
156
+
157
+ **Importante:** Seu `config.json` é preservado!
158
+
159
+ ---
160
+
105
161
  ## Começando
106
162
 
107
163
  ### 1. Criar uma Proposta
@@ -286,18 +342,45 @@ O MORPH segue a filosofia **"Free tier first"**:
286
342
 
287
343
  ---
288
344
 
289
- ## Licença
345
+ ## 📄 Licença e Distribuição
346
+
347
+ **Repositório:** Privado (código fonte protegido)
348
+ **Package npm:** Público e gratuito via `@polymorphism-tech/morph-spec`
349
+
350
+ ### Licença Proprietária
351
+
352
+ O MORPH-SPEC framework é software proprietário da Polymorphism Tech. Veja [LICENSE](LICENSE) para detalhes.
353
+
354
+ **Você PODE:**
355
+ - ✅ Usar o CLI tool gratuitamente
356
+ - ✅ Gerar projetos para uso pessoal ou comercial
357
+ - ✅ Modificar código gerado pelos templates
358
+ - ✅ Distribuir seus projetos criados com MORPH-SPEC
359
+
360
+ **Você NÃO PODE:**
361
+ - ❌ Redistribuir ou vender o framework
362
+ - ❌ Criar produtos derivados competidores
363
+ - ❌ Modificar ou fazer engenharia reversa do framework
364
+ - ❌ Remover avisos de copyright
365
+
366
+ ### Código Gerado
367
+
368
+ Todo código gerado usando MORPH-SPEC é **100% seu** para usar como quiser, incluindo uso comercial.
369
+
370
+ ### Suporte
290
371
 
291
- MIT © [Polymorphism Tech](https://polymorphism.tech)
372
+ - 📧 Email: support@polymorphism.com.br
373
+ - 🌐 Website: https://polymorphism.com.br
374
+ - 📦 npm: [@polymorphism-tech/morph-spec](https://www.npmjs.com/package/@polymorphism-tech/morph-spec)
292
375
 
293
376
  ---
294
377
 
295
378
  ## Links
296
379
 
297
- - 📦 [npm](https://www.npmjs.com/package/@polymorphism-tech/morph-spec)
380
+ - 📦 [npm Package](https://www.npmjs.com/package/@polymorphism-tech/morph-spec)
298
381
  - 📚 [Documentação](docs/)
299
382
  - 💡 [Exemplos](content/.morph/examples/)
300
- - 🐛 [Issues](https://github.com/polymorphism-tech/morph-spec-framework/issues)
383
+ - 🌐 [Polymorphism Tech](https://polymorphism.com.br)
301
384
 
302
385
  ---
303
386
 
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * MORPH-SPEC Agent Detection CLI
5
+ *
6
+ * Detecta automaticamente quais agentes devem ser ativados baseado
7
+ * em keywords no input do usuário.
8
+ *
9
+ * Uso:
10
+ * node bin/detect-agents.js "implementar jobs agendados"
11
+ * node bin/detect-agents.js --verbose "criar dashboard com charts"
12
+ * node bin/detect-agents.js --json "adicionar background tasks"
13
+ */
14
+
15
+ import { readFileSync } from 'fs';
16
+ import { join, dirname } from 'path';
17
+ import { fileURLToPath } from 'url';
18
+
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const AGENTS_CONFIG_PATH = join(__dirname, '../content/.morph/config/agents.json');
21
+
22
+ // Cores para output no terminal
23
+ const colors = {
24
+ reset: '\x1b[0m',
25
+ bright: '\x1b[1m',
26
+ green: '\x1b[32m',
27
+ yellow: '\x1b[33m',
28
+ blue: '\x1b[34m',
29
+ cyan: '\x1b[36m',
30
+ gray: '\x1b[90m'
31
+ };
32
+
33
+ function log(message, color = 'reset') {
34
+ console.log(`${colors[color]}${message}${colors.reset}`);
35
+ }
36
+
37
+ /**
38
+ * Carrega configuração de agentes
39
+ * @returns {Object} Configuração de agentes
40
+ */
41
+ function loadAgentsConfig() {
42
+ try {
43
+ const content = readFileSync(AGENTS_CONFIG_PATH, 'utf8');
44
+ return JSON.parse(content);
45
+ } catch (err) {
46
+ console.error(`ERROR: Failed to load agents config: ${err.message}`);
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Detecta agentes baseado em user input
53
+ * @param {string} userInput - Input do usuário
54
+ * @param {Object} config - Configuração de agentes
55
+ * @returns {Object} Resultado da detecção { core, specialists, all, matches }
56
+ */
57
+ function detectAgents(userInput, config) {
58
+ const input = userInput.toLowerCase();
59
+ const coreAgents = config.agents.core || [];
60
+ const specialists = config.agents.specialists || [];
61
+
62
+ // Core agents sempre ativos
63
+ const coreIds = coreAgents.map(a => a.id);
64
+
65
+ // Detectar specialists por keyword matching
66
+ const specialistMatches = [];
67
+
68
+ for (const agent of specialists) {
69
+ const keywords = agent.autoActivation?.keywords || [];
70
+ const matchedKeywords = [];
71
+
72
+ for (const keyword of keywords) {
73
+ if (input.includes(keyword.toLowerCase())) {
74
+ matchedKeywords.push(keyword);
75
+ }
76
+ }
77
+
78
+ if (matchedKeywords.length > 0) {
79
+ specialistMatches.push({
80
+ id: agent.id,
81
+ name: agent.name,
82
+ emoji: agent.emoji,
83
+ matchedKeywords: matchedKeywords,
84
+ matchCount: matchedKeywords.length
85
+ });
86
+ }
87
+ }
88
+
89
+ // Ordenar por número de matches (mais relevante primeiro)
90
+ specialistMatches.sort((a, b) => b.matchCount - a.matchCount);
91
+
92
+ const specialistIds = specialistMatches.map(m => m.id);
93
+ const allIds = [...new Set([...coreIds, ...specialistIds])];
94
+
95
+ return {
96
+ core: coreIds,
97
+ specialists: specialistIds,
98
+ all: allIds,
99
+ matches: specialistMatches,
100
+ input: userInput
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Formata output em modo verbose
106
+ * @param {Object} result - Resultado da detecção
107
+ */
108
+ function formatVerbose(result) {
109
+ log('\n╔════════════════════════════════════════════════════════════════╗', 'cyan');
110
+ log('║ AGENT DETECTION RESULT ║', 'cyan');
111
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
112
+ log(`║ Input: ${result.input.substring(0, 54).padEnd(54)} ║`, 'bright');
113
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
114
+ log('║ CORE AGENTS (always active) ║', 'cyan');
115
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
116
+
117
+ result.core.forEach(id => {
118
+ log(`║ ✓ ${id.padEnd(58)}║`, 'green');
119
+ });
120
+
121
+ if (result.specialists.length > 0) {
122
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
123
+ log('║ SPECIALIST AGENTS (keyword matched) ║', 'cyan');
124
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
125
+
126
+ result.matches.forEach(match => {
127
+ const line = `${match.emoji} ${match.name} (${match.matchCount} matches)`;
128
+ log(`║ ${line.padEnd(61)}║`, 'yellow');
129
+ const keywords = match.matchedKeywords.join(', ');
130
+ const keywordLine = `Keywords: ${keywords}`;
131
+ // Quebrar em múltiplas linhas se necessário
132
+ if (keywordLine.length > 58) {
133
+ const chunks = keywordLine.match(/.{1,58}/g) || [];
134
+ chunks.forEach((chunk, i) => {
135
+ log(`║ ${chunk.padEnd(59)}║`, 'gray');
136
+ });
137
+ } else {
138
+ log(`║ ${keywordLine.padEnd(59)}║`, 'gray');
139
+ }
140
+ });
141
+ } else {
142
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
143
+ log('║ No specialist agents matched ║', 'gray');
144
+ }
145
+
146
+ log('╠════════════════════════════════════════════════════════════════╣', 'cyan');
147
+ log(`║ TOTAL: ${result.all.length} agents activated ║`, 'bright');
148
+ log('╚════════════════════════════════════════════════════════════════╝\n', 'cyan');
149
+ }
150
+
151
+ /**
152
+ * Formata output em modo simples (apenas IDs)
153
+ * @param {Object} result - Resultado da detecção
154
+ */
155
+ function formatSimple(result) {
156
+ result.all.forEach(id => console.log(id));
157
+ }
158
+
159
+ /**
160
+ * Formata output em modo JSON
161
+ * @param {Object} result - Resultado da detecção
162
+ */
163
+ function formatJSON(result) {
164
+ console.log(JSON.stringify(result, null, 2));
165
+ }
166
+
167
+ // ============================================================================
168
+ // MAIN
169
+ // ============================================================================
170
+
171
+ function main() {
172
+ const args = process.argv.slice(2);
173
+
174
+ // Parse flags
175
+ const hasVerbose = args.includes('--verbose') || args.includes('-v');
176
+ const hasJSON = args.includes('--json') || args.includes('-j');
177
+ const hasHelp = args.includes('--help') || args.includes('-h');
178
+ const hasIdsOnly = args.includes('--ids-only') || args.includes('-i');
179
+
180
+ // Remove flags para pegar user input
181
+ const userInput = args
182
+ .filter(arg => !arg.startsWith('--') && !arg.startsWith('-'))
183
+ .join(' ');
184
+
185
+ if (hasHelp || args.length === 0) {
186
+ log('\nMORPH-SPEC Agent Detection CLI', 'bright');
187
+ log('\nUsage:', 'cyan');
188
+ log(' node bin/detect-agents.js [options] "<user input>"', 'gray');
189
+ log('\nOptions:', 'cyan');
190
+ log(' -v, --verbose Show detailed detection results', 'gray');
191
+ log(' -j, --json Output full result as JSON', 'gray');
192
+ log(' -i, --ids-only Output only agent IDs (one per line)', 'gray');
193
+ log(' -h, --help Show this help', 'gray');
194
+ log('\nExamples:', 'cyan');
195
+ log(' node bin/detect-agents.js "criar dashboard com charts"', 'gray');
196
+ log(' node bin/detect-agents.js --verbose "implementar jobs agendados"', 'gray');
197
+ log(' node bin/detect-agents.js --json "adicionar RAG pipeline"', 'gray');
198
+ log(' node bin/detect-agents.js --ids-only "background tasks"\n', 'gray');
199
+ process.exit(0);
200
+ }
201
+
202
+ if (!userInput) {
203
+ console.error('ERROR: User input is required');
204
+ console.error('Run with --help for usage information');
205
+ process.exit(1);
206
+ }
207
+
208
+ // Carregar config e detectar agentes
209
+ const config = loadAgentsConfig();
210
+ const result = detectAgents(userInput, config);
211
+
212
+ // Formatar output
213
+ if (hasJSON) {
214
+ formatJSON(result);
215
+ } else if (hasVerbose) {
216
+ formatVerbose(result);
217
+ } else if (hasIdsOnly) {
218
+ formatSimple(result);
219
+ } else {
220
+ // Default: JSON compact (só all array)
221
+ console.log(JSON.stringify(result.all));
222
+ }
223
+ }
224
+
225
+ main();
package/bin/morph-spec.js CHANGED
@@ -9,6 +9,15 @@ import { readFileSync } from 'fs';
9
9
  import { initCommand } from '../src/commands/init.js';
10
10
  import { updateCommand } from '../src/commands/update.js';
11
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 { costCommand } from '../src/commands/cost.js';
19
+ import { generateDesignSystemCommand } from '../src/commands/generate.js';
20
+ import { updateResourcePricing, showPricing, validatePricing } from '../src/commands/update-pricing.js';
12
21
 
13
22
  const __dirname = dirname(fileURLToPath(import.meta.url));
14
23
  const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
@@ -50,4 +59,115 @@ program
50
59
  .description('Check MORPH installation health')
51
60
  .action(doctorCommand);
52
61
 
62
+ program
63
+ .command('detect')
64
+ .description('Detect project stack, architecture, and patterns')
65
+ .option('-p, --path <path>', 'Project path (default: current directory)')
66
+ .option('-v, --verbose', 'Show detailed detection results')
67
+ .option('--no-save', 'Do not save results to .morph/project/')
68
+ .action(detectCommand);
69
+
70
+ program
71
+ .command('sync')
72
+ .description('Sync standards from feature decisions')
73
+ .option('-p, --path <path>', 'Project path (default: current directory)')
74
+ .option('--dry-run', 'Show what would be synced without updating files')
75
+ .action(syncCommand);
76
+
77
+ // Story-driven development commands
78
+ const storyCommand = program
79
+ .command('story')
80
+ .description('Story-driven development commands');
81
+
82
+ storyCommand
83
+ .command('create <feature> <story-id>')
84
+ .description('Create a new story with auto-injected Dev Notes')
85
+ .option('--title <title>', 'Story title')
86
+ .option('--epic <epic>', 'Epic name')
87
+ .option('--context <context>', 'Story context')
88
+ .option('--tasks <tasks>', 'Comma-separated tasks')
89
+ .option('--dry-run', 'Preview without writing file')
90
+ .action(createStoryCommand);
91
+
92
+ storyCommand
93
+ .command('shard <feature>')
94
+ .description('Shard spec.md into manageable chunks (90% token savings)')
95
+ .option('--dry-run', 'Preview shards without writing files')
96
+ .option('--verbose', 'Show detailed shard info')
97
+ .action(shardSpecCommand);
98
+
99
+ storyCommand
100
+ .command('status <feature> [action] [story-id]')
101
+ .description('Manage sprint status (show | start | qa | done | next)')
102
+ .action(sprintStatusCommand);
103
+
104
+ // State management commands
105
+ program
106
+ .command('state <action> [args...]')
107
+ .description('Manage state.json (init | get | set | checkpoint | list | add-agent | remove-agent | mark-output)')
108
+ .option('--force', 'Force overwrite (init command)')
109
+ .option('--project <name>', 'Project name (init command)')
110
+ .option('--type <type>', 'Project type (init command)')
111
+ .option('--json', 'Output as JSON (get command)')
112
+ .action((action, args, options) => stateCommand(action, args, options));
113
+
114
+ // Cost calculation command
115
+ program
116
+ .command('cost <bicep-files>')
117
+ .description('Calculate Azure infrastructure costs from Bicep files')
118
+ .option('--config <path>', 'Custom config path')
119
+ .option('--verbose', 'Show detailed breakdown')
120
+ .option('--json', 'Output as JSON')
121
+ .option('--strict', 'Exit with error if cost exceeds ADR threshold')
122
+ .action(costCommand);
123
+
124
+ // Pricing management commands
125
+ const pricingCommand = program
126
+ .command('pricing')
127
+ .description('Manage Azure pricing table');
128
+
129
+ pricingCommand
130
+ .command('show [resource-type]')
131
+ .description('Show current pricing (all or specific resource type)')
132
+ .option('--json', 'Output as JSON')
133
+ .action((resourceType, options) => showPricing({ resourceType, format: options.json ? 'json' : 'table' }));
134
+
135
+ pricingCommand
136
+ .command('update <resource-type> <sku> <price>')
137
+ .description('Update pricing for a specific SKU')
138
+ .option('--dry-run', 'Preview without saving')
139
+ .option('--no-validate', 'Skip validation')
140
+ .action((resourceType, sku, price, options) =>
141
+ updateResourcePricing({
142
+ resourceType,
143
+ sku,
144
+ price: parseFloat(price),
145
+ dryRun: options.dryRun,
146
+ validate: options.validate !== false
147
+ })
148
+ );
149
+
150
+ pricingCommand
151
+ .command('validate')
152
+ .description('Validate pricing file against JSON schema')
153
+ .action(validatePricing);
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
+
53
173
  program.parse();