hippo-memory 1.70.0 → 1.71.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 (629) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/claude-code.d.ts +4 -2
  3. package/dist/agent-memories/claude-code.js +14 -5
  4. package/dist/agent-memories/files.js +23 -12
  5. package/dist/agent-memories/markdown.d.ts +1 -3
  6. package/dist/agent-memories/markdown.js +1 -3
  7. package/dist/agent-memories/report.js +2 -1
  8. package/dist/agent-memories/sync.d.ts +4 -2
  9. package/dist/agent-memories/sync.js +10 -5
  10. package/dist/api/assemble.d.ts +7 -44
  11. package/dist/api/assemble.js +2 -22
  12. package/dist/api/audit.d.ts +5 -1
  13. package/dist/api/audit.js +9 -1
  14. package/dist/api/auth.d.ts +13 -22
  15. package/dist/api/auth.js +34 -24
  16. package/dist/api/auto-sleep.js +2 -2
  17. package/dist/api/availability.d.ts +2 -15
  18. package/dist/api/availability.js +2 -15
  19. package/dist/api/context-select.js +3 -4
  20. package/dist/api/context-types.d.ts +10 -35
  21. package/dist/api/context.d.ts +5 -22
  22. package/dist/api/context.js +21 -38
  23. package/dist/api/dormant.d.ts +5 -21
  24. package/dist/api/dormant.js +7 -26
  25. package/dist/api/drill-down.d.ts +7 -46
  26. package/dist/api/drill-down.js +5 -26
  27. package/dist/api/forget.d.ts +5 -24
  28. package/dist/api/forget.js +5 -28
  29. package/dist/api/graph.d.ts +8 -0
  30. package/dist/api/graph.js +7 -0
  31. package/dist/api/index.d.ts +2 -0
  32. package/dist/api/index.js +2 -0
  33. package/dist/api/instruction-detect.js +16 -5
  34. package/dist/api/ledger-db.d.ts +2 -1
  35. package/dist/api/ledger-db.js +5 -3
  36. package/dist/api/memories.d.ts +5 -0
  37. package/dist/api/memories.js +7 -0
  38. package/dist/api/objects.d.ts +9 -0
  39. package/dist/api/objects.js +11 -0
  40. package/dist/api/on-store.js +5 -3
  41. package/dist/api/predictions.d.ts +9 -0
  42. package/dist/api/predictions.js +18 -0
  43. package/dist/api/promote.d.ts +13 -17
  44. package/dist/api/promote.js +11 -19
  45. package/dist/api/prompt-hook.d.ts +4 -4
  46. package/dist/api/prompt-hook.js +10 -9
  47. package/dist/api/recall-cli.d.ts +55 -0
  48. package/dist/api/recall-cli.js +94 -0
  49. package/dist/api/recall-core.js +14 -6
  50. package/dist/api/recall-finish.d.ts +53 -0
  51. package/dist/api/recall-finish.js +30 -0
  52. package/dist/api/recall-history.d.ts +17 -84
  53. package/dist/api/recall-history.js +15 -88
  54. package/dist/api/recall-pipeline.d.ts +2 -3
  55. package/dist/api/recall-pipeline.js +16 -9
  56. package/dist/api/recall-types.d.ts +64 -304
  57. package/dist/api/recall.d.ts +5 -33
  58. package/dist/api/recall.js +59 -60
  59. package/dist/api/refine.d.ts +7 -0
  60. package/dist/api/refine.js +10 -0
  61. package/dist/api/remember-local.d.ts +57 -0
  62. package/dist/api/remember-local.js +90 -0
  63. package/dist/api/remember.d.ts +18 -1
  64. package/dist/api/remember.js +13 -1
  65. package/dist/api/sleep-run.d.ts +1 -3
  66. package/dist/api/sleep-run.js +17 -21
  67. package/dist/api/sleep.d.ts +9 -28
  68. package/dist/api/tokens.d.ts +3 -10
  69. package/dist/api/tokens.js +3 -10
  70. package/dist/api/types.d.ts +6 -29
  71. package/dist/api/types.js +4 -22
  72. package/dist/capture/command.d.ts +4 -12
  73. package/dist/capture/command.js +6 -22
  74. package/dist/capture/compact.d.ts +4 -15
  75. package/dist/capture/compact.js +16 -25
  76. package/dist/capture/compaction-record.js +101 -69
  77. package/dist/capture/compaction-spool.d.ts +1 -1
  78. package/dist/capture/compaction-spool.js +1 -1
  79. package/dist/capture/session-digest.d.ts +1 -1
  80. package/dist/capture/session-digest.js +13 -7
  81. package/dist/capture/transcript.d.ts +2 -10
  82. package/dist/capture/transcript.js +4 -18
  83. package/dist/cli/api-context.d.ts +3 -0
  84. package/dist/cli/api-context.js +6 -0
  85. package/dist/cli/audit-prune.d.ts +6 -39
  86. package/dist/cli/audit-prune.js +6 -39
  87. package/dist/cli/audit.d.ts +1 -1
  88. package/dist/cli/audit.js +33 -34
  89. package/dist/cli/auth.d.ts +2 -2
  90. package/dist/cli/auth.js +57 -39
  91. package/dist/cli/briefs.d.ts +4 -4
  92. package/dist/cli/briefs.js +18 -22
  93. package/dist/cli/card.d.ts +2 -2
  94. package/dist/cli/card.js +31 -32
  95. package/dist/cli/client.d.ts +7 -27
  96. package/dist/cli/client.js +24 -43
  97. package/dist/cli/compact-resume-payload.js +3 -2
  98. package/dist/cli/context.d.ts +1 -2
  99. package/dist/cli/context.js +12 -8
  100. package/dist/cli/continuity.d.ts +6 -6
  101. package/dist/cli/continuity.js +62 -64
  102. package/dist/cli/correction-latency.d.ts +2 -14
  103. package/dist/cli/correction-latency.js +2 -14
  104. package/dist/cli/curate.d.ts +13 -17
  105. package/dist/cli/curate.js +68 -92
  106. package/dist/cli/dag.d.ts +4 -4
  107. package/dist/cli/dag.js +33 -27
  108. package/dist/cli/decisions.d.ts +4 -4
  109. package/dist/cli/decisions.js +33 -47
  110. package/dist/cli/eval.js +15 -13
  111. package/dist/cli/exit.d.ts +6 -0
  112. package/dist/cli/exit.js +11 -0
  113. package/dist/cli/explain.d.ts +1 -2
  114. package/dist/cli/explain.js +6 -4
  115. package/dist/cli/flag-values.d.ts +6 -1
  116. package/dist/cli/flag-values.js +27 -10
  117. package/dist/cli/flags.d.ts +1 -0
  118. package/dist/cli/flags.js +1 -1
  119. package/dist/cli/github.d.ts +14 -0
  120. package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
  121. package/dist/cli/goals.d.ts +2 -2
  122. package/dist/cli/goals.js +46 -50
  123. package/dist/cli/hook-runtime.d.ts +9 -27
  124. package/dist/cli/hook-runtime.js +15 -31
  125. package/dist/cli/init.d.ts +2 -2
  126. package/dist/cli/init.js +6 -12
  127. package/dist/cli/install-steps.js +3 -12
  128. package/dist/cli/last-sleep.d.ts +2 -1
  129. package/dist/cli/last-sleep.js +3 -0
  130. package/dist/cli/maintenance.d.ts +4 -4
  131. package/dist/cli/maintenance.js +14 -19
  132. package/dist/cli/object-verbs.js +4 -3
  133. package/dist/cli/owner-validation.d.ts +5 -28
  134. package/dist/cli/owner-validation.js +5 -28
  135. package/dist/cli/playbooks.d.ts +4 -4
  136. package/dist/cli/playbooks.js +23 -28
  137. package/dist/cli/print.d.ts +2 -5
  138. package/dist/cli/print.js +1 -4
  139. package/dist/cli/projects.d.ts +2 -2
  140. package/dist/cli/projects.js +1 -3
  141. package/dist/cli/provenance-coverage.d.ts +2 -6
  142. package/dist/cli/provenance-coverage.js +2 -6
  143. package/dist/cli/quality-repair-once.js +2 -2
  144. package/dist/cli/recall.d.ts +2 -4
  145. package/dist/cli/recall.js +55 -131
  146. package/dist/cli/refine-llm.d.ts +5 -31
  147. package/dist/cli/refine-llm.js +9 -36
  148. package/dist/cli/remember.d.ts +3 -3
  149. package/dist/cli/remember.js +122 -180
  150. package/dist/cli/scheduler.d.ts +2 -17
  151. package/dist/cli/scheduler.js +12 -18
  152. package/dist/cli/serve.js +21 -12
  153. package/dist/cli/session-hooks.d.ts +10 -18
  154. package/dist/cli/session-hooks.js +112 -113
  155. package/dist/cli/setup.d.ts +4 -4
  156. package/dist/cli/setup.js +19 -21
  157. package/dist/cli/shared.d.ts +9 -23
  158. package/dist/cli/shared.js +9 -32
  159. package/dist/cli/slack.d.ts +2 -2
  160. package/dist/cli/slack.js +19 -23
  161. package/dist/cli/sleep.d.ts +3 -2
  162. package/dist/cli/sleep.js +15 -16
  163. package/dist/cli/status.d.ts +9 -12
  164. package/dist/cli/status.js +55 -98
  165. package/dist/cli/stdin.d.ts +4 -6
  166. package/dist/cli/stdin.js +2 -3
  167. package/dist/cli/transfer.d.ts +9 -9
  168. package/dist/cli/transfer.js +66 -89
  169. package/dist/cli/usage.js +11 -5
  170. package/dist/cli.d.ts +66 -448
  171. package/dist/cli.js +87 -263
  172. package/dist/connectors/github/backfill.d.ts +5 -25
  173. package/dist/connectors/github/backfill.js +14 -49
  174. package/dist/connectors/github/deletion.d.ts +4 -18
  175. package/dist/connectors/github/deletion.js +2 -15
  176. package/dist/connectors/github/dlq.d.ts +8 -33
  177. package/dist/connectors/github/dlq.js +12 -29
  178. package/dist/connectors/github/ingest.d.ts +2 -6
  179. package/dist/connectors/github/ingest.js +4 -10
  180. package/dist/connectors/github/octokit-client.d.ts +4 -16
  181. package/dist/connectors/github/octokit-client.js +27 -24
  182. package/dist/connectors/github/ratelimit.d.ts +3 -14
  183. package/dist/connectors/github/ratelimit.js +3 -14
  184. package/dist/connectors/github/scope.d.ts +3 -5
  185. package/dist/connectors/github/scope.js +3 -5
  186. package/dist/connectors/github/signature.d.ts +4 -26
  187. package/dist/connectors/github/signature.js +4 -26
  188. package/dist/connectors/github/tenant-routing.d.ts +2 -24
  189. package/dist/connectors/github/tenant-routing.js +4 -26
  190. package/dist/connectors/github/transform.js +2 -16
  191. package/dist/connectors/github/types.d.ts +3 -15
  192. package/dist/connectors/github/types.js +2 -9
  193. package/dist/connectors/github/webhook.d.ts +2 -16
  194. package/dist/connectors/github/webhook.js +6 -22
  195. package/dist/connectors/slack/backfill.d.ts +4 -17
  196. package/dist/connectors/slack/backfill.js +4 -13
  197. package/dist/connectors/slack/dlq.d.ts +2 -19
  198. package/dist/connectors/slack/dlq.js +2 -19
  199. package/dist/connectors/slack/ingest.d.ts +2 -3
  200. package/dist/connectors/slack/ingest.js +2 -3
  201. package/dist/connectors/slack/scope.d.ts +2 -8
  202. package/dist/connectors/slack/scope.js +2 -8
  203. package/dist/connectors/slack/signature.d.ts +1 -6
  204. package/dist/connectors/slack/tenant-routing.d.ts +2 -19
  205. package/dist/connectors/slack/tenant-routing.js +2 -21
  206. package/dist/connectors/slack/transform.d.ts +2 -18
  207. package/dist/connectors/slack/transform.js +2 -18
  208. package/dist/connectors/slack/types.d.ts +3 -9
  209. package/dist/connectors/slack/types.js +2 -4
  210. package/dist/connectors/slack/web-client.js +33 -27
  211. package/dist/connectors/slack/webhook.d.ts +2 -19
  212. package/dist/connectors/slack/webhook.js +5 -26
  213. package/dist/connectors/slack/workspaces.d.ts +4 -24
  214. package/dist/connectors/slack/workspaces.js +4 -24
  215. package/dist/consolidate/conflicts.js +6 -14
  216. package/dist/consolidate/dag-summary.d.ts +8 -0
  217. package/dist/consolidate/dag-summary.js +41 -0
  218. package/dist/consolidate/dag.d.ts +5 -28
  219. package/dist/consolidate/dag.js +14 -75
  220. package/dist/consolidate/decay.js +7 -19
  221. package/dist/consolidate/dedupe.d.ts +6 -52
  222. package/dist/consolidate/dedupe.js +13 -71
  223. package/dist/consolidate/flush-units.d.ts +3 -4
  224. package/dist/consolidate/flush-units.js +3 -3
  225. package/dist/consolidate/half-life-migration.d.ts +3 -26
  226. package/dist/consolidate/half-life-migration.js +11 -28
  227. package/dist/consolidate/llm-passes.js +4 -21
  228. package/dist/consolidate/memory-value-weights.d.ts +2 -13
  229. package/dist/consolidate/memory-value-weights.js +2 -13
  230. package/dist/consolidate/memory-value.d.ts +11 -84
  231. package/dist/consolidate/memory-value.js +16 -104
  232. package/dist/consolidate/merge.js +10 -31
  233. package/dist/consolidate/merged-row.js +2 -1
  234. package/dist/consolidate/physics-pass.js +1 -3
  235. package/dist/consolidate/replay.d.ts +6 -38
  236. package/dist/consolidate/replay.js +14 -52
  237. package/dist/consolidate/run.js +1 -1
  238. package/dist/consolidate/sleep.d.ts +1 -8
  239. package/dist/consolidate/sleep.js +5 -17
  240. package/dist/consolidate/trace.d.ts +3 -18
  241. package/dist/consolidate/trace.js +3 -18
  242. package/dist/consolidate/traces.js +6 -22
  243. package/dist/core/ablation.d.ts +4 -91
  244. package/dist/core/ablation.js +4 -91
  245. package/dist/core/ambient.d.ts +1 -8
  246. package/dist/core/ambient.js +1 -8
  247. package/dist/core/capture-contract.d.ts +4 -2
  248. package/dist/core/capture-contract.js +4 -2
  249. package/dist/core/card.d.ts +4 -1
  250. package/dist/core/card.js +8 -0
  251. package/dist/core/compare.d.ts +11 -67
  252. package/dist/core/compare.js +9 -63
  253. package/dist/core/config.d.ts +10 -24
  254. package/dist/core/config.js +13 -14
  255. package/dist/core/handoff.d.ts +1 -7
  256. package/dist/core/handoff.js +1 -7
  257. package/dist/core/memory-quality.js +1 -1
  258. package/dist/core/memory.d.ts +41 -164
  259. package/dist/core/memory.js +51 -221
  260. package/dist/core/package-root.d.ts +3 -0
  261. package/dist/core/package-root.js +5 -0
  262. package/dist/core/physics-config.d.ts +1 -4
  263. package/dist/core/physics-config.js +3 -8
  264. package/dist/core/physics.d.ts +15 -61
  265. package/dist/core/physics.js +59 -122
  266. package/dist/core/project-identity.d.ts +17 -58
  267. package/dist/core/project-identity.js +17 -38
  268. package/dist/core/project-remote.js +13 -2
  269. package/dist/core/raw-append-only.d.ts +5 -0
  270. package/dist/core/raw-append-only.js +7 -0
  271. package/dist/core/salience.d.ts +1 -7
  272. package/dist/core/salience.js +1 -7
  273. package/dist/dashboard/dashboard-actions.js +2 -2
  274. package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
  275. package/dist/dashboard/dashboard-snapshot.js +11 -2
  276. package/dist/dashboard/dashboard-types.d.ts +2 -1
  277. package/dist/dashboard/dashboard.d.ts +1 -0
  278. package/dist/dashboard/dashboard.js +50 -4
  279. package/dist/db/busy.d.ts +1 -1
  280. package/dist/db/busy.js +17 -8
  281. package/dist/db/connect.d.ts +1 -0
  282. package/dist/db/connect.js +3 -3
  283. package/dist/db/migrate.js +3 -3
  284. package/dist/db/migrations/types.d.ts +2 -5
  285. package/dist/db/migrations/v14.js +2 -3
  286. package/dist/db/migrations/v15.js +2 -8
  287. package/dist/db/migrations/v16.js +2 -3
  288. package/dist/db/migrations/v17.js +2 -3
  289. package/dist/db/migrations/v19.js +2 -5
  290. package/dist/db/migrations/v20.js +2 -7
  291. package/dist/db/migrations/v22.js +4 -17
  292. package/dist/db/migrations/v23.js +3 -14
  293. package/dist/db/migrations/v24.js +2 -4
  294. package/dist/db/migrations/v25.js +3 -8
  295. package/dist/db/migrations/v26.js +2 -13
  296. package/dist/db/migrations/v27.js +3 -11
  297. package/dist/db/migrations/v28.js +2 -14
  298. package/dist/db/migrations/v29.js +4 -18
  299. package/dist/db/migrations/v30.js +4 -16
  300. package/dist/db/migrations/v31.js +2 -15
  301. package/dist/db/migrations/v32.js +4 -22
  302. package/dist/db/migrations/v33.js +2 -15
  303. package/dist/db/migrations/v34.js +2 -11
  304. package/dist/db/migrations/v35.js +2 -11
  305. package/dist/db/migrations/v36.js +2 -11
  306. package/dist/db/migrations/v37.js +8 -33
  307. package/dist/db/migrations/v38.js +5 -38
  308. package/dist/db/migrations/v39.js +9 -20
  309. package/dist/db/migrations/v40.js +2 -9
  310. package/dist/db/migrations/v41.js +2 -24
  311. package/dist/db/migrations/v43.js +1 -1
  312. package/dist/db/migrations/v44.js +2 -8
  313. package/dist/db/migrations/v45.js +2 -7
  314. package/dist/db/migrations/v47.js +2 -3
  315. package/dist/db/migrations/v51.js +1 -1
  316. package/dist/db/open.d.ts +2 -0
  317. package/dist/db/open.js +17 -1
  318. package/dist/db/physics-state.d.ts +6 -22
  319. package/dist/db/physics-state.js +25 -36
  320. package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
  321. package/dist/db/raw-archive-mirror-cleanup.js +2 -17
  322. package/dist/db/vector-store.d.ts +2 -0
  323. package/dist/db/vector-store.js +8 -1
  324. package/dist/doctor.js +74 -19
  325. package/dist/entry/session-text.js +2 -1
  326. package/dist/eval/eval-stats.d.ts +15 -53
  327. package/dist/eval/eval-stats.js +12 -42
  328. package/dist/eval/eval-suite.d.ts +2 -13
  329. package/dist/eval/eval-suite.js +74 -34
  330. package/dist/eval/eval.d.ts +6 -24
  331. package/dist/eval/eval.js +7 -34
  332. package/dist/eval/judgment.d.ts +0 -3
  333. package/dist/eval/judgment.js +19 -11
  334. package/dist/extensions/openclaw-plugin/index.js +1 -1
  335. package/dist/graph/extract.d.ts +5 -27
  336. package/dist/graph/extract.js +7 -33
  337. package/dist/graph/recall.d.ts +7 -20
  338. package/dist/graph/recall.js +14 -76
  339. package/dist/graph/stream.d.ts +7 -39
  340. package/dist/graph/stream.js +11 -34
  341. package/dist/graph/view.d.ts +9 -35
  342. package/dist/graph/view.js +11 -39
  343. package/dist/hooks/codex-wrapper.js +2 -2
  344. package/dist/hooks/copilot.js +2 -1
  345. package/dist/hooks/hook-blocks.d.ts +6 -2
  346. package/dist/hooks/hook-blocks.js +37 -124
  347. package/dist/hooks/json-hooks.d.ts +4 -36
  348. package/dist/hooks/json-hooks.js +18 -57
  349. package/dist/hooks/opencode.d.ts +0 -38
  350. package/dist/hooks/opencode.js +9 -76
  351. package/dist/hooks/shared.d.ts +8 -17
  352. package/dist/hooks/shared.js +29 -20
  353. package/dist/importers/core.d.ts +12 -37
  354. package/dist/importers/core.js +9 -27
  355. package/dist/importers/markdown-parse.d.ts +8 -22
  356. package/dist/importers/markdown-parse.js +8 -25
  357. package/dist/importers/markdown.js +3 -12
  358. package/dist/importers/sources.js +7 -35
  359. package/dist/importers/vault.d.ts +2 -8
  360. package/dist/importers/vault.js +25 -81
  361. package/dist/index.d.ts +6 -2
  362. package/dist/index.js +6 -2
  363. package/dist/learn/autolearn.d.ts +14 -41
  364. package/dist/learn/autolearn.js +14 -41
  365. package/dist/learn/extract.js +2 -4
  366. package/dist/learn/forward-claim-detector.d.ts +6 -30
  367. package/dist/learn/forward-claim-detector.js +14 -66
  368. package/dist/learn/invalidation.d.ts +6 -18
  369. package/dist/learn/invalidation.js +9 -26
  370. package/dist/mcp/admin-tools.js +3 -5
  371. package/dist/mcp/memory-tools.js +4 -9
  372. package/dist/mcp/protocol.d.ts +8 -26
  373. package/dist/mcp/protocol.js +3 -6
  374. package/dist/mcp/recall-tools.js +3 -3
  375. package/dist/mcp/request.d.ts +3 -11
  376. package/dist/mcp/request.js +10 -26
  377. package/dist/mcp/server.d.ts +3 -9
  378. package/dist/mcp/server.js +5 -16
  379. package/dist/mcp/session-state.d.ts +1 -1
  380. package/dist/mcp/session-state.js +5 -11
  381. package/dist/mcp/stdio.d.ts +2 -6
  382. package/dist/mcp/stdio.js +48 -12
  383. package/dist/mcp/tools.js +5 -3
  384. package/dist/objects/customer-notes.d.ts +7 -42
  385. package/dist/objects/customer-notes.js +7 -48
  386. package/dist/objects/decisions.d.ts +12 -50
  387. package/dist/objects/decisions.js +15 -53
  388. package/dist/objects/incidents.d.ts +7 -38
  389. package/dist/objects/incidents.js +7 -41
  390. package/dist/objects/policies.d.ts +11 -89
  391. package/dist/objects/policies.js +11 -98
  392. package/dist/objects/processes.d.ts +7 -52
  393. package/dist/objects/processes.js +7 -61
  394. package/dist/objects/project-briefs.d.ts +11 -55
  395. package/dist/objects/project-briefs.js +14 -75
  396. package/dist/objects/skills.d.ts +7 -42
  397. package/dist/objects/skills.js +8 -54
  398. package/dist/postinstall.js +6 -19
  399. package/dist/predictions/planning-fallacy.d.ts +11 -34
  400. package/dist/rerankers/clef.js +3 -31
  401. package/dist/rerankers/cross-encoder.js +4 -6
  402. package/dist/rerankers/jev.js +9 -6
  403. package/dist/rerankers/llm.d.ts +2 -11
  404. package/dist/rerankers/llm.js +14 -14
  405. package/dist/rerankers/outage-warning.d.ts +2 -1
  406. package/dist/rerankers/outage-warning.js +2 -1
  407. package/dist/rerankers/remote.d.ts +1 -0
  408. package/dist/rerankers/remote.js +2 -0
  409. package/dist/rerankers/types.d.ts +2 -14
  410. package/dist/search/boosts.d.ts +0 -2
  411. package/dist/search/boosts.js +2 -2
  412. package/dist/search/goal-boost.d.ts +23 -0
  413. package/dist/search/goal-boost.js +90 -0
  414. package/dist/search/hybrid.d.ts +2 -0
  415. package/dist/search/multihop.js +2 -3
  416. package/dist/search/path-context.d.ts +5 -18
  417. package/dist/search/path-context.js +5 -18
  418. package/dist/search/physics-search.js +11 -8
  419. package/dist/search/rrf.d.ts +7 -35
  420. package/dist/search/rrf.js +5 -30
  421. package/dist/search/vector.d.ts +7 -0
  422. package/dist/search/vector.js +35 -5
  423. package/dist/server/auth.d.ts +9 -28
  424. package/dist/server/auth.js +32 -25
  425. package/dist/server/boot.d.ts +2 -21
  426. package/dist/server/boot.js +63 -96
  427. package/dist/server/client-ip.d.ts +3 -19
  428. package/dist/server/client-ip.js +5 -28
  429. package/dist/server/defaults.d.ts +3 -0
  430. package/dist/server/defaults.js +4 -0
  431. package/dist/server/key-check-bounds.d.ts +2 -1
  432. package/dist/server/lifecycle.d.ts +5 -4
  433. package/dist/server/lifecycle.js +19 -4
  434. package/dist/server/mcp-http.js +10 -44
  435. package/dist/server/rate-limit.d.ts +5 -18
  436. package/dist/server/rate-limit.js +4 -13
  437. package/dist/server/request.d.ts +4 -8
  438. package/dist/server/request.js +9 -17
  439. package/dist/server/route-table.js +42 -49
  440. package/dist/server/routes/admin.js +22 -28
  441. package/dist/server/routes/customer-notes.js +7 -12
  442. package/dist/server/routes/decisions.js +10 -17
  443. package/dist/server/routes/incidents.js +12 -20
  444. package/dist/server/routes/memories.js +12 -32
  445. package/dist/server/routes/object-routes.d.ts +0 -5
  446. package/dist/server/routes/object-routes.js +7 -15
  447. package/dist/server/routes/policies.js +10 -18
  448. package/dist/server/routes/predictions.js +13 -25
  449. package/dist/server/routes/processes.js +16 -26
  450. package/dist/server/routes/project-briefs.js +9 -16
  451. package/dist/server/routes/recall.js +10 -35
  452. package/dist/server/routes/skills.js +8 -18
  453. package/dist/server/server-detect.d.ts +9 -53
  454. package/dist/server/server-detect.js +24 -90
  455. package/dist/server/sleep-offload.js +4 -1
  456. package/dist/server/types.d.ts +12 -10
  457. package/dist/server/validation.d.ts +3 -1
  458. package/dist/server/validation.js +10 -23
  459. package/dist/server.d.ts +2 -2
  460. package/dist/server.js +3 -2
  461. package/dist/sharing/global-store.d.ts +19 -0
  462. package/dist/sharing/global-store.js +75 -0
  463. package/dist/sharing/global-sync.d.ts +6 -0
  464. package/dist/sharing/global-sync.js +80 -0
  465. package/dist/sharing/project-merge.d.ts +4 -5
  466. package/dist/sharing/project-merge.js +9 -7
  467. package/dist/sharing/scope.d.ts +4 -11
  468. package/dist/sharing/scope.js +4 -11
  469. package/dist/sharing/search-both.d.ts +60 -0
  470. package/dist/sharing/search-both.js +138 -0
  471. package/dist/sharing/share.d.ts +38 -0
  472. package/dist/sharing/share.js +226 -0
  473. package/dist/store/ambient.js +4 -9
  474. package/dist/store/audit-event.d.ts +4 -12
  475. package/dist/store/audit-event.js +4 -12
  476. package/dist/store/audit.d.ts +2 -5
  477. package/dist/store/audit.js +4 -12
  478. package/dist/store/auth.d.ts +6 -6
  479. package/dist/store/auth.js +10 -9
  480. package/dist/store/candidates.d.ts +20 -3
  481. package/dist/store/candidates.js +77 -48
  482. package/dist/store/card-detail.d.ts +2 -1
  483. package/dist/store/card-detail.js +2 -1
  484. package/dist/store/cards.d.ts +14 -9
  485. package/dist/store/cards.js +72 -126
  486. package/dist/store/conflicts.d.ts +4 -21
  487. package/dist/store/conflicts.js +71 -150
  488. package/dist/store/connectors/github.d.ts +10 -10
  489. package/dist/store/connectors/github.js +10 -10
  490. package/dist/store/dashboard-reads.js +4 -8
  491. package/dist/store/delete-and-batch.d.ts +11 -31
  492. package/dist/store/delete-and-batch.js +48 -64
  493. package/dist/store/delivery-recorder.d.ts +8 -4
  494. package/dist/store/delivery-recorder.js +25 -15
  495. package/dist/store/diagnostics.js +6 -13
  496. package/dist/store/dormant.d.ts +7 -29
  497. package/dist/store/dormant.js +15 -56
  498. package/dist/store/embeddings/index.d.ts +11 -80
  499. package/dist/store/embeddings/index.js +71 -207
  500. package/dist/store/embeddings/local.js +15 -32
  501. package/dist/store/embeddings/provider.d.ts +16 -53
  502. package/dist/store/embeddings/provider.js +41 -69
  503. package/dist/store/entry-reads.d.ts +21 -57
  504. package/dist/store/entry-reads.js +65 -126
  505. package/dist/store/entry-row.d.ts +6 -35
  506. package/dist/store/entry-row.js +9 -37
  507. package/dist/store/entry-writes.d.ts +10 -16
  508. package/dist/store/entry-writes.js +17 -35
  509. package/dist/store/goals.d.ts +3 -40
  510. package/dist/store/goals.js +21 -160
  511. package/dist/store/graph-queue.d.ts +6 -22
  512. package/dist/store/graph-queue.js +14 -45
  513. package/dist/store/graph-reads.d.ts +11 -35
  514. package/dist/store/graph-reads.js +20 -58
  515. package/dist/store/graph-rows.d.ts +3 -6
  516. package/dist/store/graph-rows.js +6 -9
  517. package/dist/store/graph-view-rows.d.ts +2 -1
  518. package/dist/store/graph-view-rows.js +2 -1
  519. package/dist/store/graph-writes.d.ts +6 -31
  520. package/dist/store/graph-writes.js +13 -37
  521. package/dist/store/half-life.d.ts +2 -1
  522. package/dist/store/half-life.js +14 -16
  523. package/dist/store/handoffs.d.ts +5 -11
  524. package/dist/store/handoffs.js +16 -34
  525. package/dist/store/index-and-stats.d.ts +6 -19
  526. package/dist/store/index-and-stats.js +34 -82
  527. package/dist/store/markdown.d.ts +2 -6
  528. package/dist/store/markdown.js +21 -20
  529. package/dist/store/mirrors.d.ts +2 -6
  530. package/dist/store/mirrors.js +14 -23
  531. package/dist/store/open.js +6 -13
  532. package/dist/store/planning-fallacy-evidence.d.ts +2 -30
  533. package/dist/store/planning-fallacy-evidence.js +8 -37
  534. package/dist/store/port.d.ts +82 -79
  535. package/dist/store/predictions.d.ts +11 -51
  536. package/dist/store/predictions.js +38 -119
  537. package/dist/{cli → store}/quality-repair.js +15 -31
  538. package/dist/store/raw-archive.d.ts +4 -16
  539. package/dist/store/raw-archive.js +14 -29
  540. package/dist/store/recall-scope.d.ts +19 -79
  541. package/dist/store/recall-scope.js +21 -82
  542. package/dist/store/recall-trace.d.ts +10 -77
  543. package/dist/store/recall-trace.js +19 -95
  544. package/dist/store/rejected-values.js +7 -19
  545. package/dist/store/rejection.d.ts +12 -58
  546. package/dist/store/rejection.js +13 -65
  547. package/dist/store/report-reads.d.ts +6 -0
  548. package/dist/store/report-reads.js +29 -0
  549. package/dist/store/rows.d.ts +9 -19
  550. package/dist/store/rows.js +36 -34
  551. package/dist/store/rule-sql.d.ts +5 -0
  552. package/dist/store/rule-sql.js +37 -0
  553. package/dist/store/search-rows.d.ts +7 -38
  554. package/dist/store/search-rows.js +14 -50
  555. package/dist/store/sessions.d.ts +10 -47
  556. package/dist/store/sessions.js +17 -73
  557. package/dist/store/sqlite/connector-events-group.js +2 -2
  558. package/dist/store/sqlite/entry-writes-group.js +2 -2
  559. package/dist/store/sqlite/error-codec.js +4 -2
  560. package/dist/store/sqlite/executor.d.ts +2 -1
  561. package/dist/store/sqlite/executor.js +2 -1
  562. package/dist/store/sqlite/local.d.ts +3 -3
  563. package/dist/store/sqlite/local.js +1 -0
  564. package/dist/store/sqlite/object-rows.js +6 -3
  565. package/dist/store/sqlite/objects-group.js +4 -2
  566. package/dist/store/sqlite/quarantine-group.js +2 -2
  567. package/dist/store/sqlite/store.d.ts +1 -4
  568. package/dist/store/sqlite/store.js +2 -3
  569. package/dist/store/sqlite/vector-reads-group.js +2 -2
  570. package/dist/store/sqlite/worker-jobs.js +1 -1
  571. package/dist/store/sqlite/worker-ops.d.ts +13 -2
  572. package/dist/store/sqlite/worker-ops.js +13 -2
  573. package/dist/store/sqlite/worker-store.js +5 -2
  574. package/dist/store/summaries.d.ts +10 -62
  575. package/dist/store/summaries.js +34 -146
  576. package/dist/store/summary-dirty.js +1 -1
  577. package/dist/store/tenant-lookup.d.ts +6 -1
  578. package/dist/store/tenant-lookup.js +7 -0
  579. package/dist/store/tenant.d.ts +2 -16
  580. package/dist/store/tenant.js +4 -19
  581. package/dist/store/token-ledger.d.ts +13 -43
  582. package/dist/store/token-ledger.js +19 -50
  583. package/dist/store/usage-reports.js +5 -13
  584. package/dist/store/vector-index.d.ts +46 -0
  585. package/dist/store/vector-index.js +170 -0
  586. package/dist/store/working-memory.d.ts +6 -25
  587. package/dist/store/working-memory.js +18 -52
  588. package/dist/store/yaml.d.ts +1 -5
  589. package/dist/store/yaml.js +2 -6
  590. package/dist/support-bundle.js +7 -5
  591. package/dist/trust/reject-flow.js +1 -3
  592. package/dist/util/anthropic-messages.js +14 -2
  593. package/dist/util/atomic-write.d.ts +2 -1
  594. package/dist/util/atomic-write.js +35 -4
  595. package/dist/util/capped-json.d.ts +6 -0
  596. package/dist/util/capped-json.js +46 -0
  597. package/dist/util/crash-handlers.d.ts +8 -1
  598. package/dist/util/crash-handlers.js +52 -10
  599. package/dist/util/env.d.ts +13 -6
  600. package/dist/util/env.js +14 -7
  601. package/dist/util/home-path.d.ts +2 -1
  602. package/dist/util/home-path.js +4 -2
  603. package/dist/util/http-retry.d.ts +3 -1
  604. package/dist/util/http-retry.js +26 -5
  605. package/dist/util/log.d.ts +3 -2
  606. package/dist/util/log.js +25 -9
  607. package/dist/util/request-scope.d.ts +2 -1
  608. package/dist/util/request-scope.js +2 -1
  609. package/dist/util/secret-detect.d.ts +5 -30
  610. package/dist/util/secret-detect.js +13 -39
  611. package/dist/util/stored-json.d.ts +1 -1
  612. package/dist/util/stored-json.js +1 -1
  613. package/dist/util/token-text.d.ts +1 -4
  614. package/dist/util/token-text.js +1 -4
  615. package/dist/util/transcript-tail.d.ts +2 -0
  616. package/dist/util/transcript-tail.js +24 -23
  617. package/dist/util/version.d.ts +5 -20
  618. package/dist/util/version.js +5 -20
  619. package/extensions/openclaw-plugin/index.ts +1 -1
  620. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  621. package/extensions/openclaw-plugin/package.json +1 -1
  622. package/openclaw.plugin.json +1 -1
  623. package/package.json +1 -1
  624. package/dist/connectors/github/cli-impl.d.ts +0 -25
  625. package/dist/sharing/shared.d.ts +0 -187
  626. package/dist/sharing/shared.js +0 -563
  627. package/dist/store/vector-writes.d.ts +0 -13
  628. package/dist/store/vector-writes.js +0 -89
  629. /package/dist/{cli → store}/quality-repair.d.ts +0 -0
