vireum-spec-cli 0.4.1 → 0.5.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/dist/commands/enrich.js +144 -0
- package/dist/commands/setup.js +61 -4
- package/dist/index.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.runEnrich = runEnrich;
|
|
40
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
41
|
+
const ora_1 = __importDefault(require("ora"));
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
async function runEnrich() {
|
|
45
|
+
console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Enrich\n'));
|
|
46
|
+
console.log(chalk_1.default.gray(' Gera um prompt para a IA identificar gaps no spec\n'));
|
|
47
|
+
const specDir = path.join(process.cwd(), '.spec');
|
|
48
|
+
if (!fs.existsSync(path.join(specDir, 'INDEX.md'))) {
|
|
49
|
+
console.log(chalk_1.default.red('\n❌ Spec não encontrado.'));
|
|
50
|
+
console.log(chalk_1.default.gray(' Execute primeiro: ') + chalk_1.default.white('vireum-spec retrofit') + chalk_1.default.gray(' ou ') + chalk_1.default.white('vireum-spec distill\n'));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
const spinner = (0, ora_1.default)('Lendo spec...').start();
|
|
54
|
+
await sleep(600);
|
|
55
|
+
const arquivos = [
|
|
56
|
+
{ nome: 'INDEX.md', path: path.join(specDir, 'INDEX.md') },
|
|
57
|
+
{ nome: 'briefing.md', path: path.join(specDir, 'briefing.md') },
|
|
58
|
+
{ nome: 'requirements.md', path: path.join(specDir, 'requirements.md') },
|
|
59
|
+
{ nome: 'architecture.md', path: path.join(specDir, 'architecture.md') },
|
|
60
|
+
{ nome: 'users.md', path: path.join(specDir, 'users.md') },
|
|
61
|
+
{ nome: 'risks.md', path: path.join(specDir, 'risks.md') },
|
|
62
|
+
{ nome: 'rules.md', path: path.join(specDir, 'rules.md') },
|
|
63
|
+
{ nome: 'tasks/active.md', path: path.join(specDir, 'tasks', 'active.md') },
|
|
64
|
+
{ nome: 'tasks/backlog.md', path: path.join(specDir, 'tasks', 'backlog.md') },
|
|
65
|
+
];
|
|
66
|
+
const conteudos = [];
|
|
67
|
+
for (const arq of arquivos) {
|
|
68
|
+
if (fs.existsSync(arq.path)) {
|
|
69
|
+
const conteudo = fs.readFileSync(arq.path, 'utf-8');
|
|
70
|
+
conteudos.push(`### ${arq.nome}\n\`\`\`\n${conteudo}\n\`\`\``);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
spinner.succeed('Spec lido');
|
|
74
|
+
const prompt = gerarPrompt(conteudos.join('\n\n'));
|
|
75
|
+
const promptPath = path.join(specDir, 'enrich-prompt.md');
|
|
76
|
+
const s2 = (0, ora_1.default)('Gerando prompt...').start();
|
|
77
|
+
await sleep(400);
|
|
78
|
+
fs.writeFileSync(promptPath, prompt, 'utf-8');
|
|
79
|
+
s2.succeed('.spec/enrich-prompt.md gerado');
|
|
80
|
+
console.log(chalk_1.default.green.bold('\n✅ Prompt pronto!\n'));
|
|
81
|
+
console.log(chalk_1.default.white(' Proximos passos:\n'));
|
|
82
|
+
console.log(chalk_1.default.gray(' 1. Abra o arquivo: ') + chalk_1.default.white('.spec/enrich-prompt.md'));
|
|
83
|
+
console.log(chalk_1.default.gray(' 2. Cole o conteudo no seu agente de IA (Claude Code, Cursor, Codex)'));
|
|
84
|
+
console.log(chalk_1.default.gray(' 3. Responda as perguntas que a IA fizer'));
|
|
85
|
+
console.log(chalk_1.default.gray(' 4. Salve as respostas nos arquivos de spec relevantes\n'));
|
|
86
|
+
console.log(chalk_1.default.hex('#2D7DD2')(' Dica: use o modo 4 do protocolo Vireum para garantir que as respostas\n sejam incorporadas corretamente ao spec.\n'));
|
|
87
|
+
}
|
|
88
|
+
// ─── GERADOR DE PROMPT ────────────────────────────────────────────────────────
|
|
89
|
+
function gerarPrompt(specConteudo) {
|
|
90
|
+
return `# Vireum Spec — Enrich Prompt
|
|
91
|
+
|
|
92
|
+
> Cole este prompt inteiro no seu agente de IA (Claude Code, Cursor, Codex CLI).
|
|
93
|
+
> O agente vai analisar o spec e fazer perguntas para preencher os gaps.
|
|
94
|
+
> Responda as perguntas e salve as respostas nos arquivos de spec relevantes.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Instrucao para a IA
|
|
99
|
+
|
|
100
|
+
Voce e um especialista em desenvolvimento de software e analise de requisitos.
|
|
101
|
+
Analise o spec abaixo de um projeto em desenvolvimento e identifique:
|
|
102
|
+
|
|
103
|
+
1. **Gaps de negocio** — informacoes sobre o negocio que estao faltando ou vagas
|
|
104
|
+
2. **Gaps tecnicos** — decisoes arquiteturais nao documentadas ou ambiguas
|
|
105
|
+
3. **Riscos nao mapeados** — situacoes de risco que nao foram identificadas
|
|
106
|
+
4. **Regras de negocio implicitas** — comportamentos que provavelmente existem mas nao estao documentados
|
|
107
|
+
5. **Ambiguidades** — partes do spec que podem ser interpretadas de formas diferentes
|
|
108
|
+
|
|
109
|
+
Para cada gap identificado, faca UMA pergunta clara e direta ao dev.
|
|
110
|
+
Organize as perguntas por prioridade — comece pelas mais criticas para o desenvolvimento.
|
|
111
|
+
Limite a no maximo 15 perguntas — foque no que realmente importa.
|
|
112
|
+
|
|
113
|
+
Apos o dev responder, indique em qual arquivo de spec cada resposta deve ser salva:
|
|
114
|
+
- Regras de negocio → .spec/requirements.md
|
|
115
|
+
- Decisoes tecnicas → .spec/architecture.md
|
|
116
|
+
- Riscos → .spec/risks.md
|
|
117
|
+
- Perfis de usuario → .spec/users.md
|
|
118
|
+
- Regras do projeto → .spec/rules.md
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Spec atual do projeto
|
|
123
|
+
|
|
124
|
+
${specConteudo}
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Formato esperado da sua resposta
|
|
129
|
+
|
|
130
|
+
Comece com um resumo de 2-3 linhas do que voce entendeu sobre o projeto.
|
|
131
|
+
Depois liste as perguntas numeradas, cada uma com:
|
|
132
|
+
- A pergunta em si
|
|
133
|
+
- Por que essa informacao e importante
|
|
134
|
+
- Onde a resposta deve ser salva
|
|
135
|
+
|
|
136
|
+
Exemplo:
|
|
137
|
+
**Pergunta 1:** Como o sistema lida com usuarios inativos?
|
|
138
|
+
**Importancia:** Afeta logica de autenticacao e limpeza de dados
|
|
139
|
+
**Salvar em:** .spec/requirements.md e .spec/rules.md
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
function sleep(ms) {
|
|
143
|
+
return new Promise(r => setTimeout(r, ms));
|
|
144
|
+
}
|
package/dist/commands/setup.js
CHANGED
|
@@ -246,6 +246,24 @@ async function runSetup() {
|
|
|
246
246
|
fs.writeFileSync(arq.path, arq.conteudo, 'utf-8');
|
|
247
247
|
s.succeed(path.relative(process.cwd(), arq.path));
|
|
248
248
|
}
|
|
249
|
+
// ── Git hook ───────────────────────────────────────────────────────────────
|
|
250
|
+
const gitHookDir = path.join(process.cwd(), '.git', 'hooks');
|
|
251
|
+
const hookPath = path.join(gitHookDir, 'pre-push');
|
|
252
|
+
if (fs.existsSync(path.join(process.cwd(), '.git'))) {
|
|
253
|
+
const sHook = (0, ora_1.default)('Configurando git hook pre-push...').start();
|
|
254
|
+
await sleep(400);
|
|
255
|
+
if (!fs.existsSync(gitHookDir))
|
|
256
|
+
fs.mkdirSync(gitHookDir, { recursive: true });
|
|
257
|
+
fs.writeFileSync(hookPath, gerarPrePushHook(), 'utf-8');
|
|
258
|
+
try {
|
|
259
|
+
fs.chmodSync(hookPath, '755');
|
|
260
|
+
}
|
|
261
|
+
catch { }
|
|
262
|
+
sHook.succeed('.git/hooks/pre-push configurado');
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
console.log(chalk_1.default.yellow(' ⚠ Repositorio git nao encontrado — hook nao configurado'));
|
|
266
|
+
}
|
|
249
267
|
console.log(chalk_1.default.green.bold('\n✅ Setup concluído!\n'));
|
|
250
268
|
console.log(chalk_1.default.gray(' Protocolo da IA configurado para Claude Code, Codex CLI e Cursor\n'));
|
|
251
269
|
console.log(chalk_1.default.gray(' Próximo passo: ') + chalk_1.default.white('vireum-spec prioritize') + chalk_1.default.gray(' para classificar as features\n'));
|
|
@@ -265,6 +283,30 @@ function sleep(ms) {
|
|
|
265
283
|
return new Promise(r => setTimeout(r, ms));
|
|
266
284
|
}
|
|
267
285
|
// ─── GERADORES ────────────────────────────────────────────────────────────────
|
|
286
|
+
function gerarPrePushHook() {
|
|
287
|
+
return `#!/bin/sh
|
|
288
|
+
# Vireum Spec — Health Check automatico pre-push
|
|
289
|
+
# Gerado por vireum-spec setup
|
|
290
|
+
|
|
291
|
+
echo ""
|
|
292
|
+
echo " Vireum Spec — verificando consistencia do spec..."
|
|
293
|
+
echo ""
|
|
294
|
+
|
|
295
|
+
npx vireum-spec-cli health
|
|
296
|
+
|
|
297
|
+
STATUS=$?
|
|
298
|
+
|
|
299
|
+
if [ $STATUS -ne 0 ]; then
|
|
300
|
+
echo ""
|
|
301
|
+
echo " Spec com problemas criticos. Corrija antes de fazer push."
|
|
302
|
+
echo " Execute: vireum-spec health para detalhes"
|
|
303
|
+
echo ""
|
|
304
|
+
exit 1
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
exit 0
|
|
308
|
+
`;
|
|
309
|
+
}
|
|
268
310
|
function gerarArchitecture(d) {
|
|
269
311
|
const { stack, infra, mcps, projeto } = d;
|
|
270
312
|
const tenant = stack.multiTenant
|
|
@@ -347,6 +389,11 @@ function gerarRulesGlobal() {
|
|
|
347
389
|
- Nunca hardcodar cores — usar sempre os tokens definidos em design.md
|
|
348
390
|
- Nunca misturar design systems
|
|
349
391
|
|
|
392
|
+
## Regras de Health
|
|
393
|
+
- Verificar consistencia do spec no inicio de cada sessao
|
|
394
|
+
- Avisar o dev sobre inconsistencias antes de qualquer implementacao
|
|
395
|
+
- Tasks sem criterios de aceitacao devem ser sinalizadas antes de implementar
|
|
396
|
+
|
|
350
397
|
## Regras de Spec
|
|
351
398
|
- Nunca marcar task como done sem validar os critérios de aceitação
|
|
352
399
|
- Nunca tomar decisão de arquitetura sem registrar em architecture.md com justificativa
|
|
@@ -414,8 +461,13 @@ function gerarClaudeMd(d) {
|
|
|
414
461
|
|
|
415
462
|
## Início de cada sessão
|
|
416
463
|
1. Leia \`.spec/INDEX.md\` — estado atual do projeto
|
|
417
|
-
2.
|
|
418
|
-
|
|
464
|
+
2. Verifique consistencia do spec:
|
|
465
|
+
- tasks/active.md tem tasks sem criterios de aceitacao? → avisar o dev
|
|
466
|
+
- architecture.md tem stack definida? → se nao, avisar
|
|
467
|
+
- INDEX.md reflete o estado real do MVP? → se desatualizado, avisar
|
|
468
|
+
3. Se encontrar inconsistencias criticas → avisar antes de qualquer implementacao
|
|
469
|
+
4. Identifique o modo da sessão pela solicitação do dev
|
|
470
|
+
5. Carregue arquivos adicionais apenas se a task exigir
|
|
419
471
|
|
|
420
472
|
## Modos de operação
|
|
421
473
|
|
|
@@ -485,6 +537,7 @@ ${mcps.map((m) => `- ${m}`).join('\n')}
|
|
|
485
537
|
- Decisão de lib nova: registrar em architecture.md antes de usar
|
|
486
538
|
- Risco identificado: adicionar em risks.md antes de continuar
|
|
487
539
|
- UI sem consultar design.md → PARAR e consultar primeiro
|
|
540
|
+
- Spec inconsistente → avisar o dev antes de implementar
|
|
488
541
|
`;
|
|
489
542
|
}
|
|
490
543
|
function gerarAgentsMd(d) {
|
|
@@ -495,8 +548,10 @@ function gerarAgentsMd(d) {
|
|
|
495
548
|
|
|
496
549
|
## Início de cada sessão
|
|
497
550
|
1. Leia \`.spec/INDEX.md\`
|
|
498
|
-
2.
|
|
499
|
-
3.
|
|
551
|
+
2. Verifique consistencia do spec — tasks sem criterios, stack indefinida, INDEX desatualizado
|
|
552
|
+
3. Avise o dev sobre inconsistencias antes de implementar
|
|
553
|
+
4. Identifique o modo pela solicitação
|
|
554
|
+
5. Siga o protocolo em CLAUDE.md
|
|
500
555
|
|
|
501
556
|
## Planejamento obrigatorio
|
|
502
557
|
Antes de qualquer implementacao:
|
|
@@ -535,6 +590,8 @@ Este projeto usa Spec Driven Development pela Vireum Desenvolvimento.
|
|
|
535
590
|
|
|
536
591
|
## Início de sessão
|
|
537
592
|
- Sempre leia \`.spec/INDEX.md\` primeiro
|
|
593
|
+
- Verifique consistencia: tasks sem criterios, stack indefinida, INDEX desatualizado
|
|
594
|
+
- Avise inconsistencias antes de qualquer implementacao
|
|
538
595
|
- Carregue outros arquivos de spec apenas quando necessário
|
|
539
596
|
|
|
540
597
|
## Planejamento obrigatorio
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ const brief_1 = require("./commands/brief");
|
|
|
15
15
|
const verify_mcps_1 = require("./commands/verify-mcps");
|
|
16
16
|
const skills_1 = require("./commands/skills");
|
|
17
17
|
const retrofit_1 = require("./commands/retrofit");
|
|
18
|
+
const enrich_1 = require("./commands/enrich");
|
|
18
19
|
const program = new commander_1.Command();
|
|
19
20
|
program
|
|
20
21
|
.name('vireum-spec')
|
|
@@ -56,5 +57,9 @@ program
|
|
|
56
57
|
.command('retrofit')
|
|
57
58
|
.description('Gera o spec a partir de um projeto ja em andamento')
|
|
58
59
|
.action(async () => { await (0, retrofit_1.runRetrofit)(); });
|
|
60
|
+
program
|
|
61
|
+
.command('enrich')
|
|
62
|
+
.description('Gera prompt para a IA identificar gaps no spec')
|
|
63
|
+
.action(async () => { await (0, enrich_1.runEnrich)(); });
|
|
59
64
|
console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec Framework\n'));
|
|
60
65
|
program.parse(process.argv);
|