@tekmidian/pai 0.66.0 → 0.66.2

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 (165) hide show
  1. package/dist/{aibroker-client-B8c42Lh8.mjs → aibroker-client-CHEEvJZW.mjs} +2 -2
  2. package/dist/{aibroker-client-C5Fw7DNz.mjs → aibroker-client-Dfv7j1Od.mjs} +3 -3
  3. package/dist/{aibroker-client-C5Fw7DNz.mjs.map → aibroker-client-Dfv7j1Od.mjs.map} +1 -1
  4. package/dist/{auto-route-o0BOsXn7.mjs → auto-route-BnizyALK.mjs} +65 -4
  5. package/dist/auto-route-BnizyALK.mjs.map +1 -0
  6. package/dist/auto-route-D6fW1Q8z.mjs +3 -0
  7. package/dist/{chain-D4PuQ2c-.mjs → chain-D5876UQX.mjs} +3 -4
  8. package/dist/{chain-D4PuQ2c-.mjs.map → chain-D5876UQX.mjs.map} +1 -1
  9. package/dist/cli/index.mjs +18 -23
  10. package/dist/cli/index.mjs.map +1 -1
  11. package/dist/cli/program.mjs +17 -22
  12. package/dist/{config-BbLFD7Uf.mjs → config-C-LiGlop.mjs} +2 -2
  13. package/dist/{config-BbLFD7Uf.mjs.map → config-C-LiGlop.mjs.map} +1 -1
  14. package/dist/{config-YinjgXEJ.mjs → config-DKIA7wgF.mjs} +1 -1
  15. package/dist/{context-handover-cache-pkHzmL3c.mjs → context-handover-cache-9PGvXRIw.mjs} +984 -10
  16. package/dist/context-handover-cache-9PGvXRIw.mjs.map +1 -0
  17. package/dist/daemon/index.mjs +17 -19
  18. package/dist/daemon/index.mjs.map +1 -1
  19. package/dist/daemon-BUgNvMUh.mjs +5029 -0
  20. package/dist/daemon-BUgNvMUh.mjs.map +1 -0
  21. package/dist/daemon-DL0eglMJ.mjs +18 -0
  22. package/dist/daemon-mcp/index.mjs +15 -10
  23. package/dist/daemon-mcp/index.mjs.map +1 -1
  24. package/dist/{embeddings-CcscYWwk.mjs → embeddings-CEBGrzwu.mjs} +1 -1
  25. package/dist/{embeddings-Bx3q0QOY.mjs → embeddings-DOLZnT1X.mjs} +1 -1
  26. package/dist/{embeddings-Bx3q0QOY.mjs.map → embeddings-DOLZnT1X.mjs.map} +1 -1
  27. package/dist/{env-JNEIrQWg.mjs → env-DiolswKQ.mjs} +1 -1
  28. package/dist/{env-JNEIrQWg.mjs.map → env-DiolswKQ.mjs.map} +1 -1
  29. package/dist/factory-DrBg24UT.mjs +8 -0
  30. package/dist/factory-Ypf8r0fK.mjs +2892 -0
  31. package/dist/factory-Ypf8r0fK.mjs.map +1 -0
  32. package/dist/{fallback-B5svk75f.mjs → fallback-D51R4shY.mjs} +27 -13
  33. package/dist/fallback-D51R4shY.mjs.map +1 -0
  34. package/dist/{chunker-BH4i-F2b.mjs → helpers-CZsi_49C.mjs} +221 -2
  35. package/dist/helpers-CZsi_49C.mjs.map +1 -0
  36. package/dist/hooks/block-sleep-poll.mjs.map +2 -2
  37. package/dist/hooks/load-project-context.mjs.map +2 -2
  38. package/dist/hooks/worker-guard.mjs +5 -0
  39. package/dist/hooks/worker-guard.mjs.map +2 -2
  40. package/dist/hooks/worker-status-line.mjs +1 -0
  41. package/dist/hooks/worker-status-line.mjs.map +2 -2
  42. package/dist/index.mjs +6 -7
  43. package/dist/{ipc-client-D16Xw6Uo.mjs → ipc-client-BLYX51nG.mjs} +2 -2
  44. package/dist/{ipc-client-D16Xw6Uo.mjs.map → ipc-client-BLYX51nG.mjs.map} +1 -1
  45. package/dist/main-resolver-BYgP86C1.mjs +7 -0
  46. package/dist/{main-resolver-DPPwHNtn.mjs → main-resolver-kVkMJZUD.mjs} +6 -6
  47. package/dist/{main-resolver-DPPwHNtn.mjs.map → main-resolver-kVkMJZUD.mjs.map} +1 -1
  48. package/dist/{migrate-BD7D8EEh.mjs → migrate-Bq0esMOa.mjs} +2 -2
  49. package/dist/{migrate-BD7D8EEh.mjs.map → migrate-Bq0esMOa.mjs.map} +1 -1
  50. package/dist/{pai-marker-D1MMswkz.mjs → pai-marker-DXVpFsYz.mjs} +1 -1
  51. package/dist/{pai-marker-D1MMswkz.mjs.map → pai-marker-DXVpFsYz.mjs.map} +1 -1
  52. package/dist/{planner-EJPZnnif.mjs → planner-D5yt0EfA.mjs} +10 -7
  53. package/dist/{planner-EJPZnnif.mjs.map → planner-D5yt0EfA.mjs.map} +1 -1
  54. package/dist/postgres-BmLr0MUm.mjs +5 -0
  55. package/dist/{postgres-Ceqsa64C.mjs → postgres-D3xc2RB4.mjs} +364 -9
  56. package/dist/postgres-D3xc2RB4.mjs.map +1 -0
  57. package/dist/{program-DSETzrWg.mjs → program-DIXRtAFy.mjs} +80 -70
  58. package/dist/program-DIXRtAFy.mjs.map +1 -0
  59. package/dist/{query-feedback-BIaZTTFO.mjs → query-feedback-B7FYE4JR.mjs} +1 -1
  60. package/dist/{query-feedback-BIaZTTFO.mjs.map → query-feedback-B7FYE4JR.mjs.map} +1 -1
  61. package/dist/{reranker-DKv80KO5.mjs → reranker-3lnggwgq.mjs} +1 -1
  62. package/dist/{reranker-DKv80KO5.mjs.map → reranker-3lnggwgq.mjs.map} +1 -1
  63. package/dist/{reranker-CFiEzHQu.mjs → reranker-CZ2mP4cf.mjs} +1 -1
  64. package/dist/router-BK-hFeQ6.mjs +3 -0
  65. package/dist/{router-a5G7q8_3.mjs → router-BaTbc9VX.mjs} +2 -2
  66. package/dist/{router-a5G7q8_3.mjs.map → router-BaTbc9VX.mjs.map} +1 -1
  67. package/dist/{run-Z4akoa8G.mjs → run-CLYTOm0x.mjs} +764 -25
  68. package/dist/run-CLYTOm0x.mjs.map +1 -0
  69. package/dist/{run-env-DRcp7A8K.mjs → run-env-Bnmf6bRI.mjs} +2 -2
  70. package/dist/{run-env-DRcp7A8K.mjs.map → run-env-Bnmf6bRI.mjs.map} +1 -1
  71. package/dist/{runtime-paths-CHTg3ywb.mjs → runtime-paths-D3FKAm69.mjs} +1 -1
  72. package/dist/{runtime-paths-CHTg3ywb.mjs.map → runtime-paths-D3FKAm69.mjs.map} +1 -1
  73. package/dist/{search-BOSphCJ1.mjs → search-CNAGTiJP.mjs} +2 -2
  74. package/dist/{search-BOSphCJ1.mjs.map → search-CNAGTiJP.mjs.map} +1 -1
  75. package/dist/{sources-CijVso3n.mjs → sources-CM2g-CLT.mjs} +2 -2
  76. package/dist/{sources-CijVso3n.mjs.map → sources-CM2g-CLT.mjs.map} +1 -1
  77. package/dist/{stop-words-BdQuaE9K.mjs → stop-words-DtxaTWU_.mjs} +1 -1
  78. package/dist/{stop-words-BdQuaE9K.mjs.map → stop-words-DtxaTWU_.mjs.map} +1 -1
  79. package/dist/{utils-C9HsYDpO.mjs → utils-DddRwMsG.mjs} +2 -2
  80. package/dist/{utils-C9HsYDpO.mjs.map → utils-DddRwMsG.mjs.map} +1 -1
  81. package/dist/{zettelkasten-CtGHQWPU.mjs → zettelkasten-BhZMvmoK.mjs} +149 -7
  82. package/dist/zettelkasten-BhZMvmoK.mjs.map +1 -0
  83. package/dist/zettelkasten-BwV1pluL.mjs +5 -0
  84. package/docs/commands/worker.md +2 -0
  85. package/package.json +1 -1
  86. package/src/hooks/ts/lib/worker-guard.test.ts +12 -0
  87. package/src/hooks/ts/lib/worker-guard.ts +9 -0
  88. package/dist/async-C2Bm_Lal.mjs +0 -300
  89. package/dist/async-C2Bm_Lal.mjs.map +0 -1
  90. package/dist/auto-route-o0BOsXn7.mjs.map +0 -1
  91. package/dist/chunker-BH4i-F2b.mjs.map +0 -1
  92. package/dist/clusters-BCtD3fbe.mjs +0 -169
  93. package/dist/clusters-BCtD3fbe.mjs.map +0 -1
  94. package/dist/context-handover-cache-pkHzmL3c.mjs.map +0 -1
  95. package/dist/daemon-BEoVgVfJ.mjs +0 -1741
  96. package/dist/daemon-BEoVgVfJ.mjs.map +0 -1
  97. package/dist/daemon-DPAYU9hp.mjs +0 -19
  98. package/dist/detector-BEPFsINR.mjs +0 -3
  99. package/dist/detector-BRTtAWrM.mjs +0 -65
  100. package/dist/detector-BRTtAWrM.mjs.map +0 -1
  101. package/dist/factory-CNpPQQ-5.mjs +0 -249
  102. package/dist/factory-CNpPQQ-5.mjs.map +0 -1
  103. package/dist/factory-DY7x73mE.mjs +0 -3
  104. package/dist/fallback-B5svk75f.mjs.map +0 -1
  105. package/dist/federation-db-BTyoufBh.mjs +0 -139
  106. package/dist/federation-db-BTyoufBh.mjs.map +0 -1
  107. package/dist/federation-db-HfIFc7FG.mjs +0 -3
  108. package/dist/helpers-BRCJg0G3.mjs +0 -223
  109. package/dist/helpers-BRCJg0G3.mjs.map +0 -1
  110. package/dist/indexer-backend-DFF2FrYx.mjs +0 -5
  111. package/dist/indexer-backend-isSLg6yE.mjs +0 -1
  112. package/dist/kg-entity-DCOcsVFD.mjs +0 -29
  113. package/dist/kg-entity-DCOcsVFD.mjs.map +0 -1
  114. package/dist/latent-ideas-wwAXquGe.mjs +0 -191
  115. package/dist/latent-ideas-wwAXquGe.mjs.map +0 -1
  116. package/dist/link-boost-CnI7UVMJ.mjs +0 -34
  117. package/dist/link-boost-CnI7UVMJ.mjs.map +0 -1
  118. package/dist/main-resolver-BKz_OuEh.mjs +0 -7
  119. package/dist/merge-2gqRPFu2.mjs +0 -3
  120. package/dist/merge-DgU9OgZy.mjs +0 -6
  121. package/dist/merge-DgU9OgZy.mjs.map +0 -1
  122. package/dist/module-paths-DdRzbkUI.mjs +0 -44
  123. package/dist/module-paths-DdRzbkUI.mjs.map +0 -1
  124. package/dist/neighborhood-2FsmzoxG.mjs +0 -114
  125. package/dist/neighborhood-2FsmzoxG.mjs.map +0 -1
  126. package/dist/note-context-De63k8na.mjs +0 -106
  127. package/dist/note-context-De63k8na.mjs.map +0 -1
  128. package/dist/postgres-Ceqsa64C.mjs.map +0 -1
  129. package/dist/program-DSETzrWg.mjs.map +0 -1
  130. package/dist/query-feedback-B_iigYj-.mjs +0 -3
  131. package/dist/registry-db-C7voqML9.mjs +0 -213
  132. package/dist/registry-db-C7voqML9.mjs.map +0 -1
  133. package/dist/registry-db-JHPhA8vF.mjs +0 -3
  134. package/dist/registry-postgres-nOfyBSIW.mjs +0 -795
  135. package/dist/registry-postgres-nOfyBSIW.mjs.map +0 -1
  136. package/dist/registry-sqlite-DrCW1aRK.mjs +0 -593
  137. package/dist/registry-sqlite-DrCW1aRK.mjs.map +0 -1
  138. package/dist/router-CXUGsv85.mjs +0 -3
  139. package/dist/run-Z4akoa8G.mjs.map +0 -1
  140. package/dist/search-Bf3Kub3F.mjs +0 -3
  141. package/dist/server-DgmAHyFK.mjs +0 -403
  142. package/dist/server-DgmAHyFK.mjs.map +0 -1
  143. package/dist/session-keepalive-BDhytXEo.mjs +0 -582
  144. package/dist/session-keepalive-BDhytXEo.mjs.map +0 -1
  145. package/dist/sqlite-CqsTy6xo.mjs +0 -936
  146. package/dist/sqlite-CqsTy6xo.mjs.map +0 -1
  147. package/dist/state-DW8zdweW.mjs +0 -3
  148. package/dist/state-HyjqTihC.mjs +0 -76
  149. package/dist/state-HyjqTihC.mjs.map +0 -1
  150. package/dist/themes-CTaOj3e1.mjs +0 -148
  151. package/dist/themes-CTaOj3e1.mjs.map +0 -1
  152. package/dist/tools-BcOKPBtg.mjs +0 -1489
  153. package/dist/tools-BcOKPBtg.mjs.map +0 -1
  154. package/dist/tools-C-_l0o8Z.mjs +0 -6
  155. package/dist/trace-CtV0RO6n.mjs +0 -137
  156. package/dist/trace-CtV0RO6n.mjs.map +0 -1
  157. package/dist/utils-BrX9FLeK.mjs +0 -3
  158. package/dist/vault-indexer-BG1sEVyM.mjs +0 -537
  159. package/dist/vault-indexer-BG1sEVyM.mjs.map +0 -1
  160. package/dist/wakeup-D8n33hYV.mjs +0 -335
  161. package/dist/wakeup-D8n33hYV.mjs.map +0 -1
  162. package/dist/work-queue-worker-4tLa5gpQ.mjs +0 -567
  163. package/dist/work-queue-worker-4tLa5gpQ.mjs.map +0 -1
  164. package/dist/work-queue-worker-rFZvTO3p.mjs +0 -11
  165. package/dist/zettelkasten-CtGHQWPU.mjs.map +0 -1
