hippo-memory 1.68.0 → 1.70.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 (864) hide show
  1. package/README.md +6 -3
  2. package/dist/agent-memories/apply.d.ts +3 -3
  3. package/dist/agent-memories/apply.js +16 -31
  4. package/dist/agent-memories/claude-code.d.ts +1 -3
  5. package/dist/agent-memories/claude-code.js +11 -7
  6. package/dist/agent-memories/copilot.d.ts +3 -1
  7. package/dist/agent-memories/copilot.js +5 -4
  8. package/dist/agent-memories/files.js +3 -2
  9. package/dist/agent-memories/gemini.js +6 -5
  10. package/dist/agent-memories/keys.js +3 -2
  11. package/dist/agent-memories/legacy.d.ts +2 -2
  12. package/dist/agent-memories/legacy.js +2 -2
  13. package/dist/agent-memories/report.d.ts +1 -1
  14. package/dist/agent-memories/report.js +1 -1
  15. package/dist/agent-memories/source.d.ts +1 -1
  16. package/dist/agent-memories/source.js +6 -5
  17. package/dist/agent-memories/sync.d.ts +1 -1
  18. package/dist/agent-memories/sync.js +24 -33
  19. package/dist/agent-memories/types.d.ts +1 -1
  20. package/dist/api/assemble.d.ts +2 -2
  21. package/dist/api/assemble.js +42 -32
  22. package/dist/api/audit.d.ts +4 -7
  23. package/dist/api/audit.js +6 -20
  24. package/dist/api/auth.d.ts +5 -18
  25. package/dist/api/auth.js +44 -194
  26. package/dist/api/auto-sleep.d.ts +13 -0
  27. package/dist/api/auto-sleep.js +32 -0
  28. package/dist/{availability.d.ts → api/availability.d.ts} +2 -2
  29. package/dist/{availability.js → api/availability.js} +12 -29
  30. package/dist/{context-auto.js → api/context-auto.js} +2 -1
  31. package/dist/{context-render.d.ts → api/context-render.d.ts} +4 -4
  32. package/dist/{context-render.js → api/context-render.js} +7 -6
  33. package/dist/api/context-select.d.ts +14 -4
  34. package/dist/api/context-select.js +50 -60
  35. package/dist/api/context-types.d.ts +5 -5
  36. package/dist/api/context.d.ts +2 -4
  37. package/dist/api/context.js +113 -85
  38. package/dist/api/dormant.d.ts +3 -3
  39. package/dist/api/dormant.js +38 -107
  40. package/dist/api/drill-down.d.ts +2 -2
  41. package/dist/api/drill-down.js +37 -65
  42. package/dist/api/forget.d.ts +4 -13
  43. package/dist/api/forget.js +13 -35
  44. package/dist/api/goals.d.ts +1 -1
  45. package/dist/api/goals.js +2 -2
  46. package/dist/api/index.d.ts +26 -0
  47. package/dist/api/index.js +29 -0
  48. package/dist/api/instruction-detect.js +74 -0
  49. package/dist/api/learn.js +63 -55
  50. package/dist/api/ledger-db.d.ts +20 -0
  51. package/dist/api/ledger-db.js +79 -0
  52. package/dist/api/on-store.d.ts +16 -0
  53. package/dist/api/on-store.js +36 -0
  54. package/dist/api/outcome.d.ts +9 -46
  55. package/dist/api/outcome.js +15 -57
  56. package/dist/{pilot-arm.d.ts → api/pilot-arm.d.ts} +1 -1
  57. package/dist/{pilot-arm.js → api/pilot-arm.js} +15 -23
  58. package/dist/api/promote.d.ts +7 -18
  59. package/dist/api/promote.js +30 -152
  60. package/dist/{prompt-hook.d.ts → api/prompt-hook.d.ts} +7 -7
  61. package/dist/{prompt-hook.js → api/prompt-hook.js} +34 -53
  62. package/dist/api/quarantine.d.ts +5 -5
  63. package/dist/api/quarantine.js +30 -106
  64. package/dist/api/recall-core.d.ts +4 -0
  65. package/dist/api/recall-core.js +112 -0
  66. package/dist/{recall-history.js → api/recall-history.js} +30 -25
  67. package/dist/{recall-pipeline.d.ts → api/recall-pipeline.d.ts} +5 -5
  68. package/dist/{recall-pipeline.js → api/recall-pipeline.js} +47 -42
  69. package/dist/api/recall-record.d.ts +10 -13
  70. package/dist/api/recall-record.js +10 -30
  71. package/dist/api/recall-request.d.ts +2 -2
  72. package/dist/api/recall-request.js +3 -3
  73. package/dist/api/recall-types.d.ts +41 -16
  74. package/dist/api/recall.d.ts +1 -1
  75. package/dist/api/recall.js +39 -37
  76. package/dist/api/remember.d.ts +12 -13
  77. package/dist/api/remember.js +38 -27
  78. package/dist/api/session-owners.d.ts +4 -0
  79. package/dist/api/session-owners.js +17 -0
  80. package/dist/api/sleep-run.d.ts +7 -7
  81. package/dist/api/sleep-run.js +63 -75
  82. package/dist/api/sleep.d.ts +1 -1
  83. package/dist/api/tokens.d.ts +2 -2
  84. package/dist/api/tokens.js +9 -21
  85. package/dist/api/types.d.ts +2 -2
  86. package/dist/api/types.js +1 -1
  87. package/dist/capture/caller-session.d.ts +2 -2
  88. package/dist/capture/caller-session.js +8 -8
  89. package/dist/{capture-error.d.ts → capture/capture-error.d.ts} +2 -2
  90. package/dist/{capture-error.js → capture/capture-error.js} +7 -7
  91. package/dist/{codex-patch.js → capture/codex-patch.js} +1 -1
  92. package/dist/capture/command.d.ts +1 -1
  93. package/dist/capture/command.js +54 -41
  94. package/dist/capture/compact-resume-caller.d.ts +1 -1
  95. package/dist/capture/compact-resume-caller.js +7 -7
  96. package/dist/capture/compact.d.ts +4 -1
  97. package/dist/capture/compact.js +59 -22
  98. package/dist/capture/compaction-items-caller.d.ts +1 -1
  99. package/dist/capture/compaction-items-caller.js +7 -5
  100. package/dist/{compaction-items.js → capture/compaction-items.js} +27 -3
  101. package/dist/{compaction-record.d.ts → capture/compaction-record.d.ts} +10 -6
  102. package/dist/{compaction-record.js → capture/compaction-record.js} +48 -94
  103. package/dist/{compaction-spool.js → capture/compaction-spool.js} +17 -13
  104. package/dist/capture/copilot-transcript.d.ts +3 -0
  105. package/dist/capture/copilot-transcript.js +9 -2
  106. package/dist/capture/extract.js +2 -2
  107. package/dist/capture/failure-caller.d.ts +2 -2
  108. package/dist/capture/failure-caller.js +6 -6
  109. package/dist/capture/failure-reading.d.ts +2 -5
  110. package/dist/capture/failure-reading.js +11 -12
  111. package/dist/{handoff-evidence.d.ts → capture/handoff-evidence.d.ts} +1 -1
  112. package/dist/{handoff-evidence.js → capture/handoff-evidence.js} +2 -1
  113. package/dist/capture/pre-compact-caller.d.ts +1 -1
  114. package/dist/capture/pre-compact-caller.js +2 -2
  115. package/dist/{session-digest.d.ts → capture/session-digest.d.ts} +1 -5
  116. package/dist/{session-digest.js → capture/session-digest.js} +17 -23
  117. package/dist/capture/session-end-caller.d.ts +2 -2
  118. package/dist/capture/session-end-caller.js +1 -1
  119. package/dist/capture/session-texts.d.ts +1 -1
  120. package/dist/capture/session-texts.js +5 -5
  121. package/dist/capture/session-worker.d.ts +13 -0
  122. package/dist/capture/session-worker.js +196 -0
  123. package/dist/{share-scrub.js → capture/share-scrub.js} +2 -2
  124. package/dist/capture/transcript.js +68 -74
  125. package/dist/capture/working-state.d.ts +0 -3
  126. package/dist/capture/working-state.js +7 -7
  127. package/dist/{audit-prune.d.ts → cli/audit-prune.d.ts} +1 -2
  128. package/dist/{audit-prune.js → cli/audit-prune.js} +5 -39
  129. package/dist/cli/audit.d.ts +2 -2
  130. package/dist/cli/audit.js +77 -72
  131. package/dist/cli/auth.d.ts +2 -1
  132. package/dist/cli/auth.js +18 -20
  133. package/dist/cli/briefs.d.ts +4 -3
  134. package/dist/cli/briefs.js +59 -181
  135. package/dist/cli/card.d.ts +2 -1
  136. package/dist/cli/card.js +25 -23
  137. package/dist/{client.d.ts → cli/client.d.ts} +1 -1
  138. package/dist/{client.js → cli/client.js} +1 -1
  139. package/dist/cli/compact-resume-payload.d.ts +8 -0
  140. package/dist/cli/compact-resume-payload.js +39 -0
  141. package/dist/cli/context.d.ts +2 -13
  142. package/dist/cli/context.js +41 -71
  143. package/dist/cli/continuity.d.ts +6 -5
  144. package/dist/cli/continuity.js +109 -99
  145. package/dist/{correction-latency.d.ts → cli/correction-latency.d.ts} +1 -1
  146. package/dist/cli/curate.d.ts +9 -9
  147. package/dist/cli/curate.js +177 -149
  148. package/dist/cli/dag.d.ts +4 -4
  149. package/dist/cli/dag.js +46 -34
  150. package/dist/cli/decisions.d.ts +4 -3
  151. package/dist/cli/decisions.js +108 -218
  152. package/dist/cli/eval.d.ts +1 -3
  153. package/dist/cli/eval.js +43 -31
  154. package/dist/cli/explain.d.ts +1 -1
  155. package/dist/cli/explain.js +35 -19
  156. package/dist/cli/flag-values.d.ts +25 -0
  157. package/dist/cli/flag-values.js +103 -0
  158. package/dist/cli/flags.d.ts +303 -0
  159. package/dist/cli/flags.js +169 -0
  160. package/dist/cli/goals.d.ts +2 -1
  161. package/dist/cli/goals.js +39 -34
  162. package/dist/cli/hook-runtime.d.ts +49 -0
  163. package/dist/cli/hook-runtime.js +155 -0
  164. package/dist/cli/init.d.ts +2 -1
  165. package/dist/cli/init.js +151 -118
  166. package/dist/cli/install-steps.d.ts +7 -0
  167. package/dist/cli/install-steps.js +110 -0
  168. package/dist/cli/last-sleep.d.ts +2 -1
  169. package/dist/cli/last-sleep.js +9 -7
  170. package/dist/cli/maintenance.d.ts +5 -4
  171. package/dist/cli/maintenance.js +31 -27
  172. package/dist/cli/object-verbs.d.ts +40 -0
  173. package/dist/cli/object-verbs.js +65 -0
  174. package/dist/{owner-validation.d.ts → cli/owner-validation.d.ts} +0 -1
  175. package/dist/{owner-validation.js → cli/owner-validation.js} +2 -2
  176. package/dist/cli/playbooks.d.ts +4 -3
  177. package/dist/cli/playbooks.js +77 -280
  178. package/dist/cli/print.d.ts +18 -0
  179. package/dist/cli/print.js +85 -0
  180. package/dist/cli/projects.d.ts +2 -3
  181. package/dist/cli/projects.js +56 -49
  182. package/dist/{provenance-coverage.d.ts → cli/provenance-coverage.d.ts} +1 -1
  183. package/dist/cli/quality-repair-once.js +4 -4
  184. package/dist/{quality-repair.js → cli/quality-repair.js} +23 -37
  185. package/dist/cli/recall.d.ts +2 -4
  186. package/dist/cli/recall.js +101 -150
  187. package/dist/{refine-llm.d.ts → cli/refine-llm.d.ts} +1 -1
  188. package/dist/{refine-llm.js → cli/refine-llm.js} +70 -82
  189. package/dist/cli/remember.d.ts +1 -3
  190. package/dist/cli/remember.js +124 -103
  191. package/dist/{scheduler.d.ts → cli/scheduler.d.ts} +3 -1
  192. package/dist/{scheduler.js → cli/scheduler.js} +13 -7
  193. package/dist/cli/serve.d.ts +1 -1
  194. package/dist/cli/serve.js +34 -4
  195. package/dist/cli/session-hooks.d.ts +4 -4
  196. package/dist/cli/session-hooks.js +265 -191
  197. package/dist/cli/setup.d.ts +2 -1
  198. package/dist/cli/setup.js +111 -45
  199. package/dist/cli/shared.d.ts +5 -95
  200. package/dist/cli/shared.js +18 -369
  201. package/dist/cli/slack.d.ts +2 -1
  202. package/dist/cli/slack.js +31 -55
  203. package/dist/cli/sleep-render.d.ts +4 -0
  204. package/dist/cli/sleep-render.js +61 -0
  205. package/dist/cli/sleep.d.ts +2 -8
  206. package/dist/cli/sleep.js +20 -76
  207. package/dist/cli/status.d.ts +3 -3
  208. package/dist/cli/status.js +39 -41
  209. package/dist/{stdin.js → cli/stdin.js} +6 -6
  210. package/dist/cli/transfer.d.ts +4 -4
  211. package/dist/cli/transfer.js +68 -42
  212. package/dist/cli/usage.js +8 -3
  213. package/dist/cli.d.ts +289 -5
  214. package/dist/cli.js +184 -117
  215. package/dist/connectors/dlq.d.ts +44 -0
  216. package/dist/connectors/dlq.js +30 -0
  217. package/dist/connectors/github/backfill.d.ts +1 -1
  218. package/dist/connectors/github/backfill.js +29 -66
  219. package/dist/connectors/github/cli-impl.js +59 -74
  220. package/dist/connectors/github/deletion.d.ts +5 -6
  221. package/dist/connectors/github/deletion.js +18 -52
  222. package/dist/connectors/github/dlq.d.ts +7 -61
  223. package/dist/connectors/github/dlq.js +19 -119
  224. package/dist/connectors/github/ingest.d.ts +2 -31
  225. package/dist/connectors/github/ingest.js +20 -82
  226. package/dist/connectors/github/octokit-client.d.ts +1 -1
  227. package/dist/connectors/github/octokit-client.js +2 -1
  228. package/dist/connectors/github/tenant-routing.d.ts +2 -2
  229. package/dist/connectors/github/tenant-routing.js +10 -36
  230. package/dist/connectors/github/transform.d.ts +1 -1
  231. package/dist/connectors/github/types.d.ts +1 -1
  232. package/dist/connectors/github/types.js +15 -18
  233. package/dist/connectors/github/webhook.d.ts +3 -2
  234. package/dist/connectors/github/webhook.js +84 -87
  235. package/dist/connectors/slack/backfill.d.ts +1 -1
  236. package/dist/connectors/slack/backfill.js +5 -29
  237. package/dist/connectors/slack/deletion.d.ts +4 -7
  238. package/dist/connectors/slack/deletion.js +20 -48
  239. package/dist/connectors/slack/dlq.d.ts +7 -49
  240. package/dist/connectors/slack/dlq.js +25 -118
  241. package/dist/connectors/slack/ingest.d.ts +5 -18
  242. package/dist/connectors/slack/ingest.js +27 -90
  243. package/dist/connectors/slack/signature.js +2 -1
  244. package/dist/connectors/slack/tenant-routing.d.ts +4 -1
  245. package/dist/connectors/slack/tenant-routing.js +13 -14
  246. package/dist/connectors/slack/transform.d.ts +1 -1
  247. package/dist/connectors/slack/types.d.ts +1 -1
  248. package/dist/connectors/slack/types.js +3 -12
  249. package/dist/connectors/slack/web-client.js +2 -2
  250. package/dist/connectors/slack/webhook.d.ts +3 -2
  251. package/dist/connectors/slack/webhook.js +75 -82
  252. package/dist/connectors/slack/workspaces.d.ts +4 -17
  253. package/dist/connectors/slack/workspaces.js +4 -34
  254. package/dist/consolidate/conflicts.d.ts +1 -1
  255. package/dist/consolidate/conflicts.js +4 -4
  256. package/dist/{dag.d.ts → consolidate/dag.d.ts} +1 -1
  257. package/dist/{dag.js → consolidate/dag.js} +60 -81
  258. package/dist/consolidate/decay.d.ts +2 -2
  259. package/dist/consolidate/decay.js +28 -22
  260. package/dist/{dedupe.js → consolidate/dedupe.js} +11 -19
  261. package/dist/consolidate/flush-units.d.ts +2 -2
  262. package/dist/{half-life-migration.d.ts → consolidate/half-life-migration.d.ts} +3 -9
  263. package/dist/consolidate/half-life-migration.js +106 -0
  264. package/dist/consolidate/llm-passes.js +8 -8
  265. package/dist/{memory-value.d.ts → consolidate/memory-value.d.ts} +7 -2
  266. package/dist/{memory-value.js → consolidate/memory-value.js} +9 -7
  267. package/dist/consolidate/merge.js +57 -54
  268. package/dist/{merged-row.d.ts → consolidate/merged-row.d.ts} +1 -1
  269. package/dist/{merged-row.js → consolidate/merged-row.js} +2 -2
  270. package/dist/consolidate/physics-pass.js +46 -46
  271. package/dist/{replay.d.ts → consolidate/replay.d.ts} +1 -1
  272. package/dist/{replay.js → consolidate/replay.js} +2 -2
  273. package/dist/consolidate/run.d.ts +7 -13
  274. package/dist/consolidate/run.js +6 -37
  275. package/dist/consolidate/sleep.d.ts +1 -1
  276. package/dist/consolidate/sleep.js +64 -134
  277. package/dist/{trace.js → consolidate/trace.js} +4 -6
  278. package/dist/consolidate/traces.js +34 -29
  279. package/dist/{ablation.js → core/ablation.js} +1 -1
  280. package/dist/{agent-memories/tools.d.ts → core/agent-memory-tools.d.ts} +1 -1
  281. package/dist/{agent-memories/tools.js → core/agent-memory-tools.js} +1 -1
  282. package/dist/{ambient.js → core/ambient.js} +12 -10
  283. package/dist/{capture-contract.d.ts → core/capture-contract.d.ts} +16 -3
  284. package/dist/core/capture-contract.js +149 -0
  285. package/dist/{compare.d.ts → core/compare.d.ts} +2 -0
  286. package/dist/{compare.js → core/compare.js} +10 -3
  287. package/dist/{config.d.ts → core/config.d.ts} +6 -6
  288. package/dist/{config.js → core/config.js} +99 -72
  289. package/dist/core/handoff.js +87 -0
  290. package/dist/{memory-quality.js → core/memory-quality.js} +1 -1
  291. package/dist/{memory.d.ts → core/memory.d.ts} +19 -5
  292. package/dist/{memory.js → core/memory.js} +117 -82
  293. package/dist/{physics.d.ts → core/physics.d.ts} +1 -1
  294. package/dist/{physics.js → core/physics.js} +2 -1
  295. package/dist/{project-identity.d.ts → core/project-identity.d.ts} +0 -5
  296. package/dist/{project-identity.js → core/project-identity.js} +5 -17
  297. package/dist/{project-remote.js → core/project-remote.js} +4 -4
  298. package/dist/{prompt-recall.d.ts → core/prompt-recall.d.ts} +5 -0
  299. package/dist/{prompt-recall.js → core/prompt-recall.js} +14 -1
  300. package/dist/{salience.js → core/salience.js} +35 -20
  301. package/dist/{search/types.d.ts → core/search-types.d.ts} +2 -2
  302. package/dist/{search/types.js → core/search-types.js} +1 -1
  303. package/dist/core/session-digest-row.d.ts +5 -0
  304. package/dist/core/session-digest-row.js +6 -0
  305. package/dist/{dashboard-actions.d.ts → dashboard/dashboard-actions.d.ts} +1 -1
  306. package/dist/{dashboard-actions.js → dashboard/dashboard-actions.js} +5 -5
  307. package/dist/{dashboard-queries.d.ts → dashboard/dashboard-queries.d.ts} +7 -2
  308. package/dist/{dashboard-queries.js → dashboard/dashboard-queries.js} +6 -10
  309. package/dist/{dashboard-snapshot.d.ts → dashboard/dashboard-snapshot.d.ts} +9 -9
  310. package/dist/{dashboard-snapshot.js → dashboard/dashboard-snapshot.js} +101 -104
  311. package/dist/{dashboard.js → dashboard/dashboard.js} +124 -53
  312. package/dist/db/backup.js +1 -1
  313. package/dist/db/busy.d.ts +18 -1
  314. package/dist/db/busy.js +74 -9
  315. package/dist/db/connect.d.ts +10 -2
  316. package/dist/db/connect.js +43 -10
  317. package/dist/db/index.d.ts +9 -0
  318. package/dist/db/index.js +8 -0
  319. package/dist/db/meta.d.ts +4 -0
  320. package/dist/db/meta.js +11 -1
  321. package/dist/db/migrate.d.ts +8 -1
  322. package/dist/db/migrate.js +25 -30
  323. package/dist/db/migrations/v08.js +1 -1
  324. package/dist/db/migrations/v14.js +39 -35
  325. package/dist/db/migrations/v16.js +29 -26
  326. package/dist/db/migrations/v18.js +6 -5
  327. package/dist/db/migrations/v20.js +4 -2
  328. package/dist/db/migrations/v22.js +39 -36
  329. package/dist/db/migrations/v24.js +27 -22
  330. package/dist/db/migrations/v29.js +37 -32
  331. package/dist/db/migrations/v31.js +36 -31
  332. package/dist/db/migrations/v35.js +1 -1
  333. package/dist/db/migrations/v39.js +1 -1
  334. package/dist/db/migrations/v40.js +15 -14
  335. package/dist/db/migrations/v43.js +7 -6
  336. package/dist/db/migrations/v44.js +1 -1
  337. package/dist/db/migrations/v45.js +1 -1
  338. package/dist/db/migrations/v46.js +1 -1
  339. package/dist/db/migrations/v47.js +1 -1
  340. package/dist/db/migrations/v48.js +1 -1
  341. package/dist/db/migrations/v49.js +1 -1
  342. package/dist/db/migrations/v50.js +8 -7
  343. package/dist/db/migrations/v52.js +1 -1
  344. package/dist/db/open.d.ts +9 -1
  345. package/dist/db/open.js +21 -4
  346. package/dist/{physics-state.d.ts → db/physics-state.d.ts} +3 -3
  347. package/dist/{physics-state.js → db/physics-state.js} +9 -16
  348. package/dist/{raw-archive-mirror-cleanup.d.ts → db/raw-archive-mirror-cleanup.d.ts} +5 -5
  349. package/dist/{raw-archive-mirror-cleanup.js → db/raw-archive-mirror-cleanup.js} +11 -6
  350. package/dist/db/request-stores.d.ts +15 -2
  351. package/dist/db/request-stores.js +37 -15
  352. package/dist/db/tables.d.ts +2 -0
  353. package/dist/db/tables.js +6 -0
  354. package/dist/{vector-store.d.ts → db/vector-store.d.ts} +4 -2
  355. package/dist/{vector-store.js → db/vector-store.js} +76 -51
  356. package/dist/db/wal-checkpointer.d.ts +11 -0
  357. package/dist/db/wal-checkpointer.js +92 -0
  358. package/dist/doctor.js +105 -136
  359. package/dist/entry/json-hooks.d.ts +1 -1
  360. package/dist/entry/json-hooks.js +1 -1
  361. package/dist/entry/project-identity.d.ts +1 -1
  362. package/dist/entry/project-identity.js +1 -1
  363. package/dist/entry/session-text.d.ts +3 -3
  364. package/dist/entry/session-text.js +3 -3
  365. package/dist/{eval-stats.js → eval/eval-stats.js} +12 -9
  366. package/dist/{eval-suite.d.ts → eval/eval-suite.d.ts} +1 -1
  367. package/dist/{eval-suite.js → eval/eval-suite.js} +25 -23
  368. package/dist/{eval.d.ts → eval/eval.d.ts} +1 -1
  369. package/dist/{eval.js → eval/eval.js} +29 -22
  370. package/dist/{judgment.d.ts → eval/judgment.d.ts} +1 -3
  371. package/dist/{judgment.js → eval/judgment.js} +4 -9
  372. package/dist/extensions/openclaw-plugin/index.js +1 -2
  373. package/dist/graph/delta.d.ts +3 -2
  374. package/dist/graph/delta.js +9 -23
  375. package/dist/{graph-extract.d.ts → graph/extract.d.ts} +6 -6
  376. package/dist/{graph-extract.js → graph/extract.js} +37 -52
  377. package/dist/{graph-recall.d.ts → graph/recall.d.ts} +2 -2
  378. package/dist/{graph-recall.js → graph/recall.js} +55 -36
  379. package/dist/{graph-stream.d.ts → graph/stream.d.ts} +2 -2
  380. package/dist/{graph-stream.js → graph/stream.js} +9 -7
  381. package/dist/{graph-view.d.ts → graph/view.d.ts} +6 -3
  382. package/dist/{graph-view.js → graph/view.js} +127 -167
  383. package/dist/graph/write.d.ts +4 -76
  384. package/dist/graph/write.js +13 -397
  385. package/dist/hooks/codex-session.js +1 -1
  386. package/dist/hooks/codex-wrapper.js +14 -15
  387. package/dist/hooks/copilot.d.ts +48 -13
  388. package/dist/hooks/copilot.js +124 -39
  389. package/dist/{cli → hooks}/hook-blocks.js +1 -1
  390. package/dist/hooks/json-hooks.d.ts +3 -1
  391. package/dist/hooks/json-hooks.js +40 -122
  392. package/dist/hooks/opencode.js +35 -27
  393. package/dist/hooks/shared.d.ts +7 -5
  394. package/dist/hooks/shared.js +19 -8
  395. package/dist/importers/core.d.ts +2 -6
  396. package/dist/importers/core.js +41 -39
  397. package/dist/importers/markdown-parse.d.ts +1 -10
  398. package/dist/importers/markdown-parse.js +2 -19
  399. package/dist/importers/markdown.js +2 -1
  400. package/dist/importers/sources.js +50 -46
  401. package/dist/importers/vault.js +71 -92
  402. package/dist/index.d.ts +22 -22
  403. package/dist/index.js +21 -21
  404. package/dist/{autolearn.d.ts → learn/autolearn.d.ts} +2 -2
  405. package/dist/{autolearn.js → learn/autolearn.js} +13 -11
  406. package/dist/{churn-git.d.ts → learn/churn-git.d.ts} +1 -1
  407. package/dist/{churn-git.js → learn/churn-git.js} +6 -4
  408. package/dist/{extract.d.ts → learn/extract.d.ts} +1 -1
  409. package/dist/learn/extract.js +125 -0
  410. package/dist/{forward-claim-detector.d.ts → learn/forward-claim-detector.d.ts} +1 -1
  411. package/dist/{forward-claim-detector.js → learn/forward-claim-detector.js} +1 -1
  412. package/dist/{invalidation.d.ts → learn/invalidation.d.ts} +4 -0
  413. package/dist/{invalidation.js → learn/invalidation.js} +83 -99
  414. package/dist/mcp/admin-tools.d.ts +1 -1
  415. package/dist/mcp/admin-tools.js +37 -60
  416. package/dist/mcp/format.d.ts +5 -5
  417. package/dist/mcp/format.js +7 -6
  418. package/dist/mcp/framing.d.ts +6 -0
  419. package/dist/mcp/framing.js +11 -3
  420. package/dist/mcp/memory-tools.d.ts +2 -2
  421. package/dist/mcp/memory-tools.js +12 -31
  422. package/dist/mcp/protocol.d.ts +6 -10
  423. package/dist/mcp/protocol.js +8 -14
  424. package/dist/mcp/recall-tools.d.ts +2 -2
  425. package/dist/mcp/recall-tools.js +68 -50
  426. package/dist/mcp/request.js +65 -63
  427. package/dist/mcp/server.js +1 -1
  428. package/dist/mcp/session-state.d.ts +1 -2
  429. package/dist/mcp/session-state.js +2 -2
  430. package/dist/mcp/shared-gate.js +1 -1
  431. package/dist/mcp/stdio.js +69 -31
  432. package/dist/mcp/tool-args.js +2 -1
  433. package/dist/mcp/tools.js +2 -2
  434. package/dist/{customer-notes.d.ts → objects/customer-notes.d.ts} +7 -24
  435. package/dist/objects/customer-notes.js +112 -0
  436. package/dist/{decisions.d.ts → objects/decisions.d.ts} +13 -28
  437. package/dist/objects/decisions.js +101 -0
  438. package/dist/objects/descriptor.d.ts +52 -0
  439. package/dist/objects/descriptor.js +4 -0
  440. package/dist/objects/fields.d.ts +15 -0
  441. package/dist/objects/fields.js +21 -0
  442. package/dist/{incidents.d.ts → objects/incidents.d.ts} +17 -44
  443. package/dist/objects/incidents.js +130 -0
  444. package/dist/objects/lifecycle.d.ts +27 -0
  445. package/dist/objects/lifecycle.js +96 -0
  446. package/dist/{policies.d.ts → objects/policies.d.ts} +14 -27
  447. package/dist/objects/policies.js +189 -0
  448. package/dist/{processes.d.ts → objects/processes.d.ts} +14 -34
  449. package/dist/objects/processes.js +146 -0
  450. package/dist/{project-briefs.d.ts → objects/project-briefs.d.ts} +19 -40
  451. package/dist/objects/project-briefs.js +255 -0
  452. package/dist/{skills.d.ts → objects/skills.d.ts} +11 -26
  453. package/dist/objects/skills.js +156 -0
  454. package/dist/postinstall.js +4 -2
  455. package/dist/predictions/planning-fallacy.d.ts +4 -76
  456. package/dist/predictions/planning-fallacy.js +4 -129
  457. package/dist/rerankers/clef.d.ts +2 -6
  458. package/dist/rerankers/clef.js +27 -47
  459. package/dist/rerankers/cross-encoder.d.ts +0 -7
  460. package/dist/rerankers/cross-encoder.js +15 -23
  461. package/dist/rerankers/index.js +8 -7
  462. package/dist/rerankers/jev.d.ts +1 -4
  463. package/dist/rerankers/jev.js +30 -49
  464. package/dist/rerankers/llm.d.ts +2 -4
  465. package/dist/rerankers/llm.js +33 -50
  466. package/dist/rerankers/outage-warning.d.ts +7 -0
  467. package/dist/rerankers/outage-warning.js +31 -0
  468. package/dist/rerankers/remote.d.ts +3 -0
  469. package/dist/rerankers/remote.js +23 -0
  470. package/dist/rerankers/types.d.ts +1 -1
  471. package/dist/search/as-of.d.ts +1 -1
  472. package/dist/search/bm25-search.d.ts +2 -2
  473. package/dist/search/bm25-search.js +7 -7
  474. package/dist/search/bm25.d.ts +1 -1
  475. package/dist/search/bm25.js +1 -1
  476. package/dist/search/boosts.d.ts +5 -1
  477. package/dist/search/boosts.js +34 -13
  478. package/dist/search/breakdown.d.ts +2 -2
  479. package/dist/search/breakdown.js +2 -1
  480. package/dist/search/explain.d.ts +1 -1
  481. package/dist/search/explain.js +3 -2
  482. package/dist/search/finalize.d.ts +2 -2
  483. package/dist/search/finalize.js +4 -3
  484. package/dist/search/fusion.d.ts +1 -1
  485. package/dist/search/fusion.js +3 -3
  486. package/dist/search/hybrid-score.d.ts +2 -2
  487. package/dist/search/hybrid-score.js +1 -1
  488. package/dist/search/hybrid.d.ts +4 -4
  489. package/dist/search/hybrid.js +11 -8
  490. package/dist/{multihop.d.ts → search/multihop.d.ts} +2 -2
  491. package/dist/{multihop.js → search/multihop.js} +7 -5
  492. package/dist/{path-context.js → search/path-context.js} +3 -1
  493. package/dist/search/physics-search.d.ts +4 -4
  494. package/dist/search/physics-search.js +15 -15
  495. package/dist/search/rerank.d.ts +3 -3
  496. package/dist/search/rerank.js +4 -3
  497. package/dist/search/temporal.d.ts +1 -1
  498. package/dist/search/temporal.js +5 -2
  499. package/dist/search/vector.d.ts +3 -3
  500. package/dist/search/vector.js +17 -11
  501. package/dist/server/auth.d.ts +1 -1
  502. package/dist/server/auth.js +26 -18
  503. package/dist/server/boot.d.ts +24 -0
  504. package/dist/server/boot.js +465 -0
  505. package/dist/server/client-ip.d.ts +5 -1
  506. package/dist/server/client-ip.js +18 -6
  507. package/dist/server/cursor.d.ts +1 -1
  508. package/dist/server/cursor.js +2 -3
  509. package/dist/server/deadline.d.ts +13 -0
  510. package/dist/server/deadline.js +45 -0
  511. package/dist/server/key-check-bounds.d.ts +8 -0
  512. package/dist/server/key-check-bounds.js +46 -0
  513. package/dist/server/lifecycle.js +1 -1
  514. package/dist/server/mcp-http.d.ts +1 -4
  515. package/dist/server/mcp-http.js +34 -24
  516. package/dist/server/ready.d.ts +7 -0
  517. package/dist/server/ready.js +38 -0
  518. package/dist/server/request.d.ts +10 -4
  519. package/dist/server/request.js +63 -12
  520. package/dist/server/route-table.d.ts +15 -0
  521. package/dist/server/route-table.js +209 -0
  522. package/dist/server/routes/admin.js +13 -8
  523. package/dist/server/routes/customer-notes.d.ts +5 -5
  524. package/dist/server/routes/customer-notes.js +32 -97
  525. package/dist/server/routes/decisions.d.ts +5 -5
  526. package/dist/server/routes/decisions.js +42 -105
  527. package/dist/server/routes/incidents.d.ts +5 -5
  528. package/dist/server/routes/incidents.js +42 -95
  529. package/dist/server/routes/memories.js +21 -20
  530. package/dist/server/routes/object-routes.d.ts +40 -0
  531. package/dist/server/routes/object-routes.js +80 -0
  532. package/dist/server/routes/policies.d.ts +6 -6
  533. package/dist/server/routes/policies.js +40 -124
  534. package/dist/server/routes/predictions.js +29 -45
  535. package/dist/server/routes/processes.d.ts +5 -5
  536. package/dist/server/routes/processes.js +38 -118
  537. package/dist/server/routes/project-briefs.d.ts +6 -6
  538. package/dist/server/routes/project-briefs.js +38 -110
  539. package/dist/server/routes/recall.js +14 -12
  540. package/dist/server/routes/skills.d.ts +6 -6
  541. package/dist/server/routes/skills.js +37 -125
  542. package/dist/{server-detect.js → server/server-detect.js} +3 -2
  543. package/dist/server/sleep-child.d.ts +2 -0
  544. package/dist/server/sleep-child.js +19 -0
  545. package/dist/server/sleep-offload.d.ts +20 -0
  546. package/dist/server/sleep-offload.js +70 -0
  547. package/dist/server/tls.d.ts +6 -0
  548. package/dist/server/tls.js +24 -0
  549. package/dist/server/types.d.ts +27 -8
  550. package/dist/server/validation.d.ts +3 -4
  551. package/dist/server/validation.js +6 -11
  552. package/dist/server.d.ts +41 -50
  553. package/dist/server.js +26 -560
  554. package/dist/{project-merge.d.ts → sharing/project-merge.d.ts} +1 -1
  555. package/dist/{project-merge.js → sharing/project-merge.js} +26 -45
  556. package/dist/{scope.js → sharing/scope.js} +1 -1
  557. package/dist/{shared.d.ts → sharing/shared.d.ts} +10 -9
  558. package/dist/{shared.js → sharing/shared.js} +100 -77
  559. package/dist/{ambient-store.d.ts → store/ambient.d.ts} +2 -2
  560. package/dist/{ambient-store.js → store/ambient.js} +10 -10
  561. package/dist/store/audit-event.d.ts +12 -6
  562. package/dist/store/audit-event.js +6 -5
  563. package/dist/{audit.d.ts → store/audit.d.ts} +27 -3
  564. package/dist/{audit.js → store/audit.js} +91 -6
  565. package/dist/{auth.d.ts → store/auth.d.ts} +15 -32
  566. package/dist/{auth.js → store/auth.js} +100 -92
  567. package/dist/store/candidates.d.ts +23 -12
  568. package/dist/store/candidates.js +87 -35
  569. package/dist/{card-detail.d.ts → store/card-detail.d.ts} +3 -3
  570. package/dist/{card-detail.js → store/card-detail.js} +1 -1
  571. package/dist/{store-cards.d.ts → store/cards.d.ts} +14 -9
  572. package/dist/{store-cards.js → store/cards.js} +85 -146
  573. package/dist/store/compactions.d.ts +78 -0
  574. package/dist/store/compactions.js +93 -0
  575. package/dist/store/conflicts.d.ts +22 -5
  576. package/dist/store/conflicts.js +160 -109
  577. package/dist/store/connectors/github.d.ts +84 -0
  578. package/dist/store/connectors/github.js +180 -0
  579. package/dist/store/connectors/slack.d.ts +69 -0
  580. package/dist/store/connectors/slack.js +177 -0
  581. package/dist/store/dashboard-reads.d.ts +27 -0
  582. package/dist/store/dashboard-reads.js +92 -0
  583. package/dist/store/delete-and-batch.d.ts +20 -24
  584. package/dist/store/delete-and-batch.js +64 -40
  585. package/dist/{delivery-recorder.d.ts → store/delivery-recorder.d.ts} +12 -5
  586. package/dist/{delivery-recorder.js → store/delivery-recorder.js} +42 -30
  587. package/dist/store/descendant-page.d.ts +12 -0
  588. package/dist/store/descendant-page.js +99 -0
  589. package/dist/store/diagnostics.d.ts +47 -0
  590. package/dist/store/diagnostics.js +51 -0
  591. package/dist/store/doctor-reads.d.ts +16 -0
  592. package/dist/store/doctor-reads.js +19 -0
  593. package/dist/{dormant.d.ts → store/dormant.d.ts} +46 -12
  594. package/dist/{dormant.js → store/dormant.js} +151 -6
  595. package/dist/{embeddings.d.ts → store/embeddings/index.d.ts} +10 -6
  596. package/dist/{embeddings.js → store/embeddings/index.js} +60 -44
  597. package/dist/{local-embedding.d.ts → store/embeddings/local.d.ts} +1 -1
  598. package/dist/{local-embedding.js → store/embeddings/local.js} +68 -57
  599. package/dist/{embedding-provider.d.ts → store/embeddings/provider.d.ts} +2 -2
  600. package/dist/{embedding-provider.js → store/embeddings/provider.js} +47 -32
  601. package/dist/store/entry-reads.d.ts +46 -7
  602. package/dist/store/entry-reads.js +120 -21
  603. package/dist/store/entry-row.d.ts +8 -2
  604. package/dist/store/entry-row.js +28 -8
  605. package/dist/store/entry-writes.d.ts +33 -4
  606. package/dist/store/entry-writes.js +108 -26
  607. package/dist/{failure-log.d.ts → store/failure-log.d.ts} +7 -2
  608. package/dist/{failure-log.js → store/failure-log.js} +9 -2
  609. package/dist/{goals.d.ts → store/goals.d.ts} +6 -46
  610. package/dist/{goals.js → store/goals.js} +45 -94
  611. package/dist/store/graph-queue.d.ts +29 -0
  612. package/dist/store/graph-queue.js +101 -0
  613. package/dist/{graph/read.d.ts → store/graph-reads.d.ts} +26 -34
  614. package/dist/{graph/read.js → store/graph-reads.js} +63 -115
  615. package/dist/{graph/types.d.ts → store/graph-rows.d.ts} +68 -8
  616. package/dist/{graph/rows.js → store/graph-rows.js} +14 -3
  617. package/dist/store/graph-view-rows.d.ts +12 -0
  618. package/dist/store/graph-view-rows.js +67 -0
  619. package/dist/store/graph-writes.d.ts +58 -0
  620. package/dist/store/graph-writes.js +256 -0
  621. package/dist/store/half-life.d.ts +34 -0
  622. package/dist/store/half-life.js +77 -0
  623. package/dist/store/handoffs.d.ts +6 -3
  624. package/dist/store/handoffs.js +70 -31
  625. package/dist/store/index-and-stats.d.ts +8 -1
  626. package/dist/store/index-and-stats.js +51 -48
  627. package/dist/store/index.d.ts +4 -0
  628. package/dist/store/index.js +3 -0
  629. package/dist/store/key-audit.d.ts +2 -2
  630. package/dist/store/key-audit.js +4 -4
  631. package/dist/store/key-writes.d.ts +12 -5
  632. package/dist/store/key-writes.js +30 -4
  633. package/dist/store/ledger-turn.d.ts +17 -0
  634. package/dist/store/ledger-turn.js +27 -0
  635. package/dist/store/markdown.d.ts +1 -1
  636. package/dist/store/markdown.js +4 -3
  637. package/dist/store/mirrors.d.ts +5 -7
  638. package/dist/store/mirrors.js +39 -25
  639. package/dist/store/object-types.d.ts +189 -0
  640. package/dist/store/object-types.js +4 -0
  641. package/dist/store/open.d.ts +8 -4
  642. package/dist/store/open.js +34 -23
  643. package/dist/store/planning-fallacy-evidence.d.ts +42 -0
  644. package/dist/store/planning-fallacy-evidence.js +81 -0
  645. package/dist/store/port.d.ts +646 -0
  646. package/dist/store/port.js +17 -0
  647. package/dist/{predictions/store.d.ts → store/predictions.d.ts} +15 -2
  648. package/dist/{predictions/store.js → store/predictions.js} +52 -67
  649. package/dist/{quarantine.d.ts → store/quarantine.d.ts} +8 -8
  650. package/dist/{quarantine.js → store/quarantine.js} +64 -22
  651. package/dist/{raw-archive.d.ts → store/raw-archive.d.ts} +5 -3
  652. package/dist/{raw-archive.js → store/raw-archive.js} +11 -5
  653. package/dist/{recall-scope.d.ts → store/recall-scope.d.ts} +4 -7
  654. package/dist/{recall-scope.js → store/recall-scope.js} +8 -9
  655. package/dist/{recall-trace.d.ts → store/recall-trace.d.ts} +13 -14
  656. package/dist/{recall-trace.js → store/recall-trace.js} +38 -43
  657. package/dist/store/rejected-values.d.ts +55 -0
  658. package/dist/store/rejected-values.js +162 -0
  659. package/dist/{rejection.d.ts → store/rejection.d.ts} +2 -2
  660. package/dist/{rejection.js → store/rejection.js} +3 -2
  661. package/dist/store/rows.d.ts +2 -3
  662. package/dist/store/rows.js +18 -11
  663. package/dist/store/search-rows.d.ts +15 -4
  664. package/dist/store/search-rows.js +43 -36
  665. package/dist/store/sessions.d.ts +18 -2
  666. package/dist/store/sessions.js +83 -46
  667. package/dist/store/sqlite/commit-watch.d.ts +4 -0
  668. package/dist/store/sqlite/commit-watch.js +29 -0
  669. package/dist/store/sqlite/connector-events-group.d.ts +5 -0
  670. package/dist/store/sqlite/connector-events-group.js +50 -0
  671. package/dist/store/sqlite/connector-writes-group.d.ts +6 -0
  672. package/dist/store/sqlite/connector-writes-group.js +65 -0
  673. package/dist/store/sqlite/dag-reads-group.d.ts +3 -0
  674. package/dist/store/sqlite/dag-reads-group.js +45 -0
  675. package/dist/store/sqlite/entry-writes-group.d.ts +18 -0
  676. package/dist/store/sqlite/entry-writes-group.js +170 -0
  677. package/dist/store/sqlite/error-codec.d.ts +17 -0
  678. package/dist/store/sqlite/error-codec.js +59 -0
  679. package/dist/store/sqlite/executor-counts.d.ts +10 -0
  680. package/dist/store/sqlite/executor-counts.js +11 -0
  681. package/dist/store/sqlite/executor.d.ts +28 -0
  682. package/dist/store/sqlite/executor.js +286 -0
  683. package/dist/store/sqlite/graph-reads-group.d.ts +5 -0
  684. package/dist/store/sqlite/graph-reads-group.js +18 -0
  685. package/dist/store/sqlite/local.d.ts +21 -0
  686. package/dist/store/sqlite/local.js +38 -0
  687. package/dist/store/sqlite/object-rows.d.ts +102 -0
  688. package/dist/store/sqlite/object-rows.js +218 -0
  689. package/dist/store/sqlite/objects-group.d.ts +20 -0
  690. package/dist/store/sqlite/objects-group.js +314 -0
  691. package/dist/store/sqlite/predictions-group.d.ts +5 -0
  692. package/dist/store/sqlite/predictions-group.js +28 -0
  693. package/dist/store/sqlite/quarantine-group.d.ts +5 -0
  694. package/dist/store/sqlite/quarantine-group.js +38 -0
  695. package/dist/store/sqlite/store.d.ts +26 -0
  696. package/dist/store/sqlite/store.js +295 -0
  697. package/dist/store/sqlite/vector-pack.d.ts +18 -0
  698. package/dist/store/sqlite/vector-pack.js +46 -0
  699. package/dist/store/sqlite/vector-reads-group.d.ts +3 -0
  700. package/dist/store/sqlite/vector-reads-group.js +23 -0
  701. package/dist/store/sqlite/worker-entry.d.ts +2 -0
  702. package/dist/store/sqlite/worker-entry.js +8 -0
  703. package/dist/store/sqlite/worker-jobs.d.ts +5 -0
  704. package/dist/store/sqlite/worker-jobs.js +116 -0
  705. package/dist/store/sqlite/worker-ops.d.ts +124 -0
  706. package/dist/store/sqlite/worker-ops.js +82 -0
  707. package/dist/store/sqlite/worker-store.d.ts +8 -0
  708. package/dist/store/sqlite/worker-store.js +76 -0
  709. package/dist/store/summaries.d.ts +2 -11
  710. package/dist/store/summaries.js +17 -44
  711. package/dist/{summary-dirty.d.ts → store/summary-dirty.d.ts} +1 -1
  712. package/dist/store/tenant-lookup.d.ts +1 -1
  713. package/dist/{tenant.d.ts → store/tenant.d.ts} +2 -2
  714. package/dist/{tenant.js → store/tenant.js} +1 -1
  715. package/dist/store/token-ledger-rows.d.ts +61 -0
  716. package/dist/store/token-ledger-rows.js +68 -0
  717. package/dist/{token-ledger.d.ts → store/token-ledger.d.ts} +2 -9
  718. package/dist/{token-ledger.js → store/token-ledger.js} +31 -78
  719. package/dist/store/tombstone-checks.d.ts +12 -0
  720. package/dist/store/tombstone-checks.js +31 -0
  721. package/dist/store/usage-reports.d.ts +7 -0
  722. package/dist/store/usage-reports.js +26 -0
  723. package/dist/store/vector-writes.d.ts +10 -3
  724. package/dist/store/vector-writes.js +35 -5
  725. package/dist/{working-memory.d.ts → store/working-memory.d.ts} +5 -1
  726. package/dist/{working-memory.js → store/working-memory.js} +39 -41
  727. package/dist/support-bundle.d.ts +1 -1
  728. package/dist/support-bundle.js +13 -33
  729. package/dist/{gated-write.d.ts → trust/gated-write.d.ts} +2 -2
  730. package/dist/{gated-write.js → trust/gated-write.js} +6 -6
  731. package/dist/trust/quarantine.d.ts +4 -0
  732. package/dist/trust/quarantine.js +8 -0
  733. package/dist/trust/reject-flow.d.ts +23 -0
  734. package/dist/trust/reject-flow.js +67 -0
  735. package/dist/util/anthropic-messages.d.ts +31 -0
  736. package/dist/util/anthropic-messages.js +46 -0
  737. package/dist/util/atomic-write.d.ts +3 -0
  738. package/dist/util/atomic-write.js +107 -0
  739. package/dist/util/crash-handlers.d.ts +5 -0
  740. package/dist/util/crash-handlers.js +30 -0
  741. package/dist/{env.d.ts → util/env.d.ts} +17 -2
  742. package/dist/{env.js → util/env.js} +22 -2
  743. package/dist/util/home-path.js +67 -0
  744. package/dist/{http-retry.d.ts → util/http-retry.d.ts} +6 -2
  745. package/dist/{http-retry.js → util/http-retry.js} +38 -7
  746. package/dist/{http-util.d.ts → util/http-util.d.ts} +14 -3
  747. package/dist/{http-util.js → util/http-util.js} +31 -11
  748. package/dist/util/json.d.ts +17 -0
  749. package/dist/util/json.js +25 -0
  750. package/dist/{log.d.ts → util/log.d.ts} +5 -2
  751. package/dist/{log.js → util/log.js} +12 -3
  752. package/dist/util/real-path.d.ts +3 -0
  753. package/dist/util/real-path.js +15 -0
  754. package/dist/util/request-scope.d.ts +27 -0
  755. package/dist/util/request-scope.js +47 -0
  756. package/dist/{same-text.d.ts → util/same-text.d.ts} +1 -1
  757. package/dist/{secret-detect.js → util/secret-detect.js} +5 -4
  758. package/dist/util/stored-json.d.ts +9 -0
  759. package/dist/util/stored-json.js +8 -0
  760. package/dist/util/time.d.ts +2 -0
  761. package/dist/util/time.js +3 -0
  762. package/dist/util/token-text.d.ts +18 -0
  763. package/dist/util/token-text.js +23 -0
  764. package/dist/{version.d.ts → util/version.d.ts} +1 -1
  765. package/dist/{version.js → util/version.js} +1 -1
  766. package/extensions/openclaw-plugin/index.ts +1 -5
  767. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  768. package/extensions/openclaw-plugin/package.json +1 -1
  769. package/openclaw.plugin.json +1 -1
  770. package/package.json +2 -2
  771. package/dist/api.d.ts +0 -26
  772. package/dist/api.js +0 -29
  773. package/dist/capture-contract.js +0 -49
  774. package/dist/connectors/github/idempotency.d.ts +0 -19
  775. package/dist/connectors/github/idempotency.js +0 -27
  776. package/dist/connectors/slack/idempotency.d.ts +0 -17
  777. package/dist/connectors/slack/idempotency.js +0 -31
  778. package/dist/customer-notes.js +0 -336
  779. package/dist/db.d.ts +0 -9
  780. package/dist/db.js +0 -8
  781. package/dist/decisions.js +0 -326
  782. package/dist/extract.js +0 -133
  783. package/dist/graph/rows.d.ts +0 -45
  784. package/dist/graph/types.js +0 -11
  785. package/dist/half-life-migration.js +0 -182
  786. package/dist/handoff.js +0 -68
  787. package/dist/home-path.js +0 -24
  788. package/dist/incidents.js +0 -349
  789. package/dist/instruction-detect.js +0 -27
  790. package/dist/json.d.ts +0 -7
  791. package/dist/json.js +0 -11
  792. package/dist/ledger-db.d.ts +0 -10
  793. package/dist/ledger-db.js +0 -42
  794. package/dist/policies.js +0 -434
  795. package/dist/processes.js +0 -371
  796. package/dist/project-briefs.js +0 -523
  797. package/dist/reject-flow.d.ts +0 -69
  798. package/dist/reject-flow.js +0 -260
  799. package/dist/session-owners.d.ts +0 -7
  800. package/dist/session-owners.js +0 -54
  801. package/dist/skills.js +0 -367
  802. package/dist/store-port.d.ts +0 -191
  803. package/dist/store-port.js +0 -166
  804. /package/dist/{context-auto.d.ts → api/context-auto.d.ts} +0 -0
  805. /package/dist/{instruction-detect.d.ts → api/instruction-detect.d.ts} +0 -0
  806. /package/dist/{recall-history.d.ts → api/recall-history.d.ts} +0 -0
  807. /package/dist/{codex-patch.d.ts → capture/codex-patch.d.ts} +0 -0
  808. /package/dist/{compaction-items.d.ts → capture/compaction-items.d.ts} +0 -0
  809. /package/dist/{compaction-spool.d.ts → capture/compaction-spool.d.ts} +0 -0
  810. /package/dist/{share-scrub.d.ts → capture/share-scrub.d.ts} +0 -0
  811. /package/dist/{correction-latency.js → cli/correction-latency.js} +0 -0
  812. /package/dist/{provenance-coverage.js → cli/provenance-coverage.js} +0 -0
  813. /package/dist/{quality-repair.d.ts → cli/quality-repair.d.ts} +0 -0
  814. /package/dist/{stdin.d.ts → cli/stdin.d.ts} +0 -0
  815. /package/dist/{dedupe.d.ts → consolidate/dedupe.d.ts} +0 -0
  816. /package/dist/{memory-value-weights.d.ts → consolidate/memory-value-weights.d.ts} +0 -0
  817. /package/dist/{memory-value-weights.js → consolidate/memory-value-weights.js} +0 -0
  818. /package/dist/{overlap-index.d.ts → consolidate/overlap-index.d.ts} +0 -0
  819. /package/dist/{overlap-index.js → consolidate/overlap-index.js} +0 -0
  820. /package/dist/{trace.d.ts → consolidate/trace.d.ts} +0 -0
  821. /package/dist/{ablation.d.ts → core/ablation.d.ts} +0 -0
  822. /package/dist/{ambient.d.ts → core/ambient.d.ts} +0 -0
  823. /package/dist/{api-errors.d.ts → core/api-errors.d.ts} +0 -0
  824. /package/dist/{api-errors.js → core/api-errors.js} +0 -0
  825. /package/dist/{card.d.ts → core/card.d.ts} +0 -0
  826. /package/dist/{card.js → core/card.js} +0 -0
  827. /package/dist/{handoff.d.ts → core/handoff.d.ts} +0 -0
  828. /package/dist/{memory-quality.d.ts → core/memory-quality.d.ts} +0 -0
  829. /package/dist/{physics-config.d.ts → core/physics-config.d.ts} +0 -0
  830. /package/dist/{physics-config.js → core/physics-config.js} +0 -0
  831. /package/dist/{project-remote.d.ts → core/project-remote.d.ts} +0 -0
  832. /package/dist/{salience.d.ts → core/salience.d.ts} +0 -0
  833. /package/dist/{dashboard-params.d.ts → dashboard/dashboard-params.d.ts} +0 -0
  834. /package/dist/{dashboard-params.js → dashboard/dashboard-params.js} +0 -0
  835. /package/dist/{dashboard-types.d.ts → dashboard/dashboard-types.d.ts} +0 -0
  836. /package/dist/{dashboard-types.js → dashboard/dashboard-types.js} +0 -0
  837. /package/dist/{dashboard.d.ts → dashboard/dashboard.d.ts} +0 -0
  838. /package/dist/{eval-stats.d.ts → eval/eval-stats.d.ts} +0 -0
  839. /package/dist/{cli → hooks}/hook-blocks.d.ts +0 -0
  840. /package/dist/{path-context.d.ts → search/path-context.d.ts} +0 -0
  841. /package/dist/{rrf.d.ts → search/rrf.d.ts} +0 -0
  842. /package/dist/{rrf.js → search/rrf.js} +0 -0
  843. /package/dist/{rate-limit.d.ts → server/rate-limit.d.ts} +0 -0
  844. /package/dist/{rate-limit.js → server/rate-limit.js} +0 -0
  845. /package/dist/{server-detect.d.ts → server/server-detect.d.ts} +0 -0
  846. /package/dist/{scope.d.ts → sharing/scope.d.ts} +0 -0
  847. /package/dist/{summary-dirty.js → store/summary-dirty.js} +0 -0
  848. /package/dist/{yaml.d.ts → store/yaml.d.ts} +0 -0
  849. /package/dist/{yaml.js → store/yaml.js} +0 -0
  850. /package/dist/{escape.d.ts → util/escape.d.ts} +0 -0
  851. /package/dist/{escape.js → util/escape.js} +0 -0
  852. /package/dist/{home-path.d.ts → util/home-path.d.ts} +0 -0
  853. /package/dist/{keyset.d.ts → util/keyset.d.ts} +0 -0
  854. /package/dist/{keyset.js → util/keyset.js} +0 -0
  855. /package/dist/{same-text.js → util/same-text.js} +0 -0
  856. /package/dist/{secret-detect.d.ts → util/secret-detect.d.ts} +0 -0
  857. /package/dist/{db → util}/sqlite-blocked.d.ts +0 -0
  858. /package/dist/{db → util}/sqlite-blocked.js +0 -0
  859. /package/dist/{tokenize.d.ts → util/tokenize.d.ts} +0 -0
  860. /package/dist/{tokenize.js → util/tokenize.js} +0 -0
  861. /package/dist/{transcript-tail.d.ts → util/transcript-tail.d.ts} +0 -0
  862. /package/dist/{transcript-tail.js → util/transcript-tail.js} +0 -0
  863. /package/dist/{write-budget.d.ts → util/write-budget.d.ts} +0 -0
  864. /package/dist/{write-budget.js → util/write-budget.js} +0 -0
