hippo-memory 1.71.0 → 1.72.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 (555) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/apply.d.ts +0 -11
  3. package/dist/agent-memories/apply.js +6 -21
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/copilot.d.ts +1 -3
  7. package/dist/agent-memories/copilot.js +1 -17
  8. package/dist/agent-memories/project-folds.d.ts +10 -0
  9. package/dist/agent-memories/project-folds.js +34 -0
  10. package/dist/agent-memories/sync.js +8 -6
  11. package/dist/api/assemble.js +1 -1
  12. package/dist/api/audit.d.ts +29 -1
  13. package/dist/api/audit.js +44 -5
  14. package/dist/api/auth.d.ts +7 -4
  15. package/dist/api/auth.js +12 -8
  16. package/dist/api/auto-sleep.d.ts +5 -2
  17. package/dist/api/auto-sleep.js +7 -3
  18. package/dist/api/availability.js +2 -3
  19. package/dist/api/cards.d.ts +42 -0
  20. package/dist/api/cards.js +52 -0
  21. package/dist/api/conflicts.d.ts +28 -0
  22. package/dist/api/conflicts.js +61 -0
  23. package/dist/api/context-render.js +4 -3
  24. package/dist/api/context-select.js +9 -11
  25. package/dist/api/context.js +17 -8
  26. package/dist/api/continuity.d.ts +47 -0
  27. package/dist/api/continuity.js +66 -0
  28. package/dist/api/dormant.js +4 -2
  29. package/dist/api/drill-down.js +1 -1
  30. package/dist/api/embeddings.d.ts +17 -0
  31. package/dist/api/embeddings.js +28 -0
  32. package/dist/api/error-reply.d.ts +8 -0
  33. package/dist/api/error-reply.js +21 -0
  34. package/dist/api/forget.d.ts +6 -2
  35. package/dist/api/forget.js +18 -7
  36. package/dist/api/goals.d.ts +1 -1
  37. package/dist/api/goals.js +5 -9
  38. package/dist/api/index.d.ts +4 -2
  39. package/dist/api/index.js +4 -2
  40. package/dist/api/instruction-detect.js +5 -1
  41. package/dist/api/learn.d.ts +4 -0
  42. package/dist/api/learn.js +53 -27
  43. package/dist/api/ledger-db.d.ts +2 -6
  44. package/dist/api/ledger-db.js +4 -36
  45. package/dist/api/memories.d.ts +19 -1
  46. package/dist/api/memories.js +39 -0
  47. package/dist/api/objects.d.ts +1 -1
  48. package/dist/api/outcome.js +1 -1
  49. package/dist/api/pilot-arm.d.ts +1 -11
  50. package/dist/api/pilot-arm.js +5 -45
  51. package/dist/api/predictions.d.ts +3 -1
  52. package/dist/api/predictions.js +6 -0
  53. package/dist/api/projects.d.ts +21 -0
  54. package/dist/api/projects.js +24 -0
  55. package/dist/api/promote.js +1 -1
  56. package/dist/api/prompt-hook.d.ts +15 -2
  57. package/dist/api/prompt-hook.js +44 -4
  58. package/dist/api/recall-cli.d.ts +3 -0
  59. package/dist/api/recall-cli.js +13 -4
  60. package/dist/api/recall-core.js +3 -3
  61. package/dist/api/recall-pipeline.js +6 -7
  62. package/dist/api/recall-request.js +1 -1
  63. package/dist/api/recall.d.ts +0 -3
  64. package/dist/api/recall.js +19 -44
  65. package/dist/api/remember-local.js +1 -1
  66. package/dist/api/remember.d.ts +2 -1
  67. package/dist/api/remember.js +3 -2
  68. package/dist/api/session-end.d.ts +22 -0
  69. package/dist/api/session-end.js +101 -0
  70. package/dist/api/sleep-run.d.ts +1 -1
  71. package/dist/api/sleep-run.js +13 -9
  72. package/dist/api/status.d.ts +24 -0
  73. package/dist/api/status.js +40 -0
  74. package/dist/api/store-init.d.ts +4 -0
  75. package/dist/api/store-init.js +9 -0
  76. package/dist/api/tokens.js +1 -1
  77. package/dist/api/types.d.ts +2 -0
  78. package/dist/api/types.js +6 -1
  79. package/dist/capture/caller-session.d.ts +0 -3
  80. package/dist/capture/caller-session.js +1 -12
  81. package/dist/capture/capture-error.d.ts +2 -2
  82. package/dist/capture/capture-error.js +23 -18
  83. package/dist/capture/codex-patch.js +3 -1
  84. package/dist/capture/command.js +36 -95
  85. package/dist/capture/compact.js +10 -5
  86. package/dist/capture/compaction-items-caller.js +11 -20
  87. package/dist/capture/compaction-record.d.ts +7 -93
  88. package/dist/capture/compaction-record.js +29 -426
  89. package/dist/capture/compaction-spool.d.ts +4 -2
  90. package/dist/capture/compaction-spool.js +20 -6
  91. package/dist/capture/copilot-transcript.d.ts +2 -1
  92. package/dist/capture/copilot-transcript.js +2 -1
  93. package/dist/capture/extract.d.ts +5 -2
  94. package/dist/capture/extract.js +4 -3
  95. package/dist/capture/failure-caller.d.ts +1 -1
  96. package/dist/capture/failure-caller.js +21 -16
  97. package/dist/capture/failure-reading.d.ts +2 -1
  98. package/dist/capture/failure-reading.js +7 -9
  99. package/dist/capture/pre-compact-caller.js +5 -4
  100. package/dist/capture/session-digest.js +4 -3
  101. package/dist/capture/session-end-caller.js +2 -1
  102. package/dist/capture/session-worker.js +3 -4
  103. package/dist/capture/transcript.d.ts +2 -1
  104. package/dist/capture/transcript.js +6 -3
  105. package/dist/capture/working-state.d.ts +4 -2
  106. package/dist/capture/working-state.js +4 -2
  107. package/dist/cli/audit-prune.d.ts +0 -25
  108. package/dist/cli/audit-prune.js +1 -27
  109. package/dist/cli/audit.js +13 -13
  110. package/dist/cli/auth.d.ts +1 -1
  111. package/dist/cli/auth.js +12 -13
  112. package/dist/cli/briefs.d.ts +1 -4
  113. package/dist/cli/briefs.js +37 -292
  114. package/dist/cli/card.js +41 -33
  115. package/dist/cli/client.d.ts +5 -0
  116. package/dist/cli/client.js +24 -8
  117. package/dist/cli/compact-resume-payload.js +1 -1
  118. package/dist/cli/context.d.ts +1 -1
  119. package/dist/cli/context.js +12 -12
  120. package/dist/cli/continuity.d.ts +1 -1
  121. package/dist/cli/continuity.js +36 -39
  122. package/dist/cli/curate.d.ts +1 -1
  123. package/dist/cli/curate.js +23 -27
  124. package/dist/cli/dag.d.ts +1 -1
  125. package/dist/cli/dag.js +23 -8
  126. package/dist/cli/decisions.d.ts +0 -2
  127. package/dist/cli/decisions.js +4 -281
  128. package/dist/cli/eval.d.ts +1 -1
  129. package/dist/cli/eval.js +12 -13
  130. package/dist/cli/explain.d.ts +1 -1
  131. package/dist/cli/explain.js +21 -25
  132. package/dist/cli/flag-values.js +16 -6
  133. package/dist/cli/flags.d.ts +0 -289
  134. package/dist/cli/flags.js +3 -138
  135. package/dist/cli/graph.d.ts +3 -0
  136. package/dist/cli/graph.js +83 -0
  137. package/dist/cli/hook-runtime.d.ts +3 -5
  138. package/dist/cli/hook-runtime.js +7 -34
  139. package/dist/cli/incidents.d.ts +3 -0
  140. package/dist/cli/incidents.js +112 -0
  141. package/dist/cli/init.d.ts +1 -1
  142. package/dist/cli/init.js +28 -19
  143. package/dist/cli/install-steps.d.ts +2 -1
  144. package/dist/cli/install-steps.js +11 -3
  145. package/dist/cli/last-sleep.js +1 -1
  146. package/dist/cli/lenient-id.d.ts +2 -0
  147. package/dist/cli/lenient-id.js +13 -0
  148. package/dist/cli/maintenance.d.ts +3 -3
  149. package/dist/cli/maintenance.js +29 -30
  150. package/dist/cli/notes.d.ts +2 -0
  151. package/dist/cli/notes.js +41 -0
  152. package/dist/cli/open-browser.d.ts +14 -0
  153. package/dist/cli/open-browser.js +26 -0
  154. package/dist/cli/playbooks.d.ts +3 -4
  155. package/dist/cli/playbooks.js +126 -290
  156. package/dist/cli/predictions.d.ts +3 -0
  157. package/dist/cli/predictions.js +175 -0
  158. package/dist/cli/print.js +2 -1
  159. package/dist/cli/projects.js +30 -22
  160. package/dist/cli/quality-repair-once.d.ts +1 -1
  161. package/dist/cli/quality-repair-once.js +6 -5
  162. package/dist/cli/recall.js +13 -7
  163. package/dist/cli/refine-llm.js +17 -17
  164. package/dist/cli/remember.js +12 -12
  165. package/dist/cli/scheduler.js +2 -1
  166. package/dist/cli/serve.js +3 -3
  167. package/dist/cli/session-hooks.d.ts +1 -1
  168. package/dist/cli/session-hooks.js +45 -115
  169. package/dist/cli/setup.d.ts +1 -1
  170. package/dist/cli/setup.js +17 -10
  171. package/dist/cli/shared.d.ts +2 -6
  172. package/dist/cli/shared.js +9 -29
  173. package/dist/cli/sleep-render.js +6 -3
  174. package/dist/cli/sleep.js +6 -37
  175. package/dist/cli/status.d.ts +3 -3
  176. package/dist/cli/status.js +32 -35
  177. package/dist/cli/transfer.d.ts +1 -1
  178. package/dist/cli/transfer.js +33 -31
  179. package/dist/cli/usage.d.ts +0 -79
  180. package/dist/cli/usage.js +1 -695
  181. package/dist/cli/verb-row.d.ts +32 -0
  182. package/dist/cli/verb-row.js +6 -0
  183. package/dist/cli/verbs/health.d.ts +27 -0
  184. package/dist/cli/verbs/health.js +232 -0
  185. package/dist/cli/verbs/memory.d.ts +16 -0
  186. package/dist/cli/verbs/memory.js +244 -0
  187. package/dist/cli/verbs/objects.d.ts +20 -0
  188. package/dist/cli/verbs/objects.js +254 -0
  189. package/dist/cli/verbs/sessions.d.ts +31 -0
  190. package/dist/cli/verbs/sessions.js +312 -0
  191. package/dist/cli/verbs.d.ts +81 -0
  192. package/dist/cli/verbs.js +7 -0
  193. package/dist/cli/versioned-verbs.d.ts +51 -0
  194. package/dist/cli/versioned-verbs.js +79 -0
  195. package/dist/cli.d.ts +1 -272
  196. package/dist/cli.js +23 -313
  197. package/dist/connectors/dlq.d.ts +39 -3
  198. package/dist/connectors/dlq.js +37 -3
  199. package/dist/connectors/github/backfill.js +12 -3
  200. package/dist/connectors/github/dlq.js +31 -73
  201. package/dist/connectors/github/ingest.d.ts +2 -6
  202. package/dist/connectors/github/ingest.js +3 -28
  203. package/dist/connectors/github/webhook.d.ts +2 -1
  204. package/dist/connectors/github/webhook.js +33 -2
  205. package/dist/connectors/ingest.d.ts +10 -0
  206. package/dist/connectors/ingest.js +28 -0
  207. package/dist/connectors/slack/dlq.js +49 -71
  208. package/dist/connectors/slack/ingest.d.ts +2 -6
  209. package/dist/connectors/slack/ingest.js +2 -27
  210. package/dist/connectors/slack/webhook.d.ts +2 -1
  211. package/dist/connectors/slack/webhook.js +2 -1
  212. package/dist/consolidate/conflicts.js +1 -1
  213. package/dist/consolidate/dag.js +15 -9
  214. package/dist/consolidate/dedupe.d.ts +7 -0
  215. package/dist/consolidate/dedupe.js +5 -3
  216. package/dist/consolidate/llm-passes.js +45 -19
  217. package/dist/consolidate/memory-value.js +2 -1
  218. package/dist/consolidate/merge.js +2 -2
  219. package/dist/consolidate/physics-pass.d.ts +6 -1
  220. package/dist/consolidate/physics-pass.js +26 -6
  221. package/dist/consolidate/replay.js +11 -4
  222. package/dist/consolidate/sleep.js +8 -5
  223. package/dist/consolidate/traces.js +3 -3
  224. package/dist/core/ablation.d.ts +10 -0
  225. package/dist/core/ablation.js +12 -0
  226. package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
  227. package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
  228. package/dist/core/ambient.d.ts +4 -0
  229. package/dist/core/ambient.js +39 -18
  230. package/dist/core/api-errors.d.ts +16 -0
  231. package/dist/core/api-errors.js +20 -0
  232. package/dist/core/card.js +3 -1
  233. package/dist/core/compaction-timing.d.ts +7 -0
  234. package/dist/core/compaction-timing.js +9 -0
  235. package/dist/core/config.d.ts +1 -1
  236. package/dist/core/config.js +7 -2
  237. package/dist/core/cosine.d.ts +3 -0
  238. package/dist/core/cosine.js +19 -0
  239. package/dist/{store → core}/markdown.d.ts +1 -1
  240. package/dist/{store → core}/markdown.js +2 -2
  241. package/dist/core/memory-audit.d.ts +17 -0
  242. package/dist/core/memory-audit.js +54 -0
  243. package/dist/core/memory.d.ts +10 -4
  244. package/dist/core/memory.js +25 -18
  245. package/dist/{consolidate → core}/merged-row.d.ts +1 -1
  246. package/dist/{consolidate → core}/merged-row.js +1 -1
  247. package/dist/core/physics.js +6 -16
  248. package/dist/core/prediction.d.ts +3 -0
  249. package/dist/core/prediction.js +6 -0
  250. package/dist/core/project-identity.d.ts +3 -0
  251. package/dist/core/project-identity.js +10 -1
  252. package/dist/{store → core}/recall-scope.d.ts +1 -10
  253. package/dist/{store → core}/recall-scope.js +2 -19
  254. package/dist/db/busy.d.ts +2 -7
  255. package/dist/db/busy.js +21 -26
  256. package/dist/db/connect.d.ts +0 -1
  257. package/dist/db/connect.js +5 -6
  258. package/dist/db/index.d.ts +3 -3
  259. package/dist/db/index.js +3 -3
  260. package/dist/db/migrations/index.d.ts +1 -1
  261. package/dist/db/migrations/index.js +3 -1
  262. package/dist/db/migrations/v55.d.ts +3 -0
  263. package/dist/db/migrations/v55.js +17 -0
  264. package/dist/db/open.d.ts +0 -2
  265. package/dist/db/open.js +6 -10
  266. package/dist/db/physics-state.js +3 -3
  267. package/dist/db/tables.d.ts +2 -0
  268. package/dist/db/tables.js +6 -2
  269. package/dist/db/vector-store.js +17 -4
  270. package/dist/db/wal-checkpointer.js +2 -1
  271. package/dist/doctor.js +11 -8
  272. package/dist/embeddings/local.d.ts +62 -0
  273. package/dist/embeddings/local.js +146 -0
  274. package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
  275. package/dist/{store/embeddings → embeddings}/provider.js +18 -15
  276. package/dist/embeddings/transformers.d.ts +26 -0
  277. package/dist/embeddings/transformers.js +89 -0
  278. package/dist/entry/session-text.d.ts +1 -1
  279. package/dist/entry/session-text.js +1 -1
  280. package/dist/eval/eval-suite.js +17 -11
  281. package/dist/eval/eval.js +1 -1
  282. package/dist/eval/judgment.js +11 -4
  283. package/dist/graph/extract.js +3 -3
  284. package/dist/graph/recall.js +1 -1
  285. package/dist/graph/view.js +13 -5
  286. package/dist/graph/write.d.ts +1 -1
  287. package/dist/graph/write.js +9 -9
  288. package/dist/hooks/codex-session.js +3 -2
  289. package/dist/hooks/codex-wrapper.js +2 -1
  290. package/dist/hooks/json-hooks.js +4 -2
  291. package/dist/hooks/opencode.js +8 -5
  292. package/dist/hooks/shared.d.ts +0 -6
  293. package/dist/hooks/shared.js +4 -15
  294. package/dist/importers/core.js +1 -1
  295. package/dist/importers/sources.js +5 -4
  296. package/dist/importers/vault.js +7 -5
  297. package/dist/index.d.ts +3 -2
  298. package/dist/index.js +3 -2
  299. package/dist/learn/autolearn.d.ts +10 -2
  300. package/dist/learn/autolearn.js +32 -12
  301. package/dist/learn/churn-git.js +13 -4
  302. package/dist/learn/extract.d.ts +3 -2
  303. package/dist/learn/extract.js +6 -4
  304. package/dist/learn/forward-claim-detector.js +4 -2
  305. package/dist/learn/invalidation.js +10 -6
  306. package/dist/mcp/admin-tools.d.ts +2 -2
  307. package/dist/mcp/admin-tools.js +27 -48
  308. package/dist/mcp/format.js +3 -2
  309. package/dist/mcp/framing.d.ts +1 -0
  310. package/dist/mcp/framing.js +1 -1
  311. package/dist/mcp/memory-tools.js +3 -1
  312. package/dist/mcp/protocol.d.ts +11 -7
  313. package/dist/mcp/protocol.js +25 -12
  314. package/dist/mcp/recall-tools.js +12 -9
  315. package/dist/mcp/request.js +2 -1
  316. package/dist/mcp/stdio.js +24 -8
  317. package/dist/mcp/tool-args.js +2 -1
  318. package/dist/mcp/tools.js +44 -21
  319. package/dist/objects/customer-notes.d.ts +2 -2
  320. package/dist/objects/decisions.d.ts +2 -2
  321. package/dist/objects/descriptor.d.ts +1 -1
  322. package/dist/objects/incidents.d.ts +2 -2
  323. package/dist/objects/lifecycle.d.ts +1 -1
  324. package/dist/objects/lifecycle.js +2 -1
  325. package/dist/objects/policies.d.ts +2 -2
  326. package/dist/objects/policies.js +2 -1
  327. package/dist/objects/processes.d.ts +2 -2
  328. package/dist/objects/project-briefs.d.ts +2 -2
  329. package/dist/objects/project-briefs.js +2 -3
  330. package/dist/objects/skills.d.ts +2 -2
  331. package/dist/postinstall.js +1 -1
  332. package/dist/rerankers/clef.js +3 -6
  333. package/dist/rerankers/cross-encoder.d.ts +31 -2
  334. package/dist/rerankers/cross-encoder.js +63 -97
  335. package/dist/rerankers/index.js +5 -4
  336. package/dist/rerankers/jev.js +2 -4
  337. package/dist/rerankers/outage-warning.d.ts +3 -1
  338. package/dist/rerankers/outage-warning.js +5 -3
  339. package/dist/search/bm25-search.js +1 -1
  340. package/dist/search/boosts.js +1 -1
  341. package/dist/search/embed-memories.d.ts +9 -0
  342. package/dist/search/embed-memories.js +377 -0
  343. package/dist/search/goal-boost.d.ts +1 -1
  344. package/dist/search/goal-boost.js +6 -3
  345. package/dist/search/hybrid.d.ts +9 -2
  346. package/dist/search/hybrid.js +9 -4
  347. package/dist/search/physics-search.d.ts +6 -3
  348. package/dist/search/physics-search.js +22 -15
  349. package/dist/search/rerank.js +1 -1
  350. package/dist/search/vector.d.ts +8 -6
  351. package/dist/search/vector.js +10 -13
  352. package/dist/server/auth.d.ts +2 -0
  353. package/dist/server/auth.js +17 -7
  354. package/dist/server/boot.js +7 -66
  355. package/dist/server/client-ip.d.ts +0 -2
  356. package/dist/server/client-ip.js +3 -2
  357. package/dist/server/deadline.d.ts +0 -2
  358. package/dist/server/deadline.js +1 -7
  359. package/dist/server/defaults.d.ts +1 -0
  360. package/dist/server/defaults.js +1 -0
  361. package/dist/server/mcp-http.js +16 -11
  362. package/dist/server/request.js +7 -2
  363. package/dist/server/route-checks.d.ts +7 -0
  364. package/dist/server/route-checks.js +42 -0
  365. package/dist/server/route-table.d.ts +9 -8
  366. package/dist/server/route-table.js +127 -132
  367. package/dist/server/routes/admin.d.ts +8 -8
  368. package/dist/server/routes/admin.js +13 -21
  369. package/dist/server/routes/customer-notes.d.ts +6 -6
  370. package/dist/server/routes/customer-notes.js +1 -2
  371. package/dist/server/routes/decisions.d.ts +6 -6
  372. package/dist/server/routes/decisions.js +2 -4
  373. package/dist/server/routes/incidents.d.ts +6 -6
  374. package/dist/server/routes/incidents.js +2 -5
  375. package/dist/server/routes/memories.d.ts +9 -9
  376. package/dist/server/routes/memories.js +15 -38
  377. package/dist/server/routes/object-routes.d.ts +6 -6
  378. package/dist/server/routes/object-routes.js +4 -7
  379. package/dist/server/routes/policies.d.ts +7 -7
  380. package/dist/server/routes/policies.js +2 -4
  381. package/dist/server/routes/predictions.d.ts +6 -6
  382. package/dist/server/routes/predictions.js +9 -13
  383. package/dist/server/routes/processes.d.ts +6 -6
  384. package/dist/server/routes/processes.js +1 -2
  385. package/dist/server/routes/project-briefs.d.ts +7 -7
  386. package/dist/server/routes/project-briefs.js +2 -4
  387. package/dist/server/routes/recall.d.ts +5 -5
  388. package/dist/server/routes/recall.js +6 -10
  389. package/dist/server/routes/skills.d.ts +7 -7
  390. package/dist/server/routes/skills.js +2 -4
  391. package/dist/server/server-detect.d.ts +7 -1
  392. package/dist/server/server-detect.js +36 -11
  393. package/dist/server/sleep-child.js +26 -7
  394. package/dist/server/sleep-offload.d.ts +11 -5
  395. package/dist/server/sleep-offload.js +17 -11
  396. package/dist/server/types.d.ts +22 -10
  397. package/dist/server/validation.d.ts +1 -2
  398. package/dist/server/validation.js +6 -11
  399. package/dist/server.d.ts +5 -4
  400. package/dist/server.js +5 -4
  401. package/dist/sharing/global-store.js +2 -2
  402. package/dist/sharing/global-sync.js +38 -45
  403. package/dist/sharing/project-merge.d.ts +7 -14
  404. package/dist/sharing/project-merge.js +57 -121
  405. package/dist/sharing/search-both.js +1 -1
  406. package/dist/sharing/share.d.ts +2 -0
  407. package/dist/sharing/share.js +37 -34
  408. package/dist/store/ambient.js +5 -6
  409. package/dist/store/audit-event.d.ts +1 -1
  410. package/dist/store/audit.d.ts +0 -16
  411. package/dist/store/audit.js +4 -55
  412. package/dist/store/auth.d.ts +4 -2
  413. package/dist/store/auth.js +7 -3
  414. package/dist/store/candidates.d.ts +3 -2
  415. package/dist/store/candidates.js +42 -23
  416. package/dist/store/capture-write.d.ts +17 -0
  417. package/dist/store/capture-write.js +35 -0
  418. package/dist/store/cards.js +1 -1
  419. package/dist/store/compaction-caller.d.ts +18 -0
  420. package/dist/store/compaction-caller.js +29 -0
  421. package/dist/store/compactions-record.d.ts +115 -0
  422. package/dist/store/compactions-record.js +417 -0
  423. package/dist/store/compactions.js +6 -4
  424. package/dist/store/conflicts.js +7 -4
  425. package/dist/store/connectors/dlq.d.ts +10 -0
  426. package/dist/store/connectors/dlq.js +32 -0
  427. package/dist/store/connectors/github.d.ts +7 -9
  428. package/dist/store/connectors/github.js +30 -53
  429. package/dist/store/connectors/slack.d.ts +2 -11
  430. package/dist/store/connectors/slack.js +18 -47
  431. package/dist/store/dashboard-reads.js +7 -6
  432. package/dist/store/delete-and-batch.d.ts +6 -0
  433. package/dist/store/delete-and-batch.js +36 -3
  434. package/dist/store/delivery-recorder.d.ts +10 -3
  435. package/dist/store/delivery-recorder.js +12 -5
  436. package/dist/store/descendant-page.js +6 -3
  437. package/dist/store/dormant.d.ts +1 -1
  438. package/dist/store/dormant.js +3 -1
  439. package/dist/store/embeddings/index.d.ts +2 -12
  440. package/dist/store/embeddings/index.js +5 -374
  441. package/dist/store/entry-reads.d.ts +13 -4
  442. package/dist/store/entry-reads.js +47 -11
  443. package/dist/store/entry-writes.d.ts +5 -5
  444. package/dist/store/entry-writes.js +32 -12
  445. package/dist/store/failure-log-at.d.ts +8 -0
  446. package/dist/store/failure-log-at.js +16 -0
  447. package/dist/store/failure-log.d.ts +2 -2
  448. package/dist/store/failure-log.js +5 -3
  449. package/dist/{trust → store}/gated-write.d.ts +3 -1
  450. package/dist/{trust → store}/gated-write.js +7 -5
  451. package/dist/store/goals.js +20 -18
  452. package/dist/store/graph-reads.js +4 -2
  453. package/dist/store/graph-writes.d.ts +6 -6
  454. package/dist/store/graph-writes.js +48 -71
  455. package/dist/store/handoffs.d.ts +1 -1
  456. package/dist/store/handoffs.js +6 -6
  457. package/dist/store/index-and-stats.js +2 -2
  458. package/dist/store/key-writes.js +1 -1
  459. package/dist/store/ledger-turn.d.ts +9 -0
  460. package/dist/store/ledger-turn.js +38 -0
  461. package/dist/store/mirrors.js +10 -6
  462. package/dist/store/open.d.ts +0 -4
  463. package/dist/store/open.js +40 -53
  464. package/dist/store/pilot-arm.d.ts +12 -0
  465. package/dist/store/pilot-arm.js +42 -0
  466. package/dist/store/port.d.ts +9 -3
  467. package/dist/store/port.js +8 -0
  468. package/dist/store/predictions.d.ts +1 -2
  469. package/dist/store/predictions.js +3 -6
  470. package/dist/store/project-tags.d.ts +62 -0
  471. package/dist/store/project-tags.js +67 -0
  472. package/dist/store/quarantine.js +2 -1
  473. package/dist/store/recall-trace.d.ts +2 -0
  474. package/dist/store/recall-trace.js +18 -2
  475. package/dist/store/rejected-values.js +2 -1
  476. package/dist/store/rejection-probe.d.ts +4 -0
  477. package/dist/store/rejection-probe.js +19 -0
  478. package/dist/store/rejection.d.ts +0 -17
  479. package/dist/store/rejection.js +1 -21
  480. package/dist/store/rule-sql.d.ts +9 -0
  481. package/dist/store/rule-sql.js +21 -2
  482. package/dist/store/search-rows.js +9 -4
  483. package/dist/store/sessions.js +4 -2
  484. package/dist/store/set-aside.d.ts +14 -0
  485. package/dist/store/set-aside.js +23 -0
  486. package/dist/store/sqlite/busy.d.ts +3 -0
  487. package/dist/store/sqlite/busy.js +8 -0
  488. package/dist/store/sqlite/connector-events-group.js +4 -7
  489. package/dist/store/sqlite/connector-writes-group.js +3 -3
  490. package/dist/store/sqlite/entry-writes-group.js +2 -2
  491. package/dist/store/sqlite/error-codec.js +4 -3
  492. package/dist/store/sqlite/executor.js +10 -4
  493. package/dist/store/sqlite/graph-reads-group.js +1 -1
  494. package/dist/store/sqlite/held-connection.d.ts +9 -0
  495. package/dist/store/sqlite/held-connection.js +41 -0
  496. package/dist/store/sqlite/object-rows.d.ts +1 -1
  497. package/dist/store/sqlite/objects-group.d.ts +1 -1
  498. package/dist/store/sqlite/objects-group.js +1 -1
  499. package/dist/store/sqlite/store.js +14 -12
  500. package/dist/store/summaries.d.ts +3 -3
  501. package/dist/store/summaries.js +5 -4
  502. package/dist/store/token-ledger.d.ts +0 -7
  503. package/dist/store/token-ledger.js +0 -35
  504. package/dist/store/vector-index.js +3 -2
  505. package/dist/support-bundle.js +2 -3
  506. package/dist/trust/reject-flow.js +2 -2
  507. package/dist/util/agent-homes.d.ts +15 -0
  508. package/dist/util/agent-homes.js +34 -0
  509. package/dist/util/anthropic-messages.d.ts +3 -0
  510. package/dist/util/anthropic-messages.js +22 -5
  511. package/dist/util/chunked.d.ts +3 -0
  512. package/dist/util/chunked.js +10 -0
  513. package/dist/util/ellipsize.d.ts +3 -0
  514. package/dist/util/ellipsize.js +5 -0
  515. package/dist/util/env.d.ts +2 -1
  516. package/dist/util/env.js +2 -1
  517. package/dist/util/format.d.ts +3 -0
  518. package/dist/util/format.js +6 -0
  519. package/dist/util/hook-payload.d.ts +8 -0
  520. package/dist/util/hook-payload.js +37 -0
  521. package/dist/util/http-retry.d.ts +6 -0
  522. package/dist/util/http-retry.js +43 -5
  523. package/dist/util/http-util.d.ts +0 -8
  524. package/dist/util/http-util.js +10 -21
  525. package/dist/util/limits.d.ts +7 -0
  526. package/dist/util/limits.js +14 -0
  527. package/dist/util/log.d.ts +4 -0
  528. package/dist/util/log.js +9 -0
  529. package/dist/util/request-scope.d.ts +3 -1
  530. package/dist/util/request-scope.js +11 -6
  531. package/dist/util/secret-detect.js +6 -1
  532. package/dist/util/sqlite-blocked.d.ts +2 -0
  533. package/dist/util/sqlite-blocked.js +5 -0
  534. package/dist/util/stream-tee.d.ts +3 -0
  535. package/dist/util/stream-tee.js +35 -0
  536. package/dist/util/time.d.ts +4 -0
  537. package/dist/util/time.js +4 -0
  538. package/dist/util/version.d.ts +1 -1
  539. package/dist/util/version.js +1 -1
  540. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  541. package/extensions/openclaw-plugin/package.json +1 -1
  542. package/openclaw.plugin.json +1 -1
  543. package/package.json +2 -2
  544. package/dist/store/embeddings/local.d.ts +0 -15
  545. package/dist/store/embeddings/local.js +0 -175
  546. /package/dist/{cli → api}/correction-latency.d.ts +0 -0
  547. /package/dist/{cli → api}/correction-latency.js +0 -0
  548. /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
  549. /package/dist/{cli → api}/provenance-coverage.js +0 -0
  550. /package/dist/{store → core}/object-types.d.ts +0 -0
  551. /package/dist/{store → core}/object-types.js +0 -0
  552. /package/dist/{capture → util}/compaction-items.d.ts +0 -0
  553. /package/dist/{capture → util}/compaction-items.js +0 -0
  554. /package/dist/{store → util}/yaml.d.ts +0 -0
  555. /package/dist/{store → util}/yaml.js +0 -0