@@ -1,936 +0,0 @@
1
- import { i as fileContentHash, n as chunkMarkdown, s as sha256File } from "./chunker-BH4i-F2b.mjs";
2
- import { a as parseSessionTitleChunk, c as yieldToEventLoop, i as isPathTooBroadForContentScan, n as chunkId, o as walkContentFiles, r as detectTier, s as walkMdFiles, t as INDEX_YIELD_EVERY } from "./helpers-BRCJg0G3.mjs";
3
- import { t as STOP_WORDS } from "./stop-words-BdQuaE9K.mjs";
4
- import { n as buildFtsQuery, r as isQuerySyntaxError } from "./search-BOSphCJ1.mjs";
5
- import { n as cosineSimilarity, r as deserializeEmbedding } from "./embeddings-Bx3q0QOY.mjs";
6
- import { t as entityContentId } from "./kg-entity-DCOcsVFD.mjs";
7
- import { existsSync, readFileSync, statSync } from "node:fs";
8
- import { basename, join, relative } from "node:path";
9
-
10
- //#region src/storage/sqlite/indexer.ts
11
- /**
12
- * Synchronous (SQLite) indexer — moved from memory/indexer/sync.ts so the
13
- * only file that opens prepared statements against the federation database
14
- * lives under src/storage/ (design doc docs/design/postgres-only.md, unit 7).
15
- *
16
- * Scans project memory/ and Notes/ directories, chunks markdown files, and
17
- * inserts the resulting chunks into the federation memory store for BM25
18
- * search. Uses raw better-sqlite3 Database directly for maximum SQLite
19
- * performance (synchronous transactions, no serialisation overhead) — the
20
- * reason SQLiteBackend keeps this path instead of routing through the
21
- * generic (StorageBackend) indexer that Postgres uses.
22
- */
23
- /**
24
- * Index a single file into the federation database.
25
- *
26
- * @returns true if the file was re-indexed (changed or new), false if skipped.
27
- */
28
- function indexFile(db, projectId, rootPath, relativePath, source, tier) {
29
- const absPath = join(rootPath, relativePath);
30
- let content;
31
- let stat;
32
- try {
33
- content = readFileSync(absPath, "utf8");
34
- stat = statSync(absPath);
35
- } catch {
36
- return false;
37
- }
38
- const hash = fileContentHash(content);
39
- const mtime = Math.floor(stat.mtimeMs);
40
- const size = stat.size;
41
- if (db.prepare("SELECT hash FROM memory_files WHERE project_id = ? AND path = ?").get(projectId, relativePath)?.hash === hash) return false;
42
- const oldChunkIds = db.prepare("SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?").all(projectId, relativePath);
43
- const deleteFts = db.prepare("DELETE FROM memory_fts WHERE id = ?");
44
- const deleteChunk = db.prepare("DELETE FROM memory_chunks WHERE project_id = ? AND path = ?");
45
- db.transaction(() => {
46
- for (const row of oldChunkIds) deleteFts.run(row.id);
47
- deleteChunk.run(projectId, relativePath);
48
- })();
49
- const chunks = chunkMarkdown(content);
50
- const insertChunk = db.prepare(`
51
- INSERT INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)
52
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
53
- `);
54
- const insertFts = db.prepare(`
55
- INSERT INTO memory_fts (text, id, project_id, path, source, tier, start_line, end_line)
56
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
57
- `);
58
- const upsertFile = db.prepare(`
59
- INSERT INTO memory_files (project_id, path, source, tier, hash, mtime, size)
60
- VALUES (?, ?, ?, ?, ?, ?, ?)
61
- ON CONFLICT(project_id, path) DO UPDATE SET
62
- source = excluded.source,
63
- tier = excluded.tier,
64
- hash = excluded.hash,
65
- mtime = excluded.mtime,
66
- size = excluded.size
67
- `);
68
- const updatedAt = Date.now();
69
- db.transaction(() => {
70
- for (let i = 0; i < chunks.length; i++) {
71
- const chunk = chunks[i];
72
- const id = chunkId(projectId, relativePath, i, chunk.startLine, chunk.endLine);
73
- insertChunk.run(id, projectId, source, tier, relativePath, chunk.startLine, chunk.endLine, chunk.hash, chunk.text, updatedAt);
74
- insertFts.run(chunk.text, id, projectId, relativePath, source, tier, chunk.startLine, chunk.endLine);
75
- }
76
- upsertFile.run(projectId, relativePath, source, tier, hash, mtime, size);
77
- })();
78
- return true;
79
- }
80
- /**
81
- * Index all memory, Notes, and content files for a single registered project.
82
- */
83
- async function indexProject(db, projectId, rootPath, claudeNotesDir) {
84
- const result = {
85
- filesProcessed: 0,
86
- chunksCreated: 0,
87
- filesSkipped: 0
88
- };
89
- const filesToIndex = [];
90
- const rootMemoryMd = join(rootPath, "MEMORY.md");
91
- if (existsSync(rootMemoryMd)) filesToIndex.push({
92
- absPath: rootMemoryMd,
93
- rootBase: rootPath,
94
- source: "memory",
95
- tier: "evergreen"
96
- });
97
- const memoryDir = join(rootPath, "memory");
98
- for (const absPath of walkMdFiles(memoryDir)) {
99
- const tier = detectTier(relative(rootPath, absPath));
100
- filesToIndex.push({
101
- absPath,
102
- rootBase: rootPath,
103
- source: "memory",
104
- tier
105
- });
106
- }
107
- const notesDir = join(rootPath, "Notes");
108
- for (const absPath of walkMdFiles(notesDir)) filesToIndex.push({
109
- absPath,
110
- rootBase: rootPath,
111
- source: "notes",
112
- tier: "session"
113
- });
114
- {
115
- const titleInsertChunk = db.prepare(`
116
- INSERT OR IGNORE INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)
117
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
118
- `);
119
- const titleInsertFts = db.prepare(`
120
- INSERT OR IGNORE INTO memory_fts (text, id, project_id, path, source, tier, start_line, end_line)
121
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
122
- `);
123
- const updatedAt = Date.now();
124
- for (const absPath of walkMdFiles(notesDir)) {
125
- const text = parseSessionTitleChunk(basename(absPath));
126
- if (!text) continue;
127
- const syntheticPath = `${relative(rootPath, absPath)}::title`;
128
- const id = chunkId(projectId, syntheticPath, 0, 0, 0);
129
- const hash = sha256File(text);
130
- db.transaction(() => {
131
- titleInsertChunk.run(id, projectId, "notes", "session", syntheticPath, 0, 0, hash, text, updatedAt);
132
- titleInsertFts.run(text, id, projectId, syntheticPath, "notes", "session", 0, 0);
133
- })();
134
- }
135
- }
136
- if (!isPathTooBroadForContentScan(rootPath)) for (const absPath of walkContentFiles(rootPath)) filesToIndex.push({
137
- absPath,
138
- rootBase: rootPath,
139
- source: "content",
140
- tier: "topic"
141
- });
142
- if (claudeNotesDir && claudeNotesDir !== notesDir) {
143
- for (const absPath of walkMdFiles(claudeNotesDir)) filesToIndex.push({
144
- absPath,
145
- rootBase: claudeNotesDir,
146
- source: "notes",
147
- tier: "session"
148
- });
149
- {
150
- const updatedAt = Date.now();
151
- const titleInsertChunk2 = db.prepare(`
152
- INSERT OR IGNORE INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)
153
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
154
- `);
155
- const titleInsertFts2 = db.prepare(`
156
- INSERT OR IGNORE INTO memory_fts (text, id, project_id, path, source, tier, start_line, end_line)
157
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
158
- `);
159
- for (const absPath of walkMdFiles(claudeNotesDir)) {
160
- const text = parseSessionTitleChunk(basename(absPath));
161
- if (!text) continue;
162
- const syntheticPath = `${relative(claudeNotesDir, absPath)}::title`;
163
- const id = chunkId(projectId, syntheticPath, 0, 0, 0);
164
- const hash = sha256File(text);
165
- db.transaction(() => {
166
- titleInsertChunk2.run(id, projectId, "notes", "session", syntheticPath, 0, 0, hash, text, updatedAt);
167
- titleInsertFts2.run(text, id, projectId, syntheticPath, "notes", "session", 0, 0);
168
- })();
169
- }
170
- }
171
- if (claudeNotesDir.endsWith("/Notes")) {
172
- const claudeProjectDir = claudeNotesDir.slice(0, -6);
173
- const claudeMemoryDir = join(claudeProjectDir, "memory");
174
- const claudeMemoryMd = join(claudeProjectDir, "MEMORY.md");
175
- if (existsSync(claudeMemoryMd)) filesToIndex.push({
176
- absPath: claudeMemoryMd,
177
- rootBase: claudeProjectDir,
178
- source: "memory",
179
- tier: "evergreen"
180
- });
181
- for (const absPath of walkMdFiles(claudeMemoryDir)) {
182
- const tier = detectTier(relative(claudeProjectDir, absPath));
183
- filesToIndex.push({
184
- absPath,
185
- rootBase: claudeProjectDir,
186
- source: "memory",
187
- tier
188
- });
189
- }
190
- }
191
- }
192
- await yieldToEventLoop();
193
- let filesSinceYield = 0;
194
- for (const { absPath, rootBase, source, tier } of filesToIndex) {
195
- if (filesSinceYield >= INDEX_YIELD_EVERY) {
196
- await yieldToEventLoop();
197
- filesSinceYield = 0;
198
- }
199
- filesSinceYield++;
200
- const relPath = relative(rootBase, absPath);
201
- if (indexFile(db, projectId, rootBase, relPath, source, tier)) {
202
- const count = db.prepare("SELECT COUNT(*) as n FROM memory_chunks WHERE project_id = ? AND path = ?").get(projectId, relPath);
203
- result.filesProcessed++;
204
- result.chunksCreated += count.n;
205
- } else result.filesSkipped++;
206
- }
207
- const livePaths = /* @__PURE__ */ new Set();
208
- for (const { absPath, rootBase } of filesToIndex) livePaths.add(relative(rootBase, absPath));
209
- const dbChunkPaths = db.prepare("SELECT DISTINCT path FROM memory_chunks WHERE project_id = ?").all(projectId);
210
- const stalePaths = [];
211
- for (const row of dbChunkPaths) {
212
- const basePath = row.path.endsWith("::title") ? row.path.slice(0, -7) : row.path;
213
- if (!livePaths.has(basePath)) stalePaths.push(row.path);
214
- }
215
- if (stalePaths.length > 0) {
216
- const deleteChunksFts = db.prepare("DELETE FROM memory_fts WHERE id = ?");
217
- const deleteChunks = db.prepare("DELETE FROM memory_chunks WHERE project_id = ? AND path = ?");
218
- const deleteFile = db.prepare("DELETE FROM memory_files WHERE project_id = ? AND path = ?");
219
- db.transaction(() => {
220
- for (const stalePath of stalePaths) {
221
- const chunkIds = db.prepare("SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?").all(projectId, stalePath);
222
- for (const { id } of chunkIds) deleteChunksFts.run(id);
223
- deleteChunks.run(projectId, stalePath);
224
- deleteFile.run(projectId, stalePath);
225
- }
226
- })();
227
- }
228
- return result;
229
- }
230
- /**
231
- * Index all active projects registered in the registry DB.
232
- *
233
- * Async: yields to the event loop between each project so that the daemon's
234
- * Unix socket server can process IPC requests (e.g. status) while indexing.
235
- */
236
- async function indexAllSqlite(db, registry) {
237
- const projects = await registry.listProjects({ status: "active" });
238
- const totals = {
239
- filesProcessed: 0,
240
- chunksCreated: 0,
241
- filesSkipped: 0
242
- };
243
- for (const project of projects) {
244
- await yieldToEventLoop();
245
- const r = await indexProject(db, project.id, project.root_path, project.claude_notes_dir);
246
- totals.filesProcessed += r.filesProcessed;
247
- totals.chunksCreated += r.chunksCreated;
248
- totals.filesSkipped += r.filesSkipped;
249
- }
250
- return {
251
- projects: projects.length,
252
- result: totals
253
- };
254
- }
255
-
256
- //#endregion
257
- //#region src/storage/sqlite/tunnels.ts
258
- async function findTunnelsForSlugMap(db, slugMap, opts) {
259
- const projectIds = Object.keys(slugMap).map(Number);
260
- if (projectIds.length < 2) return {
261
- tunnels: [],
262
- projects_analyzed: projectIds.length,
263
- total_concepts_evaluated: 0
264
- };
265
- let candidateTerms = [];
266
- try {
267
- candidateTerms = db.prepare(`SELECT term, SUM(doc) AS doc_count, SUM(cnt) AS total_cnt
268
- FROM memory_fts_v
269
- GROUP BY term
270
- HAVING SUM(cnt) >= ?
271
- ORDER BY SUM(doc) DESC
272
- LIMIT 500`).all(opts.min_occurrences).map((r) => r.term).filter((t) => t.length >= 3 && !STOP_WORDS.has(t));
273
- } catch {
274
- const sampleRows = db.prepare(`SELECT LOWER(text) AS text FROM memory_chunks
275
- WHERE LENGTH(text) > 20
276
- ORDER BY RANDOM()
277
- LIMIT 2000`).all();
278
- const freq = /* @__PURE__ */ new Map();
279
- for (const { text } of sampleRows) {
280
- const tokens = text.split(/[\s\p{P}]+/u).filter(Boolean).filter((t) => t.length >= 3 && !STOP_WORDS.has(t));
281
- for (const t of tokens) freq.set(t, (freq.get(t) ?? 0) + 1);
282
- }
283
- candidateTerms = [...freq.entries()].filter(([, n]) => n >= opts.min_occurrences).sort((a, b) => b[1] - a[1]).slice(0, 200).map(([t]) => t);
284
- }
285
- if (candidateTerms.length === 0) return {
286
- tunnels: [],
287
- projects_analyzed: projectIds.length,
288
- total_concepts_evaluated: 0
289
- };
290
- const tunnels = [];
291
- for (const term of candidateTerms) try {
292
- const rows = db.prepare(`SELECT c.project_id, COUNT(*) AS cnt,
293
- MIN(c.updated_at) AS first_seen,
294
- MAX(c.updated_at) AS last_seen
295
- FROM memory_fts f
296
- JOIN memory_chunks c ON c.id = f.id
297
- WHERE memory_fts MATCH ?
298
- AND c.project_id IN (${projectIds.map(() => "?").join(", ")})
299
- GROUP BY c.project_id`).all(`"${term.replace(/"/g, "\"\"")}"`, ...projectIds);
300
- if (rows.length < opts.min_projects) continue;
301
- const totalOccurrences = rows.reduce((s, r) => s + Number(r.cnt), 0);
302
- if (totalOccurrences < opts.min_occurrences) continue;
303
- const projects = rows.map((r) => slugMap[r.project_id] ?? String(r.project_id)).filter(Boolean);
304
- const firstSeen = Math.min(...rows.map((r) => r.first_seen));
305
- const lastSeen = Math.max(...rows.map((r) => r.last_seen));
306
- tunnels.push({
307
- concept: term,
308
- projects,
309
- occurrences: totalOccurrences,
310
- first_seen: firstSeen,
311
- last_seen: lastSeen
312
- });
313
- } catch {
314
- continue;
315
- }
316
- tunnels.sort((a, b) => {
317
- const byProjects = b.projects.length - a.projects.length;
318
- if (byProjects !== 0) return byProjects;
319
- return b.occurrences - a.occurrences;
320
- });
321
- return {
322
- tunnels: tunnels.slice(0, opts.limit),
323
- projects_analyzed: projectIds.length,
324
- total_concepts_evaluated: candidateTerms.length
325
- };
326
- }
327
- /** Find cross-project concept tunnels against a SQLite federation database. */
328
- async function findTunnelsSqlite(db, registry, options) {
329
- const opts = {
330
- min_projects: options?.min_projects ?? 2,
331
- min_occurrences: options?.min_occurrences ?? 3,
332
- limit: options?.limit ?? 20
333
- };
334
- const projectRows = await registry.listProjects({ excludeArchived: true });
335
- const slugMap = {};
336
- for (const { id, slug } of projectRows) slugMap[id] = slug;
337
- return findTunnelsForSlugMap(db, slugMap, opts);
338
- }
339
-
340
- //#endregion
341
- //#region src/storage/sqlite/sources.ts
342
- function getMemorySourcesReportSqlite(db) {
343
- return {
344
- composition: db.prepare(`SELECT source, tier, COUNT(*) AS chunks,
345
- SUM(CASE WHEN embedding IS NOT NULL THEN 1 ELSE 0 END) AS embedded
346
- FROM memory_chunks GROUP BY source, tier ORDER BY COUNT(*) DESC`).all(),
347
- paths: db.prepare(`SELECT path, COUNT(*) AS chunks FROM memory_chunks GROUP BY path`).all(),
348
- churn: db.prepare(`SELECT date(updated_at/1000,'unixepoch') AS day, COUNT(*) AS chunks,
349
- SUM(CASE WHEN embedding IS NOT NULL THEN 1 ELSE 0 END) AS embedded
350
- FROM memory_chunks GROUP BY day ORDER BY day DESC LIMIT 10`).all()
351
- };
352
- }
353
-
354
- //#endregion
355
- //#region src/storage/sqlite/search.ts
356
- /**
357
- * Search across all indexed memory using FTS5 BM25 ranking.
358
- *
359
- * Results are ordered by BM25 score (most relevant first).
360
- * FTS5 bm25() returns negative values; closer to 0 = more relevant.
361
- * We negate the score so callers get positive values where higher = better.
362
- */
363
- function searchMemory(db, query, opts) {
364
- const maxResults = opts?.maxResults ?? 10;
365
- const ftsQuery = buildFtsQuery(query);
366
- const conditions = [];
367
- const params = [ftsQuery];
368
- if (opts?.projectIds && opts.projectIds.length > 0) {
369
- const placeholders = opts.projectIds.map(() => "?").join(", ");
370
- conditions.push(`c.project_id IN (${placeholders})`);
371
- params.push(...opts.projectIds);
372
- }
373
- if (opts?.sources && opts.sources.length > 0) {
374
- const placeholders = opts.sources.map(() => "?").join(", ");
375
- conditions.push(`c.source IN (${placeholders})`);
376
- params.push(...opts.sources);
377
- }
378
- if (opts?.tiers && opts.tiers.length > 0) {
379
- const placeholders = opts.tiers.map(() => "?").join(", ");
380
- conditions.push(`c.tier IN (${placeholders})`);
381
- params.push(...opts.tiers);
382
- }
383
- const whereClause = conditions.length > 0 ? "AND " + conditions.join(" AND ") : "";
384
- params.push(maxResults);
385
- const sql = `
386
- SELECT
387
- c.id,
388
- c.project_id,
389
- c.path,
390
- c.start_line,
391
- c.end_line,
392
- c.text AS snippet,
393
- c.tier,
394
- c.source,
395
- c.updated_at,
396
- c.last_accessed_at,
397
- c.relevance_score,
398
- bm25(memory_fts) AS bm25_score
399
- FROM memory_fts
400
- JOIN memory_chunks c ON memory_fts.id = c.id
401
- WHERE memory_fts MATCH ?
402
- ${whereClause}
403
- ORDER BY bm25_score
404
- LIMIT ?
405
- `;
406
- let rows;
407
- try {
408
- rows = db.prepare(sql).all(...params);
409
- } catch (e) {
410
- if (!isQuerySyntaxError(e)) throw new Error(`Memory keyword search failed — the index is unusable, so this is NOT an empty result set. Cause: ${e instanceof Error ? e.message : String(e)}`);
411
- return [];
412
- }
413
- const minScore = opts?.minScore ?? 0;
414
- return rows.map((row) => {
415
- const score = -row.bm25_score * (.5 + (row.relevance_score ?? .5));
416
- return {
417
- chunkId: row.id,
418
- projectId: row.project_id,
419
- path: row.path,
420
- startLine: row.start_line,
421
- endLine: row.end_line,
422
- snippet: row.snippet,
423
- score,
424
- tier: row.tier,
425
- source: row.source,
426
- updatedAt: row.updated_at,
427
- lastAccessedAt: row.last_accessed_at ?? void 0
428
- };
429
- }).filter((r) => r.score >= minScore);
430
- }
431
- /**
432
- * Search chunks using brute-force cosine similarity over stored embeddings.
433
- *
434
- * Only chunks that have a non-null embedding BLOB are considered.
435
- *
436
- * @param queryEmbedding Pre-computed Float32Array for the search query.
437
- */
438
- function searchMemorySemantic(db, queryEmbedding, opts) {
439
- const maxResults = opts?.maxResults ?? 10;
440
- const conditions = ["embedding IS NOT NULL"];
441
- const params = [];
442
- if (opts?.projectIds && opts.projectIds.length > 0) {
443
- const placeholders = opts.projectIds.map(() => "?").join(", ");
444
- conditions.push(`project_id IN (${placeholders})`);
445
- params.push(...opts.projectIds);
446
- }
447
- if (opts?.sources && opts.sources.length > 0) {
448
- const placeholders = opts.sources.map(() => "?").join(", ");
449
- conditions.push(`source IN (${placeholders})`);
450
- params.push(...opts.sources);
451
- }
452
- if (opts?.tiers && opts.tiers.length > 0) {
453
- const placeholders = opts.tiers.map(() => "?").join(", ");
454
- conditions.push(`tier IN (${placeholders})`);
455
- params.push(...opts.tiers);
456
- }
457
- const sql = `
458
- SELECT id, project_id, path, start_line, end_line, text, tier, source, embedding, updated_at, last_accessed_at, relevance_score
459
- FROM memory_chunks
460
- ${"WHERE " + conditions.join(" AND ")}
461
- LIMIT 5000
462
- `;
463
- const rows = db.prepare(sql).all(...params);
464
- if (rows.length === 0) return [];
465
- const scored = rows.map((row) => {
466
- const score = cosineSimilarity(queryEmbedding, deserializeEmbedding(row.embedding)) * (.5 + (row.relevance_score ?? .5));
467
- return {
468
- chunkId: row.id,
469
- projectId: row.project_id,
470
- path: row.path,
471
- startLine: row.start_line,
472
- endLine: row.end_line,
473
- snippet: row.text,
474
- score,
475
- tier: row.tier,
476
- source: row.source,
477
- updatedAt: row.updated_at,
478
- lastAccessedAt: row.last_accessed_at ?? void 0
479
- };
480
- });
481
- const minScore = opts?.minScore ?? -Infinity;
482
- return scored.filter((r) => r.score >= minScore).sort((a, b) => b.score - a.score).slice(0, maxResults);
483
- }
484
- /**
485
- * Update last_accessed_at for a set of chunk IDs to the current timestamp.
486
- *
487
- * Best-effort: errors are silently ignored so search is never blocked.
488
- */
489
- function touchChunksLastAccessed(db, chunkIds) {
490
- if (chunkIds.length === 0) return;
491
- try {
492
- const now = Date.now();
493
- const placeholders = chunkIds.map(() => "?").join(", ");
494
- db.prepare(`UPDATE memory_chunks SET last_accessed_at = ? WHERE id IN (${placeholders})`).run(now, ...chunkIds);
495
- } catch {}
496
- }
497
-
498
- //#endregion
499
- //#region src/storage/sqlite/kg-entity.ts
500
- /**
501
- * Upsert a KG entity in the federation SQLite database.
502
- *
503
- * If the entity already exists for this tenant:
504
- * - Updates last_seen to now
505
- * - Increments mention_count
506
- * - Updates description if provided (overwrites older description)
507
- *
508
- * Returns the entity_id for use as a foreign key in kg_triples.
509
- */
510
- function upsertKgEntitySqlite(db, params) {
511
- const tenantId = params.tenantId ?? "default";
512
- const entityId = entityContentId(params.name, tenantId);
513
- const now = Date.now();
514
- db.prepare(`
515
- INSERT INTO kg_entities
516
- (entity_id, tenant_id, name, type, description, first_seen, last_seen, mention_count, feedback_weight)
517
- VALUES
518
- (?, ?, ?, ?, ?, ?, ?, 1, 0.5)
519
- ON CONFLICT(entity_id) DO UPDATE SET
520
- last_seen = excluded.last_seen,
521
- mention_count = mention_count + 1,
522
- description = COALESCE(excluded.description, description),
523
- type = CASE WHEN excluded.type != 'unknown' THEN excluded.type ELSE type END
524
- `).run(entityId, tenantId, params.name, params.type ?? "unknown", params.description ?? null, now, now);
525
- return entityId;
526
- }
527
- /**
528
- * Look up a KG entity by name within a tenant.
529
- * Returns null if the entity does not exist.
530
- */
531
- function findKgEntitySqlite(db, name, tenantId = "default") {
532
- const entityId = entityContentId(name, tenantId);
533
- return db.prepare("SELECT * FROM kg_entities WHERE entity_id = ? AND tenant_id = ?").get(entityId, tenantId) ?? null;
534
- }
535
- /**
536
- * List KG entities for a tenant, optionally filtered by type.
537
- */
538
- function listKgEntitiesSqlite(db, tenantId = "default", type, limit = 100) {
539
- if (type) return db.prepare("SELECT * FROM kg_entities WHERE tenant_id = ? AND type = ? ORDER BY mention_count DESC LIMIT ?").all(tenantId, type, limit);
540
- return db.prepare("SELECT * FROM kg_entities WHERE tenant_id = ? ORDER BY mention_count DESC LIMIT ?").all(tenantId, limit);
541
- }
542
- /**
543
- * Apply an EMA (Exponential Moving Average) feedback update to an entity's weight.
544
- *
545
- * EMA formula: new_weight = old_weight + alpha * (target - old_weight)
546
- */
547
- function updateEntityFeedbackWeightSqlite(db, entityId, normalizedRating, alpha = .1) {
548
- const row = db.prepare("SELECT feedback_weight FROM kg_entities WHERE entity_id = ?").get(entityId);
549
- if (!row) return;
550
- const newWeight = row.feedback_weight + alpha * (normalizedRating - row.feedback_weight);
551
- db.prepare("UPDATE kg_entities SET feedback_weight = ? WHERE entity_id = ?").run(newWeight, entityId);
552
- }
553
-
554
- //#endregion
555
- //#region src/storage/sqlite.ts
556
- var SQLiteBackend = class {
557
- backendType = "sqlite";
558
- supportsPostgresFeatures = false;
559
- db;
560
- constructor(db) {
561
- this.db = db;
562
- }
563
- /**
564
- * Expose the raw better-sqlite3 Database handle. Storage-internal only —
565
- * used by db-admin.ts for `pai db query|tables|schema` (the one place
566
- * outside this class allowed to reach for it). Every other operation must
567
- * be a StorageBackend method; nothing outside src/storage/ may call this.
568
- */
569
- getRawDb() {
570
- return this.db;
571
- }
572
- async close() {
573
- try {
574
- this.db.close();
575
- } catch {}
576
- }
577
- async getStats() {
578
- return {
579
- files: this.db.prepare("SELECT COUNT(*) AS n FROM memory_files").get().n,
580
- chunks: this.db.prepare("SELECT COUNT(*) AS n FROM memory_chunks").get().n
581
- };
582
- }
583
- async getProjectStats(projectId) {
584
- return {
585
- files: this.db.prepare("SELECT COUNT(*) AS n FROM memory_files WHERE project_id = ?").get(projectId).n,
586
- chunks: this.db.prepare("SELECT COUNT(*) AS n FROM memory_chunks WHERE project_id = ?").get(projectId).n
587
- };
588
- }
589
- async getFileHash(projectId, path) {
590
- return this.db.prepare("SELECT hash FROM memory_files WHERE project_id = ? AND path = ?").get(projectId, path)?.hash;
591
- }
592
- async upsertFile(file) {
593
- this.db.prepare(`INSERT INTO memory_files (project_id, path, source, tier, hash, mtime, size)
594
- VALUES (?, ?, ?, ?, ?, ?, ?)
595
- ON CONFLICT(project_id, path) DO UPDATE SET
596
- source = excluded.source,
597
- tier = excluded.tier,
598
- hash = excluded.hash,
599
- mtime = excluded.mtime,
600
- size = excluded.size`).run(file.projectId, file.path, file.source, file.tier, file.hash, file.mtime, file.size);
601
- }
602
- async getChunkIds(projectId, path) {
603
- return this.db.prepare("SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?").all(projectId, path).map((r) => r.id);
604
- }
605
- async deleteChunksForFile(projectId, path) {
606
- const ids = await this.getChunkIds(projectId, path);
607
- const deleteFts = this.db.prepare("DELETE FROM memory_fts WHERE id = ?");
608
- const deleteChunks = this.db.prepare("DELETE FROM memory_chunks WHERE project_id = ? AND path = ?");
609
- this.db.transaction(() => {
610
- for (const id of ids) deleteFts.run(id);
611
- deleteChunks.run(projectId, path);
612
- })();
613
- }
614
- async insertChunks(chunks) {
615
- if (chunks.length === 0) return;
616
- const insertChunk = this.db.prepare(`INSERT INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)
617
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
618
- const insertFts = this.db.prepare(`INSERT INTO memory_fts (text, id, project_id, path, source, tier, start_line, end_line)
619
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
620
- this.db.transaction(() => {
621
- for (const c of chunks) {
622
- insertChunk.run(c.id, c.projectId, c.source, c.tier, c.path, c.startLine, c.endLine, c.hash, c.text, c.updatedAt);
623
- insertFts.run(c.text, c.id, c.projectId, c.path, c.source, c.tier, c.startLine, c.endLine);
624
- }
625
- })();
626
- }
627
- async getDistinctChunkPaths(projectId) {
628
- return this.db.prepare("SELECT DISTINCT path FROM memory_chunks WHERE project_id = ?").all(projectId).map((r) => r.path);
629
- }
630
- async deletePaths(projectId, paths) {
631
- if (paths.length === 0) return;
632
- const deleteFts = this.db.prepare("DELETE FROM memory_fts WHERE id = ?");
633
- const deleteChunks = this.db.prepare("DELETE FROM memory_chunks WHERE project_id = ? AND path = ?");
634
- const deleteFile = this.db.prepare("DELETE FROM memory_files WHERE project_id = ? AND path = ?");
635
- this.db.transaction(() => {
636
- for (const path of paths) {
637
- const ids = this.db.prepare("SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?").all(projectId, path);
638
- for (const { id } of ids) deleteFts.run(id);
639
- deleteChunks.run(projectId, path);
640
- deleteFile.run(projectId, path);
641
- }
642
- })();
643
- }
644
- async getUnembeddedChunkIds(projectId, limit, after) {
645
- const conditions = ["embedding IS NULL"];
646
- const params = [];
647
- if (projectId !== void 0) {
648
- conditions.push("project_id = ?");
649
- params.push(projectId);
650
- }
651
- const paginating = after !== void 0;
652
- if (after) {
653
- conditions.push("(project_id > ? OR (project_id = ? AND id > ?))");
654
- params.push(after.projectId, after.projectId, after.id);
655
- }
656
- const where = "WHERE " + conditions.join(" AND ");
657
- const orderBy = paginating ? "project_id, id" : `CASE
658
- WHEN path LIKE '🧠 Ideaverse/%' THEN 0
659
- WHEN path LIKE 'Z - Zettelkasten/%' THEN 0
660
- WHEN path LIKE '💼 Business/%' THEN 0
661
- WHEN path LIKE '📆 Meetings/%' THEN 1
662
- WHEN path LIKE '💡 Insights/%' THEN 1
663
- WHEN path LIKE '👨‍💻 People/%' THEN 1
664
- WHEN path LIKE 'University/%' THEN 1
665
- WHEN path LIKE 'Copilot/%' THEN 1
666
- WHEN path LIKE '🗓️ Daily Notes/%' THEN 2
667
- WHEN path LIKE 'PAI/%' THEN 3
668
- WHEN path LIKE '09-job-search/%' THEN 4
669
- WHEN path LIKE 'seriousletter/%' THEN 4
670
- WHEN path LIKE 'Attachments/%' THEN 5
671
- ELSE 2
672
- END, id`;
673
- return this.db.prepare(`SELECT id, text, project_id, path FROM memory_chunks ${where}
674
- ORDER BY ${orderBy}${limit !== void 0 ? " LIMIT ?" : ""}`).all(...params, ...limit !== void 0 ? [limit] : []);
675
- }
676
- async updateEmbedding(chunkId, embedding) {
677
- this.db.prepare("UPDATE memory_chunks SET embedding = ? WHERE id = ?").run(embedding, chunkId);
678
- }
679
- async searchKeyword(query, opts) {
680
- return searchMemory(this.db, query, opts);
681
- }
682
- async searchSemantic(queryEmbedding, opts) {
683
- return searchMemorySemantic(this.db, queryEmbedding, opts);
684
- }
685
- vaultNotSupported() {
686
- throw new Error("Vault operations require the Postgres backend");
687
- }
688
- async upsertVaultFile() {
689
- this.vaultNotSupported();
690
- }
691
- async deleteVaultFile() {
692
- this.vaultNotSupported();
693
- }
694
- async getVaultFile() {
695
- this.vaultNotSupported();
696
- }
697
- async getVaultFileByInode() {
698
- this.vaultNotSupported();
699
- }
700
- async getAllVaultFiles() {
701
- this.vaultNotSupported();
702
- }
703
- async getRecentVaultFiles() {
704
- this.vaultNotSupported();
705
- }
706
- async countVaultFiles() {
707
- this.vaultNotSupported();
708
- }
709
- async upsertVaultAliases() {
710
- this.vaultNotSupported();
711
- }
712
- async deleteVaultAliases() {
713
- this.vaultNotSupported();
714
- }
715
- async replaceLinksForSources() {
716
- this.vaultNotSupported();
717
- }
718
- async getLinksFromSource() {
719
- this.vaultNotSupported();
720
- }
721
- async getLinksToTarget() {
722
- this.vaultNotSupported();
723
- }
724
- async getVaultLinkGraph() {
725
- this.vaultNotSupported();
726
- }
727
- async upsertVaultHealth() {
728
- this.vaultNotSupported();
729
- }
730
- async getVaultHealth() {
731
- this.vaultNotSupported();
732
- }
733
- async getOrphans() {
734
- this.vaultNotSupported();
735
- }
736
- async getDeadLinks() {
737
- this.vaultNotSupported();
738
- }
739
- async upsertNameIndex() {
740
- this.vaultNotSupported();
741
- }
742
- async replaceNameIndex() {
743
- this.vaultNotSupported();
744
- }
745
- async resolveVaultName() {
746
- this.vaultNotSupported();
747
- }
748
- async searchVaultNameIndex() {
749
- this.vaultNotSupported();
750
- }
751
- async getVaultFilesByPaths() {
752
- this.vaultNotSupported();
753
- }
754
- async getVaultFilesByPathsAfter() {
755
- this.vaultNotSupported();
756
- }
757
- async getVaultLinksFromPaths() {
758
- this.vaultNotSupported();
759
- }
760
- async getChunksWithEmbeddings() {
761
- this.vaultNotSupported();
762
- }
763
- async getChunksForPath() {
764
- this.vaultNotSupported();
765
- }
766
- async searchChunksByText() {
767
- this.vaultNotSupported();
768
- }
769
- async countVaultFilesWithPrefix() {
770
- this.vaultNotSupported();
771
- }
772
- async countVaultFilesAfter() {
773
- this.vaultNotSupported();
774
- }
775
- async countVaultLinksWithPrefix() {
776
- this.vaultNotSupported();
777
- }
778
- async countVaultLinksAfter() {
779
- this.vaultNotSupported();
780
- }
781
- async getDeadLinksWithLineNumbers() {
782
- this.vaultNotSupported();
783
- }
784
- async getDeadLinksWithPrefix() {
785
- this.vaultNotSupported();
786
- }
787
- async getDeadLinksAfter() {
788
- this.vaultNotSupported();
789
- }
790
- async getOrphansWithPrefix() {
791
- this.vaultNotSupported();
792
- }
793
- async getOrphansAfter() {
794
- this.vaultNotSupported();
795
- }
796
- async getLowConnectivity() {
797
- this.vaultNotSupported();
798
- }
799
- async getLowConnectivityWithPrefix() {
800
- this.vaultNotSupported();
801
- }
802
- async getLowConnectivityAfter() {
803
- this.vaultNotSupported();
804
- }
805
- async getAllVaultFilePaths() {
806
- this.vaultNotSupported();
807
- }
808
- async getVaultFilePathsWithPrefix() {
809
- this.vaultNotSupported();
810
- }
811
- async getVaultFilePathsAfter() {
812
- this.vaultNotSupported();
813
- }
814
- async getVaultLinkEdges() {
815
- this.vaultNotSupported();
816
- }
817
- async getVaultLinkEdgesWithPrefix() {
818
- this.vaultNotSupported();
819
- }
820
- async getVaultLinkEdgesAfter() {
821
- this.vaultNotSupported();
822
- }
823
- async getVaultAlias() {
824
- this.vaultNotSupported();
825
- }
826
- async upsertKgEntity(params) {
827
- return upsertKgEntitySqlite(this.db, params);
828
- }
829
- async findKgEntity(name, tenantId = "default") {
830
- return findKgEntitySqlite(this.db, name, tenantId);
831
- }
832
- async listKgEntities(tenantId = "default", type, limit = 100) {
833
- return listKgEntitiesSqlite(this.db, tenantId, type, limit);
834
- }
835
- async updateEntityFeedbackWeight(entityId, normalizedRating, alpha = .1) {
836
- return updateEntityFeedbackWeightSqlite(this.db, entityId, normalizedRating, alpha);
837
- }
838
- async getChunksForFeedback(chunkIds) {
839
- if (chunkIds.length === 0) return [];
840
- const placeholders = chunkIds.map(() => "?").join(", ");
841
- return this.db.prepare(`SELECT id, text, relevance_score FROM memory_chunks WHERE id IN (${placeholders})`).all(...chunkIds).map((r) => ({
842
- id: r.id,
843
- text: r.text,
844
- relevanceScore: r.relevance_score
845
- }));
846
- }
847
- async updateChunkRelevanceScore(chunkId, score) {
848
- this.db.prepare("UPDATE memory_chunks SET relevance_score = ? WHERE id = ?").run(score, chunkId);
849
- }
850
- async touchChunksLastAccessed(chunkIds) {
851
- touchChunksLastAccessed(this.db, chunkIds);
852
- }
853
- async indexAll(registry) {
854
- return indexAllSqlite(this.db, registry);
855
- }
856
- async findTunnels(registry, options) {
857
- return findTunnelsSqlite(this.db, registry, options);
858
- }
859
- async getMemorySourcesReport() {
860
- return getMemorySourcesReportSqlite(this.db);
861
- }
862
- postgresOnly(feature) {
863
- throw new Error(`${feature} is not supported on the sqlite backend — set "storageBackend": "postgres" in the daemon config`);
864
- }
865
- async addKgTriple() {
866
- this.postgresOnly("kg_triples");
867
- }
868
- async queryKgTriples() {
869
- this.postgresOnly("kg_triples");
870
- }
871
- async invalidateKgTriple() {
872
- this.postgresOnly("kg_triples");
873
- }
874
- async getKgContradictions() {
875
- this.postgresOnly("kg_triples");
876
- }
877
- async getKgStats() {
878
- this.postgresOnly("kg_triples");
879
- }
880
- async storeObservation() {
881
- this.postgresOnly("observations");
882
- }
883
- async storeObservationWithProject() {
884
- this.postgresOnly("observations");
885
- }
886
- async queryObservations() {
887
- this.postgresOnly("observations");
888
- }
889
- async queryRecentObservations() {
890
- this.postgresOnly("observations");
891
- }
892
- async querySessionObservations() {
893
- this.postgresOnly("observations");
894
- }
895
- async getObservationStats() {
896
- this.postgresOnly("observations");
897
- }
898
- async getObservationTypesForPaths() {
899
- return /* @__PURE__ */ new Map();
900
- }
901
- async storeSessionSummary() {
902
- this.postgresOnly("session summaries");
903
- }
904
- async queryRecentSummaries() {
905
- this.postgresOnly("session summaries");
906
- }
907
- async recordSkillInvocation() {
908
- this.postgresOnly("skill telemetry");
909
- }
910
- async querySkillTelemetry() {
911
- this.postgresOnly("skill telemetry");
912
- }
913
- async countFilesWithPaths(paths) {
914
- if (paths.length === 0) return 0;
915
- const placeholders = paths.map(() => "?").join(", ");
916
- return this.db.prepare(`SELECT COUNT(*) AS n FROM memory_files WHERE path IN (${placeholders})`).get(...paths).n;
917
- }
918
- async renameFilePaths(moves) {
919
- if (moves.length === 0) return 0;
920
- const updateFiles = this.db.prepare("UPDATE memory_files SET path = ? WHERE path = ?");
921
- const updateChunks = this.db.prepare("UPDATE memory_chunks SET path = ? WHERE path = ?");
922
- let filesUpdated = 0;
923
- this.db.transaction(() => {
924
- for (const { oldPath, newPath } of moves) {
925
- const r = updateFiles.run(newPath, oldPath);
926
- filesUpdated += r.changes;
927
- updateChunks.run(newPath, oldPath);
928
- }
929
- })();
930
- return filesUpdated;
931
- }
932
- };
933
-
934
- //#endregion
935
- export { SQLiteBackend };
936
- //# sourceMappingURL=sqlite-CqsTy6xo.mjs.map