hippo-memory 1.59.0 → 1.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (596) hide show
  1. package/README.md +1 -1
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.js +4 -1
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/gemini.js +1 -1
  7. package/dist/agent-memories/legacy.js +1 -1
  8. package/dist/agent-memories/source.js +1 -1
  9. package/dist/agent-memories/sync.js +8 -3
  10. package/dist/ambient-store.d.ts +14 -0
  11. package/dist/ambient-store.js +90 -0
  12. package/dist/ambient.d.ts +23 -0
  13. package/dist/ambient.js +72 -50
  14. package/dist/api/assemble.d.ts +93 -0
  15. package/dist/api/assemble.js +152 -0
  16. package/dist/api/audit.d.ts +17 -0
  17. package/dist/api/audit.js +23 -0
  18. package/dist/api/auth.d.ts +79 -0
  19. package/dist/api/auth.js +178 -0
  20. package/dist/api/context-types.d.ts +105 -0
  21. package/dist/api/context-types.js +3 -0
  22. package/dist/api/context.d.ts +31 -0
  23. package/dist/api/context.js +705 -0
  24. package/dist/api/dormant.d.ts +30 -0
  25. package/dist/api/dormant.js +140 -0
  26. package/dist/api/drill-down.d.ts +84 -0
  27. package/dist/api/drill-down.js +123 -0
  28. package/dist/api/forget.d.ts +57 -0
  29. package/dist/api/forget.js +87 -0
  30. package/dist/api/goals.d.ts +18 -0
  31. package/dist/api/goals.js +33 -0
  32. package/dist/api/learn.d.ts +31 -0
  33. package/dist/api/learn.js +88 -0
  34. package/dist/api/outcome.d.ts +61 -0
  35. package/dist/api/outcome.js +66 -0
  36. package/dist/api/promote.d.ts +54 -0
  37. package/dist/api/promote.js +203 -0
  38. package/dist/api/quarantine.d.ts +24 -0
  39. package/dist/api/quarantine.js +121 -0
  40. package/dist/api/recall-types.d.ts +390 -0
  41. package/dist/api/recall-types.js +3 -0
  42. package/dist/api/recall.d.ts +36 -0
  43. package/dist/api/recall.js +634 -0
  44. package/dist/api/remember.d.ts +35 -0
  45. package/dist/api/remember.js +43 -0
  46. package/dist/api/sleep.d.ts +136 -0
  47. package/dist/api/sleep.js +271 -0
  48. package/dist/api/tokens.d.ts +26 -0
  49. package/dist/api/tokens.js +60 -0
  50. package/dist/api/types.d.ts +56 -0
  51. package/dist/api/types.js +38 -0
  52. package/dist/api.d.ts +20 -1260
  53. package/dist/api.js +25 -2711
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +7 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +7 -4
  59. package/dist/capture/command.d.ts +33 -0
  60. package/dist/capture/command.js +264 -0
  61. package/dist/capture/compact.d.ts +44 -0
  62. package/dist/capture/compact.js +354 -0
  63. package/dist/capture/extract.d.ts +21 -0
  64. package/dist/capture/extract.js +464 -0
  65. package/dist/capture/transcript.d.ts +40 -0
  66. package/dist/capture/transcript.js +193 -0
  67. package/dist/capture-error.js +2 -1
  68. package/dist/churn-git.js +4 -2
  69. package/dist/cli/audit.d.ts +3 -0
  70. package/dist/cli/audit.js +159 -0
  71. package/dist/cli/auth.d.ts +2 -0
  72. package/dist/cli/auth.js +171 -0
  73. package/dist/cli/briefs.d.ts +4 -0
  74. package/dist/cli/briefs.js +435 -0
  75. package/dist/cli/card.d.ts +3 -0
  76. package/dist/cli/card.js +333 -0
  77. package/dist/cli/context.d.ts +15 -0
  78. package/dist/cli/context.js +366 -0
  79. package/dist/cli/continuity.d.ts +6 -0
  80. package/dist/cli/continuity.js +445 -0
  81. package/dist/cli/curate.d.ts +19 -0
  82. package/dist/cli/curate.js +555 -0
  83. package/dist/cli/dag.d.ts +5 -0
  84. package/dist/cli/dag.js +177 -0
  85. package/dist/cli/decisions.d.ts +4 -0
  86. package/dist/cli/decisions.js +528 -0
  87. package/dist/cli/eval.d.ts +5 -0
  88. package/dist/cli/eval.js +213 -0
  89. package/dist/cli/explain.d.ts +4 -0
  90. package/dist/cli/explain.js +150 -0
  91. package/dist/cli/goals.d.ts +2 -0
  92. package/dist/cli/goals.js +196 -0
  93. package/dist/cli/hook-blocks.d.ts +18 -0
  94. package/dist/cli/hook-blocks.js +233 -0
  95. package/dist/cli/init.d.ts +2 -0
  96. package/dist/cli/init.js +305 -0
  97. package/dist/cli/maintenance.d.ts +4 -0
  98. package/dist/cli/maintenance.js +179 -0
  99. package/dist/cli/playbooks.d.ts +4 -0
  100. package/dist/cli/playbooks.js +556 -0
  101. package/dist/cli/projects.js +1 -1
  102. package/dist/cli/recall.d.ts +7 -0
  103. package/dist/cli/recall.js +597 -0
  104. package/dist/cli/remember.d.ts +5 -0
  105. package/dist/cli/remember.js +442 -0
  106. package/dist/cli/serve.d.ts +5 -0
  107. package/dist/cli/serve.js +40 -0
  108. package/dist/cli/session-hooks.d.ts +29 -0
  109. package/dist/cli/session-hooks.js +637 -0
  110. package/dist/cli/setup.d.ts +4 -0
  111. package/dist/cli/setup.js +376 -0
  112. package/dist/cli/shared.d.ts +15 -19
  113. package/dist/cli/shared.js +50 -341
  114. package/dist/cli/slack.d.ts +2 -0
  115. package/dist/cli/slack.js +171 -0
  116. package/dist/cli/status.d.ts +18 -0
  117. package/dist/cli/status.js +400 -0
  118. package/dist/cli/transfer.d.ts +10 -0
  119. package/dist/cli/transfer.js +438 -0
  120. package/dist/cli/usage.d.ts +85 -0
  121. package/dist/cli/usage.js +741 -0
  122. package/dist/cli.d.ts +319 -13
  123. package/dist/cli.js +436 -8580
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +12 -9
  126. package/dist/config.js +12 -11
  127. package/dist/connectors/github/backfill.js +94 -87
  128. package/dist/connectors/github/cli-impl.js +5 -3
  129. package/dist/connectors/github/dlq.js +67 -54
  130. package/dist/connectors/github/ingest.js +34 -35
  131. package/dist/connectors/github/tenant-routing.js +3 -2
  132. package/dist/connectors/github/webhook.js +135 -216
  133. package/dist/connectors/slack/dlq.js +49 -61
  134. package/dist/connectors/slack/ingest.js +55 -48
  135. package/dist/connectors/slack/tenant-routing.js +4 -3
  136. package/dist/connectors/slack/webhook.js +72 -74
  137. package/dist/consolidate/conflicts.d.ts +10 -0
  138. package/dist/consolidate/conflicts.js +178 -0
  139. package/dist/consolidate/decay.d.ts +12 -0
  140. package/dist/consolidate/decay.js +145 -0
  141. package/dist/consolidate/llm-passes.d.ts +3 -0
  142. package/dist/consolidate/llm-passes.js +141 -0
  143. package/dist/consolidate/merge.d.ts +7 -0
  144. package/dist/consolidate/merge.js +251 -0
  145. package/dist/consolidate/physics-pass.d.ts +3 -0
  146. package/dist/consolidate/physics-pass.js +60 -0
  147. package/dist/consolidate/run.d.ts +69 -0
  148. package/dist/consolidate/run.js +76 -0
  149. package/dist/consolidate/sleep.d.ts +18 -0
  150. package/dist/consolidate/sleep.js +209 -0
  151. package/dist/consolidate/traces.d.ts +4 -0
  152. package/dist/consolidate/traces.js +178 -0
  153. package/dist/context-auto.js +7 -11
  154. package/dist/context-render.d.ts +1 -1
  155. package/dist/context-render.js +1 -1
  156. package/dist/customer-notes.d.ts +3 -0
  157. package/dist/customer-notes.js +6 -4
  158. package/dist/dag.js +13 -12
  159. package/dist/dashboard-actions.d.ts +20 -0
  160. package/dist/dashboard-actions.js +88 -0
  161. package/dist/dashboard-params.d.ts +45 -0
  162. package/dist/dashboard-params.js +127 -0
  163. package/dist/dashboard-queries.d.ts +15 -0
  164. package/dist/dashboard-queries.js +355 -0
  165. package/dist/dashboard-snapshot.d.ts +138 -0
  166. package/dist/dashboard-snapshot.js +308 -0
  167. package/dist/dashboard-types.d.ts +163 -0
  168. package/dist/dashboard-types.js +3 -0
  169. package/dist/dashboard.d.ts +6 -7
  170. package/dist/dashboard.js +231 -203
  171. package/dist/db/busy.d.ts +5 -0
  172. package/dist/db/busy.js +24 -0
  173. package/dist/db/continuity.d.ts +5 -0
  174. package/dist/db/continuity.js +145 -0
  175. package/dist/db/meta.d.ts +8 -0
  176. package/dist/db/meta.js +35 -0
  177. package/dist/db/migrate.d.ts +9 -0
  178. package/dist/db/migrate.js +138 -0
  179. package/dist/db/migrations/index.d.ts +5 -0
  180. package/dist/db/migrations/index.js +109 -0
  181. package/dist/db/migrations/types.d.ts +14 -0
  182. package/dist/db/migrations/types.js +2 -0
  183. package/dist/db/migrations/v01.d.ts +3 -0
  184. package/dist/db/migrations/v01.js +38 -0
  185. package/dist/db/migrations/v02.d.ts +3 -0
  186. package/dist/db/migrations/v02.js +21 -0
  187. package/dist/db/migrations/v03.d.ts +3 -0
  188. package/dist/db/migrations/v03.js +22 -0
  189. package/dist/db/migrations/v04.d.ts +3 -0
  190. package/dist/db/migrations/v04.js +28 -0
  191. package/dist/db/migrations/v05.d.ts +3 -0
  192. package/dist/db/migrations/v05.js +21 -0
  193. package/dist/db/migrations/v06.d.ts +3 -0
  194. package/dist/db/migrations/v06.js +25 -0
  195. package/dist/db/migrations/v07.d.ts +3 -0
  196. package/dist/db/migrations/v07.js +13 -0
  197. package/dist/db/migrations/v08.d.ts +3 -0
  198. package/dist/db/migrations/v08.js +8 -0
  199. package/dist/db/migrations/v09.d.ts +3 -0
  200. package/dist/db/migrations/v09.js +13 -0
  201. package/dist/db/migrations/v10.d.ts +3 -0
  202. package/dist/db/migrations/v10.js +17 -0
  203. package/dist/db/migrations/v11.d.ts +3 -0
  204. package/dist/db/migrations/v11.js +15 -0
  205. package/dist/db/migrations/v12.d.ts +3 -0
  206. package/dist/db/migrations/v12.js +11 -0
  207. package/dist/db/migrations/v13.d.ts +3 -0
  208. package/dist/db/migrations/v13.js +15 -0
  209. package/dist/db/migrations/v14.d.ts +3 -0
  210. package/dist/db/migrations/v14.js +66 -0
  211. package/dist/db/migrations/v15.d.ts +3 -0
  212. package/dist/db/migrations/v15.js +42 -0
  213. package/dist/db/migrations/v16.d.ts +3 -0
  214. package/dist/db/migrations/v16.js +61 -0
  215. package/dist/db/migrations/v17.d.ts +3 -0
  216. package/dist/db/migrations/v17.js +46 -0
  217. package/dist/db/migrations/v18.d.ts +3 -0
  218. package/dist/db/migrations/v18.js +60 -0
  219. package/dist/db/migrations/v19.d.ts +3 -0
  220. package/dist/db/migrations/v19.js +28 -0
  221. package/dist/db/migrations/v20.d.ts +3 -0
  222. package/dist/db/migrations/v20.js +42 -0
  223. package/dist/db/migrations/v21.d.ts +3 -0
  224. package/dist/db/migrations/v21.js +16 -0
  225. package/dist/db/migrations/v22.d.ts +3 -0
  226. package/dist/db/migrations/v22.js +82 -0
  227. package/dist/db/migrations/v23.d.ts +3 -0
  228. package/dist/db/migrations/v23.js +48 -0
  229. package/dist/db/migrations/v24.d.ts +3 -0
  230. package/dist/db/migrations/v24.js +72 -0
  231. package/dist/db/migrations/v25.d.ts +3 -0
  232. package/dist/db/migrations/v25.js +46 -0
  233. package/dist/db/migrations/v26.d.ts +3 -0
  234. package/dist/db/migrations/v26.js +23 -0
  235. package/dist/db/migrations/v27.d.ts +3 -0
  236. package/dist/db/migrations/v27.js +57 -0
  237. package/dist/db/migrations/v28.d.ts +3 -0
  238. package/dist/db/migrations/v28.js +38 -0
  239. package/dist/db/migrations/v29.d.ts +3 -0
  240. package/dist/db/migrations/v29.js +78 -0
  241. package/dist/db/migrations/v30.d.ts +3 -0
  242. package/dist/db/migrations/v30.js +92 -0
  243. package/dist/db/migrations/v31.d.ts +3 -0
  244. package/dist/db/migrations/v31.js +74 -0
  245. package/dist/db/migrations/v32.d.ts +3 -0
  246. package/dist/db/migrations/v32.js +102 -0
  247. package/dist/db/migrations/v33.d.ts +3 -0
  248. package/dist/db/migrations/v33.js +104 -0
  249. package/dist/db/migrations/v34.d.ts +3 -0
  250. package/dist/db/migrations/v34.js +93 -0
  251. package/dist/db/migrations/v35.d.ts +3 -0
  252. package/dist/db/migrations/v35.js +98 -0
  253. package/dist/db/migrations/v36.d.ts +3 -0
  254. package/dist/db/migrations/v36.js +98 -0
  255. package/dist/db/migrations/v37.d.ts +3 -0
  256. package/dist/db/migrations/v37.js +219 -0
  257. package/dist/db/migrations/v38.d.ts +3 -0
  258. package/dist/db/migrations/v38.js +277 -0
  259. package/dist/db/migrations/v39.d.ts +3 -0
  260. package/dist/db/migrations/v39.js +59 -0
  261. package/dist/db/migrations/v40.d.ts +3 -0
  262. package/dist/db/migrations/v40.js +74 -0
  263. package/dist/db/migrations/v41.d.ts +3 -0
  264. package/dist/db/migrations/v41.js +43 -0
  265. package/dist/db/migrations/v42.d.ts +3 -0
  266. package/dist/db/migrations/v42.js +41 -0
  267. package/dist/db/migrations/v43.d.ts +3 -0
  268. package/dist/db/migrations/v43.js +67 -0
  269. package/dist/db/migrations/v44.d.ts +3 -0
  270. package/dist/db/migrations/v44.js +28 -0
  271. package/dist/db/migrations/v45.d.ts +3 -0
  272. package/dist/db/migrations/v45.js +30 -0
  273. package/dist/db/migrations/v46.d.ts +3 -0
  274. package/dist/db/migrations/v46.js +25 -0
  275. package/dist/db/migrations/v47.d.ts +3 -0
  276. package/dist/db/migrations/v47.js +17 -0
  277. package/dist/db/migrations/v48.d.ts +3 -0
  278. package/dist/db/migrations/v48.js +10 -0
  279. package/dist/db/migrations/v49.d.ts +3 -0
  280. package/dist/db/migrations/v49.js +31 -0
  281. package/dist/db/migrations/v50.d.ts +3 -0
  282. package/dist/db/migrations/v50.js +67 -0
  283. package/dist/db/migrations/v51.d.ts +3 -0
  284. package/dist/db/migrations/v51.js +14 -0
  285. package/dist/db/migrations/v52.d.ts +3 -0
  286. package/dist/db/migrations/v52.js +7 -0
  287. package/dist/db/open.d.ts +23 -0
  288. package/dist/db/open.js +146 -0
  289. package/dist/db/sqlite.d.ts +21 -0
  290. package/dist/db/sqlite.js +8 -0
  291. package/dist/db/tables.d.ts +7 -0
  292. package/dist/db/tables.js +38 -0
  293. package/dist/db.d.ts +6 -46
  294. package/dist/db.js +5 -3036
  295. package/dist/decisions.d.ts +4 -1
  296. package/dist/decisions.js +9 -7
  297. package/dist/dedupe.js +3 -2
  298. package/dist/delivery-recorder.js +5 -1
  299. package/dist/doctor.js +4 -3
  300. package/dist/dormant.js +1 -0
  301. package/dist/embedding-provider.d.ts +1 -1
  302. package/dist/embedding-provider.js +7 -5
  303. package/dist/embeddings.d.ts +9 -52
  304. package/dist/embeddings.js +47 -298
  305. package/dist/env.d.ts +75 -0
  306. package/dist/env.js +119 -0
  307. package/dist/eval-suite.js +1 -1
  308. package/dist/eval.js +2 -2
  309. package/dist/extract.js +5 -4
  310. package/dist/gated-write.js +3 -1
  311. package/dist/goals.d.ts +3 -1
  312. package/dist/goals.js +18 -0
  313. package/dist/graph/read.d.ts +73 -0
  314. package/dist/graph/read.js +325 -0
  315. package/dist/graph/rows.d.ts +45 -0
  316. package/dist/graph/rows.js +51 -0
  317. package/dist/graph/types.d.ts +83 -0
  318. package/dist/graph/types.js +11 -0
  319. package/dist/graph/write.d.ts +93 -0
  320. package/dist/{graph.js → graph/write.js} +8 -391
  321. package/dist/graph-extract.js +2 -1
  322. package/dist/graph-recall.d.ts +1 -1
  323. package/dist/graph-recall.js +2 -2
  324. package/dist/graph-stream.js +1 -1
  325. package/dist/graph-view.d.ts +1 -1
  326. package/dist/graph-view.js +1 -1
  327. package/dist/half-life-migration.d.ts +1 -1
  328. package/dist/half-life-migration.js +2 -1
  329. package/dist/handoff.js +3 -0
  330. package/dist/hooks/codex-session.d.ts +8 -0
  331. package/dist/hooks/codex-session.js +76 -0
  332. package/dist/hooks/codex-wrapper.d.ts +55 -0
  333. package/dist/hooks/codex-wrapper.js +288 -0
  334. package/dist/hooks/json-hooks.d.ts +63 -0
  335. package/dist/hooks/json-hooks.js +356 -0
  336. package/dist/hooks/opencode.d.ts +50 -0
  337. package/dist/hooks/opencode.js +202 -0
  338. package/dist/hooks/shared.d.ts +54 -0
  339. package/dist/hooks/shared.js +77 -0
  340. package/dist/http-retry.d.ts +2 -0
  341. package/dist/http-retry.js +4 -3
  342. package/dist/http-util.d.ts +3 -0
  343. package/dist/http-util.js +10 -0
  344. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  345. package/dist/importers/core.js +141 -0
  346. package/dist/importers/markdown-parse.d.ts +41 -0
  347. package/dist/importers/markdown-parse.js +132 -0
  348. package/dist/importers/markdown.d.ts +3 -0
  349. package/dist/importers/markdown.js +92 -0
  350. package/dist/importers/sources.d.ts +7 -0
  351. package/dist/importers/sources.js +229 -0
  352. package/dist/importers/vault.d.ts +11 -0
  353. package/dist/importers/vault.js +352 -0
  354. package/dist/incidents.d.ts +3 -0
  355. package/dist/incidents.js +8 -5
  356. package/dist/index.d.ts +25 -6
  357. package/dist/index.js +23 -6
  358. package/dist/invalidation.js +2 -1
  359. package/dist/judgment.js +7 -3
  360. package/dist/keyset.d.ts +13 -0
  361. package/dist/keyset.js +8 -0
  362. package/dist/local-embedding.d.ts +13 -0
  363. package/dist/local-embedding.js +165 -0
  364. package/dist/log.d.ts +7 -0
  365. package/dist/log.js +19 -1
  366. package/dist/mcp/admin-tools.d.ts +8 -0
  367. package/dist/mcp/admin-tools.js +116 -0
  368. package/dist/mcp/format.d.ts +27 -0
  369. package/dist/mcp/format.js +135 -0
  370. package/dist/mcp/memory-tools.d.ts +5 -0
  371. package/dist/mcp/memory-tools.js +83 -0
  372. package/dist/mcp/protocol.d.ts +83 -0
  373. package/dist/mcp/protocol.js +55 -0
  374. package/dist/mcp/recall-tools.d.ts +6 -0
  375. package/dist/mcp/recall-tools.js +320 -0
  376. package/dist/mcp/request.d.ts +10 -0
  377. package/dist/mcp/request.js +163 -0
  378. package/dist/mcp/server.d.ts +4 -70
  379. package/dist/mcp/server.js +8 -1172
  380. package/dist/mcp/session-state.d.ts +11 -0
  381. package/dist/mcp/session-state.js +28 -0
  382. package/dist/mcp/stdio.d.ts +8 -0
  383. package/dist/mcp/stdio.js +79 -0
  384. package/dist/mcp/tools.d.ts +11 -0
  385. package/dist/mcp/tools.js +247 -0
  386. package/dist/memory.d.ts +8 -3
  387. package/dist/memory.js +27 -1
  388. package/dist/multihop.d.ts +1 -1
  389. package/dist/multihop.js +2 -1
  390. package/dist/owner-validation.js +2 -1
  391. package/dist/physics-state.js +10 -7
  392. package/dist/policies.d.ts +3 -0
  393. package/dist/policies.js +8 -6
  394. package/dist/postinstall.js +3 -2
  395. package/dist/predictions/planning-fallacy.d.ts +100 -0
  396. package/dist/predictions/planning-fallacy.js +190 -0
  397. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  398. package/dist/predictions/store.js +434 -0
  399. package/dist/processes.d.ts +3 -0
  400. package/dist/processes.js +8 -5
  401. package/dist/project-briefs.d.ts +3 -0
  402. package/dist/project-briefs.js +7 -5
  403. package/dist/project-identity.d.ts +1 -1
  404. package/dist/project-identity.js +12 -6
  405. package/dist/project-merge.js +3 -1
  406. package/dist/quarantine.d.ts +2 -1
  407. package/dist/quarantine.js +8 -5
  408. package/dist/raw-archive-mirror-cleanup.js +2 -1
  409. package/dist/raw-archive.js +1 -1
  410. package/dist/recall-history.js +3 -2
  411. package/dist/recall-pipeline.d.ts +2 -2
  412. package/dist/recall-pipeline.js +16 -8
  413. package/dist/recall-scope.js +1 -1
  414. package/dist/recall-trace.d.ts +3 -3
  415. package/dist/recall-trace.js +10 -14
  416. package/dist/refine-llm.js +20 -11
  417. package/dist/reject-flow.js +6 -1
  418. package/dist/rerankers/clef.d.ts +2 -2
  419. package/dist/rerankers/clef.js +72 -30
  420. package/dist/rerankers/cross-encoder.js +6 -4
  421. package/dist/rerankers/jev.d.ts +4 -2
  422. package/dist/rerankers/jev.js +24 -19
  423. package/dist/rerankers/llm.d.ts +4 -2
  424. package/dist/rerankers/llm.js +61 -41
  425. package/dist/rerankers/types.d.ts +1 -1
  426. package/dist/salience.js +1 -1
  427. package/dist/same-text.d.ts +2 -0
  428. package/dist/same-text.js +4 -0
  429. package/dist/scheduler.d.ts +1 -0
  430. package/dist/scheduler.js +26 -3
  431. package/dist/scope.js +4 -3
  432. package/dist/search/as-of.d.ts +10 -0
  433. package/dist/search/as-of.js +22 -0
  434. package/dist/search/bm25-search.d.ts +14 -0
  435. package/dist/search/bm25-search.js +43 -0
  436. package/dist/search/bm25.d.ts +15 -0
  437. package/dist/search/bm25.js +54 -0
  438. package/dist/search/boosts.d.ts +54 -0
  439. package/dist/search/boosts.js +94 -0
  440. package/dist/search/breakdown.d.ts +7 -0
  441. package/dist/search/breakdown.js +20 -0
  442. package/dist/search/explain.d.ts +25 -0
  443. package/dist/search/explain.js +31 -0
  444. package/dist/search/finalize.d.ts +8 -0
  445. package/dist/search/finalize.js +52 -0
  446. package/dist/search/fusion.d.ts +27 -0
  447. package/dist/search/fusion.js +42 -0
  448. package/dist/search/hybrid-score.d.ts +20 -0
  449. package/dist/search/hybrid-score.js +73 -0
  450. package/dist/search/hybrid.d.ts +46 -0
  451. package/dist/search/hybrid.js +64 -0
  452. package/dist/search/physics-search.d.ts +29 -0
  453. package/dist/search/physics-search.js +162 -0
  454. package/dist/search/rerank.d.ts +10 -0
  455. package/dist/search/rerank.js +72 -0
  456. package/dist/search/temporal.d.ts +15 -0
  457. package/dist/search/temporal.js +45 -0
  458. package/dist/search/types.d.ts +91 -0
  459. package/dist/search/types.js +2 -0
  460. package/dist/search/vector.d.ts +30 -0
  461. package/dist/search/vector.js +71 -0
  462. package/dist/secret-detect.d.ts +2 -0
  463. package/dist/secret-detect.js +3 -1
  464. package/dist/server/auth.d.ts +52 -0
  465. package/dist/server/auth.js +221 -0
  466. package/dist/server/client-ip.d.ts +25 -0
  467. package/dist/server/client-ip.js +92 -0
  468. package/dist/server/cursor.d.ts +23 -0
  469. package/dist/server/cursor.js +58 -0
  470. package/dist/server/lifecycle.d.ts +7 -0
  471. package/dist/server/lifecycle.js +29 -0
  472. package/dist/server/mcp-http.d.ts +5 -0
  473. package/dist/server/mcp-http.js +199 -0
  474. package/dist/server/request.d.ts +33 -0
  475. package/dist/server/request.js +103 -0
  476. package/dist/server/routes/admin.d.ts +9 -0
  477. package/dist/server/routes/admin.js +158 -0
  478. package/dist/server/routes/customer-notes.d.ts +7 -0
  479. package/dist/server/routes/customer-notes.js +112 -0
  480. package/dist/server/routes/decisions.d.ts +7 -0
  481. package/dist/server/routes/decisions.js +133 -0
  482. package/dist/server/routes/incidents.d.ts +7 -0
  483. package/dist/server/routes/incidents.js +126 -0
  484. package/dist/server/routes/memories.d.ts +10 -0
  485. package/dist/server/routes/memories.js +179 -0
  486. package/dist/server/routes/policies.d.ts +8 -0
  487. package/dist/server/routes/policies.js +151 -0
  488. package/dist/server/routes/predictions.d.ts +7 -0
  489. package/dist/server/routes/predictions.js +164 -0
  490. package/dist/server/routes/processes.d.ts +7 -0
  491. package/dist/server/routes/processes.js +161 -0
  492. package/dist/server/routes/project-briefs.d.ts +8 -0
  493. package/dist/server/routes/project-briefs.js +136 -0
  494. package/dist/server/routes/recall.d.ts +8 -0
  495. package/dist/server/routes/recall.js +340 -0
  496. package/dist/server/routes/skills.d.ts +8 -0
  497. package/dist/server/routes/skills.js +150 -0
  498. package/dist/server/types.d.ts +56 -0
  499. package/dist/server/types.js +2 -0
  500. package/dist/server/validation.d.ts +14 -0
  501. package/dist/server/validation.js +91 -0
  502. package/dist/server.d.ts +7 -61
  503. package/dist/server.js +92 -2368
  504. package/dist/session-digest.d.ts +1 -1
  505. package/dist/session-digest.js +9 -2
  506. package/dist/shared.d.ts +3 -1
  507. package/dist/shared.js +46 -40
  508. package/dist/skills.d.ts +3 -0
  509. package/dist/skills.js +7 -5
  510. package/dist/stdin.js +3 -2
  511. package/dist/store/audit-event.d.ts +19 -0
  512. package/dist/store/audit-event.js +33 -0
  513. package/dist/store/candidates.d.ts +42 -0
  514. package/dist/store/candidates.js +152 -0
  515. package/dist/store/conflicts.d.ts +44 -0
  516. package/dist/store/conflicts.js +444 -0
  517. package/dist/store/delete-and-batch.d.ts +63 -0
  518. package/dist/store/delete-and-batch.js +310 -0
  519. package/dist/store/entry-reads.d.ts +92 -0
  520. package/dist/store/entry-reads.js +255 -0
  521. package/dist/store/entry-row.d.ts +67 -0
  522. package/dist/store/entry-row.js +208 -0
  523. package/dist/store/entry-writes.d.ts +46 -0
  524. package/dist/store/entry-writes.js +148 -0
  525. package/dist/store/handoffs.d.ts +26 -0
  526. package/dist/store/handoffs.js +184 -0
  527. package/dist/store/index-and-stats.d.ts +52 -0
  528. package/dist/store/index-and-stats.js +214 -0
  529. package/dist/store/markdown.d.ts +10 -0
  530. package/dist/store/markdown.js +108 -0
  531. package/dist/store/mirrors.d.ts +49 -0
  532. package/dist/store/mirrors.js +312 -0
  533. package/dist/store/open.d.ts +15 -0
  534. package/dist/store/open.js +223 -0
  535. package/dist/store/rows.d.ts +178 -0
  536. package/dist/store/rows.js +158 -0
  537. package/dist/store/search-rows.d.ts +86 -0
  538. package/dist/store/search-rows.js +254 -0
  539. package/dist/store/sessions.d.ts +83 -0
  540. package/dist/store/sessions.js +272 -0
  541. package/dist/store/summaries.d.ts +94 -0
  542. package/dist/store/summaries.js +377 -0
  543. package/dist/store/tenant-lookup.d.ts +12 -0
  544. package/dist/store/tenant-lookup.js +16 -0
  545. package/dist/store-cards.js +2 -1
  546. package/dist/summary-dirty.d.ts +4 -0
  547. package/dist/summary-dirty.js +32 -0
  548. package/dist/support-bundle.js +4 -3
  549. package/dist/tenant.js +2 -2
  550. package/dist/token-ledger.js +1 -0
  551. package/dist/tokenize.d.ts +2 -0
  552. package/dist/tokenize.js +16 -0
  553. package/dist/transcript-tail.d.ts +7 -0
  554. package/dist/transcript-tail.js +48 -0
  555. package/dist/vector-store.d.ts +27 -0
  556. package/dist/vector-store.js +210 -0
  557. package/dist/version.d.ts +2 -2
  558. package/dist/version.js +2 -2
  559. package/dist/working-memory.js +1 -1
  560. package/dist/yaml.js +36 -11
  561. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  562. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  563. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  564. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  565. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  566. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  567. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  568. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  569. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  570. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  571. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  572. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  573. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  574. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  575. package/dist-ui/index.html +3 -25
  576. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  577. package/extensions/openclaw-plugin/package.json +1 -1
  578. package/openclaw.plugin.json +1 -1
  579. package/package.json +2 -1
  580. package/dist/capture.d.ts +0 -155
  581. package/dist/capture.js +0 -1293
  582. package/dist/consolidate.d.ts +0 -58
  583. package/dist/consolidate.js +0 -1123
  584. package/dist/graph.d.ts +0 -245
  585. package/dist/hooks.d.ts +0 -208
  586. package/dist/hooks.js +0 -1073
  587. package/dist/importers.js +0 -897
  588. package/dist/predictions.js +0 -620
  589. package/dist/search.d.ts +0 -320
  590. package/dist/search.js +0 -968
  591. package/dist/store.d.ts +0 -744
  592. package/dist/store.js +0 -3372
  593. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  594. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  595. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  596. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -12,7 +12,7 @@
