@neetru/cli 2.2.0 → 2.3.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/dist/index.js CHANGED
@@ -5,12 +5,12 @@ import { CLI_VERSION } from './version.js';
5
5
  const program = new Command();
6
6
  program
7
7
  .name('neetru')
8
- .description('Neetru Developer Kit scaffold, AI assistant e deploy para produtos SaaS')
8
+ .description('Operar o Neetru Developer Kit (scaffold, AI, deploy)')
9
9
  .version(CLI_VERSION);
10
10
  // ── neetru ai ─────────────────────────────────────────────────────────
11
11
  program
12
12
  .command('ai')
13
- .description('REPL interativo com IA Neetru-aware (Claude / OpenAI / Gemini)')
13
+ .description('Abrir REPL de IA Neetru-aware (Claude/OpenAI/Gemini)')
14
14
  .option('-m, --model <model>', 'modelo: claude | openai | gemini | auto', 'auto')
15
15
  .action(async (opts) => {
16
16
  const { runAiRepl } = await import('./commands/ai.js');
@@ -20,7 +20,7 @@ program
20
20
  // v2.1.1 — prompt interativo de caminho + merge mode + preserva arquivos
21
21
  program
22
22
  .command('init <name>')
23
- .description('Scaffold de novo produto SaaS Neetru (interativo — escolhe new subdir | merge cwd | custom path)')
23
+ .description('Inicializar scaffold de produto SaaS Neetru')
24
24
  .option('--type <type>', 'nextjs | node-api', 'nextjs')
25
25
  .option('--here', 'init no cwd atual (modo merge — preserva existentes)')
26
26
  .option('--path <path>', 'custom path target')
@@ -41,7 +41,7 @@ program
41
41
  // Cria produto + workspace + scaffold local + abre painel — single command.
42
42
  program
43
43
  .command('new <name>')
44
- .description('Macro: cria produto + workspace + scaffold + abre painel (end-to-end)')
44
+ .description('Criar produto, workspace, scaffold e abrir painel')
45
45
  .option('--product-slug <slug>', 'slug do produto (default: derivado de <name>)')
46
46
  .option('--env <env>', 'dev (default) | staging | prod', 'dev')
47
47
  .option('--tier <tier>', 'standard (default) | dev | enterprise', 'standard')
@@ -61,27 +61,56 @@ program
61
61
  json: !!opts.json,
62
62
  });
63
63
  });
64
+ // ── neetru auth ───────────────────────────────────────────────────────
65
+ // Wave D — detecta Claude Code/Codex/Gemini instalados e reaproveita creds.
66
+ const authCmd = program
67
+ .command('auth')
68
+ .description('Gerenciar credenciais de IA (Claude, Codex, Gemini)');
69
+ authCmd
70
+ .command('status')
71
+ .description('Listar provedores detectados e estado das credenciais')
72
+ .option('--json', 'saída JSON')
73
+ .action(async (opts) => {
74
+ const { runAuthStatus } = await import('./commands/auth.js');
75
+ await runAuthStatus({ json: !!opts.json });
76
+ });
77
+ authCmd
78
+ .command('setup')
79
+ .description('Wizard interativo: detectar, instalar, configurar')
80
+ .option('--json', 'modo não-interativo (equivalente a pull)')
81
+ .action(async (opts) => {
82
+ const { runAuthSetup } = await import('./commands/auth.js');
83
+ await runAuthSetup({ json: !!opts.json });
84
+ });
85
+ authCmd
86
+ .command('pull')
87
+ .description('Copiar creds dos CLIs detectados pra config do Neetru')
88
+ .option('--json', 'saída JSON')
89
+ .action(async (opts) => {
90
+ const { runAuthPull } = await import('./commands/auth.js');
91
+ await runAuthPull({ json: !!opts.json });
92
+ });
64
93
  // ── neetru config ─────────────────────────────────────────────────────
65
94
  const configCmd = program
66
95
  .command('config')
67
- .description('Gerenciar configurações do CLI (chaves de API, modelo padrão)');
96
+ .description('Gerenciar configurações do CLI');
68
97
  configCmd
69
98
  .command('set <key> <value>')
70
- .description('Define uma configuração')
99
+ .description('Definir valor de configuração')
71
100
  .action(async (key, value) => {
72
101
  const { configSet } = await import('./commands/config.js');
73
102
  configSet(key, value);
74
103
  });
75
104
  configCmd
76
105
  .command('get [key]')
77
- .description(' configuração(ões)')
106
+ .description('Ler configuração por chave (ou todas)')
78
107
  .action(async (key) => {
79
108
  const { configGet } = await import('./commands/config.js');
80
109
  configGet(key);
81
110
  });
82
111
  configCmd
83
112
  .command('path')
