vireum-spec-cli 0.1.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.
@@ -0,0 +1,436 @@
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.runSetup = runSetup;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const prompts_1 = require("@inquirer/prompts");
42
+ const ora_1 = __importDefault(require("ora"));
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ async function runSetup() {
46
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Setup\n'));
47
+ console.log(chalk_1.default.gray(' Configure a stack e o protocolo da IA para este projeto\n'));
48
+ const specDir = path.join(process.cwd(), '.spec');
49
+ const vireumDir = path.join(process.cwd(), '.vireum');
50
+ const cursorDir = path.join(process.cwd(), '.cursor', 'rules');
51
+ if (!fs.existsSync(path.join(specDir, 'briefing.md'))) {
52
+ console.log(chalk_1.default.red('\n❌ briefing.md não encontrado.'));
53
+ console.log(chalk_1.default.gray(' Execute primeiro: ') + chalk_1.default.white('vireum-spec init\n'));
54
+ process.exit(1);
55
+ }
56
+ if (!fs.existsSync(path.join(specDir, 'INDEX.md'))) {
57
+ console.log(chalk_1.default.red('\n❌ Spec não gerado ainda.'));
58
+ console.log(chalk_1.default.gray(' Execute primeiro: ') + chalk_1.default.white('vireum-spec distill\n'));
59
+ process.exit(1);
60
+ }
61
+ // ── Stack ──────────────────────────────────────────────────────────────────
62
+ console.log(chalk_1.default.hex('#2D7DD2').bold('⚙️ Stack do Projeto\n'));
63
+ const stack = {
64
+ frontend: await (0, prompts_1.select)({
65
+ message: 'Frontend:',
66
+ choices: [
67
+ { value: 'Next.js' }, { value: 'React' }, { value: 'Vue' },
68
+ { value: 'Nuxt' }, { value: 'Outro' }, { value: 'Nenhum' },
69
+ ],
70
+ }),
71
+ backend: await (0, prompts_1.select)({
72
+ message: 'Backend:',
73
+ choices: [
74
+ { value: 'Node.js + Express' }, { value: 'Node.js + Fastify' },
75
+ { value: 'NestJS' }, { value: 'Python + FastAPI' },
76
+ { value: 'Outro' }, { value: 'Nenhum' },
77
+ ],
78
+ }),
79
+ banco: await (0, prompts_1.select)({
80
+ message: 'Banco de dados:',
81
+ choices: [
82
+ { value: 'PostgreSQL' }, { value: 'MySQL' },
83
+ { value: 'SQLite' }, { value: 'MongoDB' }, { value: 'Outro' },
84
+ ],
85
+ }),
86
+ orm: await (0, prompts_1.select)({
87
+ message: 'ORM / Query Builder:',
88
+ choices: [
89
+ { value: 'Prisma' }, { value: 'TypeORM' }, { value: 'Drizzle' },
90
+ { value: 'Sequelize' }, { value: 'Nenhum' }, { value: 'Outro' },
91
+ ],
92
+ }),
93
+ cache: await (0, prompts_1.select)({
94
+ message: 'Cache / Filas:',
95
+ choices: [
96
+ { value: 'Redis + BullMQ' }, { value: 'Redis simples' },
97
+ { value: 'Nenhum' }, { value: 'Outro' },
98
+ ],
99
+ }),
100
+ auth: await (0, prompts_1.select)({
101
+ message: 'Autenticação:',
102
+ choices: [
103
+ { value: 'JWT + Refresh Token' }, { value: 'NextAuth' },
104
+ { value: 'Supabase Auth' }, { value: 'Clerk' }, { value: 'Outro' },
105
+ ],
106
+ }),
107
+ multiTenant: await (0, prompts_1.confirm)({ message: 'Projeto multi-tenant?', default: false }),
108
+ };
109
+ stack.tenantStrategy = stack.multiTenant
110
+ ? await (0, prompts_1.select)({
111
+ message: 'Estratégia de multi-tenancy:',
112
+ choices: [
113
+ { value: 'Row-level (tenantId)' },
114
+ { value: 'Schema separado por tenant' },
115
+ { value: 'Banco separado por tenant' },
116
+ ],
117
+ })
118
+ : '';
119
+ // ── Infra ──────────────────────────────────────────────────────────────────
120
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🏗️ Infraestrutura\n'));
121
+ const infra = {
122
+ hospedagem: await (0, prompts_1.select)({
123
+ message: 'Hospedagem:',
124
+ choices: [
125
+ { value: 'DigitalOcean' }, { value: 'Hetzner' }, { value: 'AWS' },
126
+ { value: 'Vercel + Railway' }, { value: 'Outro' },
127
+ ],
128
+ }),
129
+ containerizacao: await (0, prompts_1.select)({
130
+ message: 'Containerização:',
131
+ choices: [
132
+ { value: 'Docker + Docker Compose' },
133
+ { value: 'Docker simples' },
134
+ { value: 'Nenhum' },
135
+ ],
136
+ }),
137
+ cicd: await (0, prompts_1.confirm)({ message: 'CI/CD ativo desde o início?', default: false }),
138
+ };
139
+ infra.cicdFerramenta = infra.cicd
140
+ ? await (0, prompts_1.select)({
141
+ message: 'Ferramenta de CI/CD:',
142
+ choices: [
143
+ { value: 'GitHub Actions' }, { value: 'GitLab CI' }, { value: 'Outro' },
144
+ ],
145
+ })
146
+ : '';
147
+ // ── MCPs ───────────────────────────────────────────────────────────────────
148
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🔌 MCPs — Ferramentas da IA\n'));
149
+ const mcpsSelecionados = await (0, prompts_1.checkbox)({
150
+ message: 'Selecione os MCPs para este projeto:',
151
+ choices: [
152
+ { name: 'github — PRs, issues, branches', value: 'github', checked: true },
153
+ { name: 'database — consultar banco em dev', value: 'database', checked: true },
154
+ { name: 'browser — testar endpoints e fluxos', value: 'browser', checked: true },
155
+ { name: 'puppeteer — testes de UI', value: 'puppeteer', checked: false },
156
+ { name: 'docker — gerenciar containers', value: 'docker', checked: false },
157
+ { name: 'redis — inspecionar cache e filas', value: 'redis', checked: false },
158
+ ],
159
+ });
160
+ // ── Gerar arquivos ─────────────────────────────────────────────────────────
161
+ console.log('');
162
+ const projeto = extrairProjeto(path.join(specDir, 'INDEX.md'));
163
+ const dados = { stack, infra, mcps: mcpsSelecionados, projeto };
164
+ for (const dir of [vireumDir, cursorDir]) {
165
+ if (!fs.existsSync(dir))
166
+ fs.mkdirSync(dir, { recursive: true });
167
+ }
168
+ const arquivos = [
169
+ { path: path.join(specDir, 'architecture.md'), conteudo: gerarArchitecture(dados), msg: 'Atualizando architecture.md...' },
170
+ { path: path.join(specDir, 'mcp-setup.md'), conteudo: gerarMcpSetup(dados), msg: 'Gerando mcp-setup.md...' },
171
+ { path: path.join(vireumDir, 'rules.md'), conteudo: gerarRulesGlobal(), msg: 'Gerando .vireum/rules.md...' },
172
+ { path: path.join(vireumDir, 'mcps.md'), conteudo: gerarMcpsGlobal(dados), msg: 'Gerando .vireum/mcps.md...' },
173
+ { path: path.join(process.cwd(), 'CLAUDE.md'), conteudo: gerarClaudeMd(dados), msg: 'Gerando CLAUDE.md...' },
174
+ { path: path.join(process.cwd(), 'AGENTS.md'), conteudo: gerarAgentsMd(dados), msg: 'Gerando AGENTS.md...' },
175
+ { path: path.join(cursorDir, 'vireum.mdc'), conteudo: gerarCursorRules(dados), msg: 'Gerando .cursor/rules/vireum.mdc...' },
176
+ ];
177
+ for (const arq of arquivos) {
178
+ const s = (0, ora_1.default)(arq.msg).start();
179
+ await sleep(400);
180
+ fs.writeFileSync(arq.path, arq.conteudo, 'utf-8');
181
+ s.succeed(path.relative(process.cwd(), arq.path));
182
+ }
183
+ console.log(chalk_1.default.green.bold('\n✅ Setup concluído!\n'));
184
+ console.log(chalk_1.default.gray(' Protocolo da IA configurado para Claude Code, Codex CLI e Cursor\n'));
185
+ 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'));
186
+ }
187
+ // ─── HELPERS ──────────────────────────────────────────────────────────────────
188
+ function extrairProjeto(indexPath) {
189
+ try {
190
+ const content = fs.readFileSync(indexPath, 'utf-8');
191
+ const match = content.match(/# INDEX — (.+)/);
192
+ return match ? match[1].trim() : 'projeto';
193
+ }
194
+ catch {
195
+ return 'projeto';
196
+ }
197
+ }
198
+ function sleep(ms) {
199
+ return new Promise(r => setTimeout(r, ms));
200
+ }
201
+ // ─── GERADORES ────────────────────────────────────────────────────────────────
202
+ function gerarArchitecture(d) {
203
+ const { stack, infra, mcps, projeto } = d;
204
+ const tenant = stack.multiTenant
205
+ ? `\n## Multi-Tenancy\n- Estratégia: ${stack.tenantStrategy}\n- Nunca fazer query sem filtro de tenantId`
206
+ : '';
207
+ return `# Architecture — ${projeto}
208
+
209
+ > Atualizado via vireum-spec setup
210
+ > A IA deve registrar aqui cada decisão técnica relevante
211
+
212
+ ## Stack
213
+ - Frontend: ${stack.frontend}
214
+ - Backend: ${stack.backend}
215
+ - Banco de dados: ${stack.banco}
216
+ - ORM: ${stack.orm}
217
+ - Cache / Filas: ${stack.cache}
218
+ - Auth: ${stack.auth}
219
+ ${tenant}
220
+
221
+ ## Infraestrutura
222
+ - Hospedagem: ${infra.hospedagem}
223
+ - Containerização: ${infra.containerizacao}
224
+ - CI/CD: ${infra.cicd ? infra.cicdFerramenta : 'Não configurado'}
225
+
226
+ ## MCPs Ativos
227
+ ${mcps.map((m) => `- ${m}`).join('\n')}
228
+
229
+ ## Decisões Arquiteturais
230
+ > A IA deve registrar aqui cada decisão técnica com justificativa
231
+
232
+ | Data | Decisão | Alternativas descartadas | Motivo |
233
+ |------|---------|--------------------------|--------|
234
+ | | | | |
235
+ `;
236
+ }
237
+ function gerarMcpSetup(d) {
238
+ const mcpInfo = {
239
+ github: 'https://github.com/modelcontextprotocol/servers/tree/main/src/github',
240
+ database: 'https://github.com/modelcontextprotocol/servers/tree/main/src/postgres',
241
+ browser: 'https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer',
242
+ puppeteer: 'https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer',
243
+ docker: 'https://github.com/modelcontextprotocol/servers',
244
+ redis: 'https://github.com/modelcontextprotocol/servers',
245
+ };
246
+ 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');
247
+ return `# MCP Setup — ${d.projeto}
248
+
249
+ > MCPs necessários para este projeto.
250
+ > Instalação é feita manualmente — o framework não acessa credenciais.
251
+
252
+ ## MCPs do Projeto
253
+ ${lista}
254
+
255
+ ## Como instalar
256
+ 1. Acesse o link de cada MCP acima
257
+ 2. Siga as instruções de instalação
258
+ 3. Configure as credenciais manualmente no seu cliente (Claude Code / Cursor)
259
+ 4. Execute: vireum-spec verify-mcps (em breve)
260
+ `;
261
+ }
262
+ function gerarRulesGlobal() {
263
+ return `# Rules — Global Vireum
264
+
265
+ > Regras globais que se aplicam a TODOS os projetos Vireum.
266
+ > Nunca editar por projeto. Em conflito com .spec/rules.md, estas prevalecem.
267
+
268
+ ## Regras de Escopo
269
+ - Nunca implementar funcionalidade fora do requirements.md sem criar task [PENDING]
270
+ - Nunca puxar task do backlog para active sem validação humana explícita
271
+ - Sempre avisar escopo creep antes de implementar — parar e perguntar
272
+
273
+ ## Regras de Spec
274
+ - Nunca marcar task como done sem validar os critérios de aceitação
275
+ - Nunca tomar decisão de arquitetura sem registrar em architecture.md com justificativa
276
+ - Sempre definir contrato de interface antes de implementar features com frontend e backend
277
+ - Ao identificar risco novo, adicionar em risks.md antes de continuar
278
+
279
+ ## Regras de Contexto
280
+ - Sempre ler INDEX.md no início de cada sessão
281
+ - Carregar outros arquivos de spec apenas quando a task exigir
282
+ - Registrar decisões relevantes em changelog.md com data
283
+
284
+ ## Regras de Tasks
285
+ - Bugs viram hotfix com tag [H] — nunca são tratados como tasks normais
286
+ - Demandas novas do cliente viram [PENDING] no backlog — nunca vão direto para active
287
+ - Task só é done quando critérios de aceitação estão validados
288
+
289
+ ## Nunca
290
+ - Implementar sem ler o spec primeiro
291
+ - Tomar decisão de lib ou stack sem documentar o porquê
292
+ - Responder dúvida de escopo sem consultar requirements.md
293
+ - Comunicar diretamente com o cliente — isso é papel do dev
294
+ `;
295
+ }
296
+ function gerarMcpsGlobal(d) {
297
+ return `# MCPs — Global Vireum
298
+
299
+ > MCPs padrão disponíveis nos projetos Vireum.
300
+ > MCPs ativos por projeto estão em .spec/architecture.md
301
+
302
+ ## Stack Padrão
303
+ - filesystem — leitura e escrita no projeto (nativo)
304
+ - github — PRs, issues, branches referenciando tasks
305
+ - database — validar schema e dados em desenvolvimento
306
+ - browser — testar endpoints e validar fluxos
307
+ - puppeteer — testes de jornada de UI
308
+ - docker — gerenciar containers em desenvolvimento
309
+ - redis — inspecionar cache e filas (quando aplicável)
310
+
311
+ ## MCPs Ativos Neste Projeto
312
+ ${d.mcps.map((m) => `- ${m}`).join('\n')}
313
+
314
+ ## Quando usar cada MCP
315
+ - Task concluída → github: criar PR referenciando a task
316
+ - Bug identificado → github: abrir issue com contexto
317
+ - Decisão de schema → database: validar antes de implementar
318
+ - Feature implementada → browser: testar endpoint ou fluxo
319
+ - Jornada de UI → puppeteer: validar fluxo completo
320
+ `;
321
+ }
322
+ function gerarClaudeMd(d) {
323
+ const { projeto, stack, mcps } = d;
324
+ const tenant = stack.multiTenant
325
+ ? '\n- NUNCA fazer query sem filtro de tenantId — projeto multi-tenant' : '';
326
+ return `# ${projeto} — Vireum Spec Protocol
327
+
328
+ > Este projeto usa Spec Driven Development pela Vireum Desenvolvimento.
329
+ > Leia este arquivo completamente antes de qualquer ação.
330
+
331
+ ## Início de cada sessão
332
+ 1. Leia \`.spec/INDEX.md\` — estado atual do projeto
333
+ 2. Identifique o modo da sessão pela solicitação do dev
334
+ 3. Carregue arquivos adicionais apenas se a task exigir
335
+
336
+ ## Modos de operação
337
+
338
+ ### Modo 1 — Implementar
339
+ Acionado por: "desenvolve", "implementa", "cria", + nome de task
340
+ 1. Leia \`.spec/tasks/active.md\`
341
+ 2. Leia \`.spec/requirements.md\` para contexto da feature
342
+ 3. Implemente seguindo os critérios de aceitação da task
343
+ 4. Ao concluir: marque como done, mova para \`tasks/done.md\`, atualize \`INDEX.md\`
344
+ 5. Se decisão arquitetural tomada: registre em \`architecture.md\`
345
+
346
+ ### Modo 2 — Bug
347
+ Acionado por: "erro", "bug", "quebrou", "não funciona"
348
+ 1. Crie hotfix em \`tasks/active.md\` com tag [H] e prioridade crítica
349
+ 2. Identifique e resolva a causa raiz
350
+ 3. Registre causa raiz em \`changelog.md\`
351
+ 4. Verifique se o bug afeta outras tasks em \`tasks/active.md\`
352
+
353
+ ### Modo 3 — Nova demanda
354
+ Acionado por: "cliente pediu", "adiciona", "quero incluir" (fora do spec)
355
+ 1. Verifique se já existe em \`.spec/requirements.md\`
356
+ 2. Se não existir: crie task com tag [PENDING] em \`tasks/backlog.md\`
357
+ 3. Informe o impacto estimado e aguarde decisão do dev
358
+ 4. NUNCA implemente demanda nova sem aprovação explícita
359
+
360
+ ### Modo 4 — Dúvida de escopo
361
+ Acionado por: "como deve funcionar", "o que foi combinado", "qual o comportamento"
362
+ 1. Leia \`.spec/requirements.md\`
363
+ 2. Responda com base no spec — não invente comportamento
364
+
365
+ ## Regras globais
366
+ Leia \`.vireum/rules.md\` — aplicam-se a todas as sessões.
367
+
368
+ ## Regras do projeto
369
+ Leia \`.spec/rules.md\` — regras específicas deste projeto.
370
+
371
+ ## Stack
372
+ - Frontend: ${stack.frontend}
373
+ - Backend: ${stack.backend}
374
+ - Banco: ${stack.banco}
375
+ - Auth: ${stack.auth}${tenant}
376
+
377
+ ## MCPs ativos
378
+ ${mcps.map((m) => `- ${m}`).join('\n')}
379
+
380
+ ## Alertas
381
+ - Escopo creep: se a solicitação não está em requirements.md → PARAR e avisar
382
+ - Decisão de lib nova: registrar em architecture.md antes de usar
383
+ - Risco identificado: adicionar em risks.md antes de continuar
384
+ `;
385
+ }
386
+ function gerarAgentsMd(d) {
387
+ return `# ${d.projeto} — Vireum Spec Protocol (Codex CLI / Agents)
388
+
389
+ > Mesmo protocolo do CLAUDE.md adaptado para Codex CLI e outros agentes.
390
+ > Leia CLAUDE.md para o protocolo completo.
391
+
392
+ ## Início de cada sessão
393
+ 1. Leia \`.spec/INDEX.md\`
394
+ 2. Identifique o modo pela solicitação
395
+ 3. Siga o protocolo em CLAUDE.md
396
+
397
+ ## Regras globais
398
+ Ver \`.vireum/rules.md\`
399
+
400
+ ## Regras do projeto
401
+ Ver \`.spec/rules.md\`
402
+
403
+ ## Stack
404
+ - Frontend: ${d.stack.frontend}
405
+ - Backend: ${d.stack.backend}
406
+ - Banco: ${d.stack.banco}
407
+ `;
408
+ }
409
+ function gerarCursorRules(d) {
410
+ return `---
411
+ description: Vireum Spec Protocol — ${d.projeto}
412
+ globs: ["**/*"]
413
+ alwaysApply: true
414
+ ---
415
+
416
+ # Vireum Spec Protocol
417
+
418
+ Este projeto usa Spec Driven Development pela Vireum Desenvolvimento.
419
+
420
+ ## Início de sessão
421
+ - Sempre leia \`.spec/INDEX.md\` primeiro
422
+ - Carregue outros arquivos de spec apenas quando necessário
423
+
424
+ ## Modos
425
+ - Implementar → leia tasks/active.md, siga critérios de aceitação
426
+ - Bug → crie hotfix [H] em active.md, registre causa raiz em changelog.md
427
+ - Nova demanda → crie [PENDING] em backlog.md, aguarde aprovação
428
+ - Dúvida de escopo → consulte requirements.md
429
+
430
+ ## Regras
431
+ - Ver \`.vireum/rules.md\` — regras globais
432
+ - Ver \`.spec/rules.md\` — regras do projeto
433
+ - Nunca implementar fora do spec sem [PENDING] aprovado
434
+ - Nunca marcar done sem critérios validados
435
+ `;
436
+ }
@@ -0,0 +1,147 @@
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.runSkills = runSkills;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const prompts_1 = require("@inquirer/prompts");
42
+ const ora_1 = __importDefault(require("ora"));
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const os = __importStar(require("os"));
46
+ const SKILLS = [
47
+ 'task-implement',
48
+ 'bug-fix',
49
+ 'new-demand',
50
+ 'spec-update',
51
+ 'contract-first',
52
+ 'scope-check',
53
+ ];
54
+ async function runSkills() {
55
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Skills\n'));
56
+ console.log(chalk_1.default.gray(' Instala as skills do framework no seu cliente de IA\n'));
57
+ const cliente = await (0, prompts_1.select)({
58
+ message: 'Instalar skills para qual cliente:',
59
+ choices: [
60
+ { name: 'Claude Code — ~/.claude/skills/', value: 'claude' },
61
+ { name: 'Cursor — .cursor/rules/ (no projeto)', value: 'cursor' },
62
+ { name: 'Codex CLI — ~/.codex/skills/', value: 'codex' },
63
+ { name: 'Todos', value: 'todos' },
64
+ ],
65
+ });
66
+ console.log('');
67
+ if (cliente === 'claude' || cliente === 'todos') {
68
+ await instalarClaudeCode();
69
+ }
70
+ if (cliente === 'cursor' || cliente === 'todos') {
71
+ await instalarCursor();
72
+ }
73
+ if (cliente === 'codex' || cliente === 'todos') {
74
+ await instalarCodex();
75
+ }
76
+ console.log(chalk_1.default.green.bold('\n✅ Skills instaladas!\n'));
77
+ console.log(chalk_1.default.gray(' A IA agora conhece o protocolo Vireum para tarefas específicas\n'));
78
+ }
79
+ // ─── INSTALADORES ─────────────────────────────────────────────────────────────
80
+ async function instalarClaudeCode() {
81
+ console.log(chalk_1.default.white.bold(' Claude Code\n'));
82
+ const skillsDir = path.join(os.homedir(), '.claude', 'skills', 'vireum');
83
+ if (!fs.existsSync(skillsDir)) {
84
+ fs.mkdirSync(skillsDir, { recursive: true });
85
+ }
86
+ for (const skill of SKILLS) {
87
+ const s = (0, ora_1.default)(` Instalando ${skill}...`).start();
88
+ await sleep(300);
89
+ const origem = path.join(__dirname, '..', 'skills', `${skill}.md`);
90
+ const destino = path.join(skillsDir, `${skill}.md`);
91
+ if (fs.existsSync(origem)) {
92
+ fs.copyFileSync(origem, destino);
93
+ s.succeed(` ${skill}.md → ~/.claude/skills/vireum/`);
94
+ }
95
+ else {
96
+ s.warn(` ${skill}.md não encontrado no framework`);
97
+ }
98
+ }
99
+ console.log('');
100
+ }
101
+ async function instalarCursor() {
102
+ console.log(chalk_1.default.white.bold(' Cursor\n'));
103
+ const cursorDir = path.join(process.cwd(), '.cursor', 'rules', 'skills');
104
+ if (!fs.existsSync(cursorDir)) {
105
+ fs.mkdirSync(cursorDir, { recursive: true });
106
+ }
107
+ for (const skill of SKILLS) {
108
+ const s = (0, ora_1.default)(` Instalando ${skill}...`).start();
109
+ await sleep(300);
110
+ const origem = path.join(__dirname, '..', 'skills', `${skill}.md`);
111
+ const destino = path.join(cursorDir, `${skill}.mdc`);
112
+ if (fs.existsSync(origem)) {
113
+ const conteudo = fs.readFileSync(origem, 'utf-8');
114
+ const comHeader = `---\ndescription: Vireum Skill — ${skill}\nglobs: ["**/*"]\nalwaysApply: false\n---\n\n${conteudo}`;
115
+ fs.writeFileSync(destino, comHeader, 'utf-8');
116
+ s.succeed(` ${skill}.mdc → .cursor/rules/skills/`);
117
+ }
118
+ else {
119
+ s.warn(` ${skill}.md não encontrado no framework`);
120
+ }
121
+ }
122
+ console.log('');
123
+ }
124
+ async function instalarCodex() {
125
+ console.log(chalk_1.default.white.bold(' Codex CLI\n'));
126
+ const skillsDir = path.join(os.homedir(), '.codex', 'skills', 'vireum');
127
+ if (!fs.existsSync(skillsDir)) {
128
+ fs.mkdirSync(skillsDir, { recursive: true });
129
+ }
130
+ for (const skill of SKILLS) {
131
+ const s = (0, ora_1.default)(` Instalando ${skill}...`).start();
132
+ await sleep(300);
133
+ const origem = path.join(__dirname, '..', 'skills', `${skill}.md`);
134
+ const destino = path.join(skillsDir, `${skill}.md`);
135
+ if (fs.existsSync(origem)) {
136
+ fs.copyFileSync(origem, destino);
137
+ s.succeed(` ${skill}.md → ~/.codex/skills/vireum/`);
138
+ }
139
+ else {
140
+ s.warn(` ${skill}.md não encontrado no framework`);
141
+ }
142
+ }
143
+ console.log('');
144
+ }
145
+ function sleep(ms) {
146
+ return new Promise(r => setTimeout(r, ms));
147
+ }