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
package/dist/client.js CHANGED
@@ -13,8 +13,19 @@
13
13
  * Network errors (ECONNREFUSED on a stale pidfile, etc.) propagate as the
14
14
  * native fetch failure so the caller can detect them and self-heal.
15
15
  */
16
+ import { fetchWithRetry } from './http-retry.js';
16
17
  /** A write the local server has not answered in this long is stuck; the caller treats it as delivery-unknown. */
17
18
  const SERVER_TIMEOUT_MS = 30_000;
19
+ /** Five tries at the server's 1 s Retry-After keeps the roughly 5 s wait the CLI had before the server answered busy with 503. */
20
+ const STORE_BUSY_ATTEMPTS = 5;
21
+ /** The server sets Retry-After on a 503 only for a held write lock (server.ts replyFor); the auth-provider 503 has none. */
22
+ function isStoreBusy(res) {
23
+ return res.status === 503 && res.headers.has('retry-after');
24
+ }
25
+ /** Replaying is safe because each routed write commits in one transaction and anything after it is best-effort, so a busy 503 means nothing landed. */
26
+ function sendWrite(url, init) {
27
+ return fetchWithRetry(url, init, { timeoutMs: SERVER_TIMEOUT_MS, attempts: STORE_BUSY_ATTEMPTS, retryOn: isStoreBusy });
28
+ }
18
29
  function buildHeaders(apiKey, withBody) {
19
30
  const headers = {};
20
31
  if (withBody)
@@ -57,10 +68,9 @@ async function throwForStatus(res) {
57
68
  throw new HttpResponseError(message, res.status);
58
69
  }
59
70
  export async function remember(serverUrl, apiKey, opts) {
60
- const res = await fetch(`${serverUrl}/v1/memories`, {
71
+ const res = await sendWrite(`${serverUrl}/v1/memories`, {
61
72
  method: 'POST',
62
73
  headers: buildHeaders(apiKey, true),
63
- signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
64
74
  body: JSON.stringify(opts),
65
75
  });
66
76
  if (!res.ok)
@@ -69,10 +79,9 @@ export async function remember(serverUrl, apiKey, opts) {
69
79
  return result;
70
80
  }
71
81
  export async function forget(serverUrl, apiKey, id) {
72
- const res = await fetch(`${serverUrl}/v1/memories/${encodeURIComponent(id)}`, {
82
+ const res = await sendWrite(`${serverUrl}/v1/memories/${encodeURIComponent(id)}`, {
73
83
  method: 'DELETE',
74
84
  headers: buildHeaders(apiKey, false),
75
- signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
76
85
  });
77
86
  if (!res.ok)
78
87
  await throwForStatus(res);
@@ -80,10 +89,9 @@ export async function forget(serverUrl, apiKey, id) {
80
89
  return result;
81
90
  }
82
91
  export async function promote(serverUrl, apiKey, id) {
83
- const res = await fetch(`${serverUrl}/v1/memories/${encodeURIComponent(id)}/promote`, {
92
+ const res = await sendWrite(`${serverUrl}/v1/memories/${encodeURIComponent(id)}/promote`, {
84
93
  method: 'POST',
85
94
  headers: buildHeaders(apiKey, false),
86
- signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
87
95
  });
88
96
  if (!res.ok)
89
97
  await throwForStatus(res);
@@ -91,10 +99,9 @@ export async function promote(serverUrl, apiKey, id) {
91
99
  return result;
92
100
  }
93
101
  export async function archiveRaw(serverUrl, apiKey, id, reason) {
94
- const res = await fetch(`${serverUrl}/v1/memories/${encodeURIComponent(id)}/archive`, {
102
+ const res = await sendWrite(`${serverUrl}/v1/memories/${encodeURIComponent(id)}/archive`, {
95
103
  method: 'POST',
96
104
  headers: buildHeaders(apiKey, true),
97
- signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
98
105
  body: JSON.stringify({ reason }),
99
106
  });
100
107
  if (!res.ok)
@@ -25,8 +25,6 @@ export interface CompactionRecord {
25
25
  status: CompactionStatus;
26
26
  }
27
27
  export type Log = (message: string) => void;
28
- /** Where the session ran: rows written through the global store keep the project the session was in. */
29
- export declare function compactionOrigin(hippoRoot: string, cwd: string | null): string;
30
28
  interface ScrubbedSummary {
31
29
  summary: string;
32
30
  items: string[];
@@ -1,7 +1,6 @@
1
1
  // One record per Claude Code compaction, and what turns its summary into kept memories.
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
- import { errorMessage, readTranscriptTail, truncateCodePointSafe } from './capture.js';
5
4
  import { isObjectLike, isStringValue } from './capture-contract.js';
6
5
  import { compactSummaryBody, parseCompactionItems, selectItemRows } from './compaction-items.js';
7
6
  import { loadConfig } from './config.js';
@@ -10,9 +9,12 @@ import { gatedWrite } from './gated-write.js';
10
9
  import { COMPACTION_MEMORY_TAG, COMPACTION_SOURCE_PREFIX, Layer, createMemory, generateId } from './memory.js';
11
10
  import { deriveOriginProject, isGlobalStoreRoot } from './project-identity.js';
12
11
  import { maskEmails, redactSecretsStrict } from './secret-detect.js';
13
- import { strengthenRetrievedOn, updateStats, writeEntryMirrors } from './store.js';
12
+ import { strengthenRetrievedOn, writeEntryMirrors } from './store/entry-writes.js';
13
+ import { isRecallBoostAblated } from './ablation.js';
14
+ import { updateStats } from './store/index-and-stats.js';
14
15
  import { resolveTenantId } from './tenant.js';
15
- import { log as logger } from './log.js';
16
+ import { errorMessage, log as logger } from './log.js';
17
+ import { readTranscriptTail, truncateCodePointSafe } from './transcript-tail.js';
16
18
  /** PostCompact has 10 s in all (PreCompact 30 s), so a locked store must be given up on early. */
17
19
  export const COMPACTION_DB_WAIT_MS = 2000;
18
20
  /** Tested verbatim: Claude Code hands PreCompact stdout to the summariser as instructions. */
@@ -28,7 +30,7 @@ const CLAIMED_SUFFIX = '.claimed';
28
30
  /** The marker redactSecretsStrict writes; an item holding it was a secret before it was stored. */
29
31
  const REDACTED = '[REDACTED]';
30
32
  /** Where the session ran: rows written through the global store keep the project the session was in. */
31
- export function compactionOrigin(hippoRoot, cwd) {
33
+ function compactionOrigin(hippoRoot, cwd) {
32
34
  if (!isGlobalStoreRoot(hippoRoot))
33
35
  return deriveOriginProject(path.dirname(hippoRoot));
34
36
  // No cwd means user-global, as stampOriginProject gives the global store; undefined would fall back to the hook's own cwd.
@@ -226,7 +228,7 @@ export function saveItems(db, hippoRoot, ctx, log) {
226
228
  }
227
229
  }
228
230
  // Said again by another session is the same signal as being recalled; the same session carrying it forward is not.
229
- strengthenRetrievedOn(db, [...restated], ctx.tenantId);
231
+ strengthenRetrievedOn(db, [...restated], { tenantId: ctx.tenantId, recallBoostAblated: isRecallBoostAblated() });
230
232
  if (ctx.recordId !== null) {
231
233
  db.prepare(`UPDATE compactions SET items_written = ?, status = 'done' WHERE tenant_id = ? AND id = ?`).run(written.length, ctx.tenantId, ctx.recordId);
232
234
  }
@@ -172,6 +172,82 @@ async function drainStream(ctx, url0, toIngestEvent, fetcher, token, sleep, maxI
172
172
  }
173
173
  return { ingested, pages, maxUpdatedAt, drained: true };
174
174
  }
175
+ function issueItemToEvent(item, repository) {
176
+ if (!isIssuesItem(item))
177
+ return null;
178
+ // Codex P1 #2: /issues returns PRs too — skip them.
179
+ if (item.pull_request)
180
+ return null;
181
+ const payload = {
182
+ action: 'opened',
183
+ repository,
184
+ issue: {
185
+ number: item.number,
186
+ title: item.title,
187
+ body: item.body ?? null,
188
+ user: { login: item.user.login, id: item.user.id },
189
+ updated_at: item.updated_at,
190
+ },
191
+ };
192
+ return { eventName: 'issues', payload };
193
+ }
194
+ function issueCommentItemToEvent(item, repository) {
195
+ if (!isCommentItem(item))
196
+ return null;
197
+ // SAFETY: this closure only runs against the /issues/comments stream,
198
+ // so every item isCommentItem validates here is genuinely an
199
+ // IssueCommentItem; a missing issue_url is handled defensively below.
200
+ const c = item;
201
+ const issueNumber = parseTrailingNumber(c.issue_url);
202
+ if (issueNumber === null)
203
+ return null;
204
+ const payload = {
205
+ action: 'created',
206
+ repository,
207
+ issue: { number: issueNumber },
208
+ comment: {
209
+ id: c.id,
210
+ body: c.body ?? null,
211
+ user: { login: c.user.login, id: c.user.id },
212
+ updated_at: c.updated_at,
213
+ },
214
+ };
215
+ return { eventName: 'issue_comment', payload };
216
+ }
217
+ function prReviewCommentItemToEvent(item, repository) {
218
+ if (!isCommentItem(item))
219
+ return null;
220
+ // SAFETY: this closure only runs against the /pulls/comments stream,
221
+ // so every item isCommentItem validates here is genuinely a
222
+ // PrReviewCommentItem; a missing pull_request_url is handled below.
223
+ const c = item;
224
+ const prNumber = parseTrailingNumber(c.pull_request_url);
225
+ if (prNumber === null)
226
+ return null;
227
+ const payload = {
228
+ action: 'created',
229
+ repository,
230
+ pull_request: { number: prNumber },
231
+ comment: {
232
+ id: c.id,
233
+ body: c.body ?? null,
234
+ user: { login: c.user.login, id: c.user.id },
235
+ updated_at: c.updated_at,
236
+ },
237
+ };
238
+ return { eventName: 'pull_request_review_comment', payload };
239
+ }
240
+ /** Drains one stream, then persists its HWM only when the stream ran to the end. */
241
+ async function backfillStream(ctx, opts, sleep, stream) {
242
+ const res = await drainStream(ctx, stream.url, stream.toIngestEvent, opts.fetcher, opts.token, sleep, opts.maxPerStream);
243
+ // v1.3.1: only advance HWM when the stream actually drained. A capped run
244
+ // (--max) must leave the HWM at its previous value so the next invocation
245
+ // re-fetches the unprocessed tail.
246
+ if (res.drained && res.maxUpdatedAt) {
247
+ writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, stream.column, res.maxUpdatedAt);
248
+ }
249
+ return { ingested: res.ingested, pages: res.pages };
250
+ }
175
251
  export async function backfillRepo(ctx, opts) {
176
252
  const sleep = opts.sleepMs ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
177
253
  const cursors = readCursor(ctx.hippoRoot, ctx.tenantId, opts.repoFullName);
@@ -181,101 +257,32 @@ export async function backfillRepo(ctx, opts) {
181
257
  pages: { issues: 0, issueComments: 0, prReviewComments: 0 },
182
258
  };
183
259
  // ---------- Stream 1: issues (skip PRs) ----------
184
- const issuesUrl = `${API}/repos/${opts.repoFullName}/issues?state=all&per_page=100` +
185
- (cursors.issues ? `&since=${encodeURIComponent(cursors.issues)}` : '');
186
- const issuesRes = await drainStream(ctx, issuesUrl, (item) => {
187
- if (!isIssuesItem(item))
188
- return null;
189
- // Codex P1 #2: /issues returns PRs too — skip them.
190
- if (item.pull_request)
191
- return null;
192
- const payload = {
193
- action: 'opened',
194
- repository,
195
- issue: {
196
- number: item.number,
197
- title: item.title,
198
- body: item.body ?? null,
199
- user: { login: item.user.login, id: item.user.id },
200
- updated_at: item.updated_at,
201
- },
202
- };
203
- return { eventName: 'issues', payload };
204
- }, opts.fetcher, opts.token, sleep, opts.maxPerStream);
260
+ const issuesRes = await backfillStream(ctx, opts, sleep, {
261
+ url: `${API}/repos/${opts.repoFullName}/issues?state=all&per_page=100` +
262
+ (cursors.issues ? `&since=${encodeURIComponent(cursors.issues)}` : ''),
263
+ column: 'issues_hwm',
264
+ toIngestEvent: (item) => issueItemToEvent(item, repository),
265
+ });
205
266
  result.ingested.issues = issuesRes.ingested;
206
267
  result.pages.issues = issuesRes.pages;
207
- // v1.3.1: only advance HWM when the stream actually drained. A capped run
208
- // (--max) must leave the HWM at its previous value so the next invocation
209
- // re-fetches the unprocessed tail.
210
- if (issuesRes.drained && issuesRes.maxUpdatedAt) {
211
- writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, 'issues_hwm', issuesRes.maxUpdatedAt);
212
- }
213
268
  // ---------- Stream 2: repo-level issue comments ----------
214
- const commentsUrl = `${API}/repos/${opts.repoFullName}/issues/comments?per_page=100` +
215
- (cursors.issueComments
216
- ? `&since=${encodeURIComponent(cursors.issueComments)}`
217
- : '');
218
- const commentsRes = await drainStream(ctx, commentsUrl, (item) => {
219
- if (!isCommentItem(item))
220
- return null;
221
- // SAFETY: this closure only runs against the /issues/comments stream,
222
- // so every item isCommentItem validates here is genuinely an
223
- // IssueCommentItem; a missing issue_url is handled defensively below.
224
- const c = item;
225
- const issueNumber = parseTrailingNumber(c.issue_url);
226
- if (issueNumber === null)
227
- return null;
228
- const payload = {
229
- action: 'created',
230
- repository,
231
- issue: { number: issueNumber },
232
- comment: {
233
- id: c.id,
234
- body: c.body ?? null,
235
- user: { login: c.user.login, id: c.user.id },
236
- updated_at: c.updated_at,
237
- },
238
- };
239
- return { eventName: 'issue_comment', payload };
240
- }, opts.fetcher, opts.token, sleep, opts.maxPerStream);
269
+ const commentsRes = await backfillStream(ctx, opts, sleep, {
270
+ url: `${API}/repos/${opts.repoFullName}/issues/comments?per_page=100` +
271
+ (cursors.issueComments ? `&since=${encodeURIComponent(cursors.issueComments)}` : ''),
272
+ column: 'issue_comments_hwm',
273
+ toIngestEvent: (item) => issueCommentItemToEvent(item, repository),
274
+ });
241
275
  result.ingested.issueComments = commentsRes.ingested;
242
276
  result.pages.issueComments = commentsRes.pages;
243
- if (commentsRes.drained && commentsRes.maxUpdatedAt) {
244
- writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, 'issue_comments_hwm', commentsRes.maxUpdatedAt);
245
- }
246
277
  // ---------- Stream 3: repo-level PR review comments ----------
247
- const prCommentsUrl = `${API}/repos/${opts.repoFullName}/pulls/comments?per_page=100` +
248
- (cursors.prReviewComments
249
- ? `&since=${encodeURIComponent(cursors.prReviewComments)}`
250
- : '');
251
- const prCommentsRes = await drainStream(ctx, prCommentsUrl, (item) => {
252
- if (!isCommentItem(item))
253
- return null;
254
- // SAFETY: this closure only runs against the /pulls/comments stream,
255
- // so every item isCommentItem validates here is genuinely a
256
- // PrReviewCommentItem; a missing pull_request_url is handled below.
257
- const c = item;
258
- const prNumber = parseTrailingNumber(c.pull_request_url);
259
- if (prNumber === null)
260
- return null;
261
- const payload = {
262
- action: 'created',
263
- repository,
264
- pull_request: { number: prNumber },
265
- comment: {
266
- id: c.id,
267
- body: c.body ?? null,
268
- user: { login: c.user.login, id: c.user.id },
269
- updated_at: c.updated_at,
270
- },
271
- };
272
- return { eventName: 'pull_request_review_comment', payload };
273
- }, opts.fetcher, opts.token, sleep, opts.maxPerStream);
278
+ const prCommentsRes = await backfillStream(ctx, opts, sleep, {
279
+ url: `${API}/repos/${opts.repoFullName}/pulls/comments?per_page=100` +
280
+ (cursors.prReviewComments ? `&since=${encodeURIComponent(cursors.prReviewComments)}` : ''),
281
+ column: 'pr_review_comments_hwm',
282
+ toIngestEvent: (item) => prReviewCommentItemToEvent(item, repository),
283
+ });
274
284
  result.ingested.prReviewComments = prCommentsRes.ingested;
275
285
  result.pages.prReviewComments = prCommentsRes.pages;
276
- if (prCommentsRes.drained && prCommentsRes.maxUpdatedAt) {
277
- writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, 'pr_review_comments_hwm', prCommentsRes.maxUpdatedAt);
278
- }
279
286
  return result;
280
287
  }
281
288
  //# sourceMappingURL=backfill.js.map
@@ -9,6 +9,7 @@
9
9
  * - hippo github dlq list
10
10
  * - hippo github dlq replay <id> [--force]
11
11
  */
12
+ import { envGithubToken, envGithubWebhookSecret, envGithubWebhookSecretPrevious } from '../../env.js';
12
13
  import { adminActor } from '../../api.js';
13
14
  import { openHippoDb, closeHippoDb } from '../../db.js';
14
15
  import { resolveTenantId } from '../../tenant.js';
@@ -70,7 +71,7 @@ export async function cmdGithubBackfill(hippoRoot, flags, fetcher = realGitHubFe
70
71
  printGithubBackfillUsage();
71
72
  process.exit(2);
72
73
  }
73
- const token = process.env.GITHUB_TOKEN;
74
+ const token = envGithubToken();
74
75
  if (!token) {
75
76
  console.error('GITHUB_TOKEN is not set. Backfill requires a personal access token with repo read scope.');
76
77
  process.exit(2);
@@ -166,8 +167,8 @@ export async function cmdGithubDlqReplay(hippoRoot, args, flags) {
166
167
  // real hook so `replay` actually re-runs the ingest path.
167
168
  const result = await replayDlqEntry(ctx, id, {
168
169
  force,
169
- webhookSecret: process.env.GITHUB_WEBHOOK_SECRET,
170
- previousSecret: process.env.GITHUB_WEBHOOK_SECRET_PREVIOUS,
170
+ webhookSecret: envGithubWebhookSecret(),
171
+ previousSecret: envGithubWebhookSecretPrevious(),
171
172
  ingestHook: async (innerCtx, args) => {
172
173
  const parsed = JSON.parse(args.rawPayload);
173
174
  const event = parsedToIngestEvent(parsed, args.eventName);
@@ -104,61 +104,13 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
104
104
  }
105
105
  // Signature verification (current secret, not the one in effect when DLQed).
106
106
  if (!opts.force && opts.webhookSecret) {
107
- if (!row.signature) {
108
- return {
109
- ok: false,
110
- status: 'sig_missing',
111
- memoryId: null,
112
- retryCount: row.retryCount,
113
- reason: 'row has no signature (legacy, or redacted before storing); pass --force to replay',
114
- };
115
- }
116
- const sigOk = verifyGitHubSignature({
117
- rawBody: row.rawPayload,
118
- signature: row.signature,
119
- webhookSecret: opts.webhookSecret,
120
- previousSecret: opts.previousSecret,
121
- });
122
- if (!sigOk) {
123
- bumpRetryCount(ctx.hippoRoot, id);
124
- return {
125
- ok: false,
126
- status: 'sig_fail',
127
- memoryId: null,
128
- retryCount: row.retryCount + 1,
129
- reason: 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway',
130
- };
131
- }
132
- }
133
- // Parse + envelope guard.
134
- let parsed;
135
- try {
136
- parsed = JSON.parse(row.rawPayload);
137
- }
138
- catch (e) {
139
- bumpRetryCount(ctx.hippoRoot, id);
140
- // SAFETY: this is a best-effort error message only; property access on
141
- // any JS value is safe (undefined if absent), preserving the existing
142
- // lenient formatting even when something non-Error was thrown.
143
- const message = e.message;
144
- return {
145
- ok: false,
146
- status: 'parse_error',
147
- memoryId: null,
148
- retryCount: row.retryCount + 1,
149
- reason: `still unparseable: ${message}`,
150
- };
151
- }
152
- if (!isGitHubWebhookEnvelope(parsed)) {
153
- bumpRetryCount(ctx.hippoRoot, id);
154
- return {
155
- ok: false,
156
- status: 'unhandled',
157
- memoryId: null,
158
- retryCount: row.retryCount + 1,
159
- reason: 'not a GitHub webhook envelope',
160
- };
107
+ const sigFailure = checkReplaySignature(ctx.hippoRoot, id, row, opts.webhookSecret, opts.previousSecret);
108
+ if (sigFailure)
109
+ return sigFailure;
161
110
  }
111
+ const envelopeFailure = checkReplayEnvelope(ctx.hippoRoot, id, row);
112
+ if (envelopeFailure)
113
+ return envelopeFailure;
162
114
  // Without an ingest hook this is a dry-run validation. Bump and report.
163
115
  if (!opts.ingestHook) {
164
116
  bumpRetryCount(ctx.hippoRoot, id);
@@ -190,4 +142,65 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
190
142
  retryCount: row.retryCount + 1,
191
143
  };
192
144
  }
145
+ /** The failure result when the row cannot pass the signature gate, else null. */
146
+ function checkReplaySignature(hippoRoot, id, row, webhookSecret, previousSecret) {
147
+ if (!row.signature) {
148
+ return {
149
+ ok: false,
150
+ status: 'sig_missing',
151
+ memoryId: null,
152
+ retryCount: row.retryCount,
153
+ reason: 'row has no signature (legacy, or redacted before storing); pass --force to replay',
154
+ };
155
+ }
156
+ const sigOk = verifyGitHubSignature({
157
+ rawBody: row.rawPayload,
158
+ signature: row.signature,
159
+ webhookSecret,
160
+ previousSecret,
161
+ });
162
+ if (!sigOk) {
163
+ bumpRetryCount(hippoRoot, id);
164
+ return {
165
+ ok: false,
166
+ status: 'sig_fail',
167
+ memoryId: null,
168
+ retryCount: row.retryCount + 1,
169
+ reason: 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway',
170
+ };
171
+ }
172
+ return null;
173
+ }
174
+ /** Parse + envelope guard; the failure result after bumping the count, else null. */
175
+ function checkReplayEnvelope(hippoRoot, id, row) {
176
+ let parsed;
177
+ try {
178
+ parsed = JSON.parse(row.rawPayload);
179
+ }
180
+ catch (e) {
181
+ bumpRetryCount(hippoRoot, id);
182
+ // SAFETY: this is a best-effort error message only; property access on
183
+ // any JS value is safe (undefined if absent), preserving the existing
184
+ // lenient formatting even when something non-Error was thrown.
185
+ const message = e.message;
186
+ return {
187
+ ok: false,
188
+ status: 'parse_error',
189
+ memoryId: null,
190
+ retryCount: row.retryCount + 1,
191
+ reason: `still unparseable: ${message}`,
192
+ };
193
+ }
194
+ if (!isGitHubWebhookEnvelope(parsed)) {
195
+ bumpRetryCount(hippoRoot, id);
196
+ return {
197
+ ok: false,
198
+ status: 'unhandled',
199
+ memoryId: null,
200
+ retryCount: row.retryCount + 1,
201
+ reason: 'not a GitHub webhook envelope',
202
+ };
203
+ }
204
+ return null;
205
+ }
193
206
  //# sourceMappingURL=dlq.js.map
@@ -69,6 +69,7 @@ function eventUpdatedAt(event) {
69
69
  return event.payload.comment.updated_at ?? null;
70
70
  }
71
71
  }
72
+ const INSERT_EVENT_LOG_SQL = `INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`;
72
73
  export function ingestEvent(ctx, input) {
73
74
  const idempotencyKey = computeIdempotencyKey(eventArtifactRef(input.event), eventUpdatedAt(input.event));
74
75
  // Fast path: pre-check. Avoids running the transform / opening a write tx
@@ -87,15 +88,7 @@ export function ingestEvent(ctx, input) {
87
88
  // Empty body: no memory to write, but mark seen so a retry of the same
88
89
  // empty event returns 'duplicate' (not 'skipped' again — that would
89
90
  // re-run the transform on every retry).
90
- const db2 = openHippoDb(ctx.hippoRoot);
91
- try {
92
- db2
93
- .prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`)
94
- .run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), null);
95
- }
96
- finally {
97
- closeHippoDb(db2);
98
- }
91
+ markKeySeenWithoutMemory(ctx.hippoRoot, idempotencyKey, input);
99
92
  return { status: 'skipped', memoryId: null };
100
93
  }
101
94
  // Atomic write via afterWrite. Inside writeEntry's SAVEPOINT:
@@ -105,23 +98,7 @@ export function ingestEvent(ctx, input) {
105
98
  // the test injection) beat us, changes=0 -> throw -> SAVEPOINT rolls
106
99
  // back our memory row. Other worker's commit stands.
107
100
  try {
108
- // v1.12.0: drop the legacy `|| 'connector:github'` fallback (see slack/ingest.ts:73 for rationale).
109
- const result = remember(ctx, {
110
- ...opts,
111
- untrusted: true,
112
- afterWrite: (innerDb, memoryId) => {
113
- if (input.__testInjectBeforeLog) {
114
- input.__testInjectBeforeLog(innerDb, idempotencyKey);
115
- }
116
- const inserted = innerDb
117
- .prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`)
118
- .run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), memoryId);
119
- if (Number(inserted.changes ?? 0) === 0) {
120
- throw new DuplicateIdempotencyError(idempotencyKey);
121
- }
122
- },
123
- });
124
- return { status: 'ingested', memoryId: result.id };
101
+ return rememberWithEventLog(ctx, input, idempotencyKey, opts);
125
102
  }
126
103
  catch (e) {
127
104
  if (e instanceof DuplicateIdempotencyError) {
@@ -140,18 +117,40 @@ export function ingestEvent(ctx, input) {
140
117
  // a transient failure — never DLQ-retry it. Mark the idempotency key
141
118
  // seen exactly like the empty-body branch above so a GitHub retry of
142
119
  // the same delivery acks as done, not error.
143
- const db4 = openHippoDb(ctx.hippoRoot);
144
- try {
145
- db4
146
- .prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`)
147
- .run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), null);
148
- }
149
- finally {
150
- closeHippoDb(db4);
151
- }
120
+ markKeySeenWithoutMemory(ctx.hippoRoot, idempotencyKey, input);
152
121
  return { status: 'skipped', memoryId: null };
153
122
  }
154
123
  throw e;
155
124
  }
156
125
  }
126
+ function markKeySeenWithoutMemory(hippoRoot, idempotencyKey, input) {
127
+ const db = openHippoDb(hippoRoot);
128
+ try {
129
+ db
130
+ .prepare(INSERT_EVENT_LOG_SQL)
131
+ .run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), null);
132
+ }
133
+ finally {
134
+ closeHippoDb(db);
135
+ }
136
+ }
137
+ function rememberWithEventLog(ctx, input, idempotencyKey, opts) {
138
+ // v1.12.0: drop the legacy `|| 'connector:github'` fallback (see slack/ingest.ts:73 for rationale).
139
+ const result = remember(ctx, {
140
+ ...opts,
141
+ untrusted: true,
142
+ afterWrite: (innerDb, memoryId) => {
143
+ if (input.__testInjectBeforeLog) {
144
+ input.__testInjectBeforeLog(innerDb, idempotencyKey);
145
+ }
146
+ const inserted = innerDb
147
+ .prepare(INSERT_EVENT_LOG_SQL)
148
+ .run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), memoryId);
149
+ if (Number(inserted.changes ?? 0) === 0) {
150
+ throw new DuplicateIdempotencyError(idempotencyKey);
151
+ }
152
+ },
153
+ });
154
+ return { status: 'ingested', memoryId: result.id };
155
+ }
157
156
  //# sourceMappingURL=ingest.js.map
@@ -1,3 +1,4 @@
1
+ import { envGithubAllowUnknownInstallationFallback, envTenant } from '../../env.js';
1
2
  /**
2
3
  * Resolve the tenant_id for a GitHub webhook envelope.
3
4
  *
@@ -23,8 +24,8 @@
23
24
  * replay, future MCP) gets identical protection.
24
25
  */
25
26
  export function resolveTenantForGitHub(db, args) {
26
- const envFallback = () => process.env.HIPPO_TENANT?.trim() || 'default';
27
- const escapeHatch = process.env.GITHUB_ALLOW_UNKNOWN_INSTALLATION_FALLBACK === '1';
27
+ const envFallback = () => envTenant();
28
+ const escapeHatch = envGithubAllowUnknownInstallationFallback();
28
29
  // SAFETY: the row comes from the SELECT above, which projects exactly one
29
30
  // column, `c`, as a COUNT(*).
30
31
  const instCount = db