hippo-memory 1.71.0 → 2.0.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 (625) hide show
  1. package/README.md +7 -5
  2. package/dist/agent-memories/apply.d.ts +0 -11
  3. package/dist/agent-memories/apply.js +11 -26
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/copilot.d.ts +1 -3
  7. package/dist/agent-memories/copilot.js +1 -17
  8. package/dist/agent-memories/project-folds.d.ts +10 -0
  9. package/dist/agent-memories/project-folds.js +34 -0
  10. package/dist/agent-memories/sync.js +8 -6
  11. package/dist/api/assemble.js +3 -2
  12. package/dist/api/audit.d.ts +30 -2
  13. package/dist/api/audit.js +48 -7
  14. package/dist/api/auth.d.ts +11 -9
  15. package/dist/api/auth.js +39 -40
  16. package/dist/api/auto-sleep.d.ts +5 -2
  17. package/dist/api/auto-sleep.js +7 -3
  18. package/dist/api/availability.js +2 -3
  19. package/dist/api/cards.d.ts +42 -0
  20. package/dist/api/cards.js +52 -0
  21. package/dist/api/conflicts.d.ts +28 -0
  22. package/dist/api/conflicts.js +61 -0
  23. package/dist/api/context-auto.js +4 -2
  24. package/dist/api/context-render.js +4 -3
  25. package/dist/api/context-select.js +15 -29
  26. package/dist/api/context.js +29 -18
  27. package/dist/api/continuity.d.ts +47 -0
  28. package/dist/api/continuity.js +66 -0
  29. package/dist/api/dormant.js +4 -2
  30. package/dist/api/drill-down.js +3 -2
  31. package/dist/api/embeddings.d.ts +17 -0
  32. package/dist/api/embeddings.js +28 -0
  33. package/dist/api/error-reply.d.ts +8 -0
  34. package/dist/api/error-reply.js +21 -0
  35. package/dist/api/forget.d.ts +7 -3
  36. package/dist/api/forget.js +24 -14
  37. package/dist/api/goals.d.ts +1 -1
  38. package/dist/api/goals.js +5 -9
  39. package/dist/api/graph.js +2 -1
  40. package/dist/api/index.d.ts +4 -2
  41. package/dist/api/index.js +4 -2
  42. package/dist/api/instruction-detect.js +5 -1
  43. package/dist/api/learn.d.ts +5 -1
  44. package/dist/api/learn.js +71 -44
  45. package/dist/api/ledger-db.d.ts +2 -6
  46. package/dist/api/ledger-db.js +4 -36
  47. package/dist/api/memories.d.ts +21 -1
  48. package/dist/api/memories.js +51 -1
  49. package/dist/api/objects.d.ts +1 -1
  50. package/dist/api/objects.js +2 -1
  51. package/dist/api/outcome.d.ts +5 -5
  52. package/dist/api/outcome.js +17 -16
  53. package/dist/api/pilot-arm.d.ts +1 -11
  54. package/dist/api/pilot-arm.js +5 -45
  55. package/dist/api/predictions.d.ts +3 -1
  56. package/dist/api/predictions.js +8 -1
  57. package/dist/api/projects.d.ts +21 -0
  58. package/dist/api/projects.js +24 -0
  59. package/dist/api/promote.d.ts +3 -3
  60. package/dist/api/promote.js +26 -28
  61. package/dist/api/prompt-hook.d.ts +17 -2
  62. package/dist/api/prompt-hook.js +45 -4
  63. package/dist/api/quarantine.js +2 -1
  64. package/dist/api/recall-cli.d.ts +3 -0
  65. package/dist/api/recall-cli.js +13 -4
  66. package/dist/api/recall-core.js +10 -5
  67. package/dist/api/recall-pipeline.js +23 -24
  68. package/dist/api/recall-request.js +1 -1
  69. package/dist/api/recall-types.d.ts +3 -1
  70. package/dist/api/recall.d.ts +0 -3
  71. package/dist/api/recall.js +51 -73
  72. package/dist/api/remember-local.d.ts +5 -2
  73. package/dist/api/remember-local.js +15 -7
  74. package/dist/api/remember.d.ts +7 -3
  75. package/dist/api/remember.js +19 -16
  76. package/dist/api/session-end.d.ts +46 -0
  77. package/dist/api/session-end.js +131 -0
  78. package/dist/api/sleep-run.d.ts +1 -1
  79. package/dist/api/sleep-run.js +16 -11
  80. package/dist/api/sleep.js +4 -3
  81. package/dist/api/status.d.ts +24 -0
  82. package/dist/api/status.js +40 -0
  83. package/dist/api/store-init.d.ts +4 -0
  84. package/dist/api/store-init.js +9 -0
  85. package/dist/api/tokens.js +2 -2
  86. package/dist/api/types.d.ts +3 -7
  87. package/dist/api/types.js +6 -1
  88. package/dist/capture/caller-session.d.ts +0 -3
  89. package/dist/capture/caller-session.js +1 -12
  90. package/dist/capture/capture-error.d.ts +2 -2
  91. package/dist/capture/capture-error.js +23 -18
  92. package/dist/capture/codex-patch.js +3 -1
  93. package/dist/capture/command.js +36 -95
  94. package/dist/capture/compact.js +10 -5
  95. package/dist/capture/compaction-items-caller.js +11 -20
  96. package/dist/capture/compaction-record.d.ts +7 -93
  97. package/dist/capture/compaction-record.js +29 -426
  98. package/dist/capture/compaction-spool.d.ts +7 -7
  99. package/dist/capture/compaction-spool.js +60 -51
  100. package/dist/capture/copilot-transcript.d.ts +2 -1
  101. package/dist/capture/copilot-transcript.js +2 -1
  102. package/dist/capture/extract.d.ts +5 -2
  103. package/dist/capture/extract.js +4 -3
  104. package/dist/capture/failure-caller.d.ts +1 -1
  105. package/dist/capture/failure-caller.js +21 -16
  106. package/dist/capture/failure-reading.d.ts +2 -1
  107. package/dist/capture/failure-reading.js +7 -9
  108. package/dist/capture/pre-compact-caller.js +5 -4
  109. package/dist/capture/session-digest.js +4 -3
  110. package/dist/capture/session-end-caller.js +3 -2
  111. package/dist/capture/session-worker.js +22 -10
  112. package/dist/capture/transcript.d.ts +2 -1
  113. package/dist/capture/transcript.js +6 -3
  114. package/dist/capture/working-state.d.ts +4 -2
  115. package/dist/capture/working-state.js +4 -2
  116. package/dist/cli/audit-prune.d.ts +0 -25
  117. package/dist/cli/audit-prune.js +1 -27
  118. package/dist/cli/audit.js +20 -20
  119. package/dist/cli/auth.d.ts +1 -1
  120. package/dist/cli/auth.js +16 -17
  121. package/dist/cli/briefs.d.ts +1 -4
  122. package/dist/cli/briefs.js +37 -292
  123. package/dist/cli/card.js +41 -33
  124. package/dist/cli/client.d.ts +6 -2
  125. package/dist/cli/client.js +37 -21
  126. package/dist/cli/compact-resume-payload.js +1 -1
  127. package/dist/cli/context.d.ts +1 -1
  128. package/dist/cli/context.js +13 -13
  129. package/dist/cli/continuity.d.ts +1 -1
  130. package/dist/cli/continuity.js +36 -39
  131. package/dist/cli/curate.d.ts +2 -2
  132. package/dist/cli/curate.js +32 -36
  133. package/dist/cli/dag.d.ts +1 -1
  134. package/dist/cli/dag.js +23 -8
  135. package/dist/cli/decisions.d.ts +0 -2
  136. package/dist/cli/decisions.js +7 -285
  137. package/dist/cli/eval.d.ts +1 -1
  138. package/dist/cli/eval.js +12 -13
  139. package/dist/cli/explain.d.ts +1 -1
  140. package/dist/cli/explain.js +21 -25
  141. package/dist/cli/flag-values.js +16 -6
  142. package/dist/cli/flags.d.ts +0 -289
  143. package/dist/cli/flags.js +3 -138
  144. package/dist/cli/graph.d.ts +3 -0
  145. package/dist/cli/graph.js +83 -0
  146. package/dist/cli/hook-runtime.d.ts +6 -6
  147. package/dist/cli/hook-runtime.js +9 -36
  148. package/dist/cli/incidents.d.ts +3 -0
  149. package/dist/cli/incidents.js +112 -0
  150. package/dist/cli/init.d.ts +1 -1
  151. package/dist/cli/init.js +28 -19
  152. package/dist/cli/install-steps.d.ts +2 -1
  153. package/dist/cli/install-steps.js +11 -3
  154. package/dist/cli/last-sleep.js +1 -1
  155. package/dist/cli/maintenance.d.ts +3 -3
  156. package/dist/cli/maintenance.js +29 -30
  157. package/dist/cli/notes.d.ts +2 -0
  158. package/dist/cli/notes.js +41 -0
  159. package/dist/cli/object-verbs.d.ts +2 -2
  160. package/dist/cli/object-verbs.js +4 -4
  161. package/dist/cli/open-browser.d.ts +14 -0
  162. package/dist/cli/open-browser.js +26 -0
  163. package/dist/cli/playbooks.d.ts +3 -4
  164. package/dist/cli/playbooks.js +126 -290
  165. package/dist/cli/predictions.d.ts +3 -0
  166. package/dist/cli/predictions.js +174 -0
  167. package/dist/cli/print.js +2 -1
  168. package/dist/cli/projects.js +30 -22
  169. package/dist/cli/quality-repair-once.d.ts +1 -1
  170. package/dist/cli/quality-repair-once.js +6 -5
  171. package/dist/cli/recall.js +13 -7
  172. package/dist/cli/refine-llm.js +18 -17
  173. package/dist/cli/remember.js +17 -17
  174. package/dist/cli/scheduler.js +2 -1
  175. package/dist/cli/serve.js +11 -6
  176. package/dist/cli/session-hooks.d.ts +1 -5
  177. package/dist/cli/session-hooks.js +89 -168
  178. package/dist/cli/setup.d.ts +1 -1
  179. package/dist/cli/setup.js +17 -10
  180. package/dist/cli/shared.d.ts +2 -6
  181. package/dist/cli/shared.js +9 -29
  182. package/dist/cli/sleep-render.js +6 -3
  183. package/dist/cli/sleep.js +6 -37
  184. package/dist/cli/status.d.ts +3 -3
  185. package/dist/cli/status.js +32 -35
  186. package/dist/cli/transfer.d.ts +3 -3
  187. package/dist/cli/transfer.js +64 -43
  188. package/dist/cli/usage.d.ts +1 -80
  189. package/dist/cli/usage.js +2 -696
  190. package/dist/cli/verb-row.d.ts +34 -0
  191. package/dist/cli/verb-row.js +6 -0
  192. package/dist/cli/verbs/health.d.ts +27 -0
  193. package/dist/cli/verbs/health.js +234 -0
  194. package/dist/cli/verbs/memory.d.ts +16 -0
  195. package/dist/cli/verbs/memory.js +236 -0
  196. package/dist/cli/verbs/objects.d.ts +20 -0
  197. package/dist/cli/verbs/objects.js +257 -0
  198. package/dist/cli/verbs/sessions.d.ts +31 -0
  199. package/dist/cli/verbs/sessions.js +314 -0
  200. package/dist/cli/verbs.d.ts +81 -0
  201. package/dist/cli/verbs.js +7 -0
  202. package/dist/cli/versioned-verbs.d.ts +51 -0
  203. package/dist/cli/versioned-verbs.js +79 -0
  204. package/dist/cli.d.ts +1 -272
  205. package/dist/cli.js +24 -315
  206. package/dist/connectors/dlq.d.ts +39 -3
  207. package/dist/connectors/dlq.js +39 -4
  208. package/dist/connectors/github/backfill.js +12 -3
  209. package/dist/connectors/github/deletion.js +2 -1
  210. package/dist/connectors/github/dlq.js +31 -73
  211. package/dist/connectors/github/ingest.d.ts +2 -6
  212. package/dist/connectors/github/ingest.js +5 -29
  213. package/dist/connectors/github/tenant-routing.js +2 -1
  214. package/dist/connectors/github/webhook.d.ts +2 -1
  215. package/dist/connectors/github/webhook.js +35 -2
  216. package/dist/connectors/ingest.d.ts +10 -0
  217. package/dist/connectors/ingest.js +29 -0
  218. package/dist/connectors/slack/deletion.js +2 -1
  219. package/dist/connectors/slack/dlq.js +49 -71
  220. package/dist/connectors/slack/ingest.d.ts +2 -6
  221. package/dist/connectors/slack/ingest.js +4 -28
  222. package/dist/connectors/slack/tenant-routing.js +2 -1
  223. package/dist/connectors/slack/webhook.d.ts +2 -1
  224. package/dist/connectors/slack/webhook.js +2 -1
  225. package/dist/consolidate/conflicts.js +2 -2
  226. package/dist/consolidate/dag.js +29 -18
  227. package/dist/consolidate/dedupe.d.ts +7 -0
  228. package/dist/consolidate/dedupe.js +6 -4
  229. package/dist/consolidate/llm-passes.js +45 -19
  230. package/dist/consolidate/memory-value.js +3 -2
  231. package/dist/consolidate/merge.js +8 -8
  232. package/dist/consolidate/physics-pass.d.ts +6 -1
  233. package/dist/consolidate/physics-pass.js +26 -6
  234. package/dist/consolidate/replay.js +11 -4
  235. package/dist/consolidate/sleep.js +9 -6
  236. package/dist/consolidate/traces.js +5 -5
  237. package/dist/core/ablation.d.ts +10 -0
  238. package/dist/core/ablation.js +12 -0
  239. package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
  240. package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
  241. package/dist/core/ambient.d.ts +4 -0
  242. package/dist/core/ambient.js +39 -18
  243. package/dist/core/api-errors.d.ts +16 -0
  244. package/dist/core/api-errors.js +20 -0
  245. package/dist/core/card.js +3 -1
  246. package/dist/core/compaction-timing.d.ts +7 -0
  247. package/dist/core/compaction-timing.js +9 -0
  248. package/dist/core/config.d.ts +1 -1
  249. package/dist/core/config.js +22 -18
  250. package/dist/core/cosine.d.ts +3 -0
  251. package/dist/core/cosine.js +19 -0
  252. package/dist/{store → core}/markdown.d.ts +1 -1
  253. package/dist/{store → core}/markdown.js +4 -4
  254. package/dist/core/memory-audit.d.ts +17 -0
  255. package/dist/core/memory-audit.js +54 -0
  256. package/dist/core/memory.d.ts +14 -8
  257. package/dist/core/memory.js +35 -23
  258. package/dist/{consolidate → core}/merged-row.d.ts +1 -1
  259. package/dist/{consolidate → core}/merged-row.js +1 -1
  260. package/dist/core/physics.d.ts +3 -1
  261. package/dist/core/physics.js +23 -18
  262. package/dist/core/prediction.d.ts +3 -0
  263. package/dist/core/prediction.js +6 -0
  264. package/dist/core/project-identity.d.ts +3 -0
  265. package/dist/core/project-identity.js +12 -2
  266. package/dist/{store → core}/recall-scope.d.ts +1 -10
  267. package/dist/{store → core}/recall-scope.js +2 -19
  268. package/dist/core/search-types.d.ts +1 -1
  269. package/dist/dashboard/dashboard-actions.d.ts +2 -2
  270. package/dist/dashboard/dashboard-actions.js +5 -5
  271. package/dist/dashboard/dashboard-queries.js +2 -7
  272. package/dist/dashboard/dashboard-snapshot.js +1 -3
  273. package/dist/dashboard/dashboard.js +16 -5
  274. package/dist/db/busy.d.ts +2 -7
  275. package/dist/db/busy.js +21 -26
  276. package/dist/db/connect.d.ts +2 -2
  277. package/dist/db/connect.js +7 -7
  278. package/dist/db/index.d.ts +3 -3
  279. package/dist/db/index.js +3 -3
  280. package/dist/db/migrate.js +14 -7
  281. package/dist/db/migrations/index.d.ts +1 -1
  282. package/dist/db/migrations/index.js +3 -1
  283. package/dist/db/migrations/v11.js +1 -0
  284. package/dist/db/migrations/v14.js +1 -0
  285. package/dist/db/migrations/v55.d.ts +3 -0
  286. package/dist/db/migrations/v55.js +17 -0
  287. package/dist/db/open.d.ts +0 -2
  288. package/dist/db/open.js +6 -10
  289. package/dist/db/physics-state.d.ts +0 -4
  290. package/dist/db/physics-state.js +7 -33
  291. package/dist/db/request-stores.d.ts +1 -0
  292. package/dist/db/request-stores.js +2 -1
  293. package/dist/db/tables.d.ts +2 -0
  294. package/dist/db/tables.js +6 -2
  295. package/dist/db/vector-store.js +19 -5
  296. package/dist/db/wal-checkpointer.js +2 -1
  297. package/dist/doctor.d.ts +3 -0
  298. package/dist/doctor.js +18 -15
  299. package/dist/embeddings/local.d.ts +62 -0
  300. package/dist/embeddings/local.js +146 -0
  301. package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
  302. package/dist/{store/embeddings → embeddings}/provider.js +19 -25
  303. package/dist/embeddings/transformers.d.ts +26 -0
  304. package/dist/embeddings/transformers.js +89 -0
  305. package/dist/entry/session-text.d.ts +1 -1
  306. package/dist/entry/session-text.js +1 -1
  307. package/dist/entry/store-kit.d.ts +37 -0
  308. package/dist/entry/store-kit.js +25 -0
  309. package/dist/entry/testing.d.ts +6 -0
  310. package/dist/entry/testing.js +7 -0
  311. package/dist/eval/eval-suite.js +17 -11
  312. package/dist/eval/eval.js +1 -1
  313. package/dist/eval/judgment.js +12 -5
  314. package/dist/graph/extract.js +3 -3
  315. package/dist/graph/recall.js +1 -1
  316. package/dist/graph/view.js +13 -5
  317. package/dist/graph/write.d.ts +1 -1
  318. package/dist/graph/write.js +9 -9
  319. package/dist/hooks/codex-session.js +3 -2
  320. package/dist/hooks/codex-wrapper.js +2 -1
  321. package/dist/hooks/json-hooks.js +10 -4
  322. package/dist/hooks/opencode.js +8 -5
  323. package/dist/hooks/shared.d.ts +0 -6
  324. package/dist/hooks/shared.js +4 -15
  325. package/dist/importers/core.js +4 -4
  326. package/dist/importers/sources.js +5 -4
  327. package/dist/importers/vault.d.ts +1 -1
  328. package/dist/importers/vault.js +25 -23
  329. package/dist/index.d.ts +5 -4
  330. package/dist/index.js +4 -3
  331. package/dist/learn/autolearn.d.ts +15 -3
  332. package/dist/learn/autolearn.js +38 -16
  333. package/dist/learn/churn-git.js +13 -4
  334. package/dist/learn/extract.d.ts +3 -2
  335. package/dist/learn/extract.js +7 -5
  336. package/dist/learn/forward-claim-detector.js +4 -2
  337. package/dist/learn/invalidation.d.ts +2 -1
  338. package/dist/learn/invalidation.js +18 -9
  339. package/dist/mcp/admin-tools.d.ts +2 -2
  340. package/dist/mcp/admin-tools.js +27 -48
  341. package/dist/mcp/format.js +3 -2
  342. package/dist/mcp/framing.d.ts +1 -0
  343. package/dist/mcp/framing.js +1 -1
  344. package/dist/mcp/memory-tools.d.ts +1 -1
  345. package/dist/mcp/memory-tools.js +8 -9
  346. package/dist/mcp/protocol.d.ts +11 -7
  347. package/dist/mcp/protocol.js +25 -12
  348. package/dist/mcp/recall-tools.js +12 -9
  349. package/dist/mcp/request.js +22 -20
  350. package/dist/mcp/stdio.js +37 -16
  351. package/dist/mcp/tool-args.js +2 -1
  352. package/dist/mcp/tools.js +44 -21
  353. package/dist/objects/customer-notes.d.ts +2 -2
  354. package/dist/objects/decisions.d.ts +2 -2
  355. package/dist/objects/descriptor.d.ts +1 -1
  356. package/dist/objects/incidents.d.ts +2 -2
  357. package/dist/objects/lifecycle.d.ts +1 -1
  358. package/dist/objects/lifecycle.js +2 -1
  359. package/dist/objects/policies.d.ts +2 -2
  360. package/dist/objects/policies.js +2 -1
  361. package/dist/objects/processes.d.ts +2 -2
  362. package/dist/objects/project-briefs.d.ts +2 -2
  363. package/dist/objects/project-briefs.js +2 -3
  364. package/dist/objects/skills.d.ts +2 -2
  365. package/dist/postinstall.js +1 -1
  366. package/dist/rerankers/clef.js +3 -6
  367. package/dist/rerankers/cross-encoder.d.ts +31 -2
  368. package/dist/rerankers/cross-encoder.js +71 -98
  369. package/dist/rerankers/index.js +5 -4
  370. package/dist/rerankers/jev.js +2 -4
  371. package/dist/rerankers/outage-warning.d.ts +3 -1
  372. package/dist/rerankers/outage-warning.js +5 -3
  373. package/dist/search/bm25-search.js +1 -1
  374. package/dist/search/boosts.js +1 -1
  375. package/dist/search/embed-memories.d.ts +12 -0
  376. package/dist/search/embed-memories.js +389 -0
  377. package/dist/search/engine.d.ts +8 -0
  378. package/dist/search/engine.js +10 -0
  379. package/dist/search/goal-boost.d.ts +1 -1
  380. package/dist/search/goal-boost.js +6 -3
  381. package/dist/search/hybrid.d.ts +9 -2
  382. package/dist/search/hybrid.js +9 -4
  383. package/dist/search/physics-search.d.ts +6 -3
  384. package/dist/search/physics-search.js +22 -15
  385. package/dist/search/rerank.js +1 -1
  386. package/dist/search/vector.d.ts +8 -6
  387. package/dist/search/vector.js +14 -17
  388. package/dist/server/auth.d.ts +3 -1
  389. package/dist/server/auth.js +24 -15
  390. package/dist/server/boot.d.ts +2 -1
  391. package/dist/server/boot.js +34 -84
  392. package/dist/server/client-ip.d.ts +9 -6
  393. package/dist/server/client-ip.js +36 -17
  394. package/dist/server/deadline.d.ts +0 -2
  395. package/dist/server/deadline.js +1 -7
  396. package/dist/server/defaults.d.ts +1 -0
  397. package/dist/server/defaults.js +1 -0
  398. package/dist/server/mcp-http.js +16 -11
  399. package/dist/server/request.js +7 -2
  400. package/dist/server/route-checks.d.ts +7 -0
  401. package/dist/server/route-checks.js +42 -0
  402. package/dist/server/route-table.d.ts +9 -8
  403. package/dist/server/route-table.js +127 -133
  404. package/dist/server/routes/admin.d.ts +8 -8
  405. package/dist/server/routes/admin.js +13 -21
  406. package/dist/server/routes/customer-notes.d.ts +6 -6
  407. package/dist/server/routes/customer-notes.js +1 -2
  408. package/dist/server/routes/decisions.d.ts +6 -6
  409. package/dist/server/routes/decisions.js +2 -4
  410. package/dist/server/routes/incidents.d.ts +6 -6
  411. package/dist/server/routes/incidents.js +2 -5
  412. package/dist/server/routes/memories.d.ts +9 -9
  413. package/dist/server/routes/memories.js +19 -40
  414. package/dist/server/routes/object-routes.d.ts +6 -6
  415. package/dist/server/routes/object-routes.js +4 -7
  416. package/dist/server/routes/policies.d.ts +7 -7
  417. package/dist/server/routes/policies.js +2 -4
  418. package/dist/server/routes/predictions.d.ts +6 -6
  419. package/dist/server/routes/predictions.js +9 -13
  420. package/dist/server/routes/processes.d.ts +6 -6
  421. package/dist/server/routes/processes.js +1 -2
  422. package/dist/server/routes/project-briefs.d.ts +7 -7
  423. package/dist/server/routes/project-briefs.js +2 -4
  424. package/dist/server/routes/recall.d.ts +5 -5
  425. package/dist/server/routes/recall.js +6 -10
  426. package/dist/server/routes/skills.d.ts +7 -7
  427. package/dist/server/routes/skills.js +2 -4
  428. package/dist/server/server-detect.d.ts +7 -1
  429. package/dist/server/server-detect.js +36 -11
  430. package/dist/server/sleep-child.js +26 -7
  431. package/dist/server/sleep-offload.d.ts +11 -5
  432. package/dist/server/sleep-offload.js +17 -11
  433. package/dist/server/tls.d.ts +7 -2
  434. package/dist/server/tls.js +17 -5
  435. package/dist/server/types.d.ts +29 -12
  436. package/dist/server/validation.d.ts +1 -2
  437. package/dist/server/validation.js +6 -11
  438. package/dist/server.d.ts +4 -40
  439. package/dist/server.js +3 -29
  440. package/dist/sharing/global-store.d.ts +4 -5
  441. package/dist/sharing/global-store.js +8 -13
  442. package/dist/sharing/global-sync.js +38 -45
  443. package/dist/sharing/project-merge.d.ts +7 -14
  444. package/dist/sharing/project-merge.js +57 -121
  445. package/dist/sharing/search-both.js +10 -3
  446. package/dist/sharing/share.d.ts +2 -0
  447. package/dist/sharing/share.js +39 -38
  448. package/dist/store/ambient.js +7 -7
  449. package/dist/store/audit-event.d.ts +1 -1
  450. package/dist/store/audit.d.ts +0 -16
  451. package/dist/store/audit.js +4 -55
  452. package/dist/store/auth.d.ts +4 -2
  453. package/dist/store/auth.js +7 -3
  454. package/dist/store/candidates.d.ts +3 -2
  455. package/dist/store/candidates.js +59 -30
  456. package/dist/store/capture-write.d.ts +17 -0
  457. package/dist/store/capture-write.js +35 -0
  458. package/dist/store/cards.js +6 -5
  459. package/dist/store/compaction-caller.d.ts +18 -0
  460. package/dist/store/compaction-caller.js +29 -0
  461. package/dist/store/compactions-record.d.ts +115 -0
  462. package/dist/store/compactions-record.js +418 -0
  463. package/dist/store/compactions.js +6 -4
  464. package/dist/store/conflicts.d.ts +7 -1
  465. package/dist/store/conflicts.js +13 -9
  466. package/dist/store/connectors/dlq.d.ts +10 -0
  467. package/dist/store/connectors/dlq.js +33 -0
  468. package/dist/store/connectors/event-log.d.ts +13 -0
  469. package/dist/store/connectors/event-log.js +24 -0
  470. package/dist/store/connectors/github.d.ts +7 -9
  471. package/dist/store/connectors/github.js +35 -60
  472. package/dist/store/connectors/slack.d.ts +2 -11
  473. package/dist/store/connectors/slack.js +24 -57
  474. package/dist/store/dashboard-reads.js +8 -6
  475. package/dist/store/delete-and-batch.d.ts +6 -0
  476. package/dist/store/delete-and-batch.js +40 -6
  477. package/dist/store/delivery-recorder.d.ts +12 -5
  478. package/dist/store/delivery-recorder.js +13 -11
  479. package/dist/store/descendant-page.js +8 -4
  480. package/dist/store/dormant.d.ts +1 -1
  481. package/dist/store/dormant.js +10 -4
  482. package/dist/store/embeddings/index.d.ts +2 -12
  483. package/dist/store/embeddings/index.js +5 -374
  484. package/dist/store/entry-reads.d.ts +35 -4
  485. package/dist/store/entry-reads.js +86 -19
  486. package/dist/store/entry-row.js +9 -2
  487. package/dist/store/entry-writes.d.ts +15 -12
  488. package/dist/store/entry-writes.js +54 -22
  489. package/dist/store/failure-log-at.d.ts +8 -0
  490. package/dist/store/failure-log-at.js +16 -0
  491. package/dist/store/failure-log.d.ts +2 -2
  492. package/dist/store/failure-log.js +5 -3
  493. package/dist/{trust → store}/gated-write.d.ts +3 -1
  494. package/dist/{trust → store}/gated-write.js +7 -5
  495. package/dist/store/goals.js +22 -19
  496. package/dist/store/graph-reads.js +9 -6
  497. package/dist/store/graph-view-rows.js +2 -1
  498. package/dist/store/graph-writes.d.ts +6 -6
  499. package/dist/store/graph-writes.js +48 -71
  500. package/dist/store/half-life.js +2 -2
  501. package/dist/store/handoffs.d.ts +10 -4
  502. package/dist/store/handoffs.js +10 -9
  503. package/dist/store/index-and-stats.js +2 -2
  504. package/dist/store/index.d.ts +2 -2
  505. package/dist/store/index.js +1 -1
  506. package/dist/store/key-writes.js +1 -1
  507. package/dist/store/ledger-turn.d.ts +9 -0
  508. package/dist/store/ledger-turn.js +38 -0
  509. package/dist/store/mirrors.js +19 -10
  510. package/dist/store/open.d.ts +2 -5
  511. package/dist/store/open.js +42 -54
  512. package/dist/store/pilot-arm.d.ts +12 -0
  513. package/dist/store/pilot-arm.js +42 -0
  514. package/dist/store/port.d.ts +68 -6
  515. package/dist/store/port.js +8 -0
  516. package/dist/store/predictions.d.ts +1 -2
  517. package/dist/store/predictions.js +3 -6
  518. package/dist/store/project-tags.d.ts +62 -0
  519. package/dist/store/project-tags.js +67 -0
  520. package/dist/store/quality-repair.js +1 -1
  521. package/dist/store/quarantine.js +2 -1
  522. package/dist/store/recall-trace.d.ts +2 -0
  523. package/dist/store/recall-trace.js +20 -3
  524. package/dist/store/rejected-values.js +16 -10
  525. package/dist/store/rejection-probe.d.ts +4 -0
  526. package/dist/store/rejection-probe.js +19 -0
  527. package/dist/store/rejection.d.ts +0 -17
  528. package/dist/store/rejection.js +1 -21
  529. package/dist/store/rows.js +2 -2
  530. package/dist/store/rule-sql.d.ts +11 -0
  531. package/dist/store/rule-sql.js +31 -6
  532. package/dist/store/search-rows.d.ts +5 -5
  533. package/dist/store/search-rows.js +18 -16
  534. package/dist/store/sessions.js +4 -2
  535. package/dist/store/set-aside.d.ts +14 -0
  536. package/dist/store/set-aside.js +23 -0
  537. package/dist/store/sqlite/busy.d.ts +3 -0
  538. package/dist/store/sqlite/busy.js +8 -0
  539. package/dist/store/sqlite/connector-events-group.js +4 -7
  540. package/dist/store/sqlite/connector-writes-group.js +6 -4
  541. package/dist/store/sqlite/entry-writes-group.d.ts +3 -3
  542. package/dist/store/sqlite/entry-writes-group.js +3 -3
  543. package/dist/store/sqlite/error-codec.js +4 -3
  544. package/dist/store/sqlite/executor.js +10 -4
  545. package/dist/store/sqlite/graph-reads-group.js +1 -1
  546. package/dist/store/sqlite/held-connection.d.ts +11 -0
  547. package/dist/store/sqlite/held-connection.js +41 -0
  548. package/dist/store/sqlite/last-recall-group.d.ts +13 -0
  549. package/dist/store/sqlite/last-recall-group.js +57 -0
  550. package/dist/store/sqlite/local.d.ts +0 -17
  551. package/dist/store/sqlite/local.js +0 -31
  552. package/dist/store/sqlite/maintenance-groups.d.ts +6 -0
  553. package/dist/store/sqlite/maintenance-groups.js +60 -0
  554. package/dist/store/sqlite/object-rows.d.ts +1 -1
  555. package/dist/store/sqlite/objects-group.d.ts +1 -1
  556. package/dist/store/sqlite/objects-group.js +15 -7
  557. package/dist/store/sqlite/store.d.ts +1 -8
  558. package/dist/store/sqlite/store.js +13 -22
  559. package/dist/store/summaries.d.ts +10 -3
  560. package/dist/store/summaries.js +54 -11
  561. package/dist/store/token-ledger-rows.js +3 -2
  562. package/dist/store/token-ledger.d.ts +0 -7
  563. package/dist/store/token-ledger.js +0 -35
  564. package/dist/store/vector-index.js +8 -4
  565. package/dist/support-bundle.js +2 -3
  566. package/dist/trust/reject-flow.js +2 -2
  567. package/dist/util/agent-homes.d.ts +15 -0
  568. package/dist/util/agent-homes.js +34 -0
  569. package/dist/util/anthropic-messages.d.ts +6 -1
  570. package/dist/util/anthropic-messages.js +26 -7
  571. package/dist/util/atomic-write.d.ts +5 -2
  572. package/dist/util/atomic-write.js +12 -8
  573. package/dist/util/chunked.d.ts +3 -0
  574. package/dist/util/chunked.js +10 -0
  575. package/dist/util/ellipsize.d.ts +3 -0
  576. package/dist/util/ellipsize.js +5 -0
  577. package/dist/util/env.d.ts +12 -2
  578. package/dist/util/env.js +12 -2
  579. package/dist/util/format.d.ts +5 -0
  580. package/dist/util/format.js +10 -0
  581. package/dist/util/hook-payload.d.ts +8 -0
  582. package/dist/util/hook-payload.js +37 -0
  583. package/dist/util/http-retry.d.ts +6 -0
  584. package/dist/util/http-retry.js +43 -5
  585. package/dist/util/http-util.d.ts +0 -8
  586. package/dist/util/http-util.js +10 -21
  587. package/dist/util/limits.d.ts +7 -0
  588. package/dist/util/limits.js +14 -0
  589. package/dist/util/log.d.ts +4 -0
  590. package/dist/util/log.js +9 -0
  591. package/dist/util/request-scope.d.ts +9 -3
  592. package/dist/util/request-scope.js +18 -9
  593. package/dist/util/secret-detect.js +6 -1
  594. package/dist/util/spawn-argv.d.ts +9 -0
  595. package/dist/util/spawn-argv.js +57 -0
  596. package/dist/util/sql.d.ts +3 -0
  597. package/dist/util/sql.js +6 -0
  598. package/dist/util/sqlite-blocked.d.ts +2 -0
  599. package/dist/util/sqlite-blocked.js +5 -0
  600. package/dist/util/stream-tee.d.ts +3 -0
  601. package/dist/util/stream-tee.js +35 -0
  602. package/dist/util/time.d.ts +4 -0
  603. package/dist/util/time.js +4 -0
  604. package/dist/util/vector-codec.d.ts +4 -0
  605. package/dist/util/vector-codec.js +15 -0
  606. package/dist/util/version.d.ts +1 -1
  607. package/dist/util/version.js +1 -1
  608. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  609. package/extensions/openclaw-plugin/package.json +1 -1
  610. package/openclaw.plugin.json +1 -1
  611. package/package.json +4 -2
  612. package/dist/api/on-store.d.ts +0 -16
  613. package/dist/api/on-store.js +0 -38
  614. package/dist/store/embeddings/local.d.ts +0 -15
  615. package/dist/store/embeddings/local.js +0 -175
  616. /package/dist/{cli → api}/correction-latency.d.ts +0 -0
  617. /package/dist/{cli → api}/correction-latency.js +0 -0
  618. /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
  619. /package/dist/{cli → api}/provenance-coverage.js +0 -0
  620. /package/dist/{store → core}/object-types.d.ts +0 -0
  621. /package/dist/{store → core}/object-types.js +0 -0
  622. /package/dist/{capture → util}/compaction-items.d.ts +0 -0
  623. /package/dist/{capture → util}/compaction-items.js +0 -0
  624. /package/dist/{store → util}/yaml.d.ts +0 -0
  625. /package/dist/{store → util}/yaml.js +0 -0
