@codexa/cli 9.0.31 → 9.0.33

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,5 +1,4 @@
1
- import { getDb } from "../db/connection";
2
- import { initSchema } from "../db/schema";
1
+ import { dbGet, dbAll } from "../db/connection";
3
2
  import { CodexaError } from "../errors";
4
3
 
5
4
  export interface ResolvedSpec {
@@ -18,15 +17,14 @@ export interface ResolvedSpec {
18
17
  * - Se nao fornecido: busca o mais recente ativo (ORDER BY created_at DESC LIMIT 1)
19
18
  * - Se requiredPhases: valida que spec.phase esta na lista
20
19
  */
21
- export function resolveSpec(specId?: string, requiredPhases?: string[]): ResolvedSpec {
22
- const db = getDb();
23
-
20
+ export async function resolveSpec(specId?: string, requiredPhases?: string[]): Promise<ResolvedSpec> {
24
21
  let spec: any;
25
22
 
26
23
  if (specId) {
27
- spec = db
28
- .query("SELECT * FROM specs WHERE id = ?")
29
- .get(specId);
24
+ spec = await dbGet<any>(
25
+ "SELECT * FROM specs WHERE id = ?",
26
+ [specId]
27
+ );
30
28
 
31
29
  if (!spec) {
32
30
  throw new CodexaError(`Spec '${specId}' nao encontrado.`);
@@ -36,9 +34,10 @@ export function resolveSpec(specId?: string, requiredPhases?: string[]): Resolve
36
34
  throw new CodexaError(`Spec '${specId}' ja esta ${spec.phase}.`);
37
35
  }
38
36
  } else {
39
- spec = db
40
- .query("SELECT * FROM specs WHERE phase NOT IN ('completed', 'cancelled') ORDER BY created_at DESC LIMIT 1")
41
- .get();
37
+ spec = await dbGet<any>(
38
+ "SELECT * FROM specs WHERE phase NOT IN ('completed', 'cancelled') ORDER BY created_at DESC LIMIT 1",
39
+ []
40
+ );
42
41
 
43
42
  if (!spec) {
44
43
  throw new CodexaError("Nenhuma feature ativa.");
@@ -58,19 +57,18 @@ export function resolveSpec(specId?: string, requiredPhases?: string[]): Resolve
58
57
  * Versao silenciosa de resolveSpec que retorna null em vez de process.exit(1).
59
58
  * Util para comandos que tem tratamento especial (ex: json output, throw customizado).
60
59
  */
61
- export function resolveSpecOrNull(specId?: string, requiredPhases?: string[]): ResolvedSpec | null {
62
- const db = getDb();
63
-
60
+ export async function resolveSpecOrNull(specId?: string, requiredPhases?: string[]): Promise<ResolvedSpec | null> {
64
61
  let spec: any;
65
62
 
66
63
  if (specId) {
67
- spec = db.query("SELECT * FROM specs WHERE id = ?").get(specId);
64
+ spec = await dbGet<any>("SELECT * FROM specs WHERE id = ?", [specId]);
68
65
  if (!spec) return null;
69
66
  if (spec.phase === "completed" || spec.phase === "cancelled") return null;
70
67
  } else {
71
- spec = db
72
- .query("SELECT * FROM specs WHERE phase NOT IN ('completed', 'cancelled') ORDER BY created_at DESC LIMIT 1")
73
- .get();
68
+ spec = await dbGet<any>(
69
+ "SELECT * FROM specs WHERE phase NOT IN ('completed', 'cancelled') ORDER BY created_at DESC LIMIT 1",
70
+ []
71
+ );
74
72
  if (!spec) return null;
75
73
  }
76
74
 
@@ -82,9 +80,9 @@ export function resolveSpecOrNull(specId?: string, requiredPhases?: string[]): R
82
80
  /**
83
81
  * Retorna todos os specs ativos (nao completed/cancelled).
84
82
  */
85
- export function getAllActiveSpecs(): ResolvedSpec[] {
86
- const db = getDb();
87
- return db
88
- .query("SELECT * FROM specs WHERE phase NOT IN ('completed', 'cancelled') ORDER BY created_at DESC")
89
- .all() as ResolvedSpec[];
83
+ export async function getAllActiveSpecs(): Promise<ResolvedSpec[]> {
84
+ return await dbAll<ResolvedSpec>(
85
+ "SELECT * FROM specs WHERE phase NOT IN ('completed', 'cancelled') ORDER BY created_at DESC",
86
+ []
87
+ );
90
88
  }
@@ -1,11 +1,10 @@
1
- import { getDb } from "../db/connection";
1
+ import { dbGet, dbAll, dbRun } from "../db/connection";
2
2
  import { initSchema } from "../db/schema";
3
3
  import { generateStandardsMarkdown } from "./discover";
4
4
  import { CodexaError, ValidationError } from "../errors";
5
5
 
6
- export function standardsList(options: { category?: string; scope?: string; json?: boolean }): void {
7
- initSchema();
8
- const db = getDb();
6
+ export async function standardsList(options: { category?: string; scope?: string; json?: boolean }): Promise<void> {
7
+ await initSchema();
9
8
 
10
9
  let query = "SELECT * FROM standards WHERE 1=1";
11
10
  const params: any[] = [];
@@ -22,7 +21,7 @@ export function standardsList(options: { category?: string; scope?: string; json
22
21
 
23
22
  query += " ORDER BY category, scope";
24
23
 
25
- const standards = db.query(query).all(...params) as any[];
24
+ const standards = await dbAll<any>(query, params);
26
25
 
27
26
  if (options.json) {
28
27
  console.log(JSON.stringify({ standards }, null, 2));
@@ -57,7 +56,7 @@ export function standardsList(options: { category?: string; scope?: string; json
57
56
  console.log("Legenda: [REQ] = Obrigatorio [REC] = Recomendado\n");
58
57
  }
59
58
 
60
- export function standardsAdd(options: {
59
+ export async function standardsAdd(options: {
61
60
  category: string;
62
61
  scope: string;
63
62
  rule: string;
@@ -66,9 +65,8 @@ export function standardsAdd(options: {
66
65
  enforcement?: string;
67
66
  semanticQuery?: string;
68
67
  expect?: string;
69
- }): void {
70
- initSchema();
71
- const db = getDb();
68
+ }): Promise<void> {
69
+ await initSchema();
72
70
 
73
71
  const validCategories = ["stack", "structure", "naming", "code", "library", "practice"];
74
72
  const validScopes = ["all", "database", "backend", "frontend", "testing"];
@@ -104,13 +102,12 @@ export function standardsAdd(options: {
104
102
  antiExamples = JSON.stringify(options.antiExamples.split(",").map((s) => s.trim()));
105
103
  }
106
104
 
107
- const result = db.run(
105
+ const result = await dbRun(
108
106
  `INSERT INTO standards (category, scope, rule, examples, anti_examples, enforcement, semantic_query, expect, source, created_at)
109
107
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'user', datetime('now'))`,
110
108
  [options.category, options.scope, options.rule, examples, antiExamples, enforcement, options.semanticQuery || null, expectVal]
111
109
  );
112
110
 
113
- // Regenerar markdown
114
111
  generateStandardsMarkdown();
115
112
 
116
113
  console.log(`\nStandard #${result.lastInsertRowid} adicionado:`);
@@ -124,7 +121,7 @@ export function standardsAdd(options: {
124
121
  console.log("\nArquivo atualizado: .codexa/standards.md\n");
125
122
  }
126
123
 
127
- export function standardsEdit(
124
+ export async function standardsEdit(
128
125
  id: string,
129
126
  options: {
130
127
  rule?: string;
@@ -134,12 +131,11 @@ export function standardsEdit(
134
131
  semanticQuery?: string;
135
132
  expect?: string;
136
133
  }
137
- ): void {
138
- initSchema();
139
- const db = getDb();
134
+ ): Promise<void> {
135
+ await initSchema();
140
136
 
141
137
  const standardId = parseInt(id);
142
- const existing = db.query("SELECT * FROM standards WHERE id = ?").get(standardId) as any;
138
+ const existing = await dbGet<any>("SELECT * FROM standards WHERE id = ?", [standardId]);
143
139
 
144
140
  if (!existing) {
145
141
  throw new CodexaError(`Standard #${id} nao encontrado.`);
@@ -187,37 +183,34 @@ export function standardsEdit(
187
183
  }
188
184
 
189
185
  params.push(standardId);
190
- db.run(`UPDATE standards SET ${updates.join(", ")} WHERE id = ?`, params);
186
+ await dbRun(`UPDATE standards SET ${updates.join(", ")} WHERE id = ?`, params);
191
187
 
192
- // Regenerar markdown
193
188
  generateStandardsMarkdown();
194
189
 
195
190
  console.log(`\nStandard #${id} atualizado.`);
196
191
  console.log("Arquivo atualizado: .codexa/standards.md\n");
197
192
  }
198
193
 
199
- export function standardsRemove(id: string): void {
200
- initSchema();
201
- const db = getDb();
194
+ export async function standardsRemove(id: string): Promise<void> {
195
+ await initSchema();
202
196
 
203
197
  const standardId = parseInt(id);
204
- const existing = db.query("SELECT * FROM standards WHERE id = ?").get(standardId) as any;
198
+ const existing = await dbGet<any>("SELECT * FROM standards WHERE id = ?", [standardId]);
205
199
 
206
200
  if (!existing) {
207
201
  throw new CodexaError(`Standard #${id} nao encontrado.`);
208
202
  }
209
203
 
210
- db.run("DELETE FROM standards WHERE id = ?", [standardId]);
204
+ await dbRun("DELETE FROM standards WHERE id = ?", [standardId]);
211
205
 
212
- // Regenerar markdown
213
206
  generateStandardsMarkdown();
214
207
 
215
208
  console.log(`\nStandard #${id} removido: ${existing.rule}`);
216
209
  console.log("Arquivo atualizado: .codexa/standards.md\n");
217
210
  }
218
211
 
219
- export function standardsExport(): void {
220
- initSchema();
212
+ export async function standardsExport(): Promise<void> {
213
+ await initSchema();
221
214
  generateStandardsMarkdown();
222
215
  console.log("\nArquivo gerado: .codexa/standards.md\n");
223
- }
216
+ }
package/commands/sync.ts CHANGED
@@ -4,14 +4,12 @@ import { join } from "path";
4
4
  import { CodexaError } from "../errors";
5
5
  import { getGrepaiWorkspace } from "./patterns";
6
6
 
7
- // Agents que sao referencias (nao spawnables como subagent_type)
8
7
  const REFERENCE_FILES = new Set([
9
8
  "common-directives.md",
10
9
  "subagent-return-protocol.md",
11
10
  ]);
12
11
 
13
12
  function findPluginAgentsDir(): string | null {
14
- // 1. Dev repo: git root + plugins/codexa-workflow/agents/
15
13
  try {
16
14
  const gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
17
15
  const pluginDir = join(gitRoot, "plugins", "codexa-workflow", "agents");
@@ -20,17 +18,14 @@ function findPluginAgentsDir(): string | null {
20
18
  // Not in git repo
21
19
  }
22
20
 
23
- // 2. Global install: resolve from @codexa/cli package location
24
21
  try {
25
22
  const cliPath = execSync("bun pm ls -g 2>/dev/null || npm list -g @codexa/cli --parseable 2>/dev/null", {
26
23
  encoding: "utf-8",
27
24
  }).trim();
28
25
  if (cliPath) {
29
- // Navigate from cli package to sibling plugin
30
26
  const lines = cliPath.split("\n").filter(l => l.includes("codexa"));
31
27
  for (const line of lines) {
32
28
  const trimmed = line.trim();
33
- // Try parent paths to find the monorepo root
34
29
  const parts = trimmed.split(/[/\\]/);
35
30
  for (let i = parts.length - 1; i >= 0; i--) {
36
31
  const candidate = join(parts.slice(0, i + 1).join("/"), "plugins", "codexa-workflow", "agents");
@@ -45,7 +40,7 @@ function findPluginAgentsDir(): string | null {
45
40
  return null;
46
41
  }
47
42
 
48
- export function syncAgents(options: { force?: boolean } = {}): void {
43
+ export async function syncAgents(options: { force?: boolean } = {}): Promise<void> {
49
44
  const pluginDir = findPluginAgentsDir();
50
45
 
51
46
  if (!pluginDir) {
@@ -73,9 +68,8 @@ export function syncAgents(options: { force?: boolean } = {}): void {
73
68
 
74
69
  copyFileSync(src, dst);
75
70
 
76
- // Inject workspace flag in deep-explore if configured
77
71
  if (file === "deep-explore.md") {
78
- const workspace = getGrepaiWorkspace();
72
+ const workspace = await getGrepaiWorkspace();
79
73
  const wsFlag = workspace ? ` --workspace ${workspace}` : "";
80
74
  let agentContent = readFileSync(dst, "utf-8");
81
75
  agentContent = agentContent.replace(/\{\{GREPAI_WS_FLAG\}\}/g, wsFlag);