llm-kb 0.4.0 → 0.4.2

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.
Files changed (58) hide show
  1. package/README.md +183 -42
  2. package/bin/anthropic-5TIU2EED.js +5515 -0
  3. package/bin/azure-openai-responses-ZVUVMK3G.js +190 -0
  4. package/bin/chunk-2WV6TQRI.js +4792 -0
  5. package/bin/chunk-3YMNGUZZ.js +262 -0
  6. package/bin/chunk-5PYKQQLA.js +14295 -0
  7. package/bin/chunk-65KFH7OI.js +31 -0
  8. package/bin/chunk-DHOXVEIR.js +7261 -0
  9. package/bin/chunk-EAQYK3U2.js +41 -0
  10. package/bin/chunk-IFS3OKBN.js +428 -0
  11. package/bin/chunk-LDHOKBJA.js +86 -0
  12. package/bin/chunk-SLYBG6ZQ.js +32681 -0
  13. package/bin/chunk-UEODFF7H.js +17 -0
  14. package/bin/chunk-XCXTZJGO.js +174 -0
  15. package/bin/chunk-XFV534WU.js +7056 -0
  16. package/bin/cli.js +30 -4
  17. package/bin/dist-3YH7P2QF.js +1244 -0
  18. package/bin/google-JFC43EFJ.js +371 -0
  19. package/bin/google-gemini-cli-K4XNMYDI.js +712 -0
  20. package/bin/google-vertex-Y42F254G.js +414 -0
  21. package/bin/indexer-KSYRIVVN.js +10 -0
  22. package/bin/mistral-ZU2JS5XZ.js +38406 -0
  23. package/bin/multipart-parser-CO464TZY.js +371 -0
  24. package/bin/openai-codex-responses-NW2LELBH.js +712 -0
  25. package/bin/openai-completions-TW3VKTHO.js +662 -0
  26. package/bin/openai-responses-VGL522MK.js +198 -0
  27. package/bin/src-Y22OHE3S.js +1408 -0
  28. package/package.json +6 -1
  29. package/PHASE2_SPEC.md +0 -274
  30. package/PHASE3_SPEC.md +0 -245
  31. package/PHASE4_SPEC.md +0 -358
  32. package/SPEC.md +0 -275
  33. package/plan.md +0 -300
  34. package/src/auth.ts +0 -55
  35. package/src/cli.ts +0 -257
  36. package/src/config.ts +0 -61
  37. package/src/eval.ts +0 -548
  38. package/src/indexer.ts +0 -152
  39. package/src/md-stream.ts +0 -133
  40. package/src/pdf.ts +0 -119
  41. package/src/query.ts +0 -408
  42. package/src/resolve-kb.ts +0 -19
  43. package/src/scan.ts +0 -59
  44. package/src/session-store.ts +0 -22
  45. package/src/session-watcher.ts +0 -89
  46. package/src/trace-builder.ts +0 -168
  47. package/src/tui-display.ts +0 -281
  48. package/src/utils.ts +0 -17
  49. package/src/watcher.ts +0 -87
  50. package/src/wiki-updater.ts +0 -136
  51. package/test/auth.test.ts +0 -65
  52. package/test/config.test.ts +0 -96
  53. package/test/md-stream.test.ts +0 -98
  54. package/test/resolve-kb.test.ts +0 -33
  55. package/test/scan.test.ts +0 -65
  56. package/test/trace-builder.test.ts +0 -215
  57. package/tsconfig.json +0 -14
  58. package/vitest.config.ts +0 -8
