hippo-memory 1.72.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (995) hide show
  1. package/README.md +6 -4
  2. package/dist/agent-memories/apply.d.ts +7 -5
  3. package/dist/agent-memories/apply.js +66 -39
  4. package/dist/agent-memories/claude-code.d.ts +8 -2
  5. package/dist/agent-memories/claude-code.js +26 -7
  6. package/dist/agent-memories/copilot.js +2 -1
  7. package/dist/agent-memories/files.js +2 -1
  8. package/dist/agent-memories/legacy.d.ts +6 -3
  9. package/dist/agent-memories/legacy.js +35 -14
  10. package/dist/agent-memories/markdown.d.ts +3 -1
  11. package/dist/agent-memories/markdown.js +3 -1
  12. package/dist/agent-memories/openclaw.js +5 -2
  13. package/dist/agent-memories/plan.js +11 -1
  14. package/dist/agent-memories/project-folds.js +2 -1
  15. package/dist/agent-memories/report.d.ts +4 -1
  16. package/dist/agent-memories/report.js +43 -9
  17. package/dist/agent-memories/source.d.ts +8 -2
  18. package/dist/agent-memories/source.js +11 -3
  19. package/dist/agent-memories/sync.d.ts +7 -2
  20. package/dist/agent-memories/sync.js +141 -101
  21. package/dist/api/assemble.d.ts +6 -4
  22. package/dist/api/assemble.js +11 -5
  23. package/dist/api/{audit.d.ts → auth/audit.d.ts} +18 -16
  24. package/dist/api/auth/audit.js +58 -0
  25. package/dist/api/{auth.d.ts → auth/auth.d.ts} +19 -16
  26. package/dist/api/{auth.js → auth/auth.js} +66 -54
  27. package/dist/api/{quarantine.d.ts → auth/quarantine.d.ts} +8 -7
  28. package/dist/api/{quarantine.js → auth/quarantine.js} +8 -7
  29. package/dist/api/auth/session-owners.d.ts +10 -0
  30. package/dist/api/auth/session-owners.js +35 -0
  31. package/dist/api/availability.d.ts +3 -1
  32. package/dist/api/availability.js +3 -1
  33. package/dist/api/busy.d.ts +2 -0
  34. package/dist/api/busy.js +2 -0
  35. package/dist/api/cli-surface.d.ts +6 -0
  36. package/dist/api/cli-surface.js +6 -0
  37. package/dist/api/config-of.d.ts +5 -0
  38. package/dist/api/config-of.js +6 -0
  39. package/dist/api/context-auto.d.ts +4 -1
  40. package/dist/api/context-auto.js +14 -4
  41. package/dist/api/context-render.js +14 -7
  42. package/dist/api/context-select.d.ts +4 -1
  43. package/dist/api/context-select.js +31 -34
  44. package/dist/api/context-types.d.ts +38 -12
  45. package/dist/api/context.d.ts +8 -5
  46. package/dist/api/context.js +120 -63
  47. package/dist/api/continuity.d.ts +24 -21
  48. package/dist/api/continuity.js +18 -20
  49. package/dist/api/correction-latency.d.ts +3 -1
  50. package/dist/api/correction-latency.js +3 -1
  51. package/dist/api/error-reply.d.ts +4 -1
  52. package/dist/api/error-reply.js +12 -3
  53. package/dist/api/index.d.ts +39 -23
  54. package/dist/api/index.js +21 -23
  55. package/dist/api/instruction-detect.d.ts +4 -1
  56. package/dist/api/instruction-detect.js +75 -20
  57. package/dist/api/ledger-db.d.ts +15 -11
  58. package/dist/api/ledger-db.js +21 -23
  59. package/dist/api/memories/conflicts.d.ts +33 -0
  60. package/dist/api/memories/conflicts.js +67 -0
  61. package/dist/api/{forget.d.ts → memories/forget.d.ts} +11 -9
  62. package/dist/api/{forget.js → memories/forget.js} +23 -17
  63. package/dist/api/memories/memories.d.ts +27 -0
  64. package/dist/api/memories/memories.js +52 -0
  65. package/dist/api/memories/outcome.d.ts +22 -0
  66. package/dist/api/memories/outcome.js +28 -0
  67. package/dist/api/memories/promote.d.ts +40 -0
  68. package/dist/api/memories/promote.js +76 -0
  69. package/dist/api/memories/refine.d.ts +10 -0
  70. package/dist/api/memories/refine.js +12 -0
  71. package/dist/api/{remember-local.d.ts → memories/remember-local.d.ts} +17 -9
  72. package/dist/api/{remember-local.js → memories/remember-local.js} +46 -24
  73. package/dist/api/{remember.d.ts → memories/remember.d.ts} +22 -13
  74. package/dist/api/{remember.js → memories/remember.js} +50 -32
  75. package/dist/api/objects/cards.d.ts +39 -0
  76. package/dist/api/{cards.js → objects/cards.js} +12 -14
  77. package/dist/api/{drill-down.d.ts → objects/drill-down.d.ts} +12 -10
  78. package/dist/api/{drill-down.js → objects/drill-down.js} +7 -7
  79. package/dist/api/objects/goals.d.ts +18 -0
  80. package/dist/api/{goals.js → objects/goals.js} +12 -12
  81. package/dist/api/objects/graph.d.ts +11 -0
  82. package/dist/api/objects/graph.js +16 -0
  83. package/dist/api/objects/objects.d.ts +9 -0
  84. package/dist/api/{objects.js → objects/objects.js} +2 -3
  85. package/dist/api/objects/predictions.d.ts +11 -0
  86. package/dist/api/{predictions.js → objects/predictions.js} +7 -5
  87. package/dist/api/{projects.d.ts → objects/projects.d.ts} +8 -5
  88. package/dist/api/{projects.js → objects/projects.js} +8 -4
  89. package/dist/api/pilot-arm.d.ts +8 -4
  90. package/dist/api/pilot-arm.js +5 -4
  91. package/dist/api/prompt-hook.d.ts +35 -20
  92. package/dist/api/prompt-hook.js +66 -44
  93. package/dist/api/provenance-coverage.d.ts +3 -1
  94. package/dist/api/provenance-coverage.js +3 -1
  95. package/dist/api/recall/finish.d.ts +185 -0
  96. package/dist/api/recall/finish.js +301 -0
  97. package/dist/api/{recall-pipeline.d.ts → recall/pipeline.d.ts} +12 -8
  98. package/dist/api/{recall-pipeline.js → recall/pipeline.js} +185 -101
  99. package/dist/api/recall/recall.d.ts +6 -0
  100. package/dist/api/{recall.js → recall/recall.js} +116 -72
  101. package/dist/api/recall/render.d.ts +39 -0
  102. package/dist/api/recall/render.js +60 -0
  103. package/dist/api/{recall-request.d.ts → recall/request.d.ts} +7 -5
  104. package/dist/api/recall/request.js +261 -0
  105. package/dist/api/{recall-cli.d.ts → recall/rows.d.ts} +18 -12
  106. package/dist/api/{recall-cli.js → recall/rows.js} +28 -27
  107. package/dist/api/{recall-types.d.ts → recall/types.d.ts} +95 -68
  108. package/dist/api/{recall-types.js → recall/types.js} +1 -1
  109. package/dist/api/session-end.d.ts +36 -8
  110. package/dist/api/session-end.js +71 -25
  111. package/dist/api/{auto-sleep.d.ts → sleep/auto-sleep.d.ts} +9 -5
  112. package/dist/api/{auto-sleep.js → sleep/auto-sleep.js} +7 -12
  113. package/dist/api/sleep/dormant.d.ts +25 -0
  114. package/dist/api/sleep/dormant.js +64 -0
  115. package/dist/api/{learn.d.ts → sleep/learn.d.ts} +5 -4
  116. package/dist/api/sleep/learn.js +138 -0
  117. package/dist/api/sleep/sleep-run.d.ts +38 -0
  118. package/dist/api/{sleep-run.js → sleep/sleep-run.js} +54 -45
  119. package/dist/api/{sleep.d.ts → sleep/sleep.d.ts} +17 -11
  120. package/dist/api/sleep/sleep.js +9 -0
  121. package/dist/api/status.d.ts +3 -1
  122. package/dist/api/status.js +3 -1
  123. package/dist/api/store-init.d.ts +4 -1
  124. package/dist/api/store-init.js +4 -1
  125. package/dist/api/tokens.d.ts +10 -9
  126. package/dist/api/tokens.js +9 -10
  127. package/dist/api/types.d.ts +27 -12
  128. package/dist/api/types.js +13 -4
  129. package/dist/capture/caller-session.d.ts +8 -2
  130. package/dist/capture/caller-session.js +16 -6
  131. package/dist/capture/capture-error.d.ts +3 -1
  132. package/dist/capture/capture-error.js +3 -1
  133. package/dist/capture/codex-patch.js +7 -2
  134. package/dist/capture/command.d.ts +4 -2
  135. package/dist/capture/command.js +34 -15
  136. package/dist/capture/compact-resume-caller.js +15 -8
  137. package/dist/capture/compact.d.ts +8 -5
  138. package/dist/capture/compact.js +34 -23
  139. package/dist/capture/compaction-items-caller.js +9 -3
  140. package/dist/capture/compaction-record.d.ts +4 -3
  141. package/dist/capture/compaction-record.js +20 -12
  142. package/dist/capture/compaction-spool.d.ts +18 -9
  143. package/dist/capture/compaction-spool.js +105 -63
  144. package/dist/capture/copilot-transcript.d.ts +11 -3
  145. package/dist/capture/copilot-transcript.js +16 -6
  146. package/dist/capture/extract.js +20 -8
  147. package/dist/capture/failure-caller.js +23 -12
  148. package/dist/capture/failure-reading.d.ts +10 -3
  149. package/dist/capture/failure-reading.js +24 -7
  150. package/dist/capture/pre-compact-caller.js +11 -4
  151. package/dist/capture/session-digest.d.ts +15 -4
  152. package/dist/capture/session-digest.js +39 -13
  153. package/dist/capture/session-end-caller.d.ts +4 -1
  154. package/dist/capture/session-end-caller.js +20 -8
  155. package/dist/capture/session-texts.d.ts +6 -2
  156. package/dist/capture/session-texts.js +22 -7
  157. package/dist/capture/session-worker.d.ts +4 -2
  158. package/dist/capture/session-worker.js +58 -17
  159. package/dist/capture/transcript.d.ts +13 -4
  160. package/dist/capture/transcript.js +32 -10
  161. package/dist/capture/working-state.d.ts +13 -4
  162. package/dist/capture/working-state.js +50 -56
  163. package/dist/cli/api-context.d.ts +14 -2
  164. package/dist/cli/api-context.js +45 -2
  165. package/dist/cli/audit.js +33 -33
  166. package/dist/cli/auth.js +23 -31
  167. package/dist/cli/briefs.d.ts +1 -1
  168. package/dist/cli/briefs.js +20 -15
  169. package/dist/cli/card.d.ts +1 -1
  170. package/dist/cli/card.js +56 -73
  171. package/dist/cli/client.d.ts +12 -5
  172. package/dist/cli/client.js +53 -23
  173. package/dist/cli/compact-resume-payload.d.ts +4 -1
  174. package/dist/cli/compact-resume-payload.js +12 -5
  175. package/dist/cli/context.js +43 -18
  176. package/dist/cli/continuity.d.ts +5 -5
  177. package/dist/cli/continuity.js +90 -107
  178. package/dist/cli/curate.d.ts +5 -4
  179. package/dist/cli/curate.js +55 -77
  180. package/dist/cli/dag.d.ts +1 -1
  181. package/dist/cli/dag.js +14 -17
  182. package/dist/cli/decisions.js +30 -30
  183. package/dist/cli/eval.js +16 -21
  184. package/dist/cli/exit.d.ts +4 -1
  185. package/dist/cli/exit.js +10 -2
  186. package/dist/cli/explain.js +12 -11
  187. package/dist/cli/flag-values.d.ts +1 -1
  188. package/dist/cli/flag-values.js +9 -18
  189. package/dist/cli/github.d.ts +6 -0
  190. package/dist/cli/github.js +25 -13
  191. package/dist/cli/goals.d.ts +1 -1
  192. package/dist/cli/goals.js +39 -56
  193. package/dist/cli/graph.d.ts +1 -1
  194. package/dist/cli/graph.js +15 -11
  195. package/dist/cli/hook-runtime.d.ts +34 -10
  196. package/dist/cli/hook-runtime.js +41 -16
  197. package/dist/cli/incidents.d.ts +1 -1
  198. package/dist/cli/incidents.js +25 -25
  199. package/dist/cli/init.d.ts +1 -1
  200. package/dist/cli/init.js +35 -20
  201. package/dist/cli/install-steps.d.ts +12 -3
  202. package/dist/cli/install-steps.js +42 -18
  203. package/dist/cli/last-sleep.d.ts +4 -1
  204. package/dist/cli/last-sleep.js +9 -4
  205. package/dist/cli/maintenance.d.ts +1 -1
  206. package/dist/cli/maintenance.js +11 -12
  207. package/dist/cli/notes.d.ts +1 -1
  208. package/dist/cli/notes.js +8 -5
  209. package/dist/cli/object-verbs.d.ts +5 -5
  210. package/dist/cli/object-verbs.js +13 -16
  211. package/dist/cli/open-browser.js +11 -2
  212. package/dist/cli/playbooks.d.ts +3 -3
  213. package/dist/cli/playbooks.js +40 -32
  214. package/dist/cli/predictions.js +17 -22
  215. package/dist/cli/print.js +4 -2
  216. package/dist/cli/projects.js +21 -11
  217. package/dist/cli/quality-repair-once.d.ts +1 -1
  218. package/dist/cli/quality-repair-once.js +7 -6
  219. package/dist/cli/recall.js +129 -93
  220. package/dist/cli/refine-llm.d.ts +15 -4
  221. package/dist/cli/refine-llm.js +17 -7
  222. package/dist/cli/remember.js +51 -55
  223. package/dist/cli/scheduler.d.ts +4 -1
  224. package/dist/cli/scheduler.js +9 -5
  225. package/dist/cli/serve.js +28 -18
  226. package/dist/cli/session-hooks.d.ts +2 -6
  227. package/dist/cli/session-hooks.js +140 -112
  228. package/dist/cli/setup.d.ts +1 -1
  229. package/dist/cli/setup.js +56 -34
  230. package/dist/cli/shared.d.ts +4 -2
  231. package/dist/cli/shared.js +26 -11
  232. package/dist/cli/slack.js +15 -24
  233. package/dist/cli/sleep-render.d.ts +3 -1
  234. package/dist/cli/sleep-render.js +8 -5
  235. package/dist/cli/sleep.js +16 -8
  236. package/dist/cli/status.d.ts +4 -4
  237. package/dist/cli/status.js +32 -27
  238. package/dist/cli/stdin.d.ts +10 -3
  239. package/dist/cli/stdin.js +10 -3
  240. package/dist/cli/transfer.d.ts +4 -4
  241. package/dist/cli/transfer.js +97 -82
  242. package/dist/cli/usage.d.ts +1 -1
  243. package/dist/cli/usage.js +1 -1
  244. package/dist/cli/verb-row.d.ts +2 -0
  245. package/dist/cli/verbs/health.js +2 -0
  246. package/dist/cli/verbs/memory.js +47 -53
  247. package/dist/cli/verbs/objects.js +16 -7
  248. package/dist/cli/verbs/sessions.js +4 -2
  249. package/dist/cli/versioned-verbs.d.ts +8 -7
  250. package/dist/cli/versioned-verbs.js +31 -21
  251. package/dist/cli.js +14 -18
  252. package/dist/connectors/dlq.d.ts +6 -6
  253. package/dist/connectors/dlq.js +12 -7
  254. package/dist/connectors/github/backfill.d.ts +4 -4
  255. package/dist/connectors/github/backfill.js +6 -4
  256. package/dist/connectors/github/deletion.d.ts +6 -4
  257. package/dist/connectors/github/deletion.js +5 -4
  258. package/dist/connectors/github/dlq.d.ts +8 -6
  259. package/dist/connectors/github/dlq.js +11 -5
  260. package/dist/connectors/github/ingest.d.ts +2 -2
  261. package/dist/connectors/github/ingest.js +9 -5
  262. package/dist/connectors/github/octokit-client.d.ts +3 -1
  263. package/dist/connectors/github/octokit-client.js +7 -2
  264. package/dist/connectors/github/ratelimit.d.ts +6 -2
  265. package/dist/connectors/github/ratelimit.js +6 -2
  266. package/dist/connectors/github/signature.d.ts +14 -3
  267. package/dist/connectors/github/signature.js +17 -3
  268. package/dist/connectors/github/tenant-routing.d.ts +6 -4
  269. package/dist/connectors/github/tenant-routing.js +6 -5
  270. package/dist/connectors/github/transform.js +50 -67
  271. package/dist/connectors/github/types.d.ts +10 -3
  272. package/dist/connectors/github/types.js +6 -2
  273. package/dist/connectors/github/webhook.d.ts +5 -5
  274. package/dist/connectors/github/webhook.js +36 -23
  275. package/dist/connectors/ingest.d.ts +5 -3
  276. package/dist/connectors/ingest.js +3 -3
  277. package/dist/connectors/slack/backfill.d.ts +5 -5
  278. package/dist/connectors/slack/backfill.js +3 -3
  279. package/dist/connectors/slack/deletion.d.ts +4 -4
  280. package/dist/connectors/slack/deletion.js +6 -5
  281. package/dist/connectors/slack/dlq.d.ts +4 -4
  282. package/dist/connectors/slack/dlq.js +6 -6
  283. package/dist/connectors/slack/ingest.d.ts +6 -4
  284. package/dist/connectors/slack/ingest.js +5 -4
  285. package/dist/connectors/slack/signature.d.ts +4 -1
  286. package/dist/connectors/slack/tenant-routing.d.ts +6 -4
  287. package/dist/connectors/slack/tenant-routing.js +6 -5
  288. package/dist/connectors/slack/transform.d.ts +6 -2
  289. package/dist/connectors/slack/transform.js +6 -2
  290. package/dist/connectors/slack/types.d.ts +3 -1
  291. package/dist/connectors/slack/web-client.js +8 -3
  292. package/dist/connectors/slack/webhook.d.ts +5 -5
  293. package/dist/connectors/slack/webhook.js +19 -11
  294. package/dist/connectors/slack/workspaces.d.ts +7 -3
  295. package/dist/connectors/slack/workspaces.js +7 -3
  296. package/dist/connectors/store.d.ts +8 -0
  297. package/dist/connectors/store.js +2 -0
  298. package/dist/consolidate/conflicts.js +24 -10
  299. package/dist/consolidate/dag-summary.js +2 -1
  300. package/dist/consolidate/dag.d.ts +10 -5
  301. package/dist/consolidate/dag.js +45 -39
  302. package/dist/consolidate/decay.js +19 -6
  303. package/dist/consolidate/dedupe.d.ts +14 -5
  304. package/dist/consolidate/dedupe.js +28 -17
  305. package/dist/consolidate/flush-units.d.ts +4 -1
  306. package/dist/consolidate/flush-units.js +4 -1
  307. package/dist/consolidate/half-life-migration.d.ts +18 -8
  308. package/dist/consolidate/half-life-migration.js +48 -18
  309. package/dist/consolidate/llm-passes.js +27 -11
  310. package/dist/consolidate/memory-value-weights.d.ts +6 -2
  311. package/dist/consolidate/memory-value-weights.js +6 -2
  312. package/dist/consolidate/memory-value.d.ts +30 -10
  313. package/dist/consolidate/memory-value.js +37 -14
  314. package/dist/consolidate/merge.d.ts +4 -1
  315. package/dist/consolidate/merge.js +47 -37
  316. package/dist/consolidate/overlap-index.d.ts +8 -2
  317. package/dist/consolidate/overlap-index.js +11 -4
  318. package/dist/consolidate/physics-pass.d.ts +3 -1
  319. package/dist/consolidate/physics-pass.js +10 -7
  320. package/dist/consolidate/replay.d.ts +11 -4
  321. package/dist/consolidate/replay.js +19 -7
  322. package/dist/consolidate/run.d.ts +13 -5
  323. package/dist/consolidate/run.js +4 -4
  324. package/dist/consolidate/sleep.d.ts +14 -6
  325. package/dist/consolidate/sleep.js +42 -39
  326. package/dist/consolidate/trace.d.ts +7 -2
  327. package/dist/consolidate/trace.js +7 -2
  328. package/dist/consolidate/traces.js +27 -30
  329. package/dist/core/ablation.d.ts +9 -3
  330. package/dist/core/ablation.js +14 -4
  331. package/dist/core/active-scope.d.ts +3 -1
  332. package/dist/core/active-scope.js +3 -1
  333. package/dist/core/agent-memory-tools.d.ts +2 -0
  334. package/dist/core/agent-memory-tools.js +2 -0
  335. package/dist/core/ambient.d.ts +4 -3
  336. package/dist/core/ambient.js +8 -6
  337. package/dist/core/api-errors.d.ts +9 -3
  338. package/dist/core/api-errors.js +9 -3
  339. package/dist/core/capture-contract.d.ts +4 -1
  340. package/dist/core/capture-contract.js +27 -8
  341. package/dist/core/compare.d.ts +24 -8
  342. package/dist/core/compare.js +24 -8
  343. package/dist/core/config.d.ts +18 -9
  344. package/dist/core/config.js +38 -29
  345. package/dist/core/cosine.d.ts +4 -1
  346. package/dist/core/cosine.js +4 -1
  347. package/dist/core/handoff.d.ts +7 -2
  348. package/dist/core/handoff.js +4 -1
  349. package/dist/core/markdown.js +22 -17
  350. package/dist/core/memory-audit.js +14 -3
  351. package/dist/core/memory-quality.d.ts +12 -3
  352. package/dist/core/memory-quality.js +57 -21
  353. package/dist/core/memory.d.ts +87 -30
  354. package/dist/core/memory.js +82 -33
  355. package/dist/core/merged-row.d.ts +8 -2
  356. package/dist/core/merged-row.js +10 -3
  357. package/dist/core/package-root.d.ts +3 -1
  358. package/dist/core/package-root.js +3 -1
  359. package/dist/core/particle-refresh.d.ts +8 -0
  360. package/dist/core/particle-refresh.js +22 -0
  361. package/dist/core/physics-config.d.ts +4 -1
  362. package/dist/core/physics-config.js +6 -2
  363. package/dist/core/physics.d.ts +39 -11
  364. package/dist/core/physics.js +71 -21
  365. package/dist/core/project-identity.d.ts +34 -17
  366. package/dist/core/project-identity.js +35 -18
  367. package/dist/core/project-remote.d.ts +8 -4
  368. package/dist/core/project-remote.js +31 -14
  369. package/dist/core/recall-scope.d.ts +33 -11
  370. package/dist/core/recall-scope.js +42 -15
  371. package/dist/core/rejection-digest.d.ts +7 -0
  372. package/dist/core/rejection-digest.js +13 -0
  373. package/dist/core/salience.d.ts +3 -1
  374. package/dist/core/salience.js +10 -4
  375. package/dist/core/search-types.d.ts +15 -2
  376. package/dist/core/search-types.js +11 -0
  377. package/dist/dashboard/dashboard-actions.d.ts +2 -2
  378. package/dist/dashboard/dashboard-actions.js +18 -7
  379. package/dist/dashboard/dashboard-queries.js +2 -7
  380. package/dist/dashboard/dashboard-snapshot.d.ts +2 -2
  381. package/dist/dashboard/dashboard-snapshot.js +5 -7
  382. package/dist/dashboard/dashboard.js +22 -8
  383. package/dist/db/backup.js +2 -2
  384. package/dist/db/busy.d.ts +10 -3
  385. package/dist/db/busy.js +27 -5
  386. package/dist/db/connect.d.ts +10 -2
  387. package/dist/db/connect.js +8 -2
  388. package/dist/db/continuity.d.ts +1 -1
  389. package/dist/db/continuity.js +27 -11
  390. package/dist/db/meta.d.ts +4 -1
  391. package/dist/db/meta.js +4 -1
  392. package/dist/db/migrate.d.ts +10 -5
  393. package/dist/db/migrate.js +40 -20
  394. package/dist/db/migrations/index.d.ts +1 -1
  395. package/dist/db/migrations/index.js +3 -1
  396. package/dist/db/migrations/types.d.ts +2 -1
  397. package/dist/db/migrations/v11.js +1 -0
  398. package/dist/db/migrations/v12.js +2 -1
  399. package/dist/db/migrations/v14.js +2 -0
  400. package/dist/db/migrations/v15.js +4 -2
  401. package/dist/db/migrations/v16.js +6 -3
  402. package/dist/db/migrations/v17.js +2 -1
  403. package/dist/db/migrations/v19.js +4 -2
  404. package/dist/db/migrations/v20.js +2 -1
  405. package/dist/db/migrations/v22.js +12 -6
  406. package/dist/db/migrations/v23.js +6 -3
  407. package/dist/db/migrations/v24.js +6 -3
  408. package/dist/db/migrations/v25.js +4 -2
  409. package/dist/db/migrations/v26.js +4 -2
  410. package/dist/db/migrations/v27.js +6 -3
  411. package/dist/db/migrations/v28.js +4 -2
  412. package/dist/db/migrations/v29.js +4 -2
  413. package/dist/db/migrations/v30.js +6 -3
  414. package/dist/db/migrations/v31.js +4 -2
  415. package/dist/db/migrations/v32.js +6 -3
  416. package/dist/db/migrations/v33.js +4 -2
  417. package/dist/db/migrations/v34.js +2 -1
  418. package/dist/db/migrations/v35.js +2 -1
  419. package/dist/db/migrations/v36.js +2 -1
  420. package/dist/db/migrations/v37.js +10 -5
  421. package/dist/db/migrations/v38.js +10 -5
  422. package/dist/db/migrations/v39.js +14 -6
  423. package/dist/db/migrations/v40.js +4 -2
  424. package/dist/db/migrations/v41.js +4 -2
  425. package/dist/db/migrations/v42.js +2 -1
  426. package/dist/db/migrations/v44.js +4 -2
  427. package/dist/db/migrations/v45.js +4 -2
  428. package/dist/db/migrations/v49.js +2 -1
  429. package/dist/db/migrations/v50.js +4 -2
  430. package/dist/db/migrations/v51.js +4 -2
  431. package/dist/db/migrations/v52.js +2 -1
  432. package/dist/db/migrations/v53.js +8 -4
  433. package/dist/db/migrations/v54.js +2 -1
  434. package/dist/db/migrations/v55.js +4 -2
  435. package/dist/db/migrations/v56.d.ts +3 -0
  436. package/dist/db/migrations/v56.js +28 -0
  437. package/dist/db/open.d.ts +24 -12
  438. package/dist/db/open.js +25 -13
  439. package/dist/db/physics-state.d.ts +8 -8
  440. package/dist/db/physics-state.js +17 -50
  441. package/dist/db/raw-archive-mirror-cleanup.d.ts +4 -2
  442. package/dist/db/raw-archive-mirror-cleanup.js +6 -4
  443. package/dist/db/request-stores.d.ts +20 -5
  444. package/dist/db/request-stores.js +15 -5
  445. package/dist/db/tables.d.ts +2 -1
  446. package/dist/db/tables.js +12 -4
  447. package/dist/db/vector-store.d.ts +13 -4
  448. package/dist/db/vector-store.js +35 -14
  449. package/dist/db/wal-checkpointer.d.ts +2 -1
  450. package/dist/db/wal-checkpointer.js +19 -7
  451. package/dist/doctor.d.ts +7 -1
  452. package/dist/doctor.js +128 -46
  453. package/dist/embeddings/local.d.ts +8 -4
  454. package/dist/embeddings/local.js +11 -7
  455. package/dist/embeddings/provider.d.ts +19 -10
  456. package/dist/embeddings/provider.js +32 -27
  457. package/dist/embeddings/transformers.d.ts +16 -4
  458. package/dist/embeddings/transformers.js +32 -15
  459. package/dist/entry/json-hooks.d.ts +1 -1
  460. package/dist/entry/json-hooks.js +1 -1
  461. package/dist/entry/project-identity.js +2 -1
  462. package/dist/entry/session-text.d.ts +1 -1
  463. package/dist/entry/session-text.js +1 -1
  464. package/dist/entry/sqlite-handles.d.ts +10 -0
  465. package/dist/entry/sqlite-handles.js +9 -0
  466. package/dist/entry/store-kit.d.ts +50 -0
  467. package/dist/entry/store-kit.js +27 -0
  468. package/dist/entry/testing.d.ts +6 -0
  469. package/dist/entry/testing.js +7 -0
  470. package/dist/eval/eval-stats.d.ts +27 -8
  471. package/dist/eval/eval-stats.js +17 -5
  472. package/dist/eval/eval-suite.d.ts +3 -1
  473. package/dist/eval/eval-suite.js +409 -187
  474. package/dist/eval/eval.d.ts +8 -2
  475. package/dist/eval/eval.js +8 -2
  476. package/dist/eval/judgment.js +17 -7
  477. package/dist/graph/delta.d.ts +9 -42
  478. package/dist/graph/delta.js +17 -11
  479. package/dist/graph/extract.d.ts +10 -7
  480. package/dist/graph/extract.js +57 -25
  481. package/dist/graph/recall.d.ts +12 -4
  482. package/dist/graph/recall.js +30 -13
  483. package/dist/graph/stream.d.ts +18 -6
  484. package/dist/graph/stream.js +32 -10
  485. package/dist/graph/view.d.ts +19 -6
  486. package/dist/graph/view.js +42 -17
  487. package/dist/hooks/codex-session.js +2 -2
  488. package/dist/hooks/codex-wrapper.d.ts +3 -1
  489. package/dist/hooks/codex-wrapper.js +9 -4
  490. package/dist/hooks/copilot.d.ts +19 -5
  491. package/dist/hooks/copilot.js +54 -15
  492. package/dist/hooks/hook-blocks.d.ts +4 -1
  493. package/dist/hooks/hook-blocks.js +8 -3
  494. package/dist/hooks/json-hooks.d.ts +9 -5
  495. package/dist/hooks/json-hooks.js +72 -33
  496. package/dist/hooks/opencode.js +15 -5
  497. package/dist/hooks/shared.d.ts +27 -8
  498. package/dist/hooks/shared.js +57 -16
  499. package/dist/importers/core.d.ts +12 -4
  500. package/dist/importers/core.js +11 -10
  501. package/dist/importers/markdown-parse.d.ts +15 -5
  502. package/dist/importers/markdown-parse.js +16 -7
  503. package/dist/importers/markdown.js +6 -9
  504. package/dist/importers/sources.js +10 -23
  505. package/dist/importers/vault.d.ts +3 -3
  506. package/dist/importers/vault.js +61 -45
  507. package/dist/index.d.ts +33 -7
  508. package/dist/index.js +26 -8
  509. package/dist/learn/autolearn.d.ts +21 -6
  510. package/dist/learn/autolearn.js +57 -26
  511. package/dist/learn/churn-git.d.ts +4 -1
  512. package/dist/learn/churn-git.js +29 -5
  513. package/dist/learn/extract.d.ts +4 -1
  514. package/dist/learn/extract.js +17 -10
  515. package/dist/learn/forward-claim-detector.d.ts +17 -5
  516. package/dist/learn/forward-claim-detector.js +34 -15
  517. package/dist/learn/invalidation.d.ts +12 -6
  518. package/dist/learn/invalidation.js +62 -28
  519. package/dist/learn/roots.d.ts +3 -0
  520. package/dist/learn/roots.js +5 -0
  521. package/dist/mcp/admin-tools.d.ts +5 -5
  522. package/dist/mcp/admin-tools.js +28 -23
  523. package/dist/mcp/format.d.ts +1 -1
  524. package/dist/mcp/format.js +4 -2
  525. package/dist/mcp/framing.d.ts +3 -1
  526. package/dist/mcp/framing.js +20 -8
  527. package/dist/mcp/memory-tools.d.ts +3 -3
  528. package/dist/mcp/memory-tools.js +21 -20
  529. package/dist/mcp/protocol.d.ts +32 -16
  530. package/dist/mcp/protocol.js +12 -9
  531. package/dist/mcp/recall-tools.d.ts +3 -3
  532. package/dist/mcp/recall-tools.js +62 -74
  533. package/dist/mcp/request.d.ts +7 -5
  534. package/dist/mcp/request.js +61 -77
  535. package/dist/mcp/server.d.ts +3 -1
  536. package/dist/mcp/server.js +8 -3
  537. package/dist/mcp/session-state.d.ts +1 -1
  538. package/dist/mcp/session-state.js +4 -3
  539. package/dist/mcp/shared-gate.d.ts +3 -2
  540. package/dist/mcp/shared-gate.js +3 -2
  541. package/dist/mcp/stdio.d.ts +6 -3
  542. package/dist/mcp/stdio.js +59 -23
  543. package/dist/mcp/tool-args.d.ts +4 -1
  544. package/dist/mcp/tool-args.js +8 -3
  545. package/dist/mcp/tools.js +76 -32
  546. package/dist/objects/customer-notes.d.ts +12 -10
  547. package/dist/objects/customer-notes.js +21 -15
  548. package/dist/objects/decisions.d.ts +18 -10
  549. package/dist/objects/decisions.js +23 -17
  550. package/dist/objects/descriptor.js +2 -1
  551. package/dist/objects/fields.d.ts +4 -1
  552. package/dist/objects/fields.js +6 -2
  553. package/dist/objects/incidents.d.ts +14 -16
  554. package/dist/objects/incidents.js +29 -30
  555. package/dist/objects/lifecycle.d.ts +0 -4
  556. package/dist/objects/lifecycle.js +21 -24
  557. package/dist/objects/policies.d.ts +12 -16
  558. package/dist/objects/policies.js +17 -21
  559. package/dist/objects/processes.d.ts +16 -10
  560. package/dist/objects/processes.js +20 -15
  561. package/dist/objects/project-briefs.d.ts +13 -14
  562. package/dist/objects/project-briefs.js +33 -39
  563. package/dist/objects/skills.d.ts +10 -12
  564. package/dist/objects/skills.js +17 -22
  565. package/dist/postinstall.js +15 -7
  566. package/dist/predictions/planning-fallacy.d.ts +19 -6
  567. package/dist/predictions/planning-fallacy.js +4 -2
  568. package/dist/rerankers/clef.d.ts +8 -2
  569. package/dist/rerankers/clef.js +14 -9
  570. package/dist/rerankers/cross-encoder.d.ts +2 -1
  571. package/dist/rerankers/cross-encoder.js +19 -9
  572. package/dist/rerankers/index.js +2 -1
  573. package/dist/rerankers/jev.js +2 -1
  574. package/dist/rerankers/llm.d.ts +6 -2
  575. package/dist/rerankers/llm.js +8 -3
  576. package/dist/rerankers/remote.d.ts +3 -1
  577. package/dist/rerankers/remote.js +5 -2
  578. package/dist/rerankers/types.d.ts +6 -2
  579. package/dist/search/bm25-search.d.ts +3 -1
  580. package/dist/search/bm25-search.js +15 -2
  581. package/dist/search/boosts.js +4 -3
  582. package/dist/search/embed-memories.d.ts +12 -4
  583. package/dist/search/embed-memories.js +96 -58
  584. package/dist/search/engine.d.ts +11 -0
  585. package/dist/search/engine.js +14 -0
  586. package/dist/search/goal-boost.d.ts +10 -3
  587. package/dist/search/goal-boost.js +13 -6
  588. package/dist/search/hybrid-score.d.ts +4 -1
  589. package/dist/search/hybrid-score.js +4 -1
  590. package/dist/search/hybrid.d.ts +23 -8
  591. package/dist/search/hybrid.js +12 -7
  592. package/dist/search/multihop.js +14 -13
  593. package/dist/search/path-context.d.ts +10 -3
  594. package/dist/search/path-context.js +10 -3
  595. package/dist/search/physics-search.d.ts +9 -4
  596. package/dist/search/physics-search.js +38 -14
  597. package/dist/search/rerank.d.ts +2 -1
  598. package/dist/search/rerank.js +2 -1
  599. package/dist/search/rrf.d.ts +14 -5
  600. package/dist/search/rrf.js +11 -4
  601. package/dist/search/vector.d.ts +8 -2
  602. package/dist/search/vector.js +14 -8
  603. package/dist/server/auth.d.ts +19 -15
  604. package/dist/server/auth.js +68 -38
  605. package/dist/server/boot.d.ts +4 -1
  606. package/dist/server/boot.js +115 -67
  607. package/dist/server/client-ip.d.ts +17 -5
  608. package/dist/server/client-ip.js +56 -21
  609. package/dist/server/cursor.d.ts +10 -3
  610. package/dist/server/cursor.js +10 -3
  611. package/dist/server/deadline.d.ts +5 -2
  612. package/dist/server/deadline.js +10 -3
  613. package/dist/server/key-check-bounds.js +12 -4
  614. package/dist/server/lifecycle.d.ts +4 -1
  615. package/dist/server/lifecycle.js +10 -4
  616. package/dist/server/mcp-http.d.ts +2 -1
  617. package/dist/server/mcp-http.js +37 -22
  618. package/dist/server/rate-limit.d.ts +17 -5
  619. package/dist/server/rate-limit.js +55 -26
  620. package/dist/server/ready.js +7 -4
  621. package/dist/server/request.d.ts +15 -4
  622. package/dist/server/request.js +42 -15
  623. package/dist/server/route-checks.d.ts +4 -1
  624. package/dist/server/route-checks.js +8 -3
  625. package/dist/server/route-table.d.ts +8 -6
  626. package/dist/server/route-table.js +550 -97
  627. package/dist/server/routes/admin.d.ts +7 -7
  628. package/dist/server/routes/admin.js +36 -15
  629. package/dist/server/routes/customer-notes.d.ts +5 -5
  630. package/dist/server/routes/customer-notes.js +5 -4
  631. package/dist/server/routes/decisions.d.ts +5 -5
  632. package/dist/server/routes/decisions.js +12 -6
  633. package/dist/server/routes/incidents.d.ts +5 -5
  634. package/dist/server/routes/incidents.js +10 -4
  635. package/dist/server/routes/memories.d.ts +8 -8
  636. package/dist/server/routes/memories.js +12 -17
  637. package/dist/server/routes/object-routes.d.ts +8 -5
  638. package/dist/server/routes/object-routes.js +4 -2
  639. package/dist/server/routes/policies.d.ts +6 -6
  640. package/dist/server/routes/policies.js +11 -4
  641. package/dist/server/routes/predictions.d.ts +5 -5
  642. package/dist/server/routes/predictions.js +9 -4
  643. package/dist/server/routes/processes.d.ts +5 -5
  644. package/dist/server/routes/processes.js +15 -6
  645. package/dist/server/routes/project-briefs.d.ts +6 -6
  646. package/dist/server/routes/project-briefs.js +3 -2
  647. package/dist/server/routes/recall.d.ts +3 -3
  648. package/dist/server/routes/recall.js +21 -10
  649. package/dist/server/routes/skills.d.ts +6 -6
  650. package/dist/server/routes/skills.js +12 -4
  651. package/dist/server/server-detect.d.ts +24 -8
  652. package/dist/server/server-detect.js +57 -22
  653. package/dist/server/sleep-child.js +16 -10
  654. package/dist/server/sleep-offload.d.ts +8 -5
  655. package/dist/server/sleep-offload.js +40 -18
  656. package/dist/server/tls.d.ts +10 -2
  657. package/dist/server/tls.js +25 -5
  658. package/dist/server/types.d.ts +41 -24
  659. package/dist/server/validation.d.ts +4 -1
  660. package/dist/server/validation.js +22 -9
  661. package/dist/server.d.ts +17 -49
  662. package/dist/server.js +33 -40
  663. package/dist/sharing/global-store.d.ts +6 -12
  664. package/dist/sharing/global-store.js +8 -48
  665. package/dist/sharing/global-sync.d.ts +3 -1
  666. package/dist/sharing/global-sync.js +17 -7
  667. package/dist/sharing/project-merge.d.ts +25 -7
  668. package/dist/sharing/project-merge.js +49 -17
  669. package/dist/sharing/search-both.d.ts +8 -4
  670. package/dist/sharing/search-both.js +28 -14
  671. package/dist/sharing/share.d.ts +8 -4
  672. package/dist/sharing/share.js +40 -18
  673. package/dist/store/ambient.js +10 -5
  674. package/dist/store/audit-event.d.ts +2 -2
  675. package/dist/store/audit-event.js +8 -3
  676. package/dist/store/audit.d.ts +6 -3
  677. package/dist/store/audit.js +16 -6
  678. package/dist/store/auth.d.ts +4 -2
  679. package/dist/store/auth.js +63 -20
  680. package/dist/store/busy.d.ts +9 -0
  681. package/dist/store/busy.js +16 -0
  682. package/dist/store/candidates.d.ts +12 -5
  683. package/dist/store/candidates.js +90 -41
  684. package/dist/store/capture-write.d.ts +2 -1
  685. package/dist/store/capture-write.js +2 -1
  686. package/dist/store/card-detail.d.ts +4 -4
  687. package/dist/store/card-detail.js +15 -8
  688. package/dist/store/cards.d.ts +24 -10
  689. package/dist/store/cards.js +97 -63
  690. package/dist/store/compaction-caller.d.ts +2 -1
  691. package/dist/store/compaction-caller.js +2 -1
  692. package/dist/store/compactions-record.d.ts +14 -8
  693. package/dist/store/compactions-record.js +101 -37
  694. package/dist/store/compactions.js +35 -15
  695. package/dist/store/conflicts.d.ts +16 -5
  696. package/dist/store/conflicts.js +104 -48
  697. package/dist/store/connectors/dlq.d.ts +17 -5
  698. package/dist/store/connectors/dlq.js +58 -6
  699. package/dist/store/connectors/event-log.d.ts +122 -0
  700. package/dist/store/connectors/event-log.js +25 -0
  701. package/dist/store/connectors/github.d.ts +6 -3
  702. package/dist/store/connectors/github.js +30 -48
  703. package/dist/store/connectors/slack.d.ts +2 -1
  704. package/dist/store/connectors/slack.js +31 -47
  705. package/dist/store/dashboard-reads.d.ts +7 -3
  706. package/dist/store/dashboard-reads.js +32 -10
  707. package/dist/store/delete-and-batch.d.ts +17 -11
  708. package/dist/store/delete-and-batch.js +70 -28
  709. package/dist/store/delivery-recorder.d.ts +10 -7
  710. package/dist/store/delivery-recorder.js +70 -37
  711. package/dist/store/descendant-page.d.ts +2 -1
  712. package/dist/store/descendant-page.js +26 -10
  713. package/dist/store/diagnostics.d.ts +2 -1
  714. package/dist/store/diagnostics.js +2 -1
  715. package/dist/store/doctor-reads.d.ts +2 -1
  716. package/dist/store/doctor-reads.js +13 -5
  717. package/dist/store/dormant.d.ts +19 -11
  718. package/dist/store/dormant.js +45 -19
  719. package/dist/store/embeddings/index.d.ts +13 -9
  720. package/dist/store/embeddings/index.js +19 -12
  721. package/dist/store/entry-reads.d.ts +72 -21
  722. package/dist/store/entry-reads.js +215 -69
  723. package/dist/store/entry-row.d.ts +10 -6
  724. package/dist/store/entry-row.js +26 -14
  725. package/dist/store/entry-writes.d.ts +28 -13
  726. package/dist/store/entry-writes.js +61 -22
  727. package/dist/store/failure-log-at.js +1 -1
  728. package/dist/store/failure-log.d.ts +4 -2
  729. package/dist/store/failure-log.js +13 -6
  730. package/dist/store/gated-write.d.ts +3 -3
  731. package/dist/store/gated-write.js +3 -3
  732. package/dist/store/goals.d.ts +5 -4
  733. package/dist/store/goals.js +11 -12
  734. package/dist/store/graph-apply.d.ts +21 -0
  735. package/dist/{graph/write.js → store/graph-apply.js} +31 -11
  736. package/dist/store/graph-queue.d.ts +9 -6
  737. package/dist/store/graph-queue.js +15 -10
  738. package/dist/store/graph-reads.d.ts +16 -11
  739. package/dist/store/graph-reads.js +29 -19
  740. package/dist/store/graph-rows.d.ts +41 -3
  741. package/dist/store/graph-rows.js +10 -7
  742. package/dist/store/graph-view-rows.js +15 -7
  743. package/dist/store/graph-writes.d.ts +16 -10
  744. package/dist/store/graph-writes.js +59 -36
  745. package/dist/store/half-life.js +2 -2
  746. package/dist/store/handoffs.d.ts +13 -7
  747. package/dist/store/handoffs.js +44 -22
  748. package/dist/store/index-and-stats.d.ts +2 -2
  749. package/dist/store/index-and-stats.js +6 -5
  750. package/dist/store/index.d.ts +4 -2
  751. package/dist/store/index.js +2 -1
  752. package/dist/store/key-audit.d.ts +2 -1
  753. package/dist/store/key-audit.js +2 -1
  754. package/dist/store/key-writes.d.ts +2 -1
  755. package/dist/store/key-writes.js +9 -2
  756. package/dist/store/ledger-turn.d.ts +4 -1
  757. package/dist/store/ledger-turn.js +7 -2
  758. package/dist/store/mirrors.d.ts +11 -4
  759. package/dist/store/mirrors.js +96 -19
  760. package/dist/store/narrow.d.ts +6 -0
  761. package/dist/store/narrow.js +11 -0
  762. package/dist/store/open.d.ts +6 -3
  763. package/dist/store/open.js +20 -10
  764. package/dist/store/pilot-arm.d.ts +2 -1
  765. package/dist/store/pilot-arm.js +18 -6
  766. package/dist/store/planning-fallacy-evidence.d.ts +2 -2
  767. package/dist/store/planning-fallacy-evidence.js +8 -5
  768. package/dist/store/port/agent-import.d.ts +62 -0
  769. package/dist/store/port/agent-import.js +2 -0
  770. package/dist/store/port/consolidation.d.ts +129 -0
  771. package/dist/store/port/consolidation.js +2 -0
  772. package/dist/store/port/learning.d.ts +19 -0
  773. package/dist/store/port/learning.js +2 -0
  774. package/dist/store/port/local-files.d.ts +18 -0
  775. package/dist/store/port/local-files.js +2 -0
  776. package/dist/store/port/promotion.d.ts +20 -0
  777. package/dist/store/port/promotion.js +3 -0
  778. package/dist/store/port-groups.d.ts +160 -0
  779. package/dist/store/port-groups.js +2 -0
  780. package/dist/store/port.d.ts +261 -219
  781. package/dist/store/port.js +3 -9
  782. package/dist/store/predictions.d.ts +14 -10
  783. package/dist/store/predictions.js +37 -17
  784. package/dist/store/project-tags.d.ts +4 -1
  785. package/dist/store/project-tags.js +16 -5
  786. package/dist/store/quality-repair.d.ts +8 -4
  787. package/dist/store/quality-repair.js +53 -20
  788. package/dist/store/quarantine.d.ts +1 -0
  789. package/dist/store/quarantine.js +23 -9
  790. package/dist/store/raw-archive.d.ts +5 -4
  791. package/dist/store/raw-archive.js +11 -10
  792. package/dist/store/recall-trace.d.ts +22 -17
  793. package/dist/store/recall-trace.js +128 -64
  794. package/dist/store/rejected-values.d.ts +15 -10
  795. package/dist/store/rejected-values.js +46 -20
  796. package/dist/store/rejection.d.ts +12 -11
  797. package/dist/store/rejection.js +18 -19
  798. package/dist/store/report-reads.d.ts +2 -1
  799. package/dist/store/report-reads.js +2 -1
  800. package/dist/store/rows.d.ts +7 -5
  801. package/dist/store/rows.js +20 -13
  802. package/dist/store/rule-sql.d.ts +7 -3
  803. package/dist/store/rule-sql.js +26 -13
  804. package/dist/store/search-rows.d.ts +16 -11
  805. package/dist/store/search-rows.js +54 -32
  806. package/dist/store/sessions.d.ts +12 -10
  807. package/dist/store/sessions.js +40 -21
  808. package/dist/store/set-aside.d.ts +2 -2
  809. package/dist/store/set-aside.js +18 -5
  810. package/dist/store/sqlite/agent-import.d.ts +3 -0
  811. package/dist/store/sqlite/agent-import.js +77 -0
  812. package/dist/store/sqlite/cards-group.d.ts +6 -0
  813. package/dist/store/sqlite/cards-group.js +37 -0
  814. package/dist/store/sqlite/conflicts-group.d.ts +6 -0
  815. package/dist/store/sqlite/conflicts-group.js +18 -0
  816. package/dist/store/sqlite/connector-events-group.d.ts +2 -1
  817. package/dist/store/sqlite/connector-events-group.js +17 -6
  818. package/dist/store/sqlite/connector-writes-group.d.ts +2 -1
  819. package/dist/store/sqlite/connector-writes-group.js +12 -5
  820. package/dist/store/sqlite/consolidation-group.d.ts +4 -0
  821. package/dist/store/sqlite/consolidation-group.js +64 -0
  822. package/dist/store/sqlite/dag-reads-group.js +1 -1
  823. package/dist/store/sqlite/dormant-group.d.ts +6 -0
  824. package/dist/store/sqlite/dormant-group.js +29 -0
  825. package/dist/store/sqlite/entry-writes-group.d.ts +9 -6
  826. package/dist/store/sqlite/entry-writes-group.js +37 -14
  827. package/dist/store/sqlite/error-codec.d.ts +4 -2
  828. package/dist/store/sqlite/error-codec.js +32 -10
  829. package/dist/store/sqlite/executor-counts.js +2 -1
  830. package/dist/store/sqlite/executor.d.ts +8 -3
  831. package/dist/store/sqlite/executor.js +56 -18
  832. package/dist/store/sqlite/global-promote.d.ts +5 -0
  833. package/dist/store/sqlite/global-promote.js +48 -0
  834. package/dist/store/sqlite/goals-group.d.ts +6 -0
  835. package/dist/store/sqlite/goals-group.js +23 -0
  836. package/dist/store/sqlite/graph-reads-group.d.ts +2 -1
  837. package/dist/store/sqlite/graph-reads-group.js +2 -1
  838. package/dist/store/sqlite/held-connection.d.ts +8 -0
  839. package/dist/store/sqlite/held-connection.js +34 -7
  840. package/dist/store/sqlite/last-recall-group.d.ts +15 -0
  841. package/dist/store/sqlite/last-recall-group.js +62 -0
  842. package/dist/store/sqlite/learning-group.d.ts +4 -0
  843. package/dist/store/sqlite/learning-group.js +17 -0
  844. package/dist/store/sqlite/maintenance-groups.d.ts +6 -0
  845. package/dist/store/sqlite/maintenance-groups.js +61 -0
  846. package/dist/store/sqlite/object-rows.d.ts +6 -3
  847. package/dist/store/sqlite/object-rows.js +34 -5
  848. package/dist/store/sqlite/objects-group.d.ts +5 -4
  849. package/dist/store/sqlite/objects-group.js +97 -38
  850. package/dist/store/sqlite/predictions-group.d.ts +2 -1
  851. package/dist/store/sqlite/predictions-group.js +4 -2
  852. package/dist/store/sqlite/promotion-group.d.ts +3 -0
  853. package/dist/store/sqlite/promotion-group.js +10 -0
  854. package/dist/store/sqlite/quarantine-group.d.ts +2 -1
  855. package/dist/store/sqlite/quarantine-group.js +4 -2
  856. package/dist/store/sqlite/reports-group.d.ts +6 -0
  857. package/dist/store/sqlite/reports-group.js +33 -0
  858. package/dist/store/sqlite/request-scope.d.ts +6 -0
  859. package/dist/store/sqlite/request-scope.js +18 -0
  860. package/dist/store/sqlite/sessions-group.d.ts +6 -0
  861. package/dist/store/sqlite/sessions-group.js +46 -0
  862. package/dist/store/sqlite/store.d.ts +22 -18
  863. package/dist/store/sqlite/store.js +95 -33
  864. package/dist/store/sqlite/vector-pack.js +2 -1
  865. package/dist/store/sqlite/vector-reads-group.js +2 -1
  866. package/dist/store/sqlite/worker-jobs.d.ts +2 -1
  867. package/dist/store/sqlite/worker-jobs.js +19 -7
  868. package/dist/store/sqlite/worker-ops.d.ts +10 -5
  869. package/dist/store/sqlite/worker-ops.js +6 -3
  870. package/dist/store/sqlite/worker-store.d.ts +4 -3
  871. package/dist/store/sqlite/worker-store.js +24 -14
  872. package/dist/store/summaries.d.ts +25 -11
  873. package/dist/store/summaries.js +84 -27
  874. package/dist/store/summary-dirty.d.ts +2 -1
  875. package/dist/store/summary-dirty.js +2 -1
  876. package/dist/store/tenant.d.ts +3 -2
  877. package/dist/store/tenant.js +5 -4
  878. package/dist/store/token-ledger-rows.js +8 -4
  879. package/dist/store/token-ledger.d.ts +19 -13
  880. package/dist/store/token-ledger.js +27 -14
  881. package/dist/store/tombstone-checks.d.ts +4 -1
  882. package/dist/store/tombstone-checks.js +10 -1
  883. package/dist/store/usage-reports.js +2 -1
  884. package/dist/store/vector-index.d.ts +8 -5
  885. package/dist/store/vector-index.js +28 -11
  886. package/dist/store/working-memory.d.ts +6 -4
  887. package/dist/store/working-memory.js +14 -9
  888. package/dist/support-bundle.js +10 -5
  889. package/dist/trust/quarantine.d.ts +1 -2
  890. package/dist/trust/quarantine.js +1 -5
  891. package/dist/trust/reject-flow.d.ts +12 -3
  892. package/dist/trust/reject-flow.js +12 -4
  893. package/dist/util/anthropic-messages.d.ts +7 -2
  894. package/dist/util/anthropic-messages.js +18 -7
  895. package/dist/util/atomic-write.d.ts +8 -3
  896. package/dist/util/atomic-write.js +36 -21
  897. package/dist/util/compaction-items.d.ts +4 -1
  898. package/dist/util/compaction-items.js +8 -2
  899. package/dist/util/crash-handlers.d.ts +7 -2
  900. package/dist/util/crash-handlers.js +13 -4
  901. package/dist/util/env.d.ts +26 -5
  902. package/dist/util/env.js +87 -25
  903. package/dist/util/format.d.ts +2 -0
  904. package/dist/util/format.js +4 -0
  905. package/dist/util/home-path.js +12 -6
  906. package/dist/util/hook-payload.d.ts +3 -1
  907. package/dist/util/hook-payload.js +3 -1
  908. package/dist/util/http-retry.d.ts +12 -6
  909. package/dist/util/http-retry.js +16 -6
  910. package/dist/util/http-util.d.ts +20 -5
  911. package/dist/util/http-util.js +28 -9
  912. package/dist/util/json.d.ts +4 -1
  913. package/dist/util/json.js +4 -1
  914. package/dist/util/keyset.js +2 -1
  915. package/dist/util/limits.js +4 -2
  916. package/dist/util/log.d.ts +13 -5
  917. package/dist/util/log.js +29 -6
  918. package/dist/util/net.d.ts +5 -0
  919. package/dist/util/net.js +19 -0
  920. package/dist/util/real-path.d.ts +2 -1
  921. package/dist/util/real-path.js +4 -3
  922. package/dist/util/request-scope.d.ts +16 -4
  923. package/dist/util/request-scope.js +19 -6
  924. package/dist/util/same-text.d.ts +10 -3
  925. package/dist/util/same-text.js +10 -3
  926. package/dist/util/secret-detect.d.ts +24 -7
  927. package/dist/util/secret-detect.js +49 -14
  928. package/dist/util/spawn-argv.d.ts +11 -0
  929. package/dist/util/spawn-argv.js +66 -0
  930. package/dist/util/sql.d.ts +3 -0
  931. package/dist/util/sql.js +6 -0
  932. package/dist/util/sqlite-blocked.d.ts +15 -4
  933. package/dist/util/sqlite-blocked.js +19 -6
  934. package/dist/util/stored-json.d.ts +4 -1
  935. package/dist/util/stored-json.js +6 -2
  936. package/dist/util/stream-tee.d.ts +2 -1
  937. package/dist/util/stream-tee.js +8 -5
  938. package/dist/util/transcript-tail.d.ts +4 -1
  939. package/dist/util/transcript-tail.js +4 -1
  940. package/dist/util/vector-codec.d.ts +4 -0
  941. package/dist/util/vector-codec.js +15 -0
  942. package/dist/util/version.d.ts +8 -3
  943. package/dist/util/version.js +8 -3
  944. package/dist/util/write-budget.d.ts +7 -2
  945. package/dist/util/write-budget.js +5 -2
  946. package/dist/util/yaml.d.ts +4 -1
  947. package/dist/util/yaml.js +4 -1
  948. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  949. package/extensions/openclaw-plugin/package.json +1 -1
  950. package/openclaw.plugin.json +1 -1
  951. package/package.json +4 -1
  952. package/scripts/postinstall.cjs +3 -1
  953. package/dist/api/audit.js +0 -56
  954. package/dist/api/cards.d.ts +0 -42
  955. package/dist/api/conflicts.d.ts +0 -28
  956. package/dist/api/conflicts.js +0 -61
  957. package/dist/api/dormant.d.ts +0 -14
  958. package/dist/api/dormant.js +0 -58
  959. package/dist/api/goals.d.ts +0 -18
  960. package/dist/api/graph.d.ts +0 -8
  961. package/dist/api/graph.js +0 -7
  962. package/dist/api/learn.js +0 -124
  963. package/dist/api/memories.d.ts +0 -23
  964. package/dist/api/memories.js +0 -46
  965. package/dist/api/objects.d.ts +0 -9
  966. package/dist/api/on-store.d.ts +0 -16
  967. package/dist/api/on-store.js +0 -38
  968. package/dist/api/outcome.d.ts +0 -19
  969. package/dist/api/outcome.js +0 -21
  970. package/dist/api/predictions.d.ts +0 -11
  971. package/dist/api/promote.d.ts +0 -36
  972. package/dist/api/promote.js +0 -65
  973. package/dist/api/recall-core.d.ts +0 -4
  974. package/dist/api/recall-core.js +0 -120
  975. package/dist/api/recall-finish.d.ts +0 -53
  976. package/dist/api/recall-finish.js +0 -30
  977. package/dist/api/recall-history.d.ts +0 -64
  978. package/dist/api/recall-history.js +0 -159
  979. package/dist/api/recall-record.d.ts +0 -43
  980. package/dist/api/recall-record.js +0 -78
  981. package/dist/api/recall-request.js +0 -121
  982. package/dist/api/recall.d.ts +0 -6
  983. package/dist/api/refine.d.ts +0 -7
  984. package/dist/api/refine.js +0 -10
  985. package/dist/api/session-owners.d.ts +0 -4
  986. package/dist/api/session-owners.js +0 -17
  987. package/dist/api/sleep-run.d.ts +0 -26
  988. package/dist/api/sleep.js +0 -10
  989. package/dist/cli/lenient-id.d.ts +0 -2
  990. package/dist/cli/lenient-id.js +0 -13
  991. package/dist/graph/write.d.ts +0 -14
  992. package/dist/store/sqlite/busy.d.ts +0 -3
  993. package/dist/store/sqlite/busy.js +0 -8
  994. package/dist/store/sqlite/local.d.ts +0 -21
  995. package/dist/store/sqlite/local.js +0 -39
