hippo-memory 1.60.0 → 1.62.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 (593) hide show
  1. package/README.md +29 -54
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.d.ts +1 -1
  4. package/dist/agent-memories/apply.js +4 -1
  5. package/dist/agent-memories/claude-code.d.ts +3 -1
  6. package/dist/agent-memories/claude-code.js +54 -10
  7. package/dist/agent-memories/codex.js +1 -1
  8. package/dist/agent-memories/gemini.js +1 -1
  9. package/dist/agent-memories/legacy.js +1 -1
  10. package/dist/agent-memories/source.js +1 -1
  11. package/dist/agent-memories/sync.d.ts +3 -3
  12. package/dist/agent-memories/sync.js +22 -9
  13. package/dist/agent-memories/types.d.ts +0 -2
  14. package/dist/ambient-store.d.ts +14 -0
  15. package/dist/ambient-store.js +90 -0
  16. package/dist/ambient.d.ts +23 -0
  17. package/dist/ambient.js +72 -50
  18. package/dist/api/assemble.d.ts +93 -0
  19. package/dist/api/assemble.js +153 -0
  20. package/dist/api/audit.d.ts +17 -0
  21. package/dist/api/audit.js +23 -0
  22. package/dist/api/auth.d.ts +79 -0
  23. package/dist/api/auth.js +178 -0
  24. package/dist/api/context-select.d.ts +49 -0
  25. package/dist/api/context-select.js +344 -0
  26. package/dist/api/context-types.d.ts +105 -0
  27. package/dist/api/context-types.js +3 -0
  28. package/dist/api/context.d.ts +31 -0
  29. package/dist/api/context.js +378 -0
  30. package/dist/api/dormant.d.ts +30 -0
  31. package/dist/api/dormant.js +140 -0
  32. package/dist/api/drill-down.d.ts +84 -0
  33. package/dist/api/drill-down.js +126 -0
  34. package/dist/api/forget.d.ts +57 -0
  35. package/dist/api/forget.js +87 -0
  36. package/dist/api/goals.d.ts +18 -0
  37. package/dist/api/goals.js +33 -0
  38. package/dist/api/learn.d.ts +31 -0
  39. package/dist/api/learn.js +88 -0
  40. package/dist/api/outcome.d.ts +61 -0
  41. package/dist/api/outcome.js +66 -0
  42. package/dist/api/promote.d.ts +54 -0
  43. package/dist/api/promote.js +192 -0
  44. package/dist/api/quarantine.d.ts +24 -0
  45. package/dist/api/quarantine.js +121 -0
  46. package/dist/api/recall-types.d.ts +390 -0
  47. package/dist/api/recall-types.js +3 -0
  48. package/dist/api/recall.d.ts +36 -0
  49. package/dist/api/recall.js +499 -0
  50. package/dist/api/remember.d.ts +35 -0
  51. package/dist/api/remember.js +43 -0
  52. package/dist/api/sleep.d.ts +136 -0
  53. package/dist/api/sleep.js +256 -0
  54. package/dist/api/tokens.d.ts +26 -0
  55. package/dist/api/tokens.js +60 -0
  56. package/dist/api/types.d.ts +56 -0
  57. package/dist/api/types.js +38 -0
  58. package/dist/api.d.ts +20 -1262
  59. package/dist/api.js +25 -2727
  60. package/dist/audit.d.ts +3 -0
  61. package/dist/audit.js +6 -3
  62. package/dist/auth.d.ts +45 -4
  63. package/dist/auth.js +125 -48
  64. package/dist/autolearn.js +2 -2
  65. package/dist/capture/command.d.ts +33 -0
  66. package/dist/capture/command.js +264 -0
  67. package/dist/capture/compact.d.ts +44 -0
  68. package/dist/capture/compact.js +354 -0
  69. package/dist/capture/extract.d.ts +21 -0
  70. package/dist/capture/extract.js +464 -0
  71. package/dist/capture/transcript.d.ts +40 -0
  72. package/dist/capture/transcript.js +193 -0
  73. package/dist/capture-error.js +2 -1
  74. package/dist/churn-git.js +4 -2
  75. package/dist/cli/audit.d.ts +3 -0
  76. package/dist/cli/audit.js +159 -0
  77. package/dist/cli/auth.d.ts +2 -0
  78. package/dist/cli/auth.js +171 -0
  79. package/dist/cli/briefs.d.ts +4 -0
  80. package/dist/cli/briefs.js +453 -0
  81. package/dist/cli/card.d.ts +3 -0
  82. package/dist/cli/card.js +333 -0
  83. package/dist/cli/context.d.ts +15 -0
  84. package/dist/cli/context.js +376 -0
  85. package/dist/cli/continuity.d.ts +6 -0
  86. package/dist/cli/continuity.js +457 -0
  87. package/dist/cli/curate.d.ts +19 -0
  88. package/dist/cli/curate.js +556 -0
  89. package/dist/cli/dag.d.ts +5 -0
  90. package/dist/cli/dag.js +177 -0
  91. package/dist/cli/decisions.d.ts +4 -0
  92. package/dist/cli/decisions.js +528 -0
  93. package/dist/cli/eval.d.ts +5 -0
  94. package/dist/cli/eval.js +213 -0
  95. package/dist/cli/explain.d.ts +4 -0
  96. package/dist/cli/explain.js +156 -0
  97. package/dist/cli/goals.d.ts +2 -0
  98. package/dist/cli/goals.js +196 -0
  99. package/dist/cli/hook-blocks.d.ts +18 -0
  100. package/dist/cli/hook-blocks.js +233 -0
  101. package/dist/cli/init.d.ts +2 -0
  102. package/dist/cli/init.js +305 -0
  103. package/dist/cli/maintenance.d.ts +4 -0
  104. package/dist/cli/maintenance.js +190 -0
  105. package/dist/cli/playbooks.d.ts +4 -0
  106. package/dist/cli/playbooks.js +573 -0
  107. package/dist/cli/projects.js +9 -6
  108. package/dist/cli/recall.d.ts +7 -0
  109. package/dist/cli/recall.js +582 -0
  110. package/dist/cli/remember.d.ts +5 -0
  111. package/dist/cli/remember.js +485 -0
  112. package/dist/cli/serve.d.ts +5 -0
  113. package/dist/cli/serve.js +40 -0
  114. package/dist/cli/session-hooks.d.ts +29 -0
  115. package/dist/cli/session-hooks.js +647 -0
  116. package/dist/cli/setup.d.ts +4 -0
  117. package/dist/cli/setup.js +397 -0
  118. package/dist/cli/shared.d.ts +15 -19
  119. package/dist/cli/shared.js +50 -341
  120. package/dist/cli/slack.d.ts +2 -0
  121. package/dist/cli/slack.js +171 -0
  122. package/dist/cli/status.d.ts +18 -0
  123. package/dist/cli/status.js +409 -0
  124. package/dist/cli/transfer.d.ts +10 -0
  125. package/dist/cli/transfer.js +424 -0
  126. package/dist/cli/usage.d.ts +85 -0
  127. package/dist/cli/usage.js +741 -0
  128. package/dist/cli.d.ts +71 -120
  129. package/dist/cli.js +170 -8469
  130. package/dist/client.js +15 -8
  131. package/dist/compaction-record.d.ts +0 -2
  132. package/dist/compaction-record.js +7 -5
  133. package/dist/connectors/github/backfill.js +94 -87
  134. package/dist/connectors/github/cli-impl.js +4 -3
  135. package/dist/connectors/github/dlq.js +67 -54
  136. package/dist/connectors/github/ingest.js +34 -35
  137. package/dist/connectors/github/tenant-routing.js +3 -2
  138. package/dist/connectors/github/webhook.js +135 -216
  139. package/dist/connectors/slack/dlq.js +49 -61
  140. package/dist/connectors/slack/ingest.js +55 -48
  141. package/dist/connectors/slack/tenant-routing.js +4 -3
  142. package/dist/connectors/slack/webhook.js +72 -74
  143. package/dist/consolidate/conflicts.d.ts +10 -0
  144. package/dist/consolidate/conflicts.js +178 -0
  145. package/dist/consolidate/decay.d.ts +12 -0
  146. package/dist/consolidate/decay.js +145 -0
  147. package/dist/consolidate/llm-passes.d.ts +3 -0
  148. package/dist/consolidate/llm-passes.js +141 -0
  149. package/dist/consolidate/merge.d.ts +7 -0
  150. package/dist/consolidate/merge.js +251 -0
  151. package/dist/consolidate/physics-pass.d.ts +3 -0
  152. package/dist/consolidate/physics-pass.js +60 -0
  153. package/dist/consolidate/run.d.ts +69 -0
  154. package/dist/consolidate/run.js +76 -0
  155. package/dist/consolidate/sleep.d.ts +18 -0
  156. package/dist/consolidate/sleep.js +209 -0
  157. package/dist/consolidate/traces.d.ts +4 -0
  158. package/dist/consolidate/traces.js +178 -0
  159. package/dist/context-auto.js +7 -11
  160. package/dist/context-render.d.ts +1 -1
  161. package/dist/context-render.js +1 -1
  162. package/dist/customer-notes.d.ts +3 -0
  163. package/dist/customer-notes.js +83 -72
  164. package/dist/dag.js +225 -188
  165. package/dist/dashboard-actions.d.ts +20 -0
  166. package/dist/dashboard-actions.js +88 -0
  167. package/dist/dashboard-params.d.ts +45 -0
  168. package/dist/dashboard-params.js +127 -0
  169. package/dist/dashboard-queries.d.ts +15 -0
  170. package/dist/dashboard-queries.js +355 -0
  171. package/dist/dashboard-snapshot.d.ts +138 -0
  172. package/dist/dashboard-snapshot.js +308 -0
  173. package/dist/dashboard-types.d.ts +163 -0
  174. package/dist/dashboard-types.js +3 -0
  175. package/dist/dashboard.d.ts +6 -7
  176. package/dist/dashboard.js +228 -202
  177. package/dist/db/busy.d.ts +5 -0
  178. package/dist/db/busy.js +24 -0
  179. package/dist/db/continuity.d.ts +5 -0
  180. package/dist/db/continuity.js +145 -0
  181. package/dist/db/meta.d.ts +8 -0
  182. package/dist/db/meta.js +35 -0
  183. package/dist/db/migrate.d.ts +9 -0
  184. package/dist/db/migrate.js +138 -0
  185. package/dist/db/migrations/index.d.ts +5 -0
  186. package/dist/db/migrations/index.js +109 -0
  187. package/dist/db/migrations/types.d.ts +14 -0
  188. package/dist/db/migrations/types.js +2 -0
  189. package/dist/db/migrations/v01.d.ts +3 -0
  190. package/dist/db/migrations/v01.js +38 -0
  191. package/dist/db/migrations/v02.d.ts +3 -0
  192. package/dist/db/migrations/v02.js +21 -0
  193. package/dist/db/migrations/v03.d.ts +3 -0
  194. package/dist/db/migrations/v03.js +22 -0
  195. package/dist/db/migrations/v04.d.ts +3 -0
  196. package/dist/db/migrations/v04.js +28 -0
  197. package/dist/db/migrations/v05.d.ts +3 -0
  198. package/dist/db/migrations/v05.js +21 -0
  199. package/dist/db/migrations/v06.d.ts +3 -0
  200. package/dist/db/migrations/v06.js +25 -0
  201. package/dist/db/migrations/v07.d.ts +3 -0
  202. package/dist/db/migrations/v07.js +13 -0
  203. package/dist/db/migrations/v08.d.ts +3 -0
  204. package/dist/db/migrations/v08.js +8 -0
  205. package/dist/db/migrations/v09.d.ts +3 -0
  206. package/dist/db/migrations/v09.js +13 -0
  207. package/dist/db/migrations/v10.d.ts +3 -0
  208. package/dist/db/migrations/v10.js +17 -0
  209. package/dist/db/migrations/v11.d.ts +3 -0
  210. package/dist/db/migrations/v11.js +15 -0
  211. package/dist/db/migrations/v12.d.ts +3 -0
  212. package/dist/db/migrations/v12.js +11 -0
  213. package/dist/db/migrations/v13.d.ts +3 -0
  214. package/dist/db/migrations/v13.js +15 -0
  215. package/dist/db/migrations/v14.d.ts +3 -0
  216. package/dist/db/migrations/v14.js +66 -0
  217. package/dist/db/migrations/v15.d.ts +3 -0
  218. package/dist/db/migrations/v15.js +42 -0
  219. package/dist/db/migrations/v16.d.ts +3 -0
  220. package/dist/db/migrations/v16.js +61 -0
  221. package/dist/db/migrations/v17.d.ts +3 -0
  222. package/dist/db/migrations/v17.js +46 -0
  223. package/dist/db/migrations/v18.d.ts +3 -0
  224. package/dist/db/migrations/v18.js +60 -0
  225. package/dist/db/migrations/v19.d.ts +3 -0
  226. package/dist/db/migrations/v19.js +28 -0
  227. package/dist/db/migrations/v20.d.ts +3 -0
  228. package/dist/db/migrations/v20.js +42 -0
  229. package/dist/db/migrations/v21.d.ts +3 -0
  230. package/dist/db/migrations/v21.js +16 -0
  231. package/dist/db/migrations/v22.d.ts +3 -0
  232. package/dist/db/migrations/v22.js +82 -0
  233. package/dist/db/migrations/v23.d.ts +3 -0
  234. package/dist/db/migrations/v23.js +48 -0
  235. package/dist/db/migrations/v24.d.ts +3 -0
  236. package/dist/db/migrations/v24.js +72 -0
  237. package/dist/db/migrations/v25.d.ts +3 -0
  238. package/dist/db/migrations/v25.js +46 -0
  239. package/dist/db/migrations/v26.d.ts +3 -0
  240. package/dist/db/migrations/v26.js +23 -0
  241. package/dist/db/migrations/v27.d.ts +3 -0
  242. package/dist/db/migrations/v27.js +57 -0
  243. package/dist/db/migrations/v28.d.ts +3 -0
  244. package/dist/db/migrations/v28.js +38 -0
  245. package/dist/db/migrations/v29.d.ts +3 -0
  246. package/dist/db/migrations/v29.js +78 -0
  247. package/dist/db/migrations/v30.d.ts +3 -0
  248. package/dist/db/migrations/v30.js +92 -0
  249. package/dist/db/migrations/v31.d.ts +3 -0
  250. package/dist/db/migrations/v31.js +74 -0
  251. package/dist/db/migrations/v32.d.ts +3 -0
  252. package/dist/db/migrations/v32.js +102 -0
  253. package/dist/db/migrations/v33.d.ts +3 -0
  254. package/dist/db/migrations/v33.js +104 -0
  255. package/dist/db/migrations/v34.d.ts +3 -0
  256. package/dist/db/migrations/v34.js +93 -0
  257. package/dist/db/migrations/v35.d.ts +3 -0
  258. package/dist/db/migrations/v35.js +98 -0
  259. package/dist/db/migrations/v36.d.ts +3 -0
  260. package/dist/db/migrations/v36.js +98 -0
  261. package/dist/db/migrations/v37.d.ts +3 -0
  262. package/dist/db/migrations/v37.js +219 -0
  263. package/dist/db/migrations/v38.d.ts +3 -0
  264. package/dist/db/migrations/v38.js +277 -0
  265. package/dist/db/migrations/v39.d.ts +3 -0
  266. package/dist/db/migrations/v39.js +59 -0
  267. package/dist/db/migrations/v40.d.ts +3 -0
  268. package/dist/db/migrations/v40.js +74 -0
  269. package/dist/db/migrations/v41.d.ts +3 -0
  270. package/dist/db/migrations/v41.js +43 -0
  271. package/dist/db/migrations/v42.d.ts +3 -0
  272. package/dist/db/migrations/v42.js +41 -0
  273. package/dist/db/migrations/v43.d.ts +3 -0
  274. package/dist/db/migrations/v43.js +67 -0
  275. package/dist/db/migrations/v44.d.ts +3 -0
  276. package/dist/db/migrations/v44.js +28 -0
  277. package/dist/db/migrations/v45.d.ts +3 -0
  278. package/dist/db/migrations/v45.js +30 -0
  279. package/dist/db/migrations/v46.d.ts +3 -0
  280. package/dist/db/migrations/v46.js +25 -0
  281. package/dist/db/migrations/v47.d.ts +3 -0
  282. package/dist/db/migrations/v47.js +17 -0
  283. package/dist/db/migrations/v48.d.ts +3 -0
  284. package/dist/db/migrations/v48.js +10 -0
  285. package/dist/db/migrations/v49.d.ts +3 -0
  286. package/dist/db/migrations/v49.js +31 -0
  287. package/dist/db/migrations/v50.d.ts +3 -0
  288. package/dist/db/migrations/v50.js +67 -0
  289. package/dist/db/migrations/v51.d.ts +3 -0
  290. package/dist/db/migrations/v51.js +14 -0
  291. package/dist/db/migrations/v52.d.ts +3 -0
  292. package/dist/db/migrations/v52.js +7 -0
  293. package/dist/db/open.d.ts +23 -0
  294. package/dist/db/open.js +146 -0
  295. package/dist/db/sqlite.d.ts +21 -0
  296. package/dist/db/sqlite.js +8 -0
  297. package/dist/db/tables.d.ts +7 -0
  298. package/dist/db/tables.js +38 -0
  299. package/dist/db.d.ts +6 -46
  300. package/dist/db.js +5 -3049
  301. package/dist/decisions.d.ts +4 -1
  302. package/dist/decisions.js +102 -83
  303. package/dist/dedupe.js +3 -2
  304. package/dist/delivery-recorder.js +4 -1
  305. package/dist/doctor.js +14 -10
  306. package/dist/embedding-provider.d.ts +1 -1
  307. package/dist/embedding-provider.js +4 -3
  308. package/dist/embeddings.d.ts +9 -52
  309. package/dist/embeddings.js +43 -297
  310. package/dist/env.d.ts +75 -0
  311. package/dist/env.js +119 -0
  312. package/dist/eval-suite.js +1 -1
  313. package/dist/eval.js +2 -2
  314. package/dist/extract.js +1 -1
  315. package/dist/gated-write.js +3 -1
  316. package/dist/goals.d.ts +3 -1
  317. package/dist/goals.js +117 -86
  318. package/dist/graph/read.d.ts +73 -0
  319. package/dist/graph/read.js +325 -0
  320. package/dist/graph/rows.d.ts +45 -0
  321. package/dist/graph/rows.js +51 -0
  322. package/dist/graph/types.d.ts +83 -0
  323. package/dist/graph/types.js +11 -0
  324. package/dist/graph/write.d.ts +93 -0
  325. package/dist/{graph.js → graph/write.js} +6 -384
  326. package/dist/graph-extract.js +2 -1
  327. package/dist/graph-recall.d.ts +1 -1
  328. package/dist/graph-recall.js +2 -2
  329. package/dist/graph-stream.js +1 -1
  330. package/dist/graph-view.d.ts +1 -1
  331. package/dist/graph-view.js +1 -1
  332. package/dist/half-life-migration.d.ts +1 -1
  333. package/dist/half-life-migration.js +2 -1
  334. package/dist/hooks/codex-session.d.ts +8 -0
  335. package/dist/hooks/codex-session.js +76 -0
  336. package/dist/hooks/codex-wrapper.d.ts +55 -0
  337. package/dist/hooks/codex-wrapper.js +288 -0
  338. package/dist/hooks/json-hooks.d.ts +63 -0
  339. package/dist/hooks/json-hooks.js +356 -0
  340. package/dist/hooks/opencode.d.ts +50 -0
  341. package/dist/hooks/opencode.js +202 -0
  342. package/dist/hooks/shared.d.ts +54 -0
  343. package/dist/hooks/shared.js +77 -0
  344. package/dist/http-retry.d.ts +2 -0
  345. package/dist/http-retry.js +4 -3
  346. package/dist/http-util.d.ts +3 -0
  347. package/dist/http-util.js +10 -0
  348. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  349. package/dist/importers/core.js +141 -0
  350. package/dist/importers/markdown-parse.d.ts +41 -0
  351. package/dist/importers/markdown-parse.js +132 -0
  352. package/dist/importers/markdown.d.ts +3 -0
  353. package/dist/importers/markdown.js +92 -0
  354. package/dist/importers/sources.d.ts +7 -0
  355. package/dist/importers/sources.js +229 -0
  356. package/dist/importers/vault.d.ts +11 -0
  357. package/dist/importers/vault.js +352 -0
  358. package/dist/incidents.d.ts +3 -0
  359. package/dist/incidents.js +52 -43
  360. package/dist/index.d.ts +25 -6
  361. package/dist/index.js +23 -6
  362. package/dist/invalidation.js +2 -1
  363. package/dist/judgment.js +2 -1
  364. package/dist/keyset.d.ts +13 -0
  365. package/dist/keyset.js +8 -0
  366. package/dist/local-embedding.d.ts +13 -0
  367. package/dist/local-embedding.js +165 -0
  368. package/dist/log.d.ts +7 -0
  369. package/dist/log.js +19 -1
  370. package/dist/mcp/admin-tools.d.ts +8 -0
  371. package/dist/mcp/admin-tools.js +116 -0
  372. package/dist/mcp/format.d.ts +27 -0
  373. package/dist/mcp/format.js +135 -0
  374. package/dist/mcp/memory-tools.d.ts +5 -0
  375. package/dist/mcp/memory-tools.js +83 -0
  376. package/dist/mcp/protocol.d.ts +83 -0
  377. package/dist/mcp/protocol.js +55 -0
  378. package/dist/mcp/recall-tools.d.ts +6 -0
  379. package/dist/mcp/recall-tools.js +320 -0
  380. package/dist/mcp/request.d.ts +10 -0
  381. package/dist/mcp/request.js +163 -0
  382. package/dist/mcp/server.d.ts +4 -75
  383. package/dist/mcp/server.js +7 -1190
  384. package/dist/mcp/session-state.d.ts +11 -0
  385. package/dist/mcp/session-state.js +28 -0
  386. package/dist/mcp/stdio.d.ts +8 -0
  387. package/dist/mcp/stdio.js +79 -0
  388. package/dist/mcp/tools.d.ts +11 -0
  389. package/dist/mcp/tools.js +247 -0
  390. package/dist/memory.d.ts +3 -0
  391. package/dist/memory.js +27 -1
  392. package/dist/multihop.d.ts +1 -1
  393. package/dist/multihop.js +2 -1
  394. package/dist/owner-validation.js +2 -1
  395. package/dist/physics-state.js +10 -7
  396. package/dist/policies.d.ts +3 -0
  397. package/dist/policies.js +93 -74
  398. package/dist/postinstall.js +3 -2
  399. package/dist/predictions/planning-fallacy.d.ts +100 -0
  400. package/dist/predictions/planning-fallacy.js +190 -0
  401. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  402. package/dist/predictions/store.js +434 -0
  403. package/dist/processes.d.ts +3 -0
  404. package/dist/processes.js +94 -76
  405. package/dist/project-briefs.d.ts +3 -0
  406. package/dist/project-briefs.js +142 -113
  407. package/dist/project-identity.js +3 -2
  408. package/dist/project-merge.d.ts +12 -4
  409. package/dist/project-merge.js +132 -45
  410. package/dist/quarantine.d.ts +2 -1
  411. package/dist/quarantine.js +8 -5
  412. package/dist/raw-archive.js +1 -1
  413. package/dist/recall-history.js +3 -2
  414. package/dist/recall-pipeline.d.ts +2 -2
  415. package/dist/recall-pipeline.js +16 -8
  416. package/dist/recall-scope.js +1 -1
  417. package/dist/recall-trace.d.ts +1 -1
  418. package/dist/refine-llm.js +2 -1
  419. package/dist/reject-flow.js +6 -1
  420. package/dist/rerankers/clef.js +6 -5
  421. package/dist/rerankers/jev.d.ts +1 -1
  422. package/dist/rerankers/jev.js +4 -4
  423. package/dist/rerankers/llm.d.ts +4 -2
  424. package/dist/rerankers/llm.js +58 -38
  425. package/dist/rerankers/types.d.ts +1 -1
  426. package/dist/salience.js +1 -1
  427. package/dist/scheduler.d.ts +1 -0
  428. package/dist/scheduler.js +26 -4
  429. package/dist/scope.js +4 -3
  430. package/dist/search/as-of.d.ts +10 -0
  431. package/dist/search/as-of.js +22 -0
  432. package/dist/search/bm25-search.d.ts +14 -0
  433. package/dist/search/bm25-search.js +43 -0
  434. package/dist/search/bm25.d.ts +15 -0
  435. package/dist/search/bm25.js +54 -0
  436. package/dist/search/boosts.d.ts +54 -0
  437. package/dist/search/boosts.js +94 -0
  438. package/dist/search/breakdown.d.ts +7 -0
  439. package/dist/search/breakdown.js +20 -0
  440. package/dist/search/explain.d.ts +25 -0
  441. package/dist/search/explain.js +31 -0
  442. package/dist/search/finalize.d.ts +8 -0
  443. package/dist/search/finalize.js +52 -0
  444. package/dist/search/fusion.d.ts +27 -0
  445. package/dist/search/fusion.js +42 -0
  446. package/dist/search/hybrid-score.d.ts +20 -0
  447. package/dist/search/hybrid-score.js +73 -0
  448. package/dist/search/hybrid.d.ts +46 -0
  449. package/dist/search/hybrid.js +64 -0
  450. package/dist/search/physics-search.d.ts +29 -0
  451. package/dist/search/physics-search.js +162 -0
  452. package/dist/search/rerank.d.ts +10 -0
  453. package/dist/search/rerank.js +72 -0
  454. package/dist/search/temporal.d.ts +15 -0
  455. package/dist/search/temporal.js +45 -0
  456. package/dist/search/types.d.ts +91 -0
  457. package/dist/search/types.js +2 -0
  458. package/dist/search/vector.d.ts +30 -0
  459. package/dist/search/vector.js +71 -0
  460. package/dist/secret-detect.d.ts +2 -0
  461. package/dist/secret-detect.js +2 -1
  462. package/dist/server/auth.d.ts +52 -0
  463. package/dist/server/auth.js +221 -0
  464. package/dist/server/client-ip.d.ts +25 -0
  465. package/dist/server/client-ip.js +92 -0
  466. package/dist/server/cursor.d.ts +23 -0
  467. package/dist/server/cursor.js +58 -0
  468. package/dist/server/lifecycle.d.ts +7 -0
  469. package/dist/server/lifecycle.js +29 -0
  470. package/dist/server/mcp-http.d.ts +5 -0
  471. package/dist/server/mcp-http.js +199 -0
  472. package/dist/server/request.d.ts +33 -0
  473. package/dist/server/request.js +103 -0
  474. package/dist/server/routes/admin.d.ts +9 -0
  475. package/dist/server/routes/admin.js +158 -0
  476. package/dist/server/routes/customer-notes.d.ts +7 -0
  477. package/dist/server/routes/customer-notes.js +112 -0
  478. package/dist/server/routes/decisions.d.ts +7 -0
  479. package/dist/server/routes/decisions.js +133 -0
  480. package/dist/server/routes/incidents.d.ts +7 -0
  481. package/dist/server/routes/incidents.js +126 -0
  482. package/dist/server/routes/memories.d.ts +10 -0
  483. package/dist/server/routes/memories.js +179 -0
  484. package/dist/server/routes/policies.d.ts +8 -0
  485. package/dist/server/routes/policies.js +151 -0
  486. package/dist/server/routes/predictions.d.ts +7 -0
  487. package/dist/server/routes/predictions.js +164 -0
  488. package/dist/server/routes/processes.d.ts +7 -0
  489. package/dist/server/routes/processes.js +161 -0
  490. package/dist/server/routes/project-briefs.d.ts +8 -0
  491. package/dist/server/routes/project-briefs.js +136 -0
  492. package/dist/server/routes/recall.d.ts +8 -0
  493. package/dist/server/routes/recall.js +340 -0
  494. package/dist/server/routes/skills.d.ts +8 -0
  495. package/dist/server/routes/skills.js +150 -0
  496. package/dist/server/types.d.ts +56 -0
  497. package/dist/server/types.js +2 -0
  498. package/dist/server/validation.d.ts +14 -0
  499. package/dist/server/validation.js +91 -0
  500. package/dist/server.d.ts +7 -61
  501. package/dist/server.js +69 -2362
  502. package/dist/session-digest.d.ts +1 -1
  503. package/dist/session-digest.js +9 -2
  504. package/dist/shared.d.ts +12 -1
  505. package/dist/shared.js +33 -27
  506. package/dist/skills.d.ts +3 -0
  507. package/dist/skills.js +88 -70
  508. package/dist/stdin.js +2 -2
  509. package/dist/store/audit-event.d.ts +19 -0
  510. package/dist/store/audit-event.js +33 -0
  511. package/dist/store/candidates.d.ts +42 -0
  512. package/dist/store/candidates.js +152 -0
  513. package/dist/store/conflicts.d.ts +44 -0
  514. package/dist/store/conflicts.js +444 -0
  515. package/dist/store/delete-and-batch.d.ts +63 -0
  516. package/dist/store/delete-and-batch.js +310 -0
  517. package/dist/store/entry-reads.d.ts +92 -0
  518. package/dist/store/entry-reads.js +255 -0
  519. package/dist/store/entry-row.d.ts +67 -0
  520. package/dist/store/entry-row.js +208 -0
  521. package/dist/store/entry-writes.d.ts +46 -0
  522. package/dist/store/entry-writes.js +148 -0
  523. package/dist/store/handoffs.d.ts +26 -0
  524. package/dist/store/handoffs.js +184 -0
  525. package/dist/store/index-and-stats.d.ts +52 -0
  526. package/dist/store/index-and-stats.js +214 -0
  527. package/dist/store/markdown.d.ts +10 -0
  528. package/dist/store/markdown.js +108 -0
  529. package/dist/store/mirrors.d.ts +49 -0
  530. package/dist/store/mirrors.js +312 -0
  531. package/dist/store/open.d.ts +15 -0
  532. package/dist/store/open.js +223 -0
  533. package/dist/store/rows.d.ts +178 -0
  534. package/dist/store/rows.js +158 -0
  535. package/dist/store/search-rows.d.ts +86 -0
  536. package/dist/store/search-rows.js +260 -0
  537. package/dist/store/sessions.d.ts +83 -0
  538. package/dist/store/sessions.js +272 -0
  539. package/dist/store/summaries.d.ts +94 -0
  540. package/dist/store/summaries.js +377 -0
  541. package/dist/store/tenant-lookup.d.ts +12 -0
  542. package/dist/store/tenant-lookup.js +16 -0
  543. package/dist/store-cards.js +2 -1
  544. package/dist/summary-dirty.d.ts +4 -0
  545. package/dist/summary-dirty.js +32 -0
  546. package/dist/support-bundle.js +4 -3
  547. package/dist/tenant.js +2 -2
  548. package/dist/tokenize.d.ts +2 -0
  549. package/dist/tokenize.js +16 -0
  550. package/dist/transcript-tail.d.ts +7 -0
  551. package/dist/transcript-tail.js +48 -0
  552. package/dist/vector-store.d.ts +27 -0
  553. package/dist/vector-store.js +210 -0
  554. package/dist/version.d.ts +2 -2
  555. package/dist/version.js +2 -2
  556. package/dist/working-memory.js +1 -1
  557. package/dist/yaml.js +36 -11
  558. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  559. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  560. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  561. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  562. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  563. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  564. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  565. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  566. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  567. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  568. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  569. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  570. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  571. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  572. package/dist-ui/index.html +3 -25
  573. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  574. package/extensions/openclaw-plugin/package.json +1 -1
  575. package/openclaw.plugin.json +1 -1
  576. package/package.json +1 -1
  577. package/dist/capture.d.ts +0 -155
  578. package/dist/capture.js +0 -1295
  579. package/dist/consolidate.d.ts +0 -58
  580. package/dist/consolidate.js +0 -1124
  581. package/dist/graph.d.ts +0 -245
  582. package/dist/hooks.d.ts +0 -208
  583. package/dist/hooks.js +0 -1076
  584. package/dist/importers.js +0 -900
  585. package/dist/predictions.js +0 -620
  586. package/dist/search.d.ts +0 -320
  587. package/dist/search.js +0 -970
  588. package/dist/store.d.ts +0 -776
  589. package/dist/store.js +0 -3473
  590. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  591. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  592. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  593. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -1,5 +1,6 @@
