@codexa/cli 9.0.31 → 9.0.32

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/workflow.ts CHANGED
@@ -42,14 +42,14 @@ import {
42
42
  } from "./commands/architect";
43
43
  import { teamSuggest } from "./commands/team";
44
44
  import { initSchema } from "./db/schema";
45
- import { getDb, closeDb } from "./db/connection";
45
+ import { closeDb, dbGet, dbRun, ensureDatabase, getResolvedDbUrl } from "./db/connection";
46
46
  import { execSync } from "child_process";
47
47
  import { existsSync, readFileSync } from "fs";
48
48
  import { join } from "path";
49
49
  import pkg from "./package.json";
50
50
  import { CodexaError, ValidationError, GateError } from "./errors";
51
51
 
52
- function checkVersionSync(): void {
52
+ async function checkVersionSync(): Promise<void> {
53
53
  // 1. Check CLI vs Plugin (dev repo only — igualdade estrita)
54
54
  try {
55
55
  const gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
@@ -71,19 +71,12 @@ function checkVersionSync(): void {
71
71
 
72
72
  // 2. Track CLI version in project DB (informativo, migracoes garantem compatibilidade)
73
73
  try {
74
- const dbPath = join(process.cwd(), ".codexa", "db", "workflow.db");
75
- if (!existsSync(dbPath)) return;
76
-
77
- initSchema();
78
- const db = getDb();
79
- const project = db.query("SELECT cli_version FROM project WHERE id = 'default'").get() as any;
74
+ await initSchema();
75
+ const project = await dbGet<any>("SELECT cli_version FROM project WHERE id = 'default'");
80
76
  if (!project) return;
81
77
 
82
78
  if (!project.cli_version) {
83
- db.run(
84
- `UPDATE project SET cli_version = ? WHERE id = 'default'`,
85
- [pkg.version]
86
- );
79
+ await dbRun("UPDATE project SET cli_version = ? WHERE id = 'default'", [pkg.version]);
87
80
  console.log(`✓ Versao do CLI (${pkg.version}) registrada no projeto.`);
88
81
  return;
89
82
  }
@@ -93,10 +86,7 @@ function checkVersionSync(): void {
93
86
  `ℹ Projeto configurado com CLI v${project.cli_version}, rodando v${pkg.version}. ` +
94
87
  `Migracoes aplicadas automaticamente.`
95
88
  );
96
- db.run(
97
- `UPDATE project SET cli_version = ? WHERE id = 'default'`,
98
- [pkg.version]
99
- );
89
+ await dbRun("UPDATE project SET cli_version = ? WHERE id = 'default'", [pkg.version]);
100
90
  }
101
91
  } catch {
102
92
  // DB not available or column doesn't exist yet — skip
@@ -154,8 +144,8 @@ program
154
144
  .name("codexa")
155
145
  .description(`Codexa Workflow v${pkg.version} - Sistema de workflow para Claude Code`)
156
146
  .version(pkg.version)
157
- .hook("preAction", () => {
158
- checkVersionSync();
147
+ .hook("preAction", async () => {
148
+ await checkVersionSync();
159
149
  });
160
150
 
161
151
  // ═══════════════════════════════════════════════════════════════
@@ -170,8 +160,8 @@ planCmd
170
160
  .option("--from-analysis <id>", "Importar baby steps de analise arquitetural aprovada")
171
161
  .option("--max-tasks-per-phase <n>", "Maximo de tasks por fase (padrao: 12)", parseInt)
172
162
  .option("--json", "Saida em JSON")
173
- .action((description: string, options: { fromAnalysis?: string; maxTasksPerPhase?: number; json?: boolean }) => {
174
- planStart(description, options);
163
+ .action(async (description: string, options: { fromAnalysis?: string; maxTasksPerPhase?: number; json?: boolean }) => {
164
+ await planStart(description, options);
175
165
  });
176
166
 
177
167
  planCmd
@@ -179,8 +169,8 @@ planCmd
179
169
  .description("Mostra o plano atual")
180
170
  .option("--json", "Saida em JSON")
181
171
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
182
- .action((options) => {
183
- planShow(options.json, options.spec);
172
+ .action(async (options) => {
173
+ await planShow(options.json, options.spec);
184
174
  });
185
175
 
186
176
  planCmd
@@ -192,16 +182,16 @@ planCmd
192
182
  .option("--files <files>", "Arquivos esperados (ex: src/a.ts,src/b.ts)")
193
183
  .option("--sequential", "Marca como sequencial (nao paralelizavel)")
194
184
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
195
- .action((options) => {
196
- planTaskAdd({ ...options, specId: options.spec });
185
+ .action(async (options) => {
186
+ await planTaskAdd({ ...options, specId: options.spec });
197
187
  });
198
188
 
199
189
  planCmd
200
190
  .command("cancel")
201
191
  .description("Cancela a feature atual (soft-cancel, preserva historico)")
202
192
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
203
- .action((options) => {
204
- planCancel(options.spec);
193
+ .action(async (options) => {
194
+ await planCancel(options.spec);
205
195
  });
206
196
 
207
197
  // ═══════════════════════════════════════════════════════════════
@@ -214,24 +204,24 @@ checkCmd
214
204
  .command("request")
215
205
  .description("Solicita aprovacao do plano")
216
206
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
217
- .action((options) => {
218
- checkRequest(options.spec);
207
+ .action(async (options) => {
208
+ await checkRequest(options.spec);
219
209
  });
220
210
 
221
211
  checkCmd
222
212
  .command("approve")
223
213
  .description("Aprova o plano")
224
214
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
225
- .action((options) => {
226
- checkApprove(options.spec);
215
+ .action(async (options) => {
216
+ await checkApprove(options.spec);
227
217
  });
228
218
 
229
219
  checkCmd
230
220
  .command("reject <reason>")
231
221
  .description("Rejeita o plano com motivo")
232
222
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
233
- .action((reason: string, options) => {
234
- checkReject(reason, options.spec);
223
+ .action(async (reason: string, options) => {
224
+ await checkReject(reason, options.spec);
235
225
  });
236
226
 
237
227
  // ═══════════════════════════════════════════════════════════════
@@ -245,8 +235,8 @@ taskCmd
245
235
  .description("Mostra proximas tasks disponiveis")
246
236
  .option("--json", "Saida em JSON")
247
237
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
248
- .action(wrapAction((options) => {
249
- taskNext(options.json, options.spec);
238
+ .action(wrapAction(async (options) => {
239
+ await taskNext(options.json, options.spec);
250
240
  }));
251
241
 
252
242
  taskCmd
@@ -255,8 +245,8 @@ taskCmd
255
245
  .option("--json", "Saida em JSON")
256
246
  .option("--minimal-context", "Usar contexto reduzido (~2KB) em vez do completo")
257
247
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
258
- .action(wrapAction((ids: string, options) => {
259
- taskStart(ids, options.json, options.minimalContext, options.spec);
248
+ .action(wrapAction(async (ids: string, options) => {
249
+ await taskStart(ids, options.json, options.minimalContext, options.spec);
260
250
  }));
261
251
 
262
252
  taskCmd
@@ -269,7 +259,7 @@ taskCmd
269
259
  .option("--force", "Ignorar validacao de standards (sera registrado)")
270
260
  .option("--force-reason <reason>", "Motivo do bypass de validacao")
271
261
  .option("--simplify", "Gerar prompt de simplificacao com standards do projeto")
272
- .action(wrapAction((id: string, options) => {
262
+ .action(wrapAction(async (id: string, options) => {
273
263
  // Resolver --output-file: ler conteudo do arquivo
274
264
  if (options.outputFile && !options.output) {
275
265
  try {
@@ -299,7 +289,7 @@ taskCmd
299
289
  );
300
290
  }
301
291
 
302
- taskDone(id, {
292
+ await taskDone(id, {
303
293
  checkpoint: options.checkpoint || "",
304
294
  files: options.files,
305
295
  force: options.force,
@@ -315,8 +305,8 @@ taskCmd
315
305
  .option("--json", "Saida em JSON")
316
306
  .option("--no-compact", "Nao compactar knowledge antes de avancar")
317
307
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
318
- .action(wrapAction((options) => {
319
- taskPhaseAdvance({ noCompact: options.compact === false, json: options.json, spec: options.spec });
308
+ .action(wrapAction(async (options) => {
309
+ await taskPhaseAdvance({ noCompact: options.compact === false, json: options.json, spec: options.spec });
320
310
  }));
321
311
 
322
312
  // ═══════════════════════════════════════════════════════════════
@@ -328,9 +318,9 @@ program
328
318
  .description("Gera prompt de simplificacao com standards do projeto para uma task")
329
319
  .option("--audit", "Modo auditoria (apenas relatorio, sem aplicar mudancas)")
330
320
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
331
- .action(wrapAction((taskId: string, options) => {
321
+ .action(wrapAction(async (taskId: string, options) => {
332
322
  const { simplifyTask } = require("./commands/simplify");
333
- simplifyTask(taskId, { audit: options.audit, specId: options.spec });
323
+ await simplifyTask(taskId, { audit: options.audit, specId: options.spec });
334
324
  }));
335
325
 
336
326
  // ═══════════════════════════════════════════════════════════════
@@ -343,8 +333,8 @@ program
343
333
  .option("--rationale <text>", "Justificativa da decisao")
344
334
  .option("--force", "Ignorar deteccao de conflitos")
345
335
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
346
- .action((title: string, decision: string, options) => {
347
- decide(title, decision, { ...options, specId: options.spec });
336
+ .action(async (title: string, decision: string, options) => {
337
+ await decide(title, decision, { ...options, specId: options.spec });
348
338
  });
349
339
 
350
340
  program
@@ -352,8 +342,8 @@ program
352
342
  .description("Lista decisoes")
353
343
  .option("--json", "Saida em JSON")
354
344
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
355
- .action((options) => {
356
- listDecisions(options.json, options.spec);
345
+ .action(async (options) => {
346
+ await listDecisions(options.json, options.spec);
357
347
  });
358
348
 
359
349
  program
@@ -361,8 +351,8 @@ program
361
351
  .description("Revoga uma decisao ativa")
362
352
  .option("--reason <text>", "Motivo da revogacao")
363
353
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
364
- .action(wrapAction((id: string, options) => {
365
- revokeDecision(id, options.reason, options.spec);
354
+ .action(wrapAction(async (id: string, options) => {
355
+ await revokeDecision(id, options.reason, options.spec);
366
356
  }));
367
357
 
368
358
  program
@@ -370,8 +360,8 @@ program
370
360
  .description("Substitui uma decisao ativa por uma nova")
371
361
  .option("--rationale <text>", "Justificativa da nova decisao")
372
362
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
373
- .action(wrapAction((id: string, title: string, decision: string, options) => {
374
- supersedeDecision(id, title, decision, { rationale: options.rationale, specId: options.spec });
363
+ .action(wrapAction(async (id: string, title: string, decision: string, options) => {
364
+ await supersedeDecision(id, title, decision, { rationale: options.rationale, specId: options.spec });
375
365
  }));
376
366
 
377
367
  // ═══════════════════════════════════════════════════════════════
@@ -388,8 +378,8 @@ knowledgeCmd
388
378
  .option("--severity <level>", "Severidade (info, warning, critical)", "info")
389
379
  .option("--broadcast <target>", "Destino (all ou IDs separados por virgula)", "all")
390
380
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
391
- .action((options) => {
392
- addKnowledge({
381
+ .action(async (options) => {
382
+ await addKnowledge({
393
383
  content: options.content,
394
384
  category: options.category,
395
385
  severity: options.severity,
@@ -406,16 +396,16 @@ knowledgeCmd
406
396
  .option("--severity <level>", "Filtrar por severidade (critical, warning, info)")
407
397
  .option("--json", "Saida em JSON")
408
398
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
409
- .action((options) => {
410
- listKnowledge({ ...options, specId: options.spec });
399
+ .action(async (options) => {
400
+ await listKnowledge({ ...options, specId: options.spec });
411
401
  });
412
402
 
413
403
  knowledgeCmd
414
404
  .command("ack <id>")
415
405
  .description("Marca knowledge como lido pela task atual")
416
406
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
417
- .action((id: string, options) => {
418
- acknowledgeKnowledge(id, options.spec);
407
+ .action(async (id: string, options) => {
408
+ await acknowledgeKnowledge(id, options.spec);
419
409
  });
420
410
 
421
411
  knowledgeCmd
@@ -423,8 +413,8 @@ knowledgeCmd
423
413
  .description("Resolve/reconhece knowledge item(s) critico(s)")
424
414
  .option("--resolution <text>", "Descricao de como o blocker foi resolvido")
425
415
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
426
- .action((ids: string, opts: { resolution?: string; spec?: string }) => {
427
- resolveKnowledge(ids, opts.resolution, opts.spec);
416
+ .action(async (ids: string, opts: { resolution?: string; spec?: string }) => {
417
+ await resolveKnowledge(ids, opts.resolution, opts.spec);
428
418
  });
429
419
 
430
420
  knowledgeCmd
@@ -434,8 +424,8 @@ knowledgeCmd
434
424
  .option("--decision <id>", "Buscar arquivos afetados por uma decisao")
435
425
  .option("--json", "Saida em JSON")
436
426
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
437
- .action((options) => {
438
- queryGraph({ ...options, specId: options.spec });
427
+ .action(async (options) => {
428
+ await queryGraph({ ...options, specId: options.spec });
439
429
  });
440
430
 
441
431
  knowledgeCmd
@@ -444,8 +434,8 @@ knowledgeCmd
444
434
  .option("--spec <id>", "ID do spec (padrao: todos)")
445
435
  .option("--dry-run", "Apenas mostrar o que seria compactado")
446
436
  .option("--json", "Saida em JSON")
447
- .action((options) => {
448
- compactKnowledge({ specId: options.spec, dryRun: options.dryRun, json: options.json });
437
+ .action(async (options) => {
438
+ await compactKnowledge({ specId: options.spec, dryRun: options.dryRun, json: options.json });
449
439
  });
450
440
 
451
441
  // ═══════════════════════════════════════════════════════════════
@@ -459,8 +449,8 @@ reviewCmd
459
449
  .description("Inicia o review")
460
450
  .option("--json", "Saida em JSON")
461
451
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
462
- .action((options) => {
463
- reviewStart(options.json, options.spec);
452
+ .action(async (options) => {
453
+ await reviewStart(options.json, options.spec);
464
454
  });
465
455
 
466
456
  reviewCmd
@@ -469,16 +459,16 @@ reviewCmd
469
459
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
470
460
  .option("--force", "Aprovar mesmo com score baixo (<50)")
471
461
  .option("--force-reason <reason>", "Motivo para aprovacao forcada")
472
- .action((options) => {
473
- reviewApprove({ specId: options.spec, force: options.force, forceReason: options.forceReason });
462
+ .action(async (options) => {
463
+ await reviewApprove({ specId: options.spec, force: options.force, forceReason: options.forceReason });
474
464
  });
475
465
 
476
466
  reviewCmd
477
467
  .command("skip")
478
468
  .description("Pula o review e finaliza a feature diretamente")
479
469
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
480
- .action((options) => {
481
- reviewSkip(options.spec);
470
+ .action(async (options) => {
471
+ await reviewSkip(options.spec);
482
472
  });
483
473
 
484
474
  // ═══════════════════════════════════════════════════════════════
@@ -490,8 +480,8 @@ program
490
480
  .description("Mostra status atual")
491
481
  .option("--json", "Saida em JSON")
492
482
  .option("--spec <id>", "ID do spec (padrao: todos ativos)")
493
- .action((options) => {
494
- status(options.json, options.spec);
483
+ .action(async (options) => {
484
+ await status(options.json, options.spec);
495
485
  });
496
486
 
497
487
  const contextCmd = program.command("context").description("Comandos de contexto");
@@ -501,8 +491,8 @@ contextCmd
501
491
  .description("Exporta contexto para subagent")
502
492
  .option("--task <id>", "ID da task especifica")
503
493
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
504
- .action((options) => {
505
- contextExport({ ...options, json: true, specId: options.spec }); // Sempre JSON
494
+ .action(async (options) => {
495
+ await contextExport({ ...options, json: true, specId: options.spec }); // Sempre JSON
506
496
  });
507
497
 
508
498
  contextCmd
@@ -510,8 +500,8 @@ contextCmd
510
500
  .description("Mostra secao especifica do contexto (standards, decisions, patterns, knowledge, architecture)")
511
501
  .option("--json", "Output JSON")
512
502
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
513
- .action((section: string, opts: { json?: boolean; spec?: string }) => {
514
- contextDetail(section, opts.json, opts.spec);
503
+ .action(async (section: string, opts: { json?: boolean; spec?: string }) => {
504
+ await contextDetail(section, opts.json, opts.spec);
515
505
  });
516
506
 
517
507
  contextCmd
@@ -519,13 +509,10 @@ contextCmd
519
509
  .description("Mostra estimativa de uso de contexto para uma task")
520
510
  .option("--task <id>", "ID da task")
521
511
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
522
- .action(wrapAction((options: { task?: string; spec?: string }) => {
512
+ .action(wrapAction(async (options: { task?: string; spec?: string }) => {
523
513
  const { getContextForSubagent, getMinimalContextForSubagent } = require("./context/generator");
524
514
  const { getContextBudget, formatContextWarning } = require("./context/monitor");
525
- const { getDb } = require("./db/connection");
526
- const { initSchema } = require("./db/schema");
527
- initSchema();
528
- const db = getDb();
515
+ await initSchema();
529
516
 
530
517
  const taskId = options.task ? parseInt(options.task) : null;
531
518
  if (!taskId) {
@@ -533,13 +520,15 @@ contextCmd
533
520
  return;
534
521
  }
535
522
 
536
- const fullCtx = getContextForSubagent(taskId);
537
- const minCtx = getMinimalContextForSubagent(taskId);
523
+ const fullCtx = await getContextForSubagent(taskId);
524
+ const minCtx = await getMinimalContextForSubagent(taskId);
538
525
 
539
- const task = db.query("SELECT spec_id FROM tasks WHERE id = ?").get(taskId) as any;
540
- const completedCount = task ? (db.query(
541
- "SELECT COUNT(*) as c FROM tasks WHERE spec_id = ? AND status = 'done'"
542
- ).get(task.spec_id) as any)?.c || 0 : 0;
526
+ const task = await dbGet<any>("SELECT spec_id FROM tasks WHERE id = ?", [taskId]);
527
+ const completedRow = task ? await dbGet<any>(
528
+ "SELECT COUNT(*) as c FROM tasks WHERE spec_id = ? AND status = 'done'",
529
+ [task.spec_id]
530
+ ) : null;
531
+ const completedCount = completedRow?.c || 0;
543
532
 
544
533
  const budget = getContextBudget(fullCtx, completedCount);
545
534
  const warning = formatContextWarning(budget);
@@ -560,8 +549,8 @@ program
560
549
  .description("Alias para context export (compatibilidade)")
561
550
  .option("--task <id>", "ID da task especifica")
562
551
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
563
- .action((options) => {
564
- contextExport({ ...options, json: true, specId: options.spec });
552
+ .action(async (options) => {
553
+ await contextExport({ ...options, json: true, specId: options.spec });
565
554
  });
566
555
 
567
556
  program
@@ -571,16 +560,18 @@ program
571
560
  .option("--snapshot <id>", "Mostra detalhes de um snapshot")
572
561
  .option("--restore", "Restaura o snapshot especificado")
573
562
  .option("--auto", "Restaura o ultimo snapshot automaticamente")
574
- .action((options) => {
575
- recover(options);
563
+ .action(async (options) => {
564
+ await recover(options);
576
565
  });
577
566
 
578
567
  program
579
568
  .command("init")
580
- .description("Inicializa o banco de dados")
581
- .action(() => {
582
- initSchema();
583
- console.log("\nBanco de dados inicializado em .codexa/db/workflow.db\n");
569
+ .description("Inicializa o banco de dados no Turso")
570
+ .action(async () => {
571
+ await ensureDatabase();
572
+ await initSchema();
573
+ const url = getResolvedDbUrl();
574
+ console.log(`\nBanco de dados inicializado: ${url}\n`);
584
575
  });
585
576
 
586
577
  // ═══════════════════════════════════════════════════════════════
@@ -600,16 +591,16 @@ discoverCmd
600
591
  discoverCmd
601
592
  .command("confirm")
602
593
  .description("Confirma e salva a descoberta")
603
- .action(() => {
604
- discoverConfirm();
594
+ .action(async () => {
595
+ await discoverConfirm();
605
596
  });
606
597
 
607
598
  discoverCmd
608
599
  .command("show")
609
600
  .description("Mostra projeto descoberto")
610
601
  .option("--json", "Saida em JSON")
611
- .action((options) => {
612
- discoverShow(options.json);
602
+ .action(async (options) => {
603
+ await discoverShow(options.json);
613
604
  });
614
605
 
615
606
  discoverCmd
@@ -626,15 +617,12 @@ discoverCmd
626
617
  .option("--grepai-workspace <name>", "Nome do workspace grepai para busca semantica cross-project. Vazio para remover.")
627
618
  .option("--auto-simplify", "Habilitar simplificacao automatica pos-task com standards do projeto")
628
619
  .option("--no-auto-simplify", "Desabilitar simplificacao automatica pos-task")
629
- .action((options) => {
620
+ .action(async (options) => {
630
621
  // Tratar typecheck-command separadamente
631
622
  if (options.typecheckCommand !== undefined) {
632
- const { initSchema } = require("./db/schema");
633
- const { getDb } = require("./db/connection");
634
- initSchema();
635
- const db = getDb();
623
+ await initSchema();
636
624
  const value = options.typecheckCommand === "" ? null : options.typecheckCommand;
637
- db.run("UPDATE project SET typecheck_command = ? WHERE id = 'default'", [value]);
625
+ await dbRun("UPDATE project SET typecheck_command = ? WHERE id = 'default'", [value]);
638
626
  if (value) {
639
627
  console.log(`\n[ok] Typecheck command configurado: ${value}`);
640
628
  } else {
@@ -644,17 +632,14 @@ discoverCmd
644
632
  }
645
633
  // Tratar grepai-workspace separadamente
646
634
  if (options.grepaiWorkspace !== undefined) {
647
- const { initSchema } = require("./db/schema");
648
- const { getDb } = require("./db/connection");
649
- initSchema();
650
- const db = getDb();
635
+ await initSchema();
651
636
  const value = options.grepaiWorkspace === "" ? null : options.grepaiWorkspace;
652
637
  if (value && !isValidWorkspaceName(value)) {
653
638
  console.error(`\n[erro] Nome de workspace invalido: "${value}"`);
654
639
  console.error(" Use apenas letras, numeros, hifens e underscores (ex: meu-workspace, dotnet_ws)\n");
655
640
  return;
656
641
  }
657
- db.run("UPDATE project SET grepai_workspace = ? WHERE id = 'default'", [value]);
642
+ await dbRun("UPDATE project SET grepai_workspace = ? WHERE id = 'default'", [value]);
658
643
  if (value) {
659
644
  console.log(`\n✓ Grepai workspace configurado: ${value}`);
660
645
  console.log(" Sera usado em: semantic search (standards), deep-explore agent, grepai trace");
@@ -667,7 +652,7 @@ discoverCmd
667
652
  // Tratar auto-simplify
668
653
  if (options.autoSimplify !== undefined) {
669
654
  const { setAutoSimplify } = require("./commands/simplify");
670
- setAutoSimplify(!!options.autoSimplify);
655
+ await setAutoSimplify(!!options.autoSimplify);
671
656
  }
672
657
  // Tratar stack options normalmente
673
658
  const stackOptions = { ...options };
@@ -675,15 +660,15 @@ discoverCmd
675
660
  delete stackOptions.grepaiWorkspace;
676
661
  delete stackOptions.autoSimplify;
677
662
  if (Object.keys(stackOptions).length > 0) {
678
- discoverSetStack(stackOptions);
663
+ await discoverSetStack(stackOptions);
679
664
  }
680
665
  });
681
666
 
682
667
  discoverCmd
683
668
  .command("reset", { hidden: true })
684
669
  .description("Reseta descoberta para refazer")
685
- .action(() => {
686
- discoverReset();
670
+ .action(async () => {
671
+ await discoverReset();
687
672
  });
688
673
 
689
674
  discoverCmd
@@ -711,11 +696,11 @@ discoverCmd
711
696
  .option("--category <cat>", "Filtrar por categoria")
712
697
  .option("--show <name>", "Mostra detalhes de um pattern")
713
698
  .option("--json", "Saida em JSON")
714
- .action((options) => {
699
+ .action(async (options) => {
715
700
  if (options.show) {
716
- discoverPatternsShow(options.show, options.json);
701
+ await discoverPatternsShow(options.show, options.json);
717
702
  } else {
718
- discoverPatterns({ category: options.category, json: options.json });
703
+ await discoverPatterns({ category: options.category, json: options.json });
719
704
  }
720
705
  });
721
706
 
@@ -732,8 +717,8 @@ discoverCmd
732
717
  .option("--anti-patterns <json>", "JSON array de anti-patterns")
733
718
  .option("--confidence <num>", "Confianca 0-1", "0.8")
734
719
  .option("--extracted-from <num>", "Numero de arquivos analisados", "1")
735
- .action((options) => {
736
- discoverPatternAdd({
720
+ .action(async (options) => {
721
+ await discoverPatternAdd({
737
722
  category: options.category,
738
723
  name: options.name,
739
724
  scope: options.scope,
@@ -758,8 +743,8 @@ discoverCmd
758
743
  .option("--examples <json>", "Novos exemplos JSON")
759
744
  .option("--anti-patterns <json>", "Novos anti-patterns JSON")
760
745
  .option("--confidence <num>", "Nova confianca 0-1")
761
- .action((name, options) => {
762
- discoverPatternEdit(name, {
746
+ .action(async (name, options) => {
747
+ await discoverPatternEdit(name, {
763
748
  category: options.category,
764
749
  scope: options.scope,
765
750
  appliesTo: options.appliesTo,
@@ -774,15 +759,15 @@ discoverCmd
774
759
  discoverCmd
775
760
  .command("pattern-remove <name>")
776
761
  .description("Remove um implementation pattern")
777
- .action((name) => {
778
- discoverPatternRemove(name);
762
+ .action(async (name) => {
763
+ await discoverPatternRemove(name);
779
764
  });
780
765
 
781
766
  discoverCmd
782
767
  .command("refresh-patterns")
783
768
  .description("Re-extrai patterns do codigo (requer analise manual)")
784
- .action(() => {
785
- discoverRefreshPatterns();
769
+ .action(async () => {
770
+ await discoverRefreshPatterns();
786
771
  });
787
772
 
788
773
  discoverCmd
@@ -814,8 +799,8 @@ discoverCmd
814
799
  discoverCmd
815
800
  .command("export-patterns", { hidden: true })
816
801
  .description("Regenera arquivo patterns.md")
817
- .action(() => {
818
- discoverExportPatterns();
802
+ .action(async () => {
803
+ await discoverExportPatterns();
819
804
  });
820
805
 
821
806
  // ═══════════════════════════════════════════════════════════════
@@ -830,8 +815,8 @@ standardsCmd
830
815
  .option("--category <cat>", "Filtrar por categoria")
831
816
  .option("--scope <scope>", "Filtrar por escopo")
832
817
  .option("--json", "Saida em JSON")
833
- .action((options) => {
834
- standardsList(options);
818
+ .action(async (options) => {
819
+ await standardsList(options);
835
820
  });
836
821
 
837
822
  standardsCmd
@@ -847,13 +832,13 @@ standardsCmd
847
832
  .option("--recommended", "Alias para --enforcement recommended")
848
833
  .option("--semantic-query <query>", "Query semantica para grepai (ingles)")
849
834
  .option("--expect <type>", "Expectativa: no_match ou must_match", "no_match")
850
- .action((options) => {
835
+ .action(async (options) => {
851
836
  // Resolver aliases de enforcement
852
837
  let enforcement = options.enforcement;
853
838
  if (options.required) enforcement = "required";
854
839
  if (options.recommended) enforcement = "recommended";
855
840
 
856
- standardsAdd({
841
+ await standardsAdd({
857
842
  category: options.category,
858
843
  scope: options.scope,
859
844
  rule: options.rule,
@@ -874,8 +859,8 @@ standardsCmd
874
859
  .option("--enforcement <level>", "Novo nivel de enforcement")
875
860
  .option("--semantic-query <query>", "Query semantica para grepai (ingles)")
876
861
  .option("--expect <type>", "Expectativa: no_match ou must_match")
877
- .action((id, options) => {
878
- standardsEdit(id, {
862
+ .action(async (id, options) => {
863
+ await standardsEdit(id, {
879
864
  rule: options.rule,
880
865
  examples: options.examples,
881
866
  antiExamples: options.antiExamples,
@@ -888,15 +873,15 @@ standardsCmd
888
873
  standardsCmd
889
874
  .command("remove <id>")
890
875
  .description("Remove um standard")
891
- .action((id) => {
892
- standardsRemove(id);
876
+ .action(async (id) => {
877
+ await standardsRemove(id);
893
878
  });
894
879
 
895
880
  standardsCmd
896
881
  .command("export")
897
882
  .description("Regenera arquivo standards.md")
898
- .action(() => {
899
- standardsExport();
883
+ .action(async () => {
884
+ await standardsExport();
900
885
  });
901
886
 
902
887
  // ═══════════════════════════════════════════════════════════════
@@ -910,8 +895,8 @@ productCmd
910
895
  .description("Importa PRD existente")
911
896
  .option("--file <path>", "Caminho para arquivo PRD")
912
897
  .option("--content <text>", "Conteudo do PRD")
913
- .action((options) => {
914
- productImport(options);
898
+ .action(async (options) => {
899
+ await productImport(options);
915
900
  });
916
901
 
917
902
  productCmd
@@ -927,8 +912,8 @@ productCmd
927
912
  .option("--constraints <list>", "Restricoes (separadas por virgula)")
928
913
  .option("--goal <spec>", "Adiciona objetivo (formato: categoria:texto:prioridade)")
929
914
  .option("--feature <spec>", "Adiciona feature (formato: nome:descricao:prioridade)")
930
- .action((options) => {
931
- productSet(options);
915
+ .action(async (options) => {
916
+ await productSet(options);
932
917
  });
933
918
 
934
919
  productCmd
@@ -936,22 +921,22 @@ productCmd
936
921
  .description("Mostra contexto de produto")
937
922
  .option("--json", "Saida em JSON")
938
923
  .option("--pending", "Mostra contexto pendente (nao confirmado)")
939
- .action((options) => {
940
- productShow(options);
924
+ .action(async (options) => {
925
+ await productShow(options);
941
926
  });
942
927
 
943
928
  productCmd
944
929
  .command("confirm")
945
930
  .description("Confirma e salva o contexto de produto")
946
- .action(() => {
947
- productConfirm();
931
+ .action(async () => {
932
+ await productConfirm();
948
933
  });
949
934
 
950
935
  productCmd
951
936
  .command("reset")
952
937
  .description("Reseta contexto de produto para refazer")
953
- .action(() => {
954
- productReset();
938
+ .action(async () => {
939
+ await productReset();
955
940
  });
956
941
 
957
942
  // ═══════════════════════════════════════════════════════════════
@@ -973,16 +958,16 @@ researchCmd
973
958
  .description("Mostra status das bibliotecas detectadas")
974
959
  .option("--json", "Saida em JSON")
975
960
  .option("--lib <name>", "Filtrar por biblioteca especifica")
976
- .action((options) => {
977
- researchShow(options);
961
+ .action(async (options) => {
962
+ await researchShow(options);
978
963
  });
979
964
 
980
965
  researchCmd
981
966
  .command("fill <lib>")
982
967
  .description("Gera instrucoes para preencher contexto de uma biblioteca")
983
968
  .option("--json", "Saida em JSON")
984
- .action((lib: string, options) => {
985
- researchFill(lib, options);
969
+ .action(async (lib: string, options) => {
970
+ await researchFill(lib, options);
986
971
  });
987
972
 
988
973
  researchCmd
@@ -992,15 +977,15 @@ researchCmd
992
977
  .option("--add <libs>", "Adicionar bibliotecas (separadas por virgula)")
993
978
  .option("--remove <libs>", "Remover bibliotecas (separadas por virgula)")
994
979
  .option("--json", "Saida em JSON")
995
- .action((options) => {
996
- researchMapAgent(options);
980
+ .action(async (options) => {
981
+ await researchMapAgent(options);
997
982
  });
998
983
 
999
984
  researchCmd
1000
985
  .command("reset")
1001
986
  .description("Remove todos os contextos de biblioteca")
1002
- .action(() => {
1003
- researchReset();
987
+ .action(async () => {
988
+ await researchReset();
1004
989
  });
1005
990
 
1006
991
  // ═══════════════════════════════════════════════════════════════
@@ -1013,11 +998,11 @@ program
1013
998
  .option("--force", "Confirma a limpeza (sem isso apenas mostra o que sera removido)")
1014
999
  .option("--show", "Mostra estado atual dos arquivos do workflow")
1015
1000
  .option("--spec <id>", "Limpa apenas o spec especificado")
1016
- .action((options) => {
1001
+ .action(async (options) => {
1017
1002
  if (options.show) {
1018
- clearShow();
1003
+ await clearShow();
1019
1004
  } else {
1020
- clearTasks({ force: options.force, specId: options.spec });
1005
+ await clearTasks({ force: options.force, specId: options.spec });
1021
1006
  }
1022
1007
  });
1023
1008
 
@@ -1031,8 +1016,8 @@ architectCmd
1031
1016
  .command("start <description>")
1032
1017
  .description("Inicia nova analise arquitetural")
1033
1018
  .option("--json", "Saida em JSON")
1034
- .action((description: string, options) => {
1035
- architectStart(description, options);
1019
+ .action(async (description: string, options) => {
1020
+ await architectStart(description, options);
1036
1021
  });
1037
1022
 
1038
1023
  architectCmd
@@ -1040,8 +1025,8 @@ architectCmd
1040
1025
  .description("Mostra analise atual ou especifica")
1041
1026
  .option("--id <id>", "ID da analise")
1042
1027
  .option("--json", "Saida em JSON")
1043
- .action((options) => {
1044
- architectShow(options);
1028
+ .action(async (options) => {
1029
+ await architectShow(options);
1045
1030
  });
1046
1031
 
1047
1032
  architectCmd
@@ -1049,8 +1034,8 @@ architectCmd
1049
1034
  .description("Lista todas as analises")
1050
1035
  .option("--status <status>", "Filtrar por status (pending, approved, implemented, rejected)")
1051
1036
  .option("--json", "Saida em JSON")
1052
- .action((options) => {
1053
- architectList(options);
1037
+ .action(async (options) => {
1038
+ await architectList(options);
1054
1039
  });
1055
1040
 
1056
1041
  architectCmd
@@ -1058,8 +1043,8 @@ architectCmd
1058
1043
  .description("Salva analise em arquivo markdown")
1059
1044
  .option("--file <path>", "Caminho do arquivo (default: .codexa/analysis/ARCH-xxx.md)")
1060
1045
  .option("--json", "Saida em JSON")
1061
- .action((options) => {
1062
- architectSave(options);
1046
+ .action(async (options) => {
1047
+ await architectSave(options);
1063
1048
  });
1064
1049
 
1065
1050
  architectCmd
@@ -1067,8 +1052,8 @@ architectCmd
1067
1052
  .description("Aprova analise para implementacao")
1068
1053
  .option("--id <id>", "ID da analise")
1069
1054
  .option("--json", "Saida em JSON")
1070
- .action((options) => {
1071
- architectApprove(options);
1055
+ .action(async (options) => {
1056
+ await architectApprove(options);
1072
1057
  });
1073
1058
 
1074
1059
  architectCmd
@@ -1076,8 +1061,8 @@ architectCmd
1076
1061
  .description("Exporta baby steps como comandos para criar tasks")
1077
1062
  .option("--id <id>", "ID da analise")
1078
1063
  .option("--json", "Saida em JSON")
1079
- .action((options) => {
1080
- architectExport(options);
1064
+ .action(async (options) => {
1065
+ await architectExport(options);
1081
1066
  });
1082
1067
 
1083
1068
  architectCmd
@@ -1085,8 +1070,8 @@ architectCmd
1085
1070
  .description("Cancela analise pendente")
1086
1071
  .option("--id <id>", "ID da analise")
1087
1072
  .option("--json", "Saida em JSON")
1088
- .action((options) => {
1089
- architectCancel(options);
1073
+ .action(async (options) => {
1074
+ await architectCancel(options);
1090
1075
  });
1091
1076
 
1092
1077
  // ═══════════════════════════════════════════════════════════════
@@ -1101,8 +1086,8 @@ teamCmd
1101
1086
  .option("--json", "Saida em JSON")
1102
1087
  .option("--phase <phase>", "Fase especifica (imp, rev, architect)")
1103
1088
  .option("--spec <id>", "ID do spec (padrao: mais recente)")
1104
- .action(wrapAction((options) => {
1105
- teamSuggest(options);
1089
+ .action(wrapAction(async (options) => {
1090
+ await teamSuggest(options);
1106
1091
  }));
1107
1092
 
1108
1093
  // ═══════════════════════════════════════════════════════════════
@@ -1115,8 +1100,8 @@ pluginCmd
1115
1100
  .command("sync-agents")
1116
1101
  .description("Copia agents do plugin para .claude/agents/ do projeto (resolve limitacao de subagent_type)")
1117
1102
  .option("--force", "Sobrescrever agents existentes")
1118
- .action((options) => {
1119
- syncAgents(options);
1103
+ .action(async (options) => {
1104
+ await syncAgents(options);
1120
1105
  });
1121
1106
 
1122
1107
  // Parse e executa