hippo-memory 1.69.0 → 1.71.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 (1014) hide show
  1. package/README.md +5 -2
  2. package/dist/agent-memories/apply.d.ts +3 -3
  3. package/dist/agent-memories/apply.js +16 -31
  4. package/dist/agent-memories/claude-code.d.ts +5 -5
  5. package/dist/agent-memories/claude-code.js +25 -12
  6. package/dist/agent-memories/copilot.js +3 -2
  7. package/dist/agent-memories/files.js +26 -14
  8. package/dist/agent-memories/gemini.js +6 -5
  9. package/dist/agent-memories/keys.js +3 -2
  10. package/dist/agent-memories/legacy.d.ts +2 -2
  11. package/dist/agent-memories/legacy.js +2 -2
  12. package/dist/agent-memories/markdown.d.ts +1 -3
  13. package/dist/agent-memories/markdown.js +1 -3
  14. package/dist/agent-memories/report.d.ts +1 -1
  15. package/dist/agent-memories/report.js +3 -2
  16. package/dist/agent-memories/source.d.ts +1 -1
  17. package/dist/agent-memories/source.js +6 -5
  18. package/dist/agent-memories/sync.d.ts +5 -3
  19. package/dist/agent-memories/sync.js +34 -38
  20. package/dist/agent-memories/types.d.ts +1 -1
  21. package/dist/api/assemble.d.ts +9 -46
  22. package/dist/api/assemble.js +44 -54
  23. package/dist/api/audit.d.ts +8 -7
  24. package/dist/api/audit.js +15 -21
  25. package/dist/api/auth.d.ts +17 -39
  26. package/dist/api/auth.js +76 -216
  27. package/dist/api/auto-sleep.d.ts +13 -0
  28. package/dist/api/auto-sleep.js +32 -0
  29. package/dist/{availability.d.ts → api/availability.d.ts} +4 -17
  30. package/dist/{availability.js → api/availability.js} +14 -44
  31. package/dist/{context-auto.js → api/context-auto.js} +2 -1
  32. package/dist/{context-render.d.ts → api/context-render.d.ts} +4 -4
  33. package/dist/{context-render.js → api/context-render.js} +7 -6
  34. package/dist/api/context-select.d.ts +5 -5
  35. package/dist/api/context-select.js +39 -48
  36. package/dist/api/context-types.d.ts +15 -40
  37. package/dist/api/context.d.ts +7 -26
  38. package/dist/api/context.js +67 -97
  39. package/dist/api/dormant.d.ts +7 -23
  40. package/dist/api/dormant.js +40 -128
  41. package/dist/api/drill-down.d.ts +9 -48
  42. package/dist/api/drill-down.js +41 -90
  43. package/dist/api/forget.d.ts +5 -33
  44. package/dist/api/forget.js +17 -73
  45. package/dist/api/goals.d.ts +1 -1
  46. package/dist/api/goals.js +2 -2
  47. package/dist/api/graph.d.ts +8 -0
  48. package/dist/api/graph.js +7 -0
  49. package/dist/api/index.d.ts +28 -0
  50. package/dist/api/index.js +31 -0
  51. package/dist/api/instruction-detect.js +85 -0
  52. package/dist/api/learn.js +63 -55
  53. package/dist/api/ledger-db.d.ts +21 -0
  54. package/dist/api/ledger-db.js +81 -0
  55. package/dist/api/memories.d.ts +5 -0
  56. package/dist/api/memories.js +7 -0
  57. package/dist/api/objects.d.ts +9 -0
  58. package/dist/api/objects.js +11 -0
  59. package/dist/api/on-store.d.ts +16 -0
  60. package/dist/api/on-store.js +38 -0
  61. package/dist/api/outcome.d.ts +5 -42
  62. package/dist/api/outcome.js +15 -80
  63. package/dist/{pilot-arm.d.ts → api/pilot-arm.d.ts} +1 -1
  64. package/dist/{pilot-arm.js → api/pilot-arm.js} +15 -23
  65. package/dist/api/predictions.d.ts +9 -0
  66. package/dist/api/predictions.js +18 -0
  67. package/dist/api/promote.d.ts +16 -31
  68. package/dist/api/promote.js +38 -123
  69. package/dist/{prompt-hook.d.ts → api/prompt-hook.d.ts} +11 -11
  70. package/dist/{prompt-hook.js → api/prompt-hook.js} +42 -60
  71. package/dist/api/quarantine.d.ts +5 -5
  72. package/dist/api/quarantine.js +30 -106
  73. package/dist/api/recall-cli.d.ts +55 -0
  74. package/dist/api/recall-cli.js +94 -0
  75. package/dist/api/recall-core.d.ts +4 -0
  76. package/dist/api/recall-core.js +120 -0
  77. package/dist/api/recall-finish.d.ts +53 -0
  78. package/dist/api/recall-finish.js +30 -0
  79. package/dist/api/recall-history.d.ts +64 -0
  80. package/dist/api/recall-history.js +159 -0
  81. package/dist/{recall-pipeline.d.ts → api/recall-pipeline.d.ts} +7 -8
  82. package/dist/{recall-pipeline.js → api/recall-pipeline.js} +60 -48
  83. package/dist/api/recall-record.d.ts +10 -13
  84. package/dist/api/recall-record.js +10 -30
  85. package/dist/api/recall-request.d.ts +2 -2
  86. package/dist/api/recall-request.js +3 -3
  87. package/dist/api/recall-types.d.ts +101 -316
  88. package/dist/api/recall.d.ts +5 -33
  89. package/dist/api/recall.js +92 -91
  90. package/dist/api/refine.d.ts +7 -0
  91. package/dist/api/refine.js +10 -0
  92. package/dist/api/remember-local.d.ts +57 -0
  93. package/dist/api/remember-local.js +90 -0
  94. package/dist/api/remember.d.ts +27 -12
  95. package/dist/api/remember.js +42 -46
  96. package/dist/api/session-owners.d.ts +4 -0
  97. package/dist/api/session-owners.js +17 -0
  98. package/dist/api/sleep-run.d.ts +7 -9
  99. package/dist/api/sleep-run.js +78 -94
  100. package/dist/api/sleep.d.ts +10 -29
  101. package/dist/api/tokens.d.ts +5 -12
  102. package/dist/api/tokens.js +12 -31
  103. package/dist/api/types.d.ts +8 -31
  104. package/dist/api/types.js +5 -23
  105. package/dist/capture/caller-session.d.ts +2 -2
  106. package/dist/capture/caller-session.js +8 -8
  107. package/dist/{capture-error.d.ts → capture/capture-error.d.ts} +2 -2
  108. package/dist/{capture-error.js → capture/capture-error.js} +7 -7
  109. package/dist/{codex-patch.js → capture/codex-patch.js} +1 -1
  110. package/dist/capture/command.d.ts +5 -13
  111. package/dist/capture/command.js +57 -60
  112. package/dist/capture/compact-resume-caller.d.ts +1 -1
  113. package/dist/capture/compact-resume-caller.js +7 -7
  114. package/dist/capture/compact.d.ts +8 -16
  115. package/dist/capture/compact.js +56 -47
  116. package/dist/capture/compaction-items-caller.d.ts +1 -1
  117. package/dist/capture/compaction-items-caller.js +7 -5
  118. package/dist/{compaction-items.js → capture/compaction-items.js} +27 -3
  119. package/dist/{compaction-record.d.ts → capture/compaction-record.d.ts} +10 -6
  120. package/dist/{compaction-record.js → capture/compaction-record.js} +143 -157
  121. package/dist/{compaction-spool.d.ts → capture/compaction-spool.d.ts} +1 -1
  122. package/dist/{compaction-spool.js → capture/compaction-spool.js} +18 -14
  123. package/dist/capture/copilot-transcript.js +1 -1
  124. package/dist/capture/extract.js +2 -2
  125. package/dist/capture/failure-caller.d.ts +2 -2
  126. package/dist/capture/failure-caller.js +6 -6
  127. package/dist/capture/failure-reading.d.ts +2 -5
  128. package/dist/capture/failure-reading.js +11 -12
  129. package/dist/{handoff-evidence.d.ts → capture/handoff-evidence.d.ts} +1 -1
  130. package/dist/{handoff-evidence.js → capture/handoff-evidence.js} +2 -1
  131. package/dist/capture/pre-compact-caller.d.ts +1 -1
  132. package/dist/capture/pre-compact-caller.js +2 -2
  133. package/dist/{session-digest.d.ts → capture/session-digest.d.ts} +2 -6
  134. package/dist/{session-digest.js → capture/session-digest.js} +29 -29
  135. package/dist/capture/session-end-caller.d.ts +2 -2
  136. package/dist/capture/session-end-caller.js +1 -1
  137. package/dist/capture/session-texts.d.ts +1 -1
  138. package/dist/capture/session-texts.js +5 -5
  139. package/dist/capture/session-worker.js +6 -4
  140. package/dist/{share-scrub.js → capture/share-scrub.js} +2 -2
  141. package/dist/capture/transcript.d.ts +2 -10
  142. package/dist/capture/transcript.js +72 -92
  143. package/dist/capture/working-state.d.ts +0 -3
  144. package/dist/capture/working-state.js +7 -7
  145. package/dist/cli/api-context.d.ts +3 -0
  146. package/dist/cli/api-context.js +6 -0
  147. package/dist/cli/audit-prune.d.ts +28 -0
  148. package/dist/cli/audit-prune.js +40 -0
  149. package/dist/cli/audit.d.ts +2 -2
  150. package/dist/cli/audit.js +92 -88
  151. package/dist/cli/auth.d.ts +2 -1
  152. package/dist/cli/auth.js +69 -53
  153. package/dist/cli/briefs.d.ts +4 -3
  154. package/dist/cli/briefs.js +76 -202
  155. package/dist/cli/card.d.ts +2 -1
  156. package/dist/cli/card.js +55 -54
  157. package/dist/cli/client.d.ts +28 -0
  158. package/dist/{client.js → cli/client.js} +25 -44
  159. package/dist/cli/compact-resume-payload.d.ts +8 -0
  160. package/dist/cli/compact-resume-payload.js +40 -0
  161. package/dist/cli/context.d.ts +1 -13
  162. package/dist/cli/context.js +51 -77
  163. package/dist/cli/continuity.d.ts +6 -5
  164. package/dist/cli/continuity.js +153 -145
  165. package/dist/cli/correction-latency.d.ts +24 -0
  166. package/dist/{correction-latency.js → cli/correction-latency.js} +2 -14
  167. package/dist/cli/curate.d.ts +13 -17
  168. package/dist/cli/curate.js +226 -222
  169. package/dist/cli/dag.d.ts +4 -4
  170. package/dist/cli/dag.js +70 -52
  171. package/dist/cli/decisions.d.ts +4 -3
  172. package/dist/cli/decisions.js +129 -253
  173. package/dist/cli/eval.d.ts +1 -3
  174. package/dist/cli/eval.js +56 -42
  175. package/dist/cli/exit.d.ts +6 -0
  176. package/dist/cli/exit.js +11 -0
  177. package/dist/cli/explain.d.ts +1 -2
  178. package/dist/cli/explain.js +39 -21
  179. package/dist/cli/flag-values.d.ts +30 -0
  180. package/dist/cli/flag-values.js +120 -0
  181. package/dist/cli/flags.d.ts +304 -0
  182. package/dist/cli/flags.js +169 -0
  183. package/dist/cli/github.d.ts +14 -0
  184. package/dist/cli/github.js +184 -0
  185. package/dist/cli/goals.d.ts +2 -1
  186. package/dist/cli/goals.js +76 -75
  187. package/dist/cli/hook-runtime.d.ts +31 -0
  188. package/dist/cli/hook-runtime.js +139 -0
  189. package/dist/cli/init.d.ts +2 -1
  190. package/dist/cli/init.js +153 -126
  191. package/dist/cli/install-steps.d.ts +7 -0
  192. package/dist/cli/install-steps.js +101 -0
  193. package/dist/cli/last-sleep.d.ts +3 -1
  194. package/dist/cli/last-sleep.js +12 -7
  195. package/dist/cli/maintenance.d.ts +5 -4
  196. package/dist/cli/maintenance.js +41 -42
  197. package/dist/cli/object-verbs.d.ts +40 -0
  198. package/dist/cli/object-verbs.js +66 -0
  199. package/dist/cli/owner-validation.d.ts +18 -0
  200. package/dist/cli/owner-validation.js +33 -0
  201. package/dist/cli/playbooks.d.ts +4 -3
  202. package/dist/cli/playbooks.js +98 -306
  203. package/dist/cli/print.d.ts +15 -0
  204. package/dist/cli/print.js +82 -0
  205. package/dist/cli/projects.d.ts +2 -3
  206. package/dist/cli/projects.js +56 -51
  207. package/dist/cli/provenance-coverage.d.ts +14 -0
  208. package/dist/{provenance-coverage.js → cli/provenance-coverage.js} +2 -6
  209. package/dist/cli/quality-repair-once.js +4 -4
  210. package/dist/cli/recall.d.ts +2 -6
  211. package/dist/cli/recall.js +128 -253
  212. package/dist/cli/refine-llm.d.ts +35 -0
  213. package/dist/cli/refine-llm.js +128 -0
  214. package/dist/cli/remember.d.ts +4 -6
  215. package/dist/cli/remember.js +193 -230
  216. package/dist/{scheduler.d.ts → cli/scheduler.d.ts} +4 -17
  217. package/dist/{scheduler.js → cli/scheduler.js} +22 -22
  218. package/dist/cli/serve.d.ts +1 -1
  219. package/dist/cli/serve.js +46 -7
  220. package/dist/cli/session-hooks.d.ts +11 -19
  221. package/dist/cli/session-hooks.js +263 -258
  222. package/dist/cli/setup.d.ts +4 -3
  223. package/dist/cli/setup.js +55 -37
  224. package/dist/cli/shared.d.ts +14 -118
  225. package/dist/cli/shared.js +26 -400
  226. package/dist/cli/slack.d.ts +2 -1
  227. package/dist/cli/slack.js +46 -74
  228. package/dist/cli/sleep-render.d.ts +4 -0
  229. package/dist/cli/sleep-render.js +61 -0
  230. package/dist/cli/sleep.d.ts +3 -8
  231. package/dist/cli/sleep.js +34 -91
  232. package/dist/cli/status.d.ts +9 -12
  233. package/dist/cli/status.js +86 -131
  234. package/dist/{stdin.d.ts → cli/stdin.d.ts} +4 -6
  235. package/dist/{stdin.js → cli/stdin.js} +8 -9
  236. package/dist/cli/transfer.d.ts +9 -9
  237. package/dist/cli/transfer.js +125 -122
  238. package/dist/cli/usage.js +13 -5
  239. package/dist/cli.d.ts +69 -167
  240. package/dist/cli.js +187 -296
  241. package/dist/connectors/dlq.d.ts +44 -0
  242. package/dist/connectors/dlq.js +30 -0
  243. package/dist/connectors/github/backfill.d.ts +6 -26
  244. package/dist/connectors/github/backfill.js +42 -114
  245. package/dist/connectors/github/deletion.d.ts +6 -21
  246. package/dist/connectors/github/deletion.js +17 -64
  247. package/dist/connectors/github/dlq.d.ts +12 -91
  248. package/dist/connectors/github/dlq.js +23 -140
  249. package/dist/connectors/github/ingest.d.ts +4 -37
  250. package/dist/connectors/github/ingest.js +24 -93
  251. package/dist/connectors/github/octokit-client.d.ts +5 -17
  252. package/dist/connectors/github/octokit-client.js +29 -25
  253. package/dist/connectors/github/ratelimit.d.ts +3 -14
  254. package/dist/connectors/github/ratelimit.js +3 -14
  255. package/dist/connectors/github/scope.d.ts +3 -5
  256. package/dist/connectors/github/scope.js +3 -5
  257. package/dist/connectors/github/signature.d.ts +4 -26
  258. package/dist/connectors/github/signature.js +4 -26
  259. package/dist/connectors/github/tenant-routing.d.ts +4 -26
  260. package/dist/connectors/github/tenant-routing.js +13 -61
  261. package/dist/connectors/github/transform.d.ts +1 -1
  262. package/dist/connectors/github/transform.js +2 -16
  263. package/dist/connectors/github/types.d.ts +4 -16
  264. package/dist/connectors/github/types.js +17 -27
  265. package/dist/connectors/github/webhook.d.ts +5 -18
  266. package/dist/connectors/github/webhook.js +86 -105
  267. package/dist/connectors/slack/backfill.d.ts +5 -18
  268. package/dist/connectors/slack/backfill.js +9 -42
  269. package/dist/connectors/slack/deletion.d.ts +4 -7
  270. package/dist/connectors/slack/deletion.js +20 -49
  271. package/dist/connectors/slack/dlq.d.ts +9 -68
  272. package/dist/connectors/slack/dlq.js +26 -136
  273. package/dist/connectors/slack/ingest.d.ts +4 -18
  274. package/dist/connectors/slack/ingest.js +26 -91
  275. package/dist/connectors/slack/scope.d.ts +2 -8
  276. package/dist/connectors/slack/scope.js +2 -8
  277. package/dist/connectors/slack/signature.d.ts +1 -6
  278. package/dist/connectors/slack/signature.js +2 -1
  279. package/dist/connectors/slack/tenant-routing.d.ts +4 -18
  280. package/dist/connectors/slack/tenant-routing.js +11 -31
  281. package/dist/connectors/slack/transform.d.ts +3 -19
  282. package/dist/connectors/slack/transform.js +2 -18
  283. package/dist/connectors/slack/types.d.ts +4 -10
  284. package/dist/connectors/slack/types.js +5 -16
  285. package/dist/connectors/slack/web-client.js +34 -28
  286. package/dist/connectors/slack/webhook.d.ts +5 -21
  287. package/dist/connectors/slack/webhook.js +80 -108
  288. package/dist/connectors/slack/workspaces.d.ts +8 -41
  289. package/dist/connectors/slack/workspaces.js +8 -58
  290. package/dist/consolidate/conflicts.d.ts +1 -1
  291. package/dist/consolidate/conflicts.js +10 -18
  292. package/dist/consolidate/dag-summary.d.ts +8 -0
  293. package/dist/consolidate/dag-summary.js +41 -0
  294. package/dist/{dag.d.ts → consolidate/dag.d.ts} +6 -29
  295. package/dist/{dag.js → consolidate/dag.js} +49 -131
  296. package/dist/consolidate/decay.d.ts +2 -2
  297. package/dist/consolidate/decay.js +35 -41
  298. package/dist/consolidate/dedupe.d.ts +29 -0
  299. package/dist/consolidate/dedupe.js +103 -0
  300. package/dist/consolidate/flush-units.d.ts +5 -6
  301. package/dist/consolidate/flush-units.js +3 -3
  302. package/dist/consolidate/half-life-migration.d.ts +34 -0
  303. package/dist/consolidate/half-life-migration.js +89 -0
  304. package/dist/consolidate/llm-passes.js +12 -29
  305. package/dist/consolidate/memory-value-weights.d.ts +8 -0
  306. package/dist/{memory-value-weights.js → consolidate/memory-value-weights.js} +2 -13
  307. package/dist/consolidate/memory-value.d.ts +45 -0
  308. package/dist/consolidate/memory-value.js +164 -0
  309. package/dist/consolidate/merge.js +65 -83
  310. package/dist/{merged-row.d.ts → consolidate/merged-row.d.ts} +1 -1
  311. package/dist/{merged-row.js → consolidate/merged-row.js} +4 -3
  312. package/dist/consolidate/physics-pass.js +46 -48
  313. package/dist/consolidate/replay.d.ts +9 -0
  314. package/dist/consolidate/replay.js +84 -0
  315. package/dist/consolidate/run.d.ts +7 -13
  316. package/dist/consolidate/run.js +6 -37
  317. package/dist/consolidate/sleep.d.ts +2 -9
  318. package/dist/consolidate/sleep.js +69 -151
  319. package/dist/consolidate/trace.d.ts +19 -0
  320. package/dist/{trace.js → consolidate/trace.js} +7 -24
  321. package/dist/consolidate/traces.js +40 -51
  322. package/dist/core/ablation.d.ts +15 -0
  323. package/dist/core/ablation.js +49 -0
  324. package/dist/{agent-memories/tools.d.ts → core/agent-memory-tools.d.ts} +1 -1
  325. package/dist/{agent-memories/tools.js → core/agent-memory-tools.js} +1 -1
  326. package/dist/{ambient.d.ts → core/ambient.d.ts} +1 -8
  327. package/dist/{ambient.js → core/ambient.js} +13 -18
  328. package/dist/{capture-contract.d.ts → core/capture-contract.d.ts} +16 -3
  329. package/dist/{capture-contract.js → core/capture-contract.js} +67 -1
  330. package/dist/{card.d.ts → core/card.d.ts} +4 -1
  331. package/dist/{card.js → core/card.js} +8 -0
  332. package/dist/core/compare.d.ts +32 -0
  333. package/dist/core/compare.js +70 -0
  334. package/dist/{config.d.ts → core/config.d.ts} +14 -28
  335. package/dist/{config.js → core/config.js} +101 -75
  336. package/dist/{handoff.d.ts → core/handoff.d.ts} +1 -7
  337. package/dist/core/handoff.js +81 -0
  338. package/dist/{memory-quality.js → core/memory-quality.js} +2 -2
  339. package/dist/core/memory.d.ts +183 -0
  340. package/dist/core/memory.js +380 -0
  341. package/dist/core/package-root.d.ts +3 -0
  342. package/dist/core/package-root.js +5 -0
  343. package/dist/{physics-config.d.ts → core/physics-config.d.ts} +1 -4
  344. package/dist/{physics-config.js → core/physics-config.js} +3 -8
  345. package/dist/{physics.d.ts → core/physics.d.ts} +16 -62
  346. package/dist/{physics.js → core/physics.js} +60 -122
  347. package/dist/{project-identity.d.ts → core/project-identity.d.ts} +17 -63
  348. package/dist/{project-identity.js → core/project-identity.js} +22 -55
  349. package/dist/{project-remote.js → core/project-remote.js} +17 -6
  350. package/dist/{prompt-recall.js → core/prompt-recall.js} +1 -1
  351. package/dist/core/raw-append-only.d.ts +5 -0
  352. package/dist/core/raw-append-only.js +7 -0
  353. package/dist/{salience.d.ts → core/salience.d.ts} +1 -7
  354. package/dist/{salience.js → core/salience.js} +36 -27
  355. package/dist/{search/types.d.ts → core/search-types.d.ts} +2 -2
  356. package/dist/{search/types.js → core/search-types.js} +1 -1
  357. package/dist/core/session-digest-row.d.ts +5 -0
  358. package/dist/core/session-digest-row.js +6 -0
  359. package/dist/{dashboard-actions.d.ts → dashboard/dashboard-actions.d.ts} +1 -1
  360. package/dist/{dashboard-actions.js → dashboard/dashboard-actions.js} +7 -7
  361. package/dist/{dashboard-queries.d.ts → dashboard/dashboard-queries.d.ts} +7 -2
  362. package/dist/{dashboard-queries.js → dashboard/dashboard-queries.js} +6 -10
  363. package/dist/{dashboard-snapshot.d.ts → dashboard/dashboard-snapshot.d.ts} +11 -10
  364. package/dist/{dashboard-snapshot.js → dashboard/dashboard-snapshot.js} +110 -104
  365. package/dist/{dashboard-types.d.ts → dashboard/dashboard-types.d.ts} +2 -1
  366. package/dist/{dashboard.d.ts → dashboard/dashboard.d.ts} +1 -0
  367. package/dist/{dashboard.js → dashboard/dashboard.js} +172 -55
  368. package/dist/db/backup.js +1 -1
  369. package/dist/db/busy.d.ts +19 -2
  370. package/dist/db/busy.js +88 -14
  371. package/dist/db/connect.d.ts +11 -2
  372. package/dist/db/connect.js +43 -10
  373. package/dist/db/index.d.ts +9 -0
  374. package/dist/db/index.js +8 -0
  375. package/dist/db/meta.d.ts +4 -0
  376. package/dist/db/meta.js +11 -1
  377. package/dist/db/migrate.d.ts +8 -1
  378. package/dist/db/migrate.js +28 -33
  379. package/dist/db/migrations/types.d.ts +2 -5
  380. package/dist/db/migrations/v08.js +1 -1
  381. package/dist/db/migrations/v14.js +39 -36
  382. package/dist/db/migrations/v15.js +2 -8
  383. package/dist/db/migrations/v16.js +31 -29
  384. package/dist/db/migrations/v17.js +2 -3
  385. package/dist/db/migrations/v18.js +6 -5
  386. package/dist/db/migrations/v19.js +2 -5
  387. package/dist/db/migrations/v20.js +5 -8
  388. package/dist/db/migrations/v22.js +28 -38
  389. package/dist/db/migrations/v23.js +3 -14
  390. package/dist/db/migrations/v24.js +25 -22
  391. package/dist/db/migrations/v25.js +3 -8
  392. package/dist/db/migrations/v26.js +2 -13
  393. package/dist/db/migrations/v27.js +3 -11
  394. package/dist/db/migrations/v28.js +2 -14
  395. package/dist/db/migrations/v29.js +23 -32
  396. package/dist/db/migrations/v30.js +4 -16
  397. package/dist/db/migrations/v31.js +23 -31
  398. package/dist/db/migrations/v32.js +4 -22
  399. package/dist/db/migrations/v33.js +2 -15
  400. package/dist/db/migrations/v34.js +2 -11
  401. package/dist/db/migrations/v35.js +2 -11
  402. package/dist/db/migrations/v36.js +2 -11
  403. package/dist/db/migrations/v37.js +8 -33
  404. package/dist/db/migrations/v38.js +5 -38
  405. package/dist/db/migrations/v39.js +10 -21
  406. package/dist/db/migrations/v40.js +8 -14
  407. package/dist/db/migrations/v41.js +2 -24
  408. package/dist/db/migrations/v43.js +7 -6
  409. package/dist/db/migrations/v44.js +2 -8
  410. package/dist/db/migrations/v45.js +2 -7
  411. package/dist/db/migrations/v46.js +1 -1
  412. package/dist/db/migrations/v47.js +2 -3
  413. package/dist/db/migrations/v48.js +1 -1
  414. package/dist/db/migrations/v49.js +1 -1
  415. package/dist/db/migrations/v50.js +8 -7
  416. package/dist/db/migrations/v51.js +1 -1
  417. package/dist/db/migrations/v52.js +1 -1
  418. package/dist/db/open.d.ts +11 -1
  419. package/dist/db/open.js +37 -4
  420. package/dist/db/physics-state.d.ts +23 -0
  421. package/dist/{physics-state.js → db/physics-state.js} +34 -52
  422. package/dist/db/raw-archive-mirror-cleanup.d.ts +5 -0
  423. package/dist/{raw-archive-mirror-cleanup.js → db/raw-archive-mirror-cleanup.js} +10 -20
  424. package/dist/db/request-stores.d.ts +15 -2
  425. package/dist/db/request-stores.js +37 -15
  426. package/dist/db/tables.d.ts +2 -0
  427. package/dist/db/tables.js +6 -0
  428. package/dist/{vector-store.d.ts → db/vector-store.d.ts} +6 -2
  429. package/dist/{vector-store.js → db/vector-store.js} +83 -51
  430. package/dist/db/wal-checkpointer.d.ts +11 -0
  431. package/dist/db/wal-checkpointer.js +92 -0
  432. package/dist/doctor.js +176 -152
  433. package/dist/entry/json-hooks.d.ts +1 -1
  434. package/dist/entry/json-hooks.js +1 -1
  435. package/dist/entry/project-identity.d.ts +1 -1
  436. package/dist/entry/project-identity.js +1 -1
  437. package/dist/entry/session-text.d.ts +3 -3
  438. package/dist/entry/session-text.js +5 -4
  439. package/dist/{eval-stats.d.ts → eval/eval-stats.d.ts} +15 -53
  440. package/dist/{eval-stats.js → eval/eval-stats.js} +24 -51
  441. package/dist/{eval-suite.d.ts → eval/eval-suite.d.ts} +3 -14
  442. package/dist/{eval-suite.js → eval/eval-suite.js} +99 -57
  443. package/dist/{eval.d.ts → eval/eval.d.ts} +7 -25
  444. package/dist/{eval.js → eval/eval.js} +35 -55
  445. package/dist/{judgment.d.ts → eval/judgment.d.ts} +1 -6
  446. package/dist/{judgment.js → eval/judgment.js} +23 -20
  447. package/dist/extensions/openclaw-plugin/index.js +2 -3
  448. package/dist/graph/delta.d.ts +3 -2
  449. package/dist/graph/delta.js +9 -23
  450. package/dist/{graph-extract.d.ts → graph/extract.d.ts} +10 -32
  451. package/dist/{graph-extract.js → graph/extract.js} +40 -81
  452. package/dist/{graph-recall.d.ts → graph/recall.d.ts} +9 -22
  453. package/dist/{graph-recall.js → graph/recall.js} +65 -108
  454. package/dist/graph/stream.d.ts +38 -0
  455. package/dist/{graph-stream.js → graph/stream.js} +20 -41
  456. package/dist/graph/view.d.ts +50 -0
  457. package/dist/graph/view.js +265 -0
  458. package/dist/graph/write.d.ts +4 -76
  459. package/dist/graph/write.js +13 -397
  460. package/dist/hooks/codex-session.js +1 -1
  461. package/dist/hooks/codex-wrapper.js +16 -17
  462. package/dist/hooks/copilot.d.ts +1 -8
  463. package/dist/hooks/copilot.js +16 -16
  464. package/dist/{cli → hooks}/hook-blocks.d.ts +6 -2
  465. package/dist/{cli → hooks}/hook-blocks.js +38 -125
  466. package/dist/hooks/json-hooks.d.ts +5 -37
  467. package/dist/hooks/json-hooks.js +49 -179
  468. package/dist/hooks/opencode.d.ts +0 -38
  469. package/dist/hooks/opencode.js +44 -103
  470. package/dist/hooks/shared.d.ts +8 -21
  471. package/dist/hooks/shared.js +30 -25
  472. package/dist/importers/core.d.ts +13 -42
  473. package/dist/importers/core.js +48 -64
  474. package/dist/importers/markdown-parse.d.ts +9 -32
  475. package/dist/importers/markdown-parse.js +10 -44
  476. package/dist/importers/markdown.js +5 -13
  477. package/dist/importers/sources.js +57 -81
  478. package/dist/importers/vault.d.ts +2 -8
  479. package/dist/importers/vault.js +95 -172
  480. package/dist/index.d.ts +26 -22
  481. package/dist/index.js +25 -21
  482. package/dist/learn/autolearn.d.ts +29 -0
  483. package/dist/{autolearn.js → learn/autolearn.js} +26 -51
  484. package/dist/{churn-git.d.ts → learn/churn-git.d.ts} +1 -1
  485. package/dist/{churn-git.js → learn/churn-git.js} +6 -4
  486. package/dist/{extract.d.ts → learn/extract.d.ts} +1 -1
  487. package/dist/learn/extract.js +123 -0
  488. package/dist/learn/forward-claim-detector.d.ts +12 -0
  489. package/dist/learn/forward-claim-detector.js +60 -0
  490. package/dist/{invalidation.d.ts → learn/invalidation.d.ts} +10 -18
  491. package/dist/{invalidation.js → learn/invalidation.js} +92 -125
  492. package/dist/mcp/admin-tools.d.ts +1 -1
  493. package/dist/mcp/admin-tools.js +39 -64
  494. package/dist/mcp/format.d.ts +5 -5
  495. package/dist/mcp/format.js +7 -6
  496. package/dist/mcp/framing.d.ts +6 -0
  497. package/dist/mcp/framing.js +11 -3
  498. package/dist/mcp/memory-tools.js +10 -35
  499. package/dist/mcp/protocol.d.ts +14 -36
  500. package/dist/mcp/protocol.js +10 -19
  501. package/dist/mcp/recall-tools.d.ts +2 -2
  502. package/dist/mcp/recall-tools.js +70 -52
  503. package/dist/mcp/request.d.ts +3 -11
  504. package/dist/mcp/request.js +71 -85
  505. package/dist/mcp/server.d.ts +3 -9
  506. package/dist/mcp/server.js +6 -17
  507. package/dist/mcp/session-state.d.ts +2 -3
  508. package/dist/mcp/session-state.js +7 -13
  509. package/dist/mcp/shared-gate.js +1 -1
  510. package/dist/mcp/stdio.d.ts +2 -6
  511. package/dist/mcp/stdio.js +112 -38
  512. package/dist/mcp/tool-args.js +2 -1
  513. package/dist/mcp/tools.js +7 -5
  514. package/dist/objects/customer-notes.d.ts +44 -0
  515. package/dist/objects/customer-notes.js +71 -0
  516. package/dist/objects/decisions.d.ts +41 -0
  517. package/dist/objects/decisions.js +63 -0
  518. package/dist/objects/descriptor.d.ts +52 -0
  519. package/dist/objects/descriptor.js +4 -0
  520. package/dist/objects/fields.d.ts +15 -0
  521. package/dist/objects/fields.js +21 -0
  522. package/dist/objects/incidents.d.ts +45 -0
  523. package/dist/objects/incidents.js +96 -0
  524. package/dist/objects/lifecycle.d.ts +27 -0
  525. package/dist/objects/lifecycle.js +96 -0
  526. package/dist/objects/policies.d.ts +60 -0
  527. package/dist/objects/policies.js +102 -0
  528. package/dist/objects/processes.d.ts +43 -0
  529. package/dist/objects/processes.js +92 -0
  530. package/dist/objects/project-briefs.d.ts +63 -0
  531. package/dist/objects/project-briefs.js +194 -0
  532. package/dist/objects/skills.d.ts +51 -0
  533. package/dist/objects/skills.js +110 -0
  534. package/dist/postinstall.js +10 -21
  535. package/dist/predictions/planning-fallacy.d.ts +14 -109
  536. package/dist/predictions/planning-fallacy.js +4 -129
  537. package/dist/rerankers/clef.d.ts +2 -6
  538. package/dist/rerankers/clef.js +28 -76
  539. package/dist/rerankers/cross-encoder.d.ts +0 -7
  540. package/dist/rerankers/cross-encoder.js +18 -28
  541. package/dist/rerankers/index.js +8 -7
  542. package/dist/rerankers/jev.d.ts +1 -4
  543. package/dist/rerankers/jev.js +36 -52
  544. package/dist/rerankers/llm.d.ts +2 -13
  545. package/dist/rerankers/llm.js +42 -59
  546. package/dist/rerankers/outage-warning.d.ts +8 -0
  547. package/dist/rerankers/outage-warning.js +32 -0
  548. package/dist/rerankers/remote.d.ts +4 -0
  549. package/dist/rerankers/remote.js +25 -0
  550. package/dist/rerankers/types.d.ts +3 -15
  551. package/dist/search/as-of.d.ts +1 -1
  552. package/dist/search/bm25-search.d.ts +2 -2
  553. package/dist/search/bm25-search.js +7 -7
  554. package/dist/search/bm25.d.ts +1 -1
  555. package/dist/search/bm25.js +1 -1
  556. package/dist/search/boosts.d.ts +5 -3
  557. package/dist/search/boosts.js +36 -15
  558. package/dist/search/breakdown.d.ts +2 -2
  559. package/dist/search/breakdown.js +2 -1
  560. package/dist/search/explain.d.ts +1 -1
  561. package/dist/search/explain.js +3 -2
  562. package/dist/search/finalize.d.ts +2 -2
  563. package/dist/search/finalize.js +4 -3
  564. package/dist/search/fusion.d.ts +1 -1
  565. package/dist/search/fusion.js +3 -3
  566. package/dist/search/goal-boost.d.ts +23 -0
  567. package/dist/search/goal-boost.js +90 -0
  568. package/dist/search/hybrid-score.d.ts +2 -2
  569. package/dist/search/hybrid-score.js +1 -1
  570. package/dist/search/hybrid.d.ts +6 -4
  571. package/dist/search/hybrid.js +11 -8
  572. package/dist/{multihop.d.ts → search/multihop.d.ts} +2 -2
  573. package/dist/{multihop.js → search/multihop.js} +9 -8
  574. package/dist/search/path-context.d.ts +11 -0
  575. package/dist/{path-context.js → search/path-context.js} +8 -19
  576. package/dist/search/physics-search.d.ts +4 -4
  577. package/dist/search/physics-search.js +25 -22
  578. package/dist/search/rerank.d.ts +3 -3
  579. package/dist/search/rerank.js +4 -3
  580. package/dist/search/rrf.d.ts +15 -0
  581. package/dist/search/rrf.js +36 -0
  582. package/dist/search/temporal.d.ts +1 -1
  583. package/dist/search/temporal.js +5 -2
  584. package/dist/search/vector.d.ts +10 -3
  585. package/dist/search/vector.js +51 -15
  586. package/dist/server/auth.d.ts +10 -29
  587. package/dist/server/auth.js +57 -42
  588. package/dist/server/boot.d.ts +5 -0
  589. package/dist/server/boot.js +432 -0
  590. package/dist/server/client-ip.d.ts +8 -20
  591. package/dist/server/client-ip.js +23 -34
  592. package/dist/server/cursor.d.ts +1 -1
  593. package/dist/server/cursor.js +2 -3
  594. package/dist/server/deadline.d.ts +13 -0
  595. package/dist/server/deadline.js +45 -0
  596. package/dist/server/defaults.d.ts +3 -0
  597. package/dist/server/defaults.js +4 -0
  598. package/dist/server/key-check-bounds.d.ts +9 -0
  599. package/dist/server/key-check-bounds.js +46 -0
  600. package/dist/server/lifecycle.d.ts +5 -4
  601. package/dist/server/lifecycle.js +20 -5
  602. package/dist/server/mcp-http.d.ts +1 -4
  603. package/dist/server/mcp-http.js +44 -68
  604. package/dist/server/rate-limit.d.ts +21 -0
  605. package/dist/{rate-limit.js → server/rate-limit.js} +4 -13
  606. package/dist/server/ready.d.ts +7 -0
  607. package/dist/server/ready.js +38 -0
  608. package/dist/server/request.d.ts +14 -12
  609. package/dist/server/request.js +71 -28
  610. package/dist/server/route-table.d.ts +15 -0
  611. package/dist/server/route-table.js +202 -0
  612. package/dist/server/routes/admin.js +29 -30
  613. package/dist/server/routes/customer-notes.d.ts +5 -5
  614. package/dist/server/routes/customer-notes.js +35 -105
  615. package/dist/server/routes/decisions.d.ts +5 -5
  616. package/dist/server/routes/decisions.js +45 -115
  617. package/dist/server/routes/incidents.d.ts +5 -5
  618. package/dist/server/routes/incidents.js +44 -105
  619. package/dist/server/routes/memories.js +21 -43
  620. package/dist/server/routes/object-routes.d.ts +35 -0
  621. package/dist/server/routes/object-routes.js +72 -0
  622. package/dist/server/routes/policies.d.ts +6 -6
  623. package/dist/server/routes/policies.js +42 -134
  624. package/dist/server/routes/predictions.js +35 -63
  625. package/dist/server/routes/processes.d.ts +5 -5
  626. package/dist/server/routes/processes.js +44 -134
  627. package/dist/server/routes/project-briefs.d.ts +6 -6
  628. package/dist/server/routes/project-briefs.js +41 -120
  629. package/dist/server/routes/recall.js +21 -44
  630. package/dist/server/routes/skills.d.ts +6 -6
  631. package/dist/server/routes/skills.js +40 -138
  632. package/dist/server/server-detect.d.ts +28 -0
  633. package/dist/server/server-detect.js +156 -0
  634. package/dist/server/sleep-child.d.ts +2 -0
  635. package/dist/server/sleep-child.js +19 -0
  636. package/dist/server/sleep-offload.d.ts +20 -0
  637. package/dist/server/sleep-offload.js +73 -0
  638. package/dist/server/tls.d.ts +6 -0
  639. package/dist/server/tls.js +24 -0
  640. package/dist/server/types.d.ts +35 -14
  641. package/dist/server/validation.d.ts +6 -5
  642. package/dist/server/validation.js +16 -34
  643. package/dist/server.d.ts +39 -61
  644. package/dist/server.js +26 -569
  645. package/dist/sharing/global-store.d.ts +19 -0
  646. package/dist/sharing/global-store.js +75 -0
  647. package/dist/sharing/global-sync.d.ts +6 -0
  648. package/dist/sharing/global-sync.js +80 -0
  649. package/dist/{project-merge.d.ts → sharing/project-merge.d.ts} +5 -6
  650. package/dist/{project-merge.js → sharing/project-merge.js} +34 -51
  651. package/dist/sharing/scope.d.ts +7 -0
  652. package/dist/{scope.js → sharing/scope.js} +5 -12
  653. package/dist/sharing/search-both.d.ts +60 -0
  654. package/dist/sharing/search-both.js +138 -0
  655. package/dist/sharing/share.d.ts +38 -0
  656. package/dist/sharing/share.js +226 -0
  657. package/dist/{ambient-store.d.ts → store/ambient.d.ts} +2 -2
  658. package/dist/{ambient-store.js → store/ambient.js} +11 -16
  659. package/dist/store/audit-event.d.ts +15 -17
  660. package/dist/store/audit-event.js +9 -16
  661. package/dist/{audit.d.ts → store/audit.d.ts} +29 -8
  662. package/dist/{audit.js → store/audit.js} +95 -18
  663. package/dist/{auth.d.ts → store/auth.d.ts} +19 -36
  664. package/dist/{auth.js → store/auth.js} +108 -99
  665. package/dist/store/candidates.d.ts +41 -13
  666. package/dist/store/candidates.js +141 -60
  667. package/dist/{card-detail.d.ts → store/card-detail.d.ts} +5 -4
  668. package/dist/{card-detail.js → store/card-detail.js} +3 -2
  669. package/dist/{store-cards.d.ts → store/cards.d.ts} +26 -16
  670. package/dist/{store-cards.js → store/cards.js} +133 -248
  671. package/dist/store/compactions.d.ts +78 -0
  672. package/dist/store/compactions.js +93 -0
  673. package/dist/store/conflicts.d.ts +26 -26
  674. package/dist/store/conflicts.js +194 -222
  675. package/dist/store/connectors/github.d.ts +84 -0
  676. package/dist/store/connectors/github.js +180 -0
  677. package/dist/store/connectors/slack.d.ts +69 -0
  678. package/dist/store/connectors/slack.js +177 -0
  679. package/dist/store/dashboard-reads.d.ts +27 -0
  680. package/dist/store/dashboard-reads.js +88 -0
  681. package/dist/store/delete-and-batch.d.ts +27 -51
  682. package/dist/store/delete-and-batch.js +100 -92
  683. package/dist/{delivery-recorder.d.ts → store/delivery-recorder.d.ts} +16 -5
  684. package/dist/{delivery-recorder.js → store/delivery-recorder.js} +60 -38
  685. package/dist/store/descendant-page.d.ts +12 -0
  686. package/dist/store/descendant-page.js +99 -0
  687. package/dist/store/diagnostics.d.ts +47 -0
  688. package/dist/store/diagnostics.js +44 -0
  689. package/dist/store/doctor-reads.d.ts +16 -0
  690. package/dist/store/doctor-reads.js +19 -0
  691. package/dist/store/dormant.d.ts +105 -0
  692. package/dist/store/dormant.js +241 -0
  693. package/dist/store/embeddings/index.d.ts +36 -0
  694. package/dist/{embeddings.js → store/embeddings/index.js} +104 -224
  695. package/dist/{local-embedding.d.ts → store/embeddings/local.d.ts} +1 -1
  696. package/dist/{local-embedding.js → store/embeddings/local.js} +69 -75
  697. package/dist/store/embeddings/provider.d.ts +40 -0
  698. package/dist/{embedding-provider.js → store/embeddings/provider.js} +78 -91
  699. package/dist/store/entry-reads.d.ts +66 -63
  700. package/dist/store/entry-reads.js +159 -121
  701. package/dist/store/entry-row.d.ts +14 -37
  702. package/dist/store/entry-row.js +37 -45
  703. package/dist/store/entry-writes.d.ts +40 -17
  704. package/dist/store/entry-writes.js +105 -41
  705. package/dist/{failure-log.d.ts → store/failure-log.d.ts} +7 -2
  706. package/dist/{failure-log.js → store/failure-log.js} +9 -2
  707. package/dist/store/goals.d.ts +96 -0
  708. package/dist/store/goals.js +260 -0
  709. package/dist/store/graph-queue.d.ts +13 -0
  710. package/dist/store/graph-queue.js +70 -0
  711. package/dist/store/graph-reads.d.ts +41 -0
  712. package/dist/{graph/read.js → store/graph-reads.js} +72 -162
  713. package/dist/{graph/types.d.ts → store/graph-rows.d.ts} +71 -14
  714. package/dist/{graph/rows.js → store/graph-rows.js} +20 -12
  715. package/dist/store/graph-view-rows.d.ts +13 -0
  716. package/dist/store/graph-view-rows.js +68 -0
  717. package/dist/store/graph-writes.d.ts +33 -0
  718. package/dist/store/graph-writes.js +232 -0
  719. package/dist/store/half-life.d.ts +35 -0
  720. package/dist/store/half-life.js +75 -0
  721. package/dist/store/handoffs.d.ts +6 -12
  722. package/dist/store/handoffs.js +54 -63
  723. package/dist/store/index-and-stats.d.ts +14 -20
  724. package/dist/store/index-and-stats.js +74 -119
  725. package/dist/store/index.d.ts +4 -0
  726. package/dist/store/index.js +3 -0
  727. package/dist/store/key-audit.d.ts +2 -2
  728. package/dist/store/key-audit.js +4 -4
  729. package/dist/store/key-writes.d.ts +12 -5
  730. package/dist/store/key-writes.js +30 -4
  731. package/dist/store/ledger-turn.d.ts +17 -0
  732. package/dist/store/ledger-turn.js +27 -0
  733. package/dist/store/markdown.d.ts +3 -7
  734. package/dist/store/markdown.js +25 -23
  735. package/dist/store/mirrors.d.ts +7 -13
  736. package/dist/store/mirrors.js +52 -47
  737. package/dist/store/object-types.d.ts +189 -0
  738. package/dist/store/object-types.js +4 -0
  739. package/dist/store/open.d.ts +6 -4
  740. package/dist/store/open.js +30 -36
  741. package/dist/store/planning-fallacy-evidence.d.ts +14 -0
  742. package/dist/store/planning-fallacy-evidence.js +52 -0
  743. package/dist/store/port.d.ts +649 -0
  744. package/dist/store/port.js +17 -0
  745. package/dist/{predictions/store.d.ts → store/predictions.d.ts} +25 -52
  746. package/dist/{predictions/store.js → store/predictions.js} +88 -184
  747. package/dist/{quality-repair.js → store/quality-repair.js} +27 -57
  748. package/dist/{quarantine.d.ts → store/quarantine.d.ts} +8 -8
  749. package/dist/{quarantine.js → store/quarantine.js} +64 -22
  750. package/dist/store/raw-archive.d.ts +14 -0
  751. package/dist/{raw-archive.js → store/raw-archive.js} +20 -31
  752. package/dist/store/recall-scope.d.ts +78 -0
  753. package/dist/{recall-scope.js → store/recall-scope.js} +23 -84
  754. package/dist/{recall-trace.d.ts → store/recall-trace.d.ts} +13 -81
  755. package/dist/{recall-trace.js → store/recall-trace.js} +41 -122
  756. package/dist/store/rejected-values.d.ts +55 -0
  757. package/dist/store/rejected-values.js +150 -0
  758. package/dist/store/rejection.d.ts +54 -0
  759. package/dist/{rejection.js → store/rejection.js} +16 -67
  760. package/dist/store/report-reads.d.ts +6 -0
  761. package/dist/store/report-reads.js +29 -0
  762. package/dist/store/rows.d.ts +11 -22
  763. package/dist/store/rows.js +52 -43
  764. package/dist/store/rule-sql.d.ts +5 -0
  765. package/dist/store/rule-sql.js +37 -0
  766. package/dist/store/search-rows.d.ts +22 -42
  767. package/dist/store/search-rows.js +55 -78
  768. package/dist/store/sessions.d.ts +23 -49
  769. package/dist/store/sessions.js +96 -118
  770. package/dist/store/sqlite/commit-watch.d.ts +4 -0
  771. package/dist/store/sqlite/commit-watch.js +29 -0
  772. package/dist/store/sqlite/connector-events-group.d.ts +5 -0
  773. package/dist/store/sqlite/connector-events-group.js +50 -0
  774. package/dist/store/sqlite/connector-writes-group.d.ts +6 -0
  775. package/dist/store/sqlite/connector-writes-group.js +65 -0
  776. package/dist/store/sqlite/dag-reads-group.d.ts +3 -0
  777. package/dist/store/sqlite/dag-reads-group.js +45 -0
  778. package/dist/store/sqlite/entry-writes-group.d.ts +18 -0
  779. package/dist/store/{entry-writes-group.js → sqlite/entry-writes-group.js} +73 -60
  780. package/dist/store/sqlite/error-codec.d.ts +17 -0
  781. package/dist/store/sqlite/error-codec.js +61 -0
  782. package/dist/store/sqlite/executor-counts.d.ts +10 -0
  783. package/dist/store/sqlite/executor-counts.js +11 -0
  784. package/dist/store/sqlite/executor.d.ts +29 -0
  785. package/dist/store/sqlite/executor.js +287 -0
  786. package/dist/store/sqlite/graph-reads-group.d.ts +5 -0
  787. package/dist/store/sqlite/graph-reads-group.js +18 -0
  788. package/dist/store/sqlite/local.d.ts +21 -0
  789. package/dist/store/sqlite/local.js +39 -0
  790. package/dist/store/sqlite/object-rows.d.ts +102 -0
  791. package/dist/store/sqlite/object-rows.js +221 -0
  792. package/dist/store/sqlite/objects-group.d.ts +20 -0
  793. package/dist/store/sqlite/objects-group.js +316 -0
  794. package/dist/store/sqlite/predictions-group.d.ts +5 -0
  795. package/dist/store/sqlite/predictions-group.js +28 -0
  796. package/dist/store/sqlite/quarantine-group.d.ts +5 -0
  797. package/dist/store/sqlite/quarantine-group.js +38 -0
  798. package/dist/store/sqlite/store.d.ts +23 -0
  799. package/dist/store/sqlite/store.js +294 -0
  800. package/dist/store/sqlite/vector-pack.d.ts +18 -0
  801. package/dist/store/sqlite/vector-pack.js +46 -0
  802. package/dist/store/sqlite/vector-reads-group.d.ts +3 -0
  803. package/dist/store/sqlite/vector-reads-group.js +23 -0
  804. package/dist/store/sqlite/worker-entry.d.ts +2 -0
  805. package/dist/store/sqlite/worker-entry.js +8 -0
  806. package/dist/store/sqlite/worker-jobs.d.ts +5 -0
  807. package/dist/store/sqlite/worker-jobs.js +116 -0
  808. package/dist/store/sqlite/worker-ops.d.ts +135 -0
  809. package/dist/store/sqlite/worker-ops.js +93 -0
  810. package/dist/store/sqlite/worker-store.d.ts +8 -0
  811. package/dist/store/sqlite/worker-store.js +79 -0
  812. package/dist/store/summaries.d.ts +11 -72
  813. package/dist/store/summaries.js +47 -186
  814. package/dist/{summary-dirty.d.ts → store/summary-dirty.d.ts} +1 -1
  815. package/dist/{summary-dirty.js → store/summary-dirty.js} +1 -1
  816. package/dist/store/tenant-lookup.d.ts +6 -1
  817. package/dist/store/tenant-lookup.js +7 -0
  818. package/dist/store/tenant.d.ts +11 -0
  819. package/dist/store/tenant.js +28 -0
  820. package/dist/store/token-ledger-rows.d.ts +61 -0
  821. package/dist/store/token-ledger-rows.js +68 -0
  822. package/dist/{token-ledger.d.ts → store/token-ledger.d.ts} +14 -51
  823. package/dist/{token-ledger.js → store/token-ledger.js} +51 -129
  824. package/dist/store/tombstone-checks.d.ts +12 -0
  825. package/dist/store/tombstone-checks.js +31 -0
  826. package/dist/store/usage-reports.d.ts +7 -0
  827. package/dist/store/usage-reports.js +18 -0
  828. package/dist/store/vector-index.d.ts +46 -0
  829. package/dist/store/vector-index.js +170 -0
  830. package/dist/{working-memory.d.ts → store/working-memory.d.ts} +11 -26
  831. package/dist/store/working-memory.js +118 -0
  832. package/dist/{yaml.d.ts → store/yaml.d.ts} +1 -5
  833. package/dist/{yaml.js → store/yaml.js} +2 -6
  834. package/dist/support-bundle.d.ts +1 -1
  835. package/dist/support-bundle.js +19 -37
  836. package/dist/{gated-write.d.ts → trust/gated-write.d.ts} +2 -2
  837. package/dist/{gated-write.js → trust/gated-write.js} +6 -6
  838. package/dist/trust/quarantine.d.ts +4 -0
  839. package/dist/trust/quarantine.js +8 -0
  840. package/dist/trust/reject-flow.d.ts +23 -0
  841. package/dist/trust/reject-flow.js +65 -0
  842. package/dist/util/anthropic-messages.d.ts +31 -0
  843. package/dist/util/anthropic-messages.js +58 -0
  844. package/dist/util/atomic-write.d.ts +4 -0
  845. package/dist/util/atomic-write.js +138 -0
  846. package/dist/util/capped-json.d.ts +6 -0
  847. package/dist/util/capped-json.js +46 -0
  848. package/dist/util/crash-handlers.d.ts +12 -0
  849. package/dist/util/crash-handlers.js +72 -0
  850. package/dist/{env.d.ts → util/env.d.ts} +27 -7
  851. package/dist/{env.js → util/env.js} +33 -8
  852. package/dist/{home-path.d.ts → util/home-path.d.ts} +2 -1
  853. package/dist/util/home-path.js +69 -0
  854. package/dist/{http-retry.d.ts → util/http-retry.d.ts} +8 -2
  855. package/dist/util/http-retry.js +103 -0
  856. package/dist/{http-util.d.ts → util/http-util.d.ts} +14 -3
  857. package/dist/{http-util.js → util/http-util.js} +31 -11
  858. package/dist/util/json.d.ts +17 -0
  859. package/dist/util/json.js +25 -0
  860. package/dist/{log.d.ts → util/log.d.ts} +7 -3
  861. package/dist/{log.js → util/log.js} +36 -11
  862. package/dist/util/real-path.d.ts +3 -0
  863. package/dist/util/real-path.js +15 -0
  864. package/dist/util/request-scope.d.ts +28 -0
  865. package/dist/util/request-scope.js +48 -0
  866. package/dist/{same-text.d.ts → util/same-text.d.ts} +1 -1
  867. package/dist/{secret-detect.d.ts → util/secret-detect.d.ts} +5 -30
  868. package/dist/{secret-detect.js → util/secret-detect.js} +17 -42
  869. package/dist/util/stored-json.d.ts +9 -0
  870. package/dist/util/stored-json.js +8 -0
  871. package/dist/util/time.d.ts +2 -0
  872. package/dist/util/time.js +3 -0
  873. package/dist/util/token-text.d.ts +15 -0
  874. package/dist/util/token-text.js +20 -0
  875. package/dist/{transcript-tail.d.ts → util/transcript-tail.d.ts} +2 -0
  876. package/dist/util/transcript-tail.js +49 -0
  877. package/dist/util/version.d.ts +11 -0
  878. package/dist/util/version.js +26 -0
  879. package/extensions/openclaw-plugin/index.ts +2 -6
  880. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  881. package/extensions/openclaw-plugin/package.json +1 -1
  882. package/openclaw.plugin.json +1 -1
  883. package/package.json +2 -2
  884. package/dist/ablation.d.ts +0 -102
  885. package/dist/ablation.js +0 -136
  886. package/dist/api.d.ts +0 -26
  887. package/dist/api.js +0 -29
  888. package/dist/audit-prune.d.ts +0 -62
  889. package/dist/audit-prune.js +0 -107
  890. package/dist/autolearn.d.ts +0 -56
  891. package/dist/client.d.ts +0 -48
  892. package/dist/compare.d.ts +0 -86
  893. package/dist/compare.js +0 -117
  894. package/dist/connectors/github/cli-impl.d.ts +0 -25
  895. package/dist/connectors/github/cli-impl.js +0 -227
  896. package/dist/connectors/github/idempotency.d.ts +0 -19
  897. package/dist/connectors/github/idempotency.js +0 -27
  898. package/dist/connectors/slack/idempotency.d.ts +0 -17
  899. package/dist/connectors/slack/idempotency.js +0 -31
  900. package/dist/correction-latency.d.ts +0 -36
  901. package/dist/customer-notes.d.ts +0 -96
  902. package/dist/customer-notes.js +0 -336
  903. package/dist/db.d.ts +0 -9
  904. package/dist/db.js +0 -8
  905. package/dist/decisions.d.ts +0 -94
  906. package/dist/decisions.js +0 -326
  907. package/dist/dedupe.d.ts +0 -75
  908. package/dist/dedupe.js +0 -169
  909. package/dist/dormant.d.ts +0 -93
  910. package/dist/dormant.js +0 -137
  911. package/dist/embedding-provider.d.ts +0 -77
  912. package/dist/embeddings.d.ts +0 -101
  913. package/dist/extract.js +0 -133
  914. package/dist/forward-claim-detector.d.ts +0 -36
  915. package/dist/forward-claim-detector.js +0 -112
  916. package/dist/goals.d.ts +0 -173
  917. package/dist/goals.js +0 -448
  918. package/dist/graph/read.d.ts +0 -73
  919. package/dist/graph/rows.d.ts +0 -45
  920. package/dist/graph/types.js +0 -11
  921. package/dist/graph-stream.d.ts +0 -70
  922. package/dist/graph-view.d.ts +0 -73
  923. package/dist/graph-view.js +0 -333
  924. package/dist/half-life-migration.d.ts +0 -63
  925. package/dist/half-life-migration.js +0 -182
  926. package/dist/handoff.js +0 -68
  927. package/dist/home-path.js +0 -24
  928. package/dist/http-retry.js +0 -51
  929. package/dist/incidents.d.ts +0 -103
  930. package/dist/incidents.js +0 -349
  931. package/dist/instruction-detect.js +0 -27
  932. package/dist/json.d.ts +0 -7
  933. package/dist/json.js +0 -11
  934. package/dist/ledger-db.d.ts +0 -10
  935. package/dist/ledger-db.js +0 -42
  936. package/dist/memory-value-weights.d.ts +0 -19
  937. package/dist/memory-value.d.ts +0 -113
  938. package/dist/memory-value.js +0 -250
  939. package/dist/memory.d.ts +0 -294
  940. package/dist/memory.js +0 -522
  941. package/dist/owner-validation.d.ts +0 -42
  942. package/dist/owner-validation.js +0 -56
  943. package/dist/path-context.d.ts +0 -24
  944. package/dist/physics-state.d.ts +0 -39
  945. package/dist/policies.d.ts +0 -151
  946. package/dist/policies.js +0 -434
  947. package/dist/processes.d.ts +0 -108
  948. package/dist/processes.js +0 -371
  949. package/dist/project-briefs.d.ts +0 -128
  950. package/dist/project-briefs.js +0 -523
  951. package/dist/provenance-coverage.d.ts +0 -18
  952. package/dist/rate-limit.d.ts +0 -34
  953. package/dist/raw-archive-mirror-cleanup.d.ts +0 -20
  954. package/dist/raw-archive.d.ts +0 -24
  955. package/dist/recall-history.d.ts +0 -131
  956. package/dist/recall-history.js +0 -227
  957. package/dist/recall-scope.d.ts +0 -138
  958. package/dist/refine-llm.d.ts +0 -61
  959. package/dist/refine-llm.js +0 -167
  960. package/dist/reject-flow.d.ts +0 -69
  961. package/dist/reject-flow.js +0 -260
  962. package/dist/rejection.d.ts +0 -100
  963. package/dist/replay.d.ts +0 -41
  964. package/dist/replay.js +0 -122
  965. package/dist/rrf.d.ts +0 -43
  966. package/dist/rrf.js +0 -61
  967. package/dist/scope.d.ts +0 -14
  968. package/dist/server-detect.d.ts +0 -72
  969. package/dist/server-detect.js +0 -222
  970. package/dist/session-owners.d.ts +0 -7
  971. package/dist/session-owners.js +0 -54
  972. package/dist/shared.d.ts +0 -186
  973. package/dist/shared.js +0 -540
  974. package/dist/skills.d.ts +0 -101
  975. package/dist/skills.js +0 -367
  976. package/dist/store/entry-writes-group.d.ts +0 -9
  977. package/dist/store/vector-writes.d.ts +0 -6
  978. package/dist/store/vector-writes.js +0 -59
  979. package/dist/store-port.d.ts +0 -262
  980. package/dist/store-port.js +0 -178
  981. package/dist/tenant.d.ts +0 -25
  982. package/dist/tenant.js +0 -43
  983. package/dist/trace.d.ts +0 -34
  984. package/dist/transcript-tail.js +0 -48
  985. package/dist/version.d.ts +0 -26
  986. package/dist/version.js +0 -41
  987. package/dist/working-memory.js +0 -154
  988. /package/dist/{context-auto.d.ts → api/context-auto.d.ts} +0 -0
  989. /package/dist/{instruction-detect.d.ts → api/instruction-detect.d.ts} +0 -0
  990. /package/dist/{codex-patch.d.ts → capture/codex-patch.d.ts} +0 -0
  991. /package/dist/{compaction-items.d.ts → capture/compaction-items.d.ts} +0 -0
  992. /package/dist/{share-scrub.d.ts → capture/share-scrub.d.ts} +0 -0
  993. /package/dist/{overlap-index.d.ts → consolidate/overlap-index.d.ts} +0 -0
  994. /package/dist/{overlap-index.js → consolidate/overlap-index.js} +0 -0
  995. /package/dist/{api-errors.d.ts → core/api-errors.d.ts} +0 -0
  996. /package/dist/{api-errors.js → core/api-errors.js} +0 -0
  997. /package/dist/{memory-quality.d.ts → core/memory-quality.d.ts} +0 -0
  998. /package/dist/{project-remote.d.ts → core/project-remote.d.ts} +0 -0
  999. /package/dist/{prompt-recall.d.ts → core/prompt-recall.d.ts} +0 -0
  1000. /package/dist/{dashboard-params.d.ts → dashboard/dashboard-params.d.ts} +0 -0
  1001. /package/dist/{dashboard-params.js → dashboard/dashboard-params.js} +0 -0
  1002. /package/dist/{dashboard-types.js → dashboard/dashboard-types.js} +0 -0
  1003. /package/dist/{quality-repair.d.ts → store/quality-repair.d.ts} +0 -0
  1004. /package/dist/{escape.d.ts → util/escape.d.ts} +0 -0
  1005. /package/dist/{escape.js → util/escape.js} +0 -0
  1006. /package/dist/{keyset.d.ts → util/keyset.d.ts} +0 -0
  1007. /package/dist/{keyset.js → util/keyset.js} +0 -0
  1008. /package/dist/{same-text.js → util/same-text.js} +0 -0
  1009. /package/dist/{db → util}/sqlite-blocked.d.ts +0 -0
  1010. /package/dist/{db → util}/sqlite-blocked.js +0 -0
  1011. /package/dist/{tokenize.d.ts → util/tokenize.d.ts} +0 -0
  1012. /package/dist/{tokenize.js → util/tokenize.js} +0 -0
  1013. /package/dist/{write-budget.d.ts → util/write-budget.d.ts} +0 -0
  1014. /package/dist/{write-budget.js → util/write-budget.js} +0 -0
