kynjal-cli 4.0.0 → 4.0.1

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 (502) hide show
  1. package/dist/src/appliance/gguf-engine.d.ts +91 -0
  2. package/dist/src/appliance/gguf-engine.d.ts.map +1 -0
  3. package/dist/src/appliance/gguf-engine.js +286 -525
  4. package/dist/src/appliance/gguf-engine.js.map +1 -1
  5. package/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
  6. package/dist/src/appliance/ruvllm-bridge.d.ts.map +1 -0
  7. package/dist/src/appliance/ruvllm-bridge.js +203 -403
  8. package/dist/src/appliance/ruvllm-bridge.js.map +1 -1
  9. package/dist/src/appliance/rvfa-builder.d.ts +44 -0
  10. package/dist/src/appliance/rvfa-builder.d.ts.map +1 -0
  11. package/dist/src/appliance/rvfa-builder.js +154 -208
  12. package/dist/src/appliance/rvfa-builder.js.map +1 -1
  13. package/dist/src/appliance/rvfa-distribution.d.ts +97 -0
  14. package/dist/src/appliance/rvfa-distribution.d.ts.map +1 -0
  15. package/dist/src/appliance/rvfa-distribution.js +260 -423
  16. package/dist/src/appliance/rvfa-distribution.js.map +1 -1
  17. package/dist/src/appliance/rvfa-format.d.ts +111 -0
  18. package/dist/src/appliance/rvfa-format.d.ts.map +1 -0
  19. package/dist/src/appliance/rvfa-format.js +128 -200
  20. package/dist/src/appliance/rvfa-format.js.map +1 -1
  21. package/dist/src/appliance/rvfa-runner.d.ts +69 -0
  22. package/dist/src/appliance/rvfa-runner.d.ts.map +1 -0
  23. package/dist/src/appliance/rvfa-runner.js +168 -304
  24. package/dist/src/appliance/rvfa-runner.js.map +1 -1
  25. package/dist/src/appliance/rvfa-signing.d.ts +123 -0
  26. package/dist/src/appliance/rvfa-signing.d.ts.map +1 -0
  27. package/dist/src/appliance/rvfa-signing.js +173 -295
  28. package/dist/src/appliance/rvfa-signing.js.map +1 -1
  29. package/dist/src/benchmarks/pretrain/index.d.ts +58 -0
  30. package/dist/src/benchmarks/pretrain/index.d.ts.map +1 -0
  31. package/dist/src/benchmarks/pretrain/index.js +331 -542
  32. package/dist/src/benchmarks/pretrain/index.js.map +1 -1
  33. package/dist/src/commands/agent.js +574 -697
  34. package/dist/src/commands/agent.js.map +1 -1
  35. package/dist/src/commands/analyze.js +1218 -1548
  36. package/dist/src/commands/analyze.js.map +1 -1
  37. package/dist/src/commands/appliance-advanced.js +158 -267
  38. package/dist/src/commands/appliance-advanced.js.map +1 -1
  39. package/dist/src/commands/appliance.js +318 -493
  40. package/dist/src/commands/appliance.js.map +1 -1
  41. package/dist/src/commands/benchmark.js +372 -523
  42. package/dist/src/commands/benchmark.js.map +1 -1
  43. package/dist/src/commands/claims.js +274 -364
  44. package/dist/src/commands/claims.js.map +1 -1
  45. package/dist/src/commands/cleanup.js +113 -157
  46. package/dist/src/commands/cleanup.js.map +1 -1
  47. package/dist/src/commands/completions.js +477 -118
  48. package/dist/src/commands/completions.js.map +1 -1
  49. package/dist/src/commands/config.js +237 -303
  50. package/dist/src/commands/config.js.map +1 -1
  51. package/dist/src/commands/daemon.js +487 -596
  52. package/dist/src/commands/daemon.js.map +1 -1
  53. package/dist/src/commands/deployment.js +194 -275
  54. package/dist/src/commands/deployment.js.map +1 -1
  55. package/dist/src/commands/doctor.js +504 -686
  56. package/dist/src/commands/doctor.js.map +1 -1
  57. package/dist/src/commands/embeddings.js +1293 -1543
  58. package/dist/src/commands/embeddings.js.map +1 -1
  59. package/dist/src/commands/guidance.js +449 -596
  60. package/dist/src/commands/guidance.js.map +1 -1
  61. package/dist/src/commands/hive-mind.js +854 -938
  62. package/dist/src/commands/hive-mind.js.map +1 -1
  63. package/dist/src/commands/hooks.js +3112 -3519
  64. package/dist/src/commands/hooks.js.map +1 -1
  65. package/dist/src/commands/index.d.ts +115 -0
  66. package/dist/src/commands/index.d.ts.map +1 -0
  67. package/dist/src/commands/index.js +126 -308
  68. package/dist/src/commands/index.js.map +1 -1
  69. package/dist/src/commands/init.js +788 -940
  70. package/dist/src/commands/init.js.map +1 -1
  71. package/dist/src/commands/issues.js +383 -558
  72. package/dist/src/commands/issues.js.map +1 -1
  73. package/dist/src/commands/mcp.js +493 -605
  74. package/dist/src/commands/mcp.js.map +1 -1
  75. package/dist/src/commands/memory.js +833 -1026
  76. package/dist/src/commands/memory.js.map +1 -1
  77. package/dist/src/commands/migrate.js +282 -347
  78. package/dist/src/commands/migrate.js.map +1 -1
  79. package/dist/src/commands/neural.js +1289 -1563
  80. package/dist/src/commands/neural.js.map +1 -1
  81. package/dist/src/commands/performance.js +497 -643
  82. package/dist/src/commands/performance.js.map +1 -1
  83. package/dist/src/commands/plugins.js +668 -841
  84. package/dist/src/commands/plugins.js.map +1 -1
  85. package/dist/src/commands/process.js +392 -447
  86. package/dist/src/commands/process.js.map +1 -1
  87. package/dist/src/commands/progress.js +162 -256
  88. package/dist/src/commands/progress.js.map +1 -1
  89. package/dist/src/commands/providers.js +150 -220
  90. package/dist/src/commands/providers.js.map +1 -1
  91. package/dist/src/commands/route.js +520 -665
  92. package/dist/src/commands/route.js.map +1 -1
  93. package/dist/src/commands/ruvector/backup.js +505 -651
  94. package/dist/src/commands/ruvector/backup.js.map +1 -1
  95. package/dist/src/commands/ruvector/benchmark.js +349 -401
  96. package/dist/src/commands/ruvector/benchmark.js.map +1 -1
  97. package/dist/src/commands/ruvector/import.js +224 -266
  98. package/dist/src/commands/ruvector/import.js.map +1 -1
  99. package/dist/src/commands/ruvector/index.js +37 -75
  100. package/dist/src/commands/ruvector/index.js.map +1 -1
  101. package/dist/src/commands/ruvector/init.js +336 -359
  102. package/dist/src/commands/ruvector/init.js.map +1 -1
  103. package/dist/src/commands/ruvector/migrate.js +335 -322
  104. package/dist/src/commands/ruvector/migrate.js.map +1 -1
  105. package/dist/src/commands/ruvector/optimize.js +375 -431
  106. package/dist/src/commands/ruvector/optimize.js.map +1 -1
  107. package/dist/src/commands/ruvector/setup.js +703 -117
  108. package/dist/src/commands/ruvector/setup.js.map +1 -1
  109. package/dist/src/commands/ruvector/status.js +364 -419
  110. package/dist/src/commands/ruvector/status.js.map +1 -1
  111. package/dist/src/commands/security.js +485 -608
  112. package/dist/src/commands/security.js.map +1 -1
  113. package/dist/src/commands/session.js +504 -626
  114. package/dist/src/commands/session.js.map +1 -1
  115. package/dist/src/commands/start.js +267 -364
  116. package/dist/src/commands/start.js.map +1 -1
  117. package/dist/src/commands/status.js +380 -486
  118. package/dist/src/commands/status.js.map +1 -1
  119. package/dist/src/commands/swarm.js +408 -488
  120. package/dist/src/commands/swarm.js.map +1 -1
  121. package/dist/src/commands/task.js +423 -538
  122. package/dist/src/commands/task.js.map +1 -1
  123. package/dist/src/commands/transfer-store.js +322 -412
  124. package/dist/src/commands/transfer-store.js.map +1 -1
  125. package/dist/src/commands/update.js +196 -291
  126. package/dist/src/commands/update.js.map +1 -1
  127. package/dist/src/commands/workflow.js +386 -486
  128. package/dist/src/commands/workflow.js.map +1 -1
  129. package/dist/src/config-adapter.d.ts +15 -0
  130. package/dist/src/config-adapter.d.ts.map +1 -0
  131. package/dist/src/config-adapter.js +38 -39
  132. package/dist/src/config-adapter.js.map +1 -1
  133. package/dist/src/index.d.ts +77 -0
  134. package/dist/src/index.d.ts.map +1 -0
  135. package/dist/src/index.js +309 -411
  136. package/dist/src/index.js.map +1 -1
  137. package/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
  138. package/dist/src/infrastructure/in-memory-repositories.d.ts.map +1 -0
  139. package/dist/src/infrastructure/in-memory-repositories.js +246 -507
  140. package/dist/src/infrastructure/in-memory-repositories.js.map +1 -1
  141. package/dist/src/init/claudemd-generator.d.ts +25 -0
  142. package/dist/src/init/claudemd-generator.d.ts.map +1 -0
  143. package/dist/src/init/claudemd-generator.js +368 -78
  144. package/dist/src/init/claudemd-generator.js.map +1 -1
  145. package/dist/src/init/executor.d.ts +41 -0
  146. package/dist/src/init/executor.d.ts.map +1 -0
  147. package/dist/src/init/executor.js +1307 -996
  148. package/dist/src/init/executor.js.map +1 -1
  149. package/dist/src/init/helpers-generator.d.ts +60 -0
  150. package/dist/src/init/helpers-generator.d.ts.map +1 -0
  151. package/dist/src/init/helpers-generator.js +657 -12
  152. package/dist/src/init/helpers-generator.js.map +1 -1
  153. package/dist/src/init/index.d.ts +1 -1
  154. package/dist/src/init/index.d.ts.map +1 -1
  155. package/dist/src/init/index.js +1 -1
  156. package/dist/src/init/index.js.map +1 -1
  157. package/dist/src/init/mcp-generator.js +33 -37
  158. package/dist/src/init/mcp-generator.js.map +1 -1
  159. package/dist/src/init/settings-generator.js +76 -77
  160. package/dist/src/init/settings-generator.js.map +1 -1
  161. package/dist/src/init/statusline-generator.js +801 -3
  162. package/dist/src/init/statusline-generator.js.map +1 -1
  163. package/dist/src/init/types.d.ts +1 -1
  164. package/dist/src/init/types.d.ts.map +1 -1
  165. package/dist/src/init/types.js +76 -59
  166. package/dist/src/init/types.js.map +1 -1
  167. package/dist/src/mcp-client.d.ts +92 -0
  168. package/dist/src/mcp-client.d.ts.map +1 -0
  169. package/dist/src/mcp-client.js +81 -125
  170. package/dist/src/mcp-client.js.map +1 -1
  171. package/dist/src/mcp-server.d.ts +161 -0
  172. package/dist/src/mcp-server.d.ts.map +1 -0
  173. package/dist/src/mcp-server.js +470 -757
  174. package/dist/src/mcp-server.js.map +1 -1
  175. package/dist/src/mcp-tools/agent-tools.js +391 -492
  176. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  177. package/dist/src/mcp-tools/agentdb-tools.js +332 -533
  178. package/dist/src/mcp-tools/agentdb-tools.js.map +1 -1
  179. package/dist/src/mcp-tools/analyze-tools.js +172 -236
  180. package/dist/src/mcp-tools/analyze-tools.js.map +1 -1
  181. package/dist/src/mcp-tools/auto-install.d.ts +83 -0
  182. package/dist/src/mcp-tools/auto-install.d.ts.map +1 -0
  183. package/dist/src/mcp-tools/auto-install.js +80 -142
  184. package/dist/src/mcp-tools/auto-install.js.map +1 -1
  185. package/dist/src/mcp-tools/browser-tools.js +252 -375
  186. package/dist/src/mcp-tools/browser-tools.js.map +1 -1
  187. package/dist/src/mcp-tools/claims-tools.js +473 -565
  188. package/dist/src/mcp-tools/claims-tools.js.map +1 -1
  189. package/dist/src/mcp-tools/config-tools.js +197 -272
  190. package/dist/src/mcp-tools/config-tools.js.map +1 -1
  191. package/dist/src/mcp-tools/coordination-tools.js +500 -572
  192. package/dist/src/mcp-tools/coordination-tools.js.map +1 -1
  193. package/dist/src/mcp-tools/daa-tools.js +286 -364
  194. package/dist/src/mcp-tools/daa-tools.js.map +1 -1
  195. package/dist/src/mcp-tools/embeddings-tools.js +582 -693
  196. package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
  197. package/dist/src/mcp-tools/github-tools.js +260 -311
  198. package/dist/src/mcp-tools/github-tools.js.map +1 -1
  199. package/dist/src/mcp-tools/hive-mind-tools.js +573 -640
  200. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
  201. package/dist/src/mcp-tools/hooks-tools.js +2215 -2648
  202. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  203. package/dist/src/mcp-tools/memory-tools.js +350 -505
  204. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  205. package/dist/src/mcp-tools/neural-tools.js +315 -412
  206. package/dist/src/mcp-tools/neural-tools.js.map +1 -1
  207. package/dist/src/mcp-tools/performance-tools.js +420 -480
  208. package/dist/src/mcp-tools/performance-tools.js.map +1 -1
  209. package/dist/src/mcp-tools/progress-tools.js +204 -278
  210. package/dist/src/mcp-tools/progress-tools.js.map +1 -1
  211. package/dist/src/mcp-tools/ruvllm-tools.js +163 -279
  212. package/dist/src/mcp-tools/ruvllm-tools.js.map +1 -1
  213. package/dist/src/mcp-tools/security-tools.js +297 -429
  214. package/dist/src/mcp-tools/security-tools.js.map +1 -1
  215. package/dist/src/mcp-tools/session-tools.js +185 -234
  216. package/dist/src/mcp-tools/session-tools.js.map +1 -1
  217. package/dist/src/mcp-tools/swarm-tools.js +207 -260
  218. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  219. package/dist/src/mcp-tools/system-tools.js +276 -325
  220. package/dist/src/mcp-tools/system-tools.js.map +1 -1
  221. package/dist/src/mcp-tools/task-tools.js +270 -336
  222. package/dist/src/mcp-tools/task-tools.js.map +1 -1
  223. package/dist/src/mcp-tools/terminal-tools.js +148 -196
  224. package/dist/src/mcp-tools/terminal-tools.js.map +1 -1
  225. package/dist/src/mcp-tools/transfer-tools.js +186 -333
  226. package/dist/src/mcp-tools/transfer-tools.js.map +1 -1
  227. package/dist/src/mcp-tools/types.d.ts +31 -0
  228. package/dist/src/mcp-tools/types.d.ts.map +1 -0
  229. package/dist/src/mcp-tools/wasm-agent-tools.js +133 -280
  230. package/dist/src/mcp-tools/wasm-agent-tools.js.map +1 -1
  231. package/dist/src/mcp-tools/workflow-tools.js +405 -450
  232. package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
  233. package/dist/src/memory/ewc-consolidation.d.ts +295 -0
  234. package/dist/src/memory/ewc-consolidation.d.ts.map +1 -0
  235. package/dist/src/memory/ewc-consolidation.js +190 -303
  236. package/dist/src/memory/ewc-consolidation.js.map +1 -1
  237. package/dist/src/memory/intelligence.d.ts +338 -0
  238. package/dist/src/memory/intelligence.d.ts.map +1 -0
  239. package/dist/src/memory/intelligence.js +569 -794
  240. package/dist/src/memory/intelligence.js.map +1 -1
  241. package/dist/src/memory/memory-bridge.d.ts +407 -0
  242. package/dist/src/memory/memory-bridge.d.ts.map +1 -0
  243. package/dist/src/memory/memory-bridge.js +1170 -1640
  244. package/dist/src/memory/memory-bridge.js.map +1 -1
  245. package/dist/src/memory/memory-initializer.d.ts +412 -0
  246. package/dist/src/memory/memory-initializer.d.ts.map +1 -0
  247. package/dist/src/memory/memory-initializer.js +1836 -1851
  248. package/dist/src/memory/memory-initializer.js.map +1 -1
  249. package/dist/src/memory/sona-optimizer.d.ts +227 -0
  250. package/dist/src/memory/sona-optimizer.d.ts.map +1 -0
  251. package/dist/src/memory/sona-optimizer.js +199 -329
  252. package/dist/src/memory/sona-optimizer.js.map +1 -1
  253. package/dist/src/output.d.ts +2 -2
  254. package/dist/src/output.d.ts.map +1 -1
  255. package/dist/src/output.js +242 -272
  256. package/dist/src/output.js.map +1 -1
  257. package/dist/src/parser.d.ts +51 -0
  258. package/dist/src/parser.d.ts.map +1 -0
  259. package/dist/src/parser.js +140 -187
  260. package/dist/src/parser.js.map +1 -1
  261. package/dist/src/plugins/manager.d.ts +133 -0
  262. package/dist/src/plugins/manager.d.ts.map +1 -0
  263. package/dist/src/plugins/manager.js +285 -521
  264. package/dist/src/plugins/manager.js.map +1 -1
  265. package/dist/src/plugins/store/discovery.d.ts +88 -0
  266. package/dist/src/plugins/store/discovery.d.ts.map +1 -0
  267. package/dist/src/plugins/store/discovery.js +271 -358
  268. package/dist/src/plugins/store/discovery.js.map +1 -1
  269. package/dist/src/plugins/store/index.d.ts +76 -0
  270. package/dist/src/plugins/store/index.d.ts.map +1 -0
  271. package/dist/src/plugins/store/index.js +48 -105
  272. package/dist/src/plugins/store/index.js.map +1 -1
  273. package/dist/src/plugins/store/search.d.ts +46 -0
  274. package/dist/src/plugins/store/search.d.ts.map +1 -0
  275. package/dist/src/plugins/store/search.js +69 -107
  276. package/dist/src/plugins/store/search.js.map +1 -1
  277. package/dist/src/plugins/store/types.d.ts +274 -0
  278. package/dist/src/plugins/store/types.d.ts.map +1 -0
  279. package/dist/src/plugins/tests/demo-plugin-store.js +113 -160
  280. package/dist/src/plugins/tests/demo-plugin-store.js.map +1 -1
  281. package/dist/src/plugins/tests/standalone-test.js +172 -223
  282. package/dist/src/plugins/tests/standalone-test.js.map +1 -1
  283. package/dist/src/plugins/tests/test-plugin-store.js +190 -228
  284. package/dist/src/plugins/tests/test-plugin-store.js.map +1 -1
  285. package/dist/src/production/circuit-breaker.d.ts +101 -0
  286. package/dist/src/production/circuit-breaker.d.ts.map +1 -0
  287. package/dist/src/production/circuit-breaker.js +62 -126
  288. package/dist/src/production/circuit-breaker.js.map +1 -1
  289. package/dist/src/production/error-handler.d.ts +92 -0
  290. package/dist/src/production/error-handler.d.ts.map +1 -0
  291. package/dist/src/production/error-handler.js +86 -156
  292. package/dist/src/production/error-handler.js.map +1 -1
  293. package/dist/src/production/monitoring.d.ts +161 -0
  294. package/dist/src/production/monitoring.d.ts.map +1 -0
  295. package/dist/src/production/monitoring.js +139 -220
  296. package/dist/src/production/monitoring.js.map +1 -1
  297. package/dist/src/production/rate-limiter.d.ts +80 -0
  298. package/dist/src/production/rate-limiter.d.ts.map +1 -0
  299. package/dist/src/production/rate-limiter.js +74 -93
  300. package/dist/src/production/rate-limiter.js.map +1 -1
  301. package/dist/src/production/retry.d.ts +48 -0
  302. package/dist/src/production/retry.d.ts.map +1 -0
  303. package/dist/src/production/retry.js +75 -167
  304. package/dist/src/production/retry.js.map +1 -1
  305. package/dist/src/prompt.d.ts +44 -0
  306. package/dist/src/prompt.d.ts.map +1 -0
  307. package/dist/src/prompt.js +436 -560
  308. package/dist/src/prompt.js.map +1 -1
  309. package/dist/src/runtime/headless.d.ts +60 -0
  310. package/dist/src/runtime/headless.d.ts.map +1 -0
  311. package/dist/src/runtime/headless.js +197 -286
  312. package/dist/src/runtime/headless.js.map +1 -1
  313. package/dist/src/ruvector/agent-wasm.d.ts +182 -0
  314. package/dist/src/ruvector/agent-wasm.d.ts.map +1 -0
  315. package/dist/src/ruvector/agent-wasm.js +156 -351
  316. package/dist/src/ruvector/agent-wasm.js.map +1 -1
  317. package/dist/src/ruvector/ast-analyzer.d.ts +67 -0
  318. package/dist/src/ruvector/ast-analyzer.d.ts.map +1 -0
  319. package/dist/src/ruvector/ast-analyzer.js +145 -232
  320. package/dist/src/ruvector/ast-analyzer.js.map +1 -1
  321. package/dist/src/ruvector/coverage-router.d.ts +160 -0
  322. package/dist/src/ruvector/coverage-router.d.ts.map +1 -0
  323. package/dist/src/ruvector/coverage-router.js +287 -419
  324. package/dist/src/ruvector/coverage-router.js.map +1 -1
  325. package/dist/src/ruvector/coverage-tools.js +56 -101
  326. package/dist/src/ruvector/coverage-tools.js.map +1 -1
  327. package/dist/src/ruvector/diff-classifier.d.ts +175 -0
  328. package/dist/src/ruvector/diff-classifier.d.ts.map +1 -0
  329. package/dist/src/ruvector/diff-classifier.js +324 -451
  330. package/dist/src/ruvector/diff-classifier.js.map +1 -1
  331. package/dist/src/ruvector/enhanced-model-router.d.ts +146 -0
  332. package/dist/src/ruvector/enhanced-model-router.d.ts.map +1 -0
  333. package/dist/src/ruvector/enhanced-model-router.js +260 -336
  334. package/dist/src/ruvector/enhanced-model-router.js.map +1 -1
  335. package/dist/src/ruvector/flash-attention.d.ts +195 -0
  336. package/dist/src/ruvector/flash-attention.d.ts.map +1 -0
  337. package/dist/src/ruvector/flash-attention.js +223 -254
  338. package/dist/src/ruvector/flash-attention.js.map +1 -1
  339. package/dist/src/ruvector/graph-analyzer.d.ts +187 -0
  340. package/dist/src/ruvector/graph-analyzer.d.ts.map +1 -0
  341. package/dist/src/ruvector/graph-analyzer.js +486 -680
  342. package/dist/src/ruvector/graph-analyzer.js.map +1 -1
  343. package/dist/src/ruvector/index.d.ts +40 -0
  344. package/dist/src/ruvector/index.d.ts.map +1 -0
  345. package/dist/src/ruvector/index.js +36 -106
  346. package/dist/src/ruvector/index.js.map +1 -1
  347. package/dist/src/ruvector/lora-adapter.d.ts +218 -0
  348. package/dist/src/ruvector/lora-adapter.d.ts.map +1 -0
  349. package/dist/src/ruvector/lora-adapter.js +155 -248
  350. package/dist/src/ruvector/lora-adapter.js.map +1 -1
  351. package/dist/src/ruvector/model-router.d.ts +220 -0
  352. package/dist/src/ruvector/model-router.d.ts.map +1 -0
  353. package/dist/src/ruvector/model-router.js +175 -248
  354. package/dist/src/ruvector/model-router.js.map +1 -1
  355. package/dist/src/ruvector/moe-router.d.ts +206 -0
  356. package/dist/src/ruvector/moe-router.d.ts.map +1 -0
  357. package/dist/src/ruvector/moe-router.js +228 -286
  358. package/dist/src/ruvector/moe-router.js.map +1 -1
  359. package/dist/src/ruvector/q-learning-router.d.ts +211 -0
  360. package/dist/src/ruvector/q-learning-router.d.ts.map +1 -0
  361. package/dist/src/ruvector/q-learning-router.js +257 -338
  362. package/dist/src/ruvector/q-learning-router.js.map +1 -1
  363. package/dist/src/ruvector/ruvllm-wasm.d.ts +179 -0
  364. package/dist/src/ruvector/ruvllm-wasm.d.ts.map +1 -0
  365. package/dist/src/ruvector/ruvllm-wasm.js +270 -434
  366. package/dist/src/ruvector/ruvllm-wasm.js.map +1 -1
  367. package/dist/src/ruvector/semantic-router.d.ts +77 -0
  368. package/dist/src/ruvector/semantic-router.d.ts.map +1 -0
  369. package/dist/src/ruvector/semantic-router.js +60 -67
  370. package/dist/src/ruvector/semantic-router.js.map +1 -1
  371. package/dist/src/ruvector/vector-db.d.ts +69 -0
  372. package/dist/src/ruvector/vector-db.d.ts.map +1 -0
  373. package/dist/src/ruvector/vector-db.js +119 -205
  374. package/dist/src/ruvector/vector-db.js.map +1 -1
  375. package/dist/src/services/agentic-flow-bridge.d.ts +50 -0
  376. package/dist/src/services/agentic-flow-bridge.d.ts.map +1 -0
  377. package/dist/src/services/agentic-flow-bridge.js +32 -105
  378. package/dist/src/services/agentic-flow-bridge.js.map +1 -1
  379. package/dist/src/services/claim-service.d.ts +204 -0
  380. package/dist/src/services/claim-service.d.ts.map +1 -0
  381. package/dist/src/services/claim-service.js +615 -940
  382. package/dist/src/services/claim-service.js.map +1 -1
  383. package/dist/src/services/container-worker-pool.d.ts +197 -0
  384. package/dist/src/services/container-worker-pool.d.ts.map +1 -0
  385. package/dist/src/services/container-worker-pool.js +398 -666
  386. package/dist/src/services/container-worker-pool.js.map +1 -1
  387. package/dist/src/services/headless-worker-executor.d.ts +304 -0
  388. package/dist/src/services/headless-worker-executor.d.ts.map +1 -0
  389. package/dist/src/services/headless-worker-executor.js +441 -467
  390. package/dist/src/services/headless-worker-executor.js.map +1 -1
  391. package/dist/src/services/index.d.ts +4 -4
  392. package/dist/src/services/index.d.ts.map +1 -1
  393. package/dist/src/services/index.js +4 -4
  394. package/dist/src/services/index.js.map +1 -1
  395. package/dist/src/services/registry-api.d.ts +58 -0
  396. package/dist/src/services/registry-api.d.ts.map +1 -0
  397. package/dist/src/services/registry-api.js +92 -200
  398. package/dist/src/services/registry-api.js.map +1 -1
  399. package/dist/src/services/ruvector-training.d.ts +222 -0
  400. package/dist/src/services/ruvector-training.d.ts.map +1 -0
  401. package/dist/src/services/ruvector-training.js +257 -337
  402. package/dist/src/services/ruvector-training.js.map +1 -1
  403. package/dist/src/services/worker-daemon.d.ts +228 -0
  404. package/dist/src/services/worker-daemon.d.ts.map +1 -0
  405. package/dist/src/services/worker-daemon.js +591 -849
  406. package/dist/src/services/worker-daemon.js.map +1 -1
  407. package/dist/src/services/worker-queue.d.ts +194 -0
  408. package/dist/src/services/worker-queue.d.ts.map +1 -0
  409. package/dist/src/services/worker-queue.js +331 -548
  410. package/dist/src/services/worker-queue.js.map +1 -1
  411. package/dist/src/suggest.d.ts +53 -0
  412. package/dist/src/suggest.d.ts.map +1 -0
  413. package/dist/src/suggest.js +45 -55
  414. package/dist/src/suggest.js.map +1 -1
  415. package/dist/src/transfer/anonymization/index.js +29 -37
  416. package/dist/src/transfer/anonymization/index.js.map +1 -1
  417. package/dist/src/transfer/deploy-seraphine.js +128 -155
  418. package/dist/src/transfer/deploy-seraphine.js.map +1 -1
  419. package/dist/src/transfer/export.d.ts +25 -0
  420. package/dist/src/transfer/export.d.ts.map +1 -0
  421. package/dist/src/transfer/export.js +84 -142
  422. package/dist/src/transfer/export.js.map +1 -1
  423. package/dist/src/transfer/index.d.ts +1 -1
  424. package/dist/src/transfer/index.d.ts.map +1 -1
  425. package/dist/src/transfer/index.js +0 -2
  426. package/dist/src/transfer/index.js.map +1 -1
  427. package/dist/src/transfer/ipfs/client.d.ts +109 -0
  428. package/dist/src/transfer/ipfs/client.d.ts.map +1 -0
  429. package/dist/src/transfer/ipfs/client.js +187 -337
  430. package/dist/src/transfer/ipfs/client.js.map +1 -1
  431. package/dist/src/transfer/ipfs/upload.d.ts +95 -0
  432. package/dist/src/transfer/ipfs/upload.d.ts.map +1 -0
  433. package/dist/src/transfer/ipfs/upload.js +288 -434
  434. package/dist/src/transfer/ipfs/upload.js.map +1 -1
  435. package/dist/src/transfer/models/seraphine.d.ts +72 -0
  436. package/dist/src/transfer/models/seraphine.d.ts.map +1 -0
  437. package/dist/src/transfer/models/seraphine.js +55 -55
  438. package/dist/src/transfer/models/seraphine.js.map +1 -1
  439. package/dist/src/transfer/serialization/cfp.d.ts +49 -0
  440. package/dist/src/transfer/serialization/cfp.d.ts.map +1 -0
  441. package/dist/src/transfer/serialization/cfp.js +30 -31
  442. package/dist/src/transfer/serialization/cfp.js.map +1 -1
  443. package/dist/src/transfer/storage/gcs.d.ts +82 -0
  444. package/dist/src/transfer/storage/gcs.d.ts.map +1 -0
  445. package/dist/src/transfer/storage/gcs.js +165 -232
  446. package/dist/src/transfer/storage/gcs.js.map +1 -1
  447. package/dist/src/transfer/store/discovery.d.ts +84 -0
  448. package/dist/src/transfer/store/discovery.d.ts.map +1 -0
  449. package/dist/src/transfer/store/discovery.js +239 -349
  450. package/dist/src/transfer/store/discovery.js.map +1 -1
  451. package/dist/src/transfer/store/download.d.ts +70 -0
  452. package/dist/src/transfer/store/download.d.ts.map +1 -0
  453. package/dist/src/transfer/store/download.js +243 -365
  454. package/dist/src/transfer/store/download.js.map +1 -1
  455. package/dist/src/transfer/store/index.d.ts +84 -0
  456. package/dist/src/transfer/store/index.d.ts.map +1 -0
  457. package/dist/src/transfer/store/index.js +63 -130
  458. package/dist/src/transfer/store/index.js.map +1 -1
  459. package/dist/src/transfer/store/publish.d.ts +76 -0
  460. package/dist/src/transfer/store/publish.d.ts.map +1 -0
  461. package/dist/src/transfer/store/publish.js +184 -258
  462. package/dist/src/transfer/store/publish.js.map +1 -1
  463. package/dist/src/transfer/store/registry.js +50 -72
  464. package/dist/src/transfer/store/registry.js.map +1 -1
  465. package/dist/src/transfer/store/search.d.ts +54 -0
  466. package/dist/src/transfer/store/search.d.ts.map +1 -0
  467. package/dist/src/transfer/store/search.js +64 -96
  468. package/dist/src/transfer/store/search.js.map +1 -1
  469. package/dist/src/transfer/store/tests/standalone-test.js +174 -231
  470. package/dist/src/transfer/store/tests/standalone-test.js.map +1 -1
  471. package/dist/src/transfer/test-seraphine.js +95 -130
  472. package/dist/src/transfer/test-seraphine.js.map +1 -1
  473. package/dist/src/transfer/tests/test-store.js +194 -239
  474. package/dist/src/transfer/tests/test-store.js.map +1 -1
  475. package/dist/src/transfer/types.d.ts +245 -0
  476. package/dist/src/transfer/types.d.ts.map +1 -0
  477. package/dist/src/types.d.ts +198 -0
  478. package/dist/src/types.d.ts.map +1 -0
  479. package/dist/src/types.js +26 -55
  480. package/dist/src/types.js.map +1 -1
  481. package/dist/src/update/checker.d.ts +34 -0
  482. package/dist/src/update/checker.d.ts.map +1 -0
  483. package/dist/src/update/checker.js +106 -183
  484. package/dist/src/update/checker.js.map +1 -1
  485. package/dist/src/update/executor.d.ts +32 -0
  486. package/dist/src/update/executor.d.ts.map +1 -0
  487. package/dist/src/update/executor.js +135 -198
  488. package/dist/src/update/executor.js.map +1 -1
  489. package/dist/src/update/index.d.ts +33 -0
  490. package/dist/src/update/index.d.ts.map +1 -0
  491. package/dist/src/update/index.js +38 -85
  492. package/dist/src/update/index.js.map +1 -1
  493. package/dist/src/update/rate-limiter.d.ts +20 -0
  494. package/dist/src/update/rate-limiter.d.ts.map +1 -0
  495. package/dist/src/update/rate-limiter.js +19 -31
  496. package/dist/src/update/rate-limiter.js.map +1 -1
  497. package/dist/src/update/validator.d.ts +17 -0
  498. package/dist/src/update/validator.d.ts.map +1 -0
  499. package/dist/src/update/validator.js +38 -64
  500. package/dist/src/update/validator.js.map +1 -1
  501. package/dist/tsconfig.tsbuildinfo +1 -1
  502. package/package.json +1 -1