@@ -1,32 +1,22 @@
1
1
  import { closeHippoDb } from '../db/index.js';
2
2
  import { MEMORY_SELECT_COLUMNS, rowToEntry, parseJsonArray } from './rows.js';
3
- import { openStore } from './open.js';
3
+ import { onHandle, openStore } from './open.js';
4
4
  import { escapeLike } from '../util/escape.js';
5
5
  import { originInSql } from '../core/project-identity.js';
6
6
  import { scopeAdmitSql } from './recall-scope.js';
7
7
  const MAX_IDS_PER_READ = 500;
8
8
  // The plus keeps SQLite on the primary key for an id list: with a bare tenant_id it walks every row of the tenant instead.
9
9
  export const TENANT_IS = '+tenant_id = ?';
10
- /**
11
- * Read a memory entry by ID.
12
- *
13
- * When `tenantId` is provided, the read is scoped to that tenant (cross-tenant
14
- * lookups return null). When omitted, no tenant filter is applied — preserves
15
- * legacy single-tenant callers and the writeEntry/readEntry round-trip.
16
- */
10
+ /** Read a memory entry by ID. With `tenantId` the read is tenant-scoped (cross-tenant returns null); omitted, no tenant filter is applied. */
17
11
  export function readEntry(hippoRoot, id, tenantId) {
18
- const db = openStore(hippoRoot);
19
- try {
12
+ return onHandle(hippoRoot, (db) => {
20
13
  // SAFETY: both branches select exactly MEMORY_SELECT_COLUMNS, matching
21
14
  // MemoryRow's field set.
22
15
  const row = tenantId !== undefined
23
16
  ? db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id = ? AND tenant_id = ?`).get(id, tenantId)
24
17
  : db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id = ?`).get(id);
25
18
  return row ? rowToEntry(row) : null;
26
- }
27
- finally {
28
- closeHippoDb(db);
29
- }
19
+ }, openStore);
30
20
  }