12
12
  * - Per-feature breakdown so you see exactly what a change helped/hurt
13
13
  */
14
14
  import { createMemory, Layer } from './memory.js';
15
- import { search } from './search.js';
15
+ import { search } from './search/bm25-search.js';
16
16
  import { multihopSearch } from './multihop.js';
17
17
  import { mrr, recallAtK, ndcgAtK } from './eval.js';
18
18
  // ---------------------------------------------------------------------------
package/dist/eval.js CHANGED
@@ -8,9 +8,9 @@
8
8
  * weights, and future scoring tweaks can be tuned against evidence instead
9
9
  * of intuition.
10
10
  */
11
- import { hybridSearch } from './search.js';
11
+ import { hybridSearch } from './search/hybrid.js';
12
12
  import { searchBothHybrid } from './shared.js';
13
- import { isInitialized } from './store.js';
13
+ import { isInitialized } from './store/open.js';
14
14
  // ---------------------------------------------------------------------------
15
15
  // Metrics — pure functions. K is inclusive of position K.
16
16
  // ---------------------------------------------------------------------------
package/dist/extract.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Layer, createMemory } from './memory.js';
2
- import { writeEntry } from './store.js';
2
+ import { writeEntry } from './store/entry-writes.js';
3
3
  import { loadConfig } from './config.js';
