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
@@ -0,0 +1,31 @@
1
+ import { type MemoryEntry } from '../memory.js';
2
+ import type { ContextOpts, ContextResult } from './context-types.js';
3
+ import type { Context } from './types.js';
4
+ export { oneCopyPerMemory } from './context-select.js';
5
+ /**
6
+ * v39 S4: the secret half of the ambient policy on its own, for callers
7
+ * that apply their own scope rule. A flagged row is only admitted inside its owning project;
8
+ * flagged rows with no project origin never ambient-inject.
9
+ */
10
+ export declare function ambientSecretAdmit(e: MemoryEntry, currentProjectName: string): boolean;
11
+ /** Most rows per store a no-query context reads; past it, ranking and ambientState see the strongest by decay. */
12
+ export declare const CONTEXT_CANDIDATE_CAP = 2000;
13
+ /**
14
+ * Assemble a context bundle: recalled memories (pinned-only / strength-sorted
15
+ * fallback / hybrid search) + active task snapshot + session handoff + recent
16
+ * session events. Budget-bounded, tenant-scoped. Mutates `last_retrieval_ids`
17
+ * + emits a 'recall' audit row for non-pinned, non-'*' queries.
18
+ *
19
+ * Behaves like the pre-extraction `cmdContext` data-loading + selection
20
+ * pipeline. CLI presentation (markdown / json / additional-context rendering)
21
+ * stays in `cli.ts`.
22
+ *
23
+ * Tenant scope: all `loadAllEntries` / snapshot / handoff / events reads use
24
+ * `ctx.tenantId`. Cross-tenant rows are filtered out.
25
+ *
26
+ * @returns An empty result (`entries: []`, snapshot/handoff/events undefined)
27
+ * when there's nothing to surface (no memories AND no snapshot AND no handoff
28
+ * AND no recent events).
29
+ */
30
+ export declare function getContext(ctx: Context, opts?: ContextOpts): Promise<ContextResult>;
31
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1,378 @@
1
+ // Ambient context injection: the admission policy and getContext.
2
+ import { isInitialized } from '../store/open.js';
3
+ import { strengthenRetrieved } from '../store/entry-writes.js';
4
+ import { loadRecallSearchEntries } from '../store/search-rows.js';
5
+ import { DEFAULT_SEARCH_CANDIDATE_LIMIT } from '../store/rows.js';
6
+ import { loadAmbientCandidates, loadContextCandidates, } from '../store/candidates.js';
7
+ import { loadIndex, saveIndex, updateStats } from '../store/index-and-stats.js';
8
+ import { loadFreshActiveTaskSnapshot, listSessionEvents, SNAPSHOT_AMBIENT_MAX_AGE_MS } from '../store/sessions.js';
9
+ import { loadLatestHandoff } from '../store/handoffs.js';
10
+ import { estimateTokens } from '../token-ledger.js';
11
+ import { markRetrieved, COMPACTION_MEMORY_TAG } from '../memory.js';
12
+ import { isContentWorthStoring } from '../audit.js';
13
+ import { getGlobalRoot } from '../shared.js';
14
+ import { writeRecallTraceAtRoot } from '../recall-trace.js';
15
+ import { evalNow, isRecallBoostAblated } from '../ablation.js';
16
+ import { dropHeldCopies } from '../same-text.js';
17
+ import { loadConfig } from '../config.js';
18
+ import { resolveProjectIdentity, classifyOriginProject, isGlobalStoreRoot } from '../project-identity.js';
19
+ import { promptTokens } from '../prompt-recall.js';
20
+ import { detectSecret } from '../secret-detect.js';
21
+ import { isSessionDigestRow } from '../session-digest.js';
22
+ import { addAmbientTallies, ambientStateFromTallies } from '../ambient.js';
23
+ import { loadAmbientTallies } from '../ambient-store.js';
24
+ import { passesScopeFilterForRecall, assertScopeRequestAllowed } from '../recall-scope.js';
25
+ import { finiteOr, selectBySearch, selectPinned, selectStrongest, } from './context-select.js';
26
+ export { oneCopyPerMemory } from './context-select.js';
27
+ /**
28
+ * v39: the single ambient-injection admission policy, shared by getContext
29
+ * and the CLI-side ambient-state summary so the two cannot drift.
30
+ *
31
+ * - S4 secret veto is UNCONDITIONAL: neither crossProject nor
32
+ * contextProjectIsolation:false re-includes secrets. A flagged row only
33
+ * injects inside its owning project; flagged rows with no project origin
34
+ * (''/null) never ambient-inject at all. Explicit recall is unaffected -
35
+ * recalling a secret is a deliberate act.
36
+ * - S2 envelope parity: private/quarantine scopes never inject unless `exactScope` names one.
37
+ * - S3 origin partition: other-project rows are excluded unless
38
+ * `includeCrossProject`.
39
+ */
40
+ function ambientAdmitEntry(e, currentProjectName, includeCrossProject, exactScope) {
41
+ if (!ambientSecretAdmit(e, currentProjectName))
42
+ return false;
43
+ if (!passesScopeFilterForRecall(e.scope ?? null, exactScope))
44
+ return false;
45
+ if (includeCrossProject)
46
+ return true;
47
+ return classifyOriginProject(e.origin_project, currentProjectName) !== 'cross-project';
48
+ }
49
+ /**
50
+ * v39 S4: the secret half of the ambient policy on its own, for callers
51
+ * that apply their own scope rule. A flagged row is only admitted inside its owning project;
52
+ * flagged rows with no project origin never ambient-inject.
53
+ */
54
+ export function ambientSecretAdmit(e, currentProjectName) {
55
+ if (!detectSecret(e).flagged)
56
+ return true;
57
+ const origin = e.origin_project;
58
+ if (origin === undefined || origin === null || origin === '')
59
+ return false;
60
+ return origin === currentProjectName;
61
+ }
62
+ /** Most rows per store a no-query context reads; past it, ranking and ambientState see the strongest by decay. */
63
+ export const CONTEXT_CANDIDATE_CAP = 2000;
64
+ // The pinned-only branch needs pins and recent-N candidates, not the corpus; `recall` applies there only.
65
+ function loadAmbientEntries(hippoRoot, tenantId, pinnedOnly, includeRecent, admit, window, recall, onQualityDrop) {
66
+ if (!pinnedOnly) {
67
+ const rows = 'query' in window
68
+ ? loadRecallSearchEntries(hippoRoot, window.query, DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, window.exactScope, 'exact', false, window.project)
69
+ : loadContextCandidates(hippoRoot, tenantId, window);
70
+ return { entries: rows.filter(admit) };
71
+ }
72
+ // DF3's quality floor runs on the recent-N slice AFTER this load, so the load
73
+ // counts by it too, or it stops short of a store whose newest rows are junk.
74
+ const admitAmbient = (e) => {
75
+ if (!admit(e))
76
+ return false;
77
+ if (e.pinned || isContentWorthStoring(e.content))
78
+ return true;
79
+ onQualityDrop?.(e);
80
+ return false;
81
+ };
82
+ return loadAmbientCandidates(hippoRoot, tenantId, includeRecent, admitAmbient, recall);
83
+ }
84
+ /**
85
+ * Assemble a context bundle: recalled memories (pinned-only / strength-sorted
86
+ * fallback / hybrid search) + active task snapshot + session handoff + recent
87
+ * session events. Budget-bounded, tenant-scoped. Mutates `last_retrieval_ids`
88
+ * + emits a 'recall' audit row for non-pinned, non-'*' queries.
89
+ *
90
+ * Behaves like the pre-extraction `cmdContext` data-loading + selection
91
+ * pipeline. CLI presentation (markdown / json / additional-context rendering)
92
+ * stays in `cli.ts`.
93
+ *
94
+ * Tenant scope: all `loadAllEntries` / snapshot / handoff / events reads use
95
+ * `ctx.tenantId`. Cross-tenant rows are filtered out.
96
+ *
97
+ * @returns An empty result (`entries: []`, snapshot/handoff/events undefined)
98
+ * when there's nothing to surface (no memories AND no snapshot AND no handoff
99
+ * AND no recent events).
100
+ */
101
+ export async function getContext(ctx, opts = {}) {
102
+ const budget = opts.budget ?? 1500;
103
+ assertScopeRequestAllowed(ctx.actor, opts.exactScope);
104
+ if (budget <= 0) {
105
+ return { entries: [], tokens: 0 };
106
+ }
107
+ const plan = planContext(ctx, opts);
108
+ const sections = loadTaskSections(ctx, opts, plan, openBlockBudget(plan, opts, budget));
109
+ const admission = ambientAdmission(opts, plan, sections.shownHandoff);
110
+ const pools = loadPools(ctx, plan, admission, promptRecallRequest(opts, plan));
111
+ const noSections = !sections.shownSnapshot && !sections.shownHandoff && sections.shownEvents.length === 0;
112
+ if (!plan.promptRecallPending && pools.local.entries.length === 0 && pools.global.entries.length === 0 && noSections) {
113
+ return { entries: [], tokens: 0 };
114
+ }
115
+ const picked = plan.pinnedOnly
116
+ ? selectPinned(ctx, opts, plan, sections.left, pools, admission)
117
+ : plan.query === '*'
118
+ ? selectStrongest(plan, sections.left, pools)
119
+ : await selectBySearch(ctx, plan, sections.left, pools, admission);
120
+ if (picked === null) {
121
+ return { entries: [], tokens: 0 };
122
+ }
123
+ const { items, tokens } = finalizeSelection(picked, plan);
124
+ if (items.length === 0 && noSections) {
125
+ // A query that found nothing is the coverage-gap signal, so it still gets a trace; pinned-only stays read-only.
126
+ if (!plan.pinnedOnly)
127
+ traceEmptyContext(ctx, opts, plan.query);
128
+ return { entries: [], tokens: 0 };
129
+ }
130
+ // pinnedOnly is the UserPromptSubmit hot path — read-only so pinned
131
+ // memories don't inflate retrieval_count or extend half_life every turn.
132
+ const recorded = plan.pinnedOnly
133
+ ? { items, ambientState: undefined }
134
+ : recordRetrieval(ctx, opts, plan, items, sections.activeSnapshot);
135
+ return {
136
+ entries: recorded.items,
137
+ tokens,
138
+ activeSnapshot: sections.shownSnapshot ?? undefined,
139
+ sessionHandoff: sections.shownHandoff ?? undefined,
140
+ recentEvents: sections.shownEvents.length > 0 ? sections.shownEvents : undefined,
141
+ ambientState: recorded.ambientState,
142
+ };
143
+ }
144
+ function planContext(ctx, opts) {
145
+ const pinnedOnly = opts.pinnedOnly === true;
146
+ // Global memories do not establish a project boundary for task state.
147
+ const hasLocal = isInitialized(ctx.hippoRoot);
148
+ const query = (opts.q ?? '').trim() || '*';
149
+ const globalRoot = getGlobalRoot();
150
+ const hasGlobal = isInitialized(globalRoot);
151
+ const primaryIsGlobal = isGlobalStoreRoot(ctx.hippoRoot);
152
+ // opts.scope is only the tag boost, opts.exactScope the envelope request; other-project memories are
153
+ // excluded unless the caller asks for them (crossProject) or isolation is disabled.
154
+ const config = loadConfig(ctx.hippoRoot);
155
+ const isolationEnabled = config.contextProjectIsolation !== false;
156
+ const currentProjectName = opts.currentProject ?? resolveProjectIdentity(process.cwd()).name;
157
+ const includeCrossProject = opts.crossProject === true || !isolationEnabled;
158
+ // Decided before the ambient loads so the pinned-only FTS candidate query can share their connection.
159
+ const promptRecallPending = pinnedOnly && Boolean(opts.prompt?.trim()) && config.pinnedInject.promptRecall === true;
160
+ const cost = opts.cost;
161
+ const price = (entry, isGlobal, promptRecall) => cost
162
+ ? cost.entry({ entry, isGlobal, promptRecall, origin: entry.origin_project ?? null, category: classifyOriginProject(entry.origin_project, currentProjectName) })
163
+ : estimateTokens(entry.content);
164
+ return {
165
+ pinnedOnly,
166
+ limit: opts.limit ?? Number.POSITIVE_INFINITY,
167
+ includeRecent: opts.includeRecent ?? 0,
168
+ activeScope: opts.scope ?? '',
169
+ exactScope: opts.exactScope || undefined,
170
+ query,
171
+ hasLocal,
172
+ hasGlobal,
173
+ globalRoot,
174
+ primaryIsGlobal,
175
+ hasLocalTaskState: hasLocal && !primaryIsGlobal,
176
+ config,
177
+ currentProjectName,
178
+ includeCrossProject,
179
+ originProject: includeCrossProject || currentProjectName === '' ? undefined : currentProjectName,
180
+ promptRecallPending,
181
+ cost,
182
+ price,
183
+ obs: opts.deliveryObserver,
184
+ };
185
+ }
186
+ /** The prompt-recall candidate request the ambient loads carry, when the prompt has any terms. */
187
+ function promptRecallRequest(opts, plan) {
188
+ const { pinnedInject } = plan.config;
189
+ const promptRecallTerms = plan.promptRecallPending && pinnedInject.enabled
190
+ ? Array.from(promptTokens(opts.prompt ?? ''))
191
+ : [];
192
+ return promptRecallTerms.length > 0
193
+ ? { terms: promptRecallTerms, limit: Math.floor(finiteOr(pinnedInject.promptRecallCandidates, 100, 1)) }
194
+ : undefined;
195
+ }
196
+ /** Reports the block's facts to the observer and returns the budget left after the fixed headers. */
197
+ function openBlockBudget(plan, opts, budget) {
198
+ const { config, cost, obs, pinnedOnly, promptRecallPending } = plan;
199
+ const blockBudget = pinnedOnly && opts.budget === undefined ? config.pinnedInject.budget : budget;
200
+ obs?.facts({ projectName: plan.currentProjectName, budgetTokens: blockBudget, promptRecall: promptRecallPending });
201
+ if (pinnedOnly && !config.pinnedInject.enabled)
202
+ obs?.disabled();
203
+ return cost
204
+ ? Math.max(0, blockBudget - cost.fixed(blockBudget, { cross: plan.includeCrossProject, promptRecall: promptRecallPending, ambient: !pinnedOnly && config.ambient.enabled }))
205
+ : blockBudget;
206
+ }
207
+ // Sections print ahead of the memories, so they are paid first; one that does not fit is dropped, as an oversize entry is.
208
+ function loadTaskSections(ctx, opts, plan, startLeft) {
209
+ const { exactScope, hasLocalTaskState, cost } = plan;
210
+ let left = startLeft;
211
+ const pays = (tokens) => {
212
+ if (tokens > left)
213
+ return false;
214
+ left -= tokens;
215
+ return true;
216
+ };
217
+ // Bounded read: an orphaned snapshot ages out of this ambient surface; the owner session's read stays unbounded.
218
+ const rowScope = (r) => r?.scope ?? null;
219
+ const rawActiveSnapshot = hasLocalTaskState
220
+ ? loadFreshActiveTaskSnapshot(ctx.hippoRoot, ctx.tenantId, {
221
+ sessionId: opts.currentSessionId,
222
+ })
223
+ : null;
224
+ // The same envelope rule ambientAdmitEntry applies to memory rows.
225
+ const activeSnapshot = rawActiveSnapshot && passesScopeFilterForRecall(rowScope(rawActiveSnapshot), exactScope)
226
+ ? rawActiveSnapshot
227
+ : null;
228
+ // Key on the RAW snapshot: a scope-hidden active session must not fall through to another session's ambient handoff.
229
+ const rawSessionHandoff = !hasLocalTaskState
230
+ ? null
231
+ : rawActiveSnapshot?.session_id
232
+ ? loadLatestHandoff(ctx.hippoRoot, ctx.tenantId, rawActiveSnapshot.session_id)
233
+ : loadLatestHandoff(ctx.hippoRoot, ctx.tenantId, undefined, {
234
+ unfinishedOnly: true,
235
+ maxAgeMs: SNAPSHOT_AMBIENT_MAX_AGE_MS,
236
+ // Scope is admitted in SQL so a newer denied row can't hide an older eligible one before LIMIT 1.
237
+ scopeFilter: 'default-deny',
238
+ });
239
+ const sessionHandoff = rawSessionHandoff && passesScopeFilterForRecall(rowScope(rawSessionHandoff), exactScope)
240
+ ? rawSessionHandoff
241
+ : null;
242
+ // Raw session id here too: each event is admitted on its own scope, same as recall and the CLI.
243
+ const recentSessionEvents = hasLocalTaskState && rawActiveSnapshot?.session_id
244
+ ? listSessionEvents(ctx.hippoRoot, ctx.tenantId, {
245
+ session_id: rawActiveSnapshot.session_id,
246
+ limit: 5,
247
+ }).filter((e) => passesScopeFilterForRecall(rowScope(e), exactScope))
248
+ : [];
249
+ const shownSnapshot = activeSnapshot && (!cost || pays(cost.snapshot(activeSnapshot))) ? activeSnapshot : null;
250
+ const shownHandoff = sessionHandoff && (!cost || pays(cost.handoff(sessionHandoff))) ? sessionHandoff : null;
251
+ const shownEvents = recentSessionEvents.length > 0 && (!cost || pays(cost.trail(recentSessionEvents))) ? recentSessionEvents : [];
252
+ plan.obs?.sections(Number(shownSnapshot !== null) + Number(shownHandoff !== null) + Number(shownEvents.length > 0), Number(activeSnapshot !== shownSnapshot) + Number(sessionHandoff !== shownHandoff) + Number(recentSessionEvents.length !== shownEvents.length));
253
+ return { activeSnapshot, shownSnapshot, shownHandoff, shownEvents, left };
254
+ }
255
+ function ambientAdmission(opts, plan, shownHandoff) {
256
+ const transcriptHandoffSession = shownHandoff?.evidence?.derivedFrom === 'transcript' ? shownHandoff.sessionId : null;
257
+ let digestHiddenForHandoff = false;
258
+ const ambientAdmit = (e) => {
259
+ // A printed handoff already carries the session's closing message, which its digest would print a second time.
260
+ if (transcriptHandoffSession !== null && e.source_session_id === transcriptHandoffSession && isSessionDigestRow(e)) {
261
+ digestHiddenForHandoff = true;
262
+ return false;
263
+ }
264
+ return ambientAdmitEntry(e, plan.currentProjectName, plan.includeCrossProject, plan.exactScope);
265
+ };
266
+ const ownSessionId = opts.currentSessionId || '';
267
+ // Inside admit, not after the load, so the loader's window widens past a session's own items.
268
+ const isOwnCompactionItem = (e) => ownSessionId !== '' &&
269
+ e.source_session_id === ownSessionId &&
270
+ e.tags.includes(COMPACTION_MEMORY_TAG);
271
+ // Superseded rows never inject; which rows reach ambientAdmitEntry matters because it regex-scans content for secrets.
272
+ const admit = (e) => !e.superseded_by && !isOwnCompactionItem(e) && ambientAdmit(e);
273
+ // The two-store search has always ranked a session's own compaction items; only the local search drops them.
274
+ const bothStoresAdmit = (e) => !e.superseded_by && ambientAdmit(e);
275
+ return { ambientAdmit, admit, bothStoresAdmit, digestHidden: () => digestHiddenForHandoff };
276
+ }
277
+ function loadPools(ctx, plan, admission, recallRequest) {
278
+ const { obs, pinnedOnly, primaryIsGlobal, hasGlobal, exactScope } = plan;
279
+ const searches = plan.query !== '*' && !pinnedOnly;
280
+ const searchesBoth = searches && hasGlobal && !primaryIsGlobal;
281
+ const poolAdmit = searchesBoth ? admission.bothStoresAdmit : admission.admit;
282
+ const loadAdmit = obs ? obs.watchAdmit(poolAdmit) : poolAdmit;
283
+ const qualityDrop = (isGlobal) => obs && !plan.promptRecallPending ? (e) => obs.qualityDropped(e, isGlobal) : undefined;
284
+ // The window's predicates are ones admit applies anyway, so below the cap the admitted rows are unchanged.
285
+ const window = searches
286
+ ? { query: plan.query, exactScope, project: plan.originProject }
287
+ : {
288
+ exactScope,
289
+ project: plan.originProject,
290
+ cap: CONTEXT_CANDIDATE_CAP,
291
+ now: evalNow(),
292
+ };
293
+ // Tenant-scoped loads: never resolveTenantId({}) here.
294
+ const local = plan.hasLocal
295
+ ? loadAmbientEntries(ctx.hippoRoot, ctx.tenantId, pinnedOnly, plan.includeRecent, loadAdmit, window, recallRequest, qualityDrop(primaryIsGlobal))
296
+ : { entries: [] };
297
+ const global = hasGlobal && !primaryIsGlobal
298
+ ? loadAmbientEntries(plan.globalRoot, ctx.tenantId, pinnedOnly, plan.includeRecent, loadAdmit, window, recallRequest, qualityDrop(true))
299
+ : { entries: [] };
300
+ return { local, global };
301
+ }
302
+ /** The `limit` cut, then the held-copy drop, then each entry's origin annotation. */
303
+ function finalizeSelection(picked, plan) {
304
+ const { obs } = plan;
305
+ let selected = picked;
306
+ if (plan.limit < selected.length) {
307
+ const cut = selected.slice(0, plan.limit);
308
+ obs?.dropMissing(selected.map((r) => r.entry), cut.map((r) => r.entry), 'limit', 'limit');
309
+ selected = cut;
310
+ }
311
+ const heldDropped = dropHeldCopies(selected, (r) => r.entry); // after the last cut, so a merged row that was cut hides nothing
312
+ obs?.dropMissing(selected.map((r) => r.entry), heldDropped.map((r) => r.entry), 'limit', 'duplicate');
313
+ selected = heldDropped;
314
+ const tokens = selected.reduce((sum, r) => sum + r.tokens, 0);
315
+ // Every returned entry carries its origin and how it relates to the active project, so renderers can mark cross-project rows.
316
+ selected = selected.map((r) => ({
317
+ ...r,
318
+ origin: r.entry.origin_project ?? null,
319
+ category: classifyOriginProject(r.entry.origin_project, plan.currentProjectName),
320
+ }));
321
+ obs?.selected(selected);
322
+ return { items: selected, tokens };
323
+ }
324
+ // Never touches the index, so it cannot desync last_retrieval_ids from last_trace_id; fail-soft, never throws.
325
+ function traceEmptyContext(ctx, opts, query) {
326
+ // No snapshot in this branch, so the caller's own id is the only session to stamp.
327
+ writeRecallTraceAtRoot(ctx.hippoRoot, {
328
+ tenantId: ctx.tenantId,
329
+ sessionId: opts.currentSessionId || null,
330
+ pipeline: 'context',
331
+ query,
332
+ explainMode: false,
333
+ results: [],
334
+ });
335
+ }
336
+ /** Strengthens and marks the returned rows, then writes the trace and index together. */
337
+ function recordRetrieval(ctx, opts, plan, selected, activeSnapshot) {
338
+ const toUpdate = selected.map((s) => s.entry);
339
+ const updatedEntries = markRetrieved(toUpdate);
340
+ const localIndex = loadIndex(ctx.hippoRoot);
341
+ const retrievedIds = updatedEntries.map((u) => u.id);
342
+ const strengthenedHere = strengthenRetrieved(ctx.hippoRoot, retrievedIds, { recallBoostAblated: isRecallBoostAblated() });
343
+ if (plan.hasGlobal)
344
+ strengthenRetrieved(plan.globalRoot, retrievedIds.filter((id) => !strengthenedHere.has(id)), { recallBoostAblated: isRecallBoostAblated() });
345
+ localIndex.last_retrieval_ids = retrievedIds;
346
+ // Trace first on its own short-lived connection, then fold its id into localIndex so one saveIndex moves
347
+ // last_retrieval_ids and last_trace_id in lockstep; a failed trace write stores null, never a stale id.
348
+ const traceId = writeRecallTraceAtRoot(ctx.hippoRoot, {
349
+ tenantId: ctx.tenantId,
350
+ sessionId: opts.currentSessionId || activeSnapshot?.session_id || null,
351
+ pipeline: 'context',
352
+ query: plan.query,
353
+ explainMode: false,
354
+ results: selected.map((s) => ({
355
+ memoryId: s.entry.id,
356
+ score: s.score,
357
+ })),
358
+ });
359
+ localIndex.last_trace_id = traceId !== null ? String(traceId) : null;
360
+ saveIndex(ctx.hippoRoot, localIndex);
361
+ updateStats(ctx.hippoRoot, { recalled: selected.length });
362
+ // Replace selectedItems entries with markRetrieved-updated copies so
363
+ // the returned ContextResult reflects post-recall state.
364
+ const items = selected.map((s) => ({
365
+ ...s,
366
+ entry: updatedEntries.find((u) => u.id === s.entry.id) ?? s.entry,
367
+ }));
368
+ // Read after strengthenRetrieved commits, so the rows just retrieved count at their new strength.
369
+ return { items, ambientState: plan.config.ambient.enabled ? readAmbientState(ctx, plan) : undefined };
370
+ }
371
+ function readAmbientState(ctx, plan) {
372
+ const filter = { exactScope: plan.exactScope, project: plan.originProject, currentProject: plan.currentProjectName, now: evalNow() };
373
+ const roots = [...(plan.hasLocal ? [ctx.hippoRoot] : []), ...(plan.hasGlobal && !plan.primaryIsGlobal ? [plan.globalRoot] : [])];
374
+ const tallies = roots.map((root) => loadAmbientTallies(root, ctx.tenantId, filter));
375
+ const total = tallies.length > 0 ? tallies.reduce(addAmbientTallies) : undefined;
376
+ return total && total.total > 0 ? ambientStateFromTallies(total) : undefined;
377
+ }
378
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1,30 @@
1
+ import { type DormantMemory, type ListDormantOpts } from '../dormant.js';
2
+ import { type MemoryEntry } from '../memory.js';
3
+ import type { Context } from './types.js';
4
+ /**
5
+ * A tenant's dormant memories (src/dormant.ts): what sleep moved out of
6
+ * active memory instead of deleting, when `dormant.enabled` is on. Newest
7
+ * first; `opts.query` keeps rows containing every term (case-insensitive).
8
+ */
9
+ export declare function listDormant(ctx: Context, opts?: ListDormantOpts): DormantMemory[];
10
+ /**
11
+ * Bring a dormant memory back into active memory. It returns as if just
12
+ * recalled: `last_retrieved` is now, so it gets a full half-life before it
13
+ * can fade again. Every other field is the snapshot taken when it went
14
+ * dormant.
15
+ *
16
+ * Throws when the tenant has no dormant memory with that id (another
17
+ * tenant's id reads the same way), when a live memory already holds the id,
18
+ * and RejectedValueError when the value has been rejected since. On any
19
+ * throw the dormant copy stays where it is.
20
+ */
21
+ export declare function restoreDormant(ctx: Context, id: string): MemoryEntry;
22
+ /**
23
+ * Permanently delete a dormant memory: the explicit "forget it for good"
24
+ * that dormant storage leaves to the user. Throws when the tenant has no
25
+ * dormant memory with that id.
26
+ */
27
+ export declare function forgetDormant(ctx: Context, id: string): void;
28
+ /** Whether the tenant holds a dormant memory with this id (for "not found" hints). */
29
+ export declare function isDormant(ctx: Context, id: string): boolean;
30
+ //# sourceMappingURL=dormant.d.ts.map
@@ -0,0 +1,140 @@
1
+ // Dormant memories: list, restore, forget and check.
2
+ import { openHippoDb, closeHippoDb } from '../db.js';
3
+ import { ConflictError, NotFoundError } from '../api-errors.js';
4
+ import { auditRejectionRefusal } from '../store/audit-event.js';
5
+ import { stampOriginProject } from '../store/entry-row.js';
6
+ import { writeEntryDbOnly, writeEntryMirrors } from '../store/entry-writes.js';
7
+ import { updateStatsUnlessBusy } from '../store/index-and-stats.js';
8
+ import { RejectedValueError } from '../rejection.js';
9
+ import { listDormantRows, readDormantSnapshot, deleteDormantRow, hasDormantRow, } from '../dormant.js';
10
+ import { createMemory, calculateStrength } from '../memory.js';
11
+ import { appendAuditEvent, reportAuditWriteFailure } from '../audit.js';
12
+ import { loadConfig } from '../config.js';
13
+ /**
14
+ * A tenant's dormant memories (src/dormant.ts): what sleep moved out of
15
+ * active memory instead of deleting, when `dormant.enabled` is on. Newest
16
+ * first; `opts.query` keeps rows containing every term (case-insensitive).
17
+ */
18
+ export function listDormant(ctx, opts = {}) {
19
+ const db = openHippoDb(ctx.hippoRoot);
20
+ try {
21
+ return listDormantRows(db, ctx.tenantId, opts);
22
+ }
23
+ finally {
24
+ closeHippoDb(db);
25
+ }
26
+ }
27
+ /**
28
+ * Bring a dormant memory back into active memory. It returns as if just
29
+ * recalled: `last_retrieved` is now, so it gets a full half-life before it
30
+ * can fade again. Every other field is the snapshot taken when it went
31
+ * dormant.
32
+ *
33
+ * Throws when the tenant has no dormant memory with that id (another
34
+ * tenant's id reads the same way), when a live memory already holds the id,
35
+ * and RejectedValueError when the value has been rejected since. On any
36
+ * throw the dormant copy stays where it is.
37
+ */
38
+ export function restoreDormant(ctx, id) {
39
+ const db = openHippoDb(ctx.hippoRoot);
40
+ try {
41
+ let restored;
42
+ db.exec('BEGIN IMMEDIATE');
43
+ try {
44
+ const dormant = readDormantSnapshot(db, ctx.tenantId, id);
45
+ if (!dormant) {
46
+ throw new NotFoundError(`dormant memory not found: ${id}`);
47
+ }
48
+ if (db.prepare(`SELECT 1 FROM memories WHERE id = ?`).get(id) !== undefined) {
49
+ throw new ConflictError(`memory ${id} is already active; forget it before restoring its dormant copy`);
50
+ }
51
+ const now = new Date();
52
+ // Dormant rows are long-lived, so a snapshot can predate a field added
53
+ // later: createMemory supplies a default for anything it lacks, then
54
+ // the snapshot overrides every field it does carry, content included.
55
+ // (The placeholder only satisfies createMemory's minimum length, so a
56
+ // legacy row shorter than 3 chars can still be restored.)
57
+ const revived = {
58
+ ...createMemory('dormant snapshot defaults', { baseHalfLifeDays: loadConfig(ctx.hippoRoot).defaultHalfLifeDays }),
59
+ ...dormant.entry,
60
+ last_retrieved: now.toISOString(),
61
+ };
62
+ restored = stampOriginProject(ctx.hippoRoot, { ...revived, strength: calculateStrength(revived, now) });
63
+ writeEntryDbOnly(db, restored, { actor: ctx.actor.subject });
64
+ deleteDormantRow(db, ctx.tenantId, id);
65
+ // A restore is a labelled "forgot it, then needed it" event: the
66
+ // signal a learned lifecycle (ROADMAP LC3) trains on. Same transaction
67
+ // as the restore, so the label exists exactly when the restore does.
68
+ appendAuditEvent(db, {
69
+ tenantId: ctx.tenantId,
70
+ actor: ctx.actor.subject,
71
+ op: 'dormant_restore',
72
+ targetId: id,
73
+ metadata: {
74
+ reason: dormant.reason,
75
+ strengthAtDormancy: dormant.strength,
76
+ dormantAt: dormant.dormantAt,
77
+ daysDormant: Math.max(0, (now.getTime() - Date.parse(dormant.dormantAt)) / (24 * 60 * 60 * 1000)),
78
+ },
79
+ });
80
+ db.exec('COMMIT');
81
+ }
82
+ catch (err) {
83
+ try {
84
+ db.exec('ROLLBACK');
85
+ }
86
+ catch { /* already rolled back */ }
87
+ if (err instanceof RejectedValueError) {
88
+ auditRejectionRefusal(db, err, ctx.actor.subject);
89
+ }
90
+ throw err;
91
+ }
92
+ writeEntryMirrors(ctx.hippoRoot, restored);
93
+ return restored;
94
+ }
95
+ finally {
96
+ closeHippoDb(db);
97
+ }
98
+ }
99
+ /**
100
+ * Permanently delete a dormant memory: the explicit "forget it for good"
101
+ * that dormant storage leaves to the user. Throws when the tenant has no
102
+ * dormant memory with that id.
103
+ */
104
+ export function forgetDormant(ctx, id) {
105
+ const db = openHippoDb(ctx.hippoRoot);
106
+ try {
107
+ if (!deleteDormantRow(db, ctx.tenantId, id)) {
108
+ throw new NotFoundError(`dormant memory not found: ${id}`);
109
+ }
110
+ try {
111
+ appendAuditEvent(db, {
112
+ tenantId: ctx.tenantId,
113
+ actor: ctx.actor.subject,
114
+ op: 'forget',
115
+ targetId: id,
116
+ metadata: { dormant: true },
117
+ });
118
+ }
119
+ catch (error) {
120
+ // Best-effort, like every other forget audit row: the delete stands.
121
+ reportAuditWriteFailure('forget', String(error), id);
122
+ }
123
+ }
124
+ finally {
125
+ closeHippoDb(db);
126
+ }
127
+ // Counted like every other permanent removal (forget, archiveRaw).
128
+ updateStatsUnlessBusy(ctx.hippoRoot, { forgotten: 1 }, `removed ${id}`);
129
+ }
130
+ /** Whether the tenant holds a dormant memory with this id (for "not found" hints). */
131
+ export function isDormant(ctx, id) {
132
+ const db = openHippoDb(ctx.hippoRoot);
133
+ try {
134
+ return hasDormantRow(db, ctx.tenantId, id);
135
+ }
136
+ finally {
137
+ closeHippoDb(db);
138
+ }
139
+ }
140
+ //# sourceMappingURL=dormant.js.map
@@ -0,0 +1,84 @@
1
+ import type { Context } from './types.js';
2
+ export interface DrillDownOpts {
3
+ /** Cap on number of children returned. Default 50. */
4
+ limit?: number;
5
+ /**
6
+ * Optional token budget. When set, children are appended in chronological
7
+ * order (created ASC) until adding the next child would exceed the budget.
8
+ * Token cost = the child's printed line under `cost`, else ceil(content.length / 4).
9
+ *
10
+ * For depth > 1, the budget is GLOBAL cumulative (NOT per-level).
11
+ */
12
+ budget?: number;
13
+ /**
14
+ * v0.30 / E5 — walk N levels down (default 1 = direct children only).
15
+ * Higher values include children of children, etc. Internal hard cap 10
16
+ * to prevent pathological depth walks. BFS uses visited Set for dedup
17
+ * (defensive against shared-child data anomalies; DAG is acyclic by
18
+ * construction).
19
+ */
20
+ depth?: number;
21
+ cost?: DrillDownCost;
22
+ }
23
+ export interface DrillDownSummary {
24
+ id: string;
25
+ content: string;
26
+ descendantCount: number;
27
+ earliestAt: string | null;
28
+ latestAt: string | null;
29
+ }
30
+ export interface DrillDownChild {
31
+ id: string;
32
+ content: string;
33
+ layer: string;
34
+ dagLevel: number;
35
+ created: string;
36
+ }
37
+ export interface DrillDownCost {
38
+ child: (c: DrillDownChild) => number;
39
+ fixed: (summary: DrillDownSummary, widest: number) => number;
40
+ }
41
+ export interface DrillDownResult {
42
+ summary: DrillDownSummary;
43
+ children: DrillDownChild[];
44
+ totalChildren: number;
45
+ truncated: boolean;
46
+ }
47
+ /**
48
+ * v1.6.4 discriminated failure shape. Two reasons distinguishable:
49
+ * - `not_found`: covers genuinely-missing, wrong-tenant, AND
50
+ * scope-blocked (codex round 3 P1 — distinguishing scope_blocked
51
+ * from not_found on non-HTTP surfaces leaked private-row existence
52
+ * to no-scope callers, even though the HTTP route already collapsed
53
+ * them. Collapse at the API layer.)
54
+ * - `not_drillable`: id is a leaf row (level 0/1). Caller-actionable.
55
+ *
56
+ * If a future drillDown gains a `scope` opt for explicit-scope callers,
57
+ * a `scope_blocked` failure could be safely re-introduced ONLY for that
58
+ * code path (caller already proved authorization by passing a scope).
59
+ */
60
+ export interface DrillDownFailure {
61
+ failure: 'not_found' | 'not_drillable';
62
+ }
63
+ export type DrillDownOutcome = DrillDownResult | DrillDownFailure;
64
+ /**
65
+ * Walk one step down the DAG from a level-2 (or higher) summary to its direct
66
+ * children. Companion to `recall(... summarizeOverflow: true)` — when recall
67
+ * surfaces a summary with `substitutedFor: [...]`, the caller drills into the
68
+ * summary id to recover the original detail.
69
+ *
70
+ * Tenant scope: only summaries owned by `ctx.tenantId` are reachable. The same
71
+ * scope filter that recall applies is enforced on the children — a level-2
72
+ * summary in `slack:public:CGEN` cannot leak `slack:private:*` children even
73
+ * if the underlying DAG accidentally linked across scopes.
74
+ *
75
+ * Returns a discriminated `DrillDownOutcome`: `DrillDownResult` on success,
76
+ * or `{failure: '...'}` for `not_found` (covers genuinely-missing AND wrong-
77
+ * tenant, intentionally indistinguishable), `not_drillable` (id is a leaf
78
+ * row), or `scope_blocked` (caller has no scope grant for the row's scope).
79
+ *
80
+ * Pre-v1.6.4 returned null for all four cases. JS callers migrate via
81
+ * `'failure' in result` checks; HTTP route maps `not_drillable` to 422.
82
+ */
83
+ export declare function drillDown(ctx: Context, summaryId: string, opts?: DrillDownOpts): DrillDownOutcome;
84
+ //# sourceMappingURL=drill-down.d.ts.map