vireum-spec-cli 0.4.0 → 0.4.2
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/setup.js +110 -6
- package/package.json +1 -1
package/dist/commands/setup.js
CHANGED
|
@@ -174,7 +174,7 @@ async function runSetup() {
|
|
|
174
174
|
{ name: 'Nenhum — sem design system definido', value: 'none' },
|
|
175
175
|
],
|
|
176
176
|
});
|
|
177
|
-
const design = { system: designSystem, cores: {}, fontes: {}, customizacoes: '' };
|
|
177
|
+
const design = { system: designSystem, cores: {}, fontes: {}, customizacoes: '', gerarBase: false, baseTailwind: false };
|
|
178
178
|
if (['shadcn', 'tailwind', 'chakra', 'mui'].includes(designSystem)) {
|
|
179
179
|
const temCustom = await (0, prompts_1.confirm)({
|
|
180
180
|
message: 'Tem customizacoes? (cores da marca, fontes especificas?)',
|
|
@@ -204,6 +204,24 @@ async function runSetup() {
|
|
|
204
204
|
design.customizacoes = await (0, prompts_1.input)({ message: 'Componentes ou convencoes importantes (Enter para pular):', default: '' });
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
|
+
if (designSystem === 'none') {
|
|
208
|
+
const criarBase = await (0, prompts_1.confirm)({
|
|
209
|
+
message: 'Quer criar uma estrutura de design basica para o projeto?',
|
|
210
|
+
default: true,
|
|
211
|
+
});
|
|
212
|
+
if (criarBase) {
|
|
213
|
+
design.system = 'base';
|
|
214
|
+
design.gerarBase = true;
|
|
215
|
+
design.baseTailwind = await (0, prompts_1.confirm)({ message: 'Usar Tailwind CSS como base?', default: true });
|
|
216
|
+
design.cores.primary = await (0, prompts_1.input)({ message: 'Cor primaria (Enter para #2D7DD2):', default: '#2D7DD2' });
|
|
217
|
+
design.cores.secondary = await (0, prompts_1.input)({ message: 'Cor secundaria (Enter para #1A3A5C):', default: '#1A3A5C' });
|
|
218
|
+
design.cores.accent = await (0, prompts_1.input)({ message: 'Cor de destaque (Enter para #1D9E75):', default: '#1D9E75' });
|
|
219
|
+
design.cores.background = await (0, prompts_1.input)({ message: 'Cor de fundo (Enter para #F4F7FB):', default: '#F4F7FB' });
|
|
220
|
+
design.cores.text = await (0, prompts_1.input)({ message: 'Cor de texto (Enter para #1A1A2E):', default: '#1A1A2E' });
|
|
221
|
+
design.fontes.heading = await (0, prompts_1.input)({ message: 'Fonte de titulos (Enter para Inter):', default: 'Inter' });
|
|
222
|
+
design.fontes.body = await (0, prompts_1.input)({ message: 'Fonte de corpo (Enter para Inter):', default: 'Inter' });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
207
225
|
// ── Gerar arquivos ─────────────────────────────────────────────────────────
|
|
208
226
|
console.log('');
|
|
209
227
|
const projeto = extrairProjeto(path.join(specDir, 'INDEX.md'));
|
|
@@ -228,6 +246,24 @@ async function runSetup() {
|
|
|
228
246
|
fs.writeFileSync(arq.path, arq.conteudo, 'utf-8');
|
|
229
247
|
s.succeed(path.relative(process.cwd(), arq.path));
|
|
230
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
|
+
}
|
|
231
267
|
console.log(chalk_1.default.green.bold('\n✅ Setup concluído!\n'));
|
|
232
268
|
console.log(chalk_1.default.gray(' Protocolo da IA configurado para Claude Code, Codex CLI e Cursor\n'));
|
|
233
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'));
|
|
@@ -247,6 +283,30 @@ function sleep(ms) {
|
|
|
247
283
|
return new Promise(r => setTimeout(r, ms));
|
|
248
284
|
}
|
|
249
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
|
+
}
|
|
250
310
|
function gerarArchitecture(d) {
|
|
251
311
|
const { stack, infra, mcps, projeto } = d;
|
|
252
312
|
const tenant = stack.multiTenant
|
|
@@ -329,6 +389,11 @@ function gerarRulesGlobal() {
|
|
|
329
389
|
- Nunca hardcodar cores — usar sempre os tokens definidos em design.md
|
|
330
390
|
- Nunca misturar design systems
|
|
331
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
|
+
|
|
332
397
|
## Regras de Spec
|
|
333
398
|
- Nunca marcar task como done sem validar os critérios de aceitação
|
|
334
399
|
- Nunca tomar decisão de arquitetura sem registrar em architecture.md com justificativa
|
|
@@ -396,8 +461,13 @@ function gerarClaudeMd(d) {
|
|
|
396
461
|
|
|
397
462
|
## Início de cada sessão
|
|
398
463
|
1. Leia \`.spec/INDEX.md\` — estado atual do projeto
|
|
399
|
-
2.
|
|
400
|
-
|
|
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
|
|
401
471
|
|
|
402
472
|
## Modos de operação
|
|
403
473
|
|
|
@@ -467,6 +537,7 @@ ${mcps.map((m) => `- ${m}`).join('\n')}
|
|
|
467
537
|
- Decisão de lib nova: registrar em architecture.md antes de usar
|
|
468
538
|
- Risco identificado: adicionar em risks.md antes de continuar
|
|
469
539
|
- UI sem consultar design.md → PARAR e consultar primeiro
|
|
540
|
+
- Spec inconsistente → avisar o dev antes de implementar
|
|
470
541
|
`;
|
|
471
542
|
}
|
|
472
543
|
function gerarAgentsMd(d) {
|
|
@@ -477,8 +548,10 @@ function gerarAgentsMd(d) {
|
|
|
477
548
|
|
|
478
549
|
## Início de cada sessão
|
|
479
550
|
1. Leia \`.spec/INDEX.md\`
|
|
480
|
-
2.
|
|
481
|
-
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
|
|
482
555
|
|
|
483
556
|
## Planejamento obrigatorio
|
|
484
557
|
Antes de qualquer implementacao:
|
|
@@ -517,6 +590,8 @@ Este projeto usa Spec Driven Development pela Vireum Desenvolvimento.
|
|
|
517
590
|
|
|
518
591
|
## Início de sessão
|
|
519
592
|
- Sempre leia \`.spec/INDEX.md\` primeiro
|
|
593
|
+
- Verifique consistencia: tasks sem criterios, stack indefinida, INDEX desatualizado
|
|
594
|
+
- Avise inconsistencias antes de qualquer implementacao
|
|
520
595
|
- Carregue outros arquivos de spec apenas quando necessário
|
|
521
596
|
|
|
522
597
|
## Planejamento obrigatorio
|
|
@@ -592,6 +667,18 @@ function gerarDesign(d) {
|
|
|
592
667
|
],
|
|
593
668
|
tokens: 'createTheme()',
|
|
594
669
|
},
|
|
670
|
+
base: {
|
|
671
|
+
descricao: 'Design system basico gerado pelo Vireum Spec Framework',
|
|
672
|
+
convencoes: [
|
|
673
|
+
`Usar ${design.baseTailwind ? 'Tailwind CSS' : 'CSS customizado'} para estilizacao`,
|
|
674
|
+
'Tokens de cor definidos neste arquivo — nunca hardcodar valores',
|
|
675
|
+
'Componentes em src/components/',
|
|
676
|
+
'Tipografia consistente — usar apenas as fontes definidas aqui',
|
|
677
|
+
'Espacamento em multiplos de 4px',
|
|
678
|
+
'Bordas arredondadas padrao: 8px',
|
|
679
|
+
],
|
|
680
|
+
tokens: design.baseTailwind ? 'tailwind.config.ts + CSS variables' : 'CSS variables em globals.css',
|
|
681
|
+
},
|
|
595
682
|
custom: {
|
|
596
683
|
descricao: 'Design system proprio',
|
|
597
684
|
convencoes: ['Ver secao de convencoes abaixo'],
|
|
@@ -616,6 +703,22 @@ function gerarDesign(d) {
|
|
|
616
703
|
.map(([k, v]) => `- ${k}: ${v}`)
|
|
617
704
|
.join('\n')
|
|
618
705
|
: '> Usar fonte padrao do sistema';
|
|
706
|
+
const baseSection = design.system === 'base' ? `
|
|
707
|
+
## Espacamento
|
|
708
|
+
- Base: 4px
|
|
709
|
+
- xs: 4px | sm: 8px | md: 16px | lg: 24px | xl: 32px | 2xl: 48px
|
|
710
|
+
|
|
711
|
+
## Bordas
|
|
712
|
+
- Radius padrao: 8px
|
|
713
|
+
- Radius pequeno: 4px
|
|
714
|
+
- Radius grande: 16px
|
|
715
|
+
- Radius pill: 9999px
|
|
716
|
+
|
|
717
|
+
## Sombras
|
|
718
|
+
- sm: 0 1px 2px rgba(0,0,0,0.05)
|
|
719
|
+
- md: 0 4px 6px rgba(0,0,0,0.07)
|
|
720
|
+
- lg: 0 10px 15px rgba(0,0,0,0.10)
|
|
721
|
+
` : '';
|
|
619
722
|
return `# Design — ${projeto}
|
|
620
723
|
|
|
621
724
|
> A IA deve consultar este arquivo antes de criar ou modificar qualquer componente de UI.
|
|
@@ -634,7 +737,7 @@ ${fontesSection}
|
|
|
634
737
|
## Convencoes
|
|
635
738
|
${ds.convencoes.map((c) => `- ${c}`).join('\n')}
|
|
636
739
|
${design.customizacoes ? `\n## Convencoes Customizadas\n${design.customizacoes}` : ''}
|
|
637
|
-
|
|
740
|
+
${baseSection}
|
|
638
741
|
## Regras para a IA
|
|
639
742
|
- Nunca criar componente sem consultar este arquivo primeiro
|
|
640
743
|
- Nunca hardcodar cores — usar sempre os tokens definidos acima
|
|
@@ -643,6 +746,7 @@ ${design.customizacoes ? `\n## Convencoes Customizadas\n${design.customizacoes}`
|
|
|
643
746
|
- Em caso de duvida sobre UI, perguntar ao dev antes de implementar
|
|
644
747
|
${design.system === 'shadcn' ? '- Sempre usar cn() para mesclar classes condicionais\n- Preferir componentes do Shadcn antes de criar do zero' : ''}
|
|
645
748
|
${design.system === 'tailwind' ? '- Preferir classes Tailwind a CSS customizado\n- Nao criar novas classes sem necessidade real' : ''}
|
|
749
|
+
${design.system === 'base' ? `- Seguir tokens de espacamento e bordas definidos acima\n- ${design.baseTailwind ? 'Usar classes Tailwind mapeadas para os tokens' : 'Usar CSS variables definidas em globals.css'}` : ''}
|
|
646
750
|
|
|
647
751
|
## Componentes Existentes
|
|
648
752
|
> A IA deve atualizar esta secao conforme novos componentes sao criados
|