@@ -8,103 +8,70 @@ import { resolveJsonHookPaths } from '../hooks/json-hooks.js';
8
8
  import { isInitialized } from '../store/open.js';
9
9
  import { loadActiveTaskSnapshot, loadFreshActiveTaskSnapshot, closeTaskSnapshotsForSession, listSessionEvents, } from '../store/sessions.js';
10
10
  import { writeSessionEndHandoff } from '../store/handoffs.js';
11
- import { readSessionScan, recordSessionDigest } from '../session-digest.js';
12
- import { openHippoDb, closeHippoDb } from '../db.js';
13
- import { captureToolFailure } from '../capture-error.js';
14
- import { estimateTokens, isSubagentPayload, readApiCalls, recordRereads, recordTokenUse, } from '../token-ledger.js';
11
+ import { readSessionScan, recordSessionDigest } from '../capture/session-digest.js';
12
+ import { captureToolFailure } from '../capture/capture-error.js';
13
+ import { readApiCalls, recordRereads, } from '../store/token-ledger.js';
14
+ import { estimateTokens } from '../util/token-text.js';
15
15
  import { currentMachine, importSessionFolder } from '../agent-memories/sync.js';
16
16
  import { summaryLine } from '../agent-memories/report.js';
17
- import { resolveProjectIdentity } from '../project-identity.js';
18
- import { getGlobalRoot } from '../shared.js';
17
+ import { resolveProjectIdentity } from '../core/project-identity.js';
18
+ import { getGlobalRoot } from '../sharing/global-store.js';
19
19
  import { cmdCapture } from '../capture/command.js';