@@ -0,0 +1,7 @@
1
+ // Test seams for add-ons and hippo's own suite. Not for production code; no semver guarantee beyond the major version.
2
+ export { _resetAblationCacheForTests } from '../core/ablation.js';
3
+ export { _resetSharedStoreCacheForTests } from '../core/config.js';
4
+ export { _resetLossAversionRatioCacheForTests } from '../core/memory.js';
5
+ export { _resetSessionRecallHistoryMcpForTests } from '../mcp/session-state.js';
6
+ export { __resetSessionRecallHistoryHttp } from '../server/routes/recall.js';
7
+ //# sourceMappingURL=testing.js.map
@@ -5,6 +5,7 @@ import { search } from '../search/bm25-search.js';
5
5
  import { multihopSearch } from '../search/multihop.js';
6
6
  import { mrr, recallAtK, ndcgAtK } from './eval.js';
7
7
  import { DAY_MS } from '../util/time.js';
8
+ import { pct } from '../util/format.js';
8
9
  const BASE_DATE = new Date('2026-01-15T10:00:00Z');
9
10
  function dateOffset(days) {
10
11
  const d = new Date(BASE_DATE.getTime() + days * DAY_MS);
@@ -51,19 +52,24 @@ function addDirectRecall(entries, cases) {
51
52
  }
52
53
  /** Extraction preference: extracted facts should rank above raw source. */
53
54
  function addExtractionPreference(entries, cases) {
54
- entries.push(mem('ep-src-1', 'speaker:Alice: So we had this big meeting yesterday about the deployment pipeline and Bob mentioned that the staging environment is using Kubernetes 1.28 and we should upgrade to 1.30 before the end of Q2 because of the security patches', {
55
+ entries.push(mem('ep-src-1', 'speaker:Alice: So we had this big meeting yesterday about the deployment pipeline and Bob mentioned that the staging environment is ' +
56
+ 'using Kubernetes 1.28 and we should upgrade to 1.30 before the end of Q2 because of the security patches', {
55
57
  created: dateOffset(10), tags: ['speaker:Alice', 'topic:infrastructure', 'session:meeting-1'],
56
58
  }), mem('ep-ext-1', 'The staging environment runs Kubernetes 1.28 and needs to be upgraded to 1.30 before end of Q2 for security patches', {
57
59
  created: dateOffset(10), layer: Layer.Semantic, tags: ['speaker:Alice', 'topic:infrastructure', 'extracted'],
58
60
  extracted_from: 'ep-src-1',
59
- }), mem('ep-src-2', 'speaker:Bob: Yeah and the thing about the monitoring is that we switched from Datadog to Grafana last month and the alerting rules still need to be migrated, Carol was supposed to handle that but she has been busy with the frontend rewrite', {
61
+ }), mem('ep-src-2', 'speaker:Bob: Yeah and the thing about the monitoring is that we switched from Datadog to Grafana last month and the alerting rules ' +
62
+ 'still need to be migrated, Carol was supposed to handle that but she has been busy with the frontend rewrite', {
60
63
  created: dateOffset(11), tags: ['speaker:Bob', 'topic:monitoring', 'session:meeting-1'],
61
- }), mem('ep-ext-2', 'The team switched from Datadog to Grafana last month but alerting rules have not been migrated yet. Carol is responsible but blocked by the frontend rewrite.', {
64
+ }), mem('ep-ext-2', 'The team switched from Datadog to Grafana last month but alerting rules have not been migrated yet. Carol is responsible but blocked ' +
65
+ 'by the frontend rewrite.', {
62
66
  created: dateOffset(11), layer: Layer.Semantic, tags: ['speaker:Bob', 'topic:monitoring', 'extracted'],
63
67
  extracted_from: 'ep-src-2',
64
- }), mem('ep-src-3', 'speaker:Carol: The login page redesign is almost done, I just need to wire up the OAuth2 PKCE flow with the new identity provider and write the integration tests', {
68
+ }), mem('ep-src-3', 'speaker:Carol: The login page redesign is almost done, I just need to wire up the OAuth2 PKCE flow with the new identity provider and ' +
69
+ 'write the integration tests', {
65
70
  created: dateOffset(12), tags: ['speaker:Carol', 'topic:auth', 'session:meeting-2'],
66
- }), mem('ep-ext-3', 'Carol is nearly done with the login page redesign. Remaining work: wire up OAuth2 PKCE flow with the new identity provider and write integration tests.', {
71
+ }), mem('ep-ext-3', 'Carol is nearly done with the login page redesign. Remaining work: wire up OAuth2 PKCE flow with the new identity provider and write ' +
72
+ 'integration tests.', {
67
73
  created: dateOffset(12), layer: Layer.Semantic, tags: ['speaker:Carol', 'topic:auth', 'extracted'],
68
74
  extracted_from: 'ep-src-3',
69
75
  }));
@@ -89,7 +95,8 @@ function addDagDrilldown(entries, cases) {
89
95
  }), mem('dag-child-3', 'Batch API endpoint /reports/generate takes 8 seconds because it runs synchronously instead of using a job queue', {
90
96
  created: dateOffset(15), layer: Layer.Semantic, tags: ['topic:api-performance', 'extracted'],
91
97
  dag_level: 1,
92
- }), mem('dag-summary-1', 'API performance issues: /users degraded to 300ms (permissions check), /orders spiked to 500ms (missing index), /reports takes 8s (needs job queue)', {
98
+ }), mem('dag-summary-1', 'API performance issues: /users degraded to 300ms (permissions check), /orders spiked to 500ms (missing index), /reports takes 8s ' +
99
+ '(needs job queue)', {
93
100
  created: dateOffset(16), layer: Layer.Semantic, tags: ['topic:api-performance'],
94
101
  dag_level: 2, dag_parent_id: undefined,
95
102
  }));
@@ -171,7 +178,8 @@ function addMultiHop(entries, cases) {
171
178
  created: dateOffset(26), tags: ['speaker:Bob', 'topic:payments'],
172
179
  }), mem('mh-3', 'speaker:Alice fixed the Stripe webhook by switching to the production secret key. Payment confirmations now arrive within 2 seconds.', {
173
180
  created: dateOffset(27), tags: ['speaker:Alice', 'topic:payments'],
174
- }), mem('mh-4', 'speaker:Carol reported that the billing dashboard shows incorrect revenue numbers because it reads from the payments_raw table instead of payments_reconciled.', {
181
+ }), mem('mh-4', 'speaker:Carol reported that the billing dashboard shows incorrect revenue numbers because it reads from the payments_raw table instead of ' +
182
+ 'payments_reconciled.', {
175
183
  created: dateOffset(28), tags: ['speaker:Carol', 'topic:billing'],
176
184
  }));
177
185
  cases.push({
@@ -286,9 +294,6 @@ export function resultToBaseline(result) {
286
294
  overall: result.overall,
287
295
  };
288
296
  }
289
- function pct(n) {
290
- return (n * 100).toFixed(1) + '%';
291
- }
292
297
  function pad(s, w) {
293
298
  return s.padEnd(w);
294
299
  }
@@ -315,7 +320,8 @@ export function formatResult(result, baseline) {
315
320
  vsBaseline = deltaStr(delta);
316
321
  verdict = delta < -REGRESSION_THRESHOLD ? 'REGRESS' : 'PASS';
317
322
  }
318
- lines.push(`${pad(feat.category, 24)} | ${pad(pct(feat.mrr), 8)} | ${pad(pct(feat.recallAt5), 8)} | ${pad(pct(feat.ndcgAt5), 8)} | ${pad(vsBaseline, 12)} | ${verdict}`);
323
+ const cells = [pad(feat.category, 24), pad(pct(feat.mrr), 8), pad(pct(feat.recallAt5), 8), pad(pct(feat.ndcgAt5), 8), pad(vsBaseline, 12), verdict];
324
+ lines.push(cells.join(' | '));
319
325
  }
320
326
  lines.push('');
321
327
  lines.push(`Overall: MRR ${pct(result.overall.mrr)} | R@5 ${pct(result.overall.recallAt5)} | NDCG@5 ${pct(result.overall.ndcgAt5)}`);
package/dist/eval/eval.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * It exists so MMR lambda, embedding weights and scoring tweaks are tuned against evidence instead of intuition. */
3
3
  import { hybridSearch } from '../search/hybrid.js';
4
4
  import { searchBothHybrid } from '../sharing/search-both.js';
5
- import { isInitialized } from '../store/open.js';
5
+ import { isInitialized } from '../core/project-identity.js';
6
6
  // Generous so metrics are not truncated.
7
7
  const DEFAULT_EVAL_BUDGET = 100_000;
8
8
  const QUERY_WORDS = 8;
@@ -2,7 +2,7 @@
2
2
  * Regex picks WHAT is a candidate; it cannot say what is worth keeping, so
3
3
  * every captured memory currently lands on a flat schema_fit of 0.5. */
4
4
  import { fetchWithRetry } from '../util/http-retry.js';
5
- import { errorMessage, log } from '../util/log.js';
5
+ import { errorFields, errorMessage, log } from '../util/log.js';
6
6
  import { readCappedJson } from '../util/capped-json.js';
7
7
  import { isJsonNumber, isJsonObject, isJsonString } from '../util/json.js';
8
8
  const ENDPOINT = 'https://api.typesafe.ai/v1/systemone';
@@ -19,7 +19,9 @@ function answerNamed(reply, name) {
19
19
  const QUESTIONS = {
20
20
  durable: {
21
21
  type: 'noul',
22
- instructions: 'This text was extracted from an AI coding agent transcript as a candidate memory. It is worth storing long-term only if it would still be useful to a future agent working on this codebase weeks from now: a durable preference, a convention, a decision with a reason, or a gotcha that will recur. Transient chatter, one-off status, restatements of code already in the repo, and anything only true inside this one session are not worth storing.',
22
+ instructions: 'This text was extracted from an AI coding agent transcript as a candidate memory. It is worth storing long-term only if it would still be useful to ' +
23
+ 'a future agent working on this codebase weeks from now: a durable preference, a convention, a decision with a reason, or a gotcha that will recur. ' +
24
+ 'Transient chatter, one-off status, restatements of code already in the repo, and anything only true inside this one session are not worth storing.',
23
25
  },
24
26
  kind: {
25
27
  type: 'choice',
@@ -73,10 +75,15 @@ async function post(content, opts) {
73
75
  }, { timeoutMs: JUDGE_TIMEOUT_MS, fetchFn: opts.fetcher });
74
76
  }
75
77
  catch (err) {
76
- log.debug(`judge: request failed: ${errorMessage(err)}`);
78
+ log.warn(`judge: request failed: ${errorMessage(err)}`, errorFields(err));
77
79
  return null;
78
80
  }
79
- return res.ok ? res : null;
81
+ if (res.ok)
82
+ return res;
83
+ // The body is the server's reply, never the request, so it cannot hold the key.
84
+ const snippet = (await res.text().catch(() => '')).slice(0, 200);
85
+ log.warn('judge: non-2xx reply', { status: res.status, body: snippet });
86
+ return null;
80
87
  }
81
88
  /** `null` on any failure, so a Jev outage degrades capture to today's
82
89
  * behaviour instead of blocking the write. */
@@ -92,7 +99,7 @@ async function judge(content, opts) {
92
99
  data = await readCappedJson(res, JUDGE_MAX_REPLY_BYTES);
93
100
  }
94
101
  catch (err) {
95
- log.debug(`judge: unreadable response: ${errorMessage(err)}`);
102
+ log.warnThenDebug('judge-unreadable', `judge: unreadable response: ${errorMessage(err)}`, errorFields(err));
96
103
  return null;
97
104
  }
98
105
  const durable = answerNamed(data, 'durable').noul;
@@ -101,7 +101,7 @@ function deriveEntities(loaded) {
101
101
  pass.byType[entityType] = 0;
102
102
  for (const row of rows) {
103
103
  pass.allRows.push(row);
104
- // Names are uncapped at source; trimming on both sides of the cap gives the exact name insertEntity stores.
104
+ // Names are uncapped at source; trimming on both sides of the cap gives the exact name insertEntityRow stores.
105
105
  const name = (row.name ?? '').trim().slice(0, MAX_ENTITY_NAME_LEN).trim();
106
106
  const key = keyOf(row.entityType, row.e2Id);
107
107
  // A row seen twice was superseded between the two status loads; its first sighting stands.
@@ -220,7 +220,7 @@ export function extractGraph(hippoRoot, tenantId) {
220
220
  // Loaded first: opening a second connection under the rebuild's BEGIN IMMEDIATE dead-locks ('database is locked').
221
221
  const derived = deriveGraph(loadGraphSources(hippoRoot, tenantId));
222
222
  // Diffed and applied under one lock, so two concurrent rebuilds serialize instead of both inserting a missing row.
223
- const skipped = runGraphRebuildTransaction(hippoRoot, tenantId, (txDb) => applyGraphOps(txDb, hippoRoot, tenantId, graphDelta(txDb, tenantId, derived), { from: 0, holdMs: Infinity }).skipped);
223
+ const skipped = runGraphRebuildTransaction(hippoRoot, tenantId, (txDb) => applyGraphOps(txDb, tenantId, graphDelta(txDb, tenantId, derived), { from: 0, holdMs: Infinity }).skipped);
224
224
  return resultOf(derived, skipped);
225
225
  }
226
226
  /** extractGraph for sleep: diffs outside the lock, then applies in transactions of about `budget.holdMs` with a pause
@@ -237,7 +237,7 @@ export async function extractGraphChunked(hippoRoot, tenantId, budget = WRITE_BU
237
237
  await budget.pause(committedAt);
238
238
  const from = next;
239
239
  // Sleep's wait, not a server request's 250 ms: each chunk is a fresh BEGIN IMMEDIATE a hook's write could otherwise fail.
240
- const chunk = runGraphRebuildTransaction(hippoRoot, tenantId, (txDb) => applyGraphOps(txDb, hippoRoot, tenantId, ops, { from, holdMs: budget.holdMs, clock: budget.clock }), { busyWaitMs: SLEEP_DB_WAIT_MS });
240
+ const chunk = runGraphRebuildTransaction(hippoRoot, tenantId, (txDb) => applyGraphOps(txDb, tenantId, ops, { from, holdMs: budget.holdMs, clock: budget.clock }), { busyWaitMs: SLEEP_DB_WAIT_MS });
241
241
  committedAt = budget.clock();
242
242
  next = chunk.next;
243
243
  skipped += chunk.skipped;
@@ -6,7 +6,7 @@ import { DEFAULT_RECALL_BUDGET } from '../core/search-types.js';
6
6
  import { estimateTokens } from '../util/token-text.js';
7
7
  import { compareEntryIdentity, compareScoresDesc } from '../core/compare.js';
8
8
  import { loadEntitiesByMemoryId, loadEntitiesByIds, loadNeighborRelations } from '../store/graph-reads.js';
9
- import { passesCliRecallScopeFilter, passesScopeFilterForRecall } from '../store/recall-scope.js';
9
+ import { passesCliRecallScopeFilter, passesScopeFilterForRecall } from '../core/recall-scope.js';
10
10
  /** Hard cap on `--hops` (a higher value just walks more of a finite graph; this bounds
11
11
  * worst-case work and keeps the flag honest). */
12
12
  export const MAX_HOPS = 3;
@@ -146,15 +146,23 @@ const CLIENT_JS = [
146
146
  " var panning=false,sx=0,sy=0;",
147
147
  " svg.addEventListener('mousedown',function(e){if(e.target.closest('.node'))return;panning=true;sx=e.clientX;sy=e.clientY;});",
148
148
  " window.addEventListener('mouseup',function(){panning=false;});",
149
- " window.addEventListener('mousemove',function(e){if(!panning)return;var r=svg.getBoundingClientRect();var k=view.w/r.width;view.x-=(e.clientX-sx)*k;view.y-=(e.clientY-sy)*k;sx=e.clientX;sy=e.clientY;apply();});",
150
- " svg.addEventListener('wheel',function(e){e.preventDefault();var r=svg.getBoundingClientRect();var mx=view.x+(e.clientX-r.left)/r.width*view.w;var my=view.y+(e.clientY-r.top)/r.height*view.h;var f=e.deltaY<0?0.9:1.1;view.x=mx-(mx-view.x)*f;view.y=my-(my-view.y)*f;view.w*=f;view.h*=f;apply();},{passive:false});",
151
- " var data={};try{data=JSON.parse(document.getElementById('graph-data').textContent);}catch(_){}",
149
+ " window.addEventListener('mousemove',function(e){if(!panning)return;var r=svg.getBoundingClientRect();var " +
150
+ "k=view.w/r.width;view.x-=(e.clientX-sx)*k;view.y-=(e.clientY-sy)*k;sx=e.clientX;sy=e.clientY;apply();});",
151
+ " svg.addEventListener('wheel',function(e){e.preventDefault();var r=svg.getBoundingClientRect();var mx=view.x+(e.clientX-r.left)/r.width*view.w;var " +
152
+ "my=view.y+(e.clientY-r.top)/r.height*view.h;var " +
153
+ "f=e.deltaY<0?0.9:1.1;view.x=mx-(mx-view.x)*f;view.y=my-(my-view.y)*f;view.w*=f;view.h*=f;apply();},{passive:false});",
154
+ " var data={};try{data=JSON.parse(document.getElementById('graph-data').textContent);}",
155
+ " catch(e){console.error('hippo graph: embedded model is not valid JSON',e);}",
152
156
  " var adj={};(data.edges||[]).forEach(function(e){(adj[e.from]=adj[e.from]||[]).push(e.to);(adj[e.to]=adj[e.to]||[]).push(e.from);});",
153
157
  " var active=null;",
154
- " document.querySelectorAll('.node').forEach(function(g){g.addEventListener('click',function(ev){ev.stopPropagation();var id=g.getAttribute('data-id');if(active===id){clearHi();active=null;return;}active=id;highlight(id);});});",
158
+ " document.querySelectorAll('.node').forEach(function(g){g.addEventListener('click',function(ev){ev.stopPropagation();var " +
159
+ "id=g.getAttribute('data-id');if(active===id){clearHi();active=null;return;}active=id;highlight(id);});});",
155
160
  " svg.addEventListener('click',function(){clearHi();active=null;});",
156
161
  " function clearHi(){svg.classList.remove('focused');document.querySelectorAll('.hi').forEach(function(el){el.classList.remove('hi');});}",
157
- " function highlight(id){clearHi();svg.classList.add('focused');var keep={};keep[id]=1;(adj[id]||[]).forEach(function(n){keep[n]=1;});document.querySelectorAll('.node').forEach(function(g){if(keep[g.getAttribute('data-id')])g.classList.add('hi');});document.querySelectorAll('.edge').forEach(function(l){if(l.getAttribute('data-from')===id||l.getAttribute('data-to')===id)l.classList.add('hi');});}",
162
+ " function highlight(id){clearHi();svg.classList.add('focused');var " +
163
+ "keep={};keep[id]=1;(adj[id]||[]).forEach(function(n){keep[n]=1;});document.querySelectorAll('.node').forEach(" +
164
+ "function(g){if(keep[g.getAttribute('data-id')])g.classList.add('hi');});document.querySelectorAll('.edge').forEach(" +
165
+ "function(l){if(l.getAttribute('data-from')===id||l.getAttribute('data-to')===id)l.classList.add('hi');});}",
158
166
  "})();",
159
167
  ].join("\n");
160
168
  const STYLE = [
@@ -6,7 +6,7 @@ export interface ApplyGraphOpsResult {
6
6
  }
7
7
  /** Applies `ops` from index `opts.from` on the caller's open transaction and stops at the first op boundary past `opts.holdMs`.
8
8
  * Returns where the next chunk starts and how many ops were skipped as stale. */
9
- export declare function applyGraphOps(db: DatabaseSyncLike, hippoRoot: string, tenantId: string, ops: readonly GraphOp[], opts: {
9
+ export declare function applyGraphOps(db: DatabaseSyncLike, tenantId: string, ops: readonly GraphOp[], opts: {
10
10
  readonly from: number;
11
11
  readonly holdMs: number;
12
12
  readonly clock?: () => number;
@@ -1,19 +1,19 @@
1
1
  // Applies a rebuild's op list on the caller's transaction. The statements and the consolidated-source guard sit in the store's graph writers.
2
2
  import { assertTenantId } from '../store/tenant.js';
3
3
  import { clock } from '../util/write-budget.js';
4
- import { deleteEntityRow, deleteRelationRow, entityIdBySource, insertEntity, insertRelation, objectInForce, relationPresent, updateEntity } from '../store/graph-writes.js';
5
- function insertDesiredRelation(db, hippoRoot, tenantId, rel) {
4
+ import { deleteEntityRow, deleteRelationRow, entityIdBySource, insertEntityRow, insertRelationRow, objectInForce, relationPresent, updateEntityRow } from '../store/graph-writes.js';
5
+ function insertDesiredRelation(db, tenantId, rel) {
6
6
  const fromEntityId = entityIdBySource(db, tenantId, rel.from.entityType, rel.from.sourceObject);
7
7
  const toEntityId = entityIdBySource(db, tenantId, rel.to.entityType, rel.to.sourceObject);
8
8
  if (fromEntityId === undefined || toEntityId === undefined || !objectInForce(db, tenantId, rel.sourceObject))
9
9
  return false;
10
10
  if (relationPresent(db, tenantId, fromEntityId, toEntityId, rel.relType))
11
11
  return false;
12
- insertRelation(hippoRoot, tenantId, { fromEntityId, toEntityId, relType: rel.relType, memoryId: rel.memoryId, sourceObject: rel.sourceObject }, db);
12
+ insertRelationRow(db, tenantId, { fromEntityId, toEntityId, relType: rel.relType, memoryId: rel.memoryId, sourceObject: rel.sourceObject });
13
13
  return true;
14
14
  }
15
15
  /** Applies one op; false when a writer since the diff made it stale, which the next run's diff repairs. */
16
- function applyGraphOp(db, hippoRoot, tenantId, op) {
16
+ function applyGraphOp(db, tenantId, op) {
17
17
  switch (op.op) {
18
18
  case 'deleteEntity':
19
19
  deleteEntityRow(db, tenantId, op.id);
@@ -24,27 +24,27 @@ function applyGraphOp(db, hippoRoot, tenantId, op) {
24
24
  case 'updateEntity':
25
25
  if (!objectInForce(db, tenantId, op.entity.sourceObject))
26
26
  return false;
27
- return updateEntity(hippoRoot, tenantId, op.id, op.entity, db) !== null;
27
+ return updateEntityRow(db, tenantId, op.id, op.entity) !== null;
28
28
  case 'insertEntity':
29
29
  // A mirrorless object closed since the load is never enqueued again, so a stale insert would stay for good.
30
30
  if (!objectInForce(db, tenantId, op.entity.sourceObject) || entityIdBySource(db, tenantId, op.entity.entityType, op.entity.sourceObject) !== undefined)
31
31
  return false;
32
- insertEntity(hippoRoot, tenantId, op.entity, db);
32
+ insertEntityRow(db, tenantId, op.entity);
33
33
  return true;
34
34
  case 'insertRelation':
35
- return insertDesiredRelation(db, hippoRoot, tenantId, op.relation);
35
+ return insertDesiredRelation(db, tenantId, op.relation);
36
36
  }
37
37
  }
38
38
  /** Applies `ops` from index `opts.from` on the caller's open transaction and stops at the first op boundary past `opts.holdMs`.
39
39
  * Returns where the next chunk starts and how many ops were skipped as stale. */
40
- export function applyGraphOps(db, hippoRoot, tenantId, ops, opts) {
40
+ export function applyGraphOps(db, tenantId, ops, opts) {
41
41
  assertTenantId('applyGraphOps', tenantId);
42
42
  const now = opts.clock ?? clock;
43
43
  const begunAt = now();
44
44
  let next = opts.from;
45
45
  let skipped = 0;
46
46
  while (next < ops.length) {
47
- if (!applyGraphOp(db, hippoRoot, tenantId, ops[next]))
47
+ if (!applyGraphOp(db, tenantId, ops[next]))
48
48
  skipped += 1;
49
49
  next += 1;
50
50
  if (now() - begunAt >= opts.holdMs)
@@ -1,6 +1,7 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { isJsonString } from '../util/json.js';
4
+ import { errorMessage, log } from '../util/log.js';
4
5
  function collectFiles(dir) {
5
6
  if (!fs.existsSync(dir))
6
7
  return [];
@@ -42,8 +43,8 @@ function readCodexSessionIdsFromHistoryDelta(historyPath, startOffsetBytes) {
42
43
  ordered.push(sessionId);
43
44
  }
44
45
  }
45
- catch {
46
- // ignore malformed JSONL lines
46
+ catch (err) {
47
+ log.warn(`codex history ${historyPath}: skipped a malformed JSONL line (${errorMessage(err)})`);
47
48
  }
48
49
  }
49
50
  return ordered;
@@ -3,7 +3,8 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { PACKAGE_ROOT } from '../core/package-root.js';
5
5
  import { errorMessage, log } from '../util/log.js';
6
- import { HIPPO_CODEX_WRAPPER_MARKER, homeDir, codexHomeDir, ensureDir } from './shared.js';
6
+ import { HIPPO_CODEX_WRAPPER_MARKER, ensureDir } from './shared.js';
7
+ import { homeDir, codexHomeDir } from '../util/agent-homes.js';
7
8
  import { isJsonString } from '../util/json.js';
8
9
  import { writeFileAtomic } from '../util/atomic-write.js';
9
10
  export function resolveCodexWrapperPaths() {
@@ -2,10 +2,12 @@
2
2
  * OpenCode rejects the JSON-hook schema (no `hooks` key), so it gets a TS plugin (OPENCODE_PLUGIN_SOURCE); see installCodexHooks, installCopilotHooks. */
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
- import { HIPPO_SLEEP_MARKER, HIPPO_LAST_SLEEP_MARKER, HIPPO_CAPTURE_MARKER, HIPPO_SESSION_END_MARKER, HIPPO_PINNED_INJECT_MARKER, HIPPO_PINNED_INJECT_COMMAND, HIPPO_PRE_COMPACT_MARKER, HIPPO_COMPACT_RESUME_MARKER, HIPPO_CAPTURE_ERROR_MARKER, HIPPO_POST_COMPACT_MARKER, homeDir, claudeConfigDir, codexHomeDir, copilotHooksFile, defaultPreCompactLogPath } from './shared.js';
5
+ import { HIPPO_SLEEP_MARKER, HIPPO_LAST_SLEEP_MARKER, HIPPO_CAPTURE_MARKER, HIPPO_SESSION_END_MARKER, HIPPO_PINNED_INJECT_MARKER, HIPPO_PINNED_INJECT_COMMAND, HIPPO_PRE_COMPACT_MARKER, HIPPO_COMPACT_RESUME_MARKER, HIPPO_CAPTURE_ERROR_MARKER, HIPPO_POST_COMPACT_MARKER, copilotHooksFile, defaultPreCompactLogPath } from './shared.js';
6
+ import { claudeConfigDir, codexHomeDir, homeDir } from '../util/agent-homes.js';
6
7
  import { isJsonString, readJsonFile, isJsonObjectLiteral } from '../util/json.js';
7
8
  import { escapeRegex } from '../util/escape.js';
8
9
  import { writeFileAtomic } from '../util/atomic-write.js';
10
+ import { errorMessage, log } from '../util/log.js';
9
11
  /** The paths for `target` under the current home directory; reads and writes nothing. */
10
12
  export function resolveJsonHookPaths(target) {
11
13
  const home = homeDir();
@@ -348,7 +350,8 @@ function warnKeptHippoHandlers(settingsPath, hooks) {
348
350
  });
349
351
  if (kept.length === 0)
350
352
  return;
351
- process.stderr.write(`hippo kept these hook handlers in ${settingsPath} because they do not start with a hippo command; remove any that are hippo's by hand: ${kept.map((c) => JSON.stringify(c)).join(', ')}\n`);
353
+ process.stderr.write(`hippo kept these hook handlers in ${settingsPath} because they do not start with a hippo command; ` +
354
+ `remove any that are hippo's by hand: ${kept.map((c) => JSON.stringify(c)).join(', ')}\n`);
352
355
  }
353
356
  /** Removes hippo's own hook handlers from `target`'s settings file and keeps every other handler; true when the file changed. */
354
357
  export function uninstallJsonHooks(target) {
@@ -364,8 +367,11 @@ export function uninstallJsonHooks(target) {
364
367
  try {
365
368
  settings = readJsonFile(settingsPath);
366
369
  }
367
- catch {
368
- // Never rewrite a settings file we cannot parse; report nothing uninstalled.
370
+ catch (err) {
371
+ // Never rewrite a settings file we cannot parse; a read failure (permissions, a directory) is the caller's to see.
372
+ if (!(err instanceof SyntaxError))
373
+ throw new Error(`could not read ${settingsPath}: ${errorMessage(err)}`, { cause: err });
374
+ log.warn(`${settingsPath} is not valid JSON, so no hippo hooks were removed from it: ${err.message}`);
369
375
  return false;
370
376
  }
371
377
  if (!isJsonObjectLiteral(settings) || !isJsonObjectLiteral(settings.hooks))
@@ -1,6 +1,6 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
- import { homeDir } from './shared.js';
3
+ import { homeDir } from '../util/agent-homes.js';
4
4
  import { writeFileAtomic } from '../util/atomic-write.js';
5
5
  import { isJsonString, isJsonObjectLiteral } from '../util/json.js';
6
6
  const HIPPO_OPENCODE_PLUGIN_MARKER = 'HIPPO_OPENCODE_PLUGIN_V1';
@@ -20,12 +20,15 @@ export const HippoPlugin = async ({ $ }) => {
20
20
  if (typeof $ !== "function") return;
21
21
  try {
22
22
  if (event.type === "session.idle") {
23
- await $\`hippo session-end\`.quiet().nothrow();
23
+ const r = await $\`hippo session-end\`.quiet().nothrow();
24
+ if (r && r.exitCode !== 0) console.error("[hippo] session-end exited " + r.exitCode);
24
25
  } else if (event.type === "session.created") {
25
- await $\`hippo last-sleep\`.quiet().nothrow();
26
+ const r = await $\`hippo last-sleep\`.quiet().nothrow();
27
+ if (r && r.exitCode !== 0) console.error("[hippo] last-sleep exited " + r.exitCode);
26
28
  }
27
- } catch {
28
- // hippo CLI not on PATH or other failure — never crash the host session.
29
+ } catch (err) {
30
+ // hippo CLI not on PATH or other failure: never crash the host session.
31
+ console.error("[hippo] plugin hook failed: " + (err && err.message ? err.message : err));
29
32
  }
30
33
  },
31
34
  };
@@ -17,15 +17,9 @@ export declare const HIPPO_PRE_COMPACT_MARKER = "hippo pre-compact";
17
17
  export declare const HIPPO_COMPACT_RESUME_MARKER = "hippo compact-resume";
18
18
  export declare const HIPPO_CAPTURE_ERROR_MARKER = "hippo capture-error";
19
19
  export declare const HIPPO_POST_COMPACT_MARKER = "hippo post-compact";
20
- export declare function homeDir(): string;
21
- /** Codex's config folder: $CODEX_HOME, else ~/.codex, as the Codex hooks docs describe. */
22
- export declare function codexHomeDir(home?: string, env?: Readonly<Record<string, string | undefined>>): string;
23
20
  /** Copilot's config folder: $COPILOT_HOME, else ~/.copilot under os.homedir(), as the
24
21
  * Copilot apps resolve it (a HOME that differs from the profile must not move it). */
25
22
  export declare function copilotHomeDir(home?: string, env?: Readonly<Record<string, string | undefined>>): string;
26
- /** Claude Code's config folder, where it reads settings.json: $CLAUDE_CONFIG_DIR when set and non-empty, else
27
- * ~/.claude under os.homedir(), as Claude Code does (a HOME that differs from the profile must not move it). */
28
- export declare function claudeConfigDir(home?: string, env?: Readonly<Record<string, string | undefined>>): string;
29
23
  /** Codex counts as installed only when its config folder exists: Codex itself refuses a CODEX_HOME that is not a folder. */
30
24
  export declare function isCodexPresent(home?: string): boolean;
31
25
  /** hippo's own hooks file, in the hooks folder the Copilot CLI reads. */
@@ -1,8 +1,8 @@
1
- import { envHomeDir, processEnv } from '../util/env.js';
1
+ import { processEnv } from '../util/env.js';
2
2
  import * as fs from 'fs';
3
3
  import * as os from 'os';
4
4
  import * as path from 'path';
5
- import { vscodeDataFolders } from '../agent-memories/copilot.js';
5
+ import { claudeConfigDir, codexHomeDir, homeDir, vscodeDataFolders } from '../util/agent-homes.js';
6
6
  export const HIPPO_SLEEP_MARKER = 'hippo sleep';
7
7
  export const HIPPO_LAST_SLEEP_MARKER = 'hippo last-sleep';
8
8
  export const HIPPO_CAPTURE_MARKER = 'hippo capture --last-session';
@@ -14,23 +14,11 @@ export const HIPPO_PRE_COMPACT_MARKER = 'hippo pre-compact';
14
14
  export const HIPPO_COMPACT_RESUME_MARKER = 'hippo compact-resume';
15
15
  export const HIPPO_CAPTURE_ERROR_MARKER = 'hippo capture-error';
16
16
  export const HIPPO_POST_COMPACT_MARKER = 'hippo post-compact';
17
- export function homeDir() {
18
- return envHomeDir() || os.homedir();
19
- }
20
- /** Codex's config folder: $CODEX_HOME, else ~/.codex, as the Codex hooks docs describe. */
21
- export function codexHomeDir(home = homeDir(), env = processEnv()) {
22
- return env.CODEX_HOME || path.join(home, '.codex');
23
- }
24
17
  /** Copilot's config folder: $COPILOT_HOME, else ~/.copilot under os.homedir(), as the
25
18
  * Copilot apps resolve it (a HOME that differs from the profile must not move it). */
26
19
  export function copilotHomeDir(home = os.homedir(), env = processEnv()) {
27
20
  return env.COPILOT_HOME || path.join(home, '.copilot');
28
21
  }
29
- /** Claude Code's config folder, where it reads settings.json: $CLAUDE_CONFIG_DIR when set and non-empty, else
30
- * ~/.claude under os.homedir(), as Claude Code does (a HOME that differs from the profile must not move it). */
31
- export function claudeConfigDir(home = os.homedir(), env = processEnv()) {
32
- return env.CLAUDE_CONFIG_DIR || path.join(home, '.claude');
33
- }
34
22
  /** Codex counts as installed only when its config folder exists: Codex itself refuses a CODEX_HOME that is not a folder. */
35
23
  export function isCodexPresent(home = homeDir()) {
36
24
  return fs.statSync(codexHomeDir(home), { throwIfNoEntry: false })?.isDirectory() === true;
@@ -90,7 +78,8 @@ export function detectInstalledTools() {
90
78
  kind: 'wrapper',
91
79
  notes: 'memory hooks in hooks.json, and wraps the detected codex launcher for session-end consolidation'
92
80
  },
93
- { name: 'copilot', configDir: copilotHomeDir(), detected: isCopilotPresent(), kind: 'json-hook', notes: 'hooks in hooks/hippo.json, the MCP server in mcp-config.json and a block in copilot-instructions.md; for VS Code, the server in each User mcp.json and prompts/hippo.instructions.md' },
81
+ { name: 'copilot', configDir: copilotHomeDir(), detected: isCopilotPresent(), kind: 'json-hook', notes: 'hooks in hooks/hippo.json, the MCP server in ' +
82
+ 'mcp-config.json and a block in copilot-instructions.md; for VS Code, the server in each User mcp.json and prompts/hippo.instructions.md' },
94
83
  {
95
84
  name: 'cursor',
96
85
  configDir: '~/.cursor',
@@ -3,11 +3,11 @@
3
3
  import { DEFAULT_TENANT_ID } from '../util/env.js';
4
4
  import { createMemory, Layer } from '../core/memory.js';
5
5
  import { writeEntry } from '../store/entry-writes.js';
6
- import { loadAllEntries } from '../store/entry-reads.js';
6
+ import { loadEntryTextKeys } from '../store/entry-reads.js';
7
7
  import { duplicateKey, storedTextKeys } from '../util/same-text.js';
8
8
  import { getGlobalRoot, initGlobal } from '../sharing/global-store.js';
9
9
  import { withRequestStoresSync } from '../db/request-stores.js';
10
- import { RejectedValueError } from '../store/rejection.js';
10
+ import { RejectedValueError } from '../core/api-errors.js';
11
11
  import { rejectionGuardRefuses } from '../store/rejected-values.js';
12
12
  import { loadConfig } from '../core/config.js';
13
13
  import { vetSecrets } from '../util/secret-detect.js';
@@ -58,7 +58,7 @@ function openImportTarget(options) {
58
58
  if (options.global) {
59
59
  initGlobal();
60
60
  }
61
- const keys = storedTextKeys(loadAllEntries(targetRoot, options.global ? undefined : options.tenantId));
61
+ const keys = storedTextKeys(loadEntryTextKeys(targetRoot, options.global ? undefined : options.tenantId));
62
62
  return { targetRoot, keys };
63
63
  }
64
64
  function skipReason(chunk, keys) {
@@ -95,7 +95,7 @@ function createImportEntry(chunk, source, allTags, options, baseHalfLifeDays) {
95
95
  /** Writes the entry, or on a dry run only probes the guard; false when a rejected value refuses it. */
96
96
  function writeOrProbeImport(targetRoot, entry, options) {
97
97
  if (options.dryRun)
98
- return !rejectionGuardRefuses(targetRoot, entry.tenantId ?? DEFAULT_TENANT_ID, entry.id, entry.content);
98
+ return !rejectionGuardRefuses(targetRoot, entry.tenant_id ?? DEFAULT_TENANT_ID, entry.id, entry.content);
99
99
  // A rejection refuses one chunk, not the whole import, so siblings still land.
100
100
  try {
101
101
  writeEntry(targetRoot, entry);
@@ -2,6 +2,7 @@ import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { importEntries } from './core.js';
4
4
  import { splitMarkdownFrontmatter, collectMarkdownFiles } from './markdown-parse.js';
5
+ import { errorMessage, log } from '../util/log.js';
5
6
  import { isJsonString, isJsonObject } from '../util/json.js';
6
7
  /** Coerce one imported record (string, `{content|text: ...}` object, or
7
8
  * anything else) into the plain-text memory chunk it represents. */
@@ -29,8 +30,8 @@ function parseChatGPTFile(filePath) {
29
30
  return parsed.map(extractMemoryText).filter(Boolean);
30
31
  }
31
32
  }
32
- catch {
33
- // Fall through to plain text
33
+ catch (err) {
34
+ log.warn(`import: ${filePath} is not valid JSON (${errorMessage(err)}); reading it as plain text`);
34
35
  }
35
36
  }
36
37
  // Plain text: one memory per line
@@ -116,8 +117,8 @@ function parseClaudeFile(filePath) {
116
117
  return parsed.map(extractMemoryText).filter(Boolean);
117
118
  }
118
119
  }
119
- catch {
120
- // Fall through to markdown
120
+ catch (err) {
121
+ log.warn(`import: ${filePath} is not valid JSON (${errorMessage(err)}); reading it as markdown`);
121
122
  }
122
123
  }
123
124
  // Markdown file: strip hippo block and split
@@ -1,5 +1,5 @@
1
1
  import { type ImportResult, type ImportOptions } from './core.js';
2
2
  /** Import a markdown vault FOLDER as `kind='raw'` memories.
3
3
  * NOT re-entrant: idempotency rests on the in-memory `existing` Map loaded once, so two concurrent runs over one vault can double-insert. */
4
- export declare function importVault(folderPath: string, options: ImportOptions): ImportResult;
4
+ export declare function importVault(folderPath: string, options: ImportOptions): Promise<ImportResult>;
5
5
  //# sourceMappingURL=vault.d.ts.map