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.
@@ -39,9 +39,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.runSetup = runSetup;
40
40
  const chalk_1 = __importDefault(require("chalk"));
41
41
  const prompts_1 = require("@inquirer/prompts");
42
+ const crypto = __importStar(require("crypto"));
42
43
  const ora_1 = __importDefault(require("ora"));
43
44
  const fs = __importStar(require("fs"));
44
45
  const path = __importStar(require("path"));
46
+ const gen = __importStar(require("../lib/generators-setup"));
45
47
  async function runSetup() {
46
48
  console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Setup\n'));
47
49
  console.log(chalk_1.default.gray(' Configure a stack e o protocolo da IA para este projeto\n'));
@@ -230,31 +232,71 @@ async function runSetup() {
230
232
  if (!fs.existsSync(dir))
231
233
  fs.mkdirSync(dir, { recursive: true });
232
234
  }
235
+ // ── Verificar se .vireum/rules.md foi customizado ─────────────────────────
236
+ const rulesGlobalPath = path.join(vireumDir, 'rules.md');
237
+ const rulesGlobalConteudo = gen.gerarRulesGlobal();
238
+ let sobrescreverRules = true;
239
+ if (fs.existsSync(rulesGlobalPath)) {
240
+ const existente = fs.readFileSync(rulesGlobalPath, 'utf-8');
241
+ const hashExistente = md5(existente);
242
+ const hashNovo = md5(rulesGlobalConteudo);
243
+ if (hashExistente !== hashNovo) {
244
+ console.log(chalk_1.default.yellow('\n ⚠ .vireum/rules.md foi modificado manualmente.\n'));
245
+ sobrescreverRules = await (0, prompts_1.confirm)({
246
+ message: 'Sobrescrever .vireum/rules.md com a versão padrão do framework?',
247
+ default: false,
248
+ });
249
+ if (!sobrescreverRules) {
250
+ console.log(chalk_1.default.gray(' → .vireum/rules.md mantido sem alterações.\n'));
251
+ }
252
+ }
253
+ }
233
254
  const arquivos = [
234
- { path: path.join(specDir, 'architecture.md'), conteudo: gerarArchitecture(dados), msg: 'Atualizando architecture.md...' },
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...' },
237
- { path: path.join(vireumDir, 'rules.md'), conteudo: gerarRulesGlobal(), msg: 'Gerando .vireum/rules.md...' },
238
- { path: path.join(vireumDir, 'mcps.md'), conteudo: gerarMcpsGlobal(dados), msg: 'Gerando .vireum/mcps.md...' },
239
- { path: path.join(process.cwd(), 'CLAUDE.md'), conteudo: gerarClaudeMd(dados), msg: 'Gerando CLAUDE.md...' },
240
- { path: path.join(process.cwd(), 'AGENTS.md'), conteudo: gerarAgentsMd(dados), msg: 'Gerando AGENTS.md...' },
241
- { path: path.join(cursorDir, 'vireum.mdc'), conteudo: gerarCursorRules(dados), msg: 'Gerando .cursor/rules/vireum.mdc...' },
255
+ { path: path.join(specDir, 'architecture.md'), conteudo: gen.gerarArchitecture(dados), msg: 'Atualizando architecture.md...' },
256
+ { path: path.join(specDir, 'mcp-setup.md'), conteudo: gen.gerarMcpSetup(dados), msg: 'Gerando mcp-setup.md...' },
257
+ { path: path.join(specDir, 'design.md'), conteudo: gen.gerarDesign(dados), msg: 'Gerando design.md...' },
258
+ { path: path.join(vireumDir, 'mcps.md'), conteudo: gen.gerarMcpsGlobal(dados), msg: 'Gerando .vireum/mcps.md...' },
259
+ { path: path.join(process.cwd(), 'CLAUDE.md'), conteudo: gen.gerarClaudeMd(dados), msg: 'Gerando CLAUDE.md...' },
260
+ { path: path.join(process.cwd(), 'AGENTS.md'), conteudo: gen.gerarAgentsMd(dados), msg: 'Gerando AGENTS.md...' },
261
+ { path: path.join(cursorDir, 'vireum.mdc'), conteudo: gen.gerarCursorRules(dados), msg: 'Gerando .cursor/rules/vireum.mdc...' },
242
262
  ];
243
263
  for (const arq of arquivos) {
244
264
  const s = (0, ora_1.default)(arq.msg).start();
245
- await sleep(400);
246
265
  fs.writeFileSync(arq.path, arq.conteudo, 'utf-8');
247
266
  s.succeed(path.relative(process.cwd(), arq.path));
248
267
  }
268
+ if (sobrescreverRules) {
269
+ const s = (0, ora_1.default)('Gerando .vireum/rules.md...').start();
270
+ fs.writeFileSync(rulesGlobalPath, rulesGlobalConteudo, 'utf-8');
271
+ s.succeed('.vireum/rules.md');
272
+ }
273
+ // ── Hooks do Claude Code ──────────────────────────────────────────────────
274
+ const hooksDir = path.join(vireumDir, 'hooks');
275
+ const claudeDir = path.join(process.cwd(), '.claude');
276
+ if (!fs.existsSync(hooksDir))
277
+ fs.mkdirSync(hooksDir, { recursive: true });
278
+ if (!fs.existsSync(claudeDir))
279
+ fs.mkdirSync(claudeDir, { recursive: true });
280
+ const sHooks = (0, ora_1.default)('Gerando hooks do Claude Code...').start();
281
+ fs.writeFileSync(path.join(hooksDir, 'context-inject.sh'), gen.gerarContextInjectHook(), 'utf-8');
282
+ fs.writeFileSync(path.join(hooksDir, 'pre-tool-guard.sh'), gen.gerarPreToolGuardHook(), 'utf-8');
283
+ try {
284
+ fs.chmodSync(path.join(hooksDir, 'context-inject.sh'), '755');
285
+ fs.chmodSync(path.join(hooksDir, 'pre-tool-guard.sh'), '755');
286
+ }
287
+ catch { }
288
+ sHooks.succeed('.vireum/hooks/ configurado');
289
+ const sSettings = (0, ora_1.default)('Configurando .claude/settings.json...').start();
290
+ fs.writeFileSync(path.join(claudeDir, 'settings.json'), gen.gerarClaudeSettings(), 'utf-8');
291
+ sSettings.succeed('.claude/settings.json configurado');
249
292
  // ── Git hook ───────────────────────────────────────────────────────────────
250
293
  const gitHookDir = path.join(process.cwd(), '.git', 'hooks');
251
294
  const hookPath = path.join(gitHookDir, 'pre-push');
252
295
  if (fs.existsSync(path.join(process.cwd(), '.git'))) {
253
296
  const sHook = (0, ora_1.default)('Configurando git hook pre-push...').start();
254
- await sleep(400);
255
297
  if (!fs.existsSync(gitHookDir))
256
298
  fs.mkdirSync(gitHookDir, { recursive: true });
257
- fs.writeFileSync(hookPath, gerarPrePushHook(), 'utf-8');
299
+ fs.writeFileSync(hookPath, gen.gerarPrePushHook(), 'utf-8');
258
300
  try {
259
301
  fs.chmodSync(hookPath, '755');
260
302
  }
@@ -269,6 +311,9 @@ async function runSetup() {
269
311
  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'));
270
312
  }
271
313
  // ─── HELPERS ──────────────────────────────────────────────────────────────────
314
+ function md5(content) {
315
+ return crypto.createHash('md5').update(content).digest('hex');
316
+ }
272
317
  function extrairProjeto(indexPath) {
273
318
  try {
274
319
  const content = fs.readFileSync(indexPath, 'utf-8');
@@ -279,480 +324,3 @@ function extrairProjeto(indexPath) {
279
324
  return 'projeto';
280
325
  }
281
326
  }
282
- function sleep(ms) {
283
- return new Promise(r => setTimeout(r, ms));
284
- }
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
- }
310
- function gerarArchitecture(d) {
311
- const { stack, infra, mcps, projeto } = d;
312
- const tenant = stack.multiTenant
313
- ? `\n## Multi-Tenancy\n- Estratégia: ${stack.tenantStrategy}\n- Nunca fazer query sem filtro de tenantId`
314
- : '';
315
- return `# Architecture — ${projeto}
316
-
317
- > Atualizado via vireum-spec setup
318
- > A IA deve registrar aqui cada decisão técnica relevante
319
-
320
- ## Stack
321
- - Frontend: ${stack.frontend}
322
- - Backend: ${stack.backend}
323
- - Banco de dados: ${stack.banco}
324
- - ORM: ${stack.orm}
325
- - Cache / Filas: ${stack.cache}
326
- - Auth: ${stack.auth}
327
- ${tenant}
328
-
329
- ## Infraestrutura
330
- - Hospedagem: ${infra.hospedagem}
331
- - Containerização: ${infra.containerizacao}
332
- - CI/CD: ${infra.cicd ? infra.cicdFerramenta : 'Não configurado'}
333
-
334
- ## MCPs Ativos
335
- ${mcps.map((m) => `- ${m}`).join('\n')}
336
-
337
- ## Decisões Arquiteturais
338
- > A IA deve registrar aqui cada decisão técnica com justificativa
339
-
340
- | Data | Decisão | Alternativas descartadas | Motivo |
341
- |------|---------|--------------------------|--------|
342
- | | | | |
343
- `;
344
- }
345
- function gerarMcpSetup(d) {
346
- const mcpInfo = {
347
- context7: 'https://github.com/upstash/context7',
348
- github: 'https://github.com/modelcontextprotocol/servers/tree/main/src/github',
349
- database: 'https://github.com/modelcontextprotocol/servers/tree/main/src/postgres',
350
- browser: 'https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer',
351
- puppeteer: 'https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer',
352
- docker: 'https://github.com/modelcontextprotocol/servers',
353
- redis: 'https://github.com/modelcontextprotocol/servers',
354
- };
355
- const lista = d.mcps.map((m) => `### ${m}\n- Instalação: ${mcpInfo[m] || 'Ver documentação oficial'}\n- Credenciais: configurar manualmente após instalação`).join('\n\n');
356
- return `# MCP Setup — ${d.projeto}
357
-
358
- > MCPs necessários para este projeto.
359
- > Instalação é feita manualmente — o framework não acessa credenciais.
360
-
361
- ## MCPs do Projeto
362
- ${lista}
363
-
364
- ## Como instalar
365
- 1. Acesse o link de cada MCP acima
366
- 2. Siga as instruções de instalação
367
- 3. Configure as credenciais manualmente no seu cliente (Claude Code / Cursor)
368
- 4. Execute: vireum-spec verify-mcps
369
- `;
370
- }
371
- function gerarRulesGlobal() {
372
- return `# Rules — Global Vireum
373
-
374
- > Regras globais que se aplicam a TODOS os projetos Vireum.
375
- > Nunca editar por projeto. Em conflito com .spec/rules.md, estas prevalecem.
376
-
377
- ## Regras de Escopo
378
- - Nunca implementar funcionalidade fora do requirements.md sem criar task [PENDING]
379
- - Nunca puxar task do backlog para active sem validação humana explícita
380
- - Sempre avisar escopo creep antes de implementar — parar e perguntar
381
-
382
- ## Regras de Planejamento
383
- - Sempre planejar antes de implementar — escrever o que sera feito e quais arquivos serao tocados
384
- - Confirmar o plano com o dev em tasks complexas antes de executar
385
- - Nunca comecar a escrever codigo sem ter um plano claro
386
-
387
- ## Regras de Design
388
- - Sempre consultar .spec/design.md antes de criar ou modificar qualquer componente de UI
389
- - Nunca hardcodar cores — usar sempre os tokens definidos em design.md
390
- - Nunca misturar design systems
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
-
397
- ## Regras de Spec
398
- - Nunca marcar task como done sem validar os critérios de aceitação
399
- - Nunca tomar decisão de arquitetura sem registrar em architecture.md com justificativa
400
- - Sempre definir contrato de interface antes de implementar features com frontend e backend
401
- - Ao identificar risco novo, adicionar em risks.md antes de continuar
402
-
403
- ## Regras de Contexto
404
- - Sempre ler INDEX.md no início de cada sessão
405
- - Carregar outros arquivos de spec apenas quando a task exigir
406
- - Registrar decisões relevantes em changelog.md com data
407
-
408
- ## Regras de Tasks
409
- - Bugs viram hotfix com tag [H] — nunca são tratados como tasks normais
410
- - Demandas novas do cliente viram [PENDING] no backlog — nunca vão direto para active
411
- - Task só é done quando critérios de aceitação estão validados
412
-
413
- ## Nunca
414
- - Implementar sem ler o spec primeiro
415
- - Implementar sem planejar primeiro
416
- - Criar componente de UI sem consultar design.md
417
- - Tomar decisão de lib ou stack sem documentar o porquê
418
- - Responder dúvida de escopo sem consultar requirements.md
419
- - Comunicar diretamente com o cliente — isso é papel do dev
420
- `;
421
- }
422
- function gerarMcpsGlobal(d) {
423
- return `# MCPs — Global Vireum
424
-
425
- > MCPs padrão disponíveis nos projetos Vireum.
426
- > MCPs ativos por projeto estão em .spec/architecture.md
427
-
428
- ## Stack Padrão
429
- - context7 — documentação atualizada das libs (sempre ativo)
430
- - filesystem — leitura e escrita no projeto (nativo)
431
- - github — PRs, issues, branches referenciando tasks
432
- - database — validar schema e dados em desenvolvimento
433
- - browser — testar endpoints e validar fluxos
434
- - puppeteer — testes de jornada de UI
435
- - docker — gerenciar containers em desenvolvimento
436
- - redis — inspecionar cache e filas (quando aplicável)
437
-
438
- ## MCPs Ativos Neste Projeto
439
- ${d.mcps.map((m) => `- ${m}`).join('\n')}
440
-
441
- ## Quando usar cada MCP
442
- - Antes de usar qualquer lib → context7: buscar docs atualizadas
443
- - Task concluída → github: criar PR referenciando a task
444
- - Bug identificado → github: abrir issue com contexto
445
- - Decisão de schema → database: validar antes de implementar
446
- - Feature implementada → browser: testar endpoint ou fluxo
447
- - Jornada de UI → puppeteer: validar fluxo completo
448
- `;
449
- }
450
- function gerarClaudeMd(d) {
451
- const { projeto, stack, mcps } = d;
452
- const tenant = stack.multiTenant
453
- ? '\n- NUNCA fazer query sem filtro de tenantId — projeto multi-tenant' : '';
454
- const libs = [stack.frontend, stack.backend, stack.orm, stack.cache]
455
- .filter((l) => l && l !== 'Nenhum' && l !== 'Outro')
456
- .join(', ');
457
- return `# ${projeto} — Vireum Spec Protocol
458
-
459
- > Este projeto usa Spec Driven Development pela Vireum Desenvolvimento.
460
- > Leia este arquivo completamente antes de qualquer ação.
461
-
462
- ## Início de cada sessão
463
- 1. Leia \`.spec/INDEX.md\` — estado atual do projeto
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
471
-
472
- ## Modos de operação
473
-
474
- ### Modo 1 — Implementar
475
- Acionado por: "desenvolve", "implementa", "cria", + nome de task
476
- 1. Leia \`.spec/tasks/active.md\`
477
- 2. Leia \`.spec/requirements.md\` para contexto da feature
478
- 3. Consulte o Context7 para docs atualizadas da lib que vai usar
479
- 4. Se task de UI: leia \`.spec/design.md\` antes de qualquer componente
480
- 5. PLANEJAR: escreva o que sera implementado, quais arquivos serao tocados e riscos identificados
481
- 6. Confirme o plano com o dev antes de executar em tasks complexas
482
- 7. Implemente seguindo os critérios de aceitação da task
483
- 8. Ao concluir: marque como done, mova para \`tasks/done.md\`, atualize \`INDEX.md\`
484
- 9. Se decisão arquitetural tomada: registre em \`architecture.md\`
485
-
486
- ### Modo 2 — Bug
487
- Acionado por: "erro", "bug", "quebrou", "não funciona"
488
- 1. PLANEJAR: descreva o que sera investigado e quais arquivos serao tocados
489
- 2. Crie hotfix em \`tasks/active.md\` com tag [H] e prioridade crítica
490
- 3. Identifique e resolva a causa raiz
491
- 4. Registre causa raiz em \`changelog.md\`
492
- 5. Verifique se o bug afeta outras tasks em \`tasks/active.md\`
493
-
494
- ### Modo 3 — Nova demanda
495
- Acionado por: "cliente pediu", "adiciona", "quero incluir" (fora do spec)
496
- 1. Verifique se já existe em \`.spec/requirements.md\`
497
- 2. Se não existir: crie task com tag [PENDING] em \`tasks/backlog.md\`
498
- 3. Informe o impacto estimado e aguarde decisão do dev
499
- 4. NUNCA implemente demanda nova sem aprovação explícita
500
-
501
- ### Modo 4 — Dúvida de escopo
502
- Acionado por: "como deve funcionar", "o que foi combinado", "qual o comportamento"
503
- 1. Leia \`.spec/requirements.md\`
504
- 2. Responda com base no spec — não invente comportamento
505
-
506
- ## Context7 — Documentação atualizada
507
- Sempre que for usar uma lib do projeto, consulte a documentação atualizada via Context7 antes de implementar.
508
- Nunca assuma que você conhece a API mais recente — sempre verifique.
509
- Libs deste projeto: ${libs}
510
-
511
- ## Arquivos de contexto disponíveis
512
- - Escopo e features → leia \`.spec/requirements.md\`
513
- - Decisoes tecnicas → leia \`.spec/architecture.md\`
514
- - Perfis e permissoes → leia \`.spec/users.md\`
515
- - Riscos → leia \`.spec/risks.md\`
516
- - Tarefas ativas → leia \`.spec/tasks/active.md\`
517
- - Historico → leia \`.spec/changelog.md\`
518
- - Design e componentes → leia \`.spec/design.md\` antes de qualquer UI
519
-
520
- ## Regras globais
521
- Leia \`.vireum/rules.md\` — aplicam-se a todas as sessões.
522
-
523
- ## Regras do projeto
524
- Leia \`.spec/rules.md\` — regras específicas deste projeto.
525
-
526
- ## Stack
527
- - Frontend: ${stack.frontend}
528
- - Backend: ${stack.backend}
529
- - Banco: ${stack.banco}
530
- - Auth: ${stack.auth}${tenant}
531
-
532
- ## MCPs ativos
533
- ${mcps.map((m) => `- ${m}`).join('\n')}
534
-
535
- ## Alertas
536
- - Escopo creep: se a solicitação não está em requirements.md → PARAR e avisar
537
- - Decisão de lib nova: registrar em architecture.md antes de usar
538
- - Risco identificado: adicionar em risks.md antes de continuar
539
- - UI sem consultar design.md → PARAR e consultar primeiro
540
- - Spec inconsistente → avisar o dev antes de implementar
541
- `;
542
- }
543
- function gerarAgentsMd(d) {
544
- return `# ${d.projeto} — Vireum Spec Protocol (Codex CLI / Agents)
545
-
546
- > Mesmo protocolo do CLAUDE.md adaptado para Codex CLI e outros agentes.
547
- > Leia CLAUDE.md para o protocolo completo.
548
-
549
- ## Início de cada sessão
550
- 1. Leia \`.spec/INDEX.md\`
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
555
-
556
- ## Planejamento obrigatorio
557
- Antes de qualquer implementacao:
558
- 1. Escreva o que sera feito e quais arquivos serao tocados
559
- 2. Identifique riscos e dependencias
560
- 3. Confirme com o dev em tasks complexas antes de executar
561
-
562
- ## Design
563
- Sempre consultar \`.spec/design.md\` antes de criar ou modificar qualquer componente de UI.
564
-
565
- ## Context7
566
- Sempre consultar docs atualizadas via Context7 antes de usar qualquer lib.
567
-
568
- ## Regras globais
569
- Ver \`.vireum/rules.md\`
570
-
571
- ## Regras do projeto
572
- Ver \`.spec/rules.md\`
573
-
574
- ## Stack
575
- - Frontend: ${d.stack.frontend}
576
- - Backend: ${d.stack.backend}
577
- - Banco: ${d.stack.banco}
578
- `;
579
- }
580
- function gerarCursorRules(d) {
581
- return `---
582
- description: Vireum Spec Protocol — ${d.projeto}
583
- globs: ["**/*"]
584
- alwaysApply: true
585
- ---
586
-
587
- # Vireum Spec Protocol
588
-
589
- Este projeto usa Spec Driven Development pela Vireum Desenvolvimento.
590
-
591
- ## Início de sessão
592
- - Sempre leia \`.spec/INDEX.md\` primeiro
593
- - Verifique consistencia: tasks sem criterios, stack indefinida, INDEX desatualizado
594
- - Avise inconsistencias antes de qualquer implementacao
595
- - Carregue outros arquivos de spec apenas quando necessário
596
-
597
- ## Planejamento obrigatorio
598
- Antes de qualquer implementacao:
599
- - Escreva o que sera feito e quais arquivos serao tocados
600
- - Identifique riscos e dependencias
601
- - Confirme com o dev em tasks complexas antes de executar
602
-
603
- ## Design
604
- - SEMPRE leia \`.spec/design.md\` antes de criar ou modificar qualquer componente de UI
605
- - Nunca hardcodar cores — usar tokens do design.md
606
-
607
- ## Context7
608
- - Sempre consultar Context7 antes de usar qualquer lib do projeto
609
- - Nunca assumir que conhece a API mais recente
610
-
611
- ## Modos
612
- - Implementar → PLANEJAR primeiro, consulte Context7, leia tasks/active.md, se UI leia design.md
613
- - Bug → PLANEJAR investigacao, crie hotfix [H] em active.md, registre causa raiz em changelog.md
614
- - Nova demanda → crie [PENDING] em backlog.md, aguarde aprovação
615
- - Dúvida de escopo → consulte requirements.md
616
-
617
- ## Regras
618
- - Ver \`.vireum/rules.md\` — regras globais
619
- - Ver \`.spec/rules.md\` — regras do projeto
620
- - Nunca implementar fora do spec sem [PENDING] aprovado
621
- - Nunca implementar sem planejar primeiro
622
- - Nunca criar UI sem consultar design.md
623
- - Nunca marcar done sem critérios validados
624
- `;
625
- }
626
- function gerarDesign(d) {
627
- const { design, projeto } = d;
628
- const sistemas = {
629
- shadcn: {
630
- descricao: 'Shadcn/ui com Tailwind CSS e Radix UI',
631
- convencoes: [
632
- 'Usar cn() para mesclar classes Tailwind',
633
- 'Componentes em src/components/ui/',
634
- 'Variaveis CSS em globals.css via --primary, --secondary, etc.',
635
- 'Icones via lucide-react',
636
- 'Formularios com react-hook-form + zod',
637
- ],
638
- tokens: 'Tailwind config + CSS variables',
639
- },
640
- tailwind: {
641
- descricao: 'Tailwind CSS puro',
642
- convencoes: [
643
- 'Classes utilitarias diretamente nos componentes',
644
- 'Cores customizadas em tailwind.config.ts',
645
- 'Componentes em src/components/',
646
- 'Nao criar classes CSS customizadas sem necessidade',
647
- ],
648
- tokens: 'tailwind.config.ts',
649
- },
650
- chakra: {
651
- descricao: 'Chakra UI',
652
- convencoes: [
653
- 'Usar componentes do Chakra sempre que disponivel',
654
- 'Theme customizado em src/theme/',
655
- 'Variaveis de cor via useColorModeValue para dark/light mode',
656
- 'Spacing seguindo escala do Chakra (1 = 4px)',
657
- ],
658
- tokens: 'ChakraProvider theme',
659
- },
660
- mui: {
661
- descricao: 'Material UI (MUI)',
662
- convencoes: [
663
- 'Usar componentes MUI sempre que disponivel',
664
- 'Theme customizado em src/theme/index.ts',
665
- 'Usar sx prop para customizacoes pontuais',
666
- 'Evitar inline styles — preferir theme tokens',
667
- ],
668
- tokens: 'createTheme()',
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
- },
682
- custom: {
683
- descricao: 'Design system proprio',
684
- convencoes: ['Ver secao de convencoes abaixo'],
685
- tokens: 'Ver secao de tokens abaixo',
686
- },
687
- none: {
688
- descricao: 'Sem design system definido',
689
- convencoes: ['A definir'],
690
- tokens: 'A definir',
691
- },
692
- };
693
- const ds = sistemas[design.system] || sistemas.none;
694
- const coresSection = Object.keys(design.cores).filter(k => design.cores[k]).length
695
- ? Object.entries(design.cores)
696
- .filter(([, v]) => v)
697
- .map(([k, v]) => `- ${k}: ${v}`)
698
- .join('\n')
699
- : `> Usar tokens padrao do ${ds.descricao}`;
700
- const fontesSection = Object.keys(design.fontes).filter(k => design.fontes[k]).length
701
- ? Object.entries(design.fontes)
702
- .filter(([, v]) => v)
703
- .map(([k, v]) => `- ${k}: ${v}`)
704
- .join('\n')
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
- ` : '';
722
- return `# Design — ${projeto}
723
-
724
- > A IA deve consultar este arquivo antes de criar ou modificar qualquer componente de UI.
725
- > Nunca usar cores, fontes ou espacamentos fora dos tokens definidos aqui.
726
-
727
- ## Design System
728
- **${ds.descricao}**
729
- - Tokens: ${ds.tokens}
730
-
731
- ## Cores
732
- ${coresSection}
733
-
734
- ## Fontes
735
- ${fontesSection}
736
-
737
- ## Convencoes
738
- ${ds.convencoes.map((c) => `- ${c}`).join('\n')}
739
- ${design.customizacoes ? `\n## Convencoes Customizadas\n${design.customizacoes}` : ''}
740
- ${baseSection}
741
- ## Regras para a IA
742
- - Nunca criar componente sem consultar este arquivo primeiro
743
- - Nunca hardcodar cores — usar sempre os tokens definidos acima
744
- - Nunca misturar design systems — usar apenas ${ds.descricao}
745
- - Novos componentes seguem as convencoes desta secao
746
- - Em caso de duvida sobre UI, perguntar ao dev antes de implementar
747
- ${design.system === 'shadcn' ? '- Sempre usar cn() para mesclar classes condicionais\n- Preferir componentes do Shadcn antes de criar do zero' : ''}
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'}` : ''}
750
-
751
- ## Componentes Existentes
752
- > A IA deve atualizar esta secao conforme novos componentes sao criados
753
-
754
- | Componente | Localizacao | Descricao |
755
- |------------|-------------|-----------|
756
- | | | |
757
- `;
758
- }
@@ -85,7 +85,6 @@ async function instalarClaudeCode() {
85
85
  }
86
86
  for (const skill of SKILLS) {
87
87
  const s = (0, ora_1.default)(` Instalando ${skill}...`).start();
88
- await sleep(300);
89
88
  const origem = path.join(__dirname, '..', 'skills', `${skill}.md`);
90
89
  const destino = path.join(skillsDir, `${skill}.md`);
91
90
  if (fs.existsSync(origem)) {
@@ -106,7 +105,6 @@ async function instalarCursor() {
106
105
  }
107
106
  for (const skill of SKILLS) {
108
107
  const s = (0, ora_1.default)(` Instalando ${skill}...`).start();
109
- await sleep(300);
110
108
  const origem = path.join(__dirname, '..', 'skills', `${skill}.md`);
111
109
  const destino = path.join(cursorDir, `${skill}.mdc`);
112
110
  if (fs.existsSync(origem)) {
@@ -129,7 +127,6 @@ async function instalarCodex() {
129
127
  }
130
128
  for (const skill of SKILLS) {
131
129
  const s = (0, ora_1.default)(` Instalando ${skill}...`).start();
132
- await sleep(300);
133
130
  const origem = path.join(__dirname, '..', 'skills', `${skill}.md`);
134
131
  const destino = path.join(skillsDir, `${skill}.md`);
135
132
  if (fs.existsSync(origem)) {
@@ -142,6 +139,3 @@ async function instalarCodex() {
142
139
  }
143
140
  console.log('');
144
141
  }
145
- function sleep(ms) {
146
- return new Promise(r => setTimeout(r, ms));
147
- }
@@ -52,7 +52,6 @@ async function runVerifyMcps() {
52
52
  process.exit(1);
53
53
  }
54
54
  const spinner = (0, ora_1.default)('Lendo MCPs do projeto...').start();
55
- await sleep(400);
56
55
  const arch = fs.readFileSync(archPath, 'utf-8');
57
56
  const mcpsProjeto = extrairMcpsProjeto(arch);
58
57
  spinner.stop();
@@ -143,6 +142,3 @@ function extrairMcpsInstalados(config) {
143
142
  }
144
143
  return nomes;
145
144
  }
146
- function sleep(ms) {
147
- return new Promise(r => setTimeout(r, ms));
148
- }