1
1
  /** Quarantine tier (CD5, AT3): pending/approved/rejected record for a memory `remember` flagged as untrusted. */
2
2
  import type { DatabaseSyncLike } from './db.js';
3
+ import { type KeysetPosition } from './keyset.js';
3
4
  export declare const QUARANTINE_SCOPE_PREFIX = "quarantine:private:";
4
5
  /** Scope a quarantined memory is stored under; matches PRIVATE_SCOPE_RE so every default-deny site hides it. */
5
6
  export declare function quarantineScopeFor(original: string | null): string;
@@ -25,7 +26,7 @@ export interface RecordQuarantineOpts {
25
26
  /** Insert the quarantine row + its audit event; caller runs this inside the memory's own write transaction. */
26
27
  export declare function recordQuarantine(db: DatabaseSyncLike, opts: RecordQuarantineOpts): void;
27
28
  export declare function getQuarantineRow(db: DatabaseSyncLike, tenantId: string, memoryId: string): QuarantineRow | null;
28
- export declare function listQuarantineRows(db: DatabaseSyncLike, tenantId: string, status?: QuarantineStatus | 'all', limit?: number): QuarantineRow[];
29
+ export declare function listQuarantineRows(db: DatabaseSyncLike, tenantId: string, status?: QuarantineStatus | 'all', limit?: number, afterRow?: KeysetPosition): QuarantineRow[];
29
30
  export declare function approveQuarantineRow(db: DatabaseSyncLike, tenantId: string, memoryId: string, decidedBy: string): void;
30
31
  export declare function rejectQuarantineRow(db: DatabaseSyncLike, tenantId: string, memoryId: string, decidedBy: string): void;
31
32
  //# sourceMappingURL=quarantine.d.ts.map
@@ -1,5 +1,6 @@
1
1
  /** Quarantine tier (CD5, AT3): pending/approved/rejected record for a memory `remember` flagged as untrusted. */
2
2
  import { appendAuditEvent } from './audit.js';
3
+ import { keysetAfter } from './keyset.js';
3
4
  export const QUARANTINE_SCOPE_PREFIX = 'quarantine:private:';
4
5
  /** Scope a quarantined memory is stored under; matches PRIVATE_SCOPE_RE so every default-deny site hides it. */
5
6
  export function quarantineScopeFor(original) {
@@ -39,16 +40,18 @@ export function getQuarantineRow(db, tenantId, memoryId) {
39
40
  .get(tenantId, memoryId);
40
41
  return row ? fromDbRow(row) : null;
41
42
  }
42
- export function listQuarantineRows(db, tenantId, status = 'pending', limit = 100) {
43
+ export function listQuarantineRows(db, tenantId, status = 'pending', limit = 100, afterRow) {
43
44
  // A pending row whose memory was deleted (e.g. Slack message_deleted) is dead; keep its history, drop it from the queue.
44
45
  const live = status === 'pending'
45
46
  ? ' AND EXISTS (SELECT 1 FROM memories m WHERE m.id = memory_quarantine.memory_id AND m.tenant_id = memory_quarantine.tenant_id)'
46
47
  : '';
48
+ const after = keysetAfter('quarantined_at', 'memory_id', afterRow);
49
+ const order = 'ORDER BY quarantined_at DESC, memory_id DESC LIMIT ?';
47
50
  const rows = status === 'all'
48
- ? db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ? ORDER BY quarantined_at DESC LIMIT ?`)
49
- .all(tenantId, limit)
50
- : db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ? AND status = ?${live} ORDER BY quarantined_at DESC LIMIT ?`)
51
- .all(tenantId, status, limit);
51
+ ? db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ?${after.sql} ${order}`)
52
+ .all(tenantId, ...after.params, limit)
53
+ : db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ? AND status = ?${live}${after.sql} ${order}`)
54
+ .all(tenantId, status, ...after.params, limit);
52
55
  // SAFETY: both branches select SELECT_COLUMNS, matching QuarantineDbRow's field set.
53
56
  return rows.map(fromDbRow);
54
57
  }
@@ -1,7 +1,7 @@
1
1
  import { BadRequestError, NotFoundError } from './api-errors.js';
2
2
  import { isFtsAvailable } from './db.js';
3
3
  import { appendAuditEvent, reportAuditWriteFailure } from './audit.js';
4
- import { markSummaryDirtyInTx } from './store.js';
4
+ import { markSummaryDirtyInTx } from './summary-dirty.js';
5
5
  export function archiveRawMemory(db, id, opts) {
6
6
  // SAFETY: SELECT * FROM memories returns every column of the memories table; only
7
7
  // kind, tenant_id, and dag_parent_id are read below, all guaranteed present (possibly
@@ -18,6 +18,7 @@
18
18
  * Composes with J3.2: AnchoringHint + PlanningFallacyHint are independent
19
19
  * signals; both can fire on the same recall.
20
20
  */
21
+ import { envAnchoringOff, envAvailabilityOff } from './env.js';
21
22
  const DEFAULT_MIN_DOMINANCE = 3;
22
23
  const DEFAULT_RECENT_REPEAT_WINDOW = 5;
23
24
  const DEFAULT_COOLDOWN = 3;
@@ -238,7 +239,7 @@ export function snapshotRing(ring) {
238
239
  */
239
240
  export function biasHintEnabled(kind) {
240
241
  return kind === 'anchoring'
241
- ? process.env.HIPPO_ANCHORING !== 'off'
242
- : process.env.HIPPO_AVAILABILITY !== 'off';
242
+ ? !envAnchoringOff()
243
+ : !envAvailabilityOff();
243
244
  }
244
245
  //# sourceMappingURL=recall-history.js.map
@@ -2,7 +2,7 @@ import { type GoalRecallLogRow } from './goals.js';
2
2
  import { type MemoryEntry } from './memory.js';
3
3
  import type { PhysicsConfig } from './physics-config.js';
4
4
  import type { RerankerFn } from './rerankers/types.js';
5
- import { type ResultCost, type SearchResult } from './search.js';
5
+ import type { ResultCost, SearchResult } from './search/types.js';
6
6
  /** Stores rankRecall reads and where it sends operator notes. */
7
7
  export interface RankRecallCtx {
8
8
  hippoRoot: string;
@@ -23,7 +23,7 @@ export interface RecallSearchOpts {
23
23
  mmrLambda: number;
24
24
  localBump: number;
25
25
  minResults?: number;
26
- /** Score breakdowns for `hippo explain`; explain's physics call also leaves out the bi-temporal flags. */
26
+ /** Score breakdowns for `hippo explain`; explain's physics call also leaves out minResults and includeSuperseded. */
27
27
  explain: boolean;
28
28
  }
29
29
  /** `--graph-hops` and `--graph-seeds`. */
@@ -4,17 +4,18 @@ import { evalNow } from './ablation.js';
4
4
  import { oneCopyPerMemory } from './api.js';
5
5
  import { compareEntryIdentity } from './compare.js';
6
6
  import { closeHippoDb, openHippoDb } from './db.js';
7
- import { isEmbeddingAvailable } from './embeddings.js';
7
+ import { isEmbeddingAvailable } from './local-embedding.js';
8
8
  import { computeGoalStackBoost } from './goals.js';
9
9
  import { graphExpandRecall } from './graph-recall.js';
10
10
  import { DEFAULT_GRAPH_STREAM_WEIGHT } from './graph-stream.js';
11
11
  import { Layer } from './memory.js';
12
12
  import { multihopSearch } from './multihop.js';
13
13
  import { passesCliRecallScopeFilter } from './recall-scope.js';
14
- import { hybridSearch, physicsSearch, textOverlap } from './search.js';
14
+ import { hybridSearch } from './search/hybrid.js';
15
+ import { physicsSearch } from './search/physics-search.js';
15
16
  import { searchBothHybrid } from './shared.js';
16
- import { loadRecallSearchEntries } from './store.js';
17
- import { tokenize as tokenizeQuery } from './tokenize.js';
17
+ import { loadRecallSearchEntries, recallScopeFilter } from './store/search-rows.js';
18
+ import { textOverlap, tokenize as tokenizeQuery } from './tokenize.js';
18
19
  /** Ranks memories for a query as `hippo recall` does, through the `limit` slice. Reads stores, embeddings and
19
20
  * physics state; writes nothing and prints nothing (notes go to `ctx.note`). The caller supplies the cost
20
21
  * function and reranker in `opts`, and persists the returned goal-log rows. */
@@ -124,10 +125,17 @@ async function searchPool(ctx, opts, pool) {
124
125
  const allEntries = oneCopyPerMemory(pool.local, pool.global, evalNow()).flat();
125
126
  return multihopSearch(query, allEntries, { budget, cost, hippoRoot: ctx.hippoRoot, minResults, includeSuperseded, asOf });
126
127
  }
128
+ const requested = opts.explicitScope || undefined;
129
+ const vectorCandidates = {
130
+ tenantId: ctx.tenantId,
131
+ scope: recallScopeFilter(requested, 'additive'),
132
+ includeSuperseded: includeSuperseded || Boolean(asOf),
133
+ admit: (e) => passesCliRecallScopeFilter(e.scope ?? null, requested),
134
+ };
127
135
  if (search.usePhysics && !globalRoot) {
128
- // Explain has never passed the bi-temporal flags to physics; keeping that holds its output steady.
129
- const temporal = explain ? {} : { minResults, includeSuperseded, asOf };
130
- return physicsSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, physicsConfig: search.physicsConfig, scope, explain, ...temporal });
136
+ // Explain leaves minResults and includeSuperseded out to hold its output steady; asOf must reach physics or later rows leak.
137
+ const temporal = explain ? { asOf } : { minResults, includeSuperseded, asOf };
138
+ return physicsSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, physicsConfig: search.physicsConfig, scope, explain, vectorCandidates, ...temporal });
131
139
  }