84
- .description('Mostra o caminho do arquivo de configuração')
113
+ .description('Mostrar caminho do arquivo de configuração')
85
114
  .action(async () => {
86
115
  const { configPath } = await import('./commands/config.js');
87
116
  configPath();
@@ -89,7 +118,7 @@ configCmd
89
118
  // ── neetru login ──────────────────────────────────────────────────────
90
119
  program
91
120
  .command('login')
92
- .description('Autentica o CLI via Device Code OAuth (RFC 8628)')
121
+ .description('Autenticar CLI via Device Code OAuth (RFC 8628)')
93
122
  .option('--token <token>', 'token nrt_<keyId>_<secret> (modo CI/legado, pula browser)')
94
123
  .option('--json', 'saída em JSON (machine-readable)')
95
124
  .action(async (opts) => {
@@ -99,7 +128,7 @@ program
99
128
  // ── neetru logout ─────────────────────────────────────────────────────
100
129
  program
101
130
  .command('logout')
102
- .description('Apaga as credenciais locais (~/.config/neetru-cli/auth.json + cache legado)')
131
+ .description('Remover credenciais locais do CLI')
103
132
  .action(async () => {
104
133
  const { runLogout } = await import('./commands/logout.js');
105
134
  await runLogout();
@@ -107,7 +136,7 @@ program
107
136
  // ── neetru whoami ─────────────────────────────────────────────────────
108
137
  program
109
138
  .command('whoami')
110
- .description('Mostra a identidade da chave CLI corrente')
139
+ .description('Mostrar identidade da chave CLI corrente')
111
140
  .option('--json', 'saída em JSON')
112
141
  .action(async (opts) => {
113
142
  const { runWhoami } = await import('./commands/whoami.js');
@@ -116,7 +145,7 @@ program
116
145
  // ── neetru build ──────────────────────────────────────────────────────
117
146
  program
118
147
  .command('build')
119
- .description('Empacota o produto no diretório atual num tarball pronto para deploy')
148
+ .description('Construir tarball do produto pronto para deploy')
120
149
  .option('--product <slug>', 'override do slug (default: lê neetru.config.json)')
121
150
  .option('--stack <stack>', 'node | docker | php-apache | static (default: detectado)')
122
151
  .option('--output <dir>', 'diretório de saída', '.neetru-build')
@@ -135,7 +164,7 @@ program
135
164
  // ── neetru deploy ─────────────────────────────────────────────────────
136
165
  program
137
166
  .command('deploy')
138
- .description('Deploy do produto via pipeline Neetru Core (interativo por default)')
167
+ .description('Deployar produto via pipeline do Neetru Core')
139
168
  .option('--product <slug>', 'slug do produto')
140
169
  .option('--version <version>', 'versão a deployar')
141
170
  .option('--stack <stack>', 'node | docker | php-apache | static')
@@ -174,7 +203,7 @@ program
174
203
  // delega ao status de workspace legado (backward-compat).
175
204
  program
176
205
  .command('status')
177
- .description('Saúde das superfícies públicas (landing/api/portal/políticas). --client-id = status de workspace')
206
+ .description('Verificar saúde das superfícies públicas do Core')
178
207
  .option('--client-id <id>', 'oauthClientId do workspace (status de workspace legado)')
179
208
  .option('--json', 'saída em JSON')
180
209
  .action(async (opts) => {
@@ -184,10 +213,10 @@ program
184
213
  // ── neetru tenants ────────────────────────────────────────────────────
185
214
  const tenantsCmd = program
186
215
  .command('tenants')
187
- .description('Control plane — inspeção de tenants (read-only)');
216
+ .description('Gerenciar tenants (read-only)');
188
217
  tenantsCmd
189
218
  .command('list')
190
- .description('Lista tenants (filtros --status / --product)')
219
+ .description('Listar tenants')
191
220
  .option('--status <status>', 'ativo | em provisionamento | suspenso | arquivado')
192
221
  .option('--product <productId>', 'filtra por productId')
193
222
  .option('--limit <n>', 'máximo de resultados (default 100, max 500)')
@@ -203,7 +232,7 @@ tenantsCmd
203
232
  });
204
233
  tenantsCmd
205
234
  .command('get <id>')
206
- .description('Detalha um tenant pelo ID')
235
+ .description('Mostrar detalhes de um tenant')
207
236
  .option('--json', 'saída em JSON')
208
237
  .action(async (id, opts) => {
209
238
  const { runTenantsGet } = await import('./commands/tenants.js');
@@ -211,7 +240,7 @@ tenantsCmd
211
240
  });
212
241
  tenantsCmd
213
242
  .command('create')
214
- .description('Cria um tenant (status inicial: em provisionamento)')
243
+ .description('Criar tenant (status inicial: em provisionamento)')
215
244
  .requiredOption('--name <name>', 'nome do tenant')
216
245
  .requiredOption('--slug <slug>', 'slug do tenant')
217
246
  .requiredOption('--customer <customerId>', 'id do customer')
@@ -233,7 +262,7 @@ tenantsCmd
233
262
  });
234
263
  tenantsCmd
235
264
  .command('update <id>')
236
- .description('Atualiza dados de um tenant existente')
265
+ .description('Atualizar dados de um tenant')
237
266
  .requiredOption('--name <name>', 'nome do tenant')
238
267
  .requiredOption('--slug <slug>', 'slug do tenant')
239
268
  .requiredOption('--customer <customerId>', 'id do customer')
@@ -255,7 +284,7 @@ tenantsCmd
255
284
  });
256
285
  tenantsCmd
257
286
  .command('suspend <id>')
258
- .description('Suspende um tenant (destrutivo — confirmação interativa)')
287
+ .description('Suspender tenant (destrutivo — exige confirmação)')
259
288
  .option('--yes', 'pula a confirmação interativa (modo script)')
260
289
  .option('--force', 'alias de --yes')
261
290
  .option('--json', 'saída em JSON')
@@ -265,7 +294,7 @@ tenantsCmd
265
294
  });
266
295
  tenantsCmd
267
296
  .command('reactivate <id>')
268
- .description('Reativa um tenant suspenso')
297
+ .description('Reativar tenant suspenso')
269
298
  .option('--json', 'saída em JSON')
270
299
  .action(async (id, opts) => {
271
300
  const { runTenantsReactivate } = await import('./commands/tenants.js');
@@ -274,10 +303,10 @@ tenantsCmd
274
303
  // ── neetru audit ──────────────────────────────────────────────────────
275
304
  const auditCmd = program
276
305
  .command('audit')
277
- .description('Control plane — trilha de auditoria do Core (read-only)');
306
+ .description('Consultar trilha de auditoria do Core (read-only)');
278
307
  auditCmd
279
308
  .command('tail')
280
- .description('Últimos N eventos de audit_logs (mais recente primeiro)')
309
+ .description('Listar últimos eventos de audit_logs')
281
310
  .option('-n, --limit <n>', 'número de eventos (default 50, max 200)')
282
311
  .option('--action <substring>', 'filtra por substring da ação (ex: billing, tenant.create)')
283
312
  .option('--severity <level>', 'info | warning | critical')
@@ -296,10 +325,10 @@ auditCmd
296
325
  // ── neetru billing ────────────────────────────────────────────────────
297
326
  const billingCmd = program
298
327
  .command('billing')
299
- .description('Control plane billing/contabilidade (read-only)');
328
+ .description('Consultar billing e contabilidade (read-only)');
300
329
  billingCmd
301
330
  .command('summary')
302
- .description('Sumário contábil do mês corrente (MRR, invoices, subscriptions)')
331
+ .description('Mostrar sumário contábil do mês (MRR, invoices, subs)')
303
332
  .option('--year <YYYY>', 'ano (default: corrente)')
304
333
  .option('--month <1-12>', 'mês (default: corrente)')
305
334
  .option('--json', 'saída em JSON')
@@ -310,10 +339,10 @@ billingCmd
310
339
  // ── neetru servers ────────────────────────────────────────────────────
311
340
  const serversCmd = program
312
341
  .command('servers')
313
- .description('Control plane inventário de servers (read-only)');
342
+ .description('Gerenciar servers e inventário de VMs');
314
343
  serversCmd
315
344
  .command('list')
316
- .description('Lista servers (filtros --status / --provider / --capacity)')
345
+ .description('Listar servers')
317
346
  .option('--status <status>', 'online (operacional + heartbeat fresco)')
318
347
  .option('--provider <provider>', 'hetzner | digitalocean | aws | ...')
319
348
  .option('--capacity', 'inclui colunas de RAM/CPU/disco')
@@ -329,7 +358,7 @@ serversCmd
329
358
  });
330
359
  serversCmd
331
360
  .command('provision')
332
- .description('Provisiona uma VM GCP (admin only) — cria server + registration token')
361
+ .description('Provisionar VM GCP e gerar registration token (admin)')
333
362
  .requiredOption('--name <name>', 'nome do servidor')
334
363
  .requiredOption('--zone <zone>', 'zona GCP (ex: us-central1-a)')
335
364
  .requiredOption('--machine-type <type>', 'machine type GCP (ex: e2-small)')
@@ -349,7 +378,7 @@ serversCmd
349
378
  });
