hippo-memory 1.60.0 → 1.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (585) hide show
  1. package/README.md +1 -1
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.js +4 -1
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/gemini.js +1 -1
  7. package/dist/agent-memories/legacy.js +1 -1
  8. package/dist/agent-memories/source.js +1 -1
  9. package/dist/agent-memories/sync.js +8 -3
  10. package/dist/ambient-store.d.ts +14 -0
  11. package/dist/ambient-store.js +90 -0
  12. package/dist/ambient.d.ts +23 -0
  13. package/dist/ambient.js +72 -50
  14. package/dist/api/assemble.d.ts +93 -0
  15. package/dist/api/assemble.js +152 -0
  16. package/dist/api/audit.d.ts +17 -0
  17. package/dist/api/audit.js +23 -0
  18. package/dist/api/auth.d.ts +79 -0
  19. package/dist/api/auth.js +178 -0
  20. package/dist/api/context-types.d.ts +105 -0
  21. package/dist/api/context-types.js +3 -0
  22. package/dist/api/context.d.ts +31 -0
  23. package/dist/api/context.js +705 -0
  24. package/dist/api/dormant.d.ts +30 -0
  25. package/dist/api/dormant.js +140 -0
  26. package/dist/api/drill-down.d.ts +84 -0
  27. package/dist/api/drill-down.js +123 -0
  28. package/dist/api/forget.d.ts +57 -0
  29. package/dist/api/forget.js +87 -0
  30. package/dist/api/goals.d.ts +18 -0
  31. package/dist/api/goals.js +33 -0
  32. package/dist/api/learn.d.ts +31 -0
  33. package/dist/api/learn.js +88 -0
  34. package/dist/api/outcome.d.ts +61 -0
  35. package/dist/api/outcome.js +66 -0
  36. package/dist/api/promote.d.ts +54 -0
  37. package/dist/api/promote.js +203 -0
  38. package/dist/api/quarantine.d.ts +24 -0
  39. package/dist/api/quarantine.js +121 -0
  40. package/dist/api/recall-types.d.ts +390 -0
  41. package/dist/api/recall-types.js +3 -0
  42. package/dist/api/recall.d.ts +36 -0
  43. package/dist/api/recall.js +634 -0
  44. package/dist/api/remember.d.ts +35 -0
  45. package/dist/api/remember.js +43 -0
  46. package/dist/api/sleep.d.ts +136 -0
  47. package/dist/api/sleep.js +271 -0
  48. package/dist/api/tokens.d.ts +26 -0
  49. package/dist/api/tokens.js +60 -0
  50. package/dist/api/types.d.ts +56 -0
  51. package/dist/api/types.js +38 -0
  52. package/dist/api.d.ts +20 -1262
  53. package/dist/api.js +25 -2727
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +6 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +2 -2
  59. package/dist/capture/command.d.ts +33 -0
  60. package/dist/capture/command.js +264 -0
  61. package/dist/capture/compact.d.ts +44 -0
  62. package/dist/capture/compact.js +354 -0
  63. package/dist/capture/extract.d.ts +21 -0
  64. package/dist/capture/extract.js +464 -0
  65. package/dist/capture/transcript.d.ts +40 -0
  66. package/dist/capture/transcript.js +193 -0
  67. package/dist/capture-error.js +2 -1
  68. package/dist/churn-git.js +4 -2
  69. package/dist/cli/audit.d.ts +3 -0
  70. package/dist/cli/audit.js +159 -0
  71. package/dist/cli/auth.d.ts +2 -0
  72. package/dist/cli/auth.js +171 -0
  73. package/dist/cli/briefs.d.ts +4 -0
  74. package/dist/cli/briefs.js +435 -0
  75. package/dist/cli/card.d.ts +3 -0
  76. package/dist/cli/card.js +333 -0
  77. package/dist/cli/context.d.ts +15 -0
  78. package/dist/cli/context.js +366 -0
  79. package/dist/cli/continuity.d.ts +6 -0
  80. package/dist/cli/continuity.js +445 -0
  81. package/dist/cli/curate.d.ts +19 -0
  82. package/dist/cli/curate.js +555 -0
  83. package/dist/cli/dag.d.ts +5 -0
  84. package/dist/cli/dag.js +177 -0
  85. package/dist/cli/decisions.d.ts +4 -0
  86. package/dist/cli/decisions.js +528 -0
  87. package/dist/cli/eval.d.ts +5 -0
  88. package/dist/cli/eval.js +213 -0
  89. package/dist/cli/explain.d.ts +4 -0
  90. package/dist/cli/explain.js +150 -0
  91. package/dist/cli/goals.d.ts +2 -0
  92. package/dist/cli/goals.js +196 -0
  93. package/dist/cli/hook-blocks.d.ts +18 -0
  94. package/dist/cli/hook-blocks.js +233 -0
  95. package/dist/cli/init.d.ts +2 -0
  96. package/dist/cli/init.js +305 -0
  97. package/dist/cli/maintenance.d.ts +4 -0
  98. package/dist/cli/maintenance.js +179 -0
  99. package/dist/cli/playbooks.d.ts +4 -0
  100. package/dist/cli/playbooks.js +556 -0
  101. package/dist/cli/projects.js +1 -1
  102. package/dist/cli/recall.d.ts +7 -0
  103. package/dist/cli/recall.js +597 -0
  104. package/dist/cli/remember.d.ts +5 -0
  105. package/dist/cli/remember.js +442 -0
  106. package/dist/cli/serve.d.ts +5 -0
  107. package/dist/cli/serve.js +40 -0
  108. package/dist/cli/session-hooks.d.ts +29 -0
  109. package/dist/cli/session-hooks.js +637 -0
  110. package/dist/cli/setup.d.ts +4 -0
  111. package/dist/cli/setup.js +376 -0
  112. package/dist/cli/shared.d.ts +15 -19
  113. package/dist/cli/shared.js +50 -341
  114. package/dist/cli/slack.d.ts +2 -0
  115. package/dist/cli/slack.js +171 -0
  116. package/dist/cli/status.d.ts +18 -0
  117. package/dist/cli/status.js +400 -0
  118. package/dist/cli/transfer.d.ts +10 -0
  119. package/dist/cli/transfer.js +438 -0
  120. package/dist/cli/usage.d.ts +85 -0
  121. package/dist/cli/usage.js +741 -0
  122. package/dist/cli.d.ts +71 -120
  123. package/dist/cli.js +170 -8469
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +6 -4
  126. package/dist/connectors/github/backfill.js +94 -87
  127. package/dist/connectors/github/cli-impl.js +4 -3
  128. package/dist/connectors/github/dlq.js +67 -54
  129. package/dist/connectors/github/ingest.js +34 -35
  130. package/dist/connectors/github/tenant-routing.js +3 -2
  131. package/dist/connectors/github/webhook.js +135 -216
  132. package/dist/connectors/slack/dlq.js +49 -61
  133. package/dist/connectors/slack/ingest.js +55 -48
  134. package/dist/connectors/slack/tenant-routing.js +4 -3
  135. package/dist/connectors/slack/webhook.js +72 -74
  136. package/dist/consolidate/conflicts.d.ts +10 -0
  137. package/dist/consolidate/conflicts.js +178 -0
  138. package/dist/consolidate/decay.d.ts +12 -0
  139. package/dist/consolidate/decay.js +145 -0
  140. package/dist/consolidate/llm-passes.d.ts +3 -0
  141. package/dist/consolidate/llm-passes.js +141 -0
  142. package/dist/consolidate/merge.d.ts +7 -0
  143. package/dist/consolidate/merge.js +251 -0
  144. package/dist/consolidate/physics-pass.d.ts +3 -0
  145. package/dist/consolidate/physics-pass.js +60 -0
  146. package/dist/consolidate/run.d.ts +69 -0
  147. package/dist/consolidate/run.js +76 -0
  148. package/dist/consolidate/sleep.d.ts +18 -0
  149. package/dist/consolidate/sleep.js +209 -0
  150. package/dist/consolidate/traces.d.ts +4 -0
  151. package/dist/consolidate/traces.js +178 -0
  152. package/dist/context-auto.js +7 -11
  153. package/dist/context-render.d.ts +1 -1
  154. package/dist/context-render.js +1 -1
  155. package/dist/customer-notes.d.ts +3 -0
  156. package/dist/customer-notes.js +6 -4
  157. package/dist/dag.js +6 -5
  158. package/dist/dashboard-actions.d.ts +20 -0
  159. package/dist/dashboard-actions.js +88 -0
  160. package/dist/dashboard-params.d.ts +45 -0
  161. package/dist/dashboard-params.js +127 -0
  162. package/dist/dashboard-queries.d.ts +15 -0
  163. package/dist/dashboard-queries.js +355 -0
  164. package/dist/dashboard-snapshot.d.ts +138 -0
  165. package/dist/dashboard-snapshot.js +308 -0
  166. package/dist/dashboard-types.d.ts +163 -0
  167. package/dist/dashboard-types.js +3 -0
  168. package/dist/dashboard.d.ts +6 -7
  169. package/dist/dashboard.js +228 -202
  170. package/dist/db/busy.d.ts +5 -0
  171. package/dist/db/busy.js +24 -0
  172. package/dist/db/continuity.d.ts +5 -0
  173. package/dist/db/continuity.js +145 -0
  174. package/dist/db/meta.d.ts +8 -0
  175. package/dist/db/meta.js +35 -0
  176. package/dist/db/migrate.d.ts +9 -0
  177. package/dist/db/migrate.js +138 -0
  178. package/dist/db/migrations/index.d.ts +5 -0
  179. package/dist/db/migrations/index.js +109 -0
  180. package/dist/db/migrations/types.d.ts +14 -0
  181. package/dist/db/migrations/types.js +2 -0
  182. package/dist/db/migrations/v01.d.ts +3 -0
  183. package/dist/db/migrations/v01.js +38 -0
  184. package/dist/db/migrations/v02.d.ts +3 -0
  185. package/dist/db/migrations/v02.js +21 -0
  186. package/dist/db/migrations/v03.d.ts +3 -0
  187. package/dist/db/migrations/v03.js +22 -0
  188. package/dist/db/migrations/v04.d.ts +3 -0
  189. package/dist/db/migrations/v04.js +28 -0
  190. package/dist/db/migrations/v05.d.ts +3 -0
  191. package/dist/db/migrations/v05.js +21 -0
  192. package/dist/db/migrations/v06.d.ts +3 -0
  193. package/dist/db/migrations/v06.js +25 -0
  194. package/dist/db/migrations/v07.d.ts +3 -0
  195. package/dist/db/migrations/v07.js +13 -0
  196. package/dist/db/migrations/v08.d.ts +3 -0
  197. package/dist/db/migrations/v08.js +8 -0
  198. package/dist/db/migrations/v09.d.ts +3 -0
  199. package/dist/db/migrations/v09.js +13 -0
  200. package/dist/db/migrations/v10.d.ts +3 -0
  201. package/dist/db/migrations/v10.js +17 -0
  202. package/dist/db/migrations/v11.d.ts +3 -0
  203. package/dist/db/migrations/v11.js +15 -0
  204. package/dist/db/migrations/v12.d.ts +3 -0
  205. package/dist/db/migrations/v12.js +11 -0
  206. package/dist/db/migrations/v13.d.ts +3 -0
  207. package/dist/db/migrations/v13.js +15 -0
  208. package/dist/db/migrations/v14.d.ts +3 -0
  209. package/dist/db/migrations/v14.js +66 -0
  210. package/dist/db/migrations/v15.d.ts +3 -0
  211. package/dist/db/migrations/v15.js +42 -0
  212. package/dist/db/migrations/v16.d.ts +3 -0
  213. package/dist/db/migrations/v16.js +61 -0
  214. package/dist/db/migrations/v17.d.ts +3 -0
  215. package/dist/db/migrations/v17.js +46 -0
  216. package/dist/db/migrations/v18.d.ts +3 -0
  217. package/dist/db/migrations/v18.js +60 -0
  218. package/dist/db/migrations/v19.d.ts +3 -0
  219. package/dist/db/migrations/v19.js +28 -0
  220. package/dist/db/migrations/v20.d.ts +3 -0
  221. package/dist/db/migrations/v20.js +42 -0
  222. package/dist/db/migrations/v21.d.ts +3 -0
  223. package/dist/db/migrations/v21.js +16 -0
  224. package/dist/db/migrations/v22.d.ts +3 -0
  225. package/dist/db/migrations/v22.js +82 -0
  226. package/dist/db/migrations/v23.d.ts +3 -0
  227. package/dist/db/migrations/v23.js +48 -0
  228. package/dist/db/migrations/v24.d.ts +3 -0
  229. package/dist/db/migrations/v24.js +72 -0
  230. package/dist/db/migrations/v25.d.ts +3 -0
  231. package/dist/db/migrations/v25.js +46 -0
  232. package/dist/db/migrations/v26.d.ts +3 -0
  233. package/dist/db/migrations/v26.js +23 -0
  234. package/dist/db/migrations/v27.d.ts +3 -0
  235. package/dist/db/migrations/v27.js +57 -0
  236. package/dist/db/migrations/v28.d.ts +3 -0
  237. package/dist/db/migrations/v28.js +38 -0
  238. package/dist/db/migrations/v29.d.ts +3 -0
  239. package/dist/db/migrations/v29.js +78 -0
  240. package/dist/db/migrations/v30.d.ts +3 -0
  241. package/dist/db/migrations/v30.js +92 -0
  242. package/dist/db/migrations/v31.d.ts +3 -0
  243. package/dist/db/migrations/v31.js +74 -0
  244. package/dist/db/migrations/v32.d.ts +3 -0
  245. package/dist/db/migrations/v32.js +102 -0
  246. package/dist/db/migrations/v33.d.ts +3 -0
  247. package/dist/db/migrations/v33.js +104 -0
  248. package/dist/db/migrations/v34.d.ts +3 -0
  249. package/dist/db/migrations/v34.js +93 -0
  250. package/dist/db/migrations/v35.d.ts +3 -0
  251. package/dist/db/migrations/v35.js +98 -0
  252. package/dist/db/migrations/v36.d.ts +3 -0
  253. package/dist/db/migrations/v36.js +98 -0
  254. package/dist/db/migrations/v37.d.ts +3 -0
  255. package/dist/db/migrations/v37.js +219 -0
  256. package/dist/db/migrations/v38.d.ts +3 -0
  257. package/dist/db/migrations/v38.js +277 -0
  258. package/dist/db/migrations/v39.d.ts +3 -0
  259. package/dist/db/migrations/v39.js +59 -0
  260. package/dist/db/migrations/v40.d.ts +3 -0
  261. package/dist/db/migrations/v40.js +74 -0
  262. package/dist/db/migrations/v41.d.ts +3 -0
  263. package/dist/db/migrations/v41.js +43 -0
  264. package/dist/db/migrations/v42.d.ts +3 -0
  265. package/dist/db/migrations/v42.js +41 -0
  266. package/dist/db/migrations/v43.d.ts +3 -0
  267. package/dist/db/migrations/v43.js +67 -0
  268. package/dist/db/migrations/v44.d.ts +3 -0
  269. package/dist/db/migrations/v44.js +28 -0
  270. package/dist/db/migrations/v45.d.ts +3 -0
  271. package/dist/db/migrations/v45.js +30 -0
  272. package/dist/db/migrations/v46.d.ts +3 -0
  273. package/dist/db/migrations/v46.js +25 -0
  274. package/dist/db/migrations/v47.d.ts +3 -0
  275. package/dist/db/migrations/v47.js +17 -0
  276. package/dist/db/migrations/v48.d.ts +3 -0
  277. package/dist/db/migrations/v48.js +10 -0
  278. package/dist/db/migrations/v49.d.ts +3 -0
  279. package/dist/db/migrations/v49.js +31 -0
  280. package/dist/db/migrations/v50.d.ts +3 -0
  281. package/dist/db/migrations/v50.js +67 -0
  282. package/dist/db/migrations/v51.d.ts +3 -0
  283. package/dist/db/migrations/v51.js +14 -0
  284. package/dist/db/migrations/v52.d.ts +3 -0
  285. package/dist/db/migrations/v52.js +7 -0
  286. package/dist/db/open.d.ts +23 -0
  287. package/dist/db/open.js +146 -0
  288. package/dist/db/sqlite.d.ts +21 -0
  289. package/dist/db/sqlite.js +8 -0
  290. package/dist/db/tables.d.ts +7 -0
  291. package/dist/db/tables.js +38 -0
  292. package/dist/db.d.ts +6 -46
  293. package/dist/db.js +5 -3049
  294. package/dist/decisions.d.ts +4 -1
  295. package/dist/decisions.js +9 -7
  296. package/dist/dedupe.js +3 -2
  297. package/dist/delivery-recorder.js +4 -1
  298. package/dist/doctor.js +3 -3
  299. package/dist/embedding-provider.d.ts +1 -1
  300. package/dist/embedding-provider.js +4 -3
  301. package/dist/embeddings.d.ts +9 -52
  302. package/dist/embeddings.js +43 -297
  303. package/dist/env.d.ts +75 -0
  304. package/dist/env.js +119 -0
  305. package/dist/eval-suite.js +1 -1
  306. package/dist/eval.js +2 -2
  307. package/dist/extract.js +1 -1
  308. package/dist/gated-write.js +3 -1
  309. package/dist/goals.d.ts +3 -1
  310. package/dist/goals.js +18 -0
  311. package/dist/graph/read.d.ts +73 -0
  312. package/dist/graph/read.js +325 -0
  313. package/dist/graph/rows.d.ts +45 -0
  314. package/dist/graph/rows.js +51 -0
  315. package/dist/graph/types.d.ts +83 -0
  316. package/dist/graph/types.js +11 -0
  317. package/dist/graph/write.d.ts +93 -0
  318. package/dist/{graph.js → graph/write.js} +6 -384
  319. package/dist/graph-extract.js +2 -1
  320. package/dist/graph-recall.d.ts +1 -1
  321. package/dist/graph-recall.js +2 -2
  322. package/dist/graph-stream.js +1 -1
  323. package/dist/graph-view.d.ts +1 -1
  324. package/dist/graph-view.js +1 -1
  325. package/dist/half-life-migration.d.ts +1 -1
  326. package/dist/half-life-migration.js +2 -1
  327. package/dist/hooks/codex-session.d.ts +8 -0
  328. package/dist/hooks/codex-session.js +76 -0
  329. package/dist/hooks/codex-wrapper.d.ts +55 -0
  330. package/dist/hooks/codex-wrapper.js +288 -0
  331. package/dist/hooks/json-hooks.d.ts +63 -0
  332. package/dist/hooks/json-hooks.js +356 -0
  333. package/dist/hooks/opencode.d.ts +50 -0
  334. package/dist/hooks/opencode.js +202 -0
  335. package/dist/hooks/shared.d.ts +54 -0
  336. package/dist/hooks/shared.js +77 -0
  337. package/dist/http-retry.d.ts +2 -0
  338. package/dist/http-retry.js +4 -3
  339. package/dist/http-util.d.ts +3 -0
  340. package/dist/http-util.js +10 -0
  341. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  342. package/dist/importers/core.js +141 -0
  343. package/dist/importers/markdown-parse.d.ts +41 -0
  344. package/dist/importers/markdown-parse.js +132 -0
  345. package/dist/importers/markdown.d.ts +3 -0
  346. package/dist/importers/markdown.js +92 -0
  347. package/dist/importers/sources.d.ts +7 -0
  348. package/dist/importers/sources.js +229 -0
  349. package/dist/importers/vault.d.ts +11 -0
  350. package/dist/importers/vault.js +352 -0
  351. package/dist/incidents.d.ts +3 -0
  352. package/dist/incidents.js +7 -5
  353. package/dist/index.d.ts +25 -6
  354. package/dist/index.js +23 -6
  355. package/dist/invalidation.js +2 -1
  356. package/dist/judgment.js +2 -1
  357. package/dist/keyset.d.ts +13 -0
  358. package/dist/keyset.js +8 -0
  359. package/dist/local-embedding.d.ts +13 -0
  360. package/dist/local-embedding.js +165 -0
  361. package/dist/log.d.ts +7 -0
  362. package/dist/log.js +19 -1
  363. package/dist/mcp/admin-tools.d.ts +8 -0
  364. package/dist/mcp/admin-tools.js +116 -0
  365. package/dist/mcp/format.d.ts +27 -0
  366. package/dist/mcp/format.js +135 -0
  367. package/dist/mcp/memory-tools.d.ts +5 -0
  368. package/dist/mcp/memory-tools.js +83 -0
  369. package/dist/mcp/protocol.d.ts +83 -0
  370. package/dist/mcp/protocol.js +55 -0
  371. package/dist/mcp/recall-tools.d.ts +6 -0
  372. package/dist/mcp/recall-tools.js +320 -0
  373. package/dist/mcp/request.d.ts +10 -0
  374. package/dist/mcp/request.js +163 -0
  375. package/dist/mcp/server.d.ts +4 -75
  376. package/dist/mcp/server.js +7 -1190
  377. package/dist/mcp/session-state.d.ts +11 -0
  378. package/dist/mcp/session-state.js +28 -0
  379. package/dist/mcp/stdio.d.ts +8 -0
  380. package/dist/mcp/stdio.js +79 -0
  381. package/dist/mcp/tools.d.ts +11 -0
  382. package/dist/mcp/tools.js +247 -0
  383. package/dist/memory.d.ts +3 -0
  384. package/dist/memory.js +27 -1
  385. package/dist/multihop.d.ts +1 -1
  386. package/dist/multihop.js +2 -1
  387. package/dist/owner-validation.js +2 -1
  388. package/dist/physics-state.js +10 -7
  389. package/dist/policies.d.ts +3 -0
  390. package/dist/policies.js +8 -6
  391. package/dist/postinstall.js +3 -2
  392. package/dist/predictions/planning-fallacy.d.ts +100 -0
  393. package/dist/predictions/planning-fallacy.js +190 -0
  394. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  395. package/dist/predictions/store.js +434 -0
  396. package/dist/processes.d.ts +3 -0
  397. package/dist/processes.js +7 -5
  398. package/dist/project-briefs.d.ts +3 -0
  399. package/dist/project-briefs.js +7 -5
  400. package/dist/project-identity.js +3 -2
  401. package/dist/project-merge.js +3 -1
  402. package/dist/quarantine.d.ts +2 -1
  403. package/dist/quarantine.js +8 -5
  404. package/dist/raw-archive.js +1 -1
  405. package/dist/recall-history.js +3 -2
  406. package/dist/recall-pipeline.d.ts +2 -2
  407. package/dist/recall-pipeline.js +16 -8
  408. package/dist/recall-scope.js +1 -1
  409. package/dist/recall-trace.d.ts +1 -1
  410. package/dist/refine-llm.js +2 -1
  411. package/dist/reject-flow.js +6 -1
  412. package/dist/rerankers/clef.js +6 -5
  413. package/dist/rerankers/jev.d.ts +1 -1
  414. package/dist/rerankers/jev.js +4 -4
  415. package/dist/rerankers/llm.d.ts +4 -2
  416. package/dist/rerankers/llm.js +58 -38
  417. package/dist/rerankers/types.d.ts +1 -1
  418. package/dist/salience.js +1 -1
  419. package/dist/scheduler.d.ts +1 -0
  420. package/dist/scheduler.js +26 -4
  421. package/dist/scope.js +4 -3
  422. package/dist/search/as-of.d.ts +10 -0
  423. package/dist/search/as-of.js +22 -0
  424. package/dist/search/bm25-search.d.ts +14 -0
  425. package/dist/search/bm25-search.js +43 -0
  426. package/dist/search/bm25.d.ts +15 -0
  427. package/dist/search/bm25.js +54 -0
  428. package/dist/search/boosts.d.ts +54 -0
  429. package/dist/search/boosts.js +94 -0
  430. package/dist/search/breakdown.d.ts +7 -0
  431. package/dist/search/breakdown.js +20 -0
  432. package/dist/search/explain.d.ts +25 -0
  433. package/dist/search/explain.js +31 -0
  434. package/dist/search/finalize.d.ts +8 -0
  435. package/dist/search/finalize.js +52 -0
  436. package/dist/search/fusion.d.ts +27 -0
  437. package/dist/search/fusion.js +42 -0
  438. package/dist/search/hybrid-score.d.ts +20 -0
  439. package/dist/search/hybrid-score.js +73 -0
  440. package/dist/search/hybrid.d.ts +46 -0
  441. package/dist/search/hybrid.js +64 -0
  442. package/dist/search/physics-search.d.ts +29 -0
  443. package/dist/search/physics-search.js +162 -0
  444. package/dist/search/rerank.d.ts +10 -0
  445. package/dist/search/rerank.js +72 -0
  446. package/dist/search/temporal.d.ts +15 -0
  447. package/dist/search/temporal.js +45 -0
  448. package/dist/search/types.d.ts +91 -0
  449. package/dist/search/types.js +2 -0
  450. package/dist/search/vector.d.ts +30 -0
  451. package/dist/search/vector.js +71 -0
  452. package/dist/secret-detect.d.ts +2 -0
  453. package/dist/secret-detect.js +2 -1
  454. package/dist/server/auth.d.ts +52 -0
  455. package/dist/server/auth.js +221 -0
  456. package/dist/server/client-ip.d.ts +25 -0
  457. package/dist/server/client-ip.js +92 -0
  458. package/dist/server/cursor.d.ts +23 -0
  459. package/dist/server/cursor.js +58 -0
  460. package/dist/server/lifecycle.d.ts +7 -0
  461. package/dist/server/lifecycle.js +29 -0
  462. package/dist/server/mcp-http.d.ts +5 -0
  463. package/dist/server/mcp-http.js +199 -0
  464. package/dist/server/request.d.ts +33 -0
  465. package/dist/server/request.js +103 -0
  466. package/dist/server/routes/admin.d.ts +9 -0
  467. package/dist/server/routes/admin.js +158 -0
  468. package/dist/server/routes/customer-notes.d.ts +7 -0
  469. package/dist/server/routes/customer-notes.js +112 -0
  470. package/dist/server/routes/decisions.d.ts +7 -0
  471. package/dist/server/routes/decisions.js +133 -0
  472. package/dist/server/routes/incidents.d.ts +7 -0
  473. package/dist/server/routes/incidents.js +126 -0
  474. package/dist/server/routes/memories.d.ts +10 -0
  475. package/dist/server/routes/memories.js +179 -0
  476. package/dist/server/routes/policies.d.ts +8 -0
  477. package/dist/server/routes/policies.js +151 -0
  478. package/dist/server/routes/predictions.d.ts +7 -0
  479. package/dist/server/routes/predictions.js +164 -0
  480. package/dist/server/routes/processes.d.ts +7 -0
  481. package/dist/server/routes/processes.js +161 -0
  482. package/dist/server/routes/project-briefs.d.ts +8 -0
  483. package/dist/server/routes/project-briefs.js +136 -0
  484. package/dist/server/routes/recall.d.ts +8 -0
  485. package/dist/server/routes/recall.js +340 -0
  486. package/dist/server/routes/skills.d.ts +8 -0
  487. package/dist/server/routes/skills.js +150 -0
  488. package/dist/server/types.d.ts +56 -0
  489. package/dist/server/types.js +2 -0
  490. package/dist/server/validation.d.ts +14 -0
  491. package/dist/server/validation.js +91 -0
  492. package/dist/server.d.ts +7 -61
  493. package/dist/server.js +69 -2362
  494. package/dist/session-digest.d.ts +1 -1
  495. package/dist/session-digest.js +9 -2
  496. package/dist/shared.d.ts +3 -1
  497. package/dist/shared.js +26 -22
  498. package/dist/skills.d.ts +3 -0
  499. package/dist/skills.js +7 -5
  500. package/dist/stdin.js +2 -2
  501. package/dist/store/audit-event.d.ts +19 -0
  502. package/dist/store/audit-event.js +33 -0
  503. package/dist/store/candidates.d.ts +42 -0
  504. package/dist/store/candidates.js +152 -0
  505. package/dist/store/conflicts.d.ts +44 -0
  506. package/dist/store/conflicts.js +444 -0
  507. package/dist/store/delete-and-batch.d.ts +63 -0
  508. package/dist/store/delete-and-batch.js +310 -0
  509. package/dist/store/entry-reads.d.ts +92 -0
  510. package/dist/store/entry-reads.js +255 -0
  511. package/dist/store/entry-row.d.ts +67 -0
  512. package/dist/store/entry-row.js +208 -0
  513. package/dist/store/entry-writes.d.ts +46 -0
  514. package/dist/store/entry-writes.js +148 -0
  515. package/dist/store/handoffs.d.ts +26 -0
  516. package/dist/store/handoffs.js +184 -0
  517. package/dist/store/index-and-stats.d.ts +52 -0
  518. package/dist/store/index-and-stats.js +214 -0
  519. package/dist/store/markdown.d.ts +10 -0
  520. package/dist/store/markdown.js +108 -0
  521. package/dist/store/mirrors.d.ts +49 -0
  522. package/dist/store/mirrors.js +312 -0
  523. package/dist/store/open.d.ts +15 -0
  524. package/dist/store/open.js +223 -0
  525. package/dist/store/rows.d.ts +178 -0
  526. package/dist/store/rows.js +158 -0
  527. package/dist/store/search-rows.d.ts +86 -0
  528. package/dist/store/search-rows.js +254 -0
  529. package/dist/store/sessions.d.ts +83 -0
  530. package/dist/store/sessions.js +272 -0
  531. package/dist/store/summaries.d.ts +94 -0
  532. package/dist/store/summaries.js +377 -0
  533. package/dist/store/tenant-lookup.d.ts +12 -0
  534. package/dist/store/tenant-lookup.js +16 -0
  535. package/dist/store-cards.js +2 -1
  536. package/dist/summary-dirty.d.ts +4 -0
  537. package/dist/summary-dirty.js +32 -0
  538. package/dist/support-bundle.js +4 -3
  539. package/dist/tenant.js +2 -2
  540. package/dist/tokenize.d.ts +2 -0
  541. package/dist/tokenize.js +16 -0
  542. package/dist/transcript-tail.d.ts +7 -0
  543. package/dist/transcript-tail.js +48 -0
  544. package/dist/vector-store.d.ts +27 -0
  545. package/dist/vector-store.js +210 -0
  546. package/dist/version.d.ts +2 -2
  547. package/dist/version.js +2 -2
  548. package/dist/working-memory.js +1 -1
  549. package/dist/yaml.js +36 -11
  550. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  551. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  552. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  553. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  554. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  555. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  556. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  557. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  558. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  559. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  560. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  561. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  562. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  563. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  564. package/dist-ui/index.html +3 -25
  565. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  566. package/extensions/openclaw-plugin/package.json +1 -1
  567. package/openclaw.plugin.json +1 -1
  568. package/package.json +1 -1
  569. package/dist/capture.d.ts +0 -155
  570. package/dist/capture.js +0 -1295
  571. package/dist/consolidate.d.ts +0 -58
  572. package/dist/consolidate.js +0 -1124
  573. package/dist/graph.d.ts +0 -245
  574. package/dist/hooks.d.ts +0 -208
  575. package/dist/hooks.js +0 -1076
  576. package/dist/importers.js +0 -900
  577. package/dist/predictions.js +0 -620
  578. package/dist/search.d.ts +0 -320
  579. package/dist/search.js +0 -970
  580. package/dist/store.d.ts +0 -776
  581. package/dist/store.js +0 -3473
  582. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  583. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  584. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  585. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -0,0 +1,77 @@