4
4
  import { RejectedValueError } from './rejection.js';
5
- import { redactSecrets } from './secret-detect.js';
5
+ import { redactSecretsStrict } from './secret-detect.js';
6
6
  import { fetchWithRetry, llmTimeoutMs } from './http-retry.js';
7
7
  import { neverAutoShareTags } from './shared.js';
8
+ import { log } from './log.js';
8
9
  function isJsonString(value) {
9
10
  return typeof value === 'string';
10
11
  }
@@ -35,7 +36,7 @@ export async function extractFacts(text, opts) {
35
36
  body: JSON.stringify({
36
37
  model,
37
38
  max_tokens: 1200,
38
- messages: [{ role: 'user', content: EXTRACTION_PROMPT + redactSecrets(text) }],
39
+ messages: [{ role: 'user', content: EXTRACTION_PROMPT + redactSecretsStrict(text) }],
39
40
  }),
40
41
  }, { timeoutMs: llmTimeoutMs(), fetchFn });
41
42
  }
@@ -124,7 +125,7 @@ export function storeExtractedFacts(hippoRoot, source, facts) {
124
125
  entries.push(entry);
125
126
  }
126
127
  if (rejected > 0) {
127
- console.error(`storeExtractedFacts: skipped ${rejected} rejected value(s)`);
128
+ log.warn(`storeExtractedFacts: skipped ${rejected} rejected value(s)`);
128
129
  }