350
379
  serversCmd
351
380
  .command('deactivate <serverId>')
352
- .description('Desativa um server (destrutivo top-tier — confirmação + step-up MFA)')
381
+ .description('Desativar server (destrutivo top-tier — exige MFA)')
353
382
  .option('--yes', 'pula a confirmação interativa (modo script)')
354
383
  .option('--force', 'alias de --yes')
355
384
  .option('--dry-run', 'valida e mostra o efeito sem aplicar')
@@ -367,7 +396,7 @@ serversCmd
367
396
  });
368
397
  serversCmd
369
398
  .command('dispatch <serverId> <commandType>')
370
- .description('Enfileira um comando pro agente Linux do server')
399
+ .description('Enfileirar comando para o agente Linux do server')
371
400
  .option('--params <json>', 'objeto JSON de params do comando')
372
401
  .option('--json', 'saída em JSON')
373
402
  .action(async (id, commandType, opts) => {
@@ -377,10 +406,10 @@ serversCmd
377
406
  // ── neetru workspaces ─────────────────────────────────────────────────
378
407
  const workspacesCmd = program
379
408
  .command('workspaces')
380
- .description('Control plane — runtime shared de workspaces');
409
+ .description('Gerenciar workspaces compartilhados');
381
410
  workspacesCmd
382
411
  .command('create')
383
- .description('Cria um workspace (devolve OAuth client secret one-time)')
412
+ .description('Criar workspace (retorna OAuth secret one-time)')
384
413
  .requiredOption('--product <productId>', 'id do produto')
385
414
  .requiredOption('--customer <customerId>', 'id do customer')
386
415
  .requiredOption('--env <env>', 'dev | staging | prod')
@@ -400,7 +429,7 @@ workspacesCmd
400
429
  });
401
430
  workspacesCmd
402
431
  .command('advance <workspaceId>')
403
- .description('Promove uma versão de bundle pra "running" no workspace')
432
+ .description('Promover versão de bundle para running no workspace')
404
433
  .requiredOption('--product <slug>', 'productSlug do bundle')
405
434
  .requiredOption('--version <version>', 'versão do bundle a ativar')
406
435
  .option('--json', 'saída em JSON')
@@ -414,7 +443,7 @@ workspacesCmd
414
443
  });
415
444
  workspacesCmd
416
445
  .command('list')
417
- .description('Lista workspaces (filtros --product / --env / --status)')
446
+ .description('Listar workspaces')
418
447
  .option('--product <productId>', 'filtra por productId')
419
448
  .option('--env <env>', 'dev | staging | prod')
420
449
  .option('--status <status>', 'active | paused | provisioning | …')
@@ -430,7 +459,7 @@ workspacesCmd
430
459
  });
431
460
  workspacesCmd
432
461
  .command('get <workspaceId>')
433
- .description('Detalha um workspace pelo ID')
462
+ .description('Mostrar detalhes de um workspace')
434
463
  .option('--json', 'saída em JSON')
435
464
  .action(async (id, opts) => {
436
465
  const { runWorkspacesGet } = await import('./commands/workspaces.js');
@@ -438,7 +467,7 @@ workspacesCmd
438
467
  });
439
468
  workspacesCmd
440
469
  .command('open <workspaceId>')