1
+ import { envHomeDir, processEnv } from '../env.js';
2
+ import * as fs from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ /** JSON-value string check. `constructor` narrows a primitive via its boxed wrapper
6
+ * instead of inspecting the `typeof` tag (anti-slop/no-runtime-typeof); equivalent to
7
+ * `typeof value === 'string'` for every value JSON.parse can ever produce. */
8
+ export function isJsonString(value) {
9
+ return value !== undefined && value !== null && value.constructor === String;
10
+ }
11
+ /** JSON-value plain-object check (excludes arrays and null), typeof-free for the same
12
+ * reason as isJsonString above. */
13
+ export function isJsonObject(value) {
14
+ return value !== undefined && value !== null && !Array.isArray(value) && value.constructor === Object;
15
+ }
16
+ export const HIPPO_SLEEP_MARKER = 'hippo sleep';
17
+ export const HIPPO_LAST_SLEEP_MARKER = 'hippo last-sleep';
18
+ export const HIPPO_CAPTURE_MARKER = 'hippo capture --last-session';
19
+ export const HIPPO_SESSION_END_MARKER = 'hippo session-end';
20
+ export const HIPPO_PINNED_INJECT_MARKER = 'hippo context --pinned-only';
21
+ export const HIPPO_PINNED_INJECT_COMMAND = 'hippo context --pinned-only --include-recent 5 --format additional-context';
22
+ export const HIPPO_CODEX_WRAPPER_MARKER = 'hippo codex wrapper';
23
+ export const HIPPO_PRE_COMPACT_MARKER = 'hippo pre-compact';
24
+ export const HIPPO_COMPACT_RESUME_MARKER = 'hippo compact-resume';
25
+ export const HIPPO_CAPTURE_ERROR_MARKER = 'hippo capture-error';
26
+ export const HIPPO_POST_COMPACT_MARKER = 'hippo post-compact';
27
+ export function homeDir() {
28
+ return envHomeDir() || os.homedir();
29
+ }
30
+ /** Codex's config folder: $CODEX_HOME, else ~/.codex, as the Codex hooks docs describe. */
31
+ export function codexHomeDir(home = homeDir(), env = processEnv()) {
32
+ return env.CODEX_HOME || path.join(home, '.codex');
33
+ }
34
+ /** Codex counts as installed only when its config folder exists: Codex itself refuses a CODEX_HOME that is not a folder. */
35
+ export function isCodexPresent(home = homeDir()) {
36
+ return fs.statSync(codexHomeDir(home), { throwIfNoEntry: false })?.isDirectory() === true;
37
+ }
38
+ /** Codex hashes each hook and skips new or changed ones until the user reviews them in `/hooks`, so the reminder says what they would trust. */
39
+ export const CODEX_TRUST_LINE = "The per-prompt hook sends your pinned memories plus up to 5 that match the prompt. Codex runs hippo's hooks only after you trust them once in `/hooks`.";
40
+ /**
41
+ * Default log path consumed by `hippo last-sleep`. Shared fallback when
42
+ * a caller doesn't pass --path explicitly.
43
+ */
44
+ export function defaultSleepLogPath() {
45
+ return path.join(homeDir(), '.hippo', 'logs', 'last-sleep.log');
46
+ }
47
+ /**
48
+ * Diagnostic-only log path for `hippo pre-compact`. Deliberately separate
49
+ * from the SessionEnd sleep log: `hippo last-sleep` truncates that file on
50
+ * every SessionStart, which would wipe pre-compact lines before anyone
51
+ * could read them. Nothing consumes this file programmatically — it exists
52
+ * for manual troubleshooting only. Overridden by `--log-file`.
53
+ */
54
+ export function defaultPreCompactLogPath() {
55
+ return path.join(homeDir(), '.hippo', 'logs', 'pre-compact.log');
56
+ }
57
+ export function ensureDir(dir) {
58
+ if (!fs.existsSync(dir))
59
+ fs.mkdirSync(dir, { recursive: true });
60
+ }
61
+ /**
62
+ * Detect which AI coding tools are installed based on config directory presence.
63
+ * Used by `hippo setup` to decide which JSON-hook installs to run.
64
+ */
65
+ export function detectInstalledTools() {
66
+ const home = homeDir();
67
+ const exists = (...parts) => fs.existsSync(path.join(home, ...parts));
68
+ return [
69
+ { name: 'claude-code', configDir: '~/.claude', detected: exists('.claude'), kind: 'json-hook' },
70
+ { name: 'opencode', configDir: '~/.config/opencode', detected: exists('.config', 'opencode'), kind: 'plugin', notes: 'installs a TS plugin at ~/.config/opencode/plugins/hippo.ts' },
71
+ { name: 'openclaw', configDir: '~/.openclaw', detected: exists('.openclaw'), kind: 'plugin', notes: 'install via `openclaw plugins install hippo-memory`' },
72
+ { name: 'codex', configDir: '~/.codex', detected: isCodexPresent(home), kind: 'wrapper', notes: 'memory hooks in hooks.json, and wraps the detected codex launcher for session-end consolidation' },
73
+ { name: 'cursor', configDir: '~/.cursor', detected: exists('.cursor'), kind: 'markdown-instruction', notes: 'no hook API - patches AGENTS.md in the project' },
74
+ { name: 'pi', configDir: '~/.pi', detected: exists('.pi'), kind: 'markdown-instruction', notes: 'no hook API - patches AGENTS.md in the project' },
75
+ ];
76
+ }
77
+ //# sourceMappingURL=shared.js.map
@@ -7,6 +7,8 @@ export interface RetryPolicy {
7
7
  baseDelayMs?: number;
8
8
  /** A Retry-After longer than this hands the response back, so a caller with its own long pause keeps it. */
9
9
  maxDelayMs?: number;
10
+ /** Which responses to retry; defaults to 429 and 5xx. A write narrows it to answers that prove nothing committed. */
11
+ retryOn?: (res: Response) => boolean;
10
12
  fetchFn?: typeof fetch;
11
13
  sleep?: (ms: number) => Promise<void>;
12
14
  random?: () => number;
@@ -1,12 +1,12 @@
1
1
  /** One retry policy for outbound HTTP: a timeout on every attempt, and backoff on 429 and 5xx only. */
2
+ import { envLlmTimeoutMs } from './env.js';
2
3
  const DEFAULT_ATTEMPTS = 3;
3
4
  const DEFAULT_BASE_DELAY_MS = 250;
4
5
  const DEFAULT_MAX_DELAY_MS = 8_000;
5
6
  const DEFAULT_LLM_TIMEOUT_MS = 60_000;
6
7
  /** LLM calls (consolidation refine, DAG summaries, fact extraction) share one budget; `HIPPO_LLM_TIMEOUT_MS` overrides it. */
7
8
  export function llmTimeoutMs() {
8
- const parsed = Number.parseInt(process.env.HIPPO_LLM_TIMEOUT_MS ?? '', 10);
9
- return parsed > 0 ? parsed : DEFAULT_LLM_TIMEOUT_MS;
9
+ return envLlmTimeoutMs() ?? DEFAULT_LLM_TIMEOUT_MS;
10
10
  }
11
11
  export function isRetryableStatus(status) {
12
12
  return status === 429 || (status >= 500 && status <= 599);
@@ -30,11 +30,12 @@ export async function fetchWithRetry(url, init, policy) {
30
30
  const maxDelayMs = policy.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
31
31
  const sleep = policy.sleep ?? realSleep;
32
32
  const random = policy.random ?? Math.random;
33
+ const retryOn = policy.retryOn ?? ((res) => isRetryableStatus(res.status));
33
34
  for (let attempt = 1;; attempt++) {
34
35
  const timeout = AbortSignal.timeout(policy.timeoutMs);
35
36
  const signal = init.signal ? AbortSignal.any([init.signal, timeout]) : timeout;
36
37
  const res = await fetchFn(url, { ...init, signal });
37
- if (!isRetryableStatus(res.status) || attempt >= attempts)
38
+ if (!retryOn(res) || attempt >= attempts)
38
39
  return res;
39
40
  const retryAfter = parseRetryAfterMs(res.headers.get('retry-after'));
40
41
  if (retryAfter !== null && retryAfter > maxDelayMs)
@@ -28,6 +28,9 @@ export declare function sendJson<T>(res: ServerResponse, status: number, body: T
28
28
  * mid-stream so we don't wait for an attacker to finish before erroring out.
29
29
  */
30
30
  export declare function readBody(req: IncomingMessage): Promise<string>;
31
+ export declare const LOOPBACK_HOST_HEADER: RegExp;
32
+ /** A browser request sent by another site. Non-browser clients send neither header and pass. */
33
+ export declare function isCrossSite(req: IncomingMessage): boolean;
31
34
  /** Per-request values a connector webhook receiver reads; ServeOpts and the /v1 RouteRequest both satisfy it. */
32
35
  export interface WebhookRequest {
33
36
  req: IncomingMessage;
package/dist/http-util.js CHANGED
@@ -53,4 +53,14 @@ export async function readBody(req) {
53
53
  }
54
54
  return Buffer.concat(chunks).toString('utf8');
55
55
  }
56
+ // Any other Host on a loopback socket is DNS rebinding: a hostile page resolved to 127.0.0.1.
57
+ export const LOOPBACK_HOST_HEADER = /^(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/i;
58
+ /** A browser request sent by another site. Non-browser clients send neither header and pass. */
59
+ export function isCrossSite(req) {
60
+ const site = req.headers['sec-fetch-site'];
61
+ if (site !== undefined && site !== 'same-origin' && site !== 'none')
62
+ return true;
63
+ const origin = req.headers.origin;
64
+ return origin !== undefined && origin !== `http://${req.headers.host}`;
65
+ }
56
66
  //# sourceMappingURL=http-util.js.map
@@ -2,7 +2,7 @@
2
2
  * Memory importers for Hippo.
3
3
  * Imports memories from ChatGPT, Claude, Cursor, generic files, and structured markdown.
4
4
  */
5
- import { MemoryEntry } from './memory.js';
5
+ import { MemoryEntry } from '../memory.js';
6
6
  export interface ImportResult {
7
7
  total: number;
8
8
  imported: number;
@@ -58,19 +58,15 @@ export interface ImportOptions {
58
58
  * create MemoryEntry objects, write them (unless dry-run), and return a result.
59
59
  */
60
60
  export declare function importEntries(chunks: string[], source: string, tags: string[], options: ImportOptions): ImportResult;
61
- export declare function importChatGPT(filePath: string, options: ImportOptions): ImportResult;
62
- export declare function importClaude(filePath: string, options: ImportOptions): ImportResult;
63
- /** Import `.cursorrules`, one rule file, or a `.cursor/rules` tree of `.mdc` and `.md` rules. */
64
- export declare function importCursor(sourcePath: string, options: ImportOptions): ImportResult;
65
- export declare function importGenericFile(filePath: string, options: ImportOptions): ImportResult;
66
- export declare function importMarkdown(filePath: string, options: ImportOptions): ImportResult;
67
- /**
68
- * Import a markdown vault FOLDER as `kind='raw'` memories.
69
- *
70
- * NOT re-entrant: idempotency rests on the in-memory `existing` Map loaded once
71
- * at the top. Two concurrent importVault runs over the same vault could both see
72
- * a note as absent and double-insert (the connector pattern relies on a single
73
- * sequential writer; same caveat applies here).
74
- */
75
- export declare function importVault(folderPath: string, options: ImportOptions): ImportResult;
76
- //# sourceMappingURL=importers.d.ts.map
61
+ /** The full value space `JSON.parse` can produce. Boundary-guard functions in
62
+ * this file accept `JsonValue` (never `unknown`) so a value's origin as
63
+ * unparsed external JSON stays visible in its type, then narrow it via the
64
+ * `isJson*` predicates below. */
65
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
66
+ [key: string]: JsonValue;
67
+ };
68
+ export declare function isJsonString(x: JsonValue): x is string;
69
+ export declare function isJsonPlainObject(x: JsonValue): x is {
70
+ [key: string]: JsonValue;
71
+ };
72
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Memory importers for Hippo.
3
+ * Imports memories from ChatGPT, Claude, Cursor, generic files, and structured markdown.
4
+ */
5
+ import { createMemory, Layer } from '../memory.js';
6
+ import { writeEntry } from '../store/entry-writes.js';
7
+ import { loadAllEntries } from '../store/entry-reads.js';
8
+ import { duplicateKey, storedTextKeys } from '../same-text.js';
9
+ import { getGlobalRoot, initGlobal } from '../shared.js';
10
+ import { openHippoDb, closeHippoDb } from '../db.js';
11
+ import { RejectedValueError, checkRejectionGuard } from '../rejection.js';
12
+ import { loadConfig } from '../config.js';
13
+ import { vetSecrets } from '../secret-detect.js';
14
+ import { log } from '../log.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Shared core: dedup + write
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Given an array of raw text chunks, deduplicate against existing memories,
20
+ * create MemoryEntry objects, write them (unless dry-run), and return a result.
21
+ */
22
+ export function importEntries(chunks, source, tags, options) {
23
+ const targetRoot = options.global ? getGlobalRoot() : options.hippoRoot;
24
+ // Ensure store is ready
25
+ if (options.global) {
26
+ initGlobal();
27
+ }
28
+ const keys = storedTextKeys(loadAllEntries(targetRoot, options.global ? undefined : options.tenantId));
29
+ const allTags = [...new Set([...tags, ...(options.extraTags ?? [])])];
30
+ const baseHalfLifeDays = loadConfig(targetRoot).defaultHalfLifeDays;
31
+ let total = 0;
32
+ let imported = 0;
33
+ let skipped = 0;
34
+ let rejected = 0;
35
+ let redacted = 0;
36
+ const entries = [];
37
+ // AT1 P2 fix: a dry-run preview never called writeEntry, so it never
38
+ // checked tombstones either — every non-duplicate chunk counted as
39
+ // `imported` even when a real run would refuse it, making the preview's
40
+ // `rejected` count silently 0. Probe (read-only) via the same guard
41
+ // writeEntry uses internally, without ever writing.
42
+ const dryRunDb = options.dryRun ? openHippoDb(targetRoot) : null;
43
+ try {
44
+ for (const raw of chunks) {
45
+ const { chunk, wasRedacted } = prepareImportChunk(raw, allTags);
46
+ // Skip empty or too-short chunks
47
+ if (!chunk || chunk.length < 10) {
48
+ skipped++;
49
+ continue;
50
+ }
51
+ total++;
52
+ // Dedup check: skip only when the same text is already stored
53
+ if (keys.has(duplicateKey(chunk))) {
54
+ skipped++;
55
+ continue;
56
+ }
57
+ const entry = createImportEntry(chunk, source, allTags, options, baseHalfLifeDays);
58
+ if (!writeOrProbeImport(targetRoot, entry, options, dryRunDb)) {
59
+ rejected++;
60
+ continue;
61
+ }
62
+ // Add to existing so subsequent chunks dedup against freshly imported ones
63
+ if (!options.dryRun)
64
+ keys.add(duplicateKey(chunk));
65
+ entries.push(entry);
66
+ imported++;
67
+ if (wasRedacted)
68
+ redacted++;
69
+ }
70
+ return { total, imported, skipped, rejected, redacted, entries };
71
+ }
72
+ finally {
73
+ if (dryRunDb)
74
+ closeHippoDb(dryRunDb);
75
+ }
76
+ }
77
+ /** The secret-vetted chunk capped at 1000 chars, and whether vetting changed it. */
78
+ function prepareImportChunk(raw, allTags) {
79
+ const original = raw.trim();
80
+ const trimmed = vetSecrets(original, allTags, true).content;
81
+ const wasRedacted = trimmed !== original;
82
+ if (trimmed.length > 1000) {
83
+ log.warn(`imported memory truncated from ${trimmed.length} to 1000 chars`);
84
+ }
85
+ return { chunk: trimmed.slice(0, 1000), wasRedacted };
86
+ }
87
+ function createImportEntry(chunk, source, allTags, options, baseHalfLifeDays) {
88
+ // A3: kind defaults to 'distilled'. ChatGPT/Claude/Cursor exports are curated
89
+ // user pastes, not raw transcripts from a system of record, so distilled is
90
+ // correct here. E1.3 (Slack ingestion) shipped 2026-04-29 in src/connectors/slack/
91
+ // and sets kind: 'raw' + routes deletions through archiveRawMemory() — these
92
+ // importers stay 'distilled' per the original reasoning. See MEMORY_ENVELOPE.md.
93
+ // L9: the dedup read above is scoped by options.tenantId — the WRITE
94
+ // must match, or scoped-dedup-passes-then-default-tenant-write breaks
95
+ // the per-tenant contract. Mirror the dedup-read guard: global=true
96
+ // → host-wide write to global store (tenantId irrelevant, createMemory
97
+ // defaults to 'default'). global=false → write to the same tenant as
98
+ // the dedup read.
99
+ return createMemory(chunk, {
100
+ layer: Layer.Episodic,
101
+ tags: allTags,
102
+ source,
103
+ confidence: 'observed',
104
+ tenantId: options.global ? undefined : options.tenantId,
105
+ baseHalfLifeDays,
106
+ });
107
+ }
108
+ /** Writes the entry, or on a dry run only probes the guard; false when a rejected value refuses it. */
109
+ function writeOrProbeImport(targetRoot, entry, options, dryRunDb) {
110
+ if (options.dryRun) {
111
+ if (dryRunDb) {
112
+ try {
113
+ checkRejectionGuard(dryRunDb, entry.tenantId ?? 'default', entry.id, entry.content);
114
+ }
115
+ catch (err) {
116
+ if (err instanceof RejectedValueError)
117
+ return false;
118
+ throw err;
119
+ }
120
+ }
121
+ return true;
122
+ }
123
+ // AT1 (plan §3 containment): a rejection refuses one CHUNK, not the
124
+ // whole import batch. Caught per-item so siblings still land.
125
+ try {
126
+ writeEntry(targetRoot, entry);
127
+ }
128
+ catch (err) {
129
+ if (err instanceof RejectedValueError)
130
+ return false;
131
+ throw err;
132
+ }
133
+ return true;
134
+ }
135
+ export function isJsonString(x) {
136
+ return typeof x === 'string';
137
+ }
138
+ export function isJsonPlainObject(x) {
139
+ return x !== null && !Array.isArray(x) && typeof x === 'object';
140
+ }
141
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1,41 @@
1
+ /** Minimal inline frontmatter split. Recognises a leading `---\n…\n---\n`
2
+ * block (no YAML dep). Returns the parsed key→value map plus the body with the
3
+ * block removed. When no well-formed block is present, `fm` is empty and
4
+ * `body` is the original content. */
5
+ interface FrontmatterParseResult {
6
+ fm: Record<string, string>;
7
+ body: string;
8
+ }
9
+ export declare function parseFrontmatter(raw: string): FrontmatterParseResult;
10
+ /** Pull a frontmatter field that may be a YAML flow list (`[a, b]`), a
11
+ * comma-separated scalar (`a, b`), or a single token, into a string[]. Quotes
12
+ * and surrounding brackets are stripped; empty entries dropped. */
13
+ export declare function frontmatterList(value: string | undefined): string[];
14
+ /** Parse `[[wikilinks]]` from body text. `[[target]]` and `[[target|alias]]`
15
+ * both yield `target` (alias dropped). Returns de-duplicated, order-preserving
16
+ * target strings (trimmed). Embeds (`![[…]]`) are intentionally matched too —
17
+ * the leading `!` is not part of the `[[…]]` capture, so an embed contributes
18
+ * its target as a candidate, which is the desired no-crash baseline behaviour. */
19
+ export declare function parseWikilinks(body: string): string[];
20
+ /** Recursively collect files whose name matches `match` (`*.md` by default) under `root`,
21
+ * as paths relative to `root` with forward-slash separators (stable artifactRef keys across OSes).
22
+ * Symlinks are not followed. Skips dot-directories (the default `.hippo` store,
23
+ * `.git`, `.obsidian`, `.trash`) AND the canonicalized Hippo store path during
24
+ * the walk, so re-importing a vault that CONTAINS the store never ingests its own
25
+ * markdown mirror files (codex R5 P1: `hippo import --vault .` after `hippo
26
+ * init` in the vault would otherwise self-import its mirror rows and grow on
27
+ * every run). The root-IS-the-store case is handled one level up in
28
+ * importVault (a no-op early return), NOT here: returning [] for it would feed
29
+ * the deletion-sync an empty scan that mass-archives every live row (codex R8). */
30
+ export declare function collectMarkdownFiles(root: string, hippoRoot: string, match?: RegExp): string[];
31
+ /** Canonicalize a path for the self-store comparison: dereference symlinks /
32
+ * junctions and normalize case (Windows) via the OS realpath, so a junction or
33
+ * a case-variant path to the store is still recognized as self-store (codex R9
34
+ * P2: path.resolve does neither, so an aliased store path slipped past the
35
+ * guard and triggered the mass-archive). Falls back to path.resolve when the
36
+ * path does not exist yet - an uninitialized store or a typo'd vault path
37
+ * cannot be a live self-store, and a non-existent vault folder fails later in
38
+ * the walk (readdirSync) before deletion-sync can archive anything. */
39
+ export declare function realpathOrResolve(p: string): string;
40
+ export {};
41
+ //# sourceMappingURL=markdown-parse.d.ts.map
@@ -0,0 +1,132 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { log } from '../log.js';
4
+ export function parseFrontmatter(raw) {
5
+ // Must start with `---` on its own line. Accept CRLF or LF.
6
+ const m = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
7
+ if (!m)
8
+ return { fm: {}, body: raw };
9
+ const block = m[1];
10
+ const body = raw.slice(m[0].length);
11
+ const fm = {};
12
+ const lines = block.split(/\r?\n/);
13
+ for (let i = 0; i < lines.length; i++) {
14
+ const kv = lines[i].match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);
15
+ if (!kv)
16
+ continue;
17
+ let val = kv[2].trim();
18
+ if (val === '') {
19
+ // YAML block-style list: `key:` followed by indented `- item` lines
20
+ // (common in Obsidian/Dendron frontmatter). Collect them into a
21
+ // comma-joined value so frontmatterList parses them (codex P2).
22
+ const items = [];
23
+ let j = i + 1;
24
+ let item;
25
+ while (j < lines.length && (item = lines[j].match(/^\s+-\s+(.+?)\s*$/)) !== null) {
26
+ items.push(item[1].replace(/^['"]|['"]$/g, '').trim());
27
+ j++;
28
+ }
29
+ if (items.length) {
30
+ val = items.join(', ');
31
+ i = j - 1;
32
+ }
33
+ }
34
+ fm[kv[1]] = val;
35
+ }
36
+ return { fm, body };
37
+ }
38
+ /** Pull a frontmatter field that may be a YAML flow list (`[a, b]`), a
39
+ * comma-separated scalar (`a, b`), or a single token, into a string[]. Quotes
40
+ * and surrounding brackets are stripped; empty entries dropped. */
41
+ export function frontmatterList(value) {
42
+ if (!value)
43
+ return [];
44
+ let v = value.trim();
45
+ if (v.startsWith('[') && v.endsWith(']'))
46
+ v = v.slice(1, -1);
47
+ return v
48
+ .split(',')
49
+ .map((s) => s.trim().replace(/^['"]|['"]$/g, '').trim())
50
+ .filter(Boolean);
51
+ }
52
+ /** Parse `[[wikilinks]]` from body text. `[[target]]` and `[[target|alias]]`
53
+ * both yield `target` (alias dropped). Returns de-duplicated, order-preserving
54
+ * target strings (trimmed). Embeds (`![[…]]`) are intentionally matched too —
55
+ * the leading `!` is not part of the `[[…]]` capture, so an embed contributes
56
+ * its target as a candidate, which is the desired no-crash baseline behaviour. */
57
+ export function parseWikilinks(body) {
58
+ const out = [];
59
+ const seen = new Set();
60
+ const re = /\[\[([^\]]+?)\]\]/g;
61
+ let match;
62
+ while ((match = re.exec(body)) !== null) {
63
+ const inner = match[1];
64
+ const target = (inner.split('|')[0] ?? '').trim();
65
+ if (!target)
66
+ continue;
67
+ if (seen.has(target))
68
+ continue;
69
+ seen.add(target);
70
+ out.push(target);
71
+ }
72
+ return out;
73
+ }
74
+ /** Recursively collect files whose name matches `match` (`*.md` by default) under `root`,
75
+ * as paths relative to `root` with forward-slash separators (stable artifactRef keys across OSes).
76
+ * Symlinks are not followed. Skips dot-directories (the default `.hippo` store,
77
+ * `.git`, `.obsidian`, `.trash`) AND the canonicalized Hippo store path during
78
+ * the walk, so re-importing a vault that CONTAINS the store never ingests its own
79
+ * markdown mirror files (codex R5 P1: `hippo import --vault .` after `hippo
80
+ * init` in the vault would otherwise self-import its mirror rows and grow on
81
+ * every run). The root-IS-the-store case is handled one level up in
82
+ * importVault (a no-op early return), NOT here: returning [] for it would feed
83
+ * the deletion-sync an empty scan that mass-archives every live row (codex R8). */
84
+ export function collectMarkdownFiles(root, hippoRoot, match = /\.md$/i) {
85
+ const out = [];
86
+ // Canonicalize (realpath) so a non-dot HIPPO_HOME store nested in the vault is
87
+ // skipped even when hippoRoot is an aliased path (junction / Windows case
88
+ // variant); path.resolve would miss it and self-import the store's mirror
89
+ // files (codex R9 follow-up: same gap as the importVault guard, sibling site).
90
+ const resolvedHippoRoot = realpathOrResolve(hippoRoot);
91
+ const walk = (dir) => {
92
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
93
+ for (const ent of entries) {
94
+ if (ent.isSymbolicLink())
95
+ continue;
96
+ const abs = path.join(dir, ent.name);
97
+ if (ent.isDirectory()) {
98
+ // Skip dot-dirs (config/system, incl. the default `.hippo` store) and
99
+ // the canonicalized store path (covers a HIPPO_HOME outside `.hippo`).
100
+ if (ent.name.startsWith('.'))
101
+ continue;
102
+ if (realpathOrResolve(abs) === resolvedHippoRoot)
103
+ continue;
104
+ walk(abs);
105
+ }
106
+ else if (ent.isFile() && match.test(ent.name)) {
107
+ out.push(path.relative(root, abs).split(path.sep).join('/'));
108
+ }
109
+ }
110
+ };
111
+ walk(root);
112
+ out.sort();
113
+ return out;
114
+ }
115
+ /** Canonicalize a path for the self-store comparison: dereference symlinks /
116
+ * junctions and normalize case (Windows) via the OS realpath, so a junction or
117
+ * a case-variant path to the store is still recognized as self-store (codex R9
118
+ * P2: path.resolve does neither, so an aliased store path slipped past the
119
+ * guard and triggered the mass-archive). Falls back to path.resolve when the
120
+ * path does not exist yet - an uninitialized store or a typo'd vault path
121
+ * cannot be a live self-store, and a non-existent vault folder fails later in
122
+ * the walk (readdirSync) before deletion-sync can archive anything. */
123
+ export function realpathOrResolve(p) {
124
+ try {
125
+ return fs.realpathSync.native(p);
126
+ }
127
+ catch (err) {
128
+ log.debug(`import: realpath fell back to resolve for ${p}: ${err instanceof Error ? err.message : String(err)}`);
129
+ return path.resolve(p);
130
+ }
131
+ }
132
+ //# sourceMappingURL=markdown-parse.js.map
@@ -0,0 +1,3 @@
1
+ import { type ImportResult, type ImportOptions } from './core.js';
2
+ export declare function importMarkdown(filePath: string, options: ImportOptions): ImportResult;
3
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1,92 @@
1
+ import * as fs from 'fs';
2
+ import { importEntries } from './core.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Structured markdown importer (MEMORY.md / AGENTS.md format)
5
+ // ---------------------------------------------------------------------------
6
+ /**
7
+ * Slugify a heading for use as a tag.
8
+ * "Data Pipeline & Cache" -> "data-pipeline-cache"
9
+ */
10
+ function slugify(heading) {
11
+ return heading
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9\s-]/g, ' ')
14
+ .trim()
15
+ .replace(/\s+/g, '-')
16
+ .replace(/-+/g, '-')
17
+ .slice(0, 50);
18
+ }
19
+ /**
20
+ * Parse structured markdown into {content, sectionSlug} pairs.
21
+ * Each heading starts a new section. Bullet points / numbered items under
22
+ * the heading become individual memories tagged with the section slug.
23
+ */
24
+ function parseStructuredMarkdown(raw) {
25
+ const results = [];
26
+ const lines = raw.split('\n');
27
+ let currentSection = '';
28
+ let currentSlug = '';
29
+ let pendingText = '';
30
+ function flush() {
31
+ if (!pendingText.trim())
32
+ return;
33
+ results.push({ content: pendingText.trim(), sectionSlug: currentSlug });
34
+ pendingText = '';
35
+ }
36
+ for (const line of lines) {
37
+ const trimmed = line.trim();
38
+ // Heading
39
+ const headingMatch = trimmed.match(/^(#{1,6})\s+(.+)/);
40
+ if (headingMatch) {
41
+ flush();
42
+ currentSection = headingMatch[2].trim();
43
+ currentSlug = slugify(currentSection);
44
+ continue;
45
+ }
46
+ // Bullet or numbered item: flush previous, start new
47
+ if (/^[-*+]\s+/.test(trimmed) || /^\d+\.\s+/.test(trimmed)) {
48
+ flush();
49
+ const itemText = trimmed.replace(/^[-*+]\s+/, '').replace(/^\d+\.\s+/, '').trim();
50
+ pendingText = itemText;
51
+ continue;
52
+ }
53
+ // Empty line: flush current pending
54
+ if (!trimmed) {
55
+ flush();
56
+ continue;
57
+ }
58
+ // Continuation of current item
59
+ pendingText = pendingText ? pendingText + ' ' + trimmed : trimmed;
60
+ }
61
+ flush();
62
+ return results.filter((r) => r.content.length > 0);
63
+ }
64
+ export function importMarkdown(filePath, options) {
65
+ const raw = fs.readFileSync(filePath, 'utf8');
66
+ const parsed = parseStructuredMarkdown(raw);
67
+ // Group by section slug so we can pass per-chunk tags
68
+ // We call importEntries per unique slug to get the right tags per section
69
+ const bySlug = new Map();
70
+ for (const { content, sectionSlug } of parsed) {
71
+ const list = bySlug.get(sectionSlug) ?? [];
72
+ list.push(content);
73
+ bySlug.set(sectionSlug, list);
74
+ }
75
+ let totalResult = { total: 0, imported: 0, skipped: 0, rejected: 0, entries: [] };
76
+ for (const [slug, chunks] of bySlug.entries()) {
77
+ const sectionTags = slug ? ['imported', slug] : ['imported'];
78
+ const result = importEntries(chunks, 'import:markdown', sectionTags, options);
79
+ totalResult = {
80
+ total: totalResult.total + result.total,
81
+ imported: totalResult.imported + result.imported,
82
+ skipped: totalResult.skipped + result.skipped,
83
+ // AT1 P2 fix: `rejected` is now optional on ImportResult (compat) — tolerate
84
+ // undefined on either side of the accumulation.
85
+ rejected: (totalResult.rejected ?? 0) + (result.rejected ?? 0),
86
+ redacted: (totalResult.redacted ?? 0) + (result.redacted ?? 0),
87
+ entries: [...totalResult.entries, ...result.entries],
88
+ };
89
+ }
90
+ return totalResult;
91
+ }
92
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1,7 @@
1
+ import { type ImportResult, type ImportOptions } from './core.js';
2
+ export declare function importChatGPT(filePath: string, options: ImportOptions): ImportResult;
3
+ export declare function importClaude(filePath: string, options: ImportOptions): ImportResult;
4
+ /** Import `.cursorrules`, one rule file, or a `.cursor/rules` tree of `.mdc` and `.md` rules. */
5
+ export declare function importCursor(sourcePath: string, options: ImportOptions): ImportResult;
6
+ export declare function importGenericFile(filePath: string, options: ImportOptions): ImportResult;
7
+ //# sourceMappingURL=sources.d.ts.map