opencode-mem 1.0.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 (84) hide show
  1. package/README.md +588 -0
  2. package/dist/config.d.ts +33 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +258 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +618 -0
  8. package/dist/plugin.d.ts +5 -0
  9. package/dist/plugin.d.ts.map +1 -0
  10. package/dist/plugin.js +15 -0
  11. package/dist/services/api-handlers.d.ts +102 -0
  12. package/dist/services/api-handlers.d.ts.map +1 -0
  13. package/dist/services/api-handlers.js +494 -0
  14. package/dist/services/auto-capture.d.ts +32 -0
  15. package/dist/services/auto-capture.d.ts.map +1 -0
  16. package/dist/services/auto-capture.js +451 -0
  17. package/dist/services/cleanup-service.d.ts +20 -0
  18. package/dist/services/cleanup-service.d.ts.map +1 -0
  19. package/dist/services/cleanup-service.js +88 -0
  20. package/dist/services/client.d.ts +104 -0
  21. package/dist/services/client.d.ts.map +1 -0
  22. package/dist/services/client.js +251 -0
  23. package/dist/services/compaction.d.ts +92 -0
  24. package/dist/services/compaction.d.ts.map +1 -0
  25. package/dist/services/compaction.js +421 -0
  26. package/dist/services/context.d.ts +17 -0
  27. package/dist/services/context.d.ts.map +1 -0
  28. package/dist/services/context.js +41 -0
  29. package/dist/services/deduplication-service.d.ts +30 -0
  30. package/dist/services/deduplication-service.d.ts.map +1 -0
  31. package/dist/services/deduplication-service.js +131 -0
  32. package/dist/services/embedding.d.ts +10 -0
  33. package/dist/services/embedding.d.ts.map +1 -0
  34. package/dist/services/embedding.js +77 -0
  35. package/dist/services/jsonc.d.ts +7 -0
  36. package/dist/services/jsonc.d.ts.map +1 -0
  37. package/dist/services/jsonc.js +76 -0
  38. package/dist/services/logger.d.ts +2 -0
  39. package/dist/services/logger.d.ts.map +1 -0
  40. package/dist/services/logger.js +16 -0
  41. package/dist/services/migration-service.d.ts +42 -0
  42. package/dist/services/migration-service.d.ts.map +1 -0
  43. package/dist/services/migration-service.js +258 -0
  44. package/dist/services/privacy.d.ts +4 -0
  45. package/dist/services/privacy.d.ts.map +1 -0
  46. package/dist/services/privacy.js +10 -0
  47. package/dist/services/sqlite/connection-manager.d.ts +10 -0
  48. package/dist/services/sqlite/connection-manager.d.ts.map +1 -0
  49. package/dist/services/sqlite/connection-manager.js +45 -0
  50. package/dist/services/sqlite/shard-manager.d.ts +20 -0
  51. package/dist/services/sqlite/shard-manager.d.ts.map +1 -0
  52. package/dist/services/sqlite/shard-manager.js +221 -0
  53. package/dist/services/sqlite/types.d.ts +39 -0
  54. package/dist/services/sqlite/types.d.ts.map +1 -0
  55. package/dist/services/sqlite/types.js +1 -0
  56. package/dist/services/sqlite/vector-search.d.ts +18 -0
  57. package/dist/services/sqlite/vector-search.d.ts.map +1 -0
  58. package/dist/services/sqlite/vector-search.js +129 -0
  59. package/dist/services/sqlite-client.d.ts +116 -0
  60. package/dist/services/sqlite-client.d.ts.map +1 -0
  61. package/dist/services/sqlite-client.js +284 -0
  62. package/dist/services/tags.d.ts +20 -0
  63. package/dist/services/tags.d.ts.map +1 -0
  64. package/dist/services/tags.js +76 -0
  65. package/dist/services/web-server-lock.d.ts +12 -0
  66. package/dist/services/web-server-lock.d.ts.map +1 -0
  67. package/dist/services/web-server-lock.js +157 -0
  68. package/dist/services/web-server-worker.d.ts +2 -0
  69. package/dist/services/web-server-worker.d.ts.map +1 -0
  70. package/dist/services/web-server-worker.js +221 -0
  71. package/dist/services/web-server.d.ts +22 -0
  72. package/dist/services/web-server.d.ts.map +1 -0
  73. package/dist/services/web-server.js +134 -0
  74. package/dist/types/index.d.ts +48 -0
  75. package/dist/types/index.d.ts.map +1 -0
  76. package/dist/types/index.js +1 -0
  77. package/dist/web/app.d.ts +2 -0
  78. package/dist/web/app.d.ts.map +1 -0
  79. package/dist/web/app.js +691 -0
  80. package/dist/web/favicon.ico +0 -0
  81. package/dist/web/favicon.svg +14 -0
  82. package/dist/web/index.html +202 -0
  83. package/dist/web/styles.css +851 -0
  84. package/package.json +52 -0