441
- .description('Abre o painel do workspace no browser (core.neetru.com/workspaces/<id>)')
470
+ .description('Abrir painel do workspace no browser')
442
471
  .action(async (id) => {
443
472
  const { runWorkspacesOpen } = await import('./commands/workspaces.js');
444
473
  await runWorkspacesOpen(id);
@@ -446,10 +475,10 @@ workspacesCmd
446
475
  // ── neetru deployments ────────────────────────────────────────────────
447
476
  const deploymentsCmd = program
448
477
  .command('deployments')
449
- .description('Control plane — recurso deployments/ (paridade com a UI)');
478
+ .description('Gerenciar deployments do Core');
450
479
  deploymentsCmd
451
480
  .command('create')
452
- .description('Cria um deployment (dispara comando deploy pro agente)')
481
+ .description('Criar deployment (dispara comando para o agente)')
453
482
  .requiredOption('--product <productId>', 'id do produto')
454
483
  .requiredOption('--tenant <tenantId>', 'id do tenant alvo')
455
484
  .requiredOption('--version <version>', 'versão a deployar')
@@ -469,7 +498,7 @@ deploymentsCmd
469
498
  });
470
499
  deploymentsCmd
471
500
  .command('rollback <deploymentId>')
472
- .description('Rollback de um deployment (destrutivo top-tier — confirmação + step-up MFA)')
501
+ .description('Reverter deployment (destrutivo top-tier — exige MFA)')
473
502
  .option('--yes', 'pula a confirmação interativa (modo script)')
474
503
  .option('--force', 'alias de --yes')
475
504
  .option('--dry-run', 'valida e mostra o efeito sem aplicar')
@@ -488,10 +517,10 @@ deploymentsCmd
488
517
  // ── neetru cloud-run ──────────────────────────────────────────────────
489
518
  const cloudRunCmd = program
490
519
  .command('cloud-run')
491
- .description('Control plane — serviços Cloud Run (admin only)');
520
+ .description('Gerenciar serviços Cloud Run (admin)');
492
521
  cloudRunCmd
493
522
  .command('pause <service>')
494
- .description('Pausa um serviço Cloud Run (scale-to-zero)')
523
+ .description('Pausar serviço Cloud Run (scale-to-zero)')
495
524
  .option('--json', 'saída em JSON')
496
525
  .action(async (service, opts) => {
497
526
  const { runCloudRunPause } = await import('./commands/cloud-run.js');
@@ -499,7 +528,7 @@ cloudRunCmd
499
528
  });
500
529
  cloudRunCmd
501
530
  .command('resume <service>')
502
- .description('Retoma um serviço Cloud Run pausado')
531
+ .description('Retomar serviço Cloud Run pausado')
503
532
  .option('--min-instances <n>', 'minInstanceCount')
504
533
  .option('--max-instances <n>', 'maxInstanceCount')
505
534
  .option('--json', 'saída em JSON')
@@ -513,7 +542,7 @@ cloudRunCmd
513
542
  });
514
543
  cloudRunCmd
515
544
  .command('delete <service>')
516
- .description('Exclui um serviço Cloud Run (IRREVERSÍVEL — confirmação + step-up MFA)')
545
+ .description('Remover serviço Cloud Run (IRREVERSÍVEL — exige MFA)')
517
546
  .option('--yes', 'pula a confirmação interativa (modo script)')
518
547
  .option('--force', 'alias de --yes')
519
548
  .option('--dry-run', 'valida e mostra o efeito sem aplicar')
@@ -532,10 +561,10 @@ cloudRunCmd
532
561
  // ── neetru api-catalog ────────────────────────────────────────────────
533
562
  const apiCatalogCmd = program
534
563
  .command('api-catalog')
535
- .description('Control plane — registry de APIs versionadas (apis/)');
564
+ .description('Gerenciar catálogo de APIs versionadas');
536
565
  apiCatalogCmd
537
566
  .command('create <slug>')
538
- .description('Registra uma nova API no catálogo')
567
+ .description('Registrar nova API no catálogo')
539
568
  .requiredOption('--name <name>', 'nome da API')
540
569
  .requiredOption('--base-url <url>', 'base URL')
541
570
  .requiredOption('--version <version>', 'versão')
@@ -565,7 +594,7 @@ apiCatalogCmd
565
594
  });
566
595
  apiCatalogCmd
567
596
  .command('update <slug>')
568
- .description('Atualiza uma entrada do catálogo (slug é imutável)')
597
+ .description('Atualizar entrada do catálogo (slug imutável)')
569
598
  .requiredOption('--name <name>', 'nome da API')
570
599
  .requiredOption('--base-url <url>', 'base URL')
571
600
  .requiredOption('--version <version>', 'versão')
@@ -595,7 +624,7 @@ apiCatalogCmd
595
624
  });
596
625
  apiCatalogCmd
597
626
  .command('archive <slug>')
598
- .description('Soft-delete de uma API (--unarchive reativa)')
627
+ .description('Arquivar API por soft-delete (--unarchive reverte)')
599
628
  .option('--unarchive', 'reativa em vez de arquivar')
600
629
  .option('--yes', 'pula a confirmação interativa (modo script)')
601
630
  .option('--force', 'alias de --yes')
@@ -611,7 +640,7 @@ apiCatalogCmd
611
640
  });
612
641
  apiCatalogCmd
613
642
  .command('delete <slug>')
614
- .description('Delete físico de uma API (IRREVERSÍVEL — confirmação + step-up MFA)')
643
+ .description('Remover API fisicamente (IRREVERSÍVEL — exige MFA)')
615
644
  .option('--yes', 'pula a confirmação interativa (modo script)')
616
645
  .option('--force', 'alias de --yes')
617
646
  .option('--dry-run', 'valida e mostra o efeito sem aplicar')
@@ -630,10 +659,10 @@ apiCatalogCmd
630
659
  // ── neetru products ───────────────────────────────────────────────────
631
660
  const productsCmd = program
632
661
  .command('products')
633
- .description('Control plane — registry interno de produtos SaaS (read-only)');
662
+ .description('Gerenciar registry de produtos SaaS internos');
634
663
  productsCmd
635
664
  .command('list')
636
- .description('Lista produtos internos (registry products/, filtro --status)')
665
+ .description('Listar produtos internos')
637
666
  .option('--status <status>', 'ativo | beta | descontinuado')
638
667
  .option('--limit <n>', 'máximo de resultados (default 100, max 500)')