20
20
  import { cmdPreCompact, cmdPostCompact } from '../capture/compact.js';
21
21
  import { transcriptWorkingState } from '../capture/working-state.js';
22
- import { collectHandoffEvidence } from '../handoff-evidence.js';
23
- import { resolveLastSessionTranscript } from '../capture/transcript.js';
22
+ import { collectHandoffEvidence } from '../capture/handoff-evidence.js';
24
23
  import { copilotTranscriptFor, SESSION_ID_RE } from '../capture/copilot-transcript.js';
25
24
  import { loadTurnPosition, runSessionWorker, saveTurnPosition, turnsAfter } from '../capture/session-worker.js';
26
- import { isStringValue, readVscodeStop } from '../capture-contract.js';
27
- import { loadConfig } from '../config.js';
28
- import { countCreatedSinceLastSleep } from '../store/index-and-stats.js';
29
- import { truncateCodePointSafe } from '../transcript-tail.js';
30
- import { COMPACTION_DB_WAIT_MS } from '../compaction-record.js';
31
- import { COMPACT_RESUME_EVENT_CONTENT_CAP, COMPACT_RESUME_MAX_AGE_MS, compactResumeText } from '../context-render.js';
32
- import { normaliseHookPayload, readHookStdin, readStdinBounded } from '../stdin.js';
33
- import { resolveTenantId } from '../tenant.js';
34
- import { errorMessage, log } from '../log.js';
35
- import { withLedgerDb } from '../ledger-db.js';
25
+ import { isStringValue, readSessionEnd, readVscodeStop } from '../core/capture-contract.js';
26
+ import { loadConfig } from '../core/config.js';
27
+ import { autoSleepDue } from '../api/auto-sleep.js';
28
+ import { truncateCodePointSafe } from '../util/transcript-tail.js';
29
+ import { COMPACTION_DB_WAIT_MS } from '../capture/compaction-record.js';
30
+ import { COMPACT_RESUME_EVENT_CONTENT_CAP, COMPACT_RESUME_MAX_AGE_MS, compactResumeText } from '../api/context-render.js';
31
+ import { normaliseHookPayload, readHookStdin, readStdinBounded } from './stdin.js';
32
+ import { errorMessage, log } from '../util/log.js';
33
+ import { bookLedgerTurn } from '../api/ledger-db.js';
34
+ import { flushDeliveryRecorder } from '../api/prompt-hook.js';
36
35
  import { printError } from './output.js';