@@ -0,0 +1,465 @@
1
+ import { envPort, envRequireAuth, envV1Rps } from '../util/env.js';
2
+ import { existsSync } from 'node:fs';
3
+ 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';
7
+ import { workerSqliteStore } from '../store/sqlite/worker-store.js';
8
+ import { markSharedStore } from '../core/config.js';
9
+ import { auditWriteFailureCount } from '../store/audit.js';
10
+ import { PACKAGE_VERSION } from '../util/version.js';
11
+ import { errorFields, errorMessage, log } from '../util/log.js';
12
+ import { runWithRequestId } from '../util/request-scope.js';
13
+ import { createRateLimiter } from './rate-limit.js';
14
+ 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';
18
+ import { workerCounts } from '../store/sqlite/executor-counts.js';
19
+ import { isLoopback, LIMITER_MAX_KEYS } from './auth.js';
20
+ import { enforceRateLimit, warnIfClientIpHeaderUnpinned } from './client-ip.js';
21
+ import { answerAtDeadline, handlerDeadlineCount, isAbandoned, requestDeadlineFor } from './deadline.js';
22
+ import { drainAndClose } from './lifecycle.js';
23
+ import { readyProbeFor } from './ready.js';
24
+ import { installCrashHandlers } from '../util/crash-handlers.js';
25
+ import { handleMcpPost, handleMcpStream } from './mcp-http.js';
26
+ import { MCP_PROJECT_SCOPED_HEADER } from '../core/project-identity.js';
27
+ import { logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError } from './request.js';
28
+ import { createListener, warnIfCleartext } from './tls.js';
29
+ import { assertAddonRoutes, assertPublicJson, dispatchAddonRoute, dispatchPublicJson, dispatchV1Route, isPublicRoute } from './route-table.js';
30
+ // server.address() returns AddressInfo once a TCP socket is bound; null before
31
+ // listening, a string only for pipe/unix-socket listeners (never used here).
32
+ function isAddressInfo(a) {
33
+ return a !== null && typeof a !== 'string';
34
+ }
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.
39
+ const VERSION = PACKAGE_VERSION;
40
+ const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
41
+ async function handleRequest(req, res, opts, options) {
42
+ const { startedAt, streamSlots, limiter } = options;
43
+ // Pre-decode raw-URL slash check. Catches `%2F` / `%2f` before
44
+ // Node's URL parser collapses them and they slip past the route table.
45
+ rejectEncodedSlash(req.url ?? '/');
46
+ const { method, path, query } = parseRequest(req);
47
+ // An older core ignores X-Hippo-Project, so every /mcp reply, a 429 or 401 too, tells the client this one filters by it.
48
+ if (path === '/mcp')
49
+ res.setHeader(MCP_PROJECT_SCOPED_HEADER, '1');
50
+ if (method === 'GET' && path === '/health') {
51
+ noteAccess(req, { route: path });
52
+ sendHealth(req, res, startedAt);
53
+ return;
54
+ }
55
+ if (method === 'GET' && path === '/ready') {
56
+ noteAccess(req, { route: path });
57
+ await sendReady(res, opts.store);
58
+ return;
59
+ }
60
+ enforceRateLimit(req, path, limiter);
61
+ const routeRequest = { req, res, opts, query };
62
+ if (await runWithRequestStores(() => dispatchScopedRoute(routeRequest, method, path), { busyWaitMs: SERVER_DB_WAIT_MS }))
63
+ 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.
65
+ if (method === 'GET' && path === '/mcp/stream') {
66
+ noteAccess(req, { route: path });
67
+ await runWithRequestStores(() => handleMcpStream(req, res, opts, streamSlots), { busyWaitMs: SERVER_DB_WAIT_MS });
68
+ return;
69
+ }
70
+ res.writeHead(404, JSON_HEADERS);
71
+ res.end(JSON.stringify({ error: 'not found' }));
72
+ }
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. */
80
+ async function dispatchScopedRoute(r, method, path) {
81
+ if (await dispatchV1Route(r, method, path))
82
+ return true;
83
+ if (dispatchPublicJson(r, method, path))
84
+ return true;
85
+ if (await dispatchAddonRoute(r, method, path))
86
+ return true;
87
+ 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
+ // Store-ready: under another store the MCP layer lists and runs only the tools ported to the port.
109
+ if (method === 'POST' && path === '/mcp') {
110
+ noteAccess(req, { route: path });
111
+ await handleMcpPost(req, res, opts);
112
+ return true;
113
+ }
114
+ return false;
115
+ }
116
+ 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)) {
122
+ sendJson(res, 200, {
123
+ ok: true,
124
+ version: VERSION,
125
+ started_at: startedAt,
126
+ pid: process.pid,
127
+ audit_write_failures: auditWriteFailureCount(),
128
+ store_queue_refusals: workerCounts.queueRefusals,
129
+ store_jobs_expired: workerCounts.jobsExpired,
130
+ store_workers_replaced: workerCounts.workersReplaced,
131
+ handler_deadlines: handlerDeadlineCount(),
132
+ });
133
+ }
134
+ else {
135
+ sendJson(res, 200, { ok: true });
136
+ }
137
+ }
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. */
139
+ async function sendReady(res, store) {
140
+ const { readiness } = store;
141
+ if (readiness === undefined) {
142
+ sendJson(res, 200, { ok: true, store: 'unchecked' });
143
+ return;
144
+ }
145
+ if (!(await readyProbeFor(store, readiness)())) {
146
+ sendJson(res, 503, { ok: false, error: 'store_unavailable' });
147
+ return;
148
+ }
149
+ sendJson(res, 200, { ok: true });
150
+ }
151
+ function assertBindable(host) {
152
+ if (!LOOPBACK_HOSTS.has(host) && !envRequireAuth()) {
153
+ throw new Error(`Refusing to bind hippo serve to non-loopback host '${host}' without auth. ` +
154
+ `Set HIPPO_REQUIRE_AUTH=1 to bind non-loopback; every request then requires ` +
155
+ `a valid API key. Bind to 127.0.0.1 / ::1 / localhost otherwise.`);
156
+ }
157
+ }
158
+ 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.
163
+ const existing = await detectServer(hippoRoot);
164
+ if (existing) {
165
+ throw new Error(`hippo serve: already running on port ${existing.port} (pid ${existing.pid}). ` +
166
+ `Stop that server before starting another on the same hippoRoot.`);
167
+ }
168
+ }
169
+ // 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.
170
+ function limiterFor({ ratePerSec, burst }) {
171
+ return createRateLimiter({ ratePerSec, burst, idleEvictMs: 60000, maxKeys: LIMITER_MAX_KEYS });
172
+ }
173
+ function bootRateLimiter(perAddress) {
174
+ if (perAddress === 'off')
175
+ return undefined;
176
+ if (perAddress !== undefined)
177
+ 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).
182
+ const v1Rps = Number(envV1Rps() ?? 20);
183
+ return Number.isFinite(v1Rps) && v1Rps > 0 ? limiterFor({ ratePerSec: v1Rps, burst: v1Rps * 2 }) : undefined;
184
+ }
185
+ const DEFAULT_FAILED_AUTH = { ratePerSec: 20, burst: 40 };
186
+ function assertRateLimitSpec(name, { ratePerSec, burst }) {
187
+ if (!Number.isFinite(ratePerSec) || ratePerSec <= 0)
188
+ throw new Error(`rateLimits.${name}.ratePerSec must be a finite number above 0`);
189
+ if (!Number.isFinite(burst) || burst < 1)
190
+ throw new Error(`rateLimits.${name}.burst must be a finite number of at least 1`);
191
+ }
192
+ /** Refuses a bad spec at boot, since a NaN or zero rate would otherwise turn a bucket off or refuse every request. */
193
+ function bootLimiters(rateLimits) {
194
+ const { perCaller, perAddress, failedAuthPerAddress = DEFAULT_FAILED_AUTH } = rateLimits ?? {};
195
+ if (perCaller !== undefined)
196
+ assertRateLimitSpec('perCaller', perCaller);
197
+ if (perAddress !== undefined && perAddress !== 'off')
198
+ assertRateLimitSpec('perAddress', perAddress);
199
+ assertRateLimitSpec('failedAuthPerAddress', failedAuthPerAddress);
200
+ warnIfClientIpHeaderUnpinned();
201
+ return {
202
+ perAddress: bootRateLimiter(perAddress),
203
+ callerLimiter: perCaller === undefined ? undefined : limiterFor(perCaller),
204
+ failedAuthLimiter: limiterFor(failedAuthPerAddress),
205
+ };
206
+ }
207
+ function createStoreHolder(hippoRoot, store) {
208
+ if (store.kind !== 'sqlite') {
209
+ log.info(`serve: the '${store.kind}' store serves ${hippoRoot}, so no hippo.db connection is held`);
210
+ return { hold: () => { }, afterResponse: () => { }, release: async () => { } };
211
+ }
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 };
245
+ }
246
+ // 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
+ function outsideRouteBlock(resolver) {
248
+ return resolver && ((token) => outsideSqliteOffLoop(() => resolver(token)));
249
+ }
250
+ function replyWithFailure(req, res, err, requestId) {
251
+ const mapped = replyFor(err);
252
+ logRequestFailure(req, err, mapped.status);
253
+ if (res.headersSent) {
254
+ try {
255
+ res.end();
256
+ }
257
+ catch { /* socket already gone */ }
258
+ return;
259
+ }
260
+ if (isStoreBusy(err))
261
+ res.setHeader('Retry-After', '1');
262
+ else if (err instanceof HttpError && err.retryAfterSec !== undefined)
263
+ res.setHeader('Retry-After', String(err.retryAfterSec));
264
+ if (mapped.status === 500) {
265
+ // The id lets an operator find the logged cause without the client seeing internal text.
266
+ sendJson(res, 500, { error: mapped.message, requestId });
267
+ return;
268
+ }
269
+ // RecallContractError keeps the shared {error} shape and adds `code` so clients branch without parsing prose.
270
+ if (err instanceof RecallContractError) {
271
+ sendJson(res, 400, { error: err.message, code: err.code });
272
+ return;
273
+ }
274
+ if (err instanceof DeadlineExceededError) {
275
+ sendJson(res, 504, { error: err.message, code: err.code, requestId });
276
+ return;
277
+ }
278
+ // readBody hit its cap or deadline, so close once the 413 or 408 is out rather than drain what the client keeps sending.
279
+ if (err instanceof BodyTooLargeError || err instanceof BodyTimeoutError)
280
+ res.once('finish', () => closeAfterReply(req));
281
+ sendError(res, mapped.status, mapped.message);
282
+ }
283
+ 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)}`);
287
+ }
288
+ function replyOrClose(req, res, err, requestId) {
289
+ try {
290
+ replyWithFailure(req, res, err, requestId);
291
+ }
292
+ catch (replyErr) {
293
+ // 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)}`);
295
+ res.destroy();
296
+ }
297
+ }
298
+ /** Runs `handle` under the request's id and deadline; a failure becomes the reply, unless the deadline has already answered. */
299
+ function answerRequest(req, res, handle, slowWarnMs) {
300
+ const requestId = openRequest(req, res, slowWarnMs);
301
+ const deadline = requestDeadlineFor(req);
302
+ // Inside the scope, so the failure reply's log line carries the id too.
303
+ runWithRequestId(requestId, () => {
304
+ if (deadline)
305
+ answerAtDeadline(res, deadline, () => replyOrClose(req, res, new DeadlineExceededError(HANDLER_LATE), requestId));
306
+ handle().catch((err) => {
307
+ if (isAbandoned(res))
308
+ logLateFailure(req, err);
309
+ else
310
+ replyOrClose(req, res, err, requestId);
311
+ });
312
+ }, deadline);
313
+ }
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
+ function listenOn(server, port, host) {
325
+ return new Promise((resolve, reject) => {
326
+ const onError = (err) => {
327
+ server.removeListener('listening', onListening);
328
+ reject(err);
329
+ };
330
+ const onListening = () => {
331
+ server.removeListener('error', onError);
332
+ // With no listener, an 'error' event after boot is an uncaught exception that stops the server for every caller.
333
+ server.on('error', (err) => log.error(`serve: listener error: ${err.message}`, errorFields(err)));
334
+ resolve();
335
+ };
336
+ server.once('error', onError);
337
+ server.once('listening', onListening);
338
+ server.listen(port, host);
339
+ });
340
+ }
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'); });
359
+ }
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
+ */
381
+ export async function serve(opts) {
382
+ const host = opts.host ?? '127.0.0.1';
383
+ const requestedPort = opts.port ?? Number(envPort() ?? 6789);
384
+ const routes = frozenAddonRoutes(opts.routes);
385
+ const publicJsonBodies = assertPublicJson(opts.publicJson ?? {});
386
+ const limiters = bootLimiters(opts.rateLimits);
387
+ assertBindable(host);
388
+ 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.
392
+ const startedAt = new Date().toISOString();
393
+ // Open /mcp/stream count per client key, so the cap is per server rather than per process.
394
+ const streamSlots = new Map();
395
+ const served = servedOptsFor(opts, routes, publicJsonBodies, limiters);
396
+ // A store other than hippo.db is a team's central server, so its folder's config.json must not decide shared-ness.
397
+ if (served.store.kind !== 'sqlite')
398
+ markSharedStore(opts.hippoRoot);
399
+ const holder = createStoreHolder(opts.hippoRoot, served.store);
400
+ const inflight = new Set();
401
+ const server = acceptingServer(served, holder, inflight, { startedAt, streamSlots, limiter: limiters.perAddress });
402
+ setKeepAliveTimeouts(server);
403
+ const { port: actualPort, url } = await listenAndDescribe(server, requestedPort, host, opts.tls);
404
+ writePidfile(opts.hippoRoot, { port: actualPort, url, startedAt });
405
+ holder.hold();
406
+ let stopping = false;
407
+ const stop = async () => {
408
+ if (stopping)
409
+ return;
410
+ stopping = true;
411
+ await stopListening(opts, server, inflight, startedAt);
412
+ // The store's worker threads close their connections first, so the held one is still SQLite's last.
413
+ if (!opts.store)
414
+ await served.store.close();
415
+ await holder.release();
416
+ };
417
+ if (opts.handleSignals) {
418
+ installSignalHandlers(stop);
419
+ installCrashHandlers('serve', stop);
420
+ }
421
+ return { port: actualPort, url, stop, server };
422
+ }
423
+ function frozenAddonRoutes(addonRoutes) {
424
+ // 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 })));
426
+ assertAddonRoutes(routes);
427
+ return routes;
428
+ }
429
+ function servedOptsFor(opts, routes, publicJsonBodies, { callerLimiter, failedAuthLimiter }) {
430
+ return {
431
+ ...opts, routes, publicJsonBodies, store: opts.store ?? workerSqliteStore(opts.hippoRoot), callerLimiter, failedAuthLimiter,
432
+ authResolver: outsideRouteBlock(opts.authResolver),
433
+ };
434
+ }
435
+ function acceptingServer(served, holder, inflight, options) {
436
+ const { kind } = served.store;
437
+ return createListener(served.tls, (req, res) => {
438
+ res.once('finish', holder.afterResponse);
439
+ inflight.add(res);
440
+ res.once('close', () => inflight.delete(res));
441
+ const run = () => handleRequest(req, res, served, options);
442
+ // A missed port under another store would otherwise create and write a hippo.db that store never reads.
443
+ answerRequest(req, res, () => (kind === 'sqlite' ? run() : withSqliteBlocked(kind, run)), served.slowRequestWarnMs);
444
+ });
445
+ }
446
+ async function listenAndDescribe(server, port, host, tls) {
447
+ await listenOn(server, port, host);
448
+ const address = server.address();
449
+ if (!isAddressInfo(address)) {
450
+ throw new Error('server.address() returned unexpected shape');
451
+ }
452
+ const addressInfo = address;
453
+ const actualPort = addressInfo.port;
454
+ const url = `${tls ? 'https' : 'http'}://${host.includes(':') ? `[${host}]` : host}:${actualPort}`;
455
+ warnIfCleartext(host, tls, LOOPBACK_HOSTS);
456
+ return { port: actualPort, url };
457
+ }
458
+ 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.
462
+ removePidfileIfOwned(opts.hippoRoot, { pid: process.pid, startedAt });
463
+ await drainAndClose(server, inflight, opts.shutdownDrainMs ?? 5000);
464
+ }
465
+ //# sourceMappingURL=boot.js.map
@@ -1,5 +1,5 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
- import type { RateLimiter } from '../rate-limit.js';
2
+ import type { RateLimiter } from './rate-limit.js';
3
3
  /**
4
4
  * Rate-limit key for a request. Defaults to the socket's remote address.
5
5
  *
@@ -21,7 +21,11 @@ import type { RateLimiter } from '../rate-limit.js';
21
21
  * the client sent, so they never pick the bucket.
22
22
  */
