ralph-hero-knowledge-index 0.1.21 → 0.1.24

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/.claude-plugin/plugin.json +1 -1
  2. package/.mcp.json +1 -1
  3. package/README.md +109 -0
  4. package/dist/config.d.ts +32 -0
  5. package/dist/config.js +75 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/db.d.ts +7 -0
  8. package/dist/db.js +17 -0
  9. package/dist/db.js.map +1 -1
  10. package/dist/embedder.d.ts +27 -0
  11. package/dist/embedder.js +43 -4
  12. package/dist/embedder.js.map +1 -1
  13. package/dist/file-scanner.d.ts +13 -1
  14. package/dist/file-scanner.js +30 -3
  15. package/dist/file-scanner.js.map +1 -1
  16. package/dist/hybrid-search.d.ts +12 -0
  17. package/dist/hybrid-search.js +74 -5
  18. package/dist/hybrid-search.js.map +1 -1
  19. package/dist/ignore.d.ts +29 -0
  20. package/dist/ignore.js +65 -0
  21. package/dist/ignore.js.map +1 -0
  22. package/dist/index.d.ts +9 -1
  23. package/dist/index.js +166 -6
  24. package/dist/index.js.map +1 -1
  25. package/dist/llm-client.d.ts +41 -0
  26. package/dist/llm-client.js +98 -0
  27. package/dist/llm-client.js.map +1 -0
  28. package/dist/reindex.d.ts +22 -3
  29. package/dist/reindex.js +85 -13
  30. package/dist/reindex.js.map +1 -1
  31. package/dist/search.d.ts +12 -0
  32. package/dist/search.js +15 -1
  33. package/dist/search.js.map +1 -1
  34. package/dist/vector-search.d.ts +10 -0
  35. package/dist/vector-search.js +15 -0
  36. package/dist/vector-search.js.map +1 -1
  37. package/package.json +2 -1
  38. package/src/__tests__/config.test.ts +173 -0
  39. package/src/__tests__/embedder.test.ts +103 -4
  40. package/src/__tests__/file-scanner.test.ts +88 -0
  41. package/src/__tests__/hybrid-search.test.ts +107 -0
  42. package/src/__tests__/ignore.test.ts +86 -0
  43. package/src/__tests__/index.test.ts +450 -0
  44. package/src/__tests__/llm-client.test.ts +349 -0
  45. package/src/__tests__/memory-stats.test.ts +204 -0
  46. package/src/__tests__/reindex.test.ts +187 -11
  47. package/src/__tests__/search.test.ts +37 -0
  48. package/src/config.ts +105 -0
  49. package/src/db.ts +17 -0
  50. package/src/embedder.ts +61 -4
  51. package/src/file-scanner.ts +28 -3
  52. package/src/hybrid-search.ts +88 -5
  53. package/src/ignore.ts +82 -0
  54. package/src/index.ts +202 -7
  55. package/src/llm-client.ts +136 -0
  56. package/src/reindex.ts +115 -14
  57. package/src/search.ts +27 -1
  58. package/src/vector-search.ts +16 -0
package/src/search.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import type { KnowledgeDB } from "./db.js";
2
2
 
3
+ export type MemoryTier = "doc" | "raw" | "reflection" | "any";
4
+
3
5
  export interface SearchOptions {
4
6
  type?: string;
5
7
  tags?: string[];
6
8
  includeSuperseded?: boolean;
7
9
  limit?: number;
10
+ memoryTier?: MemoryTier;
8
11
  }
9
12
 
10
13
  export interface SearchResult {
@@ -16,6 +19,13 @@ export interface SearchResult {
16
19
  date: string | null;
17
20
  score: number;
18
21
  snippet: string;
22
+ // Optional chunk-level metadata. Populated when chunk data is available
23
+ // for the best-scoring chunk of this document.
24
+ chunkIndex?: number;
25
+ charStart?: number;
26
+ charEnd?: number;
27
+ contextPrefix?: string;
28
+ bestChunkId?: string;
19
29
  }
20
30
 
21
31
  export class FtsSearch {
@@ -99,8 +109,19 @@ export class FtsSearch {
99
109
  return tokens.map(t => '"' + t.replace(/"/g, '""') + '"').join(" ");
100
110
  }
101
111
 
112
+ /**
113
+ * Returns true when the `documents.memory_tier` column exists (schema v3+).
114
+ * On v2 schemas this is false and the memoryTier filter is silently ignored.
115
+ */
116
+ private memoryTierColumnExists(): boolean {
117
+ const rows = this.db.db
118
+ .prepare("PRAGMA table_info(documents)")
119
+ .all() as Array<{ name: string }>;
120
+ return rows.some((r) => r.name === "memory_tier");
121
+ }
122
+
102
123
  search(query: string, options: SearchOptions = {}): SearchResult[] {
103
- const { type, tags, includeSuperseded = false, limit = 20 } = options;
124
+ const { type, tags, includeSuperseded = false, limit = 20, memoryTier } = options;
104
125
 
105
126
  const conditions: string[] = ["documents_fts MATCH @query"];
106
127
  const params: Record<string, unknown> = { query: this.escapeFts5Query(query), limit };
@@ -114,6 +135,11 @@ export class FtsSearch {
114
135
  params.type = type;
115
136
  }
116
137
 
138
+ if (memoryTier && memoryTier !== "any" && this.memoryTierColumnExists()) {
139
+ conditions.push("d.memory_tier = @memoryTier");
140
+ params.memoryTier = memoryTier;
141
+ }
142
+
117
143
  let joinClause = "";
118
144
  if (tags && tags.length > 0) {
119
145
  joinClause = "JOIN tags t ON t.doc_id = d.id";
@@ -54,6 +54,22 @@ export class VectorSearch {
54
54
  .run(id);
55
55
  }
56
56
 
57
+ /**
58
+ * Delete all chunk-level vec rows for a document. Chunk ids follow the
59
+ * pattern `${docId}#c${index}` so we match via a SQLite GLOB.
60
+ *
61
+ * This is used by reindex to drop stale chunks when a source markdown file
62
+ * has been deleted or modified. Complements `ON DELETE CASCADE` on the
63
+ * `chunks` table (which deletes chunk rows but not their vec counterparts,
64
+ * because the vec0 virtual table does not participate in FK cascades).
65
+ */
66
+ deleteChunkVecsByDoc(docId: string): void {
67
+ this.ensureVecLoaded();
68
+ this.knowledgeDb.db
69
+ .prepare("DELETE FROM documents_vec WHERE id GLOB ?")
70
+ .run(`${docId}#c*`);
71
+ }
72
+
57
73
  search(queryEmbedding: Float32Array, limit: number = 10): VectorResult[] {
58
74
  this.ensureVecLoaded();
59
75
  const buf = float32ToBuffer(queryEmbedding);