hippo-memory 1.72.0 → 2.1.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 (995) hide show
  1. package/README.md +6 -4
  2. package/dist/agent-memories/apply.d.ts +7 -5
  3. package/dist/agent-memories/apply.js +66 -39
  4. package/dist/agent-memories/claude-code.d.ts +8 -2
  5. package/dist/agent-memories/claude-code.js +26 -7
  6. package/dist/agent-memories/copilot.js +2 -1
  7. package/dist/agent-memories/files.js +2 -1
  8. package/dist/agent-memories/legacy.d.ts +6 -3
  9. package/dist/agent-memories/legacy.js +35 -14
  10. package/dist/agent-memories/markdown.d.ts +3 -1
  11. package/dist/agent-memories/markdown.js +3 -1
  12. package/dist/agent-memories/openclaw.js +5 -2
  13. package/dist/agent-memories/plan.js +11 -1
  14. package/dist/agent-memories/project-folds.js +2 -1
  15. package/dist/agent-memories/report.d.ts +4 -1
  16. package/dist/agent-memories/report.js +43 -9
  17. package/dist/agent-memories/source.d.ts +8 -2
  18. package/dist/agent-memories/source.js +11 -3
  19. package/dist/agent-memories/sync.d.ts +7 -2
  20. package/dist/agent-memories/sync.js +141 -101
  21. package/dist/api/assemble.d.ts +6 -4
  22. package/dist/api/assemble.js +11 -5
  23. package/dist/api/{audit.d.ts → auth/audit.d.ts} +18 -16
  24. package/dist/api/auth/audit.js +58 -0
  25. package/dist/api/{auth.d.ts → auth/auth.d.ts} +19 -16
  26. package/dist/api/{auth.js → auth/auth.js} +66 -54
  27. package/dist/api/{quarantine.d.ts → auth/quarantine.d.ts} +8 -7
  28. package/dist/api/{quarantine.js → auth/quarantine.js} +8 -7
  29. package/dist/api/auth/session-owners.d.ts +10 -0
  30. package/dist/api/auth/session-owners.js +35 -0
  31. package/dist/api/availability.d.ts +3 -1
  32. package/dist/api/availability.js +3 -1
  33. package/dist/api/busy.d.ts +2 -0
  34. package/dist/api/busy.js +2 -0
  35. package/dist/api/cli-surface.d.ts +6 -0
  36. package/dist/api/cli-surface.js +6 -0
  37. package/dist/api/config-of.d.ts +5 -0
  38. package/dist/api/config-of.js +6 -0
  39. package/dist/api/context-auto.d.ts +4 -1
  40. package/dist/api/context-auto.js +14 -4
  41. package/dist/api/context-render.js +14 -7
  42. package/dist/api/context-select.d.ts +4 -1
  43. package/dist/api/context-select.js +31 -34
  44. package/dist/api/context-types.d.ts +38 -12
  45. package/dist/api/context.d.ts +8 -5
  46. package/dist/api/context.js +120 -63
  47. package/dist/api/continuity.d.ts +24 -21
  48. package/dist/api/continuity.js +18 -20
  49. package/dist/api/correction-latency.d.ts +3 -1
  50. package/dist/api/correction-latency.js +3 -1
  51. package/dist/api/error-reply.d.ts +4 -1
  52. package/dist/api/error-reply.js +12 -3
  53. package/dist/api/index.d.ts +39 -23
  54. package/dist/api/index.js +21 -23
  55. package/dist/api/instruction-detect.d.ts +4 -1
  56. package/dist/api/instruction-detect.js +75 -20
  57. package/dist/api/ledger-db.d.ts +15 -11
  58. package/dist/api/ledger-db.js +21 -23
  59. package/dist/api/memories/conflicts.d.ts +33 -0
  60. package/dist/api/memories/conflicts.js +67 -0
  61. package/dist/api/{forget.d.ts → memories/forget.d.ts} +11 -9
  62. package/dist/api/{forget.js → memories/forget.js} +23 -17
  63. package/dist/api/memories/memories.d.ts +27 -0
  64. package/dist/api/memories/memories.js +52 -0
  65. package/dist/api/memories/outcome.d.ts +22 -0
  66. package/dist/api/memories/outcome.js +28 -0
  67. package/dist/api/memories/promote.d.ts +40 -0
  68. package/dist/api/memories/promote.js +76 -0
  69. package/dist/api/memories/refine.d.ts +10 -0
  70. package/dist/api/memories/refine.js +12 -0
  71. package/dist/api/{remember-local.d.ts → memories/remember-local.d.ts} +17 -9
  72. package/dist/api/{remember-local.js → memories/remember-local.js} +46 -24
  73. package/dist/api/{remember.d.ts → memories/remember.d.ts} +22 -13
  74. package/dist/api/{remember.js → memories/remember.js} +50 -32
  75. package/dist/api/objects/cards.d.ts +39 -0
  76. package/dist/api/{cards.js → objects/cards.js} +12 -14
  77. package/dist/api/{drill-down.d.ts → objects/drill-down.d.ts} +12 -10
  78. package/dist/api/{drill-down.js → objects/drill-down.js} +7 -7
  79. package/dist/api/objects/goals.d.ts +18 -0
  80. package/dist/api/{goals.js → objects/goals.js} +12 -12
  81. package/dist/api/objects/graph.d.ts +11 -0
  82. package/dist/api/objects/graph.js +16 -0
  83. package/dist/api/objects/objects.d.ts +9 -0
  84. package/dist/api/{objects.js → objects/objects.js} +2 -3
  85. package/dist/api/objects/predictions.d.ts +11 -0
  86. package/dist/api/{predictions.js → objects/predictions.js} +7 -5
  87. package/dist/api/{projects.d.ts → objects/projects.d.ts} +8 -5
  88. package/dist/api/{projects.js → objects/projects.js} +8 -4
  89. package/dist/api/pilot-arm.d.ts +8 -4
  90. package/dist/api/pilot-arm.js +5 -4
  91. package/dist/api/prompt-hook.d.ts +35 -20
  92. package/dist/api/prompt-hook.js +66 -44
  93. package/dist/api/provenance-coverage.d.ts +3 -1
  94. package/dist/api/provenance-coverage.js +3 -1
  95. package/dist/api/recall/finish.d.ts +185 -0
  96. package/dist/api/recall/finish.js +301 -0
  97. package/dist/api/{recall-pipeline.d.ts → recall/pipeline.d.ts} +12 -8
  98. package/dist/api/{recall-pipeline.js → recall/pipeline.js} +185 -101
  99. package/dist/api/recall/recall.d.ts +6 -0
  100. package/dist/api/{recall.js → recall/recall.js} +116 -72
  101. package/dist/api/recall/render.d.ts +39 -0
  102. package/dist/api/recall/render.js +60 -0
  103. package/dist/api/{recall-request.d.ts → recall/request.d.ts} +7 -5
  104. package/dist/api/recall/request.js +261 -0
  105. package/dist/api/{recall-cli.d.ts → recall/rows.d.ts} +18 -12
  106. package/dist/api/{recall-cli.js → recall/rows.js} +28 -27
  107. package/dist/api/{recall-types.d.ts → recall/types.d.ts} +95 -68
  108. package/dist/api/{recall-types.js → recall/types.js} +1 -1
  109. package/dist/api/session-end.d.ts +36 -8
  110. package/dist/api/session-end.js +71 -25
  111. package/dist/api/{auto-sleep.d.ts → sleep/auto-sleep.d.ts} +9 -5
  112. package/dist/api/{auto-sleep.js → sleep/auto-sleep.js} +7 -12
  113. package/dist/api/sleep/dormant.d.ts +25 -0
  114. package/dist/api/sleep/dormant.js +64 -0
  115. package/dist/api/{learn.d.ts → sleep/learn.d.ts} +5 -4
  116. package/dist/api/sleep/learn.js +138 -0
  117. package/dist/api/sleep/sleep-run.d.ts +38 -0
  118. package/dist/api/{sleep-run.js → sleep/sleep-run.js} +54 -45
  119. package/dist/api/{sleep.d.ts → sleep/sleep.d.ts} +17 -11
  120. package/dist/api/sleep/sleep.js +9 -0
  121. package/dist/api/status.d.ts +3 -1
  122. package/dist/api/status.js +3 -1
  123. package/dist/api/store-init.d.ts +4 -1
  124. package/dist/api/store-init.js +4 -1
  125. package/dist/api/tokens.d.ts +10 -9
  126. package/dist/api/tokens.js +9 -10
  127. package/dist/api/types.d.ts +27 -12
  128. package/dist/api/types.js +13 -4
  129. package/dist/capture/caller-session.d.ts +8 -2
  130. package/dist/capture/caller-session.js +16 -6
  131. package/dist/capture/capture-error.d.ts +3 -1
  132. package/dist/capture/capture-error.js +3 -1
  133. package/dist/capture/codex-patch.js +7 -2
  134. package/dist/capture/command.d.ts +4 -2
  135. package/dist/capture/command.js +34 -15
  136. package/dist/capture/compact-resume-caller.js +15 -8
  137. package/dist/capture/compact.d.ts +8 -5
  138. package/dist/capture/compact.js +34 -23
  139. package/dist/capture/compaction-items-caller.js +9 -3
  140. package/dist/capture/compaction-record.d.ts +4 -3
  141. package/dist/capture/compaction-record.js +20 -12
  142. package/dist/capture/compaction-spool.d.ts +18 -9
  143. package/dist/capture/compaction-spool.js +105 -63
  144. package/dist/capture/copilot-transcript.d.ts +11 -3
  145. package/dist/capture/copilot-transcript.js +16 -6
  146. package/dist/capture/extract.js +20 -8
  147. package/dist/capture/failure-caller.js +23 -12
  148. package/dist/capture/failure-reading.d.ts +10 -3
  149. package/dist/capture/failure-reading.js +24 -7
  150. package/dist/capture/pre-compact-caller.js +11 -4
  151. package/dist/capture/session-digest.d.ts +15 -4
  152. package/dist/capture/session-digest.js +39 -13
  153. package/dist/capture/session-end-caller.d.ts +4 -1
  154. package/dist/capture/session-end-caller.js +20 -8
  155. package/dist/capture/session-texts.d.ts +6 -2
  156. package/dist/capture/session-texts.js +22 -7
  157. package/dist/capture/session-worker.d.ts +4 -2
  158. package/dist/capture/session-worker.js +58 -17
  159. package/dist/capture/transcript.d.ts +13 -4
  160. package/dist/capture/transcript.js +32 -10
  161. package/dist/capture/working-state.d.ts +13 -4
  162. package/dist/capture/working-state.js +50 -56
  163. package/dist/cli/api-context.d.ts +14 -2
  164. package/dist/cli/api-context.js +45 -2
  165. package/dist/cli/audit.js +33 -33
  166. package/dist/cli/auth.js +23 -31
  167. package/dist/cli/briefs.d.ts +1 -1
  168. package/dist/cli/briefs.js +20 -15
  169. package/dist/cli/card.d.ts +1 -1
  170. package/dist/cli/card.js +56 -73
  171. package/dist/cli/client.d.ts +12 -5
  172. package/dist/cli/client.js +53 -23
  173. package/dist/cli/compact-resume-payload.d.ts +4 -1
  174. package/dist/cli/compact-resume-payload.js +12 -5
  175. package/dist/cli/context.js +43 -18
  176. package/dist/cli/continuity.d.ts +5 -5
  177. package/dist/cli/continuity.js +90 -107
  178. package/dist/cli/curate.d.ts +5 -4
  179. package/dist/cli/curate.js +55 -77
  180. package/dist/cli/dag.d.ts +1 -1
  181. package/dist/cli/dag.js +14 -17
  182. package/dist/cli/decisions.js +30 -30
  183. package/dist/cli/eval.js +16 -21
  184. package/dist/cli/exit.d.ts +4 -1
  185. package/dist/cli/exit.js +10 -2
  186. package/dist/cli/explain.js +12 -11
  187. package/dist/cli/flag-values.d.ts +1 -1
  188. package/dist/cli/flag-values.js +9 -18
  189. package/dist/cli/github.d.ts +6 -0
  190. package/dist/cli/github.js +25 -13
  191. package/dist/cli/goals.d.ts +1 -1
  192. package/dist/cli/goals.js +39 -56
  193. package/dist/cli/graph.d.ts +1 -1
  194. package/dist/cli/graph.js +15 -11
  195. package/dist/cli/hook-runtime.d.ts +34 -10
  196. package/dist/cli/hook-runtime.js +41 -16
  197. package/dist/cli/incidents.d.ts +1 -1
  198. package/dist/cli/incidents.js +25 -25
  199. package/dist/cli/init.d.ts +1 -1
  200. package/dist/cli/init.js +35 -20
  201. package/dist/cli/install-steps.d.ts +12 -3
  202. package/dist/cli/install-steps.js +42 -18
  203. package/dist/cli/last-sleep.d.ts +4 -1
  204. package/dist/cli/last-sleep.js +9 -4
  205. package/dist/cli/maintenance.d.ts +1 -1
  206. package/dist/cli/maintenance.js +11 -12
  207. package/dist/cli/notes.d.ts +1 -1
  208. package/dist/cli/notes.js +8 -5
  209. package/dist/cli/object-verbs.d.ts +5 -5
  210. package/dist/cli/object-verbs.js +13 -16
  211. package/dist/cli/open-browser.js +11 -2
  212. package/dist/cli/playbooks.d.ts +3 -3
  213. package/dist/cli/playbooks.js +40 -32
  214. package/dist/cli/predictions.js +17 -22
  215. package/dist/cli/print.js +4 -2
  216. package/dist/cli/projects.js +21 -11
  217. package/dist/cli/quality-repair-once.d.ts +1 -1
  218. package/dist/cli/quality-repair-once.js +7 -6
  219. package/dist/cli/recall.js +129 -93
  220. package/dist/cli/refine-llm.d.ts +15 -4
  221. package/dist/cli/refine-llm.js +17 -7
  222. package/dist/cli/remember.js +51 -55
  223. package/dist/cli/scheduler.d.ts +4 -1
  224. package/dist/cli/scheduler.js +9 -5
  225. package/dist/cli/serve.js +28 -18
  226. package/dist/cli/session-hooks.d.ts +2 -6
  227. package/dist/cli/session-hooks.js +140 -112
  228. package/dist/cli/setup.d.ts +1 -1
  229. package/dist/cli/setup.js +56 -34
  230. package/dist/cli/shared.d.ts +4 -2
  231. package/dist/cli/shared.js +26 -11
  232. package/dist/cli/slack.js +15 -24
  233. package/dist/cli/sleep-render.d.ts +3 -1
  234. package/dist/cli/sleep-render.js +8 -5
  235. package/dist/cli/sleep.js +16 -8
  236. package/dist/cli/status.d.ts +4 -4
  237. package/dist/cli/status.js +32 -27
  238. package/dist/cli/stdin.d.ts +10 -3
  239. package/dist/cli/stdin.js +10 -3
  240. package/dist/cli/transfer.d.ts +4 -4
  241. package/dist/cli/transfer.js +97 -82
  242. package/dist/cli/usage.d.ts +1 -1
  243. package/dist/cli/usage.js +1 -1
  244. package/dist/cli/verb-row.d.ts +2 -0
  245. package/dist/cli/verbs/health.js +2 -0
  246. package/dist/cli/verbs/memory.js +47 -53
  247. package/dist/cli/verbs/objects.js +16 -7
  248. package/dist/cli/verbs/sessions.js +4 -2
  249. package/dist/cli/versioned-verbs.d.ts +8 -7
  250. package/dist/cli/versioned-verbs.js +31 -21
  251. package/dist/cli.js +14 -18
  252. package/dist/connectors/dlq.d.ts +6 -6
  253. package/dist/connectors/dlq.js +12 -7
  254. package/dist/connectors/github/backfill.d.ts +4 -4
  255. package/dist/connectors/github/backfill.js +6 -4
  256. package/dist/connectors/github/deletion.d.ts +6 -4
  257. package/dist/connectors/github/deletion.js +5 -4
  258. package/dist/connectors/github/dlq.d.ts +8 -6
  259. package/dist/connectors/github/dlq.js +11 -5
  260. package/dist/connectors/github/ingest.d.ts +2 -2
  261. package/dist/connectors/github/ingest.js +9 -5
  262. package/dist/connectors/github/octokit-client.d.ts +3 -1
  263. package/dist/connectors/github/octokit-client.js +7 -2
  264. package/dist/connectors/github/ratelimit.d.ts +6 -2
  265. package/dist/connectors/github/ratelimit.js +6 -2
  266. package/dist/connectors/github/signature.d.ts +14 -3
  267. package/dist/connectors/github/signature.js +17 -3
  268. package/dist/connectors/github/tenant-routing.d.ts +6 -4
  269. package/dist/connectors/github/tenant-routing.js +6 -5
  270. package/dist/connectors/github/transform.js +50 -67
  271. package/dist/connectors/github/types.d.ts +10 -3
  272. package/dist/connectors/github/types.js +6 -2
  273. package/dist/connectors/github/webhook.d.ts +5 -5
  274. package/dist/connectors/github/webhook.js +36 -23
  275. package/dist/connectors/ingest.d.ts +5 -3
  276. package/dist/connectors/ingest.js +3 -3
  277. package/dist/connectors/slack/backfill.d.ts +5 -5
  278. package/dist/connectors/slack/backfill.js +3 -3
  279. package/dist/connectors/slack/deletion.d.ts +4 -4
  280. package/dist/connectors/slack/deletion.js +6 -5
  281. package/dist/connectors/slack/dlq.d.ts +4 -4
  282. package/dist/connectors/slack/dlq.js +6 -6
  283. package/dist/connectors/slack/ingest.d.ts +6 -4
  284. package/dist/connectors/slack/ingest.js +5 -4
  285. package/dist/connectors/slack/signature.d.ts +4 -1
  286. package/dist/connectors/slack/tenant-routing.d.ts +6 -4
  287. package/dist/connectors/slack/tenant-routing.js +6 -5
  288. package/dist/connectors/slack/transform.d.ts +6 -2
  289. package/dist/connectors/slack/transform.js +6 -2
  290. package/dist/connectors/slack/types.d.ts +3 -1
  291. package/dist/connectors/slack/web-client.js +8 -3
  292. package/dist/connectors/slack/webhook.d.ts +5 -5
  293. package/dist/connectors/slack/webhook.js +19 -11
  294. package/dist/connectors/slack/workspaces.d.ts +7 -3
  295. package/dist/connectors/slack/workspaces.js +7 -3
  296. package/dist/connectors/store.d.ts +8 -0
  297. package/dist/connectors/store.js +2 -0
  298. package/dist/consolidate/conflicts.js +24 -10
  299. package/dist/consolidate/dag-summary.js +2 -1
  300. package/dist/consolidate/dag.d.ts +10 -5
  301. package/dist/consolidate/dag.js +45 -39
  302. package/dist/consolidate/decay.js +19 -6
  303. package/dist/consolidate/dedupe.d.ts +14 -5
  304. package/dist/consolidate/dedupe.js +28 -17
  305. package/dist/consolidate/flush-units.d.ts +4 -1
  306. package/dist/consolidate/flush-units.js +4 -1
  307. package/dist/consolidate/half-life-migration.d.ts +18 -8
  308. package/dist/consolidate/half-life-migration.js +48 -18
  309. package/dist/consolidate/llm-passes.js +27 -11
  310. package/dist/consolidate/memory-value-weights.d.ts +6 -2
  311. package/dist/consolidate/memory-value-weights.js +6 -2
  312. package/dist/consolidate/memory-value.d.ts +30 -10
  313. package/dist/consolidate/memory-value.js +37 -14
  314. package/dist/consolidate/merge.d.ts +4 -1
  315. package/dist/consolidate/merge.js +47 -37
  316. package/dist/consolidate/overlap-index.d.ts +8 -2
  317. package/dist/consolidate/overlap-index.js +11 -4
  318. package/dist/consolidate/physics-pass.d.ts +3 -1
  319. package/dist/consolidate/physics-pass.js +10 -7
  320. package/dist/consolidate/replay.d.ts +11 -4
  321. package/dist/consolidate/replay.js +19 -7
  322. package/dist/consolidate/run.d.ts +13 -5
  323. package/dist/consolidate/run.js +4 -4
  324. package/dist/consolidate/sleep.d.ts +14 -6
  325. package/dist/consolidate/sleep.js +42 -39
  326. package/dist/consolidate/trace.d.ts +7 -2
  327. package/dist/consolidate/trace.js +7 -2
  328. package/dist/consolidate/traces.js +27 -30
  329. package/dist/core/ablation.d.ts +9 -3
  330. package/dist/core/ablation.js +14 -4
  331. package/dist/core/active-scope.d.ts +3 -1
  332. package/dist/core/active-scope.js +3 -1
  333. package/dist/core/agent-memory-tools.d.ts +2 -0
  334. package/dist/core/agent-memory-tools.js +2 -0
  335. package/dist/core/ambient.d.ts +4 -3
  336. package/dist/core/ambient.js +8 -6
  337. package/dist/core/api-errors.d.ts +9 -3
  338. package/dist/core/api-errors.js +9 -3
  339. package/dist/core/capture-contract.d.ts +4 -1
  340. package/dist/core/capture-contract.js +27 -8
  341. package/dist/core/compare.d.ts +24 -8
  342. package/dist/core/compare.js +24 -8
  343. package/dist/core/config.d.ts +18 -9
  344. package/dist/core/config.js +38 -29
  345. package/dist/core/cosine.d.ts +4 -1
  346. package/dist/core/cosine.js +4 -1
  347. package/dist/core/handoff.d.ts +7 -2
  348. package/dist/core/handoff.js +4 -1
  349. package/dist/core/markdown.js +22 -17
  350. package/dist/core/memory-audit.js +14 -3
  351. package/dist/core/memory-quality.d.ts +12 -3
  352. package/dist/core/memory-quality.js +57 -21
  353. package/dist/core/memory.d.ts +87 -30
  354. package/dist/core/memory.js +82 -33
  355. package/dist/core/merged-row.d.ts +8 -2
  356. package/dist/core/merged-row.js +10 -3
  357. package/dist/core/package-root.d.ts +3 -1
  358. package/dist/core/package-root.js +3 -1
  359. package/dist/core/particle-refresh.d.ts +8 -0
  360. package/dist/core/particle-refresh.js +22 -0
  361. package/dist/core/physics-config.d.ts +4 -1
  362. package/dist/core/physics-config.js +6 -2
  363. package/dist/core/physics.d.ts +39 -11
  364. package/dist/core/physics.js +71 -21
  365. package/dist/core/project-identity.d.ts +34 -17
  366. package/dist/core/project-identity.js +35 -18
  367. package/dist/core/project-remote.d.ts +8 -4
  368. package/dist/core/project-remote.js +31 -14
  369. package/dist/core/recall-scope.d.ts +33 -11
  370. package/dist/core/recall-scope.js +42 -15
  371. package/dist/core/rejection-digest.d.ts +7 -0
  372. package/dist/core/rejection-digest.js +13 -0
  373. package/dist/core/salience.d.ts +3 -1
  374. package/dist/core/salience.js +10 -4
  375. package/dist/core/search-types.d.ts +15 -2
  376. package/dist/core/search-types.js +11 -0
  377. package/dist/dashboard/dashboard-actions.d.ts +2 -2
  378. package/dist/dashboard/dashboard-actions.js +18 -7
  379. package/dist/dashboard/dashboard-queries.js +2 -7
  380. package/dist/dashboard/dashboard-snapshot.d.ts +2 -2
  381. package/dist/dashboard/dashboard-snapshot.js +5 -7
  382. package/dist/dashboard/dashboard.js +22 -8
  383. package/dist/db/backup.js +2 -2
  384. package/dist/db/busy.d.ts +10 -3
  385. package/dist/db/busy.js +27 -5
  386. package/dist/db/connect.d.ts +10 -2
  387. package/dist/db/connect.js +8 -2
  388. package/dist/db/continuity.d.ts +1 -1
  389. package/dist/db/continuity.js +27 -11
  390. package/dist/db/meta.d.ts +4 -1
  391. package/dist/db/meta.js +4 -1
  392. package/dist/db/migrate.d.ts +10 -5
  393. package/dist/db/migrate.js +40 -20
  394. package/dist/db/migrations/index.d.ts +1 -1
  395. package/dist/db/migrations/index.js +3 -1
  396. package/dist/db/migrations/types.d.ts +2 -1
  397. package/dist/db/migrations/v11.js +1 -0
  398. package/dist/db/migrations/v12.js +2 -1
  399. package/dist/db/migrations/v14.js +2 -0
  400. package/dist/db/migrations/v15.js +4 -2
  401. package/dist/db/migrations/v16.js +6 -3
  402. package/dist/db/migrations/v17.js +2 -1
  403. package/dist/db/migrations/v19.js +4 -2
  404. package/dist/db/migrations/v20.js +2 -1
  405. package/dist/db/migrations/v22.js +12 -6
  406. package/dist/db/migrations/v23.js +6 -3
  407. package/dist/db/migrations/v24.js +6 -3
  408. package/dist/db/migrations/v25.js +4 -2
  409. package/dist/db/migrations/v26.js +4 -2
  410. package/dist/db/migrations/v27.js +6 -3
  411. package/dist/db/migrations/v28.js +4 -2
  412. package/dist/db/migrations/v29.js +4 -2
  413. package/dist/db/migrations/v30.js +6 -3
  414. package/dist/db/migrations/v31.js +4 -2
  415. package/dist/db/migrations/v32.js +6 -3
  416. package/dist/db/migrations/v33.js +4 -2
  417. package/dist/db/migrations/v34.js +2 -1
  418. package/dist/db/migrations/v35.js +2 -1
  419. package/dist/db/migrations/v36.js +2 -1
  420. package/dist/db/migrations/v37.js +10 -5
  421. package/dist/db/migrations/v38.js +10 -5
  422. package/dist/db/migrations/v39.js +14 -6
  423. package/dist/db/migrations/v40.js +4 -2
  424. package/dist/db/migrations/v41.js +4 -2
  425. package/dist/db/migrations/v42.js +2 -1
  426. package/dist/db/migrations/v44.js +4 -2
  427. package/dist/db/migrations/v45.js +4 -2
  428. package/dist/db/migrations/v49.js +2 -1
  429. package/dist/db/migrations/v50.js +4 -2
  430. package/dist/db/migrations/v51.js +4 -2
  431. package/dist/db/migrations/v52.js +2 -1
  432. package/dist/db/migrations/v53.js +8 -4
  433. package/dist/db/migrations/v54.js +2 -1
  434. package/dist/db/migrations/v55.js +4 -2
  435. package/dist/db/migrations/v56.d.ts +3 -0
  436. package/dist/db/migrations/v56.js +28 -0
  437. package/dist/db/open.d.ts +24 -12
  438. package/dist/db/open.js +25 -13
  439. package/dist/db/physics-state.d.ts +8 -8
  440. package/dist/db/physics-state.js +17 -50
  441. package/dist/db/raw-archive-mirror-cleanup.d.ts +4 -2
  442. package/dist/db/raw-archive-mirror-cleanup.js +6 -4
  443. package/dist/db/request-stores.d.ts +20 -5
  444. package/dist/db/request-stores.js +15 -5
  445. package/dist/db/tables.d.ts +2 -1
  446. package/dist/db/tables.js +12 -4
  447. package/dist/db/vector-store.d.ts +13 -4
  448. package/dist/db/vector-store.js +35 -14
  449. package/dist/db/wal-checkpointer.d.ts +2 -1
  450. package/dist/db/wal-checkpointer.js +19 -7
  451. package/dist/doctor.d.ts +7 -1
  452. package/dist/doctor.js +128 -46
  453. package/dist/embeddings/local.d.ts +8 -4
  454. package/dist/embeddings/local.js +11 -7
  455. package/dist/embeddings/provider.d.ts +19 -10
  456. package/dist/embeddings/provider.js +32 -27
  457. package/dist/embeddings/transformers.d.ts +16 -4
  458. package/dist/embeddings/transformers.js +32 -15
  459. package/dist/entry/json-hooks.d.ts +1 -1
  460. package/dist/entry/json-hooks.js +1 -1
  461. package/dist/entry/project-identity.js +2 -1
  462. package/dist/entry/session-text.d.ts +1 -1
  463. package/dist/entry/session-text.js +1 -1
  464. package/dist/entry/sqlite-handles.d.ts +10 -0
  465. package/dist/entry/sqlite-handles.js +9 -0
  466. package/dist/entry/store-kit.d.ts +50 -0
  467. package/dist/entry/store-kit.js +27 -0
  468. package/dist/entry/testing.d.ts +6 -0
  469. package/dist/entry/testing.js +7 -0
  470. package/dist/eval/eval-stats.d.ts +27 -8
  471. package/dist/eval/eval-stats.js +17 -5
  472. package/dist/eval/eval-suite.d.ts +3 -1
  473. package/dist/eval/eval-suite.js +409 -187
  474. package/dist/eval/eval.d.ts +8 -2
  475. package/dist/eval/eval.js +8 -2
  476. package/dist/eval/judgment.js +17 -7
  477. package/dist/graph/delta.d.ts +9 -42
  478. package/dist/graph/delta.js +17 -11
  479. package/dist/graph/extract.d.ts +10 -7
  480. package/dist/graph/extract.js +57 -25
  481. package/dist/graph/recall.d.ts +12 -4
  482. package/dist/graph/recall.js +30 -13
  483. package/dist/graph/stream.d.ts +18 -6
  484. package/dist/graph/stream.js +32 -10
  485. package/dist/graph/view.d.ts +19 -6
  486. package/dist/graph/view.js +42 -17
  487. package/dist/hooks/codex-session.js +2 -2
  488. package/dist/hooks/codex-wrapper.d.ts +3 -1
  489. package/dist/hooks/codex-wrapper.js +9 -4
  490. package/dist/hooks/copilot.d.ts +19 -5
  491. package/dist/hooks/copilot.js +54 -15
  492. package/dist/hooks/hook-blocks.d.ts +4 -1
  493. package/dist/hooks/hook-blocks.js +8 -3
  494. package/dist/hooks/json-hooks.d.ts +9 -5
  495. package/dist/hooks/json-hooks.js +72 -33
  496. package/dist/hooks/opencode.js +15 -5
  497. package/dist/hooks/shared.d.ts +27 -8
  498. package/dist/hooks/shared.js +57 -16
  499. package/dist/importers/core.d.ts +12 -4
  500. package/dist/importers/core.js +11 -10
  501. package/dist/importers/markdown-parse.d.ts +15 -5
  502. package/dist/importers/markdown-parse.js +16 -7
  503. package/dist/importers/markdown.js +6 -9
  504. package/dist/importers/sources.js +10 -23
  505. package/dist/importers/vault.d.ts +3 -3
  506. package/dist/importers/vault.js +61 -45
  507. package/dist/index.d.ts +33 -7
  508. package/dist/index.js +26 -8
  509. package/dist/learn/autolearn.d.ts +21 -6
  510. package/dist/learn/autolearn.js +57 -26
  511. package/dist/learn/churn-git.d.ts +4 -1
  512. package/dist/learn/churn-git.js +29 -5
  513. package/dist/learn/extract.d.ts +4 -1
  514. package/dist/learn/extract.js +17 -10
  515. package/dist/learn/forward-claim-detector.d.ts +17 -5
  516. package/dist/learn/forward-claim-detector.js +34 -15
  517. package/dist/learn/invalidation.d.ts +12 -6
  518. package/dist/learn/invalidation.js +62 -28
  519. package/dist/learn/roots.d.ts +3 -0
  520. package/dist/learn/roots.js +5 -0
  521. package/dist/mcp/admin-tools.d.ts +5 -5
  522. package/dist/mcp/admin-tools.js +28 -23
  523. package/dist/mcp/format.d.ts +1 -1
  524. package/dist/mcp/format.js +4 -2
  525. package/dist/mcp/framing.d.ts +3 -1
  526. package/dist/mcp/framing.js +20 -8
  527. package/dist/mcp/memory-tools.d.ts +3 -3
  528. package/dist/mcp/memory-tools.js +21 -20
  529. package/dist/mcp/protocol.d.ts +32 -16
  530. package/dist/mcp/protocol.js +12 -9
  531. package/dist/mcp/recall-tools.d.ts +3 -3
  532. package/dist/mcp/recall-tools.js +62 -74
  533. package/dist/mcp/request.d.ts +7 -5
  534. package/dist/mcp/request.js +61 -77
  535. package/dist/mcp/server.d.ts +3 -1
  536. package/dist/mcp/server.js +8 -3
  537. package/dist/mcp/session-state.d.ts +1 -1
  538. package/dist/mcp/session-state.js +4 -3
  539. package/dist/mcp/shared-gate.d.ts +3 -2
  540. package/dist/mcp/shared-gate.js +3 -2
  541. package/dist/mcp/stdio.d.ts +6 -3
  542. package/dist/mcp/stdio.js +59 -23
  543. package/dist/mcp/tool-args.d.ts +4 -1
  544. package/dist/mcp/tool-args.js +8 -3
  545. package/dist/mcp/tools.js +76 -32
  546. package/dist/objects/customer-notes.d.ts +12 -10
  547. package/dist/objects/customer-notes.js +21 -15
  548. package/dist/objects/decisions.d.ts +18 -10
  549. package/dist/objects/decisions.js +23 -17
  550. package/dist/objects/descriptor.js +2 -1
  551. package/dist/objects/fields.d.ts +4 -1
  552. package/dist/objects/fields.js +6 -2
  553. package/dist/objects/incidents.d.ts +14 -16
  554. package/dist/objects/incidents.js +29 -30
  555. package/dist/objects/lifecycle.d.ts +0 -4
  556. package/dist/objects/lifecycle.js +21 -24
  557. package/dist/objects/policies.d.ts +12 -16
  558. package/dist/objects/policies.js +17 -21
  559. package/dist/objects/processes.d.ts +16 -10
  560. package/dist/objects/processes.js +20 -15
  561. package/dist/objects/project-briefs.d.ts +13 -14
  562. package/dist/objects/project-briefs.js +33 -39
  563. package/dist/objects/skills.d.ts +10 -12
  564. package/dist/objects/skills.js +17 -22
  565. package/dist/postinstall.js +15 -7
  566. package/dist/predictions/planning-fallacy.d.ts +19 -6
  567. package/dist/predictions/planning-fallacy.js +4 -2
  568. package/dist/rerankers/clef.d.ts +8 -2
  569. package/dist/rerankers/clef.js +14 -9
  570. package/dist/rerankers/cross-encoder.d.ts +2 -1
  571. package/dist/rerankers/cross-encoder.js +19 -9
  572. package/dist/rerankers/index.js +2 -1
  573. package/dist/rerankers/jev.js +2 -1
  574. package/dist/rerankers/llm.d.ts +6 -2
  575. package/dist/rerankers/llm.js +8 -3
  576. package/dist/rerankers/remote.d.ts +3 -1
  577. package/dist/rerankers/remote.js +5 -2
  578. package/dist/rerankers/types.d.ts +6 -2
  579. package/dist/search/bm25-search.d.ts +3 -1
  580. package/dist/search/bm25-search.js +15 -2
  581. package/dist/search/boosts.js +4 -3
  582. package/dist/search/embed-memories.d.ts +12 -4
  583. package/dist/search/embed-memories.js +96 -58
  584. package/dist/search/engine.d.ts +11 -0
  585. package/dist/search/engine.js +14 -0
  586. package/dist/search/goal-boost.d.ts +10 -3
  587. package/dist/search/goal-boost.js +13 -6
  588. package/dist/search/hybrid-score.d.ts +4 -1
  589. package/dist/search/hybrid-score.js +4 -1
  590. package/dist/search/hybrid.d.ts +23 -8
  591. package/dist/search/hybrid.js +12 -7
  592. package/dist/search/multihop.js +14 -13
  593. package/dist/search/path-context.d.ts +10 -3
  594. package/dist/search/path-context.js +10 -3
  595. package/dist/search/physics-search.d.ts +9 -4
  596. package/dist/search/physics-search.js +38 -14
  597. package/dist/search/rerank.d.ts +2 -1
  598. package/dist/search/rerank.js +2 -1
  599. package/dist/search/rrf.d.ts +14 -5
  600. package/dist/search/rrf.js +11 -4
  601. package/dist/search/vector.d.ts +8 -2
  602. package/dist/search/vector.js +14 -8
  603. package/dist/server/auth.d.ts +19 -15
  604. package/dist/server/auth.js +68 -38
  605. package/dist/server/boot.d.ts +4 -1
  606. package/dist/server/boot.js +115 -67
  607. package/dist/server/client-ip.d.ts +17 -5
  608. package/dist/server/client-ip.js +56 -21
  609. package/dist/server/cursor.d.ts +10 -3
  610. package/dist/server/cursor.js +10 -3
  611. package/dist/server/deadline.d.ts +5 -2
  612. package/dist/server/deadline.js +10 -3
  613. package/dist/server/key-check-bounds.js +12 -4
  614. package/dist/server/lifecycle.d.ts +4 -1
  615. package/dist/server/lifecycle.js +10 -4
  616. package/dist/server/mcp-http.d.ts +2 -1
  617. package/dist/server/mcp-http.js +37 -22
  618. package/dist/server/rate-limit.d.ts +17 -5
  619. package/dist/server/rate-limit.js +55 -26
  620. package/dist/server/ready.js +7 -4
  621. package/dist/server/request.d.ts +15 -4
  622. package/dist/server/request.js +42 -15
  623. package/dist/server/route-checks.d.ts +4 -1
  624. package/dist/server/route-checks.js +8 -3
  625. package/dist/server/route-table.d.ts +8 -6
  626. package/dist/server/route-table.js +550 -97
  627. package/dist/server/routes/admin.d.ts +7 -7
  628. package/dist/server/routes/admin.js +36 -15
  629. package/dist/server/routes/customer-notes.d.ts +5 -5
  630. package/dist/server/routes/customer-notes.js +5 -4
  631. package/dist/server/routes/decisions.d.ts +5 -5
  632. package/dist/server/routes/decisions.js +12 -6
  633. package/dist/server/routes/incidents.d.ts +5 -5
  634. package/dist/server/routes/incidents.js +10 -4
  635. package/dist/server/routes/memories.d.ts +8 -8
  636. package/dist/server/routes/memories.js +12 -17
  637. package/dist/server/routes/object-routes.d.ts +8 -5
  638. package/dist/server/routes/object-routes.js +4 -2
  639. package/dist/server/routes/policies.d.ts +6 -6
  640. package/dist/server/routes/policies.js +11 -4
  641. package/dist/server/routes/predictions.d.ts +5 -5
  642. package/dist/server/routes/predictions.js +9 -4
  643. package/dist/server/routes/processes.d.ts +5 -5
  644. package/dist/server/routes/processes.js +15 -6
  645. package/dist/server/routes/project-briefs.d.ts +6 -6
  646. package/dist/server/routes/project-briefs.js +3 -2
  647. package/dist/server/routes/recall.d.ts +3 -3
  648. package/dist/server/routes/recall.js +21 -10
  649. package/dist/server/routes/skills.d.ts +6 -6
  650. package/dist/server/routes/skills.js +12 -4
  651. package/dist/server/server-detect.d.ts +24 -8
  652. package/dist/server/server-detect.js +57 -22
  653. package/dist/server/sleep-child.js +16 -10
  654. package/dist/server/sleep-offload.d.ts +8 -5
  655. package/dist/server/sleep-offload.js +40 -18
  656. package/dist/server/tls.d.ts +10 -2
  657. package/dist/server/tls.js +25 -5
  658. package/dist/server/types.d.ts +41 -24
  659. package/dist/server/validation.d.ts +4 -1
  660. package/dist/server/validation.js +22 -9
  661. package/dist/server.d.ts +17 -49
  662. package/dist/server.js +33 -40
  663. package/dist/sharing/global-store.d.ts +6 -12
  664. package/dist/sharing/global-store.js +8 -48
  665. package/dist/sharing/global-sync.d.ts +3 -1
  666. package/dist/sharing/global-sync.js +17 -7
  667. package/dist/sharing/project-merge.d.ts +25 -7
  668. package/dist/sharing/project-merge.js +49 -17
  669. package/dist/sharing/search-both.d.ts +8 -4
  670. package/dist/sharing/search-both.js +28 -14
  671. package/dist/sharing/share.d.ts +8 -4
  672. package/dist/sharing/share.js +40 -18
  673. package/dist/store/ambient.js +10 -5
  674. package/dist/store/audit-event.d.ts +2 -2
  675. package/dist/store/audit-event.js +8 -3
  676. package/dist/store/audit.d.ts +6 -3
  677. package/dist/store/audit.js +16 -6
  678. package/dist/store/auth.d.ts +4 -2
  679. package/dist/store/auth.js +63 -20
  680. package/dist/store/busy.d.ts +9 -0
  681. package/dist/store/busy.js +16 -0
  682. package/dist/store/candidates.d.ts +12 -5
  683. package/dist/store/candidates.js +90 -41
  684. package/dist/store/capture-write.d.ts +2 -1
  685. package/dist/store/capture-write.js +2 -1
  686. package/dist/store/card-detail.d.ts +4 -4
  687. package/dist/store/card-detail.js +15 -8
  688. package/dist/store/cards.d.ts +24 -10
  689. package/dist/store/cards.js +97 -63
  690. package/dist/store/compaction-caller.d.ts +2 -1
  691. package/dist/store/compaction-caller.js +2 -1
  692. package/dist/store/compactions-record.d.ts +14 -8
  693. package/dist/store/compactions-record.js +101 -37
  694. package/dist/store/compactions.js +35 -15
  695. package/dist/store/conflicts.d.ts +16 -5
  696. package/dist/store/conflicts.js +104 -48
  697. package/dist/store/connectors/dlq.d.ts +17 -5
  698. package/dist/store/connectors/dlq.js +58 -6
  699. package/dist/store/connectors/event-log.d.ts +122 -0
  700. package/dist/store/connectors/event-log.js +25 -0
  701. package/dist/store/connectors/github.d.ts +6 -3
  702. package/dist/store/connectors/github.js +30 -48
  703. package/dist/store/connectors/slack.d.ts +2 -1
  704. package/dist/store/connectors/slack.js +31 -47
  705. package/dist/store/dashboard-reads.d.ts +7 -3
  706. package/dist/store/dashboard-reads.js +32 -10
  707. package/dist/store/delete-and-batch.d.ts +17 -11
  708. package/dist/store/delete-and-batch.js +70 -28
  709. package/dist/store/delivery-recorder.d.ts +10 -7
  710. package/dist/store/delivery-recorder.js +70 -37
  711. package/dist/store/descendant-page.d.ts +2 -1
  712. package/dist/store/descendant-page.js +26 -10
  713. package/dist/store/diagnostics.d.ts +2 -1
  714. package/dist/store/diagnostics.js +2 -1
  715. package/dist/store/doctor-reads.d.ts +2 -1
  716. package/dist/store/doctor-reads.js +13 -5
  717. package/dist/store/dormant.d.ts +19 -11
  718. package/dist/store/dormant.js +45 -19
  719. package/dist/store/embeddings/index.d.ts +13 -9
  720. package/dist/store/embeddings/index.js +19 -12
  721. package/dist/store/entry-reads.d.ts +72 -21
  722. package/dist/store/entry-reads.js +215 -69
  723. package/dist/store/entry-row.d.ts +10 -6
  724. package/dist/store/entry-row.js +26 -14
  725. package/dist/store/entry-writes.d.ts +28 -13
  726. package/dist/store/entry-writes.js +61 -22
  727. package/dist/store/failure-log-at.js +1 -1
  728. package/dist/store/failure-log.d.ts +4 -2
  729. package/dist/store/failure-log.js +13 -6
  730. package/dist/store/gated-write.d.ts +3 -3
  731. package/dist/store/gated-write.js +3 -3
  732. package/dist/store/goals.d.ts +5 -4
  733. package/dist/store/goals.js +11 -12
  734. package/dist/store/graph-apply.d.ts +21 -0
  735. package/dist/{graph/write.js → store/graph-apply.js} +31 -11
  736. package/dist/store/graph-queue.d.ts +9 -6
  737. package/dist/store/graph-queue.js +15 -10
  738. package/dist/store/graph-reads.d.ts +16 -11
  739. package/dist/store/graph-reads.js +29 -19
  740. package/dist/store/graph-rows.d.ts +41 -3
  741. package/dist/store/graph-rows.js +10 -7
  742. package/dist/store/graph-view-rows.js +15 -7
  743. package/dist/store/graph-writes.d.ts +16 -10
  744. package/dist/store/graph-writes.js +59 -36
  745. package/dist/store/half-life.js +2 -2
  746. package/dist/store/handoffs.d.ts +13 -7
  747. package/dist/store/handoffs.js +44 -22
  748. package/dist/store/index-and-stats.d.ts +2 -2
  749. package/dist/store/index-and-stats.js +6 -5
  750. package/dist/store/index.d.ts +4 -2
  751. package/dist/store/index.js +2 -1
  752. package/dist/store/key-audit.d.ts +2 -1
  753. package/dist/store/key-audit.js +2 -1
  754. package/dist/store/key-writes.d.ts +2 -1
  755. package/dist/store/key-writes.js +9 -2
  756. package/dist/store/ledger-turn.d.ts +4 -1
  757. package/dist/store/ledger-turn.js +7 -2
  758. package/dist/store/mirrors.d.ts +11 -4
  759. package/dist/store/mirrors.js +96 -19
  760. package/dist/store/narrow.d.ts +6 -0
  761. package/dist/store/narrow.js +11 -0
  762. package/dist/store/open.d.ts +6 -3
  763. package/dist/store/open.js +20 -10
  764. package/dist/store/pilot-arm.d.ts +2 -1
  765. package/dist/store/pilot-arm.js +18 -6
  766. package/dist/store/planning-fallacy-evidence.d.ts +2 -2
  767. package/dist/store/planning-fallacy-evidence.js +8 -5
  768. package/dist/store/port/agent-import.d.ts +62 -0
  769. package/dist/store/port/agent-import.js +2 -0
  770. package/dist/store/port/consolidation.d.ts +129 -0
  771. package/dist/store/port/consolidation.js +2 -0
  772. package/dist/store/port/learning.d.ts +19 -0
  773. package/dist/store/port/learning.js +2 -0
  774. package/dist/store/port/local-files.d.ts +18 -0
  775. package/dist/store/port/local-files.js +2 -0
  776. package/dist/store/port/promotion.d.ts +20 -0
  777. package/dist/store/port/promotion.js +3 -0
  778. package/dist/store/port-groups.d.ts +160 -0
  779. package/dist/store/port-groups.js +2 -0
  780. package/dist/store/port.d.ts +261 -219
  781. package/dist/store/port.js +3 -9
  782. package/dist/store/predictions.d.ts +14 -10
  783. package/dist/store/predictions.js +37 -17
  784. package/dist/store/project-tags.d.ts +4 -1
  785. package/dist/store/project-tags.js +16 -5
  786. package/dist/store/quality-repair.d.ts +8 -4
  787. package/dist/store/quality-repair.js +53 -20
  788. package/dist/store/quarantine.d.ts +1 -0
  789. package/dist/store/quarantine.js +23 -9
  790. package/dist/store/raw-archive.d.ts +5 -4
  791. package/dist/store/raw-archive.js +11 -10
  792. package/dist/store/recall-trace.d.ts +22 -17
  793. package/dist/store/recall-trace.js +128 -64
  794. package/dist/store/rejected-values.d.ts +15 -10
  795. package/dist/store/rejected-values.js +46 -20
  796. package/dist/store/rejection.d.ts +12 -11
  797. package/dist/store/rejection.js +18 -19
  798. package/dist/store/report-reads.d.ts +2 -1
  799. package/dist/store/report-reads.js +2 -1
  800. package/dist/store/rows.d.ts +7 -5
  801. package/dist/store/rows.js +20 -13
  802. package/dist/store/rule-sql.d.ts +7 -3
  803. package/dist/store/rule-sql.js +26 -13
  804. package/dist/store/search-rows.d.ts +16 -11
  805. package/dist/store/search-rows.js +54 -32
  806. package/dist/store/sessions.d.ts +12 -10
  807. package/dist/store/sessions.js +40 -21
  808. package/dist/store/set-aside.d.ts +2 -2
  809. package/dist/store/set-aside.js +18 -5
  810. package/dist/store/sqlite/agent-import.d.ts +3 -0
  811. package/dist/store/sqlite/agent-import.js +77 -0
  812. package/dist/store/sqlite/cards-group.d.ts +6 -0
  813. package/dist/store/sqlite/cards-group.js +37 -0
  814. package/dist/store/sqlite/conflicts-group.d.ts +6 -0
  815. package/dist/store/sqlite/conflicts-group.js +18 -0
  816. package/dist/store/sqlite/connector-events-group.d.ts +2 -1
  817. package/dist/store/sqlite/connector-events-group.js +17 -6
  818. package/dist/store/sqlite/connector-writes-group.d.ts +2 -1
  819. package/dist/store/sqlite/connector-writes-group.js +12 -5
  820. package/dist/store/sqlite/consolidation-group.d.ts +4 -0
  821. package/dist/store/sqlite/consolidation-group.js +64 -0
  822. package/dist/store/sqlite/dag-reads-group.js +1 -1
  823. package/dist/store/sqlite/dormant-group.d.ts +6 -0
  824. package/dist/store/sqlite/dormant-group.js +29 -0
  825. package/dist/store/sqlite/entry-writes-group.d.ts +9 -6
  826. package/dist/store/sqlite/entry-writes-group.js +37 -14
  827. package/dist/store/sqlite/error-codec.d.ts +4 -2
  828. package/dist/store/sqlite/error-codec.js +32 -10
  829. package/dist/store/sqlite/executor-counts.js +2 -1
  830. package/dist/store/sqlite/executor.d.ts +8 -3
  831. package/dist/store/sqlite/executor.js +56 -18
  832. package/dist/store/sqlite/global-promote.d.ts +5 -0
  833. package/dist/store/sqlite/global-promote.js +48 -0
  834. package/dist/store/sqlite/goals-group.d.ts +6 -0
  835. package/dist/store/sqlite/goals-group.js +23 -0
  836. package/dist/store/sqlite/graph-reads-group.d.ts +2 -1
  837. package/dist/store/sqlite/graph-reads-group.js +2 -1
  838. package/dist/store/sqlite/held-connection.d.ts +8 -0
  839. package/dist/store/sqlite/held-connection.js +34 -7
  840. package/dist/store/sqlite/last-recall-group.d.ts +15 -0
  841. package/dist/store/sqlite/last-recall-group.js +62 -0
  842. package/dist/store/sqlite/learning-group.d.ts +4 -0
  843. package/dist/store/sqlite/learning-group.js +17 -0
  844. package/dist/store/sqlite/maintenance-groups.d.ts +6 -0
  845. package/dist/store/sqlite/maintenance-groups.js +61 -0
  846. package/dist/store/sqlite/object-rows.d.ts +6 -3
  847. package/dist/store/sqlite/object-rows.js +34 -5
  848. package/dist/store/sqlite/objects-group.d.ts +5 -4
  849. package/dist/store/sqlite/objects-group.js +97 -38
  850. package/dist/store/sqlite/predictions-group.d.ts +2 -1
  851. package/dist/store/sqlite/predictions-group.js +4 -2
  852. package/dist/store/sqlite/promotion-group.d.ts +3 -0
  853. package/dist/store/sqlite/promotion-group.js +10 -0
  854. package/dist/store/sqlite/quarantine-group.d.ts +2 -1
  855. package/dist/store/sqlite/quarantine-group.js +4 -2
  856. package/dist/store/sqlite/reports-group.d.ts +6 -0
  857. package/dist/store/sqlite/reports-group.js +33 -0
  858. package/dist/store/sqlite/request-scope.d.ts +6 -0
  859. package/dist/store/sqlite/request-scope.js +18 -0
  860. package/dist/store/sqlite/sessions-group.d.ts +6 -0
  861. package/dist/store/sqlite/sessions-group.js +46 -0
  862. package/dist/store/sqlite/store.d.ts +22 -18
  863. package/dist/store/sqlite/store.js +95 -33
  864. package/dist/store/sqlite/vector-pack.js +2 -1
  865. package/dist/store/sqlite/vector-reads-group.js +2 -1
  866. package/dist/store/sqlite/worker-jobs.d.ts +2 -1
  867. package/dist/store/sqlite/worker-jobs.js +19 -7
  868. package/dist/store/sqlite/worker-ops.d.ts +10 -5
  869. package/dist/store/sqlite/worker-ops.js +6 -3
  870. package/dist/store/sqlite/worker-store.d.ts +4 -3
  871. package/dist/store/sqlite/worker-store.js +24 -14
  872. package/dist/store/summaries.d.ts +25 -11
  873. package/dist/store/summaries.js +84 -27
  874. package/dist/store/summary-dirty.d.ts +2 -1
  875. package/dist/store/summary-dirty.js +2 -1
  876. package/dist/store/tenant.d.ts +3 -2
  877. package/dist/store/tenant.js +5 -4
  878. package/dist/store/token-ledger-rows.js +8 -4
  879. package/dist/store/token-ledger.d.ts +19 -13
  880. package/dist/store/token-ledger.js +27 -14
  881. package/dist/store/tombstone-checks.d.ts +4 -1
  882. package/dist/store/tombstone-checks.js +10 -1
  883. package/dist/store/usage-reports.js +2 -1
  884. package/dist/store/vector-index.d.ts +8 -5
  885. package/dist/store/vector-index.js +28 -11
  886. package/dist/store/working-memory.d.ts +6 -4
  887. package/dist/store/working-memory.js +14 -9
  888. package/dist/support-bundle.js +10 -5
  889. package/dist/trust/quarantine.d.ts +1 -2
  890. package/dist/trust/quarantine.js +1 -5
  891. package/dist/trust/reject-flow.d.ts +12 -3
  892. package/dist/trust/reject-flow.js +12 -4
  893. package/dist/util/anthropic-messages.d.ts +7 -2
  894. package/dist/util/anthropic-messages.js +18 -7
  895. package/dist/util/atomic-write.d.ts +8 -3
  896. package/dist/util/atomic-write.js +36 -21
  897. package/dist/util/compaction-items.d.ts +4 -1
  898. package/dist/util/compaction-items.js +8 -2
  899. package/dist/util/crash-handlers.d.ts +7 -2
  900. package/dist/util/crash-handlers.js +13 -4
  901. package/dist/util/env.d.ts +26 -5
  902. package/dist/util/env.js +87 -25
  903. package/dist/util/format.d.ts +2 -0
  904. package/dist/util/format.js +4 -0
  905. package/dist/util/home-path.js +12 -6
  906. package/dist/util/hook-payload.d.ts +3 -1
  907. package/dist/util/hook-payload.js +3 -1
  908. package/dist/util/http-retry.d.ts +12 -6
  909. package/dist/util/http-retry.js +16 -6
  910. package/dist/util/http-util.d.ts +20 -5
  911. package/dist/util/http-util.js +28 -9
  912. package/dist/util/json.d.ts +4 -1
  913. package/dist/util/json.js +4 -1
  914. package/dist/util/keyset.js +2 -1
  915. package/dist/util/limits.js +4 -2
  916. package/dist/util/log.d.ts +13 -5
  917. package/dist/util/log.js +29 -6
  918. package/dist/util/net.d.ts +5 -0
  919. package/dist/util/net.js +19 -0
  920. package/dist/util/real-path.d.ts +2 -1
  921. package/dist/util/real-path.js +4 -3
  922. package/dist/util/request-scope.d.ts +16 -4
  923. package/dist/util/request-scope.js +19 -6
  924. package/dist/util/same-text.d.ts +10 -3
  925. package/dist/util/same-text.js +10 -3
  926. package/dist/util/secret-detect.d.ts +24 -7
  927. package/dist/util/secret-detect.js +49 -14
  928. package/dist/util/spawn-argv.d.ts +11 -0
  929. package/dist/util/spawn-argv.js +66 -0
  930. package/dist/util/sql.d.ts +3 -0
  931. package/dist/util/sql.js +6 -0
  932. package/dist/util/sqlite-blocked.d.ts +15 -4
  933. package/dist/util/sqlite-blocked.js +19 -6
  934. package/dist/util/stored-json.d.ts +4 -1
  935. package/dist/util/stored-json.js +6 -2
  936. package/dist/util/stream-tee.d.ts +2 -1
  937. package/dist/util/stream-tee.js +8 -5
  938. package/dist/util/transcript-tail.d.ts +4 -1
  939. package/dist/util/transcript-tail.js +4 -1
  940. package/dist/util/vector-codec.d.ts +4 -0
  941. package/dist/util/vector-codec.js +15 -0
  942. package/dist/util/version.d.ts +8 -3
  943. package/dist/util/version.js +8 -3
  944. package/dist/util/write-budget.d.ts +7 -2
  945. package/dist/util/write-budget.js +5 -2
  946. package/dist/util/yaml.d.ts +4 -1
  947. package/dist/util/yaml.js +4 -1
  948. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  949. package/extensions/openclaw-plugin/package.json +1 -1
  950. package/openclaw.plugin.json +1 -1
  951. package/package.json +4 -1
  952. package/scripts/postinstall.cjs +3 -1
  953. package/dist/api/audit.js +0 -56
  954. package/dist/api/cards.d.ts +0 -42
  955. package/dist/api/conflicts.d.ts +0 -28
  956. package/dist/api/conflicts.js +0 -61
  957. package/dist/api/dormant.d.ts +0 -14
  958. package/dist/api/dormant.js +0 -58
  959. package/dist/api/goals.d.ts +0 -18
  960. package/dist/api/graph.d.ts +0 -8
  961. package/dist/api/graph.js +0 -7
  962. package/dist/api/learn.js +0 -124
  963. package/dist/api/memories.d.ts +0 -23
  964. package/dist/api/memories.js +0 -46
  965. package/dist/api/objects.d.ts +0 -9
  966. package/dist/api/on-store.d.ts +0 -16
  967. package/dist/api/on-store.js +0 -38
  968. package/dist/api/outcome.d.ts +0 -19
  969. package/dist/api/outcome.js +0 -21
  970. package/dist/api/predictions.d.ts +0 -11
  971. package/dist/api/promote.d.ts +0 -36
  972. package/dist/api/promote.js +0 -65
  973. package/dist/api/recall-core.d.ts +0 -4
  974. package/dist/api/recall-core.js +0 -120
  975. package/dist/api/recall-finish.d.ts +0 -53
  976. package/dist/api/recall-finish.js +0 -30
  977. package/dist/api/recall-history.d.ts +0 -64
  978. package/dist/api/recall-history.js +0 -159
  979. package/dist/api/recall-record.d.ts +0 -43
  980. package/dist/api/recall-record.js +0 -78
  981. package/dist/api/recall-request.js +0 -121
  982. package/dist/api/recall.d.ts +0 -6
  983. package/dist/api/refine.d.ts +0 -7
  984. package/dist/api/refine.js +0 -10
  985. package/dist/api/session-owners.d.ts +0 -4
  986. package/dist/api/session-owners.js +0 -17
  987. package/dist/api/sleep-run.d.ts +0 -26
  988. package/dist/api/sleep.js +0 -10
  989. package/dist/cli/lenient-id.d.ts +0 -2
  990. package/dist/cli/lenient-id.js +0 -13
  991. package/dist/graph/write.d.ts +0 -14
  992. package/dist/store/sqlite/busy.d.ts +0 -3
  993. package/dist/store/sqlite/busy.js +0 -8
  994. package/dist/store/sqlite/local.d.ts +0 -21
  995. package/dist/store/sqlite/local.js +0 -39
