ralph-hero-knowledge-index 0.1.0

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 (47) hide show
  1. package/.claude-plugin/plugin.json +21 -0
  2. package/.mcp.json +12 -0
  3. package/dist/db.d.ts +30 -0
  4. package/dist/db.js +73 -0
  5. package/dist/db.js.map +1 -0
  6. package/dist/embedder.d.ts +4 -0
  7. package/dist/embedder.js +24 -0
  8. package/dist/embedder.js.map +1 -0
  9. package/dist/hybrid-search.d.ts +13 -0
  10. package/dist/hybrid-search.js +85 -0
  11. package/dist/hybrid-search.js.map +1 -0
  12. package/dist/index.d.ts +14 -0
  13. package/dist/index.js +64 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/parser.d.ts +18 -0
  16. package/dist/parser.js +39 -0
  17. package/dist/parser.js.map +1 -0
  18. package/dist/reindex.d.ts +1 -0
  19. package/dist/reindex.js +77 -0
  20. package/dist/reindex.js.map +1 -0
  21. package/dist/search.d.ts +23 -0
  22. package/dist/search.js +63 -0
  23. package/dist/search.js.map +1 -0
  24. package/dist/traverse.d.ts +22 -0
  25. package/dist/traverse.js +91 -0
  26. package/dist/traverse.js.map +1 -0
  27. package/dist/vector-search.d.ts +15 -0
  28. package/dist/vector-search.js +52 -0
  29. package/dist/vector-search.js.map +1 -0
  30. package/package.json +27 -0
  31. package/src/__tests__/db.test.ts +51 -0
  32. package/src/__tests__/hybrid-search.test.ts +112 -0
  33. package/src/__tests__/index.test.ts +8 -0
  34. package/src/__tests__/parser.test.ts +100 -0
  35. package/src/__tests__/search.test.ts +92 -0
  36. package/src/__tests__/traverse.test.ts +115 -0
  37. package/src/__tests__/vector-search.test.ts +66 -0
  38. package/src/db.ts +103 -0
  39. package/src/embedder.ts +37 -0
  40. package/src/hybrid-search.ts +102 -0
  41. package/src/index.ts +76 -0
  42. package/src/parser.ts +63 -0
  43. package/src/reindex.ts +89 -0
  44. package/src/search.ts +92 -0
  45. package/src/traverse.ts +130 -0
  46. package/src/vector-search.ts +64 -0
  47. package/tsconfig.json +17 -0