23
23
  export declare function clientIpForRateLimit(req: IncomingMessage): string;
24
+ /** 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
+ export declare function warnIfClientIpHeaderUnpinned(): void;
24
26
  /** The key for one subscriber: an IPv6 address's /64, since one host may hold the whole /64; any other key as is. */
25
27
  export declare function subscriberKey(ip: string): string;
28
+ /** The one key every per-address limit and slot count uses, so rotating inside a /64 never buys a fresh bucket. */
29
+ export declare function clientLimitKey(req: IncomingMessage): string;
26
30
  export declare function enforceRateLimit(req: IncomingMessage, path: string, limiter?: RateLimiter): void;
27
31
  //# sourceMappingURL=client-ip.d.ts.map
@@ -1,8 +1,9 @@
1
1
  // Client IP keying and the per-IP rate limit for /v1 and /mcp.
2
- import { envClientIpHeader, envTrustedProxies } from '../env.js';
2
+ import { envClientIpHeader, envTrustedProxies } from '../util/env.js';
3
3
  import { BlockList, isIP } from 'node:net';
4
- import { log } from '../log.js';
5
- import { HttpError } from '../http-util.js';
4
+ import { log } from '../util/log.js';
5
+ import { HttpError } from '../util/http-util.js';
6
+ const IPV6_PREFIX_GROUPS = 4;
6
7
  /**
7
8
  * Rate-limit key for a request. Defaults to the socket's remote address.
8
9
  *
@@ -67,6 +68,14 @@ function trustedProxyList(raw) {
67
68
  trustedProxyCache = { raw, list };
68
69
  return list;
69
70
  }
71
+ /** 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. */
72
+ export function warnIfClientIpHeaderUnpinned() {
73
+ const header = envClientIpHeader();
74
+ if (!header || trustedProxyList(envTrustedProxies()))
75
+ return;
76
+ log.warn(`serve: HIPPO_CLIENT_IP_HEADER is ${header} and HIPPO_TRUSTED_PROXIES is unset, so any caller that reaches this port without passing the proxy can send that header and pick its own rate-limit bucket. ` +
77
+ "Set HIPPO_TRUSTED_PROXIES to the proxy's addresses or CIDRs, so the header is read from the proxy alone.");
78
+ }
70
79
  /** The key for one subscriber: an IPv6 address's /64, since one host may hold the whole /64; any other key as is. */
