vireum-spec-cli 0.3.1 → 0.4.1
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 +227 -8
- package/package.json +1 -1
package/dist/commands/setup.js
CHANGED
|
@@ -158,14 +158,74 @@ async function runSetup() {
|
|
|
158
158
|
{ name: 'redis — inspecionar cache e filas', value: 'redis', checked: false },
|
|
159
159
|
],
|
|
160
160
|
});
|
|
161
|
-
// Context7 sempre presente
|
|
162
161
|
const mcpsFinais = mcpsSelecionados.includes('context7')
|
|
163
162
|
? mcpsSelecionados
|
|
164
163
|
: ['context7', ...mcpsSelecionados];
|
|
164
|
+
// ── Design System ──────────────────────────────────────────────────────────
|
|
165
|
+
console.log(chalk_1.default.hex('#2D7DD2').bold('\n🎨 Design System\n'));
|
|
166
|
+
const designSystem = await (0, prompts_1.select)({
|
|
167
|
+
message: 'Design system do projeto:',
|
|
168
|
+
choices: [
|
|
169
|
+
{ name: 'Shadcn/ui — componentes com Tailwind e Radix', value: 'shadcn' },
|
|
170
|
+
{ name: 'Tailwind — utilitários CSS puro', value: 'tailwind' },
|
|
171
|
+
{ name: 'Chakra UI — componentes React acessíveis', value: 'chakra' },
|
|
172
|
+
{ name: 'Material UI — componentes Google Material', value: 'mui' },
|
|
173
|
+
{ name: 'Custom — design system próprio', value: 'custom' },
|
|
174
|
+
{ name: 'Nenhum — sem design system definido', value: 'none' },
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
const design = { system: designSystem, cores: {}, fontes: {}, customizacoes: '', gerarBase: false, baseTailwind: false };
|
|
178
|
+
if (['shadcn', 'tailwind', 'chakra', 'mui'].includes(designSystem)) {
|
|
179
|
+
const temCustom = await (0, prompts_1.confirm)({
|
|
180
|
+
message: 'Tem customizacoes? (cores da marca, fontes especificas?)',
|
|
181
|
+
default: false,
|
|
182
|
+
});
|
|
183
|
+
if (temCustom) {
|
|
184
|
+
design.cores.primary = await (0, prompts_1.input)({ message: 'Cor primaria (ex: #2D7DD2 ou blue-600):', default: '' });
|
|
185
|
+
design.cores.secondary = await (0, prompts_1.input)({ message: 'Cor secundaria (ex: #1A3A5C ou slate-800):', default: '' });
|
|
186
|
+
design.cores.accent = await (0, prompts_1.input)({ message: 'Cor de destaque (ex: #1D9E75 ou green-500):', default: '' });
|
|
187
|
+
design.fontes.heading = await (0, prompts_1.input)({ message: 'Fonte de titulos (ex: Inter, Geist):', default: '' });
|
|
188
|
+
design.fontes.body = await (0, prompts_1.input)({ message: 'Fonte de corpo (ex: Inter, Roboto):', default: '' });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (designSystem === 'custom') {
|
|
192
|
+
const preencherAgora = await (0, prompts_1.confirm)({
|
|
193
|
+
message: 'Quer preencher o design system agora?',
|
|
194
|
+
default: true,
|
|
195
|
+
});
|
|
196
|
+
if (preencherAgora) {
|
|
197
|
+
design.cores.primary = await (0, prompts_1.input)({ message: 'Cor primaria:', default: '' });
|
|
198
|
+
design.cores.secondary = await (0, prompts_1.input)({ message: 'Cor secundaria:', default: '' });
|
|
199
|
+
design.cores.accent = await (0, prompts_1.input)({ message: 'Cor de destaque:', default: '' });
|
|
200
|
+
design.cores.background = await (0, prompts_1.input)({ message: 'Cor de fundo:', default: '' });
|
|
201
|
+
design.cores.text = await (0, prompts_1.input)({ message: 'Cor de texto:', default: '' });
|
|
202
|
+
design.fontes.heading = await (0, prompts_1.input)({ message: 'Fonte de titulos:', default: '' });
|
|
203
|
+
design.fontes.body = await (0, prompts_1.input)({ message: 'Fonte de corpo:', default: '' });
|
|
204
|
+
design.customizacoes = await (0, prompts_1.input)({ message: 'Componentes ou convencoes importantes (Enter para pular):', default: '' });
|
|
205
|
+
}
|
|
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
|
+
}
|
|
165
225
|
// ── Gerar arquivos ─────────────────────────────────────────────────────────
|
|
166
226
|
console.log('');
|
|
167
227
|
const projeto = extrairProjeto(path.join(specDir, 'INDEX.md'));
|
|
168
|
-
const dados = { stack, infra, mcps: mcpsFinais, projeto };
|
|
228
|
+
const dados = { stack, infra, mcps: mcpsFinais, projeto, design };
|
|
169
229
|
for (const dir of [vireumDir, cursorDir]) {
|
|
170
230
|
if (!fs.existsSync(dir))
|
|
171
231
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -173,6 +233,7 @@ async function runSetup() {
|
|
|
173
233
|
const arquivos = [
|
|
174
234
|
{ path: path.join(specDir, 'architecture.md'), conteudo: gerarArchitecture(dados), msg: 'Atualizando architecture.md...' },
|
|
175
235
|
{ path: path.join(specDir, 'mcp-setup.md'), conteudo: gerarMcpSetup(dados), msg: 'Gerando mcp-setup.md...' },
|
|
236
|
+
{ path: path.join(specDir, 'design.md'), conteudo: gerarDesign(dados), msg: 'Gerando design.md...' },
|
|
176
237
|
{ path: path.join(vireumDir, 'rules.md'), conteudo: gerarRulesGlobal(), msg: 'Gerando .vireum/rules.md...' },
|
|
177
238
|
{ path: path.join(vireumDir, 'mcps.md'), conteudo: gerarMcpsGlobal(dados), msg: 'Gerando .vireum/mcps.md...' },
|
|
178
239
|
{ path: path.join(process.cwd(), 'CLAUDE.md'), conteudo: gerarClaudeMd(dados), msg: 'Gerando CLAUDE.md...' },
|
|
@@ -281,6 +342,11 @@ function gerarRulesGlobal() {
|
|
|
281
342
|
- Confirmar o plano com o dev em tasks complexas antes de executar
|
|
282
343
|
- Nunca comecar a escrever codigo sem ter um plano claro
|
|
283
344
|
|
|
345
|
+
## Regras de Design
|
|
346
|
+
- Sempre consultar .spec/design.md antes de criar ou modificar qualquer componente de UI
|
|
347
|
+
- Nunca hardcodar cores — usar sempre os tokens definidos em design.md
|
|
348
|
+
- Nunca misturar design systems
|
|
349
|
+
|
|
284
350
|
## Regras de Spec
|
|
285
351
|
- Nunca marcar task como done sem validar os critérios de aceitação
|
|
286
352
|
- Nunca tomar decisão de arquitetura sem registrar em architecture.md com justificativa
|
|
@@ -300,6 +366,7 @@ function gerarRulesGlobal() {
|
|
|
300
366
|
## Nunca
|
|
301
367
|
- Implementar sem ler o spec primeiro
|
|
302
368
|
- Implementar sem planejar primeiro
|
|
369
|
+
- Criar componente de UI sem consultar design.md
|
|
303
370
|
- Tomar decisão de lib ou stack sem documentar o porquê
|
|
304
371
|
- Responder dúvida de escopo sem consultar requirements.md
|
|
305
372
|
- Comunicar diretamente com o cliente — isso é papel do dev
|
|
@@ -357,11 +424,12 @@ Acionado por: "desenvolve", "implementa", "cria", + nome de task
|
|
|
357
424
|
1. Leia \`.spec/tasks/active.md\`
|
|
358
425
|
2. Leia \`.spec/requirements.md\` para contexto da feature
|
|
359
426
|
3. Consulte o Context7 para docs atualizadas da lib que vai usar
|
|
360
|
-
4.
|
|
361
|
-
5.
|
|
362
|
-
6.
|
|
363
|
-
7.
|
|
364
|
-
8.
|
|
427
|
+
4. Se task de UI: leia \`.spec/design.md\` antes de qualquer componente
|
|
428
|
+
5. PLANEJAR: escreva o que sera implementado, quais arquivos serao tocados e riscos identificados
|
|
429
|
+
6. Confirme o plano com o dev antes de executar em tasks complexas
|
|
430
|
+
7. Implemente seguindo os critérios de aceitação da task
|
|
431
|
+
8. Ao concluir: marque como done, mova para \`tasks/done.md\`, atualize \`INDEX.md\`
|
|
432
|
+
9. Se decisão arquitetural tomada: registre em \`architecture.md\`
|
|
365
433
|
|
|
366
434
|
### Modo 2 — Bug
|
|
367
435
|
Acionado por: "erro", "bug", "quebrou", "não funciona"
|
|
@@ -388,6 +456,15 @@ Sempre que for usar uma lib do projeto, consulte a documentação atualizada via
|
|
|
388
456
|
Nunca assuma que você conhece a API mais recente — sempre verifique.
|
|
389
457
|
Libs deste projeto: ${libs}
|
|
390
458
|
|
|
459
|
+
## Arquivos de contexto disponíveis
|
|
460
|
+
- Escopo e features → leia \`.spec/requirements.md\`
|
|
461
|
+
- Decisoes tecnicas → leia \`.spec/architecture.md\`
|
|
462
|
+
- Perfis e permissoes → leia \`.spec/users.md\`
|
|
463
|
+
- Riscos → leia \`.spec/risks.md\`
|
|
464
|
+
- Tarefas ativas → leia \`.spec/tasks/active.md\`
|
|
465
|
+
- Historico → leia \`.spec/changelog.md\`
|
|
466
|
+
- Design e componentes → leia \`.spec/design.md\` antes de qualquer UI
|
|
467
|
+
|
|
391
468
|
## Regras globais
|
|
392
469
|
Leia \`.vireum/rules.md\` — aplicam-se a todas as sessões.
|
|
393
470
|
|
|
@@ -407,6 +484,7 @@ ${mcps.map((m) => `- ${m}`).join('\n')}
|
|
|
407
484
|
- Escopo creep: se a solicitação não está em requirements.md → PARAR e avisar
|
|
408
485
|
- Decisão de lib nova: registrar em architecture.md antes de usar
|
|
409
486
|
- Risco identificado: adicionar em risks.md antes de continuar
|
|
487
|
+
- UI sem consultar design.md → PARAR e consultar primeiro
|
|
410
488
|
`;
|
|
411
489
|
}
|
|
412
490
|
function gerarAgentsMd(d) {
|
|
@@ -426,6 +504,9 @@ Antes de qualquer implementacao:
|
|
|
426
504
|
2. Identifique riscos e dependencias
|
|
427
505
|
3. Confirme com o dev em tasks complexas antes de executar
|
|
428
506
|
|
|
507
|
+
## Design
|
|
508
|
+
Sempre consultar \`.spec/design.md\` antes de criar ou modificar qualquer componente de UI.
|
|
509
|
+
|
|
429
510
|
## Context7
|
|
430
511
|
Sempre consultar docs atualizadas via Context7 antes de usar qualquer lib.
|
|
431
512
|
|
|
@@ -462,12 +543,16 @@ Antes de qualquer implementacao:
|
|
|
462
543
|
- Identifique riscos e dependencias
|
|
463
544
|
- Confirme com o dev em tasks complexas antes de executar
|
|
464
545
|
|
|
546
|
+
## Design
|
|
547
|
+
- SEMPRE leia \`.spec/design.md\` antes de criar ou modificar qualquer componente de UI
|
|
548
|
+
- Nunca hardcodar cores — usar tokens do design.md
|
|
549
|
+
|
|
465
550
|
## Context7
|
|
466
551
|
- Sempre consultar Context7 antes de usar qualquer lib do projeto
|
|
467
552
|
- Nunca assumir que conhece a API mais recente
|
|
468
553
|
|
|
469
554
|
## Modos
|
|
470
|
-
- Implementar → PLANEJAR primeiro, consulte Context7, leia tasks/active.md,
|
|
555
|
+
- Implementar → PLANEJAR primeiro, consulte Context7, leia tasks/active.md, se UI leia design.md
|
|
471
556
|
- Bug → PLANEJAR investigacao, crie hotfix [H] em active.md, registre causa raiz em changelog.md
|
|
472
557
|
- Nova demanda → crie [PENDING] em backlog.md, aguarde aprovação
|
|
473
558
|
- Dúvida de escopo → consulte requirements.md
|
|
@@ -477,6 +562,140 @@ Antes de qualquer implementacao:
|
|
|
477
562
|
- Ver \`.spec/rules.md\` — regras do projeto
|
|
478
563
|
- Nunca implementar fora do spec sem [PENDING] aprovado
|
|
479
564
|
- Nunca implementar sem planejar primeiro
|
|
565
|
+
- Nunca criar UI sem consultar design.md
|
|
480
566
|
- Nunca marcar done sem critérios validados
|
|
481
567
|
`;
|
|
482
568
|
}
|
|
569
|
+
function gerarDesign(d) {
|
|
570
|
+
const { design, projeto } = d;
|
|
571
|
+
const sistemas = {
|
|
572
|
+
shadcn: {
|
|
573
|
+
descricao: 'Shadcn/ui com Tailwind CSS e Radix UI',
|
|
574
|
+
convencoes: [
|
|
575
|
+
'Usar cn() para mesclar classes Tailwind',
|
|
576
|
+
'Componentes em src/components/ui/',
|
|
577
|
+
'Variaveis CSS em globals.css via --primary, --secondary, etc.',
|
|
578
|
+
'Icones via lucide-react',
|
|
579
|
+
'Formularios com react-hook-form + zod',
|
|
580
|
+
],
|
|
581
|
+
tokens: 'Tailwind config + CSS variables',
|
|
582
|
+
},
|
|
583
|
+
tailwind: {
|
|
584
|
+
descricao: 'Tailwind CSS puro',
|
|
585
|
+
convencoes: [
|
|
586
|
+
'Classes utilitarias diretamente nos componentes',
|
|
587
|
+
'Cores customizadas em tailwind.config.ts',
|
|
588
|
+
'Componentes em src/components/',
|
|
589
|
+
'Nao criar classes CSS customizadas sem necessidade',
|
|
590
|
+
],
|
|
591
|
+
tokens: 'tailwind.config.ts',
|
|
592
|
+
},
|
|
593
|
+
chakra: {
|
|
594
|
+
descricao: 'Chakra UI',
|
|
595
|
+
convencoes: [
|
|
596
|
+
'Usar componentes do Chakra sempre que disponivel',
|
|
597
|
+
'Theme customizado em src/theme/',
|
|
598
|
+
'Variaveis de cor via useColorModeValue para dark/light mode',
|
|
599
|
+
'Spacing seguindo escala do Chakra (1 = 4px)',
|
|
600
|
+
],
|
|
601
|
+
tokens: 'ChakraProvider theme',
|
|
602
|
+
},
|
|
603
|
+
mui: {
|
|
604
|
+
descricao: 'Material UI (MUI)',
|
|
605
|
+
convencoes: [
|
|
606
|
+
'Usar componentes MUI sempre que disponivel',
|
|
607
|
+
'Theme customizado em src/theme/index.ts',
|
|
608
|
+
'Usar sx prop para customizacoes pontuais',
|
|
609
|
+
'Evitar inline styles — preferir theme tokens',
|
|
610
|
+
],
|
|
611
|
+
tokens: 'createTheme()',
|
|
612
|
+
},
|
|
613
|
+
base: {
|
|
614
|
+
descricao: 'Design system basico gerado pelo Vireum Spec Framework',
|
|
615
|
+
convencoes: [
|
|
616
|
+
`Usar ${design.baseTailwind ? 'Tailwind CSS' : 'CSS customizado'} para estilizacao`,
|
|
617
|
+
'Tokens de cor definidos neste arquivo — nunca hardcodar valores',
|
|
618
|
+
'Componentes em src/components/',
|
|
619
|
+
'Tipografia consistente — usar apenas as fontes definidas aqui',
|
|
620
|
+
'Espacamento em multiplos de 4px',
|
|
621
|
+
'Bordas arredondadas padrao: 8px',
|
|
622
|
+
],
|
|
623
|
+
tokens: design.baseTailwind ? 'tailwind.config.ts + CSS variables' : 'CSS variables em globals.css',
|
|
624
|
+
},
|
|
625
|
+
custom: {
|
|
626
|
+
descricao: 'Design system proprio',
|
|
627
|
+
convencoes: ['Ver secao de convencoes abaixo'],
|
|
628
|
+
tokens: 'Ver secao de tokens abaixo',
|
|
629
|
+
},
|
|
630
|
+
none: {
|
|
631
|
+
descricao: 'Sem design system definido',
|
|
632
|
+
convencoes: ['A definir'],
|
|
633
|
+
tokens: 'A definir',
|
|
634
|
+
},
|
|
635
|
+
};
|
|
636
|
+
const ds = sistemas[design.system] || sistemas.none;
|
|
637
|
+
const coresSection = Object.keys(design.cores).filter(k => design.cores[k]).length
|
|
638
|
+
? Object.entries(design.cores)
|
|
639
|
+
.filter(([, v]) => v)
|
|
640
|
+
.map(([k, v]) => `- ${k}: ${v}`)
|
|
641
|
+
.join('\n')
|
|
642
|
+
: `> Usar tokens padrao do ${ds.descricao}`;
|
|
643
|
+
const fontesSection = Object.keys(design.fontes).filter(k => design.fontes[k]).length
|
|
644
|
+
? Object.entries(design.fontes)
|
|
645
|
+
.filter(([, v]) => v)
|
|
646
|
+
.map(([k, v]) => `- ${k}: ${v}`)
|
|
647
|
+
.join('\n')
|
|
648
|
+
: '> Usar fonte padrao do sistema';
|
|
649
|
+
const baseSection = design.system === 'base' ? `
|
|
650
|
+
## Espacamento
|
|
651
|
+
- Base: 4px
|
|
652
|
+
- xs: 4px | sm: 8px | md: 16px | lg: 24px | xl: 32px | 2xl: 48px
|
|
653
|
+
|
|
654
|
+
## Bordas
|
|
655
|
+
- Radius padrao: 8px
|
|
656
|
+
- Radius pequeno: 4px
|
|
657
|
+
- Radius grande: 16px
|
|
658
|
+
- Radius pill: 9999px
|
|
659
|
+
|
|
660
|
+
## Sombras
|
|
661
|
+
- sm: 0 1px 2px rgba(0,0,0,0.05)
|
|
662
|
+
- md: 0 4px 6px rgba(0,0,0,0.07)
|
|
663
|
+
- lg: 0 10px 15px rgba(0,0,0,0.10)
|
|
664
|
+
` : '';
|
|
665
|
+
return `# Design — ${projeto}
|
|
666
|
+
|
|
667
|
+
> A IA deve consultar este arquivo antes de criar ou modificar qualquer componente de UI.
|
|
668
|
+
> Nunca usar cores, fontes ou espacamentos fora dos tokens definidos aqui.
|
|
669
|
+
|
|
670
|
+
## Design System
|
|
671
|
+
**${ds.descricao}**
|
|
672
|
+
- Tokens: ${ds.tokens}
|
|
673
|
+
|
|
674
|
+
## Cores
|
|
675
|
+
${coresSection}
|
|
676
|
+
|
|
677
|
+
## Fontes
|
|
678
|
+
${fontesSection}
|
|
679
|
+
|
|
680
|
+
## Convencoes
|
|
681
|
+
${ds.convencoes.map((c) => `- ${c}`).join('\n')}
|
|
682
|
+
${design.customizacoes ? `\n## Convencoes Customizadas\n${design.customizacoes}` : ''}
|
|
683
|
+
${baseSection}
|
|
684
|
+
## Regras para a IA
|
|
685
|
+
- Nunca criar componente sem consultar este arquivo primeiro
|
|
686
|
+
- Nunca hardcodar cores — usar sempre os tokens definidos acima
|
|
687
|
+
- Nunca misturar design systems — usar apenas ${ds.descricao}
|
|
688
|
+
- Novos componentes seguem as convencoes desta secao
|
|
689
|
+
- Em caso de duvida sobre UI, perguntar ao dev antes de implementar
|
|
690
|
+
${design.system === 'shadcn' ? '- Sempre usar cn() para mesclar classes condicionais\n- Preferir componentes do Shadcn antes de criar do zero' : ''}
|
|
691
|
+
${design.system === 'tailwind' ? '- Preferir classes Tailwind a CSS customizado\n- Nao criar novas classes sem necessidade real' : ''}
|
|
692
|
+
${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'}` : ''}
|
|
693
|
+
|
|
694
|
+
## Componentes Existentes
|
|
695
|
+
> A IA deve atualizar esta secao conforme novos componentes sao criados
|
|
696
|
+
|
|
697
|
+
| Componente | Localizacao | Descricao |
|
|
698
|
+
|------------|-------------|-----------|
|
|
699
|
+
| | | |
|
|
700
|
+
`;
|
|
701
|
+
}
|