@@ -8,384 +8,563 @@
8
8
  *
9
9
  * @module v3/cli/memory-initializer
10
10
  */
11
- var __assign = (this && this.__assign) || function () {
12
- __assign = Object.assign || function(t) {
13
- for (var s, i = 1, n = arguments.length; i < n; i++) {
14
- s = arguments[i];
15
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
16
- t[p] = s[p];
17
- }
18
- return t;
19
- };
20
- return __assign.apply(this, arguments);
21
- };
22
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
23
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
24
- return new (P || (P = Promise))(function (resolve, reject) {
25
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
26
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
27
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
28
- step((generator = generator.apply(thisArg, _arguments || [])).next());
29
- });
30
- };
31
- var __generator = (this && this.__generator) || function (thisArg, body) {
32
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
33
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
34
- function verb(n) { return function (v) { return step([n, v]); }; }
35
- function step(op) {
36
- if (f) throw new TypeError("Generator is already executing.");
37
- while (_) try {
38
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
39
- if (y = 0, t) op = [op[0] & 2, t.value];
40
- switch (op[0]) {
41
- case 0: case 1: t = op; break;
42
- case 4: _.label++; return { value: op[1], done: false };
43
- case 5: _.label++; y = op[1]; op = [0]; continue;
44
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
45
- default:
46
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
47
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
48
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
49
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
50
- if (t[2]) _.ops.pop();
51
- _.trys.pop(); continue;
52
- }
53
- op = body.call(thisArg, _);
54
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
55
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
56
- }
57
- };
58
11
  import * as fs from 'fs';
59
12
  import * as path from 'path';
60
13
  // ADR-053: Lazy import of AgentDB v3 bridge
61
- var _bridge;
62
- function getBridge() {
63
- return __awaiter(this, void 0, Promise, function () {
64
- var _a;
65
- return __generator(this, function (_b) {
66
- switch (_b.label) {
67
- case 0:
68
- if (_bridge === null)
69
- return [2 /*return*/, null];
70
- if (_bridge)
71
- return [2 /*return*/, _bridge];
72
- _b.label = 1;
73
- case 1:
74
- _b.trys.push([1, 3, , 4]);
75
- return [4 /*yield*/, import('./memory-bridge.js')];
76
- case 2:
77
- _bridge = _b.sent();
78
- return [2 /*return*/, _bridge];
79
- case 3:
80
- _a = _b.sent();
81
- _bridge = null;
82
- return [2 /*return*/, null];
83
- case 4: return [2 /*return*/];
84
- }
85
- });
86
- });
14
+ let _bridge;
15
+ async function getBridge() {
16
+ if (_bridge === null)
17
+ return null;
18
+ if (_bridge)
19
+ return _bridge;
20
+ try {
21
+ _bridge = await import('./memory-bridge.js');
22
+ return _bridge;
23
+ }
24
+ catch {
25
+ _bridge = null;
26
+ return null;
27
+ }
87
28
  }
88
29
  /**
89
30
  * Enhanced schema with pattern confidence, temporal decay, versioning
90
31
  * Vector embeddings enabled for semantic search
91
32
  */
92
- export var MEMORY_SCHEMA_V3 = "\n-- RuFlo V3 Memory Database\n-- Version: 3.0.0\n-- Features: Pattern learning, vector embeddings, temporal decay, migration tracking\n\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA foreign_keys = ON;\n\n-- ============================================\n-- CORE MEMORY TABLES\n-- ============================================\n\n-- Memory entries (main storage)\nCREATE TABLE IF NOT EXISTS memory_entries (\n id TEXT PRIMARY KEY,\n key TEXT NOT NULL,\n namespace TEXT DEFAULT 'default',\n content TEXT NOT NULL,\n type TEXT DEFAULT 'semantic' CHECK(type IN ('semantic', 'episodic', 'procedural', 'working', 'pattern')),\n\n -- Vector embedding for semantic search (stored as JSON array)\n embedding TEXT,\n embedding_model TEXT DEFAULT 'local',\n embedding_dimensions INTEGER,\n\n -- Metadata\n tags TEXT, -- JSON array\n metadata TEXT, -- JSON object\n owner_id TEXT,\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n expires_at INTEGER,\n last_accessed_at INTEGER,\n\n -- Access tracking for hot/cold detection\n access_count INTEGER DEFAULT 0,\n\n -- Status\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deleted')),\n\n UNIQUE(namespace, key)\n);\n\n-- Indexes for memory entries\nCREATE INDEX IF NOT EXISTS idx_memory_namespace ON memory_entries(namespace);\nCREATE INDEX IF NOT EXISTS idx_memory_key ON memory_entries(key);\nCREATE INDEX IF NOT EXISTS idx_memory_type ON memory_entries(type);\nCREATE INDEX IF NOT EXISTS idx_memory_status ON memory_entries(status);\nCREATE INDEX IF NOT EXISTS idx_memory_created ON memory_entries(created_at);\nCREATE INDEX IF NOT EXISTS idx_memory_accessed ON memory_entries(last_accessed_at);\nCREATE INDEX IF NOT EXISTS idx_memory_owner ON memory_entries(owner_id);\n\n-- ============================================\n-- PATTERN LEARNING TABLES\n-- ============================================\n\n-- Learned patterns with confidence scoring and versioning\nCREATE TABLE IF NOT EXISTS patterns (\n id TEXT PRIMARY KEY,\n\n -- Pattern identification\n name TEXT NOT NULL,\n pattern_type TEXT NOT NULL CHECK(pattern_type IN (\n 'task-routing', 'error-recovery', 'optimization', 'learning',\n 'coordination', 'prediction', 'code-pattern', 'workflow'\n )),\n\n -- Pattern definition\n condition TEXT NOT NULL, -- Regex or semantic match\n action TEXT NOT NULL, -- What to do when pattern matches\n description TEXT,\n\n -- Confidence scoring (0.0 - 1.0)\n confidence REAL DEFAULT 0.5,\n success_count INTEGER DEFAULT 0,\n failure_count INTEGER DEFAULT 0,\n\n -- Temporal decay\n decay_rate REAL DEFAULT 0.01, -- How fast confidence decays\n half_life_days INTEGER DEFAULT 30, -- Days until confidence halves without use\n\n -- Vector embedding for semantic pattern matching\n embedding TEXT,\n embedding_dimensions INTEGER,\n\n -- Versioning\n version INTEGER DEFAULT 1,\n parent_id TEXT REFERENCES patterns(id),\n\n -- Metadata\n tags TEXT, -- JSON array\n metadata TEXT, -- JSON object\n source TEXT, -- Where the pattern was learned from\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n last_matched_at INTEGER,\n last_success_at INTEGER,\n last_failure_at INTEGER,\n\n -- Status\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deprecated', 'experimental'))\n);\n\n-- Indexes for patterns\nCREATE INDEX IF NOT EXISTS idx_patterns_type ON patterns(pattern_type);\nCREATE INDEX IF NOT EXISTS idx_patterns_confidence ON patterns(confidence DESC);\nCREATE INDEX IF NOT EXISTS idx_patterns_status ON patterns(status);\nCREATE INDEX IF NOT EXISTS idx_patterns_last_matched ON patterns(last_matched_at);\n\n-- Pattern evolution history (for versioning)\nCREATE TABLE IF NOT EXISTS pattern_history (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n pattern_id TEXT NOT NULL REFERENCES patterns(id),\n version INTEGER NOT NULL,\n\n -- Snapshot of pattern state\n confidence REAL,\n success_count INTEGER,\n failure_count INTEGER,\n condition TEXT,\n action TEXT,\n\n -- What changed\n change_type TEXT CHECK(change_type IN ('created', 'updated', 'success', 'failure', 'decay', 'merged', 'split')),\n change_reason TEXT,\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_pattern_history_pattern ON pattern_history(pattern_id);\n\n-- ============================================\n-- LEARNING & TRAJECTORY TABLES\n-- ============================================\n\n-- Learning trajectories (SONA integration)\nCREATE TABLE IF NOT EXISTS trajectories (\n id TEXT PRIMARY KEY,\n session_id TEXT,\n\n -- Trajectory state\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed', 'abandoned')),\n verdict TEXT CHECK(verdict IN ('success', 'failure', 'partial', NULL)),\n\n -- Context\n task TEXT,\n context TEXT, -- JSON object\n\n -- Metrics\n total_steps INTEGER DEFAULT 0,\n total_reward REAL DEFAULT 0,\n\n -- Timestamps\n started_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n ended_at INTEGER,\n\n -- Reference to extracted pattern (if any)\n extracted_pattern_id TEXT REFERENCES patterns(id)\n);\n\n-- Trajectory steps\nCREATE TABLE IF NOT EXISTS trajectory_steps (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n trajectory_id TEXT NOT NULL REFERENCES trajectories(id),\n step_number INTEGER NOT NULL,\n\n -- Step data\n action TEXT NOT NULL,\n observation TEXT,\n reward REAL DEFAULT 0,\n\n -- Metadata\n metadata TEXT, -- JSON object\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_steps_trajectory ON trajectory_steps(trajectory_id);\n\n-- ============================================\n-- MIGRATION STATE TRACKING\n-- ============================================\n\n-- Migration state (for resume capability)\nCREATE TABLE IF NOT EXISTS migration_state (\n id TEXT PRIMARY KEY,\n migration_type TEXT NOT NULL, -- 'v2-to-v3', 'pattern', 'memory', etc.\n\n -- Progress tracking\n status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'in_progress', 'completed', 'failed', 'rolled_back')),\n total_items INTEGER DEFAULT 0,\n processed_items INTEGER DEFAULT 0,\n failed_items INTEGER DEFAULT 0,\n skipped_items INTEGER DEFAULT 0,\n\n -- Current position (for resume)\n current_batch INTEGER DEFAULT 0,\n last_processed_id TEXT,\n\n -- Source/destination info\n source_path TEXT,\n source_type TEXT,\n destination_path TEXT,\n\n -- Backup info\n backup_path TEXT,\n backup_created_at INTEGER,\n\n -- Error tracking\n last_error TEXT,\n errors TEXT, -- JSON array of errors\n\n -- Timestamps\n started_at INTEGER,\n completed_at INTEGER,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- ============================================\n-- SESSION MANAGEMENT\n-- ============================================\n\n-- Sessions for context persistence\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n\n -- Session state\n state TEXT NOT NULL, -- JSON object with full session state\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'paused', 'completed', 'expired')),\n\n -- Context\n project_path TEXT,\n branch TEXT,\n\n -- Metrics\n tasks_completed INTEGER DEFAULT 0,\n patterns_learned INTEGER DEFAULT 0,\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n expires_at INTEGER\n);\n\n-- ============================================\n-- VECTOR INDEX METADATA (for HNSW)\n-- ============================================\n\n-- Track HNSW index state\nCREATE TABLE IF NOT EXISTS vector_indexes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n\n -- Index configuration\n dimensions INTEGER NOT NULL,\n metric TEXT DEFAULT 'cosine' CHECK(metric IN ('cosine', 'euclidean', 'dot')),\n\n -- HNSW parameters\n hnsw_m INTEGER DEFAULT 16,\n hnsw_ef_construction INTEGER DEFAULT 200,\n hnsw_ef_search INTEGER DEFAULT 100,\n\n -- Quantization\n quantization_type TEXT CHECK(quantization_type IN ('none', 'scalar', 'product')),\n quantization_bits INTEGER DEFAULT 8,\n\n -- Statistics\n total_vectors INTEGER DEFAULT 0,\n last_rebuild_at INTEGER,\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- ============================================\n-- SYSTEM METADATA\n-- ============================================\n\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at INTEGER DEFAULT (strftime('%s', 'now') * 1000)\n);\n";
93
- var hnswIndex = null;
94
- var hnswInitializing = false;
33
+ export const MEMORY_SCHEMA_V3 = `
34
+ -- RuFlo V3 Memory Database
35
+ -- Version: 3.0.0
36
+ -- Features: Pattern learning, vector embeddings, temporal decay, migration tracking
37
+
38
+ PRAGMA journal_mode = WAL;
39
+ PRAGMA synchronous = NORMAL;
40
+ PRAGMA foreign_keys = ON;
41
+
42
+ -- ============================================
43
+ -- CORE MEMORY TABLES
44
+ -- ============================================
45
+
46
+ -- Memory entries (main storage)
47
+ CREATE TABLE IF NOT EXISTS memory_entries (
48
+ id TEXT PRIMARY KEY,
49
+ key TEXT NOT NULL,
50
+ namespace TEXT DEFAULT 'default',
51
+ content TEXT NOT NULL,
52
+ type TEXT DEFAULT 'semantic' CHECK(type IN ('semantic', 'episodic', 'procedural', 'working', 'pattern')),
53
+
54
+ -- Vector embedding for semantic search (stored as JSON array)
55
+ embedding TEXT,
56
+ embedding_model TEXT DEFAULT 'local',
57
+ embedding_dimensions INTEGER,
58
+
59
+ -- Metadata
60
+ tags TEXT, -- JSON array
61
+ metadata TEXT, -- JSON object
62
+ owner_id TEXT,
63
+
64
+ -- Timestamps
65
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
66
+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
67
+ expires_at INTEGER,
68
+ last_accessed_at INTEGER,
69
+
70
+ -- Access tracking for hot/cold detection
71
+ access_count INTEGER DEFAULT 0,
72
+
73
+ -- Status
74
+ status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deleted')),
75
+
76
+ UNIQUE(namespace, key)
77
+ );
78
+
79
+ -- Indexes for memory entries
80
+ CREATE INDEX IF NOT EXISTS idx_memory_namespace ON memory_entries(namespace);
81
+ CREATE INDEX IF NOT EXISTS idx_memory_key ON memory_entries(key);
82
+ CREATE INDEX IF NOT EXISTS idx_memory_type ON memory_entries(type);
83
+ CREATE INDEX IF NOT EXISTS idx_memory_status ON memory_entries(status);
84
+ CREATE INDEX IF NOT EXISTS idx_memory_created ON memory_entries(created_at);
85
+ CREATE INDEX IF NOT EXISTS idx_memory_accessed ON memory_entries(last_accessed_at);
86
+ CREATE INDEX IF NOT EXISTS idx_memory_owner ON memory_entries(owner_id);
87
+
88
+ -- ============================================
89
+ -- PATTERN LEARNING TABLES
90
+ -- ============================================
91
+
92
+ -- Learned patterns with confidence scoring and versioning
93
+ CREATE TABLE IF NOT EXISTS patterns (
94
+ id TEXT PRIMARY KEY,
95
+
96
+ -- Pattern identification
97
+ name TEXT NOT NULL,
98
+ pattern_type TEXT NOT NULL CHECK(pattern_type IN (
99
+ 'task-routing', 'error-recovery', 'optimization', 'learning',
100
+ 'coordination', 'prediction', 'code-pattern', 'workflow'
101
+ )),
102
+
103
+ -- Pattern definition
104
+ condition TEXT NOT NULL, -- Regex or semantic match
105
+ action TEXT NOT NULL, -- What to do when pattern matches
106
+ description TEXT,
107
+
108
+ -- Confidence scoring (0.0 - 1.0)
109
+ confidence REAL DEFAULT 0.5,
110
+ success_count INTEGER DEFAULT 0,
111
+ failure_count INTEGER DEFAULT 0,
112
+
113
+ -- Temporal decay
114
+ decay_rate REAL DEFAULT 0.01, -- How fast confidence decays
115
+ half_life_days INTEGER DEFAULT 30, -- Days until confidence halves without use
116
+
117
+ -- Vector embedding for semantic pattern matching
118
+ embedding TEXT,
119
+ embedding_dimensions INTEGER,
120
+
121
+ -- Versioning
122
+ version INTEGER DEFAULT 1,
123
+ parent_id TEXT REFERENCES patterns(id),
124
+
125
+ -- Metadata
126
+ tags TEXT, -- JSON array
127
+ metadata TEXT, -- JSON object
128
+ source TEXT, -- Where the pattern was learned from
129
+
130
+ -- Timestamps
131
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
132
+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
133
+ last_matched_at INTEGER,
134
+ last_success_at INTEGER,
135
+ last_failure_at INTEGER,
136
+
137
+ -- Status
138
+ status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deprecated', 'experimental'))
139
+ );
140
+
141
+ -- Indexes for patterns
142
+ CREATE INDEX IF NOT EXISTS idx_patterns_type ON patterns(pattern_type);
143
+ CREATE INDEX IF NOT EXISTS idx_patterns_confidence ON patterns(confidence DESC);
144
+ CREATE INDEX IF NOT EXISTS idx_patterns_status ON patterns(status);
145
+ CREATE INDEX IF NOT EXISTS idx_patterns_last_matched ON patterns(last_matched_at);
146
+
147
+ -- Pattern evolution history (for versioning)
148
+ CREATE TABLE IF NOT EXISTS pattern_history (
149
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
150
+ pattern_id TEXT NOT NULL REFERENCES patterns(id),
151
+ version INTEGER NOT NULL,
152
+
153
+ -- Snapshot of pattern state
154
+ confidence REAL,
155
+ success_count INTEGER,
156
+ failure_count INTEGER,
157
+ condition TEXT,
158
+ action TEXT,
159
+
160
+ -- What changed
161
+ change_type TEXT CHECK(change_type IN ('created', 'updated', 'success', 'failure', 'decay', 'merged', 'split')),
162
+ change_reason TEXT,
163
+
164
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)
165
+ );
166
+
167
+ CREATE INDEX IF NOT EXISTS idx_pattern_history_pattern ON pattern_history(pattern_id);
168
+
169
+ -- ============================================
170
+ -- LEARNING & TRAJECTORY TABLES
171
+ -- ============================================
172
+
173
+ -- Learning trajectories (SONA integration)
174
+ CREATE TABLE IF NOT EXISTS trajectories (
175
+ id TEXT PRIMARY KEY,
176
+ session_id TEXT,
177
+
178
+ -- Trajectory state
179
+ status TEXT DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed', 'abandoned')),
180
+ verdict TEXT CHECK(verdict IN ('success', 'failure', 'partial', NULL)),
181
+
182
+ -- Context
183
+ task TEXT,
184
+ context TEXT, -- JSON object
185
+
186
+ -- Metrics
187
+ total_steps INTEGER DEFAULT 0,
188
+ total_reward REAL DEFAULT 0,
189
+
190
+ -- Timestamps
191
+ started_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
192
+ ended_at INTEGER,
193
+
194
+ -- Reference to extracted pattern (if any)
195
+ extracted_pattern_id TEXT REFERENCES patterns(id)
196
+ );
197
+
198
+ -- Trajectory steps
199
+ CREATE TABLE IF NOT EXISTS trajectory_steps (
200
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
201
+ trajectory_id TEXT NOT NULL REFERENCES trajectories(id),
202
+ step_number INTEGER NOT NULL,
203
+
204
+ -- Step data
205
+ action TEXT NOT NULL,
206
+ observation TEXT,
207
+ reward REAL DEFAULT 0,
208
+
209
+ -- Metadata
210
+ metadata TEXT, -- JSON object
211
+
212
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)
213
+ );
214
+
215
+ CREATE INDEX IF NOT EXISTS idx_steps_trajectory ON trajectory_steps(trajectory_id);
216
+
217
+ -- ============================================
218
+ -- MIGRATION STATE TRACKING
219
+ -- ============================================
220
+
221
+ -- Migration state (for resume capability)
222
+ CREATE TABLE IF NOT EXISTS migration_state (
223
+ id TEXT PRIMARY KEY,
224
+ migration_type TEXT NOT NULL, -- 'v2-to-v3', 'pattern', 'memory', etc.
225
+
226
+ -- Progress tracking
227
+ status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'in_progress', 'completed', 'failed', 'rolled_back')),
228
+ total_items INTEGER DEFAULT 0,
229
+ processed_items INTEGER DEFAULT 0,
230
+ failed_items INTEGER DEFAULT 0,
231
+ skipped_items INTEGER DEFAULT 0,
232
+
233
+ -- Current position (for resume)
234
+ current_batch INTEGER DEFAULT 0,
235
+ last_processed_id TEXT,
236
+
237
+ -- Source/destination info
238
+ source_path TEXT,
239
+ source_type TEXT,
240
+ destination_path TEXT,
241
+
242
+ -- Backup info
243
+ backup_path TEXT,
244
+ backup_created_at INTEGER,
245
+
246
+ -- Error tracking
247
+ last_error TEXT,
248
+ errors TEXT, -- JSON array of errors
249
+
250
+ -- Timestamps
251
+ started_at INTEGER,
252
+ completed_at INTEGER,
253
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
254
+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)
255
+ );
256
+
257
+ -- ============================================
258
+ -- SESSION MANAGEMENT
259
+ -- ============================================
260
+
261
+ -- Sessions for context persistence
262
+ CREATE TABLE IF NOT EXISTS sessions (
263
+ id TEXT PRIMARY KEY,
264
+
265
+ -- Session state
266
+ state TEXT NOT NULL, -- JSON object with full session state
267
+ status TEXT DEFAULT 'active' CHECK(status IN ('active', 'paused', 'completed', 'expired')),
268
+
269
+ -- Context
270
+ project_path TEXT,
271
+ branch TEXT,
272
+
273
+ -- Metrics
274
+ tasks_completed INTEGER DEFAULT 0,
275
+ patterns_learned INTEGER DEFAULT 0,
276
+
277
+ -- Timestamps
278
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
279
+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
280
+ expires_at INTEGER
281
+ );
282
+
283
+ -- ============================================
284
+ -- VECTOR INDEX METADATA (for HNSW)
285
+ -- ============================================
286
+
287
+ -- Track HNSW index state
288
+ CREATE TABLE IF NOT EXISTS vector_indexes (
289
+ id TEXT PRIMARY KEY,
290
+ name TEXT NOT NULL UNIQUE,
291
+
292
+ -- Index configuration
293
+ dimensions INTEGER NOT NULL,
294
+ metric TEXT DEFAULT 'cosine' CHECK(metric IN ('cosine', 'euclidean', 'dot')),
295
+
296
+ -- HNSW parameters
297
+ hnsw_m INTEGER DEFAULT 16,
298
+ hnsw_ef_construction INTEGER DEFAULT 200,
299
+ hnsw_ef_search INTEGER DEFAULT 100,
300
+
301
+ -- Quantization
302
+ quantization_type TEXT CHECK(quantization_type IN ('none', 'scalar', 'product')),
303
+ quantization_bits INTEGER DEFAULT 8,
304
+
305
+ -- Statistics
306
+ total_vectors INTEGER DEFAULT 0,
307
+ last_rebuild_at INTEGER,
308
+
309
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
310
+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)
311
+ );
312
+
313
+ -- ============================================
314
+ -- SYSTEM METADATA
315
+ -- ============================================
316
+
317
+ CREATE TABLE IF NOT EXISTS metadata (
318
+ key TEXT PRIMARY KEY,
319
+ value TEXT NOT NULL,
320
+ updated_at INTEGER DEFAULT (strftime('%s', 'now') * 1000)
321
+ );
322
+ `;
323
+ let hnswIndex = null;
324
+ let hnswInitializing = false;
95
325
  /**
96
326
  * Get or create the HNSW index singleton
97
327
  * Lazily initializes from SQLite data on first use
98
328
  */
99
- export function getHNSWIndex(options) {
100
- var _a, _b;
101
- return __awaiter(this, void 0, Promise, function () {
102
- var dimensions, ruvectorModule, ruvectorCore, VectorDb, swarmDir, hnswPath, metadataPath, dbPath, db, entries, metadataJson, metadata, _i, metadata_1, _c, key, value, existingLen, initSqlJs, SQL, fileBuffer, sqlDb, result, _d, _e, row, _f, id, key, ns, content, embeddingJson, embedding, vector, _g, _h, _j;
103
- return __generator(this, function (_k) {
104
- switch (_k.label) {
105
- case 0:
106
- dimensions = (_a = options === null || options === void 0 ? void 0 : options.dimensions) !== null && _a !== void 0 ? _a : 384;
107
- // Return existing index if already initialized
108
- if ((hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.initialized) && !(options === null || options === void 0 ? void 0 : options.forceRebuild)) {
109
- return [2 /*return*/, hnswIndex];
110
- }
111
- if (!hnswInitializing) return [3 /*break*/, 4];
112
- _k.label = 1;
113
- case 1:
114
- if (!hnswInitializing) return [3 /*break*/, 3];
115
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 10); })];
116
- case 2:
117
- _k.sent();
118
- return [3 /*break*/, 1];
119
- case 3: return [2 /*return*/, hnswIndex];
120
- case 4:
121
- hnswInitializing = true;
122
- _k.label = 5;
123
- case 5:
124
- _k.trys.push([5, 19, , 20]);
125
- return [4 /*yield*/, import('@ruvector/core')["catch"](function () { return null; })];
126
- case 6:
127
- ruvectorModule = _k.sent();
128
- if (!ruvectorModule) {
129
- hnswInitializing = false;
130
- return [2 /*return*/, null]; // HNSW not available
131
- }
132
- ruvectorCore = ruvectorModule["default"] || ruvectorModule;
133
- if (!(ruvectorCore === null || ruvectorCore === void 0 ? void 0 : ruvectorCore.VectorDb)) {
134
- hnswInitializing = false;
135
- return [2 /*return*/, null]; // VectorDb not found
136
- }
137
- VectorDb = ruvectorCore.VectorDb;
138
- swarmDir = path.join(process.cwd(), '.swarm');
139
- if (!fs.existsSync(swarmDir)) {
140
- fs.mkdirSync(swarmDir, { recursive: true });
141
- }
142
- hnswPath = path.join(swarmDir, 'hnsw.index');
143
- metadataPath = path.join(swarmDir, 'hnsw.metadata.json');
144
- dbPath = (options === null || options === void 0 ? void 0 : options.dbPath) || path.join(swarmDir, 'memory.db');
145
- db = new VectorDb({
146
- dimensions: dimensions,
147
- distanceMetric: 'Cosine',
148
- storagePath: hnswPath // Persistent storage!
149
- });
150
- entries = new Map();
151
- if (fs.existsSync(metadataPath)) {
152
- try {
153
- metadataJson = fs.readFileSync(metadataPath, 'utf-8');
154
- metadata = JSON.parse(metadataJson);
155
- for (_i = 0, metadata_1 = metadata; _i < metadata_1.length; _i++) {
156
- _c = metadata_1[_i], key = _c[0], value = _c[1];
157
- entries.set(key, value);
329
+ export async function getHNSWIndex(options) {
330
+ const dimensions = options?.dimensions ?? 384;
331
+ // Return existing index if already initialized
332
+ if (hnswIndex?.initialized && !options?.forceRebuild) {
333
+ return hnswIndex;
334
+ }
335
+ // Prevent concurrent initialization
336
+ if (hnswInitializing) {
337
+ // Wait for initialization to complete
338
+ while (hnswInitializing) {
339
+ await new Promise(resolve => setTimeout(resolve, 10));
340
+ }
341
+ return hnswIndex;
342
+ }
343
+ hnswInitializing = true;
344
+ try {
345
+ // Import @ruvector/core dynamically
346
+ // Handle both ESM (default export) and CJS patterns
347
+ const ruvectorModule = await import('@ruvector/core').catch(() => null);
348
+ if (!ruvectorModule) {
349
+ hnswInitializing = false;
350
+ return null; // HNSW not available
351
+ }
352
+ // ESM returns { default: { VectorDb, ... } }, CJS returns { VectorDb, ... }
353
+ const ruvectorCore = ruvectorModule.default || ruvectorModule;
354
+ if (!ruvectorCore?.VectorDb) {
355
+ hnswInitializing = false;
356
+ return null; // VectorDb not found
357
+ }
358
+ const { VectorDb } = ruvectorCore;
359
+ // Persistent storage paths
360
+ const swarmDir = path.join(process.cwd(), '.swarm');
361
+ if (!fs.existsSync(swarmDir)) {
362
+ fs.mkdirSync(swarmDir, { recursive: true });
363
+ }
364
+ const hnswPath = path.join(swarmDir, 'hnsw.index');
365
+ const metadataPath = path.join(swarmDir, 'hnsw.metadata.json');
366
+ const dbPath = options?.dbPath || path.join(swarmDir, 'memory.db');
367
+ // Create HNSW index with persistent storage
368
+ // @ruvector/core uses string enum for distanceMetric: 'Cosine', 'Euclidean', 'DotProduct', 'Manhattan'
369
+ const db = new VectorDb({
370
+ dimensions,
371
+ distanceMetric: 'Cosine',
372
+ storagePath: hnswPath // Persistent storage!
373
+ });
374
+ // Load metadata (entry info) if exists
375
+ const entries = new Map();
376
+ if (fs.existsSync(metadataPath)) {
377
+ try {
378
+ const metadataJson = fs.readFileSync(metadataPath, 'utf-8');
379
+ const metadata = JSON.parse(metadataJson);
380
+ for (const [key, value] of metadata) {
381
+ entries.set(key, value);
382
+ }
383
+ }
384
+ catch {
385
+ // Metadata load failed, will rebuild
386
+ }
387
+ }
388
+ hnswIndex = {
389
+ db,
390
+ entries,
391
+ dimensions,
392
+ initialized: false
393
+ };
394
+ // Check if index already has data (from persistent storage)
395
+ const existingLen = await db.len();
396
+ if (existingLen > 0 && entries.size > 0) {
397
+ // Index loaded from disk, skip SQLite sync
398
+ hnswIndex.initialized = true;
399
+ hnswInitializing = false;
400
+ return hnswIndex;
401
+ }
402
+ if (fs.existsSync(dbPath)) {
403
+ try {
404
+ const initSqlJs = (await import('sql.js')).default;
405
+ const SQL = await initSqlJs();
406
+ const fileBuffer = fs.readFileSync(dbPath);
407
+ const sqlDb = new SQL.Database(fileBuffer);
408
+ // Load all entries with embeddings
409
+ const result = sqlDb.exec(`
410
+ SELECT id, key, namespace, content, embedding
411
+ FROM memory_entries
412
+ WHERE status = 'active' AND embedding IS NOT NULL
413
+ LIMIT 10000
414
+ `);
415
+ if (result[0]?.values) {
416
+ for (const row of result[0].values) {
417
+ const [id, key, ns, content, embeddingJson] = row;
418
+ if (embeddingJson) {
419
+ try {
420
+ const embedding = JSON.parse(embeddingJson);
421
+ const vector = new Float32Array(embedding);
422
+ await db.insert({
423
+ id: String(id),
424
+ vector
425
+ });
426
+ hnswIndex.entries.set(String(id), {
427
+ id: String(id),
428
+ key: key || String(id),
429
+ namespace: ns || 'default',
430
+ content: content || ''
431
+ });
432
+ }
433
+ catch {
434
+ // Skip invalid embeddings
158
435
  }
159
436
  }
160
- catch (_l) {
161
- // Metadata load failed, will rebuild
162
- }
163
- }
164
- hnswIndex = {
165
- db: db,
166
- entries: entries,
167
- dimensions: dimensions,
168
- initialized: false
169
- };
170
- return [4 /*yield*/, db.len()];
171
- case 7:
172
- existingLen = _k.sent();
173
- if (existingLen > 0 && entries.size > 0) {
174
- // Index loaded from disk, skip SQLite sync
175
- hnswIndex.initialized = true;
176
- hnswInitializing = false;
177
- return [2 /*return*/, hnswIndex];
178
437
  }
179
- if (!fs.existsSync(dbPath)) return [3 /*break*/, 18];
180
- _k.label = 8;
181
- case 8:
182
- _k.trys.push([8, 17, , 18]);
183
- return [4 /*yield*/, import('sql.js')];
184
- case 9:
185
- initSqlJs = (_k.sent())["default"];
186
- return [4 /*yield*/, initSqlJs()];
187
- case 10:
188
- SQL = _k.sent();
189
- fileBuffer = fs.readFileSync(dbPath);
190
- sqlDb = new SQL.Database(fileBuffer);
191
- result = sqlDb.exec("\n SELECT id, key, namespace, content, embedding\n FROM memory_entries\n WHERE status = 'active' AND embedding IS NOT NULL\n LIMIT 10000\n ");
192
- if (!((_b = result[0]) === null || _b === void 0 ? void 0 : _b.values)) return [3 /*break*/, 16];
193
- _d = 0, _e = result[0].values;
194
- _k.label = 11;
195
- case 11:
196
- if (!(_d < _e.length)) return [3 /*break*/, 16];
197
- row = _e[_d];
198
- _f = row, id = _f[0], key = _f[1], ns = _f[2], content = _f[3], embeddingJson = _f[4];
199
- if (!embeddingJson) return [3 /*break*/, 15];
200
- _k.label = 12;
201
- case 12:
202
- _k.trys.push([12, 14, , 15]);
203
- embedding = JSON.parse(embeddingJson);
204
- vector = new Float32Array(embedding);
205
- return [4 /*yield*/, db.insert({
206
- id: String(id),
207
- vector: vector
208
- })];
209
- case 13:
210
- _k.sent();
211
- hnswIndex.entries.set(String(id), {
212
- id: String(id),
213
- key: key || String(id),
214
- namespace: ns || 'default',
215
- content: content || ''
216
- });
217
- return [3 /*break*/, 15];
218
- case 14:
219
- _g = _k.sent();
220
- return [3 /*break*/, 15];
221
- case 15:
222
- _d++;
223
- return [3 /*break*/, 11];
224
- case 16:
225
- sqlDb.close();
226
- return [3 /*break*/, 18];
227
- case 17:
228
- _h = _k.sent();
229
- return [3 /*break*/, 18];
230
- case 18:
231
- hnswIndex.initialized = true;
232
- hnswInitializing = false;
233
- return [2 /*return*/, hnswIndex];
234
- case 19:
235
- _j = _k.sent();
236
- hnswInitializing = false;
237
- return [2 /*return*/, null];
238
- case 20: return [2 /*return*/];
438
+ }
439
+ sqlDb.close();
239
440
  }
240
- });
241
- });
441
+ catch {
442
+ // SQLite load failed, start with empty index
443
+ }
444
+ }
445
+ hnswIndex.initialized = true;
446
+ hnswInitializing = false;
447
+ return hnswIndex;
448
+ }
449
+ catch {
450
+ hnswInitializing = false;
451
+ return null;
452
+ }
242
453
  }
243
454
  /**
244
455
  * Save HNSW metadata to disk for persistence
245
456
  */
246
457
  function saveHNSWMetadata() {
247
- if (!(hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.entries))
458
+ if (!hnswIndex?.entries)
248
459
  return;
249
460
  try {
250
- var swarmDir = path.join(process.cwd(), '.swarm');
251
- var metadataPath = path.join(swarmDir, 'hnsw.metadata.json');
252
- var metadata = Array.from(hnswIndex.entries.entries());
461
+ const swarmDir = path.join(process.cwd(), '.swarm');
462
+ const metadataPath = path.join(swarmDir, 'hnsw.metadata.json');
463
+ const metadata = Array.from(hnswIndex.entries.entries());
253
464
  fs.writeFileSync(metadataPath, JSON.stringify(metadata));
254
465
  }
255
- catch (_a) {
466
+ catch {
256
467
  // Silently fail - metadata save is best-effort
257
468
  }
258
469
  }
259
470
  /**
260
471
  * Add entry to HNSW index (with automatic persistence)
261
472
  */
262
- export function addToHNSWIndex(id, embedding, entry) {
263
- return __awaiter(this, void 0, Promise, function () {
264
- var bridge, bridgeResult, index, vector, _a;
265
- return __generator(this, function (_b) {
266
- switch (_b.label) {
267
- case 0: return [4 /*yield*/, getBridge()];
268
- case 1:
269
- bridge = _b.sent();
270
- if (!bridge) return [3 /*break*/, 3];
271
- return [4 /*yield*/, bridge.bridgeAddToHNSW(id, embedding, entry)];
272
- case 2:
273
- bridgeResult = _b.sent();
274
- if (bridgeResult === true)
275
- return [2 /*return*/, true];
276
- _b.label = 3;
277
- case 3: return [4 /*yield*/, getHNSWIndex({ dimensions: embedding.length })];
278
- case 4:
279
- index = _b.sent();
280
- if (!index)
281
- return [2 /*return*/, false];
282
- _b.label = 5;
283
- case 5:
284
- _b.trys.push([5, 7, , 8]);
285
- vector = new Float32Array(embedding);
286
- return [4 /*yield*/, index.db.insert({
287
- id: id,
288
- vector: vector
289
- })];
290
- case 6:
291
- _b.sent();
292
- index.entries.set(id, entry);
293
- // Save metadata for persistence (debounced would be better for high-volume)
294
- saveHNSWMetadata();
295
- return [2 /*return*/, true];
296
- case 7:
297
- _a = _b.sent();
298
- return [2 /*return*/, false];
299
- case 8: return [2 /*return*/];
300
- }
473
+ export async function addToHNSWIndex(id, embedding, entry) {
474
+ // ADR-053: Try AgentDB v3 bridge first
475
+ const bridge = await getBridge();
476
+ if (bridge) {
477
+ const bridgeResult = await bridge.bridgeAddToHNSW(id, embedding, entry);
478
+ if (bridgeResult === true)
479
+ return true;
480
+ }
481
+ const index = await getHNSWIndex({ dimensions: embedding.length });
482
+ if (!index)
483
+ return false;
484
+ try {
485
+ const vector = new Float32Array(embedding);
486
+ await index.db.insert({
487
+ id,
488
+ vector
301
489
  });
302
- });
490
+ index.entries.set(id, entry);
491
+ // Save metadata for persistence (debounced would be better for high-volume)
492
+ saveHNSWMetadata();
493
+ return true;
494
+ }
495
+ catch {
496
+ return false;
497
+ }
303
498
  }
304
499
  /**
305
500
  * Search HNSW index (150x faster than brute-force)
306
501
  * Returns results sorted by similarity (highest first)
307
502
  */
308
- export function searchHNSWIndex(queryEmbedding, options) {
309
- var _a;
310
- return __awaiter(this, void 0, Promise, function () {
311
- var bridge, bridgeResult, index, vector, k, results, filtered, _i, results_1, result, entry, score, _b;
312
- return __generator(this, function (_c) {
313
- switch (_c.label) {
314
- case 0: return [4 /*yield*/, getBridge()];
315
- case 1:
316
- bridge = _c.sent();
317
- if (!bridge) return [3 /*break*/, 3];
318
- return [4 /*yield*/, bridge.bridgeSearchHNSW(queryEmbedding, options)];
319
- case 2:
320
- bridgeResult = _c.sent();
321
- if (bridgeResult)
322
- return [2 /*return*/, bridgeResult];
323
- _c.label = 3;
324
- case 3: return [4 /*yield*/, getHNSWIndex({ dimensions: queryEmbedding.length })];
325
- case 4:
326
- index = _c.sent();
327
- if (!index)
328
- return [2 /*return*/, null];
329
- _c.label = 5;
330
- case 5:
331
- _c.trys.push([5, 7, , 8]);
332
- vector = new Float32Array(queryEmbedding);
333
- k = (_a = options === null || options === void 0 ? void 0 : options.k) !== null && _a !== void 0 ? _a : 10;
334
- return [4 /*yield*/, index.db.search({ vector: vector, k: k * 2 })];
335
- case 6:
336
- results = _c.sent();
337
- filtered = [];
338
- for (_i = 0, results_1 = results; _i < results_1.length; _i++) {
339
- result = results_1[_i];
340
- entry = index.entries.get(result.id);
341
- if (!entry)
342
- continue;
343
- // Filter by namespace if specified
344
- if ((options === null || options === void 0 ? void 0 : options.namespace) && options.namespace !== 'all' && entry.namespace !== options.namespace) {
345
- continue;
346
- }
347
- score = 1 - (result.score / 2);
348
- filtered.push({
349
- id: entry.id.substring(0, 12),
350
- key: entry.key || entry.id.substring(0, 15),
351
- content: entry.content.substring(0, 60) + (entry.content.length > 60 ? '...' : ''),
352
- score: score,
353
- namespace: entry.namespace
354
- });
355
- if (filtered.length >= k)
356
- break;
357
- }
358
- // Sort by score descending (highest similarity first)
359
- filtered.sort(function (a, b) { return b.score - a.score; });
360
- return [2 /*return*/, filtered];
361
- case 7:
362
- _b = _c.sent();
363
- return [2 /*return*/, null];
364
- case 8: return [2 /*return*/];
503
+ export async function searchHNSWIndex(queryEmbedding, options) {
504
+ // ADR-053: Try AgentDB v3 bridge first
505
+ const bridge = await getBridge();
506
+ if (bridge) {
507
+ const bridgeResult = await bridge.bridgeSearchHNSW(queryEmbedding, options);
508
+ if (bridgeResult)
509
+ return bridgeResult;
510
+ }
511
+ const index = await getHNSWIndex({ dimensions: queryEmbedding.length });
512
+ if (!index)
513
+ return null;
514
+ try {
515
+ const vector = new Float32Array(queryEmbedding);
516
+ const k = options?.k ?? 10;
517
+ // HNSW search returns results with cosine distance (lower = more similar)
518
+ const results = await index.db.search({ vector, k: k * 2 }); // Get extra for filtering
519
+ const filtered = [];
520
+ for (const result of results) {
521
+ const entry = index.entries.get(result.id);
522
+ if (!entry)
523
+ continue;
524
+ // Filter by namespace if specified
525
+ if (options?.namespace && options.namespace !== 'all' && entry.namespace !== options.namespace) {
526
+ continue;
365
527
  }
366
- });
367
- });
528
+ // Convert cosine distance to similarity score (1 - distance)
529
+ // Cosine distance from @ruvector/core: 0 = identical, 2 = opposite
530
+ const score = 1 - (result.score / 2);
531
+ filtered.push({
532
+ id: entry.id.substring(0, 12),
533
+ key: entry.key || entry.id.substring(0, 15),
534
+ content: entry.content.substring(0, 60) + (entry.content.length > 60 ? '...' : ''),
535
+ score,
536
+ namespace: entry.namespace
537
+ });
538
+ if (filtered.length >= k)
539
+ break;
540
+ }
541
+ // Sort by score descending (highest similarity first)
542
+ filtered.sort((a, b) => b.score - a.score);
543
+ return filtered;
544
+ }
545
+ catch {
546
+ return null;
547
+ }
368
548
  }
369
549
  /**
370
550
  * Get HNSW index status
371
551
  */
372
552
  export function getHNSWStatus() {
373
- var _a, _b, _c, _d, _e;
374
553
  // ADR-053: If bridge was previously loaded, report availability
375
554
  if (_bridge && _bridge !== null) {
376
555
  // Bridge is loaded — HNSW-equivalent is available via AgentDB v3
377
556
  return {
378
557
  available: true,
379
558
  initialized: true,
380
- entryCount: (_a = hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.entries.size) !== null && _a !== void 0 ? _a : 0,
381
- dimensions: (_b = hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.dimensions) !== null && _b !== void 0 ? _b : 384
559
+ entryCount: hnswIndex?.entries.size ?? 0,
560
+ dimensions: hnswIndex?.dimensions ?? 384
382
561
  };
383
562
  }
384
563
  return {
385
564
  available: hnswIndex !== null,
386
- initialized: (_c = hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.initialized) !== null && _c !== void 0 ? _c : false,
387
- entryCount: (_d = hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.entries.size) !== null && _d !== void 0 ? _d : 0,
388
- dimensions: (_e = hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.dimensions) !== null && _e !== void 0 ? _e : 384
565
+ initialized: hnswIndex?.initialized ?? false,
566
+ entryCount: hnswIndex?.entries.size ?? 0,
567
+ dimensions: hnswIndex?.dimensions ?? 384
389
568
  };
390
569
  }
391
570
  /**
@@ -414,27 +593,27 @@ export function rebuildSearchIndex() {
414
593
  * @returns Quantized Int8 array with scale factor
415
594
  */
416
595
  export function quantizeInt8(embedding) {
417
- var arr = embedding instanceof Float32Array ? embedding : new Float32Array(embedding);
596
+ const arr = embedding instanceof Float32Array ? embedding : new Float32Array(embedding);
418
597
  // Find min/max for symmetric quantization
419
- var min = Infinity, max = -Infinity;
420
- for (var i = 0; i < arr.length; i++) {
598
+ let min = Infinity, max = -Infinity;
599
+ for (let i = 0; i < arr.length; i++) {
421
600
  if (arr[i] < min)
422
601
  min = arr[i];
423
602
  if (arr[i] > max)
424
603
  max = arr[i];
425
604
  }
426
605
  // Symmetric quantization: scale = max(|min|, |max|) / 127
427
- var absMax = Math.max(Math.abs(min), Math.abs(max));
428
- var scale = absMax / 127 || 1e-10; // Avoid division by zero
429
- var zeroPoint = 0; // Symmetric quantization
606
+ const absMax = Math.max(Math.abs(min), Math.abs(max));
607
+ const scale = absMax / 127 || 1e-10; // Avoid division by zero
608
+ const zeroPoint = 0; // Symmetric quantization
430
609
  // Quantize
431
- var quantized = new Int8Array(arr.length);
432
- for (var i = 0; i < arr.length; i++) {
610
+ const quantized = new Int8Array(arr.length);
611
+ for (let i = 0; i < arr.length; i++) {
433
612
  // Clamp to [-127, 127] to leave room for potential rounding
434
- var q = Math.round(arr[i] / scale);
613
+ const q = Math.round(arr[i] / scale);
435
614
  quantized[i] = Math.max(-127, Math.min(127, q));
436
615
  }
437
- return { quantized: quantized, scale: scale, zeroPoint: zeroPoint };
616
+ return { quantized, scale, zeroPoint };
438
617
  }
439
618
  /**
440
619
  * Dequantize Int8 back to Float32
@@ -444,10 +623,9 @@ export function quantizeInt8(embedding) {
444
623
  * @param zeroPoint - Zero point (usually 0 for symmetric)
445
624
  * @returns Float32Array
446
625
  */
447
- export function dequantizeInt8(quantized, scale, zeroPoint) {
448
- if (zeroPoint === void 0) { zeroPoint = 0; }
449
- var result = new Float32Array(quantized.length);
450
- for (var i = 0; i < quantized.length; i++) {
626
+ export function dequantizeInt8(quantized, scale, zeroPoint = 0) {
627
+ const result = new Float32Array(quantized.length);
628
+ for (let i = 0; i < quantized.length; i++) {
451
629
  result[i] = (quantized[i] - zeroPoint) * scale;
452
630
  }
453
631
  return result;
@@ -459,25 +637,25 @@ export function dequantizeInt8(quantized, scale, zeroPoint) {
459
637
  export function quantizedCosineSim(a, aScale, b, bScale) {
460
638
  if (a.length !== b.length)
461
639
  return 0;
462
- var dot = 0, normA = 0, normB = 0;
463
- for (var i = 0; i < a.length; i++) {
640
+ let dot = 0, normA = 0, normB = 0;
641
+ for (let i = 0; i < a.length; i++) {
464
642
  dot += a[i] * b[i];
465
643
  normA += a[i] * a[i];
466
644
  normB += b[i] * b[i];
467
645
  }
468
646
  // Scales cancel out in cosine similarity for normalized vectors
469
- var mag = Math.sqrt(normA * normB);
647
+ const mag = Math.sqrt(normA * normB);
470
648
  return mag === 0 ? 0 : dot / mag;
471
649
  }
472
650
  /**
473
651
  * Get quantization statistics for an embedding
474
652
  */
475
653
  export function getQuantizationStats(embedding) {
476
- var len = embedding.length;
477
- var originalBytes = len * 4; // Float32 = 4 bytes
478
- var quantizedBytes = len + 8; // Int8 = 1 byte + 8 bytes for scale/zeroPoint
479
- var compressionRatio = originalBytes / quantizedBytes;
480
- return { originalBytes: originalBytes, quantizedBytes: quantizedBytes, compressionRatio: compressionRatio };
654
+ const len = embedding.length;
655
+ const originalBytes = len * 4; // Float32 = 4 bytes
656
+ const quantizedBytes = len + 8; // Int8 = 1 byte + 8 bytes for scale/zeroPoint
657
+ const compressionRatio = originalBytes / quantizedBytes;
658
+ return { originalBytes, quantizedBytes, compressionRatio };
481
659
  }
482
660
  // ============================================================================
483
661
  // FLASH ATTENTION-STYLE BATCH OPERATIONS (V8-Optimized)
@@ -488,24 +666,24 @@ export function getQuantizationStats(embedding) {
488
666
  * ~50μs per 1000 vectors (384-dim)
489
667
  */
490
668
  export function batchCosineSim(query, vectors) {
491
- var n = vectors.length;
492
- var scores = new Float32Array(n);
669
+ const n = vectors.length;
670
+ const scores = new Float32Array(n);
493
671
  if (n === 0 || query.length === 0)
494
672
  return scores;
495
673
  // Pre-compute query norm
496
- var queryNorm = 0;
497
- for (var i = 0; i < query.length; i++) {
674
+ let queryNorm = 0;
675
+ for (let i = 0; i < query.length; i++) {
498
676
  queryNorm += query[i] * query[i];
499
677
  }
500
678
  queryNorm = Math.sqrt(queryNorm);
501
679
  if (queryNorm === 0)
502
680
  return scores;
503
681
  // Compute similarities
504
- for (var v = 0; v < n; v++) {
505
- var vec = vectors[v];
506
- var len = Math.min(query.length, vec.length);
507
- var dot = 0, vecNorm = 0;
508
- for (var i = 0; i < len; i++) {
682
+ for (let v = 0; v < n; v++) {
683
+ const vec = vectors[v];
684
+ const len = Math.min(query.length, vec.length);
685
+ let dot = 0, vecNorm = 0;
686
+ for (let i = 0; i < len; i++) {
509
687
  dot += query[i] * vec[i];
510
688
  vecNorm += vec[i] * vec[i];
511
689
  }
@@ -518,27 +696,26 @@ export function batchCosineSim(query, vectors) {
518
696
  * Softmax normalization for attention scores
519
697
  * Numerically stable implementation
520
698
  */
521
- export function softmaxAttention(scores, temperature) {
522
- if (temperature === void 0) { temperature = 1.0; }
523
- var n = scores.length;
524
- var result = new Float32Array(n);
699
+ export function softmaxAttention(scores, temperature = 1.0) {
700
+ const n = scores.length;
701
+ const result = new Float32Array(n);
525
702
  if (n === 0)
526
703
  return result;
527
704
  // Find max for numerical stability
528
- var max = scores[0];
529
- for (var i = 1; i < n; i++) {
705
+ let max = scores[0];
706
+ for (let i = 1; i < n; i++) {
530
707
  if (scores[i] > max)
531
708
  max = scores[i];
532
709
  }
533
710
  // Compute exp and sum
534
- var sum = 0;
535
- for (var i = 0; i < n; i++) {
711
+ let sum = 0;
712
+ for (let i = 0; i < n; i++) {
536
713
  result[i] = Math.exp((scores[i] - max) / temperature);
537
714
  sum += result[i];
538
715
  }
539
716
  // Normalize
540
717
  if (sum > 0) {
541
- for (var i = 0; i < n; i++) {
718
+ for (let i = 0; i < n; i++) {
542
719
  result[i] /= sum;
543
720
  }
544
721
  }
@@ -549,24 +726,23 @@ export function softmaxAttention(scores, temperature) {
549
726
  * More efficient than full sort for small k
550
727
  */
551
728
  export function topKIndices(scores, k) {
552
- var _a, _b;
553
- var n = scores.length;
729
+ const n = scores.length;
554
730
  if (k >= n) {
555
731
  // Return all indices sorted by score
556
- return Array.from({ length: n }, function (_, i) { return i; })
557
- .sort(function (a, b) { return scores[b] - scores[a]; });
732
+ return Array.from({ length: n }, (_, i) => i)
733
+ .sort((a, b) => scores[b] - scores[a]);
558
734
  }
559
735
  // Build min-heap of size k
560
- var heap = [];
561
- for (var i = 0; i < n; i++) {
736
+ const heap = [];
737
+ for (let i = 0; i < n; i++) {
562
738
  if (heap.length < k) {
563
739
  heap.push({ idx: i, score: scores[i] });
564
740
  // Bubble up
565
- var j = heap.length - 1;
741
+ let j = heap.length - 1;
566
742
  while (j > 0) {
567
- var parent = Math.floor((j - 1) / 2);
743
+ const parent = Math.floor((j - 1) / 2);
568
744
  if (heap[j].score < heap[parent].score) {
569
- _a = [heap[parent], heap[j]], heap[j] = _a[0], heap[parent] = _a[1];
745
+ [heap[j], heap[parent]] = [heap[parent], heap[j]];
570
746
  j = parent;
571
747
  }
572
748
  else
@@ -576,46 +752,45 @@ export function topKIndices(scores, k) {
576
752
  else if (scores[i] > heap[0].score) {
577
753
  // Replace min and heapify down
578
754
  heap[0] = { idx: i, score: scores[i] };
579
- var j = 0;
755
+ let j = 0;
580
756
  while (true) {
581
- var left = 2 * j + 1, right = 2 * j + 2;
582
- var smallest = j;
757
+ const left = 2 * j + 1, right = 2 * j + 2;
758
+ let smallest = j;
583
759
  if (left < k && heap[left].score < heap[smallest].score)
584
760
  smallest = left;
585
761
  if (right < k && heap[right].score < heap[smallest].score)
586
762
  smallest = right;
587
763
  if (smallest === j)
588
764
  break;
589
- _b = [heap[smallest], heap[j]], heap[j] = _b[0], heap[smallest] = _b[1];
765
+ [heap[j], heap[smallest]] = [heap[smallest], heap[j]];
590
766
  j = smallest;
591
767
  }
592
768
  }
593
769
  }
594
770
  // Extract and sort descending
595
- return heap.sort(function (a, b) { return b.score - a.score; }).map(function (h) { return h.idx; });
771
+ return heap.sort((a, b) => b.score - a.score).map(h => h.idx);
596
772
  }
597
773
  /**
598
774
  * Flash Attention-style search
599
775
  * Combines batch similarity, softmax, and top-k in one pass
600
776
  * Returns indices and attention weights
601
777
  */
602
- export function flashAttentionSearch(query, vectors, options) {
603
- if (options === void 0) { options = {}; }
604
- var _a = options.k, k = _a === void 0 ? 10 : _a, _b = options.temperature, temperature = _b === void 0 ? 1.0 : _b, _c = options.threshold, threshold = _c === void 0 ? 0 : _c;
778
+ export function flashAttentionSearch(query, vectors, options = {}) {
779
+ const { k = 10, temperature = 1.0, threshold = 0 } = options;
605
780
  // Compute batch similarity
606
- var scores = batchCosineSim(query, vectors);
781
+ const scores = batchCosineSim(query, vectors);
607
782
  // Get top-k indices
608
- var indices = topKIndices(scores, k);
783
+ const indices = topKIndices(scores, k);
609
784
  // Filter by threshold
610
- var filtered = indices.filter(function (i) { return scores[i] >= threshold; });
785
+ const filtered = indices.filter(i => scores[i] >= threshold);
611
786
  // Extract scores for filtered results
612
- var topScores = new Float32Array(filtered.length);
613
- for (var i = 0; i < filtered.length; i++) {
787
+ const topScores = new Float32Array(filtered.length);
788
+ for (let i = 0; i < filtered.length; i++) {
614
789
  topScores[i] = scores[filtered[i]];
615
790
  }
616
791
  // Compute attention weights (softmax over top-k)
617
- var weights = softmaxAttention(topScores, temperature);
618
- return { indices: filtered, scores: topScores, weights: weights };
792
+ const weights = softmaxAttention(topScores, temperature);
793
+ return { indices: filtered, scores: topScores, weights };
619
794
  }
620
795
  // ============================================================================
621
796
  // METADATA AND INITIALIZATION
@@ -624,143 +799,129 @@ export function flashAttentionSearch(query, vectors, options) {
624
799
  * Initial metadata to insert after schema creation
625
800
  */
626
801
  export function getInitialMetadata(backend) {
627
- return "\nINSERT OR REPLACE INTO metadata (key, value) VALUES\n ('schema_version', '3.0.0'),\n ('backend', '" + backend + "'),\n ('created_at', '" + new Date().toISOString() + "'),\n ('sql_js', 'true'),\n ('vector_embeddings', 'enabled'),\n ('pattern_learning', 'enabled'),\n ('temporal_decay', 'enabled'),\n ('hnsw_indexing', 'enabled');\n\n-- Create default vector index configuration\nINSERT OR IGNORE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 768),\n ('patterns', 'patterns', 768);\n";
802
+ return `
803
+ INSERT OR REPLACE INTO metadata (key, value) VALUES
804
+ ('schema_version', '3.0.0'),
805
+ ('backend', '${backend}'),
806
+ ('created_at', '${new Date().toISOString()}'),
807
+ ('sql_js', 'true'),
808
+ ('vector_embeddings', 'enabled'),
809
+ ('pattern_learning', 'enabled'),
810
+ ('temporal_decay', 'enabled'),
811
+ ('hnsw_indexing', 'enabled');
812
+
813
+ -- Create default vector index configuration
814
+ INSERT OR IGNORE INTO vector_indexes (id, name, dimensions) VALUES
815
+ ('default', 'default', 768),
816
+ ('patterns', 'patterns', 768);
817
+ `;
628
818
  }
629
819
  /**
630
820
  * Ensure memory_entries table has all required columns
631
821
  * Adds missing columns for older databases (e.g., 'content' column)
632
822
  */
633
- export function ensureSchemaColumns(dbPath) {
634
- var _a, _b;
635
- return __awaiter(this, void 0, Promise, function () {
636
- var columnsAdded, initSqlJs, SQL, fileBuffer, db, tableInfo, existingColumns, requiredColumns, modified, _i, requiredColumns_1, col, data, error_1;
637
- return __generator(this, function (_c) {
638
- switch (_c.label) {
639
- case 0:
640
- columnsAdded = [];
641
- _c.label = 1;
642
- case 1:
643
- _c.trys.push([1, 4, , 5]);
644
- if (!fs.existsSync(dbPath)) {
645
- return [2 /*return*/, { success: true, columnsAdded: [] }];
646
- }
647
- return [4 /*yield*/, import('sql.js')];
648
- case 2:
649
- initSqlJs = (_c.sent())["default"];
650
- return [4 /*yield*/, initSqlJs()];
651
- case 3:
652
- SQL = _c.sent();
653
- fileBuffer = fs.readFileSync(dbPath);
654
- db = new SQL.Database(fileBuffer);
655
- tableInfo = db.exec("PRAGMA table_info(memory_entries)");
656
- existingColumns = new Set(((_b = (_a = tableInfo[0]) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.map(function (row) { return row[1]; })) || []);
657
- requiredColumns = [
658
- { name: 'content', definition: "content TEXT DEFAULT ''" },
659
- { name: 'type', definition: "type TEXT DEFAULT 'semantic'" },
660
- { name: 'embedding', definition: 'embedding TEXT' },
661
- { name: 'embedding_model', definition: "embedding_model TEXT DEFAULT 'local'" },
662
- { name: 'embedding_dimensions', definition: 'embedding_dimensions INTEGER' },
663
- { name: 'tags', definition: 'tags TEXT' },
664
- { name: 'metadata', definition: 'metadata TEXT' },
665
- { name: 'owner_id', definition: 'owner_id TEXT' },
666
- { name: 'expires_at', definition: 'expires_at INTEGER' },
667
- { name: 'last_accessed_at', definition: 'last_accessed_at INTEGER' },
668
- { name: 'access_count', definition: 'access_count INTEGER DEFAULT 0' },
669
- { name: 'status', definition: "status TEXT DEFAULT 'active'" }
670
- ];
671
- modified = false;
672
- for (_i = 0, requiredColumns_1 = requiredColumns; _i < requiredColumns_1.length; _i++) {
673
- col = requiredColumns_1[_i];
674
- if (!existingColumns.has(col.name)) {
675
- try {
676
- db.run("ALTER TABLE memory_entries ADD COLUMN " + col.definition);
677
- columnsAdded.push(col.name);
678
- modified = true;
679
- }
680
- catch (e) {
681
- // Column might already exist or other error - continue
682
- }
683
- }
684
- }
685
- if (modified) {
686
- data = db["export"]();
687
- fs.writeFileSync(dbPath, Buffer.from(data));
688
- }
689
- db.close();
690
- return [2 /*return*/, { success: true, columnsAdded: columnsAdded }];
691
- case 4:
692
- error_1 = _c.sent();
693
- return [2 /*return*/, {
694
- success: false,
695
- columnsAdded: columnsAdded,
696
- error: error_1 instanceof Error ? error_1.message : String(error_1)
697
- }];
698
- case 5: return [2 /*return*/];
823
+ export async function ensureSchemaColumns(dbPath) {
824
+ const columnsAdded = [];
825
+ try {
826
+ if (!fs.existsSync(dbPath)) {
827
+ return { success: true, columnsAdded: [] };
828
+ }
829
+ const initSqlJs = (await import('sql.js')).default;
830
+ const SQL = await initSqlJs();
831
+ const fileBuffer = fs.readFileSync(dbPath);
832
+ const db = new SQL.Database(fileBuffer);
833
+ // Get current columns in memory_entries
834
+ const tableInfo = db.exec("PRAGMA table_info(memory_entries)");
835
+ const existingColumns = new Set(tableInfo[0]?.values?.map(row => row[1]) || []);
836
+ // Required columns that may be missing in older schemas
837
+ // Issue #977: 'type' column was missing from this list, causing store failures on older DBs
838
+ const requiredColumns = [
839
+ { name: 'content', definition: "content TEXT DEFAULT ''" },
840
+ { name: 'type', definition: "type TEXT DEFAULT 'semantic'" },
841
+ { name: 'embedding', definition: 'embedding TEXT' },
842
+ { name: 'embedding_model', definition: "embedding_model TEXT DEFAULT 'local'" },
843
+ { name: 'embedding_dimensions', definition: 'embedding_dimensions INTEGER' },
844
+ { name: 'tags', definition: 'tags TEXT' },
845
+ { name: 'metadata', definition: 'metadata TEXT' },
846
+ { name: 'owner_id', definition: 'owner_id TEXT' },
847
+ { name: 'expires_at', definition: 'expires_at INTEGER' },
848
+ { name: 'last_accessed_at', definition: 'last_accessed_at INTEGER' },
849
+ { name: 'access_count', definition: 'access_count INTEGER DEFAULT 0' },
850
+ { name: 'status', definition: "status TEXT DEFAULT 'active'" }
851
+ ];
852
+ let modified = false;
853
+ for (const col of requiredColumns) {
854
+ if (!existingColumns.has(col.name)) {
855
+ try {
856
+ db.run(`ALTER TABLE memory_entries ADD COLUMN ${col.definition}`);
857
+ columnsAdded.push(col.name);
858
+ modified = true;
859
+ }
860
+ catch (e) {
861
+ // Column might already exist or other error - continue
862
+ }
699
863
  }
700
- });
701
- });
864
+ }
865
+ if (modified) {
866
+ // Save updated database
867
+ const data = db.export();
868
+ fs.writeFileSync(dbPath, Buffer.from(data));
869
+ }
870
+ db.close();
871
+ return { success: true, columnsAdded };
872
+ }
873
+ catch (error) {
874
+ return {
875
+ success: false,
876
+ columnsAdded,
877
+ error: error instanceof Error ? error.message : String(error)
878
+ };
879
+ }
702
880
  }
703
881
  /**
704
882
  * Check for legacy database installations and migrate if needed
705
883
  */
706
- export function checkAndMigrateLegacy(options) {
707
- var _a, _b, _c, _d;
708
- return __awaiter(this, void 0, Promise, function () {
709
- var dbPath, _e, verbose, legacyPaths, _i, legacyPaths_1, legacyPath, initSqlJs, SQL, legacyBuffer, legacyDb, countResult, count, version, versionResult, _f;
710
- return __generator(this, function (_g) {
711
- switch (_g.label) {
712
- case 0:
713
- dbPath = options.dbPath, _e = options.verbose, verbose = _e === void 0 ? false : _e;
714
- legacyPaths = [
715
- path.join(process.cwd(), 'memory.db'),
716
- path.join(process.cwd(), '.claude/memory.db'),
717
- path.join(process.cwd(), 'data/memory.db'),
718
- path.join(process.cwd(), '.claude-flow/memory.db')
719
- ];
720
- _i = 0, legacyPaths_1 = legacyPaths;
721
- _g.label = 1;
722
- case 1:
723
- if (!(_i < legacyPaths_1.length)) return [3 /*break*/, 7];
724
- legacyPath = legacyPaths_1[_i];
725
- if (!(fs.existsSync(legacyPath) && legacyPath !== dbPath)) return [3 /*break*/, 6];
726
- _g.label = 2;
727
- case 2:
728
- _g.trys.push([2, 5, , 6]);
729
- return [4 /*yield*/, import('sql.js')];
730
- case 3:
731
- initSqlJs = (_g.sent())["default"];
732
- return [4 /*yield*/, initSqlJs()];
733
- case 4:
734
- SQL = _g.sent();
735
- legacyBuffer = fs.readFileSync(legacyPath);
736
- legacyDb = new SQL.Database(legacyBuffer);
737
- countResult = legacyDb.exec('SELECT COUNT(*) FROM memory_entries');
738
- count = ((_b = (_a = countResult[0]) === null || _a === void 0 ? void 0 : _a.values[0]) === null || _b === void 0 ? void 0 : _b[0]) || 0;
739
- version = 'unknown';
740
- try {
741
- versionResult = legacyDb.exec("SELECT value FROM metadata WHERE key='schema_version'");
742
- version = ((_d = (_c = versionResult[0]) === null || _c === void 0 ? void 0 : _c.values[0]) === null || _d === void 0 ? void 0 : _d[0]) || 'unknown';
743
- }
744
- catch ( /* no metadata table */_h) { /* no metadata table */ }
745
- legacyDb.close();
746
- if (count > 0) {
747
- return [2 /*return*/, {
748
- needsMigration: true,
749
- legacyVersion: version,
750
- legacyEntries: count
751
- }];
752
- }
753
- return [3 /*break*/, 6];
754
- case 5:
755
- _f = _g.sent();
756
- return [3 /*break*/, 6];
757
- case 6:
758
- _i++;
759
- return [3 /*break*/, 1];
760
- case 7: return [2 /*return*/, { needsMigration: false }];
884
+ export async function checkAndMigrateLegacy(options) {
885
+ const { dbPath, verbose = false } = options;
886
+ // Check for legacy locations
887
+ const legacyPaths = [
888
+ path.join(process.cwd(), 'memory.db'),
889
+ path.join(process.cwd(), '.claude/memory.db'),
890
+ path.join(process.cwd(), 'data/memory.db'),
891
+ path.join(process.cwd(), '.claude-flow/memory.db')
892
+ ];
893
+ for (const legacyPath of legacyPaths) {
894
+ if (fs.existsSync(legacyPath) && legacyPath !== dbPath) {
895
+ try {
896
+ const initSqlJs = (await import('sql.js')).default;
897
+ const SQL = await initSqlJs();
898
+ const legacyBuffer = fs.readFileSync(legacyPath);
899
+ const legacyDb = new SQL.Database(legacyBuffer);
900
+ // Check if it has data
901
+ const countResult = legacyDb.exec('SELECT COUNT(*) FROM memory_entries');
902
+ const count = countResult[0]?.values[0]?.[0] || 0;
903
+ // Get version if available
904
+ let version = 'unknown';
905
+ try {
906
+ const versionResult = legacyDb.exec("SELECT value FROM metadata WHERE key='schema_version'");
907
+ version = versionResult[0]?.values[0]?.[0] || 'unknown';
908
+ }
909
+ catch { /* no metadata table */ }
910
+ legacyDb.close();
911
+ if (count > 0) {
912
+ return {
913
+ needsMigration: true,
914
+ legacyVersion: version,
915
+ legacyEntries: count
916
+ };
917
+ }
761
918
  }
762
- });
763
- });
919
+ catch {
920
+ // Not a valid SQLite database, skip
921
+ }
922
+ }
923
+ }
924
+ return { needsMigration: false };
764
925
  }
765
926
  /**
766
927
  * ADR-053: Activate ControllerRegistry so AgentDB v3 controllers
@@ -773,585 +934,509 @@ export function checkAndMigrateLegacy(options) {
773
934
  * Failures are isolated: if @claude-flow/memory or agentdb is not installed,
774
935
  * this returns an empty result without throwing.
775
936
  */
776
- function activateControllerRegistry(dbPath, verbose) {
777
- return __awaiter(this, void 0, Promise, function () {
778
- var startTime, activated, failed, bridge, registry, controllers, _i, controllers_1, ctrl, _a;
779
- return __generator(this, function (_b) {
780
- switch (_b.label) {
781
- case 0:
782
- startTime = performance.now();
783
- activated = [];
784
- failed = [];
785
- _b.label = 1;
786
- case 1:
787
- _b.trys.push([1, 4, , 5]);
788
- return [4 /*yield*/, getBridge()];
789
- case 2:
790
- bridge = _b.sent();
791
- if (!bridge) {
792
- return [2 /*return*/, { activated: activated, failed: failed, initTimeMs: performance.now() - startTime }];
793
- }
794
- return [4 /*yield*/, bridge.getControllerRegistry(dbPath)];
795
- case 3:
796
- registry = _b.sent();
797
- if (!registry) {
798
- return [2 /*return*/, { activated: activated, failed: failed, initTimeMs: performance.now() - startTime }];
799
- }
800
- // Collect controller status from the registry
801
- if (typeof registry.listControllers === 'function') {
802
- controllers = registry.listControllers();
803
- for (_i = 0, controllers_1 = controllers; _i < controllers_1.length; _i++) {
804
- ctrl = controllers_1[_i];
805
- if (ctrl.enabled) {
806
- activated.push(ctrl.name);
807
- }
808
- else {
809
- failed.push(ctrl.name);
810
- }
811
- }
812
- }
813
- if (verbose && activated.length > 0) {
814
- console.log("ControllerRegistry: " + activated.length + " controllers activated");
815
- }
816
- return [3 /*break*/, 5];
817
- case 4:
818
- _a = _b.sent();
819
- return [3 /*break*/, 5];
820
- case 5: return [2 /*return*/, { activated: activated, failed: failed, initTimeMs: performance.now() - startTime }];
937
+ async function activateControllerRegistry(dbPath, verbose) {
938
+ const startTime = performance.now();
939
+ const activated = [];
940
+ const failed = [];
941
+ try {
942
+ const bridge = await getBridge();
943
+ if (!bridge) {
944
+ return { activated, failed, initTimeMs: performance.now() - startTime };
945
+ }
946
+ const registry = await bridge.getControllerRegistry(dbPath);
947
+ if (!registry) {
948
+ return { activated, failed, initTimeMs: performance.now() - startTime };
949
+ }
950
+ // Collect controller status from the registry
951
+ if (typeof registry.listControllers === 'function') {
952
+ const controllers = registry.listControllers();
953
+ for (const ctrl of controllers) {
954
+ if (ctrl.enabled) {
955
+ activated.push(ctrl.name);
956
+ }
957
+ else {
958
+ failed.push(ctrl.name);
959
+ }
821
960
  }
822
- });
823
- });
961
+ }
962
+ if (verbose && activated.length > 0) {
963
+ console.log(`ControllerRegistry: ${activated.length} controllers activated`);
964
+ }
965
+ }
966
+ catch {
967
+ // ControllerRegistry activation is best-effort
968
+ }
969
+ return { activated, failed, initTimeMs: performance.now() - startTime };
824
970
  }
825
971
  /**
826
972
  * Initialize the memory database properly using sql.js
827
973
  */
828
- export function initializeMemoryDatabase(options) {
829
- return __awaiter(this, void 0, Promise, function () {
830
- var _a, backend, customPath, _b, force, _c, verbose, _d, migrate, swarmDir, dbPath, dbDir, legacyCheck, db, usedSqlJs, initSqlJs, SQL, e_1, data, buffer, schemaPath, controllerResult, schemaPath, sqliteHeader, controllerResult, error_2;
831
- return __generator(this, function (_e) {
832
- switch (_e.label) {
833
- case 0:
834
- _a = options.backend, backend = _a === void 0 ? 'hybrid' : _a, customPath = options.dbPath, _b = options.force, force = _b === void 0 ? false : _b, _c = options.verbose, verbose = _c === void 0 ? false : _c, _d = options.migrate, migrate = _d === void 0 ? true : _d;
835
- swarmDir = path.join(process.cwd(), '.swarm');
836
- dbPath = customPath || path.join(swarmDir, 'memory.db');
837
- dbDir = path.dirname(dbPath);
838
- _e.label = 1;
839
- case 1:
840
- _e.trys.push([1, 13, , 14]);
841
- // Create directory if needed
842
- if (!fs.existsSync(dbDir)) {
843
- fs.mkdirSync(dbDir, { recursive: true });
844
- }
845
- if (!migrate) return [3 /*break*/, 3];
846
- return [4 /*yield*/, checkAndMigrateLegacy({ dbPath: dbPath, verbose: verbose })];
847
- case 2:
848
- legacyCheck = _e.sent();
849
- if (legacyCheck.needsMigration && verbose) {
850
- console.log("Found legacy database (v" + legacyCheck.legacyVersion + ") with " + legacyCheck.legacyEntries + " entries");
851
- }
852
- _e.label = 3;
853
- case 3:
854
- // Check existing database
855
- if (fs.existsSync(dbPath) && !force) {
856
- return [2 /*return*/, {
857
- success: false,
858
- backend: backend,
859
- dbPath: dbPath,
860
- schemaVersion: '3.0.0',
861
- tablesCreated: [],
862
- indexesCreated: [],
863
- features: {
864
- vectorEmbeddings: false,
865
- patternLearning: false,
866
- temporalDecay: false,
867
- hnswIndexing: false,
868
- migrationTracking: false
869
- },
870
- error: 'Database already exists. Use --force to reinitialize.'
871
- }];
872
- }
873
- db = void 0;
874
- usedSqlJs = false;
875
- _e.label = 4;
876
- case 4:
877
- _e.trys.push([4, 7, , 8]);
878
- return [4 /*yield*/, import('sql.js')];
879
- case 5:
880
- initSqlJs = (_e.sent())["default"];
881
- return [4 /*yield*/, initSqlJs()];
882
- case 6:
883
- SQL = _e.sent();
884
- // Load existing database or create new
885
- if (fs.existsSync(dbPath) && force) {
886
- fs.unlinkSync(dbPath);
887
- }
888
- db = new SQL.Database();
889
- usedSqlJs = true;
890
- return [3 /*break*/, 8];
891
- case 7:
892
- e_1 = _e.sent();
893
- // sql.js not available, fall back to writing schema file
894
- if (verbose) {
895
- console.log('sql.js not available, writing schema file for later initialization');
896
- }
897
- return [3 /*break*/, 8];
898
- case 8:
899
- if (!(usedSqlJs && db)) return [3 /*break*/, 10];
900
- // Execute schema
901
- db.run(MEMORY_SCHEMA_V3);
902
- // Insert initial metadata
903
- db.run(getInitialMetadata(backend));
904
- data = db["export"]();
905
- buffer = Buffer.from(data);
906
- fs.writeFileSync(dbPath, buffer);
907
- // Close database
908
- db.close();
909
- schemaPath = path.join(dbDir, 'schema.sql');
910
- fs.writeFileSync(schemaPath, MEMORY_SCHEMA_V3 + '\n' + getInitialMetadata(backend));
911
- return [4 /*yield*/, activateControllerRegistry(dbPath, verbose)];
912
- case 9:
913
- controllerResult = _e.sent();
914
- return [2 /*return*/, {
915
- success: true,
916
- backend: backend,
917
- dbPath: dbPath,
918
- schemaVersion: '3.0.0',
919
- tablesCreated: [
920
- 'memory_entries',
921
- 'patterns',
922
- 'pattern_history',
923
- 'trajectories',
924
- 'trajectory_steps',
925
- 'migration_state',
926
- 'sessions',
927
- 'vector_indexes',
928
- 'metadata'
929
- ],
930
- indexesCreated: [
931
- 'idx_memory_namespace',
932
- 'idx_memory_key',
933
- 'idx_memory_type',
934
- 'idx_memory_status',
935
- 'idx_memory_created',
936
- 'idx_memory_accessed',
937
- 'idx_memory_owner',
938
- 'idx_patterns_type',
939
- 'idx_patterns_confidence',
940
- 'idx_patterns_status',
941
- 'idx_patterns_last_matched',
942
- 'idx_pattern_history_pattern',
943
- 'idx_steps_trajectory'
944
- ],
945
- features: {
946
- vectorEmbeddings: true,
947
- patternLearning: true,
948
- temporalDecay: true,
949
- hnswIndexing: true,
950
- migrationTracking: true
951
- },
952
- controllers: controllerResult
953
- }];
954
- case 10:
955
- schemaPath = path.join(dbDir, 'schema.sql');
956
- fs.writeFileSync(schemaPath, MEMORY_SCHEMA_V3 + '\n' + getInitialMetadata(backend));
957
- sqliteHeader = Buffer.alloc(4096, 0);
958
- // SQLite format 3 header
959
- Buffer.from('SQLite format 3\0').copy(sqliteHeader, 0);
960
- sqliteHeader[16] = 0x10; // page size high byte (4096)
961
- sqliteHeader[17] = 0x00; // page size low byte
962
- sqliteHeader[18] = 0x01; // file format write version
963
- sqliteHeader[19] = 0x01; // file format read version
964
- sqliteHeader[24] = 0x00; // max embedded payload
965
- sqliteHeader[25] = 0x40;
966
- sqliteHeader[26] = 0x20; // min embedded payload
967
- sqliteHeader[27] = 0x20; // leaf payload
968
- fs.writeFileSync(dbPath, sqliteHeader);
969
- return [4 /*yield*/, activateControllerRegistry(dbPath, verbose)];
970
- case 11:
971
- controllerResult = _e.sent();
972
- return [2 /*return*/, {
973
- success: true,
974
- backend: backend,
975
- dbPath: dbPath,
976
- schemaVersion: '3.0.0',
977
- tablesCreated: [
978
- 'memory_entries (pending)',
979
- 'patterns (pending)',
980
- 'pattern_history (pending)',
981
- 'trajectories (pending)',
982
- 'trajectory_steps (pending)',
983
- 'migration_state (pending)',
984
- 'sessions (pending)',
985
- 'vector_indexes (pending)',
986
- 'metadata (pending)'
987
- ],
988
- indexesCreated: [],
989
- features: {
990
- vectorEmbeddings: true,
991
- patternLearning: true,
992
- temporalDecay: true,
993
- hnswIndexing: true,
994
- migrationTracking: true
995
- },
996
- controllers: controllerResult
997
- }];
998
- case 12: return [3 /*break*/, 14];
999
- case 13:
1000
- error_2 = _e.sent();
1001
- return [2 /*return*/, {
1002
- success: false,
1003
- backend: backend,
1004
- dbPath: dbPath,
1005
- schemaVersion: '3.0.0',
1006
- tablesCreated: [],
1007
- indexesCreated: [],
1008
- features: {
1009
- vectorEmbeddings: false,
1010
- patternLearning: false,
1011
- temporalDecay: false,
1012
- hnswIndexing: false,
1013
- migrationTracking: false
1014
- },
1015
- error: error_2 instanceof Error ? error_2.message : String(error_2)
1016
- }];
1017
- case 14: return [2 /*return*/];
974
+ export async function initializeMemoryDatabase(options) {
975
+ const { backend = 'hybrid', dbPath: customPath, force = false, verbose = false, migrate = true } = options;
976
+ const swarmDir = path.join(process.cwd(), '.swarm');
977
+ const dbPath = customPath || path.join(swarmDir, 'memory.db');
978
+ const dbDir = path.dirname(dbPath);
979
+ try {
980
+ // Create directory if needed
981
+ if (!fs.existsSync(dbDir)) {
982
+ fs.mkdirSync(dbDir, { recursive: true });
983
+ }
984
+ // Check for legacy installations
985
+ if (migrate) {
986
+ const legacyCheck = await checkAndMigrateLegacy({ dbPath, verbose });
987
+ if (legacyCheck.needsMigration && verbose) {
988
+ console.log(`Found legacy database (v${legacyCheck.legacyVersion}) with ${legacyCheck.legacyEntries} entries`);
1018
989
  }
1019
- });
1020
- });
990
+ }
991
+ // Check existing database
992
+ if (fs.existsSync(dbPath) && !force) {
993
+ return {
994
+ success: false,
995
+ backend,
996
+ dbPath,
997
+ schemaVersion: '3.0.0',
998
+ tablesCreated: [],
999
+ indexesCreated: [],
1000
+ features: {
1001
+ vectorEmbeddings: false,
1002
+ patternLearning: false,
1003
+ temporalDecay: false,
1004
+ hnswIndexing: false,
1005
+ migrationTracking: false
1006
+ },
1007
+ error: 'Database already exists. Use --force to reinitialize.'
1008
+ };
1009
+ }
1010
+ // Try to use sql.js (WASM SQLite)
1011
+ let db;
1012
+ let usedSqlJs = false;
1013
+ try {
1014
+ // Dynamic import of sql.js
1015
+ const initSqlJs = (await import('sql.js')).default;
1016
+ const SQL = await initSqlJs();
1017
+ // Load existing database or create new
1018
+ if (fs.existsSync(dbPath) && force) {
1019
+ fs.unlinkSync(dbPath);
1020
+ }
1021
+ db = new SQL.Database();
1022
+ usedSqlJs = true;
1023
+ }
1024
+ catch (e) {
1025
+ // sql.js not available, fall back to writing schema file
1026
+ if (verbose) {
1027
+ console.log('sql.js not available, writing schema file for later initialization');
1028
+ }
1029
+ }
1030
+ if (usedSqlJs && db) {
1031
+ // Execute schema
1032
+ db.run(MEMORY_SCHEMA_V3);
1033
+ // Insert initial metadata
1034
+ db.run(getInitialMetadata(backend));
1035
+ // Save to file
1036
+ const data = db.export();
1037
+ const buffer = Buffer.from(data);
1038
+ fs.writeFileSync(dbPath, buffer);
1039
+ // Close database
1040
+ db.close();
1041
+ // Also create schema file for reference
1042
+ const schemaPath = path.join(dbDir, 'schema.sql');
1043
+ fs.writeFileSync(schemaPath, MEMORY_SCHEMA_V3 + '\n' + getInitialMetadata(backend));
1044
+ // ADR-053: Activate ControllerRegistry so controllers (ReasoningBank,
1045
+ // SkillLibrary, ExplainableRecall, etc.) are instantiated during init
1046
+ const controllerResult = await activateControllerRegistry(dbPath, verbose);
1047
+ return {
1048
+ success: true,
1049
+ backend,
1050
+ dbPath,
1051
+ schemaVersion: '3.0.0',
1052
+ tablesCreated: [
1053
+ 'memory_entries',
1054
+ 'patterns',
1055
+ 'pattern_history',
1056
+ 'trajectories',
1057
+ 'trajectory_steps',
1058
+ 'migration_state',
1059
+ 'sessions',
1060
+ 'vector_indexes',
1061
+ 'metadata'
1062
+ ],
1063
+ indexesCreated: [
1064
+ 'idx_memory_namespace',
1065
+ 'idx_memory_key',
1066
+ 'idx_memory_type',
1067
+ 'idx_memory_status',
1068
+ 'idx_memory_created',
1069
+ 'idx_memory_accessed',
1070
+ 'idx_memory_owner',
1071
+ 'idx_patterns_type',
1072
+ 'idx_patterns_confidence',
1073
+ 'idx_patterns_status',
1074
+ 'idx_patterns_last_matched',
1075
+ 'idx_pattern_history_pattern',
1076
+ 'idx_steps_trajectory'
1077
+ ],
1078
+ features: {
1079
+ vectorEmbeddings: true,
1080
+ patternLearning: true,
1081
+ temporalDecay: true,
1082
+ hnswIndexing: true,
1083
+ migrationTracking: true
1084
+ },
1085
+ controllers: controllerResult,
1086
+ };
1087
+ }
1088
+ else {
1089
+ // Fall back to schema file approach
1090
+ const schemaPath = path.join(dbDir, 'schema.sql');
1091
+ fs.writeFileSync(schemaPath, MEMORY_SCHEMA_V3 + '\n' + getInitialMetadata(backend));
1092
+ // Create minimal valid SQLite file
1093
+ const sqliteHeader = Buffer.alloc(4096, 0);
1094
+ // SQLite format 3 header
1095
+ Buffer.from('SQLite format 3\0').copy(sqliteHeader, 0);
1096
+ sqliteHeader[16] = 0x10; // page size high byte (4096)
1097
+ sqliteHeader[17] = 0x00; // page size low byte
1098
+ sqliteHeader[18] = 0x01; // file format write version
1099
+ sqliteHeader[19] = 0x01; // file format read version
1100
+ sqliteHeader[24] = 0x00; // max embedded payload
1101
+ sqliteHeader[25] = 0x40;
1102
+ sqliteHeader[26] = 0x20; // min embedded payload
1103
+ sqliteHeader[27] = 0x20; // leaf payload
1104
+ fs.writeFileSync(dbPath, sqliteHeader);
1105
+ // ADR-053: Activate ControllerRegistry even on fallback path
1106
+ const controllerResult = await activateControllerRegistry(dbPath, verbose);
1107
+ return {
1108
+ success: true,
1109
+ backend,
1110
+ dbPath,
1111
+ schemaVersion: '3.0.0',
1112
+ tablesCreated: [
1113
+ 'memory_entries (pending)',
1114
+ 'patterns (pending)',
1115
+ 'pattern_history (pending)',
1116
+ 'trajectories (pending)',
1117
+ 'trajectory_steps (pending)',
1118
+ 'migration_state (pending)',
1119
+ 'sessions (pending)',
1120
+ 'vector_indexes (pending)',
1121
+ 'metadata (pending)'
1122
+ ],
1123
+ indexesCreated: [],
1124
+ features: {
1125
+ vectorEmbeddings: true,
1126
+ patternLearning: true,
1127
+ temporalDecay: true,
1128
+ hnswIndexing: true,
1129
+ migrationTracking: true
1130
+ },
1131
+ controllers: controllerResult,
1132
+ };
1133
+ }
1134
+ }
1135
+ catch (error) {
1136
+ return {
1137
+ success: false,
1138
+ backend,
1139
+ dbPath,
1140
+ schemaVersion: '3.0.0',
1141
+ tablesCreated: [],
1142
+ indexesCreated: [],
1143
+ features: {
1144
+ vectorEmbeddings: false,
1145
+ patternLearning: false,
1146
+ temporalDecay: false,
1147
+ hnswIndexing: false,
1148
+ migrationTracking: false
1149
+ },
1150
+ error: error instanceof Error ? error.message : String(error)
1151
+ };
1152
+ }
1021
1153
  }
1022
1154
  /**
1023
1155
  * Check if memory database is properly initialized
1024
1156
  */
1025
- export function checkMemoryInitialization(dbPath) {
1026
- var _a, _b, _c, _d, _e, _f;
1027
- return __awaiter(this, void 0, Promise, function () {
1028
- var swarmDir, path_, initSqlJs, SQL, fileBuffer, db, tables, tableNames, version, backend, versionResult, backendResult, _g;
1029
- return __generator(this, function (_h) {
1030
- switch (_h.label) {
1031
- case 0:
1032
- swarmDir = path.join(process.cwd(), '.swarm');
1033
- path_ = dbPath || path.join(swarmDir, 'memory.db');
1034
- if (!fs.existsSync(path_)) {
1035
- return [2 /*return*/, { initialized: false }];
1036
- }
1037
- _h.label = 1;
1038
- case 1:
1039
- _h.trys.push([1, 4, , 5]);
1040
- return [4 /*yield*/, import('sql.js')];
1041
- case 2:
1042
- initSqlJs = (_h.sent())["default"];
1043
- return [4 /*yield*/, initSqlJs()];
1044
- case 3:
1045
- SQL = _h.sent();
1046
- fileBuffer = fs.readFileSync(path_);
1047
- db = new SQL.Database(fileBuffer);
1048
- tables = db.exec("SELECT name FROM sqlite_master WHERE type='table'");
1049
- tableNames = ((_b = (_a = tables[0]) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.map(function (v) { return v[0]; })) || [];
1050
- version = 'unknown';
1051
- backend = 'unknown';
1052
- try {
1053
- versionResult = db.exec("SELECT value FROM metadata WHERE key='schema_version'");
1054
- version = ((_d = (_c = versionResult[0]) === null || _c === void 0 ? void 0 : _c.values[0]) === null || _d === void 0 ? void 0 : _d[0]) || 'unknown';
1055
- backendResult = db.exec("SELECT value FROM metadata WHERE key='backend'");
1056
- backend = ((_f = (_e = backendResult[0]) === null || _e === void 0 ? void 0 : _e.values[0]) === null || _f === void 0 ? void 0 : _f[0]) || 'unknown';
1057
- }
1058
- catch (_j) {
1059
- // Metadata table might not exist
1060
- }
1061
- db.close();
1062
- return [2 /*return*/, {
1063
- initialized: true,
1064
- version: version,
1065
- backend: backend,
1066
- features: {
1067
- vectorEmbeddings: tableNames.includes('vector_indexes'),
1068
- patternLearning: tableNames.includes('patterns'),
1069
- temporalDecay: tableNames.includes('pattern_history')
1070
- },
1071
- tables: tableNames
1072
- }];
1073
- case 4:
1074
- _g = _h.sent();
1075
- // Could not read database
1076
- return [2 /*return*/, { initialized: false }];
1077
- case 5: return [2 /*return*/];
1078
- }
1079
- });
1080
- });
1157
+ export async function checkMemoryInitialization(dbPath) {
1158
+ const swarmDir = path.join(process.cwd(), '.swarm');
1159
+ const path_ = dbPath || path.join(swarmDir, 'memory.db');
1160
+ if (!fs.existsSync(path_)) {
1161
+ return { initialized: false };
1162
+ }
1163
+ try {
1164
+ // Try to load with sql.js
1165
+ const initSqlJs = (await import('sql.js')).default;
1166
+ const SQL = await initSqlJs();
1167
+ const fileBuffer = fs.readFileSync(path_);
1168
+ const db = new SQL.Database(fileBuffer);
1169
+ // Check for metadata table
1170
+ const tables = db.exec("SELECT name FROM sqlite_master WHERE type='table'");
1171
+ const tableNames = tables[0]?.values?.map(v => v[0]) || [];
1172
+ // Get version
1173
+ let version = 'unknown';
1174
+ let backend = 'unknown';
1175
+ try {
1176
+ const versionResult = db.exec("SELECT value FROM metadata WHERE key='schema_version'");
1177
+ version = versionResult[0]?.values[0]?.[0] || 'unknown';
1178
+ const backendResult = db.exec("SELECT value FROM metadata WHERE key='backend'");
1179
+ backend = backendResult[0]?.values[0]?.[0] || 'unknown';
1180
+ }
1181
+ catch {
1182
+ // Metadata table might not exist
1183
+ }
1184
+ db.close();
1185
+ return {
1186
+ initialized: true,
1187
+ version,
1188
+ backend,
1189
+ features: {
1190
+ vectorEmbeddings: tableNames.includes('vector_indexes'),
1191
+ patternLearning: tableNames.includes('patterns'),
1192
+ temporalDecay: tableNames.includes('pattern_history')
1193
+ },
1194
+ tables: tableNames
1195
+ };
1196
+ }
1197
+ catch {
1198
+ // Could not read database
1199
+ return { initialized: false };
1200
+ }
1081
1201
  }
1082
1202
  /**
1083
1203
  * Apply temporal decay to patterns
1084
1204
  * Reduces confidence of patterns that haven't been used recently
1085
1205
  */
1086
- export function applyTemporalDecay(dbPath) {
1087
- return __awaiter(this, void 0, Promise, function () {
1088
- var swarmDir, path_, initSqlJs, SQL, fileBuffer, db, now, decayQuery, changes, data, error_3;
1089
- return __generator(this, function (_a) {
1090
- switch (_a.label) {
1091
- case 0:
1092
- swarmDir = path.join(process.cwd(), '.swarm');
1093
- path_ = dbPath || path.join(swarmDir, 'memory.db');
1094
- _a.label = 1;
1095
- case 1:
1096
- _a.trys.push([1, 4, , 5]);
1097
- return [4 /*yield*/, import('sql.js')];
1098
- case 2:
1099
- initSqlJs = (_a.sent())["default"];
1100
- return [4 /*yield*/, initSqlJs()];
1101
- case 3:
1102
- SQL = _a.sent();
1103
- fileBuffer = fs.readFileSync(path_);
1104
- db = new SQL.Database(fileBuffer);
1105
- now = Date.now();
1106
- decayQuery = "\n UPDATE patterns\n SET\n confidence = confidence * (1.0 - decay_rate * ((? - COALESCE(last_matched_at, created_at)) / 86400000.0)),\n updated_at = ?\n WHERE status = 'active'\n AND confidence > 0.1\n AND (? - COALESCE(last_matched_at, created_at)) > 86400000\n ";
1107
- db.run(decayQuery, [now, now, now]);
1108
- changes = db.getRowsModified();
1109
- data = db["export"]();
1110
- fs.writeFileSync(path_, Buffer.from(data));
1111
- db.close();
1112
- return [2 /*return*/, {
1113
- success: true,
1114
- patternsDecayed: changes
1115
- }];
1116
- case 4:
1117
- error_3 = _a.sent();
1118
- return [2 /*return*/, {
1119
- success: false,
1120
- patternsDecayed: 0,
1121
- error: error_3 instanceof Error ? error_3.message : String(error_3)
1122
- }];
1123
- case 5: return [2 /*return*/];
1124
- }
1125
- });
1126
- });
1206
+ export async function applyTemporalDecay(dbPath) {
1207
+ const swarmDir = path.join(process.cwd(), '.swarm');
1208
+ const path_ = dbPath || path.join(swarmDir, 'memory.db');
1209
+ try {
1210
+ const initSqlJs = (await import('sql.js')).default;
1211
+ const SQL = await initSqlJs();
1212
+ const fileBuffer = fs.readFileSync(path_);
1213
+ const db = new SQL.Database(fileBuffer);
1214
+ // Apply decay: confidence *= exp(-decay_rate * days_since_last_use)
1215
+ const now = Date.now();
1216
+ const decayQuery = `
1217
+ UPDATE patterns
1218
+ SET
1219
+ confidence = confidence * (1.0 - decay_rate * ((? - COALESCE(last_matched_at, created_at)) / 86400000.0)),
1220
+ updated_at = ?
1221
+ WHERE status = 'active'
1222
+ AND confidence > 0.1
1223
+ AND (? - COALESCE(last_matched_at, created_at)) > 86400000
1224
+ `;
1225
+ db.run(decayQuery, [now, now, now]);
1226
+ const changes = db.getRowsModified();
1227
+ // Save
1228
+ const data = db.export();
1229
+ fs.writeFileSync(path_, Buffer.from(data));
1230
+ db.close();
1231
+ return {
1232
+ success: true,
1233
+ patternsDecayed: changes
1234
+ };
1235
+ }
1236
+ catch (error) {
1237
+ return {
1238
+ success: false,
1239
+ patternsDecayed: 0,
1240
+ error: error instanceof Error ? error.message : String(error)
1241
+ };
1242
+ }
1127
1243
  }
1128
- var embeddingModelState = null;
1244
+ let embeddingModelState = null;
1129
1245
  /**
1130
1246
  * Lazy load ONNX embedding model
1131
1247
  * Only loads when first embedding is requested
1132
1248
  */
1133
- export function loadEmbeddingModel(options) {
1134
- var _a;
1135
- return __awaiter(this, void 0, Promise, function () {
1136
- var _b, verbose, startTime, bridge, bridgeResult, transformers, pipeline, embedder, reasoningBank, ruvector, onnxEmb_1, probe, _c, agenticFlow, error_4;
1137
- return __generator(this, function (_d) {
1138
- switch (_d.label) {
1139
- case 0:
1140
- _b = (options || {}).verbose, verbose = _b === void 0 ? false : _b;
1141
- startTime = Date.now();
1142
- // Already loaded
1143
- if (embeddingModelState === null || embeddingModelState === void 0 ? void 0 : embeddingModelState.loaded) {
1144
- return [2 /*return*/, {
1145
- success: true,
1146
- dimensions: embeddingModelState.dimensions,
1147
- modelName: 'cached',
1148
- loadTime: 0
1149
- }];
1150
- }
1151
- return [4 /*yield*/, getBridge()];
1152
- case 1:
1153
- bridge = _d.sent();
1154
- if (!bridge) return [3 /*break*/, 3];
1155
- return [4 /*yield*/, bridge.bridgeLoadEmbeddingModel()];
1156
- case 2:
1157
- bridgeResult = _d.sent();
1158
- if (bridgeResult && bridgeResult.success) {
1159
- // Mark local state as loaded too so subsequent calls use cache
1160
- embeddingModelState = {
1161
- loaded: true,
1162
- model: null,
1163
- tokenizer: null,
1164
- dimensions: bridgeResult.dimensions
1165
- };
1166
- return [2 /*return*/, bridgeResult];
1167
- }
1168
- _d.label = 3;
1169
- case 3:
1170
- _d.trys.push([3, 16, , 17]);
1171
- return [4 /*yield*/, import('@xenova/transformers')["catch"](function () { return null; })];
1172
- case 4:
1173
- transformers = _d.sent();
1174
- if (!transformers) return [3 /*break*/, 6];
1175
- if (verbose) {
1176
- console.log('Loading ONNX embedding model (all-MiniLM-L6-v2)...');
1177
- }
1178
- pipeline = transformers.pipeline;
1179
- return [4 /*yield*/, pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2')];
1180
- case 5:
1181
- embedder = _d.sent();
1182
- embeddingModelState = {
1183
- loaded: true,
1184
- model: embedder,
1185
- tokenizer: null,
1186
- dimensions: 384 // MiniLM-L6 produces 384-dim vectors
1187
- };
1188
- return [2 /*return*/, {
1189
- success: true,
1190
- dimensions: 384,
1191
- modelName: 'all-MiniLM-L6-v2',
1192
- loadTime: Date.now() - startTime
1193
- }];
1194
- case 6: return [4 /*yield*/, import('agentic-flow/reasoningbank')["catch"](function () { return null; })];
1195
- case 7:
1196
- reasoningBank = _d.sent();
1197
- if (reasoningBank === null || reasoningBank === void 0 ? void 0 : reasoningBank.computeEmbedding) {
1198
- if (verbose) {
1199
- console.log('Loading agentic-flow ReasoningBank embedding model...');
1200
- }
1201
- embeddingModelState = {
1202
- loaded: true,
1203
- model: { embed: reasoningBank.computeEmbedding },
1204
- tokenizer: null,
1205
- dimensions: 768
1206
- };
1207
- return [2 /*return*/, {
1208
- success: true,
1209
- dimensions: 768,
1210
- modelName: 'agentic-flow/reasoningbank',
1211
- loadTime: Date.now() - startTime
1212
- }];
1213
- }
1214
- return [4 /*yield*/, import('ruvector')["catch"](function () { return null; })];
1215
- case 8:
1216
- ruvector = _d.sent();
1217
- if (!(ruvector === null || ruvector === void 0 ? void 0 : ruvector.initOnnxEmbedder)) return [3 /*break*/, 14];
1218
- _d.label = 9;
1219
- case 9:
1220
- _d.trys.push([9, 13, , 14]);
1221
- return [4 /*yield*/, ruvector.initOnnxEmbedder()];
1222
- case 10:
1223
- _d.sent();
1224
- onnxEmb_1 = (_a = ruvector.getOptimizedOnnxEmbedder) === null || _a === void 0 ? void 0 : _a.call(ruvector);
1225
- if (!(onnxEmb_1 === null || onnxEmb_1 === void 0 ? void 0 : onnxEmb_1.embed)) return [3 /*break*/, 12];
1226
- return [4 /*yield*/, onnxEmb_1.embed('test')];
1227
- case 11:
1228
- probe = _d.sent();
1229
- if (probe && probe.length > 0 && (Array.isArray(probe) ? probe.some(function (v) { return v !== 0; }) : true)) {
1249
+ export async function loadEmbeddingModel(options) {
1250
+ const { verbose = false } = options || {};
1251
+ const startTime = Date.now();
1252
+ // Already loaded
1253
+ if (embeddingModelState?.loaded) {
1254
+ return {
1255
+ success: true,
1256
+ dimensions: embeddingModelState.dimensions,
1257
+ modelName: 'cached',
1258
+ loadTime: 0
1259
+ };
1260
+ }
1261
+ // ADR-053: Try AgentDB v3 bridge first
1262
+ const bridge = await getBridge();
1263
+ if (bridge) {
1264
+ const bridgeResult = await bridge.bridgeLoadEmbeddingModel();
1265
+ if (bridgeResult && bridgeResult.success) {
1266
+ // Mark local state as loaded too so subsequent calls use cache
1267
+ embeddingModelState = {
1268
+ loaded: true,
1269
+ model: null, // Bridge handles embedding
1270
+ tokenizer: null,
1271
+ dimensions: bridgeResult.dimensions
1272
+ };
1273
+ return bridgeResult;
1274
+ }
1275
+ }
1276
+ try {
1277
+ // Try to import @xenova/transformers for ONNX embeddings
1278
+ const transformers = await import('@xenova/transformers').catch(() => null);
1279
+ if (transformers) {
1280
+ if (verbose) {
1281
+ console.log('Loading ONNX embedding model (all-MiniLM-L6-v2)...');
1282
+ }
1283
+ // Use small, fast model for local embeddings
1284
+ const { pipeline } = transformers;
1285
+ const embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
1286
+ embeddingModelState = {
1287
+ loaded: true,
1288
+ model: embedder,
1289
+ tokenizer: null,
1290
+ dimensions: 384 // MiniLM-L6 produces 384-dim vectors
1291
+ };
1292
+ return {
1293
+ success: true,
1294
+ dimensions: 384,
1295
+ modelName: 'all-MiniLM-L6-v2',
1296
+ loadTime: Date.now() - startTime
1297
+ };
1298
+ }
1299
+ // Fallback: Check for agentic-flow ReasoningBank embeddings (v3)
1300
+ const reasoningBank = await import('agentic-flow/reasoningbank').catch(() => null);
1301
+ if (reasoningBank?.computeEmbedding) {
1302
+ if (verbose) {
1303
+ console.log('Loading agentic-flow ReasoningBank embedding model...');
1304
+ }
1305
+ embeddingModelState = {
1306
+ loaded: true,
1307
+ model: { embed: reasoningBank.computeEmbedding },
1308
+ tokenizer: null,
1309
+ dimensions: 768
1310
+ };
1311
+ return {
1312
+ success: true,
1313
+ dimensions: 768,
1314
+ modelName: 'agentic-flow/reasoningbank',
1315
+ loadTime: Date.now() - startTime
1316
+ };
1317
+ }
1318
+ // Fallback: Check for ruvector ONNX embedder (bundled MiniLM-L6-v2 since v0.2.15)
1319
+ // v0.2.16: LoRA B=0 fix makes AdaptiveEmbedder safe (identity when untrained)
1320
+ // Note: isReady() returns false until first embed() call (lazy init), so we
1321
+ // skip the isReady() gate and verify with a probe embed instead.
1322
+ const ruvector = await import('ruvector').catch(() => null);
1323
+ if (ruvector?.initOnnxEmbedder) {
1324
+ try {
1325
+ await ruvector.initOnnxEmbedder();
1326
+ // Fallback: OptimizedOnnxEmbedder (raw ONNX, lazy-inits on first embed)
1327
+ const onnxEmb = ruvector.getOptimizedOnnxEmbedder?.();
1328
+ if (onnxEmb?.embed) {
1329
+ // Probe embed to trigger lazy ONNX init and verify it works
1330
+ const probe = await onnxEmb.embed('test');
1331
+ if (probe && probe.length > 0 && (Array.isArray(probe) ? probe.some((v) => v !== 0) : true)) {
1230
1332
  if (verbose) {
1231
- console.log("Loading ruvector ONNX embedder (all-MiniLM-L6-v2, " + probe.length + "d)...");
1333
+ console.log(`Loading ruvector ONNX embedder (all-MiniLM-L6-v2, ${probe.length}d)...`);
1232
1334
  }
1233
1335
  embeddingModelState = {
1234
1336
  loaded: true,
1235
- model: function (text) { return onnxEmb_1.embed(text); },
1337
+ model: (text) => onnxEmb.embed(text),
1236
1338
  tokenizer: null,
1237
1339
  dimensions: probe.length || 384
1238
1340
  };
1239
- return [2 /*return*/, {
1240
- success: true,
1241
- dimensions: probe.length || 384,
1242
- modelName: 'ruvector/onnx',
1243
- loadTime: Date.now() - startTime
1244
- }];
1245
- }
1246
- _d.label = 12;
1247
- case 12: return [3 /*break*/, 14];
1248
- case 13:
1249
- _c = _d.sent();
1250
- return [3 /*break*/, 14];
1251
- case 14: return [4 /*yield*/, import('agentic-flow')["catch"](function () { return null; })];
1252
- case 15:
1253
- agenticFlow = _d.sent();
1254
- if (agenticFlow && agenticFlow.embeddings) {
1255
- if (verbose) {
1256
- console.log('Loading agentic-flow embedding model...');
1257
- }
1258
- embeddingModelState = {
1259
- loaded: true,
1260
- model: agenticFlow.embeddings,
1261
- tokenizer: null,
1262
- dimensions: 768
1263
- };
1264
- return [2 /*return*/, {
1265
- success: true,
1266
- dimensions: 768,
1267
- modelName: 'agentic-flow',
1268
- loadTime: Date.now() - startTime
1269
- }];
1270
- }
1271
- // No ONNX model available - use fallback
1272
- embeddingModelState = {
1273
- loaded: true,
1274
- model: null,
1275
- tokenizer: null,
1276
- dimensions: 128 // Smaller fallback dimensions
1277
- };
1278
- return [2 /*return*/, {
1341
+ return {
1279
1342
  success: true,
1280
- dimensions: 128,
1281
- modelName: 'hash-fallback',
1343
+ dimensions: probe.length || 384,
1344
+ modelName: 'ruvector/onnx',
1282
1345
  loadTime: Date.now() - startTime
1283
- }];
1284
- case 16:
1285
- error_4 = _d.sent();
1286
- return [2 /*return*/, {
1287
- success: false,
1288
- dimensions: 0,
1289
- modelName: 'none',
1290
- error: error_4 instanceof Error ? error_4.message : String(error_4)
1291
- }];
1292
- case 17: return [2 /*return*/];
1346
+ };
1347
+ }
1348
+ }
1293
1349
  }
1294
- });
1295
- });
1350
+ catch {
1351
+ // ruvector ONNX init failed, continue to next fallback
1352
+ }
1353
+ }
1354
+ // Legacy fallback: Check for agentic-flow core embeddings
1355
+ const agenticFlow = await import('agentic-flow').catch(() => null);
1356
+ if (agenticFlow && agenticFlow.embeddings) {
1357
+ if (verbose) {
1358
+ console.log('Loading agentic-flow embedding model...');
1359
+ }
1360
+ embeddingModelState = {
1361
+ loaded: true,
1362
+ model: agenticFlow.embeddings,
1363
+ tokenizer: null,
1364
+ dimensions: 768
1365
+ };
1366
+ return {
1367
+ success: true,
1368
+ dimensions: 768,
1369
+ modelName: 'agentic-flow',
1370
+ loadTime: Date.now() - startTime
1371
+ };
1372
+ }
1373
+ // No ONNX model available - use fallback
1374
+ embeddingModelState = {
1375
+ loaded: true,
1376
+ model: null, // Will use simple hash-based fallback
1377
+ tokenizer: null,
1378
+ dimensions: 128 // Smaller fallback dimensions
1379
+ };
1380
+ return {
1381
+ success: true,
1382
+ dimensions: 128,
1383
+ modelName: 'hash-fallback',
1384
+ loadTime: Date.now() - startTime
1385
+ };
1386
+ }
1387
+ catch (error) {
1388
+ return {
1389
+ success: false,
1390
+ dimensions: 0,
1391
+ modelName: 'none',
1392
+ error: error instanceof Error ? error.message : String(error)
1393
+ };
1394
+ }
1296
1395
  }
1297
1396
  /**
1298
1397
  * Generate real embedding for text
1299
1398
  * Uses ONNX model if available, falls back to deterministic hash
1300
1399
  */
1301
- export function generateEmbedding(text) {
1302
- return __awaiter(this, void 0, Promise, function () {
1303
- var bridge, bridgeResult, state, output, embedding_1, _a, embedding;
1304
- return __generator(this, function (_b) {
1305
- switch (_b.label) {
1306
- case 0: return [4 /*yield*/, getBridge()];
1307
- case 1:
1308
- bridge = _b.sent();
1309
- if (!bridge) return [3 /*break*/, 3];
1310
- return [4 /*yield*/, bridge.bridgeGenerateEmbedding(text)];
1311
- case 2:
1312
- bridgeResult = _b.sent();
1313
- if (bridgeResult)
1314
- return [2 /*return*/, bridgeResult];
1315
- _b.label = 3;
1316
- case 3:
1317
- if (!!(embeddingModelState === null || embeddingModelState === void 0 ? void 0 : embeddingModelState.loaded)) return [3 /*break*/, 5];
1318
- return [4 /*yield*/, loadEmbeddingModel()];
1319
- case 4:
1320
- _b.sent();
1321
- _b.label = 5;
1322
- case 5:
1323
- state = embeddingModelState;
1324
- if (!(state.model && typeof state.model === 'function')) return [3 /*break*/, 9];
1325
- _b.label = 6;
1326
- case 6:
1327
- _b.trys.push([6, 8, , 9]);
1328
- return [4 /*yield*/, state.model(text, { pooling: 'mean', normalize: true })];
1329
- case 7:
1330
- output = _b.sent();
1331
- embedding_1 = (output === null || output === void 0 ? void 0 : output.data)
1332
- ? Array.from(output.data)
1333
- : Array.isArray(output) ? output : null;
1334
- if (embedding_1) {
1335
- return [2 /*return*/, {
1336
- embedding: embedding_1,
1337
- dimensions: embedding_1.length,
1338
- model: 'onnx'
1339
- }];
1340
- }
1341
- return [3 /*break*/, 9];
1342
- case 8:
1343
- _a = _b.sent();
1344
- return [3 /*break*/, 9];
1345
- case 9:
1346
- embedding = generateHashEmbedding(text, state.dimensions);
1347
- return [2 /*return*/, {
1348
- embedding: embedding,
1349
- dimensions: state.dimensions,
1350
- model: 'hash-fallback'
1351
- }];
1400
+ export async function generateEmbedding(text) {
1401
+ // ADR-053: Try AgentDB v3 bridge first
1402
+ const bridge = await getBridge();
1403
+ if (bridge) {
1404
+ const bridgeResult = await bridge.bridgeGenerateEmbedding(text);
1405
+ if (bridgeResult)
1406
+ return bridgeResult;
1407
+ }
1408
+ // Ensure model is loaded
1409
+ if (!embeddingModelState?.loaded) {
1410
+ await loadEmbeddingModel();
1411
+ }
1412
+ const state = embeddingModelState;
1413
+ // Use ONNX model if available
1414
+ if (state.model && typeof state.model === 'function') {
1415
+ try {
1416
+ const output = await state.model(text, { pooling: 'mean', normalize: true });
1417
+ // Handle both @xenova/transformers (output.data) and ruvector (plain array) formats
1418
+ const embedding = output?.data
1419
+ ? Array.from(output.data)
1420
+ : Array.isArray(output) ? output : null;
1421
+ if (embedding) {
1422
+ return {
1423
+ embedding,
1424
+ dimensions: embedding.length,
1425
+ model: 'onnx'
1426
+ };
1352
1427
  }
1353
- });
1354
- });
1428
+ }
1429
+ catch {
1430
+ // Fall through to fallback
1431
+ }
1432
+ }
1433
+ // Deterministic hash-based fallback (for testing/demo without ONNX)
1434
+ const embedding = generateHashEmbedding(text, state.dimensions);
1435
+ return {
1436
+ embedding,
1437
+ dimensions: state.dimensions,
1438
+ model: 'hash-fallback'
1439
+ };
1355
1440
  }
1356
1441
  /**
1357
1442
  * Generate embeddings for multiple texts
@@ -1362,510 +1447,437 @@ export function generateEmbedding(text) {
1362
1447
  * @param options - Batch options
1363
1448
  * @returns Array of embedding results with timing info
1364
1449
  */
1365
- export function generateBatchEmbeddings(texts, options) {
1366
- return __awaiter(this, void 0, Promise, function () {
1367
- var _a, _b, concurrency, onProgress, startTime, embeddings, totalTime_1, results, completed, i, chunk, chunkResults, totalTime;
1368
- var _this = this;
1369
- return __generator(this, function (_c) {
1370
- switch (_c.label) {
1371
- case 0:
1372
- _a = options || {}, _b = _a.concurrency, concurrency = _b === void 0 ? texts.length : _b, onProgress = _a.onProgress;
1373
- startTime = Date.now();
1374
- if (!!(embeddingModelState === null || embeddingModelState === void 0 ? void 0 : embeddingModelState.loaded)) return [3 /*break*/, 2];
1375
- return [4 /*yield*/, loadEmbeddingModel()];
1376
- case 1:
1377
- _c.sent();
1378
- _c.label = 2;
1379
- case 2:
1380
- if (!(concurrency >= texts.length)) return [3 /*break*/, 4];
1381
- return [4 /*yield*/, Promise.all(texts.map(function (text, i) { return __awaiter(_this, void 0, void 0, function () {
1382
- var result;
1383
- return __generator(this, function (_a) {
1384
- switch (_a.label) {
1385
- case 0: return [4 /*yield*/, generateEmbedding(text)];
1386
- case 1:
1387
- result = _a.sent();
1388
- onProgress === null || onProgress === void 0 ? void 0 : onProgress(i + 1, texts.length);
1389
- return [2 /*return*/, __assign({ text: text }, result)];
1390
- }
1391
- });
1392
- }); }))];
1393
- case 3:
1394
- embeddings = _c.sent();
1395
- totalTime_1 = Date.now() - startTime;
1396
- return [2 /*return*/, {
1397
- results: embeddings,
1398
- totalTime: totalTime_1,
1399
- avgTime: totalTime_1 / texts.length
1400
- }];
1401
- case 4:
1402
- results = [];
1403
- completed = 0;
1404
- i = 0;
1405
- _c.label = 5;
1406
- case 5:
1407
- if (!(i < texts.length)) return [3 /*break*/, 8];
1408
- chunk = texts.slice(i, i + concurrency);
1409
- return [4 /*yield*/, Promise.all(chunk.map(function (text) { return __awaiter(_this, void 0, void 0, function () {
1410
- var result;
1411
- return __generator(this, function (_a) {
1412
- switch (_a.label) {
1413
- case 0: return [4 /*yield*/, generateEmbedding(text)];
1414
- case 1:
1415
- result = _a.sent();
1416
- completed++;
1417
- onProgress === null || onProgress === void 0 ? void 0 : onProgress(completed, texts.length);
1418
- return [2 /*return*/, __assign({ text: text }, result)];
1419
- }
1420
- });
1421
- }); }))];
1422
- case 6:
1423
- chunkResults = _c.sent();
1424
- results.push.apply(results, chunkResults);
1425
- _c.label = 7;
1426
- case 7:
1427
- i += concurrency;
1428
- return [3 /*break*/, 5];
1429
- case 8:
1430
- totalTime = Date.now() - startTime;
1431
- return [2 /*return*/, {
1432
- results: results,
1433
- totalTime: totalTime,
1434
- avgTime: totalTime / texts.length
1435
- }];
1436
- }
1437
- });
1438
- });
1450
+ export async function generateBatchEmbeddings(texts, options) {
1451
+ const { concurrency = texts.length, onProgress } = options || {};
1452
+ const startTime = Date.now();
1453
+ // Ensure model is loaded first (prevents cold start in parallel)
1454
+ if (!embeddingModelState?.loaded) {
1455
+ await loadEmbeddingModel();
1456
+ }
1457
+ // Process in parallel with optional concurrency limit
1458
+ if (concurrency >= texts.length) {
1459
+ // Full parallelism
1460
+ const embeddings = await Promise.all(texts.map(async (text, i) => {
1461
+ const result = await generateEmbedding(text);
1462
+ onProgress?.(i + 1, texts.length);
1463
+ return { text, ...result };
1464
+ }));
1465
+ const totalTime = Date.now() - startTime;
1466
+ return {
1467
+ results: embeddings,
1468
+ totalTime,
1469
+ avgTime: totalTime / texts.length
1470
+ };
1471
+ }
1472
+ // Limited concurrency using chunking
1473
+ const results = [];
1474
+ let completed = 0;
1475
+ for (let i = 0; i < texts.length; i += concurrency) {
1476
+ const chunk = texts.slice(i, i + concurrency);
1477
+ const chunkResults = await Promise.all(chunk.map(async (text) => {
1478
+ const result = await generateEmbedding(text);
1479
+ completed++;
1480
+ onProgress?.(completed, texts.length);
1481
+ return { text, ...result };
1482
+ }));
1483
+ results.push(...chunkResults);
1484
+ }
1485
+ const totalTime = Date.now() - startTime;
1486
+ return {
1487
+ results,
1488
+ totalTime,
1489
+ avgTime: totalTime / texts.length
1490
+ };
1439
1491
  }
1440
1492
  /**
1441
1493
  * Generate deterministic hash-based embedding
1442
1494
  * Not semantic, but deterministic and useful for testing
1443
1495
  */
1444
1496
  function generateHashEmbedding(text, dimensions) {
1445
- var embedding = new Array(dimensions).fill(0);
1497
+ const embedding = new Array(dimensions).fill(0);
1446
1498
  // Simple hash-based approach for reproducibility
1447
- var words = text.toLowerCase().split(/\s+/);
1448
- for (var i = 0; i < words.length; i++) {
1449
- var word = words[i];
1450
- for (var j = 0; j < word.length; j++) {
1451
- var charCode = word.charCodeAt(j);
1452
- var idx = (charCode * (i + 1) * (j + 1)) % dimensions;
1499
+ const words = text.toLowerCase().split(/\s+/);
1500
+ for (let i = 0; i < words.length; i++) {
1501
+ const word = words[i];
1502
+ for (let j = 0; j < word.length; j++) {
1503
+ const charCode = word.charCodeAt(j);
1504
+ const idx = (charCode * (i + 1) * (j + 1)) % dimensions;
1453
1505
  embedding[idx] += Math.sin(charCode * 0.1) * 0.1;
1454
1506
  }
1455
1507
  }
1456
1508
  // Normalize to unit vector
1457
- var magnitude = Math.sqrt(embedding.reduce(function (sum, v) { return sum + v * v; }, 0)) || 1;
1458
- return embedding.map(function (v) { return v / magnitude; });
1509
+ const magnitude = Math.sqrt(embedding.reduce((sum, v) => sum + v * v, 0)) || 1;
1510
+ return embedding.map(v => v / magnitude);
1459
1511
  }
1460
1512
  /**
1461
1513
  * Verify memory initialization works correctly
1462
1514
  * Tests: write, read, search, patterns
1463
1515
  */
1464
- export function verifyMemoryInit(dbPath, options) {
1465
- var _a, _b, _c, _d, _e;
1466
- return __awaiter(this, void 0, Promise, function () {
1467
- var _f, verbose, tests, initSqlJs, SQL, fs_1, fileBuffer, db, schemaStart, tables, tableNames_1, expectedTables, missingTables, writeStart, testId, testKey, testValue, readStart, result, content, embeddingStart, _g, embedding, dimensions, model, embeddingJson, e_2, patternStart, patternId, indexStart, indexResult, indexes, data, passed, failed, error_5;
1468
- return __generator(this, function (_h) {
1469
- switch (_h.label) {
1470
- case 0:
1471
- _f = (options || {}).verbose, verbose = _f === void 0 ? false : _f;
1472
- tests = [];
1473
- _h.label = 1;
1474
- case 1:
1475
- _h.trys.push([1, 9, , 10]);
1476
- return [4 /*yield*/, import('sql.js')];
1477
- case 2:
1478
- initSqlJs = (_h.sent())["default"];
1479
- return [4 /*yield*/, initSqlJs()];
1480
- case 3:
1481
- SQL = _h.sent();
1482
- return [4 /*yield*/, import('fs')];
1483
- case 4:
1484
- fs_1 = _h.sent();
1485
- fileBuffer = fs_1.readFileSync(dbPath);
1486
- db = new SQL.Database(fileBuffer);
1487
- schemaStart = Date.now();
1488
- tables = db.exec("SELECT name FROM sqlite_master WHERE type='table'");
1489
- tableNames_1 = ((_b = (_a = tables[0]) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.map(function (v) { return v[0]; })) || [];
1490
- expectedTables = ['memory_entries', 'patterns', 'metadata', 'vector_indexes'];
1491
- missingTables = expectedTables.filter(function (t) { return !tableNames_1.includes(t); });
1492
- tests.push({
1493
- name: 'Schema verification',
1494
- passed: missingTables.length === 0,
1495
- details: missingTables.length > 0 ? "Missing: " + missingTables.join(', ') : tableNames_1.length + " tables found",
1496
- duration: Date.now() - schemaStart
1497
- });
1498
- writeStart = Date.now();
1499
- testId = "test_" + Date.now();
1500
- testKey = 'verification_test';
1501
- testValue = 'This is a verification test entry for memory initialization';
1502
- try {
1503
- db.run("\n INSERT INTO memory_entries (id, key, namespace, content, type, created_at, updated_at)\n VALUES (?, ?, 'test', ?, 'semantic', ?, ?)\n ", [testId, testKey, testValue, Date.now(), Date.now()]);
1504
- tests.push({
1505
- name: 'Write entry',
1506
- passed: true,
1507
- details: 'Entry written successfully',
1508
- duration: Date.now() - writeStart
1509
- });
1510
- }
1511
- catch (e) {
1512
- tests.push({
1513
- name: 'Write entry',
1514
- passed: false,
1515
- details: e instanceof Error ? e.message : 'Write failed',
1516
- duration: Date.now() - writeStart
1517
- });
1518
- }
1519
- readStart = Date.now();
1520
- try {
1521
- result = db.exec("SELECT content FROM memory_entries WHERE id = ?", [testId]);
1522
- content = (_d = (_c = result[0]) === null || _c === void 0 ? void 0 : _c.values[0]) === null || _d === void 0 ? void 0 : _d[0];
1523
- tests.push({
1524
- name: 'Read entry',
1525
- passed: content === testValue,
1526
- details: content === testValue ? 'Content matches' : 'Content mismatch',
1527
- duration: Date.now() - readStart
1528
- });
1529
- }
1530
- catch (e) {
1531
- tests.push({
1532
- name: 'Read entry',
1533
- passed: false,
1534
- details: e instanceof Error ? e.message : 'Read failed',
1535
- duration: Date.now() - readStart
1536
- });
1537
- }
1538
- embeddingStart = Date.now();
1539
- _h.label = 5;
1540
- case 5:
1541
- _h.trys.push([5, 7, , 8]);
1542
- return [4 /*yield*/, generateEmbedding(testValue)];
1543
- case 6:
1544
- _g = _h.sent(), embedding = _g.embedding, dimensions = _g.dimensions, model = _g.model;
1545
- embeddingJson = JSON.stringify(embedding);
1546
- db.run("\n UPDATE memory_entries\n SET embedding = ?, embedding_dimensions = ?, embedding_model = ?\n WHERE id = ?\n ", [embeddingJson, dimensions, model, testId]);
1547
- tests.push({
1548
- name: 'Generate embedding',
1549
- passed: true,
1550
- details: dimensions + "-dim vector (" + model + ")",
1551
- duration: Date.now() - embeddingStart
1552
- });
1553
- return [3 /*break*/, 8];
1554
- case 7:
1555
- e_2 = _h.sent();
1556
- tests.push({
1557
- name: 'Generate embedding',
1558
- passed: false,
1559
- details: e_2 instanceof Error ? e_2.message : 'Embedding failed',
1560
- duration: Date.now() - embeddingStart
1561
- });
1562
- return [3 /*break*/, 8];
1563
- case 8:
1564
- patternStart = Date.now();
1565
- try {
1566
- patternId = "pattern_" + Date.now();
1567
- db.run("\n INSERT INTO patterns (id, name, pattern_type, condition, action, confidence, created_at, updated_at)\n VALUES (?, 'test-pattern', 'task-routing', 'test condition', 'test action', 0.5, ?, ?)\n ", [patternId, Date.now(), Date.now()]);
1568
- tests.push({
1569
- name: 'Pattern storage',
1570
- passed: true,
1571
- details: 'Pattern stored with confidence scoring',
1572
- duration: Date.now() - patternStart
1573
- });
1574
- // Cleanup test pattern
1575
- db.run("DELETE FROM patterns WHERE id = ?", [patternId]);
1576
- }
1577
- catch (e) {
1578
- tests.push({
1579
- name: 'Pattern storage',
1580
- passed: false,
1581
- details: e instanceof Error ? e.message : 'Pattern storage failed',
1582
- duration: Date.now() - patternStart
1583
- });
1584
- }
1585
- indexStart = Date.now();
1586
- try {
1587
- indexResult = db.exec("SELECT name, dimensions, hnsw_m, hnsw_ef_construction FROM vector_indexes");
1588
- indexes = ((_e = indexResult[0]) === null || _e === void 0 ? void 0 : _e.values) || [];
1589
- tests.push({
1590
- name: 'Vector index config',
1591
- passed: indexes.length > 0,
1592
- details: indexes.length + " indexes configured (HNSW M=16, ef=200)",
1593
- duration: Date.now() - indexStart
1594
- });
1595
- }
1596
- catch (e) {
1597
- tests.push({
1598
- name: 'Vector index config',
1599
- passed: false,
1600
- details: e instanceof Error ? e.message : 'Index check failed',
1601
- duration: Date.now() - indexStart
1602
- });
1603
- }
1604
- // Cleanup test entry
1605
- db.run("DELETE FROM memory_entries WHERE id = ?", [testId]);
1606
- data = db["export"]();
1607
- fs_1.writeFileSync(dbPath, Buffer.from(data));
1608
- db.close();
1609
- passed = tests.filter(function (t) { return t.passed; }).length;
1610
- failed = tests.filter(function (t) { return !t.passed; }).length;
1611
- return [2 /*return*/, {
1612
- success: failed === 0,
1613
- tests: tests,
1614
- summary: {
1615
- passed: passed,
1616
- failed: failed,
1617
- total: tests.length
1618
- }
1619
- }];
1620
- case 9:
1621
- error_5 = _h.sent();
1622
- return [2 /*return*/, {
1623
- success: false,
1624
- tests: [{
1625
- name: 'Database access',
1626
- passed: false,
1627
- details: error_5 instanceof Error ? error_5.message : 'Unknown error'
1628
- }],
1629
- summary: { passed: 0, failed: 1, total: 1 }
1630
- }];
1631
- case 10: return [2 /*return*/];
1632
- }
1516
+ export async function verifyMemoryInit(dbPath, options) {
1517
+ const { verbose = false } = options || {};
1518
+ const tests = [];
1519
+ try {
1520
+ const initSqlJs = (await import('sql.js')).default;
1521
+ const SQL = await initSqlJs();
1522
+ const fs = await import('fs');
1523
+ // Load database
1524
+ const fileBuffer = fs.readFileSync(dbPath);
1525
+ const db = new SQL.Database(fileBuffer);
1526
+ // Test 1: Schema verification
1527
+ const schemaStart = Date.now();
1528
+ const tables = db.exec("SELECT name FROM sqlite_master WHERE type='table'");
1529
+ const tableNames = tables[0]?.values?.map(v => v[0]) || [];
1530
+ const expectedTables = ['memory_entries', 'patterns', 'metadata', 'vector_indexes'];
1531
+ const missingTables = expectedTables.filter(t => !tableNames.includes(t));
1532
+ tests.push({
1533
+ name: 'Schema verification',
1534
+ passed: missingTables.length === 0,
1535
+ details: missingTables.length > 0 ? `Missing: ${missingTables.join(', ')}` : `${tableNames.length} tables found`,
1536
+ duration: Date.now() - schemaStart
1633
1537
  });
1634
- });
1538
+ // Test 2: Write entry
1539
+ const writeStart = Date.now();
1540
+ const testId = `test_${Date.now()}`;
1541
+ const testKey = 'verification_test';
1542
+ const testValue = 'This is a verification test entry for memory initialization';
1543
+ try {
1544
+ db.run(`
1545
+ INSERT INTO memory_entries (id, key, namespace, content, type, created_at, updated_at)
1546
+ VALUES (?, ?, 'test', ?, 'semantic', ?, ?)
1547
+ `, [testId, testKey, testValue, Date.now(), Date.now()]);
1548
+ tests.push({
1549
+ name: 'Write entry',
1550
+ passed: true,
1551
+ details: 'Entry written successfully',
1552
+ duration: Date.now() - writeStart
1553
+ });
1554
+ }
1555
+ catch (e) {
1556
+ tests.push({
1557
+ name: 'Write entry',
1558
+ passed: false,
1559
+ details: e instanceof Error ? e.message : 'Write failed',
1560
+ duration: Date.now() - writeStart
1561
+ });
1562
+ }
1563
+ // Test 3: Read entry
1564
+ const readStart = Date.now();
1565
+ try {
1566
+ const result = db.exec(`SELECT content FROM memory_entries WHERE id = ?`, [testId]);
1567
+ const content = result[0]?.values[0]?.[0];
1568
+ tests.push({
1569
+ name: 'Read entry',
1570
+ passed: content === testValue,
1571
+ details: content === testValue ? 'Content matches' : 'Content mismatch',
1572
+ duration: Date.now() - readStart
1573
+ });
1574
+ }
1575
+ catch (e) {
1576
+ tests.push({
1577
+ name: 'Read entry',
1578
+ passed: false,
1579
+ details: e instanceof Error ? e.message : 'Read failed',
1580
+ duration: Date.now() - readStart
1581
+ });
1582
+ }
1583
+ // Test 4: Write with embedding
1584
+ const embeddingStart = Date.now();
1585
+ try {
1586
+ const { embedding, dimensions, model } = await generateEmbedding(testValue);
1587
+ const embeddingJson = JSON.stringify(embedding);
1588
+ db.run(`
1589
+ UPDATE memory_entries
1590
+ SET embedding = ?, embedding_dimensions = ?, embedding_model = ?
1591
+ WHERE id = ?
1592
+ `, [embeddingJson, dimensions, model, testId]);
1593
+ tests.push({
1594
+ name: 'Generate embedding',
1595
+ passed: true,
1596
+ details: `${dimensions}-dim vector (${model})`,
1597
+ duration: Date.now() - embeddingStart
1598
+ });
1599
+ }
1600
+ catch (e) {
1601
+ tests.push({
1602
+ name: 'Generate embedding',
1603
+ passed: false,
1604
+ details: e instanceof Error ? e.message : 'Embedding failed',
1605
+ duration: Date.now() - embeddingStart
1606
+ });
1607
+ }
1608
+ // Test 5: Pattern storage
1609
+ const patternStart = Date.now();
1610
+ try {
1611
+ const patternId = `pattern_${Date.now()}`;
1612
+ db.run(`
1613
+ INSERT INTO patterns (id, name, pattern_type, condition, action, confidence, created_at, updated_at)
1614
+ VALUES (?, 'test-pattern', 'task-routing', 'test condition', 'test action', 0.5, ?, ?)
1615
+ `, [patternId, Date.now(), Date.now()]);
1616
+ tests.push({
1617
+ name: 'Pattern storage',
1618
+ passed: true,
1619
+ details: 'Pattern stored with confidence scoring',
1620
+ duration: Date.now() - patternStart
1621
+ });
1622
+ // Cleanup test pattern
1623
+ db.run(`DELETE FROM patterns WHERE id = ?`, [patternId]);
1624
+ }
1625
+ catch (e) {
1626
+ tests.push({
1627
+ name: 'Pattern storage',
1628
+ passed: false,
1629
+ details: e instanceof Error ? e.message : 'Pattern storage failed',
1630
+ duration: Date.now() - patternStart
1631
+ });
1632
+ }
1633
+ // Test 6: Vector index configuration
1634
+ const indexStart = Date.now();
1635
+ try {
1636
+ const indexResult = db.exec(`SELECT name, dimensions, hnsw_m, hnsw_ef_construction FROM vector_indexes`);
1637
+ const indexes = indexResult[0]?.values || [];
1638
+ tests.push({
1639
+ name: 'Vector index config',
1640
+ passed: indexes.length > 0,
1641
+ details: `${indexes.length} indexes configured (HNSW M=16, ef=200)`,
1642
+ duration: Date.now() - indexStart
1643
+ });
1644
+ }
1645
+ catch (e) {
1646
+ tests.push({
1647
+ name: 'Vector index config',
1648
+ passed: false,
1649
+ details: e instanceof Error ? e.message : 'Index check failed',
1650
+ duration: Date.now() - indexStart
1651
+ });
1652
+ }
1653
+ // Cleanup test entry
1654
+ db.run(`DELETE FROM memory_entries WHERE id = ?`, [testId]);
1655
+ // Save changes
1656
+ const data = db.export();
1657
+ fs.writeFileSync(dbPath, Buffer.from(data));
1658
+ db.close();
1659
+ const passed = tests.filter(t => t.passed).length;
1660
+ const failed = tests.filter(t => !t.passed).length;
1661
+ return {
1662
+ success: failed === 0,
1663
+ tests,
1664
+ summary: {
1665
+ passed,
1666
+ failed,
1667
+ total: tests.length
1668
+ }
1669
+ };
1670
+ }
1671
+ catch (error) {
1672
+ return {
1673
+ success: false,
1674
+ tests: [{
1675
+ name: 'Database access',
1676
+ passed: false,
1677
+ details: error instanceof Error ? error.message : 'Unknown error'
1678
+ }],
1679
+ summary: { passed: 0, failed: 1, total: 1 }
1680
+ };
1681
+ }
1635
1682
  }
1636
1683
  /**
1637
1684
  * Store an entry directly using sql.js
1638
1685
  * This bypasses MCP and writes directly to the database
1639
1686
  */
1640
- export function storeEntry(options) {
1641
- return __awaiter(this, void 0, Promise, function () {
1642
- var bridge, bridgeResult, key, value, _a, namespace, _b, generateEmbeddingFlag, _c, tags, ttl, customPath, _d, upsert, swarmDir, dbPath, initSqlJs, SQL, fileBuffer, db, id, now, embeddingJson, embeddingDimensions, embeddingModel, embResult, insertSql, data, embResult, error_6;
1643
- return __generator(this, function (_e) {
1644
- switch (_e.label) {
1645
- case 0: return [4 /*yield*/, getBridge()];
1646
- case 1:
1647
- bridge = _e.sent();
1648
- if (!bridge) return [3 /*break*/, 3];
1649
- return [4 /*yield*/, bridge.bridgeStoreEntry(options)];
1650
- case 2:
1651
- bridgeResult = _e.sent();
1652
- if (bridgeResult)
1653
- return [2 /*return*/, bridgeResult];
1654
- _e.label = 3;
1655
- case 3:
1656
- key = options.key, value = options.value, _a = options.namespace, namespace = _a === void 0 ? 'default' : _a, _b = options.generateEmbeddingFlag, generateEmbeddingFlag = _b === void 0 ? true : _b, _c = options.tags, tags = _c === void 0 ? [] : _c, ttl = options.ttl, customPath = options.dbPath, _d = options.upsert, upsert = _d === void 0 ? false : _d;
1657
- swarmDir = path.join(process.cwd(), '.swarm');
1658
- dbPath = customPath || path.join(swarmDir, 'memory.db');
1659
- _e.label = 4;
1660
- case 4:
1661
- _e.trys.push([4, 12, , 13]);
1662
- if (!fs.existsSync(dbPath)) {
1663
- return [2 /*return*/, { success: false, id: '', error: 'Database not initialized. Run: claude-flow memory init' }];
1664
- }
1665
- // Ensure schema has all required columns (migration for older DBs)
1666
- return [4 /*yield*/, ensureSchemaColumns(dbPath)];
1667
- case 5:
1668
- // Ensure schema has all required columns (migration for older DBs)
1669
- _e.sent();
1670
- return [4 /*yield*/, import('sql.js')];
1671
- case 6:
1672
- initSqlJs = (_e.sent())["default"];
1673
- return [4 /*yield*/, initSqlJs()];
1674
- case 7:
1675
- SQL = _e.sent();
1676
- fileBuffer = fs.readFileSync(dbPath);
1677
- db = new SQL.Database(fileBuffer);
1678
- id = "entry_" + Date.now() + "_" + Math.random().toString(36).substring(7);
1679
- now = Date.now();
1680
- embeddingJson = null;
1681
- embeddingDimensions = null;
1682
- embeddingModel = null;
1683
- if (!(generateEmbeddingFlag && value.length > 0)) return [3 /*break*/, 9];
1684
- return [4 /*yield*/, generateEmbedding(value)];
1685
- case 8:
1686
- embResult = _e.sent();
1687
- embeddingJson = JSON.stringify(embResult.embedding);
1688
- embeddingDimensions = embResult.dimensions;
1689
- embeddingModel = embResult.model;
1690
- _e.label = 9;
1691
- case 9:
1692
- insertSql = upsert
1693
- ? "INSERT OR REPLACE INTO memory_entries (\n id, key, namespace, content, type,\n embedding, embedding_dimensions, embedding_model,\n tags, metadata, created_at, updated_at, expires_at, status\n ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, ?, ?, ?, ?, ?, ?, 'active')"
1694
- : "INSERT INTO memory_entries (\n id, key, namespace, content, type,\n embedding, embedding_dimensions, embedding_model,\n tags, metadata, created_at, updated_at, expires_at, status\n ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, ?, ?, ?, ?, ?, ?, 'active')";
1695
- db.run(insertSql, [
1696
- id,
1697
- key,
1698
- namespace,
1699
- value,
1700
- embeddingJson,
1701
- embeddingDimensions,
1702
- embeddingModel,
1703
- tags.length > 0 ? JSON.stringify(tags) : null,
1704
- '{}',
1705
- now,
1706
- now,
1707
- ttl ? now + (ttl * 1000) : null
1708
- ]);
1709
- data = db["export"]();
1710
- fs.writeFileSync(dbPath, Buffer.from(data));
1711
- db.close();
1712
- if (!embeddingJson) return [3 /*break*/, 11];
1713
- embResult = JSON.parse(embeddingJson);
1714
- return [4 /*yield*/, addToHNSWIndex(id, embResult, {
1715
- id: id,
1716
- key: key,
1717
- namespace: namespace,
1718
- content: value
1719
- })];
1720
- case 10:
1721
- _e.sent();
1722
- _e.label = 11;
1723
- case 11: return [2 /*return*/, {
1724
- success: true,
1725
- id: id,
1726
- embedding: embeddingJson ? { dimensions: embeddingDimensions, model: embeddingModel } : undefined
1727
- }];
1728
- case 12:
1729
- error_6 = _e.sent();
1730
- return [2 /*return*/, {
1731
- success: false,
1732
- id: '',
1733
- error: error_6 instanceof Error ? error_6.message : String(error_6)
1734
- }];
1735
- case 13: return [2 /*return*/];
1736
- }
1737
- });
1738
- });
1687
+ export async function storeEntry(options) {
1688
+ // ADR-053: Try AgentDB v3 bridge first
1689
+ const bridge = await getBridge();
1690
+ if (bridge) {
1691
+ const bridgeResult = await bridge.bridgeStoreEntry(options);
1692
+ if (bridgeResult)
1693
+ return bridgeResult;
1694
+ }
1695
+ // Fallback: raw sql.js
1696
+ const { key, value, namespace = 'default', generateEmbeddingFlag = true, tags = [], ttl, dbPath: customPath, upsert = false } = options;
1697
+ const swarmDir = path.join(process.cwd(), '.swarm');
1698
+ const dbPath = customPath || path.join(swarmDir, 'memory.db');
1699
+ try {
1700
+ if (!fs.existsSync(dbPath)) {
1701
+ return { success: false, id: '', error: 'Database not initialized. Run: claude-flow memory init' };
1702
+ }
1703
+ // Ensure schema has all required columns (migration for older DBs)
1704
+ await ensureSchemaColumns(dbPath);
1705
+ const initSqlJs = (await import('sql.js')).default;
1706
+ const SQL = await initSqlJs();
1707
+ const fileBuffer = fs.readFileSync(dbPath);
1708
+ const db = new SQL.Database(fileBuffer);
1709
+ const id = `entry_${Date.now()}_${Math.random().toString(36).substring(7)}`;
1710
+ const now = Date.now();
1711
+ // Generate embedding if requested
1712
+ let embeddingJson = null;
1713
+ let embeddingDimensions = null;
1714
+ let embeddingModel = null;
1715
+ if (generateEmbeddingFlag && value.length > 0) {
1716
+ const embResult = await generateEmbedding(value);
1717
+ embeddingJson = JSON.stringify(embResult.embedding);
1718
+ embeddingDimensions = embResult.dimensions;
1719
+ embeddingModel = embResult.model;
1720
+ }
1721
+ // Insert or update entry (upsert mode uses REPLACE)
1722
+ const insertSql = upsert
1723
+ ? `INSERT OR REPLACE INTO memory_entries (
1724
+ id, key, namespace, content, type,
1725
+ embedding, embedding_dimensions, embedding_model,
1726
+ tags, metadata, created_at, updated_at, expires_at, status
1727
+ ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, ?, ?, ?, ?, ?, ?, 'active')`
1728
+ : `INSERT INTO memory_entries (
1729
+ id, key, namespace, content, type,
1730
+ embedding, embedding_dimensions, embedding_model,
1731
+ tags, metadata, created_at, updated_at, expires_at, status
1732
+ ) VALUES (?, ?, ?, ?, 'semantic', ?, ?, ?, ?, ?, ?, ?, ?, 'active')`;
1733
+ db.run(insertSql, [
1734
+ id,
1735
+ key,
1736
+ namespace,
1737
+ value,
1738
+ embeddingJson,
1739
+ embeddingDimensions,
1740
+ embeddingModel,
1741
+ tags.length > 0 ? JSON.stringify(tags) : null,
1742
+ '{}',
1743
+ now,
1744
+ now,
1745
+ ttl ? now + (ttl * 1000) : null
1746
+ ]);
1747
+ // Save
1748
+ const data = db.export();
1749
+ fs.writeFileSync(dbPath, Buffer.from(data));
1750
+ db.close();
1751
+ // Add to HNSW index for faster future searches
1752
+ if (embeddingJson) {
1753
+ const embResult = JSON.parse(embeddingJson);
1754
+ await addToHNSWIndex(id, embResult, {
1755
+ id,
1756
+ key,
1757
+ namespace,
1758
+ content: value
1759
+ });
1760
+ }
1761
+ return {
1762
+ success: true,
1763
+ id,
1764
+ embedding: embeddingJson ? { dimensions: embeddingDimensions, model: embeddingModel } : undefined
1765
+ };
1766
+ }
1767
+ catch (error) {
1768
+ return {
1769
+ success: false,
1770
+ id: '',
1771
+ error: error instanceof Error ? error.message : String(error)
1772
+ };
1773
+ }
1739
1774
  }
1740
1775
  /**
1741
1776
  * Search entries using sql.js with vector similarity
1742
1777
  * Uses HNSW index for 150x faster search when available
1743
1778
  */
1744
- export function searchEntries(options) {
1745
- var _a;
1746
- return __awaiter(this, void 0, Promise, function () {
1747
- var bridge, bridgeResult, query, _b, namespace, _c, limit, _d, threshold, customPath, swarmDir, dbPath, startTime, queryEmb, queryEmbedding, hnswResults, filtered, initSqlJs, SQL, fileBuffer, db, searchStmt, searchRows, entries, results, _loop_1, _i, _e, row, error_7;
1748
- return __generator(this, function (_f) {
1749
- switch (_f.label) {
1750
- case 0: return [4 /*yield*/, getBridge()];
1751
- case 1:
1752
- bridge = _f.sent();
1753
- if (!bridge) return [3 /*break*/, 3];
1754
- return [4 /*yield*/, bridge.bridgeSearchEntries(options)];
1755
- case 2:
1756
- bridgeResult = _f.sent();
1757
- if (bridgeResult)
1758
- return [2 /*return*/, bridgeResult];
1759
- _f.label = 3;
1760
- case 3:
1761
- query = options.query, _b = options.namespace, namespace = _b === void 0 ? 'default' : _b, _c = options.limit, limit = _c === void 0 ? 10 : _c, _d = options.threshold, threshold = _d === void 0 ? 0.3 : _d, customPath = options.dbPath;
1762
- swarmDir = path.join(process.cwd(), '.swarm');
1763
- dbPath = customPath || path.join(swarmDir, 'memory.db');
1764
- startTime = Date.now();
1765
- _f.label = 4;
1766
- case 4:
1767
- _f.trys.push([4, 10, , 11]);
1768
- if (!fs.existsSync(dbPath)) {
1769
- return [2 /*return*/, { success: false, results: [], searchTime: 0, error: 'Database not found' }];
1770
- }
1771
- // Ensure schema has all required columns (migration for older DBs)
1772
- return [4 /*yield*/, ensureSchemaColumns(dbPath)];
1773
- case 5:
1774
- // Ensure schema has all required columns (migration for older DBs)
1775
- _f.sent();
1776
- return [4 /*yield*/, generateEmbedding(query)];
1777
- case 6:
1778
- queryEmb = _f.sent();
1779
- queryEmbedding = queryEmb.embedding;
1780
- return [4 /*yield*/, searchHNSWIndex(queryEmbedding, { k: limit, namespace: namespace })];
1781
- case 7:
1782
- hnswResults = _f.sent();
1783
- if (hnswResults && hnswResults.length > 0) {
1784
- filtered = hnswResults.filter(function (r) { return r.score >= threshold; });
1785
- return [2 /*return*/, {
1786
- success: true,
1787
- results: filtered,
1788
- searchTime: Date.now() - startTime
1789
- }];
1790
- }
1791
- return [4 /*yield*/, import('sql.js')];
1792
- case 8:
1793
- initSqlJs = (_f.sent())["default"];
1794
- return [4 /*yield*/, initSqlJs()];
1795
- case 9:
1796
- SQL = _f.sent();
1797
- fileBuffer = fs.readFileSync(dbPath);
1798
- db = new SQL.Database(fileBuffer);
1799
- searchStmt = db.prepare(namespace !== 'all'
1800
- ? "SELECT id, key, namespace, content, embedding FROM memory_entries WHERE status = 'active' AND namespace = ? LIMIT 1000"
1801
- : "SELECT id, key, namespace, content, embedding FROM memory_entries WHERE status = 'active' LIMIT 1000");
1802
- if (namespace !== 'all') {
1803
- searchStmt.bind([namespace]);
1804
- }
1805
- searchRows = [];
1806
- while (searchStmt.step()) {
1807
- searchRows.push(searchStmt.get());
1779
+ export async function searchEntries(options) {
1780
+ // ADR-053: Try AgentDB v3 bridge first
1781
+ const bridge = await getBridge();
1782
+ if (bridge) {
1783
+ const bridgeResult = await bridge.bridgeSearchEntries(options);
1784
+ if (bridgeResult)
1785
+ return bridgeResult;
1786
+ }
1787
+ // Fallback: raw sql.js
1788
+ const { query, namespace = 'default', limit = 10, threshold = 0.3, dbPath: customPath } = options;
1789
+ const swarmDir = path.join(process.cwd(), '.swarm');
1790
+ const dbPath = customPath || path.join(swarmDir, 'memory.db');
1791
+ const startTime = Date.now();
1792
+ try {
1793
+ if (!fs.existsSync(dbPath)) {
1794
+ return { success: false, results: [], searchTime: 0, error: 'Database not found' };
1795
+ }
1796
+ // Ensure schema has all required columns (migration for older DBs)
1797
+ await ensureSchemaColumns(dbPath);
1798
+ // Generate query embedding
1799
+ const queryEmb = await generateEmbedding(query);
1800
+ const queryEmbedding = queryEmb.embedding;
1801
+ // Try HNSW search first (150x faster)
1802
+ const hnswResults = await searchHNSWIndex(queryEmbedding, { k: limit, namespace });
1803
+ if (hnswResults && hnswResults.length > 0) {
1804
+ // Filter by threshold
1805
+ const filtered = hnswResults.filter(r => r.score >= threshold);
1806
+ return {
1807
+ success: true,
1808
+ results: filtered,
1809
+ searchTime: Date.now() - startTime
1810
+ };
1811
+ }
1812
+ // Fall back to brute-force SQLite search
1813
+ const initSqlJs = (await import('sql.js')).default;
1814
+ const SQL = await initSqlJs();
1815
+ const fileBuffer = fs.readFileSync(dbPath);
1816
+ const db = new SQL.Database(fileBuffer);
1817
+ // Get entries with embeddings
1818
+ const searchStmt = db.prepare(namespace !== 'all'
1819
+ ? `SELECT id, key, namespace, content, embedding FROM memory_entries WHERE status = 'active' AND namespace = ? LIMIT 1000`
1820
+ : `SELECT id, key, namespace, content, embedding FROM memory_entries WHERE status = 'active' LIMIT 1000`);
1821
+ if (namespace !== 'all') {
1822
+ searchStmt.bind([namespace]);
1823
+ }
1824
+ const searchRows = [];
1825
+ while (searchStmt.step()) {
1826
+ searchRows.push(searchStmt.get());
1827
+ }
1828
+ searchStmt.free();
1829
+ const entries = searchRows.length > 0 ? [{ values: searchRows }] : [];
1830
+ const results = [];
1831
+ if (entries[0]?.values) {
1832
+ for (const row of entries[0].values) {
1833
+ const [id, key, ns, content, embeddingJson] = row;
1834
+ let score = 0;
1835
+ if (embeddingJson) {
1836
+ try {
1837
+ const embedding = JSON.parse(embeddingJson);
1838
+ score = cosineSim(queryEmbedding, embedding);
1808
1839
  }
1809
- searchStmt.free();
1810
- entries = searchRows.length > 0 ? [{ values: searchRows }] : [];
1811
- results = [];
1812
- if ((_a = entries[0]) === null || _a === void 0 ? void 0 : _a.values) {
1813
- _loop_1 = function (row) {
1814
- var _g = row, id = _g[0], key = _g[1], ns = _g[2], content = _g[3], embeddingJson = _g[4];
1815
- var score = 0;
1816
- if (embeddingJson) {
1817
- try {
1818
- var embedding = JSON.parse(embeddingJson);
1819
- score = cosineSim(queryEmbedding, embedding);
1820
- }
1821
- catch (_h) {
1822
- // Invalid embedding, use keyword score
1823
- }
1824
- }
1825
- // Fallback to keyword matching
1826
- if (score < threshold) {
1827
- var lowerContent_1 = (content || '').toLowerCase();
1828
- var lowerQuery = query.toLowerCase();
1829
- var words = lowerQuery.split(/\s+/);
1830
- var matchCount = words.filter(function (w) { return lowerContent_1.includes(w); }).length;
1831
- var keywordScore = matchCount / words.length * 0.5;
1832
- score = Math.max(score, keywordScore);
1833
- }
1834
- if (score >= threshold) {
1835
- results.push({
1836
- id: id.substring(0, 12),
1837
- key: key || id.substring(0, 15),
1838
- content: (content || '').substring(0, 60) + ((content || '').length > 60 ? '...' : ''),
1839
- score: score,
1840
- namespace: ns || 'default'
1841
- });
1842
- }
1843
- };
1844
- for (_i = 0, _e = entries[0].values; _i < _e.length; _i++) {
1845
- row = _e[_i];
1846
- _loop_1(row);
1847
- }
1840
+ catch {
1841
+ // Invalid embedding, use keyword score
1848
1842
  }
1849
- db.close();
1850
- // Sort by score
1851
- results.sort(function (a, b) { return b.score - a.score; });
1852
- return [2 /*return*/, {
1853
- success: true,
1854
- results: results.slice(0, limit),
1855
- searchTime: Date.now() - startTime
1856
- }];
1857
- case 10:
1858
- error_7 = _f.sent();
1859
- return [2 /*return*/, {
1860
- success: false,
1861
- results: [],
1862
- searchTime: Date.now() - startTime,
1863
- error: error_7 instanceof Error ? error_7.message : String(error_7)
1864
- }];
1865
- case 11: return [2 /*return*/];
1843
+ }
1844
+ // Fallback to keyword matching
1845
+ if (score < threshold) {
1846
+ const lowerContent = (content || '').toLowerCase();
1847
+ const lowerQuery = query.toLowerCase();
1848
+ const words = lowerQuery.split(/\s+/);
1849
+ const matchCount = words.filter(w => lowerContent.includes(w)).length;
1850
+ const keywordScore = matchCount / words.length * 0.5;
1851
+ score = Math.max(score, keywordScore);
1852
+ }
1853
+ if (score >= threshold) {
1854
+ results.push({
1855
+ id: id.substring(0, 12),
1856
+ key: key || id.substring(0, 15),
1857
+ content: (content || '').substring(0, 60) + ((content || '').length > 60 ? '...' : ''),
1858
+ score,
1859
+ namespace: ns || 'default'
1860
+ });
1861
+ }
1866
1862
  }
1867
- });
1868
- });
1863
+ }
1864
+ db.close();
1865
+ // Sort by score
1866
+ results.sort((a, b) => b.score - a.score);
1867
+ return {
1868
+ success: true,
1869
+ results: results.slice(0, limit),
1870
+ searchTime: Date.now() - startTime
1871
+ };
1872
+ }
1873
+ catch (error) {
1874
+ return {
1875
+ success: false,
1876
+ results: [],
1877
+ searchTime: Date.now() - startTime,
1878
+ error: error instanceof Error ? error.message : String(error)
1879
+ };
1880
+ }
1869
1881
  }
1870
1882
  /**
1871
1883
  * Optimized cosine similarity
@@ -1875,348 +1887,321 @@ export function searchEntries(options) {
1875
1887
  function cosineSim(a, b) {
1876
1888
  if (!a || !b || a.length === 0 || b.length === 0)
1877
1889
  return 0;
1878
- var len = Math.min(a.length, b.length);
1879
- var dot = 0, normA = 0, normB = 0;
1890
+ const len = Math.min(a.length, b.length);
1891
+ let dot = 0, normA = 0, normB = 0;
1880
1892
  // Simple loop - V8 optimizes this well
1881
- for (var i = 0; i < len; i++) {
1882
- var ai = a[i], bi = b[i];
1893
+ for (let i = 0; i < len; i++) {
1894
+ const ai = a[i], bi = b[i];
1883
1895
  dot += ai * bi;
1884
1896
  normA += ai * ai;
1885
1897
  normB += bi * bi;
1886
1898
  }
1887
1899
  // Combined sqrt for slightly better performance
1888
- var mag = Math.sqrt(normA * normB);
1900
+ const mag = Math.sqrt(normA * normB);
1889
1901
  return mag === 0 ? 0 : dot / mag;
1890
1902
  }
1891
1903
  /**
1892
1904
  * List all entries from the memory database
1893
1905
  */
1894
- export function listEntries(options) {
1895
- var _a, _b, _c, _d;
1896
- return __awaiter(this, void 0, Promise, function () {
1897
- var bridge, bridgeResult, namespace, _e, limit, _f, offset, customPath, swarmDir, dbPath, initSqlJs, SQL, fileBuffer, db, countStmt, countRows, countResult, total, safeLimit, safeOffset, listStmt, listRows, result, entries, _i, _g, row, _h, id, key, ns, content, embedding, accessCount, createdAt, updatedAt, error_8;
1898
- return __generator(this, function (_j) {
1899
- switch (_j.label) {
1900
- case 0: return [4 /*yield*/, getBridge()];
1901
- case 1:
1902
- bridge = _j.sent();
1903
- if (!bridge) return [3 /*break*/, 3];
1904
- return [4 /*yield*/, bridge.bridgeListEntries(options)];
1905
- case 2:
1906
- bridgeResult = _j.sent();
1907
- if (bridgeResult)
1908
- return [2 /*return*/, bridgeResult];
1909
- _j.label = 3;
1910
- case 3:
1911
- namespace = options.namespace, _e = options.limit, limit = _e === void 0 ? 20 : _e, _f = options.offset, offset = _f === void 0 ? 0 : _f, customPath = options.dbPath;
1912
- swarmDir = path.join(process.cwd(), '.swarm');
1913
- dbPath = customPath || path.join(swarmDir, 'memory.db');
1914
- _j.label = 4;
1915
- case 4:
1916
- _j.trys.push([4, 8, , 9]);
1917
- if (!fs.existsSync(dbPath)) {
1918
- return [2 /*return*/, { success: false, entries: [], total: 0, error: 'Database not found' }];
1919
- }
1920
- // Ensure schema has all required columns (migration for older DBs)
1921
- return [4 /*yield*/, ensureSchemaColumns(dbPath)];
1922
- case 5:
1923
- // Ensure schema has all required columns (migration for older DBs)
1924
- _j.sent();
1925
- return [4 /*yield*/, import('sql.js')];
1926
- case 6:
1927
- initSqlJs = (_j.sent())["default"];
1928
- return [4 /*yield*/, initSqlJs()];
1929
- case 7:
1930
- SQL = _j.sent();
1931
- fileBuffer = fs.readFileSync(dbPath);
1932
- db = new SQL.Database(fileBuffer);
1933
- countStmt = namespace
1934
- ? db.prepare("SELECT COUNT(*) as cnt FROM memory_entries WHERE status = 'active' AND namespace = ?")
1935
- : db.prepare("SELECT COUNT(*) as cnt FROM memory_entries WHERE status = 'active'");
1936
- if (namespace) {
1937
- countStmt.bind([namespace]);
1938
- }
1939
- countRows = [];
1940
- while (countStmt.step()) {
1941
- countRows.push(countStmt.get());
1942
- }
1943
- countStmt.free();
1944
- countResult = countRows.length > 0 ? [{ values: countRows }] : [];
1945
- total = ((_c = (_b = (_a = countResult[0]) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c[0]) || 0;
1946
- safeLimit = parseInt(String(limit), 10) || 100;
1947
- safeOffset = parseInt(String(offset), 10) || 0;
1948
- listStmt = namespace
1949
- ? db.prepare("SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at FROM memory_entries WHERE status = 'active' AND namespace = ? ORDER BY updated_at DESC LIMIT ? OFFSET ?")
1950
- : db.prepare("SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at FROM memory_entries WHERE status = 'active' ORDER BY updated_at DESC LIMIT ? OFFSET ?");
1951
- if (namespace) {
1952
- listStmt.bind([namespace, safeLimit, safeOffset]);
1953
- }
1954
- else {
1955
- listStmt.bind([safeLimit, safeOffset]);
1956
- }
1957
- listRows = [];
1958
- while (listStmt.step()) {
1959
- listRows.push(listStmt.get());
1960
- }
1961
- listStmt.free();
1962
- result = listRows.length > 0 ? [{ values: listRows }] : [];
1963
- entries = [];
1964
- if ((_d = result[0]) === null || _d === void 0 ? void 0 : _d.values) {
1965
- for (_i = 0, _g = result[0].values; _i < _g.length; _i++) {
1966
- row = _g[_i];
1967
- _h = row, id = _h[0], key = _h[1], ns = _h[2], content = _h[3], embedding = _h[4], accessCount = _h[5], createdAt = _h[6], updatedAt = _h[7];
1968
- entries.push({
1969
- id: String(id).substring(0, 20),
1970
- key: key || String(id).substring(0, 15),
1971
- namespace: ns || 'default',
1972
- size: (content || '').length,
1973
- accessCount: accessCount || 0,
1974
- createdAt: createdAt || new Date().toISOString(),
1975
- updatedAt: updatedAt || new Date().toISOString(),
1976
- hasEmbedding: !!embedding && embedding.length > 10
1977
- });
1978
- }
1979
- }
1980
- db.close();
1981
- return [2 /*return*/, { success: true, entries: entries, total: total }];
1982
- case 8:
1983
- error_8 = _j.sent();
1984
- return [2 /*return*/, {
1985
- success: false,
1986
- entries: [],
1987
- total: 0,
1988
- error: error_8 instanceof Error ? error_8.message : String(error_8)
1989
- }];
1990
- case 9: return [2 /*return*/];
1906
+ export async function listEntries(options) {
1907
+ // ADR-053: Try AgentDB v3 bridge first
1908
+ const bridge = await getBridge();
1909
+ if (bridge) {
1910
+ const bridgeResult = await bridge.bridgeListEntries(options);
1911
+ if (bridgeResult)
1912
+ return bridgeResult;
1913
+ }
1914
+ // Fallback: raw sql.js
1915
+ const { namespace, limit = 20, offset = 0, dbPath: customPath } = options;
1916
+ const swarmDir = path.join(process.cwd(), '.swarm');
1917
+ const dbPath = customPath || path.join(swarmDir, 'memory.db');
1918
+ try {
1919
+ if (!fs.existsSync(dbPath)) {
1920
+ return { success: false, entries: [], total: 0, error: 'Database not found' };
1921
+ }
1922
+ // Ensure schema has all required columns (migration for older DBs)
1923
+ await ensureSchemaColumns(dbPath);
1924
+ const initSqlJs = (await import('sql.js')).default;
1925
+ const SQL = await initSqlJs();
1926
+ const fileBuffer = fs.readFileSync(dbPath);
1927
+ const db = new SQL.Database(fileBuffer);
1928
+ // Get total count
1929
+ const countStmt = namespace
1930
+ ? db.prepare(`SELECT COUNT(*) as cnt FROM memory_entries WHERE status = 'active' AND namespace = ?`)
1931
+ : db.prepare(`SELECT COUNT(*) as cnt FROM memory_entries WHERE status = 'active'`);
1932
+ if (namespace) {
1933
+ countStmt.bind([namespace]);
1934
+ }
1935
+ const countRows = [];
1936
+ while (countStmt.step()) {
1937
+ countRows.push(countStmt.get());
1938
+ }
1939
+ countStmt.free();
1940
+ const countResult = countRows.length > 0 ? [{ values: countRows }] : [];
1941
+ const total = countResult[0]?.values?.[0]?.[0] || 0;
1942
+ // Get entries
1943
+ const safeLimit = parseInt(String(limit), 10) || 100;
1944
+ const safeOffset = parseInt(String(offset), 10) || 0;
1945
+ const listStmt = namespace
1946
+ ? db.prepare(`SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at FROM memory_entries WHERE status = 'active' AND namespace = ? ORDER BY updated_at DESC LIMIT ? OFFSET ?`)
1947
+ : db.prepare(`SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at FROM memory_entries WHERE status = 'active' ORDER BY updated_at DESC LIMIT ? OFFSET ?`);
1948
+ if (namespace) {
1949
+ listStmt.bind([namespace, safeLimit, safeOffset]);
1950
+ }
1951
+ else {
1952
+ listStmt.bind([safeLimit, safeOffset]);
1953
+ }
1954
+ const listRows = [];
1955
+ while (listStmt.step()) {
1956
+ listRows.push(listStmt.get());
1957
+ }
1958
+ listStmt.free();
1959
+ const result = listRows.length > 0 ? [{ values: listRows }] : [];
1960
+ const entries = [];
1961
+ if (result[0]?.values) {
1962
+ for (const row of result[0].values) {
1963
+ const [id, key, ns, content, embedding, accessCount, createdAt, updatedAt] = row;
1964
+ entries.push({
1965
+ id: String(id).substring(0, 20),
1966
+ key: key || String(id).substring(0, 15),
1967
+ namespace: ns || 'default',
1968
+ size: (content || '').length,
1969
+ accessCount: accessCount || 0,
1970
+ createdAt: createdAt || new Date().toISOString(),
1971
+ updatedAt: updatedAt || new Date().toISOString(),
1972
+ hasEmbedding: !!embedding && embedding.length > 10
1973
+ });
1991
1974
  }
1992
- });
1993
- });
1975
+ }
1976
+ db.close();
1977
+ return { success: true, entries, total };
1978
+ }
1979
+ catch (error) {
1980
+ return {
1981
+ success: false,
1982
+ entries: [],
1983
+ total: 0,
1984
+ error: error instanceof Error ? error.message : String(error)
1985
+ };
1986
+ }
1994
1987
  }
1995
1988
  /**
1996
1989
  * Get a specific entry from the memory database
1997
1990
  */
1998
- export function getEntry(options) {
1999
- var _a, _b;
2000
- return __awaiter(this, void 0, Promise, function () {
2001
- var bridge, bridgeResult, key, _c, namespace, customPath, swarmDir, dbPath, initSqlJs, SQL, fileBuffer, db, getStmt, getRows, result, _d, id, entryKey, ns, content, embedding, accessCount, createdAt, updatedAt, tagsJson, data, tags, error_9;
2002
- return __generator(this, function (_e) {
2003
- switch (_e.label) {
2004
- case 0: return [4 /*yield*/, getBridge()];
2005
- case 1:
2006
- bridge = _e.sent();
2007
- if (!bridge) return [3 /*break*/, 3];
2008
- return [4 /*yield*/, bridge.bridgeGetEntry(options)];
2009
- case 2:
2010
- bridgeResult = _e.sent();
2011
- if (bridgeResult)
2012
- return [2 /*return*/, bridgeResult];
2013
- _e.label = 3;
2014
- case 3:
2015
- key = options.key, _c = options.namespace, namespace = _c === void 0 ? 'default' : _c, customPath = options.dbPath;
2016
- swarmDir = path.join(process.cwd(), '.swarm');
2017
- dbPath = customPath || path.join(swarmDir, 'memory.db');
2018
- _e.label = 4;
2019
- case 4:
2020
- _e.trys.push([4, 8, , 9]);
2021
- if (!fs.existsSync(dbPath)) {
2022
- return [2 /*return*/, { success: false, found: false, error: 'Database not found' }];
2023
- }
2024
- // Ensure schema has all required columns (migration for older DBs)
2025
- return [4 /*yield*/, ensureSchemaColumns(dbPath)];
2026
- case 5:
2027
- // Ensure schema has all required columns (migration for older DBs)
2028
- _e.sent();
2029
- return [4 /*yield*/, import('sql.js')];
2030
- case 6:
2031
- initSqlJs = (_e.sent())["default"];
2032
- return [4 /*yield*/, initSqlJs()];
2033
- case 7:
2034
- SQL = _e.sent();
2035
- fileBuffer = fs.readFileSync(dbPath);
2036
- db = new SQL.Database(fileBuffer);
2037
- getStmt = db.prepare("\n SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at, tags\n FROM memory_entries\n WHERE status = 'active'\n AND key = ?\n AND namespace = ?\n LIMIT 1\n ");
2038
- getStmt.bind([key, namespace]);
2039
- getRows = [];
2040
- while (getStmt.step()) {
2041
- getRows.push(getStmt.get());
2042
- }
2043
- getStmt.free();
2044
- result = getRows.length > 0 ? [{ values: getRows }] : [];
2045
- if (!((_b = (_a = result[0]) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b[0])) {
2046
- db.close();
2047
- return [2 /*return*/, { success: true, found: false }];
2048
- }
2049
- _d = result[0].values[0], id = _d[0], entryKey = _d[1], ns = _d[2], content = _d[3], embedding = _d[4], accessCount = _d[5], createdAt = _d[6], updatedAt = _d[7], tagsJson = _d[8];
2050
- // Update access count
2051
- db.run("\n UPDATE memory_entries\n SET access_count = access_count + 1, last_accessed_at = strftime('%s', 'now') * 1000\n WHERE id = ?\n ", [String(id)]);
2052
- data = db["export"]();
2053
- fs.writeFileSync(dbPath, Buffer.from(data));
2054
- db.close();
2055
- tags = [];
2056
- if (tagsJson) {
2057
- try {
2058
- tags = JSON.parse(tagsJson);
2059
- }
2060
- catch (_f) {
2061
- // Invalid JSON
2062
- }
2063
- }
2064
- return [2 /*return*/, {
2065
- success: true,
2066
- found: true,
2067
- entry: {
2068
- id: String(id),
2069
- key: entryKey || String(id),
2070
- namespace: ns || 'default',
2071
- content: content || '',
2072
- accessCount: (accessCount || 0) + 1,
2073
- createdAt: createdAt || new Date().toISOString(),
2074
- updatedAt: updatedAt || new Date().toISOString(),
2075
- hasEmbedding: !!embedding && embedding.length > 10,
2076
- tags: tags
2077
- }
2078
- }];
2079
- case 8:
2080
- error_9 = _e.sent();
2081
- return [2 /*return*/, {
2082
- success: false,
2083
- found: false,
2084
- error: error_9 instanceof Error ? error_9.message : String(error_9)
2085
- }];
2086
- case 9: return [2 /*return*/];
1991
+ export async function getEntry(options) {
1992
+ // ADR-053: Try AgentDB v3 bridge first
1993
+ const bridge = await getBridge();
1994
+ if (bridge) {
1995
+ const bridgeResult = await bridge.bridgeGetEntry(options);
1996
+ if (bridgeResult)
1997
+ return bridgeResult;
1998
+ }
1999
+ // Fallback: raw sql.js
2000
+ const { key, namespace = 'default', dbPath: customPath } = options;
2001
+ const swarmDir = path.join(process.cwd(), '.swarm');
2002
+ const dbPath = customPath || path.join(swarmDir, 'memory.db');
2003
+ try {
2004
+ if (!fs.existsSync(dbPath)) {
2005
+ return { success: false, found: false, error: 'Database not found' };
2006
+ }
2007
+ // Ensure schema has all required columns (migration for older DBs)
2008
+ await ensureSchemaColumns(dbPath);
2009
+ const initSqlJs = (await import('sql.js')).default;
2010
+ const SQL = await initSqlJs();
2011
+ const fileBuffer = fs.readFileSync(dbPath);
2012
+ const db = new SQL.Database(fileBuffer);
2013
+ // Find entry by key
2014
+ const getStmt = db.prepare(`
2015
+ SELECT id, key, namespace, content, embedding, access_count, created_at, updated_at, tags
2016
+ FROM memory_entries
2017
+ WHERE status = 'active'
2018
+ AND key = ?
2019
+ AND namespace = ?
2020
+ LIMIT 1
2021
+ `);
2022
+ getStmt.bind([key, namespace]);
2023
+ const getRows = [];
2024
+ while (getStmt.step()) {
2025
+ getRows.push(getStmt.get());
2026
+ }
2027
+ getStmt.free();
2028
+ const result = getRows.length > 0 ? [{ values: getRows }] : [];
2029
+ if (!result[0]?.values?.[0]) {
2030
+ db.close();
2031
+ return { success: true, found: false };
2032
+ }
2033
+ const [id, entryKey, ns, content, embedding, accessCount, createdAt, updatedAt, tagsJson] = result[0].values[0];
2034
+ // Update access count
2035
+ db.run(`
2036
+ UPDATE memory_entries
2037
+ SET access_count = access_count + 1, last_accessed_at = strftime('%s', 'now') * 1000
2038
+ WHERE id = ?
2039
+ `, [String(id)]);
2040
+ // Save updated database
2041
+ const data = db.export();
2042
+ fs.writeFileSync(dbPath, Buffer.from(data));
2043
+ db.close();
2044
+ let tags = [];
2045
+ if (tagsJson) {
2046
+ try {
2047
+ tags = JSON.parse(tagsJson);
2087
2048
  }
2088
- });
2089
- });
2049
+ catch {
2050
+ // Invalid JSON
2051
+ }
2052
+ }
2053
+ return {
2054
+ success: true,
2055
+ found: true,
2056
+ entry: {
2057
+ id: String(id),
2058
+ key: entryKey || String(id),
2059
+ namespace: ns || 'default',
2060
+ content: content || '',
2061
+ accessCount: (accessCount || 0) + 1,
2062
+ createdAt: createdAt || new Date().toISOString(),
2063
+ updatedAt: updatedAt || new Date().toISOString(),
2064
+ hasEmbedding: !!embedding && embedding.length > 10,
2065
+ tags
2066
+ }
2067
+ };
2068
+ }
2069
+ catch (error) {
2070
+ return {
2071
+ success: false,
2072
+ found: false,
2073
+ error: error instanceof Error ? error.message : String(error)
2074
+ };
2075
+ }
2090
2076
  }
2091
2077
  /**
2092
2078
  * Delete a memory entry by key and namespace
2093
2079
  * Issue #980: Properly supports namespaced entries
2094
2080
  */
2095
- export function deleteEntry(options) {
2096
- var _a, _b, _c, _d, _e, _f, _g, _h;
2097
- return __awaiter(this, void 0, Promise, function () {
2098
- var bridge, bridgeResult, key, _j, namespace, customPath, swarmDir, dbPath, initSqlJs, SQL, fileBuffer, db, checkStmt, checkRows, checkResult, countResult_1, remainingEntries_1, entryId, countResult, remainingEntries, data, error_10;
2099
- return __generator(this, function (_k) {
2100
- switch (_k.label) {
2101
- case 0: return [4 /*yield*/, getBridge()];
2102
- case 1:
2103
- bridge = _k.sent();
2104
- if (!bridge) return [3 /*break*/, 3];
2105
- return [4 /*yield*/, bridge.bridgeDeleteEntry(options)];
2106
- case 2:
2107
- bridgeResult = _k.sent();
2108
- if (bridgeResult)
2109
- return [2 /*return*/, bridgeResult];
2110
- _k.label = 3;
2111
- case 3:
2112
- key = options.key, _j = options.namespace, namespace = _j === void 0 ? 'default' : _j, customPath = options.dbPath;
2113
- swarmDir = path.join(process.cwd(), '.swarm');
2114
- dbPath = customPath || path.join(swarmDir, 'memory.db');
2115
- _k.label = 4;
2116
- case 4:
2117
- _k.trys.push([4, 8, , 9]);
2118
- if (!fs.existsSync(dbPath)) {
2119
- return [2 /*return*/, {
2120
- success: false,
2121
- deleted: false,
2122
- key: key,
2123
- namespace: namespace,
2124
- remainingEntries: 0,
2125
- error: 'Database not found'
2126
- }];
2127
- }
2128
- // Ensure schema has all required columns (migration for older DBs)
2129
- return [4 /*yield*/, ensureSchemaColumns(dbPath)];
2130
- case 5:
2131
- // Ensure schema has all required columns (migration for older DBs)
2132
- _k.sent();
2133
- return [4 /*yield*/, import('sql.js')];
2134
- case 6:
2135
- initSqlJs = (_k.sent())["default"];
2136
- return [4 /*yield*/, initSqlJs()];
2137
- case 7:
2138
- SQL = _k.sent();
2139
- fileBuffer = fs.readFileSync(dbPath);
2140
- db = new SQL.Database(fileBuffer);
2141
- checkStmt = db.prepare("\n SELECT id FROM memory_entries\n WHERE status = 'active'\n AND key = ?\n AND namespace = ?\n LIMIT 1\n ");
2142
- checkStmt.bind([key, namespace]);
2143
- checkRows = [];
2144
- while (checkStmt.step()) {
2145
- checkRows.push(checkStmt.get());
2146
- }
2147
- checkStmt.free();
2148
- checkResult = checkRows.length > 0 ? [{ values: checkRows }] : [];
2149
- if (!((_b = (_a = checkResult[0]) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b[0])) {
2150
- countResult_1 = db.exec("SELECT COUNT(*) FROM memory_entries WHERE status = 'active'");
2151
- remainingEntries_1 = ((_e = (_d = (_c = countResult_1[0]) === null || _c === void 0 ? void 0 : _c.values) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e[0]) || 0;
2152
- db.close();
2153
- return [2 /*return*/, {
2154
- success: true,
2155
- deleted: false,
2156
- key: key,
2157
- namespace: namespace,
2158
- remainingEntries: remainingEntries_1,
2159
- error: "Key '" + key + "' not found in namespace '" + namespace + "'"
2160
- }];
2161
- }
2162
- entryId = String(checkResult[0].values[0][0]);
2163
- // Delete the entry (soft delete by setting status to 'deleted')
2164
- // Also null out the embedding to clean up vector data from SQLite
2165
- db.run("\n UPDATE memory_entries\n SET status = 'deleted',\n embedding = NULL,\n updated_at = strftime('%s', 'now') * 1000\n WHERE key = ?\n AND namespace = ?\n AND status = 'active'\n ", [key, namespace]);
2166
- countResult = db.exec("SELECT COUNT(*) FROM memory_entries WHERE status = 'active'");
2167
- remainingEntries = ((_h = (_g = (_f = countResult[0]) === null || _f === void 0 ? void 0 : _f.values) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h[0]) || 0;
2168
- data = db["export"]();
2169
- fs.writeFileSync(dbPath, Buffer.from(data));
2170
- db.close();
2171
- // Clean up in-memory HNSW index so ghost vectors don't appear in searches.
2172
- // Remove the entry from the HNSW entries map and invalidate the index.
2173
- // The next search will rebuild the HNSW index from the remaining DB rows.
2174
- if (hnswIndex === null || hnswIndex === void 0 ? void 0 : hnswIndex.entries) {
2175
- hnswIndex.entries["delete"](entryId);
2176
- saveHNSWMetadata();
2177
- // Invalidate the HNSW index so it rebuilds from DB on next search.
2178
- // We can't surgically remove a vector from the HNSW graph, so we
2179
- // clear the entire index; it will be lazily rebuilt from SQLite.
2180
- rebuildSearchIndex();
2181
- }
2182
- return [2 /*return*/, {
2183
- success: true,
2184
- deleted: true,
2185
- key: key,
2186
- namespace: namespace,
2187
- remainingEntries: remainingEntries
2188
- }];
2189
- case 8:
2190
- error_10 = _k.sent();
2191
- return [2 /*return*/, {
2192
- success: false,
2193
- deleted: false,
2194
- key: key,
2195
- namespace: namespace,
2196
- remainingEntries: 0,
2197
- error: error_10 instanceof Error ? error_10.message : String(error_10)
2198
- }];
2199
- case 9: return [2 /*return*/];
2200
- }
2201
- });
2202
- });
2081
+ export async function deleteEntry(options) {
2082
+ // ADR-053: Try AgentDB v3 bridge first
2083
+ const bridge = await getBridge();
2084
+ if (bridge) {
2085
+ const bridgeResult = await bridge.bridgeDeleteEntry(options);
2086
+ if (bridgeResult)
2087
+ return bridgeResult;
2088
+ }
2089
+ // Fallback: raw sql.js
2090
+ const { key, namespace = 'default', dbPath: customPath } = options;
2091
+ const swarmDir = path.join(process.cwd(), '.swarm');
2092
+ const dbPath = customPath || path.join(swarmDir, 'memory.db');
2093
+ try {
2094
+ if (!fs.existsSync(dbPath)) {
2095
+ return {
2096
+ success: false,
2097
+ deleted: false,
2098
+ key,
2099
+ namespace,
2100
+ remainingEntries: 0,
2101
+ error: 'Database not found'
2102
+ };
2103
+ }
2104
+ // Ensure schema has all required columns (migration for older DBs)
2105
+ await ensureSchemaColumns(dbPath);
2106
+ const initSqlJs = (await import('sql.js')).default;
2107
+ const SQL = await initSqlJs();
2108
+ const fileBuffer = fs.readFileSync(dbPath);
2109
+ const db = new SQL.Database(fileBuffer);
2110
+ // Check if entry exists first
2111
+ const checkStmt = db.prepare(`
2112
+ SELECT id FROM memory_entries
2113
+ WHERE status = 'active'
2114
+ AND key = ?
2115
+ AND namespace = ?
2116
+ LIMIT 1
2117
+ `);
2118
+ checkStmt.bind([key, namespace]);
2119
+ const checkRows = [];
2120
+ while (checkStmt.step()) {
2121
+ checkRows.push(checkStmt.get());
2122
+ }
2123
+ checkStmt.free();
2124
+ const checkResult = checkRows.length > 0 ? [{ values: checkRows }] : [];
2125
+ if (!checkResult[0]?.values?.[0]) {
2126
+ // Get remaining count before closing
2127
+ const countResult = db.exec(`SELECT COUNT(*) FROM memory_entries WHERE status = 'active'`);
2128
+ const remainingEntries = countResult[0]?.values?.[0]?.[0] || 0;
2129
+ db.close();
2130
+ return {
2131
+ success: true,
2132
+ deleted: false,
2133
+ key,
2134
+ namespace,
2135
+ remainingEntries,
2136
+ error: `Key '${key}' not found in namespace '${namespace}'`
2137
+ };
2138
+ }
2139
+ // Capture the entry ID for HNSW cleanup
2140
+ const entryId = String(checkResult[0].values[0][0]);
2141
+ // Delete the entry (soft delete by setting status to 'deleted')
2142
+ // Also null out the embedding to clean up vector data from SQLite
2143
+ db.run(`
2144
+ UPDATE memory_entries
2145
+ SET status = 'deleted',
2146
+ embedding = NULL,
2147
+ updated_at = strftime('%s', 'now') * 1000
2148
+ WHERE key = ?
2149
+ AND namespace = ?
2150
+ AND status = 'active'
2151
+ `, [key, namespace]);
2152
+ // Get remaining count
2153
+ const countResult = db.exec(`SELECT COUNT(*) FROM memory_entries WHERE status = 'active'`);
2154
+ const remainingEntries = countResult[0]?.values?.[0]?.[0] || 0;
2155
+ // Save updated database
2156
+ const data = db.export();
2157
+ fs.writeFileSync(dbPath, Buffer.from(data));
2158
+ db.close();
2159
+ // Clean up in-memory HNSW index so ghost vectors don't appear in searches.
2160
+ // Remove the entry from the HNSW entries map and invalidate the index.
2161
+ // The next search will rebuild the HNSW index from the remaining DB rows.
2162
+ if (hnswIndex?.entries) {
2163
+ hnswIndex.entries.delete(entryId);
2164
+ saveHNSWMetadata();
2165
+ // Invalidate the HNSW index so it rebuilds from DB on next search.
2166
+ // We can't surgically remove a vector from the HNSW graph, so we
2167
+ // clear the entire index; it will be lazily rebuilt from SQLite.
2168
+ rebuildSearchIndex();
2169
+ }
2170
+ return {
2171
+ success: true,
2172
+ deleted: true,
2173
+ key,
2174
+ namespace,
2175
+ remainingEntries
2176
+ };
2177
+ }
2178
+ catch (error) {
2179
+ return {
2180
+ success: false,
2181
+ deleted: false,
2182
+ key,
2183
+ namespace,
2184
+ remainingEntries: 0,
2185
+ error: error instanceof Error ? error.message : String(error)
2186
+ };
2187
+ }
2203
2188
  }
2204
2189
  export default {
2205
- initializeMemoryDatabase: initializeMemoryDatabase,
2206
- checkMemoryInitialization: checkMemoryInitialization,
2207
- checkAndMigrateLegacy: checkAndMigrateLegacy,
2208
- ensureSchemaColumns: ensureSchemaColumns,
2209
- applyTemporalDecay: applyTemporalDecay,
2210
- loadEmbeddingModel: loadEmbeddingModel,
2211
- generateEmbedding: generateEmbedding,
2212
- verifyMemoryInit: verifyMemoryInit,
2213
- storeEntry: storeEntry,
2214
- searchEntries: searchEntries,
2215
- listEntries: listEntries,
2216
- getEntry: getEntry,
2217
- deleteEntry: deleteEntry,
2218
- rebuildSearchIndex: rebuildSearchIndex,
2219
- MEMORY_SCHEMA_V3: MEMORY_SCHEMA_V3,
2220
- getInitialMetadata: getInitialMetadata
2190
+ initializeMemoryDatabase,
2191
+ checkMemoryInitialization,
2192
+ checkAndMigrateLegacy,
2193
+ ensureSchemaColumns,
2194
+ applyTemporalDecay,
2195
+ loadEmbeddingModel,
2196
+ generateEmbedding,
2197
+ verifyMemoryInit,
2198
+ storeEntry,
2199
+ searchEntries,
2200
+ listEntries,
2201
+ getEntry,
2202
+ deleteEntry,
2203
+ rebuildSearchIndex,
2204
+ MEMORY_SCHEMA_V3,
2205
+ getInitialMetadata
2221
2206
  };
2222
2207
  //# sourceMappingURL=memory-initializer.js.map