639
668
  .option('--json', 'saída em JSON')
@@ -643,7 +672,7 @@ productsCmd
643
672
  });
644
673
  productsCmd
645
674
  .command('create')
646
- .description('Cria um produto SaaS interno (interativo por default; --yes pra non-interactive)')
675
+ .description('Criar produto SaaS interno (interativo por default)')
647
676
  .option('--name <name>', 'nome do produto (interativo se ausente)')
648
677
  .option('--slug <slug>', 'slug (auto-derivado de --name se ausente)')
649
678
  .option('--description <text>', 'descrição (opcional)')
@@ -667,7 +696,7 @@ productsCmd
667
696
  });
668
697
  productsCmd
669
698
  .command('publish <slug>')
670
- .description('Publica um produto no catálogo público (published=true)')
699
+ .description('Publicar produto no catálogo público')
671
700
  .option('--json', 'saída em JSON')
672
701
  .action(async (slug, opts) => {
673
702
  const { runProductsPublish } = await import('./commands/products.js');
@@ -675,7 +704,7 @@ productsCmd
675
704
  });
676
705
  productsCmd
677
706
  .command('unpublish <slug>')
678
- .description('Remove um produto do catálogo público (published=false)')
707
+ .description('Remover produto do catálogo público')
679
708
  .option('--json', 'saída em JSON')
680
709
  .action(async (slug, opts) => {
681
710
  const { runProductsUnpublish } = await import('./commands/products.js');
@@ -684,10 +713,10 @@ productsCmd
684
713
  // ── neetru products db (Phase A — per-product DB isolation) ────────────
685
714
  const productsDbCmd = productsCmd
686
715
  .command('db')
687
- .description('Bancos de dados isolados por produto (firestore-instance | cloud-sql-* | vm-*)');
716
+ .description('Gerenciar bancos isolados por produto');
688
717
  productsDbCmd
689
718
  .command('list')
690
- .description('Lista bancos. Filtros: --product-id, --engine, --status')
719
+ .description('Listar bancos de produtos')
691
720
  .option('--product-id <id>')
692
721
  .option('--engine <engine>')
693
722
  .option('--status <status>')
@@ -703,7 +732,7 @@ productsDbCmd
703
732
  });
704
733
  productsDbCmd
705
734
  .command('engines')
706
- .description('Lista engines suportados')
735
+ .description('Listar engines de banco suportados')
707
736
  .option('--json')
708
737
  .action(async (opts) => {
709
738
  const { runDbEngines } = await import('./commands/products-db.js');
@@ -711,7 +740,7 @@ productsDbCmd
711
740
  });
712
741
  productsDbCmd
713
742
  .command('create')
714
- .description('Cria um banco (Phase A: registra + audit; provisionamento real é Phase B)')
743
+ .description('Criar banco de produto (Phase A: registra + audit)')
715
744
  .requiredOption('--product-id <id>')
716
745
  .requiredOption('--label <label>')
717
746
  .requiredOption('--engine <engine>', 'firestore-instance|cloud-sql-postgres|cloud-sql-mysql|vm-postgres-single|vm-postgres-cluster|vm-mysql-single|vm-mysql-cluster')
@@ -735,7 +764,7 @@ productsDbCmd
735
764
  });
736
765
  productsDbCmd
737
766
  .command('get <id>')
738
- .description('Detalhes de um banco')
767
+ .description('Mostrar detalhes de um banco')
739
768
  .option('--json')
740
769
  .action(async (id, opts) => {
741
770
  const { runDbGet } = await import('./commands/products-db.js');
@@ -743,7 +772,7 @@ productsDbCmd
743
772
  });
744
773
  productsDbCmd
745
774
  .command('status <id> <status>')
746
- .description('Atualiza status (requested|provisioning|active|degraded|failed|archived)')
775
+ .description('Atualizar status de um banco de produto')
747
776
  .option('--reason <text>')
748
777
  .option('--json')
749
778
  .action(async (id, status, opts) => {
@@ -752,7 +781,7 @@ productsDbCmd
752
781
  });
753
782
  productsDbCmd
754
783
  .command('retry <id>')
755
- .description('Re-enfileira provisionamento (status failed/degraded → requested)')
784
+ .description('Reenfileirar provisionamento de banco')
756
785
  .option('--json')
757
786
  .action(async (id, opts) => {
758
787
  const { runDbRetry } = await import('./commands/products-db.js');
@@ -760,7 +789,7 @@ productsDbCmd
760
789
  });
761
790
  productsDbCmd
762
791
  .command('rotate <id>')
763
- .description('Rotaciona credenciais (admin; Phase A: intent + audit)')
792
+ .description('Rotacionar credenciais do banco (admin)')
764
793
  .option('--json')
765
794
  .action(async (id, opts) => {
766
795
  const { runDbRotate } = await import('./commands/products-db.js');
@@ -768,7 +797,7 @@ productsDbCmd
768
797
  });
769
798
  productsDbCmd
770
799
  .command('delete <id>')
771
- .description('Arquiva o banco (soft-delete; admin)')
800
+ .description('Arquivar banco por soft-delete (admin)')
772
801
  .option('--json')
