vireum-spec-cli 0.4.2 → 0.7.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.
- package/README.md +259 -0
- package/dist/commands/brief.js +0 -4
- package/dist/commands/distill.js +64 -301
- package/dist/commands/enrich.js +139 -0
- package/dist/commands/health.js +0 -4
- package/dist/commands/init/ai.js +186 -0
- package/dist/commands/init/api.js +195 -0
- package/dist/commands/init/automation.js +166 -0
- package/dist/commands/init/mobile.js +155 -0
- package/dist/commands/init/system.js +307 -0
- package/dist/commands/init/web.js +165 -0
- package/dist/commands/init.js +21 -253
- package/dist/commands/prioritize.js +82 -34
- package/dist/commands/retrofit.js +14 -400
- package/dist/commands/setup.js +56 -488
- package/dist/commands/skills.js +0 -6
- package/dist/commands/verify-mcps.js +0 -4
- package/dist/index.js +44 -2
- package/dist/lib/analyzer.js +194 -0
- package/dist/lib/generators-retrofit.js +259 -0
- package/dist/lib/generators-retrofit.test.js +112 -0
- package/dist/lib/generators-setup.js +764 -0
- package/dist/lib/generators-setup.test.js +118 -0
- package/dist/lib/generators.js +593 -0
- package/dist/lib/parsers/ai.js +54 -0
- package/dist/lib/parsers/api.js +63 -0
- package/dist/lib/parsers/automation.js +52 -0
- package/dist/lib/parsers/mobile.js +60 -0
- package/dist/lib/parsers/system.js +66 -0
- package/dist/lib/parsers/web.js +70 -0
- package/dist/lib/types.js +2 -0
- package/docs/COMO_USAR.md +322 -0
- package/docs/DOCUMENTACAO_FRAMEWORK.md +568 -0
- package/package.json +9 -3
package/README.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# Vireum Spec — Spec Driven Development Framework
|
|
2
|
+
|
|
3
|
+
> **Versão:** 0.7.0
|
|
4
|
+
> **Framework** para documentação estruturada de projetos de software
|
|
5
|
+
> **By:** Vireum Desenvolvimento
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/vireum-spec-cli)
|
|
8
|
+
[](https://opensource.org/licenses/ISC)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🎯 O que é?
|
|
13
|
+
|
|
14
|
+
**Vireum Spec** é um framework CLI que ajuda você a documentar projetos de software de forma estruturada, alinhando requisitos, arquitetura e desenvolvimento com o cliente.
|
|
15
|
+
|
|
16
|
+
Bridging the gap between:
|
|
17
|
+
- 💡 **Ideias** — O que o cliente quer
|
|
18
|
+
- 📋 **Planejamento** — Como você vai construir
|
|
19
|
+
- 💻 **Execução** — Código que funciona
|
|
20
|
+
- 📚 **Manutenção** — Por que foi feito
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## ✨ Problemas que Resolve
|
|
25
|
+
|
|
26
|
+
✅ **Falta de clareza** — Requisitos confusos e mal documentados
|
|
27
|
+
✅ **Desalinhamento** — Cliente e dev querem coisas diferentes
|
|
28
|
+
✅ **Specs desatualizadas** — Documentação não reflete realidade
|
|
29
|
+
✅ **Difícil onboarding** — Novos devs entendem pouco
|
|
30
|
+
✅ **Sem rastreabilidade** — Quem decidiu o quê? Por quê?
|
|
31
|
+
✅ **IA sem contexto** — Claude Code funciona muito melhor com briefing estruturado
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🚀 Quick Start
|
|
36
|
+
|
|
37
|
+
### Instalação
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g vireum-spec-cli
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Novo Projeto
|
|
43
|
+
```bash
|
|
44
|
+
vireum-spec init --type <tipo>
|
|
45
|
+
vireum-spec distill
|
|
46
|
+
vireum-spec setup
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Tipos:** `system`, `web`, `api`, `mobile`, `automation`, `ai`
|
|
50
|
+
|
|
51
|
+
### Projeto Existente
|
|
52
|
+
```bash
|
|
53
|
+
vireum-spec retrofit
|
|
54
|
+
vireum-spec distill
|
|
55
|
+
vireum-spec setup
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 📚 Documentação Completa
|
|
61
|
+
|
|
62
|
+
- **[Guia de Uso](./docs/COMO_USAR.md)** — Step-by-step para novos e existentes
|
|
63
|
+
- **[Documentação Técnica](./docs/DOCUMENTACAO_FRAMEWORK.md)** — Deep dive no framework
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 🎨 O que Gera
|
|
68
|
+
|
|
69
|
+
### 3 Principais Artefatos
|
|
70
|
+
|
|
71
|
+
1. **`.spec/`** — Documentação estruturada
|
|
72
|
+
- `briefing.md` — Suas respostas originais
|
|
73
|
+
- `requirements.md` — Funcionalidades
|
|
74
|
+
- `users.md` — Personas
|
|
75
|
+
- `architecture.md` — Design técnico
|
|
76
|
+
- `risks.md` — Riscos identificados
|
|
77
|
+
- `rules.md` — Regras de negócio
|
|
78
|
+
- E mais...
|
|
79
|
+
|
|
80
|
+
2. **`.vireum/`** — Configuração técnica
|
|
81
|
+
- `stack.json` — Stack escolhida
|
|
82
|
+
- `protocol.md` — Protocolo da IA
|
|
83
|
+
|
|
84
|
+
3. **`.cursor/rules/`** — Integração Claude Code
|
|
85
|
+
- Regras estruturadas para IA trabalhar melhor
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 🛠️ 10 Comandos Principais
|
|
90
|
+
|
|
91
|
+
| Comando | Purpose |
|
|
92
|
+
|---------|---------|
|
|
93
|
+
| `init` | Briefing interativo |
|
|
94
|
+
| `distill` | Gera spec do briefing |
|
|
95
|
+
| `setup` | Configura stack & IA |
|
|
96
|
+
| `retrofit` | Auto-analisa projeto |
|
|
97
|
+
| `prioritize` | MVP / Fase 2 / Fora scope |
|
|
98
|
+
| `health` | Verifica consistências |
|
|
99
|
+
| `brief` | Resumo executivo |
|
|
100
|
+
| `verify-mcps` | Diagnóstico |
|
|
101
|
+
| `skills` | Instala no Claude Code |
|
|
102
|
+
| `enrich` | Encontra gaps |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🎓 Exemplo: Projeto de IA
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# 1. Iniciar
|
|
110
|
+
vireum-spec init --type ai
|
|
111
|
+
|
|
112
|
+
# Responde perguntas (6 seções):
|
|
113
|
+
# - Projeto: "Chatbot de Suporte"
|
|
114
|
+
# - Problema: "Suporte responde 200 tickets/dia, 2-3h cada"
|
|
115
|
+
# - Provider: "Anthropic Claude"
|
|
116
|
+
# - Fonte: "PDFs internos"
|
|
117
|
+
# - Supervisão: "Human-in-the-loop"
|
|
118
|
+
|
|
119
|
+
# 2. Gerar spec
|
|
120
|
+
vireum-spec distill
|
|
121
|
+
|
|
122
|
+
# 3. Configurar
|
|
123
|
+
vireum-spec setup
|
|
124
|
+
# → Next.js, Node.js + Express, PostgreSQL, Prisma, JWT, RAG
|
|
125
|
+
|
|
126
|
+
# 4. Instalar skills
|
|
127
|
+
vireum-spec skills
|
|
128
|
+
|
|
129
|
+
# Resultado:
|
|
130
|
+
# ✓ Spec completo em .spec/
|
|
131
|
+
# ✓ Stack definido
|
|
132
|
+
# ✓ Protocol de IA pronto
|
|
133
|
+
# ✓ Tasks para dev
|
|
134
|
+
# ✓ Claude Code otimizado
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 🎯 Tipos de Projeto Suportados
|
|
140
|
+
|
|
141
|
+
| Tipo | Para |
|
|
142
|
+
|------|------|
|
|
143
|
+
| **system** | Sistemas completos/multi-módulo (padrão) |
|
|
144
|
+
| **web** | Landing pages, sites, plataformas web |
|
|
145
|
+
| **api** | REST APIs, GraphQL, backends |
|
|
146
|
+
| **mobile** | Apps iOS/Android |
|
|
147
|
+
| **automation** | RPA, workflows, automação |
|
|
148
|
+
| **ai** | Chatbots, agentes, extração de dados |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 💡 Melhores Práticas
|
|
153
|
+
|
|
154
|
+
### ✅ Faça:
|
|
155
|
+
- Responda o briefing com detalhe
|
|
156
|
+
- Revise spec gerado manualmente
|
|
157
|
+
- Use `.spec/INDEX.md` como ponto de partida
|
|
158
|
+
- Mantenha atualizado conforme aprende
|
|
159
|
+
- Rode `health` regularmente
|
|
160
|
+
|
|
161
|
+
### ❌ Evite:
|
|
162
|
+
- Deixar campos em branco
|
|
163
|
+
- Não revisar spec auto-gerado
|
|
164
|
+
- Esquecer de rodar `setup`
|
|
165
|
+
- Ignorar avisos do `health`
|
|
166
|
+
- Spec preso em git sem usar
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 🤖 Para Claude Code
|
|
171
|
+
|
|
172
|
+
Rode `vireum-spec skills` para instalar skills que fazem Claude Code:
|
|
173
|
+
- Entender melhor seu projeto
|
|
174
|
+
- Seguir padrões específicos
|
|
175
|
+
- Usar suas regras de negócio
|
|
176
|
+
- Tomar decisões alinhadas
|
|
177
|
+
- Ser mais eficiente
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## 📊 Workflow Recomendado
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
Plan → vireum-spec init + distill
|
|
185
|
+
Design → vireum-spec setup + health
|
|
186
|
+
Dev → Tasks em spec como guia
|
|
187
|
+
Review → Use spec como checklist
|
|
188
|
+
Retro → Update changelog
|
|
189
|
+
Maintain → Regular health checks
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 🛠️ Stack Técnico
|
|
195
|
+
|
|
196
|
+
**Dependências:**
|
|
197
|
+
- Node.js 18+
|
|
198
|
+
- Commander (CLI)
|
|
199
|
+
- Chalk (colors)
|
|
200
|
+
- Inquirer (prompts)
|
|
201
|
+
- Ora (spinners)
|
|
202
|
+
|
|
203
|
+
**Peso:** ~10MB instalado
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 📦 Para Publicar no NPM
|
|
208
|
+
|
|
209
|
+
O pacote está configurado para publicar com:
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"files": ["dist/", "src/skills/", "README.md", "docs/"]
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Incluindo:
|
|
217
|
+
- ✓ CLI compilado (`dist/`)
|
|
218
|
+
- ✓ Skills (`src/skills/`)
|
|
219
|
+
- ✓ README.md (esse)
|
|
220
|
+
- ✓ Documentação completa (`docs/`)
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 🗺️ Roadmap
|
|
225
|
+
|
|
226
|
+
**Planejado:**
|
|
227
|
+
- UI web para gerenciar spec
|
|
228
|
+
- Integração Linear/Jira
|
|
229
|
+
- Geração de código a partir de spec
|
|
230
|
+
- Multi-language support (EN, ES, FR)
|
|
231
|
+
- API pública para tooling
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 📝 Licença
|
|
236
|
+
|
|
237
|
+
**ISC** — Use em projetos comerciais e pessoais
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 🤝 Suporte
|
|
242
|
+
|
|
243
|
+
- **Issues:** GitHub do projeto
|
|
244
|
+
- **Comunidade:** Discord Vireum
|
|
245
|
+
- **Consulting:** vireum@dev.com
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 📖 Comece Agora
|
|
250
|
+
|
|
251
|
+
1. **Instale:** `npm install -g vireum-spec-cli`
|
|
252
|
+
2. **Leia:** [Guia de Uso](./docs/COMO_USAR.md)
|
|
253
|
+
3. **Inicie:** `vireum-spec init --type <tipo>`
|
|
254
|
+
4. **Gere:** `vireum-spec distill`
|
|
255
|
+
5. **Configure:** `vireum-spec setup`
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
Made with ❤️ by **[Vireum Desenvolvimento](https://vireum.com.br)**
|
package/dist/commands/brief.js
CHANGED
|
@@ -45,7 +45,6 @@ async function runBrief() {
|
|
|
45
45
|
console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Brief\n'));
|
|
46
46
|
const specDir = path.join(process.cwd(), '.spec');
|
|
47
47
|
const spinner = (0, ora_1.default)('Lendo spec...').start();
|
|
48
|
-
await sleep(600);
|
|
49
48
|
spinner.stop();
|
|
50
49
|
if (!fs.existsSync(path.join(specDir, 'INDEX.md'))) {
|
|
51
50
|
console.log(chalk_1.default.red('\n❌ Spec não encontrado.'));
|
|
@@ -145,6 +144,3 @@ function gerarBarra(pct) {
|
|
|
145
144
|
const cor = pct >= 80 ? chalk_1.default.green : pct >= 40 ? chalk_1.default.yellow : chalk_1.default.gray;
|
|
146
145
|
return cor('█'.repeat(preench)) + chalk_1.default.gray('░'.repeat(vazio));
|
|
147
146
|
}
|
|
148
|
-
function sleep(ms) {
|
|
149
|
-
return new Promise(r => setTimeout(r, ms));
|
|
150
|
-
}
|
package/dist/commands/distill.js
CHANGED
|
@@ -41,6 +41,13 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
41
41
|
const ora_1 = __importDefault(require("ora"));
|
|
42
42
|
const fs = __importStar(require("fs"));
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
|
+
const system_1 = require("../lib/parsers/system");
|
|
45
|
+
const web_1 = require("../lib/parsers/web");
|
|
46
|
+
const api_1 = require("../lib/parsers/api");
|
|
47
|
+
const mobile_1 = require("../lib/parsers/mobile");
|
|
48
|
+
const automation_1 = require("../lib/parsers/automation");
|
|
49
|
+
const ai_1 = require("../lib/parsers/ai");
|
|
50
|
+
const generators_1 = require("../lib/generators");
|
|
44
51
|
async function runDistill() {
|
|
45
52
|
console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Distill\n'));
|
|
46
53
|
const specDir = path.join(process.cwd(), '.spec');
|
|
@@ -52,321 +59,77 @@ async function runDistill() {
|
|
|
52
59
|
}
|
|
53
60
|
const spinner = (0, ora_1.default)('Lendo briefing...').start();
|
|
54
61
|
const briefing = fs.readFileSync(briefingPath, 'utf-8');
|
|
55
|
-
await sleep(600);
|
|
56
62
|
spinner.succeed('Briefing lido');
|
|
57
|
-
|
|
63
|
+
// ── Detectar tipo e parsear ────────────────────────────────────────────────
|
|
64
|
+
const tipo = detectarTipo(briefing, specDir);
|
|
65
|
+
const dados = parsearBriefing(briefing, tipo);
|
|
66
|
+
if (tipo !== 'system') {
|
|
67
|
+
console.log(chalk_1.default.gray(` Tipo detectado: `) + chalk_1.default.white(tipo));
|
|
68
|
+
}
|
|
69
|
+
// ── Gerar arquivos .spec/ ──────────────────────────────────────────────────
|
|
58
70
|
const arquivos = [
|
|
59
|
-
{ nome: 'requirements.md', conteudo: gerarRequirements(dados), msg: 'Gerando requirements.md...' },
|
|
60
|
-
{ nome: 'users.md', conteudo: gerarUsers(dados), msg: 'Gerando users.md...' },
|
|
61
|
-
{ nome: 'risks.md', conteudo: gerarRisks(dados), msg: 'Gerando risks.md...' },
|
|
62
|
-
{ nome: 'architecture.md', conteudo: gerarArchitecture(dados), msg: 'Gerando architecture.md...' },
|
|
63
|
-
{ nome: 'INDEX.md', conteudo: gerarIndex(dados), msg: 'Gerando INDEX.md...' },
|
|
64
|
-
{ nome: 'changelog.md', conteudo: gerarChangelog(dados), msg: 'Gerando changelog.md...' },
|
|
65
|
-
{ nome: 'rules.md', conteudo: gerarRules(dados), msg: 'Gerando rules.md...' },
|
|
71
|
+
{ nome: 'requirements.md', conteudo: (0, generators_1.gerarRequirements)(dados), msg: 'Gerando requirements.md...' },
|
|
72
|
+
{ nome: 'users.md', conteudo: (0, generators_1.gerarUsers)(dados), msg: 'Gerando users.md...' },
|
|
73
|
+
{ nome: 'risks.md', conteudo: (0, generators_1.gerarRisks)(dados), msg: 'Gerando risks.md...' },
|
|
74
|
+
{ nome: 'architecture.md', conteudo: (0, generators_1.gerarArchitecture)(dados), msg: 'Gerando architecture.md...' },
|
|
75
|
+
{ nome: 'INDEX.md', conteudo: (0, generators_1.gerarIndex)(dados), msg: 'Gerando INDEX.md...' },
|
|
76
|
+
{ nome: 'changelog.md', conteudo: (0, generators_1.gerarChangelog)(dados), msg: 'Gerando changelog.md...' },
|
|
77
|
+
{ nome: 'rules.md', conteudo: (0, generators_1.gerarRules)(dados), msg: 'Gerando rules.md...' },
|
|
66
78
|
];
|
|
67
79
|
for (const arq of arquivos) {
|
|
68
80
|
const s = (0, ora_1.default)(arq.msg).start();
|
|
69
|
-
await sleep(400);
|
|
70
81
|
fs.writeFileSync(path.join(specDir, arq.nome), arq.conteudo, 'utf-8');
|
|
71
82
|
s.succeed(arq.nome + ' gerado');
|
|
72
83
|
}
|
|
73
|
-
//
|
|
84
|
+
// ── Tasks ──────────────────────────────────────────────────────────────────
|
|
74
85
|
const tasksDir = path.join(specDir, 'tasks');
|
|
75
86
|
if (!fs.existsSync(tasksDir))
|
|
76
87
|
fs.mkdirSync(tasksDir, { recursive: true });
|
|
77
|
-
const sActive = (0, ora_1.default)('Gerando tasks
|
|
78
|
-
|
|
79
|
-
fs.writeFileSync(path.join(tasksDir, '
|
|
80
|
-
fs.writeFileSync(path.join(tasksDir, '
|
|
81
|
-
fs.writeFileSync(path.join(tasksDir, 'done.md'), gerarTasksDone(dados), 'utf-8');
|
|
88
|
+
const sActive = (0, ora_1.default)('Gerando tasks/...').start();
|
|
89
|
+
fs.writeFileSync(path.join(tasksDir, 'active.md'), (0, generators_1.gerarTasksActive)(dados), 'utf-8');
|
|
90
|
+
fs.writeFileSync(path.join(tasksDir, 'backlog.md'), (0, generators_1.gerarTasksBacklog)(dados), 'utf-8');
|
|
91
|
+
fs.writeFileSync(path.join(tasksDir, 'done.md'), (0, generators_1.gerarTasksDone)(dados), 'utf-8');
|
|
82
92
|
sActive.succeed('tasks/ gerado');
|
|
83
93
|
console.log(chalk_1.default.green.bold('\n✅ Spec gerado com sucesso!\n'));
|
|
84
94
|
console.log(chalk_1.default.gray(' Arquivos criados em ') + chalk_1.default.white('.spec/\n'));
|
|
85
95
|
console.log(chalk_1.default.gray(' Próximo passo: ') + chalk_1.default.white('vireum-spec setup') + chalk_1.default.gray(' para configurar stack e protocolo\n'));
|
|
86
96
|
}
|
|
87
|
-
// ───
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
problema: extrairCampo(secaoObjetivo, 'Problema que o sistema resolve'),
|
|
126
|
-
prioridade: extrairCampo(secaoObjetivo, 'Prioridade do cliente'),
|
|
127
|
-
usuarios: extrairCampo(secaoEscopo, 'Quem usará') || '',
|
|
128
|
-
multiUsuario: secaoEscopo.includes('Diferentes tipos de usuários: Sim'),
|
|
129
|
-
niveisAcesso: secaoEscopo.includes('Níveis de acesso: Sim'),
|
|
130
|
-
integracoes: extrairCampo(secaoEscopo, 'Integrações Externas') || '',
|
|
131
|
-
features: featuresObrig,
|
|
132
|
-
regras: secaoRegras,
|
|
133
|
-
plataforma: extrairCampo(secaoPlat, 'Tipo'),
|
|
134
|
-
hospedagem: extrairCampo(secaoPlat, 'Hospedagem'),
|
|
135
|
-
cicd: secaoPlat.includes('CI/CD desde o início: Sim'),
|
|
136
|
-
staging: secaoPlat.includes('Ambiente de staging: Sim'),
|
|
137
|
-
lgpd: secaoSeg.includes('LGPD: Sim'),
|
|
138
|
-
dadosSensiveis: secaoSeg.includes('Dados sensíveis: Sim'),
|
|
139
|
-
pagamento: secaoFinan.includes('Integração com pagamento: Sim'),
|
|
140
|
-
cobranca: extrairCampo(secaoFinan, 'Modelo de cobrança'),
|
|
141
|
-
dashboard: secaoMetricas.includes('Dashboard administrativo: Sim'),
|
|
142
|
-
kpis: extrairCampo(secaoMetricas, 'KPIs'),
|
|
143
|
-
usuariosLanc: extrairCampo(secaoEscala, 'Usuários no lançamento'),
|
|
144
|
-
riscTecnico: extrairCampo(secaoRiscos, 'Risco técnico'),
|
|
145
|
-
riscJuridico: extrairCampo(secaoRiscos, 'Risco jurídico'),
|
|
146
|
-
riscOperacional: extrairCampo(secaoRiscos, 'Risco operacional'),
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
// ─── GERADORES ────────────────────────────────────────────────────────────────
|
|
150
|
-
function gerarRequirements(d) {
|
|
151
|
-
const features = d.features.length
|
|
152
|
-
? d.features.map((f, i) => `- [ ] R-${String(i + 1).padStart(3, '0')} ${f}`).join('\n')
|
|
153
|
-
: '- [ ] R-001 (a definir)';
|
|
154
|
-
return `# Requirements — ${d.projeto}
|
|
155
|
-
|
|
156
|
-
> Gerado automaticamente a partir do briefing em ${d.data}
|
|
157
|
-
> Fonte: .spec/briefing.md
|
|
158
|
-
|
|
159
|
-
## Objetivo
|
|
160
|
-
${d.objetivo}
|
|
161
|
-
|
|
162
|
-
**Problema:** ${d.problema}
|
|
163
|
-
|
|
164
|
-
**Prioridade do cliente:** ${d.prioridade}
|
|
165
|
-
|
|
166
|
-
## Funcionalidades — MVP
|
|
167
|
-
|
|
168
|
-
${features}
|
|
169
|
-
|
|
170
|
-
## Funcionalidades — Fase 2
|
|
171
|
-
> Preencher após vireum-spec prioritize
|
|
172
|
-
|
|
173
|
-
## Regras de Negócio
|
|
174
|
-
${d.regras || '> A extrair do briefing'}
|
|
175
|
-
|
|
176
|
-
## Integrações
|
|
177
|
-
${d.integracoes || 'Nenhuma identificada'}
|
|
178
|
-
|
|
179
|
-
## Financeiro
|
|
180
|
-
${d.pagamento ? `- Integração com pagamento: Sim\n- Modelo: ${d.cobranca}` : '- Sem integração financeira'}
|
|
181
|
-
|
|
182
|
-
## Métricas
|
|
183
|
-
- KPIs: ${d.kpis || 'A definir'}
|
|
184
|
-
- Dashboard: ${d.dashboard ? 'Sim' : 'Não'}
|
|
185
|
-
`;
|
|
186
|
-
}
|
|
187
|
-
function gerarUsers(d) {
|
|
188
|
-
return `# Users — ${d.projeto}
|
|
189
|
-
|
|
190
|
-
> Gerado automaticamente a partir do briefing em ${d.data}
|
|
191
|
-
|
|
192
|
-
## Público Principal
|
|
193
|
-
${d.usuarios || 'A definir'}
|
|
194
|
-
|
|
195
|
-
## Tipos de Usuário
|
|
196
|
-
${d.multiUsuario ? '> Definir perfis após vireum-spec setup' : '- Usuário único (sem diferenciação de perfis)'}
|
|
197
|
-
|
|
198
|
-
## Níveis de Acesso
|
|
199
|
-
${d.niveisAcesso ? '> Detalhar níveis em vireum-spec setup' : '- Acesso único (sem controle de permissões diferenciado)'}
|
|
200
|
-
|
|
201
|
-
## Jornadas Principais
|
|
202
|
-
> A detalhar durante o desenvolvimento — referenciar requirements.md
|
|
203
|
-
`;
|
|
204
|
-
}
|
|
205
|
-
function gerarRisks(d) {
|
|
206
|
-
return `# Risks — ${d.projeto}
|
|
207
|
-
|
|
208
|
-
> Gerado automaticamente a partir do briefing em ${d.data}
|
|
209
|
-
|
|
210
|
-
## Riscos Identificados no Briefing
|
|
211
|
-
|
|
212
|
-
### Técnico
|
|
213
|
-
${d.riscTecnico || 'Nenhum identificado'}
|
|
214
|
-
|
|
215
|
-
### Jurídico
|
|
216
|
-
${d.riscJuridico || 'Nenhum identificado'}
|
|
217
|
-
${d.lgpd ? '\n> ⚠️ LGPD requerida — atenção ao tratamento de dados pessoais' : ''}
|
|
218
|
-
|
|
219
|
-
### Operacional
|
|
220
|
-
${d.riscOperacional || 'Nenhum identificado'}
|
|
221
|
-
|
|
222
|
-
## Riscos Identificados Durante o Desenvolvimento
|
|
223
|
-
> A IA deve adicionar entradas aqui ao identificar novos riscos
|
|
224
|
-
|
|
225
|
-
| Data | Risco | Impacto | Mitigação |
|
|
226
|
-
|------|-------|---------|-----------|
|
|
227
|
-
| | | | |
|
|
228
|
-
`;
|
|
229
|
-
}
|
|
230
|
-
function gerarArchitecture(d) {
|
|
231
|
-
return `# Architecture — ${d.projeto}
|
|
232
|
-
|
|
233
|
-
> Gerado automaticamente a partir do briefing em ${d.data}
|
|
234
|
-
> Completar com vireum-spec setup
|
|
235
|
-
|
|
236
|
-
## Stack
|
|
237
|
-
> A definir em vireum-spec setup
|
|
238
|
-
|
|
239
|
-
- Frontend:
|
|
240
|
-
- Backend:
|
|
241
|
-
- Banco de dados:
|
|
242
|
-
- Cache:
|
|
243
|
-
- Auth:
|
|
244
|
-
|
|
245
|
-
## Infraestrutura
|
|
246
|
-
- Plataforma: ${d.plataforma || 'A definir'}
|
|
247
|
-
- Hospedagem: ${d.hospedagem || 'A definir'}
|
|
248
|
-
- CI/CD: ${d.cicd ? 'Sim' : 'Não definido'}
|
|
249
|
-
- Staging: ${d.staging ? 'Sim' : 'Não'}
|
|
250
|
-
|
|
251
|
-
## Decisões Arquiteturais
|
|
252
|
-
> A IA deve registrar aqui cada decisão técnica relevante
|
|
253
|
-
|
|
254
|
-
| Data | Decisão | Alternativas descartadas | Motivo |
|
|
255
|
-
|------|---------|--------------------------|--------|
|
|
256
|
-
| | | | |
|
|
257
|
-
|
|
258
|
-
## MCPs Ativos
|
|
259
|
-
> A configurar em vireum-spec setup
|
|
260
|
-
`;
|
|
261
|
-
}
|
|
262
|
-
function gerarIndex(d) {
|
|
263
|
-
return `# INDEX — ${d.projeto}
|
|
264
|
-
|
|
265
|
-
> Arquivo de entrada. Sempre carregado pela IA no início de cada sessão.
|
|
266
|
-
> Arquivos pesados são carregados por referência — apenas quando a tarefa exigir.
|
|
267
|
-
|
|
268
|
-
## Projeto
|
|
269
|
-
- **Cliente:** ${d.cliente}
|
|
270
|
-
- **Responsável:** ${d.responsavel}
|
|
271
|
-
- **Fase atual:** MVP
|
|
272
|
-
- **Iniciado em:** ${d.data}
|
|
273
|
-
|
|
274
|
-
## Estado do MVP
|
|
275
|
-
> Atualizar conforme o desenvolvimento avança
|
|
276
|
-
|
|
277
|
-
- [ ] Nenhuma task concluída ainda
|
|
278
|
-
|
|
279
|
-
## Arquivos de contexto disponíveis
|
|
280
|
-
Não carregue esses arquivos automaticamente.
|
|
281
|
-
Carregue apenas quando a tarefa exigir:
|
|
282
|
-
|
|
283
|
-
- Escopo e features → leia \`.spec/requirements.md\`
|
|
284
|
-
- Decisões técnicas → leia \`.spec/architecture.md\`
|
|
285
|
-
- Perfis e permissões → leia \`.spec/users.md\`
|
|
286
|
-
- Riscos → leia \`.spec/risks.md\`
|
|
287
|
-
- Tarefas ativas → leia \`.spec/tasks/active.md\`
|
|
288
|
-
- Histórico de decisões → leia \`.spec/changelog.md\`
|
|
289
|
-
|
|
290
|
-
## Resumo do Objetivo
|
|
291
|
-
${d.objetivo}
|
|
292
|
-
`;
|
|
293
|
-
}
|
|
294
|
-
function gerarChangelog(d) {
|
|
295
|
-
return `# Changelog — ${d.projeto}
|
|
296
|
-
|
|
297
|
-
> Registro de decisões, mudanças e causa raiz de bugs.
|
|
298
|
-
> A IA deve adicionar entradas aqui ao tomar decisões relevantes ou resolver bugs.
|
|
299
|
-
> Formato: data, tipo, descrição.
|
|
300
|
-
|
|
301
|
-
## ${d.data} — Projeto iniciado
|
|
302
|
-
- Briefing realizado com ${d.cliente}
|
|
303
|
-
- Spec gerado via vireum-spec distill
|
|
304
|
-
`;
|
|
305
|
-
}
|
|
306
|
-
function gerarRules(d) {
|
|
307
|
-
const extras = [];
|
|
308
|
-
if (d.lgpd)
|
|
309
|
-
extras.push('- Nunca armazenar dados pessoais sem consentimento explícito (LGPD)');
|
|
310
|
-
if (d.dadosSensiveis)
|
|
311
|
-
extras.push('- Dados sensíveis devem ser encriptados em repouso e em trânsito');
|
|
312
|
-
if (d.pagamento)
|
|
313
|
-
extras.push('- Nunca logar dados de pagamento (cartão, CVV, etc.)');
|
|
314
|
-
if (d.niveisAcesso)
|
|
315
|
-
extras.push('- Toda rota deve validar o nível de acesso do usuário');
|
|
316
|
-
return `# Rules — ${d.projeto}
|
|
317
|
-
|
|
318
|
-
> Regras específicas deste projeto geradas a partir do briefing.
|
|
319
|
-
> Estas regras complementam as regras globais em .vireum/rules.md
|
|
320
|
-
> Em caso de conflito, as regras globais prevalecem.
|
|
321
|
-
|
|
322
|
-
## Regras do Projeto
|
|
323
|
-
${extras.length ? extras.join('\n') : '- Nenhuma regra específica identificada no briefing'}
|
|
324
|
-
|
|
325
|
-
## Regras a Definir
|
|
326
|
-
> Completar após vireum-spec setup com decisões técnicas do projeto
|
|
327
|
-
`;
|
|
328
|
-
}
|
|
329
|
-
function gerarTasksActive(d) {
|
|
330
|
-
return `# Tasks — Active
|
|
331
|
-
|
|
332
|
-
> Tarefas em desenvolvimento ativo.
|
|
333
|
-
> Formato: [FEATURE-TIPO_NUMERO] Descrição
|
|
334
|
-
> A IA só implementa tasks desta lista.
|
|
335
|
-
> Ao concluir, mover para done.md
|
|
336
|
-
|
|
337
|
-
## Como usar
|
|
338
|
-
- [FEATURE-T001] Descrição da task
|
|
339
|
-
- Origem: requirements.md → R-001
|
|
340
|
-
- Critérios: o que deve passar para considerar done
|
|
341
|
-
- Camada: Backend | Frontend | Integração
|
|
342
|
-
|
|
343
|
-
---
|
|
344
|
-
|
|
345
|
-
> Nenhuma task ativa ainda.
|
|
346
|
-
> Execute vireum-spec prioritize para gerar as tasks do MVP.
|
|
347
|
-
`;
|
|
348
|
-
}
|
|
349
|
-
function gerarTasksBacklog(d) {
|
|
350
|
-
const items = d.features.length
|
|
351
|
-
? d.features.map((f, i) => `- [ ] [FEATURE-T${String(i + 1).padStart(3, '0')}] ${f} [PENDING: aguarda prioritize]`).join('\n')
|
|
352
|
-
: '- [ ] (nenhuma feature mapeada ainda)';
|
|
353
|
-
return `# Tasks — Backlog
|
|
354
|
-
|
|
355
|
-
> Features mapeadas aguardando priorização.
|
|
356
|
-
> Execute vireum-spec prioritize para classificar em MVP ou Fase 2.
|
|
357
|
-
|
|
358
|
-
${items}
|
|
359
|
-
`;
|
|
360
|
-
}
|
|
361
|
-
function gerarTasksDone(d) {
|
|
362
|
-
return `# Tasks — Done
|
|
363
|
-
|
|
364
|
-
> Tasks concluídas. Arquivo de referência — raramente entra no contexto ativo.
|
|
365
|
-
|
|
366
|
-
## ${d.data}
|
|
367
|
-
- Projeto iniciado — spec gerado via vireum-spec distill
|
|
368
|
-
`;
|
|
369
|
-
}
|
|
370
|
-
function sleep(ms) {
|
|
371
|
-
return new Promise(r => setTimeout(r, ms));
|
|
97
|
+
// ─── DETECÇÃO DE TIPO ─────────────────────────────────────────────────────────
|
|
98
|
+
function detectarTipo(briefing, specDir) {
|
|
99
|
+
// Preferir .spec/meta.json — fonte canonica gravada pelo init
|
|
100
|
+
const metaPath = path.join(specDir, 'meta.json');
|
|
101
|
+
if (fs.existsSync(metaPath)) {
|
|
102
|
+
try {
|
|
103
|
+
const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
|
|
104
|
+
if (meta.tipo)
|
|
105
|
+
return meta.tipo;
|
|
106
|
+
}
|
|
107
|
+
catch { /* fallback abaixo */ }
|
|
108
|
+
}
|
|
109
|
+
// Fallback: heuristica antiga para briefings pre-meta.json
|
|
110
|
+
const match = briefing.match(/- \*\*Tipo:\*\*\s*(.+)/i);
|
|
111
|
+
if (!match)
|
|
112
|
+
return 'system';
|
|
113
|
+
const tipo = match[1].toLowerCase();
|
|
114
|
+
if (tipo.includes('web'))
|
|
115
|
+
return 'web';
|
|
116
|
+
if (tipo.includes('api') || tipo.includes('backend'))
|
|
117
|
+
return 'api';
|
|
118
|
+
if (tipo.includes('mobile'))
|
|
119
|
+
return 'mobile';
|
|
120
|
+
if (tipo.includes('automa'))
|
|
121
|
+
return 'automation';
|
|
122
|
+
if (tipo.includes('ia') || tipo.includes('feature de ia'))
|
|
123
|
+
return 'ai';
|
|
124
|
+
return 'system';
|
|
125
|
+
}
|
|
126
|
+
function parsearBriefing(briefing, tipo) {
|
|
127
|
+
switch (tipo) {
|
|
128
|
+
case 'web': return (0, web_1.parseBriefingWeb)(briefing);
|
|
129
|
+
case 'api': return (0, api_1.parseBriefingApi)(briefing);
|
|
130
|
+
case 'mobile': return (0, mobile_1.parseBriefingMobile)(briefing);
|
|
131
|
+
case 'automation': return (0, automation_1.parseBriefingAutomation)(briefing);
|
|
132
|
+
case 'ai': return (0, ai_1.parseBriefingAi)(briefing);
|
|
133
|
+
default: return (0, system_1.parseBriefingSystem)(briefing);
|
|
134
|
+
}
|
|
372
135
|
}
|