@@ -1,6 +1,8 @@
1
1
  // Bearer and loopback auth for the HTTP server.
2
- import { envAllowKeylessLocal, envRequireAuth } from '../util/env.js';
2
+ import { envAllowKeylessLocal, envKeylessLocalRole, envRequireAuth } from '../util/env.js';
3
+ import { loadConfig } from '../core/config.js';
3
4
  import { resolveTenantId } from '../store/tenant.js';
5
+ import { sqliteReach } from '../store/sqlite/store.js';
4
6
  import { errorFields, errorMessage, log } from '../util/log.js';
5
7
  import { API_KEY_PREFIX, verifyApiKeyCached } from '../store/auth.js';
6
8
  import { ownerOrSubject } from '../api/index.js';
@@ -9,38 +11,40 @@ import { MAX_ID_LEN } from '../util/limits.js';
9
11
  import { clientLimitKey } from './client-ip.js';
10
12
  import { keyCheckBounds } from './key-check-bounds.js';
11
13
  import { isJsonString } from '../util/json.js';
12
- /** Recognises loopback remote addresses, including the IPv6-mapped '::ffff:127.0.0.1' Node reports on dual-stack sockets; anything else is remote. */
13
- export function isLoopback(remoteAddress) {
14
- if (!remoteAddress)
15
- return false;
16
- if (remoteAddress === '127.0.0.1')
17
- return true;
18
- if (remoteAddress === '::1')
19
- return true;
20
- if (remoteAddress === '::ffff:127.0.0.1')
21
- return true;
22
- return false;
23
- }
24
- // A proxy on this host (nginx, Caddy, cloudflared) connects from loopback, so these headers mean the caller is not local.
14
+ import { MINUTE_MS } from '../util/time.js';
15
+ import { isLoopbackAddress } from '../util/net.js';
16
+ /** Kept under its old name because src/server.ts publishes it. */
17
+ export const isLoopback = isLoopbackAddress;
18
+ // A proxy on this host (nginx, Caddy, cloudflared) connects
19
+ // from loopback, so these headers mean the caller is not local.
25
20
  const PROXY_HEADERS = [
26
- 'forwarded', 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-real-ip', 'cf-connecting-ip', 'true-client-ip',
21
+ 'forwarded',
22
+ 'x-forwarded-for',
23
+ 'x-forwarded-host',
24
+ 'x-forwarded-proto',
25
+ 'x-real-ip',
26
+ 'cf-connecting-ip',
27
+ 'true-client-ip',
27
28
  'fly-client-ip',
28
29
  ];