129
130
  return entries;
130
131
  }
@@ -2,7 +2,9 @@
2
2
  import { isContentWorthStoring } from './audit.js';
3
3
  import { RejectedValueError } from './rejection.js';
4
4
  import { detectSecret } from './secret-detect.js';
5
- import { auditRejectionRefusal, stampOriginProject, writeEntryDbOnly } from './store.js';
5
+ import { auditRejectionRefusal } from './store/audit-event.js';
6
+ import { stampOriginProject } from './store/entry-row.js';
7
+ import { writeEntryDbOnly } from './store/entry-writes.js';
6
8
  /** Runs on the caller's handle so it nests in the caller's transaction (writeEntry would open a second handle and wait on that lock); the caller mirrors after commit with an entry it stamped itself. The rejection audit lands inside that transaction, which is safe because a batch that rolls back stays `summarised` and replay writes the audit again. */
7
9
  export function gatedWrite(db, hippoRoot, entry, opts) {
8
10
  // Off for imported agent memories: a person wrote those notes, and a one-line preference fails the check.
package/dist/goals.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type DatabaseSyncLike } from './db.js';
2
2
  import type { MemoryEntry } from './memory.js';
3
- import type { RerankStep } from './search.js';
3
+ import type { RerankStep } from './search/types.js';
4
4
  export type GoalStatus = 'active' | 'suspended' | 'completed';