@@ -5,7 +5,7 @@ import { type ContinuityKey } from './sessions.js';
5
5
  export declare const HANDOFF_COLUMNS: string;
6
6
  /** Save a session handoff record; returns the persisted handoff. */
7
7
  export declare function saveSessionHandoff(hippoRoot: string, tenantId: string, handoff: Omit<SessionHandoff, 'updatedAt'>, key?: ContinuityKey): SessionHandoff;
8
- interface HandoffFilter {
8
+ export interface HandoffFilter {
9
9
  unfinishedOnly?: boolean;
10
10
  maxAgeMs?: number;
11
11
  scopeFilter?: 'default-deny';
@@ -17,10 +17,16 @@ export declare function loadLatestHandoff(hippoRoot: string, tenantId: string, s
17
17
  export declare function loadHandoffById(hippoRoot: string, tenantId: string, id: number): SessionHandoff | null;
18
18
  /** Stamp the outcome on a session's newest handoff, only if it has none yet. Returns rows changed. */
19
19
  export declare function stampHandoffOutcome(hippoRoot: string, tenantId: string, sessionId: string, outcome: HandoffOutcome): number;
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`. */
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?: {
23
- inPlace?: boolean;
24
- }): SessionHandoff | null;
25
- export {};
20
+ export interface SessionEndHandoffRequest {
21
+ readonly tenantId: string;
22
+ readonly sessionId: string;
23
+ readonly evidence: HandoffEvidence | null;
24
+ readonly derived?: Pick<TaskSnapshot, 'task' | 'summary' | 'next_step'> | null;
25
+ readonly key?: ContinuityKey;
26
+ readonly inPlace?: boolean;
27
+ }
28
+ /** Session-end handoff from the active snapshot, else `derived` transcript state; `inPlace` rewrites an earlier
29
+ * transcript read instead of adding a revision. Returns null when no source is the session's, a newer handoff covers
30
+ * it, or the latest one is not transcript-derived or already holds `derived`. */
31
+ export declare function writeSessionEndHandoff(hippoRoot: string, request: SessionEndHandoffRequest): SessionHandoff | null;
26
32
  //# sourceMappingURL=handoffs.d.ts.map
@@ -7,6 +7,14 @@ import { continuityStamp, continuityWhere, loadActiveTaskSnapshot } from './sess
7
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, ' +
9
9
  'evidence_json, outcome, target_runtime, card_id';
10
+ function insertHandoffRow(db, tenantId, handoff, stamp, now) {
11
+ return db
12
+ .prepare(`\n INSERT INTO session_handoffs(session_id, repo_root, task_id, summary, next_action, artifacts_json, ` +
13
+ `scope, tenant_id, created_at, ` +
14
+ `constraints_json, evidence_json, outcome, target_runtime, card_id, owner_subject, origin_project)\n` +
15
+ ` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)
16
+ .run(handoff.sessionId, handoff.repoRoot ?? null, handoff.taskId ?? null, handoff.summary, handoff.nextAction ?? null, JSON.stringify(handoff.artifacts ?? []), handoff.scope ?? null, tenantId, now, JSON.stringify(handoff.constraints ?? []), handoff.evidence ? JSON.stringify(handoff.evidence) : null, handoff.outcome ?? null, handoff.targetRuntime ?? null, handoff.cardId ?? null, stamp?.owner ?? null, stamp?.origin ?? null);
17
+ }
10
18
  /** Save a session handoff record; returns the persisted handoff. */
11
19
  export function saveSessionHandoff(hippoRoot, tenantId, handoff, key) {
12
20
  assertTenantId('saveSessionHandoff', tenantId);
@@ -16,9 +24,7 @@ export function saveSessionHandoff(hippoRoot, tenantId, handoff, key) {
16
24
  // Scope is stored as given; read-side default-deny in api.recall + cmdRecall
17
25
  // continuity excludes slack:private:* and 'unknown:legacy'.
18
26
  try {
19
- const result = db.prepare(`\n INSERT INTO session_handoffs(session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, tenant_id, created_at, ` +
20
- `constraints_json, evidence_json, outcome, target_runtime, card_id, owner_subject, origin_project)\n` +
21
- ` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(handoff.sessionId, handoff.repoRoot ?? null, handoff.taskId ?? null, handoff.summary, handoff.nextAction ?? null, JSON.stringify(handoff.artifacts ?? []), handoff.scope ?? null, tenantId, now, JSON.stringify(handoff.constraints ?? []), handoff.evidence ? JSON.stringify(handoff.evidence) : null, handoff.outcome ?? null, handoff.targetRuntime ?? null, handoff.cardId ?? null, stamp?.owner ?? null, stamp?.origin ?? null);
27
+ const result = insertHandoffRow(db, tenantId, handoff, stamp, now);
22
28
  const id = Number(result.lastInsertRowid ?? 0);
23
29
  // SAFETY: row's shape matches HANDOFF_COLUMNS.
24
30
  const row = db.prepare(`SELECT ${HANDOFF_COLUMNS} FROM session_handoffs WHERE id = ?`).get(id);
@@ -48,9 +54,11 @@ function handoffConditions(tenantId, sessionId, opts, key) {
48
54
  params.push(opts.excludeSessionId);
49
55
  }
50
56
  if (opts.unfinishedOnly) {
51
- // Restrict to each session's newest revision first: stampHandoffOutcome only stamps the newest row, so an older null-outcome revision must not resurrect.
52
- // Keyed, the newest is the owner's own, so another owner's newer revision cannot hide it.
53
- conditions.push(`id IN (SELECT MAX(id) FROM session_handoffs WHERE tenant_id = ?${owned ? ` AND ${owned.sql}` : ''} GROUP BY session_id)`);
57
+ // Restrict to each session's newest revision first: stampHandoffOutcome only stamps the newest row, so an older
58
+ // null-outcome revision must not resurrect. Keyed, the newest is the owner's own, so another owner's newer revision
59
+ // cannot hide it.
60
+ conditions.push(`id IN (SELECT MAX(id) FROM session_handoffs WHERE tenant_id = ?${owned ? ` AND ${owned.sql}` : ''} GROUP BY ` +
61
+ `session_id)`);
54
62
  params.push(tenantId, ...(owned?.params ?? []));
55
63
  conditions.push(`(outcome IS NULL OR outcome IN ('partial','failure'))`);
56
64
  }
@@ -107,7 +115,8 @@ export function loadHandoffById(hippoRoot, tenantId, id) {
107
115
  export function stampHandoffOutcome(hippoRoot, tenantId, sessionId, outcome) {
108
116
  assertTenantId('stampHandoffOutcome', tenantId);
109
117
  return onHandle(hippoRoot, (db) => {
110
- const result = db.prepare(`
118
+ const result = db
119
+ .prepare(`
111
120
  UPDATE session_handoffs SET outcome = ?
112
121
  WHERE tenant_id = ? AND session_id = ? AND outcome IS NULL
113
122
  AND id = (
@@ -115,21 +124,27 @@ export function stampHandoffOutcome(hippoRoot, tenantId, sessionId, outcome) {
115
124
  WHERE tenant_id = ? AND session_id = ?
116
125
  ORDER BY created_at DESC, id DESC LIMIT 1
117
126
  )
118
- `).run(outcome, tenantId, sessionId, tenantId, sessionId);
127
+ `)
128
+ .run(outcome, tenantId, sessionId, tenantId, sessionId);
119
129
  return Number(result.changes ?? 0);
120
130
  }, openStore);
121
131
  }
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
+ /** Rewrites the session's newest handoff when it is still a transcript read, in one statement so a handoff written
133
+ * meanwhile is never overwritten; null when none was rewritten. */
124
134
  function replaceTranscriptHandoff(hippoRoot, tenantId, handoff, key) {
125
135
  const { conditions, params } = handoffConditions(tenantId, handoff.sessionId, {}, key);
126
- const newest = `SELECT id FROM session_handoffs WHERE ${conditions.join(' AND ')} ORDER BY created_at DESC, id DESC LIMIT 1`;
136
+ const newest = `SELECT id FROM session_handoffs WHERE ${conditions.join(' AND ')} ORDER BY created_at DESC, id ` +
137
+ `DESC LIMIT 1`;
127
138
  return onHandle(hippoRoot, (db) => {
128
- const result = db.prepare(`
129
- UPDATE session_handoffs SET repo_root = ?, task_id = ?, summary = ?, next_action = ?, artifacts_json = ?, scope = ?, created_at = ?,
139
+ const result = db
140
+ .prepare(`
141
+ UPDATE session_handoffs SET repo_root = ?, task_id = ?, summary = ?, next_action = ?, artifacts_json = ?, scope =
142
+ ?, created_at = ?,
130
143
  constraints_json = ?, evidence_json = ?, outcome = ?, target_runtime = ?, card_id = ?
131
- WHERE id = (${newest}) AND json_valid(evidence_json) AND json_extract(evidence_json, '$.derivedFrom') = 'transcript'
132
- `).run(handoff.repoRoot ?? null, handoff.taskId ?? null, handoff.summary, handoff.nextAction ?? null, JSON.stringify(handoff.artifacts ?? []), handoff.scope ?? null, new Date().toISOString(), JSON.stringify(handoff.constraints ?? []), handoff.evidence ? JSON.stringify(handoff.evidence) : null, handoff.outcome ?? null, handoff.targetRuntime ?? null, handoff.cardId ?? null, ...params);
144
+ WHERE id = (${newest}) AND json_valid(evidence_json) AND json_extract(evidence_json, '$.derivedFrom') =
145
+ 'transcript'
146
+ `)
147
+ .run(handoff.repoRoot ?? null, handoff.taskId ?? null, handoff.summary, handoff.nextAction ?? null, JSON.stringify(handoff.artifacts ?? []), handoff.scope ?? null, new Date().toISOString(), JSON.stringify(handoff.constraints ?? []), handoff.evidence ? JSON.stringify(handoff.evidence) : null, handoff.outcome ?? null, handoff.targetRuntime ?? null, handoff.cardId ?? null, ...params);
133
148
  if (Number(result.changes ?? 0) === 0)
134
149
  return null;
135
150
  // SAFETY: row's shape matches HANDOFF_COLUMNS.
@@ -142,8 +157,12 @@ function transcriptHandoffSource(existing, derived, evidence) {
142
157
  if (!derived || (existing && existing.evidence?.derivedFrom !== 'transcript'))
143
158
  return null;
144
159
  // A retried session end reads the same transcript, so it must not add a second revision.
145
- if (existing && existing.taskId === derived.task && existing.summary === derived.summary && existing.nextAction === derived.next_step)
160
+ if (existing &&
161
+ existing.taskId === derived.task &&
162
+ existing.summary === derived.summary &&
163
+ existing.nextAction === derived.next_step) {
146
164
  return null;
165
+ }
147
166
  return { snapshot: { ...derived, scope: null }, evidence: { ...evidence, derivedFrom: 'transcript' } };
148
167
  }
149
168
  function buildSessionEndHandoff(sessionId, snapshot, existing, handoffEvidence, outcome) {
@@ -167,9 +186,11 @@ function buildSessionEndHandoff(sessionId, snapshot, existing, handoffEvidence,
167
186
  cardId: carryForward ? existing.cardId : undefined,
168
187
  };
169
188
  }
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`. */
172
- export function writeSessionEndHandoff(hippoRoot, tenantId, sessionId, evidence, derived = null, key, options = {}) {
189
+ /** Session-end handoff from the active snapshot, else `derived` transcript state; `inPlace` rewrites an earlier
190
+ * transcript read instead of adding a revision. Returns null when no source is the session's, a newer handoff covers
191
+ * it, or the latest one is not transcript-derived or already holds `derived`. */
192
+ export function writeSessionEndHandoff(hippoRoot, request) {
193
+ const { tenantId, sessionId, evidence, derived = null, key, inPlace } = request;
173
194
  assertTenantId('writeSessionEndHandoff', tenantId);
174
195
  if (key)
175
196
  continuityStamp(key); // a partial key is a caller bug, so fail loud rather than write nothing
@@ -178,8 +199,9 @@ export function writeSessionEndHandoff(hippoRoot, tenantId, sessionId, evidence,
178
199
  let snapshot;
179
200
  let handoffEvidence = evidence;
180
201
  let fromTranscript = false;
181
- // After every reply the transcript is newer than the last compaction's snapshot, which the open chat keeps for the next one.
182
- const snapshotGivesWay = options.inPlace === true && derived !== null && active?.source === 'pre-compact';
202
+ // After every reply the transcript is newer than the last compaction's snapshot, which the open chat keeps for the
203
+ // next one.
204
+ const snapshotGivesWay = inPlace === true && derived !== null && active?.source === 'pre-compact';
183
205
  if (active && active.session_id === sessionId && !snapshotGivesWay) {
184
206
  // Strict '>': a same-millisecond tie must not swallow the session's only write (test 6e).
185
207
  if (existing && existing.updatedAt > active.updated_at)
@@ -197,7 +219,7 @@ export function writeSessionEndHandoff(hippoRoot, tenantId, sessionId, evidence,
197
219
  const outcome = sessionOutcome(hippoRoot, tenantId, sessionId);
198
220
  const handoff = buildSessionEndHandoff(sessionId, snapshot, existing, handoffEvidence, outcome);
199
221
  // A miss means a handoff landed since the read, and a new transcript row would hide it.
200
- if (fromTranscript && options.inPlace && existing)
222
+ if (fromTranscript && inPlace && existing)
201
223
  return replaceTranscriptHandoff(hippoRoot, tenantId, handoff, key);
202
224
  return saveSessionHandoff(hippoRoot, tenantId, handoff, key);
203
225
  }
@@ -4,8 +4,8 @@ import type { HippoIndex, LegacyStats } from './rows.js';
4
4
  export declare function loadIndex(hippoRoot: string): HippoIndex;
5
5
  /** The last recall's ids and its trace alone, for a caller that needs no index entry. */
6
6
  export declare function loadLastRecall(hippoRoot: string): Pick<HippoIndex, 'last_retrieval_ids' | 'last_trace_id'>;
7
- /** Persist mutable index metadata (entry rows are derived from SQLite); `last_retrieval_ids` and `last_trace_id` commit in one transaction, as callers
8
- * rely on both moving together. index.json is left to `rebuildIndex`. */
7
+ /** Persist mutable index metadata (entry rows are derived from SQLite); `last_retrieval_ids` and `last_trace_id` commit
8
+ * in one transaction, as callers rely on both moving together. index.json is left to `rebuildIndex`. */
9
9
  export declare function saveIndex(hippoRoot: string, index: Pick<HippoIndex, 'last_retrieval_ids' | 'last_trace_id'>): void;
10
10
  /** Rebuild mirrors from SQLite, importing any legacy markdown files not already present. */
11
11
  export declare function rebuildIndex(hippoRoot: string): HippoIndex;
@@ -1,9 +1,9 @@
1
- import { withWriteScope, setMeta, isSqliteBusy, pruneConsolidationRuns, getMeta } from '../db/index.js';
1
+ import { withWriteScope, setMeta, isSqliteBusy, pruneConsolidationRuns, getMeta, } from '../db/index.js';
2
2
  import { RejectedValueError } from '../core/api-errors.js';
3
3
  import { log } from '../util/log.js';
4
4
  import { audit } from './audit-event.js';
5
5
  import { stampOriginProjectForImport, upsertEntryRow } from './entry-row.js';
6
- import { buildIndexFromDb, readLastRecall, syncMirrorFiles, writeIndexMirror, writeStatsMirror, buildStatsFromDb } from './mirrors.js';
6
+ import { buildIndexFromDb, readLastRecall, syncMirrorFiles, writeIndexMirror, writeStatsMirror, buildStatsFromDb, } from './mirrors.js';
7
7
  import { onHandle, openStore, loadLegacyEntriesFromMarkdown } from './open.js';
8
8
  import { DAY_MS } from '../util/time.js';
9
9
  /** Load the derived index from SQLite. Read-only: index.json is only ever written by `rebuildIndex`. */
@@ -18,8 +18,8 @@ export function loadLastRecall(hippoRoot) {
18
18
  return readLastRecall(db);
19
19
  }, openStore);
20
20
  }
21
- /** Persist mutable index metadata (entry rows are derived from SQLite); `last_retrieval_ids` and `last_trace_id` commit in one transaction, as callers
22
- * rely on both moving together. index.json is left to `rebuildIndex`. */
21
+ /** Persist mutable index metadata (entry rows are derived from SQLite); `last_retrieval_ids` and `last_trace_id` commit
22
+ * in one transaction, as callers rely on both moving together. index.json is left to `rebuildIndex`. */
23
23
  export function saveIndex(hippoRoot, index) {
24
24
  onHandle(hippoRoot, (db) => {
25
25
  withWriteScope(db, 'save_index', () => {
@@ -77,7 +77,8 @@ export function updateStats(hippoRoot, delta) {
77
77
  }
78
78
  /** updateStats on the caller's open store, so a loop of writes opens the store once. */
79
79
  export function updateStatsOn(db, hippoRoot, delta) {
80
- // One atomic statement per named counter: a read-modify-write loses concurrent increments and stamps stale values over the untouched two.
80
+ // One atomic statement per named counter: a read-modify-write loses concurrent increments and stamps stale values
81
+ // over the untouched two.
81
82
  const increments = [
82
83
  ['total_remembered', delta.remembered ?? 0],
83
84
  ['total_recalled', delta.recalled ?? 0],
@@ -1,4 +1,6 @@
1
- export type { AmbientCandidateRequest, ContextReads, EntryRemoval, EntryTarget, EntryWrite, EntryWrites, HippoStore, KeyAudit, KeyListQuery, KeyMint, KeyRevoke, KeyWrites, OutcomeWrite, RawArchive, RecallSearchArgs, RecallWrites, SelfKeyMint, StoreGroup, StoreGroups, SupersedeWrite, VectorBackfillQuery, VectorReads, VectorRowWrite, VectorWrite, VectorWriteResult, VectorWrites, } from './port.js';
1
+ export type { AmbientCandidateRequest, ContextReads, EntryRemoval, EntryTarget, EntryWrite, EntryWrites, HippoStore, KeyAudit, KeyListQuery, KeyMint, KeyRevoke, KeyGrants, KeyWrites, LastRecall, LastRecallWrites, OutcomeWrite, RawArchive, RecallSearchArgs, RecallWrites, SelfKeyMint, StoreGroup, StoreGroups, SupersedeWrite, VectorBackfillQuery, VectorReads, VectorRowWrite, VectorWrite, VectorWriteResult, VectorWrites, } from './port.js';
2
+ export type { CardCreate, Cards, Conflicts, Dormant, DormantRestoreRequest, Goals, Reports, Sessions, WorkingMemoryFilter, WorkingMemoryPush, } from './port-groups.js';
2
3
  export { hasGroup, requireGroup } from './port.js';
3
- export * from './sqlite/store.js';
4
+ export { narrowStore, type StoreWith } from './narrow.js';
5
+ export { sqliteStore } from './sqlite/store.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,4 @@
1
1
  export { hasGroup, requireGroup } from './port.js';
2
- export * from './sqlite/store.js';
2
+ export { narrowStore } from './narrow.js';
3
+ export { sqliteStore } from './sqlite/store.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,7 @@
1
1
  import { type DatabaseSyncLike } from '../db/index.js';
2
2
  import type { KeyRevoke } from './port.js';
3
- /** The revoke and its audit row commit together, so a failed audit write leaves the key live and the caller sees the error. */
3
+ /** The revoke and its audit row commit together, so a failed audit write leaves the key live and the caller sees the
4
+ * error. */
4
5
  export declare function revokeKeyAt(db: DatabaseSyncLike, revoke: KeyRevoke): string;
5
6
  export declare function auditHighIdAt(db: DatabaseSyncLike): number;
6
7
  //# sourceMappingURL=key-audit.d.ts.map
@@ -4,7 +4,8 @@ import { appendAuditEvent } from './audit.js';
4
4
  import { revokeApiKey } from './auth.js';
5
5
  import { withWriteScope } from '../db/index.js';
6
6
  import { selectApiKeyOwner } from './tenant-lookup.js';
7
- /** The revoke and its audit row commit together, so a failed audit write leaves the key live and the caller sees the error. */
7
+ /** The revoke and its audit row commit together, so a failed audit write leaves the key live and the caller sees the
8
+ * error. */
8
9
  export function revokeKeyAt(db, revoke) {
9
10
  return withWriteScope(db, 'revoke_api_key', () => {
10
11
  const row = selectApiKeyOwner(db, revoke.keyId);
@@ -11,6 +11,7 @@ export interface ScopeGrantChange {
11
11
  readonly op: 'auth_grant' | 'auth_ungrant';
12
12
  readonly actor: string;
13
13
  }
14
- /** The key is checked under the write lock, and the change and its audit row commit together, so a failed audit write leaves the grants as they were. */
14
+ /** The key is checked under the write lock, and the change and its audit row commit together, so a failed audit write
15
+ * leaves the grants as they were. */
15
16
  export declare function changeScopeGrantAt(db: DatabaseSyncLike, { tenantId, keyId, scope, op, actor }: ScopeGrantChange): void;
16
17
  //# sourceMappingURL=key-writes.d.ts.map
@@ -24,13 +24,20 @@ export function createSelfKeyAt(db, mint) {
24
24
  insertApiKey(db, key);
25
25
  for (const keyId of replaced) {
26
26
  revokeApiKey(db, keyId, key.createdAt);
27
- appendAuditEvent(db, { tenantId: key.tenantId, actor, op: 'auth_revoke', targetId: keyId, metadata: { replacedBy: key.keyId } });
27
+ appendAuditEvent(db, {
28
+ tenantId: key.tenantId,
29
+ actor,
30
+ op: 'auth_revoke',
31
+ targetId: keyId,
32
+ metadata: { replacedBy: key.keyId },
33
+ });
28
34
  }
29
35
  appendAuditEvent(db, createAuditOf(mint));
30
36
  return replaced;
31
37
  });
32
38
  }
33
- /** The key is checked under the write lock, and the change and its audit row commit together, so a failed audit write leaves the grants as they were. */
39
+ /** The key is checked under the write lock, and the change and its audit row commit together, so a failed audit write
40
+ * leaves the grants as they were. */
34
41
  export function changeScopeGrantAt(db, { tenantId, keyId, scope, op, actor }) {
35
42
  withWriteScope(db, 'change_scope_grant', () => {
36
43
  const row = selectApiKeyOwner(db, keyId);
@@ -9,13 +9,16 @@ export type DeliveryWrite = (input: DeliveryEventInput) => number | null;
9
9
  /** The token rows of one turn and the delivery event that follows them. */
10
10
  export interface LedgerTurn {
11
11
  readonly uses: readonly TokenUse[];
12
- /** Makes each row its own attempt: a failed one is reported here and the rest still run. Without it the first failure throws. */
12
+ /** Makes each row its own attempt: a failed one is reported here and the rest still run. Without it the first failure
13
+ * throws. */
13
14
  readonly onRowError?: <E>(error: E) => void;
14
15
  /** Runs after the rows with a writer on their connection, so the delivery event costs no second open. */
15
16
  readonly delivery?: (write: DeliveryWrite) => void;
16
17
  }
17
18
  /** Books a turn's token rows, then its delivery event, on one connection. */
18
19
  export declare function recordLedgerTurn(hippoRoot: string, turn: LedgerTurn): void;
20
+ /** Books one token row in the store at `hippoRoot`. */
21
+ export declare function recordTokensAt(hippoRoot: string, use: TokenUse): void;
19
22
  /** What the session last sent on `surface`, or null, as lastSentState reads it. */
20
23
  export declare function lastSentOnSurface(hippoRoot: string, tenantId: string, sessionId: string | null | undefined, surface: TokenSurface): LastSent | null;
21
24
  /** The session's pilot arm: `write` books it as ensurePilotArm does, else the stored arm or the hash arm. */
@@ -1,4 +1,5 @@
1
- // One hook or context turn's token-ledger work by store root: each call opens hippo.db, runs on one connection and closes it.
1
+ // One hook or context turn's token-ledger work by store root: each call opens hippo.db, runs on one connection and
2
+ // closes it.
2
3
  import { isSqliteBusy, noteStoreBusy } from '../db/index.js';
3
4
  import { errorFields, errorMessage, log } from '../util/log.js';
4
5
  import { lastSentState, recordTokenUse } from './token-ledger.js';
@@ -51,6 +52,10 @@ export function recordLedgerTurn(hippoRoot, turn) {
51
52
  turn.delivery?.((input) => writeDeliveryEventOnHandle(db, input));
52
53
  });
53
54
  }
55
+ /** Books one token row in the store at `hippoRoot`. */
56
+ export function recordTokensAt(hippoRoot, use) {
57
+ onHandle(hippoRoot, (db) => recordTokenUse(db, use));
58
+ }
54
59
  /** What the session last sent on `surface`, or null, as lastSentState reads it. */
55
60
  export function lastSentOnSurface(hippoRoot, tenantId, sessionId, surface) {
56
61
  return onHandle(hippoRoot, (db) => lastSentState(db, tenantId, sessionId, surface));
@@ -60,6 +65,6 @@ export function pilotArmOnRoot(hippoRoot, tenantId, sessionId, rateBp, opts) {
60
65
  const { ownTenantOnly } = opts;
61
66
  return onHandle(hippoRoot, (db) => opts.write
62
67
  ? ensurePilotArm(db, tenantId, sessionId, rateBp, { ownTenantOnly })
63
- : readPilotArm(db, sessionId, ownTenantOnly ? tenantId : undefined) ?? hashArm(sessionId, rateBp));
68
+ : (readPilotArm(db, sessionId, ownTenantOnly ? tenantId : undefined) ?? hashArm(sessionId, rateBp)));
64
69
  }
65
70
  //# sourceMappingURL=ledger-turn.js.map
@@ -2,15 +2,17 @@ import { Layer, type MemoryEntry } from '../core/memory.js';
2
2
  import { openHippoDb } from '../db/index.js';
3
3
  import { type TaskSnapshot, type SessionEvent, type HippoIndex, type LegacyStats } from './rows.js';
4
4
  export declare function layerDir(root: string, layer: Layer): string;
5
- /** Makes the mirror folders on a store's first open in this process; a writer makes its own folder if one goes missing later. */
5
+ /** Makes the mirror folders on a store's first open in this process; a writer makes its own folder if one goes missing
6
+ * later. */
6
7
  export declare function ensureMirrorDirectories(hippoRoot: string): void;
7
8
  export declare function writeActiveTaskMirror(hippoRoot: string, tenantId: string, snapshot: TaskSnapshot): void;
8
9
  export declare function removeActiveTaskMirror(hippoRoot: string, tenantId: string): void;
9
10
  export declare function writeRecentSessionMirror(hippoRoot: string, tenantId: string, events: SessionEvent[]): void;
10
11
  export declare function writeMarkdownMirror(hippoRoot: string, entry: MemoryEntry): void;
11
12
  export declare function removeEntryMirrors(hippoRoot: string, id: string): void;
12
- /** Best-effort mirror purge: retries the unlink once (most failures are transient locks); the reaper only scans `raw_archive`,
13
- * so a non-raw id's second failure logs the leftover path(s) to delete by hand. Returns true if the mirror ended up purged. */
13
+ /** Best-effort mirror purge: retries the unlink once (most failures are transient locks); the reaper only scans
14
+ * `raw_archive`, so a non-raw id's second failure logs the leftover path(s) to delete by hand. Returns true if the
15
+ * mirror ended up purged. */
14
16
  export declare function purgeMirrorBestEffort(hippoRoot: string, id: string, isRaw: boolean, logPrefix: string): boolean;
15
17
  /** Derive the current `HippoIndex` from SQLite. Exported for `rebuildIndex`
16
18
  * (the only index.json writer) and the longmemeval benchmark. */
@@ -21,8 +23,13 @@ export declare function buildStatsFromDb(db: ReturnType<typeof openHippoDb>): Le
21
23
  /** Write the `index.json` mirror file for an already-derived index. Exported for
22
24
  * `rebuildIndex` (the only index.json writer) and the longmemeval benchmark. */
23
25
  export declare function writeIndexMirror(hippoRoot: string, index: HippoIndex): void;
26
+ /** Mirror `stats` to stats.json at once, or hold it and write the latest within a second of the last write; the
27
+ * database counters are always current. */
24
28
  export declare function writeStatsMirror(hippoRoot: string, stats: LegacyStats): void;
25
- /** Mirrors are derived from SQLite and written after COMMIT, so a failed write warns instead of failing a committed change. */
29
+ /** Write any held stats.json now, for one root or all; store close and process exit call it. */
30
+ export declare function flushStatsMirrors(hippoRoot?: string): void;
31
+ /** Mirrors are derived from SQLite and written after COMMIT, so a failed write warns instead of failing a committed
32
+ * change. */
26
33
  export declare function mirrorBestEffort(what: string, write: () => void): void;
27
34
  export declare function syncMirrorFiles(hippoRoot: string, db: ReturnType<typeof openHippoDb>): void;
28
35
  /** syncMirrorFiles for a pass that changed only `changed`: the other rows' markdown is already current. */
@@ -8,13 +8,20 @@ import { oncePerStore } from '../db/connect.js';
8
8
  import { errorFields, errorMessage, log } from '../util/log.js';
9
9
  import { parseJsonArray, INDEX_VERSION, parseLastTraceId, MEMORY_SELECT_COLUMNS, rowToEntry, rowToMemoryConflict, } from './rows.js';
10
10
  import { serializeEntry } from '../core/markdown.js';
11
+ import { writeFileAtomic } from '../util/atomic-write.js';
11
12
  const SCORE_DECIMALS = 3;
13
+ // Mirrors are derived and rebuildable from the store, so they skip the fsyncs (the cost on Windows) and keep the
14
+ // temp-and-rename atomicity.
15
+ function writeMirror(file, text) {
16
+ writeFileAtomic(file, text, { durable: false });
17
+ }
12
18
  export function layerDir(root, layer) {
13
19
  return path.join(root, layer);
14
20
  }
15
21
  // Owner-only wherever a mirror folder is made, at open or by a writer that finds it gone.
16
22
  const MIRROR_FOLDER = { recursive: true, mode: 0o700 };
17
- /** Makes the mirror folders on a store's first open in this process; a writer makes its own folder if one goes missing later. */
23
+ /** Makes the mirror folders on a store's first open in this process; a writer makes its own folder if one goes missing
24
+ * later. */
18
25
  export function ensureMirrorDirectories(hippoRoot) {
19
26
  oncePerStore(hippoRoot, 'mirror-folders', () => {
20
27
  for (const sub of ['buffer', 'episodic', 'semantic', 'conflicts']) {
@@ -61,7 +68,7 @@ export function writeActiveTaskMirror(hippoRoot, tenantId, snapshot) {
61
68
  body.push(`## Session`, snapshot.session_id, '');
62
69
  }
63
70
  fs.mkdirSync(path.dirname(filePath), MIRROR_FOLDER);
64
- fs.writeFileSync(filePath, `${fm}\n\n${body.join('\n')}`, 'utf8');
71
+ writeMirror(filePath, `${fm}\n\n${body.join('\n')}`);
65
72
  }
66
73
  export function removeActiveTaskMirror(hippoRoot, tenantId) {
67
74
  const filePath = activeTaskMirrorPath(hippoRoot, tenantId);
@@ -99,7 +106,7 @@ export function writeRecentSessionMirror(hippoRoot, tenantId, events) {
99
106
  }
100
107
  lines.push('');
101
108
  fs.mkdirSync(path.dirname(filePath), MIRROR_FOLDER);
102
- fs.writeFileSync(filePath, `${fm}\n\n${lines.join('\n')}`, 'utf8');
109
+ writeMirror(filePath, `${fm}\n\n${lines.join('\n')}`);
103
110
  }
104
111
  function writeConflictMirrors(hippoRoot, conflicts) {
105
112
  const conflictDir = path.join(hippoRoot, 'conflicts');
@@ -128,7 +135,7 @@ function writeConflictMirrors(hippoRoot, conflicts) {
128
135
  `- Status: ${conflict.status}`,
129
136
  '',
130
137
  ].join('\n');
131
- fs.writeFileSync(path.join(conflictDir, filename), `${fm}\n\n${body}`, 'utf8');
138
+ writeMirror(path.join(conflictDir, filename), `${fm}\n\n${body}`);
132
139
  }
133
140
  for (const existing of fs.readdirSync(conflictDir)) {
134
141
  if (existing === '.gitkeep')
@@ -142,7 +149,7 @@ export function writeMarkdownMirror(hippoRoot, entry) {
142
149
  removeEntryMirrors(hippoRoot, entry.id);
143
150
  const dir = layerDir(hippoRoot, entry.layer);
144
151
  fs.mkdirSync(dir, MIRROR_FOLDER);
145
- fs.writeFileSync(path.join(dir, `${entry.id}.md`), serializeEntry(entry), 'utf8');
152
+ writeMirror(path.join(dir, `${entry.id}.md`), serializeEntry(entry));
146
153
  }
147
154
  // Every layer, Trace included: `writeMarkdownMirror` writes any layer, and a stale trace mirror
148
155
  // is the resurrection channel bootstrapLegacyStore/rebuildIndex guard against.
@@ -154,21 +161,24 @@ export function removeEntryMirrors(hippoRoot, id) {
154
161
  }
155
162
  }
156
163
  }
157
- /** Mirror paths for `id` still on disk, walked like `removeEntryMirrors`, so a failed purge with no reaper to retry it can name the stuck file. */
164
+ /** Mirror paths for `id` still on disk, walked like `removeEntryMirrors`, so a failed purge with no reaper to retry it
165
+ * can name the stuck file. */
158
166
  function getExistingEntryMirrorPaths(hippoRoot, id) {
159
167
  // Layer list kept in lockstep with removeEntryMirrors.
160
168
  return [Layer.Buffer, Layer.Episodic, Layer.Semantic, Layer.Trace]
161
169
  .map((layer) => path.join(layerDir(hippoRoot, layer), `${id}.md`))
162
170
  .filter((file) => fs.existsSync(file));
163
171
  }
164
- /** Best-effort mirror purge: retries the unlink once (most failures are transient locks); the reaper only scans `raw_archive`,
165
- * so a non-raw id's second failure logs the leftover path(s) to delete by hand. Returns true if the mirror ended up purged. */
172
+ /** Best-effort mirror purge: retries the unlink once (most failures are transient locks); the reaper only scans
173
+ * `raw_archive`, so a non-raw id's second failure logs the leftover path(s) to delete by hand. Returns true if the
174
+ * mirror ended up purged. */
166
175
  export function purgeMirrorBestEffort(hippoRoot, id, isRaw, logPrefix) {
167
176
  try {
168
177
  removeEntryMirrors(hippoRoot, id);
169
178
  return true;
170
179
  }
171
- catch {
180
+ catch (firstErr) {
181
+ log.debug(`${logPrefix}: mirror cleanup for ${id} failed once, retrying: ${errorMessage(firstErr)}`, errorFields(firstErr));
172
182
  try {
173
183
  removeEntryMirrors(hippoRoot, id);
174
184
  return true;
@@ -192,7 +202,10 @@ export function purgeMirrorBestEffort(hippoRoot, id, isRaw, logPrefix) {
192
202
  * (the only index.json writer) and the longmemeval benchmark. */
193
203
  export function buildIndexFromDb(db) {
194
204
  // SAFETY: rows' shape matches the seven columns named in the SELECT below.
195
- const rows = db.prepare(`SELECT id, created, last_retrieved, strength, layer, tags_json, pinned FROM memories ORDER BY created ASC, id ASC`).all();
205
+ const rows = db
206
+ .prepare(`SELECT id, created, last_retrieved, strength, layer, tags_json, pinned FROM memories ORDER BY created ASC, id ` +
207
+ `ASC`)
208
+ .all();
196
209
  const entries = {};
197
210
  for (const row of rows) {
198
211
  // SAFETY: layer is only ever written from the Layer enum by this
@@ -213,12 +226,18 @@ export function buildIndexFromDb(db) {
213
226
  }
214
227
  /** The last recall's ids and its trace, the two meta keys saveIndex writes together. */
215
228
  export function readLastRecall(db) {
216
- // Read both lockstep keys in ONE statement: two autocommit SELECTs could straddle a concurrent saveIndex and return a mismatched pair.
217
- // SAFETY: lockstepRows' shape matches the key/value columns named above.
218
- const lockstepRows = db.prepare(`SELECT key, value FROM meta WHERE key IN ('last_retrieval_ids', 'last_trace_id')`).all();
229
+ // Read both lockstep keys in ONE statement: two autocommit SELECTs could straddle a concurrent saveIndex and return a
230
+ // mismatched pair. SAFETY: lockstepRows' shape matches the key/value columns named above.
231
+ const lockstepRows = db
232
+ .prepare(`SELECT key, value FROM meta WHERE key IN ('last_retrieval_ids', 'last_trace_id')`)
233
+ .all();
219
234
  const lockstep = new Map(lockstepRows.map((r) => [r.key, r.value]));
220
235
  return {
221
- last_retrieval_ids: parseJsonArray(lockstep.get('last_retrieval_ids') ?? '[]', { table: 'meta', id: 'last_retrieval_ids', column: 'value' }),
236
+ last_retrieval_ids: parseJsonArray(lockstep.get('last_retrieval_ids') ?? '[]', {
237
+ table: 'meta',
238
+ id: 'last_retrieval_ids',
239
+ column: 'value',
240
+ }),
222
241
  last_trace_id: parseLastTraceId(lockstep.get('last_trace_id') ?? ''),
223
242
  };
224
243
  }
@@ -246,9 +265,62 @@ export function buildStatsFromDb(db) {
246
265
  export function writeIndexMirror(hippoRoot, index) {
247
266
  mirrorBestEffort('index.json', () => overwriteInPlace(path.join(hippoRoot, 'index.json'), JSON.stringify(index, null, 2)));
248
267
  }
249
- export function writeStatsMirror(hippoRoot, stats) {
268
+ const STATS_MIRROR_INTERVAL_MS = 1000;
269
+ const statsMirrors = new Map();
270
+ let statsExitHookInstalled = false;
271
+ function putStatsMirror(hippoRoot, stats) {
272
+ // A root removed before its deferred write has nothing left to mirror.
273
+ if (!fs.existsSync(hippoRoot))
274
+ return;
250
275
  mirrorBestEffort('stats.json', () => overwriteInPlace(path.join(hippoRoot, 'stats.json'), JSON.stringify(stats, null, 2)));
251
276
  }
277
+ /** Mirror `stats` to stats.json at once, or hold it and write the latest within a second of the last write; the
278
+ * database counters are always current. */
279
+ export function writeStatsMirror(hippoRoot, stats) {
280
+ const key = path.resolve(hippoRoot);
281
+ dropIdleStatsMirrors();
282
+ const state = statsMirrors.get(key) ?? { lastWrite: 0 };
283
+ statsMirrors.set(key, state);
284
+ const wait = state.lastWrite + STATS_MIRROR_INTERVAL_MS - Date.now();
285
+ if (wait <= 0) {
286
+ state.lastWrite = Date.now();
287
+ putStatsMirror(hippoRoot, stats);
288
+ return;
289
+ }
290
+ state.pending = stats;
291
+ if (state.timer !== undefined)
292
+ return;
293
+ if (!statsExitHookInstalled) {
294
+ process.on('exit', () => flushStatsMirrors());
295
+ statsExitHookInstalled = true;
296
+ }
297
+ state.timer = setTimeout(() => flushStatsMirrors(key), wait);
298
+ state.timer.unref();
299
+ }
300
+ // A root idle for a full interval needs no throttle state, so the map holds only recently written roots.
301
+ function dropIdleStatsMirrors() {
302
+ const now = Date.now();
303
+ for (const [root, state] of statsMirrors) {
304
+ if (state.timer === undefined && state.pending === undefined && now - state.lastWrite >= STATS_MIRROR_INTERVAL_MS) {
305
+ statsMirrors.delete(root);
306
+ }
307
+ }
308
+ }
309
+ /** Write any held stats.json now, for one root or all; store close and process exit call it. */
310
+ export function flushStatsMirrors(hippoRoot) {
311
+ const key = hippoRoot === undefined ? undefined : path.resolve(hippoRoot);
312
+ for (const [root, state] of statsMirrors) {
313
+ if (key !== undefined && root !== key)
314
+ continue;
315
+ if (state.timer !== undefined)
316
+ clearTimeout(state.timer);
317
+ state.timer = undefined;
318
+ const stats = state.pending;
319
+ statsMirrors.delete(root);
320
+ if (stats !== undefined)
321
+ putStatsMirror(root, stats);
322
+ }
323
+ }
252
324
  // A truncate waits for the file's last write to reach the disk, so a file rewritten on every recall keeps its blocks.
253
325
  function overwriteInPlace(file, text) {
254
326
  const bytes = Buffer.from(text, 'utf8');
@@ -261,7 +333,8 @@ function overwriteInPlace(file, text) {
261
333
  fs.closeSync(fd);
262
334
  }
263
335
  }
264
- /** Mirrors are derived from SQLite and written after COMMIT, so a failed write warns instead of failing a committed change. */
336
+ /** Mirrors are derived from SQLite and written after COMMIT, so a failed write warns instead of failing a committed
337
+ * change. */
265
338
  export function mirrorBestEffort(what, write) {
266
339
  try {
267
340
  write();
@@ -273,7 +346,9 @@ export function mirrorBestEffort(what, write) {
273
346
  export function syncMirrorFiles(hippoRoot, db) {
274
347
  // SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
275
348
  // MemoryRow's field set.
276
- const entries = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories ORDER BY created ASC, id ASC`).all();
349
+ const entries = db
350
+ .prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories ORDER BY created ASC, id ASC`)
351
+ .all();
277
352
  syncChangedMirrors(hippoRoot, db, entries.map(rowToEntry));
278
353
  }
279
354
  /** syncMirrorFiles for a pass that changed only `changed`: the other rows' markdown is already current. */
@@ -284,12 +359,14 @@ export function syncChangedMirrors(hippoRoot, db, changed) {
284
359
  });
285
360
  // SAFETY: conflicts' shape matches the eight columns named in the SELECT
286
361
  // above.
287
- const conflicts = db.prepare(`
362
+ const conflicts = db
363
+ .prepare(`
288
364
  SELECT id, memory_a_id, memory_b_id, reason, score, status, detected_at, updated_at
289
365
  FROM memory_conflicts
290
366
  WHERE status = 'open'
291
367
  ORDER BY updated_at DESC, id DESC
292
- `).all();
368
+ `)
369
+ .all();
293
370
  mirrorBestEffort('conflict mirrors', () => writeConflictMirrors(hippoRoot, conflicts.map(rowToMemoryConflict)));
294
371
  writeStatsMirror(hippoRoot, buildStatsFromDb(db));
295
372
  }
@@ -0,0 +1,6 @@
1
+ import { type HippoStore, type StoreGroup, type StoreGroups } from './port.js';
2
+ /** A store a gate proved holds `G`, so a handler reads `store.<group>` with no run-time check. */
3
+ export type StoreWith<G extends StoreGroup> = HippoStore & Pick<StoreGroups, Exclude<G, 'base'>>;
4
+ /** The one run-time check behind a `StoreWith`: throws StoreNotPortedError for the first missing group. */
5
+ export declare function narrowStore<G extends StoreGroup>(store: HippoStore, ...groups: readonly [G, ...G[]]): StoreWith<G>;
6
+ //# sourceMappingURL=narrow.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { StoreNotPortedError } from '../util/sqlite-blocked.js';
2
+ import { hasGroup } from './port.js';
3
+ /** The one run-time check behind a `StoreWith`: throws StoreNotPortedError for the first missing group. */
4
+ export function narrowStore(store, ...groups) {
5
+ for (const group of groups)
6
+ if (!hasGroup(store, group))
7
+ throw new StoreNotPortedError(store.kind, group);
8
+ // SAFETY: the loop above proved every group.
9
+ return store;
10
+ }
11
+ //# sourceMappingURL=narrow.js.map