773
802
  .action(async (id, opts) => {
774
803
  const { runDbDelete } = await import('./commands/products-db.js');
@@ -777,7 +806,7 @@ productsDbCmd
777
806
  // ── neetru logs ───────────────────────────────────────────────────────
778
807
  program
779
808
  .command('logs')
780
- .description('Visualiza logs do workspace; suporta tail contínuo')
809
+ .description('Visualizar logs do workspace (suporta tail contínuo)')
781
810
  .option('--client-id <id>', 'oauthClientId do workspace')
782
811
  .option('-f, --follow', 'tail contínuo (poll a cada 5s)')
783
812
  .option('-n, --lines <count>', 'número de linhas a buscar', '50')
@@ -802,7 +831,7 @@ program
802
831
  // ── neetru validate ───────────────────────────────────────────────────
803
832
  program
804
833
  .command('validate')
805
- .description('Health check da config local + conexão com Core')
834
+ .description('Validar config local e conexão com o Core')
806
835
  .action(async () => {
807
836
  const { runValidate } = await import('./commands/validate.js');
808
837
  await runValidate();
@@ -810,7 +839,7 @@ program
810
839
  // ── neetru open ───────────────────────────────────────────────────────
811
840
  program
812
841
  .command('open [target]')
813
- .description('Abre uma página do painel Neetru no browser')
842
+ .description('Abrir página do painel Neetru no browser')
814
843
  .option('--client-id <id>', 'oauthClientId do workspace (anexa em targets workspace-scoped)')
815
844
  .action(async (target, opts) => {
816
845
  const { runOpen } = await import('./commands/open.js');
@@ -819,7 +848,7 @@ program
819
848
  // ── neetru publish ────────────────────────────────────────────────────
820
849
  program
821
850
  .command('publish')
822
- .description('Publica o produto no catálogo público da landing (public_products)')
851
+ .description('Publicar produto no catálogo público da landing')
823
852
  .option('--draft', 'salva como rascunho (published=false)')
824
853
  .option('--unpublish', 'remove o produto da landing (mantém o doc)')
825
854
  .option('--slug <slug>', 'override do slug do neetru.config.json')
@@ -850,7 +879,7 @@ program
850
879
  // ── neetru add ────────────────────────────────────────────────────────
851
880
  program
852
881
  .command('add <feature>')
853
- .description('v1.3 copia template (auth | billing | usage | users | support) pra src/lib/neetru/')
882
+ .description('Adicionar template de feature (auth/billing/usage/...)')
854
883
  .option('--force', 'sobrescrever arquivos existentes')
855
884
  .action(async (feature, opts) => {
856
885
  const { runAdd } = await import('./commands/add.js');
@@ -859,10 +888,10 @@ program
859
888
  // ── neetru mocks ──────────────────────────────────────────────────────
860
889
  const mocksCmd = program
861
890
  .command('mocks')
862
- .description('v1.3 gerenciar fixtures dev (NEETRU_ENV=dev)');
891
+ .description('Gerenciar fixtures de dev (NEETRU_ENV=dev)');
863
892
  mocksCmd
864
893
  .command('reset')
865
- .description('Reseta .neetru/dev-fixtures.json para {}')
894
+ .description('Resetar fixtures de dev para vazio')
866
895
  .action(async () => {
867
896
  const { runMocksReset } = await import('./commands/mocks.js');
868
897
  await runMocksReset();
@@ -870,10 +899,10 @@ mocksCmd
870
899
  // ── neetru env ────────────────────────────────────────────────────────
871
900
  const envCmd = program
872
901
  .command('env')
873
- .description('v1.3 — gerenciar configuração NEETRU_ENV no .env.local');
902
+ .description('Gerenciar NEETRU_ENV no .env.local');
874
903
  envCmd
875
904
  .command('switch <target>')
876
- .description('Alterna NEETRU_ENV: dev | workspace | production')
905
+ .description('Alternar NEETRU_ENV (dev/workspace/production)')
877
906
  .action(async (target) => {
878
907
  const { runEnvSwitch } = await import('./commands/env.js');
879
908
  await runEnvSwitch({ target });
@@ -881,10 +910,10 @@ envCmd
881
910
  // ── neetru db ─────────────────────────────────────────────────────────
882
911
  const dbCmd = program
883
912
  .command('db')
884
- .description('v1.4 gerência de schema/migrations/seed do produto');
913
+ .description('Gerenciar schema, migrations e seed do produto');
885
914
  dbCmd
886
915
  .command('init')
887
- .description('Cria manifest stub a partir de neetru.config.json')
916
+ .description('Criar manifest de schema a partir do config')
888
917
  .option('--out <path>', 'caminho do manifest (default db/schema.manifest.json)')
889
918
  .option('--force', 'sobrescreve se já existir')
890
919
  .action(async (opts) => {
@@ -893,7 +922,7 @@ dbCmd
893
922
  });
894
923
  dbCmd
895
924
  .command('migrate <toVersion>')
896
- .description('Aplica migration via Core (chama runMigrations Sprint 8)')
925
+ .description('Aplicar migration de schema via Core')
897
926
  .option('--from <fromVersion>', 'versão atual (default: schemaVersion do config)')
898
927
  .action(async (toVersion, opts) => {
899
928
  const { runDbMigrate } = await import('./commands/db.js');
@@ -901,7 +930,7 @@ dbCmd
901
930
  });
902
931
  dbCmd
903
932
  .command('seed')
904
- .description('Executa db/seed.ts no projeto (NEETRU_ENV=dev)')
933
+ .description('Executar script de seed do produto')
905
934
  .option('--script <path>', 'caminho custom do script de seed')
906
935
  .action(async (opts) => {
907
936
  const { runDbSeed } = await import('./commands/db.js');
@@ -910,10 +939,10 @@ dbCmd
910
939
  // ── neetru fn ─────────────────────────────────────────────────────────
911
940
  const fnCmd = program
912
941
  .command('fn')
913
- .description('v1.4 gestão de Functions/APIs do produto');
942
+ .description('Gerenciar Functions e APIs do produto');
914
943
  fnCmd
915
944
  .command('deploy')
916
- .description('Registra nova versão da API no catálogo neetru-apis (Sprint 7 stub)')
945
+ .description('Registrar nova versão da API no catálogo')
917
946
  .option('--version <v>', 'versão da API (default: apiVersion do config ou v1)')
918
947
  .option('--channel <channel>', 'stable | beta | alpha', 'stable')
919
948
  .option('--spec <path>', 'caminho de OpenAPI/JSON schema')
@@ -924,7 +953,7 @@ fnCmd
924
953
  // ── neetru promote ────────────────────────────────────────────────────
925
954
  program
926
955
  .command('promote')
927
- .description('v1.4 — solicita promotion entre ambientes (staff-gated). dev→workspace→beta→prod')
956
+ .description('Solicitar promotion entre ambientes (staff-gated)')
928
957
  .requiredOption('--from <env>', 'dev | workspace | beta | prod')
929
958
  .requiredOption('--to <env>', 'dev | workspace | beta | prod')
930
959
  .option('--product <slug>', 'override do slug do neetru.config.json')
@@ -945,7 +974,7 @@ program
945
974
  // ── neetru doctor ─────────────────────────────────────────────────────
946
975
  program
947
976
  .command('doctor')
948
- .description('v2.0 diagnóstico do CLI: token, core, schema, NEETRU_ENV, version')
977
+ .description('Diagnosticar saúde do CLI (token, core, schema, env)')
949
978
  .option('--json', 'saída em JSON (machine-readable)')
950
979
  .action(async (opts) => {
951
980
  const { runDoctor } = await import('./commands/doctor.js');
@@ -954,7 +983,7 @@ program
954
983
  // ── neetru upgrade ────────────────────────────────────────────────────
955
984
  program
956
985
  .command('upgrade')
957
- .description('v2.0 verifica latest no npm e exibe instrução de upgrade')
986
+ .description('Verificar versão mais recente do CLI no npm')
958
987
  .option('--json', 'saída em JSON')
959
988
  .action(async (opts) => {
960
989
  const { runUpgrade } = await import('./commands/upgrade.js');
@@ -963,7 +992,7 @@ program
963
992
  // ── neetru autocomplete ───────────────────────────────────────────────
964
993
  program
965
994
  .command('autocomplete <shell>')
966
- .description('v2.0 — gera script de shell completion (bash | zsh | pwsh)')
995
+ .description('Gerar script de shell completion (bash/zsh/pwsh)')
967
996
  .action(async (shell) => {
968
997
  const { runAutocomplete } = await import('./commands/autocomplete.js');
969
998
  await runAutocomplete(shell);
@@ -971,10 +1000,10 @@ program
971
1000
  // ── neetru agent release ──────────────────────────────────────────────
972
1001
  const agentCmd = program
973
1002
  .command('agent')
974
- .description('Operações sobre o binário do Neetru Agent (Linux daemon)');
1003
+ .description('Gerenciar binário do Neetru Agent (Linux daemon)');
975
1004
  agentCmd
976
1005
  .command('release')
977
- .description('Registra nova release do agente em agent_releases (Firestore)')
1006
+ .description('Registrar nova release do agente em agent_releases')
978
1007
  .requiredOption('--version <semver>', 'versão (ex: 1.2.0 ou 1.2.0-beta.1)')
979
1008
  .option('--channel <channel>', 'stable | beta | canary (default: beta)', 'beta')
980
1009
  .option('--changelog <text|@file>', 'changelog markdown inline ou "@path" pra ler de arquivo')
@@ -996,7 +1025,7 @@ agentCmd
996
1025
  });
997
1026
  agentCmd
998
1027
  .command('yank <version>')
999
- .description('Soft-revoke de uma release do agente (destrutivo top-tier confirmação + step-up MFA)')
1028
+ .description('Revogar release do agente (destrutivo — exige MFA)')
1000
1029
  .requiredOption('--reason <text>', 'motivo do yank (mínimo 5 caracteres)')
1001
1030
  .option('--yes', 'pula a confirmação interativa (modo script)')
1002
1031
  .option('--force', 'alias de --yes')
@@ -1016,10 +1045,10 @@ agentCmd
1016
1045
  });
1017
1046
  const agentCanaryCmd = agentCmd
1018
1047
  .command('canary')
1019
- .description('Controla o canary rollout de releases do agente');
1048
+ .description('Controlar canary rollout de releases do agente');
1020
1049
  agentCanaryCmd
1021
1050
  .command('start <version>')
1022
- .description('Inicia o canary rollout de uma release (phase1 = 5%)')
1051
+ .description('Iniciar canary rollout de uma release (phase1 5%)')
1023
1052
  .option('--json', 'saída em JSON')
1024
1053
  .action(async (version, opts) => {
1025
1054
  const { runAgentCanaryStart } = await import('./commands/agent-write.js');
@@ -1027,7 +1056,7 @@ agentCanaryCmd
1027
1056
  });
1028
1057
  agentCanaryCmd
1029
1058
  .command('rollback <version>')
1030
- .description('Rollback do canary de uma release (destrutivo top-tier confirmação + step-up MFA)')
1059
+ .description('Reverter canary de uma release (destrutivo — exige MFA)')
1031
1060
  .requiredOption('--reason <text>', 'motivo do rollback (mínimo 5 caracteres)')
1032
1061
  .option('--yes', 'pula a confirmação interativa (modo script)')
1033
1062
  .option('--force', 'alias de --yes')
@@ -1048,13 +1077,13 @@ agentCanaryCmd
1048
1077
  // ── neetru support ───────────────────────────────────────────────────
1049
1078
  const supportCmd = program
1050
1079
  .command('support')
1051
- .description('Support tickets inbox staff via CLI (F5 §4.2.6)');
1080
+ .description('Gerenciar suporte ao cliente via CLI');
1052
1081
  const supportTicketsCmd = supportCmd
1053
1082
  .command('tickets')
1054
- .description('Operações sobre support_tickets');
1083
+ .description('Operar tickets de suporte');
1055
1084
  supportTicketsCmd
1056
1085
  .command('list')
1057
- .description('Lista tickets com filtros')
1086
+ .description('Listar tickets de suporte')
1058
1087
  .option('--status <s>', 'open | in_progress | resolved | closed')
1059
1088
  .option('--severity <s>', 'sev1 | sev2 | sev3 | sev4')
1060
1089
  .option('--product <id>', 'filtra por productId')
@@ -1076,7 +1105,7 @@ supportTicketsCmd
1076
1105
  });
1077
1106
  supportTicketsCmd
1078
1107
  .command('describe <id>')
1079
- .description('Detalha um ticket + thread de mensagens')
1108
+ .description('Mostrar ticket com thread de mensagens')
1080
1109
  .option('--json', 'saída em JSON')
1081
1110
  .action(async (id, opts) => {
1082
1111
  const { runSupportTicketsDescribe } = await import('./commands/support.js');
@@ -1084,7 +1113,7 @@ supportTicketsCmd
1084
1113
  });
1085
1114
  supportTicketsCmd
1086
1115
  .command('reply <id>')
1087
- .description('Anexa mensagem staff ao ticket (transiciona open → in_progress se aplicável)')
1116
+ .description('Responder ticket com mensagem staff')
1088
1117
  .requiredOption('--message <text>', 'corpo da mensagem')
1089
1118
  .option('--json', 'saída em JSON')
1090
1119
  .action(async (id, opts) => {
@@ -1093,7 +1122,7 @@ supportTicketsCmd
1093
1122
  });
1094
1123
  supportTicketsCmd
1095
1124
  .command('assign <id>')
1096
- .description('Atribui ticket a um staff (uid)')
1125
+ .description('Atribuir ticket a um staff')
1097
1126
  .requiredOption('--to <staffUid>', 'uid do staff destino')
1098
1127
  .option('--json', 'saída em JSON')
1099
1128
  .action(async (id, opts) => {
@@ -1102,7 +1131,7 @@ supportTicketsCmd
1102
1131
  });
1103
1132
  supportTicketsCmd
1104
1133
  .command('status <id>')
1105
- .description('Transiciona status do ticket (FSM)')
1134
+ .description('Transicionar status do ticket')
1106
1135
  .requiredOption('--to <status>', 'open | in_progress | resolved | closed')
1107
1136
  .option('--json', 'saída em JSON')
1108
1137
  .action(async (id, opts) => {
@@ -1110,12 +1139,12 @@ supportTicketsCmd
1110
1139
  await runSupportTicketsStatus(id, { to: opts.to, json: !!opts.json });
1111
1140
  });
1112
1141
  // ── neetru dns ───────────────────────────────────────────────────────
1113
- const dnsCmd = program.command('dns').description('Cloud DNS managed zones');
1142
+ const dnsCmd = program.command('dns').description('Gerenciar Cloud DNS managed zones');
1114
1143
  dnsCmd
1115
1144
  .command('zones')
1116
- .description('Operações sobre managed zones')
1145
+ .description('Operar managed zones do Cloud DNS')
1117
1146
  .command('list')
1118
- .description('Lista managed zones do projeto')
1147
+ .description('Listar managed zones do projeto')
1119
1148
  .option('--json', 'saída em JSON')
1120
1149
  .action(async (opts) => {
1121
1150
  const { runDnsZonesList } = await import('./commands/infra-read.js');
@@ -1124,9 +1153,9 @@ dnsCmd
1124
1153
  // ── neetru hosting ───────────────────────────────────────────────────
1125
1154
  program
1126
1155
  .command('hosting')
1127
- .description('Customer domains hosting setup')
1156
+ .description('Gerenciar customer domains e hosting setup')
1128
1157
  .command('list')
1129
- .description('Lista customer domains com scope de tenant aplicado')
1158
+ .description('Listar customer domains com scope de tenant')
1130
1159
  .option('--json', 'saída em JSON')
1131
1160
  .action(async (opts) => {
1132
1161
  const { runHostingList } = await import('./commands/infra-read.js');
@@ -1135,9 +1164,9 @@ program
1135
1164
  // ── neetru builds ────────────────────────────────────────────────────
1136
1165
  program
1137
1166
  .command('builds')
1138
- .description('Cloud Build — builds live (status + duração)')
1167
+ .description('Consultar Cloud Build (status e duração)')
1139
1168
  .command('list')
1140
- .description('Lista Cloud Builds recentes (global + regional)')
1169
+ .description('Listar Cloud Builds recentes (global e regional)')
1141
1170
  .option('--json', 'saída em JSON')
1142
1171
  .action(async (opts) => {
1143
1172
  const { runBuildsList } = await import('./commands/infra-read.js');
@@ -1147,13 +1176,13 @@ program
1147
1176
  // Disaster Recovery — listar exports + restore assistido (admin + step-up MFA).
1148
1177
  const drCmd = program
1149
1178
  .command('dr')
1150
- .description('Disaster Recovery — exports + restore (admin only, RUNBOOK_DR_DRILL)');
1179
+ .description('Operar Disaster Recovery (admin only)');
1151
1180
  const drExportsCmd = drCmd
1152
1181
  .command('exports')
1153
- .description('Operações sobre exports de Firestore em gs://neetru-backups');
1182
+ .description('Operar exports de Firestore em gs://neetru-backups');
1154
1183
  drExportsCmd
1155
1184
  .command('list')
1156
- .description('Lista exports disponíveis (sort: mais recente primeiro)')
1185
+ .description('Listar exports de DR disponíveis')
1157
1186
  .option('--json', 'saída em JSON')
1158
1187
  .action(async (opts) => {
1159
1188
  const { runDrExportsList } = await import('./commands/dr.js');
@@ -1161,7 +1190,7 @@ drExportsCmd
1161
1190
  });
1162
1191
  drCmd
1163
1192
  .command('restore')
1164
- .description('Dispara restore Firestore (IRREVERSÍVEL no destino destrutivo top-tier)')
1193
+ .description('Restaurar Firestore de export (IRREVERSÍVEL — exige MFA)')
1165
1194
  .requiredOption('--gcs-path <path>', 'gs://neetru-backups/firestore-exports/<stamp>/')
1166
1195
  .requiredOption('--target-project <project>', 'projeto GCP de destino (deve ser STAGING)')
1167
1196
  .option('--yes', 'pula a confirmação interativa (modo script)')