132
140
  if (globalRoot) {
133
141
  // searchBothHybrid reloads candidates itself, so the scope rule is passed in rather than inherited from the pool.
@@ -137,7 +145,7 @@ async function searchPool(ctx, opts, pool) {
137
145
  recallScope: opts.explicitScope ? { requested: opts.explicitScope, additive: true } : {},
138
146
  });
139
147
  }
140
- return hybridSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, explain, mmr, mmrLambda, minResults, scope, includeSuperseded, asOf });
148
+ return hybridSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, explain, mmr, mmrLambda, minResults, scope, includeSuperseded, asOf, vectorCandidates });
141
149
  }
142
150
  /** Adds memories reached by walking the entity graph out from the lexical seeds. */
143
151
  function expandGraph(ctx, opts, graph, state) {
@@ -124,7 +124,7 @@ export function isRestrictedScope(scope) {
124
124
  return false;
125
125
  // SAFETY: RECALL_DEFAULT_DENY_SCOPES is a readonly tuple of string
126
126
  // literals; widening the array (not the input) lets .includes() take any scope.
127
- // `:private:` anywhere, any case, matches the store's SQL default-deny (store.ts:894) so JS never admits what SQL hides.
127
+ // `:private:` anywhere, any case, matches the store's SQL default-deny (store/search-rows.ts) so JS never admits what SQL hides.
128
128
  return isPrivateScope(scope) || /:private:/i.test(scope) || RECALL_DEFAULT_DENY_SCOPES.includes(scope);
129
129
  }
130
130
  /** True when `actor` may read `scope`: admin always; member needs an exact grant on a restricted scope. */
@@ -16,7 +16,7 @@
16
16
  * new debug env var).