@@ -0,0 +1,130 @@
1
+ import type { KnowledgeDB } from "./db.js";
2
+
3
+ export interface TraverseOptions {
4
+ type?: string;
5
+ depth?: number;
6
+ }
7
+
8
+ export interface TraverseResult {
9
+ sourceId: string;
10
+ targetId: string;
11
+ type: string;
12
+ depth: number;
13
+ doc: { title: string; status: string | null; date: string | null } | null;
14
+ }
15
+
16
+ export class Traverser {
17
+ private readonly db: KnowledgeDB;
18
+
19
+ constructor(db: KnowledgeDB) {
20
+ this.db = db;
21
+ }
22
+
23
+ traverse(fromId: string, options: TraverseOptions = {}): TraverseResult[] {
24
+ const { type, depth = 3 } = options;
25
+ const typeFilter = type ? "AND r.type = @type" : "";
26
+
27
+ const sql = `
28
+ WITH RECURSIVE chain AS (
29
+ SELECT r.source_id, r.target_id, r.type, 1 AS depth
30
+ FROM relationships r
31
+ WHERE r.source_id = @fromId ${typeFilter}
32
+
33
+ UNION ALL
34
+
35
+ SELECT r.source_id, r.target_id, r.type, c.depth + 1
36
+ FROM relationships r
37
+ JOIN chain c ON r.source_id = c.target_id
38
+ WHERE c.depth < @depth ${typeFilter}
39
+ )
40
+ SELECT
41
+ chain.source_id AS sourceId,
42
+ chain.target_id AS targetId,
43
+ chain.type,
44
+ chain.depth,
45
+ d.title AS docTitle,
46
+ d.status AS docStatus,
47
+ d.date AS docDate
48
+ FROM chain
49
+ LEFT JOIN documents d ON d.id = chain.target_id
50
+ ORDER BY chain.depth, chain.target_id
51
+ `;
52
+
53
+ const params: Record<string, unknown> = { fromId, depth };
54
+ if (type) params.type = type;
55
+
56
+ const rows = this.db.db.prepare(sql).all(params) as Array<{
57
+ sourceId: string;
58
+ targetId: string;
59
+ type: string;
60
+ depth: number;
61
+ docTitle: string | null;
62
+ docStatus: string | null;
63
+ docDate: string | null;
64
+ }>;
65
+
66
+ return rows.map((r) => ({
67
+ sourceId: r.sourceId,
68
+ targetId: r.targetId,
69
+ type: r.type,
70
+ depth: r.depth,
71
+ doc: r.docTitle != null
72
+ ? { title: r.docTitle, status: r.docStatus, date: r.docDate }
73
+ : null,
74
+ }));
75
+ }
76
+
77
+ traverseIncoming(toId: string, options: TraverseOptions = {}): TraverseResult[] {
78
+ const { type, depth = 3 } = options;
79
+ const typeFilter = type ? "AND r.type = @type" : "";
80
+
81
+ const sql = `
82
+ WITH RECURSIVE chain AS (
83
+ SELECT r.source_id, r.target_id, r.type, 1 AS depth
84
+ FROM relationships r
85
+ WHERE r.target_id = @toId ${typeFilter}
86
+
87
+ UNION ALL
88
+
89
+ SELECT r.source_id, r.target_id, r.type, c.depth + 1
90
+ FROM relationships r
91
+ JOIN chain c ON r.target_id = c.source_id
92
+ WHERE c.depth < @depth ${typeFilter}
93
+ )
94
+ SELECT
95
+ chain.source_id AS sourceId,
96
+ chain.target_id AS targetId,
97
+ chain.type,
98
+ chain.depth,
99
+ d.title AS docTitle,
100
+ d.status AS docStatus,
101
+ d.date AS docDate
102
+ FROM chain
103
+ LEFT JOIN documents d ON d.id = chain.source_id
104
+ ORDER BY chain.depth, chain.target_id
105
+ `;
106
+
107
+ const params: Record<string, unknown> = { toId, depth };
108
+ if (type) params.type = type;
109
+
110
+ const rows = this.db.db.prepare(sql).all(params) as Array<{
111
+ sourceId: string;
112
+ targetId: string;
113
+ type: string;
114
+ depth: number;
115
+ docTitle: string | null;
116
+ docStatus: string | null;
117
+ docDate: string | null;
118
+ }>;
119
+
120
+ return rows.map((r) => ({
121
+ sourceId: r.sourceId,
122
+ targetId: r.targetId,
123
+ type: r.type,
124
+ depth: r.depth,
125
+ doc: r.docTitle != null
126
+ ? { title: r.docTitle, status: r.docStatus, date: r.docDate }
127
+ : null,
128
+ }));
129
+ }
130
+ }
@@ -0,0 +1,64 @@
1
+ import * as sqliteVec from "sqlite-vec";
2
+ import type { KnowledgeDB } from "./db.js";
3
+
4
+ export interface VectorResult {
5
+ id: string;
6
+ distance: number;
7
+ }
8
+
9
+ function float32ToBuffer(arr: Float32Array): Buffer {
10
+ return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);
11
+ }
12
+
13
+ export class VectorSearch {
14
+ private vecLoaded = false;
15
+
16
+ constructor(private knowledgeDb: KnowledgeDB) {}
17
+
18
+ private ensureVecLoaded(): void {
19
+ if (!this.vecLoaded) {
20
+ sqliteVec.load(this.knowledgeDb.db);
21
+ this.vecLoaded = true;
22
+ }
23
+ }
24
+
25
+ createIndex(): void {
26
+ this.ensureVecLoaded();
27
+ this.knowledgeDb.db.exec(`
28
+ CREATE VIRTUAL TABLE IF NOT EXISTS documents_vec USING vec0(
29
+ id TEXT PRIMARY KEY,
30
+ embedding float[384] distance_metric=cosine
31
+ )
32
+ `);
33
+ }
34
+
35
+ dropIndex(): void {
36
+ this.knowledgeDb.db.exec("DROP TABLE IF EXISTS documents_vec");
37
+ }
38
+
39
+ upsertEmbedding(id: string, embedding: Float32Array): void {
40
+ this.ensureVecLoaded();
41
+ const buf = float32ToBuffer(embedding);
42
+ this.knowledgeDb.db
43
+ .prepare("DELETE FROM documents_vec WHERE id = ?")
44
+ .run(id);
45
+ this.knowledgeDb.db
46
+ .prepare("INSERT INTO documents_vec (id, embedding) VALUES (?, ?)")
47
+ .run(id, buf);
48
+ }
49
+
50
+ search(queryEmbedding: Float32Array, limit: number = 10): VectorResult[] {
51
+ this.ensureVecLoaded();
52
+ const buf = float32ToBuffer(queryEmbedding);
53
+ return this.knowledgeDb.db
54
+ .prepare(
55
+ `
56
+ SELECT id, distance
57
+ FROM documents_vec
58
+ WHERE embedding MATCH ? AND k = ?
59
+ ORDER BY distance
60
+ `
61
+ )
62
+ .all(buf, limit) as VectorResult[];
63
+ }
64
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "sourceMap": true,
12
+ "declaration": true,
13
+ "skipLibCheck": true
14
+ },
15
+ "include": ["src"],
16
+ "exclude": ["node_modules", "dist", "src/__tests__"]
17
+ }