hippo-memory 1.70.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 (855) hide show
  1. package/README.md +2 -2
  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.d.ts +4 -2
  5. package/dist/agent-memories/claude-code.js +15 -6
  6. package/dist/agent-memories/codex.js +1 -1
  7. package/dist/agent-memories/copilot.d.ts +1 -3
  8. package/dist/agent-memories/copilot.js +1 -17
  9. package/dist/agent-memories/files.js +23 -12
  10. package/dist/agent-memories/markdown.d.ts +1 -3
  11. package/dist/agent-memories/markdown.js +1 -3
  12. package/dist/agent-memories/project-folds.d.ts +10 -0
  13. package/dist/agent-memories/project-folds.js +34 -0
  14. package/dist/agent-memories/report.js +2 -1
  15. package/dist/agent-memories/sync.d.ts +4 -2
  16. package/dist/agent-memories/sync.js +18 -11
  17. package/dist/api/assemble.d.ts +7 -44
  18. package/dist/api/assemble.js +3 -23
  19. package/dist/api/audit.d.ts +33 -1
  20. package/dist/api/audit.js +48 -1
  21. package/dist/api/auth.d.ts +20 -26
  22. package/dist/api/auth.js +43 -29
  23. package/dist/api/auto-sleep.d.ts +5 -2
  24. package/dist/api/auto-sleep.js +9 -5
  25. package/dist/api/availability.d.ts +2 -15
  26. package/dist/api/availability.js +4 -18
  27. package/dist/api/cards.d.ts +42 -0
  28. package/dist/api/cards.js +52 -0
  29. package/dist/api/conflicts.d.ts +28 -0
  30. package/dist/api/conflicts.js +61 -0
  31. package/dist/api/context-render.js +4 -3
  32. package/dist/api/context-select.js +12 -15
  33. package/dist/api/context-types.d.ts +10 -35
  34. package/dist/api/context.d.ts +5 -22
  35. package/dist/api/context.js +38 -46
  36. package/dist/api/continuity.d.ts +47 -0
  37. package/dist/api/continuity.js +66 -0
  38. package/dist/{cli → api}/correction-latency.d.ts +2 -14
  39. package/dist/{cli → api}/correction-latency.js +2 -14
  40. package/dist/api/dormant.d.ts +5 -21
  41. package/dist/api/dormant.js +11 -28
  42. package/dist/api/drill-down.d.ts +7 -46
  43. package/dist/api/drill-down.js +6 -27
  44. package/dist/api/embeddings.d.ts +17 -0
  45. package/dist/api/embeddings.js +28 -0
  46. package/dist/api/error-reply.d.ts +8 -0
  47. package/dist/api/error-reply.js +21 -0
  48. package/dist/api/forget.d.ts +11 -26
  49. package/dist/api/forget.js +23 -35
  50. package/dist/api/goals.d.ts +1 -1
  51. package/dist/api/goals.js +5 -9
  52. package/dist/api/graph.d.ts +8 -0
  53. package/dist/api/graph.js +7 -0
  54. package/dist/api/index.d.ts +6 -2
  55. package/dist/api/index.js +6 -2
  56. package/dist/api/instruction-detect.js +21 -6
  57. package/dist/api/learn.d.ts +4 -0
  58. package/dist/api/learn.js +53 -27
  59. package/dist/api/ledger-db.d.ts +2 -5
  60. package/dist/api/ledger-db.js +5 -35
  61. package/dist/api/memories.d.ts +23 -0
  62. package/dist/api/memories.js +46 -0
  63. package/dist/api/objects.d.ts +9 -0
  64. package/dist/api/objects.js +11 -0
  65. package/dist/api/on-store.js +5 -3
  66. package/dist/api/outcome.js +1 -1
  67. package/dist/api/pilot-arm.d.ts +1 -11
  68. package/dist/api/pilot-arm.js +5 -45
  69. package/dist/api/predictions.d.ts +11 -0
  70. package/dist/api/predictions.js +24 -0
  71. package/dist/api/projects.d.ts +21 -0
  72. package/dist/api/projects.js +24 -0
  73. package/dist/api/promote.d.ts +13 -17
  74. package/dist/api/promote.js +12 -20
  75. package/dist/api/prompt-hook.d.ts +19 -6
  76. package/dist/api/prompt-hook.js +54 -13
  77. package/dist/api/provenance-coverage.d.ts +14 -0
  78. package/dist/{cli → api}/provenance-coverage.js +2 -6
  79. package/dist/api/recall-cli.d.ts +58 -0
  80. package/dist/api/recall-cli.js +103 -0
  81. package/dist/api/recall-core.js +17 -9
  82. package/dist/api/recall-finish.d.ts +53 -0
  83. package/dist/api/recall-finish.js +30 -0
  84. package/dist/api/recall-history.d.ts +17 -84
  85. package/dist/api/recall-history.js +15 -88
  86. package/dist/api/recall-pipeline.d.ts +2 -3
  87. package/dist/api/recall-pipeline.js +21 -15
  88. package/dist/api/recall-request.js +1 -1
  89. package/dist/api/recall-types.d.ts +64 -304
  90. package/dist/api/recall.d.ts +3 -34
  91. package/dist/api/recall.js +63 -89
  92. package/dist/api/refine.d.ts +7 -0
  93. package/dist/api/refine.js +10 -0
  94. package/dist/api/remember-local.d.ts +57 -0
  95. package/dist/api/remember-local.js +90 -0
  96. package/dist/api/remember.d.ts +20 -2
  97. package/dist/api/remember.js +16 -3
  98. package/dist/api/session-end.d.ts +22 -0
  99. package/dist/api/session-end.js +101 -0
  100. package/dist/api/sleep-run.d.ts +2 -4
  101. package/dist/api/sleep-run.js +28 -28
  102. package/dist/api/sleep.d.ts +9 -28
  103. package/dist/api/status.d.ts +24 -0
  104. package/dist/api/status.js +40 -0
  105. package/dist/api/store-init.d.ts +4 -0
  106. package/dist/api/store-init.js +9 -0
  107. package/dist/api/tokens.d.ts +3 -10
  108. package/dist/api/tokens.js +4 -11
  109. package/dist/api/types.d.ts +8 -29
  110. package/dist/api/types.js +10 -23
  111. package/dist/capture/caller-session.d.ts +0 -3
  112. package/dist/capture/caller-session.js +1 -12
  113. package/dist/capture/capture-error.d.ts +2 -2
  114. package/dist/capture/capture-error.js +23 -18
  115. package/dist/capture/codex-patch.js +3 -1
  116. package/dist/capture/command.d.ts +4 -12
  117. package/dist/capture/command.js +39 -114
  118. package/dist/capture/compact.d.ts +4 -15
  119. package/dist/capture/compact.js +26 -30
  120. package/dist/capture/compaction-items-caller.js +11 -20
  121. package/dist/capture/compaction-record.d.ts +7 -93
  122. package/dist/capture/compaction-record.js +34 -399
  123. package/dist/capture/compaction-spool.d.ts +5 -3
  124. package/dist/capture/compaction-spool.js +21 -7
  125. package/dist/capture/copilot-transcript.d.ts +2 -1
  126. package/dist/capture/copilot-transcript.js +2 -1
  127. package/dist/capture/extract.d.ts +5 -2
  128. package/dist/capture/extract.js +4 -3
  129. package/dist/capture/failure-caller.d.ts +1 -1
  130. package/dist/capture/failure-caller.js +21 -16
  131. package/dist/capture/failure-reading.d.ts +2 -1
  132. package/dist/capture/failure-reading.js +7 -9
  133. package/dist/capture/pre-compact-caller.js +5 -4
  134. package/dist/capture/session-digest.d.ts +1 -1
  135. package/dist/capture/session-digest.js +17 -10
  136. package/dist/capture/session-end-caller.js +2 -1
  137. package/dist/capture/session-worker.js +3 -4
  138. package/dist/capture/transcript.d.ts +4 -11
  139. package/dist/capture/transcript.js +10 -21
  140. package/dist/capture/working-state.d.ts +4 -2
  141. package/dist/capture/working-state.js +4 -2
  142. package/dist/cli/api-context.d.ts +3 -0
  143. package/dist/cli/api-context.js +6 -0
  144. package/dist/cli/audit-prune.d.ts +1 -59
  145. package/dist/cli/audit-prune.js +2 -61
  146. package/dist/cli/audit.d.ts +1 -1
  147. package/dist/cli/audit.js +42 -43
  148. package/dist/cli/auth.d.ts +2 -2
  149. package/dist/cli/auth.js +61 -44
  150. package/dist/cli/briefs.d.ts +1 -4
  151. package/dist/cli/briefs.js +42 -301
  152. package/dist/cli/card.d.ts +2 -2
  153. package/dist/cli/card.js +63 -56
  154. package/dist/cli/client.d.ts +12 -27
  155. package/dist/cli/client.js +41 -44
  156. package/dist/cli/compact-resume-payload.js +4 -3
  157. package/dist/cli/context.d.ts +2 -3
  158. package/dist/cli/context.js +22 -18
  159. package/dist/cli/continuity.d.ts +6 -6
  160. package/dist/cli/continuity.js +81 -86
  161. package/dist/cli/curate.d.ts +13 -17
  162. package/dist/cli/curate.js +88 -116
  163. package/dist/cli/dag.d.ts +4 -4
  164. package/dist/cli/dag.js +55 -34
  165. package/dist/cli/decisions.d.ts +2 -4
  166. package/dist/cli/decisions.js +18 -309
  167. package/dist/cli/eval.d.ts +1 -1
  168. package/dist/cli/eval.js +27 -26
  169. package/dist/cli/exit.d.ts +6 -0
  170. package/dist/cli/exit.js +11 -0
  171. package/dist/cli/explain.d.ts +2 -3
  172. package/dist/cli/explain.js +25 -27
  173. package/dist/cli/flag-values.d.ts +6 -1
  174. package/dist/cli/flag-values.js +42 -15
  175. package/dist/cli/flags.d.ts +0 -288
  176. package/dist/cli/flags.js +3 -138
  177. package/dist/cli/github.d.ts +14 -0
  178. package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
  179. package/dist/cli/goals.d.ts +2 -2
  180. package/dist/cli/goals.js +46 -50
  181. package/dist/cli/graph.d.ts +3 -0
  182. package/dist/cli/graph.js +83 -0
  183. package/dist/cli/hook-runtime.d.ts +12 -32
  184. package/dist/cli/hook-runtime.js +21 -64
  185. package/dist/cli/incidents.d.ts +3 -0
  186. package/dist/cli/incidents.js +112 -0
  187. package/dist/cli/init.d.ts +2 -2
  188. package/dist/cli/init.js +33 -30
  189. package/dist/cli/install-steps.d.ts +2 -1
  190. package/dist/cli/install-steps.js +13 -14
  191. package/dist/cli/last-sleep.d.ts +2 -1
  192. package/dist/cli/last-sleep.js +4 -1
  193. package/dist/cli/lenient-id.d.ts +2 -0
  194. package/dist/cli/lenient-id.js +13 -0
  195. package/dist/cli/maintenance.d.ts +5 -5
  196. package/dist/cli/maintenance.js +37 -43
  197. package/dist/cli/notes.d.ts +2 -0
  198. package/dist/cli/notes.js +41 -0
  199. package/dist/cli/object-verbs.js +4 -3
  200. package/dist/cli/open-browser.d.ts +14 -0
  201. package/dist/cli/open-browser.js +26 -0
  202. package/dist/cli/owner-validation.d.ts +5 -28
  203. package/dist/cli/owner-validation.js +5 -28
  204. package/dist/cli/playbooks.d.ts +3 -4
  205. package/dist/cli/playbooks.js +131 -300
  206. package/dist/cli/predictions.d.ts +3 -0
  207. package/dist/cli/predictions.js +175 -0
  208. package/dist/cli/print.d.ts +2 -5
  209. package/dist/cli/print.js +3 -5
  210. package/dist/cli/projects.d.ts +2 -2
  211. package/dist/cli/projects.js +31 -25
  212. package/dist/cli/quality-repair-once.d.ts +1 -1
  213. package/dist/cli/quality-repair-once.js +7 -6
  214. package/dist/cli/recall.d.ts +2 -4
  215. package/dist/cli/recall.js +67 -137
  216. package/dist/cli/refine-llm.d.ts +5 -31
  217. package/dist/cli/refine-llm.js +23 -50
  218. package/dist/cli/remember.d.ts +3 -3
  219. package/dist/cli/remember.js +134 -192
  220. package/dist/cli/scheduler.d.ts +2 -17
  221. package/dist/cli/scheduler.js +14 -19
  222. package/dist/cli/serve.js +23 -14
  223. package/dist/cli/session-hooks.d.ts +11 -19
  224. package/dist/cli/session-hooks.js +143 -214
  225. package/dist/cli/setup.d.ts +4 -4
  226. package/dist/cli/setup.js +35 -30
  227. package/dist/cli/shared.d.ts +7 -25
  228. package/dist/cli/shared.js +17 -60
  229. package/dist/cli/slack.d.ts +2 -2
  230. package/dist/cli/slack.js +19 -23
  231. package/dist/cli/sleep-render.js +6 -3
  232. package/dist/cli/sleep.d.ts +3 -2
  233. package/dist/cli/sleep.js +17 -49
  234. package/dist/cli/status.d.ts +11 -14
  235. package/dist/cli/status.js +74 -120
  236. package/dist/cli/stdin.d.ts +4 -6
  237. package/dist/cli/stdin.js +2 -3
  238. package/dist/cli/transfer.d.ts +9 -9
  239. package/dist/cli/transfer.js +87 -108
  240. package/dist/cli/usage.d.ts +0 -79
  241. package/dist/cli/usage.js +1 -689
  242. package/dist/cli/verb-row.d.ts +32 -0
  243. package/dist/cli/verb-row.js +6 -0
  244. package/dist/cli/verbs/health.d.ts +27 -0
  245. package/dist/cli/verbs/health.js +232 -0
  246. package/dist/cli/verbs/memory.d.ts +16 -0
  247. package/dist/cli/verbs/memory.js +244 -0
  248. package/dist/cli/verbs/objects.d.ts +20 -0
  249. package/dist/cli/verbs/objects.js +254 -0
  250. package/dist/cli/verbs/sessions.d.ts +31 -0
  251. package/dist/cli/verbs/sessions.js +312 -0
  252. package/dist/cli/verbs.d.ts +81 -0
  253. package/dist/cli/verbs.js +7 -0
  254. package/dist/cli/versioned-verbs.d.ts +51 -0
  255. package/dist/cli/versioned-verbs.js +79 -0
  256. package/dist/cli.d.ts +1 -654
  257. package/dist/cli.js +44 -510
  258. package/dist/connectors/dlq.d.ts +39 -3
  259. package/dist/connectors/dlq.js +37 -3
  260. package/dist/connectors/github/backfill.d.ts +5 -25
  261. package/dist/connectors/github/backfill.js +26 -52
  262. package/dist/connectors/github/deletion.d.ts +4 -18
  263. package/dist/connectors/github/deletion.js +2 -15
  264. package/dist/connectors/github/dlq.d.ts +8 -33
  265. package/dist/connectors/github/dlq.js +34 -93
  266. package/dist/connectors/github/ingest.d.ts +4 -12
  267. package/dist/connectors/github/ingest.js +5 -36
  268. package/dist/connectors/github/octokit-client.d.ts +4 -16
  269. package/dist/connectors/github/octokit-client.js +27 -24
  270. package/dist/connectors/github/ratelimit.d.ts +3 -14
  271. package/dist/connectors/github/ratelimit.js +3 -14
  272. package/dist/connectors/github/scope.d.ts +3 -5
  273. package/dist/connectors/github/scope.js +3 -5
  274. package/dist/connectors/github/signature.d.ts +4 -26
  275. package/dist/connectors/github/signature.js +4 -26
  276. package/dist/connectors/github/tenant-routing.d.ts +2 -24
  277. package/dist/connectors/github/tenant-routing.js +4 -26
  278. package/dist/connectors/github/transform.js +2 -16
  279. package/dist/connectors/github/types.d.ts +3 -15
  280. package/dist/connectors/github/types.js +2 -9
  281. package/dist/connectors/github/webhook.d.ts +3 -16
  282. package/dist/connectors/github/webhook.js +38 -23
  283. package/dist/connectors/ingest.d.ts +10 -0
  284. package/dist/connectors/ingest.js +28 -0
  285. package/dist/connectors/slack/backfill.d.ts +4 -17
  286. package/dist/connectors/slack/backfill.js +4 -13
  287. package/dist/connectors/slack/dlq.d.ts +2 -19
  288. package/dist/connectors/slack/dlq.js +51 -90
  289. package/dist/connectors/slack/ingest.d.ts +4 -9
  290. package/dist/connectors/slack/ingest.js +4 -30
  291. package/dist/connectors/slack/scope.d.ts +2 -8
  292. package/dist/connectors/slack/scope.js +2 -8
  293. package/dist/connectors/slack/signature.d.ts +1 -6
  294. package/dist/connectors/slack/tenant-routing.d.ts +2 -19
  295. package/dist/connectors/slack/tenant-routing.js +2 -21
  296. package/dist/connectors/slack/transform.d.ts +2 -18
  297. package/dist/connectors/slack/transform.js +2 -18
  298. package/dist/connectors/slack/types.d.ts +3 -9
  299. package/dist/connectors/slack/types.js +2 -4
  300. package/dist/connectors/slack/web-client.js +33 -27
  301. package/dist/connectors/slack/webhook.d.ts +3 -19
  302. package/dist/connectors/slack/webhook.js +6 -26
  303. package/dist/connectors/slack/workspaces.d.ts +4 -24
  304. package/dist/connectors/slack/workspaces.js +4 -24
  305. package/dist/consolidate/conflicts.js +7 -15
  306. package/dist/consolidate/dag-summary.d.ts +8 -0
  307. package/dist/consolidate/dag-summary.js +41 -0
  308. package/dist/consolidate/dag.d.ts +5 -28
  309. package/dist/consolidate/dag.js +29 -84
  310. package/dist/consolidate/decay.js +7 -19
  311. package/dist/consolidate/dedupe.d.ts +13 -52
  312. package/dist/consolidate/dedupe.js +18 -74
  313. package/dist/consolidate/flush-units.d.ts +3 -4
  314. package/dist/consolidate/flush-units.js +3 -3
  315. package/dist/consolidate/half-life-migration.d.ts +3 -26
  316. package/dist/consolidate/half-life-migration.js +11 -28
  317. package/dist/consolidate/llm-passes.js +49 -40
  318. package/dist/consolidate/memory-value-weights.d.ts +2 -13
  319. package/dist/consolidate/memory-value-weights.js +2 -13
  320. package/dist/consolidate/memory-value.d.ts +11 -84
  321. package/dist/consolidate/memory-value.js +18 -105
  322. package/dist/consolidate/merge.js +12 -33
  323. package/dist/consolidate/physics-pass.d.ts +6 -1
  324. package/dist/consolidate/physics-pass.js +27 -9
  325. package/dist/consolidate/replay.d.ts +6 -38
  326. package/dist/consolidate/replay.js +25 -56
  327. package/dist/consolidate/run.js +1 -1
  328. package/dist/consolidate/sleep.d.ts +1 -8
  329. package/dist/consolidate/sleep.js +13 -22
  330. package/dist/consolidate/trace.d.ts +3 -18
  331. package/dist/consolidate/trace.js +3 -18
  332. package/dist/consolidate/traces.js +9 -25
  333. package/dist/core/ablation.d.ts +14 -91
  334. package/dist/core/ablation.js +16 -91
  335. package/dist/core/active-scope.d.ts +7 -0
  336. package/dist/{sharing/scope.js → core/active-scope.js} +5 -12
  337. package/dist/core/ambient.d.ts +5 -8
  338. package/dist/core/ambient.js +40 -26
  339. package/dist/core/api-errors.d.ts +16 -0
  340. package/dist/core/api-errors.js +20 -0
  341. package/dist/core/capture-contract.d.ts +4 -2
  342. package/dist/core/capture-contract.js +4 -2
  343. package/dist/core/card.d.ts +4 -1
  344. package/dist/core/card.js +11 -1
  345. package/dist/core/compaction-timing.d.ts +7 -0
  346. package/dist/core/compaction-timing.js +9 -0
  347. package/dist/core/compare.d.ts +11 -67
  348. package/dist/core/compare.js +9 -63
  349. package/dist/core/config.d.ts +10 -24
  350. package/dist/core/config.js +20 -16
  351. package/dist/core/cosine.d.ts +3 -0
  352. package/dist/core/cosine.js +19 -0
  353. package/dist/core/handoff.d.ts +1 -7
  354. package/dist/core/handoff.js +1 -7
  355. package/dist/core/markdown.d.ts +6 -0
  356. package/dist/{store → core}/markdown.js +23 -22
  357. package/dist/core/memory-audit.d.ts +17 -0
  358. package/dist/core/memory-audit.js +54 -0
  359. package/dist/core/memory-quality.js +1 -1
  360. package/dist/core/memory.d.ts +51 -168
  361. package/dist/core/memory.js +76 -239
  362. package/dist/{consolidate → core}/merged-row.d.ts +1 -1
  363. package/dist/{consolidate → core}/merged-row.js +3 -2
  364. package/dist/core/package-root.d.ts +3 -0
  365. package/dist/core/package-root.js +5 -0
  366. package/dist/core/physics-config.d.ts +1 -4
  367. package/dist/core/physics-config.js +3 -8
  368. package/dist/core/physics.d.ts +15 -61
  369. package/dist/core/physics.js +65 -138
  370. package/dist/core/prediction.d.ts +3 -0
  371. package/dist/core/prediction.js +6 -0
  372. package/dist/core/project-identity.d.ts +20 -58
  373. package/dist/core/project-identity.js +27 -39
  374. package/dist/core/project-remote.js +13 -2
  375. package/dist/core/raw-append-only.d.ts +5 -0
  376. package/dist/core/raw-append-only.js +7 -0
  377. package/dist/core/recall-scope.d.ts +69 -0
  378. package/dist/core/recall-scope.js +138 -0
  379. package/dist/core/salience.d.ts +1 -7
  380. package/dist/core/salience.js +1 -7
  381. package/dist/dashboard/dashboard-actions.js +2 -2
  382. package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
  383. package/dist/dashboard/dashboard-snapshot.js +11 -2
  384. package/dist/dashboard/dashboard-types.d.ts +2 -1
  385. package/dist/dashboard/dashboard.d.ts +1 -0
  386. package/dist/dashboard/dashboard.js +50 -4
  387. package/dist/db/busy.d.ts +3 -8
  388. package/dist/db/busy.js +37 -33
  389. package/dist/db/connect.js +7 -8
  390. package/dist/db/index.d.ts +3 -3
  391. package/dist/db/index.js +3 -3
  392. package/dist/db/migrate.js +3 -3
  393. package/dist/db/migrations/index.d.ts +1 -1
  394. package/dist/db/migrations/index.js +3 -1
  395. package/dist/db/migrations/types.d.ts +2 -5
  396. package/dist/db/migrations/v14.js +2 -3
  397. package/dist/db/migrations/v15.js +2 -8
  398. package/dist/db/migrations/v16.js +2 -3
  399. package/dist/db/migrations/v17.js +2 -3
  400. package/dist/db/migrations/v19.js +2 -5
  401. package/dist/db/migrations/v20.js +2 -7
  402. package/dist/db/migrations/v22.js +4 -17
  403. package/dist/db/migrations/v23.js +3 -14
  404. package/dist/db/migrations/v24.js +2 -4
  405. package/dist/db/migrations/v25.js +3 -8
  406. package/dist/db/migrations/v26.js +2 -13
  407. package/dist/db/migrations/v27.js +3 -11
  408. package/dist/db/migrations/v28.js +2 -14
  409. package/dist/db/migrations/v29.js +4 -18
  410. package/dist/db/migrations/v30.js +4 -16
  411. package/dist/db/migrations/v31.js +2 -15
  412. package/dist/db/migrations/v32.js +4 -22
  413. package/dist/db/migrations/v33.js +2 -15
  414. package/dist/db/migrations/v34.js +2 -11
  415. package/dist/db/migrations/v35.js +2 -11
  416. package/dist/db/migrations/v36.js +2 -11
  417. package/dist/db/migrations/v37.js +8 -33
  418. package/dist/db/migrations/v38.js +5 -38
  419. package/dist/db/migrations/v39.js +9 -20
  420. package/dist/db/migrations/v40.js +2 -9
  421. package/dist/db/migrations/v41.js +2 -24
  422. package/dist/db/migrations/v43.js +1 -1
  423. package/dist/db/migrations/v44.js +2 -8
  424. package/dist/db/migrations/v45.js +2 -7
  425. package/dist/db/migrations/v47.js +2 -3
  426. package/dist/db/migrations/v51.js +1 -1
  427. package/dist/db/migrations/v55.d.ts +3 -0
  428. package/dist/db/migrations/v55.js +17 -0
  429. package/dist/db/open.d.ts +2 -2
  430. package/dist/db/open.js +21 -9
  431. package/dist/db/physics-state.d.ts +6 -22
  432. package/dist/db/physics-state.js +28 -39
  433. package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
  434. package/dist/db/raw-archive-mirror-cleanup.js +2 -17
  435. package/dist/db/tables.d.ts +2 -0
  436. package/dist/db/tables.js +6 -2
  437. package/dist/db/vector-store.d.ts +2 -0
  438. package/dist/db/vector-store.js +25 -5
  439. package/dist/db/wal-checkpointer.js +2 -1
  440. package/dist/doctor.js +85 -27
  441. package/dist/embeddings/local.d.ts +62 -0
  442. package/dist/embeddings/local.js +146 -0
  443. package/dist/embeddings/provider.d.ts +43 -0
  444. package/dist/{store/embeddings → embeddings}/provider.js +58 -83
  445. package/dist/embeddings/transformers.d.ts +26 -0
  446. package/dist/embeddings/transformers.js +89 -0
  447. package/dist/entry/session-text.d.ts +1 -1
  448. package/dist/entry/session-text.js +3 -2
  449. package/dist/eval/eval-stats.d.ts +15 -53
  450. package/dist/eval/eval-stats.js +12 -42
  451. package/dist/eval/eval-suite.d.ts +2 -13
  452. package/dist/eval/eval-suite.js +91 -45
  453. package/dist/eval/eval.d.ts +6 -24
  454. package/dist/eval/eval.js +8 -35
  455. package/dist/eval/judgment.d.ts +0 -3
  456. package/dist/eval/judgment.js +30 -15
  457. package/dist/extensions/openclaw-plugin/index.js +1 -1
  458. package/dist/graph/extract.d.ts +5 -27
  459. package/dist/graph/extract.js +10 -36
  460. package/dist/graph/recall.d.ts +7 -20
  461. package/dist/graph/recall.js +15 -77
  462. package/dist/graph/stream.d.ts +7 -39
  463. package/dist/graph/stream.js +11 -34
  464. package/dist/graph/view.d.ts +9 -35
  465. package/dist/graph/view.js +24 -44
  466. package/dist/graph/write.d.ts +1 -1
  467. package/dist/graph/write.js +9 -9
  468. package/dist/hooks/codex-session.js +3 -2
  469. package/dist/hooks/codex-wrapper.js +4 -3
  470. package/dist/hooks/copilot.js +2 -1
  471. package/dist/hooks/hook-blocks.d.ts +6 -2
  472. package/dist/hooks/hook-blocks.js +37 -124
  473. package/dist/hooks/json-hooks.d.ts +4 -36
  474. package/dist/hooks/json-hooks.js +22 -59
  475. package/dist/hooks/opencode.d.ts +0 -38
  476. package/dist/hooks/opencode.js +17 -81
  477. package/dist/hooks/shared.d.ts +6 -21
  478. package/dist/hooks/shared.js +31 -33
  479. package/dist/importers/core.d.ts +12 -37
  480. package/dist/importers/core.js +10 -28
  481. package/dist/importers/markdown-parse.d.ts +8 -22
  482. package/dist/importers/markdown-parse.js +8 -25
  483. package/dist/importers/markdown.js +3 -12
  484. package/dist/importers/sources.js +12 -39
  485. package/dist/importers/vault.d.ts +2 -8
  486. package/dist/importers/vault.js +31 -85
  487. package/dist/index.d.ts +8 -3
  488. package/dist/index.js +8 -3
  489. package/dist/learn/autolearn.d.ts +23 -42
  490. package/dist/learn/autolearn.js +45 -52
  491. package/dist/learn/churn-git.js +13 -4
  492. package/dist/learn/extract.d.ts +3 -2
  493. package/dist/learn/extract.js +8 -8
  494. package/dist/learn/forward-claim-detector.d.ts +6 -30
  495. package/dist/learn/forward-claim-detector.js +18 -68
  496. package/dist/learn/invalidation.d.ts +6 -18
  497. package/dist/learn/invalidation.js +18 -31
  498. package/dist/mcp/admin-tools.d.ts +2 -2
  499. package/dist/mcp/admin-tools.js +30 -53
  500. package/dist/mcp/format.js +3 -2
  501. package/dist/mcp/framing.d.ts +1 -0
  502. package/dist/mcp/framing.js +1 -1
  503. package/dist/mcp/memory-tools.js +7 -10
  504. package/dist/mcp/protocol.d.ts +15 -29
  505. package/dist/mcp/protocol.js +26 -16
  506. package/dist/mcp/recall-tools.js +14 -11
  507. package/dist/mcp/request.d.ts +3 -11
  508. package/dist/mcp/request.js +12 -27
  509. package/dist/mcp/server.d.ts +3 -9
  510. package/dist/mcp/server.js +5 -16
  511. package/dist/mcp/session-state.d.ts +1 -1
  512. package/dist/mcp/session-state.js +5 -11
  513. package/dist/mcp/stdio.d.ts +2 -6
  514. package/dist/mcp/stdio.js +68 -16
  515. package/dist/mcp/tool-args.js +2 -1
  516. package/dist/mcp/tools.js +47 -22
  517. package/dist/objects/customer-notes.d.ts +9 -44
  518. package/dist/objects/customer-notes.js +7 -48
  519. package/dist/objects/decisions.d.ts +14 -52
  520. package/dist/objects/decisions.js +15 -53
  521. package/dist/objects/descriptor.d.ts +1 -1
  522. package/dist/objects/incidents.d.ts +9 -40
  523. package/dist/objects/incidents.js +7 -41
  524. package/dist/objects/lifecycle.d.ts +1 -1
  525. package/dist/objects/lifecycle.js +2 -1
  526. package/dist/objects/policies.d.ts +13 -91
  527. package/dist/objects/policies.js +13 -99
  528. package/dist/objects/processes.d.ts +9 -54
  529. package/dist/objects/processes.js +7 -61
  530. package/dist/objects/project-briefs.d.ts +13 -57
  531. package/dist/objects/project-briefs.js +16 -78
  532. package/dist/objects/skills.d.ts +9 -44
  533. package/dist/objects/skills.js +8 -54
  534. package/dist/postinstall.js +7 -20
  535. package/dist/predictions/planning-fallacy.d.ts +11 -34
  536. package/dist/rerankers/clef.js +6 -37
  537. package/dist/rerankers/cross-encoder.d.ts +31 -2
  538. package/dist/rerankers/cross-encoder.js +65 -101
  539. package/dist/rerankers/index.js +5 -4
  540. package/dist/rerankers/jev.js +11 -10
  541. package/dist/rerankers/llm.d.ts +2 -11
  542. package/dist/rerankers/llm.js +14 -14
  543. package/dist/rerankers/outage-warning.d.ts +5 -2
  544. package/dist/rerankers/outage-warning.js +7 -4
  545. package/dist/rerankers/remote.d.ts +1 -0
  546. package/dist/rerankers/remote.js +2 -0
  547. package/dist/rerankers/types.d.ts +2 -14
  548. package/dist/search/bm25-search.js +1 -1
  549. package/dist/search/boosts.d.ts +0 -2
  550. package/dist/search/boosts.js +3 -3
  551. package/dist/search/embed-memories.d.ts +9 -0
  552. package/dist/search/embed-memories.js +377 -0
  553. package/dist/search/goal-boost.d.ts +23 -0
  554. package/dist/search/goal-boost.js +93 -0
  555. package/dist/search/hybrid.d.ts +11 -2
  556. package/dist/search/hybrid.js +9 -4
  557. package/dist/search/multihop.js +2 -3
  558. package/dist/search/path-context.d.ts +5 -18
  559. package/dist/search/path-context.js +5 -18
  560. package/dist/search/physics-search.d.ts +6 -3
  561. package/dist/search/physics-search.js +29 -19
  562. package/dist/search/rerank.js +1 -1
  563. package/dist/search/rrf.d.ts +7 -35
  564. package/dist/search/rrf.js +5 -30
  565. package/dist/search/vector.d.ts +13 -4
  566. package/dist/search/vector.js +40 -13
  567. package/dist/server/auth.d.ts +11 -28
  568. package/dist/server/auth.js +49 -32
  569. package/dist/server/boot.d.ts +2 -21
  570. package/dist/server/boot.js +69 -161
  571. package/dist/server/client-ip.d.ts +3 -21
  572. package/dist/server/client-ip.js +8 -30
  573. package/dist/server/deadline.d.ts +0 -2
  574. package/dist/server/deadline.js +1 -7
  575. package/dist/server/defaults.d.ts +4 -0
  576. package/dist/server/defaults.js +5 -0
  577. package/dist/server/key-check-bounds.d.ts +2 -1
  578. package/dist/server/lifecycle.d.ts +5 -4
  579. package/dist/server/lifecycle.js +19 -4
  580. package/dist/server/mcp-http.js +24 -53
  581. package/dist/server/rate-limit.d.ts +5 -18
  582. package/dist/server/rate-limit.js +4 -13
  583. package/dist/server/request.d.ts +4 -8
  584. package/dist/server/request.js +16 -19
  585. package/dist/server/route-checks.d.ts +7 -0
  586. package/dist/server/route-checks.js +42 -0
  587. package/dist/server/route-table.d.ts +9 -8
  588. package/dist/server/route-table.js +127 -139
  589. package/dist/server/routes/admin.d.ts +8 -8
  590. package/dist/server/routes/admin.js +35 -49
  591. package/dist/server/routes/customer-notes.d.ts +6 -6
  592. package/dist/server/routes/customer-notes.js +8 -14
  593. package/dist/server/routes/decisions.d.ts +6 -6
  594. package/dist/server/routes/decisions.js +12 -21
  595. package/dist/server/routes/incidents.d.ts +6 -6
  596. package/dist/server/routes/incidents.js +14 -25
  597. package/dist/server/routes/memories.d.ts +9 -9
  598. package/dist/server/routes/memories.js +20 -63
  599. package/dist/server/routes/object-routes.d.ts +6 -11
  600. package/dist/server/routes/object-routes.js +11 -22
  601. package/dist/server/routes/policies.d.ts +7 -7
  602. package/dist/server/routes/policies.js +12 -22
  603. package/dist/server/routes/predictions.d.ts +6 -6
  604. package/dist/server/routes/predictions.js +22 -38
  605. package/dist/server/routes/processes.d.ts +6 -6
  606. package/dist/server/routes/processes.js +17 -28
  607. package/dist/server/routes/project-briefs.d.ts +7 -7
  608. package/dist/server/routes/project-briefs.js +11 -20
  609. package/dist/server/routes/recall.d.ts +5 -5
  610. package/dist/server/routes/recall.js +16 -45
  611. package/dist/server/routes/skills.d.ts +7 -7
  612. package/dist/server/routes/skills.js +10 -22
  613. package/dist/server/server-detect.d.ts +15 -53
  614. package/dist/server/server-detect.js +55 -96
  615. package/dist/server/sleep-child.js +26 -7
  616. package/dist/server/sleep-offload.d.ts +11 -5
  617. package/dist/server/sleep-offload.js +21 -12
  618. package/dist/server/types.d.ts +32 -18
  619. package/dist/server/validation.d.ts +3 -2
  620. package/dist/server/validation.js +15 -33
  621. package/dist/server.d.ts +7 -6
  622. package/dist/server.js +8 -6
  623. package/dist/sharing/global-store.d.ts +19 -0
  624. package/dist/sharing/global-store.js +75 -0
  625. package/dist/sharing/global-sync.d.ts +6 -0
  626. package/dist/sharing/global-sync.js +73 -0
  627. package/dist/sharing/project-merge.d.ts +11 -19
  628. package/dist/sharing/project-merge.js +63 -125
  629. package/dist/sharing/search-both.d.ts +60 -0
  630. package/dist/sharing/search-both.js +138 -0
  631. package/dist/sharing/share.d.ts +40 -0
  632. package/dist/sharing/share.js +229 -0
  633. package/dist/store/ambient.js +9 -15
  634. package/dist/store/audit-event.d.ts +5 -13
  635. package/dist/store/audit-event.js +4 -12
  636. package/dist/store/audit.d.ts +2 -21
  637. package/dist/store/audit.js +8 -67
  638. package/dist/store/auth.d.ts +10 -8
  639. package/dist/store/auth.js +17 -12
  640. package/dist/store/candidates.d.ts +23 -5
  641. package/dist/store/candidates.js +119 -71
  642. package/dist/store/capture-write.d.ts +17 -0
  643. package/dist/store/capture-write.js +35 -0
  644. package/dist/store/card-detail.d.ts +2 -1
  645. package/dist/store/card-detail.js +2 -1
  646. package/dist/store/cards.d.ts +14 -9
  647. package/dist/store/cards.js +72 -126
  648. package/dist/store/compaction-caller.d.ts +18 -0
  649. package/dist/store/compaction-caller.js +29 -0
  650. package/dist/store/compactions-record.d.ts +115 -0
  651. package/dist/store/compactions-record.js +417 -0
  652. package/dist/store/compactions.js +6 -4
  653. package/dist/store/conflicts.d.ts +4 -21
  654. package/dist/store/conflicts.js +76 -152
  655. package/dist/store/connectors/dlq.d.ts +10 -0
  656. package/dist/store/connectors/dlq.js +32 -0
  657. package/dist/store/connectors/github.d.ts +14 -16
  658. package/dist/store/connectors/github.js +34 -57
  659. package/dist/store/connectors/slack.d.ts +2 -11
  660. package/dist/store/connectors/slack.js +18 -47
  661. package/dist/store/dashboard-reads.js +11 -14
  662. package/dist/store/delete-and-batch.d.ts +17 -31
  663. package/dist/store/delete-and-batch.js +84 -67
  664. package/dist/store/delivery-recorder.d.ts +15 -4
  665. package/dist/store/delivery-recorder.js +34 -17
  666. package/dist/store/descendant-page.js +6 -3
  667. package/dist/store/diagnostics.js +6 -13
  668. package/dist/store/dormant.d.ts +8 -30
  669. package/dist/store/dormant.js +18 -57
  670. package/dist/store/embeddings/index.d.ts +11 -90
  671. package/dist/store/embeddings/index.js +18 -523
  672. package/dist/store/entry-reads.d.ts +34 -61
  673. package/dist/store/entry-reads.js +111 -136
  674. package/dist/store/entry-row.d.ts +6 -35
  675. package/dist/store/entry-row.js +9 -37
  676. package/dist/store/entry-writes.d.ts +12 -18
  677. package/dist/store/entry-writes.js +46 -44
  678. package/dist/store/failure-log-at.d.ts +8 -0
  679. package/dist/store/failure-log-at.js +16 -0
  680. package/dist/store/failure-log.d.ts +2 -2
  681. package/dist/store/failure-log.js +5 -3
  682. package/dist/{trust → store}/gated-write.d.ts +3 -1
  683. package/dist/{trust → store}/gated-write.js +7 -5
  684. package/dist/store/goals.d.ts +3 -40
  685. package/dist/store/goals.js +41 -178
  686. package/dist/store/graph-queue.d.ts +6 -22
  687. package/dist/store/graph-queue.js +14 -45
  688. package/dist/store/graph-reads.d.ts +11 -35
  689. package/dist/store/graph-reads.js +24 -60
  690. package/dist/store/graph-rows.d.ts +3 -6
  691. package/dist/store/graph-rows.js +6 -9
  692. package/dist/store/graph-view-rows.d.ts +2 -1
  693. package/dist/store/graph-view-rows.js +2 -1
  694. package/dist/store/graph-writes.d.ts +10 -35
  695. package/dist/store/graph-writes.js +59 -106
  696. package/dist/store/half-life.d.ts +2 -1
  697. package/dist/store/half-life.js +14 -16
  698. package/dist/store/handoffs.d.ts +6 -12
  699. package/dist/store/handoffs.js +22 -40
  700. package/dist/store/index-and-stats.d.ts +6 -19
  701. package/dist/store/index-and-stats.js +36 -84
  702. package/dist/store/key-writes.js +1 -1
  703. package/dist/store/ledger-turn.d.ts +9 -0
  704. package/dist/store/ledger-turn.js +38 -0
  705. package/dist/store/mirrors.d.ts +2 -6
  706. package/dist/store/mirrors.js +24 -29
  707. package/dist/store/open.d.ts +0 -4
  708. package/dist/store/open.js +42 -62
  709. package/dist/store/pilot-arm.d.ts +12 -0
  710. package/dist/store/pilot-arm.js +42 -0
  711. package/dist/store/planning-fallacy-evidence.d.ts +2 -30
  712. package/dist/store/planning-fallacy-evidence.js +8 -37
  713. package/dist/store/port.d.ts +91 -82
  714. package/dist/store/port.js +8 -0
  715. package/dist/store/predictions.d.ts +12 -53
  716. package/dist/store/predictions.js +41 -125
  717. package/dist/store/project-tags.d.ts +62 -0
  718. package/dist/store/project-tags.js +67 -0
  719. package/dist/{cli → store}/quality-repair.js +15 -31
  720. package/dist/store/quarantine.js +2 -1
  721. package/dist/store/raw-archive.d.ts +4 -16
  722. package/dist/store/raw-archive.js +14 -29
  723. package/dist/store/recall-trace.d.ts +12 -77
  724. package/dist/store/recall-trace.js +37 -97
  725. package/dist/store/rejected-values.js +9 -20
  726. package/dist/store/rejection-probe.d.ts +4 -0
  727. package/dist/store/rejection-probe.js +19 -0
  728. package/dist/store/rejection.d.ts +10 -73
  729. package/dist/store/rejection.js +12 -84
  730. package/dist/store/report-reads.d.ts +6 -0
  731. package/dist/store/report-reads.js +29 -0
  732. package/dist/store/rows.d.ts +9 -19
  733. package/dist/store/rows.js +36 -34
  734. package/dist/store/rule-sql.d.ts +14 -0
  735. package/dist/store/rule-sql.js +56 -0
  736. package/dist/store/search-rows.d.ts +7 -38
  737. package/dist/store/search-rows.js +23 -54
  738. package/dist/store/sessions.d.ts +10 -47
  739. package/dist/store/sessions.js +21 -75
  740. package/dist/store/set-aside.d.ts +14 -0
  741. package/dist/store/set-aside.js +23 -0
  742. package/dist/store/sqlite/busy.d.ts +3 -0
  743. package/dist/store/sqlite/busy.js +8 -0
  744. package/dist/store/sqlite/connector-events-group.js +5 -8
  745. package/dist/store/sqlite/connector-writes-group.js +3 -3
  746. package/dist/store/sqlite/entry-writes-group.js +4 -4
  747. package/dist/store/sqlite/error-codec.js +8 -5
  748. package/dist/store/sqlite/executor.d.ts +2 -1
  749. package/dist/store/sqlite/executor.js +12 -5
  750. package/dist/store/sqlite/graph-reads-group.js +1 -1
  751. package/dist/store/sqlite/held-connection.d.ts +9 -0
  752. package/dist/store/sqlite/held-connection.js +41 -0
  753. package/dist/store/sqlite/local.d.ts +3 -3
  754. package/dist/store/sqlite/local.js +1 -0
  755. package/dist/store/sqlite/object-rows.d.ts +1 -1
  756. package/dist/store/sqlite/object-rows.js +6 -3
  757. package/dist/store/sqlite/objects-group.d.ts +1 -1
  758. package/dist/store/sqlite/objects-group.js +5 -3
  759. package/dist/store/sqlite/quarantine-group.js +2 -2
  760. package/dist/store/sqlite/store.d.ts +1 -4
  761. package/dist/store/sqlite/store.js +16 -15
  762. package/dist/store/sqlite/vector-reads-group.js +2 -2
  763. package/dist/store/sqlite/worker-jobs.js +1 -1
  764. package/dist/store/sqlite/worker-ops.d.ts +13 -2
  765. package/dist/store/sqlite/worker-ops.js +13 -2
  766. package/dist/store/sqlite/worker-store.js +5 -2
  767. package/dist/store/summaries.d.ts +11 -63
  768. package/dist/store/summaries.js +37 -148
  769. package/dist/store/summary-dirty.js +1 -1
  770. package/dist/store/tenant-lookup.d.ts +6 -1
  771. package/dist/store/tenant-lookup.js +7 -0
  772. package/dist/store/tenant.d.ts +2 -16
  773. package/dist/store/tenant.js +4 -19
  774. package/dist/store/token-ledger.d.ts +13 -50
  775. package/dist/store/token-ledger.js +19 -85
  776. package/dist/store/usage-reports.js +5 -13
  777. package/dist/store/vector-index.d.ts +46 -0
  778. package/dist/store/vector-index.js +171 -0
  779. package/dist/store/working-memory.d.ts +6 -25
  780. package/dist/store/working-memory.js +18 -52
  781. package/dist/support-bundle.js +9 -8
  782. package/dist/trust/reject-flow.js +3 -5
  783. package/dist/util/agent-homes.d.ts +15 -0
  784. package/dist/util/agent-homes.js +34 -0
  785. package/dist/util/anthropic-messages.d.ts +3 -0
  786. package/dist/util/anthropic-messages.js +35 -6
  787. package/dist/util/atomic-write.d.ts +2 -1
  788. package/dist/util/atomic-write.js +35 -4
  789. package/dist/util/capped-json.d.ts +6 -0
  790. package/dist/util/capped-json.js +46 -0
  791. package/dist/util/chunked.d.ts +3 -0
  792. package/dist/util/chunked.js +10 -0
  793. package/dist/util/crash-handlers.d.ts +8 -1
  794. package/dist/util/crash-handlers.js +52 -10
  795. package/dist/util/ellipsize.d.ts +3 -0
  796. package/dist/util/ellipsize.js +5 -0
  797. package/dist/util/env.d.ts +14 -6
  798. package/dist/util/env.js +15 -7
  799. package/dist/util/format.d.ts +3 -0
  800. package/dist/util/format.js +6 -0
  801. package/dist/util/home-path.d.ts +2 -1
  802. package/dist/util/home-path.js +4 -2
  803. package/dist/util/hook-payload.d.ts +8 -0
  804. package/dist/util/hook-payload.js +37 -0
  805. package/dist/util/http-retry.d.ts +9 -1
  806. package/dist/util/http-retry.js +67 -8
  807. package/dist/util/http-util.d.ts +0 -8
  808. package/dist/util/http-util.js +10 -21
  809. package/dist/util/limits.d.ts +7 -0
  810. package/dist/util/limits.js +14 -0
  811. package/dist/util/log.d.ts +7 -2
  812. package/dist/util/log.js +34 -9
  813. package/dist/util/request-scope.d.ts +5 -2
  814. package/dist/util/request-scope.js +13 -7
  815. package/dist/util/secret-detect.d.ts +5 -30
  816. package/dist/util/secret-detect.js +19 -40
  817. package/dist/util/sqlite-blocked.d.ts +2 -0
  818. package/dist/util/sqlite-blocked.js +5 -0
  819. package/dist/util/stored-json.d.ts +1 -1
  820. package/dist/util/stored-json.js +1 -1
  821. package/dist/util/stream-tee.d.ts +3 -0
  822. package/dist/util/stream-tee.js +35 -0
  823. package/dist/util/time.d.ts +4 -0
  824. package/dist/util/time.js +4 -0
  825. package/dist/util/token-text.d.ts +1 -4
  826. package/dist/util/token-text.js +1 -4
  827. package/dist/util/transcript-tail.d.ts +2 -0
  828. package/dist/util/transcript-tail.js +24 -23
  829. package/dist/util/version.d.ts +5 -20
  830. package/dist/util/version.js +5 -20
  831. package/dist/{store → util}/yaml.d.ts +1 -5
  832. package/dist/{store → util}/yaml.js +2 -6
  833. package/extensions/openclaw-plugin/index.ts +1 -1
  834. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  835. package/extensions/openclaw-plugin/package.json +1 -1
  836. package/openclaw.plugin.json +1 -1
  837. package/package.json +2 -2
  838. package/dist/cli/provenance-coverage.d.ts +0 -18
  839. package/dist/connectors/github/cli-impl.d.ts +0 -25
  840. package/dist/sharing/scope.d.ts +0 -14
  841. package/dist/sharing/shared.d.ts +0 -187
  842. package/dist/sharing/shared.js +0 -563
  843. package/dist/store/embeddings/local.d.ts +0 -15
  844. package/dist/store/embeddings/local.js +0 -192
  845. package/dist/store/embeddings/provider.d.ts +0 -77
  846. package/dist/store/markdown.d.ts +0 -10
  847. package/dist/store/recall-scope.d.ts +0 -138
  848. package/dist/store/recall-scope.js +0 -216
  849. package/dist/store/vector-writes.d.ts +0 -13
  850. package/dist/store/vector-writes.js +0 -89
  851. /package/dist/{store → core}/object-types.d.ts +0 -0
  852. /package/dist/{store → core}/object-types.js +0 -0
  853. /package/dist/{cli → store}/quality-repair.d.ts +0 -0
  854. /package/dist/{capture → util}/compaction-items.d.ts +0 -0
  855. /package/dist/{capture → util}/compaction-items.js +0 -0
