@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.
@@ -1,4 +1,4 @@
1
- import { getDb } from "../db/connection";
1
+ import { dbGet, dbAll, dbRun } from "../db/connection";
2
2
  import { initSchema } from "../db/schema";
3
3
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
4
4
  import { CodexaError } from "../errors";
@@ -48,34 +48,26 @@ interface ArchitecturalAnalysis {
48
48
  description: string;
49
49
  status: "pending" | "approved" | "implemented" | "rejected";
50
50
 
51
- // Contexto
52
51
  context: string;
53
52
  currentArchitecture: string;
54
53
 
55
- // Solucao
56
54
  approach: string;
57
55
  chosenAlternative: string;
58
56
 
59
- // Diagramas (Mermaid)
60
57
  diagrams: {
61
58
  name: string;
62
59
  type: string;
63
60
  content: string;
64
61
  }[];
65
62
 
66
- // Baby Steps
67
63
  babySteps: BabyStep[];
68
64
 
69
- // Riscos
70
65
  risks: Risk[];
71
66
 
72
- // Alternativas
73
67
  alternatives: Alternative[];
74
68
 
75
- // Decisoes
76
69
  decisions: ArchitecturalDecision[];
77
70
 
78
- // Metadados
79
71
  filePath?: string;
80
72
  createdAt: string;
81
73
  updatedAt?: string;
@@ -145,7 +137,6 @@ const HEADER_ALIASES: Record<string, string[]> = {
145
137
  export function extractSection(content: string, header: string): string {
146
138
  const sections = content.split(/^## /m);
147
139
 
148
- // Tier 1: Exact startsWith (fast path)
149
140
  for (const section of sections) {
150
141
  if (section.startsWith(header)) {
151
142
  const lines = section.split("\n");
@@ -153,7 +144,6 @@ export function extractSection(content: string, header: string): string {
153
144
  }
154
145
  }
155
146
 
156
- // Tier 2: Case-insensitive startsWith
157
147
  const headerLower = header.toLowerCase();
158
148
  for (const section of sections) {
159
149
  if (section.toLowerCase().startsWith(headerLower)) {
@@ -162,7 +152,6 @@ export function extractSection(content: string, header: string): string {
162
152
  }
163
153
  }
164
154
 
165
- // Tier 3: Alias-based includes matching (case-insensitive)
166
155
  const aliases = HEADER_ALIASES[header] || [];
167
156
  for (const section of sections) {
168
157
  const sectionHeader = section.split("\n")[0]?.toLowerCase().trim() || "";
@@ -182,7 +171,6 @@ export function parseBabySteps(section: string): BabyStep[] {
182
171
  if (!section) return [];
183
172
  const steps: BabyStep[] = [];
184
173
 
185
- // Detect phase headers: "## Fase N:" or "## Phase N:"
186
174
  let currentPhase = 1;
187
175
  let hasExplicitPhases = false;
188
176
  const phaseRegex = /^##\s+(?:Fase|Phase)\s+(\d+)/im;
@@ -190,8 +178,6 @@ export function parseBabySteps(section: string): BabyStep[] {
190
178
  hasExplicitPhases = true;
191
179
  }
192
180
 
193
- // Split by phase headers first, then by step headers
194
- // We process the section line-by-line to track phase context
195
181
  const lines = section.split("\n");
196
182
  let currentBlock = "";
197
183
  let blockPhase = currentPhase;
@@ -199,7 +185,6 @@ export function parseBabySteps(section: string): BabyStep[] {
199
185
  for (const line of lines) {
200
186
  const phaseMatch = line.match(/^##\s+(?:Fase|Phase)\s+(\d+)/i);
201
187
  if (phaseMatch) {
202
- // Process pending block BEFORE changing phase
203
188
  if (currentBlock.trim()) {
204
189
  const step = parseStepBlock(currentBlock, hasExplicitPhases ? blockPhase : undefined);
205
190
  if (step) steps.push(step);
@@ -210,7 +195,6 @@ export function parseBabySteps(section: string): BabyStep[] {
210
195
  continue;
211
196
  }
212
197
 
213
- // When we hit a new step header, process the previous block
214
198
  if (line.match(/^###\s+/) && currentBlock.trim()) {
215
199
  const step = parseStepBlock(currentBlock, hasExplicitPhases ? blockPhase : undefined);
216
200
  if (step) steps.push(step);
@@ -221,7 +205,6 @@ export function parseBabySteps(section: string): BabyStep[] {
221
205
  }
222
206
  }
223
207
 
224
- // Process the last block
225
208
  if (currentBlock.trim()) {
226
209
  const step = parseStepBlock(currentBlock, hasExplicitPhases ? blockPhase : undefined);
227
210
  if (step) steps.push(step);
@@ -231,7 +214,6 @@ export function parseBabySteps(section: string): BabyStep[] {
231
214
  }
232
215
 
233
216
  function parseStepBlock(block: string, phase?: number): BabyStep | null {
234
- // Remove leading "### " prefix for matching
235
217
  const content = block.replace(/^###\s+/, "");
236
218
  const headerMatch = content.match(/^(?:Step\s+)?(\d+)[.:]\s*(.+)/);
237
219
  if (!headerMatch) return null;
@@ -306,12 +288,10 @@ export function parseDecisionsTable(section: string): ArchitecturalDecision[] {
306
288
  const lines = section.split("\n");
307
289
 
308
290
  for (const line of lines) {
309
- // Match table rows: | Decision | Rationale |
310
291
  const rowMatch = line.match(/^\|\s*([^|]+)\s*\|\s*([^|]+)\s*\|$/);
311
292
  if (!rowMatch) continue;
312
293
  const decision = rowMatch[1].trim();
313
294
  const rationale = rowMatch[2].trim();
314
- // Skip header and separator rows
315
295
  if (decision === "Decisao" || decision.startsWith("---")) continue;
316
296
  if (decision && rationale) {
317
297
  decisions.push({ decision, rationale });
@@ -346,10 +326,6 @@ function parseAlternatives(section: string): Alternative[] {
346
326
  return alternatives;
347
327
  }
348
328
 
349
- /**
350
- * v8.4: Parseia um arquivo .md de analise arquitetural e extrai dados estruturados.
351
- * O .md deve seguir o template padrao do codexa:architect.
352
- */
353
329
  export function parseAnalysisMd(content: string): {
354
330
  context: string;
355
331
  currentArchitecture: string;
@@ -386,16 +362,15 @@ export function parseAnalysisMd(content: string): {
386
362
  // COMMANDS
387
363
  // ═══════════════════════════════════════════════════════════════
388
364
 
389
- export function architectStart(description: string, options: { json?: boolean } = {}): void {
390
- initSchema();
391
- const db = getDb();
365
+ export async function architectStart(description: string, options: { json?: boolean } = {}): Promise<void> {
366
+ await initSchema();
392
367
  const now = new Date().toISOString();
393
368
  const id = generateId();
394
369
 
395
- // Verificar se ja existe analise pendente
396
- const pending = db.query(
397
- "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1"
398
- ).get() as any;
370
+ const pending = await dbGet<any>(
371
+ "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1",
372
+ []
373
+ );
399
374
 
400
375
  if (pending) {
401
376
  if (options.json) {
@@ -418,8 +393,7 @@ export function architectStart(description: string, options: { json?: boolean }
418
393
  throw new CodexaError("Ja existe uma analise pendente. Use 'architect show' ou 'architect cancel'.");
419
394
  }
420
395
 
421
- // Criar nova analise
422
- db.run(
396
+ await dbRun(
423
397
  `INSERT INTO architectural_analyses (id, name, description, status, created_at)
424
398
  VALUES (?, ?, ?, 'pending', ?)`,
425
399
  [id, description, description, now]
@@ -460,24 +434,24 @@ export function architectStart(description: string, options: { json?: boolean }
460
434
  }
461
435
  }
462
436
 
463
- export function architectShow(options: { id?: string; json?: boolean } = {}): void {
464
- initSchema();
465
- const db = getDb();
437
+ export async function architectShow(options: { id?: string; json?: boolean } = {}): Promise<void> {
438
+ await initSchema();
466
439
 
467
440
  let analysis: any;
468
441
 
469
442
  if (options.id) {
470
- analysis = db.query("SELECT * FROM architectural_analyses WHERE id = ?").get(options.id);
443
+ analysis = await dbGet<any>("SELECT * FROM architectural_analyses WHERE id = ?", [options.id]);
471
444
  } else {
472
- // Pegar a mais recente pendente ou a ultima
473
- analysis = db.query(
474
- "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1"
475
- ).get();
445
+ analysis = await dbGet<any>(
446
+ "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1",
447
+ []
448
+ );
476
449
 
477
450
  if (!analysis) {
478
- analysis = db.query(
479
- "SELECT * FROM architectural_analyses ORDER BY created_at DESC LIMIT 1"
480
- ).get();
451
+ analysis = await dbGet<any>(
452
+ "SELECT * FROM architectural_analyses ORDER BY created_at DESC LIMIT 1",
453
+ []
454
+ );
481
455
  }
482
456
  }
483
457
 
@@ -491,7 +465,6 @@ export function architectShow(options: { id?: string; json?: boolean } = {}): vo
491
465
  return;
492
466
  }
493
467
 
494
- // Parse JSON fields
495
468
  const parsed: ArchitecturalAnalysis = {
496
469
  id: analysis.id,
497
470
  name: analysis.name,
@@ -557,9 +530,8 @@ export function architectShow(options: { id?: string; json?: boolean } = {}): vo
557
530
  }
558
531
  }
559
532
 
560
- export function architectList(options: { json?: boolean; status?: string } = {}): void {
561
- initSchema();
562
- const db = getDb();
533
+ export async function architectList(options: { json?: boolean; status?: string } = {}): Promise<void> {
534
+ await initSchema();
563
535
 
564
536
  let query = "SELECT id, name, status, created_at, file_path FROM architectural_analyses";
565
537
  const params: any[] = [];
@@ -571,7 +543,7 @@ export function architectList(options: { json?: boolean; status?: string } = {})
571
543
 
572
544
  query += " ORDER BY created_at DESC";
573
545
 
574
- const analyses = db.query(query).all(...params) as any[];
546
+ const analyses = await dbAll<any>(query, params);
575
547
 
576
548
  if (options.json) {
577
549
  console.log(JSON.stringify(analyses, null, 2));
@@ -601,15 +573,14 @@ export function architectList(options: { json?: boolean; status?: string } = {})
601
573
  }
602
574
  }
603
575
 
604
- export function architectSave(options: { file?: string; json?: boolean }): void {
605
- initSchema();
606
- const db = getDb();
576
+ export async function architectSave(options: { file?: string; json?: boolean }): Promise<void> {
577
+ await initSchema();
607
578
  const now = new Date().toISOString();
608
579
 
609
- // Pegar analise pendente
610
- const analysis = db.query(
611
- "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1"
612
- ).get() as any;
580
+ const analysis = await dbGet<any>(
581
+ "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1",
582
+ []
583
+ );
613
584
 
614
585
  if (!analysis) {
615
586
  if (options.json) {
@@ -620,17 +591,14 @@ export function architectSave(options: { file?: string; json?: boolean }): void
620
591
  throw new CodexaError("Nenhuma analise pendente encontrada.");
621
592
  }
622
593
 
623
- // v8.4: Resolver caminho do arquivo .md
624
594
  const dir = ensureAnalysisDir();
625
595
  let filePath: string;
626
596
  if (options.file) {
627
- // Se path fornecido, usar como-is (aceita absoluto ou relativo)
628
597
  filePath = options.file;
629
598
  } else {
630
599
  filePath = join(dir, `${analysis.id}-${analysis.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").substring(0, 30)}.md`);
631
600
  }
632
601
 
633
- // v8.4: Ler .md do disco e parsear para popular o DB
634
602
  if (!existsSync(filePath)) {
635
603
  if (options.json) {
636
604
  console.log(JSON.stringify({ error: "FILE_NOT_FOUND", message: `Arquivo nao encontrado: ${filePath}` }));
@@ -644,7 +612,6 @@ export function architectSave(options: { file?: string; json?: boolean }): void
644
612
  const content = readFileSync(filePath, "utf-8");
645
613
  const parsed = parseAnalysisMd(content);
646
614
 
647
- // v10.0: Validar secoes criticas antes de salvar
648
615
  if (!parsed.babySteps || parsed.babySteps.length === 0) {
649
616
  const msg = "Secao 'Baby Steps' esta vazia ou nao foi encontrada no .md. "
650
617
  + "Verifique se os headers seguem o formato '## Baby Steps' e cada step usa '### N. Nome'.";
@@ -667,7 +634,6 @@ export function architectSave(options: { file?: string; json?: boolean }): void
667
634
  throw new CodexaError(msg);
668
635
  }
669
636
 
670
- // Popular DB com dados extraidos do .md
671
637
  const updates: string[] = [];
672
638
  const values: any[] = [];
673
639
 
@@ -710,7 +676,7 @@ export function architectSave(options: { file?: string; json?: boolean }): void
710
676
  values.push(now);
711
677
  values.push(analysis.id);
712
678
 
713
- db.run(
679
+ await dbRun(
714
680
  `UPDATE architectural_analyses SET ${updates.join(", ")} WHERE id = ?`,
715
681
  values
716
682
  );
@@ -750,19 +716,19 @@ export function architectSave(options: { file?: string; json?: boolean }): void
750
716
  }
751
717
  }
752
718
 
753
- export function architectApprove(options: { id?: string; json?: boolean }): void {
754
- initSchema();
755
- const db = getDb();
719
+ export async function architectApprove(options: { id?: string; json?: boolean }): Promise<void> {
720
+ await initSchema();
756
721
  const now = new Date().toISOString();
757
722
 
758
723
  let analysis: any;
759
724
 
760
725
  if (options.id) {
761
- analysis = db.query("SELECT * FROM architectural_analyses WHERE id = ?").get(options.id);
726
+ analysis = await dbGet<any>("SELECT * FROM architectural_analyses WHERE id = ?", [options.id]);
762
727
  } else {
763
- analysis = db.query(
764
- "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1"
765
- ).get();
728
+ analysis = await dbGet<any>(
729
+ "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1",
730
+ []
731
+ );
766
732
  }
767
733
 
768
734
  if (!analysis) {
@@ -783,7 +749,7 @@ export function architectApprove(options: { id?: string; json?: boolean }): void
783
749
  throw new CodexaError(`Analise ja esta com status '${analysis.status}'.`);
784
750
  }
785
751
 
786
- db.run(
752
+ await dbRun(
787
753
  "UPDATE architectural_analyses SET status = 'approved', approved_at = ?, updated_at = ? WHERE id = ?",
788
754
  [now, now, analysis.id]
789
755
  );
@@ -802,19 +768,18 @@ export function architectApprove(options: { id?: string; json?: boolean }): void
802
768
  }
803
769
  }
804
770
 
805
- // v8.4: Simplificado - agora o feature importa baby steps automaticamente via --from-analysis
806
- export function architectExport(options: { id?: string; json?: boolean }): void {
807
- initSchema();
808
- const db = getDb();
771
+ export async function architectExport(options: { id?: string; json?: boolean }): Promise<void> {
772
+ await initSchema();
809
773
 
810
774
  let analysis: any;
811
775
 
812
776
  if (options.id) {
813
- analysis = db.query("SELECT * FROM architectural_analyses WHERE id = ?").get(options.id);
777
+ analysis = await dbGet<any>("SELECT * FROM architectural_analyses WHERE id = ?", [options.id]);
814
778
  } else {
815
- analysis = db.query(
816
- "SELECT * FROM architectural_analyses WHERE status = 'approved' ORDER BY approved_at DESC LIMIT 1"
817
- ).get();
779
+ analysis = await dbGet<any>(
780
+ "SELECT * FROM architectural_analyses WHERE status = 'approved' ORDER BY approved_at DESC LIMIT 1",
781
+ []
782
+ );
818
783
  }
819
784
 
820
785
  if (!analysis) {
@@ -854,19 +819,19 @@ export function architectExport(options: { id?: string; json?: boolean }): void
854
819
  }
855
820
  }
856
821
 
857
- export function architectCancel(options: { id?: string; json?: boolean }): void {
858
- initSchema();
859
- const db = getDb();
822
+ export async function architectCancel(options: { id?: string; json?: boolean }): Promise<void> {
823
+ await initSchema();
860
824
  const now = new Date().toISOString();
861
825
 
862
826
  let analysis: any;
863
827
 
864
828
  if (options.id) {
865
- analysis = db.query("SELECT * FROM architectural_analyses WHERE id = ?").get(options.id);
829
+ analysis = await dbGet<any>("SELECT * FROM architectural_analyses WHERE id = ?", [options.id]);
866
830
  } else {
867
- analysis = db.query(
868
- "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1"
869
- ).get();
831
+ analysis = await dbGet<any>(
832
+ "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY created_at DESC LIMIT 1",
833
+ []
834
+ );
870
835
  }
871
836
 
872
837
  if (!analysis) {
@@ -878,7 +843,7 @@ export function architectCancel(options: { id?: string; json?: boolean }): void
878
843
  return;
879
844
  }
880
845
 
881
- db.run(
846
+ await dbRun(
882
847
  "UPDATE architectural_analyses SET status = 'rejected', updated_at = ? WHERE id = ?",
883
848
  [now, analysis.id]
884
849
  );
package/commands/check.ts CHANGED
@@ -1,25 +1,26 @@
1
- import { getDb } from "../db/connection";
1
+ import { dbGet, dbAll, dbRun } from "../db/connection";
2
2
  import { initSchema } from "../db/schema";
3
3
  import { enforceGate } from "../gates/validator";
4
4
  import { resolveSpec } from "./spec-resolver";
5
5
 
6
- export function checkRequest(specId?: string): void {
7
- initSchema();
6
+ export async function checkRequest(specId?: string): Promise<void> {
7
+ await initSchema();
8
8
  enforceGate("check-request");
9
9
 
10
- const db = getDb();
11
10
  const spec = resolveSpec(specId, ["planning"]);
12
11
 
13
- const tasks = db
14
- .query("SELECT * FROM tasks WHERE spec_id = ? ORDER BY number")
15
- .all(spec.id) as any[];
12
+ const tasks = await dbAll<any>(
13
+ "SELECT * FROM tasks WHERE spec_id = ? ORDER BY number",
14
+ [spec.id]
15
+ );
16
16
 
17
- const context = db
18
- .query("SELECT * FROM context WHERE spec_id = ?")
19
- .get(spec.id) as any;
17
+ const context = await dbGet<any>(
18
+ "SELECT * FROM context WHERE spec_id = ?",
19
+ [spec.id]
20
+ );
20
21
 
21
22
  // Atualizar fase para checking
22
- db.run("UPDATE specs SET phase = 'checking', updated_at = ? WHERE id = ?", [
23
+ await dbRun("UPDATE specs SET phase = 'checking', updated_at = ? WHERE id = ?", [
23
24
  new Date().toISOString(),
24
25
  spec.id,
25
26
  ]);
@@ -67,29 +68,28 @@ export function checkRequest(specId?: string): void {
67
68
  console.log(`Para ajustar: plan task-add (adiciona mais tasks)\n`);
68
69
  }
69
70
 
70
- export function checkApprove(specId?: string): void {
71
- initSchema();
71
+ export async function checkApprove(specId?: string): Promise<void> {
72
+ await initSchema();
72
73
  enforceGate("check-approve");
73
74
 
74
- const db = getDb();
75
75
  const now = new Date().toISOString();
76
76
 
77
77
  const spec = resolveSpec(specId, ["checking"]);
78
78
 
79
79
  // Atualizar para aprovado
80
- db.run(
80
+ await dbRun(
81
81
  "UPDATE specs SET phase = 'implementing', approved_at = ?, updated_at = ? WHERE id = ?",
82
82
  [now, now, spec.id]
83
83
  );
84
84
 
85
85
  // Atualizar contexto
86
- db.run("UPDATE context SET current_task = 0, updated_at = ? WHERE spec_id = ?", [now, spec.id]);
86
+ await dbRun("UPDATE context SET current_task = 0, updated_at = ? WHERE spec_id = ?", [now, spec.id]);
87
87
 
88
- const taskCount = db.query("SELECT COUNT(*) as c FROM tasks WHERE spec_id = ?").get(spec.id) as any;
88
+ const taskCount = await dbGet<any>("SELECT COUNT(*) as c FROM tasks WHERE spec_id = ?", [spec.id]);
89
89
 
90
90
  console.log(`\nPlano APROVADO!`);
91
91
  console.log(`Feature: ${spec.name}`);
92
- console.log(`Tasks: ${taskCount.c}`);
92
+ console.log(`Tasks: ${taskCount?.c || 0}`);
93
93
  console.log(`Fase: implementing`);
94
94
  console.log(`\nProximos passos:`);
95
95
  console.log(`1. Veja proximas tasks com: task next`);
@@ -97,19 +97,18 @@ export function checkApprove(specId?: string): void {
97
97
  console.log(`3. Complete uma task com: task done <id> --checkpoint "..."\n`);
98
98
  }
99
99
 
100
- export function checkReject(reason: string, specId?: string): void {
101
- initSchema();
100
+ export async function checkReject(reason: string, specId?: string): Promise<void> {
101
+ await initSchema();
102
102
 
103
- const db = getDb();
104
103
  const now = new Date().toISOString();
105
104
 
106
105
  const spec = resolveSpec(specId, ["checking"]);
107
106
 
108
107
  // Voltar para planning
109
- db.run("UPDATE specs SET phase = 'planning', updated_at = ? WHERE id = ?", [now, spec.id]);
108
+ await dbRun("UPDATE specs SET phase = 'planning', updated_at = ? WHERE id = ?", [now, spec.id]);
110
109
 
111
110
  // Registrar motivo no contexto
112
- db.run(
111
+ await dbRun(
113
112
  "UPDATE context SET last_checkpoint = ?, updated_at = ? WHERE spec_id = ?",
114
113
  [`REJEITADO: ${reason}`, now, spec.id]
115
114
  );
package/commands/clear.ts CHANGED
@@ -1,29 +1,37 @@
1
- import { getDbPath, getDb } from "../db/connection";
1
+ import { dbGet, dbRun } from "../db/connection";
2
2
  import { initSchema } from "../db/schema";
3
3
  import { existsSync } from "fs";
4
- import { join, dirname } from "path";
4
+ import { join } from "path";
5
5
 
6
6
  interface ClearOptions {
7
7
  force?: boolean;
8
8
  specId?: string;
9
9
  }
10
10
 
11
+ function getDbUrl(): string {
12
+ return process.env.CODEXA_DB_URL || "(nao configurado)";
13
+ }
14
+
11
15
  /**
12
16
  * Limpa apenas as tasks/features, mantendo configurações do projeto
13
17
  * Esta é a ÚNICA forma de limpeza disponível (v8.0)
14
18
  * A limpeza completa foi removida por ser muito destrutiva
15
19
  */
16
- export function clearTasks(options: ClearOptions = {}): void {
20
+ export async function clearTasks(options: ClearOptions = {}): Promise<void> {
17
21
  // Garantir que o schema existe
18
- initSchema();
19
- const db = getDb();
22
+ await initSchema();
20
23
 
21
24
  // Contar o que existe
22
- const specsCount = (db.query("SELECT COUNT(*) as c FROM specs").get() as any).c;
23
- const tasksCount = (db.query("SELECT COUNT(*) as c FROM tasks").get() as any).c;
24
- const decisionsCount = (db.query("SELECT COUNT(*) as c FROM decisions").get() as any).c;
25
- const knowledgeCount = (db.query("SELECT COUNT(*) as c FROM knowledge").get() as any).c;
26
- const reasoningCount = (db.query("SELECT COUNT(*) as c FROM reasoning_log").get() as any).c;
25
+ const specsRow = await dbGet<any>("SELECT COUNT(*) as c FROM specs", []);
26
+ const specsCount = specsRow?.c ?? 0;
27
+ const tasksRow = await dbGet<any>("SELECT COUNT(*) as c FROM tasks", []);
28
+ const tasksCount = tasksRow?.c ?? 0;
29
+ const decisionsRow = await dbGet<any>("SELECT COUNT(*) as c FROM decisions", []);
30
+ const decisionsCount = decisionsRow?.c ?? 0;
31
+ const knowledgeRow = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge", []);
32
+ const knowledgeCount = knowledgeRow?.c ?? 0;
33
+ const reasoningRow = await dbGet<any>("SELECT COUNT(*) as c FROM reasoning_log", []);
34
+ const reasoningCount = reasoningRow?.c ?? 0;
27
35
 
28
36
  if (specsCount === 0 && tasksCount === 0) {
29
37
  console.log("\nNenhuma feature/task para limpar.\n");
@@ -87,7 +95,7 @@ export function clearTasks(options: ClearOptions = {}): void {
87
95
 
88
96
  for (const table of tablesWithSpecId) {
89
97
  try {
90
- const result = db.run(`DELETE FROM ${table} WHERE spec_id = ?`, [options.specId]);
98
+ const result = await dbRun(`DELETE FROM ${table} WHERE spec_id = ?`, [options.specId]);
91
99
  if (result.changes > 0) {
92
100
  console.log(` Limpo: ${table} (${result.changes} registros)`);
93
101
  }
@@ -126,7 +134,7 @@ export function clearTasks(options: ClearOptions = {}): void {
126
134
 
127
135
  for (const table of tablesToClear) {
128
136
  try {
129
- const result = db.run(`DELETE FROM ${table}`);
137
+ const result = await dbRun(`DELETE FROM ${table}`);
130
138
  console.log(` Limpo: ${table} (${result.changes} registros)`);
131
139
  } catch (err: any) {
132
140
  // Tabela pode não existir em bancos antigos
@@ -148,15 +156,9 @@ export function clearTasks(options: ClearOptions = {}): void {
148
156
  /**
149
157
  * Mostra o estado atual do workflow
150
158
  */
151
- export function clearShow(): void {
152
- const dbPath = getDbPath();
153
- const codexaDir = dirname(dirname(dbPath));
154
-
155
- const dbFiles = [
156
- dbPath,
157
- `${dbPath}-shm`,
158
- `${dbPath}-wal`,
159
- ];
159
+ export async function clearShow(): Promise<void> {
160
+ const codexaDir = join(process.cwd(), ".codexa");
161
+ const dbUrl = getDbUrl();
160
162
 
161
163
  const markdownFiles = [
162
164
  join(codexaDir, "standards.md"),
@@ -168,11 +170,7 @@ export function clearShow(): void {
168
170
  console.log("ESTADO DO WORKFLOW");
169
171
  console.log("═".repeat(60) + "\n");
170
172
 
171
- console.log("Banco de dados:");
172
- for (const file of dbFiles) {
173
- const status = existsSync(file) ? "existe" : "nao existe";
174
- console.log(` ${file}: ${status}`);
175
- }
173
+ console.log(`Banco de dados: ${dbUrl}`);
176
174
 
177
175
  console.log("\nArquivos gerados:");
178
176
  for (const file of markdownFiles) {
@@ -180,28 +178,24 @@ export function clearShow(): void {
180
178
  console.log(` ${file}: ${status}`);
181
179
  }
182
180
 
183
- // Mostrar estatísticas do banco se existir
184
- if (existsSync(dbPath)) {
185
- try {
186
- initSchema();
187
- const db = getDb();
188
-
189
- console.log("\nEstatisticas:");
190
-
191
- const specs = (db.query("SELECT COUNT(*) as c FROM specs").get() as any).c;
192
- const tasks = (db.query("SELECT COUNT(*) as c FROM tasks").get() as any).c;
193
- const decisions = (db.query("SELECT COUNT(*) as c FROM decisions").get() as any).c;
194
- const standards = (db.query("SELECT COUNT(*) as c FROM standards").get() as any).c;
195
- const patterns = (db.query("SELECT COUNT(*) as c FROM implementation_patterns").get() as any).c;
196
-
197
- console.log(` Features: ${specs}`);
198
- console.log(` Tasks: ${tasks}`);
199
- console.log(` Decisions: ${decisions}`);
200
- console.log(` Standards: ${standards}`);
201
- console.log(` Patterns: ${patterns}`);
202
- } catch (err: any) {
203
- console.log(`\n Erro ao ler estatisticas: ${err.message}`);
204
- }
181
+ try {
182
+ await initSchema();
183
+
184
+ console.log("\nEstatisticas:");
185
+
186
+ const specsRow = await dbGet<any>("SELECT COUNT(*) as c FROM specs", []);
187
+ const tasksRow = await dbGet<any>("SELECT COUNT(*) as c FROM tasks", []);
188
+ const decisionsRow = await dbGet<any>("SELECT COUNT(*) as c FROM decisions", []);
189
+ const standardsRow = await dbGet<any>("SELECT COUNT(*) as c FROM standards", []);
190
+ const patternsRow = await dbGet<any>("SELECT COUNT(*) as c FROM implementation_patterns", []);
191
+
192
+ console.log(` Features: ${specsRow?.c ?? 0}`);
193
+ console.log(` Tasks: ${tasksRow?.c ?? 0}`);
194
+ console.log(` Decisions: ${decisionsRow?.c ?? 0}`);
195
+ console.log(` Standards: ${standardsRow?.c ?? 0}`);
196
+ console.log(` Patterns: ${patternsRow?.c ?? 0}`);
197
+ } catch (err: any) {
198
+ console.log(`\n Erro ao ler estatisticas: ${err.message}`);
205
199
  }
206
200
 
207
201
  console.log("\n" + "─".repeat(60));