@@ -1,215 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import { buildTrace, saveTrace, appendToQueryLog, KBTrace } from "../src/trace-builder.js";
3
- import { mkdtemp, rm, writeFile, readFile, mkdir } from "node:fs/promises";
4
- import { join } from "node:path";
5
- import { tmpdir } from "node:os";
6
- import { existsSync } from "node:fs";
7
-
8
- describe("trace-builder", () => {
9
- let tempDir: string;
10
- let sourcesDir: string;
11
-
12
- beforeEach(async () => {
13
- tempDir = await mkdtemp(join(tmpdir(), "llm-kb-test-"));
14
- sourcesDir = join(tempDir, ".llm-kb", "wiki", "sources");
15
- await mkdir(sourcesDir, { recursive: true });
16
- // Create some source files
17
- await writeFile(join(sourcesDir, "doc1.md"), "# Doc 1");
18
- await writeFile(join(sourcesDir, "doc2.md"), "# Doc 2");
19
- });
20
-
21
- afterEach(async () => {
22
- await rm(tempDir, { recursive: true, force: true });
23
- });
24
-
25
- function makeSessionJsonl(entries: {
26
- header?: any;
27
- modelChange?: any;
28
- sessionInfo?: any;
29
- messages?: any[];
30
- }): string {
31
- const lines: string[] = [];
32
- const header = entries.header ?? {
33
- type: "session", version: 3, id: "test-session-id",
34
- timestamp: "2026-04-06T10:00:00Z", cwd: tempDir,
35
- };
36
- lines.push(JSON.stringify(header));
37
-
38
- if (entries.modelChange) lines.push(JSON.stringify(entries.modelChange));
39
- if (entries.sessionInfo) lines.push(JSON.stringify(entries.sessionInfo));
40
- for (const msg of entries.messages ?? []) lines.push(JSON.stringify(msg));
41
-
42
- return lines.join("\n");
43
- }
44
-
45
- describe("buildTrace", () => {
46
- it("returns null for incomplete sessions (no stop message)", async () => {
47
- const jsonl = makeSessionJsonl({
48
- messages: [
49
- {
50
- type: "message", id: "m1", parentId: null, timestamp: "2026-04-06T10:00:01Z",
51
- message: { role: "user", content: [{ type: "text", text: "Hello" }], timestamp: 1 },
52
- },
53
- {
54
- type: "message", id: "m2", parentId: "m1", timestamp: "2026-04-06T10:00:02Z",
55
- message: { role: "assistant", content: [{ type: "text", text: "Hi" }], stopReason: "toolUse", timestamp: 2 },
56
- },
57
- ],
58
- });
59
- const file = join(tempDir, "session.jsonl");
60
- await writeFile(file, jsonl);
61
- expect(await buildTrace(file, sourcesDir)).toBeNull();
62
- });
63
-
64
- it("parses a complete query session", async () => {
65
- const jsonl = makeSessionJsonl({
66
- modelChange: { type: "model_change", id: "mc1", parentId: null, timestamp: "2026-04-06T10:00:00Z", provider: "anthropic", modelId: "claude-sonnet-4-6" },
67
- sessionInfo: { type: "session_info", id: "si1", parentId: "mc1", timestamp: "2026-04-06T10:00:00Z", name: "query: What is doc1?" },
68
- messages: [
69
- {
70
- type: "message", id: "m1", parentId: "si1", timestamp: "2026-04-06T10:00:01Z",
71
- message: { role: "user", content: [{ type: "text", text: "What is doc1?" }], timestamp: 1000 },
72
- },
73
- {
74
- type: "message", id: "m2", parentId: "m1", timestamp: "2026-04-06T10:00:05Z",
75
- message: {
76
- role: "assistant",
77
- content: [
78
- { type: "toolCall", id: "tc1", name: "read", arguments: { path: ".llm-kb/wiki/sources/doc1.md" } },
79
- { type: "text", text: "Doc 1 is about X." },
80
- ],
81
- model: "claude-sonnet-4-6", stopReason: "stop", timestamp: 5000,
82
- },
83
- },
84
- ],
85
- });
86
-
87
- const file = join(tempDir, "session.jsonl");
88
- await writeFile(file, jsonl);
89
- const trace = await buildTrace(file, sourcesDir);
90
-
91
- expect(trace).not.toBeNull();
92
- expect(trace!.mode).toBe("query");
93
- expect(trace!.question).toBe("What is doc1?");
94
- expect(trace!.answer).toBe("Doc 1 is about X.");
95
- expect(trace!.model).toBe("claude-sonnet-4-6");
96
- expect(trace!.filesRead).toContain(".llm-kb/wiki/sources/doc1.md");
97
- expect(trace!.filesAvailable).toContain("doc1.md");
98
- expect(trace!.filesSkipped).toContain("doc2.md");
99
- expect(trace!.durationMs).toBe(4000);
100
- });
101
-
102
- it("identifies index sessions by session name", async () => {
103
- const jsonl = makeSessionJsonl({
104
- sessionInfo: { type: "session_info", id: "si1", parentId: null, timestamp: "2026-04-06T10:00:00Z", name: "index: 2026-04-06" },
105
- messages: [
106
- {
107
- type: "message", id: "m1", parentId: "si1", timestamp: "2026-04-06T10:00:01Z",
108
- message: { role: "user", content: "Build the index", timestamp: 1 },
109
- },
110
- {
111
- type: "message", id: "m2", parentId: "m1", timestamp: "2026-04-06T10:00:05Z",
112
- message: { role: "assistant", content: [{ type: "text", text: "Done" }], stopReason: "stop", timestamp: 2 },
113
- },
114
- ],
115
- });
116
-
117
- const file = join(tempDir, "session.jsonl");
118
- await writeFile(file, jsonl);
119
- const trace = await buildTrace(file, sourcesDir);
120
- expect(trace!.mode).toBe("index");
121
- });
122
-
123
- it("returns null for files with fewer than 2 lines", async () => {
124
- const file = join(tempDir, "empty.jsonl");
125
- await writeFile(file, '{"type":"session"}\n');
126
- expect(await buildTrace(file, sourcesDir)).toBeNull();
127
- });
128
- });
129
-
130
- describe("saveTrace", () => {
131
- it("writes trace JSON to .llm-kb/traces/", async () => {
132
- const trace: KBTrace = {
133
- sessionId: "abc123",
134
- sessionFile: "session.jsonl",
135
- timestamp: "2026-04-06T10:00:00Z",
136
- mode: "query",
137
- question: "test?",
138
- answer: "yes",
139
- filesRead: [],
140
- filesAvailable: [],
141
- filesSkipped: [],
142
- model: "test-model",
143
- };
144
-
145
- await saveTrace(tempDir, trace);
146
- const path = join(tempDir, ".llm-kb", "traces", "abc123.json");
147
- expect(existsSync(path)).toBe(true);
148
-
149
- const saved = JSON.parse(await readFile(path, "utf-8"));
150
- expect(saved.sessionId).toBe("abc123");
151
- expect(saved.question).toBe("test?");
152
- });
153
- });
154
-
155
- describe("appendToQueryLog", () => {
156
- it("creates queries.md with header on first call", async () => {
157
- const trace: KBTrace = {
158
- sessionId: "abc",
159
- sessionFile: "s.jsonl",
160
- timestamp: "2026-04-06T10:00:00Z",
161
- mode: "query",
162
- question: "What is X?",
163
- answer: "X is Y.",
164
- filesRead: ["doc1.md"],
165
- filesAvailable: ["doc1.md"],
166
- filesSkipped: [],
167
- model: "test",
168
- };
169
-
170
- await appendToQueryLog(tempDir, trace);
171
- const logPath = join(tempDir, ".llm-kb", "wiki", "queries.md");
172
- expect(existsSync(logPath)).toBe(true);
173
-
174
- const content = await readFile(logPath, "utf-8");
175
- expect(content).toContain("# Query Log");
176
- expect(content).toContain("## What is X?");
177
- expect(content).toContain("X is Y.");
178
- });
179
-
180
- it("skips non-query traces", async () => {
181
- const trace: KBTrace = {
182
- sessionId: "abc",
183
- sessionFile: "s.jsonl",
184
- timestamp: "2026-04-06T10:00:00Z",
185
- mode: "index",
186
- filesRead: [],
187
- filesAvailable: [],
188
- filesSkipped: [],
189
- };
190
-
191
- await appendToQueryLog(tempDir, trace);
192
- const logPath = join(tempDir, ".llm-kb", "wiki", "queries.md");
193
- expect(existsSync(logPath)).toBe(false);
194
- });
195
-
196
- it("prepends new entries to existing log", async () => {
197
- const trace1: KBTrace = {
198
- sessionId: "a", sessionFile: "s.jsonl", timestamp: "2026-04-06T10:00:00Z",
199
- mode: "query", question: "First?", answer: "One", filesRead: [], filesAvailable: [], filesSkipped: [],
200
- };
201
- const trace2: KBTrace = {
202
- sessionId: "b", sessionFile: "s.jsonl", timestamp: "2026-04-06T11:00:00Z",
203
- mode: "query", question: "Second?", answer: "Two", filesRead: [], filesAvailable: [], filesSkipped: [],
204
- };
205
-
206
- await appendToQueryLog(tempDir, trace1);
207
- await appendToQueryLog(tempDir, trace2);
208
-
209
- const content = await readFile(join(tempDir, ".llm-kb", "wiki", "queries.md"), "utf-8");
210
- const firstIdx = content.indexOf("Second?");
211
- const secondIdx = content.indexOf("First?");
212
- expect(firstIdx).toBeLessThan(secondIdx); // newest first
213
- });
214
- });
215
- });
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ES2022",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "outDir": "dist",
9
- "rootDir": "src",
10
- "declaration": true,
11
- "sourceMap": true
12
- },
13
- "include": ["src"]
14
- }
package/vitest.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({
4
- test: {
5
- include: ["test/**/*.test.ts"],
6
- testTimeout: 10000,
7
- },
8
- });