@@ -1,18 +1,15 @@
1
1
  // Bearer and loopback auth for the HTTP server.
2
- import { envRequireAuth } from '../util/env.js';
2
+ import { envAllowKeylessLocal, envRequireAuth } from '../util/env.js';
3
3
  import { resolveTenantId } from '../store/tenant.js';
4
- import { log } from '../util/log.js';
4
+ import { errorFields, errorMessage, log } from '../util/log.js';
5
5
  import { API_KEY_PREFIX, verifyApiKeyCached } from '../store/auth.js';
6
6
  import { ownerOrSubject } from '../api/index.js';
7
- import { HttpError, isCrossSite, isHeaderString, LOOPBACK_HOST_HEADER, MAX_ID_LEN } from '../util/http-util.js';
7
+ import { HttpError, isCrossSite, isHeaderString, LOOPBACK_HOST_HEADER } from '../util/http-util.js';
8
+ import { MAX_ID_LEN } from '../util/limits.js';
8
9
  import { clientLimitKey } from './client-ip.js';
9
10
  import { keyCheckBounds } from './key-check-bounds.js';
10
11
  import { isJsonString } from '../util/json.js';
11
- /**
12
- * Recognise loopback remote addresses. Node reports IPv6-mapped IPv4 as
13
- * '::ffff:127.0.0.1' on dual-stack sockets, so we accept that alongside
14
- * the bare v4 and v6 loopbacks. Anything else is treated as remote.
15
- */
12
+ /** Recognises loopback remote addresses, including the IPv6-mapped '::ffff:127.0.0.1' Node reports on dual-stack sockets; anything else is remote. */
16
13
  export function isLoopback(remoteAddress) {
17
14
  if (!remoteAddress)
18
15
  return false;
@@ -29,21 +26,36 @@ const PROXY_HEADERS = [
29
26
  'forwarded', 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-real-ip', 'cf-connecting-ip', 'true-client-ip',
30
27
  'fly-client-ip',
31
28
  ];
32
- // A browser on this machine is loopback too, so the no-key fallback also needs a local Host and a same-site caller.
29
+ function proxyHeaderOf(req) {
30
+ return PROXY_HEADERS.find((name) => req.headers[name] !== undefined);
31
+ }
32
+ /** A page in a browser on this machine: another site's request, or a hostile name resolved to loopback (DNS rebinding). */
33
+ function isForeignPage(req) {
34
+ const host = req.headers.host;
35
+ return (host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req);
36
+ }
37
+ /** True only for a request made on this machine by its own user: a proxy and a browser page are loopback too, so the socket alone proves nothing. */
38
+ export function isLocalCaller(req) {
39
+ return isLoopback(req.socket.remoteAddress) && proxyHeaderOf(req) === undefined && !isForeignPage(req);
40
+ }
41
+ // The throwing twin of isLocalCaller, for the no-key fallback: each refusal has its own status, and a proxied one is logged.
33
42
  function assertLocalCaller(req) {
34
43
  if (!isLoopback(req.socket.remoteAddress))
35
44
  throw new HttpError(401, 'auth required');
36
- const proxyHeader = PROXY_HEADERS.find((name) => req.headers[name] !== undefined);
45
+ const proxyHeader = proxyHeaderOf(req);
37
46
  if (proxyHeader !== undefined) {
38
47
  log.warn(`proxied loopback request refused: it carries ${proxyHeader}, so the no-key local fallback does not apply. ` +
39
48
  'Send an API key (hippo auth create, then Authorization: Bearer hk_...).');
40
49
  throw new HttpError(401, 'auth required');
41
50
  }
42
- const host = req.headers.host;
43
- if ((host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req)) {
51
+ if (isForeignPage(req)) {
44
52
  throw new HttpError(403, 'cross-site or non-local request refused; send an API key');
45
53
  }
46
54
  }
55
+ /** The 401 a keyless request from this machine gets by default; it names both fixes, since an upgrade is where most people meet it. */
56
+ const KEY_REQUIRED_MESSAGE = 'auth required: this server takes no request without an API key. Mint one with `hippo auth create` and send it as ' +
57
+ '"Authorization: Bearer <key>" (the hippo CLI reads HIPPO_API_KEY), or start the server with HIPPO_ALLOW_KEYLESS_LOCAL=1 ' +
58
+ 'to let requests from this machine in without a key.';
47
59
  export function readAuthHeader(req) {
48
60
  const raw = req.headers['authorization'];
49
61
  if (raw === undefined)
@@ -167,7 +179,7 @@ async function resolveBearer(req, token, opts) {
167
179
  id.owner = key.ownerSubject;
168
180
  return id;
169
181
  }
170
- /** The auth check without a charge: the bearer's identity, or null for the loopback fallback. */
182
+ /** The auth check without a charge: the bearer's identity, or null for the keyless local fallback. */
171
183
  async function checkAuth(req, opts) {
172
184
  const auth = readAuthHeader(req);
173
185
  if (auth.kind === 'malformed') {
@@ -175,10 +187,14 @@ async function checkAuth(req, opts) {
175
187
  }
176
188
  if (auth.kind === 'bearer')
177
189
  return resolveBearer(req, auth.token, opts);
178
- // No Authorization header: the loopback fallback, unless HIPPO_REQUIRE_AUTH=1 forbids the local-CLI escape hatch.
190
+ // No Authorization header. HIPPO_REQUIRE_AUTH=1 is checked first, so a deployment that sets both stays closed.
179
191
  if (envRequireAuth()) {
180
192
  throw new HttpError(401, 'auth required');
181
193
  }
194
+ if (!envAllowKeylessLocal()) {
195
+ // Only this machine's own user is told how to switch the key off; a proxied caller or a page learns nothing.
196
+ throw new HttpError(401, isLocalCaller(req) ? KEY_REQUIRED_MESSAGE : 'auth required');
197
+ }
182
198
  assertLocalCaller(req);
183
199
  return null;
184
200
  }
@@ -224,20 +240,23 @@ function chargeCaller(tenantId, actor, opts) {
224
240
  warnCallerLimited(key, tenantId, person);
225
241
  throw new HttpError(429, 'rate limit exceeded for this caller', limiter.retryAfterSec);
226
242
  }
227
- /**
228
- * Build a per-request Context from the Authorization header and remote
229
- * address. Throws HttpError(401) for invalid / missing credentials. Reads
230
- * the store only for an API-key-shaped Bearer token (or any Bearer token when no
231
- * auth resolver is registered), so loopback no-auth requests stay cheap.
232
- */
243
+ /** Builds a per-request Context from the Authorization header and remote address; throws HttpError(401) for invalid or missing credentials.
244
+ * Reads the store only for an API-key-shaped Bearer (or any Bearer when no auth resolver is registered), so keyless local requests stay cheap. */
233
245
  export async function buildContextWithAuth(req, opts) {
234
246
  const id = await checkAuth(req, opts);
235
- if (id !== null) {
236
- const actor = bearerActor(id);
237
- chargeCaller(id.tenantId, actor, opts);
238
- return { hippoRoot: opts.hippoRoot, tenantId: id.tenantId, actor, store: opts.store };
239
- }
240
- // Loopback fallback is process-local, treat as admin.
247
+ const ctx = contextFor(id, opts);
248
+ if (id !== null)
249
+ chargeCaller(id.tenantId, ctx.actor, opts);
250
+ return ctx;
251
+ }
252
+ /** The auth check again, uncharged, for a handler that authenticated with requireAuth before a slow body read and must re-check right before it acts. */
253
+ export async function recheckContextWithAuth(req, opts) {
254
+ return contextFor(await checkAuth(req, opts), opts);
255
+ }
256
+ function contextFor(id, opts) {
257
+ if (id !== null)
258
+ return { hippoRoot: opts.hippoRoot, tenantId: id.tenantId, actor: bearerActor(id), store: opts.store };
259
+ // The keyless local fallback (HIPPO_ALLOW_KEYLESS_LOCAL=1) is this machine's own user, so it is host admin.
241
260
  return {
242
261
  hippoRoot: opts.hippoRoot,
243
262
  tenantId: resolveTenantId({}),
@@ -245,12 +264,8 @@ export async function buildContextWithAuth(req, opts) {
245
264
  store: opts.store,
246
265
  };
247
266
  }
248
- /**
249
- * Auth check for routes that do not need a tenant Context (e.g. MCP transport,
250
- * which builds its own root resolution via findHippoRoot). Throws HttpError
251
- * 401 the same way buildContextWithAuth does, but skips building the Context
252
- * envelope. Loopback no-auth still passes.
253
- */
267
+ /** Auth check for routes that need no tenant Context (e.g. the MCP transport, which resolves its own root): throws HttpError 401 like buildContextWithAuth.
268
+ * A keyless local request passes only under HIPPO_ALLOW_KEYLESS_LOCAL=1. */
254
269
  export async function requireAuth(req, opts) {
255
270
  const id = await checkAuth(req, opts);
256
271
  if (id !== null)
@@ -263,6 +278,8 @@ export async function heartbeatVerdict(req, opts) {
263
278
  return 'ok';
264
279
  }
265
280
  catch (err) {
281
+ if (!(err instanceof HttpError))
282
+ log.error(`heartbeat auth check failed: ${errorMessage(err)}`, errorFields(err));
266
283
  return err instanceof HttpError && err.status < 500 && err.status !== 429 ? 'revoked' : 'unavailable';
267
284
  }
268
285
  }
@@ -1,24 +1,5 @@
1
1
  import type { ServeOpts, ServerHandle } from './types.js';
2
- /**
3
- * Boot the HTTP daemon on host:port and write the pidfile under hippoRoot.
4
- *
5
- * Refuses non-loopback hosts at boot unless
6
- * HIPPO_REQUIRE_AUTH=1 is set. The auth middleware (buildContextWithAuth /
7
- * requireAuth) has shipped and every route checks it except GET /health
8
- * (public by design for platform health checks) and the two connector
9
- * webhooks in PUBLIC_ROUTES, which are HMAC-gated by their own signing
10
- * secrets and 404 when those secrets are unset, and any publicJson GET path. But the loopback
11
- * no-auth fallback inside buildContextWithAuth still admits unauthenticated
12
- * requests from a loopback remote address (unless they carry Forwarded,
13
- * X-Forwarded-For/-Host/-Proto, X-Real-IP, Cf-Connecting-Ip, True-Client-Ip or Fly-Client-Ip, which mark a same-host proxy and get
14
- * a 401 like any keyless remote request), so binding to a non-loopback host
15
- * is only safe once that fallback is disabled with HIPPO_REQUIRE_AUTH=1,
16
- * which forces every request (loopback or not) through Bearer-token
17
- * validation. Without that env var set, a non-loopback bind would expose the
18
- * DB to the network with no auth, so we fail fast instead.
19
- *
20
- * Use port: 0 in tests to bind to an ephemeral port and read the actual
21
- * port back via server.address() after listen.
22
- */
2
+ /** Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses non-loopback hosts unless HIPPO_REQUIRE_AUTH=1.
3
+ * Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
23
4
  export declare function serve(opts: ServeOpts): Promise<ServerHandle>;
24
5
  //# sourceMappingURL=boot.d.ts.map
@@ -1,9 +1,8 @@
1
1
  import { envPort, envRequireAuth, envV1Rps } from '../util/env.js';
2
- import { existsSync } from 'node:fs';
3
2
  import { detectServer, removePidfileIfOwned, writePidfile } from './server-detect.js';
4
- import { closeHippoDb, getHippoDbPath, isStoreBusy, openHippoDb, outsideRequestStores, outsideSqliteOffLoop, runWithRequestStores, SERVER_DB_WAIT_MS, withSqliteBlocked } from '../db/index.js';
5
- import { startWalCheckpointer } from '../db/wal-checkpointer.js';
6
- import { requireGroup } from '../store/index.js';
3
+ import { outsideSqliteOffLoop, runWithRequestStores, SERVER_DB_WAIT_MS, withSqliteBlocked } from '../db/index.js';
4
+ import { isStoreBusy } from '../store/sqlite/busy.js';
5
+ import { holdSqliteConnection } from '../store/sqlite/held-connection.js';
7
6
  import { workerSqliteStore } from '../store/sqlite/worker-store.js';
8
7
  import { markSharedStore } from '../core/config.js';
9
8
  import { auditWriteFailureCount } from '../store/audit.js';
@@ -12,30 +11,28 @@ import { errorFields, errorMessage, log } from '../util/log.js';
12
11
  import { runWithRequestId } from '../util/request-scope.js';
13
12
  import { createRateLimiter } from './rate-limit.js';
14
13
  import { RecallContractError } from '../api/index.js';
15
- import { handleSlackEventsWebhook } from '../connectors/slack/webhook.js';
16
- import { handleGitHubEventsWebhook } from '../connectors/github/webhook.js';
17
- import { bodyDeadlineMs, BodyTimeoutError, BodyTooLargeError, closeAfterReply, DeadlineExceededError, HttpError, JSON_HEADERS, sendJson } from '../util/http-util.js';
14
+ import { BodyTimeoutError, BodyTooLargeError, closeAfterReply, DeadlineExceededError, HttpError, JSON_HEADERS, sendJson } from '../util/http-util.js';
18
15
  import { workerCounts } from '../store/sqlite/executor-counts.js';
19
- import { isLoopback, LIMITER_MAX_KEYS } from './auth.js';
16
+ import { isLocalCaller, LIMITER_MAX_KEYS } from './auth.js';
20
17
  import { enforceRateLimit, warnIfClientIpHeaderUnpinned } from './client-ip.js';
21
18
  import { answerAtDeadline, handlerDeadlineCount, isAbandoned, requestDeadlineFor } from './deadline.js';
22
- import { drainAndClose } from './lifecycle.js';
19
+ import { DEFAULT_SHUTDOWN_DRAIN_MS, drainAndClose, setKeepAliveTimeouts, shutdownBoundMs } from './lifecycle.js';
23
20
  import { readyProbeFor } from './ready.js';
24
- import { installCrashHandlers } from '../util/crash-handlers.js';
21
+ import { DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT } from './defaults.js';
22
+ import { installCrashHandlers, installSignalHandlers } from '../util/crash-handlers.js';
25
23
  import { handleMcpPost, handleMcpStream } from './mcp-http.js';
26
24
  import { MCP_PROJECT_SCOPED_HEADER } from '../core/project-identity.js';
27
- import { logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError } from './request.js';
25
+ import { accessRouteOf, logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError } from './request.js';
28
26
  import { createListener, warnIfCleartext } from './tls.js';
29
- import { assertAddonRoutes, assertPublicJson, dispatchAddonRoute, dispatchPublicJson, dispatchV1Route, isPublicRoute } from './route-table.js';
27
+ import { assertAddonRoutes, assertPublicJson } from './route-checks.js';
28
+ import { dispatchAddonRoute, dispatchPublicJson, dispatchV1Route } from './route-table.js';
30
29
  // server.address() returns AddressInfo once a TCP socket is bound; null before
31
30
  // listening, a string only for pipe/unix-socket listeners (never used here).
32
31
  function isAddressInfo(a) {
33
32
  return a !== null && typeof a !== 'string';
34
33
  }
35
- // Pinned at module load. Bumped alongside package.json on releases. The
36
- // HTTP /health response uses this; reading package.json synchronously here
37
- // would couple the daemon to its on-disk install path, which we want to
38
- // avoid for tests that mkdtemp a hippoRoot.
34
+ // Pinned at module load, bumped with package.json on releases; reading package.json synchronously here would couple the daemon to its install path,
35
+ // which tests that mkdtemp a hippoRoot avoid.
39
36
  const VERSION = PACKAGE_VERSION;
40
37
  const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
41
38
  async function handleRequest(req, res, opts, options) {
@@ -61,7 +58,8 @@ async function handleRequest(req, res, opts, options) {
61
58
  const routeRequest = { req, res, opts, query };
62
59
  if (await runWithRequestStores(() => dispatchScopedRoute(routeRequest, method, path), { busyWaitMs: SERVER_DB_WAIT_MS }))
63
60
  return;
64
- // A scope of its own, which the heartbeat timer keeps after it closes, so the key check and every heartbeat wait the server's lock wait. Store-ready: the stream only authenticates, through the port.
61
+ // A scope of its own, which the heartbeat timer keeps after it closes, so the key check and every
62
+ // heartbeat wait the server's lock wait. Store-ready: the stream only authenticates, through the port.
65
63
  if (method === 'GET' && path === '/mcp/stream') {
66
64
  noteAccess(req, { route: path });
67
65
  await runWithRequestStores(() => handleMcpStream(req, res, opts, streamSlots), { busyWaitMs: SERVER_DB_WAIT_MS });
@@ -70,13 +68,7 @@ async function handleRequest(req, res, opts, options) {
70
68
  res.writeHead(404, JSON_HEADERS);
71
69
  res.end(JSON.stringify({ error: 'not found' }));
72
70
  }
73
- const WEBHOOK_GROUPS = ['entryWrites', 'connectorWrites', 'connectorEvents'];
74
- /** A store missing a group a delivery writes through refuses the webhook up front, so no delivery is acknowledged and then half stored. */
75
- function requireWebhookGroups(store) {
76
- for (const group of WEBHOOK_GROUPS)
77
- requireGroup(store, group);
78
- }
79
- /** Every route that runs inside a request scope, so it opens each store once: the /v1 table, public JSON, add-on routes, the webhooks and POST /mcp. */
71
+ /** Every route that runs inside a request scope, so it opens each store once: the /v1 table with the webhooks, public JSON, add-on routes and POST /mcp. */
80
72
  async function dispatchScopedRoute(r, method, path) {
81
73
  if (await dispatchV1Route(r, method, path))
82
74
  return true;
@@ -85,26 +77,6 @@ async function dispatchScopedRoute(r, method, path) {
85
77
  if (await dispatchAddonRoute(r, method, path))
86
78
  return true;
87
79
  const { req, res, opts } = r;
88
- if (method === 'POST' && path === '/v1/connectors/slack/events') {
89
- noteAccess(req, { route: path });
90
- // Bearer auth deliberately skipped: this route is in PUBLIC_ROUTES and authenticates via the Slack HMAC signature.
91
- if (!isPublicRoute(method, path)) {
92
- // Defensive: PUBLIC_ROUTES drift would land here. Fail closed.
93
- throw new HttpError(401, 'auth required');
94
- }
95
- requireWebhookGroups(opts.store);
96
- await handleSlackEventsWebhook({ req, res, opts }, opts.store);
97
- return true;
98
- }
99
- if (method === 'POST' && path === '/v1/connectors/github/events') {
100
- noteAccess(req, { route: path });
101
- if (!isPublicRoute(method, path)) {
102
- throw new HttpError(401, 'auth required');
103
- }
104
- requireWebhookGroups(opts.store);
105
- await handleGitHubEventsWebhook({ req, res, opts }, opts.store);
106
- return true;
107
- }
108
80
  // Store-ready: under another store the MCP layer lists and runs only the tools ported to the port.
109
81
  if (method === 'POST' && path === '/mcp') {
110
82
  noteAccess(req, { route: path });
@@ -114,11 +86,9 @@ async function dispatchScopedRoute(r, method, path) {
114
86
  return false;
115
87
  }
116
88
  function sendHealth(req, res, startedAt) {
117
- // Loopback callers (detectServer's stale-pidfile probe reads version and
118
- // pid) get the full body. Non-loopback callers get liveness only: the
119
- // version string would fingerprint the build for the public internet and
120
- // the pid is noise. Platform health checks only need the 200.
121
- if (isLoopback(req.socket.remoteAddress)) {
89
+ // A caller on this machine (detectServer's probe reads version and pid) gets the full body; anyone else, even a proxied caller or a browser page on loopback,
90
+ // gets liveness only: the version would fingerprint the build and the pid is noise. Platform health checks only need the 200.
91
+ if (isLocalCaller(req)) {
122
92
  sendJson(res, 200, {
123
93
  ok: true,
124
94
  version: VERSION,
@@ -135,7 +105,8 @@ function sendHealth(req, res, startedAt) {
135
105
  sendJson(res, 200, { ok: true });
136
106
  }
137
107
  }
138
- /** Readiness: one cheap read on the served store under the server's lock wait. /health stays liveness only, so a probe can tell a store that does not answer from a dead process. */
108
+ /** Readiness: one cheap read on the served store under the server's lock wait. /health stays
109
+ * liveness only, so a probe can tell a store that does not answer from a dead process. */
139
110
  async function sendReady(res, store) {
140
111
  const { readiness } = store;
141
112
  if (readiness === undefined) {
@@ -156,10 +127,8 @@ function assertBindable(host) {
156
127
  }
157
128
  }
158
129
  async function assertNoLiveServer(hippoRoot) {
159
- // Refuse to start if a live hippo server already serves this hippoRoot.
160
- // detectServer probes the recorded /health — a stale pidfile is unlinked and
161
- // ignored, but a live peer means a concurrent `hippo serve` would race for
162
- // the port and clobber the pidfile.
130
+ // Refuse to start if a live hippo server already serves this hippoRoot (detectServer probes the recorded /health and unlinks a stale pidfile):
131
+ // a concurrent `hippo serve` would race for the port and clobber the pidfile.
163
132
  const existing = await detectServer(hippoRoot);
164
133
  if (existing) {
165
134
  throw new Error(`hippo serve: already running on port ${existing.port} (pid ${existing.pid}). ` +
@@ -175,10 +144,8 @@ function bootRateLimiter(perAddress) {
175
144
  return undefined;
176
145
  if (perAddress !== undefined)
177
146
  return limiterFor(perAddress);
178
- // Per-IP rate limiter for /v1/* and /mcp*. Built here (not at module scope) so
179
- // HIPPO_V1_RPS is read at boot, matching HIPPO_PORT above and letting a test
180
- // set the rate before serve(). A non-positive or non-finite value disables
181
- // limiting (the opt-out knob).
147
+ // Per-IP rate limiter for /v1/* and /mcp*, built here (not at module scope) so HIPPO_V1_RPS is read at boot and a test can set it before serve().
148
+ // A non-positive or non-finite value disables limiting (the opt-out knob).
182
149
  const v1Rps = Number(envV1Rps() ?? 20);
183
150
  return Number.isFinite(v1Rps) && v1Rps > 0 ? limiterFor({ ratePerSec: v1Rps, burst: v1Rps * 2 }) : undefined;
184
151
  }
@@ -209,39 +176,7 @@ function createStoreHolder(hippoRoot, store) {
209
176
  log.info(`serve: the '${store.kind}' store serves ${hippoRoot}, so no hippo.db connection is held`);
210
177
  return { hold: () => { }, afterResponse: () => { }, release: async () => { } };
211
178
  }
212
- // Handlers open and close their own connections; while this one is held, none of those closes is SQLite's last,
213
- // which checkpoints and deletes the WAL. It opens only once the store exists, so serving never creates one.
214
- let heldDb;
215
- let checkpointer;
216
- let stopHolding = false;
217
- const hold = () => {
218
- if (heldDb || stopHolding || !existsSync(getHippoDbPath(hippoRoot)))
219
- return;
220
- try {
221
- // The 'finish' listener can fire inside a request scope, which would close this connection with the request,
222
- // and inside the block of a `loop: 'off'` route, which would refuse the open.
223
- // 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.
224
- heldDb = outsideSqliteOffLoop(() => outsideRequestStores(() => openHippoDb(hippoRoot, { busyWaitMs: SERVER_DB_WAIT_MS })));
225
- checkpointer = startWalCheckpointer(getHippoDbPath(hippoRoot));
226
- }
227
- catch (err) {
228
- stopHolding = true;
229
- log.warn(`serve: could not hold a store connection; requests still work, only slower: ${errorMessage(err)}`);
230
- }
231
- };
232
- const afterResponse = () => {
233
- hold();
234
- checkpointer?.noteResponse();
235
- };
236
- const release = async () => {
237
- stopHolding = true;
238
- // The worker's connection closes first, so the held one is SQLite's last and its close checkpoints and deletes the WAL.
239
- await checkpointer?.stop();
240
- if (heldDb)
241
- closeHippoDb(heldDb);
242
- heldDb = undefined;
243
- };
244
- return { hold, afterResponse, release };
179
+ return holdSqliteConnection(hippoRoot);
245
180
  }
246
181
  // A plugin's resolver may read hippo.db through this package's synchronous functions, so it runs outside the block of a `loop: 'off'` route.
247
182
  function outsideRouteBlock(resolver) {
@@ -281,9 +216,23 @@ function replyWithFailure(req, res, err, requestId) {
281
216
  sendError(res, mapped.status, mapped.message);
282
217
  }
283
218
  const HANDLER_LATE = 'the request did not finish by its deadline and was abandoned; a write it started may or may not be saved';
284
- // The caller already has its 504, so a second reply would be written into a finished response.
285
- function logLateFailure(req, err) {
286
- log.debug(`${req.method ?? 'GET'} ${(req.url ?? '/').split('?')[0]} ended after its deadline reply: ${errorMessage(err)}`);
219
+ // The caller already has its 504, so this line is the only trace of the failure. The path and the error text can hold caller data, so it carries neither.
220
+ function logLateFailure(req, err, requestId) {
221
+ const fields = { requestId, method: req.method ?? 'GET', route: accessRouteOf(req), failureStatus: replyFor(err).status };
222
+ log.warn('request failed after its deadline reply', { ...fields, errorClass: errorFields(err).errorClass });
223
+ }
224
+ // A handler that ends after the 504 finds the response finished, so sending its own reply throws this: its work ran to the end.
225
+ function isDroppedLateReply(err) {
226
+ return err instanceof Error && 'code' in err && err.code === 'ERR_HTTP_HEADERS_SENT';
227
+ }
228
+ /** A GET only reads; every other method this server routes can write. */
229
+ const isRead = (method) => method === 'GET';
230
+ // A read that ends late changed nothing. A write that ends late ran to its end after its caller was told it may not have been saved.
231
+ function logLateFinish(req, requestId) {
232
+ const method = req.method ?? 'GET';
233
+ if (isRead(method))
234
+ return;
235
+ log.info('request finished after its deadline reply; its own reply was dropped', { requestId, method, route: accessRouteOf(req) });
287
236
  }
288
237
  function replyOrClose(req, res, err, requestId) {
289
238
  try {
@@ -291,7 +240,7 @@ function replyOrClose(req, res, err, requestId) {
291
240
  }
292
241
  catch (replyErr) {
293
242
  // A throw here would be an unhandled rejection, which stops the daemon for every caller.
294
- log.error(`serve: failure reply not sent, socket closed: ${errorMessage(replyErr)}`);
243
+ log.error(`serve: failure reply not sent, socket closed: ${errorMessage(replyErr)}`, errorFields(replyErr));
295
244
  res.destroy();
296
245
  }
297
246
  }
@@ -303,24 +252,19 @@ function answerRequest(req, res, handle, slowWarnMs) {
303
252
  runWithRequestId(requestId, () => {
304
253
  if (deadline)
305
254
  answerAtDeadline(res, deadline, () => replyOrClose(req, res, new DeadlineExceededError(HANDLER_LATE), requestId));
306
- handle().catch((err) => {
255
+ handle().then(() => {
307
256
  if (isAbandoned(res))
308
- logLateFailure(req, err);
309
- else
257
+ logLateFinish(req, requestId);
258
+ }, (err) => {
259
+ if (!isAbandoned(res))
310
260
  replyOrClose(req, res, err, requestId);
261
+ else if (isDroppedLateReply(err))
262
+ logLateFinish(req, requestId);
263
+ else
264
+ logLateFailure(req, err, requestId);
311
265
  });
312
266
  }, deadline);
313
267
  }
314
- // Node's own default, named so the three socket deadlines read together. It times the request arriving, never the handler, so a 10 minute sleep is not cut.
315
- const REQUEST_RECEIVE_TIMEOUT_MS = 300_000;
316
- function setKeepAliveTimeouts(server) {
317
- // The default 5s keepAliveTimeout closes idle sockets just as clients reuse them (ECONNRESET).
318
- // headersTimeout must stay ABOVE keepAliveTimeout + keepAliveTimeoutBuffer (1s), or it closes idle reused sockets itself.
319
- server.keepAliveTimeout = 65_000;
320
- server.headersTimeout = 70_000;
321
- // Never below what a raised body deadline allows, or Node's bare 408 would come before the route's own.
322
- server.requestTimeout = Math.max(REQUEST_RECEIVE_TIMEOUT_MS, server.headersTimeout + bodyDeadlineMs());
323
- }
324
268
  function listenOn(server, port, host) {
325
269
  return new Promise((resolve, reject) => {
326
270
  const onError = (err) => {
@@ -338,57 +282,23 @@ function listenOn(server, port, host) {
338
282
  server.listen(port, host);
339
283
  });
340
284
  }
341
- function installSignalHandlers(stop) {
342
- let shuttingDown = false;
343
- const gracefulShutdown = async (signal) => {
344
- if (shuttingDown)
345
- return;
346
- shuttingDown = true;
347
- log.warn(`received ${signal}, shutting down`);
348
- try {
349
- await stop();
350
- process.exit(0);
351
- }
352
- catch (err) {
353
- log.error(`error during stop: ${errorMessage(err)}`, errorFields(err));
354
- process.exit(1);
355
- }
356
- };
357
- process.once('SIGTERM', () => { void gracefulShutdown('SIGTERM'); });
358
- process.once('SIGINT', () => { void gracefulShutdown('SIGINT'); });
285
+ function exitOnSignalOrCrash(stop, drainMs) {
286
+ const shutdown = { run: stop, boundMs: shutdownBoundMs(drainMs) };
287
+ installSignalHandlers('serve', shutdown);
288
+ installCrashHandlers('serve', shutdown);
359
289
  }
360
- /**
361
- * Boot the HTTP daemon on host:port and write the pidfile under hippoRoot.
362
- *
363
- * Refuses non-loopback hosts at boot unless
364
- * HIPPO_REQUIRE_AUTH=1 is set. The auth middleware (buildContextWithAuth /
365
- * requireAuth) has shipped and every route checks it except GET /health
366
- * (public by design for platform health checks) and the two connector
367
- * webhooks in PUBLIC_ROUTES, which are HMAC-gated by their own signing
368
- * secrets and 404 when those secrets are unset, and any publicJson GET path. But the loopback
369
- * no-auth fallback inside buildContextWithAuth still admits unauthenticated
370
- * requests from a loopback remote address (unless they carry Forwarded,
371
- * X-Forwarded-For/-Host/-Proto, X-Real-IP, Cf-Connecting-Ip, True-Client-Ip or Fly-Client-Ip, which mark a same-host proxy and get
372
- * a 401 like any keyless remote request), so binding to a non-loopback host
373
- * is only safe once that fallback is disabled with HIPPO_REQUIRE_AUTH=1,
374
- * which forces every request (loopback or not) through Bearer-token
375
- * validation. Without that env var set, a non-loopback bind would expose the
376
- * DB to the network with no auth, so we fail fast instead.
377
- *
378
- * Use port: 0 in tests to bind to an ephemeral port and read the actual
379
- * port back via server.address() after listen.
380
- */
290
+ /** Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses non-loopback hosts unless HIPPO_REQUIRE_AUTH=1.
291
+ * Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
381
292
  export async function serve(opts) {
382
- const host = opts.host ?? '127.0.0.1';
383
- const requestedPort = opts.port ?? Number(envPort() ?? 6789);
293
+ const host = opts.host ?? DEFAULT_SERVER_HOST;
294
+ const requestedPort = opts.port ?? Number(envPort() ?? DEFAULT_SERVER_PORT);
384
295
  const routes = frozenAddonRoutes(opts.routes);
385
296
  const publicJsonBodies = assertPublicJson(opts.publicJson ?? {});
386
297
  const limiters = bootLimiters(opts.rateLimits);
387
298
  assertBindable(host);
388
299
  await assertNoLiveServer(opts.hippoRoot);
389
- // The server's start time. Single source of truth: it is returned by every
390
- // GET /health response and (below) written into the pidfile, so detectServer
391
- // can match the two and prove a pid-reusing impostor is not the real server.
300
+ // Single source of truth for the start time: returned by GET /health and written into the pidfile, so detectServer can prove a pid-reusing impostor is not
301
+ // this server.
392
302
  const startedAt = new Date().toISOString();
393
303
  // Open /mcp/stream count per client key, so the cap is per server rather than per process.
394
304
  const streamSlots = new Map();
@@ -414,15 +324,15 @@ export async function serve(opts) {
414
324
  await served.store.close();
415
325
  await holder.release();
416
326
  };
417
- if (opts.handleSignals) {
418
- installSignalHandlers(stop);
419
- installCrashHandlers('serve', stop);
420
- }
327
+ if (opts.handleSignals)
328
+ exitOnSignalOrCrash(stop, opts.shutdownDrainMs ?? DEFAULT_SHUTDOWN_DRAIN_MS);
421
329
  return { port: actualPort, url, stop, server };
422
330
  }
423
331
  function frozenAddonRoutes(addonRoutes) {
424
332
  // A frozen copy, so a route the caller adds or renames after boot never skips the check below.
425
- const routes = Object.freeze((addonRoutes ?? []).map(({ path, handler, storeReady }) => Object.freeze(storeReady === undefined ? { path, handler } : { path, handler, storeReady })));
333
+ const routes = Object.freeze((addonRoutes ?? []).map(({ path, handler, storeReady }) => Object.freeze(storeReady === undefined
334
+ ? { path, handler }
335
+ : { path, handler, storeReady })));
426
336
  assertAddonRoutes(routes);
427
337
  return routes;
428
338
  }
@@ -456,10 +366,8 @@ async function listenAndDescribe(server, port, host, tls) {
456
366
  return { port: actualPort, url };
457
367
  }
458
368
  async function stopListening(opts, server, inflight, startedAt) {
459
- // Remove the pidfile only if it still names this server. A newer server
460
- // may have started on this hippoRoot and rewritten the pidfile; an
461
- // unconditional unlink here would orphan it.
369
+ // Remove the pidfile only if it still names this server: a newer server may have rewritten it, and an unconditional unlink would orphan it.
462
370
  removePidfileIfOwned(opts.hippoRoot, { pid: process.pid, startedAt });
463
- await drainAndClose(server, inflight, opts.shutdownDrainMs ?? 5000);
371
+ await drainAndClose(server, inflight, opts.shutdownDrainMs ?? DEFAULT_SHUTDOWN_DRAIN_MS);
464
372
  }
465
373
  //# sourceMappingURL=boot.js.map
@@ -1,30 +1,12 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
2
  import type { RateLimiter } from './rate-limit.js';
3
3
  /**
4
- * Rate-limit key for a request. Defaults to the socket's remote address.
5
- *
6
- * Behind a TLS-terminating proxy (Fly, most PaaS ingress) every socket
7
- * carries the proxy's address, so per-IP buckets collapse into one global
8
- * bucket that unauthenticated traffic can drain before auth runs. Set
9
- * HIPPO_CLIENT_IP_HEADER to the header the proxy stamps with the real
10
- * client address (fly-client-ip on Fly, which the edge always overwrites)
11
- * to key buckets per client instead.
12
- *
13
- * Only set this when a trusted proxy fronts EVERY request: a directly
14
- * reachable server honoring the header would let clients mint a fresh
15
- * bucket per request and bypass the limiter entirely.
16
- *
17
- * HIPPO_TRUSTED_PROXIES (comma-separated IPs or CIDRs) pins which peers count
18
- * as that proxy: the header is read only when the socket peer is listed, and
19
- * listed hops are skipped. In a comma-joined chain (X-Forwarded-For) the key is
20
- * the rightmost hop no trusted proxy added; entries to its left are whatever
21
- * the client sent, so they never pick the bucket.
22
- */
4
+ * Rate-limit key: the socket's remote address, which behind a TLS proxy collapses into one bucket unauthenticated traffic can drain.
5
+ * Set HIPPO_CLIENT_IP_HEADER (fly-client-ip on Fly) only when a trusted proxy fronts EVERY request, or clients could mint a fresh bucket per request.
6
+ * HIPPO_TRUSTED_PROXIES (IPs or CIDRs) pins which peers count as that proxy; in a comma-joined chain the key is the rightmost hop no trusted proxy added. */
23
7
  export declare function clientIpForRateLimit(req: IncomingMessage): string;
24
8
  /** Said once at boot: with no proxy list, a caller that reaches the port without the proxy picks its own bucket by sending the header. */
25
9
  export declare function warnIfClientIpHeaderUnpinned(): void;
26
- /** The key for one subscriber: an IPv6 address's /64, since one host may hold the whole /64; any other key as is. */
27
- export declare function subscriberKey(ip: string): string;
28
10
  /** The one key every per-address limit and slot count uses, so rotating inside a /64 never buys a fresh bucket. */
29
11
  export declare function clientLimitKey(req: IncomingMessage): string;
30
12
  export declare function enforceRateLimit(req: IncomingMessage, path: string, limiter?: RateLimiter): void;