hippo-memory 1.60.0 → 1.61.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 (585) hide show
  1. package/README.md +1 -1
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.js +4 -1
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/gemini.js +1 -1
  7. package/dist/agent-memories/legacy.js +1 -1
  8. package/dist/agent-memories/source.js +1 -1
  9. package/dist/agent-memories/sync.js +8 -3
  10. package/dist/ambient-store.d.ts +14 -0
  11. package/dist/ambient-store.js +90 -0
  12. package/dist/ambient.d.ts +23 -0
  13. package/dist/ambient.js +72 -50
  14. package/dist/api/assemble.d.ts +93 -0
  15. package/dist/api/assemble.js +152 -0
  16. package/dist/api/audit.d.ts +17 -0
  17. package/dist/api/audit.js +23 -0
  18. package/dist/api/auth.d.ts +79 -0
  19. package/dist/api/auth.js +178 -0
  20. package/dist/api/context-types.d.ts +105 -0
  21. package/dist/api/context-types.js +3 -0
  22. package/dist/api/context.d.ts +31 -0
  23. package/dist/api/context.js +705 -0
  24. package/dist/api/dormant.d.ts +30 -0
  25. package/dist/api/dormant.js +140 -0
  26. package/dist/api/drill-down.d.ts +84 -0
  27. package/dist/api/drill-down.js +123 -0
  28. package/dist/api/forget.d.ts +57 -0
  29. package/dist/api/forget.js +87 -0
  30. package/dist/api/goals.d.ts +18 -0
  31. package/dist/api/goals.js +33 -0
  32. package/dist/api/learn.d.ts +31 -0
  33. package/dist/api/learn.js +88 -0
  34. package/dist/api/outcome.d.ts +61 -0
  35. package/dist/api/outcome.js +66 -0
  36. package/dist/api/promote.d.ts +54 -0
  37. package/dist/api/promote.js +203 -0
  38. package/dist/api/quarantine.d.ts +24 -0
  39. package/dist/api/quarantine.js +121 -0
  40. package/dist/api/recall-types.d.ts +390 -0
  41. package/dist/api/recall-types.js +3 -0
  42. package/dist/api/recall.d.ts +36 -0
  43. package/dist/api/recall.js +634 -0
  44. package/dist/api/remember.d.ts +35 -0
  45. package/dist/api/remember.js +43 -0
  46. package/dist/api/sleep.d.ts +136 -0
  47. package/dist/api/sleep.js +271 -0
  48. package/dist/api/tokens.d.ts +26 -0
  49. package/dist/api/tokens.js +60 -0
  50. package/dist/api/types.d.ts +56 -0
  51. package/dist/api/types.js +38 -0
  52. package/dist/api.d.ts +20 -1262
  53. package/dist/api.js +25 -2727
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +6 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +2 -2
  59. package/dist/capture/command.d.ts +33 -0
  60. package/dist/capture/command.js +264 -0
  61. package/dist/capture/compact.d.ts +44 -0
  62. package/dist/capture/compact.js +354 -0
  63. package/dist/capture/extract.d.ts +21 -0
  64. package/dist/capture/extract.js +464 -0
  65. package/dist/capture/transcript.d.ts +40 -0
  66. package/dist/capture/transcript.js +193 -0
  67. package/dist/capture-error.js +2 -1
  68. package/dist/churn-git.js +4 -2
  69. package/dist/cli/audit.d.ts +3 -0
  70. package/dist/cli/audit.js +159 -0
  71. package/dist/cli/auth.d.ts +2 -0
  72. package/dist/cli/auth.js +171 -0
  73. package/dist/cli/briefs.d.ts +4 -0
  74. package/dist/cli/briefs.js +435 -0
  75. package/dist/cli/card.d.ts +3 -0
  76. package/dist/cli/card.js +333 -0
  77. package/dist/cli/context.d.ts +15 -0
  78. package/dist/cli/context.js +366 -0
  79. package/dist/cli/continuity.d.ts +6 -0
  80. package/dist/cli/continuity.js +445 -0
  81. package/dist/cli/curate.d.ts +19 -0
  82. package/dist/cli/curate.js +555 -0
  83. package/dist/cli/dag.d.ts +5 -0
  84. package/dist/cli/dag.js +177 -0
  85. package/dist/cli/decisions.d.ts +4 -0
  86. package/dist/cli/decisions.js +528 -0
  87. package/dist/cli/eval.d.ts +5 -0
  88. package/dist/cli/eval.js +213 -0
  89. package/dist/cli/explain.d.ts +4 -0
  90. package/dist/cli/explain.js +150 -0
  91. package/dist/cli/goals.d.ts +2 -0
  92. package/dist/cli/goals.js +196 -0
  93. package/dist/cli/hook-blocks.d.ts +18 -0
  94. package/dist/cli/hook-blocks.js +233 -0
  95. package/dist/cli/init.d.ts +2 -0
  96. package/dist/cli/init.js +305 -0
  97. package/dist/cli/maintenance.d.ts +4 -0
  98. package/dist/cli/maintenance.js +179 -0
  99. package/dist/cli/playbooks.d.ts +4 -0
  100. package/dist/cli/playbooks.js +556 -0
  101. package/dist/cli/projects.js +1 -1
  102. package/dist/cli/recall.d.ts +7 -0
  103. package/dist/cli/recall.js +597 -0
  104. package/dist/cli/remember.d.ts +5 -0
  105. package/dist/cli/remember.js +442 -0
  106. package/dist/cli/serve.d.ts +5 -0
  107. package/dist/cli/serve.js +40 -0
  108. package/dist/cli/session-hooks.d.ts +29 -0
  109. package/dist/cli/session-hooks.js +637 -0
  110. package/dist/cli/setup.d.ts +4 -0
  111. package/dist/cli/setup.js +376 -0
  112. package/dist/cli/shared.d.ts +15 -19
  113. package/dist/cli/shared.js +50 -341
  114. package/dist/cli/slack.d.ts +2 -0
  115. package/dist/cli/slack.js +171 -0
  116. package/dist/cli/status.d.ts +18 -0
  117. package/dist/cli/status.js +400 -0
  118. package/dist/cli/transfer.d.ts +10 -0
  119. package/dist/cli/transfer.js +438 -0
  120. package/dist/cli/usage.d.ts +85 -0
  121. package/dist/cli/usage.js +741 -0
  122. package/dist/cli.d.ts +71 -120
  123. package/dist/cli.js +170 -8469
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +6 -4
  126. package/dist/connectors/github/backfill.js +94 -87
  127. package/dist/connectors/github/cli-impl.js +4 -3
  128. package/dist/connectors/github/dlq.js +67 -54
  129. package/dist/connectors/github/ingest.js +34 -35
  130. package/dist/connectors/github/tenant-routing.js +3 -2
  131. package/dist/connectors/github/webhook.js +135 -216
  132. package/dist/connectors/slack/dlq.js +49 -61
  133. package/dist/connectors/slack/ingest.js +55 -48
  134. package/dist/connectors/slack/tenant-routing.js +4 -3
  135. package/dist/connectors/slack/webhook.js +72 -74
  136. package/dist/consolidate/conflicts.d.ts +10 -0
  137. package/dist/consolidate/conflicts.js +178 -0
  138. package/dist/consolidate/decay.d.ts +12 -0
  139. package/dist/consolidate/decay.js +145 -0
  140. package/dist/consolidate/llm-passes.d.ts +3 -0
  141. package/dist/consolidate/llm-passes.js +141 -0
  142. package/dist/consolidate/merge.d.ts +7 -0
  143. package/dist/consolidate/merge.js +251 -0
  144. package/dist/consolidate/physics-pass.d.ts +3 -0
  145. package/dist/consolidate/physics-pass.js +60 -0
  146. package/dist/consolidate/run.d.ts +69 -0
  147. package/dist/consolidate/run.js +76 -0
  148. package/dist/consolidate/sleep.d.ts +18 -0
  149. package/dist/consolidate/sleep.js +209 -0
  150. package/dist/consolidate/traces.d.ts +4 -0
  151. package/dist/consolidate/traces.js +178 -0
  152. package/dist/context-auto.js +7 -11
  153. package/dist/context-render.d.ts +1 -1
  154. package/dist/context-render.js +1 -1
  155. package/dist/customer-notes.d.ts +3 -0
  156. package/dist/customer-notes.js +6 -4
  157. package/dist/dag.js +6 -5
  158. package/dist/dashboard-actions.d.ts +20 -0
  159. package/dist/dashboard-actions.js +88 -0
  160. package/dist/dashboard-params.d.ts +45 -0
  161. package/dist/dashboard-params.js +127 -0
  162. package/dist/dashboard-queries.d.ts +15 -0
  163. package/dist/dashboard-queries.js +355 -0
  164. package/dist/dashboard-snapshot.d.ts +138 -0
  165. package/dist/dashboard-snapshot.js +308 -0
  166. package/dist/dashboard-types.d.ts +163 -0
  167. package/dist/dashboard-types.js +3 -0
  168. package/dist/dashboard.d.ts +6 -7
  169. package/dist/dashboard.js +228 -202
  170. package/dist/db/busy.d.ts +5 -0
  171. package/dist/db/busy.js +24 -0
  172. package/dist/db/continuity.d.ts +5 -0
  173. package/dist/db/continuity.js +145 -0
  174. package/dist/db/meta.d.ts +8 -0
  175. package/dist/db/meta.js +35 -0
  176. package/dist/db/migrate.d.ts +9 -0
  177. package/dist/db/migrate.js +138 -0
  178. package/dist/db/migrations/index.d.ts +5 -0
  179. package/dist/db/migrations/index.js +109 -0
  180. package/dist/db/migrations/types.d.ts +14 -0
  181. package/dist/db/migrations/types.js +2 -0
  182. package/dist/db/migrations/v01.d.ts +3 -0
  183. package/dist/db/migrations/v01.js +38 -0
  184. package/dist/db/migrations/v02.d.ts +3 -0
  185. package/dist/db/migrations/v02.js +21 -0
  186. package/dist/db/migrations/v03.d.ts +3 -0
  187. package/dist/db/migrations/v03.js +22 -0
  188. package/dist/db/migrations/v04.d.ts +3 -0
  189. package/dist/db/migrations/v04.js +28 -0
  190. package/dist/db/migrations/v05.d.ts +3 -0
  191. package/dist/db/migrations/v05.js +21 -0
  192. package/dist/db/migrations/v06.d.ts +3 -0
  193. package/dist/db/migrations/v06.js +25 -0
  194. package/dist/db/migrations/v07.d.ts +3 -0
  195. package/dist/db/migrations/v07.js +13 -0
  196. package/dist/db/migrations/v08.d.ts +3 -0
  197. package/dist/db/migrations/v08.js +8 -0
  198. package/dist/db/migrations/v09.d.ts +3 -0
  199. package/dist/db/migrations/v09.js +13 -0
  200. package/dist/db/migrations/v10.d.ts +3 -0
  201. package/dist/db/migrations/v10.js +17 -0
  202. package/dist/db/migrations/v11.d.ts +3 -0
  203. package/dist/db/migrations/v11.js +15 -0
  204. package/dist/db/migrations/v12.d.ts +3 -0
  205. package/dist/db/migrations/v12.js +11 -0
  206. package/dist/db/migrations/v13.d.ts +3 -0
  207. package/dist/db/migrations/v13.js +15 -0
  208. package/dist/db/migrations/v14.d.ts +3 -0
  209. package/dist/db/migrations/v14.js +66 -0
  210. package/dist/db/migrations/v15.d.ts +3 -0
  211. package/dist/db/migrations/v15.js +42 -0
  212. package/dist/db/migrations/v16.d.ts +3 -0
  213. package/dist/db/migrations/v16.js +61 -0
  214. package/dist/db/migrations/v17.d.ts +3 -0
  215. package/dist/db/migrations/v17.js +46 -0
  216. package/dist/db/migrations/v18.d.ts +3 -0
  217. package/dist/db/migrations/v18.js +60 -0
  218. package/dist/db/migrations/v19.d.ts +3 -0
  219. package/dist/db/migrations/v19.js +28 -0
  220. package/dist/db/migrations/v20.d.ts +3 -0
  221. package/dist/db/migrations/v20.js +42 -0
  222. package/dist/db/migrations/v21.d.ts +3 -0
  223. package/dist/db/migrations/v21.js +16 -0
  224. package/dist/db/migrations/v22.d.ts +3 -0
  225. package/dist/db/migrations/v22.js +82 -0
  226. package/dist/db/migrations/v23.d.ts +3 -0
  227. package/dist/db/migrations/v23.js +48 -0
  228. package/dist/db/migrations/v24.d.ts +3 -0
  229. package/dist/db/migrations/v24.js +72 -0
  230. package/dist/db/migrations/v25.d.ts +3 -0
  231. package/dist/db/migrations/v25.js +46 -0
  232. package/dist/db/migrations/v26.d.ts +3 -0
  233. package/dist/db/migrations/v26.js +23 -0
  234. package/dist/db/migrations/v27.d.ts +3 -0
  235. package/dist/db/migrations/v27.js +57 -0
  236. package/dist/db/migrations/v28.d.ts +3 -0
  237. package/dist/db/migrations/v28.js +38 -0
  238. package/dist/db/migrations/v29.d.ts +3 -0
  239. package/dist/db/migrations/v29.js +78 -0
  240. package/dist/db/migrations/v30.d.ts +3 -0
  241. package/dist/db/migrations/v30.js +92 -0
  242. package/dist/db/migrations/v31.d.ts +3 -0
  243. package/dist/db/migrations/v31.js +74 -0
  244. package/dist/db/migrations/v32.d.ts +3 -0
  245. package/dist/db/migrations/v32.js +102 -0
  246. package/dist/db/migrations/v33.d.ts +3 -0
  247. package/dist/db/migrations/v33.js +104 -0
  248. package/dist/db/migrations/v34.d.ts +3 -0
  249. package/dist/db/migrations/v34.js +93 -0
  250. package/dist/db/migrations/v35.d.ts +3 -0
  251. package/dist/db/migrations/v35.js +98 -0
  252. package/dist/db/migrations/v36.d.ts +3 -0
  253. package/dist/db/migrations/v36.js +98 -0
  254. package/dist/db/migrations/v37.d.ts +3 -0
  255. package/dist/db/migrations/v37.js +219 -0
  256. package/dist/db/migrations/v38.d.ts +3 -0
  257. package/dist/db/migrations/v38.js +277 -0
  258. package/dist/db/migrations/v39.d.ts +3 -0
  259. package/dist/db/migrations/v39.js +59 -0
  260. package/dist/db/migrations/v40.d.ts +3 -0
  261. package/dist/db/migrations/v40.js +74 -0
  262. package/dist/db/migrations/v41.d.ts +3 -0
  263. package/dist/db/migrations/v41.js +43 -0
  264. package/dist/db/migrations/v42.d.ts +3 -0
  265. package/dist/db/migrations/v42.js +41 -0
  266. package/dist/db/migrations/v43.d.ts +3 -0
  267. package/dist/db/migrations/v43.js +67 -0
  268. package/dist/db/migrations/v44.d.ts +3 -0
  269. package/dist/db/migrations/v44.js +28 -0
  270. package/dist/db/migrations/v45.d.ts +3 -0
  271. package/dist/db/migrations/v45.js +30 -0
  272. package/dist/db/migrations/v46.d.ts +3 -0
  273. package/dist/db/migrations/v46.js +25 -0
  274. package/dist/db/migrations/v47.d.ts +3 -0
  275. package/dist/db/migrations/v47.js +17 -0
  276. package/dist/db/migrations/v48.d.ts +3 -0
  277. package/dist/db/migrations/v48.js +10 -0
  278. package/dist/db/migrations/v49.d.ts +3 -0
  279. package/dist/db/migrations/v49.js +31 -0
  280. package/dist/db/migrations/v50.d.ts +3 -0
  281. package/dist/db/migrations/v50.js +67 -0
  282. package/dist/db/migrations/v51.d.ts +3 -0
  283. package/dist/db/migrations/v51.js +14 -0
  284. package/dist/db/migrations/v52.d.ts +3 -0
  285. package/dist/db/migrations/v52.js +7 -0
  286. package/dist/db/open.d.ts +23 -0
  287. package/dist/db/open.js +146 -0
  288. package/dist/db/sqlite.d.ts +21 -0
  289. package/dist/db/sqlite.js +8 -0
  290. package/dist/db/tables.d.ts +7 -0
  291. package/dist/db/tables.js +38 -0
  292. package/dist/db.d.ts +6 -46
  293. package/dist/db.js +5 -3049
  294. package/dist/decisions.d.ts +4 -1
  295. package/dist/decisions.js +9 -7
  296. package/dist/dedupe.js +3 -2
  297. package/dist/delivery-recorder.js +4 -1
  298. package/dist/doctor.js +3 -3
  299. package/dist/embedding-provider.d.ts +1 -1
  300. package/dist/embedding-provider.js +4 -3
  301. package/dist/embeddings.d.ts +9 -52
  302. package/dist/embeddings.js +43 -297
  303. package/dist/env.d.ts +75 -0
  304. package/dist/env.js +119 -0
  305. package/dist/eval-suite.js +1 -1
  306. package/dist/eval.js +2 -2
  307. package/dist/extract.js +1 -1
  308. package/dist/gated-write.js +3 -1
  309. package/dist/goals.d.ts +3 -1
  310. package/dist/goals.js +18 -0
  311. package/dist/graph/read.d.ts +73 -0
  312. package/dist/graph/read.js +325 -0
  313. package/dist/graph/rows.d.ts +45 -0
  314. package/dist/graph/rows.js +51 -0
  315. package/dist/graph/types.d.ts +83 -0
  316. package/dist/graph/types.js +11 -0
  317. package/dist/graph/write.d.ts +93 -0
  318. package/dist/{graph.js → graph/write.js} +6 -384
  319. package/dist/graph-extract.js +2 -1
  320. package/dist/graph-recall.d.ts +1 -1
  321. package/dist/graph-recall.js +2 -2
  322. package/dist/graph-stream.js +1 -1
  323. package/dist/graph-view.d.ts +1 -1
  324. package/dist/graph-view.js +1 -1
  325. package/dist/half-life-migration.d.ts +1 -1
  326. package/dist/half-life-migration.js +2 -1
  327. package/dist/hooks/codex-session.d.ts +8 -0
  328. package/dist/hooks/codex-session.js +76 -0
  329. package/dist/hooks/codex-wrapper.d.ts +55 -0
  330. package/dist/hooks/codex-wrapper.js +288 -0
  331. package/dist/hooks/json-hooks.d.ts +63 -0
  332. package/dist/hooks/json-hooks.js +356 -0
  333. package/dist/hooks/opencode.d.ts +50 -0
  334. package/dist/hooks/opencode.js +202 -0
  335. package/dist/hooks/shared.d.ts +54 -0
  336. package/dist/hooks/shared.js +77 -0
  337. package/dist/http-retry.d.ts +2 -0
  338. package/dist/http-retry.js +4 -3
  339. package/dist/http-util.d.ts +3 -0
  340. package/dist/http-util.js +10 -0
  341. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  342. package/dist/importers/core.js +141 -0
  343. package/dist/importers/markdown-parse.d.ts +41 -0
  344. package/dist/importers/markdown-parse.js +132 -0
  345. package/dist/importers/markdown.d.ts +3 -0
  346. package/dist/importers/markdown.js +92 -0
  347. package/dist/importers/sources.d.ts +7 -0
  348. package/dist/importers/sources.js +229 -0
  349. package/dist/importers/vault.d.ts +11 -0
  350. package/dist/importers/vault.js +352 -0
  351. package/dist/incidents.d.ts +3 -0
  352. package/dist/incidents.js +7 -5
  353. package/dist/index.d.ts +25 -6
  354. package/dist/index.js +23 -6
  355. package/dist/invalidation.js +2 -1
  356. package/dist/judgment.js +2 -1
  357. package/dist/keyset.d.ts +13 -0
  358. package/dist/keyset.js +8 -0
  359. package/dist/local-embedding.d.ts +13 -0
  360. package/dist/local-embedding.js +165 -0
  361. package/dist/log.d.ts +7 -0
  362. package/dist/log.js +19 -1
  363. package/dist/mcp/admin-tools.d.ts +8 -0
  364. package/dist/mcp/admin-tools.js +116 -0
  365. package/dist/mcp/format.d.ts +27 -0
  366. package/dist/mcp/format.js +135 -0
  367. package/dist/mcp/memory-tools.d.ts +5 -0
  368. package/dist/mcp/memory-tools.js +83 -0
  369. package/dist/mcp/protocol.d.ts +83 -0
  370. package/dist/mcp/protocol.js +55 -0
  371. package/dist/mcp/recall-tools.d.ts +6 -0
  372. package/dist/mcp/recall-tools.js +320 -0
  373. package/dist/mcp/request.d.ts +10 -0
  374. package/dist/mcp/request.js +163 -0
  375. package/dist/mcp/server.d.ts +4 -75
  376. package/dist/mcp/server.js +7 -1190
  377. package/dist/mcp/session-state.d.ts +11 -0
  378. package/dist/mcp/session-state.js +28 -0
  379. package/dist/mcp/stdio.d.ts +8 -0
  380. package/dist/mcp/stdio.js +79 -0
  381. package/dist/mcp/tools.d.ts +11 -0
  382. package/dist/mcp/tools.js +247 -0
  383. package/dist/memory.d.ts +3 -0
  384. package/dist/memory.js +27 -1
  385. package/dist/multihop.d.ts +1 -1
  386. package/dist/multihop.js +2 -1
  387. package/dist/owner-validation.js +2 -1
  388. package/dist/physics-state.js +10 -7
  389. package/dist/policies.d.ts +3 -0
  390. package/dist/policies.js +8 -6
  391. package/dist/postinstall.js +3 -2
  392. package/dist/predictions/planning-fallacy.d.ts +100 -0
  393. package/dist/predictions/planning-fallacy.js +190 -0
  394. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  395. package/dist/predictions/store.js +434 -0
  396. package/dist/processes.d.ts +3 -0
  397. package/dist/processes.js +7 -5
  398. package/dist/project-briefs.d.ts +3 -0
  399. package/dist/project-briefs.js +7 -5
  400. package/dist/project-identity.js +3 -2
  401. package/dist/project-merge.js +3 -1
  402. package/dist/quarantine.d.ts +2 -1
  403. package/dist/quarantine.js +8 -5
  404. package/dist/raw-archive.js +1 -1
  405. package/dist/recall-history.js +3 -2
  406. package/dist/recall-pipeline.d.ts +2 -2
  407. package/dist/recall-pipeline.js +16 -8
  408. package/dist/recall-scope.js +1 -1
  409. package/dist/recall-trace.d.ts +1 -1
  410. package/dist/refine-llm.js +2 -1
  411. package/dist/reject-flow.js +6 -1
  412. package/dist/rerankers/clef.js +6 -5
  413. package/dist/rerankers/jev.d.ts +1 -1
  414. package/dist/rerankers/jev.js +4 -4
  415. package/dist/rerankers/llm.d.ts +4 -2
  416. package/dist/rerankers/llm.js +58 -38
  417. package/dist/rerankers/types.d.ts +1 -1
  418. package/dist/salience.js +1 -1
  419. package/dist/scheduler.d.ts +1 -0
  420. package/dist/scheduler.js +26 -4
  421. package/dist/scope.js +4 -3
  422. package/dist/search/as-of.d.ts +10 -0
  423. package/dist/search/as-of.js +22 -0
  424. package/dist/search/bm25-search.d.ts +14 -0
  425. package/dist/search/bm25-search.js +43 -0
  426. package/dist/search/bm25.d.ts +15 -0
  427. package/dist/search/bm25.js +54 -0
  428. package/dist/search/boosts.d.ts +54 -0
  429. package/dist/search/boosts.js +94 -0
  430. package/dist/search/breakdown.d.ts +7 -0
  431. package/dist/search/breakdown.js +20 -0
  432. package/dist/search/explain.d.ts +25 -0
  433. package/dist/search/explain.js +31 -0
  434. package/dist/search/finalize.d.ts +8 -0
  435. package/dist/search/finalize.js +52 -0
  436. package/dist/search/fusion.d.ts +27 -0
  437. package/dist/search/fusion.js +42 -0
  438. package/dist/search/hybrid-score.d.ts +20 -0
  439. package/dist/search/hybrid-score.js +73 -0
  440. package/dist/search/hybrid.d.ts +46 -0
  441. package/dist/search/hybrid.js +64 -0
  442. package/dist/search/physics-search.d.ts +29 -0
  443. package/dist/search/physics-search.js +162 -0
  444. package/dist/search/rerank.d.ts +10 -0
  445. package/dist/search/rerank.js +72 -0
  446. package/dist/search/temporal.d.ts +15 -0
  447. package/dist/search/temporal.js +45 -0
  448. package/dist/search/types.d.ts +91 -0
  449. package/dist/search/types.js +2 -0
  450. package/dist/search/vector.d.ts +30 -0
  451. package/dist/search/vector.js +71 -0
  452. package/dist/secret-detect.d.ts +2 -0
  453. package/dist/secret-detect.js +2 -1
  454. package/dist/server/auth.d.ts +52 -0
  455. package/dist/server/auth.js +221 -0
  456. package/dist/server/client-ip.d.ts +25 -0
  457. package/dist/server/client-ip.js +92 -0
  458. package/dist/server/cursor.d.ts +23 -0
  459. package/dist/server/cursor.js +58 -0
  460. package/dist/server/lifecycle.d.ts +7 -0
  461. package/dist/server/lifecycle.js +29 -0
  462. package/dist/server/mcp-http.d.ts +5 -0
  463. package/dist/server/mcp-http.js +199 -0
  464. package/dist/server/request.d.ts +33 -0
  465. package/dist/server/request.js +103 -0
  466. package/dist/server/routes/admin.d.ts +9 -0
  467. package/dist/server/routes/admin.js +158 -0
  468. package/dist/server/routes/customer-notes.d.ts +7 -0
  469. package/dist/server/routes/customer-notes.js +112 -0
  470. package/dist/server/routes/decisions.d.ts +7 -0
  471. package/dist/server/routes/decisions.js +133 -0
  472. package/dist/server/routes/incidents.d.ts +7 -0
  473. package/dist/server/routes/incidents.js +126 -0
  474. package/dist/server/routes/memories.d.ts +10 -0
  475. package/dist/server/routes/memories.js +179 -0
  476. package/dist/server/routes/policies.d.ts +8 -0
  477. package/dist/server/routes/policies.js +151 -0
  478. package/dist/server/routes/predictions.d.ts +7 -0
  479. package/dist/server/routes/predictions.js +164 -0
  480. package/dist/server/routes/processes.d.ts +7 -0
  481. package/dist/server/routes/processes.js +161 -0
  482. package/dist/server/routes/project-briefs.d.ts +8 -0
  483. package/dist/server/routes/project-briefs.js +136 -0
  484. package/dist/server/routes/recall.d.ts +8 -0
  485. package/dist/server/routes/recall.js +340 -0
  486. package/dist/server/routes/skills.d.ts +8 -0
  487. package/dist/server/routes/skills.js +150 -0
  488. package/dist/server/types.d.ts +56 -0
  489. package/dist/server/types.js +2 -0
  490. package/dist/server/validation.d.ts +14 -0
  491. package/dist/server/validation.js +91 -0
  492. package/dist/server.d.ts +7 -61
  493. package/dist/server.js +69 -2362
  494. package/dist/session-digest.d.ts +1 -1
  495. package/dist/session-digest.js +9 -2
  496. package/dist/shared.d.ts +3 -1
  497. package/dist/shared.js +26 -22
  498. package/dist/skills.d.ts +3 -0
  499. package/dist/skills.js +7 -5
  500. package/dist/stdin.js +2 -2
  501. package/dist/store/audit-event.d.ts +19 -0
  502. package/dist/store/audit-event.js +33 -0
  503. package/dist/store/candidates.d.ts +42 -0
  504. package/dist/store/candidates.js +152 -0
  505. package/dist/store/conflicts.d.ts +44 -0
  506. package/dist/store/conflicts.js +444 -0
  507. package/dist/store/delete-and-batch.d.ts +63 -0
  508. package/dist/store/delete-and-batch.js +310 -0
  509. package/dist/store/entry-reads.d.ts +92 -0
  510. package/dist/store/entry-reads.js +255 -0
  511. package/dist/store/entry-row.d.ts +67 -0
  512. package/dist/store/entry-row.js +208 -0
  513. package/dist/store/entry-writes.d.ts +46 -0
  514. package/dist/store/entry-writes.js +148 -0
  515. package/dist/store/handoffs.d.ts +26 -0
  516. package/dist/store/handoffs.js +184 -0
  517. package/dist/store/index-and-stats.d.ts +52 -0
  518. package/dist/store/index-and-stats.js +214 -0
  519. package/dist/store/markdown.d.ts +10 -0
  520. package/dist/store/markdown.js +108 -0
  521. package/dist/store/mirrors.d.ts +49 -0
  522. package/dist/store/mirrors.js +312 -0
  523. package/dist/store/open.d.ts +15 -0
  524. package/dist/store/open.js +223 -0
  525. package/dist/store/rows.d.ts +178 -0
  526. package/dist/store/rows.js +158 -0
  527. package/dist/store/search-rows.d.ts +86 -0
  528. package/dist/store/search-rows.js +254 -0
  529. package/dist/store/sessions.d.ts +83 -0
  530. package/dist/store/sessions.js +272 -0
  531. package/dist/store/summaries.d.ts +94 -0
  532. package/dist/store/summaries.js +377 -0
  533. package/dist/store/tenant-lookup.d.ts +12 -0
  534. package/dist/store/tenant-lookup.js +16 -0
  535. package/dist/store-cards.js +2 -1
  536. package/dist/summary-dirty.d.ts +4 -0
  537. package/dist/summary-dirty.js +32 -0
  538. package/dist/support-bundle.js +4 -3
  539. package/dist/tenant.js +2 -2
  540. package/dist/tokenize.d.ts +2 -0
  541. package/dist/tokenize.js +16 -0
  542. package/dist/transcript-tail.d.ts +7 -0
  543. package/dist/transcript-tail.js +48 -0
  544. package/dist/vector-store.d.ts +27 -0
  545. package/dist/vector-store.js +210 -0
  546. package/dist/version.d.ts +2 -2
  547. package/dist/version.js +2 -2
  548. package/dist/working-memory.js +1 -1
  549. package/dist/yaml.js +36 -11
  550. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  551. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  552. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  553. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  554. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  555. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  556. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  557. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  558. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  559. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  560. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  561. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  562. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  563. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  564. package/dist-ui/index.html +3 -25
  565. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  566. package/extensions/openclaw-plugin/package.json +1 -1
  567. package/openclaw.plugin.json +1 -1
  568. package/package.json +1 -1
  569. package/dist/capture.d.ts +0 -155
  570. package/dist/capture.js +0 -1295
  571. package/dist/consolidate.d.ts +0 -58
  572. package/dist/consolidate.js +0 -1124
  573. package/dist/graph.d.ts +0 -245
  574. package/dist/hooks.d.ts +0 -208
  575. package/dist/hooks.js +0 -1076
  576. package/dist/importers.js +0 -900
  577. package/dist/predictions.js +0 -620
  578. package/dist/search.d.ts +0 -320
  579. package/dist/search.js +0 -970
  580. package/dist/store.d.ts +0 -776
  581. package/dist/store.js +0 -3473
  582. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  583. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  584. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  585. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -0,0 +1,161 @@