31
21
  /** Ids per `IN (...)` list: far under SQLite's bound-parameter limit, with room for the tenant filter. */
32
22
  export const ID_CHUNK = 500;
@@ -41,8 +31,7 @@ export function chunked(items, size = ID_CHUNK) {
41
31
  export function heldIdLookup(hippoRoot, tenantId, ids) {
42
32
  const held = new Map();
43
33
  const lookUp = (asked) => {
44
- const db = openStore(hippoRoot);
45
- try {
34
+ onHandle(hippoRoot, (db) => {
46
35
  for (const chunk of chunked([...new Set(asked)])) {
47
36
  for (const id of chunk)
48
37
  held.set(id, false);
@@ -51,10 +40,7 @@ export function heldIdLookup(hippoRoot, tenantId, ids) {
51
40
  for (const row of rows)
52
41
  held.set(row.id, true);
53
42
  }
54
- }
55
- finally {
56
- closeHippoDb(db);
57
- }
43
+ }, openStore);
58
44
  };
59
45
  if (ids.length > 0)
60
46
  lookUp(ids);
@@ -99,48 +85,30 @@ export function selectChildrenByParent(db, parentIds, tenantId) {
99
85
  }
100
86
  return byParent;
101
87
  }
102
- /**
103
- * Batched lookup. Caps at 500 ids per call to keep the IN(?,?,...) clause
104
- * within SQLite limits. Tenant filter is enforced when `tenantId` is passed.
105
- * Used by DAG-aware recall to fetch parent summaries for a set of overflowed leaves.
106
- */
88
+ /** Batched lookup, capped at 500 ids per call to keep IN(?,?,...) within SQLite limits; tenant filter enforced when `tenantId` is passed. */
107
89
  export function loadEntriesByIds(hippoRoot, ids, tenantId) {
108
90
  if (ids.length === 0)
109
91
  return [];
110
92
  const capped = ids.slice(0, MAX_IDS_PER_READ);
111
- const db = openStore(hippoRoot);
112
- try {
93
+ return onHandle(hippoRoot, (db) => {
113
94
  const placeholders = capped.map(() => '?').join(',');
114
- // Without ORDER BY, rows follow SQLite's IN(...) scan order, which is undefined w.r.t. `ids`.
115
- // SAFETY: both branches select exactly MEMORY_SELECT_COLUMNS, matching
116
- // MemoryRow's field set.
95
+ // Without ORDER BY, rows follow SQLite's IN(...) scan order, undefined w.r.t. `ids`.
96
+ // SAFETY: both branches select exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
117
97
  const rows = tenantId !== undefined
118
98
  ? db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id IN (${placeholders}) AND ${TENANT_IS} ORDER BY created ASC, content ASC, id ASC`).all(...capped, tenantId)
119
99
  : db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id IN (${placeholders}) ORDER BY created ASC, content ASC, id ASC`).all(...capped);
120
100
  return rows.map(rowToEntry);
121
- }
122
- finally {
123
- closeHippoDb(db);
124
- }
101
+ }, openStore);
125
102
  }
126
103
  function originClause(origins) {
127
104
  return origins === undefined ? '' : ` AND (origin_project = '' OR ${originInSql(origins)})`;
128
105
  }
129
- /**
130
- * All `kind='raw'` rows for a given session, tenant-scoped, returned
131
- * oldest-first. Used by `api.assemble` to walk a session's chronological
132
- * context. Excludes superseded rows.
133
- *
134
- * Cap semantics: when `cap` is provided, the NEWEST `cap` rows are loaded (DESC LIMIT server-side,
135
- * reversed client-side); ASC + LIMIT would drop the newest rows and break fresh-tail in assemble.
136
- *
137
- * Returns `[]` for an empty sessionId. Final order: `created ASC, id ASC`.
138
- */
106
+ /** All `kind='raw'` rows for a session, tenant-scoped, oldest-first, excluding superseded; `[]` for an empty sessionId.
107
+ * With `cap`, the NEWEST rows are loaded (DESC LIMIT, reversed client-side); ASC + LIMIT would drop the newest and break fresh-tail in assemble. */
139
108
  export function loadSessionRawMemories(hippoRoot, sessionId, tenantId, cap, origins) {
140
109
  if (!sessionId)
141
110
  return [];
142
- const db = openStore(hippoRoot);
143
- try {
111
+ return onHandle(hippoRoot, (db) => {
144
112
  const params = [];
145
113
  let sql = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE kind = 'raw' AND source_session_id = ? AND superseded_by IS NULL`;
146
114
  params.push(sessionId);
@@ -161,29 +129,14 @@ export function loadSessionRawMemories(hippoRoot, sessionId, tenantId, cap, orig
161
129
  // SAFETY: sql starts from MEMORY_SELECT_COLUMNS, matching MemoryRow.
162
130
  const rows = db.prepare(sql).all(...params);
163
131
  return rows.map(rowToEntry);
164
- }
165
- finally {
166
- closeHippoDb(db);
167
- }
132
+ }, openStore);
168
133
  }
169
- /**
170
- * Pre-cap, scope-aware row count for a session. Lets `assemble` report
171
- * the full session size even when `rowCap` truncates the loaded window,
172
- * WITHOUT leaking rows the caller wouldn't have been allowed to load.
173
- *
174
- * An unscoped COUNT would let a no-scope caller infer private rows by comparing `totalRaw`
175
- * against `items.length`, so this SQL-encodes the default-deny rule `passesScopeFilterForRecall` applies in TS:
176
- * - explicit scope passed: exact-match
177
- * - no scope: `scopeAdmitSql`'s default deny, which admits `ownScope`, the caller's personal scope.
178
- *
179
- * `tenantId` is optional for back-compat. Pass `undefined` only when
180
- * intentionally counting cross-tenant; `assemble()` passes `ctx.tenantId`.
181
- */
134
+ /** Pre-cap, scope-aware row count for a session, so `assemble` reports the full size without leaking rows the caller could not load. Mirrors
135
+ * `passesScopeFilterForRecall`'s default-deny: explicit scope matches exactly, none admits only `ownScope`. `tenantId` undefined counts cross-tenant. */
182
136
  export function countSessionRawMemories(hippoRoot, sessionId, tenantId, scope, ownScope, origins) {
183
137
  if (!sessionId)
184
138
  return 0;
185
- const db = openStore(hippoRoot);
186
- try {
139
+ return onHandle(hippoRoot, (db) => {
187
140
  const params = [];
188
141
  let sql = `SELECT COUNT(*) AS c FROM memories WHERE kind = 'raw' AND source_session_id = ? AND superseded_by IS NULL`;
189
142
  params.push(sessionId);
@@ -205,31 +158,15 @@ export function countSessionRawMemories(hippoRoot, sessionId, tenantId, scope, o
205
158
  // SAFETY: row's shape matches the single `COUNT(*) AS c` column above.
206
159
  const row = db.prepare(sql).get(...params);
207
160
  return Number(row?.c ?? 0);
208
- }
209
- finally {
210
- closeHippoDb(db);
211
- }
161
+ }, openStore);
212
162
  }
213
- /**
214
- * Last N kind='raw' memories by `created` desc. Tenant scoped. When
215
- * `sessionId` is supplied, also constrains to a specific session — that
216
- * is the correct shape for "what did I just see in THIS session."
217
- *
218
- * Without `sessionId`, concurrent sessions in a tenant surface each other's rows as fresh tail;
219
- * pass undefined only for "anything new across the whole tenant".
220
- *
221
- * Bounded count cap at 200 — beyond that the caller should filter via
222
- * tags/scope rather than time-windowed recall.
223
- *
224
- * The tenant-wide shape is the back-compat default but discouraged; `api.recall` throws
225
- * `RecallContractError` for it when `HIPPO_REQUIRE_SESSION_SCOPED_FRESH_TAIL=1` is set.
226
- */
163
+ /** Last N kind='raw' memories by `created` desc, tenant-scoped, max 200; pass `sessionId` or concurrent sessions show up in each other's fresh tail.
164
+ * The tenant-wide shape is discouraged: `api.recall` throws `RecallContractError` for it when `HIPPO_REQUIRE_SESSION_SCOPED_FRESH_TAIL=1`. */
227
165
  export function loadFreshRawMemories(hippoRoot, count, tenantId, sessionId, origins) {
228
166
  if (count <= 0)
229
167
  return [];
230
168
  const capped = Math.min(count, 200);
231
- const db = openStore(hippoRoot);
232
- try {
169
+ return onHandle(hippoRoot, (db) => {
233
170
  const params = [];
234
171
  let sql = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE kind = 'raw' AND superseded_by IS NULL`;
235
172
  if (tenantId !== undefined) {
@@ -249,35 +186,52 @@ export function loadFreshRawMemories(hippoRoot, count, tenantId, sessionId, orig
249
186
  // SAFETY: sql starts from MEMORY_SELECT_COLUMNS, matching MemoryRow.
250
187
  const rows = db.prepare(sql).all(...params);
251
188
  return rows.map(rowToEntry);
252
- }
253
- finally {
254
- closeHippoDb(db);
255
- }
189
+ }, openStore);
256
190
  }
257
- /**
258
- * Load all entries from SQLite.
259
- *
260
- * When `tenantId` is provided, results are scoped to that tenant. Omitting it
261
- * yields all rows (legacy behavior used by consolidate/autolearn etc.). Recall
262
- * paths that surface results to a user MUST pass a resolved tenant.
263
- */
191
+ /** Load all entries from SQLite; omitting `tenantId` yields all rows (legacy). Recall paths that surface results to a user MUST pass a resolved tenant. */
264
192
  export function loadAllEntries(hippoRoot, tenantId) {
193
+ return onHandle(hippoRoot, (db) => {
194
+ return selectAllEntries(db, tenantId);
195
+ }, openStore);
196
+ }
197
+ /** Every tenant's memory ids in loadAllEntries' order, for a caller that reads the rows a page at a time instead of holding them all. */
198
+ export function loadAllEntryIds(hippoRoot) {
199
+ return onHandle(hippoRoot, (db) => {
200
+ // SAFETY: the SELECT names exactly the one column read.
201
+ return db.prepare('SELECT id FROM memories ORDER BY created ASC, id ASC').all().map((row) => row.id);
202
+ }, openStore);
203
+ }
204
+ /** Every entry plus a by-id lookup of each as loaded, rebuilt from its row on first use, so no deep copy of the store is kept. */
205
+ export function loadAllEntriesWithBase(hippoRoot) {
265
206
  const db = openStore(hippoRoot);
207
+ let rows;
266
208
  try {
267
- return selectAllEntries(db, tenantId);
209
+ rows = selectAllRows(db);
268
210
  }
269
211
  finally {
270
212
  closeHippoDb(db);
271
213
  }
214
+ const byId = new Map(rows.map((row) => [row.id, row]));
215
+ const built = new Map();
216
+ const get = (id) => {
217
+ let entry = built.get(id);
218
+ const row = byId.get(id);
219
+ if (!entry && row)
220
+ built.set(id, (entry = rowToEntry(row)));
221
+ return entry;
222
+ };
223
+ return { entries: rows.map(rowToEntry), base: { get } };
272
224
  }
273
- /** Every memory row on an open connection, so a caller can read inside its own transaction. */
274
- export function selectAllEntries(db, tenantId) {
225
+ function selectAllRows(db, tenantId) {
275
226
  // SAFETY: both branches select exactly MEMORY_SELECT_COLUMNS, matching
276
227
  // MemoryRow's field set.
277
- const rows = tenantId !== undefined
228
+ return tenantId !== undefined
278
229
  ? db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE tenant_id = ? ORDER BY created ASC, id ASC`).all(tenantId)
279
230
  : db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories ORDER BY created ASC, id ASC`).all();
280
- return rows.map(rowToEntry);
231
+ }
232
+ /** Every memory row on an open connection, so a caller can read inside its own transaction. */
233
+ export function selectAllEntries(db, tenantId) {
234
+ return selectAllRows(db, tenantId).map(rowToEntry);
281
235
  }
282
236
  /** Live rows whose source starts with `prefix`, on the caller's handle; LIKE folds case, so the prefix is checked again exactly. */
283
237
  export function selectLiveEntriesBySourcePrefix(db, tenantId, prefix) {
@@ -288,32 +242,24 @@ export function selectLiveEntriesBySourcePrefix(db, tenantId, prefix) {
288
242
  // Content of every team-visible tenant row tagged `tag`, without reading the rest of the store; `origins` keeps one project's rows and user-global ones.
289
243
  // No owner: a personal or connector-private row must never answer `duplicate` for, or stop, a team copy. `instr` prefilters; `includes` re-checks.
290
244
  export function loadContentsWithTag(hippoRoot, tenantId, tag, origins) {
291
- const db = openStore(hippoRoot);
292
- try {
245
+ return onHandle(hippoRoot, (db) => {
293
246
  const inProject = origins === undefined ? '' : ` AND (origin_project = '' OR ${originInSql(origins)})`;
294
247
  const admit = scopeAdmitSql('');
295
248
  /** SAFETY: rows' shape matches the two columns named in the SELECT below. */
296
249
  const rows = db.prepare(`SELECT content, tags_json FROM memories WHERE tenant_id = ? AND instr(tags_json, ?) > 0${inProject} AND ${admit.sql}`).all(tenantId, JSON.stringify(tag), ...(origins ?? []), ...admit.params);
297
250
  return rows.filter((r) => parseJsonArray(r.tags_json).includes(tag)).map((r) => r.content);
298
- }
299
- finally {
300
- closeHippoDb(db);
301
- }
251
+ }, openStore);
302
252
  }
303
253
  /** Live raw rows whose artifact_ref matches a LIKE pattern, for one tenant; the store is set up first when it is new. */
304
254
  export function loadVaultRawRows(hippoRoot, likeParam, tenantId) {
305
- const db = openStore(hippoRoot);
306
- try {
255
+ return onHandle(hippoRoot, (db) => {
307
256
  // SAFETY: query selects exactly the columns of VaultRawRow, in the same
308
257
  // names, from the memories table this module owns.
309
258
  return db
310
259
  .prepare(`SELECT id, artifact_ref, tags_json, scope FROM memories
311
260
  WHERE artifact_ref LIKE ? ESCAPE '\\' AND tenant_id = ? AND kind = 'raw'`)
312
261
  .all(likeParam, tenantId);
313
- }
314
- finally {
315
- closeHippoDb(db);
316
- }
262
+ }, openStore);
317
263
  }
318
264
  /** Reads memories from a store whose schema may predate some columns; `columns` is the table's real column set. */
319
265
  export function selectPreviewRows(db, columns, tenantId) {
@@ -352,10 +298,10 @@ export function selectRowsOutsideSourcePrefixAt(db, tenantId, sourcePrefix, orig
352
298
  return db.prepare(`SELECT id, content, source FROM memories
353
299
  WHERE tenant_id = ? AND superseded_by IS NULL AND substr(source, 1, ${sourcePrefix.length}) != ?${visible}`).all(...params);
354
300
  }
355
- /** Content of a tenant's live rows written by `source` and tagged `tag` that no extraction produced, in loadAllEntries' order and in every scope; `exceptSessionId` drops one session's own rows. */
301
+ /** Content of a tenant's live rows written by `source` and tagged `tag` that no extraction produced,
302
+ * in loadAllEntries' order and in every scope; `exceptSessionId` drops one session's own rows. */
356
303
  export function loadLiveContentsBySourceAndTag(hippoRoot, tenantId, source, tag, exceptSessionId) {
357
- const db = openStore(hippoRoot);
358
- try {
304
+ return onHandle(hippoRoot, (db) => {
359
305
  /** SAFETY: rows' shape matches the two columns named in the SELECT below. */
360
306
  const rows = db.prepare(`SELECT content, tags_json FROM memories
361
307
  WHERE tenant_id = ? AND source = ? AND instr(tags_json, ?) > 0
@@ -363,23 +309,16 @@ export function loadLiveContentsBySourceAndTag(hippoRoot, tenantId, source, tag,
363
309
  AND (source_session_id IS NULL OR source_session_id != ?)
364
310
  ORDER BY created ASC, id ASC`).all(tenantId, source, JSON.stringify(tag), exceptSessionId);
365
311
  return rows.filter((r) => parseJsonArray(r.tags_json).includes(tag)).map((r) => r.content);
366
- }
367
- finally {
368
- closeHippoDb(db);
369
- }
312
+ }, openStore);
370
313
  }
371
314
  /** Every tenant's distilled rows nothing has superseded, in loadAllEntries' order: the rows that can be each other's duplicate. */
372
315
  export function loadCurrentDistilledEntries(hippoRoot) {
373
- const db = openStore(hippoRoot);
374
- try {
316
+ return onHandle(hippoRoot, (db) => {
375
317
  // SAFETY: selects exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
376
318
  const rows = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories
377
319
  WHERE COALESCE(kind, 'distilled') = 'distilled' AND COALESCE(superseded_by, '') = ''
378
320
  ORDER BY created ASC, id ASC`).all();
379
321
  return rows.map(rowToEntry);
380
- }
381
- finally {
382
- closeHippoDb(db);
383
- }
322
+ }, openStore);
384
323
  }
385
324
  //# sourceMappingURL=entry-reads.js.map
@@ -1,7 +1,8 @@
1
1
  import type { MemoryEntry } from '../core/memory.js';
2
2
  import { openHippoDb } from '../db/index.js';
3
3
  export declare function upsertEntryRow(db: ReturnType<typeof openHippoDb>, entry: MemoryEntry): void;
4
- /** The row alone, with no rejection guard or full-text row, for `upsertEntryRow` and for `batchWriteAndDelete`, which probes tombstones and indexes per batch. Returns whether the row is new. */
4
+ /** The row alone, with no rejection guard or full-text row, for `upsertEntryRow` and for
5
+ * `batchWriteAndDelete`, which probes tombstones and indexes per batch. Returns whether the row is new. */
5
6
  export declare function upsertMemoryRow(db: ReturnType<typeof openHippoDb>, entry: MemoryEntry): boolean;
6
7
  export declare function syncFtsRow(db: ReturnType<typeof openHippoDb>, entry: MemoryEntry, isNewRow?: boolean): void;
7
8
  export declare function ftsRowExists(db: ReturnType<typeof openHippoDb>, id: string): boolean;
@@ -13,40 +14,10 @@ export declare function ftsDrift(hippoRoot: string, repair: boolean): {
13
14
  memories: number;
14
15
  fts: number;
15
16
  } | null;
16
- /**
17
- * Write a memory entry to SQLite and refresh compatibility mirrors.
18
- *
19
- * `opts.actor` defaults to 'cli' so unauthenticated direct-CLI callers still
20
- * get the right audit attribution. The HTTP server and api.* layer pass
21
- * the resolved actor (`api_key:<key_id>` / `localhost:cli`) so audit events
22
- * land with one row per write, no double-emit.
23
- *
24
- * `opts.afterWrite` is invoked inside the same SAVEPOINT as the memories
25
- * INSERT (mirrors archiveRawMemory's shape in raw-archive.ts). On callback
26
- * throw, the SAVEPOINT rolls back — the memory row never lands, and the
27
- * filesystem mirrors / audit emit never run. Used by connectors to
28
- * stamp idempotency rows atomically with the memory write.
29
- */
30
- /**
31
- * Stamp origin_project from the store's own location when the entry has
32
- * never been stamped (v39 memory scope isolation). The store dir is
33
- * `<project>/.hippo`, so its parent resolves to the owning project; the
34
- * home/global store resolves to '' (user-global). Callers that know a better
35
- * origin (shareMemory, syncGlobalToLocal) set entry.origin_project before
36
- * writing and this is a no-op. Returns a stamped copy; never mutates.
37
- *
38
- * NULL is PRESERVED, not re-stamped: it means no known project (a legacy row with no evidence, or a write to a
39
- * shared store that named none) and ambient context denies it, so a writeback must not launder it.
40
- */
17
+ /** Stamp origin_project from the store's own location (parent of `<project>/.hippo`; the home store is '' = user-global) when never stamped; returns a copy.
18
+ * NULL is PRESERVED: it means no known project and ambient context denies it, so a writeback must not launder it. */
41
19
  export declare function stampOriginProject(hippoRoot: string, entry: MemoryEntry): MemoryEntry;
42
- /**
43
- * Import-time variant for a mirror with no origin field (an explicit null stays null): used only where evidence exists
44
- * for rows that predate the origin column - the legacy-markdown bootstrap and
45
- * rebuildIndex import, which are the markdown-store equivalent of the v39 SQL
46
- * backfill. Same evidence order as the migration: the provenance source
47
- * (`shared:<project>:` / `promoted:<localRoot>`) wins over the destination
48
- * store's location, so a shared row imported into the global store keeps its
49
- * owning project instead of becoming user-global.
50
- */
20
+ /** Import-time variant for a mirror with no origin field (an explicit null stays null), for rows predating the origin column.
21
+ * Like the v39 backfill, the provenance source (`shared:<project>:` / `promoted:<localRoot>`) wins over the destination store's location. */
51
22
  export declare function stampOriginProjectForImport(hippoRoot: string, entry: MemoryEntry): MemoryEntry;
52
23
  //# sourceMappingURL=entry-row.d.ts.map
@@ -1,12 +1,14 @@
1
+ import { DEFAULT_TENANT_ID } from '../util/env.js';
1
2
  import { closeHippoDb, ftsRowCounts, openHippoDb, isFtsAvailable, repairFtsDrift } from '../db/index.js';
2
3
  import { fallbackOrigin, originFromSource } from '../core/project-identity.js';
3
4
  import { checkRejectionGuard } from './rejection.js';
4
5
  import { errorMessage, log } from '../util/log.js';
5
6
  export function upsertEntryRow(db, entry) {
6
- checkRejectionGuard(db, entry.tenantId ?? 'default', entry.id, entry.content);
7
+ checkRejectionGuard(db, entry.tenantId ?? DEFAULT_TENANT_ID, entry.id, entry.content);
7
8
  syncFtsRow(db, entry, upsertMemoryRow(db, entry));
8
9
  }
9
- /** The row alone, with no rejection guard or full-text row, for `upsertEntryRow` and for `batchWriteAndDelete`, which probes tombstones and indexes per batch. Returns whether the row is new. */
10
+ /** The row alone, with no rejection guard or full-text row, for `upsertEntryRow` and for
11
+ * `batchWriteAndDelete`, which probes tombstones and indexes per batch. Returns whether the row is new. */
10
12
  export function upsertMemoryRow(db, entry) {
11
13
  const isNewRow = db.prepare(`SELECT 1 FROM memories WHERE id = ?`).get(entry.id) === undefined;
12
14
  db.prepare(UPSERT_MEMORY_SQL).run(...memoryRowValues(entry));
@@ -102,7 +104,7 @@ function memoryRowValues(entry) {
102
104
  entry.scope ?? null,
103
105
  entry.owner ?? null,
104
106
  entry.artifact_ref ?? null,
105
- entry.tenantId ?? 'default',
107
+ entry.tenantId ?? DEFAULT_TENANT_ID,
106
108
  entry.origin_project ?? null,
107
109
  entry.descendant_count ?? 0,
108
110
  entry.earliest_at ?? null,
@@ -181,45 +183,15 @@ export function ftsDrift(hippoRoot, repair) {
181
183
  closeHippoDb(db);
182
184
  }
183
185
  }
184
- /**
185
- * Write a memory entry to SQLite and refresh compatibility mirrors.
186
- *
187
- * `opts.actor` defaults to 'cli' so unauthenticated direct-CLI callers still
188
- * get the right audit attribution. The HTTP server and api.* layer pass
189
- * the resolved actor (`api_key:<key_id>` / `localhost:cli`) so audit events
190
- * land with one row per write, no double-emit.
191
- *
192
- * `opts.afterWrite` is invoked inside the same SAVEPOINT as the memories
193
- * INSERT (mirrors archiveRawMemory's shape in raw-archive.ts). On callback
194
- * throw, the SAVEPOINT rolls back — the memory row never lands, and the
195
- * filesystem mirrors / audit emit never run. Used by connectors to
196
- * stamp idempotency rows atomically with the memory write.
197
- */
198
- /**
199
- * Stamp origin_project from the store's own location when the entry has
200
- * never been stamped (v39 memory scope isolation). The store dir is
201
- * `<project>/.hippo`, so its parent resolves to the owning project; the
202
- * home/global store resolves to '' (user-global). Callers that know a better
203
- * origin (shareMemory, syncGlobalToLocal) set entry.origin_project before
204
- * writing and this is a no-op. Returns a stamped copy; never mutates.
205
- *
206
- * NULL is PRESERVED, not re-stamped: it means no known project (a legacy row with no evidence, or a write to a
207
- * shared store that named none) and ambient context denies it, so a writeback must not launder it.
208
- */
186
+ /** Stamp origin_project from the store's own location (parent of `<project>/.hippo`; the home store is '' = user-global) when never stamped; returns a copy.
187
+ * NULL is PRESERVED: it means no known project and ambient context denies it, so a writeback must not launder it. */
209
188
  export function stampOriginProject(hippoRoot, entry) {
210
189
  if (entry.origin_project !== undefined)
211
190
  return entry;
212
191
  return { ...entry, origin_project: fallbackOrigin(hippoRoot) };
213
192
  }
214
- /**
215
- * Import-time variant for a mirror with no origin field (an explicit null stays null): used only where evidence exists
216
- * for rows that predate the origin column - the legacy-markdown bootstrap and
217
- * rebuildIndex import, which are the markdown-store equivalent of the v39 SQL
218
- * backfill. Same evidence order as the migration: the provenance source
219
- * (`shared:<project>:` / `promoted:<localRoot>`) wins over the destination
220
- * store's location, so a shared row imported into the global store keeps its
221
- * owning project instead of becoming user-global.
222
- */
193
+ /** Import-time variant for a mirror with no origin field (an explicit null stays null), for rows predating the origin column.
194
+ * Like the v39 backfill, the provenance source (`shared:<project>:` / `promoted:<localRoot>`) wins over the destination store's location. */
223
195
  export function stampOriginProjectForImport(hippoRoot, entry) {
224
196
  if (entry.origin_project !== undefined)
225
197
  return entry;
@@ -6,26 +6,20 @@ export interface WriteEntryOptions {
6
6
  /** Runs after the row commits and before the mirrors, on an idle connection; keep it best-effort. */
7
7
  afterCommit?: () => void;
8
8
  }
9
+ /** Write an entry to SQLite and refresh mirrors; `opts.afterWrite` runs in the same SAVEPOINT as the INSERT, so a throw rolls the row back.
10
+ * `opts.actor` defaults to 'cli'; the api layer passes the resolved actor so the audit log gets one row per write. */
9
11
  export declare function writeEntry(hippoRoot: string, entry: MemoryEntry, opts?: WriteEntryOptions): void;
10
- /** writeEntry for each of `entries` in one transaction, so all land or none; each keeps its audit row, and mirrors follow the commit. Returns how many were written. */
12
+ /** writeEntry for each of `entries` in one transaction, so all land or none; each
13
+ * keeps its audit row, and mirrors follow the commit. Returns how many were written. */
11
14
  export declare function writeEntriesTogether(hippoRoot: string, entries: readonly MemoryEntry[]): number;
12
- /** writeEntry for each of `entries` on one open store, so the open and its lock wait are paid once; each row commits alone, and none opens the store when the list is empty. */
15
+ /** writeEntry for each of `entries` on one open store, so the open and its lock wait are
16
+ * paid once; each row commits alone, and none opens the store when the list is empty. */
13
17
  export declare function writeEntriesSeparately(hippoRoot: string, entries: readonly MemoryEntry[]): void;
14
- /** Adds `tag` to each of a tenant's rows that lacks it, in `ids` order, each read fresh on one open store and committed alone; an id the tenant does not hold is skipped. */
18
+ /** Adds `tag` to each of a tenant's rows that lacks it, in `ids` order, each read fresh
19
+ * on one open store and committed alone; an id the tenant does not hold is skipped. */
15
20
  export declare function addTagToEntries(hippoRoot: string, tenantId: string, ids: readonly string[], tag: string): void;
16
- /**
17
- * DB-only write path. Caller owns the open `db` handle. Runs upsert +
18
- * afterWrite hook + audit row inside one withWriteScope. Caller
19
- * is responsible for opening `db`, optionally wrapping in a larger BEGIN/
20
- * COMMIT (e.g. supersede's BEGIN IMMEDIATE), closing `db`, AND calling
21
- * `writeEntryMirrors` after the larger tx commits — mirrors must run
22
- * post-commit so a rolled-back tx never leaves orphan markdown.
23
- *
24
- * Audit-order note: the audit row is emitted INSIDE the write scope, so audit
25
- * commits atomically with the row INSERT. A subsequent mirror failure cannot
26
- * leave a recorded audit entry without its corresponding DB row. This is a
27
- * documented hardening over the prior writeEntry-as-monolith ordering.
28
- */
21
+ /** DB-only write path: upsert, afterWrite hook and audit row inside one withWriteScope; the caller owns `db` and must call `writeEntryMirrors` after any
22
+ * outer tx commits, so a rolled-back tx never leaves orphan markdown. The audit row commits atomically with the INSERT. */
29
23
  export declare function writeEntryDbOnly(db: DatabaseSyncLike, entry: MemoryEntry, opts?: {
30
24
  actor?: string;
31
25
  afterWrite?: (db: DatabaseSyncLike, memoryId: string) => void;
@@ -7,17 +7,16 @@ import { auditRejectionRefusal, audit } from './audit-event.js';
7
7
  import { selectEntriesByIds } from './entry-reads.js';
8
8
  import { stampOriginProject, upsertEntryRow, syncFtsRow, deleteFtsRow } from './entry-row.js';
9
9
  import { mirrorBestEffort, writeMarkdownMirror } from './mirrors.js';
10
- import { openStore } from './open.js';
10
+ import { onHandle, openStore } from './open.js';
11
+ /** Write an entry to SQLite and refresh mirrors; `opts.afterWrite` runs in the same SAVEPOINT as the INSERT, so a throw rolls the row back.
12
+ * `opts.actor` defaults to 'cli'; the api layer passes the resolved actor so the audit log gets one row per write. */
11
13
  export function writeEntry(hippoRoot, entry, opts) {
12
- const db = openStore(hippoRoot);
13
- try {
14
+ onHandle(hippoRoot, (db) => {
14
15
  writeEntryOn(db, hippoRoot, entry, opts);
15
- }
16
- finally {
17
- closeHippoDb(db);
18
- }
16
+ }, openStore);
19
17
  }
20
- /** writeEntry for each of `entries` in one transaction, so all land or none; each keeps its audit row, and mirrors follow the commit. Returns how many were written. */
18
+ /** writeEntry for each of `entries` in one transaction, so all land or none; each
19
+ * keeps its audit row, and mirrors follow the commit. Returns how many were written. */
21
20
  export function writeEntriesTogether(hippoRoot, entries) {
22
21
  const stamped = entries.map((entry) => stampOriginProject(hippoRoot, entry));
23
22
  const db = openStore(hippoRoot);
@@ -40,23 +39,20 @@ export function writeEntriesTogether(hippoRoot, entries) {
40
39
  }
41
40
  return stamped.length;
42
41
  }
43
- /** writeEntry for each of `entries` on one open store, so the open and its lock wait are paid once; each row commits alone, and none opens the store when the list is empty. */
42
+ /** writeEntry for each of `entries` on one open store, so the open and its lock wait are
43
+ * paid once; each row commits alone, and none opens the store when the list is empty. */
44
44
  export function writeEntriesSeparately(hippoRoot, entries) {
45
45
  if (entries.length === 0)
46
46
  return;
47
- const db = openStore(hippoRoot);
48
- try {
47
+ onHandle(hippoRoot, (db) => {
49
48
  for (const entry of entries)
50
49
  writeEntryOn(db, hippoRoot, entry);
51
- }
52
- finally {
53
- closeHippoDb(db);
54
- }
50
+ }, openStore);
55
51
  }
56
- /** Adds `tag` to each of a tenant's rows that lacks it, in `ids` order, each read fresh on one open store and committed alone; an id the tenant does not hold is skipped. */
52
+ /** Adds `tag` to each of a tenant's rows that lacks it, in `ids` order, each read fresh
53
+ * on one open store and committed alone; an id the tenant does not hold is skipped. */
57
54
  export function addTagToEntries(hippoRoot, tenantId, ids, tag) {
58
- const db = openStore(hippoRoot);
59
- try {
55
+ onHandle(hippoRoot, (db) => {
60
56
  const live = selectEntriesByIds(db, ids, tenantId);
61
57
  for (const id of new Set(ids)) {
62
58
  const entry = live.get(id);
@@ -64,10 +60,7 @@ export function addTagToEntries(hippoRoot, tenantId, ids, tag) {
64
60
  continue;
65
61
  writeEntryOn(db, hippoRoot, { ...entry, tags: [...entry.tags, tag] });
66
62
  }
67
- }
68
- finally {
69
- closeHippoDb(db);
70
- }
63
+ }, openStore);
71
64
  }
72
65
  /** writeEntry on the caller's open store, so a loop of writes opens the store once; each row still commits alone. */
73
66
  function writeEntryOn(db, hippoRoot, entry, opts) {
@@ -86,19 +79,8 @@ function writeEntryOn(db, hippoRoot, entry, opts) {
86
79
  throw error;
87
80
  }
88
81
  }
89
- /**
90
- * DB-only write path. Caller owns the open `db` handle. Runs upsert +
91
- * afterWrite hook + audit row inside one withWriteScope. Caller
92
- * is responsible for opening `db`, optionally wrapping in a larger BEGIN/
93
- * COMMIT (e.g. supersede's BEGIN IMMEDIATE), closing `db`, AND calling
94
- * `writeEntryMirrors` after the larger tx commits — mirrors must run
95
- * post-commit so a rolled-back tx never leaves orphan markdown.
96
- *
97
- * Audit-order note: the audit row is emitted INSIDE the write scope, so audit
98
- * commits atomically with the row INSERT. A subsequent mirror failure cannot
99
- * leave a recorded audit entry without its corresponding DB row. This is a
100
- * documented hardening over the prior writeEntry-as-monolith ordering.
101
- */
82
+ /** DB-only write path: upsert, afterWrite hook and audit row inside one withWriteScope; the caller owns `db` and must call `writeEntryMirrors` after any
83
+ * outer tx commits, so a rolled-back tx never leaves orphan markdown. The audit row commits atomically with the INSERT. */
102
84
  export function writeEntryDbOnly(db, entry, opts) {
103
85
  // Inside a caller's transaction (e.g. supersede's BEGIN IMMEDIATE) the scope is a SAVEPOINT,
104
86
  // so a throw here rolls back only this write and leaves the outer open.