@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,6 +1,7 @@
1
- import { describe, it, expect, beforeEach } from "bun:test";
1
+ import { describe, it, expect, beforeEach, afterEach } from "bun:test";
2
2
  import { jaccardSimilarity, compactKnowledge } from "./knowledge";
3
- import { getDb } from "../db/connection";
3
+ import { createClient } from "@libsql/client";
4
+ import { setClient, resetClient, dbGet, dbAll, dbRun } from "../db/connection";
4
5
  import { initSchema } from "../db/schema";
5
6
  import { cleanDb } from "../db/test-helpers";
6
7
 
@@ -34,9 +35,7 @@ describe("jaccardSimilarity", () => {
34
35
  });
35
36
 
36
37
  it("ignores short words (<=2 chars)", () => {
37
- // "a" and "is" are filtered out, only "cat" and "dog" matter
38
38
  const sim = jaccardSimilarity("a cat is here", "a dog is here");
39
- // "cat" vs "dog" + "here" in common
40
39
  expect(sim).toBeGreaterThan(0);
41
40
  expect(sim).toBeLessThan(1);
42
41
  });
@@ -48,108 +47,104 @@ describe("jaccardSimilarity", () => {
48
47
  });
49
48
 
50
49
  describe("compactKnowledge", () => {
51
- beforeEach(() => {
52
- initSchema();
53
- cleanDb();
50
+ beforeEach(async () => {
51
+ const client = createClient({ url: ":memory:" });
52
+ setClient(client);
53
+ await initSchema();
54
+ await cleanDb();
54
55
  });
55
56
 
56
- function createSpec(id: string, phase: string) {
57
- const db = getDb();
57
+ afterEach(() => {
58
+ resetClient();
59
+ });
60
+
61
+ async function createSpec(id: string, phase: string) {
58
62
  const now = new Date().toISOString();
59
- db.run(
63
+ await dbRun(
60
64
  "INSERT INTO specs (id, name, phase, created_at, updated_at) VALUES (?, ?, ?, ?, ?)",
61
65
  [id, `Feature ${id}`, phase, now, now]
62
66
  );
63
67
  }
64
68
 
65
- function addKnowledgeEntry(specId: string, content: string, category: string, severity: string, createdAt?: string) {
66
- const db = getDb();
69
+ async function addKnowledgeEntry(specId: string, content: string, category: string, severity: string, createdAt?: string) {
67
70
  const now = createdAt || new Date().toISOString();
68
- db.run(
71
+ await dbRun(
69
72
  `INSERT INTO knowledge (spec_id, task_origin, category, content, severity, broadcast_to, created_at)
70
73
  VALUES (?, 0, ?, ?, ?, 'all', ?)`,
71
74
  [specId, category, content, severity, now]
72
75
  );
73
76
  }
74
77
 
75
- it("merges similar entries in same category and spec", () => {
76
- createSpec("spec-a", "implementing");
77
- addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for the login flow", "discovery", "info");
78
- addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for login flow", "discovery", "info");
78
+ it("merges similar entries in same category and spec", async () => {
79
+ await createSpec("spec-a", "implementing");
80
+ await addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for the login flow", "discovery", "info");
81
+ await addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for login flow", "discovery", "info");
79
82
 
80
- // Dry run first
81
- compactKnowledge({ dryRun: true, json: true });
83
+ await compactKnowledge({ dryRun: true, json: true });
82
84
 
83
- // Actual compact
84
- compactKnowledge({ json: true });
85
+ await compactKnowledge({ json: true });
85
86
 
86
- const db = getDb();
87
- const archived = db.query("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'").get() as any;
87
+ const archived = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'");
88
88
  expect(archived.c).toBe(1);
89
89
  });
90
90
 
91
- it("keeps higher severity entry when merging", () => {
92
- createSpec("spec-a", "implementing");
93
- addKnowledgeEntry("spec-a", "Database connection timeout causing failures in production", "blocker", "critical");
94
- addKnowledgeEntry("spec-a", "Database connection timeout causing failures in production system", "blocker", "info");
91
+ it("keeps higher severity entry when merging", async () => {
92
+ await createSpec("spec-a", "implementing");
93
+ await addKnowledgeEntry("spec-a", "Database connection timeout causing failures in production", "blocker", "critical");
94
+ await addKnowledgeEntry("spec-a", "Database connection timeout causing failures in production system", "blocker", "info");
95
95
 
96
- compactKnowledge({ json: true });
96
+ await compactKnowledge({ json: true });
97
97
 
98
- const db = getDb();
99
- const remaining = db.query("SELECT * FROM knowledge WHERE severity != 'archived'").all() as any[];
98
+ const remaining = await dbAll<any>("SELECT * FROM knowledge WHERE severity != 'archived'");
100
99
  expect(remaining.length).toBe(1);
101
100
  expect(remaining[0].severity).toBe("critical");
102
101
  });
103
102
 
104
- it("archives old info entries (>7 days)", () => {
105
- createSpec("spec-a", "implementing");
103
+ it("archives old info entries (>7 days)", async () => {
104
+ await createSpec("spec-a", "implementing");
106
105
  const oldDate = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString();
107
- addKnowledgeEntry("spec-a", "Some old discovery that is not referenced anywhere in the graph", "discovery", "info", oldDate);
108
- addKnowledgeEntry("spec-a", "A recent discovery that should not be archived by this compaction", "discovery", "info");
106
+ await addKnowledgeEntry("spec-a", "Some old discovery that is not referenced anywhere in the graph", "discovery", "info", oldDate);
107
+ await addKnowledgeEntry("spec-a", "A recent discovery that should not be archived by this compaction", "discovery", "info");
109
108
 
110
- compactKnowledge({ json: true });
109
+ await compactKnowledge({ json: true });
111
110
 
112
- const db = getDb();
113
- const archived = db.query("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'").get() as any;
111
+ const archived = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'");
114
112
  expect(archived.c).toBe(1);
115
113
  });
116
114
 
117
- it("archives entries from completed specs", () => {
118
- createSpec("spec-done", "completed");
119
- addKnowledgeEntry("spec-done", "Something learned during completed feature implementation", "discovery", "info");
120
- addKnowledgeEntry("spec-done", "A critical blocker that was found during the implementation phase", "blocker", "critical");
115
+ it("archives entries from completed specs", async () => {
116
+ await createSpec("spec-done", "completed");
117
+ await addKnowledgeEntry("spec-done", "Something learned during completed feature implementation", "discovery", "info");
118
+ await addKnowledgeEntry("spec-done", "A critical blocker that was found during the implementation phase", "blocker", "critical");
121
119
 
122
- compactKnowledge({ json: true });
120
+ await compactKnowledge({ json: true });
123
121
 
124
- const db = getDb();
125
- const archived = db.query("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'").get() as any;
122
+ const archived = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'");
126
123
  expect(archived.c).toBe(2);
127
124
  });
128
125
 
129
- it("dry-run mode does not modify DB", () => {
130
- createSpec("spec-done", "completed");
131
- addKnowledgeEntry("spec-done", "Something that would be archived in a real compaction run", "discovery", "info");
126
+ it("dry-run mode does not modify DB", async () => {
127
+ await createSpec("spec-done", "completed");
128
+ await addKnowledgeEntry("spec-done", "Something that would be archived in a real compaction run", "discovery", "info");
132
129
 
133
- compactKnowledge({ dryRun: true, json: true });
130
+ await compactKnowledge({ dryRun: true, json: true });
134
131
 
135
- const db = getDb();
136
- const archived = db.query("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'").get() as any;
132
+ const archived = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived'");
137
133
  expect(archived.c).toBe(0);
138
134
  });
139
135
 
140
- it("respects --spec filter", () => {
141
- createSpec("spec-a", "implementing");
142
- createSpec("spec-b", "implementing");
143
- addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for the system", "discovery", "info");
144
- addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for the system flow", "discovery", "info");
145
- addKnowledgeEntry("spec-b", "Implemented user authentication with JWT tokens for the login", "discovery", "info");
146
- addKnowledgeEntry("spec-b", "Implemented user authentication with JWT tokens for the login flow", "discovery", "info");
136
+ it("respects --spec filter", async () => {
137
+ await createSpec("spec-a", "implementing");
138
+ await createSpec("spec-b", "implementing");
139
+ await addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for the system", "discovery", "info");
140
+ await addKnowledgeEntry("spec-a", "Implemented user authentication with JWT tokens for the system flow", "discovery", "info");
141
+ await addKnowledgeEntry("spec-b", "Implemented user authentication with JWT tokens for the login", "discovery", "info");
142
+ await addKnowledgeEntry("spec-b", "Implemented user authentication with JWT tokens for the login flow", "discovery", "info");
147
143
 
148
- compactKnowledge({ specId: "spec-a", json: true });
144
+ await compactKnowledge({ specId: "spec-a", json: true });
149
145
 
150
- const db = getDb();
151
- const archivedA = db.query("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived' AND spec_id = 'spec-a'").get() as any;
152
- const archivedB = db.query("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived' AND spec_id = 'spec-b'").get() as any;
146
+ const archivedA = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived' AND spec_id = 'spec-a'");
147
+ const archivedB = await dbGet<any>("SELECT COUNT(*) as c FROM knowledge WHERE severity = 'archived' AND spec_id = 'spec-b'");
153
148
  expect(archivedA.c).toBe(1);
154
149
  expect(archivedB.c).toBe(0);
155
150
  });