@@ -1,6 +1,7 @@
1
1
  import { isFtsAvailable, closeHippoDb } from '../db/index.js';
2
2
  import { tokenize } from '../util/tokenize.js';
3
- import { isPersonalScope, scopeAdmitSql } from './recall-scope.js';
3
+ import { isPersonalScope } from '../core/recall-scope.js';
4
+ import { scopeAdmitSql } from './rule-sql.js';
4
5
  import { ftsTermParts, RAREST_TERM_COUNT, rarestFtsQuery } from '../core/prompt-recall.js';
5
6
  import { errorMessage, log } from '../util/log.js';
6
7
  import { originInSql } from '../core/project-identity.js';
@@ -26,7 +27,10 @@ function withProject(scope, col, origin) {
26
27
  return scope;
27
28
  // A string is the shape published callers passed before a project could carry several names.
28
29
  const originProjects = [origin].flat();
29
- return { sql: `${scope.sql} AND (${col}origin_project = '' OR ${originInSql(originProjects, `${col}origin_project`)})`, params: [...scope.params, ...originProjects] };
30
+ return {
31
+ sql: `${scope.sql} AND (${col}origin_project = '' OR ${originInSql(originProjects, `${col}origin_project`)})`,
32
+ params: [...scope.params, ...originProjects],
33
+ };
30
34
  }