37
36
  import { cmdLastSleep } from './last-sleep.js';
38
- import { logSessionEndImport, appendSessionEndCloseLog, resetHookInjection, hookStoreRoot, hookRuntime, payloadCwdRoot, runHookWithStores, inPilotHoldout, } from './shared.js';
39
- /**
40
- * SessionStart(compact) injector. Prints the active task snapshot + recent
41
- * session trail so working state that would otherwise be lost to
42
- * compaction summarisation survives into the new context window. No pinned
43
- * memories here — the UserPromptSubmit hook already re-injects those every
44
- * turn, so duplicating them here would double token cost for nothing.
45
- *
46
- * Same exit-0/crash-safety contract as `hippo pre-compact`: every path
47
- * exits 0. A malformed payload or a store read failure
48
- * degrades to empty stdout, never a thrown error — a failing SessionStart
49
- * hook must not pollute session startup.
50
- */
51
- function cmdCompactResume(hippoRoot, stdinText, stdinTimedOut) {
37
+ import { readCompactResumePayload } from './compact-resume-payload.js';
38
+ import { boolFlag, flagIsTrue, stringFlag } from './flag-values.js';
39
+ import { logSessionEndImport, appendSessionEndCloseLog, reportSessionEndFailure, resetHookInjection, hookStoreRoot, hookRuntime, payloadCwdRoot, runHookWithStores, inPilotHoldout, startDeliveryRecorder, } from './hook-runtime.js';
40
+ import { CliExit } from './exit.js';
41
+ /** SessionStart(compact) injector: prints the task snapshot and session trail lost to compaction; no pinned memories (UserPromptSubmit re-injects them).
42
+ * Every path exits 0: a malformed payload or store read failure degrades to empty stdout, never a throw. */
43
+ function cmdCompactResume(hippoRoot, tenantId, stdinText, stdinTimedOut) {
44
+ let rec = null;
52
45
  try {
53
46
  // Gate on the non-exiting isInitialized check first: the store reads below call initStore, which would
54
47
  // silently create a store in a project that never ran `hippo init`, and this hook fires globally.
55
48
  if (!isInitialized(hippoRoot)) {
56
- process.exit(0);
57
- }
58
- // The matcher is an optimization, not a dependency: older Claude Code
59
- // that ignores `matcher: 'compact'` would run this on every SessionStart,
60
- // so we also gate on payload.source here. A payload that parses but
61
- // carries a different source (e.g. 'startup') means the matcher-based
62
- // gate failed to apply — stay silent rather than print stale state.
63
- const nonEmptyStdin = !!stdinText && stdinText.trim() !== '';
64
- // Without a payload session_id the cross-restore guard below can
65
- // never fire, so a timed-out empty read must not reach the print path.
66
- let suppressOutput = stdinTimedOut && !nonEmptyStdin;
67
- let payloadSessionId = null;
68
- if (nonEmptyStdin) {
69
- let payload = null;
70
- try {
71
- payload = JSON.parse(stdinText.trim());
72
- }
73
- catch {
74
- // Malformed JSON is handled as a null payload by the fail-closed check below.
75
- payload = null;
76
- }
77
- if (!payload || typeof payload !== 'object') {
78
- // Fail closed on malformed non-empty stdin; only a TTY/no-stdin manual run, which never reaches here, prints.
79
- suppressOutput = true;
80
- }
81
- else {
82
- // Fail closed on structurally incomplete payloads too ({}, [], source missing/non-string): real
83
- // SessionStart payloads always carry source, so a parsed one must say 'compact' to print.
84
- // A sub-agent's payload carries its parent's session id, so the mismatch guard would pass and restore the parent's snapshot into it.
85
- if (payload.source !== 'compact' || isSubagentPayload(stdinText)) {
86
- suppressOutput = true;
87
- }
88
- if (typeof payload.session_id === 'string') {
89
- payloadSessionId = payload.session_id;
90
- }
91
- }
49
+ throw new CliExit(0);
92
50
  }
51
+ const payloadState = readCompactResumePayload(stdinText, stdinTimedOut);
52
+ let suppressOutput = payloadState.suppressOutput;
53
+ const payloadSessionId = payloadState.payloadSessionId;
54
+ if (payloadState.boundary)
55
+ rec = startDeliveryRecorder(hippoRoot, stdinText, 'claude-code', 'compact-resume');
93
56
  // A compaction follows a prompt or SessionStart that booked the arm, so this only reads it.
94
- if (!suppressOutput && payloadSessionId !== null && inPilotHoldout(hippoRoot, resolveTenantId({}), payloadSessionId, false)) {
57
+ if (!suppressOutput && payloadSessionId !== null && inPilotHoldout(hippoRoot, tenantId, payloadSessionId, false)) {
95
58
  suppressOutput = true;
59
+ rec?.disabled();
96
60
  }
97
61
  if (!suppressOutput)
98
- restoreCompactSnapshot(hippoRoot, payloadSessionId);
62
+ restoreCompactSnapshot(hippoRoot, tenantId, payloadSessionId, rec);
99
63
  }
100
64
  catch (err) {
65
+ if (err instanceof CliExit)
66
+ throw err;
101
67
  // Empty stdout on any store error, never a crashed SessionStart; the reason goes to stderr, which the model never sees.
102
- log.warn(`hippo compact-resume: skipped: ${err instanceof Error ? err.message : String(err)}`);
68
+ log.warn(`hippo compact-resume: skipped: ${errorMessage(err)}`);
103
69
  }
104
- process.exit(0);
70
+ // A no-op when the token ledger's handle already wrote the row; exit would drop it otherwise.
71
+ flushDeliveryRecorder(rec);
72
+ throw new CliExit(0);
105
73
  }
106
- function restoreCompactSnapshot(hippoRoot, payloadSessionId) {
107
- const tenantId = resolveTenantId({});
74
+ function restoreCompactSnapshot(hippoRoot, tenantId, payloadSessionId, rec) {
108
75
  const snapshot = loadFreshActiveTaskSnapshot(hippoRoot, tenantId, { maxAgeMs: COMPACT_RESUME_MAX_AGE_MS });
109
76
  // Concurrent sessions must not cross-restore. Only suppress when BOTH ids are present and differ;
110
77
  // either side missing, or a manual invocation with no payload session_id, still prints.
@@ -125,101 +92,115 @@ function restoreCompactSnapshot(hippoRoot, payloadSessionId) {
125
92
  }
126
93
  }
127
94
  catch (err) {
128
- log.warn(`hippo compact-resume: trail skipped: ${err instanceof Error ? err.message : String(err)}`);
95
+ log.warn(`hippo compact-resume: trail skipped: ${errorMessage(err)}`);
129
96
  }
130
97
  // Printed in one write so the ledger books exactly the text the model is handed.
131
98
  const text = compactResumeText(snapshot, events);
132
99
  console.log(text);
133
- withLedgerDb(hippoRoot, (db) => recordTokenUse(db, {
134
- tenantId, sessionId: payloadSessionId, surface: 'compact_resume', event: 'inject', items: 1, tokens: estimateTokens(text),
135
- }));
100
+ rec?.delivered({ state: 'sent', emittedText: `${text}\n` });
101
+ bookLedgerTurn(hippoRoot, {
102
+ uses: [{
103
+ tenantId, sessionId: payloadSessionId, surface: 'compact_resume', event: 'inject', items: 1, tokens: estimateTokens(text),
104
+ }],
105
+ delivery: (write) => flushDeliveryRecorder(rec, write),
106
+ });
136
107
  }
137
- /**
138
- * SessionEnd entry point. Claude Code / OpenCode fire this on /exit while
139
- * tearing down the TUI, which kills any child that is still running when
140
- * the parent returns. Running sleep + capture synchronously here means both
141
- * get SIGTERM'd mid-consolidation.
142
- *
143
- * So we do the minimum inline (read stdin for transcript_path), then spawn
144
- * a fully detached Node child that runs sleep → capture and exit the parent
145
- * immediately. The child writes to the log file and survives TUI teardown;
146
- * the next SessionStart reads the log via `hippo last-sleep`.
147
- */
148
- export async function cmdSessionEnd(hippoRoot, flags) {
108
+ /** SessionEnd entry: TUI teardown kills children still running, so read stdin inline, spawn a detached child that runs sleep then capture, and exit.
109
+ * The child logs to a file that the next SessionStart reads via `hippo last-sleep`. */
110
+ export async function handleSessionEnd({ hippoRoot, tenantId, flags }) {
149
111
  const runtime = hookRuntime(flags);
150
- const turn = flags['turn'] === true;
112
+ const turn = flagIsTrue(flags, 'turn');
151
113
  // Copilot's hook command carries no path, since one quoted into it would need escaping for each shell; the log goes where the hook table used to point.
152
- const logFile = typeof flags['log-file'] === 'string' ? flags['log-file'] : runtime === 'copilot' ? resolveJsonHookPaths('copilot').logFile : null;
114
+ const logFile = stringFlag(flags, 'log-file') ?? (runtime === 'copilot' ? resolveJsonHookPaths('copilot').logFile : null);
153
115
  // Bounded read: extracts transcript_path + session_id for the detached worker's argv.
154
- let sessionId = null;
155
116
  const raw = await readStdinBounded();
156
117
  // Read before normalising: the Copilot CLI's agentStop shares this hook line, and camelCase keys would pass as VS Code's.
157
- if (turn && !isVscodeStopPayload(raw))
118
+ const stop = turn ? vscodeStopInput(raw) : null;
119
+ if (turn && !stop)
158
120
  return;
159
121
  const stdinText = normaliseHookPayload(raw.text);
160
122
  // Before the spawn, since the worker finds its store from the folder it inherits.
161
123
  const root = payloadCwdRoot(hippoRoot, stdinText, runtime);
162
- try {
163
- if (stdinText && stdinText.trim().startsWith('{')) {
164
- const payload = JSON.parse(stdinText);
165
- if (typeof payload.session_id === 'string') {
166
- sessionId = payload.session_id;
167
- }
168
- }
169
- }
170
- catch {
171
- // No stdin, not JSON, or read failure: the snapshot close below will no-op.
172
- }
124
+ const input = stop ?? sessionEndInput(stdinText, raw.timedOut, runtime);
125
+ // Only a host payload ends a session: a manual run and a reply's end (turn mode) are not boundaries.
126
+ const rec = !turn && input !== null && !input.manual ? startDeliveryRecorder(hookStoreRoot(root), stdinText, runtime, 'session-end') : null;
127
+ const sessionId = input?.sessionId ?? null;
173
128
  // Resolved here because only this process saw the payload; the worker captures just the path it is handed.
174
129
  // Always a hook, so never scan: an empty stdin here is not a manual run. The Copilot CLI's sessionEnd names no transcript, so its log is found by id.
175
- const transcriptPath = resolveLastSessionTranscript(undefined, stdinText, { mayScan: false })
130
+ const named = input?.transcriptPath ?? null;
131
+ const transcriptPath = (named !== null && fs.existsSync(named) ? named : null)
176
132
  ?? (runtime === 'copilot' && sessionId ? copilotTranscriptFor(sessionId) : null);
177
- const workerArgs = [process.argv[1], '__session-end-worker'];
178
- if (logFile)
179
- workerArgs.push('--log-file', logFile);
180
- if (transcriptPath)
181
- workerArgs.push('--transcript', transcriptPath);
182
- if (sessionId)
183
- workerArgs.push('--session-id', sessionId);
184
- if (turn)
185
- workerArgs.push('--turn');
186
133
  try {
187
- const child = spawn(process.execPath, workerArgs, {
188
- detached: true,
189
- stdio: 'ignore',
190
- windowsHide: true,
191
- });
192
- // An async spawn failure arrives as an 'error' event, which with no listener is an uncaught exception.
193
- child.on('error', (err) => log.warn(`hippo session-end: the worker did not start: ${errorMessage(err)}`));
194
- child.unref();
134
+ spawnSessionEndWorker(sessionEndWorkerArgs(logFile, transcriptPath, sessionId, turn));
195
135
  }
196
- catch {
197
- // If spawn fails, run inline as a last resort, handed what the child's argv would have carried.
136
+ catch (err) {
137
+ log.debug(`session-end: the worker did not spawn, running inline: ${errorMessage(err)}`);
138
+ // Inline is the last resort, handed what the child's argv would have carried.
198
139
  if (logFile)
199
140
  flags['log-file'] = logFile;
200
141
  if (transcriptPath)
201
142
  flags['transcript'] = transcriptPath;
202
143
  if (sessionId)
203
144
  flags['session-id'] = sessionId;
204
- await cmdSessionEndWorker(root, flags);
145
+ try {
146
+ await cmdSessionEndWorker(root, tenantId, flags);
147
+ }
148
+ finally {
149
+ await runHookWithStores(() => flushDeliveryRecorder(rec));
150
+ }
205
151
  return;
206
152
  }
153
+ // After the spawn, so a locked store delays only the row; the hook's short lock wait bounds it.
154
+ await runHookWithStores(() => flushDeliveryRecorder(rec));
155
+ }
156
+ /** What the session-end payload named; null for one hippo refuses or one that never arrived, and the worker then runs with neither value. */
157
+ function sessionEndInput(stdinText, timedOut, runtime) {
158
+ const receipt = readSessionEnd(stdinText, timedOut, runtime);
159
+ if (receipt.status === 'received')
160
+ return receipt.input;
161
+ log.debug(`session-end: ${receipt.reason}`);
162
+ return null;
163
+ }
164
+ function sessionEndWorkerArgs(logFile, transcriptPath, sessionId, turn) {
165
+ const workerArgs = [process.argv[1], '__session-end-worker'];
166
+ if (logFile)
167
+ workerArgs.push('--log-file', logFile);
168
+ if (transcriptPath)
169
+ workerArgs.push('--transcript', transcriptPath);
170
+ if (sessionId)
171
+ workerArgs.push('--session-id', sessionId);
172
+ if (turn)
173
+ workerArgs.push('--turn');
174
+ return workerArgs;
207
175
  }
208
- /** A VS Code Stop payload with a session id that can name the lock file; anything else makes turn mode a silent no-op. */
209
- function isVscodeStopPayload(raw) {
176
+ function spawnSessionEndWorker(workerArgs) {
177
+ const child = spawn(process.execPath, workerArgs, {
178
+ detached: true,
179
+ stdio: 'ignore',
180
+ windowsHide: true,
181
+ });
182
+ // An async spawn failure arrives as an 'error' event, which with no listener is an uncaught exception.
183
+ child.on('error', (err) => log.warn(`hippo session-end: the worker did not start: ${errorMessage(err)}`));
184
+ child.unref();
185
+ }
186
+ /** The input of a VS Code Stop payload with a session id that can name the lock file; null makes turn mode a silent no-op. */
187
+ function vscodeStopInput(raw) {
210
188
  const receipt = readVscodeStop(raw.text, raw.timedOut);
211
- return receipt.status === 'received' && receipt.input.sessionId !== null && SESSION_ID_RE.test(receipt.input.sessionId);
189
+ return receipt.status === 'received' && receipt.input.sessionId !== null && SESSION_ID_RE.test(receipt.input.sessionId) ? receipt.input : null;
212
190
  }
213
- export async function cmdSessionEndWorker(hippoRoot, flags) {
191
+ async function cmdSessionEndWorker(hippoRoot, tenantId, flags) {
214
192
  const sessionId = flags['session-id'];
215
- await runSessionWorker(isStringValue(sessionId) ? sessionId : null, flags['turn'] === true ? 'turn' : 'full', (mode) => sessionEndWork(hippoRoot, flags, mode));
216
- }
217
- async function sessionEndWork(hippoRoot, flags, mode) {
218
- const transcriptPath = typeof flags['transcript'] === 'string' ? flags['transcript'] : undefined;
219
- const closeLogFile = typeof flags['log-file'] === 'string' ? flags['log-file'] : null;
220
- const closeSessionId = typeof flags['session-id'] === 'string' ? flags['session-id'] : null;
221
- const rereadLog = await bookSessionRereads(hippoRoot, transcriptPath, closeSessionId)
222
- .catch((err) => [`re-read count failed: ${err instanceof Error ? err.message : String(err)}`]);
193
+ await runSessionWorker(isStringValue(sessionId) ? sessionId : null, flagIsTrue(flags, 'turn') ? 'turn' : 'full', (mode) => sessionEndWork(hippoRoot, tenantId, flags, mode));
194
+ }
195
+ export function handleSessionEndWorker({ hippoRoot, tenantId, flags }) {
196
+ return cmdSessionEndWorker(hippoRoot, tenantId, flags);
197
+ }
198
+ async function sessionEndWork(hippoRoot, tenantId, flags, mode) {
199
+ const transcriptPath = stringFlag(flags, 'transcript');
200
+ const closeLogFile = stringFlag(flags, 'log-file') ?? null;
201
+ const closeSessionId = stringFlag(flags, 'session-id') ?? null;
202
+ const rereadLog = await bookSessionRereads(hippoRoot, tenantId, transcriptPath, closeSessionId)
203
+ .catch((err) => [`re-read count failed: ${errorMessage(err)}`]);
223
204
  // Sleep starts the log file afresh, so the lines go in after it; on exit too, in case sleep exits the process.
224
205
  const flushRereadLog = () => { for (const line of rereadLog.splice(0))
225
206
  appendSessionEndCloseLog(closeLogFile, line); };
@@ -232,35 +213,37 @@ async function sessionEndWork(hippoRoot, flags, mode) {
232
213
  return;
233
214
  }
234
215
  if (mode === 'turn' && closeSessionId)
235
- await sleepIfDue(hippoRoot, flags, closeLogFile, transcriptPath, closeSessionId);
216
+ await sleepIfDue(hippoRoot, tenantId, flags, closeLogFile, transcriptPath, closeSessionId);
236
217
  else
237
- await sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath);
218
+ await sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath);
238
219
  flushRereadLog();
239
220
  const digestLog = (message) => appendSessionEndCloseLog(closeLogFile, message);
240
221
  const scan = transcriptPath ? readSessionScan(transcriptPath, digestLog) : null;
241
- const capture = (turns) => captureEndedSession(hippoRoot, store, flags, transcriptPath, turns);
222
+ const capture = (turns) => captureEndedSession(hippoRoot, tenantId, store, flags, transcriptPath, turns);
242
223
  if (mode === 'turn')
243
224
  captureNewTurns(transcriptPath, closeSessionId, scan, capture, digestLog);
244
225
  else
245
226
  capture(scan?.turns);
246
227
  recordSessionDigest(hippoRoot, scan, {
247
228
  key: closeSessionId || path.basename(transcriptPath ?? '', '.jsonl'),
248
- tenantId: resolveTenantId({}),
229
+ tenantId,
249
230
  log: digestLog,
250
231
  });
251
- // Close only this session's snapshot, after sleep+capture: no snapshot producer runs in session-end, and since
252
- // session-end may never fire (crash, kill -9) the freshness bound in loadFreshActiveTaskSnapshot is the backstop.
253
- // The handoff is written first, while the snapshot writeSessionEndHandoff reads is still active.
232
+ // Close only this session's snapshot, after sleep+capture; if session-end never fires (crash, kill -9) the freshness bound in
233
+ // loadFreshActiveTaskSnapshot is the backstop. The handoff is written first, while the snapshot writeSessionEndHandoff reads is active.
254
234
  if (closeSessionId)
255
- writeEndHandoff(store, closeSessionId, transcriptPath, closeLogFile, mode === 'turn');
235
+ writeEndHandoff(store, tenantId, closeSessionId, transcriptPath, closeLogFile, mode === 'turn');
256
236
  if (mode === 'turn') {
257
237
  // The chat goes on after a reply, so its snapshot stays for the next compaction to restore.
258
238
  appendSessionEndCloseLog(closeLogFile, 'skip snapshot close: turn mode');
259
239
  return;
260
240
  }
241
+ closeEndedSessionSnapshot(store, tenantId, closeSessionId, closeLogFile);
242
+ }
243
+ function closeEndedSessionSnapshot(store, tenantId, closeSessionId, closeLogFile) {
261
244
  try {
262
245
  if (closeSessionId) {
263
- const closed = closeTaskSnapshotsForSession(store, resolveTenantId({}), closeSessionId);
246
+ const closed = closeTaskSnapshotsForSession(store, tenantId, closeSessionId);
264
247
  appendSessionEndCloseLog(closeLogFile, `closed ${closed} active snapshot(s) for session ${closeSessionId}`);
265
248
  }
266
249
  else {
@@ -268,18 +251,18 @@ async function sessionEndWork(hippoRoot, flags, mode) {
268
251
  }
269
252
  }
270
253
  catch (err) {
271
- appendSessionEndCloseLog(closeLogFile, `snapshot close failed: ${err.message}`);
254
+ appendSessionEndCloseLog(closeLogFile, `snapshot close failed: ${errorMessage(err)}`);
272
255
  }
273
256
  }
274
- async function sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath) {
257
+ async function sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath) {
275
258
  // Sleeping the global store from here would learn this folder's git commits into it; it has its own daily sleep.
276
259
  if (isInitialized(hippoRoot)) {
277
260
  try {
278
- await (await import('./sleep.js')).cmdSleep(hippoRoot, flags);
261
+ await (await import('./sleep.js')).cmdSleep(hippoRoot, tenantId, flags);
279
262
  }
280
- catch {
281
- // sleep errors are already tee'd to the log file via cmdSleep's
282
- // `[hippo] sleep failed: ...` line. Continue to capture regardless.
263
+ catch (err) {
264
+ // cmdSleep writes its own failure line only once its log tee is open, and capture runs regardless.
265
+ reportSessionEndFailure(closeLogFile, 'session-end: sleep', err);
283
266
  }
284
267
  }
285
268
  else {
@@ -288,19 +271,18 @@ async function sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath)
288
271
  }
289
272
  }
290
273
  /** A close after every reply sleeps only at the MCP server's auto-sleep threshold; each line starts the log afresh, as a sleep does. */
291
- async function sleepIfDue(hippoRoot, flags, closeLogFile, transcriptPath, sessionId) {
274
+ async function sleepIfDue(hippoRoot, tenantId, flags, closeLogFile, transcriptPath, sessionId) {
292
275
  if (!isInitialized(hippoRoot))
293
- return sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath);
276
+ return sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath);
294
277
  const prefix = `turn close, session ${sessionId}`;
295
278
  try {
296
- const { enabled, threshold } = loadConfig(hippoRoot).autoSleep;
297
- const count = enabled ? countCreatedSinceLastSleep(hippoRoot, resolveTenantId({})) : 0;
298
- if (!enabled || count < threshold) {
279
+ const { enabled, count, threshold, due } = autoSleepDue(hippoRoot, tenantId, loadConfig(hippoRoot).autoSleep);
280
+ if (!due) {
299
281
  const why = enabled ? `${count} new memories, threshold ${threshold}` : 'auto-sleep is off';
300
282
  appendSessionEndCloseLog(closeLogFile, `${prefix}: skip sleep, ${why}`, { startFresh: true });
301
283
  return;
302
284
  }
303
- await sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath);
285
+ await sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath);
304
286
  appendSessionEndCloseLog(closeLogFile, `${prefix}: ran sleep at ${count} new memories (threshold ${threshold})`);
305
287
  }
306
288
  catch (err) {
@@ -322,9 +304,9 @@ function captureNewTurns(transcriptPath, sessionId, scan, capture, log) {
322
304
  saveTurnPosition(sessionId, transcriptPath, scan.turns, log);
323
305
  }
324
306
  /** True when capture ran to the end, so a turn close may move its cursor past these turns. */
325
- function captureEndedSession(hippoRoot, store, flags, transcriptPath, turns) {
307
+ function captureEndedSession(hippoRoot, tenantId, store, flags, transcriptPath, turns) {
326
308
  try {
327
- const logFile = typeof flags['log-file'] === 'string' ? flags['log-file'] : undefined;
309
+ const logFile = stringFlag(flags, 'log-file');
328
310
  // With no stdin of its own, capture would read this as a manual run and scan every project.
329
311
  if (!transcriptPath) {
330
312
  appendSessionEndCloseLog(logFile ?? null, 'skip capture: no transcript for this session');
@@ -336,21 +318,20 @@ function captureEndedSession(hippoRoot, store, flags, transcriptPath, turns) {
336
318
  logFile,
337
319
  dryRun: false,
338
320
  global: false,
339
- tenantId: resolveTenantId({}),
321
+ tenantId,
340
322
  // In the global store, rows would otherwise read as user-global and show up in every project.
341
323
  originProject: store === hippoRoot ? undefined : resolveProjectIdentity(process.cwd()),
342
324
  sessionTurns: turns,
343
325
  });
344
326
  return true;
345
327
  }
346
- catch {
347
- // Same treatment — the failure line is already in the log.
328
+ catch (err) {
329
+ reportSessionEndFailure(stringFlag(flags, 'log-file') ?? null, 'session-end: capture', err);
348
330
  return false;
349
331
  }
350
332
  }
351
- function writeEndHandoff(store, closeSessionId, transcriptPath, closeLogFile, inPlace = false) {
333
+ function writeEndHandoff(store, tenantId, closeSessionId, transcriptPath, closeLogFile, inPlace = false) {
352
334
  try {
353
- const tenantId = resolveTenantId({});
354
335
  const ownSnapshot = loadActiveTaskSnapshot(store, tenantId)?.session_id === closeSessionId;
355
336
  // A never-compacted session has no snapshot; read even when it has one, as another session's PreCompact can take the slot before the write.
356
337
  const derived = transcriptPath
@@ -367,11 +348,11 @@ function writeEndHandoff(store, closeSessionId, transcriptPath, closeLogFile, in
367
348
  }
368
349
  catch (err) {
369
350
  // SAFETY: catch clauses bind unknown, but Node/V8 always throws an Error here.
370
- appendSessionEndCloseLog(closeLogFile, `handoff write failed: ${err.message}`);
351
+ appendSessionEndCloseLog(closeLogFile, `handoff write failed: ${errorMessage(err)}`);
371
352
  }
372
353
  }
373
354
  /** Books the ending session's re-reads in each store its ledger rows can land in (project and global); returns the log lines. */
374
- async function bookSessionRereads(hippoRoot, transcriptPath, sessionId) {
355
+ async function bookSessionRereads(hippoRoot, tenantId, transcriptPath, sessionId) {
375
356
  if (!transcriptPath || !sessionId)
376
357
  return [];
377
358
  let read;
@@ -379,23 +360,17 @@ async function bookSessionRereads(hippoRoot, transcriptPath, sessionId) {
379
360
  read = await readApiCalls(transcriptPath);
380
361
  }
381
362
  catch (err) {
382
- return [`skip re-read count: cannot read the transcript: ${err instanceof Error ? err.message : String(err)}`];
363
+ return [`skip re-read count: cannot read the transcript: ${errorMessage(err)}`];
383
364
  }
384
365
  const roots = new Set([hippoRoot, getGlobalRoot()].filter((root) => isInitialized(root)).map((root) => path.resolve(root)));
385
366
  const lines = [];
386
367
  let tokens = 0;
387
368
  for (const root of roots) {
388
369
  try {
389
- const db = openHippoDb(root);
390
- try {
391
- tokens += recordRereads(db, resolveTenantId({}), sessionId, read.calls);
392
- }
393
- finally {
394
- closeHippoDb(db);
395
- }
370
+ tokens += recordRereads(root, tenantId, sessionId, read.calls);
396
371
  }
397
372
  catch (err) {
398
- lines.push(`re-read count failed: ${err instanceof Error ? err.message : String(err)}`);
373
+ lines.push(`re-read count failed: ${errorMessage(err)}`);
399
374
  }
400
375
  }
401
376
  const skipped = read.malformed > 0 ? `, ${read.malformed} unparsable transcript lines skipped` : '';
@@ -407,6 +382,7 @@ function loadCodexWrapperMetadata() {
407
382
  if (!fs.existsSync(metadataPath)) {
408
383
  throw new Error('Codex wrapper is not installed. Run `hippo hook install codex` first.');
409
384
  }
385
+ // SAFETY: the file is the one installCodexWrapper wrote; handleCodexRun reads only logFile and realCodexPath from it.
410
386
  return JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
411
387
  }
412
388
  /** Quotes one cmd.exe argument; each `%` leaves the quotes as `^%`, so no %NAME% pair can expand. */
@@ -433,7 +409,7 @@ function spawnRealCodex(realCodexPath, forwardArgs, cwd) {
433
409
  }
434
410
  return spawn(realCodexPath, forwardArgs, { cwd, stdio: 'inherit', windowsHide: false });
435
411
  }
436
- export function cmdCodexRun(hippoRoot, args) {
412
+ export function handleCodexRun({ hippoRoot, tenantId, args }) {
437
413
  const metadata = loadCodexWrapperMetadata();
438
414
  const startedAtMs = Date.now();
439
415
  // Codex reads CODEX_HOME at each launch, so resolve it now, not from the install-time metadata.
@@ -442,8 +418,8 @@ export function cmdCodexRun(hippoRoot, args) {
442
418
  try {
443
419
  cmdLastSleep(hippoRoot, { path: metadata.logFile }, 'terminal');
444
420
  }
445
- catch {
446
- // best-effort only
421
+ catch (err) {
422
+ log.debug(`codex run: the last sleep summary was not shown: ${errorMessage(err)}`);
447
423
  }
448
424
  const child = spawnRealCodex(metadata.realCodexPath, args, process.cwd());
449
425
  child.on('error', (err) => {
@@ -451,85 +427,106 @@ export function cmdCodexRun(hippoRoot, args) {
451
427
  process.exit(1);
452
428
  });
453
429
  child.on('exit', async (code, signal) => {
454
- const workerArgs = [
455
- process.argv[1],
456
- '__codex-session-end-worker',
457
- '--codex-home',
458
- path.dirname(historyPath),
459
- '--history-path',
460
- historyPath,
461
- '--start-offset',
462
- String(startOffsetBytes),
463
- '--started-at',
464
- String(startedAtMs),
465
- '--log-file',
466
- metadata.logFile,
467
- ];
430
+ await launchCodexSessionEndWorker(hippoRoot, tenantId, historyPath, startOffsetBytes, startedAtMs, metadata.logFile);
431
+ exitLikeChild(code, signal);
432
+ });
433
+ }
434
+ async function launchCodexSessionEndWorker(hippoRoot, tenantId, historyPath, startOffsetBytes, startedAtMs, logFile) {
435
+ const workerArgs = [
436
+ process.argv[1],
437
+ '__codex-session-end-worker',
438
+ '--codex-home',
439
+ path.dirname(historyPath),
440
+ '--history-path',
441
+ historyPath,
442
+ '--start-offset',
443
+ String(startOffsetBytes),
444
+ '--started-at',
445
+ String(startedAtMs),
446
+ '--log-file',
447
+ logFile,
448
+ ];
449
+ if (await detachedWorkerStarted(workerArgs))
450
+ return;
451
+ // Awaited so the sleep write can't be killed by the exit calls below.
452
+ try {
453
+ await cmdCodexSessionEndWorker(hippoRoot, tenantId, {
454
+ 'codex-home': path.dirname(historyPath),
455
+ 'history-path': historyPath,
456
+ 'start-offset': String(startOffsetBytes),
457
+ 'started-at': String(startedAtMs),
458
+ 'log-file': logFile,
459
+ });
460
+ }
461
+ catch (inlineErr) {
462
+ log.debug(`codex run: the inline session-end failed: ${errorMessage(inlineErr)}`);
463
+ }
464
+ }
465
+ /** Resolves true once the detached worker is running, false when the spawn fails, whether it throws or reports later. */
466
+ function detachedWorkerStarted(workerArgs) {
467
+ return new Promise((resolve) => {
468
+ const failed = (reason) => {
469
+ log.debug(`codex run: the session-end worker did not spawn, running inline: ${reason}`);
470
+ resolve(false);
471
+ };
468
472
  try {
469
- const worker = spawn(process.execPath, workerArgs, {
470
- detached: true,
471
- stdio: 'ignore',
472
- windowsHide: true,
473
- });
473
+ const worker = spawn(process.execPath, workerArgs, { detached: true, stdio: 'ignore', windowsHide: true });
474
+ // An async spawn failure (ENOENT, EAGAIN) arrives as an 'error' event, which a try cannot catch.
475
+ worker.on('error', (err) => failed(err.message));
476
+ worker.once('spawn', () => resolve(true));
474
477
  worker.unref();
475
478
  }
476
- catch {
477
- // Fall back to the inline path if the detached worker cannot be created.
478
- // Awaited so the sleep write can't be killed by the exit calls below.
479
- try {
480
- await cmdCodexSessionEndWorker(hippoRoot, {
481
- 'codex-home': path.dirname(historyPath),
482
- 'history-path': historyPath,
483
- 'start-offset': String(startOffsetBytes),
484
- 'started-at': String(startedAtMs),
485
- 'log-file': metadata.logFile,
486
- });
487
- }
488
- catch {
489
- // cmdCodexSessionEndWorker already fail-softs internally; this is belt-and-braces.
490
- }
491
- }
492
- if (signal) {
493
- try {
494
- process.kill(process.pid, signal);
495
- }
496
- catch {
497
- // Cannot re-raise the child's signal on this platform; a non-zero exit still reports the failure.
498
- process.exit(1);
499
- }
500
- return;
479
+ catch (err) {
480
+ failed(errorMessage(err));
501
481
  }
502
- process.exit(code ?? 0);
503
482
  });
504
483
  }
505
- export async function cmdCodexSessionEndWorker(hippoRoot, flags) {
506
- const logFile = typeof flags['log-file'] === 'string' ? flags['log-file'] : undefined;
484
+ function exitLikeChild(code, signal) {
485
+ if (signal) {
486
+ try {
487
+ process.kill(process.pid, signal);
488
+ }
489
+ catch {
490
+ // Cannot re-raise the child's signal on this platform; a non-zero exit still reports the failure.
491
+ process.exit(1);
492
+ }
493
+ return;
494
+ }
495
+ process.exit(code ?? 0);
496
+ }
497
+ export async function cmdCodexSessionEndWorker(hippoRoot, tenantId, flags) {
498
+ const logFile = stringFlag(flags, 'log-file');
507
499
  // Like the other hooks: project store, else global; a folder with neither must not get one made.
508
500
  const store = hookStoreRoot(hippoRoot);
509
501
  if (!isInitialized(store)) {
510
502
  appendSessionEndCloseLog(logFile ?? null, 'skip: no hippo store for this folder or globally', { startFresh: true });
511
503
  return;
512
504
  }
505
+ await sleepCodexProjectStore(hippoRoot, tenantId, logFile);
506
+ captureCodexTranscript(hippoRoot, tenantId, store, flags, logFile);
507
+ }
508
+ export function handleCodexSessionEndWorker({ hippoRoot, tenantId, flags }) {
509
+ return cmdCodexSessionEndWorker(hippoRoot, tenantId, flags);
510
+ }
511
+ async function sleepCodexProjectStore(hippoRoot, tenantId, logFile) {
513
512
  // Sleeping the global store from here would learn this folder's git commits into it; it has its own daily sleep.
514
513
  if (isInitialized(hippoRoot)) {
515
514
  try {
516
- await (await import('./sleep.js')).cmdSleep(hippoRoot, logFile ? { 'log-file': logFile } : {});
515
+ await (await import('./sleep.js')).cmdSleep(hippoRoot, tenantId, logFile ? { 'log-file': logFile } : {});
517
516
  }
518
- catch {
519
- // sleep errors are already written via cmdSleep
517
+ catch (err) {
518
+ reportSessionEndFailure(logFile ?? null, 'codex session-end: sleep', err);
520
519
  }
521
520
  }
522
521
  else {
523
522
  appendSessionEndCloseLog(logFile ?? null, 'skip sleep: this folder has no store of its own', { startFresh: true });
524
523
  logSessionEndImport(logFile ?? null, undefined);
525
524
  }
525
+ }
526
+ function captureCodexTranscript(hippoRoot, tenantId, store, flags, logFile) {
526
527
  try {
527
- const codexHome = typeof flags['codex-home'] === 'string'
528
- ? flags['codex-home']
529
- : resolveCodexWrapperPaths().codexHome;
530
- const historyPath = typeof flags['history-path'] === 'string'
531
- ? flags['history-path']
532
- : path.join(codexHome, 'history.jsonl');
528
+ const codexHome = stringFlag(flags, 'codex-home') ?? resolveCodexWrapperPaths().codexHome;
529
+ const historyPath = stringFlag(flags, 'history-path') ?? path.join(codexHome, 'history.jsonl');
533
530
  const startOffsetBytes = parseInt(String(flags['start-offset'] ?? '0'), 10) || 0;
534
531
  const startedAtMs = parseInt(String(flags['started-at'] ?? Date.now()), 10) || Date.now();
535
532
  const transcriptPath = resolveCodexSessionTranscript({
@@ -551,21 +548,21 @@ export async function cmdCodexSessionEndWorker(hippoRoot, flags) {
551
548
  logFile,
552
549
  dryRun: false,
553
550
  global: false,
554
- tenantId: resolveTenantId({}),
551
+ tenantId,
555
552
  originProject: store === hippoRoot ? undefined : resolveProjectIdentity(process.cwd()),
556
553
  sessionTurns: scan?.turns,
557
554
  };
558
555
  try {
559
556
  cmdCapture(store, captureOpts);
560
557
  }
561
- catch {
562
- // capture path logs its own failures
558
+ catch (err) {
559
+ reportSessionEndFailure(logFile ?? null, 'codex session-end: capture', err);
563
560
  }
564
561
  // The Codex wrapper passes no session id, so the rollout file names the session.
565
- recordSessionDigest(hippoRoot, scan, { key: path.basename(transcriptPath, '.jsonl'), tenantId: resolveTenantId({}), log: digestLog });
562
+ recordSessionDigest(hippoRoot, scan, { key: path.basename(transcriptPath, '.jsonl'), tenantId, log: digestLog });
566
563
  }
567
- catch {
568
- // capture path logs its own failures
564
+ catch (err) {
565
+ reportSessionEndFailure(logFile ?? null, 'codex session-end: transcript scan or digest', err);
569
566
  }
570
567
  }
571
568
  export async function handlePreCompact({ hippoRoot, flags }) {
@@ -574,24 +571,31 @@ export async function handlePreCompact({ hippoRoot, flags }) {
574
571
  const runtime = hookRuntime(flags);
575
572
  const root = payloadCwdRoot(hippoRoot, stdinText, runtime);
576
573
  await runHookWithStores(async () => {
574
+ // Started before any store wait, so two fires of one hook carry timestamps close enough to match as duplicates.
575
+ const rec = startDeliveryRecorder(hookStoreRoot(root), stdinText, runtime, 'pre-compact');
577
576
  resetHookInjection(root, stdinText, null);
578
577
  await cmdPreCompact(hookStoreRoot(root), {
579
578
  stdinText,
580
579
  stdinTimedOut,
581
- logFile: typeof flags['log-file'] === 'string' ? flags['log-file'] : undefined,
580
+ logFile: stringFlag(flags, 'log-file'),
582
581
  runtime,
582
+ onBoundary: (printed) => {
583
+ rec?.delivered(printed === null ? { state: 'empty' } : { state: 'sent', emittedText: printed });
584
+ flushDeliveryRecorder(rec);
585
+ },
583
586
  });
584
587
  });
585
588
  }
586
589
  export async function handlePostCompact({ hippoRoot, flags }) {
587
590
  // PostCompact hook: saves the compaction summary and its memories, then prints one plain line, because Claude Code shows this hook's stdout as-is. Always exits 0.
588
- const { text } = await readHookStdin();
591
+ const { text, timedOut } = await readHookStdin();
589
592
  const logFlag = flags['log-file'];
590
593
  const store = hookStoreRoot(hippoRoot);
591
594
  const line = await runHookWithStores(() => cmdPostCompact(store, {
592
595
  stdinText: text,
596
+ stdinTimedOut: timedOut,
593
597
  logFile: logFlag === true || logFlag === false || Array.isArray(logFlag) ? undefined : logFlag,
594
- // Passed in, since capture.ts importing the sync would close an import cycle.
598
+ // Passed in, since src/capture/ importing the sync would close an import cycle.
595
599
  afterSave: (transcriptPath, cwd, log) => {
596
600
  const report = importSessionFolder(store, transcriptPath, cwd, { machine: currentMachine(), busyWaitMs: COMPACTION_DB_WAIT_MS });
597
601
  const summary = summaryLine(report);
@@ -604,7 +608,7 @@ export async function handlePostCompact({ hippoRoot, flags }) {
604
608
  if (line !== null && line !== undefined)
605
609
  console.log(line);
606
610
  }
607
- export async function handleCaptureError({ hippoRoot, flags }) {
611
+ export async function handleCaptureError({ hippoRoot, tenantId, flags }) {
608
612
  // PostToolUseFailure hook: every path exits 0, and nothing is created
609
613
  // when no store exists (the hook fires in every directory).
610
614
  const { text } = await readHookStdin();
@@ -614,21 +618,22 @@ export async function handleCaptureError({ hippoRoot, flags }) {
614
618
  if (isInitialized(root) && payload) {
615
619
  // SAFETY: JSON.parse returns a JSON value by definition.
616
620
  const failure = JSON.parse(payload);
617
- await runHookWithStores(() => captureToolFailure(root, resolveTenantId({}), failure));
621
+ await runHookWithStores(() => captureToolFailure(root, tenantId, failure));
618
622
  }
619
623
  }
620
- catch {
621
- // A malformed payload or store error must never fail the agent's tool call.
624
+ catch (err) {
625
+ // A malformed payload or store error must never fail the agent's tool call, so it is reported and dropped.
626
+ log.warn(`failure capture skipped: ${errorMessage(err)}`);
622
627
  }
623
628
  }
624
- export async function handleCompactResume({ hippoRoot }) {
629
+ export async function handleCompactResume({ hippoRoot, tenantId }) {
625
630
  const { text: stdinText, timedOut: stdinTimedOut } = await readHookStdin();
626
631
  await runHookWithStores(() => {
627
632
  resetHookInjection(hippoRoot, stdinText, 'compact');
628
- cmdCompactResume(hookStoreRoot(hippoRoot), stdinText, stdinTimedOut);
633
+ cmdCompactResume(hookStoreRoot(hippoRoot), tenantId, stdinText, stdinTimedOut);
629
634
  });
630
635
  }
631
- export async function handleCapture({ hippoRoot, flags }) {
636
+ export async function handleCapture({ hippoRoot, tenantId, flags }) {
632
637
  let captureSource = null;
633
638
  let captureFile;
634
639
  let transcriptPath;
@@ -649,10 +654,10 @@ export async function handleCapture({ hippoRoot, flags }) {
649
654
  }
650
655
  if (!captureSource) {
651
656
  printError('Usage: hippo capture --stdin|--file <path>|--last-session [--transcript <path>] [--log-file <path>] [--dry-run] [--global]');
652
- process.exit(1);
657
+ throw new CliExit(1);
653
658
  }
654
659
  // Bounded, and only when last-session has no explicit path: the
655
- // --stdin source keeps its own blocking read in capture.ts by design.
660
+ // --stdin source keeps its own blocking read in src/capture/ by design.
656
661
  const bounded = captureSource === 'last-session' && !transcriptPath
657
662
  ? await readHookStdin()
658
663
  : { text: undefined, timedOut: false };
@@ -662,10 +667,10 @@ export async function handleCapture({ hippoRoot, flags }) {
662
667
  transcriptPath,
663
668
  stdinText: bounded.text,
664
669
  stdinTimedOut: bounded.timedOut,
665
- logFile: typeof flags['log-file'] === 'string' ? flags['log-file'] : undefined,
666
- dryRun: Boolean(flags['dry-run']),
667
- global: Boolean(flags['global']),
668
- tenantId: resolveTenantId({}),
670
+ logFile: stringFlag(flags, 'log-file'),
671
+ dryRun: boolFlag(flags, 'dry-run'),
672
+ global: boolFlag(flags, 'global'),
673
+ tenantId,
669
674
  });
670
675
  }
671
676
  //# sourceMappingURL=session-hooks.js.map