5
5
  export type PolicyType = 'schema-fit-biased' | 'error-prioritized' | 'recency-first' | 'hybrid';
6
6
  export interface GoalRow {
@@ -78,6 +78,8 @@ export interface GetActiveGoalsOpts {
78
78
  tenantId: string;
79
79
  }
80
80
  export declare function getActiveGoals(hippoRoot: string, opts: GetActiveGoalsOpts): Goal[];
81
+ /** Every goal of a (tenant, session), whatever its status, oldest first. */
82
+ export declare function getSessionGoals(hippoRoot: string, opts: GetActiveGoalsOpts): Goal[];
81
83
  export declare function getActiveGoalsWithDb(db: DatabaseSyncLike, opts: GetActiveGoalsOpts): Goal[];
82
84
  /** One `goal_recall_log` row: a boosted local memory recalled while its goal was active. */
83
85
  export interface GoalRecallLogRow {
package/dist/goals.js CHANGED
@@ -129,6 +129,24 @@ export function getActiveGoals(hippoRoot, opts) {
129
129
  closeHippoDb(db);
130
130
  }
131
131
  }
132
+ /** Every goal of a (tenant, session), whatever its status, oldest first. */
133
+ export function getSessionGoals(hippoRoot, opts) {
134
+ const db = openHippoDb(hippoRoot);
135
+ try {
136
+ // SAFETY: rows come from the SELECT below, which projects exactly GoalRow's columns.
137
+ const rows = db.prepare(`
138
+ SELECT id, session_id, tenant_id, goal_name, level, parent_goal_id, status,
139
+ success_condition, retrieval_policy_id, created_at, completed_at, outcome_score
140
+ FROM goal_stack
141
+ WHERE tenant_id = ? AND session_id = ?
142
+ ORDER BY created_at ASC
143
+ `).all(opts.tenantId, opts.sessionId);
144
+ return rows.map(rowToGoal);
145
+ }
146
+ finally {
147
+ closeHippoDb(db);
148
+ }
149
+ }
132
150
  export function getActiveGoalsWithDb(db, opts) {
133
151
  // SAFETY: rows come from the SELECT above, which projects exactly
134
152
  // GoalRow's columns (in the same order goal_stack defines them).
@@ -0,0 +1,73 @@
1
+ import { type GraphTxDb, type EntityType, type GraphQueueStatus, type Entity, type Relation, type GraphQueueItem } from './types.js';
2
+ export declare function loadEntityById(hippoRoot: string, tenantId: string, id: number): Entity | null;
3
+ /** Entities with an exact `name` (read), bounded by `limit` in SQL with a
4
+ * deterministic order. Lets the graph-view focus query find the `--entity NAME`
5
+ * entity DIRECTLY (not from a globally-capped list) WITHOUT materializing every
6
+ * same-name row when a name maps to many entities. */
7
+ export declare function loadEntitiesByName(hippoRoot: string, tenantId: string, name: string, opts?: {
8
+ limit?: number;
9
+ }, txDb?: GraphTxDb): Entity[];
10
+ export declare function loadEntities(hippoRoot: string, tenantId: string, opts?: {
11
+ entityType?: EntityType;
12
+ limit?: number;
13
+ }, txDb?: GraphTxDb): Entity[];
14
+ export declare function loadRelations(hippoRoot: string, tenantId: string, opts?: {
15
+ fromEntityId?: number;
16
+ limit?: number;
17
+ }, txDb?: GraphTxDb): Relation[];
18
+ /**
19
+ * Map consolidated source memory ids -> their graph entities. The SEED step of E3.2
20
+ * multi-hop recall (recall result memory ids -> entities to traverse from). Tenant-
21
+ * scoped, read-only; chunks the IN-list under the SQLite variable cap.
22
+ */
23
+ export declare function loadEntitiesByMemoryId(hippoRoot: string, tenantId: string, memoryIds: string[]): Entity[];
24
+ /**
25
+ * Load entities by their primary ids. Resolves the entity rows reached during the BFS
26
+ * (whose `memory_id` maps back to a recall result). Tenant-scoped, read-only.
27
+ */
28
+ export declare function loadEntitiesByIds(hippoRoot: string, tenantId: string, ids: number[], txDb?: GraphTxDb): Entity[];
29
+ /**
30
+ * All relations touching ANY of `entityIds` in EITHER direction (from OR to) — the
31
+ * per-hop neighbour query for E3.2 multi-hop traversal. ONE query for the whole frontier
32
+ * (not one per node): this is the bidirectional read `loadRelations` (from-only) lacks,
33
+ * and avoids an N+1 across BFS frontier nodes. `limit` caps rows for the frontier and
34
+ * must be a non-negative integer (the raw `LIMIT ?` rejects a fractional value).
35
+ */
36
+ export declare function loadNeighborRelations(hippoRoot: string, tenantId: string, entityIds: number[], opts?: {
37
+ limit?: number;
38
+ }, txDb?: GraphTxDb): Relation[];
39
+ /**
40
+ * Relations with BOTH endpoints in `entityIds` (edges AMONG the set, not merely
41
+ * touching it). Read. Used by the graph-view focus subgraph so the displayed
42
+ * edges are exactly the intra-union edges: the `LIMIT` only caps genuinely-many
43
+ * intra-union edges — no out-of-union row can evict a valid in-set edge. The
44
+ * caller bounds `entityIds` (<= the view limit), so a single query is safe.
45
+ */
46
+ export declare function loadRelationsAmong(hippoRoot: string, tenantId: string, entityIds: number[], opts?: {
47
+ limit?: number;
48
+ }, txDb?: GraphTxDb): Relation[];
49
+ /**
50
+ * Run `fn` inside ONE read transaction (a single WAL snapshot) so every graph read
51
+ * it performs — pass the supplied `txDb` to the `load*` functions — sees a consistent
52
+ * view, even if a `graph extract` / sleep-drain rebuild commits concurrently between
53
+ * reads (the rebuild clears + reinserts entities, so separate reads could otherwise
54
+ * mix old entity ids with new relation ids). Reads only; the connection is opened
55
+ * once and closed after.
56
+ */
57
+ export declare function withGraphReadSnapshot<T>(hippoRoot: string, fn: (txDb: GraphTxDb) => T): T;
58
+ export declare function loadExtractionQueue(hippoRoot: string, tenantId: string, opts?: {
59
+ status?: GraphQueueStatus;
60
+ limit?: number;
61
+ }): GraphQueueItem[];
62
+ /**
63
+ * The dirty tenants awaiting graph re-extraction, each with the MAX pending
64
+ * queue id at read time (a watermark). The sleep drain rebuilds each tenant's
65
+ * graph, then marks only items at or below the watermark processed, so items
66
+ * enqueued DURING the rebuild stay pending for the next sleep (no lost-update
67
+ * race). Host-wide read (the queue is per-tenant but sleep is cross-tenant).
68
+ */
69
+ export declare function loadPendingExtractionTenants(hippoRoot: string): {
70
+ tenantId: string;
71
+ maxPendingId: number;
72
+ }[];
73
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1,325 @@
1
+ import { openHippoDb, closeHippoDb } from '../db.js';
2
+ import { assertTenantId } from '../tenant.js';
3
+ import { GRAPH_ENTITY_TYPES, VALID_QUEUE_STATES } from './types.js';
4
+ import { rowToEntity, rowToRelation, rowToQueueItem, ENTITY_COLS, RELATION_COLS, QUEUE_COLS } from './rows.js';
5
+ export function loadEntityById(hippoRoot, tenantId, id) {
6
+ assertTenantId('loadEntityById', tenantId);
7
+ const db = openHippoDb(hippoRoot);
8
+ try {
9
+ // SAFETY: row's shape matches the columns named in ENTITY_COLS above.
10
+ const row = db.prepare(`SELECT ${ENTITY_COLS} FROM entities WHERE id = ? AND tenant_id = ?`)
11
+ .get(id, tenantId);
12
+ return row ? rowToEntity(row) : null;
13
+ }
14
+ finally {
15
+ closeHippoDb(db);
16
+ }
17
+ }
18
+ /** Entities with an exact `name` (read), bounded by `limit` in SQL with a
19
+ * deterministic order. Lets the graph-view focus query find the `--entity NAME`
20
+ * entity DIRECTLY (not from a globally-capped list) WITHOUT materializing every
21
+ * same-name row when a name maps to many entities. */
22
+ export function loadEntitiesByName(hippoRoot, tenantId, name, opts = {}, txDb) {
23
+ assertTenantId('loadEntitiesByName', tenantId);
24
+ const limit = opts.limit ?? 100;
25
+ if (!Number.isInteger(limit) || limit < 0) {
26
+ throw new Error(`loadEntitiesByName: limit must be a non-negative integer; got ${limit}`);
27
+ }
28
+ const ownDb = txDb ? null : openHippoDb(hippoRoot);
29
+ const db = txDb ?? ownDb;
30
+ try {
31
+ // SAFETY: rows' shape matches the columns named in ENTITY_COLS above.
32
+ const rows = db.prepare(`
33
+ SELECT ${ENTITY_COLS} FROM entities WHERE tenant_id = ? AND name = ?
34
+ ORDER BY id ASC LIMIT ?
35
+ `).all(tenantId, name, limit);
36
+ return rows.map(rowToEntity);
37
+ }
38
+ finally {
39
+ if (ownDb)
40
+ closeHippoDb(ownDb);
41
+ }
42
+ }
43
+ export function loadEntities(hippoRoot, tenantId, opts = {}, txDb) {
44
+ assertTenantId('loadEntities', tenantId);
45
+ const limit = opts.limit ?? 100;
46
+ if (opts.entityType && !GRAPH_ENTITY_TYPES.has(opts.entityType)) {
47
+ throw new Error(`loadEntities: entityType must be one of ${Array.from(GRAPH_ENTITY_TYPES).join('|')}; got ${opts.entityType}`);
48
+ }
49
+ const ownDb = txDb ? null : openHippoDb(hippoRoot);
50
+ const db = txDb ?? ownDb;
51
+ try {
52
+ const clauses = ['tenant_id = ?'];
53
+ const params = [tenantId];
54
+ if (opts.entityType) {
55
+ clauses.push('entity_type = ?');
56
+ params.push(opts.entityType);
57
+ }
58
+ params.push(limit);
59
+ // SAFETY: rows' shape matches the columns named in ENTITY_COLS above.
60
+ const rows = db.prepare(`
61
+ SELECT ${ENTITY_COLS} FROM entities
62
+ WHERE ${clauses.join(' AND ')}
63
+ ORDER BY created_at DESC, id DESC
64
+ LIMIT ?
65
+ `).all(...params);
66
+ return rows.map(rowToEntity);
67
+ }
68
+ finally {
69
+ if (ownDb)
70
+ closeHippoDb(ownDb);
71
+ }
72
+ }
73
+ export function loadRelations(hippoRoot, tenantId, opts = {}, txDb) {
74
+ assertTenantId('loadRelations', tenantId);
75
+ const limit = opts.limit ?? 100;
76
+ const ownDb = txDb ? null : openHippoDb(hippoRoot);
77
+ const db = txDb ?? ownDb;
78
+ try {
79
+ const clauses = ['tenant_id = ?'];
80
+ const params = [tenantId];
81
+ if (opts.fromEntityId !== undefined) {
82
+ clauses.push('from_entity_id = ?');
83
+ params.push(opts.fromEntityId);
84
+ }
85
+ params.push(limit);
86
+ // SAFETY: rows' shape matches the columns named in RELATION_COLS above.
87
+ const rows = db.prepare(`
88
+ SELECT ${RELATION_COLS} FROM relations
89
+ WHERE ${clauses.join(' AND ')}
90
+ ORDER BY created_at DESC, id DESC
91
+ LIMIT ?
92
+ `).all(...params);
93
+ return rows.map(rowToRelation);
94
+ }
95
+ finally {
96
+ if (ownDb)
97
+ closeHippoDb(ownDb);
98
+ }
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // E3.2 multi-hop recall read helpers (SELECT-only; the check-graph-writes lint
102
+ // permits these here and in the read-only consumer src/graph-recall.ts).
103
+ // ---------------------------------------------------------------------------
104
+ /** Chunk size for IN-list queries: well under SQLite's 999-bound-variable default
105
+ * (leaves headroom for the tenant_id param + the doubled list in neighbour lookups). */
106
+ const IN_LIST_CHUNK = 400;
107
+ /**
108
+ * Map consolidated source memory ids -> their graph entities. The SEED step of E3.2
109
+ * multi-hop recall (recall result memory ids -> entities to traverse from). Tenant-
110
+ * scoped, read-only; chunks the IN-list under the SQLite variable cap.
111
+ */
112
+ export function loadEntitiesByMemoryId(hippoRoot, tenantId, memoryIds) {
113
+ assertTenantId('loadEntitiesByMemoryId', tenantId);
114
+ if (memoryIds.length === 0)
115
+ return [];
116
+ const db = openHippoDb(hippoRoot);
117
+ try {
118
+ const out = [];
119
+ for (let i = 0; i < memoryIds.length; i += IN_LIST_CHUNK) {
120
+ const slice = memoryIds.slice(i, i + IN_LIST_CHUNK);
121
+ const ph = slice.map(() => '?').join(',');
122
+ // T2: no ORDER BY meant chunk-local scan order decided ties; id ASC
123
+ // makes it deterministic (entities.id is an autoincrement integer PK).
124
+ // SAFETY: rows' shape matches the columns named in ENTITY_COLS above.
125
+ const rows = db.prepare(`
126
+ SELECT ${ENTITY_COLS} FROM entities
127
+ WHERE tenant_id = ? AND memory_id IN (${ph})
128
+ ORDER BY id ASC
129
+ `).all(tenantId, ...slice);
130
+ out.push(...rows.map(rowToEntity));
131
+ }
132
+ return out;
133
+ }
134
+ finally {
135
+ closeHippoDb(db);
136
+ }
137
+ }
138
+ /**
139
+ * Load entities by their primary ids. Resolves the entity rows reached during the BFS
140
+ * (whose `memory_id` maps back to a recall result). Tenant-scoped, read-only.
141
+ */
142
+ export function loadEntitiesByIds(hippoRoot, tenantId, ids, txDb) {
143
+ assertTenantId('loadEntitiesByIds', tenantId);
144
+ if (ids.length === 0)
145
+ return [];
146
+ const ownDb = txDb ? null : openHippoDb(hippoRoot);
147
+ const db = txDb ?? ownDb;
148
+ try {
149
+ const out = [];
150
+ for (let i = 0; i < ids.length; i += IN_LIST_CHUNK) {
151
+ const slice = ids.slice(i, i + IN_LIST_CHUNK);
152
+ const ph = slice.map(() => '?').join(',');
153
+ // SAFETY: rows' shape matches the columns named in ENTITY_COLS above.
154
+ const rows = db.prepare(`
155
+ SELECT ${ENTITY_COLS} FROM entities
156
+ WHERE tenant_id = ? AND id IN (${ph})
157
+ `).all(tenantId, ...slice);
158
+ out.push(...rows.map(rowToEntity));
159
+ }
160
+ return out;
161
+ }
162
+ finally {
163
+ if (ownDb)
164
+ closeHippoDb(ownDb);
165
+ }
166
+ }
167
+ /**
168
+ * All relations touching ANY of `entityIds` in EITHER direction (from OR to) — the
169
+ * per-hop neighbour query for E3.2 multi-hop traversal. ONE query for the whole frontier
170
+ * (not one per node): this is the bidirectional read `loadRelations` (from-only) lacks,
171
+ * and avoids an N+1 across BFS frontier nodes. `limit` caps rows for the frontier and
172
+ * must be a non-negative integer (the raw `LIMIT ?` rejects a fractional value).
173
+ */
174
+ export function loadNeighborRelations(hippoRoot, tenantId, entityIds, opts = {}, txDb) {
175
+ assertTenantId('loadNeighborRelations', tenantId);
176
+ if (entityIds.length === 0)
177
+ return [];
178
+ const limit = opts.limit ?? 1000;
179
+ if (!Number.isInteger(limit) || limit < 0) {
180
+ throw new Error(`loadNeighborRelations: limit must be a non-negative integer; got ${limit}`);
181
+ }
182
+ const ownDb = txDb ? null : openHippoDb(hippoRoot);
183
+ const db = txDb ?? ownDb;
184
+ try {
185
+ // `limit` is applied PER CHUNK; a frontier spanning >IN_LIST_CHUNK ids could return
186
+ // up to limit*chunks rows before the by-id dedup below. Harmless for E3.2 (the
187
+ // frontier is bounded by maxNeighbors <= 200 << IN_LIST_CHUNK, so a single chunk,
188
+ // and the BFS re-enforces the per-hop fanout cap), but note the semantics if a
189
+ // tighter total cap is ever needed.
190
+ const byId = new Map();
191
+ for (let i = 0; i < entityIds.length; i += IN_LIST_CHUNK) {
192
+ const slice = entityIds.slice(i, i + IN_LIST_CHUNK);
193
+ const ph = slice.map(() => '?').join(',');
194
+ // SAFETY: rows' shape matches the columns named in RELATION_COLS above.
195
+ const rows = db.prepare(`
196
+ SELECT ${RELATION_COLS} FROM relations
197
+ WHERE tenant_id = ? AND (from_entity_id IN (${ph}) OR to_entity_id IN (${ph}))
198
+ ORDER BY created_at DESC, id DESC
199
+ LIMIT ?
200
+ `).all(tenantId, ...slice, ...slice, limit);
201
+ for (const r of rows)
202
+ byId.set(r.id, rowToRelation(r));
203
+ }
204
+ return Array.from(byId.values());
205
+ }
206
+ finally {
207
+ if (ownDb)
208
+ closeHippoDb(ownDb);
209
+ }
210
+ }
211
+ /**
212
+ * Relations with BOTH endpoints in `entityIds` (edges AMONG the set, not merely
213
+ * touching it). Read. Used by the graph-view focus subgraph so the displayed
214
+ * edges are exactly the intra-union edges: the `LIMIT` only caps genuinely-many
215
+ * intra-union edges — no out-of-union row can evict a valid in-set edge. The
216
+ * caller bounds `entityIds` (<= the view limit), so a single query is safe.
217
+ */
218
+ export function loadRelationsAmong(hippoRoot, tenantId, entityIds, opts = {}, txDb) {
219
+ assertTenantId('loadRelationsAmong', tenantId);
220
+ if (entityIds.length === 0)
221
+ return [];
222
+ const limit = opts.limit ?? 1000;
223
+ if (!Number.isInteger(limit) || limit < 0) {
224
+ throw new Error(`loadRelationsAmong: limit must be a non-negative integer; got ${limit}`);
225
+ }
226
+ const ownDb = txDb ? null : openHippoDb(hippoRoot);
227
+ const db = txDb ?? ownDb;
228
+ try {
229
+ const ph = entityIds.map(() => '?').join(',');
230
+ // SAFETY: rows' shape matches the columns named in RELATION_COLS above.
231
+ const rows = db.prepare(`
232
+ SELECT ${RELATION_COLS} FROM relations
233
+ WHERE tenant_id = ? AND from_entity_id IN (${ph}) AND to_entity_id IN (${ph})
234
+ ORDER BY created_at DESC, id DESC
235
+ LIMIT ?
236
+ `).all(tenantId, ...entityIds, ...entityIds, limit);
237
+ return rows.map(rowToRelation);
238
+ }
239
+ finally {
240
+ if (ownDb)
241
+ closeHippoDb(ownDb);
242
+ }
243
+ }
244
+ /**
245
+ * Run `fn` inside ONE read transaction (a single WAL snapshot) so every graph read
246
+ * it performs — pass the supplied `txDb` to the `load*` functions — sees a consistent
247
+ * view, even if a `graph extract` / sleep-drain rebuild commits concurrently between
248
+ * reads (the rebuild clears + reinserts entities, so separate reads could otherwise
249
+ * mix old entity ids with new relation ids). Reads only; the connection is opened
250
+ * once and closed after.
251
+ */
252
+ export function withGraphReadSnapshot(hippoRoot, fn) {
253
+ const db = openHippoDb(hippoRoot);
254
+ try {
255
+ db.exec('BEGIN');
256
+ try {
257
+ const out = fn(db);
258
+ db.exec('COMMIT');
259
+ return out;
260
+ }
261
+ catch (e) {
262
+ try {
263
+ db.exec('ROLLBACK');
264
+ }
265
+ catch { /* ignore */ }
266
+ throw e;
267
+ }
268
+ }
269
+ finally {
270
+ closeHippoDb(db);
271
+ }
272
+ }
273
+ export function loadExtractionQueue(hippoRoot, tenantId, opts = {}) {
274
+ assertTenantId('loadExtractionQueue', tenantId);
275
+ const limit = opts.limit ?? 100;
276
+ if (opts.status && !VALID_QUEUE_STATES.has(opts.status)) {
277
+ throw new Error(`loadExtractionQueue: status must be one of ${Array.from(VALID_QUEUE_STATES).join('|')}; got ${opts.status}`);
278
+ }
279
+ const db = openHippoDb(hippoRoot);
280
+ try {
281
+ const clauses = ['tenant_id = ?'];
282
+ const params = [tenantId];
283
+ if (opts.status) {
284
+ clauses.push('status = ?');
285
+ params.push(opts.status);
286
+ }
287
+ params.push(limit);
288
+ // SAFETY: rows' shape matches the columns named in QUEUE_COLS above.
289
+ const rows = db.prepare(`
290
+ SELECT ${QUEUE_COLS} FROM graph_extraction_queue
291
+ WHERE ${clauses.join(' AND ')}
292
+ ORDER BY enqueued_at ASC, id ASC
293
+ LIMIT ?
294
+ `).all(...params);
295
+ return rows.map(rowToQueueItem);
296
+ }
297
+ finally {
298
+ closeHippoDb(db);
299
+ }
300
+ }
301
+ /**
302
+ * The dirty tenants awaiting graph re-extraction, each with the MAX pending
303
+ * queue id at read time (a watermark). The sleep drain rebuilds each tenant's
304
+ * graph, then marks only items at or below the watermark processed, so items
305
+ * enqueued DURING the rebuild stay pending for the next sleep (no lost-update
306
+ * race). Host-wide read (the queue is per-tenant but sleep is cross-tenant).
307
+ */
308
+ export function loadPendingExtractionTenants(hippoRoot) {
309
+ const db = openHippoDb(hippoRoot);
310
+ try {
311
+ // SAFETY: rows' shape matches the two aliased columns (tenant_id, max_id)
312
+ // named in the SELECT above.
313
+ const rows = db.prepare(`
314
+ SELECT tenant_id AS tenant_id, MAX(id) AS max_id
315
+ FROM graph_extraction_queue
316
+ WHERE status = 'pending'
317
+ GROUP BY tenant_id
318
+ `).all();
319
+ return rows.map((r) => ({ tenantId: r.tenant_id, maxPendingId: Number(r.max_id) }));
320
+ }
321
+ finally {
322
+ closeHippoDb(db);
323
+ }
324
+ }
325
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1,45 @@
1
+ import type { Entity, Relation, GraphQueueItem } from './types.js';
2
+ export interface EntityRow {
3
+ id: number;
4
+ tenant_id: string;
5
+ entity_type: string;
6
+ name: string;
7
+ memory_id: string | null;
8
+ source_kind: string;
9
+ source_object_type: string | null;
10
+ source_object_id: number | null;
11
+ created_at: string;
12
+ }
13
+ export interface RelationRow {
14
+ id: number;
15
+ tenant_id: string;
16
+ from_entity_id: number;
17
+ to_entity_id: number;
18
+ rel_type: string;
19
+ memory_id: string | null;
20
+ source_kind: string;
21
+ source_object_type: string | null;
22
+ source_object_id: number | null;
23
+ created_at: string;
24
+ }
25
+ export interface QueueRow {
26
+ id: number;
27
+ tenant_id: string;
28
+ memory_id: string;
29
+ kind: string;
30
+ status: string;
31
+ enqueued_at: string;
32
+ processed_at: string | null;
33
+ }
34
+ export declare function rowToEntity(row: EntityRow): Entity;
35
+ export declare function rowToRelation(row: RelationRow): Relation;
36
+ export declare function rowToQueueItem(row: QueueRow): GraphQueueItem;
37
+ export declare const ENTITY_COLS = "id, tenant_id, entity_type, name, memory_id, source_kind, source_object_type, source_object_id, created_at";
38
+ export declare const RELATION_COLS = "id, tenant_id, from_entity_id, to_entity_id, rel_type, memory_id, source_kind, source_object_type, source_object_id, created_at";
39
+ export declare const QUEUE_COLS = "id, tenant_id, memory_id, kind, status, enqueued_at, processed_at";
40
+ export interface DbLike {
41
+ prepare(sql: string): {
42
+ get<T>(...params: unknown[]): T;
43
+ };
44
+ }
45
+ //# sourceMappingURL=rows.d.ts.map
@@ -0,0 +1,51 @@
1
+ export function rowToEntity(row) {
2
+ // SAFETY: entity_type/source_kind/source_object_type are DB CHECK-constrained
3
+ // (see db.ts CREATE TABLE entities) to exactly the EntityType/SourceKind/
4
+ // SourceObjectType enum values, so the row's column values match those types.
5
+ return {
6
+ id: row.id,
7
+ tenantId: row.tenant_id,
8
+ entityType: row.entity_type,
9
+ name: row.name,
10
+ memoryId: row.memory_id,
11
+ sourceKind: row.source_kind,
12
+ sourceObjectType: row.source_object_type === null ? undefined : row.source_object_type,
13
+ sourceObjectId: row.source_object_id === null ? undefined : row.source_object_id,
14
+ createdAt: row.created_at,
15
+ };
16
+ }
17
+ export function rowToRelation(row) {
18
+ // SAFETY: rel_type/source_kind/source_object_type are DB CHECK-constrained
19
+ // (see db.ts CREATE TABLE relations) to exactly the RelationType/SourceKind/
20
+ // SourceObjectType enum values, so the row's column values match those types.
21
+ return {
22
+ id: row.id,
23
+ tenantId: row.tenant_id,
24
+ fromEntityId: row.from_entity_id,
25
+ toEntityId: row.to_entity_id,
26
+ relType: row.rel_type,
27
+ memoryId: row.memory_id,
28
+ sourceKind: row.source_kind,
29
+ sourceObjectType: row.source_object_type === null ? undefined : row.source_object_type,
30
+ sourceObjectId: row.source_object_id === null ? undefined : row.source_object_id,
31
+ createdAt: row.created_at,
32
+ };
33
+ }
34
+ export function rowToQueueItem(row) {
35
+ // SAFETY: kind/status are DB CHECK-constrained (see db.ts CREATE TABLE
36
+ // graph_extraction_queue) to exactly the SourceKind/GraphQueueStatus enum
37
+ // values, so the row's column values match those types.
38
+ return {
39
+ id: row.id,
40
+ tenantId: row.tenant_id,
41
+ memoryId: row.memory_id,
42
+ kind: row.kind,
43
+ status: row.status,
44
+ enqueuedAt: row.enqueued_at,
45
+ processedAt: row.processed_at,
46
+ };
47
+ }
48
+ export const ENTITY_COLS = `id, tenant_id, entity_type, name, memory_id, source_kind, source_object_type, source_object_id, created_at`;
49
+ export const RELATION_COLS = `id, tenant_id, from_entity_id, to_entity_id, rel_type, memory_id, source_kind, source_object_type, source_object_id, created_at`;
50
+ export const QUEUE_COLS = `id, tenant_id, memory_id, kind, status, enqueued_at, processed_at`;
51
+ //# sourceMappingURL=rows.js.map