gnosys 4.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 (188) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1387 -0
  3. package/dist/cli.d.ts +7 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +3753 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +2267 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/archive.d.ts +95 -0
  12. package/dist/lib/archive.d.ts.map +1 -0
  13. package/dist/lib/archive.js +311 -0
  14. package/dist/lib/archive.js.map +1 -0
  15. package/dist/lib/ask.d.ts +77 -0
  16. package/dist/lib/ask.d.ts.map +1 -0
  17. package/dist/lib/ask.js +316 -0
  18. package/dist/lib/ask.js.map +1 -0
  19. package/dist/lib/audit.d.ts +47 -0
  20. package/dist/lib/audit.d.ts.map +1 -0
  21. package/dist/lib/audit.js +136 -0
  22. package/dist/lib/audit.js.map +1 -0
  23. package/dist/lib/bootstrap.d.ts +56 -0
  24. package/dist/lib/bootstrap.d.ts.map +1 -0
  25. package/dist/lib/bootstrap.js +163 -0
  26. package/dist/lib/bootstrap.js.map +1 -0
  27. package/dist/lib/config.d.ts +239 -0
  28. package/dist/lib/config.d.ts.map +1 -0
  29. package/dist/lib/config.js +371 -0
  30. package/dist/lib/config.js.map +1 -0
  31. package/dist/lib/dashboard.d.ts +81 -0
  32. package/dist/lib/dashboard.d.ts.map +1 -0
  33. package/dist/lib/dashboard.js +314 -0
  34. package/dist/lib/dashboard.js.map +1 -0
  35. package/dist/lib/db.d.ts +182 -0
  36. package/dist/lib/db.d.ts.map +1 -0
  37. package/dist/lib/db.js +620 -0
  38. package/dist/lib/db.js.map +1 -0
  39. package/dist/lib/dbSearch.d.ts +65 -0
  40. package/dist/lib/dbSearch.d.ts.map +1 -0
  41. package/dist/lib/dbSearch.js +239 -0
  42. package/dist/lib/dbSearch.js.map +1 -0
  43. package/dist/lib/dbWrite.d.ts +56 -0
  44. package/dist/lib/dbWrite.d.ts.map +1 -0
  45. package/dist/lib/dbWrite.js +171 -0
  46. package/dist/lib/dbWrite.js.map +1 -0
  47. package/dist/lib/dream.d.ts +170 -0
  48. package/dist/lib/dream.d.ts.map +1 -0
  49. package/dist/lib/dream.js +706 -0
  50. package/dist/lib/dream.js.map +1 -0
  51. package/dist/lib/embeddings.d.ts +84 -0
  52. package/dist/lib/embeddings.d.ts.map +1 -0
  53. package/dist/lib/embeddings.js +226 -0
  54. package/dist/lib/embeddings.js.map +1 -0
  55. package/dist/lib/export.d.ts +92 -0
  56. package/dist/lib/export.d.ts.map +1 -0
  57. package/dist/lib/export.js +362 -0
  58. package/dist/lib/export.js.map +1 -0
  59. package/dist/lib/federated.d.ts +113 -0
  60. package/dist/lib/federated.d.ts.map +1 -0
  61. package/dist/lib/federated.js +346 -0
  62. package/dist/lib/federated.js.map +1 -0
  63. package/dist/lib/graph.d.ts +50 -0
  64. package/dist/lib/graph.d.ts.map +1 -0
  65. package/dist/lib/graph.js +118 -0
  66. package/dist/lib/graph.js.map +1 -0
  67. package/dist/lib/history.d.ts +39 -0
  68. package/dist/lib/history.d.ts.map +1 -0
  69. package/dist/lib/history.js +112 -0
  70. package/dist/lib/history.js.map +1 -0
  71. package/dist/lib/hybridSearch.d.ts +80 -0
  72. package/dist/lib/hybridSearch.d.ts.map +1 -0
  73. package/dist/lib/hybridSearch.js +296 -0
  74. package/dist/lib/hybridSearch.js.map +1 -0
  75. package/dist/lib/import.d.ts +52 -0
  76. package/dist/lib/import.d.ts.map +1 -0
  77. package/dist/lib/import.js +365 -0
  78. package/dist/lib/import.js.map +1 -0
  79. package/dist/lib/ingest.d.ts +51 -0
  80. package/dist/lib/ingest.d.ts.map +1 -0
  81. package/dist/lib/ingest.js +144 -0
  82. package/dist/lib/ingest.js.map +1 -0
  83. package/dist/lib/lensing.d.ts +35 -0
  84. package/dist/lib/lensing.d.ts.map +1 -0
  85. package/dist/lib/lensing.js +85 -0
  86. package/dist/lib/lensing.js.map +1 -0
  87. package/dist/lib/llm.d.ts +84 -0
  88. package/dist/lib/llm.d.ts.map +1 -0
  89. package/dist/lib/llm.js +386 -0
  90. package/dist/lib/llm.js.map +1 -0
  91. package/dist/lib/lock.d.ts +28 -0
  92. package/dist/lib/lock.d.ts.map +1 -0
  93. package/dist/lib/lock.js +145 -0
  94. package/dist/lib/lock.js.map +1 -0
  95. package/dist/lib/maintenance.d.ts +124 -0
  96. package/dist/lib/maintenance.d.ts.map +1 -0
  97. package/dist/lib/maintenance.js +587 -0
  98. package/dist/lib/maintenance.js.map +1 -0
  99. package/dist/lib/migrate.d.ts +19 -0
  100. package/dist/lib/migrate.d.ts.map +1 -0
  101. package/dist/lib/migrate.js +260 -0
  102. package/dist/lib/migrate.js.map +1 -0
  103. package/dist/lib/preferences.d.ts +49 -0
  104. package/dist/lib/preferences.d.ts.map +1 -0
  105. package/dist/lib/preferences.js +149 -0
  106. package/dist/lib/preferences.js.map +1 -0
  107. package/dist/lib/projectIdentity.d.ts +66 -0
  108. package/dist/lib/projectIdentity.d.ts.map +1 -0
  109. package/dist/lib/projectIdentity.js +148 -0
  110. package/dist/lib/projectIdentity.js.map +1 -0
  111. package/dist/lib/recall.d.ts +82 -0
  112. package/dist/lib/recall.d.ts.map +1 -0
  113. package/dist/lib/recall.js +289 -0
  114. package/dist/lib/recall.js.map +1 -0
  115. package/dist/lib/resolver.d.ts +116 -0
  116. package/dist/lib/resolver.d.ts.map +1 -0
  117. package/dist/lib/resolver.js +372 -0
  118. package/dist/lib/resolver.js.map +1 -0
  119. package/dist/lib/retry.d.ts +24 -0
  120. package/dist/lib/retry.d.ts.map +1 -0
  121. package/dist/lib/retry.js +60 -0
  122. package/dist/lib/retry.js.map +1 -0
  123. package/dist/lib/rulesGen.d.ts +51 -0
  124. package/dist/lib/rulesGen.d.ts.map +1 -0
  125. package/dist/lib/rulesGen.js +167 -0
  126. package/dist/lib/rulesGen.js.map +1 -0
  127. package/dist/lib/search.d.ts +51 -0
  128. package/dist/lib/search.d.ts.map +1 -0
  129. package/dist/lib/search.js +190 -0
  130. package/dist/lib/search.js.map +1 -0
  131. package/dist/lib/staticSearch.d.ts +70 -0
  132. package/dist/lib/staticSearch.d.ts.map +1 -0
  133. package/dist/lib/staticSearch.js +162 -0
  134. package/dist/lib/staticSearch.js.map +1 -0
  135. package/dist/lib/store.d.ts +79 -0
  136. package/dist/lib/store.d.ts.map +1 -0
  137. package/dist/lib/store.js +227 -0
  138. package/dist/lib/store.js.map +1 -0
  139. package/dist/lib/structuredIngest.d.ts +37 -0
  140. package/dist/lib/structuredIngest.d.ts.map +1 -0
  141. package/dist/lib/structuredIngest.js +208 -0
  142. package/dist/lib/structuredIngest.js.map +1 -0
  143. package/dist/lib/tags.d.ts +26 -0
  144. package/dist/lib/tags.d.ts.map +1 -0
  145. package/dist/lib/tags.js +109 -0
  146. package/dist/lib/tags.js.map +1 -0
  147. package/dist/lib/timeline.d.ts +34 -0
  148. package/dist/lib/timeline.d.ts.map +1 -0
  149. package/dist/lib/timeline.js +116 -0
  150. package/dist/lib/timeline.js.map +1 -0
  151. package/dist/lib/trace.d.ts +42 -0
  152. package/dist/lib/trace.d.ts.map +1 -0
  153. package/dist/lib/trace.js +338 -0
  154. package/dist/lib/trace.js.map +1 -0
  155. package/dist/lib/webIndex.d.ts +28 -0
  156. package/dist/lib/webIndex.d.ts.map +1 -0
  157. package/dist/lib/webIndex.js +208 -0
  158. package/dist/lib/webIndex.js.map +1 -0
  159. package/dist/lib/webIngest.d.ts +51 -0
  160. package/dist/lib/webIngest.d.ts.map +1 -0
  161. package/dist/lib/webIngest.js +533 -0
  162. package/dist/lib/webIngest.js.map +1 -0
  163. package/dist/lib/wikilinks.d.ts +63 -0
  164. package/dist/lib/wikilinks.d.ts.map +1 -0
  165. package/dist/lib/wikilinks.js +146 -0
  166. package/dist/lib/wikilinks.js.map +1 -0
  167. package/dist/sandbox/client.d.ts +82 -0
  168. package/dist/sandbox/client.d.ts.map +1 -0
  169. package/dist/sandbox/client.js +128 -0
  170. package/dist/sandbox/client.js.map +1 -0
  171. package/dist/sandbox/helper-template.d.ts +14 -0
  172. package/dist/sandbox/helper-template.d.ts.map +1 -0
  173. package/dist/sandbox/helper-template.js +285 -0
  174. package/dist/sandbox/helper-template.js.map +1 -0
  175. package/dist/sandbox/index.d.ts +10 -0
  176. package/dist/sandbox/index.d.ts.map +1 -0
  177. package/dist/sandbox/index.js +10 -0
  178. package/dist/sandbox/index.js.map +1 -0
  179. package/dist/sandbox/manager.d.ts +40 -0
  180. package/dist/sandbox/manager.d.ts.map +1 -0
  181. package/dist/sandbox/manager.js +220 -0
  182. package/dist/sandbox/manager.js.map +1 -0
  183. package/dist/sandbox/server.d.ts +44 -0
  184. package/dist/sandbox/server.d.ts.map +1 -0
  185. package/dist/sandbox/server.js +661 -0
  186. package/dist/sandbox/server.js.map +1 -0
  187. package/package.json +103 -0
  188. package/prompts/synthesize.md +21 -0
