@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/commands/architect.ts +52 -87
- package/commands/check.ts +22 -23
- package/commands/clear.ts +42 -48
- package/commands/decide.ts +46 -44
- package/commands/discover.ts +81 -94
- package/commands/integration.test.ts +262 -313
- package/commands/knowledge.test.ts +56 -61
- package/commands/knowledge.ts +126 -131
- package/commands/patterns.ts +28 -43
- package/commands/plan.ts +50 -48
- package/commands/product.ts +57 -59
- package/commands/research.ts +64 -77
- package/commands/review.ts +100 -86
- package/commands/simplify.ts +24 -35
- package/commands/spec-resolver.test.ts +52 -48
- package/commands/spec-resolver.ts +21 -23
- package/commands/standards.ts +20 -27
- package/commands/sync.ts +2 -8
- package/commands/task.ts +106 -97
- package/commands/team.test.ts +22 -83
- package/commands/team.ts +62 -50
- package/commands/utils.ts +83 -81
- package/context/assembly.ts +0 -1
- package/context/generator.ts +66 -79
- package/context/sections.ts +8 -14
- package/db/connection.ts +195 -19
- package/db/schema.test.ts +288 -299
- package/db/schema.ts +297 -394
- package/db/test-helpers.ts +18 -29
- package/gates/standards-validator.test.ts +83 -86
- package/gates/standards-validator.ts +9 -41
- package/gates/validator.test.ts +13 -22
- package/gates/validator.ts +69 -107
- package/package.json +2 -1
- package/protocol/process-return.ts +41 -57
- package/simplify/prompt-builder.test.ts +44 -42
- package/simplify/prompt-builder.ts +12 -14
- package/workflow.ts +159 -174
|
@@ -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 {
|
|
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
|
-
|
|
53
|
-
|
|
50
|
+
beforeEach(async () => {
|
|
51
|
+
const client = createClient({ url: ":memory:" });
|
|
52
|
+
setClient(client);
|
|
53
|
+
await initSchema();
|
|
54
|
+
await cleanDb();
|
|
54
55
|
});
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
afterEach(() => {
|
|
58
|
+
resetClient();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
async function createSpec(id: string, phase: string) {
|
|
58
62
|
const now = new Date().toISOString();
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
81
|
-
compactKnowledge({ dryRun: true, json: true });
|
|
83
|
+
await compactKnowledge({ dryRun: true, json: true });
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
compactKnowledge({ json: true });
|
|
85
|
+
await compactKnowledge({ json: true });
|
|
85
86
|
|
|
86
|
-
const
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
151
|
-
const
|
|
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
|
});
|