sverklo 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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/dist/bin/sverklo.d.ts +2 -0
  4. package/dist/bin/sverklo.js +41 -0
  5. package/dist/bin/sverklo.js.map +1 -0
  6. package/dist/src/index.d.ts +3 -0
  7. package/dist/src/index.js +3 -0
  8. package/dist/src/index.js.map +1 -0
  9. package/dist/src/indexer/describer.d.ts +2 -0
  10. package/dist/src/indexer/describer.js +112 -0
  11. package/dist/src/indexer/describer.js.map +1 -0
  12. package/dist/src/indexer/embedder.d.ts +4 -0
  13. package/dist/src/indexer/embedder.js +249 -0
  14. package/dist/src/indexer/embedder.js.map +1 -0
  15. package/dist/src/indexer/file-discovery.d.ts +9 -0
  16. package/dist/src/indexer/file-discovery.js +52 -0
  17. package/dist/src/indexer/file-discovery.js.map +1 -0
  18. package/dist/src/indexer/graph-builder.d.ts +5 -0
  19. package/dist/src/indexer/graph-builder.js +77 -0
  20. package/dist/src/indexer/graph-builder.js.map +1 -0
  21. package/dist/src/indexer/indexer.d.ts +26 -0
  22. package/dist/src/indexer/indexer.js +180 -0
  23. package/dist/src/indexer/indexer.js.map +1 -0
  24. package/dist/src/indexer/parser.d.ts +2 -0
  25. package/dist/src/indexer/parser.js +467 -0
  26. package/dist/src/indexer/parser.js.map +1 -0
  27. package/dist/src/indexer/setup.d.ts +1 -0
  28. package/dist/src/indexer/setup.js +38 -0
  29. package/dist/src/indexer/setup.js.map +1 -0
  30. package/dist/src/indexer/watcher.d.ts +2 -0
  31. package/dist/src/indexer/watcher.js +51 -0
  32. package/dist/src/indexer/watcher.js.map +1 -0
  33. package/dist/src/memory/git-state.d.ts +4 -0
  34. package/dist/src/memory/git-state.js +12 -0
  35. package/dist/src/memory/git-state.js.map +1 -0
  36. package/dist/src/memory/staleness.d.ts +4 -0
  37. package/dist/src/memory/staleness.js +19 -0
  38. package/dist/src/memory/staleness.js.map +1 -0
  39. package/dist/src/search/hybrid-search.d.ts +13 -0
  40. package/dist/src/search/hybrid-search.js +97 -0
  41. package/dist/src/search/hybrid-search.js.map +1 -0
  42. package/dist/src/search/pagerank.d.ts +4 -0
  43. package/dist/src/search/pagerank.js +64 -0
  44. package/dist/src/search/pagerank.js.map +1 -0
  45. package/dist/src/search/token-budget.d.ts +10 -0
  46. package/dist/src/search/token-budget.js +67 -0
  47. package/dist/src/search/token-budget.js.map +1 -0
  48. package/dist/src/server/mcp-server.d.ts +1 -0
  49. package/dist/src/server/mcp-server.js +120 -0
  50. package/dist/src/server/mcp-server.js.map +1 -0
  51. package/dist/src/server/tools/dependencies.d.ts +29 -0
  52. package/dist/src/server/tools/dependencies.js +118 -0
  53. package/dist/src/server/tools/dependencies.js.map +1 -0
  54. package/dist/src/server/tools/find-references.d.ts +20 -0
  55. package/dist/src/server/tools/find-references.js +80 -0
  56. package/dist/src/server/tools/find-references.js.map +1 -0
  57. package/dist/src/server/tools/forget.d.ts +16 -0
  58. package/dist/src/server/tools/forget.js +24 -0
  59. package/dist/src/server/tools/forget.js.map +1 -0
  60. package/dist/src/server/tools/index-status.d.ts +10 -0
  61. package/dist/src/server/tools/index-status.js +21 -0
  62. package/dist/src/server/tools/index-status.js.map +1 -0
  63. package/dist/src/server/tools/lookup.d.ts +25 -0
  64. package/dist/src/server/tools/lookup.js +54 -0
  65. package/dist/src/server/tools/lookup.js.map +1 -0
  66. package/dist/src/server/tools/memories.d.ts +24 -0
  67. package/dist/src/server/tools/memories.js +61 -0
  68. package/dist/src/server/tools/memories.js.map +1 -0
  69. package/dist/src/server/tools/overview.d.ts +19 -0
  70. package/dist/src/server/tools/overview.js +32 -0
  71. package/dist/src/server/tools/overview.js.map +1 -0
  72. package/dist/src/server/tools/recall.d.ts +29 -0
  73. package/dist/src/server/tools/recall.js +113 -0
  74. package/dist/src/server/tools/recall.js.map +1 -0
  75. package/dist/src/server/tools/remember.d.ts +39 -0
  76. package/dist/src/server/tools/remember.js +56 -0
  77. package/dist/src/server/tools/remember.js.map +1 -0
  78. package/dist/src/server/tools/search.d.ts +33 -0
  79. package/dist/src/server/tools/search.js +43 -0
  80. package/dist/src/server/tools/search.js.map +1 -0
  81. package/dist/src/storage/chunk-store.d.ts +25 -0
  82. package/dist/src/storage/chunk-store.js +74 -0
  83. package/dist/src/storage/chunk-store.js.map +1 -0
  84. package/dist/src/storage/database.d.ts +2 -0
  85. package/dist/src/storage/database.js +140 -0
  86. package/dist/src/storage/database.js.map +1 -0
  87. package/dist/src/storage/embedding-store.d.ts +14 -0
  88. package/dist/src/storage/embedding-store.js +42 -0
  89. package/dist/src/storage/embedding-store.js.map +1 -0
  90. package/dist/src/storage/file-store.d.ts +19 -0
  91. package/dist/src/storage/file-store.js +44 -0
  92. package/dist/src/storage/file-store.js.map +1 -0
  93. package/dist/src/storage/graph-store.d.ts +16 -0
  94. package/dist/src/storage/graph-store.js +37 -0
  95. package/dist/src/storage/graph-store.js.map +1 -0
  96. package/dist/src/storage/memory-embedding-store.d.ts +13 -0
  97. package/dist/src/storage/memory-embedding-store.js +38 -0
  98. package/dist/src/storage/memory-embedding-store.js.map +1 -0
  99. package/dist/src/storage/memory-store.d.ts +29 -0
  100. package/dist/src/storage/memory-store.js +86 -0
  101. package/dist/src/storage/memory-store.js.map +1 -0
  102. package/dist/src/types/index.d.ts +87 -0
  103. package/dist/src/types/index.js +21 -0
  104. package/dist/src/types/index.js.map +1 -0
  105. package/dist/src/utils/config.d.ts +2 -0
  106. package/dist/src/utils/config.js +18 -0
  107. package/dist/src/utils/config.js.map +1 -0
  108. package/dist/src/utils/ignore.d.ts +2 -0
  109. package/dist/src/utils/ignore.js +72 -0
  110. package/dist/src/utils/ignore.js.map +1 -0
  111. package/dist/src/utils/logger.d.ts +2 -0
  112. package/dist/src/utils/logger.js +16 -0
  113. package/dist/src/utils/logger.js.map +1 -0
  114. package/dist/src/utils/tokens.d.ts +2 -0
  115. package/dist/src/utils/tokens.js +12 -0
  116. package/dist/src/utils/tokens.js.map +1 -0
  117. package/package.json +59 -0
