vireum-spec-cli 0.5.0 → 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 +50 -55
- 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 +39 -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/dist/commands/setup.js
CHANGED
|
@@ -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, '
|
|
238
|
-
{ path: path.join(
|
|
239
|
-
{ path: path.join(process.cwd(), '
|
|
240
|
-
{ path: path.join(
|
|
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
|
-
}
|
package/dist/commands/skills.js
CHANGED
|
@@ -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
|
-
}
|