@@ -0,0 +1,221 @@
1
+ import { Database } from "bun:sqlite";
2
+ import { join } from "node:path";
3
+ import { CONFIG } from "../../config.js";
4
+ import { connectionManager } from "./connection-manager.js";
5
+ import { log } from "../logger.js";
6
+ const METADATA_DB_NAME = "metadata.db";
7
+ export class ShardManager {
8
+ metadataDb;
9
+ metadataPath;
10
+ constructor() {
11
+ this.metadataPath = join(CONFIG.storagePath, METADATA_DB_NAME);
12
+ this.metadataDb = connectionManager.getConnection(this.metadataPath);
13
+ this.initMetadataDb();
14
+ }
15
+ initMetadataDb() {
16
+ this.metadataDb.run(`
17
+ CREATE TABLE IF NOT EXISTS shards (
18
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
19
+ scope TEXT NOT NULL,
20
+ scope_hash TEXT NOT NULL,
21
+ shard_index INTEGER NOT NULL,
22
+ db_path TEXT NOT NULL,
23
+ vector_count INTEGER DEFAULT 0,
24
+ is_active INTEGER DEFAULT 1,
25
+ created_at INTEGER NOT NULL,
26
+ UNIQUE(scope, scope_hash, shard_index)
27
+ )
28
+ `);
29
+ this.metadataDb.run(`
30
+ CREATE INDEX IF NOT EXISTS idx_active_shards
31
+ ON shards(scope, scope_hash, is_active)
32
+ `);
33
+ }
34
+ getShardPath(scope, scopeHash, shardIndex) {
35
+ const dir = join(CONFIG.storagePath, `${scope}s`);
36
+ return join(dir, `${scope}_${scopeHash}_shard_${shardIndex}.db`);
37
+ }
38
+ getActiveShard(scope, scopeHash) {
39
+ const stmt = this.metadataDb.prepare(`
40
+ SELECT * FROM shards
41
+ WHERE scope = ? AND scope_hash = ? AND is_active = 1
42
+ ORDER BY shard_index DESC LIMIT 1
43
+ `);
44
+ const row = stmt.get(scope, scopeHash);
45
+ if (!row)
46
+ return null;
47
+ return {
48
+ id: row.id,
49
+ scope: row.scope,
50
+ scopeHash: row.scope_hash,
51
+ shardIndex: row.shard_index,
52
+ dbPath: row.db_path,
53
+ vectorCount: row.vector_count,
54
+ isActive: row.is_active === 1,
55
+ createdAt: row.created_at,
56
+ };
57
+ }
58
+ getAllShards(scope, scopeHash) {
59
+ let stmt;
60
+ let rows;
61
+ if (scopeHash === "") {
62
+ stmt = this.metadataDb.prepare(`
63
+ SELECT * FROM shards
64
+ WHERE scope = ?
65
+ ORDER BY shard_index ASC
66
+ `);
67
+ rows = stmt.all(scope);
68
+ }
69
+ else {
70
+ stmt = this.metadataDb.prepare(`
71
+ SELECT * FROM shards
72
+ WHERE scope = ? AND scope_hash = ?
73
+ ORDER BY shard_index ASC
74
+ `);
75
+ rows = stmt.all(scope, scopeHash);
76
+ }
77
+ return rows.map((row) => ({
78
+ id: row.id,
79
+ scope: row.scope,
80
+ scopeHash: row.scope_hash,
81
+ shardIndex: row.shard_index,
82
+ dbPath: row.db_path,
83
+ vectorCount: row.vector_count,
84
+ isActive: row.is_active === 1,
85
+ createdAt: row.created_at,
86
+ }));
87
+ }
88
+ createShard(scope, scopeHash, shardIndex) {
89
+ const dbPath = this.getShardPath(scope, scopeHash, shardIndex);
90
+ const now = Date.now();
91
+ const stmt = this.metadataDb.prepare(`
92
+ INSERT INTO shards (scope, scope_hash, shard_index, db_path, vector_count, is_active, created_at)
93
+ VALUES (?, ?, ?, ?, 0, 1, ?)
94
+ `);
95
+ const result = stmt.run(scope, scopeHash, shardIndex, dbPath, now);
96
+ const db = connectionManager.getConnection(dbPath);
97
+ this.initShardDb(db);
98
+ log("Shard created", { scope, scopeHash, shardIndex, dbPath });
99
+ return {
100
+ id: Number(result.lastInsertRowid),
101
+ scope,
102
+ scopeHash,
103
+ shardIndex,
104
+ dbPath,
105
+ vectorCount: 0,
106
+ isActive: true,
107
+ createdAt: now,
108
+ };
109
+ }
110
+ initShardDb(db) {
111
+ db.run(`
112
+ CREATE TABLE IF NOT EXISTS shard_metadata (
113
+ key TEXT PRIMARY KEY,
114
+ value TEXT NOT NULL
115
+ )
116
+ `);
117
+ db.run(`
118
+ INSERT OR REPLACE INTO shard_metadata (key, value)
119
+ VALUES ('embedding_dimensions', '${CONFIG.embeddingDimensions}')
120
+ `);
121
+ db.run(`
122
+ INSERT OR REPLACE INTO shard_metadata (key, value)
123
+ VALUES ('embedding_model', '${CONFIG.embeddingModel}')
124
+ `);
125
+ db.run(`
126
+ CREATE TABLE IF NOT EXISTS memories (
127
+ id TEXT PRIMARY KEY,
128
+ content TEXT NOT NULL,
129
+ vector BLOB NOT NULL,
130
+ container_tag TEXT NOT NULL,
131
+ type TEXT,
132
+ created_at INTEGER NOT NULL,
133
+ updated_at INTEGER NOT NULL,
134
+ metadata TEXT,
135
+ display_name TEXT,
136
+ user_name TEXT,
137
+ user_email TEXT,
138
+ project_path TEXT,
139
+ project_name TEXT,
140
+ git_repo_url TEXT,
141
+ is_pinned INTEGER DEFAULT 0
142
+ )
143
+ `);
144
+ db.run(`
145
+ CREATE VIRTUAL TABLE IF NOT EXISTS vec_memories USING vec0(
146
+ memory_id TEXT PRIMARY KEY,
147
+ embedding FLOAT[${CONFIG.embeddingDimensions}]
148
+ )
149
+ `);
150
+ db.run(`CREATE INDEX IF NOT EXISTS idx_container_tag ON memories(container_tag)`);
151
+ db.run(`CREATE INDEX IF NOT EXISTS idx_type ON memories(type)`);
152
+ db.run(`CREATE INDEX IF NOT EXISTS idx_created_at ON memories(created_at DESC)`);
153
+ db.run(`CREATE INDEX IF NOT EXISTS idx_is_pinned ON memories(is_pinned)`);
154
+ }
155
+ getWriteShard(scope, scopeHash) {
156
+ let shard = this.getActiveShard(scope, scopeHash);
157
+ if (!shard) {
158
+ return this.createShard(scope, scopeHash, 0);
159
+ }
160
+ if (shard.vectorCount >= CONFIG.maxVectorsPerShard) {
161
+ this.markShardReadOnly(shard.id);
162
+ return this.createShard(scope, scopeHash, shard.shardIndex + 1);
163
+ }
164
+ return shard;
165
+ }
166
+ markShardReadOnly(shardId) {
167
+ const stmt = this.metadataDb.prepare(`
168
+ UPDATE shards SET is_active = 0 WHERE id = ?
169
+ `);
170
+ stmt.run(shardId);
171
+ log("Shard marked read-only", { shardId });
172
+ }
173
+ incrementVectorCount(shardId) {
174
+ const stmt = this.metadataDb.prepare(`
175
+ UPDATE shards SET vector_count = vector_count + 1 WHERE id = ?
176
+ `);
177
+ stmt.run(shardId);
178
+ }
179
+ decrementVectorCount(shardId) {
180
+ const stmt = this.metadataDb.prepare(`
181
+ UPDATE shards SET vector_count = vector_count - 1 WHERE id = ? AND vector_count > 0
182
+ `);
183
+ stmt.run(shardId);
184
+ }
185
+ getShardByPath(dbPath) {
186
+ const stmt = this.metadataDb.prepare(`SELECT * FROM shards WHERE db_path = ?`);
187
+ const row = stmt.get(dbPath);
188
+ if (!row)
189
+ return null;
190
+ return {
191
+ id: row.id,
192
+ scope: row.scope,
193
+ scopeHash: row.scope_hash,
194
+ shardIndex: row.shard_index,
195
+ dbPath: row.db_path,
196
+ vectorCount: row.vector_count,
197
+ isActive: row.is_active === 1,
198
+ createdAt: row.created_at,
199
+ };
200
+ }
201
+ deleteShard(shardId) {
202
+ const stmt = this.metadataDb.prepare(`SELECT db_path FROM shards WHERE id = ?`);
203
+ const row = stmt.get(shardId);
204
+ if (row) {
205
+ connectionManager.closeConnection(row.db_path);
206
+ try {
207
+ const fs = require("node:fs");
208
+ if (fs.existsSync(row.db_path)) {
209
+ fs.unlinkSync(row.db_path);
210
+ }
211
+ }
212
+ catch (error) {
213
+ log("Error deleting shard file", { dbPath: row.db_path, error: String(error) });
214
+ }
215
+ const deleteStmt = this.metadataDb.prepare(`DELETE FROM shards WHERE id = ?`);
216
+ deleteStmt.run(shardId);
217
+ log("Shard deleted", { shardId, dbPath: row.db_path });
218
+ }
219
+ }
220
+ }
221
+ export const shardManager = new ShardManager();
@@ -0,0 +1,39 @@
1
+ export interface ShardInfo {
2
+ id: number;
3
+ scope: "user" | "project";
4
+ scopeHash: string;
5
+ shardIndex: number;
6
+ dbPath: string;
7
+ vectorCount: number;
8
+ isActive: boolean;
9
+ createdAt: number;
10
+ }
11
+ export interface MemoryRecord {
12
+ id: string;
13
+ content: string;
14
+ vector: Float32Array;
15
+ containerTag: string;
16
+ type?: string;
17
+ createdAt: number;
18
+ updatedAt: number;
19
+ metadata?: string;
20
+ displayName?: string;
21
+ userName?: string;
22
+ userEmail?: string;
23
+ projectPath?: string;
24
+ projectName?: string;
25
+ gitRepoUrl?: string;
26
+ }
27
+ export interface SearchResult {
28
+ id: string;
29
+ memory: string;
30
+ similarity: number;
31
+ metadata?: Record<string, unknown>;
32
+ displayName?: string;
33
+ userName?: string;
34
+ userEmail?: string;
35
+ projectPath?: string;
36
+ projectName?: string;
37
+ gitRepoUrl?: string;
38
+ }
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { Database } from "bun:sqlite";
2
+ import type { MemoryRecord, SearchResult, ShardInfo } from "./types.js";
3
+ export declare class VectorSearch {
4
+ insertVector(db: Database, record: MemoryRecord): void;
5
+ searchInShard(shard: ShardInfo, queryVector: Float32Array, containerTag: string, limit: number): SearchResult[];
6
+ searchAcrossShards(shards: ShardInfo[], queryVector: Float32Array, containerTag: string, limit: number, similarityThreshold: number): Promise<SearchResult[]>;
7
+ deleteVector(db: Database, memoryId: string): void;
8
+ listMemories(db: Database, containerTag: string, limit: number): any[];
9
+ getAllMemories(db: Database): any[];
10
+ getMemoryById(db: Database, memoryId: string): any | null;
11
+ countVectors(db: Database, containerTag: string): number;
12
+ countAllVectors(db: Database): number;
13
+ getDistinctTags(db: Database): any[];
14
+ pinMemory(db: Database, memoryId: string): void;
15
+ unpinMemory(db: Database, memoryId: string): void;
16
+ }
17
+ export declare const vectorSearch: VectorSearch;
18
+ //# sourceMappingURL=vector-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/vector-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExE,qBAAa,YAAY;IACvB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IAkCtD,aAAa,CACX,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GACZ,YAAY,EAAE;IA4CX,kBAAkB,CACtB,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IAiB1B,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQlD,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE;IAWtE,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE;IAKnC,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAKzD,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAMxD,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM;IAMrC,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE;IAepC,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK/C,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAIlD;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -0,0 +1,129 @@
1
+ import { Database } from "bun:sqlite";
2
+ import { connectionManager } from "./connection-manager.js";
3
+ import { log } from "../logger.js";
4
+ export class VectorSearch {
5
+ insertVector(db, record) {
6
+ const insertMemory = db.prepare(`
7
+ INSERT INTO memories (
8
+ id, content, vector, container_tag, type, created_at, updated_at,
9
+ metadata, display_name, user_name, user_email, project_path, project_name, git_repo_url
10
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
11
+ `);
12
+ const vectorBuffer = new Uint8Array(record.vector.buffer);
13
+ insertMemory.run(record.id, record.content, vectorBuffer, record.containerTag, record.type || null, record.createdAt, record.updatedAt, record.metadata || null, record.displayName || null, record.userName || null, record.userEmail || null, record.projectPath || null, record.projectName || null, record.gitRepoUrl || null);
14
+ const insertVec = db.prepare(`
15
+ INSERT INTO vec_memories (memory_id, embedding) VALUES (?, ?)
16
+ `);
17
+ insertVec.run(record.id, vectorBuffer);
18
+ }
19
+ searchInShard(shard, queryVector, containerTag, limit) {
20
+ const db = connectionManager.getConnection(shard.dbPath);
21
+ const stmt = db.prepare(`
22
+ SELECT
23
+ m.id,
24
+ m.content,
25
+ m.container_tag,
26
+ m.metadata,
27
+ m.display_name,
28
+ m.user_name,
29
+ m.user_email,
30
+ m.project_path,
31
+ m.project_name,
32
+ m.git_repo_url,
33
+ m.is_pinned,
34
+ v.distance
35
+ FROM vec_memories v
36
+ INNER JOIN memories m ON v.memory_id = m.id
37
+ WHERE v.embedding MATCH ?
38
+ AND v.k = ?
39
+ AND m.container_tag = ?
40
+ ORDER BY v.distance
41
+ `);
42
+ const queryBuffer = new Uint8Array(queryVector.buffer);
43
+ const rows = stmt.all(queryBuffer, limit * 2, containerTag);
44
+ return rows.map((row) => ({
45
+ id: row.id,
46
+ memory: row.content,
47
+ similarity: 1 - row.distance,
48
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
49
+ containerTag: row.container_tag,
50
+ displayName: row.display_name,
51
+ userName: row.user_name,
52
+ userEmail: row.user_email,
53
+ projectPath: row.project_path,
54
+ projectName: row.project_name,
55
+ gitRepoUrl: row.git_repo_url,
56
+ isPinned: row.is_pinned,
57
+ }));
58
+ }
59
+ async searchAcrossShards(shards, queryVector, containerTag, limit, similarityThreshold) {
60
+ const allResults = [];
61
+ for (const shard of shards) {
62
+ try {
63
+ const results = this.searchInShard(shard, queryVector, containerTag, limit);
64
+ allResults.push(...results);
65
+ }
66
+ catch (error) {
67
+ log("Shard search error", { shardId: shard.id, error: String(error) });
68
+ }
69
+ }
70
+ allResults.sort((a, b) => b.similarity - a.similarity);
71
+ return allResults.filter((r) => r.similarity >= similarityThreshold).slice(0, limit);
72
+ }
73
+ deleteVector(db, memoryId) {
74
+ const deleteVec = db.prepare(`DELETE FROM vec_memories WHERE memory_id = ?`);
75
+ deleteVec.run(memoryId);
76
+ const deleteMemory = db.prepare(`DELETE FROM memories WHERE id = ?`);
77
+ deleteMemory.run(memoryId);
78
+ }
79
+ listMemories(db, containerTag, limit) {
80
+ const stmt = db.prepare(`
81
+ SELECT * FROM memories
82
+ WHERE container_tag = ?
83
+ ORDER BY created_at DESC
84
+ LIMIT ?
85
+ `);
86
+ return stmt.all(containerTag, limit);
87
+ }
88
+ getAllMemories(db) {
89
+ const stmt = db.prepare(`SELECT * FROM memories ORDER BY created_at DESC`);
90
+ return stmt.all();
91
+ }
92
+ getMemoryById(db, memoryId) {
93
+ const stmt = db.prepare(`SELECT * FROM memories WHERE id = ?`);
94
+ return stmt.get(memoryId);
95
+ }
96
+ countVectors(db, containerTag) {
97
+ const stmt = db.prepare(`SELECT COUNT(*) as count FROM memories WHERE container_tag = ?`);
98
+ const result = stmt.get(containerTag);
99
+ return result.count;
100
+ }
101
+ countAllVectors(db) {
102
+ const stmt = db.prepare(`SELECT COUNT(*) as count FROM memories`);
103
+ const result = stmt.get();
104
+ return result.count;
105
+ }
106
+ getDistinctTags(db) {
107
+ const stmt = db.prepare(`
108
+ SELECT DISTINCT
109
+ container_tag,
110
+ display_name,
111
+ user_name,
112
+ user_email,
113
+ project_path,
114
+ project_name,
115
+ git_repo_url
116
+ FROM memories
117
+ `);
118
+ return stmt.all();
119
+ }
120
+ pinMemory(db, memoryId) {
121
+ const stmt = db.prepare(`UPDATE memories SET is_pinned = 1 WHERE id = ?`);
122
+ stmt.run(memoryId);
123
+ }
124
+ unpinMemory(db, memoryId) {
125
+ const stmt = db.prepare(`UPDATE memories SET is_pinned = 0 WHERE id = ?`);
126
+ stmt.run(memoryId);
127
+ }
128
+ }
129
+ export const vectorSearch = new VectorSearch();
@@ -0,0 +1,116 @@
1
+ import type { MemoryType } from "../types/index.js";
2
+ interface SearchResult {
3
+ id: string;
4
+ memory: string;
5
+ similarity: number;
6
+ metadata?: Record<string, unknown>;
7
+ displayName?: string;
8
+ userName?: string;
9
+ userEmail?: string;
10
+ projectPath?: string;
11
+ projectName?: string;
12
+ gitRepoUrl?: string;
13
+ }
14
+ interface ProfileData {
15
+ static: string[];
16
+ dynamic: string[];
17
+ }
18
+ export interface EmbeddingService {
19
+ warmup(progressCallback?: (progress: any) => void): Promise<void>;
20
+ embed(text: string): Promise<number[]>;
21
+ isWarmedUp: boolean;
22
+ }
23
+ export declare class SQLiteMemoryClient {
24
+ private db;
25
+ private embedder;
26
+ private isInitialized;
27
+ constructor(embedder: EmbeddingService);
28
+ private initializeDatabase;
29
+ warmup(progressCallback?: (progress: any) => void): Promise<void>;
30
+ isReady(): Promise<boolean>;
31
+ getStatus(): {
32
+ dbConnected: boolean;
33
+ modelLoaded: boolean;
34
+ ready: boolean;
35
+ };
36
+ addMemory(content: string, containerTag: string, metadata?: {
37
+ type?: MemoryType;
38
+ displayName?: string;
39
+ userName?: string;
40
+ userEmail?: string;
41
+ projectPath?: string;
42
+ projectName?: string;
43
+ gitRepoUrl?: string;
44
+ [key: string]: unknown;
45
+ }): Promise<{
46
+ success: true;
47
+ id: string;
48
+ error?: undefined;
49
+ } | {
50
+ success: false;
51
+ error: string;
52
+ id?: undefined;
53
+ }>;
54
+ searchMemories(query: string, containerTag: string): Promise<{
55
+ success: true;
56
+ results: SearchResult[];
57
+ total: number;
58
+ timing: number;
59
+ error?: undefined;
60
+ } | {
61
+ success: false;
62
+ error: string;
63
+ results: never[];
64
+ total: number;
65
+ timing: number;
66
+ }>;
67
+ getProfile(containerTag: string, query?: string): Promise<{
68
+ success: true;
69
+ profile: ProfileData;
70
+ error?: undefined;
71
+ } | {
72
+ success: false;
73
+ error: string;
74
+ profile: null;
75
+ }>;
76
+ listMemories(containerTag: string, limit?: number): Promise<{
77
+ success: true;
78
+ memories: {
79
+ id: any;
80
+ summary: any;
81
+ createdAt: string;
82
+ metadata: any;
83
+ displayName: any;
84
+ userName: any;
85
+ userEmail: any;
86
+ projectPath: any;
87
+ projectName: any;
88
+ gitRepoUrl: any;
89
+ }[];
90
+ pagination: {
91
+ currentPage: number;
92
+ totalItems: number;
93
+ totalPages: number;
94
+ };
95
+ error?: undefined;
96
+ } | {
97
+ success: false;
98
+ error: string;
99
+ memories: never[];
100
+ pagination: {
101
+ currentPage: number;
102
+ totalItems: number;
103
+ totalPages: number;
104
+ };
105
+ }>;
106
+ deleteMemory(memoryId: string): Promise<{
107
+ success: boolean;
108
+ error?: undefined;
109
+ } | {
110
+ success: boolean;
111
+ error: string;
112
+ }>;
113
+ shutdown(): void;
114
+ }
115
+ export {};
116
+ //# sourceMappingURL=sqlite-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-client.d.ts","sourceRoot":"","sources":["../../src/services/sqlite-client.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkBpD,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAkC;IAC5C,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,aAAa,CAAkB;gBAE3B,QAAQ,EAAE,gBAAgB;IAItC,OAAO,CAAC,kBAAkB;IA8CpB,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,SAAS,IAAI;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE;IAQrE,SAAS,CACb,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,UAAU,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB;;;;;;;;;IAqEG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;IA0DlD,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;;;;;;;;;IAyC/C,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,SAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8C7C,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;;;;IA6BnC,QAAQ,IAAI,IAAI;CAQjB"}