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,46 @@
1
+ // Bounds on the scrypt work a bearer key check may start: how many derive at once, and how many one address starts for one key id.
2
+ import { HttpError } from '../util/http-util.js';
3
+ import { createRateLimiter } from './rate-limit.js';
4
+ // libuv runs scrypt on a pool of four threads by default, so two stay free for file and DNS work.
5
+ const MAX_IN_FLIGHT = 2;
6
+ // Four rounds of two, so a burst of unproved keys waits its turn and no wait is longer than four derivations.
7
+ const MAX_WAITING = 8;
8
+ // Room for a mistyped or rotated secret; a secret is 160 random bits, so this bounds CPU, not guessing.
9
+ const KEY_ADDRESS_BURST = 5;
10
+ // One more try every 12 s: past its burst, an address starts at most five derivations a minute for one key id.
11
+ const KEY_ADDRESS_TRIES_PER_SEC = 5 / 60;
12
+ export function keyCheckBounds(maxKeys) {
13
+ // A bucket idle for a full refill is back at its burst, so dropping it then gives nothing away.
14
+ const idleEvictMs = (KEY_ADDRESS_BURST / KEY_ADDRESS_TRIES_PER_SEC) * 1000;
15
+ const perKeyAddress = createRateLimiter({ ratePerSec: KEY_ADDRESS_TRIES_PER_SEC, burst: KEY_ADDRESS_BURST, idleEvictMs, maxKeys });
16
+ let inFlight = 0;
17
+ const waiting = [];
18
+ return {
19
+ admit(keyId, address) {
20
+ // Each answers in the words an existing limit uses: the request limit's for a full queue, the address's scrypt bucket's for spent tries.
21
+ if (inFlight >= MAX_IN_FLIGHT && waiting.length >= MAX_WAITING)
22
+ throw new HttpError(429, 'rate limit exceeded', 1);
23
+ if (!perKeyAddress.check(`${keyId}\u0000${address}`)) {
24
+ throw new HttpError(429, 'too many key checks from this address', perKeyAddress.retryAfterSec);
25
+ }
26
+ },
27
+ async run(derive) {
28
+ if (inFlight < MAX_IN_FLIGHT)
29
+ inFlight++;
30
+ else
31
+ await new Promise((resolve) => { waiting.push(resolve); });
32
+ try {
33
+ return await derive();
34
+ }
35
+ finally {
36
+ // A waiter takes over this slot, so the count stays put across the handover and nothing slips in between.
37
+ const next = waiting.shift();
38
+ if (next)
39
+ next();
40
+ else
41
+ inFlight--;
42
+ }
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=key-check-bounds.js.map
@@ -1,4 +1,4 @@
1
- import { log } from '../log.js';
1
+ import { log } from '../util/log.js';
2
2
  /**
3
3
  * Stop accepting, end streams at once (they never finish on their own), give other in-flight
4
4
  * requests up to `drainMs`, then close whatever is left.
@@ -1,11 +1,8 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
- import type { Context } from '../api.js';
3
- import { type McpContext } from '../mcp/server.js';
4
- import type { CallerProject } from '../prompt-hook.js';
2
+ import type { CallerProject } from '../api/prompt-hook.js';
5
3
  import type { ResolvedServeOpts } from './types.js';
6
4
  /** On a shared store, the caller's project from X-Hippo-Project and the comma-separated X-Hippo-Project-Aliases; any other store ignores both. */
7
5
  export declare function callerProjectFromHeaders(req: IncomingMessage, hippoRoot: string): CallerProject | undefined;
8
- export declare function mcpContextFor(ctx: Context, clientKey: string, autoSleep: McpContext['autoSleep'], project?: CallerProject): McpContext;
9
6
  export declare function handleMcpPost(req: IncomingMessage, res: ServerResponse, opts: ResolvedServeOpts): Promise<void>;
10
7
  export declare function handleMcpStream(req: IncomingMessage, res: ServerResponse, opts: ResolvedServeOpts, streamSlots: Map<string, number>): Promise<void>;
11
8
  //# sourceMappingURL=mcp-http.d.ts.map
@@ -1,14 +1,17 @@
1
1
  // MCP over HTTP: POST /mcp and the GET /mcp/stream SSE keepalive.
2
- import { envMcpSseHeartbeatMs, envMcpSseMaxAgeSec, envMcpSseMaxStreams } from '../env.js';
2
+ import { envMcpSseHeartbeatMs, envMcpSseMaxAgeSec, envMcpSseMaxStreams } from '../util/env.js';
3
3
  import { createHash } from 'node:crypto';
4
- import { isSharedStore } from '../config.js';
4
+ import { isSharedStore } from '../core/config.js';
5
5
  import { handleMcpRequest, mcpErrorResponse } from '../mcp/server.js';
6
- import { HttpError, isJsonObjectRecord, readBody, sendJson } from '../http-util.js';
7
- import { assertCallerProject } from '../project-identity.js';
6
+ import { HttpError, readBody, sendJson } from '../util/http-util.js';
7
+ import { assertCallerProject } from '../core/project-identity.js';
8
8
  import { buildContextWithAuth, heartbeatVerdict, readAuthHeader, requireAuth } from './auth.js';
9
- import { clientIpForRateLimit } from './client-ip.js';
10
- import { requestIds } from './request.js';
11
- import { isJsonString } from '../json.js';
9
+ import { clientLimitKey, subscriberKey } from './client-ip.js';
10
+ import { noteAccess } from './request.js';
11
+ import { isJsonString, isJsonObject } from '../util/json.js';
12
+ import { FINGERPRINT_HEX_CHARS } from '../util/token-text.js';
13
+ const DEFAULT_SSE_HEARTBEAT_MS = 60000;
14
+ const DEFAULT_SSE_MAX_AGE_SEC = 3600;
12
15
  /**
13
16
  * Build a per-client key for MCP state isolation under HTTP-MCP. Used by
14
17
  * mcp/server.ts to scope `lastRecalledIds` to the calling client so two
@@ -23,9 +26,9 @@ import { isJsonString } from '../json.js';
23
26
  function buildMcpClientKey(req) {
24
27
  const auth = readAuthHeader(req);
25
28
  const tokenHash = auth.kind === 'bearer'
26
- ? createHash('sha256').update(auth.token).digest('hex').slice(0, 16)
29
+ ? createHash('sha256').update(auth.token).digest('hex').slice(0, FINGERPRINT_HEX_CHARS)
27
30
  : 'noauth';
28
- const addr = req.socket.remoteAddress ?? 'unknown';
31
+ const addr = subscriberKey(req.socket.remoteAddress ?? 'unknown');
29
32
  return `http:${tokenHash}:${addr}`;
30
33
  }
31
34
  // ── MCP-over-HTTP/SSE transport ──
@@ -77,7 +80,7 @@ export function callerProjectFromHeaders(req, hippoRoot) {
77
80
  assertCallerProject({ name, aliases });
78
81
  return { name, legacyName: name, aliases };
79
82
  }
80
- export function mcpContextFor(ctx, clientKey, autoSleep, project) {
83
+ function mcpContextFor(ctx, clientKey, autoSleep, project) {
81
84
  const mcpCtx = {
82
85
  hippoRoot: ctx.hippoRoot,
83
86
  tenantId: ctx.tenantId,
@@ -104,6 +107,7 @@ export async function handleMcpPost(req, res, opts) {
104
107
  // pull tenant from HIPPO_TENANT, dropping a valid Bearer for tenant B
105
108
  // back to whatever the env says.
106
109
  const ctx = await buildContextWithAuth(req, opts);
110
+ noteAccess(req, { tenant: ctx.tenantId });
107
111
  const project = callerProjectFromHeaders(req, ctx.hippoRoot);
108
112
  const raw = await readBody(req);
109
113
  let mcpReq;
@@ -113,7 +117,7 @@ export async function handleMcpPost(req, res, opts) {
113
117
  catch {
114
118
  throw new HttpError(400, 'invalid JSON-RPC body');
115
119
  }
116
- if (!isJsonObjectRecord(mcpReq) || !isJsonString(mcpReq.method)) {
120
+ if (!isJsonObject(mcpReq) || !isJsonString(mcpReq.method)) {
117
121
  throw new HttpError(400, 'JSON-RPC body must include a method string');
118
122
  }
119
123
  // SAFETY: validated above as a plain JSON object carrying a string method;
@@ -125,7 +129,7 @@ export async function handleMcpPost(req, res, opts) {
125
129
  mcpRes = await handleMcpRequest(rpcReq, mcpContextFor(ctx, buildMcpClientKey(req), opts.autoSleep, project));
126
130
  }
127
131
  catch (err) {
128
- mcpRes = mcpErrorResponse(rpcReq.id, err, requestIds.get(req));
132
+ mcpRes = mcpErrorResponse(rpcReq.id, err);
129
133
  }
130
134
  if (mcpRes === null) {
131
135
  // Notification — no body, 202 Accepted.
@@ -141,8 +145,8 @@ const DEFAULT_MAX_STREAMS_PER_CLIENT = 8;
141
145
  function streamSlotKey(req) {
142
146
  const auth = readAuthHeader(req);
143
147
  if (auth.kind === 'bearer')
144
- return `key:${createHash('sha256').update(auth.token).digest('hex').slice(0, 16)}`;
145
- return `ip:${clientIpForRateLimit(req)}`;
148
+ return `key:${createHash('sha256').update(auth.token).digest('hex').slice(0, FINGERPRINT_HEX_CHARS)}`;
149
+ return `ip:${clientLimitKey(req)}`;
146
150
  }
147
151
  /** Takes a stream slot or throws 429; the slot is released once, when the response closes. */
148
152
  function acquireStreamSlot(req, res, slots) {
@@ -181,8 +185,11 @@ export async function handleMcpStream(req, res, opts, streamSlots) {
181
185
  // with reason='max_age_exceeded' when reached.
182
186
  // - MCP_SSE_HEARTBEAT_MS (default 60000) lets tests run with a short
183
187
  // interval without waiting a full minute.
184
- const heartbeatMs = envMcpSseHeartbeatMs() ?? 60000;
185
- const maxAgeMs = (envMcpSseMaxAgeSec() ?? 3600) * 1000;
188
+ keepStreamAlive(req, res, opts);
189
+ }
190
+ function keepStreamAlive(req, res, opts) {
191
+ const heartbeatMs = envMcpSseHeartbeatMs() ?? DEFAULT_SSE_HEARTBEAT_MS;
192
+ const maxAgeMs = (envMcpSseMaxAgeSec() ?? DEFAULT_SSE_MAX_AGE_SEC) * 1000;
186
193
  const startedAt = Date.now();
187
194
  let closed = false;
188
195
  let checking = false;
@@ -190,14 +197,7 @@ export async function handleMcpStream(req, res, opts, streamSlots) {
190
197
  if (closed)
191
198
  return;
192
199
  closed = true;
193
- try {
194
- res.write(`event: closed\ndata: ${JSON.stringify({ reason })}\n\n`);
195
- }
196
- catch { /* socket already gone */ }
197
- try {
198
- res.end();
199
- }
200
- catch { /* socket already gone */ }
200
+ endStreamWithReason(res, reason);
201
201
  };
202
202
  const ping = setInterval(() => {
203
203
  if (closed) {
@@ -239,4 +239,14 @@ export async function handleMcpStream(req, res, opts, streamSlots) {
239
239
  clearInterval(ping);
240
240
  });
241
241
  }
242
+ function endStreamWithReason(res, reason) {
243
+ try {
244
+ res.write(`event: closed\ndata: ${JSON.stringify({ reason })}\n\n`);
245
+ }
246
+ catch { /* socket already gone */ }
247
+ try {
248
+ res.end();
249
+ }
250
+ catch { /* socket already gone */ }
251
+ }
242
252
  //# sourceMappingURL=mcp-http.js.map
@@ -0,0 +1,7 @@
1
+ import type { HippoStore } from '../store/index.js';
2
+ export type ReadyProbe = () => Promise<boolean>;
3
+ /** The shared probe for a served store, so every request to that server draws on one remembered answer. */
4
+ export declare function readyProbeFor(store: HippoStore, readiness: {
5
+ ping(): Promise<void>;
6
+ }, now?: () => number): ReadyProbe;
7
+ //# sourceMappingURL=ready.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { SERVER_DB_WAIT_MS, runWithRequestStores } from '../db/index.js';
2
+ import { errorFields, errorMessage, log } from '../util/log.js';
3
+ // A prober must never see a 429, so the store read is bounded by remembering its answer instead of rate-limiting the route.
4
+ const READY_WINDOW_MS = 1000;
5
+ /** True when the store answered; one read per window whatever the caller count, and a failed read is remembered for the same window. */
6
+ function createReadyProbe(readiness, now = Date.now) {
7
+ let answer;
8
+ let inFlight;
9
+ async function read() {
10
+ let ok = true;
11
+ try {
12
+ await runWithRequestStores(() => readiness.ping(), { busyWaitMs: SERVER_DB_WAIT_MS });
13
+ }
14
+ catch (err) {
15
+ log.warn(`GET /ready: the store did not answer: ${errorMessage(err)}`, errorFields(err));
16
+ ok = false;
17
+ }
18
+ answer = { at: now(), ok };
19
+ return ok;
20
+ }
21
+ return () => {
22
+ if (answer !== undefined && now() - answer.at < READY_WINDOW_MS)
23
+ return Promise.resolve(answer.ok);
24
+ inFlight ??= read().finally(() => { inFlight = undefined; });
25
+ return inFlight;
26
+ };
27
+ }
28
+ const probes = new WeakMap();
29
+ /** The shared probe for a served store, so every request to that server draws on one remembered answer. */
30
+ export function readyProbeFor(store, readiness, now = Date.now) {
31
+ let probe = probes.get(store);
32
+ if (probe === undefined) {
33
+ probe = createReadyProbe(readiness, now);
34
+ probes.set(store, probe);
35
+ }
36
+ return probe;
37
+ }
38
+ //# sourceMappingURL=ready.js.map
@@ -1,13 +1,20 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
- /** The caller's `X-Request-Id` when it is a short plain token, else a fresh UUID. */
3
- export declare function resolveRequestId(header: string | string[] | undefined): string;
4
2
  /** One line per failed request; 4xx is the caller's mistake, a busy 503 is back-pressure and a 501 is a route not on this store, so none logs as an error. */
5
- export declare function logRequestFailure<E>(req: IncomingMessage, err: E, requestId: string, status: number): void;
3
+ export declare function logRequestFailure<E>(req: IncomingMessage, err: E, status: number): void;
6
4
  /** The status and client message for a failed request; a held write lock is a retryable 503, never a 500. */
7
5
  export declare function replyFor<E>(err: E): {
8
6
  status: number;
9
7
  message: string;
10
8
  };
9
+ /** What the route layer learned about a request, for its access line. */
10
+ interface AccessNote {
11
+ route?: string;
12
+ tenant?: string;
13
+ }
14
+ /** Names the matched route (the table's pattern, never the path sent) or the caller's tenant for the request's access line. */
15
+ export declare function noteAccess(req: IncomingMessage, note: AccessNote): void;
16
+ /** The request's id, after stamping the headers every reply carries and starting the slow-request watchdog and the access line. */
17
+ export declare function openRequest(req: IncomingMessage, res: ServerResponse, slowWarnMs?: number): string;
11
18
  export declare function sendError(res: ServerResponse, status: number, message: string): void;
12
19
  interface ParsedRoute {
13
20
  method: string;
@@ -16,7 +23,6 @@ interface ParsedRoute {
16
23
  }
17
24
  export declare function parseRequest(req: IncomingMessage): ParsedRoute;
18
25
  export declare function matchPath(pattern: string, path: string): Record<string, string> | null;
19
- export declare const requestIds: WeakMap<IncomingMessage, string>;
20
26
  /**
21
27
  * Reject URL-encoded slashes in path segments BEFORE the URL parser decodes
22
28
  * them — otherwise `%2F` becomes `/`, path-split runs, and the route either
@@ -1,29 +1,82 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { isStoreBusy, STORE_BUSY_MESSAGE } from '../db.js';
3
- import { errorFields, log } from '../log.js';
4
- import { HttpError, mapApiError, sendJson } from '../http-util.js';
2
+ import { isStoreBusy, STORE_BUSY_MESSAGE } from '../db/index.js';
3
+ import { errorFields, errorMessage, log } from '../util/log.js';
4
+ import { HttpError, mapApiError, sendJson } from '../util/http-util.js';
5
5
  // The caller's id lands in a response header and in logs, so only a short plain token is echoed back.
6
6
  const REQUEST_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
7
7
  /** The caller's `X-Request-Id` when it is a short plain token, else a fresh UUID. */
8
- export function resolveRequestId(header) {
8
+ function resolveRequestId(header) {
9
9
  const value = Array.isArray(header) ? undefined : header;
10
10
  return value && REQUEST_ID_RE.test(value) ? value : randomUUID();
11
11
  }
12
12
  /** One line per failed request; 4xx is the caller's mistake, a busy 503 is back-pressure and a 501 is a route not on this store, so none logs as an error. */
13
- export function logRequestFailure(req, err, requestId, status) {
14
- const message = err instanceof Error ? err.message : String(err);
13
+ export function logRequestFailure(req, err, status) {
14
+ const message = errorMessage(err);
15
15
  const line = `${req.method ?? 'GET'} ${(req.url ?? '/').split('?')[0]} failed: ${message}`;
16
- if (isStoreBusy(err))
17
- log.warn(line, { requestId, status });
16
+ // A 5xx that tells the caller when to retry is back-pressure too.
17
+ if (isStoreBusy(err) || (status >= 500 && err instanceof HttpError && err.retryAfterSec !== undefined))
18
+ log.warn(line, { status });
18
19
  else if (status >= 500 && status !== 501)
19
- log.error(line, { requestId, status, ...errorFields(err) });
20
+ log.error(line, { status, ...errorFields(err) });
20
21
  else
21
- log.info(line, { requestId, status });
22
+ log.info(line, { status });
22
23
  }
23
24
  /** The status and client message for a failed request; a held write lock is a retryable 503, never a 500. */
24
25
  export function replyFor(err) {
25
26
  return isStoreBusy(err) ? { status: 503, message: STORE_BUSY_MESSAGE } : mapApiError(err);
26
27
  }
28
+ // Above the 30 s body deadline and the 5 s resolver deadline, so a request those govern is answered before it is called slow.
29
+ const SLOW_REQUEST_WARN_MS = 60_000;
30
+ /** Logs one warn when `res` has sent nothing after `afterMs`. It never ends the request or touches the reply; the timer goes when the reply finishes or the socket closes. */
31
+ function watchSlowRequest(req, res, requestId, afterMs = SLOW_REQUEST_WARN_MS) {
32
+ const startedAt = Date.now();
33
+ const timer = setTimeout(() => {
34
+ // A reply already under way is a stream doing its job, not a stuck request.
35
+ if (res.headersSent)
36
+ return;
37
+ log.warn(`${req.method ?? 'GET'} ${(req.url ?? '/').split('?')[0]} is still running`, { requestId, elapsedMs: Date.now() - startedAt });
38
+ }, afterMs);
39
+ // The watchdog alone must never keep the process alive.
40
+ timer.unref();
41
+ const clear = () => clearTimeout(timer);
42
+ res.once('finish', clear);
43
+ res.once('close', clear);
44
+ }
45
+ const accessNotes = new WeakMap();
46
+ // A path that matched no route is caller data, so the access line never repeats it.
47
+ const UNMATCHED_ROUTE = 'unmatched';
48
+ /** Names the matched route (the table's pattern, never the path sent) or the caller's tenant for the request's access line. */
49
+ export function noteAccess(req, note) {
50
+ const held = accessNotes.get(req);
51
+ if (held)
52
+ Object.assign(held, note);
53
+ }
54
+ /** One info line per finished request. A path id and a query string can both hold caller data, so the line carries neither. */
55
+ function logAccessWhenFinished(req, res, requestId) {
56
+ const note = {};
57
+ accessNotes.set(req, note);
58
+ const startedAt = performance.now();
59
+ res.once('finish', () => {
60
+ log.info('request', {
61
+ requestId,
62
+ method: req.method ?? 'GET',
63
+ route: note.route ?? UNMATCHED_ROUTE,
64
+ status: res.statusCode,
65
+ durationMs: Math.round(performance.now() - startedAt),
66
+ tenant: note.tenant,
67
+ });
68
+ });
69
+ }
70
+ /** The request's id, after stamping the headers every reply carries and starting the slow-request watchdog and the access line. */
71
+ export function openRequest(req, res, slowWarnMs) {
72
+ const requestId = resolveRequestId(req.headers['x-request-id']);
73
+ res.setHeader('X-Request-Id', requestId);
74
+ // Memory text is caller-written, so no browser may guess a reply into HTML or script.
75
+ res.setHeader('X-Content-Type-Options', 'nosniff');
76
+ watchSlowRequest(req, res, requestId, slowWarnMs);
77
+ logAccessWhenFinished(req, res, requestId);
78
+ return requestId;
79
+ }
27
80
  export function sendError(res, status, message) {
28
81
  sendJson(res, status, { error: message });
29
82
  }
@@ -82,8 +135,6 @@ export function matchPath(pattern, path) {
82
135
  }
83
136
  return params;
84
137
  }
85
- // The auth helpers only see the request, so its id rides here for their log lines.
86
- export const requestIds = new WeakMap();
87
138
  /**
88
139
  * Reject URL-encoded slashes in path segments BEFORE the URL parser decodes
89
140
  * them — otherwise `%2F` becomes `/`, path-split runs, and the route either
@@ -0,0 +1,15 @@
1
+ import type { AddonRoute, ResolvedServeOpts, RouteRequest } from './types.js';
2
+ import type { JsonValue } from '../util/json.js';
3
+ export declare function isPublicRoute(method: string, path: string): boolean;
4
+ /** Run the first /v1 route whose method and path match. */
5
+ export declare function dispatchV1Route(r: RouteRequest, method: string, path: string): Promise<boolean>;
6
+ /** Boot-time check: an add-on path must be plain, unique and not one core serves, so no add-on shadows a core route or hides from dispatch. */
7
+ export declare function assertAddonRoutes(routes: readonly AddonRoute[]): void;
8
+ /** Boot-time check and serialization: a public path that a core GET route serves would open that route to anyone. */
9
+ export declare function assertPublicJson(publicJson: Readonly<Record<string, JsonValue>>): ReadonlyMap<string, string>;
10
+ /** Core authenticates and parses before the handler runs, so an add-on route gets the same 401, 400 and 501 as a core one. */
11
+ export declare function dispatchAddonRoute({ req, res, opts }: RouteRequest, method: string, path: string): Promise<boolean>;
12
+ /** No auth, body read or store access, so a caller with no key gets it under any store. */
13
+ export declare function dispatchPublicJson({ req, res, opts }: RouteRequest, method: string, path: string): boolean;
14
+ export declare function assertSqliteStore(opts: ResolvedServeOpts): void;
15
+ //# sourceMappingURL=route-table.d.ts.map
@@ -0,0 +1,209 @@
1
+ import { withSqliteOffLoop } from '../db/index.js';
2
+ import { hasGroup } from '../store/index.js';
3
+ import { runsOffLoop } from '../store/sqlite/worker-store.js';
4
+ import { HttpError, JSON_HEADERS, sendJson, STORE_NOT_PORTED_MESSAGE } from '../util/http-util.js';
5
+ import { buildContextWithAuth, requireAuth } from './auth.js';
6
+ import { matchPath, noteAccess } from './request.js';
7
+ import { handleApproveQuarantine, handleCreateAuthKey, handleListAudit, handleListAuthKeys, handleListQuarantine, handleRejectQuarantine, handleRevokeAuthKey } from './routes/admin.js';
8
+ import { handleCloseCustomerNote, handleCreateCustomerNote, handleGetCustomerNote, handleListCustomerNotes, handleSupersedeCustomerNote } from './routes/customer-notes.js';
9
+ import { handleCloseDecision, handleCreateDecision, handleGetDecision, handleListDecisions, handleSupersedeDecision } from './routes/decisions.js';
10
+ import { handleCloseIncident, handleCreateIncident, handleGetIncident, handleListIncidents, handleResolveIncident } from './routes/incidents.js';
11
+ import { handleApplyOutcome, handleArchiveMemory, handleCreateMemory, handleForgetMemory, handleGetGraph, handlePromoteMemory, handleSleep, handleSupersedeMemory } from './routes/memories.js';
12
+ import { handleClosePolicy, handleCreatePolicy, handleGetPolicy, handleListPolicies, handlePoliciesAsOf, handleSupersedePolicy } from './routes/policies.js';
13
+ import { handleClosePrediction, handleCreatePrediction, handleGetPrediction, handleListPredictions, handlePredictionStats } from './routes/predictions.js';
14
+ import { handleCloseProcess, handleCreateProcess, handleGetProcess, handleListProcesses, handleSupersedeProcess } from './routes/processes.js';
15
+ import { handleCloseProjectBrief, handleCreateProjectBrief, handleGetProjectBrief, handleListProjectBriefs, handleRefreshProjectBrief, handleSupersedeProjectBrief } from './routes/project-briefs.js';
16
+ import { handleAssembleSession, handleDrillRecall, handleGetContext, handleRecallMemories } from './routes/recall.js';
17
+ import { handleCloseSkill, handleCreateSkill, handleExportSkills, handleGetSkill, handleListSkills, handleSupersedeSkill } from './routes/skills.js';
18
+ import { parseJsonBody } from './validation.js';
19
+ // Review patch #2: explicit allow-list for unauthenticated /v1/* routes.
20
+ // New unauth routes MUST be added here AND get a corresponding entry in
21
+ // tests/server-bearer-lockdown.test.ts. Do not gate auth elsewhere by
22
+ // `path.startsWith` — pattern-positional auth is bypass-by-accident.
23
+ //
24
+ // The route handlers consult `isPublicRoute` before invoking
25
+ // `buildContextWithAuth` / `requireAuth`. Adding a route here without
26
+ // adding the corresponding `isPublicRoute` short-circuit in a handler is
27
+ // a no-op (auth still applies), so the failure mode is fail-closed.
28
+ // The only other unauthenticated paths are ServeOpts.publicJson's: GET only, checked at boot by assertPublicJson.
29
+ const PUBLIC_ROUTES = new Set([
30
+ 'POST /v1/connectors/slack/events',
31
+ 'POST /v1/connectors/github/events',
32
+ ]);
33
+ export function isPublicRoute(method, path) {
34
+ return PUBLIC_ROUTES.has(`${method} ${path}`);
35
+ }
36
+ /** The /v1 routes in dispatch order; the first entry whose method and path match handles the request. */
37
+ const V1_ROUTES = [
38
+ { method: 'POST', path: '/v1/memories', storeReady: 'entryWrites', loop: 'off', handler: handleCreateMemory },
39
+ { method: 'GET', path: '/v1/graph', storeReady: 'graphReads', loop: 'off', handler: handleGetGraph },
40
+ { method: 'GET', path: '/v1/memories', storeReady: 'base', loop: 'off', handler: handleRecallMemories },
41
+ { method: 'GET', pattern: '/v1/sessions/:id/assemble', storeReady: 'dagReads', loop: 'off', handler: handleAssembleSession },
42
+ { method: 'GET', pattern: '/v1/recall/drill/:id', storeReady: 'dagReads', handler: handleDrillRecall },
43
+ { method: 'POST', pattern: '/v1/memories/:id/archive', storeReady: 'entryWrites', loop: 'off', handler: handleArchiveMemory },
44
+ { method: 'POST', pattern: '/v1/memories/:id/supersede', storeReady: 'entryWrites', loop: 'off', handler: handleSupersedeMemory },
45
+ { method: 'POST', pattern: '/v1/memories/:id/promote', sqliteOnly: 'copies a memory between the two local hippo.db files', handler: handlePromoteMemory },
46
+ { method: 'DELETE', pattern: '/v1/memories/:id', storeReady: 'entryWrites', loop: 'off', handler: handleForgetMemory },
47
+ { method: 'POST', path: '/v1/outcome', storeReady: 'entryWrites', handler: handleApplyOutcome },
48
+ { method: 'GET', path: '/v1/context', storeReady: 'contextReads', handler: handleGetContext },
49
+ { method: 'POST', path: '/v1/sleep', sqliteOnly: 'consolidates every tenant under the local hippo root in this process', handler: handleSleep },
50
+ { method: 'POST', path: '/v1/auth/keys', storeReady: 'keyWrites', loop: 'off', handler: handleCreateAuthKey },
51
+ { method: 'GET', path: '/v1/auth/keys', storeReady: 'keyWrites', loop: 'off', handler: handleListAuthKeys },
52
+ { method: 'DELETE', pattern: '/v1/auth/keys/:keyId', storeReady: 'keyAudit', loop: 'off', handler: handleRevokeAuthKey },
53
+ { method: 'GET', path: '/v1/quarantine', storeReady: 'quarantine', loop: 'off', handler: handleListQuarantine },
54
+ { method: 'POST', pattern: '/v1/quarantine/:id/approve', storeReady: 'quarantine', loop: 'off', handler: handleApproveQuarantine },
55
+ { method: 'POST', pattern: '/v1/quarantine/:id/reject', storeReady: 'quarantine', loop: 'off', handler: handleRejectQuarantine },
56
+ { method: 'GET', path: '/v1/audit', storeReady: 'auditLog', loop: 'off', handler: handleListAudit },
57
+ { method: 'POST', path: '/v1/predictions', storeReady: 'predictions', loop: 'off', handler: handleCreatePrediction },
58
+ { method: 'GET', path: '/v1/predictions', storeReady: 'predictions', loop: 'off', handler: handleListPredictions },
59
+ { method: 'GET', path: '/v1/predictions/stats', storeReady: 'predictions', loop: 'off', handler: handlePredictionStats },
60
+ { method: 'GET', regex: /^\/v1\/predictions\/(\d+)$/, storeReady: 'predictions', loop: 'off', handler: handleGetPrediction },
61
+ { method: 'POST', regex: /^\/v1\/predictions\/(\d+)\/close$/, storeReady: 'predictions', loop: 'off', handler: handleClosePrediction },
62
+ { method: 'POST', path: '/v1/decisions', storeReady: 'objects', handler: handleCreateDecision },
63
+ { method: 'GET', path: '/v1/decisions', storeReady: 'objects', handler: handleListDecisions },
64
+ { method: 'POST', regex: /^\/v1\/decisions\/(\d+)\/supersede$/, storeReady: 'objects', handler: handleSupersedeDecision },
65
+ { method: 'POST', regex: /^\/v1\/decisions\/(\d+)\/close$/, storeReady: 'objects', handler: handleCloseDecision },
66
+ { method: 'GET', regex: /^\/v1\/decisions\/(\d+)$/, storeReady: 'objects', handler: handleGetDecision },
67
+ { method: 'POST', path: '/v1/incidents', storeReady: 'objects', handler: handleCreateIncident },
68
+ { method: 'GET', path: '/v1/incidents', storeReady: 'objects', handler: handleListIncidents },
69
+ { method: 'POST', regex: /^\/v1\/incidents\/(\d+)\/resolve$/, storeReady: 'objects', handler: handleResolveIncident },
70
+ { method: 'POST', regex: /^\/v1\/incidents\/(\d+)\/close$/, storeReady: 'objects', handler: handleCloseIncident },
71
+ { method: 'GET', regex: /^\/v1\/incidents\/(\d+)$/, storeReady: 'objects', handler: handleGetIncident },
72
+ { method: 'POST', path: '/v1/processes', storeReady: 'objects', handler: handleCreateProcess },
73
+ { method: 'GET', path: '/v1/processes', storeReady: 'objects', handler: handleListProcesses },
74
+ { method: 'POST', regex: /^\/v1\/processes\/(\d+)\/supersede$/, storeReady: 'objects', handler: handleSupersedeProcess },
75
+ { method: 'POST', regex: /^\/v1\/processes\/(\d+)\/close$/, storeReady: 'objects', handler: handleCloseProcess },
76
+ { method: 'GET', regex: /^\/v1\/processes\/(\d+)$/, storeReady: 'objects', handler: handleGetProcess },
77
+ { method: 'POST', path: '/v1/policies', storeReady: 'objects', handler: handleCreatePolicy },
78
+ { method: 'GET', path: '/v1/policies', storeReady: 'objects', handler: handleListPolicies },
79
+ { method: 'GET', path: '/v1/policies/asof', storeReady: 'objects', handler: handlePoliciesAsOf },
80
+ { method: 'POST', regex: /^\/v1\/policies\/(\d+)\/supersede$/, storeReady: 'objects', handler: handleSupersedePolicy },
81
+ { method: 'POST', regex: /^\/v1\/policies\/(\d+)\/close$/, storeReady: 'objects', handler: handleClosePolicy },
82
+ { method: 'GET', regex: /^\/v1\/policies\/(\d+)$/, storeReady: 'objects', handler: handleGetPolicy },
83
+ { method: 'POST', path: '/v1/skills', storeReady: 'objects', handler: handleCreateSkill },
84
+ { method: 'GET', path: '/v1/skills', storeReady: 'objects', handler: handleListSkills },
85
+ { method: 'GET', path: '/v1/skills/export', storeReady: 'objects', handler: handleExportSkills },
86
+ { method: 'POST', regex: /^\/v1\/skills\/(\d+)\/supersede$/, storeReady: 'objects', handler: handleSupersedeSkill },
87
+ { method: 'POST', regex: /^\/v1\/skills\/(\d+)\/close$/, storeReady: 'objects', handler: handleCloseSkill },
88
+ { method: 'GET', regex: /^\/v1\/skills\/(\d+)$/, storeReady: 'objects', handler: handleGetSkill },
89
+ { method: 'POST', path: '/v1/project-briefs', storeReady: 'objects', handler: handleCreateProjectBrief },
90
+ { method: 'GET', path: '/v1/project-briefs', storeReady: 'objects', handler: handleListProjectBriefs },
91
+ { method: 'POST', path: '/v1/project-briefs/refresh', storeReady: 'objects', handler: handleRefreshProjectBrief },
92
+ { method: 'POST', regex: /^\/v1\/project-briefs\/(\d+)\/supersede$/, storeReady: 'objects', handler: handleSupersedeProjectBrief },
93
+ { method: 'POST', regex: /^\/v1\/project-briefs\/(\d+)\/close$/, storeReady: 'objects', handler: handleCloseProjectBrief },
94
+ { method: 'GET', regex: /^\/v1\/project-briefs\/(\d+)$/, storeReady: 'objects', handler: handleGetProjectBrief },
95
+ { method: 'POST', path: '/v1/customer-notes', storeReady: 'objects', handler: handleCreateCustomerNote },
96
+ { method: 'GET', path: '/v1/customer-notes', storeReady: 'objects', handler: handleListCustomerNotes },
97
+ { method: 'POST', regex: /^\/v1\/customer-notes\/(\d+)\/supersede$/, storeReady: 'objects', handler: handleSupersedeCustomerNote },
98
+ { method: 'POST', regex: /^\/v1\/customer-notes\/(\d+)\/close$/, storeReady: 'objects', handler: handleCloseCustomerNote },
99
+ { method: 'GET', regex: /^\/v1\/customer-notes\/(\d+)$/, storeReady: 'objects', handler: handleGetCustomerNote },
100
+ ];
101
+ /** The route's handler bound to this request's path params, or null when method or path differ. The matcher runs before the
102
+ * method check, as the inline route blocks did, so a malformed `%` escape still throws from matchPath on any method. */
103
+ function routeMatches(route, method, path) {
104
+ if ('path' in route)
105
+ return method === route.method && path === route.path ? route.handler : null;
106
+ if ('pattern' in route) {
107
+ const params = matchPath(route.pattern, path);
108
+ return method === route.method && params ? (r) => route.handler(r, params) : null;
109
+ }
110
+ const match = path.match(route.regex);
111
+ return method === route.method && match ? (r) => route.handler(r, match) : null;
112
+ }
113
+ /** The route as the access line names it; a regex route reads as its pattern would, so no line carries a caller's id. */
114
+ function routeLabel(route) {
115
+ if ('path' in route)
116
+ return route.path;
117
+ if ('pattern' in route)
118
+ return route.pattern;
119
+ return route.regex.source.replace(/^\^|\$$/g, '').replaceAll('\\/', '/').replaceAll('(\\d+)', ':id');
120
+ }
121
+ /** Run the first /v1 route whose method and path match. */
122
+ export async function dispatchV1Route(r, method, path) {
123
+ for (const route of V1_ROUTES) {
124
+ const run = routeMatches(route, method, path);
125
+ if (run === null)
126
+ continue;
127
+ noteAccess(r.req, { route: routeLabel(route) });
128
+ await refuseUnportedRoute(r.req, r.opts, route.storeReady);
129
+ // Only a store with worker threads has moved the route's SQLite work; under any other the handler still opens hippo.db itself.
130
+ await (route.loop === 'off' && runsOffLoop(r.opts.store) ? withSqliteOffLoop(() => run(r)) : run(r));
131
+ return true;
132
+ }
133
+ return false;
134
+ }
135
+ const PLAIN_SEGMENT_RE = /^[A-Za-z0-9._~-]+$/;
136
+ function isPlainV1Path(path) {
137
+ return path.startsWith('/v1/') && new URL(path, 'http://h').pathname === path
138
+ && path.slice('/v1/'.length).split('/').every((segment) => PLAIN_SEGMENT_RE.test(segment));
139
+ }
140
+ // A plain path never holds a `%`, so matchPath cannot throw here.
141
+ function isCorePath(method, path) {
142
+ return PUBLIC_ROUTES.has(`${method} ${path}`) || V1_ROUTES.some((route) => routeMatches(route, method, path) !== null);
143
+ }
144
+ /** Boot-time check: an add-on path must be plain, unique and not one core serves, so no add-on shadows a core route or hides from dispatch. */
145
+ export function assertAddonRoutes(routes) {
146
+ const seen = new Set();
147
+ for (const { path } of routes) {
148
+ if (!isPlainV1Path(path))
149
+ throw new Error(`add-on route '${path}' is not a plain /v1/ path (segments use A-Z a-z 0-9 . _ ~ -)`);
150
+ if (seen.has(path))
151
+ throw new Error(`add-on route '${path}' is registered twice`);
152
+ if (isCorePath('POST', path))
153
+ throw new Error(`add-on route '${path}' is already served by core`);
154
+ seen.add(path);
155
+ }
156
+ }
157
+ const PUBLIC_JSON_MAX_BYTES = 64 * 1024;
158
+ /** Boot-time check and serialization: a public path that a core GET route serves would open that route to anyone. */
159
+ export function assertPublicJson(publicJson) {
160
+ const bodies = new Map();
161
+ for (const [path, value] of Object.entries(publicJson)) {
162
+ if (!isPlainV1Path(path))
163
+ throw new Error(`public JSON path '${path}' is not a plain /v1/ path (segments use A-Z a-z 0-9 . _ ~ -)`);
164
+ if (isCorePath('GET', path))
165
+ throw new Error(`public JSON path '${path}' is already served by core`);
166
+ const text = JSON.stringify(value);
167
+ if (text === undefined)
168
+ throw new Error(`public JSON at '${path}' is not JSON`);
169
+ if (Buffer.byteLength(text) > PUBLIC_JSON_MAX_BYTES)
170
+ throw new Error(`public JSON at '${path}' is over 64 KiB`);
171
+ bodies.set(path, text);
172
+ }
173
+ return bodies;
174
+ }
175
+ /** Core authenticates and parses before the handler runs, so an add-on route gets the same 401, 400 and 501 as a core one. */
176
+ export async function dispatchAddonRoute({ req, res, opts }, method, path) {
177
+ const route = method === 'POST' ? opts.routes?.find((r) => r.path === path) : undefined;
178
+ if (!route)
179
+ return false;
180
+ noteAccess(req, { route: route.path });
181
+ await refuseUnportedRoute(req, opts, route.storeReady);
182
+ const ctx = await buildContextWithAuth(req, opts);
183
+ noteAccess(req, { tenant: ctx.tenantId });
184
+ const body = await parseJsonBody(req, ctx);
185
+ sendJson(res, 200, await route.handler({ ctx, body }));
186
+ return true;
187
+ }
188
+ /** No auth, body read or store access, so a caller with no key gets it under any store. */
189
+ export function dispatchPublicJson({ req, res, opts }, method, path) {
190
+ const text = method === 'GET' ? opts.publicJsonBodies.get(path) : undefined;
191
+ if (text === undefined)
192
+ return false;
193
+ noteAccess(req, { route: path });
194
+ res.writeHead(200, { ...JSON_HEADERS, 'cache-control': 'no-store' });
195
+ res.end(text);
196
+ return true;
197
+ }
198
+ export function assertSqliteStore(opts) {
199
+ if (opts.store.kind !== 'sqlite')
200
+ throw new HttpError(501, STORE_NOT_PORTED_MESSAGE);
201
+ }
202
+ /** Under another store, a route that names no group, or one the store lacks, answers 501 without running; the caller is checked first, so a bad key is still a 401. */
203
+ async function refuseUnportedRoute(req, opts, group) {
204
+ if (opts.store.kind === 'sqlite' || (group !== undefined && hasGroup(opts.store, group)))
205
+ return;
206
+ await requireAuth(req, opts);
207
+ assertSqliteStore(opts);
208
+ }
209
+ //# sourceMappingURL=route-table.js.map