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,13 +1,12 @@
1
1
  // The graph reads a view and a traversal share. Each opens hippo.db itself unless the caller hands it the handle its snapshot runs on.
2
2
  import { openHippoDb, closeHippoDb, withReadSnapshot } from '../db/index.js';
3
+ import { onHandle } from './open.js';
3
4
  import { assertTenantId } from './tenant.js';
4
5
  import { GRAPH_ENTITY_TYPES, rowToEntity, rowToRelation, ENTITY_COLS, RELATION_COLS } from './graph-rows.js';
5
6
  const DEFAULT_GRAPH_PAGE_SIZE = 100;
6
7
  const DEFAULT_GRAPH_SCAN_LIMIT = 1000;
7
- /** Entities with an exact `name` (read), bounded by `limit` in SQL with a
8
- * deterministic order. Lets the graph-view focus query find the `--entity NAME`
9
- * entity DIRECTLY (not from a globally-capped list) WITHOUT materializing every
10
- * same-name row when a name maps to many entities. */
8
+ /** Entities with an exact `name`, bounded by `limit` in SQL with a deterministic order, so graph-view focus finds `--entity NAME` directly
9
+ * without materializing every same-name row. */
11
10
  export function loadEntitiesByName(hippoRoot, tenantId, name, opts = {}, txDb) {
12
11
  assertTenantId('loadEntitiesByName', tenantId);
13
12
  const limit = opts.limit ?? DEFAULT_GRAPH_PAGE_SIZE;
@@ -89,10 +88,7 @@ export function loadRelations(hippoRoot, tenantId, opts = {}, txDb) {
89
88
  /** Chunk size for IN-list queries: well under SQLite's 999-bound-variable default
90
89
  * (leaves headroom for the tenant_id param + the doubled list in neighbour lookups). */
91
90
  export const IN_LIST_CHUNK = 400;
92
- /**
93
- * Load entities by their primary ids. Resolves the entity rows reached during the BFS
94
- * (whose `memory_id` maps back to a recall result). Tenant-scoped, read-only.
95
- */
91
+ /** Load entities by primary id (the BFS-reached rows whose `memory_id` maps back to a recall result). Tenant-scoped, read-only. */
96
92
  export function loadEntitiesByIds(hippoRoot, tenantId, ids, txDb) {
97
93
  assertTenantId('loadEntitiesByIds', tenantId);
98
94
  if (ids.length === 0)
@@ -118,13 +114,8 @@ export function loadEntitiesByIds(hippoRoot, tenantId, ids, txDb) {
118
114
  closeHippoDb(ownDb);
119
115
  }
120
116
  }
121
- /**
122
- * All relations touching ANY of `entityIds` in EITHER direction (from OR to): the
123
- * per-hop neighbour query for multi-hop traversal. ONE query for the whole frontier
124
- * (not one per node): this is the bidirectional read `loadRelations` (from-only) lacks,
125
- * and avoids an N+1 across BFS frontier nodes. `limit` caps rows for the frontier and
126
- * must be a non-negative integer (the raw `LIMIT ?` rejects a fractional value).
127
- */
117
+ /** All relations touching ANY of `entityIds` in EITHER direction: the per-hop neighbour query for multi-hop traversal, one query for the whole frontier
118
+ * (no N+1). `limit` caps rows and must be a non-negative integer (raw `LIMIT ?` rejects a fraction). */
128
119
  export function loadNeighborRelations(hippoRoot, tenantId, entityIds, opts = {}, txDb) {
129
120
  assertTenantId('loadNeighborRelations', tenantId);
130
121
  if (entityIds.length === 0)
@@ -136,11 +127,8 @@ export function loadNeighborRelations(hippoRoot, tenantId, entityIds, opts = {},
136
127
  const ownDb = txDb ? null : openHippoDb(hippoRoot);
137
128
  const db = txDb ?? ownDb;
138
129
  try {
139
- // `limit` is applied PER CHUNK; a frontier spanning >IN_LIST_CHUNK ids could return
140
- // up to limit*chunks rows before the by-id dedup below. Harmless for multi-hop recall (the
141
- // frontier is bounded by maxNeighbors <= 200 << IN_LIST_CHUNK, so a single chunk,
142
- // and the BFS re-enforces the per-hop fanout cap), but note the semantics if a
143
- // tighter total cap is ever needed.
130
+ // `limit` applies PER CHUNK, so a frontier over IN_LIST_CHUNK ids could return limit*chunks rows before the dedup below;
131
+ // harmless today (frontier <= maxNeighbors 200, one chunk, BFS re-enforces the fanout cap).
144
132
  const byId = new Map();
145
133
  for (let i = 0; i < entityIds.length; i += IN_LIST_CHUNK) {
146
134
  const slice = entityIds.slice(i, i + IN_LIST_CHUNK);
@@ -162,13 +150,8 @@ export function loadNeighborRelations(hippoRoot, tenantId, entityIds, opts = {},
162
150
  closeHippoDb(ownDb);
163
151
  }
164
152
  }
165
- /**
166
- * Relations with BOTH endpoints in `entityIds` (edges AMONG the set, not merely
167
- * touching it). Read. Used by the graph-view focus subgraph so the displayed
168
- * edges are exactly the intra-union edges: the `LIMIT` only caps genuinely-many
169
- * intra-union edges: no out-of-union row can evict a valid in-set edge. The
170
- * caller bounds `entityIds` (<= the view limit), so a single query is safe.
171
- */
153
+ /** Relations with BOTH endpoints in `entityIds` (edges AMONG the set), for the graph-view focus subgraph; `LIMIT` caps only intra-union edges,
154
+ * so no out-of-union row evicts a valid one. The caller bounds `entityIds` (<= view limit), so a single query is safe. */
172
155
  export function loadRelationsAmong(hippoRoot, tenantId, entityIds, opts = {}, txDb) {
173
156
  assertTenantId('loadRelationsAmong', tenantId);
174
157
  if (entityIds.length === 0)
@@ -195,17 +178,13 @@ export function loadRelationsAmong(hippoRoot, tenantId, entityIds, opts = {}, tx
195
178
  closeHippoDb(ownDb);
196
179
  }
197
180
  }
198
- /**
199
- * Map consolidated source memory ids -> their graph entities. The SEED step of
200
- * multi-hop recall (recall result memory ids -> entities to traverse from). Tenant-
201
- * scoped, read-only; chunks the IN-list under the SQLite variable cap.
202
- */
181
+ /** Map consolidated source memory ids to their graph entities: the SEED step of multi-hop recall. Tenant-scoped, read-only; chunks the IN-list under the
182
+ * SQLite variable cap. */
203
183
  export function loadEntitiesByMemoryId(hippoRoot, tenantId, memoryIds) {
204
184
  assertTenantId('loadEntitiesByMemoryId', tenantId);
205
185
  if (memoryIds.length === 0)
206
186
  return [];
207
- const db = openHippoDb(hippoRoot);
208
- try {
187
+ return onHandle(hippoRoot, (db) => {
209
188
  const out = [];
210
189
  for (let i = 0; i < memoryIds.length; i += IN_LIST_CHUNK) {
211
190
  const slice = memoryIds.slice(i, i + IN_LIST_CHUNK);
@@ -220,10 +199,7 @@ export function loadEntitiesByMemoryId(hippoRoot, tenantId, memoryIds) {
220
199
  out.push(...rows.map(rowToEntity));
221
200
  }
222
201
  return out;
223
- }
224
- finally {
225
- closeHippoDb(db);
226
- }
202
+ });
227
203
  }
228
204
  /** The stored rows a rebuild diffs against, read on the caller's handle so the diff and the apply can share one write lock. */
229
205
  export function storedGraphOn(db, tenantId, memoryIds) {
@@ -244,29 +220,15 @@ function memoryKindsOn(db, memoryIds) {
244
220
  }
245
221
  /** storedGraphOn on its own connection, outside any write lock. */
246
222
  export function loadStoredGraph(hippoRoot, tenantId, memoryIds) {
247
- const db = openHippoDb(hippoRoot);
248
- try {
223
+ return onHandle(hippoRoot, (db) => {
249
224
  return storedGraphOn(db, tenantId, memoryIds);
250
- }
251
- finally {
252
- closeHippoDb(db);
253
- }
225
+ });
254
226
  }
255
- /**
256
- * Run `fn` inside ONE read transaction (a single WAL snapshot) so every graph read
257
- * it performs (pass the supplied `txDb` to the `load*` functions) sees a consistent
258
- * view, even if a `graph extract` / sleep-drain rebuild commits concurrently between
259
- * reads (the rebuild clears + reinserts entities, so separate reads could otherwise
260
- * mix old entity ids with new relation ids). Reads only; the connection is opened
261
- * once and closed after.
262
- */
227
+ /** Run `fn` in ONE read transaction (a single WAL snapshot) so every `load*` read via `txDb` sees a consistent view
228
+ * even if a rebuild commits concurrently (it clears and reinserts entities, so separate reads could mix old entity ids with new relation ids). */
263
229
  export function withGraphReadSnapshot(hippoRoot, fn) {
264
- const db = openHippoDb(hippoRoot);
265
- try {
230
+ return onHandle(hippoRoot, (db) => {
266
231
  return withReadSnapshot(db, () => fn(db));
267
- }
268
- finally {
269
- closeHippoDb(db);
270
- }
232
+ });
271
233
  }
272
234
  //# sourceMappingURL=graph-reads.js.map
@@ -6,9 +6,8 @@ export type SourceKind = 'distilled' | 'superseded';
6
6
  * provenance path, alongside the memory path). Maps to source_object_type. */
7
7
  export type SourceObjectType = 'decision' | 'policy' | 'customer' | 'project';
8
8
  export declare const GRAPH_ENTITY_TYPES: ReadonlySet<EntityType>;
9
- /** A soft (type,id) pointer to the authoritative object row a graph row descends from.
10
- * Survives a mirror memory forget/prune (memory_id may go NULL); the rebuild
11
- * re-validates it (it is not a hard FK). */
9
+ /** A soft (type,id) pointer to the authoritative object row a graph row descends from; survives a mirror forget/prune
10
+ * (memory_id may go NULL) and is re-validated by the rebuild, not a hard FK. */
12
11
  export interface SourceObjectRef {
13
12
  type: SourceObjectType;
14
13
  id: number;
@@ -22,9 +21,7 @@ export interface Entity {
22
21
  tenantId: string;
23
22
  entityType: EntityType;
24
23
  name: string;
25
- /** The consolidated source memory this entity was extracted from. NULL once the
26
- * mirror is forgotten/pruned (ON DELETE SET NULL) - the entity then survives via
27
- * its source_object provenance. */
24
+ /** The consolidated source memory this entity came from; NULL once the mirror is forgotten/pruned (ON DELETE SET NULL), then provenance is source_object. */
28
25
  memoryId: string | null;
29
26
  sourceKind: SourceKind;
30
27
  /** The authoritative object this entity is anchored to (object-provenance path).
@@ -10,9 +10,8 @@ export const VALID_QUEUE_STATES = new Set([
10
10
  ]);
11
11
  export const MAX_ENTITY_NAME_LEN = 512;
12
12
  export function rowToEntity(row) {
13
- // SAFETY: entity_type/source_kind/source_object_type are DB CHECK-constrained
14
- // (see db.ts CREATE TABLE entities) to exactly the EntityType/SourceKind/
15
- // SourceObjectType enum values, so the row's column values match those types.
13
+ // SAFETY: entity_type/source_kind/source_object_type are DB CHECK-constrained to exactly the EntityType/SourceKind/SourceObjectType enum values,
14
+ // so the row's column values match those types.
16
15
  return {
17
16
  id: row.id,
18
17
  tenantId: row.tenant_id,
@@ -26,9 +25,8 @@ export function rowToEntity(row) {
26
25
  };
27
26
  }
28
27
  export function rowToRelation(row) {
29
- // SAFETY: rel_type/source_kind/source_object_type are DB CHECK-constrained
30
- // (see db.ts CREATE TABLE relations) to exactly the RelationType/SourceKind/
31
- // SourceObjectType enum values, so the row's column values match those types.
28
+ // SAFETY: rel_type/source_kind/source_object_type are DB CHECK-constrained to exactly the RelationType/SourceKind/SourceObjectType enum values,
29
+ // so the row's column values match those types.
32
30
  return {
33
31
  id: row.id,
34
32
  tenantId: row.tenant_id,
@@ -45,9 +43,8 @@ export function rowToRelation(row) {
45
43
  export const ENTITY_COLS = `id, tenant_id, entity_type, name, memory_id, source_kind, source_object_type, source_object_id, created_at`;
46
44
  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`;
47
45
  export function rowToQueueItem(row) {
48
- // SAFETY: kind/status are DB CHECK-constrained (see db.ts CREATE TABLE
49
- // graph_extraction_queue) to exactly the SourceKind/GraphQueueStatus enum
50
- // values, so the row's column values match those types.
46
+ // SAFETY: kind/status are DB CHECK-constrained to exactly the SourceKind/GraphQueueStatus enum values,
47
+ // so the row's column values match those types.
51
48
  return {
52
49
  id: row.id,
53
50
  tenantId: row.tenant_id,
@@ -6,7 +6,8 @@ export interface GraphViewSpec {
6
6
  readonly limit: number;
7
7
  readonly canRead?: CanRead;
8
8
  }
9
- /** What `GraphReads.graphRows` answers, read on `db`: the caller opens the one snapshot that keeps entity ids and relation ids from two different rebuilds apart. */
9
+ /** What `GraphReads.graphRows` answers, read on `db`: the caller opens the one
10
+ * snapshot that keeps entity ids and relation ids from two different rebuilds apart. */
10
11
  export declare function graphViewRows(hippoRoot: string, db: DatabaseSyncLike, tenantId: string, spec: GraphViewSpec): GraphRows;
11
12
  export {};
12
13
  //# sourceMappingURL=graph-view-rows.d.ts.map
@@ -52,7 +52,8 @@ function focusRows({ hippoRoot, db, tenantId }, name, limit, canRead) {
52
52
  relations.length >= limit;
53
53
  return { entities, relations, truncated };
54
54
  }
55
- /** What `GraphReads.graphRows` answers, read on `db`: the caller opens the one snapshot that keeps entity ids and relation ids from two different rebuilds apart. */
55
+ /** What `GraphReads.graphRows` answers, read on `db`: the caller opens the one
56
+ * snapshot that keeps entity ids and relation ids from two different rebuilds apart. */
56
57
  export function graphViewRows(hippoRoot, db, tenantId, spec) {
57
58
  const source = { hippoRoot, db, tenantId };
58
59
  const raw = spec.entity !== undefined ? focusRows(source, spec.entity, spec.limit, spec.canRead) : wholeGraphRows(source, spec.limit);
@@ -1,33 +1,18 @@
1
1
  import { type DatabaseSyncLike } from '../db/index.js';
2
2
  import { type EntityType, type RelationType, type SourceKind, type SourceObjectType, type SourceObjectRef, type Entity, type Relation, type InsertEntityOpts, type InsertRelationOpts, type UpdateEntityOpts } from './graph-rows.js';
3
- /**
4
- * Resolve the `source_kind` for a graph row from AT LEAST ONE valid provenance path,
5
- * with the no-raw invariant intact. The code-level mirror of the DB trigger guard (the
6
- * trigger is the unbypassable backstop). Two paths:
7
- * - MEMORY path (`memoryId` not null): the memory must exist, be same-tenant, and be
8
- * consolidated (distilled/superseded); raw is rejected. Returns its kind.
9
- * - OBJECT path (`memoryId` null, `sourceObject` set): the object row must exist, be
10
- * same-tenant, and have status active|superseded (4-way per object table). Objects are
11
- * consolidated BY CONSTRUCTION, so this returns 'distilled'.
12
- * All-null (no memory AND no source object) is rejected.
13
- */
3
+ /** Resolve `source_kind` for a graph row from AT LEAST ONE valid provenance path, mirroring the DB trigger guard; raw is rejected.
4
+ * MEMORY path: exists, same-tenant, consolidated. OBJECT path (`memoryId` null): same-tenant, active|superseded, yields 'distilled'. All-null is rejected. */
14
5
  interface ResolvedGraphSource {
15
6
  sourceKind: SourceKind;
16
7
  memoryId: string | null;
17
8
  }
18
9
  export declare function resolveConsolidatedSource(db: DatabaseSyncLike, tenantId: string, memoryId: string | null, sourceObject: SourceObjectRef | null, label: string): ResolvedGraphSource;
19
- /**
20
- * Insert a graph entity extracted from a consolidated memory. Throws if the source
21
- * memory is missing / cross-tenant / raw (the DB trigger is the backstop).
22
- */
10
+ /** Insert a graph entity extracted from a consolidated memory; throws if the source memory is missing / cross-tenant / raw (the DB trigger is the backstop). */
23
11
  export declare function insertEntity(hippoRoot: string, tenantId: string, opts: InsertEntityOpts, txDb?: DatabaseSyncLike): Entity;
24
12
  /** Renames an entity or moves its memory provenance in place, keeping id and created_at; null when the row is gone.
25
13
  * A delete plus an insert would cascade away every relation that points at it. */
26
14
  export declare function updateEntity(hippoRoot: string, tenantId: string, id: number, opts: UpdateEntityOpts, txDb?: DatabaseSyncLike): Entity | null;
27
- /**
28
- * Insert a graph relation between two entities, sourced from a consolidated memory.
29
- * Both entities must exist in the same tenant; the source memory must be consolidated.
30
- */
15
+ /** Insert a graph relation between two same-tenant entities, sourced from a consolidated memory. */
31
16
  export declare function insertRelation(hippoRoot: string, tenantId: string, opts: InsertRelationOpts, txDb?: DatabaseSyncLike): Relation;
32
17
  /** The source object still holds the loader's rule (active or superseded); a closed or gone one gets no new graph row. */
33
18
  export declare function objectInForce(db: DatabaseSyncLike, tenantId: string, ref: SourceObjectRef): boolean;
@@ -41,18 +26,8 @@ export declare function deleteRelationRow(db: DatabaseSyncLike, tenantId: string
41
26
  export declare function runGraphRebuildTransaction<T>(hippoRoot: string, tenantId: string, fn: (txDb: DatabaseSyncLike) => T, opts?: {
42
27
  busyWaitMs?: number;
43
28
  }): T;
44
- /**
45
- * Remove the graph rows sourced from one first-class object, by its (type, id). Used when a
46
- * MIRRORLESS object is closed: it has no mirror memory, so `markGraphDirty` cannot
47
- * enqueue a rebuild (the queue is memory-keyed). Closing must still drop the object's
48
- * now-stale entity + edges from the graph, so we remove them directly here. Fail-soft
49
- * like `markGraphDirty` (never throws into the object close caller; graph staleness is
50
- * recoverable). Deleting the entity cascade-deletes any relation where it is an endpoint
51
- * (relations FK entities ON DELETE CASCADE); the explicit relations DELETE also covers a
52
- * relation whose OWN provenance is this object (defensive — every such edge has the object
53
- * as an endpoint today, so the cascade already covers it). DELETE fires no BEFORE
54
- * INSERT/UPDATE guard trigger.
55
- */
29
+ /** Remove graph rows sourced from one MIRRORLESS object by (type, id) on close: with no mirror memory `markGraphDirty` cannot enqueue a rebuild.
30
+ * Fail-soft like `markGraphDirty`; the explicit relations DELETE also covers a relation whose OWN provenance is this object. */
56
31
  export declare function removeGraphEntitiesForObject(hippoRoot: string, tenantId: string, sourceObjectType: SourceObjectType, sourceObjectId: number): void;
57
32
  export {};
58
33
  //# sourceMappingURL=graph-writes.d.ts.map
@@ -1,6 +1,7 @@
1
1
  // The writer of the entities and relations tables. Every row resolves a consolidated source first, never a raw memory;
2
2
  // the schema triggers are the backstop for a write that skips this module.
3
3
  import { openHippoDb, closeHippoDb, withWriteScope } from '../db/index.js';
4
+ import { onHandle } from './open.js';
4
5
  import { assertTenantId } from './tenant.js';
5
6
  import { errorMessage, log } from '../util/log.js';
6
7
  import { GRAPH_ENTITY_TYPES, GRAPH_RELATION_TYPES, MAX_ENTITY_NAME_LEN, rowToEntity, rowToRelation, ENTITY_COLS, RELATION_COLS } from './graph-rows.js';
@@ -29,10 +30,8 @@ function checkSourceMemory(db, tenantId, memoryId, sourceObject, label) {
29
30
  // the SELECT above.
30
31
  const row = db.prepare(`SELECT kind, tenant_id FROM memories WHERE id = ?`).get(memoryId);
31
32
  if (!row) {
32
- // Stale / forgotten mirror. Tolerate it IFF a valid source object provides provenance:
33
- // graph-extract reads object rows then inserts, and a mirror forgotten/pruned in that window
34
- // must NOT roll back the whole tenant rebuild - the active object survives mirror loss.
35
- // Anchor to the object; drop the dead memory pointer.
33
+ // Stale/forgotten mirror: tolerate it IFF a valid source object gives provenance, so a mirror pruned mid graph-extract does not roll back the tenant
34
+ // rebuild; anchor to the object and drop the dead memory pointer.
36
35
  if (sourceObject == null) {
37
36
  throw new Error(`${label}: source memory ${memoryId} not found`);
38
37
  }
@@ -54,18 +53,15 @@ function checkSourceMemory(db, tenantId, memoryId, sourceObject, label) {
54
53
  return { memKind, effectiveMemoryId };
55
54
  }
56
55
  function assertSourceObjectUsable(db, tenantId, sourceObject, label) {
57
- // Validate the object pointer WHENEVER it is provided, not only when memory is null:
58
- // a dual-set row whose object is wrong/closed/cross-tenant would become
59
- // the active provenance after ON DELETE SET NULL and could then block the memory delete.
56
+ // Validate the object pointer WHENEVER provided: a dual-set row with a bad object would become the provenance after ON DELETE SET NULL and could block
57
+ // the memory delete.
60
58
  if (sourceObject != null) {
61
59
  const table = SOURCE_OBJECT_TABLE[sourceObject.type];
62
60
  if (!table) {
63
61
  throw new Error(`${label}: unsupported source_object_type '${sourceObject.type}'`);
64
62
  }
65
- // `table` is a fixed value from the SOURCE_OBJECT_TABLE map (never user-supplied), so
66
- // this string interpolation is safe; `id`/`tenant_id` stay parametrized.
67
- // SAFETY: row's shape matches the single `status` column named in the
68
- // SELECT above.
63
+ // `table` is a fixed SOURCE_OBJECT_TABLE value (never user-supplied), so interpolation is safe; `id`/`tenant_id` stay parametrized.
64
+ // SAFETY: row's shape matches the single `status` column named in the SELECT above.
69
65
  const row = db.prepare(`SELECT status FROM ${table} WHERE id = ? AND tenant_id = ?`).get(sourceObject.id, tenantId);
70
66
  if (!row) {
71
67
  throw new Error(`${label}: source ${sourceObject.type} ${sourceObject.id} not found for tenant ${tenantId}`);
@@ -75,10 +71,7 @@ function assertSourceObjectUsable(db, tenantId, sourceObject, label) {
75
71
  }
76
72
  }
77
73
  }
78
- /**
79
- * Insert a graph entity extracted from a consolidated memory. Throws if the source
80
- * memory is missing / cross-tenant / raw (the DB trigger is the backstop).
81
- */
74
+ /** Insert a graph entity extracted from a consolidated memory; throws if the source memory is missing / cross-tenant / raw (the DB trigger is the backstop). */
82
75
  export function insertEntity(hippoRoot, tenantId, opts, txDb) {
83
76
  assertTenantId('insertEntity', tenantId);
84
77
  if (!GRAPH_ENTITY_TYPES.has(opts.entityType)) {
@@ -142,10 +135,7 @@ export function updateEntity(hippoRoot, tenantId, id, opts, txDb) {
142
135
  closeHippoDb(db);
143
136
  }
144
137
  }
145
- /**
146
- * Insert a graph relation between two entities, sourced from a consolidated memory.
147
- * Both entities must exist in the same tenant; the source memory must be consolidated.
148
- */
138
+ /** Insert a graph relation between two same-tenant entities, sourced from a consolidated memory. */
149
139
  export function insertRelation(hippoRoot, tenantId, opts, txDb) {
150
140
  assertTenantId('insertRelation', tenantId);
151
141
  if (!GRAPH_RELATION_TYPES.has(opts.relType)) {
@@ -221,33 +211,19 @@ export function runGraphRebuildTransaction(hippoRoot, tenantId, fn, opts) {
221
211
  closeHippoDb(db);
222
212
  }
223
213
  }
224
- /**
225
- * Remove the graph rows sourced from one first-class object, by its (type, id). Used when a
226
- * MIRRORLESS object is closed: it has no mirror memory, so `markGraphDirty` cannot
227
- * enqueue a rebuild (the queue is memory-keyed). Closing must still drop the object's
228
- * now-stale entity + edges from the graph, so we remove them directly here. Fail-soft
229
- * like `markGraphDirty` (never throws into the object close caller; graph staleness is
230
- * recoverable). Deleting the entity cascade-deletes any relation where it is an endpoint
231
- * (relations FK entities ON DELETE CASCADE); the explicit relations DELETE also covers a
232
- * relation whose OWN provenance is this object (defensive — every such edge has the object
233
- * as an endpoint today, so the cascade already covers it). DELETE fires no BEFORE
234
- * INSERT/UPDATE guard trigger.
235
- */
214
+ /** Remove graph rows sourced from one MIRRORLESS object by (type, id) on close: with no mirror memory `markGraphDirty` cannot enqueue a rebuild.
215
+ * Fail-soft like `markGraphDirty`; the explicit relations DELETE also covers a relation whose OWN provenance is this object. */
236
216
  export function removeGraphEntitiesForObject(hippoRoot, tenantId, sourceObjectType, sourceObjectId) {
237
217
  try {
238
218
  assertTenantId('removeGraphEntitiesForObject', tenantId);
239
- const db = openHippoDb(hippoRoot);
240
- try {
219
+ onHandle(hippoRoot, (db) => {
241
220
  withWriteScope(db, 'remove_graph_entities', () => {
242
221
  db.prepare(`DELETE FROM relations WHERE tenant_id = ? AND source_object_type = ? AND source_object_id = ?`)
243
222
  .run(tenantId, sourceObjectType, sourceObjectId);
244
223
  db.prepare(`DELETE FROM entities WHERE tenant_id = ? AND source_object_type = ? AND source_object_id = ?`)
245
224
  .run(tenantId, sourceObjectType, sourceObjectId);
246
225
  });
247
- }
248
- finally {
249
- closeHippoDb(db);
250
- }
226
+ });
251
227
  }
252
228
  catch (err) {
253
229
  log.warn(`removeGraphEntitiesForObject: failed for tenant=${tenantId} ${sourceObjectType}#${sourceObjectId}: ${errorMessage(err)}`);
@@ -20,7 +20,8 @@ export interface HalfLifeMove {
20
20
  }
21
21
  /** The base this store's memories are on: 7 days when none was ever recorded. */
22
22
  export declare function recordedHalfLifeBase(hippoRoot: string): number;
23
- /** Moves the store's half-lives to base `to` as `plan` decides from the rows read here, then records the base. `outcome` is null when no move is due; a dry run plans and writes nothing. */
23
+ /** Moves the store's half-lives to base `to` as `plan` decides from the rows read here, then
24
+ * records the base. `outcome` is null when no move is due; a dry run plans and writes nothing. */
24
25
  export declare function moveHalfLives<R>(hippoRoot: string, to: number, opts: {
25
26
  dryRun: boolean;
26
27
  actor: string;
@@ -1,10 +1,10 @@
1
1
  // A half-life move reads, writes, audits and records its base on one handle, so it commits whole or not at all.
2
- import { closeHippoDb, getMeta, openHippoDb, setMeta, withWriteScope } from '../db/index.js';
2
+ import { getMeta, setMeta, withWriteScope } from '../db/index.js';
3
3
  import { appendAuditEvent } from './audit.js';
4
4
  import { conflictResolveAuditsAt, resolvedConflictsAt } from './conflicts.js';
5
5
  import { objectMemoryRowsAt, selectAllEntries } from './entry-reads.js';
6
6
  import { setHalfLivesAt } from './entry-writes.js';
7
- import { HALF_LIFE_BASE_META_KEY, TYPED_HALF_LIFE_META_KEY, openStore } from './open.js';
7
+ import { onHandle, HALF_LIFE_BASE_META_KEY, TYPED_HALF_LIFE_META_KEY, openStore } from './open.js';
8
8
  /** The base every store used before the base was recorded. */
9
9
  const LEGACY_HALF_LIFE_BASE = 7;
10
10
  function readBase(db) {
@@ -13,13 +13,9 @@ function readBase(db) {
13
13
  }
14
14
  /** The base this store's memories are on: 7 days when none was ever recorded. */
15
15
  export function recordedHalfLifeBase(hippoRoot) {
16
- const db = openHippoDb(hippoRoot);
17
- try {
16
+ return onHandle(hippoRoot, (db) => {
18
17
  return readBase(db);
19
- }
20
- finally {
21
- closeHippoDb(db);
22
- }
18
+ });
23
19
  }
24
20
  function readRows(db, from, typedPending) {
25
21
  const all = selectAllEntries(db);
@@ -44,13 +40,18 @@ function writeMove(db, move, old, actor) {
44
40
  record[e.id] = old.get(e.id);
45
41
  }
46
42
  for (const [tenantId, oldHalfLives] of byTenant) {
47
- appendAuditEvent(db, { tenantId, actor, op: 'half_life_migrate', metadata: { from: move.from, to: move.to, ids: Object.keys(oldHalfLives), oldHalfLives } });
43
+ appendAuditEvent(db, {
44
+ tenantId,
45
+ actor,
46
+ op: 'half_life_migrate',
47
+ metadata: { from: move.from, to: move.to, ids: Object.keys(oldHalfLives), oldHalfLives }
48
+ });
48
49
  }
49
50
  }
50
- /** Moves the store's half-lives to base `to` as `plan` decides from the rows read here, then records the base. `outcome` is null when no move is due; a dry run plans and writes nothing. */
51
+ /** Moves the store's half-lives to base `to` as `plan` decides from the rows read here, then
52
+ * records the base. `outcome` is null when no move is due; a dry run plans and writes nothing. */
51
53
  export function moveHalfLives(hippoRoot, to, opts, plan) {
52
- const db = openStore(hippoRoot);
53
- try {
54
+ return onHandle(hippoRoot, (db) => {
54
55
  const run = () => {
55
56
  const from = readBase(db);
56
57
  const typedPending = getMeta(db, TYPED_HALF_LIFE_META_KEY, '') === '';
@@ -69,9 +70,6 @@ export function moveHalfLives(hippoRoot, to, opts, plan) {
69
70
  };
70
71
  // Plan, write, audit and record the base under one write lock, so a concurrent write or sleep cannot interleave.
71
72
  return opts.dryRun ? run() : withWriteScope(db, 'migrate_half_life', run);
72
- }
73
- finally {
74
- closeHippoDb(db);
75
- }
73
+ }, openStore);
76
74
  }
77
75
  //# sourceMappingURL=half-life.js.map
@@ -1,11 +1,9 @@
1
1
  import { type SessionHandoff, type HandoffOutcome, type HandoffEvidence } from '../core/handoff.js';
2
2
  import type { TaskSnapshot } from './rows.js';
3
3
  import { type ContinuityKey } from './sessions.js';
4
- /** Column list shared by every session_handoffs SELECT; store-cards.ts reuses it for the card handoff lookup. */
4
+ /** Column list shared by every session_handoffs SELECT; cards.ts reuses it for the card handoff lookup. */
5
5
  export declare const HANDOFF_COLUMNS = "id, session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, created_at, constraints_json, evidence_json, outcome, target_runtime, card_id";
6
- /**
7
- * Save a session handoff record. Returns the persisted handoff.
8
- */
6
+ /** Save a session handoff record; returns the persisted handoff. */
9
7
  export declare function saveSessionHandoff(hippoRoot: string, tenantId: string, handoff: Omit<SessionHandoff, 'updatedAt'>, key?: ContinuityKey): SessionHandoff;
10
8
  interface HandoffFilter {
11
9
  unfinishedOnly?: boolean;
@@ -15,16 +13,12 @@ interface HandoffFilter {
15
13
  }
16
14
  /** Load the most recent handoff, optionally filtered by session ID. */
17
15
  export declare function loadLatestHandoff(hippoRoot: string, tenantId: string, sessionId?: string, opts?: HandoffFilter, key?: ContinuityKey): SessionHandoff | null;
18
- /**
19
- * Load a specific handoff by its row ID.
20
- */
16
+ /** Load a specific handoff by its row ID. */
21
17
  export declare function loadHandoffById(hippoRoot: string, tenantId: string, id: number): SessionHandoff | null;
22
18
  /** Stamp the outcome on a session's newest handoff, only if it has none yet. Returns rows changed. */
23
19
  export declare function stampHandoffOutcome(hippoRoot: string, tenantId: string, sessionId: string, outcome: HandoffOutcome): number;
24
- /** Auto-write a handoff at session-end from the session's active snapshot, else from `derived`, its transcript state.
25
- * @param evidence best-effort git state; outcome comes from the newest session_complete event.
26
- * @param options.inPlace rewrite an earlier transcript read instead of adding a revision, for a close that runs after every reply.
27
- * @returns null when neither source is the session's, a newer handoff covers the snapshot, the session's latest handoff was not read off its transcript or already holds `derived`, or, in place, a handoff landed after the read. */
20
+ /** Session-end handoff from the active snapshot, else `derived` transcript state; `inPlace` rewrites an earlier transcript read instead of adding a revision.
21
+ * Returns null when no source is the session's, a newer handoff covers it, or the latest one is not transcript-derived or already holds `derived`. */
28
22
  export declare function writeSessionEndHandoff(hippoRoot: string, tenantId: string, sessionId: string, evidence: HandoffEvidence | null, derived?: Pick<TaskSnapshot, 'task' | 'summary' | 'next_step'> | null, key?: ContinuityKey, options?: {
29
23
  inPlace?: boolean;
30
24
  }): SessionHandoff | null;
@@ -1,14 +1,12 @@
1
- import { closeHippoDb, openHippoDb } from '../db/index.js';
1
+ import { closeHippoDb } from '../db/index.js';
2
2
  import { rowToSessionHandoff, isHandoffOutcome, } from '../core/handoff.js';
3
3
  import { scopeAdmitSql } from './recall-scope.js';
4
4
  import { assertTenantId } from './tenant.js';
5
- import { openStore } from './open.js';
5
+ import { onHandle, openStore } from './open.js';
6
6
  import { continuityStamp, continuityWhere, loadActiveTaskSnapshot } from './sessions.js';
7
- /** Column list shared by every session_handoffs SELECT; store-cards.ts reuses it for the card handoff lookup. */
7
+ /** Column list shared by every session_handoffs SELECT; cards.ts reuses it for the card handoff lookup. */
8
8
  export const HANDOFF_COLUMNS = 'id, session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, created_at, constraints_json, evidence_json, outcome, target_runtime, card_id';
9
- /**
10
- * Save a session handoff record. Returns the persisted handoff.
11
- */
9
+ /** Save a session handoff record; returns the persisted handoff. */
12
10
  export function saveSessionHandoff(hippoRoot, tenantId, handoff, key) {
13
11
  assertTenantId('saveSessionHandoff', tenantId);
14
12
  const stamp = key ? continuityStamp(key) : null;
@@ -50,8 +48,7 @@ function handoffConditions(tenantId, sessionId, opts, key) {
50
48
  params.push(opts.excludeSessionId);
51
49
  }
52
50
  if (opts.unfinishedOnly) {
53
- // Restrict to each session's newest revision first: stampHandoffOutcome
54
- // only stamps the newest row, so an older null-outcome revision must not resurrect.
51
+ // Restrict to each session's newest revision first: stampHandoffOutcome only stamps the newest row, so an older null-outcome revision must not resurrect.
55
52
  // Keyed, the newest is the owner's own, so another owner's newer revision cannot hide it.
56
53
  conditions.push(`id IN (SELECT MAX(id) FROM session_handoffs WHERE tenant_id = ?${owned ? ` AND ${owned.sql}` : ''} GROUP BY session_id)`);
57
54
  params.push(tenantId, ...(owned?.params ?? []));
@@ -89,9 +86,7 @@ export function loadLatestHandoff(hippoRoot, tenantId, sessionId, opts = {}, key
89
86
  closeHippoDb(db);
90
87
  }
91
88
  }
92
- /**
93
- * Load a specific handoff by its row ID.
94
- */
89
+ /** Load a specific handoff by its row ID. */
95
90
  export function loadHandoffById(hippoRoot, tenantId, id) {
96
91
  assertTenantId('loadHandoffById', tenantId);
97
92
  const db = openStore(hippoRoot);
@@ -111,8 +106,7 @@ export function loadHandoffById(hippoRoot, tenantId, id) {
111
106
  /** Stamp the outcome on a session's newest handoff, only if it has none yet. Returns rows changed. */
112
107
  export function stampHandoffOutcome(hippoRoot, tenantId, sessionId, outcome) {
113
108
  assertTenantId('stampHandoffOutcome', tenantId);
114
- const db = openStore(hippoRoot);
115
- try {
109
+ return onHandle(hippoRoot, (db) => {
116
110
  const result = db.prepare(`
117
111
  UPDATE session_handoffs SET outcome = ?
118
112
  WHERE tenant_id = ? AND session_id = ? AND outcome IS NULL
@@ -123,17 +117,14 @@ export function stampHandoffOutcome(hippoRoot, tenantId, sessionId, outcome) {
123
117
  )
124
118
  `).run(outcome, tenantId, sessionId, tenantId, sessionId);
125
119
  return Number(result.changes ?? 0);
126
- }
127
- finally {
128
- closeHippoDb(db);
129
- }
120
+ }, openStore);
130
121
  }
131
- /** Rewrites the session's newest handoff when it is still a transcript read, in one statement so a handoff written meanwhile is never overwritten; null when none was rewritten. */
122
+ /** Rewrites the session's newest handoff when it is still a transcript read, in one statement so a handoff written meanwhile is never overwritten; null
123
+ * when none was rewritten. */
132
124
  function replaceTranscriptHandoff(hippoRoot, tenantId, handoff, key) {
133
125
  const { conditions, params } = handoffConditions(tenantId, handoff.sessionId, {}, key);
134
126
  const newest = `SELECT id FROM session_handoffs WHERE ${conditions.join(' AND ')} ORDER BY created_at DESC, id DESC LIMIT 1`;
135
- const db = openStore(hippoRoot);
136
- try {
127
+ return onHandle(hippoRoot, (db) => {
137
128
  const result = db.prepare(`
138
129
  UPDATE session_handoffs SET repo_root = ?, task_id = ?, summary = ?, next_action = ?, artifacts_json = ?, scope = ?, created_at = ?,
139
130
  constraints_json = ?, evidence_json = ?, outcome = ?, target_runtime = ?, card_id = ?
@@ -144,10 +135,7 @@ function replaceTranscriptHandoff(hippoRoot, tenantId, handoff, key) {
144
135
  // SAFETY: row's shape matches HANDOFF_COLUMNS.
145
136
  const row = db.prepare(`SELECT ${HANDOFF_COLUMNS} FROM session_handoffs WHERE id = (${newest})`).get(...params);
146
137
  return row ? rowToSessionHandoff(row) : null;
147
- }
148
- finally {
149
- closeHippoDb(db);
150
- }
138
+ }, openStore);
151
139
  }
152
140
  function transcriptHandoffSource(existing, derived, evidence) {
153
141
  // Only an earlier transcript read gives way; `hippo handoff create` and unmarked older handoffs keep winning.
@@ -179,10 +167,8 @@ function buildSessionEndHandoff(sessionId, snapshot, existing, handoffEvidence,
179
167
  cardId: carryForward ? existing.cardId : undefined,
180
168
  };
181
169
  }
182
- /** Auto-write a handoff at session-end from the session's active snapshot, else from `derived`, its transcript state.
183
- * @param evidence best-effort git state; outcome comes from the newest session_complete event.
184
- * @param options.inPlace rewrite an earlier transcript read instead of adding a revision, for a close that runs after every reply.
185
- * @returns null when neither source is the session's, a newer handoff covers the snapshot, the session's latest handoff was not read off its transcript or already holds `derived`, or, in place, a handoff landed after the read. */
170
+ /** Session-end handoff from the active snapshot, else `derived` transcript state; `inPlace` rewrites an earlier transcript read instead of adding a revision.
171
+ * Returns null when no source is the session's, a newer handoff covers it, or the latest one is not transcript-derived or already holds `derived`. */
186
172
  export function writeSessionEndHandoff(hippoRoot, tenantId, sessionId, evidence, derived = null, key, options = {}) {
187
173
  assertTenantId('writeSessionEndHandoff', tenantId);
188
174
  if (key)
@@ -216,8 +202,7 @@ export function writeSessionEndHandoff(hippoRoot, tenantId, sessionId, evidence,
216
202
  return saveSessionHandoff(hippoRoot, tenantId, handoff, key);
217
203
  }
218
204
  function sessionOutcome(hippoRoot, tenantId, sessionId) {
219
- const db = openHippoDb(hippoRoot);
220
- try {
205
+ return onHandle(hippoRoot, (db) => {
221
206
  // SAFETY: row's shape matches the single `content` column below.
222
207
  const content = db.prepare(`
223
208
  SELECT content FROM session_events
@@ -225,9 +210,6 @@ function sessionOutcome(hippoRoot, tenantId, sessionId) {
225
210
  ORDER BY created_at DESC, id DESC LIMIT 1
226
211
  `).get(tenantId, sessionId)?.content;
227
212
  return isHandoffOutcome(content) ? content : null;
228
- }
229
- finally {
230
- closeHippoDb(db);
231
- }
213
+ });
232
214
  }
233
215
  //# sourceMappingURL=handoffs.js.map