29
30
  function proxyHeaderOf(req) {
30
31
  return PROXY_HEADERS.find((name) => req.headers[name] !== undefined);
31
32
  }
32
- /** A page in a browser on this machine: another site's request, or a hostile name resolved to loopback (DNS rebinding). */
33
+ /** A page in a browser on this machine: another site's request,
34
+ * or a hostile name resolved to loopback (DNS rebinding). */
33
35
  function isForeignPage(req) {
34
36
  const host = req.headers.host;
35
37
  return (host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req);
36
38
  }
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. */
39
+ /** True only for a request made on this machine by its own user: a proxy and a browser page are loopback too, so the
40
+ * socket alone proves nothing. */
38
41
  export function isLocalCaller(req) {
39
- return isLoopback(req.socket.remoteAddress) && proxyHeaderOf(req) === undefined && !isForeignPage(req);
42
+ return isLoopbackAddress(req.socket.remoteAddress) && proxyHeaderOf(req) === undefined && !isForeignPage(req);
40
43
  }
41
- // The throwing twin of isLocalCaller, for the no-key fallback: each refusal has its own status, and a proxied one is logged.
44
+ // The throwing twin of isLocalCaller, for the no-key fallback:
45
+ // each refusal has its own status, and a proxied one is logged.
42
46
  function assertLocalCaller(req) {
43
- if (!isLoopback(req.socket.remoteAddress))
47
+ if (!isLoopbackAddress(req.socket.remoteAddress))
44
48
  throw new HttpError(401, 'auth required');
45
49
  const proxyHeader = proxyHeaderOf(req);
46
50
  if (proxyHeader !== undefined) {
@@ -52,10 +56,11 @@ function assertLocalCaller(req) {
52
56
  throw new HttpError(403, 'cross-site or non-local request refused; send an API key');
53
57
  }
54
58
  }
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. */
59
+ /** The 401 a keyless request from this machine gets by default; it names both fixes, since an upgrade is where most
60
+ * people meet it. */
56
61
  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.';
62
+ '"Authorization: Bearer <key>" (the hippo CLI reads HIPPO_API_KEY), or start the server with ' +
63
+ 'HIPPO_ALLOW_KEYLESS_LOCAL=1 to let requests from this machine in without a key.';
59
64
  export function readAuthHeader(req) {
60
65
  const raw = req.headers['authorization'];
61
66
  if (raw === undefined)
@@ -149,7 +154,8 @@ async function askResolver(resolver, token, deadlineMs) {
149
154
  return clean;
150
155
  }
151
156
  const DEFAULT_RESOLVER_DEADLINE_MS = 5000;
152
- /** Runs only before scrypt, so junk, unknown, revoked and expired tokens and a proven key's re-check never spend a colleague's budget. */
157
+ /** Runs only before scrypt, so junk, unknown, revoked and expired
158
+ * tokens and a proven key's re-check never spend a colleague's budget. */
153
159
  function chargeScryptRun(req, opts) {
154
160
  const limiter = opts.failedAuthLimiter;
155
161
  // Reserving rather than peeking bounds scrypt runs exactly, even when concurrent misses await a slow store.
@@ -164,17 +170,24 @@ async function resolveBearer(req, token, opts) {
164
170
  const t = opts.authResolverTimeoutMs;
165
171
  const deadlineMs = t !== undefined && Number.isFinite(t) && t > 0 ? t : DEFAULT_RESOLVER_DEADLINE_MS;
166
172
  const clean = await askResolver(opts.authResolver, token, deadlineMs);
167
- return { ...clean, viaAuthResolver: true, owner: clean.subject }; // a resolver vouches for a person, never names one
173
+ // A resolver vouches for a person, never names one.
174
+ return { ...clean, viaAuthResolver: true, owner: clean.subject };
168
175
  }
169
176
  const key = await verifyApiKeyCached(token, opts.store, (keyId, derive) => {
170
- // The key's own bucket first, so a flood on one key id ends at its five tries and leaves the address's budget to the callers who share it.
177
+ // The key's own bucket first, so a flood on one key id ends at its five tries and leaves the address's budget to
178
+ // the callers who share it.
171
179
  keyChecks.admit(keyId, clientLimitKey(req));
172
180
  chargeScryptRun(req, opts);
173
181
  return keyChecks.run(derive);
174
182
  });
175
183
  if (!key)
176
184
  throw new HttpError(401, 'invalid api key');
177
- const id = { tenantId: key.tenantId, subject: `api_key:${key.keyId}`, role: key.role, scopes: key.scopes };
185
+ const id = {
186
+ tenantId: key.tenantId,
187
+ subject: `api_key:${key.keyId}`,
188
+ role: key.role,
189
+ scopes: key.scopes,
190
+ };
178
191
  if (key.ownerSubject)
179
192
  id.owner = key.ownerSubject;
180
193
  return id;
@@ -213,7 +226,7 @@ function bearerActor(id) {
213
226
  export const LIMITER_MAX_KEYS = 10_000;
214
227
  // One for the process, as the thread pool its derivations run on is.
215
228
  const keyChecks = keyCheckBounds(LIMITER_MAX_KEYS);
216
- const CALLER_WARN_EVERY_MS = 60_000;
229
+ const CALLER_WARN_EVERY_MS = MINUTE_MS;
217
230
  const callerWarnedAt = new Map();
218
231
  function warnCallerLimited(key, tenantId, person) {
219
232
  const now = Date.now();
@@ -240,8 +253,8 @@ function chargeCaller(tenantId, actor, opts) {
240
253
  warnCallerLimited(key, tenantId, person);
241
254
  throw new HttpError(429, 'rate limit exceeded for this caller', limiter.retryAfterSec);
242
255
  }
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. */
256
+ /** Builds a per-request Context from the Authorization header and remote address; throws HttpError(401) on bad ones.
257
+ * Reads the store only for an API-key-shaped Bearer (or any Bearer with no resolver), so keyless calls stay cheap. */
245
258
  export async function buildContextWithAuth(req, opts) {
246
259
  const id = await checkAuth(req, opts);
247
260
  const ctx = contextFor(id, opts);
@@ -249,29 +262,46 @@ export async function buildContextWithAuth(req, opts) {
249
262
  chargeCaller(id.tenantId, ctx.actor, opts);
250
263
  return ctx;
251
264
  }
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. */
265
+ /** The auth check again, uncharged, for a handler that authenticated with requireAuth before a slow body read and
266
+ * must re-check right before it acts. */
253
267
  export async function recheckContextWithAuth(req, opts) {
254
268
  return contextFor(await checkAuth(req, opts), opts);
255
269
  }
270
+ /** The keyless local caller: any process on this machine can reach
271
+ * loopback, so it is a member unless the operator names admin. */
272
+ function keylessLocalActor(opts) {
273
+ const role = opts.keylessLocalRole ?? envKeylessLocalRole();
274
+ return role === 'admin'
275
+ ? { subject: 'localhost:cli', role: 'admin', hostAdmin: true }
276
+ : { subject: 'localhost:cli', role: 'member' };
277
+ }
256
278
  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.
279
+ // Per request, never cached at serve: the global store can be created while the server runs.
280
+ const reach = sqliteReach(opts.hippoRoot, opts.store);
281
+ // loadConfig caches by file mtime, so each request still sees an edit made while the server runs.
282
+ const config = loadConfig(opts.hippoRoot);
283
+ if (id !== null) {
284
+ const actor = bearerActor(id);
285
+ return { hippoRoot: opts.hippoRoot, tenantId: id.tenantId, actor, store: opts.store, reach, config };
286
+ }
260
287
  return {
261
288
  hippoRoot: opts.hippoRoot,
262
289
  tenantId: resolveTenantId({}),
263
- actor: { subject: 'localhost:cli', role: 'admin', hostAdmin: true },
290
+ actor: keylessLocalActor(opts),
264
291
  store: opts.store,
292
+ reach,
293
+ config,
265
294
  };
266
295
  }
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. */
296
+ /** Auth check for routes that need no tenant Context (e.g. the MCP transport, which resolves its own root): throws
297
+ * HttpError 401 like buildContextWithAuth. A keyless local request passes only under HIPPO_ALLOW_KEYLESS_LOCAL=1. */
269
298
  export async function requireAuth(req, opts) {
270
299
  const id = await checkAuth(req, opts);
271
300
  if (id !== null)
272
301
  chargeCaller(id.tenantId, bearerActor(id), opts);
273
302
  }
274
- /** Never rejects or charges a caller bucket: an outage (5xx) or a throttle (429) skips one tick; only a definite 4xx denial closes the stream. */
303
+ /** Never rejects or charges a caller bucket: an outage (5xx) or a throttle (429) skips one tick; only a definite 4xx
304
+ * denial closes the stream. */
275
305
  export async function heartbeatVerdict(req, opts) {
276
306
  try {
277
307
  await checkAuth(req, opts);
@@ -1,5 +1,8 @@
1
1
  import type { ServeOpts, ServerHandle } from './types.js';
2
- /** Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses non-loopback hosts unless HIPPO_REQUIRE_AUTH=1.
2
+ /**
3
+ * Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses a non-loopback host unless
4
+ * HIPPO_REQUIRE_AUTH=1 and
5
+ * either `tls` or allowCleartext is given, and refuses HIPPO_CLIENT_IP_HEADER without HIPPO_TRUSTED_PROXIES.
3
6
  * Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
4
7
  export declare function serve(opts: ServeOpts): Promise<ServerHandle>;
5
8
  //# sourceMappingURL=boot.d.ts.map
@@ -1,20 +1,21 @@
1
- import { envPort, envRequireAuth, envV1Rps } from '../util/env.js';
1
+ import { envAllowCleartext, envCallerRps, envPort, envRequireAuth, envV1Rps } from '../util/env.js';
2
2
  import { detectServer, removePidfileIfOwned, writePidfile } from './server-detect.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';
3
+ import { hasGroup } from '../store/index.js';
4
+ import { isStoreBusy } from '../api/busy.js';
5
+ import { createStoreHolder, offLoopFor, outsideRouteBlock, } from '../store/sqlite/held-connection.js';
6
6
  import { workerSqliteStore } from '../store/sqlite/worker-store.js';
7
7
  import { markSharedStore } from '../core/config.js';
8
8
  import { auditWriteFailureCount } from '../store/audit.js';
9
9
  import { PACKAGE_VERSION } from '../util/version.js';
10
+ import { MINUTE_MS } from '../util/time.js';
10
11
  import { errorFields, errorMessage, log } from '../util/log.js';
11
12
  import { runWithRequestId } from '../util/request-scope.js';
12
13
  import { createRateLimiter } from './rate-limit.js';
13
14
  import { RecallContractError } from '../api/index.js';
14
- import { BodyTimeoutError, BodyTooLargeError, closeAfterReply, DeadlineExceededError, HttpError, JSON_HEADERS, sendJson } from '../util/http-util.js';
15
+ import { BodyTimeoutError, BodyTooLargeError, closeAfterReply, DeadlineExceededError, HttpError, JSON_HEADERS, sendJson, } from '../util/http-util.js';
15
16
  import { workerCounts } from '../store/sqlite/executor-counts.js';
16
17
  import { isLocalCaller, LIMITER_MAX_KEYS } from './auth.js';
17
- import { enforceRateLimit, warnIfClientIpHeaderUnpinned } from './client-ip.js';
18
+ import { assertClientIpHeaderPinned, enforceRateLimit } from './client-ip.js';
18
19
  import { answerAtDeadline, handlerDeadlineCount, isAbandoned, requestDeadlineFor } from './deadline.js';
19
20
  import { DEFAULT_SHUTDOWN_DRAIN_MS, drainAndClose, setKeepAliveTimeouts, shutdownBoundMs } from './lifecycle.js';
20
21
  import { readyProbeFor } from './ready.js';
@@ -22,8 +23,8 @@ import { DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT } from './defaults.js';
22
23
  import { installCrashHandlers, installSignalHandlers } from '../util/crash-handlers.js';
23
24
  import { handleMcpPost, handleMcpStream } from './mcp-http.js';
24
25
  import { MCP_PROJECT_SCOPED_HEADER } from '../core/project-identity.js';
25
- import { accessRouteOf, logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError } from './request.js';
26
- import { createListener, warnIfCleartext } from './tls.js';
26
+ import { accessRouteOf, logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError, } from './request.js';
27
+ import { assertTlsOrCleartextAllowed, createListener } from './tls.js';
27
28
  import { assertAddonRoutes, assertPublicJson } from './route-checks.js';
28
29
  import { dispatchAddonRoute, dispatchPublicJson, dispatchV1Route } from './route-table.js';
29
30
  // server.address() returns AddressInfo once a TCP socket is bound; null before
@@ -31,7 +32,8 @@ import { dispatchAddonRoute, dispatchPublicJson, dispatchV1Route } from './route
31
32
  function isAddressInfo(a) {
32
33
  return a !== null && typeof a !== 'string';
33
34
  }
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
+ // Pinned at module load, bumped with package.json on releases; reading package.json synchronously here would couple the
36
+ // daemon to its install path,
35
37
  // which tests that mkdtemp a hippoRoot avoid.
36
38
  const VERSION = PACKAGE_VERSION;
37
39
  const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
@@ -41,7 +43,8 @@ async function handleRequest(req, res, opts, options) {
41
43
  // Node's URL parser collapses them and they slip past the route table.
42
44
  rejectEncodedSlash(req.url ?? '/');
43
45
  const { method, path, query } = parseRequest(req);
44
- // An older core ignores X-Hippo-Project, so every /mcp reply, a 429 or 401 too, tells the client this one filters by it.
46
+ // An older core ignores X-Hippo-Project, so every /mcp reply, a 429 or 401 too, tells the client this one filters by
47
+ // it.
45
48
  if (path === '/mcp')
46
49
  res.setHeader(MCP_PROJECT_SCOPED_HEADER, '1');
47
50
  if (method === 'GET' && path === '/health') {
@@ -56,19 +59,22 @@ async function handleRequest(req, res, opts, options) {
56
59
  }
57
60
  enforceRateLimit(req, path, limiter);
58
61
  const routeRequest = { req, res, opts, query };
59
- if (await runWithRequestStores(() => dispatchScopedRoute(routeRequest, method, path), { busyWaitMs: SERVER_DB_WAIT_MS }))
62
+ if (await dispatchScopedRoute(routeRequest, method, path))
60
63
  return;
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.
64
+ // The request scope (the server's lock wait) is kept by the heartbeat timer after it closes, so the key check and
65
+ // every heartbeat wait that long. Store-ready: the stream only authenticates, through the port.
63
66
  if (method === 'GET' && path === '/mcp/stream') {
64
67
  noteAccess(req, { route: path });
65
- await runWithRequestStores(() => handleMcpStream(req, res, opts, streamSlots), { busyWaitMs: SERVER_DB_WAIT_MS });
68
+ await handleMcpStream(req, res, opts, streamSlots);
66
69
  return;
67
70
  }
68
71
  res.writeHead(404, JSON_HEADERS);
69
72
  res.end(JSON.stringify({ error: 'not found' }));
70
73
  }
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. */
74
+ /**
75
+ * Every route that runs inside a request scope, so it opens each store once: the /v1 table with the webhooks, public
76
+ * JSON, add-on routes and POST /mcp.
77
+ */
72
78
  async function dispatchScopedRoute(r, method, path) {
73
79
  if (await dispatchV1Route(r, method, path))
74
80
  return true;
@@ -86,8 +92,10 @@ async function dispatchScopedRoute(r, method, path) {
86
92
  return false;
87
93
  }
88
94
  function sendHealth(req, res, startedAt) {
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.
95
+ // A caller on this machine (detectServer's probe reads version and pid) gets the full body; anyone else, even a
96
+ // proxied caller or a browser page on loopback,
97
+ // gets liveness only: the version would fingerprint the build and the pid is noise. Platform health checks only need
98
+ // the 200.
91
99
  if (isLocalCaller(req)) {
92
100
  sendJson(res, 200, {
93
101
  ok: true,
@@ -127,7 +135,8 @@ function assertBindable(host) {
127
135
  }
128
136
  }
129
137
  async function assertNoLiveServer(hippoRoot) {
130
- // Refuse to start if a live hippo server already serves this hippoRoot (detectServer probes the recorded /health and unlinks a stale pidfile):
138
+ // Refuse to start if a live hippo server already serves this hippoRoot (detectServer probes the recorded /health and
139
+ // unlinks a stale pidfile):
131
140
  // a concurrent `hippo serve` would race for the port and clobber the pidfile.
132
141
  const existing = await detectServer(hippoRoot);
133
142
  if (existing) {
@@ -135,53 +144,64 @@ async function assertNoLiveServer(hippoRoot) {
135
144
  `Stop that server before starting another on the same hippoRoot.`);
136
145
  }
137
146
  }
138
- // SHORTCUT: buckets live in this process and reset on restart or LRU eviction; move them to the store if serve ever runs as several processes.
147
+ // SHORTCUT: buckets live in this process and reset on restart or LRU eviction; move them to the store if serve ever
148
+ // runs as several processes.
139
149
  function limiterFor({ ratePerSec, burst }) {
140
- return createRateLimiter({ ratePerSec, burst, idleEvictMs: 60000, maxKeys: LIMITER_MAX_KEYS });
150
+ return createRateLimiter({ ratePerSec, burst, idleEvictMs: MINUTE_MS, maxKeys: LIMITER_MAX_KEYS });
141
151
  }
142
152
  function bootRateLimiter(perAddress) {
143
153
  if (perAddress === 'off')
144
154
  return undefined;
145
155
  if (perAddress !== undefined)
146
156
  return limiterFor(perAddress);
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).
149
- const v1Rps = Number(envV1Rps() ?? 20);
150
- return Number.isFinite(v1Rps) && v1Rps > 0 ? limiterFor({ ratePerSec: v1Rps, burst: v1Rps * 2 }) : undefined;
157
+ // Per-IP rate limiter for /v1/* and /mcp*, built here (not at module scope) so HIPPO_V1_RPS is read at boot and a
158
+ // test can set it before serve().
159
+ // A typo must not switch the limit off, so only an explicit 0 does.
160
+ const raw = envV1Rps();
161
+ const v1Rps = raw === undefined ? 20 : Number(raw);
162
+ if (!Number.isFinite(v1Rps) || v1Rps < 0) {
163
+ throw new Error(`HIPPO_V1_RPS must be a number of at least 0 (0 turns the per-address limit off), not '${raw}'`);
164
+ }
165
+ return v1Rps > 0 ? limiterFor({ ratePerSec: v1Rps, burst: v1Rps * 2 }) : undefined;
151
166
  }
152
167
  const DEFAULT_FAILED_AUTH = { ratePerSec: 20, burst: 40 };
153
168
  function assertRateLimitSpec(name, { ratePerSec, burst }) {
154
- if (!Number.isFinite(ratePerSec) || ratePerSec <= 0)
169
+ if (!Number.isFinite(ratePerSec) || ratePerSec <= 0) {
155
170
  throw new Error(`rateLimits.${name}.ratePerSec must be a finite number above 0`);
156
- if (!Number.isFinite(burst) || burst < 1)
171
+ }
172
+ if (!Number.isFinite(burst) || burst < 1) {
157
173
  throw new Error(`rateLimits.${name}.burst must be a finite number of at least 1`);
174
+ }
175
+ }
176
+ const DEFAULT_CALLER_RPS = 20;
177
+ /**
178
+ * The per-caller spec when serve() names none: HIPPO_CALLER_RPS (0 is off), else 20 per second with a burst of twice
179
+ * that.
180
+ */
181
+ function defaultCallerSpec() {
182
+ const raw = envCallerRps();
183
+ const rps = raw === undefined ? DEFAULT_CALLER_RPS : Number(raw);
184
+ // A typo must not switch the limit off, so only an explicit 0 does.
185
+ if (!Number.isFinite(rps) || rps < 0) {
186
+ throw new Error(`HIPPO_CALLER_RPS must be a number of at least 0 (0 turns the per-caller limit off), not '${raw}'`);
187
+ }
188
+ return rps === 0 ? 'off' : { ratePerSec: rps, burst: Math.max(1, rps * 2) };
158
189
  }
159
190
  /** Refuses a bad spec at boot, since a NaN or zero rate would otherwise turn a bucket off or refuse every request. */
160
191
  function bootLimiters(rateLimits) {
161
- const { perCaller, perAddress, failedAuthPerAddress = DEFAULT_FAILED_AUTH } = rateLimits ?? {};
162
- if (perCaller !== undefined)
192
+ const { perCaller = defaultCallerSpec(), perAddress, failedAuthPerAddress = DEFAULT_FAILED_AUTH } = rateLimits ?? {};
193
+ if (perCaller !== 'off')
163
194
  assertRateLimitSpec('perCaller', perCaller);
164
195
  if (perAddress !== undefined && perAddress !== 'off')
165
196
  assertRateLimitSpec('perAddress', perAddress);
166
197
  assertRateLimitSpec('failedAuthPerAddress', failedAuthPerAddress);
167
- warnIfClientIpHeaderUnpinned();
198
+ assertClientIpHeaderPinned();
168
199
  return {
169
200
  perAddress: bootRateLimiter(perAddress),
170
- callerLimiter: perCaller === undefined ? undefined : limiterFor(perCaller),
201
+ callerLimiter: perCaller === 'off' ? undefined : limiterFor(perCaller),
171
202
  failedAuthLimiter: limiterFor(failedAuthPerAddress),
172
203
  };
173
204
  }
174
- function createStoreHolder(hippoRoot, store) {
175
- if (store.kind !== 'sqlite') {
176
- log.info(`serve: the '${store.kind}' store serves ${hippoRoot}, so no hippo.db connection is held`);
177
- return { hold: () => { }, afterResponse: () => { }, release: async () => { } };
178
- }
179
- return holdSqliteConnection(hippoRoot);
180
- }
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.
182
- function outsideRouteBlock(resolver) {
183
- return resolver && ((token) => outsideSqliteOffLoop(() => resolver(token)));
184
- }
185
205
  function replyWithFailure(req, res, err, requestId) {
186
206
  const mapped = replyFor(err);
187
207
  logRequestFailure(req, err, mapped.status);
@@ -192,10 +212,12 @@ function replyWithFailure(req, res, err, requestId) {
192
212
  catch { /* socket already gone */ }
193
213
  return;
194
214
  }
195
- if (isStoreBusy(err))
215
+ if (isStoreBusy(err)) {
196
216
  res.setHeader('Retry-After', '1');
197
- else if (err instanceof HttpError && err.retryAfterSec !== undefined)
217
+ }
218
+ else if (err instanceof HttpError && err.retryAfterSec !== undefined) {
198
219
  res.setHeader('Retry-After', String(err.retryAfterSec));
220
+ }
199
221
  if (mapped.status === 500) {
200
222
  // The id lets an operator find the logged cause without the client seeing internal text.
201
223
  sendJson(res, 500, { error: mapped.message, requestId });
@@ -210,29 +232,43 @@ function replyWithFailure(req, res, err, requestId) {
210
232
  sendJson(res, 504, { error: err.message, code: err.code, requestId });
211
233
  return;
212
234
  }
213
- // readBody hit its cap or deadline, so close once the 413 or 408 is out rather than drain what the client keeps sending.
214
- if (err instanceof BodyTooLargeError || err instanceof BodyTimeoutError)
235
+ // readBody hit its cap or deadline, so close once the 413 or 408 is out rather than drain what the client keeps
236
+ // sending.
237
+ if (err instanceof BodyTooLargeError || err instanceof BodyTimeoutError) {
215
238
  res.once('finish', () => closeAfterReply(req));
239
+ }
216
240
  sendError(res, mapped.status, mapped.message);
217
241
  }
218
242
  const HANDLER_LATE = 'the request did not finish by its deadline and was abandoned; a write it started may or may not be saved';
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.
243
+ // The caller already has its 504, so this line is the only trace of the failure. The path and the error text can hold
244
+ // caller data, so it carries neither.
220
245
  function logLateFailure(req, err, requestId) {
221
- const fields = { requestId, method: req.method ?? 'GET', route: accessRouteOf(req), failureStatus: replyFor(err).status };
246
+ const fields = {
247
+ requestId,
248
+ method: req.method ?? 'GET',
249
+ route: accessRouteOf(req),
250
+ failureStatus: replyFor(err).status,
251
+ };
222
252
  log.warn('request failed after its deadline reply', { ...fields, errorClass: errorFields(err).errorClass });
223
253
  }
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.
254
+ // A handler that ends after the 504 finds the response finished, so sending its own reply throws this: its work ran to
255
+ // the end.
225
256
  function isDroppedLateReply(err) {
226
257
  return err instanceof Error && 'code' in err && err.code === 'ERR_HTTP_HEADERS_SENT';
227
258
  }
228
259
  /** A GET only reads; every other method this server routes can write. */
229
260
  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.
261
+ // A read that ends late changed nothing. A write that ends late ran to its end after its caller was told it may not
262
+ // have been saved.
231
263
  function logLateFinish(req, requestId) {
232
264
  const method = req.method ?? 'GET';
233
265
  if (isRead(method))
234
266
  return;
235
- log.info('request finished after its deadline reply; its own reply was dropped', { requestId, method, route: accessRouteOf(req) });
267
+ log.info('request finished after its deadline reply; its own reply was dropped', {
268
+ requestId,
269
+ method,
270
+ route: accessRouteOf(req),
271
+ });
236
272
  }
237
273
  function replyOrClose(req, res, err, requestId) {
238
274
  try {
@@ -244,14 +280,19 @@ function replyOrClose(req, res, err, requestId) {
244
280
  res.destroy();
245
281
  }
246
282
  }
247
- /** Runs `handle` under the request's id and deadline; a failure becomes the reply, unless the deadline has already answered. */
283
+ /**
284
+ * Runs `handle` under the request's id and deadline; a failure becomes the reply, unless the deadline has already
285
+ * answered.
286
+ */
248
287
  function answerRequest(req, res, handle, slowWarnMs) {
249
288
  const requestId = openRequest(req, res, slowWarnMs);
250
289
  const deadline = requestDeadlineFor(req);
290
+ const abort = deadline ? new AbortController() : undefined;
251
291
  // Inside the scope, so the failure reply's log line carries the id too.
252
292
  runWithRequestId(requestId, () => {
253
- if (deadline)
254
- answerAtDeadline(res, deadline, () => replyOrClose(req, res, new DeadlineExceededError(HANDLER_LATE), requestId));
293
+ if (deadline) {
294
+ answerAtDeadline(res, deadline, () => replyOrClose(req, res, new DeadlineExceededError(HANDLER_LATE), requestId), () => abort?.abort(new DeadlineExceededError(HANDLER_LATE)));
295
+ }
255
296
  handle().then(() => {
256
297
  if (isAbandoned(res))
257
298
  logLateFinish(req, requestId);
@@ -263,7 +304,7 @@ function answerRequest(req, res, handle, slowWarnMs) {
263
304
  else
264
305
  logLateFailure(req, err, requestId);
265
306
  });
266
- }, deadline);
307
+ }, deadline, abort?.signal);
267
308
  }
268
309
  function listenOn(server, port, host) {
269
310
  return new Promise((resolve, reject) => {
@@ -287,7 +328,10 @@ function exitOnSignalOrCrash(stop, drainMs) {
287
328
  installSignalHandlers('serve', shutdown);
288
329
  installCrashHandlers('serve', shutdown);
289
330
  }
290
- /** Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses non-loopback hosts unless HIPPO_REQUIRE_AUTH=1.
331
+ /**
332
+ * Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses a non-loopback host unless
333
+ * HIPPO_REQUIRE_AUTH=1 and
334
+ * either `tls` or allowCleartext is given, and refuses HIPPO_CLIENT_IP_HEADER without HIPPO_TRUSTED_PROXIES.
291
335
  * Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
292
336
  export async function serve(opts) {
293
337
  const host = opts.host ?? DEFAULT_SERVER_HOST;
@@ -296,15 +340,17 @@ export async function serve(opts) {
296
340
  const publicJsonBodies = assertPublicJson(opts.publicJson ?? {});
297
341
  const limiters = bootLimiters(opts.rateLimits);
298
342
  assertBindable(host);
343
+ assertTlsOrCleartextAllowed(host, opts.tls, LOOPBACK_HOSTS, opts.allowCleartext ?? envAllowCleartext());
299
344
  await assertNoLiveServer(opts.hippoRoot);
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
345
+ // Single source of truth for the start time: returned by GET /health and written into the pidfile, so detectServer
346
+ // can prove a pid-reusing impostor is not
301
347
  // this server.
302
348
  const startedAt = new Date().toISOString();
303
349
  // Open /mcp/stream count per client key, so the cap is per server rather than per process.
304
350
  const streamSlots = new Map();
305
351
  const served = servedOptsFor(opts, routes, publicJsonBodies, limiters);
306
352
  // A store other than hippo.db is a team's central server, so its folder's config.json must not decide shared-ness.
307
- if (served.store.kind !== 'sqlite')
353
+ if (!hasGroup(served.store, 'localFiles'))
308
354
  markSharedStore(opts.hippoRoot);
309
355
  const holder = createStoreHolder(opts.hippoRoot, served.store);
310
356
  const inflight = new Set();
@@ -330,27 +376,29 @@ export async function serve(opts) {
330
376
  }
331
377
  function frozenAddonRoutes(addonRoutes) {
332
378
  // A frozen copy, so a route the caller adds or renames after boot never skips the check below.
333
- const routes = Object.freeze((addonRoutes ?? []).map(({ path, handler, storeReady }) => Object.freeze(storeReady === undefined
334
- ? { path, handler }
335
- : { path, handler, storeReady })));
379
+ const routes = Object.freeze((addonRoutes ?? []).map(({ path, handler, storeReady }) => Object.freeze(storeReady === undefined ? { path, handler } : { path, handler, storeReady })));
336
380
  assertAddonRoutes(routes);
337
381
  return routes;
338
382
  }
339
383
  function servedOptsFor(opts, routes, publicJsonBodies, { callerLimiter, failedAuthLimiter }) {
384
+ const store = opts.store ?? workerSqliteStore(opts.hippoRoot);
340
385
  return {
341
- ...opts, routes, publicJsonBodies, store: opts.store ?? workerSqliteStore(opts.hippoRoot), callerLimiter, failedAuthLimiter,
386
+ ...opts,
387
+ routes,
388
+ publicJsonBodies,
389
+ store,
390
+ offLoop: offLoopFor(store),
391
+ callerLimiter,
392
+ failedAuthLimiter,
342
393
  authResolver: outsideRouteBlock(opts.authResolver),
343
394
  };
344
395
  }
345
396
  function acceptingServer(served, holder, inflight, options) {
346
- const { kind } = served.store;
347
397
  return createListener(served.tls, (req, res) => {
348
398
  res.once('finish', holder.afterResponse);
349
399
  inflight.add(res);
350
400
  res.once('close', () => inflight.delete(res));
351
- const run = () => handleRequest(req, res, served, options);
352
- // A missed port under another store would otherwise create and write a hippo.db that store never reads.
353
- answerRequest(req, res, () => (kind === 'sqlite' ? run() : withSqliteBlocked(kind, run)), served.slowRequestWarnMs);
401
+ answerRequest(req, res, () => holder.runRequest(() => handleRequest(req, res, served, options)), served.slowRequestWarnMs);
354
402
  });
355
403
  }
356
404
  async function listenAndDescribe(server, port, host, tls) {
@@ -362,11 +410,11 @@ async function listenAndDescribe(server, port, host, tls) {
362
410
  const addressInfo = address;
363
411
  const actualPort = addressInfo.port;
364
412
  const url = `${tls ? 'https' : 'http'}://${host.includes(':') ? `[${host}]` : host}:${actualPort}`;
365
- warnIfCleartext(host, tls, LOOPBACK_HOSTS);
366
413
  return { port: actualPort, url };
367
414
  }
368
415
  async function stopListening(opts, server, inflight, startedAt) {
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.
416
+ // Remove the pidfile only if it still names this server: a newer server may have rewritten it, and an unconditional
417
+ // unlink would orphan it.
370
418
  removePidfileIfOwned(opts.hippoRoot, { pid: process.pid, startedAt });
371
419
  await drainAndClose(server, inflight, opts.shutdownDrainMs ?? DEFAULT_SHUTDOWN_DRAIN_MS);
372
420
  }
@@ -1,12 +1,24 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
2
  import type { RateLimiter } from './rate-limit.js';
3
3
  /**
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. */
4
+ * Rate-limit key: the socket's remote address, which behind a TLS proxy collapses into one bucket unauthenticated
5
+ * traffic can drain.
6
+ * HIPPO_CLIENT_IP_HEADER (fly-client-ip on Fly) is read only from a peer in HIPPO_TRUSTED_PROXIES (IPs or CIDRs, or `*`
7
+ * for any peer),
8
+ * so a caller that reaches the port past the proxy cannot pick its own bucket. In a comma-joined chain the key is the
9
+ * rightmost hop no trusted proxy added.
10
+ */
7
11
  export declare function clientIpForRateLimit(req: IncomingMessage): string;
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. */
9
- export declare function warnIfClientIpHeaderUnpinned(): void;
12
+ /**
13
+ * serve() refused HIPPO_CLIENT_IP_HEADER with no HIPPO_TRUSTED_PROXIES: the header would be read from no one, so the
14
+ * setting is a mistake.
15
+ */
16
+ export declare class UntrustedClientIpHeaderError extends Error {
17
+ readonly header: string;
18
+ constructor(header: string);
19
+ }
20
+ /** Checked at boot: a client-IP header needs a trusted-proxy list, and `*` is said once, since it believes any peer. */
21
+ export declare function assertClientIpHeaderPinned(): void;
10
22
  /** The one key every per-address limit and slot count uses, so rotating inside a /64 never buys a fresh bucket. */
11
23
  export declare function clientLimitKey(req: IncomingMessage): string;
12
24
  export declare function enforceRateLimit(req: IncomingMessage, path: string, limiter?: RateLimiter): void;