71
80
  export function subscriberKey(ip) {
72
81
  const bare = ip.split('%')[0];
@@ -80,7 +89,11 @@ export function subscriberKey(ip) {
80
89
  // A trailing dotted quad holds two groups; isIP has already checked the shape.
81
90
  const rightGroups = right.length + (right.at(-1)?.includes('.') ? 1 : 0);
82
91
  const groups = tail === undefined ? left : [...left, ...Array(8 - left.length - rightGroups).fill('0'), ...right];
83
- return `${groups.slice(0, 4).map((g) => parseInt(g, 16).toString(16)).join(':')}::/64`;
92
+ return `${groups.slice(0, IPV6_PREFIX_GROUPS).map((g) => parseInt(g, 16).toString(16)).join(':')}::/64`;
93
+ }
94
+ /** The one key every per-address limit and slot count uses, so rotating inside a /64 never buys a fresh bucket. */
95
+ export function clientLimitKey(req) {
96
+ return subscriberKey(clientIpForRateLimit(req));
84
97
  }
85
98
  function isTrustedProxy(list, ip) {
86
99
  const bare = ip.startsWith('::ffff:') && isIP(ip.slice(7)) === 4 ? ip.slice(7) : ip;
@@ -98,8 +111,7 @@ export function enforceRateLimit(req, path, limiter) {
98
111
  // HIPPO_CLIENT_IP_HEADER there so each real client gets its own bucket
99
112
  // (see clientIpForRateLimit).
100
113
  if (limiter && (path.startsWith('/v1/') || path === '/mcp' || path === '/mcp/stream')) {
101
- const ip = clientIpForRateLimit(req);
102
- if (!limiter.check(ip)) {
114
+ if (!limiter.check(clientLimitKey(req))) {
103
115
  throw new HttpError(429, 'rate limit exceeded', limiter.retryAfterSec);
104
116
  }
105
117
  }
@@ -1,5 +1,5 @@
1
1
  import type { ServerResponse } from 'node:http';
2
- import type { KeysetPosition } from '../keyset.js';
2
+ import type { KeysetPosition } from '../util/keyset.js';
3
3
  type CursorPart = 'string' | 'integer';
4
4
  /** Bare-array routes cannot grow a body field without breaking clients, so their next cursor rides this header. */
5
5
  export declare const NEXT_CURSOR_HEADER = "X-Next-Cursor";
@@ -1,6 +1,5 @@
1
- import { HttpError } from '../http-util.js';
2
- import { isJsonNumber } from './validation.js';
3
- import { isJsonString } from '../json.js';
1
+ import { HttpError } from '../util/http-util.js';
2
+ import { isJsonString, isJsonNumber } from '../util/json.js';
4
3
  /** Bare-array routes cannot grow a body field without breaking clients, so their next cursor rides this header. */
5
4
  export const NEXT_CURSOR_HEADER = 'X-Next-Cursor';
6
5
  const MAX_CURSOR_CHARS = 1024;
@@ -0,0 +1,13 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import { RequestDeadline } from '../util/request-scope.js';
3
+ /** Requests answered 504 by the handler deadline since the process started; /health reports it. */
4
+ export declare function handlerDeadlineCount(): number;
5
+ /** Whether `res` was answered at its deadline, so whatever its handler does later has no caller. */
6
+ export declare function isAbandoned(res: ServerResponse): boolean;
7
+ /** How long a request may run: 120 s, or HIPPO_REQUEST_DEADLINE_MS, where 0 turns the deadline off. */
8
+ export declare function requestDeadlineMs(): number;
9
+ /** The deadline of `req`, for every /v1 and /mcp route but the two exempt ones. */
10
+ export declare function requestDeadlineFor(req: IncomingMessage): RequestDeadline | undefined;
11
+ /** Calls `reply` when `res` has sent nothing by `deadline`. A store call still in flight answers first, since only the store knows what became of a write. */
12
+ export declare function answerAtDeadline(res: ServerResponse, deadline: RequestDeadline, reply: () => void): void;
13
+ //# sourceMappingURL=deadline.d.ts.map
@@ -0,0 +1,45 @@
1
+ import { envRequestDeadlineMs } from '../util/env.js';
2
+ import { RequestDeadline } from '../util/request-scope.js';
3
+ const DEFAULT_REQUEST_DEADLINE_MS = 120_000;
4
+ // Each has a deadline of its own kind: sleep stops its child process, and the stream is meant to stay open.
5
+ const EXEMPT = new Set(['POST /v1/sleep', 'GET /mcp/stream']);
6
+ const abandoned = new WeakSet();
7
+ let handlerDeadlines = 0;
8
+ /** Requests answered 504 by the handler deadline since the process started; /health reports it. */
9
+ export function handlerDeadlineCount() {
10
+ return handlerDeadlines;
11
+ }
12
+ /** Whether `res` was answered at its deadline, so whatever its handler does later has no caller. */
13
+ export function isAbandoned(res) {
14
+ return abandoned.has(res);
15
+ }
16
+ /** How long a request may run: 120 s, or HIPPO_REQUEST_DEADLINE_MS, where 0 turns the deadline off. */
17
+ export function requestDeadlineMs() {
18
+ return envRequestDeadlineMs() ?? DEFAULT_REQUEST_DEADLINE_MS;
19
+ }
20
+ /** The deadline of `req`, for every /v1 and /mcp route but the two exempt ones. */
21
+ export function requestDeadlineFor(req) {
22
+ const ms = requestDeadlineMs();
23
+ const path = (req.url ?? '/').split('?')[0] ?? '/';
24
+ if (ms === 0 || EXEMPT.has(`${req.method ?? 'GET'} ${path}`))
25
+ return undefined;
26
+ return path.startsWith('/v1/') || path === '/mcp' ? new RequestDeadline(Date.now() + ms) : undefined;
27
+ }
28
+ /** Calls `reply` when `res` has sent nothing by `deadline`. A store call still in flight answers first, since only the store knows what became of a write. */
29
+ export function answerAtDeadline(res, deadline, reply) {
30
+ const expire = () => {
31
+ if (res.headersSent || res.destroyed)
32
+ return;
33
+ handlerDeadlines += 1;
34
+ abandoned.add(res);
35
+ reply();
36
+ };
37
+ // One turn of the loop later, so a handler that fails on the store's answer sends that answer itself.
38
+ const timer = setTimeout(() => deadline.onceIdle(() => setImmediate(expire)), deadline.at - Date.now());
39
+ // The open socket keeps the process alive; this timer alone must not.
40
+ timer.unref();
41
+ const clear = () => clearTimeout(timer);
42
+ res.once('finish', clear);
43
+ res.once('close', clear);
44
+ }
45
+ //# sourceMappingURL=deadline.js.map
@@ -0,0 +1,8 @@
1
+ export interface KeyCheckBounds {
2
+ /** Throws the 429 a refused key check answers, before any derivation: no room left to wait (Retry-After 1), or `address` has spent its tries on `keyId` (Retry-After 12). */
3
+ admit(keyId: string, address: string): void;
4
+ /** Runs `derive` now or once a slot frees; `admit` in the same tick keeps the queue within its cap. */
5
+ run<T>(derive: () => Promise<T>): Promise<T>;
6
+ }
7
+ export declare function keyCheckBounds(maxKeys: number): KeyCheckBounds;
8
+ //# sourceMappingURL=key-check-bounds.d.ts.map