17
17
  */
18
18
  import { type DatabaseSyncLike } from './db.js';
19
- import type { RerankStep } from './search.js';
19
+ import type { RerankStep } from './search/types.js';
20
20
  import { type DeliveryEventInput } from './delivery-recorder.js';
21
21
  /** One ranked result to persist alongside its trace row. */
22
22
  export interface RecallTraceResultInput {
@@ -13,7 +13,8 @@
13
13
  * - On failure (API error, bad response), the original memory is untouched.
14
14
  */
15
15
  import { Layer } from './memory.js';
16
- import { loadAllEntries, readEntry, writeEntry } from './store.js';
16
+ import { writeEntry } from './store/entry-writes.js';
17
+ import { loadAllEntries, readEntry } from './store/entry-reads.js';
17
18
  import { redactSecretsStrict } from './secret-detect.js';
18
19
  import { fetchWithRetry, llmTimeoutMs } from './http-retry.js';
19
20
  import { log } from './log.js';
@@ -15,7 +15,12 @@ import { closeHippoDb } from './db.js';
15
15
  import { appendAuditEvent, reportAuditWriteFailure } from './audit.js';
16
16
  import { archiveRawMemory } from './raw-archive.js';
17
17
  import { deleteDormantRow, listDormantSnapshots, purgeDormantByDigest, replaceDormantEntry } from './dormant.js';
18
- import { openStore, deleteEntryCore, purgeMirrorBestEffort, selectAllEntries, stampOriginProject, writeEntryDbOnly, writeEntryMirrors, } from './store.js';
18
+ import { stampOriginProject } from './store/entry-row.js';
19
+ import { purgeMirrorBestEffort } from './store/mirrors.js';
20
+ import { openStore } from './store/open.js';
21
+ import { writeEntryDbOnly, writeEntryMirrors } from './store/entry-writes.js';
22
+ import { selectAllEntries } from './store/entry-reads.js';
23
+ import { deleteEntryCore } from './store/delete-and-batch.js';
19
24
  import { heldTexts } from './same-text.js';
20
25
  import { mergedSuccessor } from './merged-row.js';
21
26
  import { rejectionDigest, normalizeValueForRejection, insertRejectedValue, deleteRejectedValue, listRejectedValues, } from './rejection.js';
@@ -1,3 +1,4 @@
1
+ import { envClefEndpoint, envClefEndpointToken, envClefTimeoutMs, envCloudflareAccountId, envCloudflareApiToken } from '../env.js';
1
2
  import { buildRelevanceRequest, JEV_DEFAULT_TOP_K, rankByScores } from './jev.js';
2
3
  import { isJsonObjectRecord } from '../http-util.js';
3
4
  import { log } from '../log.js';
@@ -33,7 +34,7 @@ function checkHeaderSafe(name, token) {
33
34
  }
34
35
  /** Transport from trusted local env, never call arguments: HIPPO_CLEF_ENDPOINT wins over hosted Workers AI. */
35
36
  export function resolveClefRoute(model) {
36
- const endpoint = process.env.HIPPO_CLEF_ENDPOINT?.trim();
37
+ const endpoint = envClefEndpoint();
37
38
  if (endpoint) {
38
39
  let parsed;
39
40
  try {
@@ -52,13 +53,13 @@ export function resolveClefRoute(model) {
52
53
  if (parsed.protocol === 'http:' && !isLoopback(parsed.hostname)) {
53
54
  throw new Error('HIPPO_CLEF_ENDPOINT must use https unless it is on this machine');
54
55
  }
55
- const endpointToken = process.env.HIPPO_CLEF_ENDPOINT_TOKEN?.trim() || undefined;
56
+ const endpointToken = envClefEndpointToken();
56
57
  if (endpointToken)
57
58
  checkHeaderSafe('HIPPO_CLEF_ENDPOINT_TOKEN', endpointToken);
58
59
  return { url: parsed.href, token: endpointToken, backend: 'private-endpoint' };
59
60
  }
60
- const account = process.env.CLOUDFLARE_ACCOUNT_ID?.trim() ?? '';
61
- const token = process.env.CLOUDFLARE_API_TOKEN?.trim() ?? '';
61
+ const account = envCloudflareAccountId();
62
+ const token = envCloudflareApiToken();
62
63
  if (!account || !token)
63
64
  throw new Error('CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN not set');
64
65
  if (!ACCOUNT_ID.test(account))
@@ -137,7 +138,7 @@ async function readCappedJson(resp) {
137
138
  async function requestScores(model, query, head, route) {
138
139
  const { state, questions } = buildRelevanceRequest(query, head);
139
140
  // Strict parse: parseInt would read "15s" as 15 ms, and Node clamps a delay past 2^31-1 to 1 ms.
140
- const requested = Number(process.env.HIPPO_CLEF_TIMEOUT_MS);
141
+ const requested = Number(envClefTimeoutMs());
141
142
  const timeoutMs = Number.isInteger(requested) && requested > 0 && requested <= MAX_TIMEOUT_MS ? requested : DEFAULT_TIMEOUT_MS;
142
143
  const headers = new Headers({ 'content-type': 'application/json' });
143
144
  if (route.token)
@@ -1,5 +1,5 @@
1
1
  import type { RerankerFn, RerankResult } from './types.js';
2
- import type { SearchResult } from '../search.js';
2
+ import type { SearchResult } from '../search/types.js';
3
3
  export declare const JEV_DEFAULT_TOP_K = 40;
4
4
  /** The System One `state` and one `noul` question per candidate (`c1`..`cN`). */
5
5
  export interface RelevanceRequest {
@@ -1,3 +1,4 @@
1
+ import { envJevModel, envJevTimeoutMs, envTypesafeApiKey } from '../env.js';
1
2
  import { crossEncoderReranker } from './cross-encoder.js';
2
3
  import { redactSecretsStrict } from '../secret-detect.js';
3
4
  import { log } from '../log.js';
@@ -45,12 +46,11 @@ export function buildRelevanceRequest(query, head) {
45
46
  }
46
47
  /** One batched request for the whole candidate list. Rejects with the reason when there are no usable scores. */
47
48
  async function requestScores(query, head) {
48
- const key = process.env.TYPESAFE_API_KEY;
49
+ const key = envTypesafeApiKey();
49
50
  if (!key)
50
51
  throw new Error('TYPESAFE_API_KEY not set');
51
52
  const { state, questions } = buildRelevanceRequest(query, head);
52
- const parsed = Number.parseInt(process.env.HIPPO_JEV_TIMEOUT_MS ?? '', 10);
53
- const timeoutMs = parsed > 0 ? parsed : DEFAULT_TIMEOUT_MS;
53
+ const timeoutMs = envJevTimeoutMs() ?? DEFAULT_TIMEOUT_MS;
54
54
  const controller = new AbortController();
55
55
  const timer = setTimeout(() => controller.abort(), timeoutMs);
56
56
  try {
@@ -59,7 +59,7 @@ async function requestScores(query, head) {
59
59
  headers: { 'content-type': 'application/json', authorization: `Bearer ${key}` },
60
60
  body: JSON.stringify({
61
61
  state,
62
- model: process.env.HIPPO_JEV_MODEL ?? DEFAULT_MODEL,
62
+ model: envJevModel() ?? DEFAULT_MODEL,
63
63
  questions,
64
64
  }),
65
65
  signal: controller.signal,
@@ -8,8 +8,10 @@ import type { RerankerFn } from './types.js';
8
8
  * Full characterisation deferred to a follow-on plan.
9
9
  *
10
10
  * Timeout: defaults to 30s; overridable via HIPPO_LLM_RERANKER_TIMEOUT_MS.
11
- * On timeout or any fetch failure, the reranker silently falls back to
12
- * identity ordering — recall must not hang on a wedged endpoint.
11
+ * On timeout or any fetch failure, the reranker warns once per process and
12
+ * falls back to identity ordering; recall must not hang on a wedged endpoint.
13
13
  */
14
+ export declare function createLlmReranker(): RerankerFn;
15
+ /** The instance the reranker registry serves; its warn-once flag lasts the process. */
14
16
  export declare const llmReranker: RerankerFn;
15
17
  //# sourceMappingURL=llm.d.ts.map
@@ -1,4 +1,6 @@
1
+ import { envLlmRerankerKey, envLlmRerankerModel, envLlmRerankerTimeoutMs, envLlmRerankerUrl } from '../env.js';
1
2
  import { redactSecretsStrict } from '../secret-detect.js';
3
+ import { log } from '../log.js';
2
4
  const DEFAULT_TIMEOUT_MS = 30_000;
3
5
  /**
4
6
  * Track 3 reranker: listwise LLM rerank. Uses a customer-supplied
@@ -9,24 +11,50 @@ const DEFAULT_TIMEOUT_MS = 30_000;
9
11
  * Full characterisation deferred to a follow-on plan.
10
12
  *
11
13
  * Timeout: defaults to 30s; overridable via HIPPO_LLM_RERANKER_TIMEOUT_MS.
12
- * On timeout or any fetch failure, the reranker silently falls back to
13
- * identity ordering — recall must not hang on a wedged endpoint.
14
+ * On timeout or any fetch failure, the reranker warns once per process and
15
+ * falls back to identity ordering; recall must not hang on a wedged endpoint.
14
16
  */
15
- export const llmReranker = async (query, results, options) => {
16
- const url = process.env.HIPPO_LLM_RERANKER_URL;
17
- const key = process.env.HIPPO_LLM_RERANKER_KEY;
18
- if (!url) {
19
- throw new Error('HIPPO_LLM_RERANKER_URL not set; refusing to run LLM reranker.');
20
- }
21
- const topK = options?.topK ?? 20;
22
- const head = results.slice(0, topK);
17
+ export function createLlmReranker() {
18
+ let warned = false;
19
+ return async (query, results, options) => {
20
+ const url = envLlmRerankerUrl();
21
+ if (!url) {
22
+ throw new Error('HIPPO_LLM_RERANKER_URL not set; refusing to run LLM reranker.');
23
+ }
24
+ const head = results.slice(0, options?.topK ?? 20);
25
+ let permutation = null;
26
+ try {
27
+ permutation = await requestPermutation(url, query, head);
28
+ }
29
+ catch (err) {
30
+ // A read path never throws, and never hands back the unranked order without saying so.
31
+ if (!warned) {
32
+ warned = true;
33
+ const reason = err instanceof Error ? err.message : 'unknown error';
34
+ log.warn(`llm reranker unavailable (${reason}); keeping the input order. Subsequent calls will not repeat this warning.`);
35
+ }
36
+ }
37
+ const ordered = permutation ? permutation.map((idx) => head[idx]) : head;
38
+ return ordered.map((r, i) => ({
39
+ ...r,
40
+ rerankScore: ordered.length - i,
41
+ preRerankRank: r.preRerankRank ?? i + 1,
42
+ postRerankRank: i + 1,
43
+ }));
44
+ };
45
+ }
46
+ /** The instance the reranker registry serves; its warn-once flag lasts the process. */
47
+ export const llmReranker = createLlmReranker();
48
+ /** One chat-completions call; rejects with the reason when the reply holds no usable permutation. */
49
+ async function requestPermutation(url, query, head) {
50
+ const key = envLlmRerankerKey();
23
51
  const prompt = [
24
52
  `Rerank the candidates below by relevance to the query. Output a JSON array of indices (zero-indexed) in best-first order.`,
25
53
  `Query: ${redactSecretsStrict(query)}`,
26
54
  ...head.map((r, i) => `[${i}] ${redactSecretsStrict(r.entry.content)}`),
27
55
  `Output format: [<int>, <int>, ...] with all ${head.length} indices.`,
28
56
  ].join('\n');
29
- const timeoutMs = Number.parseInt(process.env.HIPPO_LLM_RERANKER_TIMEOUT_MS ?? '', 10) || DEFAULT_TIMEOUT_MS;
57
+ const timeoutMs = envLlmRerankerTimeoutMs() ?? DEFAULT_TIMEOUT_MS;
30
58
  const controller = new AbortController();
31
59
  const timer = setTimeout(() => controller.abort(), timeoutMs);
32
60
  const headers = {
@@ -35,47 +63,39 @@ export const llmReranker = async (query, results, options) => {
35
63
  if (key) {
36
64
  headers.authorization = `Bearer ${key}`;
37
65
  }
38
- let permutation = null;
39
66
  try {
40
67
  const resp = await fetch(`${url.replace(/\/$/, '')}/chat/completions`, {
41
68
  method: 'POST',
42
69
  headers: { ...headers },
43
70
  body: JSON.stringify({
44
- model: process.env.HIPPO_LLM_RERANKER_MODEL ?? 'gpt-4o-mini',
71
+ model: envLlmRerankerModel() ?? 'gpt-4o-mini',
45
72
  messages: [{ role: 'user', content: prompt }],
46
73
  temperature: 0,
47
74
  }),
48
75
  signal: controller.signal,
49
76
  });
50
- if (resp.ok) {
51
- const j = await resp.json();
52
- const txt = j.choices?.[0]?.message?.content ?? '';
53
- const m = txt.match(/\[\s*(\d+(?:\s*,\s*\d+)*)\s*\]/);
54
- if (m) {
55
- const parsed = m[1].split(',').map((s) => parseInt(s.trim(), 10));
56
- if (parsed.length === head.length &&
57
- parsed.every((n) => Number.isInteger(n) && n >= 0 && n < head.length) &&
58
- new Set(parsed).size === head.length) {
59
- permutation = parsed;
60
- }
61
- }
77
+ if (!resp.ok) {
78
+ await resp.body?.cancel();
79
+ throw new Error(`HTTP ${resp.status}`);
62
80
  }
81
+ const j = await resp.json();
82
+ const txt = j.choices?.[0]?.message?.content ?? '';
83
+ const m = txt.match(/\[\s*(\d+(?:\s*,\s*\d+)*)\s*\]/);
84
+ const parsed = m ? m[1].split(',').map((s) => parseInt(s.trim(), 10)) : [];
85
+ const isPermutation = parsed.length === head.length &&
86
+ parsed.every((n) => Number.isInteger(n) && n >= 0 && n < head.length) &&
87
+ new Set(parsed).size === head.length;
88
+ if (!isPermutation)
89
+ throw new Error('reply is not a permutation of the candidates');
90
+ return parsed;
63
91
  }
64
- catch {
65
- // Fall through to identity. Includes AbortError on timeout — see
66
- // DEFAULT_TIMEOUT_MS / HIPPO_LLM_RERANKER_TIMEOUT_MS above.
92
+ catch (err) {
93
+ if (err instanceof Error && err.name === 'AbortError')
94
+ throw new Error(`no answer within ${timeoutMs} ms`);
95
+ throw err;
67
96
  }
68
97
  finally {
69
98
  clearTimeout(timer);
70
99
  }
71
- const ordered = permutation
72
- ? permutation.map((idx) => head[idx])
73
- : head;
74
- return ordered.map((r, i) => ({
75
- ...r,
76
- rerankScore: ordered.length - i,
77
- preRerankRank: r.preRerankRank ?? i + 1,
78
- postRerankRank: i + 1,
79
- }));
80
- };
100
+ }
81
101
  //# sourceMappingURL=llm.js.map
@@ -1,4 +1,4 @@
1
- import type { SearchResult } from '../search.js';
1
+ import type { SearchResult } from '../search/types.js';
2
2
  /**
3
3
  * A reranker reorders (and optionally rescales) the candidate set produced
4
4
  * by hybridSearch's BM25 + cosine + MMR pipeline. Rerankers run AFTER MMR
package/dist/salience.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * Inspired by the biological salience network (anterior insula + dACC):
6
6
  * not everything that enters working memory deserves long-term storage.
7
7
  */
8
- import { textOverlap } from './search.js';
8
+ import { textOverlap } from './tokenize.js';
9
9
  import { duplicateKey, heldTextKeys } from './same-text.js';
10
10
  const DEFAULTS = {
11
11
  recentWindow: 20,
@@ -16,6 +16,7 @@ export interface SchedulerFsDeps {
16
16
  readFileSync: typeof fs.readFileSync;
17
17
  mkdirSync: typeof fs.mkdirSync;
18
18
  writeFileSync: typeof fs.writeFileSync;
19
+ renameSync: typeof fs.renameSync;
19
20
  }
20
21
  /** Test-only override. Not part of this module's public API surface. */
21
22
  export declare function __setSchedulerFsDeps(overrides: Partial<SchedulerFsDeps>): void;
package/dist/scheduler.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
+ import { log } from './log.js';
3
4
  export const DAILY_TASK_NAME = 'hippo-daily-runner';
4
5
  let fsDeps = {
5
6
  existsSync: fs.existsSync,
6
7
  readFileSync: fs.readFileSync,
7
8
  mkdirSync: fs.mkdirSync,
8
9
  writeFileSync: fs.writeFileSync,
10
+ renameSync: fs.renameSync,
9
11
  };
10
12
  /** Test-only override. Not part of this module's public API surface. */
11
13
  export function __setSchedulerFsDeps(overrides) {
@@ -27,8 +29,16 @@ export function loadWorkspaceRegistry(globalRoot) {
27
29
  const registryPath = workspaceRegistryPath(globalRoot);
28
30
  if (!fsDeps.existsSync(registryPath))
29
31
  return defaultRegistry();
32
+ let text;
30
33
  try {
31
- const parsed = JSON.parse(fsDeps.readFileSync(registryPath, 'utf8'));
34
+ text = fsDeps.readFileSync(registryPath, 'utf8');
35
+ }
36
+ catch (err) {
37
+ log.warn(`workspace registry ${registryPath} could not be read (${err instanceof Error ? err.message : String(err)}); starting with no workspaces`);
38
+ return defaultRegistry();
39
+ }
40
+ try {
41
+ const parsed = JSON.parse(text);
32
42
  const workspaces = Array.isArray(parsed.workspaces)
33
43
  ? [...new Set(parsed.workspaces.map((entry) => normalizeWorkspace(String(entry))).filter(Boolean))].sort()
34
44
  : [];
@@ -37,13 +47,25 @@ export function loadWorkspaceRegistry(globalRoot) {
37
47
  workspaces,
38
48
  };
39
49
  }
40
- catch {
41
- // A missing or corrupt registry starts empty; the next registration rewrites it.
50
+ catch (err) {
51
+ // The next registration rewrites the file, so keep the bad copy for the user to recover entries from.
52
+ setAsideCorruptRegistry(registryPath, err);
42
53
  return defaultRegistry();
43
54
  }
44
55
  }
56
+ function setAsideCorruptRegistry(registryPath, err) {
57
+ const reason = err instanceof Error ? err.message : String(err);
58
+ const aside = `${registryPath}.corrupt-${new Date().toISOString().replace(/[:.]/g, '-')}`;
59
+ try {
60
+ fsDeps.renameSync(registryPath, aside);
61
+ log.warn(`workspace registry ${registryPath} is corrupt (${reason}); moved it to ${aside} and starting with no workspaces`);
62
+ }
63
+ catch (renameErr) {
64
+ log.warn(`workspace registry ${registryPath} is corrupt (${reason}) and could not be moved aside (${renameErr instanceof Error ? renameErr.message : String(renameErr)}); starting with no workspaces`);
65
+ }
66
+ }
45
67
  export function saveWorkspaceRegistry(globalRoot, registry) {
46
- fsDeps.mkdirSync(globalRoot, { recursive: true });
68
+ fsDeps.mkdirSync(globalRoot, { recursive: true, mode: 0o700 });
47
69
  fsDeps.writeFileSync(workspaceRegistryPath(globalRoot), JSON.stringify({
48
70
  version: 1,
49
71
  workspaces: [...new Set(registry.workspaces.map(normalizeWorkspace))].sort(),
package/dist/scope.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { envGstackSkill, envOpenclawSkill, envScope } from './env.js';
1
2
  /**
2
3
  * Detect the current operational scope from environment signals.
3
4
  * Returns a scope name string (no prefix), or null if no scope detected.
@@ -6,13 +7,13 @@
6
7
  * Pure env var reads: no I/O, safe to call from hot paths (e.g. UserPromptSubmit hook).
7
8
  */
8
9
  export function detectScope() {
9
- const explicit = process.env['HIPPO_SCOPE'];
10
+ const explicit = envScope();
10
11
  if (explicit && explicit.trim())
11
12
  return explicit.trim();
12
- const gstackSkill = process.env['GSTACK_SKILL'];
13
+ const gstackSkill = envGstackSkill();
13
14
  if (gstackSkill && gstackSkill.trim())
14
15
  return gstackSkill.trim();
15
- const openclawSkill = process.env['OPENCLAW_SKILL'];
16
+ const openclawSkill = envOpenclawSkill();
16
17
  if (openclawSkill && openclawSkill.trim())
17
18
  return openclawSkill.trim();
18
19
  return null;
@@ -0,0 +1,10 @@
1
+ import type { MemoryEntry } from '../memory.js';
2
+ export interface CurrentnessOptions {
3
+ /** Keep only rows current at this ISO date string. */
4
+ asOf?: string;
5
+ /** Keep superseded rows when no `asOf` is given. */
6
+ includeSuperseded?: boolean;
7
+ }
8
+ /** Rows current at `asOf`, or rows not superseded unless `includeSuperseded`. */
9
+ export declare function currentEntries(entries: MemoryEntry[], options: CurrentnessOptions): MemoryEntry[];
10
+ //# sourceMappingURL=as-of.d.ts.map
@@ -0,0 +1,22 @@
1
+ /** Rows current at `asOf`, or rows not superseded unless `includeSuperseded`. */
2
+ export function currentEntries(entries, options) {
3
+ if (options.asOf)
4
+ return entriesAsOf(entries, new Date(options.asOf));
5
+ return options.includeSuperseded ? entries : entries.filter((e) => !e.superseded_by);
6
+ }
7
+ function entriesAsOf(entries, asOfDate) {
8
+ // A merged pool can repeat an id; the first row wins, as a scan from the front would pick.
9
+ const byId = new Map();
10
+ for (const e of entries)
11
+ if (!byId.has(e.id))
12
+ byId.set(e.id, e);
13
+ return entries.filter((e) => {
14
+ if (new Date(e.valid_from) > asOfDate)
15
+ return false;
16
+ if (!e.superseded_by)
17
+ return true;
18
+ const successor = byId.get(e.superseded_by);
19
+ return successor?.valid_from ? new Date(successor.valid_from) > asOfDate : true;
20
+ });
21
+ }
22
+ //# sourceMappingURL=as-of.js.map
@@ -0,0 +1,14 @@
1
+ import type { MemoryEntry } from '../memory.js';
2
+ import type { ResultCost, SearchResult } from './types.js';
3
+ export interface SearchOptions {
4
+ budget?: number;
5
+ now?: Date;
6
+ hippoRoot?: string;
7
+ minResults?: number;
8
+ cost?: ResultCost;
9
+ includeSuperseded?: boolean;
10
+ asOf?: string;
11
+ }
12
+ /** Synchronous BM25 search: relevance * strength * recency and the rank boosts, without embeddings or the outcome nudge. */
13
+ export declare function search(query: string, entries: MemoryEntry[], options?: SearchOptions): SearchResult[];
14
+ //# sourceMappingURL=bm25-search.d.ts.map
@@ -0,0 +1,43 @@
1
+ import { estimateTokens } from '../token-ledger.js';
2
+ import { tokenize } from '../tokenize.js';
3
+ import { evalNow } from '../ablation.js';
4
+ import { extractPathTags } from '../path-context.js';
5
+ import { detectScope } from '../scope.js';
6
+ import { compareScoredResults } from '../compare.js';
7
+ import { bm25Score, buildCorpus, entryText } from './bm25.js';
8
+ import { currentEntries } from './as-of.js';
9
+ import { applyRankBoosts, strengthRecencyMultipliers, NO_SUMMARY_SCORING } from './boosts.js';
10
+ import { temporalContext } from './temporal.js';
11
+ import { dedupeExtracted, fitBudget, withDagChildren } from './finalize.js';
12
+ /** Synchronous BM25 search: relevance * strength * recency and the rank boosts, without embeddings or the outcome nudge. */
13
+ export function search(query, entries, options = {}) {
14
+ const now = options.now ?? evalNow(); // honors HIPPO_FAKE_NOW (eval-only; see ablation.ts)
15
+ const pool = currentEntries(entries, options);
16
+ if (pool.length === 0)
17
+ return [];
18
+ const queryTerms = tokenize(query);
19
+ if (queryTerms.length === 0)
20
+ return [];
21
+ const corpus = buildCorpus(pool.map(entryText));
22
+ const ctx = {
23
+ now,
24
+ pathTags: extractPathTags(process.cwd()),
25
+ scope: detectScope(),
26
+ temporal: temporalContext(query, pool),
27
+ outcome: false,
28
+ summary: NO_SUMMARY_SCORING,
29
+ };
30
+ const scored = [];
31
+ for (let i = 0; i < pool.length; i++) {
32
+ const bm25 = bm25Score(corpus, i, queryTerms);
33
+ if (bm25 <= 0)
34
+ continue;
35
+ const { strength, recency } = strengthRecencyMultipliers(pool[i], now);
36
+ const normBm25 = bm25 / queryTerms.length;
37
+ const score = applyRankBoosts(normBm25 * strength * recency, pool[i], ctx).score;
38
+ scored.push({ entry: pool[i], score, bm25, cosine: 0, tokens: estimateTokens(pool[i].content) });
39
+ }
40
+ scored.sort(compareScoredResults);
41
+ return fitBudget(withDagChildren(dedupeExtracted(scored), pool), options.budget ?? 4000, options.minResults ?? 1, options.cost);
42
+ }
43
+ //# sourceMappingURL=bm25-search.js.map