package/dist/lib/db.js ADDED
@@ -0,0 +1,620 @@
1
+ /**
2
+ * Gnosys DB — Agent-native SQLite core.
3
+ *
4
+ * v2.0: Single gnosys.db per project (.gnosys/gnosys.db)
5
+ * v3.0: Central gnosys.db at ~/.gnosys/gnosys.db with project_id + scope columns
6
+ *
7
+ * 5 tables: memories, memories_fts, relationships, summaries, audit_log.
8
+ * + projects table (v3.0) for project identity registry.
9
+ */
10
+ // Dynamic import — gracefully handles missing native module
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ let Database = null;
13
+ try {
14
+ Database = (await import("better-sqlite3")).default;
15
+ }
16
+ catch {
17
+ // better-sqlite3 not available — db features disabled
18
+ }
19
+ import path from "path";
20
+ import fs from "fs";
21
+ import { enableWAL } from "./lock.js";
22
+ // ─── Schema ─────────────────────────────────────────────────────────────
23
+ const SCHEMA_VERSION = 2;
24
+ const SCHEMA_SQL = `
25
+ CREATE TABLE IF NOT EXISTS memories (
26
+ id TEXT PRIMARY KEY,
27
+ title TEXT NOT NULL,
28
+ category TEXT NOT NULL,
29
+ content TEXT NOT NULL,
30
+ summary TEXT,
31
+ tags TEXT DEFAULT '',
32
+ relevance TEXT DEFAULT '',
33
+ author TEXT NOT NULL DEFAULT 'ai',
34
+ authority TEXT NOT NULL DEFAULT 'imported',
35
+ confidence REAL DEFAULT 0.8,
36
+ reinforcement_count INTEGER DEFAULT 0,
37
+ content_hash TEXT NOT NULL,
38
+ status TEXT DEFAULT 'active',
39
+ tier TEXT DEFAULT 'active',
40
+ supersedes TEXT,
41
+ superseded_by TEXT,
42
+ last_reinforced TEXT,
43
+ created TEXT NOT NULL,
44
+ modified TEXT NOT NULL,
45
+ embedding BLOB,
46
+ source_path TEXT,
47
+ project_id TEXT,
48
+ scope TEXT DEFAULT 'project' CHECK(scope IN ('project','user','global'))
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
52
+ CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status);
53
+ CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier);
54
+ CREATE INDEX IF NOT EXISTS idx_memories_confidence ON memories(confidence);
55
+ CREATE INDEX IF NOT EXISTS idx_memories_last_reinforced ON memories(last_reinforced);
56
+ CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash);
57
+ CREATE INDEX IF NOT EXISTS idx_memories_project_id ON memories(project_id);
58
+ CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope);
59
+
60
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
61
+ id,
62
+ title,
63
+ category,
64
+ tags,
65
+ relevance,
66
+ content,
67
+ summary,
68
+ tokenize='porter unicode61'
69
+ );
70
+
71
+ CREATE TABLE IF NOT EXISTS relationships (
72
+ source_id TEXT NOT NULL,
73
+ target_id TEXT NOT NULL,
74
+ rel_type TEXT NOT NULL DEFAULT 'references',
75
+ label TEXT,
76
+ confidence REAL DEFAULT 1.0,
77
+ created TEXT NOT NULL,
78
+ PRIMARY KEY (source_id, target_id, rel_type)
79
+ );
80
+
81
+ CREATE INDEX IF NOT EXISTS idx_rel_source ON relationships(source_id);
82
+ CREATE INDEX IF NOT EXISTS idx_rel_target ON relationships(target_id);
83
+ CREATE INDEX IF NOT EXISTS idx_rel_type ON relationships(rel_type);
84
+
85
+ CREATE TABLE IF NOT EXISTS summaries (
86
+ id TEXT PRIMARY KEY,
87
+ scope TEXT NOT NULL,
88
+ scope_key TEXT NOT NULL,
89
+ content TEXT NOT NULL,
90
+ source_ids TEXT NOT NULL,
91
+ created TEXT NOT NULL,
92
+ modified TEXT NOT NULL,
93
+ UNIQUE(scope, scope_key)
94
+ );
95
+
96
+ CREATE TABLE IF NOT EXISTS audit_log (
97
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
98
+ timestamp TEXT NOT NULL,
99
+ operation TEXT NOT NULL,
100
+ memory_id TEXT,
101
+ details TEXT,
102
+ duration_ms INTEGER,
103
+ trace_id TEXT
104
+ );
105
+
106
+ CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON audit_log(timestamp);
107
+ CREATE INDEX IF NOT EXISTS idx_audit_operation ON audit_log(operation);
108
+ CREATE INDEX IF NOT EXISTS idx_audit_trace ON audit_log(trace_id);
109
+
110
+ CREATE TABLE IF NOT EXISTS projects (
111
+ id TEXT PRIMARY KEY,
112
+ name TEXT NOT NULL,
113
+ working_directory TEXT NOT NULL UNIQUE,
114
+ user TEXT NOT NULL,
115
+ agent_rules_target TEXT,
116
+ obsidian_vault TEXT,
117
+ created TEXT NOT NULL,
118
+ modified TEXT NOT NULL
119
+ );
120
+ `;
121
+ // FTS5 sync triggers — created separately (can't use IF NOT EXISTS on triggers)
122
+ const FTS_TRIGGERS_SQL = `
123
+ CREATE TRIGGER IF NOT EXISTS memories_fts_ai AFTER INSERT ON memories BEGIN
124
+ INSERT INTO memories_fts(id, title, category, tags, relevance, content, summary)
125
+ VALUES (new.id, new.title, new.category, new.tags, new.relevance, new.content, new.summary);
126
+ END;
127
+
128
+ CREATE TRIGGER IF NOT EXISTS memories_fts_ad AFTER DELETE ON memories BEGIN
129
+ INSERT INTO memories_fts(memories_fts, id, title, category, tags, relevance, content, summary)
130
+ VALUES ('delete', old.id, old.title, old.category, old.tags, old.relevance, old.content, old.summary);
131
+ END;
132
+
133
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
134
+ INSERT INTO memories_fts(memories_fts, id, title, category, tags, relevance, content, summary)
135
+ VALUES ('delete', old.id, old.title, old.category, old.tags, old.relevance, old.content, old.summary);
136
+ INSERT INTO memories_fts(id, title, category, tags, relevance, content, summary)
137
+ VALUES (new.id, new.title, new.category, new.tags, new.relevance, new.content, new.summary);
138
+ END;
139
+ `;
140
+ // ─── Column whitelists (prevent SQL injection via dynamic keys) ──────────
141
+ const MEMORY_COLUMNS = new Set([
142
+ "title", "category", "content", "summary", "tags", "relevance",
143
+ "author", "authority", "confidence", "reinforcement_count", "content_hash",
144
+ "status", "tier", "supersedes", "superseded_by", "last_reinforced",
145
+ "created", "modified", "embedding", "source_path", "project_id", "scope",
146
+ ]);
147
+ const PROJECT_COLUMNS = new Set([
148
+ "name", "working_directory", "user", "agent_rules_target",
149
+ "obsidian_vault", "created", "modified",
150
+ ]);
151
+ // ─── FNV-1a hash (same as embeddings.ts) ────────────────────────────────
152
+ function fnv1a(str) {
153
+ let hash = 0x811c9dc5;
154
+ for (let i = 0; i < str.length; i++) {
155
+ hash ^= str.charCodeAt(i);
156
+ hash = (hash * 0x01000193) >>> 0;
157
+ }
158
+ return hash.toString(16).padStart(8, "0");
159
+ }
160
+ // ─── GnosysDB Class ─────────────────────────────────────────────────────
161
+ export class GnosysDB {
162
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
+ db = null;
164
+ storePath;
165
+ available = false;
166
+ dbFilePath;
167
+ /**
168
+ * Get the central DB directory (~/.gnosys/).
169
+ * Creates it if it doesn't exist.
170
+ */
171
+ static getCentralDbDir() {
172
+ const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
173
+ return path.join(home, ".gnosys");
174
+ }
175
+ /**
176
+ * Get the central DB file path (~/.gnosys/gnosys.db).
177
+ */
178
+ static getCentralDbPath() {
179
+ return path.join(GnosysDB.getCentralDbDir(), "gnosys.db");
180
+ }
181
+ /**
182
+ * Open the central DB at ~/.gnosys/gnosys.db.
183
+ * Creates ~/.gnosys/ directory if needed.
184
+ */
185
+ static openCentral() {
186
+ const dir = GnosysDB.getCentralDbDir();
187
+ fs.mkdirSync(dir, { recursive: true });
188
+ return new GnosysDB(dir);
189
+ }
190
+ constructor(storePath, opts) {
191
+ this.storePath = storePath;
192
+ this.dbFilePath = path.join(storePath, "gnosys.db");
193
+ if (!Database)
194
+ return;
195
+ const maxRetries = opts?.retries ?? 3;
196
+ const retryDelay = opts?.retryDelayMs ?? 500;
197
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
198
+ try {
199
+ fs.mkdirSync(storePath, { recursive: true });
200
+ this.db = new Database(this.dbFilePath);
201
+ enableWAL(this.db);
202
+ this.db.pragma("foreign_keys = ON");
203
+ // Longer busy timeout for network shares (10s)
204
+ this.db.pragma("busy_timeout = 10000");
205
+ this.applySchema();
206
+ this.available = true;
207
+ return; // Success
208
+ }
209
+ catch (err) {
210
+ this.db = null;
211
+ if (attempt < maxRetries) {
212
+ // Synchronous delay for constructor (network share retry)
213
+ const start = Date.now();
214
+ while (Date.now() - start < retryDelay) { /* spin wait */ }
215
+ }
216
+ // Last attempt fails silently — db stays unavailable
217
+ }
218
+ }
219
+ }
220
+ /**
221
+ * Create a backup of the database file.
222
+ * Returns the backup file path.
223
+ */
224
+ async backup(backupDir) {
225
+ if (!this.available)
226
+ throw new Error("Database not available");
227
+ const dir = backupDir || this.storePath;
228
+ fs.mkdirSync(dir, { recursive: true });
229
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
230
+ const backupPath = path.join(dir, `gnosys-backup-${timestamp}.db`);
231
+ await this.db.backup(backupPath);
232
+ return backupPath;
233
+ }
234
+ /**
235
+ * Restore from a backup file. Closes current DB, copies backup over, re-opens.
236
+ */
237
+ static restore(backupPath, targetDir) {
238
+ const dir = targetDir || GnosysDB.getCentralDbDir();
239
+ const targetPath = path.join(dir, "gnosys.db");
240
+ // Validate backup file exists
241
+ if (!fs.existsSync(backupPath)) {
242
+ throw new Error(`Backup file not found: ${backupPath}`);
243
+ }
244
+ // Copy backup over
245
+ fs.copyFileSync(backupPath, targetPath);
246
+ // Re-open
247
+ return new GnosysDB(dir);
248
+ }
249
+ applySchema() {
250
+ // Apply main schema
251
+ this.db.exec(SCHEMA_SQL);
252
+ // Apply triggers (separate because of FTS5 delete syntax)
253
+ try {
254
+ this.db.exec(FTS_TRIGGERS_SQL);
255
+ }
256
+ catch {
257
+ // Triggers may already exist — that's fine
258
+ }
259
+ // Schema migration: v1 → v2 (add project_id, scope, projects table)
260
+ const currentVersion = this.db.pragma("user_version", { simple: true });
261
+ if (currentVersion < SCHEMA_VERSION) {
262
+ this.migrateSchema(currentVersion);
263
+ }
264
+ }
265
+ /**
266
+ * Incremental schema migration.
267
+ * Each version bump adds columns/tables without dropping existing data.
268
+ */
269
+ migrateSchema(fromVersion) {
270
+ if (fromVersion < 2) {
271
+ // v1 → v2: Add project_id and scope columns to memories
272
+ try {
273
+ this.db.exec("ALTER TABLE memories ADD COLUMN project_id TEXT");
274
+ }
275
+ catch {
276
+ // Column already exists — fine
277
+ }
278
+ try {
279
+ this.db.exec("ALTER TABLE memories ADD COLUMN scope TEXT DEFAULT 'project'");
280
+ }
281
+ catch {
282
+ // Column already exists — fine
283
+ }
284
+ // Create indexes for new columns
285
+ try {
286
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_memories_project_id ON memories(project_id)");
287
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope)");
288
+ }
289
+ catch {
290
+ // Indexes may already exist
291
+ }
292
+ // Create projects table
293
+ try {
294
+ this.db.exec(`
295
+ CREATE TABLE IF NOT EXISTS projects (
296
+ id TEXT PRIMARY KEY,
297
+ name TEXT NOT NULL,
298
+ working_directory TEXT NOT NULL UNIQUE,
299
+ user TEXT NOT NULL,
300
+ agent_rules_target TEXT,
301
+ obsidian_vault TEXT,
302
+ created TEXT NOT NULL,
303
+ modified TEXT NOT NULL
304
+ )
305
+ `);
306
+ }
307
+ catch {
308
+ // Table may already exist
309
+ }
310
+ }
311
+ this.db.pragma(`user_version = ${SCHEMA_VERSION}`);
312
+ }
313
+ isAvailable() {
314
+ return this.available;
315
+ }
316
+ getDbPath() {
317
+ return this.dbFilePath;
318
+ }
319
+ getStorePath() {
320
+ return this.storePath;
321
+ }
322
+ // ─── Memory CRUD ────────────────────────────────────────────────────
323
+ insertMemory(mem) {
324
+ const stmt = this.db.prepare(`
325
+ INSERT OR REPLACE INTO memories
326
+ (id, title, category, content, summary, tags, relevance, author, authority,
327
+ confidence, reinforcement_count, content_hash, status, tier, supersedes,
328
+ superseded_by, last_reinforced, created, modified, embedding, source_path,
329
+ project_id, scope)
330
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
331
+ `);
332
+ stmt.run(mem.id, mem.title, mem.category, mem.content, mem.summary || null, mem.tags, mem.relevance, mem.author, mem.authority, mem.confidence, mem.reinforcement_count, mem.content_hash, mem.status, mem.tier, mem.supersedes || null, mem.superseded_by || null, mem.last_reinforced || null, mem.created, mem.modified, mem.embedding || null, mem.source_path || null, mem.project_id || null, mem.scope || "project");
333
+ }
334
+ getMemory(id) {
335
+ return this.db.prepare("SELECT * FROM memories WHERE id = ?").get(id) || null;
336
+ }
337
+ getActiveMemories() {
338
+ return this.db.prepare("SELECT * FROM memories WHERE tier = 'active' AND status = 'active'").all();
339
+ }
340
+ getAllMemories() {
341
+ return this.db.prepare("SELECT * FROM memories").all();
342
+ }
343
+ getMemoriesByTier(tier) {
344
+ return this.db.prepare("SELECT * FROM memories WHERE tier = ?").all(tier);
345
+ }
346
+ getMemoriesByCategory(category) {
347
+ return this.db.prepare("SELECT * FROM memories WHERE category = ? AND tier = 'active'").all(category);
348
+ }
349
+ updateMemory(id, updates) {
350
+ const fields = [];
351
+ const values = [];
352
+ for (const [key, value] of Object.entries(updates)) {
353
+ if (key === "id")
354
+ continue;
355
+ if (!MEMORY_COLUMNS.has(key))
356
+ continue;
357
+ fields.push(`${key} = ?`);
358
+ values.push(value);
359
+ }
360
+ if (fields.length === 0)
361
+ return;
362
+ values.push(id);
363
+ const sql = `UPDATE memories SET ${fields.join(", ")} WHERE id = ?`;
364
+ try {
365
+ this.db.prepare(sql).run(...values);
366
+ }
367
+ catch {
368
+ // FTS5 update trigger may fail if INSERT OR REPLACE left FTS inconsistent.
369
+ // Workaround: drop the trigger, update manually, rebuild FTS entry.
370
+ this.db.exec("DROP TRIGGER IF EXISTS memories_fts_au");
371
+ this.db.prepare(sql).run(...values);
372
+ // Recreate trigger
373
+ try {
374
+ this.db.exec(`
375
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
376
+ INSERT INTO memories_fts(memories_fts, id, title, category, tags, relevance, content, summary)
377
+ VALUES ('delete', old.id, old.title, old.category, old.tags, old.relevance, old.content, old.summary);
378
+ INSERT INTO memories_fts(id, title, category, tags, relevance, content, summary)
379
+ VALUES (new.id, new.title, new.category, new.tags, new.relevance, new.content, new.summary);
380
+ END;
381
+ `);
382
+ }
383
+ catch {
384
+ // Trigger recreation failed — not critical
385
+ }
386
+ }
387
+ // Manually sync FTS: remove old entry, insert updated entry (reliable for standalone FTS5)
388
+ try {
389
+ this.db.prepare("DELETE FROM memories_fts WHERE id = ?").run(id);
390
+ }
391
+ catch {
392
+ // Old FTS entry may not exist — that's OK
393
+ }
394
+ const newMem = this.db.prepare("SELECT * FROM memories WHERE id = ?").get(id);
395
+ if (newMem) {
396
+ try {
397
+ this.db.prepare("INSERT INTO memories_fts(id, title, category, tags, relevance, content, summary) VALUES (?, ?, ?, ?, ?, ?, ?)").run(newMem.id, newMem.title, newMem.category, newMem.tags, newMem.relevance, newMem.content, newMem.summary);
398
+ }
399
+ catch {
400
+ // FTS insert may fail — not critical
401
+ }
402
+ }
403
+ }
404
+ deleteMemory(id) {
405
+ // FTS5 delete trigger may fail if INSERT OR REPLACE left FTS inconsistent.
406
+ try {
407
+ this.db.prepare("DELETE FROM memories WHERE id = ?").run(id);
408
+ }
409
+ catch {
410
+ // FTS trigger failed — drop trigger, delete without it
411
+ this.db.exec("DROP TRIGGER IF EXISTS memories_fts_ad");
412
+ this.db.prepare("DELETE FROM memories WHERE id = ?").run(id);
413
+ // Recreate trigger
414
+ try {
415
+ this.db.exec(`
416
+ CREATE TRIGGER IF NOT EXISTS memories_fts_ad AFTER DELETE ON memories BEGIN
417
+ INSERT INTO memories_fts(memories_fts, id, title, category, tags, relevance, content, summary)
418
+ VALUES ('delete', old.id, old.title, old.category, old.tags, old.relevance, old.content, old.summary);
419
+ END;
420
+ `);
421
+ }
422
+ catch {
423
+ // Trigger recreation failed — not critical
424
+ }
425
+ }
426
+ // Ensure FTS entry is also removed (direct DELETE is reliable for standalone FTS5)
427
+ try {
428
+ this.db.prepare("DELETE FROM memories_fts WHERE id = ?").run(id);
429
+ }
430
+ catch {
431
+ // FTS entry may not exist — that's OK
432
+ }
433
+ }
434
+ getMemoryCount() {
435
+ const active = this.db.prepare("SELECT COUNT(*) as cnt FROM memories WHERE tier = 'active'").get().cnt;
436
+ const archived = this.db.prepare("SELECT COUNT(*) as cnt FROM memories WHERE tier = 'archive'").get().cnt;
437
+ return { active, archived, total: active + archived };
438
+ }
439
+ getCategories() {
440
+ const rows = this.db.prepare("SELECT DISTINCT category FROM memories WHERE tier = 'active' ORDER BY category").all();
441
+ return rows.map((r) => r.category);
442
+ }
443
+ // ─── Scoped Queries (v3.0) ──────────────────────────────────────────
444
+ /**
445
+ * Get active memories scoped to a specific project.
446
+ */
447
+ getMemoriesByProject(projectId) {
448
+ return this.db.prepare("SELECT * FROM memories WHERE project_id = ? AND tier = 'active' AND status = 'active'").all(projectId);
449
+ }
450
+ /**
451
+ * Get memories by scope (project, user, global).
452
+ */
453
+ getMemoriesByScope(scope) {
454
+ return this.db.prepare("SELECT * FROM memories WHERE scope = ? AND tier = 'active' AND status = 'active'").all(scope);
455
+ }
456
+ // ─── Project Identity (v3.0) ──────────────────────────────────────
457
+ insertProject(project) {
458
+ this.db.prepare(`
459
+ INSERT OR REPLACE INTO projects
460
+ (id, name, working_directory, user, agent_rules_target, obsidian_vault, created, modified)
461
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
462
+ `).run(project.id, project.name, project.working_directory, project.user, project.agent_rules_target || null, project.obsidian_vault || null, project.created, project.modified);
463
+ }
464
+ getProject(id) {
465
+ return this.db.prepare("SELECT * FROM projects WHERE id = ?").get(id) || null;
466
+ }
467
+ getProjectByDirectory(dir) {
468
+ return this.db.prepare("SELECT * FROM projects WHERE working_directory = ?").get(dir) || null;
469
+ }
470
+ getAllProjects() {
471
+ return this.db.prepare("SELECT * FROM projects ORDER BY name").all();
472
+ }
473
+ updateProject(id, updates) {
474
+ const fields = [];
475
+ const values = [];
476
+ for (const [key, value] of Object.entries(updates)) {
477
+ if (key === "id")
478
+ continue;
479
+ if (!PROJECT_COLUMNS.has(key))
480
+ continue;
481
+ fields.push(`${key} = ?`);
482
+ values.push(value);
483
+ }
484
+ if (fields.length === 0)
485
+ return;
486
+ values.push(id);
487
+ this.db.prepare(`UPDATE projects SET ${fields.join(", ")} WHERE id = ?`).run(...values);
488
+ }
489
+ // ─── FTS5 Search ────────────────────────────────────────────────────
490
+ searchFts(query, limit = 20) {
491
+ const safeQuery = query.replace(/['"]/g, "").trim();
492
+ if (!safeQuery)
493
+ return [];
494
+ try {
495
+ return this.db.prepare(`
496
+ SELECT id, title,
497
+ snippet(memories_fts, 5, '>>>', '<<<', '...', 40) as snippet,
498
+ rank
499
+ FROM memories_fts
500
+ WHERE memories_fts MATCH ?
501
+ ORDER BY rank
502
+ LIMIT ?
503
+ `).all(safeQuery, limit);
504
+ }
505
+ catch {
506
+ // FTS5 syntax error — fallback to LIKE
507
+ const pattern = `%${safeQuery}%`;
508
+ return this.db.prepare(`
509
+ SELECT id, title, substr(content, 1, 200) as snippet, 0 as rank
510
+ FROM memories WHERE content LIKE ? OR title LIKE ? OR tags LIKE ?
511
+ LIMIT ?
512
+ `).all(pattern, pattern, pattern, limit);
513
+ }
514
+ }
515
+ discoverFts(query, limit = 20) {
516
+ const safeQuery = query.replace(/['"]/g, "").trim();
517
+ if (!safeQuery)
518
+ return [];
519
+ try {
520
+ const colQuery = `{relevance title tags} : ${safeQuery}`;
521
+ const results = this.db.prepare(`
522
+ SELECT id, title, relevance, rank
523
+ FROM memories_fts WHERE memories_fts MATCH ? ORDER BY rank LIMIT ?
524
+ `).all(colQuery, limit);
525
+ if (results.length > 0)
526
+ return results;
527
+ return this.db.prepare(`
528
+ SELECT id, title, relevance, rank
529
+ FROM memories_fts WHERE memories_fts MATCH ? ORDER BY rank LIMIT ?
530
+ `).all(safeQuery, limit);
531
+ }
532
+ catch {
533
+ try {
534
+ return this.db.prepare(`
535
+ SELECT id, title, relevance, rank
536
+ FROM memories_fts WHERE memories_fts MATCH ? ORDER BY rank LIMIT ?
537
+ `).all(safeQuery, limit);
538
+ }
539
+ catch {
540
+ return [];
541
+ }
542
+ }
543
+ }
544
+ // ─── Relationships ──────────────────────────────────────────────────
545
+ insertRelationship(rel) {
546
+ this.db.prepare(`
547
+ INSERT OR IGNORE INTO relationships (source_id, target_id, rel_type, label, confidence, created)
548
+ VALUES (?, ?, ?, ?, ?, ?)
549
+ `).run(rel.source_id, rel.target_id, rel.rel_type, rel.label, rel.confidence, rel.created);
550
+ }
551
+ getRelationshipsFrom(id) {
552
+ return this.db.prepare("SELECT * FROM relationships WHERE source_id = ?").all(id);
553
+ }
554
+ getRelationshipsTo(id) {
555
+ return this.db.prepare("SELECT * FROM relationships WHERE target_id = ?").all(id);
556
+ }
557
+ // ─── Summaries ──────────────────────────────────────────────────────
558
+ upsertSummary(summary) {
559
+ this.db.prepare(`
560
+ INSERT INTO summaries (id, scope, scope_key, content, source_ids, created, modified)
561
+ VALUES (?, ?, ?, ?, ?, ?, ?)
562
+ ON CONFLICT(scope, scope_key) DO UPDATE SET
563
+ content = excluded.content,
564
+ source_ids = excluded.source_ids,
565
+ modified = excluded.modified
566
+ `).run(summary.id, summary.scope, summary.scope_key, summary.content, summary.source_ids, summary.created, summary.modified);
567
+ }
568
+ getSummary(scope, scopeKey) {
569
+ return this.db.prepare("SELECT * FROM summaries WHERE scope = ? AND scope_key = ?").get(scope, scopeKey) || null;
570
+ }
571
+ getAllSummaries() {
572
+ return this.db.prepare("SELECT * FROM summaries").all();
573
+ }
574
+ // ─── Audit ──────────────────────────────────────────────────────────
575
+ logAudit(entry) {
576
+ this.db.prepare(`
577
+ INSERT INTO audit_log (timestamp, operation, memory_id, details, duration_ms, trace_id)
578
+ VALUES (?, ?, ?, ?, ?, ?)
579
+ `).run(entry.timestamp, entry.operation, entry.memory_id, entry.details, entry.duration_ms, entry.trace_id);
580
+ }
581
+ // ─── Embeddings ─────────────────────────────────────────────────────
582
+ updateEmbedding(id, embedding) {
583
+ this.db.prepare("UPDATE memories SET embedding = ? WHERE id = ?").run(embedding, id);
584
+ }
585
+ getEmbedding(id) {
586
+ const row = this.db.prepare("SELECT embedding FROM memories WHERE id = ?").get(id);
587
+ return row?.embedding || null;
588
+ }
589
+ getAllEmbeddings() {
590
+ return this.db.prepare("SELECT id, embedding FROM memories WHERE embedding IS NOT NULL").all();
591
+ }
592
+ getEmbeddingCount() {
593
+ const row = this.db.prepare("SELECT COUNT(*) as cnt FROM memories WHERE embedding IS NOT NULL").get();
594
+ return row.cnt;
595
+ }
596
+ // ─── Transactions ───────────────────────────────────────────────────
597
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
598
+ transaction(fn) {
599
+ return this.db.transaction(fn)();
600
+ }
601
+ // ─── Lifecycle ──────────────────────────────────────────────────────
602
+ close() {
603
+ this.db?.close();
604
+ }
605
+ // ─── Migration Status ───────────────────────────────────────────────
606
+ isMigrated() {
607
+ if (!this.available)
608
+ return false;
609
+ const count = this.db.prepare("SELECT COUNT(*) as cnt FROM memories").get().cnt;
610
+ return count > 0;
611
+ }
612
+ getSchemaVersion() {
613
+ if (!this.available)
614
+ return 0;
615
+ return this.db.pragma("user_version", { simple: true });
616
+ }
617
+ }
618
+ // ─── Migration Helper ─────────────────────────────────────────────────
619
+ export { fnv1a };
620
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"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"}