@codexa/cli 9.0.30 → 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/commands/team.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { getDb } from "../db/connection";
1
+ import { dbGet, dbAll } from "../db/connection";
2
2
  import { initSchema } from "../db/schema";
3
3
  import { resolveSpec, resolveSpecOrNull } from "./spec-resolver";
4
4
 
@@ -30,39 +30,37 @@ export interface TeamSuggestion {
30
30
  // Main Command
31
31
  // ─────────────────────────────────────────────────────────────────
32
32
 
33
- export function teamSuggest(options: {
33
+ export async function teamSuggest(options: {
34
34
  json?: boolean;
35
35
  phase?: string;
36
36
  spec?: string;
37
- }): void {
38
- initSchema();
39
- const db = getDb();
37
+ }): Promise<void> {
38
+ await initSchema();
40
39
 
41
40
  const envVarSet = process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1";
42
41
 
43
- // Phase pode ser fornecida ou detectada
44
42
  let spec: any = null;
45
43
  let phase = options.phase;
46
44
 
47
45
  if (!phase) {
48
- spec = resolveSpecOrNull(options.spec);
46
+ spec = await resolveSpecOrNull(options.spec);
49
47
  if (spec) {
50
- phase = detectPhase(db, spec);
48
+ phase = await detectPhase(spec);
51
49
  } else {
52
50
  phase = "unknown";
53
51
  }
54
52
  } else {
55
- spec = resolveSpecOrNull(options.spec);
53
+ spec = await resolveSpecOrNull(options.spec);
56
54
  }
57
55
 
58
56
  let result: TeamSuggestion;
59
57
 
60
58
  if (phase === "imp" && spec) {
61
- result = suggestForImp(db, spec, envVarSet);
59
+ result = await suggestForImp(spec, envVarSet);
62
60
  } else if (phase === "rev" && spec) {
63
- result = suggestForRev(db, spec, envVarSet);
61
+ result = await suggestForRev(spec, envVarSet);
64
62
  } else if (phase === "architect") {
65
- result = suggestForArchitect(db, spec, envVarSet);
63
+ result = await suggestForArchitect(spec, envVarSet);
66
64
  } else {
67
65
  result = {
68
66
  recommended: false,
@@ -83,14 +81,14 @@ export function teamSuggest(options: {
83
81
  // Phase Detection
84
82
  // ─────────────────────────────────────────────────────────────────
85
83
 
86
- export function detectPhase(db: any, spec: any): string {
84
+ export async function detectPhase(spec: any): Promise<string> {
87
85
  if (spec.phase === "implementing") return "imp";
88
86
  if (spec.phase === "reviewing") return "rev";
89
87
 
90
- // Verificar se ha analise arquitetural pendente
91
- const pendingAnalysis = db
92
- .query("SELECT id FROM architectural_analyses WHERE status = 'pending' LIMIT 1")
93
- .get();
88
+ const pendingAnalysis = await dbGet<any>(
89
+ "SELECT id FROM architectural_analyses WHERE status = 'pending' LIMIT 1",
90
+ []
91
+ );
94
92
  if (pendingAnalysis) return "architect";
95
93
 
96
94
  return spec.phase;
@@ -100,26 +98,35 @@ export function detectPhase(db: any, spec: any): string {
100
98
  // IMP Phase
101
99
  // ─────────────────────────────────────────────────────────────────
102
100
 
103
- function suggestForImp(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
104
- // 1. Buscar tasks pending com dependencias satisfeitas
105
- const allTasks = db
106
- .query("SELECT * FROM tasks WHERE spec_id = ? AND status = 'pending'")
107
- .all(spec.id) as any[];
108
-
109
- const available = allTasks.filter((t: any) => {
110
- if (!t.depends_on) return true;
101
+ async function suggestForImp(spec: any, envVarSet: boolean): Promise<TeamSuggestion> {
102
+ const allTasks = await dbAll<any>(
103
+ "SELECT * FROM tasks WHERE spec_id = ? AND status = 'pending'",
104
+ [spec.id]
105
+ );
106
+
107
+ const available: any[] = [];
108
+ for (const t of allTasks) {
109
+ if (!t.depends_on) {
110
+ available.push(t);
111
+ continue;
112
+ }
111
113
  const deps = JSON.parse(t.depends_on) as number[];
112
- return deps.every((depNum) => {
113
- const dep = db
114
- .query("SELECT status FROM tasks WHERE spec_id = ? AND number = ?")
115
- .get(spec.id, depNum) as any;
116
- return dep?.status === "done";
117
- });
118
- });
114
+ let allDone = true;
115
+ for (const depNum of deps) {
116
+ const dep = await dbGet<any>(
117
+ "SELECT status FROM tasks WHERE spec_id = ? AND number = ?",
118
+ [spec.id, depNum]
119
+ );
120
+ if (dep?.status !== "done") {
121
+ allDone = false;
122
+ break;
123
+ }
124
+ }
125
+ if (allDone) available.push(t);
126
+ }
119
127
 
120
128
  const parallelizable = available.filter((t: any) => t.can_parallel);
121
129
 
122
- // 2. Agrupar por dominio (campo agent)
123
130
  const byDomain = new Map<string, any[]>();
124
131
  for (const task of parallelizable) {
125
132
  const domain = task.agent || "general";
@@ -127,7 +134,6 @@ function suggestForImp(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
127
134
  byDomain.get(domain)!.push(task);
128
135
  }
129
136
 
130
- // 3. Recomendar se >= 3 tasks em >= 2 dominios
131
137
  if (parallelizable.length < 3 || byDomain.size < 2) {
132
138
  return {
133
139
  recommended: false,
@@ -146,7 +152,6 @@ function suggestForImp(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
146
152
  };
147
153
  }
148
154
 
149
- // 4. Gerar teammates
150
155
  const teammates: TeammateConfig[] = [];
151
156
  for (const [domain, tasks] of byDomain) {
152
157
  teammates.push({
@@ -175,14 +180,18 @@ function suggestForImp(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
175
180
  // REV Phase
176
181
  // ─────────────────────────────────────────────────────────────────
177
182
 
178
- function suggestForRev(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
179
- const totalTasks = (db
180
- .query("SELECT COUNT(*) as count FROM tasks WHERE spec_id = ?")
181
- .get(spec.id) as any).count;
183
+ async function suggestForRev(spec: any, envVarSet: boolean): Promise<TeamSuggestion> {
184
+ const totalTasksRow = await dbGet<any>(
185
+ "SELECT COUNT(*) as count FROM tasks WHERE spec_id = ?",
186
+ [spec.id]
187
+ );
188
+ const totalTasks = totalTasksRow?.count ?? 0;
182
189
 
183
- const artifactCount = (db
184
- .query("SELECT COUNT(*) as count FROM artifacts WHERE spec_id = ?")
185
- .get(spec.id) as any).count;
190
+ const artifactCountRow = await dbGet<any>(
191
+ "SELECT COUNT(*) as count FROM artifacts WHERE spec_id = ?",
192
+ [spec.id]
193
+ );
194
+ const artifactCount = artifactCountRow?.count ?? 0;
186
195
 
187
196
  if (totalTasks < 3 && artifactCount < 5) {
188
197
  return {
@@ -202,9 +211,11 @@ function suggestForRev(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
202
211
  };
203
212
  }
204
213
 
205
- const artifactList = (db
206
- .query("SELECT path FROM artifacts WHERE spec_id = ?")
207
- .all(spec.id) as any[]).map((a: any) => a.path);
214
+ const artifactRows = await dbAll<any>(
215
+ "SELECT path FROM artifacts WHERE spec_id = ?",
216
+ [spec.id]
217
+ );
218
+ const artifactList = artifactRows.map((a: any) => a.path);
208
219
 
209
220
  const lenses = ["security", "performance", "standards"] as const;
210
221
  const teammates: TeammateConfig[] = lenses.map((lens) => ({
@@ -232,10 +243,11 @@ function suggestForRev(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
232
243
  // Architect Phase
233
244
  // ─────────────────────────────────────────────────────────────────
234
245
 
235
- function suggestForArchitect(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
236
- const analysis = db
237
- .query("SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY id DESC LIMIT 1")
238
- .get() as any;
246
+ async function suggestForArchitect(spec: any, envVarSet: boolean): Promise<TeamSuggestion> {
247
+ const analysis = await dbGet<any>(
248
+ "SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY id DESC LIMIT 1",
249
+ []
250
+ );
239
251
 
240
252
  if (!analysis) {
241
253
  return {
@@ -255,7 +267,7 @@ function suggestForArchitect(db: any, spec: any, envVarSet: boolean): TeamSugges
255
267
  };
256
268
  }
257
269
 
258
- const project = db.query("SELECT * FROM project LIMIT 1").get() as any;
270
+ const project = await dbGet<any>("SELECT * FROM project LIMIT 1", []);
259
271
  const stackSummary = project?.stack ? JSON.parse(project.stack) : {};
260
272
 
261
273
  const teammates: TeammateConfig[] = [
package/commands/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { getDb } from "../db/connection";
1
+ import { dbGet, dbAll, dbRun } from "../db/connection";
2
2
  import { initSchema, getArchitecturalAnalysisForSpec, detectStuckTasks } from "../db/schema";
3
3
  import { getKnowledgeForTask } from "./knowledge";
4
4
  import { getLibContextsForAgent } from "./research";
@@ -13,20 +13,18 @@ export { AGENT_DOMAIN, getAgentDomain, domainToScope } from "../context/domains"
13
13
  export { resolveAgent, resolveAgentName, suggestAgent, getCanonicalAgentNames } from "../context/agent-registry";
14
14
  export { loadAgentExpertise, getAgentDescription } from "../context/agent-expertise";
15
15
 
16
- export function status(json: boolean = false, specId?: string): void {
17
- initSchema();
18
-
19
- const db = getDb();
16
+ export async function status(json: boolean = false, specId?: string): Promise<void> {
17
+ await initSchema();
20
18
 
21
19
  // Se --spec fornecido, mostra spec especifico
22
20
  // Se nao fornecido, mostra todos os ativos (multi-spec)
23
21
  if (specId) {
24
- const spec = resolveSpec(specId);
25
- showSingleSpecStatus(db, spec, json);
22
+ const spec = await resolveSpec(specId);
23
+ await showSingleSpecStatus(spec, json);
26
24
  return;
27
25
  }
28
26
 
29
- const allSpecs = getAllActiveSpecs();
27
+ const allSpecs = await getAllActiveSpecs();
30
28
 
31
29
  if (allSpecs.length === 0) {
32
30
  if (json) {
@@ -40,18 +38,18 @@ export function status(json: boolean = false, specId?: string): void {
40
38
  }
41
39
 
42
40
  if (allSpecs.length === 1) {
43
- showSingleSpecStatus(db, allSpecs[0], json);
41
+ await showSingleSpecStatus(allSpecs[0], json);
44
42
  return;
45
43
  }
46
44
 
47
45
  // Multi-spec: show summary table
48
- showMultiSpecStatus(db, allSpecs, json);
46
+ await showMultiSpecStatus(allSpecs, json);
49
47
  }
50
48
 
51
- function showSingleSpecStatus(db: any, spec: any, json: boolean): void {
52
- const context = db.query("SELECT * FROM context WHERE spec_id = ?").get(spec.id) as any;
53
- const tasks = db.query("SELECT * FROM tasks WHERE spec_id = ?").all(spec.id) as any[];
54
- const decisions = db.query("SELECT * FROM decisions WHERE spec_id = ? AND status = 'active'").all(spec.id) as any[];
49
+ async function showSingleSpecStatus(spec: any, json: boolean): Promise<void> {
50
+ const context = await dbGet<any>("SELECT * FROM context WHERE spec_id = ?", [spec.id]);
51
+ const tasks = await dbAll<any>("SELECT * FROM tasks WHERE spec_id = ?", [spec.id]);
52
+ const decisions = await dbAll<any>("SELECT * FROM decisions WHERE spec_id = ? AND status = 'active'", [spec.id]);
55
53
 
56
54
  const tasksDone = tasks.filter((t: any) => t.status === "done").length;
57
55
  const tasksRunning = tasks.filter((t: any) => t.status === "running").length;
@@ -94,7 +92,7 @@ function showSingleSpecStatus(db: any, spec: any, json: boolean): void {
94
92
  console.log(` Pendentes: ${tasksPending}`);
95
93
 
96
94
  if (tasksRunning > 0) {
97
- const stuck = detectStuckTasks(spec.id);
95
+ const stuck = await detectStuckTasks(spec.id);
98
96
  if (stuck.length > 0) {
99
97
  console.log(`\n[!] AVISO: ${stuck.length} task(s) parada(s) ha mais de 30 minutos:`);
100
98
  for (const t of stuck) {
@@ -136,19 +134,20 @@ function showSingleSpecStatus(db: any, spec: any, json: boolean): void {
136
134
  console.log();
137
135
  }
138
136
 
139
- function showMultiSpecStatus(db: any, specs: any[], json: boolean): void {
137
+ async function showMultiSpecStatus(specs: any[], json: boolean): Promise<void> {
140
138
  if (json) {
141
- const specsData = specs.map((spec: any) => {
142
- const tasks = db.query("SELECT * FROM tasks WHERE spec_id = ?").all(spec.id) as any[];
139
+ const specsData = [];
140
+ for (const spec of specs) {
141
+ const tasks = await dbAll<any>("SELECT * FROM tasks WHERE spec_id = ?", [spec.id]);
143
142
  const done = tasks.filter((t: any) => t.status === "done").length;
144
- return {
143
+ specsData.push({
145
144
  id: spec.id,
146
145
  name: spec.name,
147
146
  phase: spec.phase,
148
147
  progress: tasks.length > 0 ? Math.round((done / tasks.length) * 100) : 0,
149
148
  tasks: { done, total: tasks.length },
150
- };
151
- });
149
+ });
150
+ }
152
151
  console.log(JSON.stringify({ active: true, version: pkg.version, specs: specsData }));
153
152
  return;
154
153
  }
@@ -158,7 +157,7 @@ function showMultiSpecStatus(db: any, specs: any[], json: boolean): void {
158
157
  console.log(`${"=".repeat(60)}\n`);
159
158
 
160
159
  for (const spec of specs) {
161
- const tasks = db.query("SELECT * FROM tasks WHERE spec_id = ?").all(spec.id) as any[];
160
+ const tasks = await dbAll<any>("SELECT * FROM tasks WHERE spec_id = ?", [spec.id]);
162
161
  const done = tasks.filter((t: any) => t.status === "done").length;
163
162
  const progress = tasks.length > 0 ? Math.round((done / tasks.length) * 100) : 0;
164
163
  const bar = "\u2588".repeat(Math.floor(progress / 5)) + "\u2591".repeat(20 - Math.floor(progress / 5));
@@ -173,19 +172,18 @@ function showMultiSpecStatus(db: any, specs: any[], json: boolean): void {
173
172
  console.log(`Use: status --spec <id> para detalhes de uma feature\n`);
174
173
  }
175
174
 
176
- export function contextExport(options: { task?: string; json?: boolean; specId?: string; }): void {
177
- initSchema();
175
+ export async function contextExport(options: { task?: string; json?: boolean; specId?: string; }): Promise<void> {
176
+ await initSchema();
178
177
 
179
- const db = getDb();
178
+ const spec = await resolveSpec(options.specId);
180
179
 
181
- const spec = resolveSpec(options.specId);
182
-
183
- const context = db.query("SELECT * FROM context WHERE spec_id = ?").get(spec.id) as any;
184
- const decisions = db
185
- .query("SELECT * FROM decisions WHERE spec_id = ? AND status = 'active'")
186
- .all(spec.id) as any[];
187
- const artifacts = db.query("SELECT * FROM artifacts WHERE spec_id = ?").all(spec.id) as any[];
188
- const project = db.query("SELECT * FROM project WHERE id = 'default'").get() as any;
180
+ const context = await dbGet<any>("SELECT * FROM context WHERE spec_id = ?", [spec.id]);
181
+ const decisions = await dbAll<any>(
182
+ "SELECT * FROM decisions WHERE spec_id = ? AND status = 'active'",
183
+ [spec.id]
184
+ );
185
+ const artifacts = await dbAll<any>("SELECT * FROM artifacts WHERE spec_id = ?", [spec.id]);
186
+ const project = await dbGet<any>("SELECT * FROM project WHERE id = 'default'", ["default"]);
189
187
 
190
188
  let taskContext = null;
191
189
  let standards: any[] = [];
@@ -194,7 +192,7 @@ export function contextExport(options: { task?: string; json?: boolean; specId?:
194
192
 
195
193
  if (options.task) {
196
194
  const taskId = parseInt(options.task);
197
- const task = db.query("SELECT * FROM tasks WHERE id = ?").get(taskId) as any;
195
+ const task = await dbGet<any>("SELECT * FROM tasks WHERE id = ?", [taskId]);
198
196
  if (task) {
199
197
  taskContext = {
200
198
  id: task.id,
@@ -206,13 +204,12 @@ export function contextExport(options: { task?: string; json?: boolean; specId?:
206
204
 
207
205
  // Obter standards para o agente da task
208
206
  const domain = domainToScope(getAgentDomain(task.agent));
209
- standards = db
210
- .query(
211
- `SELECT * FROM standards
207
+ standards = await dbAll<any>(
208
+ `SELECT * FROM standards
212
209
  WHERE scope = 'all' OR scope = ?
213
- ORDER BY enforcement DESC, category`
214
- )
215
- .all(domain) as any[];
210
+ ORDER BY enforcement DESC, category`,
211
+ [domain]
212
+ );
216
213
 
217
214
  standards = standards.map((std) => ({
218
215
  category: std.category,
@@ -223,7 +220,8 @@ export function contextExport(options: { task?: string; json?: boolean; specId?:
223
220
  }));
224
221
 
225
222
  // Obter knowledge broadcast (automatico)
226
- knowledge = getKnowledgeForTask(spec.id, taskId).map((k) => ({
223
+ const rawKnowledge = await getKnowledgeForTask(spec.id, taskId);
224
+ knowledge = rawKnowledge.map((k) => ({
227
225
  id: k.id,
228
226
  category: k.category,
229
227
  content: k.content,
@@ -240,9 +238,9 @@ export function contextExport(options: { task?: string; json?: boolean; specId?:
240
238
  }
241
239
 
242
240
  // Obter contexto de produto
243
- const productContext = db.query("SELECT * FROM product_context WHERE id = 'default'").get() as any;
244
- const productGoals = db.query("SELECT * FROM product_goals WHERE product_id = 'default'").all() as any[];
245
- const productFeatures = db.query("SELECT * FROM product_features WHERE product_id = 'default'").all() as any[];
241
+ const productContext = await dbGet<any>("SELECT * FROM product_context WHERE id = 'default'", ["default"]);
242
+ const productGoals = await dbAll<any>("SELECT * FROM product_goals WHERE product_id = 'default'", ["default"]);
243
+ const productFeatures = await dbAll<any>("SELECT * FROM product_features WHERE product_id = 'default'", ["default"]);
246
244
 
247
245
  const exportData = {
248
246
  spec: {
@@ -291,16 +289,16 @@ export function contextExport(options: { task?: string; json?: boolean; specId?:
291
289
  console.log(JSON.stringify(exportData, null, 2));
292
290
  }
293
291
 
294
- export function contextDetail(section: string, json: boolean = false, specId?: string): void {
295
- initSchema();
296
- const db = getDb();
292
+ export async function contextDetail(section: string, json: boolean = false, specId?: string): Promise<void> {
293
+ await initSchema();
297
294
 
298
- const spec = resolveSpec(specId);
295
+ const spec = await resolveSpec(specId);
299
296
 
300
297
  // Encontrar task running (para contexto relevante)
301
- const runningTask = db.query(
302
- "SELECT * FROM tasks WHERE spec_id = ? AND status = 'running' LIMIT 1"
303
- ).get(spec.id) as any;
298
+ const runningTask = await dbGet<any>(
299
+ "SELECT * FROM tasks WHERE spec_id = ? AND status = 'running' LIMIT 1",
300
+ [spec.id]
301
+ );
304
302
 
305
303
  const domain = domainToScope(getAgentDomain(runningTask?.agent));
306
304
 
@@ -308,9 +306,10 @@ export function contextDetail(section: string, json: boolean = false, specId?: s
308
306
 
309
307
  switch (section) {
310
308
  case "standards": {
311
- const standards = db.query(
312
- "SELECT * FROM standards WHERE scope = 'all' OR scope = ? ORDER BY enforcement DESC, category"
313
- ).all(domain) as any[];
309
+ const standards = await dbAll<any>(
310
+ "SELECT * FROM standards WHERE scope = 'all' OR scope = ? ORDER BY enforcement DESC, category",
311
+ [domain]
312
+ );
314
313
 
315
314
  if (json) { console.log(JSON.stringify({ standards })); return; }
316
315
 
@@ -334,9 +333,10 @@ export function contextDetail(section: string, json: boolean = false, specId?: s
334
333
  }
335
334
 
336
335
  case "decisions": {
337
- const decisions = db.query(
338
- "SELECT * FROM decisions WHERE spec_id = ? AND status = 'active' ORDER BY created_at DESC"
339
- ).all(spec.id) as any[];
336
+ const decisions = await dbAll<any>(
337
+ "SELECT * FROM decisions WHERE spec_id = ? AND status = 'active' ORDER BY created_at DESC",
338
+ [spec.id]
339
+ );
340
340
 
341
341
  if (json) { console.log(JSON.stringify({ decisions })); return; }
342
342
 
@@ -351,9 +351,10 @@ export function contextDetail(section: string, json: boolean = false, specId?: s
351
351
  }
352
352
 
353
353
  case "patterns": {
354
- const patterns = db.query(
355
- "SELECT * FROM implementation_patterns ORDER BY category, name"
356
- ).all() as any[];
354
+ const patterns = await dbAll<any>(
355
+ "SELECT * FROM implementation_patterns ORDER BY category, name",
356
+ []
357
+ );
357
358
 
358
359
  if (json) { console.log(JSON.stringify({ patterns })); return; }
359
360
 
@@ -375,9 +376,10 @@ export function contextDetail(section: string, json: boolean = false, specId?: s
375
376
  }
376
377
 
377
378
  case "knowledge": {
378
- const knowledge = db.query(
379
- "SELECT k.*, t.number as task_number FROM knowledge k LEFT JOIN tasks t ON k.task_origin = t.id WHERE k.spec_id = ? ORDER BY k.severity DESC, k.created_at DESC LIMIT 50"
380
- ).all(spec.id) as any[];
379
+ const knowledge = await dbAll<any>(
380
+ "SELECT k.*, t.number as task_number FROM knowledge k LEFT JOIN tasks t ON k.task_origin = t.id WHERE k.spec_id = ? ORDER BY k.severity DESC, k.created_at DESC LIMIT 50",
381
+ [spec.id]
382
+ );
381
383
 
382
384
  if (json) { console.log(JSON.stringify({ knowledge })); return; }
383
385
 
@@ -391,7 +393,7 @@ export function contextDetail(section: string, json: boolean = false, specId?: s
391
393
  }
392
394
 
393
395
  case "architecture": {
394
- const analysis = getArchitecturalAnalysisForSpec(spec.name, spec.id);
396
+ const analysis = await getArchitecturalAnalysisForSpec(spec.name, spec.id);
395
397
  if (!analysis) {
396
398
  output = "Nenhuma analise arquitetural encontrada.";
397
399
  break;
@@ -430,21 +432,20 @@ export function contextDetail(section: string, json: boolean = false, specId?: s
430
432
  console.log(output || "\nNenhum dado encontrado.\n");
431
433
  }
432
434
 
433
- export function recover(options: {
435
+ export async function recover(options: {
434
436
  list?: boolean;
435
437
  snapshot?: string;
436
438
  restore?: boolean;
437
439
  auto?: boolean;
438
- }): void {
439
- initSchema();
440
-
441
- const db = getDb();
440
+ }): Promise<void> {
441
+ await initSchema();
442
442
 
443
443
  // Listar snapshots
444
444
  if (options.list) {
445
- const snapshots = db
446
- .query("SELECT id, spec_id, trigger, created_at FROM snapshots ORDER BY created_at DESC LIMIT 20")
447
- .all() as any[];
445
+ const snapshots = await dbAll<any>(
446
+ "SELECT id, spec_id, trigger, created_at FROM snapshots ORDER BY created_at DESC LIMIT 20",
447
+ []
448
+ );
448
449
 
449
450
  if (snapshots.length === 0) {
450
451
  console.log("\nNenhum snapshot disponivel.\n");
@@ -466,10 +467,10 @@ export function recover(options: {
466
467
  let snapshot: any;
467
468
 
468
469
  if (options.auto) {
469
- snapshot = db.query("SELECT * FROM snapshots ORDER BY created_at DESC LIMIT 1").get();
470
+ snapshot = await dbGet<any>("SELECT * FROM snapshots ORDER BY created_at DESC LIMIT 1", []);
470
471
  } else if (options.snapshot) {
471
472
  const snapshotId = parseInt(options.snapshot);
472
- snapshot = db.query("SELECT * FROM snapshots WHERE id = ?").get(snapshotId);
473
+ snapshot = await dbGet<any>("SELECT * FROM snapshots WHERE id = ?", [snapshotId]);
473
474
  }
474
475
 
475
476
  if (!snapshot) {
@@ -483,7 +484,7 @@ export function recover(options: {
483
484
 
484
485
  // 1. Restaurar spec
485
486
  if (data.spec) {
486
- db.run(
487
+ await dbRun(
487
488
  `UPDATE specs SET phase = ?, approved_at = ?, updated_at = ? WHERE id = ?`,
488
489
  [data.spec.phase, data.spec.approved_at, now, data.spec.id]
489
490
  );
@@ -492,7 +493,7 @@ export function recover(options: {
492
493
 
493
494
  // 2. Restaurar context
494
495
  if (data.context) {
495
- db.run(
496
+ await dbRun(
496
497
  `UPDATE context SET
497
498
  objective = ?, approach = ?, constraints = ?, patterns = ?,
498
499
  current_task = ?, last_checkpoint = ?, updated_at = ?
@@ -514,7 +515,7 @@ export function recover(options: {
514
515
  // 3. Restaurar status das tasks
515
516
  if (data.tasks && Array.isArray(data.tasks)) {
516
517
  for (const task of data.tasks) {
517
- db.run(
518
+ await dbRun(
518
519
  `UPDATE tasks SET status = ?, checkpoint = ?, completed_at = ? WHERE id = ?`,
519
520
  [task.status, task.checkpoint, task.completed_at, task.id]
520
521
  );
@@ -541,7 +542,7 @@ export function recover(options: {
541
542
  // Mostrar detalhes de snapshot específico
542
543
  if (options.snapshot) {
543
544
  const snapshotId = parseInt(options.snapshot);
544
- const snapshot = db.query("SELECT * FROM snapshots WHERE id = ?").get(snapshotId) as any;
545
+ const snapshot = await dbGet<any>("SELECT * FROM snapshots WHERE id = ?", [snapshotId]);
545
546
 
546
547
  if (!snapshot) {
547
548
  throw new CodexaError("Snapshot #" + snapshotId + " nao encontrado.");
@@ -560,9 +561,10 @@ export function recover(options: {
560
561
  }
561
562
 
562
563
  // Mostrar ultimo snapshot
563
- const last = db
564
- .query("SELECT * FROM snapshots ORDER BY created_at DESC LIMIT 1")
565
- .get() as any;
564
+ const last = await dbGet<any>(
565
+ "SELECT * FROM snapshots ORDER BY created_at DESC LIMIT 1",
566
+ []
567
+ );
566
568
 
567
569
  if (!last) {
568
570
  console.log("\nNenhum snapshot disponivel.\n");
@@ -7,7 +7,6 @@ export interface ContextSection {
7
7
  }
8
8
 
9
9
  export interface ContextData {
10
- db: any;
11
10
  task: any;
12
11
  spec: any;
13
12
  context: any;