31
35
  /** Scope rule for recall: none requested is default-deny; 'exact' narrows to the request; 'additive' adds it to the default set, unless it is personal,
32
36
  * which only `ownScope` opens. */
@@ -85,7 +89,8 @@ function searchPredicates(tenantId, scopeFilter, includeSuperseded, originProjec
85
89
  }
86
90
  /** Every admitted row, oldest first; the no-terms path and the last-resort fallback share it. */
87
91
  function selectAllCandidates(db, p, limit) {
88
- const sql = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories${p.tenantOnlyPredicate}${p.archivedClauseTenantOnly}${p.plainScope.sql}${p.currentNoAlias} ORDER BY created ASC, id ASC LIMIT ?`;
92
+ const sql = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories${p.tenantOnlyPredicate}${p.archivedClauseTenantOnly}` +
93
+ `${p.plainScope.sql}${p.currentNoAlias} ORDER BY created ASC, id ASC LIMIT ?`;
89
94
  // SAFETY: sql selects exactly MEMORY_SELECT_COLUMNS, whose column list
90
95
  // matches MemoryRow's field set.
91
96
  return db.prepare(sql).all(...p.tenantParams, ...p.scopeParams, limit);
@@ -155,7 +160,7 @@ export function loadRecallSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH
155
160
  // Split out so callers with an already-open db (the prompt-recall path) skip
156
161
  // the initStore+open/close cycle per store per call.
157
162
  export function loadRecallSearchEntriesFromDb(db, query, options = {}) {
158
- const { limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true, originProjects, ownScope } = options;
163
+ const { limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true, originProjects, ownScope, } = options;
159
164
  const scopeFilter = recallScopeFilter(requestedScope, explicitScopeMode, ownScope);
160
165
  return loadSearchRows(db, query, limit, tenantId, { scopeFilter, includeSuperseded, originProjects }).map(rowToEntry);
161
166
  }
@@ -1,3 +1,4 @@
1
+ import { HOUR_MS } from '../util/time.js';
1
2
  import { isSharedStore } from '../core/config.js';
2
3
  import { closeHippoDb, HOOK_DB_WAIT_MS, scopedBusyWait, withWriteScope } from '../db/index.js';
3
4
  import { raiseMinBinary } from '../db/meta.js';
@@ -24,8 +25,9 @@ export function continuityStamp(key) {
24
25
  }
25
26
  // An unkeyed write acts on the tenant's newest or every active row, which on a shared store belong to other owners.
26
27
  function assertKeyedOnSharedStore(fn, hippoRoot, key) {
27
- if (!key && isSharedStore(hippoRoot))
28
+ if (!key && isSharedStore(hippoRoot)) {
28
29
  throw new Error(`${fn}: a shared store keeps one task snapshot per owner and project, so this write needs their continuity key`);
30
+ }
29
31
  }
30
32
  function insertSnapshot(db, tenantId, snapshot, now, stamp) {
31
33
  const result = db.prepare(`
@@ -95,7 +97,7 @@ export function loadActiveTaskSnapshot(hippoRoot, tenantId, key) {
95
97
  }
96
98
  /** Default freshness bound for AMBIENT active-task-snapshot reads: 72h rather than 48h so a Friday-evening orphan still offers continuity on Monday;
97
99
  * override via `loadFreshActiveTaskSnapshot`'s `opts.maxAgeMs`; deliberately no env knob. */
98
- export const SNAPSHOT_AMBIENT_MAX_AGE_MS = 72 * 60 * 60 * 1000;
100
+ export const SNAPSHOT_AMBIENT_MAX_AGE_MS = 72 * HOUR_MS;
99
101
  /** A usable session id: non-null, non-empty string; named so the owner-match rule in `loadFreshActiveTaskSnapshot` states its contract once. */
100
102
  function isNonEmptySessionId(value) {
101
103
  return typeof value === 'string' && value.length > 0;
@@ -0,0 +1,14 @@
1
+ import type { DatabaseSyncLike } from '../db/index.js';
2
+ import { type MemoryEntry } from '../core/memory.js';
3
+ export declare const SYNC_ACTOR = "agent-memories";
4
+ export type SetAsideWhy = 'note-gone' | 'note-changed' | 'handover' | 'project-merge' | 'project-repair';
5
+ export type SetAsideResult = {
6
+ readonly kind: 'untagged';
7
+ readonly entry: MemoryEntry;
8
+ } | {
9
+ readonly kind: 'dormant';
10
+ readonly id: string;
11
+ };
12
+ /** Design 6's set-aside on the caller's transaction: a pinned row only loses the tag, any other goes dormant, restorable. */
13
+ export declare function setAsideRow(db: DatabaseSyncLike, tag: string, row: MemoryEntry, why: SetAsideWhy): SetAsideResult;
14
+ //# sourceMappingURL=set-aside.d.ts.map
@@ -0,0 +1,23 @@
1
+ // Takes an imported agent note out of recall on the caller's transaction; the note sync and the project repair both use it.
2
+ import { appendAuditEvent } from './audit.js';
3
+ import { insertDormantRow } from './dormant.js';
4
+ import { calculateStrength } from '../core/memory.js';
5
+ import { deleteEntryRowInTx, setEntryTagsInTx } from './entry-writes.js';
6
+ export const SYNC_ACTOR = 'agent-memories';
7
+ /** Design 6's set-aside on the caller's transaction: a pinned row only loses the tag, any other goes dormant, restorable. */
8
+ export function setAsideRow(db, tag, row, why) {
9
+ const untagged = { ...row, tags: row.tags.filter((t) => t !== tag) };
10
+ const audit = (metadata) => appendAuditEvent(db, { tenantId: row.tenantId, actor: SYNC_ACTOR, op: 'agent_memory_set_aside', targetId: row.id, metadata });
11
+ if (row.pinned) {
12
+ setEntryTagsInTx(db, untagged);
13
+ audit({ why, untagged: true });
14
+ return { kind: 'untagged', entry: untagged };
15
+ }
16
+ const now = new Date();
17
+ // Sleep's dormant move skips kept rows, so the steps are written out here without its filter.
18
+ insertDormantRow(db, { entry: untagged, strength: calculateStrength(row, now), reason: 'source-deleted', dormantAt: now.toISOString() });
19
+ deleteEntryRowInTx(db, row, SYNC_ACTOR);
20
+ audit({ why });
21
+ return { kind: 'dormant', id: row.id };
22
+ }
23
+ //# sourceMappingURL=set-aside.js.map
@@ -0,0 +1,3 @@
1
+ /** A held lock in any store: SQLite's busy codes or a port's StoreBusyError. */
2
+ export declare function isStoreBusy<E>(error: E): boolean;
3
+ //# sourceMappingURL=busy.d.ts.map
@@ -0,0 +1,8 @@
1
+ // Busy detection lives with the adapter, so the port names no SQLite error code.
2
+ import { isSqliteBusy } from '../../db/busy.js';
3
+ import { StoreBusyError } from '../port.js';
4
+ /** A held lock in any store: SQLite's busy codes or a port's StoreBusyError. */
5
+ export function isStoreBusy(error) {
6
+ return error instanceof StoreBusyError || isSqliteBusy(error);
7
+ }
8
+ //# sourceMappingURL=busy.js.map
@@ -1,22 +1,19 @@
1
1
  // hippo.db's half of the ConnectorEvents store group: each call on a handle of its own.
2
- import { archiveDeletedArtifact, eventSeenAt, githubRouting, insertGitHubDlq, logEvent, seenEvent } from '../connectors/github.js';
2
+ import { archiveDeletedArtifact, githubEventRecord, githubEventSeenAt, githubRouting, insertGitHubDlq, markGitHubEventSeen } from '../connectors/github.js';
3
3
  import { insertSlackDlq, markSlackEventSeen, rawMemoryIdForArtifactAt, slackEventRecord, slackEventSeenAt, slackTeamRoute } from '../connectors/slack.js';
4
4
  import { onHandle } from '../open.js';
5
5
  function eventRecord(hippoRoot, event) {
6
- if (event.connector === 'slack')
7
- return slackEventRecord(hippoRoot, event.eventId);
8
- const logged = seenEvent(hippoRoot, event.idempotencyKey);
9
- return logged ? { seen: true, memoryId: logged.memoryId } : { seen: false };
6
+ return event.connector === 'slack' ? slackEventRecord(hippoRoot, event.eventId) : githubEventRecord(hippoRoot, event.idempotencyKey);
10
7
  }
11
8
  function markEventSeen(hippoRoot, event) {
12
9
  if (event.connector === 'slack')
13
10
  return markSlackEventSeen(hippoRoot, event.eventId, null);
14
11
  const { idempotencyKey, deliveryId, eventName } = event;
15
- logEvent(hippoRoot, { idempotencyKey, deliveryId, eventName, memoryId: null });
12
+ markGitHubEventSeen(hippoRoot, { idempotencyKey, deliveryId, eventName, memoryId: null });
16
13
  }
17
14
  function deletionTarget(hippoRoot, { event, artifactRef, tenantId }) {
18
15
  return onHandle(hippoRoot, (db) => {
19
- const seen = event.connector === 'slack' ? slackEventSeenAt(db, event.eventId) : eventSeenAt(db, event.idempotencyKey);
16
+ const seen = event.connector === 'slack' ? slackEventSeenAt(db, event.eventId) : githubEventSeenAt(db, event.idempotencyKey);
20
17
  return seen ? { seen: true } : { seen: false, memoryId: rawMemoryIdForArtifactAt(db, artifactRef, tenantId) };
21
18
  });
22
19
  }
@@ -1,4 +1,4 @@
1
- import { eventMemoryAt, logEventAt } from '../connectors/github.js';
1
+ import { githubEventMemoryAt, markGitHubEventSeenAt } from '../connectors/github.js';
2
2
  import { markSlackEventSeenAt, slackEventMemoryAt } from '../connectors/slack.js';
3
3
  import { stampOriginProject } from '../entry-row.js';
4
4
  import { writeEntryMirrors } from '../entry-writes.js';
@@ -13,10 +13,10 @@ function logEvent(db, event, memoryId) {
13
13
  if (event.connector === 'slack')
14
14
  return markSlackEventSeenAt(db, event.eventId, memoryId);
15
15
  const { idempotencyKey, deliveryId, eventName } = event;
16
- return logEventAt(db, { idempotencyKey, deliveryId, eventName, memoryId });
16
+ return markGitHubEventSeenAt(db, { idempotencyKey, deliveryId, eventName, memoryId });
17
17
  }
18
18
  function loggedMemory(db, event) {
19
- return event.connector === 'slack' ? slackEventMemoryAt(db, event.eventId) : eventMemoryAt(db, event.idempotencyKey);
19
+ return event.connector === 'slack' ? slackEventMemoryAt(db, event.eventId) : githubEventMemoryAt(db, event.idempotencyKey);
20
20
  }
21
21
  /** The record, then the log row, go in after the memory row and ahead of its remember row, as a second store must order them. */
22
22
  function writeWithCompanions(db, { entry, actor, event, quarantine }) {
@@ -5,9 +5,9 @@ import { isSqliteBusy, withWriteScope } from '../../db/index.js';
5
5
  import { errorFields, errorMessage, log } from '../../util/log.js';
6
6
  import { entryAfterOutcome } from '../../core/memory.js';
7
7
  import { archiveRawMemory } from '../raw-archive.js';
8
- import { ownScopeTouches } from '../recall-scope.js';
8
+ import { ownScopeTouches } from '../../core/recall-scope.js';
9
9
  import { recordTraceOutcome } from '../recall-trace.js';
10
- import { RejectedValueError } from '../rejection.js';
10
+ import { RejectedValueError } from '../../core/api-errors.js';
11
11
  import { markSummaryDirtyInTx } from '../summary-dirty.js';
12
12
  import { auditRejectionRefusal } from '../audit-event.js';
13
13
  import { deleteEntryCore } from '../delete-and-batch.js';
@@ -2,11 +2,12 @@
2
2
  // of its class: the server's mappers test `instanceof`, `errcode` and fields.
3
3
  import { BadRequestError, ConflictError, ForbiddenError, NotFoundError } from '../../core/api-errors.js';
4
4
  import { RawAppendOnlyError } from '../../core/raw-append-only.js';
5
- import { IncompatibleBinaryError, StoreBusyError } from '../../db/index.js';
5
+ import { IncompatibleBinaryError } from '../../db/index.js';
6
+ import { StoreBusyError } from '../port.js';
6
7
  import { BodyTimeoutError, BodyTooLargeError, HttpError } from '../../util/http-util.js';
7
8
  import { errorMessage, log } from '../../util/log.js';
8
- import { ScopeForbiddenError } from '../recall-scope.js';
9
- import { RejectedValueError } from '../rejection.js';
9
+ import { ScopeForbiddenError } from '../../core/recall-scope.js';
10
+ import { RejectedValueError } from '../../core/api-errors.js';
10
11
  import { OtherStoreFolderError, SqliteBlockedError, StoreNotPortedError } from '../../util/sqlite-blocked.js';
11
12
  // Every class the server maps by, at or below the store layer. Abstract ApiError is absent: only its four subclasses are thrown.
12
13
  const CLASSES = [
@@ -2,11 +2,12 @@
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { SHARE_ENV, Worker } from 'node:worker_threads';
4
4
  import { addAuditWriteFailures } from '../audit.js';
5
- import { getHippoDbPath, SERVER_DB_WAIT_MS, StoreBusyError } from '../../db/index.js';
5
+ import { getHippoDbPath, SERVER_DB_WAIT_MS } from '../../db/index.js';
6
+ import { StoreBusyError } from '../port.js';
6
7
  import { autoCheckpointPages } from '../../db/wal-checkpointer.js';
7
8
  import { envStoreQueueMax } from '../../util/env.js';
8
9
  import { DeadlineExceededError } from '../../util/http-util.js';
9
- import { errorMessage, log } from '../../util/log.js';
10
+ import { errorFields, errorMessage, log } from '../../util/log.js';
10
11
  import { requestScopes } from '../../util/request-scope.js';
11
12
  import { decodeError } from './error-codec.js';
12
13
  import { workerCounts } from './executor-counts.js';
@@ -27,6 +28,10 @@ const DEFAULT_WRITE_GRACE_MS = 2000;
27
28
  function laneOf(mode) {
28
29
  return { mode, queue: [], running: undefined, worker: undefined, stopping: undefined, commitFlag: undefined };
29
30
  }
31
+ // A thread that will not stop leaves a live worker behind, so the rejection is logged rather than dropped.
32
+ function terminateLogged(worker) {
33
+ worker.terminate().catch((err) => log.warn('the store worker did not terminate cleanly', errorFields(err)));
34
+ }
30
35
  /** Gives `pending`'s caller its one answer; a second call does nothing. */
31
36
  function finish(pending, answer) {
32
37
  if (pending.answered)
@@ -153,7 +158,7 @@ class WorkerPool {
153
158
  #stopReader(lane, worker, pending) {
154
159
  finish(pending, () => pending.fail(new DeadlineExceededError(READ_LATE)));
155
160
  lane.stopping = worker;
156
- void worker.terminate();
161
+ terminateLogged(worker);
157
162
  }
158
163
  // Before its commit flag a stopped write is a known rollback; after it the thread is left to finish, since stopping it could not undo the write.
159
164
  #stopWriter(lane, worker, pending) {
@@ -195,7 +200,8 @@ class WorkerPool {
195
200
  return this.#exits.size;
196
201
  }
197
202
  terminateWriter() {
198
- void this.#writer.worker?.terminate();
203
+ if (this.#writer.worker)
204
+ terminateLogged(this.#writer.worker);
199
205
  }
200
206
  #pump(lane) {
201
207
  if (lane.running !== undefined)
@@ -1,5 +1,5 @@
1
1
  // hippo.db's half of the GraphReads store group: one read snapshot around the walk the CLI graph commands run.
2
- import { canReadScope } from '../recall-scope.js';
2
+ import { canReadScope } from '../../core/recall-scope.js';
3
3
  import { withGraphReadSnapshot } from '../graph-reads.js';
4
4
  import { graphViewRows } from '../graph-view-rows.js';
5
5
  export function sqliteGraphReads(hippoRoot) {
@@ -0,0 +1,9 @@
1
+ /** What the server calls around its responses to keep its store connection. */
2
+ export interface StoreHolder {
3
+ hold: () => void;
4
+ afterResponse: () => void;
5
+ release: () => Promise<void>;
6
+ }
7
+ /** Holds a connection to the hippo.db under `hippoRoot` once it exists, so serving never creates one. */
8
+ export declare function holdSqliteConnection(hippoRoot: string): StoreHolder;
9
+ //# sourceMappingURL=held-connection.d.ts.map
@@ -0,0 +1,41 @@
1
+ // A served hippo.db keeps one connection open for the life of the server, beside the worker that checkpoints its WAL.
2
+ import { existsSync } from 'node:fs';
3
+ import { closeHippoDb, getHippoDbPath, openHippoDb, outsideRequestStores, outsideSqliteOffLoop, SERVER_DB_WAIT_MS, } from '../../db/index.js';
4
+ import { startWalCheckpointer } from '../../db/wal-checkpointer.js';
5
+ import { errorMessage, log } from '../../util/log.js';
6
+ /** Holds a connection to the hippo.db under `hippoRoot` once it exists, so serving never creates one. */
7
+ export function holdSqliteConnection(hippoRoot) {
8
+ // Handlers open and close their own connections; while this one is held, none of those closes is SQLite's last,
9
+ // which checkpoints and deletes the WAL.
10
+ let heldDb;
11
+ let checkpointer;
12
+ let stopHolding = false;
13
+ const hold = () => {
14
+ if (heldDb || stopHolding || !existsSync(getHippoDbPath(hippoRoot)))
15
+ return;
16
+ try {
17
+ // The 'finish' listener can fire inside a request scope (closing this connection with the request) and inside a `loop: 'off'` block (refusing the open).
18
+ // The server's lock wait: this open runs on the event loop, where SQLite's 5 s default and the 30 s journal-mode retry would stall every request.
19
+ heldDb = outsideSqliteOffLoop(() => outsideRequestStores(() => openHippoDb(hippoRoot, { busyWaitMs: SERVER_DB_WAIT_MS })));
20
+ checkpointer = startWalCheckpointer(getHippoDbPath(hippoRoot));
21
+ }
22
+ catch (err) {
23
+ stopHolding = true;
24
+ log.warn(`serve: could not hold a store connection; requests still work, only slower: ${errorMessage(err)}`);
25
+ }
26
+ };
27
+ const afterResponse = () => {
28
+ hold();
29
+ checkpointer?.noteResponse();
30
+ };
31
+ const release = async () => {
32
+ stopHolding = true;
33
+ // The worker's connection closes first, so the held one is SQLite's last and its close checkpoints and deletes the WAL.
34
+ await checkpointer?.stop();
35
+ if (heldDb)
36
+ closeHippoDb(heldDb);
37
+ heldDb = undefined;
38
+ };
39
+ return { hold, afterResponse, release };
40
+ }
41
+ //# sourceMappingURL=held-connection.js.map
@@ -1,7 +1,7 @@
1
1
  import type { AuditOp } from '../audit.js';
2
2
  import type { JsonObject } from '../working-memory.js';
3
3
  import type { SourceObjectType } from '../graph-rows.js';
4
- import type { BriefStatus, DecisionStatus, IncidentStatus, NoteStatus, ObjectByKind, ObjectFields, ObjectKind, PolicyStatus, ProcessStatus, SavableKind, SkillStatus } from '../object-types.js';
4
+ import type { BriefStatus, DecisionStatus, IncidentStatus, NoteStatus, ObjectByKind, ObjectFields, ObjectKind, PolicyStatus, ProcessStatus, SavableKind, SkillStatus } from '../../core/object-types.js';
5
5
  interface HeadRow {
6
6
  id: number;
7
7
  memory_id: string | null;
@@ -1,4 +1,4 @@
1
- import type { BriefReceipt, Incident, ObjectByKind, ObjectKind, Policy, SavableKind, Skill } from '../object-types.js';
1
+ import type { BriefReceipt, Incident, ObjectByKind, ObjectKind, Policy, SavableKind, Skill } from '../../core/object-types.js';
2
2
  import { type IncidentOpen, type IncidentOpenRefusal, type IncidentResolve, type ObjectClose, type ObjectListQuery, type ObjectRefusal, type Objects, type ObjectSave, type PoliciesInForceQuery } from '../port.js';
3
3
  /** The group with each answer as its value; spelled out because `Sync<Objects>` would widen each method's kind to every kind. */
4
4
  export interface SyncObjects {
@@ -4,7 +4,7 @@ import { getMeta, withWriteScopeOr } from '../../db/index.js';
4
4
  import { escapeLike } from '../../util/escape.js';
5
5
  import { keysetAfter } from '../../util/keyset.js';
6
6
  import { calculateStrength, deriveHalfLife } from '../../core/memory.js';
7
- import { scopeAdmitSql } from '../recall-scope.js';
7
+ import { scopeAdmitSql } from '../rule-sql.js';
8
8
  import { stampOriginProject, upsertEntryRow } from '../entry-row.js';
9
9
  import { auditEntryWrite, writeEntryMirrors } from '../entry-writes.js';
10
10
  import { markGraphDirty } from '../graph-queue.js';
@@ -277,18 +277,20 @@ function continuityAt(hippoRoot, tenantId, eventLimit, key) {
277
277
  /** sqliteStore's finishRecall, for the synchronous recall that cannot await the port. */
278
278
  export function finishRecallAt(hippoRoot, writes) {
279
279
  return onHandle(hippoRoot, (db) => {
280
- // With no row to write the scope would only take the write lock.
281
- if (writes.goalLog.length > 0 || writes.audit.length > 0) {
282
- withWriteScope(db, 'finish_recall', () => {
283
- writeGoalRecallLog(db, localGoalRecallRows(db, writes.goalLog));
284
- for (const event of writes.audit)
285
- appendAuditEvent(db, event);
286
- });
287
- }
288
- // Each opens its own transaction, so neither can share the scope above.
289
- const traceId = writes.trace ? writeRecallTrace(db, writes.trace) : null;
290
- const strengthened = writes.strengthen ? strengthenRetrievedInOwnTx(db, writes.strengthen.ids, writes.strengthen.opts) : new Set();
291
- return { traceId, strengthened };
280
+ const traceAndStrengthen = () => ({
281
+ traceId: writes.trace ? writeRecallTrace(db, writes.trace) : null,
282
+ strengthened: writes.strengthen ? strengthenRetrievedInOwnTx(db, writes.strengthen.ids, writes.strengthen.opts) : new Set(),
283
+ });
284
+ // Alone, the fail-soft trace and strengthen keep their own scopes so a busy lock loses them, never the read.
285
+ if (writes.goalLog.length === 0 && writes.audit.length === 0)
286
+ return traceAndStrengthen();
287
+ // Inside this scope both run as savepoints, so one recall commits once and a failed trace or strengthen still unwinds alone.
288
+ return withWriteScope(db, 'finish_recall', () => {
289
+ writeGoalRecallLog(db, localGoalRecallRows(db, writes.goalLog));
290
+ for (const event of writes.audit)
291
+ appendAuditEvent(db, event);
292
+ return traceAndStrengthen();
293
+ });
292
294
  });
293
295
  }
294
296
  //# sourceMappingURL=store.js.map
@@ -2,9 +2,9 @@ import type { MemoryEntry } from '../core/memory.js';
2
2
  /** Host-wide loader for L2 topic summaries without an L3 parent, for consolidate phase 1.9 (buildEntityProfiles); SQL-level filter, since in-memory
3
3
  * `survivors` lacks L2s created by phase 1.7. Entries carry tenantId so per-cluster writes stay tenant-scoped. */
4
4
  export declare function loadAllL2Summaries(hippoRoot: string): MemoryEntry[];
5
- /** Dirty summaries across all tenants in one query, newest change first (latest_at DESC NULLS LAST, id ASC) so HIPPO_DAG_REBUILD_CAP takes the most
6
- * recently changed. Each entry carries its own tenantId so the children read and rebuild UPDATE stay tenant-scoped. */
7
- export declare function loadAllDirtySummaries(hippoRoot: string): MemoryEntry[];
5
+ /** Dirty summaries across all tenants, newest change first (latest_at DESC NULLS LAST, id ASC), at most `limit` (all when omitted)
6
+ * so HIPPO_DAG_REBUILD_CAP reads only the most recently changed. Each entry carries its tenantId so later writes stay tenant-scoped. */
7
+ export declare function loadAllDirtySummaries(hippoRoot: string, limit?: number): MemoryEntry[];
8
8
  /** Live (non-archived) children of a DAG summary, so a rebuild regenerates from the CURRENT child set; tenant-scoped as defence in depth. */
9
9
  export declare function loadChildrenOfSummary(hippoRoot: string, summaryId: string, tenantId: string): MemoryEntry[];
10
10
  /** Patch applied by applyRebuildResult; `bumpRebuildCount` is false for the zero-child case, true for a normal rebuild. */
@@ -27,9 +27,9 @@ export function loadAllL2Summaries(hippoRoot) {
27
27
  return rows.map(rowToEntry);
28
28
  }, openStore);
29
29
  }
30
- /** Dirty summaries across all tenants in one query, newest change first (latest_at DESC NULLS LAST, id ASC) so HIPPO_DAG_REBUILD_CAP takes the most
31
- * recently changed. Each entry carries its own tenantId so the children read and rebuild UPDATE stay tenant-scoped. */
32
- export function loadAllDirtySummaries(hippoRoot) {
30
+ /** Dirty summaries across all tenants, newest change first (latest_at DESC NULLS LAST, id ASC), at most `limit` (all when omitted)
31
+ * so HIPPO_DAG_REBUILD_CAP reads only the most recently changed. Each entry carries its tenantId so later writes stay tenant-scoped. */
32
+ export function loadAllDirtySummaries(hippoRoot, limit) {
33
33
  return onHandle(hippoRoot, (db) => {
34
34
  // SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
35
35
  // MemoryRow's field set.
@@ -39,7 +39,8 @@ export function loadAllDirtySummaries(hippoRoot) {
39
39
  WHERE summary_dirty = 1
40
40
  AND kind != 'archived'
41
41
  ORDER BY latest_at DESC NULLS LAST, id ASC
42
- `).all();
42
+ LIMIT ?
43
+ `).all(limit ?? -1);
43
44
  return rows.map(rowToEntry);
44
45
  }, openStore);
45
46
  }
@@ -82,13 +82,6 @@ interface ModelTagged {
82
82
  }
83
83
  /** Claude Code writes its own API errors and limit notices as assistant lines from this model; no model call made them. */
84
84
  export declare function isSyntheticMessage(message: ModelTagged): boolean;
85
- /** A hook payload's non-empty `session_id`, or null; with `requiredSource`, also null when its `source` differs. */
86
- export declare function hookPayloadSessionId(stdinText: string | undefined, requiredSource?: string | null): string | null;
87
- /** A hook payload's string `field` as sent, or null when the payload or the field is missing or not a string. */
88
- export declare function hookPayloadString(stdinText: string | undefined, field: string): string | null;
89
- /** Whether a hook fired inside a sub-agent, the only payload with `agent_id` (https://code.claude.com/docs/en/hooks#common-input-fields).
90
- * Its `session_id` is the parent's, so a sub-agent's blocks and compactions must not count as the parent's. */
91
- export declare function isSubagentPayload(stdinText: string | undefined): boolean;
92
85
  /** Tokens hippo sent and skipped in one session, for {@link tokensBySession}. */
93
86
  export interface SessionTokens {
94
87
  sessionId: string;
@@ -90,41 +90,6 @@ export function summarizeTokenUse(db, tenantId, sinceIso) {
90
90
  export function isSyntheticMessage(message) {
91
91
  return message.model === '<synthetic>';
92
92
  }
93
- /** A Claude Code hook payload on stdin as a JSON object; null when empty, malformed or not an object. */
94
- function parseHookPayload(stdinText) {
95
- if (!stdinText || stdinText.trim() === '')
96
- return null;
97
- try {
98
- // SAFETY: JSON.parse returns a JSON value by definition.
99
- const payload = JSON.parse(stdinText.trim());
100
- return isJsonObjectLiteral(payload) ? payload : null;
101
- }
102
- catch {
103
- // Malformed is one of the null cases the docblock names.
104
- return null;
105
- }
106
- }
107
- /** A hook payload's non-empty `session_id`, or null; with `requiredSource`, also null when its `source` differs. */
108
- export function hookPayloadSessionId(stdinText, requiredSource = null) {
109
- const payload = parseHookPayload(stdinText);
110
- const sessionId = payload?.session_id;
111
- if (!payload || !isJsonString(sessionId) || sessionId.trim() === '')
112
- return null;
113
- if (requiredSource !== null && payload.source !== requiredSource)
114
- return null;
115
- return sessionId;
116
- }
117
- /** A hook payload's string `field` as sent, or null when the payload or the field is missing or not a string. */
118
- export function hookPayloadString(stdinText, field) {
119
- const value = parseHookPayload(stdinText)?.[field];
120
- return isJsonString(value) ? value : null;
121
- }
122
- /** Whether a hook fired inside a sub-agent, the only payload with `agent_id` (https://code.claude.com/docs/en/hooks#common-input-fields).
123
- * Its `session_id` is the parent's, so a sub-agent's blocks and compactions must not count as the parent's. */
124
- export function isSubagentPayload(stdinText) {
125
- const agentId = parseHookPayload(stdinText)?.agent_id;
126
- return isJsonString(agentId) && agentId.trim() !== '';
127
- }
128
93
  /** Ledger totals per session id since `sinceIso`, across surfaces; hook rows carry the host's session id (the transcript file name), so they join to its
129
94
  * usage records. */
130
95
  export function tokensBySession(db, tenantId, sinceIso) {
@@ -1,10 +1,11 @@
1
1
  // Owns hippo.db's stored vectors, the identity of the model that built them, and the particle rows: every read and write of the three.
2
2
  import { getMeta, setMeta, withWriteScope } from '../db/index.js';
3
3
  import { onHandle } from './open.js';
4
- import { DEFAULT_EMBEDDING_MODEL } from './embeddings/local.js';
4
+ import { DEFAULT_EMBEDDING_MODEL } from '../embeddings/local.js';
5
5
  import { float32ToBuffer, initializeParticle, loadPhysicsState, resetAllPhysicsState, savePhysicsState } from '../db/physics-state.js';
6
6
  import { EMBEDDING_MODEL_META_KEY, deleteOrphanVectors, hasStoredVectors, loadVectors, loadVectorViews, replaceAllVectors, storedVectorDims, storedVectorIds, upsertVectors, } from '../db/vector-store.js';
7
- import { chunked, selectEntriesByIds } from './entry-reads.js';
7
+ import { selectEntriesByIds } from './entry-reads.js';
8
+ import { chunked } from '../util/chunked.js';
8
9
  import { MEMORY_SELECT_COLUMNS, rowToEntry } from './rows.js';
9
10
  const MAX_BACKFILL_PAGE = 500;
10
11
  /** The model the index was built by: the stored identity, else the default model when vectors exist. */
@@ -5,10 +5,9 @@ import * as fs from 'fs';
5
5
  import * as os from 'os';
6
6
  import * as path from 'path';
7
7
  import { pathToFileURL } from 'url';
8
- import { findHippoStoreDir, isGlobalStoreRoot } from './core/project-identity.js';
8
+ import { findHippoStoreDir, isGlobalStoreRoot, isInitialized } from './core/project-identity.js';
9
9
  import { realpathOrResolve } from './util/real-path.js';
10
10
  import { getGlobalRoot } from './sharing/global-store.js';
11
- import { isInitialized } from './store/open.js';
12
11
  import { readStoreInventory } from './store/diagnostics.js';
13
12
  import { runDoctor } from './doctor.js';
14
13
  import { loadConfig } from './core/config.js';
@@ -21,7 +20,7 @@ export const TAIL_MAX_LINES = 200;
21
20
  const TAIL_MAX_LINE_CHARS = 2000;
22
21
  // Greedy on purpose: complete key blocks are redacted first, so any END left is an orphan and what precedes it may be key body.
23
22
  const ORPHAN_KEY_END_RE = /^[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/;
24
- // The other env vars hippo reads outside the HIPPO_ prefix (src/store/embeddings/provider.ts, connectors/*).
23
+ // The other env vars hippo reads outside the HIPPO_ prefix (src/embeddings/provider.ts, connectors/*).
25
24
  const OTHER_ENV_NAMES = [
26
25
  'ANTHROPIC_API_KEY', 'OPENAI_API_KEY', 'VOYAGE_API_KEY', 'COHERE_API_KEY', 'TYPESAFE_API_KEY',
27
26
  'GITHUB_TOKEN', 'GITHUB_WEBHOOK_SECRET', 'GITHUB_WEBHOOK_SECRET_PREVIOUS',
@@ -1,8 +1,8 @@
1
1
  // The reject, unreject and list flow the CLI verbs and the api functions share: the rules and their wording live here,
2
2
  // and src/store/rejected-values.ts runs each one on a single handle.
3
3
  import { BadRequestError } from '../core/api-errors.js';
4
- import { isPersonalScope } from '../store/recall-scope.js';
5
- import { mergedSuccessor } from '../consolidate/merged-row.js';
4
+ import { isPersonalScope } from '../core/recall-scope.js';
5
+ import { mergedSuccessor } from '../core/merged-row.js';
6
6
  import { normalizeValueForRejection } from '../store/rejection.js';
7
7
  import { applyRejection, liftRejection, loadRejectedValues, } from '../store/rejected-values.js';
8
8
  function assertRejectOpts(opts) {
@@ -0,0 +1,15 @@
1
+ type Env = Readonly<Record<string, string | undefined>>;
2
+ export declare function homeDir(): string;
3
+ /** Codex's config folder: $CODEX_HOME, else ~/.codex, as the Codex hooks docs describe. */
4
+ export declare function codexHomeDir(home?: string, env?: Env): string;
5
+ /** Claude Code's config folder, where it reads settings.json: $CLAUDE_CONFIG_DIR when set and non-empty, else
6
+ * ~/.claude under os.homedir(), as Claude Code does (a HOME that differs from the profile must not move it). */
7
+ export declare function claudeConfigDir(home?: string, env?: Env): string;
8
+ /** VS Code's user-data resolution: portable install first, then the app-data override, then the platform default. */
9
+ export declare function vscodeDataFolders(ctx: {
10
+ readonly env: Env;
11
+ readonly home: string;
12
+ readonly platform: NodeJS.Platform;
13
+ }): string[];
14
+ export {};
15
+ //# sourceMappingURL=agent-homes.d.ts.map
@@ -0,0 +1,34 @@
1
+ // Where the agent tools keep their config and data, shared by the hook installers and the agent-memory readers.
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+ import { envHomeDir, processEnv } from './env.js';
5
+ const VSCODE_PRODUCTS = ['Code', 'Code - Insiders'];
6
+ export function homeDir() {
7
+ return envHomeDir() || os.homedir();
8
+ }
9
+ /** Codex's config folder: $CODEX_HOME, else ~/.codex, as the Codex hooks docs describe. */
10
+ export function codexHomeDir(home = homeDir(), env = processEnv()) {
11
+ return env.CODEX_HOME || path.join(home, '.codex');
12
+ }
13
+ /** Claude Code's config folder, where it reads settings.json: $CLAUDE_CONFIG_DIR when set and non-empty, else
14
+ * ~/.claude under os.homedir(), as Claude Code does (a HOME that differs from the profile must not move it). */
15
+ export function claudeConfigDir(home = os.homedir(), env = processEnv()) {
16
+ return env.CLAUDE_CONFIG_DIR || path.join(home, '.claude');
17
+ }
18
+ /** VS Code's user-data resolution: portable install first, then the app-data override, then the platform default. */
19
+ export function vscodeDataFolders(ctx) {
20
+ const { env, home, platform } = ctx;
21
+ if (env.VSCODE_PORTABLE)
22
+ return [path.join(env.VSCODE_PORTABLE, 'user-data')];
23
+ let appData;
24
+ if (env.VSCODE_APPDATA)
25
+ appData = env.VSCODE_APPDATA;
26
+ else if (platform === 'win32')
27
+ appData = env.APPDATA || path.join(home, 'AppData', 'Roaming');
28
+ else if (platform === 'darwin')
29
+ appData = path.join(home, 'Library', 'Application Support');
30
+ else
31
+ appData = env.XDG_CONFIG_HOME || path.join(home, '.config');
32
+ return VSCODE_PRODUCTS.map((product) => path.join(appData, product));
33
+ }
34
+ //# sourceMappingURL=agent-homes.js.map
@@ -13,6 +13,7 @@ export type AnthropicMessageFailure = {
13
13
  } | {
14
14
  kind: 'http';
15
15
  status: number;
16
+ detail: string;
16
17
  } | {
17
18
  kind: 'unreadable';
18
19
  message: string;
@@ -24,6 +25,8 @@ export type AnthropicMessageResult = {
24
25
  ok: false;
25
26
  failure: AnthropicMessageFailure;
26
27
  };
28
+ /** True for a failure the next call would repeat, so a caller looping over items should stop rather than retry. */
29
+ export declare function isPermanentFailure(failure: AnthropicMessageFailure): boolean;
27
30
  /** The reply's first text block, trimmed (empty when the reply has none); never throws. */
28
31
  export declare function sendAnthropicMessage(req: AnthropicMessageRequest): Promise<AnthropicMessageResult>;
29
32
  /** The text extraction and DAG summaries hand to their `onError` callback. */