1
+ // /v1/processes routes.
2
+ import { closeProcess, loadProcessById, loadProcesses, saveProcess, VALID_PROCESS_STATES } from '../../processes.js';
3
+ import { HttpError, sendJson } from '../../http-util.js';
4
+ import { buildContextWithAuth } from '../auth.js';
5
+ import { byCreatedAt, pageOf, parseCursor } from '../cursor.js';
6
+ import { isJsonString, isSetMember, parseJsonBody, parseListLimit } from '../validation.js';
7
+ // HTTP-boundary validation for a process `steps` body (untrusted). Returns the
8
+ // step strings (saveProcess re-validates + trims, this is the fail-fast 400
9
+ // gate). Caps mirror src/processes.ts MAX_PROCESS_STEPS / MAX_PROCESS_STEP_LEN.
10
+ function validateProcessStepsBody(raw) {
11
+ if (raw === undefined || raw === null)
12
+ return [];
13
+ if (!Array.isArray(raw)) {
14
+ throw new HttpError(400, 'steps must be an array of strings');
15
+ }
16
+ if (raw.length > 200) {
17
+ throw new HttpError(400, 'steps exceeds 200-step cap');
18
+ }
19
+ for (const item of raw) {
20
+ if (!isJsonString(item)) {
21
+ throw new HttpError(400, 'each step must be a string');
22
+ }
23
+ if (item.trim().length === 0) {
24
+ throw new HttpError(400, 'a step is empty');
25
+ }
26
+ if (item.length > 2000) {
27
+ throw new HttpError(400, 'a step exceeds the 2000-character cap');
28
+ }
29
+ }
30
+ // SAFETY: every item in raw was confirmed to be a string in the loop above.
31
+ return raw;
32
+ }
33
+ // ── processes (E2 first-class object) ──
34
+ //
35
+ // 5 routes: POST /v1/processes (new; body processName + steps[] + description),
36
+ // GET /v1/processes (list, status filter), GET /v1/processes/:id (show),
37
+ // POST /v1/processes/:id/supersede (active -> superseded by a new version; body
38
+ // steps[] + changeSummary + description; reuses the predecessor's name),
39
+ // POST /v1/processes/:id/close (active -> closed). Bearer-authed + tenant-scoped
40
+ // via buildContextWithAuth. status validated against VALID_PROCESS_STATES. DoS
41
+ // caps: processName/description/changeSummary 4096, steps 200x2000
42
+ // (validateProcessStepsBody). Mirrors /v1/decisions; the delta lifecycle is the
43
+ // decision supersede path.
44
+ export async function handleCreateProcess({ req, res, opts }) {
45
+ const ctx = await buildContextWithAuth(req, opts);
46
+ const body = await parseJsonBody(req, ctx);
47
+ const processName = body['processName'];
48
+ if (!isJsonString(processName) || processName.trim().length === 0) {
49
+ throw new HttpError(400, 'processName is required (non-empty string)');
50
+ }
51
+ if (processName.length > 4096) {
52
+ throw new HttpError(400, 'processName exceeds 4096-character cap');
53
+ }
54
+ const steps = validateProcessStepsBody(body['steps']);
55
+ const descriptionRaw = body['description'];
56
+ let description;
57
+ if (descriptionRaw !== undefined && descriptionRaw !== null) {
58
+ if (!isJsonString(descriptionRaw)) {
59
+ throw new HttpError(400, 'description must be a string');
60
+ }
61
+ if (descriptionRaw.length > 4096) {
62
+ throw new HttpError(400, 'description exceeds 4096-character cap');
63
+ }
64
+ description = descriptionRaw;
65
+ }
66
+ const process = saveProcess(opts.hippoRoot, ctx.tenantId, {
67
+ processName,
68
+ steps,
69
+ description,
70
+ }, ctx.actor.subject);
71
+ sendJson(res, 201, { process });
72
+ return;
73
+ }
74
+ export async function handleListProcesses({ req, res, opts, query }) {
75
+ const status = query.get('status') ?? 'all';
76
+ const limit = parseListLimit(query.get('limit'));
77
+ const after = parseCursor(query.get('cursor'), 'string', 'integer');
78
+ const ctx = await buildContextWithAuth(req, opts);
79
+ let processes;
80
+ if (status === 'all') {
81
+ processes = loadProcesses(opts.hippoRoot, ctx.tenantId, { limit: limit + 1, after });
82
+ }
83
+ else {
84
+ if (!isSetMember(VALID_PROCESS_STATES, status)) {
85
+ throw new HttpError(400, `status must be one of: active | superseded | closed | all (got "${status}")`);
86
+ }
87
+ processes = loadProcesses(opts.hippoRoot, ctx.tenantId, {
88
+ status,
89
+ limit: limit + 1,
90
+ after,
91
+ });
92
+ }
93
+ const page = pageOf(processes, limit, byCreatedAt);
94
+ sendJson(res, 200, { processes: page.items, next_cursor: page.nextCursor });
95
+ return;
96
+ }
97
+ export async function handleSupersedeProcess({ req, res, opts }, processSupersedeMatch) {
98
+ const id = parseInt(processSupersedeMatch[1], 10);
99
+ const ctx = await buildContextWithAuth(req, opts);
100
+ const body = await parseJsonBody(req, ctx);
101
+ const steps = validateProcessStepsBody(body['steps']);
102
+ if (steps.length === 0) {
103
+ throw new HttpError(400, 'steps is required (at least one step) for a supersession');
104
+ }
105
+ const changeRaw = body['changeSummary'];
106
+ let changeSummary;
107
+ if (changeRaw !== undefined && changeRaw !== null) {
108
+ if (!isJsonString(changeRaw)) {
109
+ throw new HttpError(400, 'changeSummary must be a string');
110
+ }
111
+ if (changeRaw.length > 4096) {
112
+ throw new HttpError(400, 'changeSummary exceeds 4096-character cap');
113
+ }
114
+ changeSummary = changeRaw;
115
+ }
116
+ const descRaw = body['description'];
117
+ let description;
118
+ if (descRaw !== undefined && descRaw !== null) {
119
+ if (!isJsonString(descRaw)) {
120
+ throw new HttpError(400, 'description must be a string');
121
+ }
122
+ if (descRaw.length > 4096) {
123
+ throw new HttpError(400, 'description exceeds 4096-character cap');
124
+ }
125
+ description = descRaw;
126
+ }
127
+ // A supersession is a new version of the SAME process: reuse the
128
+ // predecessor's name. 404 if the target does not exist; saveProcess's
129
+ // in-SAVEPOINT preflight is the authoritative active-state check (409).
130
+ const existing = loadProcessById(opts.hippoRoot, ctx.tenantId, id);
131
+ if (!existing) {
132
+ throw new HttpError(404, `process ${id} not found`);
133
+ }
134
+ const process = saveProcess(opts.hippoRoot, ctx.tenantId, {
135
+ processName: existing.processName,
136
+ steps,
137
+ description,
138
+ changeSummary,
139
+ supersedesProcessId: id,
140
+ }, ctx.actor.subject);
141
+ sendJson(res, 200, { process });
142
+ return;
143
+ }
144
+ export async function handleCloseProcess({ req, res, opts }, processCloseMatch) {
145
+ const id = parseInt(processCloseMatch[1], 10);
146
+ const ctx = await buildContextWithAuth(req, opts);
147
+ const process = closeProcess(opts.hippoRoot, ctx.tenantId, id, ctx.actor.subject);
148
+ sendJson(res, 200, { process });
149
+ return;
150
+ }
151
+ export async function handleGetProcess({ req, res, opts }, processByIdMatch) {
152
+ const id = parseInt(processByIdMatch[1], 10);
153
+ const ctx = await buildContextWithAuth(req, opts);
154
+ const process = loadProcessById(opts.hippoRoot, ctx.tenantId, id);
155
+ if (!process) {
156
+ throw new HttpError(404, `process ${id} not found`);
157
+ }
158
+ sendJson(res, 200, { process });
159
+ return;
160
+ }
161
+ //# sourceMappingURL=processes.js.map
@@ -0,0 +1,8 @@
1
+ import type { RouteRequest } from '../types.js';
2
+ export declare function handleCreateProjectBrief({ req, res, opts }: RouteRequest): Promise<void>;
3
+ export declare function handleListProjectBriefs({ req, res, opts, query }: RouteRequest): Promise<void>;
4
+ export declare function handleRefreshProjectBrief({ req, res, opts }: RouteRequest): Promise<void>;
5
+ export declare function handleSupersedeProjectBrief({ req, res, opts }: RouteRequest, briefSupersedeMatch: RegExpMatchArray): Promise<void>;
6
+ export declare function handleCloseProjectBrief({ req, res, opts }: RouteRequest, briefCloseMatch: RegExpMatchArray): Promise<void>;
7
+ export declare function handleGetProjectBrief({ req, res, opts }: RouteRequest, briefByIdMatch: RegExpMatchArray): Promise<void>;
8
+ //# sourceMappingURL=project-briefs.d.ts.map
@@ -0,0 +1,136 @@
1
+ // /v1/project-briefs routes.
2
+ import { assembleBriefFromReceipts, closeProjectBrief, loadProjectBriefById, loadProjectBriefs, refreshBrief, saveProjectBrief, VALID_BRIEF_STATES } from '../../project-briefs.js';
3
+ import { HttpError, sendJson } from '../../http-util.js';
4
+ import { buildContextWithAuth } from '../auth.js';
5
+ import { byCreatedAt, pageOf, parseCursor } from '../cursor.js';
6
+ import { isJsonString, isSetMember, parseJsonBody, parseListLimit } from '../validation.js';
7
+ // ── E2 project_brief routes ──
8
+ //
9
+ // 6 routes: POST /v1/project-briefs (new; body repo + summary), GET
10
+ // /v1/project-briefs (list; status + repo filter; shared parseListLimit), POST
11
+ // /v1/project-briefs/refresh (body {repo, dryRun?} -> auto-assemble the brief
12
+ // from the repo's receipts; dryRun returns {markdown} without writing; ordered
13
+ // before /:id), GET /v1/project-briefs/:id, POST /v1/project-briefs/:id/supersede,
14
+ // POST /v1/project-briefs/:id/close. DoS caps: repo 256, summary 8192,
15
+ // changeSummary 4096. The store validates + throws; the boundary maps validation
16
+ // -> 400, not-found -> 404, not-active -> 409. Mirrors /v1/skills.
17
+ export async function handleCreateProjectBrief({ req, res, opts }) {
18
+ const ctx = await buildContextWithAuth(req, opts);
19
+ const body = await parseJsonBody(req, ctx);
20
+ const repo = body['repo'];
21
+ if (!isJsonString(repo) || repo.trim().length === 0) {
22
+ throw new HttpError(400, 'repo is required (non-empty string)');
23
+ }
24
+ if (repo.length > 256) {
25
+ throw new HttpError(400, 'repo exceeds 256-character cap');
26
+ }
27
+ const summary = body['summary'];
28
+ if (!isJsonString(summary) || summary.trim().length === 0) {
29
+ throw new HttpError(400, 'summary is required (non-empty string)');
30
+ }
31
+ if (summary.length > 8192) {
32
+ throw new HttpError(400, 'summary exceeds 8192-character cap');
33
+ }
34
+ const brief = saveProjectBrief(opts.hippoRoot, ctx.tenantId, {
35
+ repo,
36
+ summary,
37
+ }, ctx.actor.subject);
38
+ sendJson(res, 201, { brief });
39
+ return;
40
+ }
41
+ export async function handleListProjectBriefs({ req, res, opts, query }) {
42
+ const status = query.get('status') ?? 'all';
43
+ const repoFilter = query.get('repo');
44
+ const limit = parseListLimit(query.get('limit'));
45
+ const after = parseCursor(query.get('cursor'), 'string', 'integer');
46
+ const ctx = await buildContextWithAuth(req, opts);
47
+ const listOpts = { limit: limit + 1, after };
48
+ if (repoFilter !== null && repoFilter.trim().length > 0) {
49
+ listOpts.repo = repoFilter.trim();
50
+ }
51
+ if (status !== 'all') {
52
+ if (!isSetMember(VALID_BRIEF_STATES, status)) {
53
+ throw new HttpError(400, `status must be one of: active | superseded | closed | all (got "${status}")`);
54
+ }
55
+ listOpts.status = status;
56
+ }
57
+ const briefs = loadProjectBriefs(opts.hippoRoot, ctx.tenantId, listOpts);
58
+ const page = pageOf(briefs, limit, byCreatedAt);
59
+ sendJson(res, 200, { briefs: page.items, next_cursor: page.nextCursor });
60
+ return;
61
+ }
62
+ // The refresh op: must precede the /:id routes (literal 'refresh' is non-numeric
63
+ // so the /(\d+)/ routes would not match it, but order it first).
64
+ export async function handleRefreshProjectBrief({ req, res, opts }) {
65
+ const ctx = await buildContextWithAuth(req, opts);
66
+ const body = await parseJsonBody(req, ctx);
67
+ const repo = body['repo'];
68
+ if (!isJsonString(repo) || repo.trim().length === 0) {
69
+ throw new HttpError(400, 'repo is required (non-empty string)');
70
+ }
71
+ if (repo.length > 256) {
72
+ throw new HttpError(400, 'repo exceeds 256-character cap');
73
+ }
74
+ const dryRun = body['dryRun'] === true;
75
+ if (dryRun) {
76
+ const { markdown, receiptCount } = assembleBriefFromReceipts(opts.hippoRoot, ctx.tenantId, repo);
77
+ sendJson(res, 200, { markdown, receiptCount });
78
+ return;
79
+ }
80
+ const brief = refreshBrief(opts.hippoRoot, ctx.tenantId, repo, ctx.actor.subject);
81
+ sendJson(res, 200, { brief });
82
+ return;
83
+ }
84
+ export async function handleSupersedeProjectBrief({ req, res, opts }, briefSupersedeMatch) {
85
+ const id = parseInt(briefSupersedeMatch[1], 10);
86
+ const ctx = await buildContextWithAuth(req, opts);
87
+ const body = await parseJsonBody(req, ctx);
88
+ const summary = body['summary'];
89
+ if (!isJsonString(summary) || summary.trim().length === 0) {
90
+ throw new HttpError(400, 'summary is required (non-empty string)');
91
+ }
92
+ if (summary.length > 8192) {
93
+ throw new HttpError(400, 'summary exceeds 8192-character cap');
94
+ }
95
+ const changeRaw = body['changeSummary'];
96
+ let changeSummary;
97
+ if (changeRaw !== undefined && changeRaw !== null) {
98
+ if (!isJsonString(changeRaw)) {
99
+ throw new HttpError(400, 'changeSummary must be a string');
100
+ }
101
+ if (changeRaw.length > 4096) {
102
+ throw new HttpError(400, 'changeSummary exceeds 4096-character cap');
103
+ }
104
+ changeSummary = changeRaw;
105
+ }
106
+ const existing = loadProjectBriefById(opts.hippoRoot, ctx.tenantId, id);
107
+ if (!existing) {
108
+ throw new HttpError(404, `project brief ${id} not found`);
109
+ }
110
+ const brief = saveProjectBrief(opts.hippoRoot, ctx.tenantId, {
111
+ repo: existing.repo,
112
+ summary,
113
+ changeSummary,
114
+ supersedesBriefId: id,
115
+ }, ctx.actor.subject);
116
+ sendJson(res, 200, { brief });
117
+ return;
118
+ }
119
+ export async function handleCloseProjectBrief({ req, res, opts }, briefCloseMatch) {
120
+ const id = parseInt(briefCloseMatch[1], 10);
121
+ const ctx = await buildContextWithAuth(req, opts);
122
+ const brief = closeProjectBrief(opts.hippoRoot, ctx.tenantId, id, ctx.actor.subject);
123
+ sendJson(res, 200, { brief });
124
+ return;
125
+ }
126
+ export async function handleGetProjectBrief({ req, res, opts }, briefByIdMatch) {
127
+ const id = parseInt(briefByIdMatch[1], 10);
128
+ const ctx = await buildContextWithAuth(req, opts);
129
+ const brief = loadProjectBriefById(opts.hippoRoot, ctx.tenantId, id);
130
+ if (!brief) {
131
+ throw new HttpError(404, `project brief ${id} not found`);
132
+ }
133
+ sendJson(res, 200, { brief });
134
+ return;
135
+ }
136
+ //# sourceMappingURL=project-briefs.js.map
@@ -0,0 +1,8 @@
1
+ import type { RouteRequest } from '../types.js';
2
+ /** Test-only: reset the module-level recall-history Map. Call from beforeEach. */
3
+ export declare function __resetSessionRecallHistoryHttp(): void;
4
+ export declare function handleRecallMemories({ req, res, opts, query }: RouteRequest): Promise<void>;
5
+ export declare function handleAssembleSession({ req, res, opts, query }: RouteRequest, assembleMatch: Record<string, string>): Promise<void>;
6
+ export declare function handleDrillRecall({ req, res, opts, query }: RouteRequest, drillMatch: Record<string, string>): Promise<void>;
7
+ export declare function handleGetContext({ req, res, opts, query }: RouteRequest): Promise<void>;
8
+ //# sourceMappingURL=recall.d.ts.map
@@ -0,0 +1,340 @@
1
+ // Recall routes: /v1/memories search, assemble, drill and /v1/context.
2
+ import { dirname, resolve } from 'node:path';
3
+ import { resolveProjectIdentity } from '../../project-identity.js';
4
+ import { assembleCost, contextCost, drillCost } from '../../context-render.js';
5
+ import { closeHippoDb, openHippoDb } from '../../db.js';
6
+ import { updateStats } from '../../store/index-and-stats.js';
7
+ import { appendRecall, biasHintEnabled, buildSessionKey, getOrCreateRing, hashQueryText, snapshotRing } from '../../recall-history.js';
8
+ import { appendAuditEvent, auditQueryFields } from '../../audit.js';
9
+ import { assemble, drillDown, getContext, recordTokens, retrieve } from '../../api.js';
10
+ import { HttpError, sendJson } from '../../http-util.js';
11
+ import { buildContextWithAuth } from '../auth.js';
12
+ import { parseListLimit, validateIdSegment } from '../validation.js';
13
+ // v0.33 / J1 — Module-level per-(tenant, session) recall-history ring map
14
+ // for the HTTP pipeline. Separate from CLI/MCP rings per plan v3 (per-
15
+ // pipeline rings; no IPC). HTTP is the only caller that threads its
16
+ // snapshot through opts.recallHistory to api.recall — api.recall's
17
+ // anchoringHint on the returned RecallResult IS the user-visible hint
18
+ // here (no separate compute needed).
19
+ const sessionRecallHistoryHttp = new Map();
20
+ /** Test-only: reset the module-level recall-history Map. Call from beforeEach. */
21
+ export function __resetSessionRecallHistoryHttp() {
22
+ sessionRecallHistoryHttp.clear();
23
+ }
24
+ // GET /v1/memories?q=...&limit=...&mode=...&scope=...&include_continuity=1
25
+ export async function handleRecallMemories({ req, res, opts, query }) {
26
+ const q = query.get('q');
27
+ if (!q) {
28
+ throw new HttpError(400, 'q is required');
29
+ }
30
+ const limitRaw = query.get('limit');
31
+ const limit = limitRaw === null ? undefined : parseListLimit(limitRaw);
32
+ const mode = query.get('mode');
33
+ if (mode !== null && mode !== 'bm25' && mode !== 'hybrid' && mode !== 'physics') {
34
+ throw new HttpError(400, "mode must be 'bm25', 'hybrid', or 'physics'");
35
+ }
36
+ const scope = query.get('scope');
37
+ const includeContinuityRaw = query.get('include_continuity');
38
+ const includeContinuity = includeContinuityRaw === '1'
39
+ || includeContinuityRaw === 'true';
40
+ // v1.6.2: surface the v1.5.0/v1.5.2 RecallOpts additions to HTTP
41
+ // callers. Pre-v1.6.2 the route silently ignored these so the
42
+ // session-scoped fresh-tail and summary substitution were JS-only.
43
+ const freshTailCountRaw = query.get('fresh_tail_count');
44
+ const freshTailCount = freshTailCountRaw === null ? undefined : Number(freshTailCountRaw);
45
+ if (freshTailCount !== undefined && (!Number.isFinite(freshTailCount) || freshTailCount < 0)) {
46
+ throw new HttpError(400, 'fresh_tail_count must be a non-negative number');
47
+ }
48
+ // v1.6.3 senior-review P1-3: cap session_id length consistent with the
49
+ // rest of the API. Untrimmed strings round-trip through the SQL layer
50
+ // and through any downstream metric/log; 256 is generous for a session
51
+ // id and matches the rest of this file's id-shaped param parsers.
52
+ const freshTailSessionIdRaw = query.get('fresh_tail_session_id');
53
+ if (freshTailSessionIdRaw !== null && freshTailSessionIdRaw.length > 256) {
54
+ throw new HttpError(400, 'fresh_tail_session_id exceeds 256-character cap');
55
+ }
56
+ const freshTailSessionId = freshTailSessionIdRaw && freshTailSessionIdRaw.length > 0
57
+ ? freshTailSessionIdRaw
58
+ : undefined;
59
+ // v1.6.3 senior-review P1-4: tighten parser to match the includeContinuity
60
+ // convention. Pre-v1.6.3 accepted any non-'0'/'false' value as `true`,
61
+ // so `?summarize_overflow=banana` and `?summarize_overflow=` both
62
+ // turned it on. Surface convention drift fixed.
63
+ const summarizeOverflowRaw = query.get('summarize_overflow');
64
+ const summarizeOverflow = summarizeOverflowRaw === null
65
+ ? undefined
66
+ : (summarizeOverflowRaw === '1' || summarizeOverflowRaw === 'true');
67
+ // recall() owns the shape rule (NaN, 0 and negatives throw invalid_scorer_window); the transport caps remote cost.
68
+ const scorerWindowRaw = query.get('scorer_window');
69
+ const scorerWindow = scorerWindowRaw === null ? undefined : Number(scorerWindowRaw);
70
+ if (scorerWindow !== undefined && scorerWindow > 1000) {
71
+ throw new HttpError(400, 'scorer_window must be <= 1000');
72
+ }
73
+ // v1.7.4: session_id for the dlPFC goal-stack boost. 256-char cap mirrors
74
+ // fresh_tail_session_id (above). Trim then drop if empty so api.recall
75
+ // sees undefined when the param is omitted or whitespace-only.
76
+ const sessionIdRaw = query.get('session_id');
77
+ if (sessionIdRaw !== null && sessionIdRaw.length > 256) {
78
+ throw new HttpError(400, 'session_id exceeds 256-character cap');
79
+ }
80
+ const sessionId = sessionIdRaw && sessionIdRaw.trim().length > 0
81
+ ? sessionIdRaw.trim()
82
+ : undefined;
83
+ // A7 recall-trace: opt-in explain flag. When set, api.recall attaches the
84
+ // lifecycle re-ranking trace (goal-boost step on the api pipeline) +
85
+ // rerankPipeline:'api' to each result item; the field then rides on the
86
+ // serialized RecallResult. Mirrors the include_continuity convention.
87
+ const explainRaw = query.get('explain');
88
+ const explain = explainRaw === '1' || explainRaw === 'true';
89
+ const ctx = await buildContextWithAuth(req, opts);
90
+ // v0.33 / J1 — HTTP per-pipeline anchoring detector. HTTP threads its
91
+ // ring snapshot via opts.recallHistory so api.recall's own
92
+ // anchoringHint compute path activates. Unlike CLI (which computes
93
+ // its own hint separately because cmdRecall runs its own physics/
94
+ // hybrid pipeline outside api.recall), HTTP's /v1/memories response
95
+ // body IS api.recall's result directly. So the api.recall-computed
96
+ // hint flows through. HIPPO_ANCHORING=off short-circuits.
97
+ let httpRecallHistory;
98
+ let httpRingKey;
99
+ if (biasHintEnabled('anchoring')) {
100
+ if (sessionId) {
101
+ // Codex round-5 P2 catch: do NOT mutate sessionRecallHistoryHttp
102
+ // before recall() preflight runs. A request with an invalid
103
+ // scorer_window / fresh_tail_count would create-or-touch the
104
+ // session ring (LRU-evicting valid sessions) even though recall
105
+ // throws 400. Snapshot the EXISTING ring if present; only
106
+ // create-or-touch after the recall returns successfully.
107
+ httpRingKey = buildSessionKey(ctx.tenantId, sessionId);
108
+ const existingRing = sessionRecallHistoryHttp.get(httpRingKey);
109
+ httpRecallHistory = existingRing ? snapshotRing(existingRing) : [];
110
+ }
111
+ else {
112
+ // Telemetry: caller had no session_id so ring tracking skipped.
113
+ // Per the normal recall-audit convention (api.ts:854 stores
114
+ // SHA-256/16 hash of the query, NOT raw text), avoid retaining
115
+ // prompts in audit_log here too — query content can contain
116
+ // secrets, PII, or RTBF-restricted material. Codex round-2 P2
117
+ // catch: hashQueryText is a 32-bit FNV-1a designed for recall
118
+ // matching, NOT a privacy hash; brute-force trivial for low-
119
+ // entropy queries. Use the same SHA-256/16 truncation as the
120
+ // canonical recall audit.
121
+ const dbForAudit = openHippoDb(opts.hippoRoot);
122
+ try {
123
+ appendAuditEvent(dbForAudit, {
124
+ tenantId: ctx.tenantId,
125
+ actor: ctx.actor.subject,
126
+ op: 'recall_anchor_skipped_no_session',
127
+ targetId: undefined,
128
+ metadata: auditQueryFields(q),
129
+ });
130
+ }
131
+ finally {
132
+ closeHippoDb(dbForAudit);
133
+ }
134
+ }
135
+ }
136
+ const recallExtra = {};
137
+ if (freshTailCount !== undefined)
138
+ recallExtra.freshTailCount = freshTailCount;
139
+ if (freshTailSessionId !== undefined)
140
+ recallExtra.freshTailSessionId = freshTailSessionId;
141
+ if (summarizeOverflow !== undefined)
142
+ recallExtra.summarizeOverflow = summarizeOverflow;
143
+ if (scorerWindow !== undefined)
144
+ recallExtra.scorerWindow = scorerWindow;
145
+ if (sessionId !== undefined)
146
+ recallExtra.sessionId = sessionId;
147
+ if (httpRecallHistory !== undefined)
148
+ recallExtra.recallHistory = httpRecallHistory;
149
+ if (explain)
150
+ recallExtra.explain = explain;
151
+ const result = await retrieve(ctx, {
152
+ query: q,
153
+ limit,
154
+ mode: mode ?? undefined,
155
+ scope: scope ?? undefined,
156
+ includeContinuity,
157
+ ...recallExtra,
158
+ });
159
+ // v0.33 / J1 — append AFTER recall completes (snapshot was taken before
160
+ // recall() ran). anchoredOn carries the memoryId of any hint that fired
161
+ // (api.recall computed it from the same snapshot we passed in), feeding
162
+ // the cooldown logic for the NEXT recall on this session.
163
+ // Codex round-5 P2 fix: create-or-touch the ring ONLY HERE, after recall
164
+ // returns successfully. Invalid requests that throw 400 in recall()
165
+ // never reach this point, so they cannot LRU-evict valid sessions.
166
+ if (httpRingKey) {
167
+ const httpRing = getOrCreateRing(sessionRecallHistoryHttp, httpRingKey);
168
+ const topId = result.results[0]?.id ?? null;
169
+ appendRecall(httpRing, hashQueryText(q), topId, result.anchoringHint?.memoryId);
170
+ }
171
+ // Each recall surface counts its own hits; api.recall is no chokepoint,
172
+ // since the CLI never calls it and MCP shows the user a different band.
173
+ updateStats(opts.hippoRoot, { recalled: result.results.length });
174
+ // Continuity payloads should never be cached. The caller is asking for
175
+ // session-state-aware data; intermediaries must not reuse it across users.
176
+ if (includeContinuity) {
177
+ res.setHeader('Cache-Control', 'no-store');
178
+ }
179
+ recordTokens(ctx, 'http_recall', { items: result.results.length, tokens: result.tokens + (result.continuityTokens ?? 0), sessionId: sessionId ?? null });
180
+ sendJson(res, 200, result);
181
+ return;
182
+ }
183
+ // GET /v1/sessions/:id/assemble?budget=N&freshTail=N&summarizeOlder=0|1
184
+ // Phase 2 context-engine API. Returns ordered AssembledContextItem[]
185
+ // with fresh-tail raws + summary substitutions + bio-aware budget fit.
186
+ // Tenant scope from Bearer; default-deny on private rows.
187
+ export async function handleAssembleSession({ req, res, opts, query }, assembleMatch) {
188
+ validateIdSegment(assembleMatch.id, 'session id');
189
+ const budgetRaw = query.get('budget');
190
+ const budget = budgetRaw === null ? undefined : Number(budgetRaw);
191
+ if (budget !== undefined && (!Number.isFinite(budget) || budget <= 0)) {
192
+ throw new HttpError(400, 'budget must be a positive number');
193
+ }
194
+ const ftRaw = query.get('freshTail');
195
+ const freshTailCount = ftRaw === null ? undefined : Number(ftRaw);
196
+ if (freshTailCount !== undefined && (!Number.isFinite(freshTailCount) || freshTailCount < 0)) {
197
+ throw new HttpError(400, 'freshTail must be a non-negative number');
198
+ }
199
+ // v1.6.3 senior review P1: same strict-parse convention as the v1.6.3
200
+ // summarize_overflow tighten on /v1/memories. Pre-v1.6.3 accepted any
201
+ // non-'0'/'false' as true; ?summarizeOlder=banana now correctly returns
202
+ // false (matches includeContinuity convention).
203
+ const sumOlderRaw = query.get('summarizeOlder');
204
+ const summarizeOlder = sumOlderRaw === null
205
+ ? undefined
206
+ : (sumOlderRaw === '1' || sumOlderRaw === 'true');
207
+ const scopeQ = query.get('scope');
208
+ const scope = scopeQ !== null && scopeQ.length > 0 ? scopeQ : undefined;
209
+ const ctx = await buildContextWithAuth(req, opts);
210
+ const assembleExtra = {};
211
+ if (budget !== undefined)
212
+ assembleExtra.budget = budget;
213
+ if (freshTailCount !== undefined)
214
+ assembleExtra.freshTailCount = freshTailCount;
215
+ if (summarizeOlder !== undefined)
216
+ assembleExtra.summarizeOlder = summarizeOlder;
217
+ if (scope !== undefined)
218
+ assembleExtra.scope = scope;
219
+ const result = assemble(ctx, assembleMatch.id, { ...assembleExtra, cost: assembleCost(assembleMatch.id) });
220
+ recordTokens(ctx, 'http_assemble', { items: result.items.length, tokens: result.tokens, sessionId: assembleMatch.id });
221
+ sendJson(res, 200, result);
222
+ return;
223
+ }
224
+ // GET /v1/recall/drill/:id?limit=N&budget=N
225
+ // Companion to /v1/memories. When recall surfaces a level-2 summary in
226
+ // place of overflowed children (RecallResultItem.isSummary === true), the
227
+ // caller drills into the summary id to recover the originals. Tenant
228
+ // scoped via Bearer; default-deny on private scopes for both summary
229
+ // and children.
230
+ export async function handleDrillRecall({ req, res, opts, query }, drillMatch) {
231
+ validateIdSegment(drillMatch.id, 'summary id');
232
+ const limitRaw = query.get('limit');
233
+ const limit = limitRaw === null ? undefined : Number(limitRaw);
234
+ if (limit !== undefined && (!Number.isFinite(limit) || limit <= 0)) {
235
+ throw new HttpError(400, 'limit must be a positive number');
236
+ }
237
+ const budgetRaw = query.get('budget');
238
+ const budget = budgetRaw === null ? undefined : Number(budgetRaw);
239
+ if (budget !== undefined && (!Number.isFinite(budget) || budget <= 0)) {
240
+ throw new HttpError(400, 'budget must be a positive number');
241
+ }
242
+ // v0.30 / E5: depth query param walks N levels (default 1, hard cap 10).
243
+ const depthRaw = query.get('depth');
244
+ let depth;
245
+ if (depthRaw !== null) {
246
+ const parsed = Number(depthRaw);
247
+ // L4 fold: reject out-of-range explicitly (no silent clamp).
248
+ if (!Number.isInteger(parsed) || parsed < 1 || parsed > 10) {
249
+ throw new HttpError(400, 'depth must be a positive integer between 1 and 10');
250
+ }
251
+ depth = parsed;
252
+ }
253
+ const ctx = await buildContextWithAuth(req, opts);
254
+ const drillExtra = {};
255
+ if (limit !== undefined)
256
+ drillExtra.limit = limit;
257
+ if (budget !== undefined)
258
+ drillExtra.budget = budget;
259
+ if (depth !== undefined)
260
+ drillExtra.depth = depth;
261
+ const result = drillDown(ctx, drillMatch.id, { ...drillExtra, cost: drillCost });
262
+ if ('failure' in result) {
263
+ // v1.6.4: leaf id maps to 422 (caller-actionable). Other cases stay
264
+ // as 404 to avoid leaking cross-tenant existence or scope grants.
265
+ if (result.failure === 'not_drillable') {
266
+ throw new HttpError(422, 'Id is a leaf row, not a level-2+ summary; nothing to drill into');
267
+ }
268
+ throw new HttpError(404, 'No drillable summary at this id');
269
+ }
270
+ sendJson(res, 200, result);
271
+ return;
272
+ }
273
+ // GET /v1/context — assemble a budget-bounded context bundle. Returns
274
+ // ContextResult JSON (entries + tokens + activeSnapshot + sessionHandoff
275
+ // + recentEvents). No server-side rendering; clients render. Tenant-scoped
276
+ // via the Bearer. Pinned-only + '*' fallback skip the recall audit emit
277
+ // (matches cmdContext); real-query hybrid search emits one 'recall' row.
278
+ export async function handleGetContext({ req, res, opts, query }) {
279
+ const q = query.get('q') ?? undefined;
280
+ // v1.11.5: DoS cap on q-param length. 1024 covers real multi-clause queries
281
+ // (pasted error messages, multi-stem searches) while bounding BM25
282
+ // tokenisation cost (~150 tokens worst case at 1024 chars).
283
+ if (q !== undefined && q.length > 1024) {
284
+ throw new HttpError(400, 'q exceeds 1024-character cap');
285
+ }
286
+ const budgetRaw = query.get('budget');
287
+ let budget;
288
+ if (budgetRaw !== null) {
289
+ budget = Number(budgetRaw);
290
+ if (!Number.isFinite(budget) || budget < 0) {
291
+ throw new HttpError(400, 'budget must be a non-negative number');
292
+ }
293
+ }
294
+ const limitRaw = query.get('limit');
295
+ let limit;
296
+ if (limitRaw !== null) {
297
+ limit = Number(limitRaw);
298
+ if (!Number.isFinite(limit) || limit <= 0) {
299
+ throw new HttpError(400, 'limit must be a positive number');
300
+ }
301
+ }
302
+ const pinnedOnlyRaw = query.get('pinned_only');
303
+ const pinnedOnly = pinnedOnlyRaw === '1' || pinnedOnlyRaw === 'true';
304
+ const scopeRaw = query.get('scope');
305
+ if (scopeRaw !== null && scopeRaw.length > 256) {
306
+ throw new HttpError(400, 'scope exceeds 256-character cap');
307
+ }
308
+ const scope = scopeRaw === null ? undefined : scopeRaw;
309
+ const includeRecentRaw = query.get('include_recent');
310
+ let includeRecent;
311
+ if (includeRecentRaw !== null) {
312
+ includeRecent = Number(includeRecentRaw);
313
+ if (!Number.isFinite(includeRecent) || includeRecent < 0) {
314
+ throw new HttpError(400, 'include_recent must be a non-negative number');
315
+ }
316
+ }
317
+ // v39 memory scope isolation: cross_project=1|true re-includes
318
+ // other-project rows (tagged category 'cross-project' in the response).
319
+ // The partition identity comes from the SERVED STORE's location, not the
320
+ // daemon's process cwd - a daemon started from anywhere still isolates
321
+ // the project it serves.
322
+ const crossProjectRaw = query.get('cross_project');
323
+ const crossProject = crossProjectRaw === '1' || crossProjectRaw === 'true';
324
+ const ctx = await buildContextWithAuth(req, opts);
325
+ const result = await getContext(ctx, {
326
+ q,
327
+ budget,
328
+ limit,
329
+ pinnedOnly,
330
+ scope,
331
+ includeRecent,
332
+ crossProject,
333
+ currentProject: resolveProjectIdentity(dirname(resolve(opts.hippoRoot))).name,
334
+ cost: contextCost('markdown', 'observe'), // clients render; the budget prices the block `hippo context` would print
335
+ });
336
+ recordTokens(ctx, 'http_context', { items: result.entries.length, tokens: result.tokens });
337
+ sendJson(res, 200, result);
338
+ return;
339
+ }
340
+ //# sourceMappingURL=recall.js.map
@@ -0,0 +1,8 @@
1
+ import type { RouteRequest } from '../types.js';
2
+ export declare function handleCreateSkill({ req, res, opts }: RouteRequest): Promise<void>;
3
+ export declare function handleListSkills({ req, res, opts, query }: RouteRequest): Promise<void>;
4
+ export declare function handleExportSkills({ req, res, opts }: RouteRequest): Promise<void>;
5
+ export declare function handleSupersedeSkill({ req, res, opts }: RouteRequest, skillSupersedeMatch: RegExpMatchArray): Promise<void>;
6
+ export declare function handleCloseSkill({ req, res, opts }: RouteRequest, skillCloseMatch: RegExpMatchArray): Promise<void>;
7
+ export declare function handleGetSkill({ req, res, opts }: RouteRequest, skillByIdMatch: RegExpMatchArray): Promise<void>;
8
+ //# sourceMappingURL=skills.d.ts.map