@@ -0,0 +1,56 @@
1
+ import { embed } from "../../indexer/embedder.js";
2
+ import { getGitState } from "../../memory/git-state.js";
3
+ export const rememberTool = {
4
+ name: "remember",
5
+ description: "Save a decision, preference, pattern, or important context as a persistent memory. Memories are searchable semantically and linked to the current git state.",
6
+ inputSchema: {
7
+ type: "object",
8
+ properties: {
9
+ content: {
10
+ type: "string",
11
+ description: "The memory to save — a decision, preference, pattern, or context",
12
+ },
13
+ category: {
14
+ type: "string",
15
+ enum: ["decision", "preference", "pattern", "context", "todo"],
16
+ description: "Memory category (default: 'context')",
17
+ },
18
+ tags: {
19
+ type: "array",
20
+ items: { type: "string" },
21
+ description: "Optional tags, e.g. ['auth', 'api-design']",
22
+ },
23
+ related_files: {
24
+ type: "array",
25
+ items: { type: "string" },
26
+ description: "File paths this memory relates to (enables staleness detection)",
27
+ },
28
+ confidence: {
29
+ type: "number",
30
+ description: "Confidence level 0.0-1.0 (default: 1.0). Lower for tentative decisions.",
31
+ },
32
+ },
33
+ required: ["content"],
34
+ },
35
+ };
36
+ export async function handleRemember(indexer, args) {
37
+ const content = args.content;
38
+ const category = args.category || "context";
39
+ const tags = args.tags || null;
40
+ const relatedFiles = args.related_files || null;
41
+ const confidence = args.confidence ?? 1.0;
42
+ const { sha, branch } = getGitState(indexer.rootPath);
43
+ const id = indexer.memoryStore.insert(category, content, tags, confidence, sha, branch, relatedFiles);
44
+ // Embed the memory for semantic search
45
+ const [vector] = await embed([content]);
46
+ indexer.memoryEmbeddingStore.insert(id, vector);
47
+ const parts = [`Remembered (id: ${id}, category: ${category})`];
48
+ if (sha)
49
+ parts.push(`git: ${branch || "detached"}@${sha.slice(0, 7)}`);
50
+ if (tags)
51
+ parts.push(`tags: ${tags.join(", ")}`);
52
+ if (relatedFiles)
53
+ parts.push(`files: ${relatedFiles.join(", ")}`);
54
+ return parts.join("\n");
55
+ }
56
+ //# sourceMappingURL=remember.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remember.js","sourceRoot":"","sources":["../../../../src/server/tools/remember.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,UAAU;IAChB,WAAW,EACT,8JAA8J;IAChK,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,kEAAkE;aACrE;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;gBAC9D,WAAW,EAAE,sCAAsC;aACpD;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EAAE,4CAA4C;aAC1D;YACD,aAAa,EAAE;gBACb,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EACT,iEAAiE;aACpE;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,yEAAyE;aAC5E;SACF;QACD,QAAQ,EAAE,CAAC,SAAS,CAAC;KACtB;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgB,EAChB,IAA6B;IAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;IACvC,MAAM,QAAQ,GAAI,IAAI,CAAC,QAA2B,IAAI,SAAS,CAAC;IAChE,MAAM,IAAI,GAAI,IAAI,CAAC,IAAiB,IAAI,IAAI,CAAC;IAC7C,MAAM,YAAY,GAAI,IAAI,CAAC,aAA0B,IAAI,IAAI,CAAC;IAC9D,MAAM,UAAU,GAAI,IAAI,CAAC,UAAqB,IAAI,GAAG,CAAC;IAEtD,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEtD,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CACnC,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,UAAU,EACV,GAAG,EACH,MAAM,EACN,YAAY,CACb,CAAC;IAEF,uCAAuC;IACvC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,CAAC,mBAAmB,EAAE,eAAe,QAAQ,GAAG,CAAC,CAAC;IAChE,IAAI,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,MAAM,IAAI,UAAU,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACvE,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjD,IAAI,YAAY;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAElE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { Indexer } from "../../indexer/indexer.js";
2
+ export declare const searchTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ query: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ token_budget: {
13
+ type: string;
14
+ description: string;
15
+ };
16
+ scope: {
17
+ type: string;
18
+ description: string;
19
+ };
20
+ language: {
21
+ type: string;
22
+ description: string;
23
+ };
24
+ type: {
25
+ type: string;
26
+ enum: string[];
27
+ description: string;
28
+ };
29
+ };
30
+ required: string[];
31
+ };
32
+ };
33
+ export declare function handleSearch(indexer: Indexer, args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,43 @@
1
+ import { hybridSearch, formatResults } from "../../search/hybrid-search.js";
2
+ export const searchTool = {
3
+ name: "search",
4
+ description: "Search the codebase using natural language or code patterns. Combines text matching, semantic similarity, and structural importance ranking. Returns the most relevant code snippets within the token budget.",
5
+ inputSchema: {
6
+ type: "object",
7
+ properties: {
8
+ query: {
9
+ type: "string",
10
+ description: "Natural language query or code pattern",
11
+ },
12
+ token_budget: {
13
+ type: "number",
14
+ description: "Max tokens to return (default: 4000)",
15
+ },
16
+ scope: {
17
+ type: "string",
18
+ description: "Limit to path prefix, e.g. 'src/api/'",
19
+ },
20
+ language: {
21
+ type: "string",
22
+ description: "Filter by language, e.g. 'typescript'",
23
+ },
24
+ type: {
25
+ type: "string",
26
+ enum: ["function", "class", "type", "interface", "method", "any"],
27
+ description: "Filter by symbol type (default: any)",
28
+ },
29
+ },
30
+ required: ["query"],
31
+ },
32
+ };
33
+ export async function handleSearch(indexer, args) {
34
+ const results = await hybridSearch(indexer, {
35
+ query: args.query,
36
+ tokenBudget: args.token_budget || 4000,
37
+ scope: args.scope,
38
+ language: args.language,
39
+ type: args.type || "any",
40
+ });
41
+ return formatResults(results);
42
+ }
43
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../src/server/tools/search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG5E,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,+MAA+M;IACjN,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,wCAAwC;aACtD;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sCAAsC;aACpD;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uCAAuC;aACrD;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uCAAuC;aACrD;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC;gBACjE,WAAW,EAAE,sCAAsC;aACpD;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAgB,EAChB,IAA6B;IAE7B,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE;QAC1C,KAAK,EAAE,IAAI,CAAC,KAAe;QAC3B,WAAW,EAAG,IAAI,CAAC,YAAuB,IAAI,IAAI;QAClD,KAAK,EAAE,IAAI,CAAC,KAA2B;QACvC,QAAQ,EAAE,IAAI,CAAC,QAA8B;QAC7C,IAAI,EAAG,IAAI,CAAC,IAA0B,IAAI,KAAK;KAChD,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { CodeChunk, ChunkType } from "../types/index.js";
3
+ export declare class ChunkStore {
4
+ private db;
5
+ private insertStmt;
6
+ private getByFileStmt;
7
+ private deleteByFileStmt;
8
+ private searchFtsStmt;
9
+ private getByIdStmt;
10
+ private getByNameStmt;
11
+ constructor(db: Database.Database);
12
+ insert(fileId: number, type: ChunkType, name: string | null, signature: string | null, startLine: number, endLine: number, content: string, description: string | null, tokenCount: number): number;
13
+ getByFile(fileId: number): CodeChunk[];
14
+ deleteByFile(fileId: number): void;
15
+ searchFts(query: string, limit?: number): (CodeChunk & {
16
+ rank: number;
17
+ })[];
18
+ getById(id: number): CodeChunk | undefined;
19
+ getByName(namePattern: string, limit?: number): CodeChunk[];
20
+ count(): number;
21
+ getAllWithFile(): (CodeChunk & {
22
+ filePath: string;
23
+ pagerank: number;
24
+ })[];
25
+ }
@@ -0,0 +1,74 @@
1
+ export class ChunkStore {
2
+ db;
3
+ insertStmt;
4
+ getByFileStmt;
5
+ deleteByFileStmt;
6
+ searchFtsStmt;
7
+ getByIdStmt;
8
+ getByNameStmt;
9
+ constructor(db) {
10
+ this.db = db;
11
+ this.insertStmt = db.prepare(`
12
+ INSERT INTO chunks (file_id, type, name, signature, start_line, end_line, content, description, token_count)
13
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
14
+ `);
15
+ this.getByFileStmt = db.prepare("SELECT * FROM chunks WHERE file_id = ? ORDER BY start_line");
16
+ this.deleteByFileStmt = db.prepare("DELETE FROM chunks WHERE file_id = ?");
17
+ this.searchFtsStmt = db.prepare(`
18
+ SELECT c.*, rank
19
+ FROM chunks_fts fts
20
+ JOIN chunks c ON c.id = fts.rowid
21
+ WHERE chunks_fts MATCH ?
22
+ ORDER BY rank
23
+ LIMIT ?
24
+ `);
25
+ this.getByIdStmt = db.prepare("SELECT * FROM chunks WHERE id = ?");
26
+ this.getByNameStmt = db.prepare(`
27
+ SELECT * FROM chunks WHERE name LIKE ? COLLATE NOCASE ORDER BY name LIMIT ?
28
+ `);
29
+ }
30
+ insert(fileId, type, name, signature, startLine, endLine, content, description, tokenCount) {
31
+ const result = this.insertStmt.run(fileId, type, name, signature, startLine, endLine, content, description, tokenCount);
32
+ return Number(result.lastInsertRowid);
33
+ }
34
+ getByFile(fileId) {
35
+ return this.getByFileStmt.all(fileId);
36
+ }
37
+ deleteByFile(fileId) {
38
+ this.deleteByFileStmt.run(fileId);
39
+ }
40
+ searchFts(query, limit = 50) {
41
+ try {
42
+ // Escape FTS5 special chars and use simple matching
43
+ const safeQuery = query
44
+ .replace(/["'(){}[\]*:^~!@#$%&]/g, " ")
45
+ .split(/\s+/)
46
+ .filter((w) => w.length > 1)
47
+ .map((w) => `"${w}"`)
48
+ .join(" OR ");
49
+ if (!safeQuery)
50
+ return [];
51
+ return this.searchFtsStmt.all(safeQuery, limit);
52
+ }
53
+ catch {
54
+ return [];
55
+ }
56
+ }
57
+ getById(id) {
58
+ return this.getByIdStmt.get(id);
59
+ }
60
+ getByName(namePattern, limit = 20) {
61
+ return this.getByNameStmt.all(`%${namePattern}%`, limit);
62
+ }
63
+ count() {
64
+ return this.db.prepare("SELECT COUNT(*) as c FROM chunks").get().c;
65
+ }
66
+ getAllWithFile() {
67
+ return this.db
68
+ .prepare(`SELECT c.*, f.path as filePath, f.pagerank
69
+ FROM chunks c JOIN files f ON c.file_id = f.id
70
+ ORDER BY f.pagerank DESC, c.start_line`)
71
+ .all();
72
+ }
73
+ }
74
+ //# sourceMappingURL=chunk-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-store.js","sourceRoot":"","sources":["../../../src/storage/chunk-store.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,UAAU;IAQD;IAPZ,UAAU,CAAqB;IAC/B,aAAa,CAAqB;IAClC,gBAAgB,CAAqB;IACrC,aAAa,CAAqB;IAClC,WAAW,CAAqB;IAChC,aAAa,CAAqB;IAE1C,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAG5B,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAC7B,4DAA4D,CAC7D,CAAC;QACF,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;QAC3E,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;KAO/B,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACnE,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC;;KAE/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CACJ,MAAc,EACd,IAAe,EACf,IAAmB,EACnB,SAAwB,EACxB,SAAiB,EACjB,OAAe,EACf,OAAe,EACf,WAA0B,EAC1B,UAAkB;QAElB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAChC,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,UAAU,CACX,CAAC;QACF,OAAO,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAgB,CAAC;IACvD,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,SAAS,CAAC,KAAa,EAAE,QAAgB,EAAE;QACzC,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,SAAS,GAAG,KAAK;iBACpB,OAAO,CAAC,wBAAwB,EAAE,GAAG,CAAC;iBACtC,KAAK,CAAC,KAAK,CAAC;iBACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;iBAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;iBACpB,IAAI,CAAC,MAAM,CAAC,CAAC;YAChB,IAAI,CAAC,SAAS;gBAAE,OAAO,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAE1C,CAAC;QACP,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAA0B,CAAC;IAC3D,CAAC;IAED,SAAS,CAAC,WAAmB,EAAE,QAAgB,EAAE;QAC/C,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,WAAW,GAAG,EAAE,KAAK,CAAgB,CAAC;IAC1E,CAAC;IAED,KAAK;QACH,OACE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,GAAG,EACxD,CAAC,CAAC,CAAC;IACN,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,EAAE;aACX,OAAO,CACN;;gDAEwC,CACzC;aACA,GAAG,EAA4D,CAAC;IACrE,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import Database from "better-sqlite3";
2
+ export declare function createDatabase(dbPath: string): Database.Database;
@@ -0,0 +1,140 @@
1
+ import Database from "better-sqlite3";
2
+ const SCHEMA = `
3
+ -- Indexed files
4
+ CREATE TABLE IF NOT EXISTS files (
5
+ id INTEGER PRIMARY KEY,
6
+ path TEXT NOT NULL UNIQUE,
7
+ language TEXT,
8
+ hash TEXT NOT NULL,
9
+ last_modified INTEGER NOT NULL,
10
+ size_bytes INTEGER NOT NULL,
11
+ pagerank REAL DEFAULT 0.0,
12
+ indexed_at INTEGER NOT NULL
13
+ );
14
+
15
+ -- Code chunks
16
+ CREATE TABLE IF NOT EXISTS chunks (
17
+ id INTEGER PRIMARY KEY,
18
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
19
+ type TEXT NOT NULL,
20
+ name TEXT,
21
+ signature TEXT,
22
+ start_line INTEGER NOT NULL,
23
+ end_line INTEGER NOT NULL,
24
+ content TEXT NOT NULL,
25
+ description TEXT,
26
+ token_count INTEGER NOT NULL
27
+ );
28
+
29
+ -- Vector embeddings
30
+ CREATE TABLE IF NOT EXISTS embeddings (
31
+ chunk_id INTEGER PRIMARY KEY REFERENCES chunks(id) ON DELETE CASCADE,
32
+ vector BLOB NOT NULL
33
+ );
34
+
35
+ -- Dependency graph
36
+ CREATE TABLE IF NOT EXISTS dependencies (
37
+ id INTEGER PRIMARY KEY,
38
+ source_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
39
+ target_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
40
+ reference_count INTEGER DEFAULT 1,
41
+ UNIQUE(source_file_id, target_file_id)
42
+ );
43
+
44
+ -- Full-text search
45
+ CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
46
+ name,
47
+ content,
48
+ description,
49
+ content=chunks,
50
+ content_rowid=id,
51
+ tokenize='porter unicode61'
52
+ );
53
+
54
+ -- Triggers to keep FTS in sync
55
+ CREATE TRIGGER IF NOT EXISTS chunks_ai AFTER INSERT ON chunks BEGIN
56
+ INSERT INTO chunks_fts(rowid, name, content, description)
57
+ VALUES (new.id, new.name, new.content, new.description);
58
+ END;
59
+
60
+ CREATE TRIGGER IF NOT EXISTS chunks_ad AFTER DELETE ON chunks BEGIN
61
+ INSERT INTO chunks_fts(chunks_fts, rowid, name, content, description)
62
+ VALUES ('delete', old.id, old.name, old.content, old.description);
63
+ END;
64
+
65
+ CREATE TRIGGER IF NOT EXISTS chunks_au AFTER UPDATE ON chunks BEGIN
66
+ INSERT INTO chunks_fts(chunks_fts, rowid, name, content, description)
67
+ VALUES ('delete', old.id, old.name, old.content, old.description);
68
+ INSERT INTO chunks_fts(rowid, name, content, description)
69
+ VALUES (new.id, new.name, new.content, new.description);
70
+ END;
71
+
72
+ -- Session memories
73
+ CREATE TABLE IF NOT EXISTS memories (
74
+ id INTEGER PRIMARY KEY,
75
+ category TEXT NOT NULL,
76
+ content TEXT NOT NULL,
77
+ tags TEXT,
78
+ confidence REAL DEFAULT 1.0,
79
+ git_sha TEXT,
80
+ git_branch TEXT,
81
+ related_files TEXT,
82
+ created_at INTEGER NOT NULL,
83
+ updated_at INTEGER NOT NULL,
84
+ last_accessed INTEGER NOT NULL,
85
+ access_count INTEGER DEFAULT 0,
86
+ is_stale INTEGER DEFAULT 0
87
+ );
88
+
89
+ CREATE TABLE IF NOT EXISTS memory_embeddings (
90
+ memory_id INTEGER PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
91
+ vector BLOB NOT NULL
92
+ );
93
+
94
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
95
+ content,
96
+ tags,
97
+ content=memories,
98
+ content_rowid=id,
99
+ tokenize='porter unicode61'
100
+ );
101
+
102
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
103
+ INSERT INTO memories_fts(rowid, content, tags)
104
+ VALUES (new.id, new.content, new.tags);
105
+ END;
106
+
107
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
108
+ INSERT INTO memories_fts(memories_fts, rowid, content, tags)
109
+ VALUES ('delete', old.id, old.content, old.tags);
110
+ END;
111
+
112
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
113
+ INSERT INTO memories_fts(memories_fts, rowid, content, tags)
114
+ VALUES ('delete', old.id, old.content, old.tags);
115
+ INSERT INTO memories_fts(rowid, content, tags)
116
+ VALUES (new.id, new.content, new.tags);
117
+ END;
118
+
119
+ -- Indexes
120
+ CREATE INDEX IF NOT EXISTS idx_files_path ON files(path);
121
+ CREATE INDEX IF NOT EXISTS idx_files_language ON files(language);
122
+ CREATE INDEX IF NOT EXISTS idx_chunks_file ON chunks(file_id);
123
+ CREATE INDEX IF NOT EXISTS idx_chunks_name ON chunks(name);
124
+ CREATE INDEX IF NOT EXISTS idx_chunks_type ON chunks(type);
125
+ CREATE INDEX IF NOT EXISTS idx_deps_source ON dependencies(source_file_id);
126
+ CREATE INDEX IF NOT EXISTS idx_deps_target ON dependencies(target_file_id);
127
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
128
+ CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
129
+ CREATE INDEX IF NOT EXISTS idx_memories_stale ON memories(is_stale);
130
+ `;
131
+ export function createDatabase(dbPath) {
132
+ const db = new Database(dbPath);
133
+ db.pragma("journal_mode = WAL");
134
+ db.pragma("foreign_keys = ON");
135
+ db.pragma("synchronous = NORMAL");
136
+ db.pragma("cache_size = -64000"); // 64MB cache
137
+ db.exec(SCHEMA);
138
+ return db;
139
+ }
140
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/storage/database.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgId,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEhC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAClC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,aAAa;IAE/C,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare class EmbeddingStore {
3
+ private db;
4
+ private insertStmt;
5
+ private getStmt;
6
+ private getAllStmt;
7
+ private deleteByChunkStmt;
8
+ constructor(db: Database.Database);
9
+ insert(chunkId: number, vector: Float32Array): void;
10
+ get(chunkId: number): Float32Array | undefined;
11
+ getAll(): Map<number, Float32Array>;
12
+ delete(chunkId: number): void;
13
+ count(): number;
14
+ }
@@ -0,0 +1,42 @@
1
+ export class EmbeddingStore {
2
+ db;
3
+ insertStmt;
4
+ getStmt;
5
+ getAllStmt;
6
+ deleteByChunkStmt;
7
+ constructor(db) {
8
+ this.db = db;
9
+ this.insertStmt = db.prepare("INSERT OR REPLACE INTO embeddings (chunk_id, vector) VALUES (?, ?)");
10
+ this.getStmt = db.prepare("SELECT vector FROM embeddings WHERE chunk_id = ?");
11
+ this.getAllStmt = db.prepare("SELECT chunk_id, vector FROM embeddings");
12
+ this.deleteByChunkStmt = db.prepare("DELETE FROM embeddings WHERE chunk_id = ?");
13
+ }
14
+ insert(chunkId, vector) {
15
+ this.insertStmt.run(chunkId, Buffer.from(vector.buffer));
16
+ }
17
+ get(chunkId) {
18
+ const row = this.getStmt.get(chunkId);
19
+ if (!row)
20
+ return undefined;
21
+ return new Float32Array(row.vector.buffer, row.vector.byteOffset, row.vector.byteLength / 4);
22
+ }
23
+ getAll() {
24
+ const map = new Map();
25
+ const rows = this.getAllStmt.all();
26
+ for (const row of rows) {
27
+ // Copy buffer to avoid shared buffer issues
28
+ const arr = new Float32Array(row.vector.length / 4);
29
+ const view = new Float32Array(row.vector.buffer, row.vector.byteOffset, row.vector.byteLength / 4);
30
+ arr.set(view);
31
+ map.set(row.chunk_id, arr);
32
+ }
33
+ return map;
34
+ }
35
+ delete(chunkId) {
36
+ this.deleteByChunkStmt.run(chunkId);
37
+ }
38
+ count() {
39
+ return this.db.prepare("SELECT COUNT(*) as c FROM embeddings").get().c;
40
+ }
41
+ }
42
+ //# sourceMappingURL=embedding-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-store.js","sourceRoot":"","sources":["../../../src/storage/embedding-store.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,cAAc;IAML;IALZ,UAAU,CAAqB;IAC/B,OAAO,CAAqB;IAC5B,UAAU,CAAqB;IAC/B,iBAAiB,CAAqB;IAE9C,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAC1B,oEAAoE,CACrE,CAAC;QACF,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CACvB,kDAAkD,CACnD,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC;QACxE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,OAAO,CACjC,2CAA2C,CAC5C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,MAAoB;QAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,GAAG,CAAC,OAAe;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAEvB,CAAC;QACd,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,GAAG,EAAwB,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAG7B,CAAC;QACJ,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,4CAA4C;YAC5C,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YACnG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACd,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,KAAK;QACH,OACE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,EAG5D,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { FileRecord } from "../types/index.js";
3
+ export declare class FileStore {
4
+ private db;
5
+ private insertStmt;
6
+ private getByPathStmt;
7
+ private getAllStmt;
8
+ private deleteStmt;
9
+ private updatePagerankStmt;
10
+ private getLanguagesStmt;
11
+ constructor(db: Database.Database);
12
+ upsert(path: string, language: string | null, hash: string, lastModified: number, sizeBytes: number): number;
13
+ getByPath(path: string): FileRecord | undefined;
14
+ getAll(): FileRecord[];
15
+ delete(path: string): void;
16
+ updatePagerank(id: number, score: number): void;
17
+ getLanguages(): string[];
18
+ count(): number;
19
+ }
@@ -0,0 +1,44 @@
1
+ export class FileStore {
2
+ db;
3
+ insertStmt;
4
+ getByPathStmt;
5
+ getAllStmt;
6
+ deleteStmt;
7
+ updatePagerankStmt;
8
+ getLanguagesStmt;
9
+ constructor(db) {
10
+ this.db = db;
11
+ this.insertStmt = db.prepare(`
12
+ INSERT OR REPLACE INTO files (path, language, hash, last_modified, size_bytes, pagerank, indexed_at)
13
+ VALUES (?, ?, ?, ?, ?, 0.0, ?)
14
+ `);
15
+ this.getByPathStmt = db.prepare("SELECT * FROM files WHERE path = ?");
16
+ this.getAllStmt = db.prepare("SELECT * FROM files ORDER BY pagerank DESC");
17
+ this.deleteStmt = db.prepare("DELETE FROM files WHERE path = ?");
18
+ this.updatePagerankStmt = db.prepare("UPDATE files SET pagerank = ? WHERE id = ?");
19
+ this.getLanguagesStmt = db.prepare("SELECT DISTINCT language FROM files WHERE language IS NOT NULL");
20
+ }
21
+ upsert(path, language, hash, lastModified, sizeBytes) {
22
+ const result = this.insertStmt.run(path, language, hash, lastModified, sizeBytes, Date.now());
23
+ return Number(result.lastInsertRowid);
24
+ }
25
+ getByPath(path) {
26
+ return this.getByPathStmt.get(path);
27
+ }
28
+ getAll() {
29
+ return this.getAllStmt.all();
30
+ }
31
+ delete(path) {
32
+ this.deleteStmt.run(path);
33
+ }
34
+ updatePagerank(id, score) {
35
+ this.updatePagerankStmt.run(score, id);
36
+ }
37
+ getLanguages() {
38
+ return this.getLanguagesStmt.all().map((r) => r.language);
39
+ }
40
+ count() {
41
+ return this.db.prepare("SELECT COUNT(*) as c FROM files").get().c;
42
+ }
43
+ }
44
+ //# sourceMappingURL=file-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-store.js","sourceRoot":"","sources":["../../../src/storage/file-store.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,SAAS;IAQA;IAPZ,UAAU,CAAqB;IAC/B,aAAa,CAAqB;IAClC,UAAU,CAAqB;IAC/B,UAAU,CAAqB;IAC/B,kBAAkB,CAAqB;IACvC,gBAAgB,CAAqB;IAE7C,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAG5B,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACtE,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;QAC3E,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACjE,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC,OAAO,CAClC,4CAA4C,CAC7C,CAAC;QACF,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAChC,gEAAgE,CACjE,CAAC;IACJ,CAAC;IAED,MAAM,CACJ,IAAY,EACZ,QAAuB,EACvB,IAAY,EACZ,YAAoB,EACpB,SAAiB;QAEjB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAChC,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,IAAI,CAAC,GAAG,EAAE,CACX,CAAC;QACF,OAAO,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAA2B,CAAC;IAChE,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAkB,CAAC;IAC/C,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,cAAc,CAAC,EAAU,EAAE,KAAa;QACtC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,YAAY;QACV,OAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAA6B,CAAC,GAAG,CAChE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAClB,CAAC;IACJ,CAAC;IAED,KAAK;QACH,OACE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,EACvD,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { DependencyEdge } from "../types/index.js";
3
+ export declare class GraphStore {
4
+ private db;
5
+ private upsertStmt;
6
+ private getImportsStmt;
7
+ private getImportersStmt;
8
+ private deleteByFileStmt;
9
+ private getAllStmt;
10
+ constructor(db: Database.Database);
11
+ upsert(sourceFileId: number, targetFileId: number, refCount: number): void;
12
+ getImports(fileId: number): DependencyEdge[];
13
+ getImporters(fileId: number): DependencyEdge[];
14
+ deleteBySourceFile(fileId: number): void;
15
+ getAll(): DependencyEdge[];
16
+ }
@@ -0,0 +1,37 @@
1
+ export class GraphStore {
2
+ db;
3
+ upsertStmt;
4
+ getImportsStmt;
5
+ getImportersStmt;
6
+ deleteByFileStmt;
7
+ getAllStmt;
8
+ constructor(db) {
9
+ this.db = db;
10
+ this.upsertStmt = db.prepare(`
11
+ INSERT INTO dependencies (source_file_id, target_file_id, reference_count)
12
+ VALUES (?, ?, ?)
13
+ ON CONFLICT(source_file_id, target_file_id)
14
+ DO UPDATE SET reference_count = excluded.reference_count
15
+ `);
16
+ this.getImportsStmt = db.prepare("SELECT * FROM dependencies WHERE source_file_id = ?");
17
+ this.getImportersStmt = db.prepare("SELECT * FROM dependencies WHERE target_file_id = ?");
18
+ this.deleteByFileStmt = db.prepare("DELETE FROM dependencies WHERE source_file_id = ?");
19
+ this.getAllStmt = db.prepare("SELECT * FROM dependencies");
20
+ }
21
+ upsert(sourceFileId, targetFileId, refCount) {
22
+ this.upsertStmt.run(sourceFileId, targetFileId, refCount);
23
+ }
24
+ getImports(fileId) {
25
+ return this.getImportsStmt.all(fileId);
26
+ }
27
+ getImporters(fileId) {
28
+ return this.getImportersStmt.all(fileId);
29
+ }
30
+ deleteBySourceFile(fileId) {
31
+ this.deleteByFileStmt.run(fileId);
32
+ }
33
+ getAll() {
34
+ return this.getAllStmt.all();
35
+ }
36
+ }
37
+ //# sourceMappingURL=graph-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-store.js","sourceRoot":"","sources":["../../../src/storage/graph-store.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,UAAU;IAOD;IANZ,UAAU,CAAqB;IAC/B,cAAc,CAAqB;IACnC,gBAAgB,CAAqB;IACrC,gBAAgB,CAAqB;IACrC,UAAU,CAAqB;IAEvC,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;KAK5B,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,OAAO,CAC9B,qDAAqD,CACtD,CAAC;QACF,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAChC,qDAAqD,CACtD,CAAC;QACF,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAChC,mDAAmD,CACpD,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,CAAC,YAAoB,EAAE,YAAoB,EAAE,QAAgB;QACjE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAqB,CAAC;IAC7D,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAqB,CAAC;IAC/D,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAsB,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare class MemoryEmbeddingStore {
3
+ private db;
4
+ private insertStmt;
5
+ private getStmt;
6
+ private getAllStmt;
7
+ private deleteStmt;
8
+ constructor(db: Database.Database);
9
+ insert(memoryId: number, vector: Float32Array): void;
10
+ get(memoryId: number): Float32Array | undefined;
11
+ getAll(): Map<number, Float32Array>;
12
+ delete(memoryId: number): void;
13
+ }
@@ -0,0 +1,38 @@
1
+ export class MemoryEmbeddingStore {
2
+ db;
3
+ insertStmt;
4
+ getStmt;
5
+ getAllStmt;
6
+ deleteStmt;
7
+ constructor(db) {
8
+ this.db = db;
9
+ this.insertStmt = db.prepare("INSERT OR REPLACE INTO memory_embeddings (memory_id, vector) VALUES (?, ?)");
10
+ this.getStmt = db.prepare("SELECT vector FROM memory_embeddings WHERE memory_id = ?");
11
+ this.getAllStmt = db.prepare("SELECT memory_id, vector FROM memory_embeddings");
12
+ this.deleteStmt = db.prepare("DELETE FROM memory_embeddings WHERE memory_id = ?");
13
+ }
14
+ insert(memoryId, vector) {
15
+ this.insertStmt.run(memoryId, Buffer.from(vector.buffer));
16
+ }
17
+ get(memoryId) {
18
+ const row = this.getStmt.get(memoryId);
19
+ if (!row)
20
+ return undefined;
21
+ return new Float32Array(row.vector.buffer, row.vector.byteOffset, row.vector.byteLength / 4);
22
+ }
23
+ getAll() {
24
+ const map = new Map();
25
+ const rows = this.getAllStmt.all();
26
+ for (const row of rows) {
27
+ const arr = new Float32Array(row.vector.length / 4);
28
+ const view = new Float32Array(row.vector.buffer, row.vector.byteOffset, row.vector.byteLength / 4);
29
+ arr.set(view);
30
+ map.set(row.memory_id, arr);
31
+ }
32
+ return map;
33
+ }
34
+ delete(memoryId) {
35
+ this.deleteStmt.run(memoryId);
36
+ }
37
+ }
38
+ //# sourceMappingURL=memory-embedding-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-embedding-store.js","sourceRoot":"","sources":["../../../src/storage/memory-embedding-store.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,oBAAoB;IAMX;IALZ,UAAU,CAAqB;IAC/B,OAAO,CAAqB;IAC5B,UAAU,CAAqB;IAC/B,UAAU,CAAqB;IAEvC,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAC1B,4EAA4E,CAC7E,CAAC;QACF,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CACvB,0DAA0D,CAC3D,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAC1B,iDAAiD,CAClD,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAC1B,mDAAmD,CACpD,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,QAAgB,EAAE,MAAoB;QAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,GAAG,CAAC,QAAgB;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAmC,CAAC;QACzE,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,GAAG,EAAwB,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAA6C,CAAC;QAC9E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YACnG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACd,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,CAAC,QAAgB;QACrB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;CACF"}