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.
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runInitAutomation = runInitAutomation;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const prompts_1 = require("@inquirer/prompts");
9
+ const system_1 = require("./system");
10
+ async function runInitAutomation() {
11
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Briefing Interativo (Automação)\n'));
12
+ console.log(chalk_1.default.gray(' Responda as perguntas abaixo. As respostas serão salvas em .spec/briefing.md\n'));
13
+ // ── 1. Informações Gerais ──────────────────────────────────────────────────
14
+ console.log(chalk_1.default.hex('#2D7DD2').bold('📌 1. Informações Gerais\n'));
15
+ const geral = {
16
+ projeto: await (0, prompts_1.input)({ message: 'Nome do projeto:' }),
17
+ cliente: await (0, prompts_1.input)({ message: 'Nome do cliente:' }),
18
+ responsavel: await (0, prompts_1.input)({ message: 'Responsável pelo projeto (Vireum):' }),
19
+ data: await (0, prompts_1.input)({ message: 'Data da reunião:', default: new Date().toLocaleDateString('pt-BR') }),
20
+ };
21
+ // ── 2. Trigger e Contexto ──────────────────────────────────────────────────
22
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🎯 2. Trigger e Contexto\n'));
23
+ const contexto = {
24
+ objetivo: await (0, prompts_1.input)({ message: 'O que esta automação faz? Descreva em uma frase:' }),
25
+ problema: await (0, prompts_1.input)({ message: 'O que acontece hoje sem essa automação? (processo manual)' }),
26
+ trigger: await (0, prompts_1.select)({
27
+ message: 'O que dispara a automação?',
28
+ choices: [
29
+ { name: 'Agendamento (cron/horário fixo)', value: 'Cron / Agendamento' },
30
+ { name: 'Webhook (evento externo)', value: 'Webhook' },
31
+ { name: 'Evento manual (botão/comando)', value: 'Evento manual' },
32
+ { name: 'Fila de mensagens', value: 'Fila (Queue)' },
33
+ { name: 'Arquivo / upload', value: 'Arquivo / Upload' },
34
+ ],
35
+ }),
36
+ frequencia: await (0, prompts_1.input)({ message: 'Com que frequência roda? (ex: todo dia às 8h, a cada novo pedido):' }),
37
+ volume: await (0, prompts_1.input)({ message: 'Volume esperado por execução (ex: 100 registros, 1 arquivo):' }),
38
+ prazo_mvp: await (0, prompts_1.input)({ message: 'Prazo esperado para entrega:' }),
39
+ tempo_execucao: await (0, prompts_1.select)({
40
+ message: 'Tempo médio esperado de execução:',
41
+ choices: [
42
+ { name: 'Menos de 1 minuto', value: 'Menos de 1 minuto' },
43
+ { name: '1–10 minutos', value: '1–10 minutos' },
44
+ { name: 'Mais de 10 minutos', value: 'Mais de 10 minutos' },
45
+ { name: 'Não sei estimar', value: 'A estimar' },
46
+ ],
47
+ }),
48
+ };
49
+ // ── 3. Dados ───────────────────────────────────────────────────────────────
50
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n📥 3. Entrada e Saída de Dados\n'));
51
+ const dados = {
52
+ fonte: await (0, prompts_1.select)({
53
+ message: 'Fonte de dados de entrada:',
54
+ choices: [
55
+ { name: 'Banco de dados (SQL)', value: 'Banco de dados SQL' },
56
+ { name: 'API externa', value: 'API externa' },
57
+ { name: 'Planilha (Excel/Google)', value: 'Planilha' },
58
+ { name: 'Arquivo (CSV, JSON, XML)', value: 'Arquivo' },
59
+ { name: 'E-mail', value: 'E-mail' },
60
+ { name: 'Múltiplas fontes', value: 'Múltiplas fontes' },
61
+ ],
62
+ }),
63
+ fonte_detalhe: await (0, prompts_1.input)({ message: 'Detalhe da fonte (URL da API, nome do banco, etc.):' }),
64
+ transformacao: await (0, prompts_1.input)({ message: 'O que faz com os dados? (ex: filtra, calcula, envia, salva):' }),
65
+ destino: await (0, prompts_1.select)({
66
+ message: 'Onde vai o resultado?',
67
+ choices: [
68
+ { name: 'Banco de dados', value: 'Banco de dados' },
69
+ { name: 'API externa', value: 'API externa' },
70
+ { name: 'E-mail', value: 'E-mail' },
71
+ { name: 'Planilha', value: 'Planilha' },
72
+ { name: 'Arquivo gerado', value: 'Arquivo' },
73
+ { name: 'Múltiplos destinos', value: 'Múltiplos destinos' },
74
+ ],
75
+ }),
76
+ destino_detalhe: await (0, prompts_1.input)({ message: 'Detalhe do destino:' }),
77
+ };
78
+ // ── 4. Confiabilidade ──────────────────────────────────────────────────────
79
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🛡️ 4. Confiabilidade e Alertas\n'));
80
+ const confiabilidade = {
81
+ retry: await (0, prompts_1.confirm)({ message: 'Precisa tentar novamente em caso de falha (retry)?', default: true }),
82
+ alerta: await (0, prompts_1.confirm)({ message: 'Precisa enviar alerta quando falhar?', default: false }),
83
+ alerta_canal: await (0, prompts_1.input)({ message: 'Canal de alerta (Slack, e-mail, WhatsApp — deixe em branco se não):' }),
84
+ notif_sucesso: await (0, prompts_1.confirm)({ message: 'Precisa de notificação de sucesso também?', default: false }),
85
+ idempotente: await (0, prompts_1.confirm)({ message: 'A automação pode rodar duas vezes sem duplicar dados (idempotente)?', default: false }),
86
+ };
87
+ // ── 5. Monitoramento e Deploy ──────────────────────────────────────────────
88
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n📊 5. Monitoramento e Deploy\n'));
89
+ const deploy = {
90
+ logs: await (0, prompts_1.confirm)({ message: 'Precisa de logs de execução?', default: true }),
91
+ dashboard: await (0, prompts_1.confirm)({ message: 'Precisa de dashboard de monitoramento?', default: false }),
92
+ custo_operacional: await (0, prompts_1.select)({
93
+ message: 'Custo operacional mensal estimado:',
94
+ choices: [
95
+ { name: 'Até R$ 200 — projeto leve, baixo tráfego', value: 'Até R$ 200' },
96
+ { name: 'R$ 200–800 — projeto moderado', value: 'R$ 200–800' },
97
+ { name: 'R$ 800–3k — projeto robusto', value: 'R$ 800–3k' },
98
+ { name: 'Acima de R$ 3k — missão crítica / alta escala', value: 'Acima de R$ 3k' },
99
+ { name: 'A definir com o cliente', value: 'A definir' },
100
+ ],
101
+ }),
102
+ linguagem: await (0, prompts_1.select)({
103
+ message: 'Linguagem:',
104
+ choices: [
105
+ { name: 'Python', value: 'Python' },
106
+ { name: 'Node.js', value: 'Node.js' },
107
+ { name: 'A definir', value: 'A definir' },
108
+ ],
109
+ }),
110
+ deploy: await (0, prompts_1.select)({
111
+ message: 'Onde vai rodar?',
112
+ choices: [
113
+ { name: 'Servidor próprio / VPS', value: 'VPS' },
114
+ { name: 'AWS Lambda / Cloud Functions', value: 'Serverless' },
115
+ { name: 'Docker / container', value: 'Docker' },
116
+ { name: 'Máquina local', value: 'Local' },
117
+ { name: 'A definir', value: 'A definir' },
118
+ ],
119
+ }),
120
+ };
121
+ const briefing = gerarBriefingAutomation({ geral, contexto, dados, confiabilidade, deploy });
122
+ (0, system_1.salvarBriefing)(briefing, 'automation');
123
+ }
124
+ function gerarBriefingAutomation(data) {
125
+ const { geral, contexto, dados, confiabilidade, deploy } = data;
126
+ return `# Briefing — ${geral.projeto}
127
+
128
+ ## 📌 1. Informações Gerais
129
+ - **Projeto:** ${geral.projeto}
130
+ - **Cliente:** ${geral.cliente}
131
+ - **Responsável:** ${geral.responsavel}
132
+ - **Data da reunião:** ${geral.data}
133
+ - **Tipo:** Automação
134
+ - **Versão:** 1.0
135
+
136
+ ## 🎯 2. Trigger e Contexto
137
+ - **O que faz:** ${contexto.objetivo}
138
+ - **Processo atual (manual):** ${contexto.problema}
139
+ - **Trigger:** ${contexto.trigger}
140
+ - **Frequência:** ${contexto.frequencia}
141
+ - **Volume por execução:** ${contexto.volume}
142
+ - **Tempo de execução estimado:** ${contexto.tempo_execucao}
143
+ - **Prazo de entrega:** ${contexto.prazo_mvp}
144
+
145
+ ## 📥 3. Entrada e Saída de Dados
146
+ - **Fonte de dados:** ${dados.fonte}
147
+ - **Detalhe da fonte:** ${dados.fonte_detalhe || 'A definir'}
148
+ - **Transformação:** ${dados.transformacao}
149
+ - **Destino:** ${dados.destino}
150
+ - **Detalhe do destino:** ${dados.destino_detalhe || 'A definir'}
151
+
152
+ ## 🛡️ 4. Confiabilidade e Alertas
153
+ - Retry em caso de falha: ${confiabilidade.retry ? 'Sim' : 'Não'}
154
+ - Alerta de falha: ${confiabilidade.alerta ? 'Sim' : 'Não'}
155
+ ${confiabilidade.alerta_canal ? `- Canal de alerta: ${confiabilidade.alerta_canal}` : ''}
156
+ - Notificação de sucesso: ${confiabilidade.notif_sucesso ? 'Sim' : 'Não'}
157
+ - Idempotente: ${confiabilidade.idempotente ? 'Sim' : 'Não (cuidado com duplicatas)'}
158
+
159
+ ## 📊 5. Monitoramento e Deploy
160
+ - Logs de execução: ${deploy.logs ? 'Sim' : 'Não'}
161
+ - Dashboard de monitoramento: ${deploy.dashboard ? 'Sim' : 'Não'}
162
+ - **Linguagem:** ${deploy.linguagem}
163
+ - **Deploy:** ${deploy.deploy}
164
+ - Custo operacional estimado: ${deploy.custo_operacional}
165
+ `;
166
+ }
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runInitMobile = runInitMobile;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const prompts_1 = require("@inquirer/prompts");
9
+ const system_1 = require("./system");
10
+ async function runInitMobile() {
11
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Briefing Interativo (Mobile)\n'));
12
+ console.log(chalk_1.default.gray(' Responda as perguntas abaixo. As respostas serão salvas em .spec/briefing.md\n'));
13
+ // ── 1. Informações Gerais ──────────────────────────────────────────────────
14
+ console.log(chalk_1.default.hex('#2D7DD2').bold('📌 1. Informações Gerais\n'));
15
+ const geral = {
16
+ projeto: await (0, prompts_1.input)({ message: 'Nome do projeto:' }),
17
+ cliente: await (0, prompts_1.input)({ message: 'Nome do cliente:' }),
18
+ responsavel: await (0, prompts_1.input)({ message: 'Responsável pelo projeto (Vireum):' }),
19
+ data: await (0, prompts_1.input)({ message: 'Data da reunião:', default: new Date().toLocaleDateString('pt-BR') }),
20
+ };
21
+ // ── 2. Objetivo ────────────────────────────────────────────────────────────
22
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🎯 2. Objetivo do App\n'));
23
+ const objetivo = {
24
+ objetivo: await (0, prompts_1.input)({ message: 'O que o app faz? Qual é seu propósito?' }),
25
+ problema: await (0, prompts_1.input)({ message: 'Qual problema resolve para o usuário?' }),
26
+ plataformas: await (0, prompts_1.select)({
27
+ message: 'Plataformas alvo:',
28
+ choices: [
29
+ { name: 'iOS e Android', value: 'iOS e Android' },
30
+ { name: 'Apenas Android', value: 'Apenas Android' },
31
+ { name: 'Apenas iOS', value: 'Apenas iOS' },
32
+ ],
33
+ }),
34
+ framework: await (0, prompts_1.select)({
35
+ message: 'Framework:',
36
+ choices: [
37
+ { name: 'React Native + Expo', value: 'React Native + Expo' },
38
+ { name: 'React Native CLI', value: 'React Native CLI' },
39
+ { name: 'Flutter', value: 'Flutter' },
40
+ { name: 'A definir', value: 'A definir' },
41
+ ],
42
+ }),
43
+ monetizacao: await (0, prompts_1.select)({
44
+ message: 'Modelo do app:',
45
+ choices: [
46
+ { name: 'Gratuito', value: 'Gratuito' },
47
+ { name: 'Pago (compra única na loja)', value: 'Pago' },
48
+ { name: 'Freemium (grátis + planos pagos)', value: 'Freemium' },
49
+ { name: 'Anúncios', value: 'Anúncios' },
50
+ { name: 'A definir', value: 'A definir' },
51
+ ],
52
+ }),
53
+ prazo_mvp: await (0, prompts_1.input)({ message: 'Prazo esperado para o MVP:' }),
54
+ };
55
+ // ── 3. Funcionalidades ─────────────────────────────────────────────────────
56
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🧩 3. Funcionalidades\n'));
57
+ const funcionalidades = {
58
+ features: await (0, prompts_1.input)({ message: 'Funcionalidades obrigatórias (separadas por vírgula):' }),
59
+ offline: await (0, prompts_1.confirm)({ message: 'Precisa funcionar offline?', default: false }),
60
+ push: await (0, prompts_1.confirm)({ message: 'Precisa de notificações push?', default: false }),
61
+ camera: await (0, prompts_1.confirm)({ message: 'Acessa câmera / galeria?', default: false }),
62
+ localizacao: await (0, prompts_1.confirm)({ message: 'Usa localização / GPS?', default: false }),
63
+ biometria: await (0, prompts_1.confirm)({ message: 'Autenticação biométrica (Face ID / Touch ID)?', default: false }),
64
+ dark_mode: await (0, prompts_1.confirm)({ message: 'Precisa de modo dark/light?', default: false }),
65
+ };
66
+ // ── 4. Integração com Backend ──────────────────────────────────────────────
67
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🔗 4. Integração com Backend\n'));
68
+ const backend = {
69
+ tem_api: await (0, prompts_1.confirm)({ message: 'O app vai se conectar a uma API?', default: true }),
70
+ api_propria: await (0, prompts_1.confirm)({ message: 'A API é própria (Vireum vai desenvolver)?', default: false }),
71
+ auth: await (0, prompts_1.select)({
72
+ message: 'Autenticação no app:',
73
+ choices: [
74
+ { name: 'JWT / Token', value: 'JWT / Token' },
75
+ { name: 'Google / Apple', value: 'OAuth (Google/Apple)' },
76
+ { name: 'WhatsApp / SMS', value: 'WhatsApp/SMS OTP' },
77
+ { name: 'Sem autenticação', value: 'Sem autenticação' },
78
+ ],
79
+ }),
80
+ analytics: await (0, prompts_1.confirm)({ message: 'Precisa de analytics de uso (Firebase, Mixpanel)?', default: false }),
81
+ };
82
+ // ── 5. Publicação nas Lojas ────────────────────────────────────────────────
83
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🏪 5. Publicação nas Lojas\n'));
84
+ const lojas = {
85
+ publicar: await (0, prompts_1.confirm)({ message: 'Precisa publicar nas lojas (App Store / Google Play)?', default: true }),
86
+ conta_existente: await (0, prompts_1.confirm)({ message: 'Já tem contas de desenvolvedor nas lojas?', default: false }),
87
+ deep_linking: await (0, prompts_1.confirm)({ message: 'Precisa de deep linking (links que abrem o app)?', default: false }),
88
+ updates_ota: await (0, prompts_1.confirm)({ message: 'Precisa de atualizações OTA sem republicar nas lojas?', default: false }),
89
+ custo_operacional: await (0, prompts_1.select)({
90
+ message: 'Custo operacional mensal estimado (backend + infra):',
91
+ choices: [
92
+ { name: 'Até R$ 200 — projeto leve, baixo tráfego', value: 'Até R$ 200' },
93
+ { name: 'R$ 200–800 — projeto moderado', value: 'R$ 200–800' },
94
+ { name: 'R$ 800–3k — projeto robusto', value: 'R$ 800–3k' },
95
+ { name: 'Acima de R$ 3k — missão crítica / alta escala', value: 'Acima de R$ 3k' },
96
+ { name: 'A definir com o cliente', value: 'A definir' },
97
+ ],
98
+ }),
99
+ };
100
+ const briefing = gerarBriefingMobile({ geral, objetivo, funcionalidades, backend, lojas });
101
+ (0, system_1.salvarBriefing)(briefing, 'mobile');
102
+ }
103
+ function gerarBriefingMobile(data) {
104
+ const { geral, objetivo, funcionalidades, backend, lojas } = data;
105
+ const features = funcionalidades.features
106
+ .split(',').map((f) => `- [ ] ${f.trim()}`).join('\n');
107
+ const permissoes = [
108
+ funcionalidades.camera && '- Câmera / Galeria',
109
+ funcionalidades.localizacao && '- Localização / GPS',
110
+ funcionalidades.push && '- Notificações push',
111
+ funcionalidades.biometria && '- Biometria (Face ID / Touch ID)',
112
+ ].filter(Boolean).join('\n') || '- Nenhuma adicional';
113
+ return `# Briefing — ${geral.projeto}
114
+
115
+ ## 📌 1. Informações Gerais
116
+ - **Projeto:** ${geral.projeto}
117
+ - **Cliente:** ${geral.cliente}
118
+ - **Responsável:** ${geral.responsavel}
119
+ - **Data da reunião:** ${geral.data}
120
+ - **Tipo:** Mobile
121
+ - **Versão:** 1.0
122
+
123
+ ## 🎯 2. Objetivo do App
124
+ - **Propósito:** ${objetivo.objetivo}
125
+ - **Problema resolvido:** ${objetivo.problema}
126
+ - **Plataformas:** ${objetivo.plataformas}
127
+ - **Framework:** ${objetivo.framework}
128
+ - **Modelo do app:** ${objetivo.monetizacao}
129
+ - **Prazo do MVP:** ${objetivo.prazo_mvp}
130
+
131
+ ## 🧩 3. Funcionalidades
132
+
133
+ ### Funcionalidades obrigatórias
134
+ ${features}
135
+
136
+ ### Funcionalidades de dispositivo
137
+ ${permissoes}
138
+
139
+ - Funcionamento offline: ${funcionalidades.offline ? 'Sim' : 'Não'}
140
+ - Modo dark/light: ${funcionalidades.dark_mode ? 'Sim' : 'Não'}
141
+
142
+ ## 🔗 4. Integração com Backend
143
+ - Conecta a API: ${backend.tem_api ? 'Sim' : 'Não'}
144
+ - API própria (Vireum): ${backend.api_propria ? 'Sim' : 'Não'}
145
+ - Autenticação: ${backend.auth}
146
+ - Analytics de uso: ${backend.analytics ? 'Sim' : 'Não'}
147
+
148
+ ## 🏪 5. Publicação nas Lojas
149
+ - Publicar nas lojas: ${lojas.publicar ? 'Sim' : 'Não'}
150
+ - Contas de desenvolvedor existentes: ${lojas.conta_existente ? 'Sim' : 'Não'}
151
+ - Deep linking: ${lojas.deep_linking ? 'Sim' : 'Não'}
152
+ - Atualizações OTA: ${lojas.updates_ota ? 'Sim (ex: Expo Updates)' : 'Não'}
153
+ - Custo operacional estimado: ${lojas.custo_operacional}
154
+ `;
155
+ }
@@ -0,0 +1,307 @@
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.runInitSystem = runInitSystem;
40
+ exports.salvarBriefing = salvarBriefing;
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const prompts_1 = require("@inquirer/prompts");
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ async function runInitSystem() {
46
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n Vireum Spec — Briefing Interativo (Sistema)\n'));
47
+ console.log(chalk_1.default.gray(' Responda as perguntas abaixo. As respostas serão salvas em .spec/briefing.md\n'));
48
+ // ── 1. Informações Gerais ──────────────────────────────────────────────────
49
+ console.log(chalk_1.default.hex('#2D7DD2').bold('📌 1. Informações Gerais\n'));
50
+ const geral = {
51
+ projeto: await (0, prompts_1.input)({ message: 'Nome do projeto:' }),
52
+ cliente: await (0, prompts_1.input)({ message: 'Nome do cliente:' }),
53
+ responsavel: await (0, prompts_1.input)({ message: 'Responsável pelo projeto (Vireum):' }),
54
+ data: await (0, prompts_1.input)({ message: 'Data da reunião:', default: new Date().toLocaleDateString('pt-BR') }),
55
+ dominio: await (0, prompts_1.select)({
56
+ message: 'Domínio do sistema:',
57
+ choices: [
58
+ { name: 'Saúde', value: 'Saúde' },
59
+ { name: 'Educação', value: 'Educação' },
60
+ { name: 'Varejo', value: 'Varejo' },
61
+ { name: 'Financeiro', value: 'Financeiro' },
62
+ { name: 'RH / Gestão de Pessoas', value: 'RH / Gestão de Pessoas' },
63
+ { name: 'Logística', value: 'Logística' },
64
+ { name: 'Jurídico', value: 'Jurídico' },
65
+ { name: 'Imobiliário', value: 'Imobiliário' },
66
+ { name: 'Indústria', value: 'Indústria' },
67
+ { name: 'Outro', value: 'Outro' },
68
+ ],
69
+ }),
70
+ };
71
+ // ── 2. Objetivo ────────────────────────────────────────────────────────────
72
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🎯 2. Objetivo do Projeto\n'));
73
+ const objetivo = {
74
+ objetivo: await (0, prompts_1.input)({ message: 'Qual é o objetivo principal da plataforma?' }),
75
+ problema: await (0, prompts_1.input)({ message: 'Qual problema o sistema resolve?' }),
76
+ curto_prazo: await (0, prompts_1.input)({ message: 'Resultado esperado no curto prazo:' }),
77
+ medio_prazo: await (0, prompts_1.input)({ message: 'Resultado esperado no médio prazo:' }),
78
+ longo_prazo: await (0, prompts_1.input)({ message: 'Resultado esperado no longo prazo:' }),
79
+ prioridade_cliente: await (0, prompts_1.input)({ message: 'O que o cliente precisa que funcione primeiro?' }),
80
+ prazo_mvp: await (0, prompts_1.input)({ message: 'Prazo esperado para o MVP:' }),
81
+ };
82
+ // ── 3. Escopo Funcional ────────────────────────────────────────────────────
83
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🧩 3. Escopo Funcional\n'));
84
+ const escopo = {
85
+ usuarios: await (0, prompts_1.input)({ message: 'Quem usará o sistema?' }),
86
+ modelo_negocio: await (0, prompts_1.select)({
87
+ message: 'Modelo de negócio:',
88
+ choices: [
89
+ { name: 'B2B (empresa para empresa)', value: 'B2B' },
90
+ { name: 'B2C (empresa para consumidor)', value: 'B2C' },
91
+ { name: 'B2B2C', value: 'B2B2C' },
92
+ { name: 'Interno (uso da própria empresa)', value: 'Interno' },
93
+ ],
94
+ }),
95
+ multi_usuario: await (0, prompts_1.confirm)({ message: 'Existem diferentes tipos de usuários?', default: false }),
96
+ niveis_acesso: await (0, prompts_1.confirm)({ message: 'Existem níveis de acesso diferentes?', default: false }),
97
+ features_obrigatorias: await (0, prompts_1.input)({ message: 'Funcionalidades obrigatórias (separadas por vírgula):' }),
98
+ features_desejaveis: await (0, prompts_1.input)({ message: 'Funcionalidades desejáveis no MVP (separadas por vírgula):' }),
99
+ integracoes: await (0, prompts_1.input)({ message: 'Integrações externas? (CRM, ERP, WhatsApp, etc.)' }),
100
+ };
101
+ // ── 4. Regras de Negócio ───────────────────────────────────────────────────
102
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🏗️ 4. Regras de Negócio\n'));
103
+ const regras = {
104
+ regras: await (0, prompts_1.input)({ message: 'Principais regras que o sistema deve obedecer:' }),
105
+ excecoes: await (0, prompts_1.input)({ message: 'Exceções importantes:' }),
106
+ };
107
+ // ── 5. Financeiro ──────────────────────────────────────────────────────────
108
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n💰 5. Modelo Financeiro\n'));
109
+ const financeiro = {
110
+ pagamento: await (0, prompts_1.confirm)({ message: 'Haverá integração com meio de pagamento?', default: false }),
111
+ cobranca: await (0, prompts_1.select)({
112
+ message: 'Modelo de cobrança:',
113
+ choices: [
114
+ { name: 'Não aplicável', value: 'Não aplicável' },
115
+ { name: 'Assinatura recorrente', value: 'Assinatura recorrente' },
116
+ { name: 'Compra única', value: 'Compra única' },
117
+ { name: 'Ambos', value: 'Ambos' },
118
+ ],
119
+ }),
120
+ estorno: await (0, prompts_1.confirm)({ message: 'Existem regras de estorno ou cancelamento?', default: false }),
121
+ };
122
+ // ── 6. Métricas ────────────────────────────────────────────────────────────
123
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n📊 6. Métricas e Indicadores\n'));
124
+ const metricas = {
125
+ kpis: await (0, prompts_1.input)({ message: 'Quais KPIs devem ser acompanhados?' }),
126
+ dashboard: await (0, prompts_1.confirm)({ message: 'Precisa de dashboard administrativo?', default: false }),
127
+ relatorios: await (0, prompts_1.confirm)({ message: 'Precisa exportar relatórios?', default: false }),
128
+ };
129
+ // ── 7. Plataforma e DevOps ─────────────────────────────────────────────────
130
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n📱 7. Plataforma e Infraestrutura\n'));
131
+ const plataforma = {
132
+ tipo: await (0, prompts_1.select)({
133
+ message: 'O sistema será:',
134
+ choices: [
135
+ { name: 'Apenas Web', value: 'Apenas Web' },
136
+ { name: 'Web + App', value: 'Web + App' },
137
+ { name: 'Apenas App', value: 'Apenas App' },
138
+ ],
139
+ }),
140
+ app_futuro: await (0, prompts_1.confirm)({ message: 'Pretende lançar aplicativo futuramente?', default: false }),
141
+ push: await (0, prompts_1.confirm)({ message: 'Precisa de notificações push?', default: false }),
142
+ hospedagem: await (0, prompts_1.input)({ message: 'Hospedagem preferida:' }),
143
+ custo_operacional: await (0, prompts_1.select)({
144
+ message: 'Custo operacional mensal estimado:',
145
+ choices: [
146
+ { name: 'Até R$ 200 — projeto leve, baixo tráfego', value: 'Até R$ 200' },
147
+ { name: 'R$ 200–800 — projeto moderado', value: 'R$ 200–800' },
148
+ { name: 'R$ 800–3k — projeto robusto', value: 'R$ 800–3k' },
149
+ { name: 'Acima de R$ 3k — missão crítica / alta escala', value: 'Acima de R$ 3k' },
150
+ { name: 'A definir com o cliente', value: 'A definir' },
151
+ ],
152
+ }),
153
+ cicd: await (0, prompts_1.confirm)({ message: 'Precisa de CI/CD desde o início?', default: false }),
154
+ staging: await (0, prompts_1.confirm)({ message: 'Precisa de ambiente de staging?', default: false }),
155
+ dominio: await (0, prompts_1.confirm)({ message: 'Já tem domínio/DNS configurado?', default: false }),
156
+ legado: await (0, prompts_1.confirm)({ message: 'Existe sistema legado que precisa integrar?', default: false }),
157
+ backup_sla: await (0, prompts_1.confirm)({ message: 'Backups e SLA são requisito do cliente?', default: false }),
158
+ };
159
+ // ── 8. Segurança e Jurídico ────────────────────────────────────────────────
160
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🔐 8. Segurança e Jurídico\n'));
161
+ const seguranca = {
162
+ dados_sensiveis: await (0, prompts_1.confirm)({ message: 'Dados sensíveis serão armazenados?', default: false }),
163
+ lgpd: await (0, prompts_1.confirm)({ message: 'Precisa de conformidade com LGPD?', default: true }),
164
+ termos: await (0, prompts_1.confirm)({ message: 'Precisa de termos de uso?', default: false }),
165
+ acesso_avancado: await (0, prompts_1.confirm)({ message: 'Haverá controle de acesso avançado?', default: false }),
166
+ };
167
+ // ── 9. Escala ──────────────────────────────────────────────────────────────
168
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n📈 9. Escala e Crescimento\n'));
169
+ const escala = {
170
+ usuarios_lancamento: await (0, prompts_1.input)({ message: 'Número esperado de usuários no lançamento:' }),
171
+ crescimento_1ano: await (0, prompts_1.input)({ message: 'Crescimento estimado em 1 ano:' }),
172
+ uso: await (0, prompts_1.select)({
173
+ message: 'Padrão de uso:',
174
+ choices: [
175
+ { name: 'Diário intenso', value: 'Diário intenso' },
176
+ { name: 'Diário moderado', value: 'Diário moderado' },
177
+ { name: 'Esporádico', value: 'Esporádico' },
178
+ ],
179
+ }),
180
+ };
181
+ // ── 10. Operacional ────────────────────────────────────────────────────────
182
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n⚙️ 10. Operacional\n'));
183
+ const operacional = {
184
+ operador: await (0, prompts_1.input)({ message: 'Quem vai operar o sistema?' }),
185
+ equipe: await (0, prompts_1.confirm)({ message: 'Haverá equipe interna dedicada?', default: false }),
186
+ treinamento: await (0, prompts_1.confirm)({ message: 'Necessita treinamento?', default: false }),
187
+ suporte: await (0, prompts_1.confirm)({ message: 'Necessita suporte mensal?', default: false }),
188
+ };
189
+ // ── 11. Riscos ─────────────────────────────────────────────────────────────
190
+ console.log(chalk_1.default.hex('#2D7DD2').bold('\n🧠 11. Riscos Identificados\n'));
191
+ const riscos = {
192
+ risco_tecnico: await (0, prompts_1.input)({ message: 'Risco técnico identificado:' }),
193
+ risco_juridico: await (0, prompts_1.input)({ message: 'Risco jurídico identificado:' }),
194
+ risco_operacional: await (0, prompts_1.input)({ message: 'Risco operacional identificado:' }),
195
+ };
196
+ const briefing = gerarBriefingSystem({ geral, objetivo, escopo, regras, financeiro, metricas, plataforma, seguranca, escala, operacional, riscos });
197
+ salvarBriefing(briefing, 'system');
198
+ }
199
+ function gerarBriefingSystem(data) {
200
+ const { geral, objetivo, escopo, regras, financeiro, metricas, plataforma, seguranca, escala, operacional, riscos } = data;
201
+ const features = escopo.features_obrigatorias
202
+ .split(',').map((f) => `- [ ] ${f.trim()}`).join('\n');
203
+ const featuresDesejaveis = escopo.features_desejaveis
204
+ .split(',').map((f) => `- [ ] ${f.trim()}`).join('\n');
205
+ return `# Briefing — ${geral.projeto}
206
+
207
+ ## 📌 1. Informações Gerais
208
+ - **Projeto:** ${geral.projeto}
209
+ - **Cliente:** ${geral.cliente}
210
+ - **Responsável:** ${geral.responsavel}
211
+ - **Data da reunião:** ${geral.data}
212
+ - **Domínio:** ${geral.dominio}
213
+ - **Versão:** 1.0
214
+
215
+ ## 🎯 2. Objetivo do Projeto
216
+ **Objetivo principal:** ${objetivo.objetivo}
217
+
218
+ **Problema que o sistema resolve:** ${objetivo.problema}
219
+
220
+ **Resultados esperados:**
221
+ - Curto prazo: ${objetivo.curto_prazo}
222
+ - Médio prazo: ${objetivo.medio_prazo}
223
+ - Longo prazo: ${objetivo.longo_prazo}
224
+
225
+ **Prioridade do cliente (o que precisa funcionar primeiro):** ${objetivo.prioridade_cliente}
226
+
227
+ **Prazo esperado para o MVP:** ${objetivo.prazo_mvp}
228
+
229
+ ## 🧩 3. Escopo Funcional
230
+
231
+ ### Público do Sistema
232
+ - Quem usará: ${escopo.usuarios}
233
+ - Modelo de negócio: ${escopo.modelo_negocio}
234
+ - Diferentes tipos de usuários: ${escopo.multi_usuario ? 'Sim' : 'Não'}
235
+ - Níveis de acesso: ${escopo.niveis_acesso ? 'Sim' : 'Não'}
236
+
237
+ ### Funcionalidades Obrigatórias
238
+ ${features}
239
+
240
+ ### Funcionalidades Desejáveis (não obrigatórias no MVP)
241
+ ${featuresDesejaveis}
242
+
243
+ ### Integrações Externas
244
+ ${escopo.integracoes || 'Nenhuma identificada'}
245
+
246
+ ## 🏗️ 4. Regras de Negócio
247
+ ${regras.regras}
248
+
249
+ **Exceções:** ${regras.excecoes || 'Nenhuma'}
250
+
251
+ ## 💰 5. Modelo Financeiro
252
+ - Integração com pagamento: ${financeiro.pagamento ? 'Sim' : 'Não'}
253
+ - Modelo de cobrança: ${financeiro.cobranca}
254
+ - Regras de estorno/cancelamento: ${financeiro.estorno ? 'Sim' : 'Não'}
255
+
256
+ ## 📊 6. Métricas e Indicadores
257
+ - KPIs: ${metricas.kpis}
258
+ - Dashboard administrativo: ${metricas.dashboard ? 'Sim' : 'Não'}
259
+ - Exportação de relatórios: ${metricas.relatorios ? 'Sim' : 'Não'}
260
+
261
+ ## 📱 7. Plataforma e Infraestrutura
262
+ - Tipo: ${plataforma.tipo}
263
+ - App futuro: ${plataforma.app_futuro ? 'Sim' : 'Não'}
264
+ - Notificações push: ${plataforma.push ? 'Sim' : 'Não'}
265
+ - Hospedagem: ${plataforma.hospedagem || 'A definir'}
266
+ - Custo operacional estimado: ${plataforma.custo_operacional}
267
+ - CI/CD desde o início: ${plataforma.cicd ? 'Sim' : 'Não'}
268
+ - Ambiente de staging: ${plataforma.staging ? 'Sim' : 'Não'}
269
+ - Domínio configurado: ${plataforma.dominio ? 'Sim' : 'Não'}
270
+ - Sistema legado: ${plataforma.legado ? 'Sim' : 'Não'}
271
+ - Backup e SLA: ${plataforma.backup_sla ? 'Sim' : 'Não'}
272
+
273
+ ## 🔐 8. Segurança e Jurídico
274
+ - Dados sensíveis: ${seguranca.dados_sensiveis ? 'Sim' : 'Não'}
275
+ - LGPD: ${seguranca.lgpd ? 'Sim' : 'Não'}
276
+ - Termos de uso: ${seguranca.termos ? 'Sim' : 'Não'}
277
+ - Controle de acesso avançado: ${seguranca.acesso_avancado ? 'Sim' : 'Não'}
278
+
279
+ ## 📈 9. Escala e Crescimento
280
+ - Usuários no lançamento: ${escala.usuarios_lancamento}
281
+ - Crescimento em 1 ano: ${escala.crescimento_1ano}
282
+ - Padrão de uso: ${escala.uso}
283
+
284
+ ## ⚙️ 10. Operacional
285
+ - Operador: ${operacional.operador}
286
+ - Equipe interna: ${operacional.equipe ? 'Sim' : 'Não'}
287
+ - Treinamento: ${operacional.treinamento ? 'Sim' : 'Não'}
288
+ - Suporte mensal: ${operacional.suporte ? 'Sim' : 'Não'}
289
+
290
+ ## 🧠 11. Riscos Identificados
291
+ - Risco técnico: ${riscos.risco_tecnico || 'Nenhum identificado'}
292
+ - Risco jurídico: ${riscos.risco_juridico || 'Nenhum identificado'}
293
+ - Risco operacional: ${riscos.risco_operacional || 'Nenhum identificado'}
294
+ `;
295
+ }
296
+ function salvarBriefing(briefing, tipo = 'system') {
297
+ const specDir = path.join(process.cwd(), '.spec');
298
+ if (!fs.existsSync(specDir))
299
+ fs.mkdirSync(specDir, { recursive: true });
300
+ const tasksDir = path.join(specDir, 'tasks');
301
+ if (!fs.existsSync(tasksDir))
302
+ fs.mkdirSync(tasksDir, { recursive: true });
303
+ fs.writeFileSync(path.join(specDir, 'briefing.md'), briefing, 'utf-8');
304
+ fs.writeFileSync(path.join(specDir, 'meta.json'), JSON.stringify({ tipo, criadoEm: new Date().toISOString() }, null, 2), 'utf-8');
305
+ console.log(chalk_1.default.green.bold('\n✅ Briefing salvo em .spec/briefing.md\n'));
306
+ console.log(chalk_1.default.gray(' Próximo passo: ') + chalk_1.default.white('vireum-spec distill') + chalk_1.default.gray(' para gerar os arquivos de spec\n'));
307
+ }