hippo-memory 1.70.0 → 1.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (629) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/claude-code.d.ts +4 -2
  3. package/dist/agent-memories/claude-code.js +14 -5
  4. package/dist/agent-memories/files.js +23 -12
  5. package/dist/agent-memories/markdown.d.ts +1 -3
  6. package/dist/agent-memories/markdown.js +1 -3
  7. package/dist/agent-memories/report.js +2 -1
  8. package/dist/agent-memories/sync.d.ts +4 -2
  9. package/dist/agent-memories/sync.js +10 -5
  10. package/dist/api/assemble.d.ts +7 -44
  11. package/dist/api/assemble.js +2 -22
  12. package/dist/api/audit.d.ts +5 -1
  13. package/dist/api/audit.js +9 -1
  14. package/dist/api/auth.d.ts +13 -22
  15. package/dist/api/auth.js +34 -24
  16. package/dist/api/auto-sleep.js +2 -2
  17. package/dist/api/availability.d.ts +2 -15
  18. package/dist/api/availability.js +2 -15
  19. package/dist/api/context-select.js +3 -4
  20. package/dist/api/context-types.d.ts +10 -35
  21. package/dist/api/context.d.ts +5 -22
  22. package/dist/api/context.js +21 -38
  23. package/dist/api/dormant.d.ts +5 -21
  24. package/dist/api/dormant.js +7 -26
  25. package/dist/api/drill-down.d.ts +7 -46
  26. package/dist/api/drill-down.js +5 -26
  27. package/dist/api/forget.d.ts +5 -24
  28. package/dist/api/forget.js +5 -28
  29. package/dist/api/graph.d.ts +8 -0
  30. package/dist/api/graph.js +7 -0
  31. package/dist/api/index.d.ts +2 -0
  32. package/dist/api/index.js +2 -0
  33. package/dist/api/instruction-detect.js +16 -5
  34. package/dist/api/ledger-db.d.ts +2 -1
  35. package/dist/api/ledger-db.js +5 -3
  36. package/dist/api/memories.d.ts +5 -0
  37. package/dist/api/memories.js +7 -0
  38. package/dist/api/objects.d.ts +9 -0
  39. package/dist/api/objects.js +11 -0
  40. package/dist/api/on-store.js +5 -3
  41. package/dist/api/predictions.d.ts +9 -0
  42. package/dist/api/predictions.js +18 -0
  43. package/dist/api/promote.d.ts +13 -17
  44. package/dist/api/promote.js +11 -19
  45. package/dist/api/prompt-hook.d.ts +4 -4
  46. package/dist/api/prompt-hook.js +10 -9
  47. package/dist/api/recall-cli.d.ts +55 -0
  48. package/dist/api/recall-cli.js +94 -0
  49. package/dist/api/recall-core.js +14 -6
  50. package/dist/api/recall-finish.d.ts +53 -0
  51. package/dist/api/recall-finish.js +30 -0
  52. package/dist/api/recall-history.d.ts +17 -84
  53. package/dist/api/recall-history.js +15 -88
  54. package/dist/api/recall-pipeline.d.ts +2 -3
  55. package/dist/api/recall-pipeline.js +16 -9
  56. package/dist/api/recall-types.d.ts +64 -304
  57. package/dist/api/recall.d.ts +5 -33
  58. package/dist/api/recall.js +59 -60
  59. package/dist/api/refine.d.ts +7 -0
  60. package/dist/api/refine.js +10 -0
  61. package/dist/api/remember-local.d.ts +57 -0
  62. package/dist/api/remember-local.js +90 -0
  63. package/dist/api/remember.d.ts +18 -1
  64. package/dist/api/remember.js +13 -1
  65. package/dist/api/sleep-run.d.ts +1 -3
  66. package/dist/api/sleep-run.js +17 -21
  67. package/dist/api/sleep.d.ts +9 -28
  68. package/dist/api/tokens.d.ts +3 -10
  69. package/dist/api/tokens.js +3 -10
  70. package/dist/api/types.d.ts +6 -29
  71. package/dist/api/types.js +4 -22
  72. package/dist/capture/command.d.ts +4 -12
  73. package/dist/capture/command.js +6 -22
  74. package/dist/capture/compact.d.ts +4 -15
  75. package/dist/capture/compact.js +16 -25
  76. package/dist/capture/compaction-record.js +101 -69
  77. package/dist/capture/compaction-spool.d.ts +1 -1
  78. package/dist/capture/compaction-spool.js +1 -1
  79. package/dist/capture/session-digest.d.ts +1 -1
  80. package/dist/capture/session-digest.js +13 -7
  81. package/dist/capture/transcript.d.ts +2 -10
  82. package/dist/capture/transcript.js +4 -18
  83. package/dist/cli/api-context.d.ts +3 -0
  84. package/dist/cli/api-context.js +6 -0
  85. package/dist/cli/audit-prune.d.ts +6 -39
  86. package/dist/cli/audit-prune.js +6 -39
  87. package/dist/cli/audit.d.ts +1 -1
  88. package/dist/cli/audit.js +33 -34
  89. package/dist/cli/auth.d.ts +2 -2
  90. package/dist/cli/auth.js +57 -39
  91. package/dist/cli/briefs.d.ts +4 -4
  92. package/dist/cli/briefs.js +18 -22
  93. package/dist/cli/card.d.ts +2 -2
  94. package/dist/cli/card.js +31 -32
  95. package/dist/cli/client.d.ts +7 -27
  96. package/dist/cli/client.js +24 -43
  97. package/dist/cli/compact-resume-payload.js +3 -2
  98. package/dist/cli/context.d.ts +1 -2
  99. package/dist/cli/context.js +12 -8
  100. package/dist/cli/continuity.d.ts +6 -6
  101. package/dist/cli/continuity.js +62 -64
  102. package/dist/cli/correction-latency.d.ts +2 -14
  103. package/dist/cli/correction-latency.js +2 -14
  104. package/dist/cli/curate.d.ts +13 -17
  105. package/dist/cli/curate.js +68 -92
  106. package/dist/cli/dag.d.ts +4 -4
  107. package/dist/cli/dag.js +33 -27
  108. package/dist/cli/decisions.d.ts +4 -4
  109. package/dist/cli/decisions.js +33 -47
  110. package/dist/cli/eval.js +15 -13
  111. package/dist/cli/exit.d.ts +6 -0
  112. package/dist/cli/exit.js +11 -0
  113. package/dist/cli/explain.d.ts +1 -2
  114. package/dist/cli/explain.js +6 -4
  115. package/dist/cli/flag-values.d.ts +6 -1
  116. package/dist/cli/flag-values.js +27 -10
  117. package/dist/cli/flags.d.ts +1 -0
  118. package/dist/cli/flags.js +1 -1
  119. package/dist/cli/github.d.ts +14 -0
  120. package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
  121. package/dist/cli/goals.d.ts +2 -2
  122. package/dist/cli/goals.js +46 -50
  123. package/dist/cli/hook-runtime.d.ts +9 -27
  124. package/dist/cli/hook-runtime.js +15 -31
  125. package/dist/cli/init.d.ts +2 -2
  126. package/dist/cli/init.js +6 -12
  127. package/dist/cli/install-steps.js +3 -12
  128. package/dist/cli/last-sleep.d.ts +2 -1
  129. package/dist/cli/last-sleep.js +3 -0
  130. package/dist/cli/maintenance.d.ts +4 -4
  131. package/dist/cli/maintenance.js +14 -19
  132. package/dist/cli/object-verbs.js +4 -3
  133. package/dist/cli/owner-validation.d.ts +5 -28
  134. package/dist/cli/owner-validation.js +5 -28
  135. package/dist/cli/playbooks.d.ts +4 -4
  136. package/dist/cli/playbooks.js +23 -28
  137. package/dist/cli/print.d.ts +2 -5
  138. package/dist/cli/print.js +1 -4
  139. package/dist/cli/projects.d.ts +2 -2
  140. package/dist/cli/projects.js +1 -3
  141. package/dist/cli/provenance-coverage.d.ts +2 -6
  142. package/dist/cli/provenance-coverage.js +2 -6
  143. package/dist/cli/quality-repair-once.js +2 -2
  144. package/dist/cli/recall.d.ts +2 -4
  145. package/dist/cli/recall.js +55 -131
  146. package/dist/cli/refine-llm.d.ts +5 -31
  147. package/dist/cli/refine-llm.js +9 -36
  148. package/dist/cli/remember.d.ts +3 -3
  149. package/dist/cli/remember.js +122 -180
  150. package/dist/cli/scheduler.d.ts +2 -17
  151. package/dist/cli/scheduler.js +12 -18
  152. package/dist/cli/serve.js +21 -12
  153. package/dist/cli/session-hooks.d.ts +10 -18
  154. package/dist/cli/session-hooks.js +112 -113
  155. package/dist/cli/setup.d.ts +4 -4
  156. package/dist/cli/setup.js +19 -21
  157. package/dist/cli/shared.d.ts +9 -23
  158. package/dist/cli/shared.js +9 -32
  159. package/dist/cli/slack.d.ts +2 -2
  160. package/dist/cli/slack.js +19 -23
  161. package/dist/cli/sleep.d.ts +3 -2
  162. package/dist/cli/sleep.js +15 -16
  163. package/dist/cli/status.d.ts +9 -12
  164. package/dist/cli/status.js +55 -98
  165. package/dist/cli/stdin.d.ts +4 -6
  166. package/dist/cli/stdin.js +2 -3
  167. package/dist/cli/transfer.d.ts +9 -9
  168. package/dist/cli/transfer.js +66 -89
  169. package/dist/cli/usage.js +11 -5
  170. package/dist/cli.d.ts +66 -448
  171. package/dist/cli.js +87 -263
  172. package/dist/connectors/github/backfill.d.ts +5 -25
  173. package/dist/connectors/github/backfill.js +14 -49
  174. package/dist/connectors/github/deletion.d.ts +4 -18
  175. package/dist/connectors/github/deletion.js +2 -15
  176. package/dist/connectors/github/dlq.d.ts +8 -33
  177. package/dist/connectors/github/dlq.js +12 -29
  178. package/dist/connectors/github/ingest.d.ts +2 -6
  179. package/dist/connectors/github/ingest.js +4 -10
  180. package/dist/connectors/github/octokit-client.d.ts +4 -16
  181. package/dist/connectors/github/octokit-client.js +27 -24
  182. package/dist/connectors/github/ratelimit.d.ts +3 -14
  183. package/dist/connectors/github/ratelimit.js +3 -14
  184. package/dist/connectors/github/scope.d.ts +3 -5
  185. package/dist/connectors/github/scope.js +3 -5
  186. package/dist/connectors/github/signature.d.ts +4 -26
  187. package/dist/connectors/github/signature.js +4 -26
  188. package/dist/connectors/github/tenant-routing.d.ts +2 -24
  189. package/dist/connectors/github/tenant-routing.js +4 -26
  190. package/dist/connectors/github/transform.js +2 -16
  191. package/dist/connectors/github/types.d.ts +3 -15
  192. package/dist/connectors/github/types.js +2 -9
  193. package/dist/connectors/github/webhook.d.ts +2 -16
  194. package/dist/connectors/github/webhook.js +6 -22
  195. package/dist/connectors/slack/backfill.d.ts +4 -17
  196. package/dist/connectors/slack/backfill.js +4 -13
  197. package/dist/connectors/slack/dlq.d.ts +2 -19
  198. package/dist/connectors/slack/dlq.js +2 -19
  199. package/dist/connectors/slack/ingest.d.ts +2 -3
  200. package/dist/connectors/slack/ingest.js +2 -3
  201. package/dist/connectors/slack/scope.d.ts +2 -8
  202. package/dist/connectors/slack/scope.js +2 -8
  203. package/dist/connectors/slack/signature.d.ts +1 -6
  204. package/dist/connectors/slack/tenant-routing.d.ts +2 -19
  205. package/dist/connectors/slack/tenant-routing.js +2 -21
  206. package/dist/connectors/slack/transform.d.ts +2 -18
  207. package/dist/connectors/slack/transform.js +2 -18
  208. package/dist/connectors/slack/types.d.ts +3 -9
  209. package/dist/connectors/slack/types.js +2 -4
  210. package/dist/connectors/slack/web-client.js +33 -27
  211. package/dist/connectors/slack/webhook.d.ts +2 -19
  212. package/dist/connectors/slack/webhook.js +5 -26
  213. package/dist/connectors/slack/workspaces.d.ts +4 -24
  214. package/dist/connectors/slack/workspaces.js +4 -24
  215. package/dist/consolidate/conflicts.js +6 -14
  216. package/dist/consolidate/dag-summary.d.ts +8 -0
  217. package/dist/consolidate/dag-summary.js +41 -0
  218. package/dist/consolidate/dag.d.ts +5 -28
  219. package/dist/consolidate/dag.js +14 -75
  220. package/dist/consolidate/decay.js +7 -19
  221. package/dist/consolidate/dedupe.d.ts +6 -52
  222. package/dist/consolidate/dedupe.js +13 -71
  223. package/dist/consolidate/flush-units.d.ts +3 -4
  224. package/dist/consolidate/flush-units.js +3 -3
  225. package/dist/consolidate/half-life-migration.d.ts +3 -26
  226. package/dist/consolidate/half-life-migration.js +11 -28
  227. package/dist/consolidate/llm-passes.js +4 -21
  228. package/dist/consolidate/memory-value-weights.d.ts +2 -13
  229. package/dist/consolidate/memory-value-weights.js +2 -13
  230. package/dist/consolidate/memory-value.d.ts +11 -84
  231. package/dist/consolidate/memory-value.js +16 -104
  232. package/dist/consolidate/merge.js +10 -31
  233. package/dist/consolidate/merged-row.js +2 -1
  234. package/dist/consolidate/physics-pass.js +1 -3
  235. package/dist/consolidate/replay.d.ts +6 -38
  236. package/dist/consolidate/replay.js +14 -52
  237. package/dist/consolidate/run.js +1 -1
  238. package/dist/consolidate/sleep.d.ts +1 -8
  239. package/dist/consolidate/sleep.js +5 -17
  240. package/dist/consolidate/trace.d.ts +3 -18
  241. package/dist/consolidate/trace.js +3 -18
  242. package/dist/consolidate/traces.js +6 -22
  243. package/dist/core/ablation.d.ts +4 -91
  244. package/dist/core/ablation.js +4 -91
  245. package/dist/core/ambient.d.ts +1 -8
  246. package/dist/core/ambient.js +1 -8
  247. package/dist/core/capture-contract.d.ts +4 -2
  248. package/dist/core/capture-contract.js +4 -2
  249. package/dist/core/card.d.ts +4 -1
  250. package/dist/core/card.js +8 -0
  251. package/dist/core/compare.d.ts +11 -67
  252. package/dist/core/compare.js +9 -63
  253. package/dist/core/config.d.ts +10 -24
  254. package/dist/core/config.js +13 -14
  255. package/dist/core/handoff.d.ts +1 -7
  256. package/dist/core/handoff.js +1 -7
  257. package/dist/core/memory-quality.js +1 -1
  258. package/dist/core/memory.d.ts +41 -164
  259. package/dist/core/memory.js +51 -221
  260. package/dist/core/package-root.d.ts +3 -0
  261. package/dist/core/package-root.js +5 -0
  262. package/dist/core/physics-config.d.ts +1 -4
  263. package/dist/core/physics-config.js +3 -8
  264. package/dist/core/physics.d.ts +15 -61
  265. package/dist/core/physics.js +59 -122
  266. package/dist/core/project-identity.d.ts +17 -58
  267. package/dist/core/project-identity.js +17 -38
  268. package/dist/core/project-remote.js +13 -2
  269. package/dist/core/raw-append-only.d.ts +5 -0
  270. package/dist/core/raw-append-only.js +7 -0
  271. package/dist/core/salience.d.ts +1 -7
  272. package/dist/core/salience.js +1 -7
  273. package/dist/dashboard/dashboard-actions.js +2 -2
  274. package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
  275. package/dist/dashboard/dashboard-snapshot.js +11 -2
  276. package/dist/dashboard/dashboard-types.d.ts +2 -1
  277. package/dist/dashboard/dashboard.d.ts +1 -0
  278. package/dist/dashboard/dashboard.js +50 -4
  279. package/dist/db/busy.d.ts +1 -1
  280. package/dist/db/busy.js +17 -8
  281. package/dist/db/connect.d.ts +1 -0
  282. package/dist/db/connect.js +3 -3
  283. package/dist/db/migrate.js +3 -3
  284. package/dist/db/migrations/types.d.ts +2 -5
  285. package/dist/db/migrations/v14.js +2 -3
  286. package/dist/db/migrations/v15.js +2 -8
  287. package/dist/db/migrations/v16.js +2 -3
  288. package/dist/db/migrations/v17.js +2 -3
  289. package/dist/db/migrations/v19.js +2 -5
  290. package/dist/db/migrations/v20.js +2 -7
  291. package/dist/db/migrations/v22.js +4 -17
  292. package/dist/db/migrations/v23.js +3 -14
  293. package/dist/db/migrations/v24.js +2 -4
  294. package/dist/db/migrations/v25.js +3 -8
  295. package/dist/db/migrations/v26.js +2 -13
  296. package/dist/db/migrations/v27.js +3 -11
  297. package/dist/db/migrations/v28.js +2 -14
  298. package/dist/db/migrations/v29.js +4 -18
  299. package/dist/db/migrations/v30.js +4 -16
  300. package/dist/db/migrations/v31.js +2 -15
  301. package/dist/db/migrations/v32.js +4 -22
  302. package/dist/db/migrations/v33.js +2 -15
  303. package/dist/db/migrations/v34.js +2 -11
  304. package/dist/db/migrations/v35.js +2 -11
  305. package/dist/db/migrations/v36.js +2 -11
  306. package/dist/db/migrations/v37.js +8 -33
  307. package/dist/db/migrations/v38.js +5 -38
  308. package/dist/db/migrations/v39.js +9 -20
  309. package/dist/db/migrations/v40.js +2 -9
  310. package/dist/db/migrations/v41.js +2 -24
  311. package/dist/db/migrations/v43.js +1 -1
  312. package/dist/db/migrations/v44.js +2 -8
  313. package/dist/db/migrations/v45.js +2 -7
  314. package/dist/db/migrations/v47.js +2 -3
  315. package/dist/db/migrations/v51.js +1 -1
  316. package/dist/db/open.d.ts +2 -0
  317. package/dist/db/open.js +17 -1
  318. package/dist/db/physics-state.d.ts +6 -22
  319. package/dist/db/physics-state.js +25 -36
  320. package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
  321. package/dist/db/raw-archive-mirror-cleanup.js +2 -17
  322. package/dist/db/vector-store.d.ts +2 -0
  323. package/dist/db/vector-store.js +8 -1
  324. package/dist/doctor.js +74 -19
  325. package/dist/entry/session-text.js +2 -1
  326. package/dist/eval/eval-stats.d.ts +15 -53
  327. package/dist/eval/eval-stats.js +12 -42
  328. package/dist/eval/eval-suite.d.ts +2 -13
  329. package/dist/eval/eval-suite.js +74 -34
  330. package/dist/eval/eval.d.ts +6 -24
  331. package/dist/eval/eval.js +7 -34
  332. package/dist/eval/judgment.d.ts +0 -3
  333. package/dist/eval/judgment.js +19 -11
  334. package/dist/extensions/openclaw-plugin/index.js +1 -1
  335. package/dist/graph/extract.d.ts +5 -27
  336. package/dist/graph/extract.js +7 -33
  337. package/dist/graph/recall.d.ts +7 -20
  338. package/dist/graph/recall.js +14 -76
  339. package/dist/graph/stream.d.ts +7 -39
  340. package/dist/graph/stream.js +11 -34
  341. package/dist/graph/view.d.ts +9 -35
  342. package/dist/graph/view.js +11 -39
  343. package/dist/hooks/codex-wrapper.js +2 -2
  344. package/dist/hooks/copilot.js +2 -1
  345. package/dist/hooks/hook-blocks.d.ts +6 -2
  346. package/dist/hooks/hook-blocks.js +37 -124
  347. package/dist/hooks/json-hooks.d.ts +4 -36
  348. package/dist/hooks/json-hooks.js +18 -57
  349. package/dist/hooks/opencode.d.ts +0 -38
  350. package/dist/hooks/opencode.js +9 -76
  351. package/dist/hooks/shared.d.ts +8 -17
  352. package/dist/hooks/shared.js +29 -20
  353. package/dist/importers/core.d.ts +12 -37
  354. package/dist/importers/core.js +9 -27
  355. package/dist/importers/markdown-parse.d.ts +8 -22
  356. package/dist/importers/markdown-parse.js +8 -25
  357. package/dist/importers/markdown.js +3 -12
  358. package/dist/importers/sources.js +7 -35
  359. package/dist/importers/vault.d.ts +2 -8
  360. package/dist/importers/vault.js +25 -81
  361. package/dist/index.d.ts +6 -2
  362. package/dist/index.js +6 -2
  363. package/dist/learn/autolearn.d.ts +14 -41
  364. package/dist/learn/autolearn.js +14 -41
  365. package/dist/learn/extract.js +2 -4
  366. package/dist/learn/forward-claim-detector.d.ts +6 -30
  367. package/dist/learn/forward-claim-detector.js +14 -66
  368. package/dist/learn/invalidation.d.ts +6 -18
  369. package/dist/learn/invalidation.js +9 -26
  370. package/dist/mcp/admin-tools.js +3 -5
  371. package/dist/mcp/memory-tools.js +4 -9
  372. package/dist/mcp/protocol.d.ts +8 -26
  373. package/dist/mcp/protocol.js +3 -6
  374. package/dist/mcp/recall-tools.js +3 -3
  375. package/dist/mcp/request.d.ts +3 -11
  376. package/dist/mcp/request.js +10 -26
  377. package/dist/mcp/server.d.ts +3 -9
  378. package/dist/mcp/server.js +5 -16
  379. package/dist/mcp/session-state.d.ts +1 -1
  380. package/dist/mcp/session-state.js +5 -11
  381. package/dist/mcp/stdio.d.ts +2 -6
  382. package/dist/mcp/stdio.js +48 -12
  383. package/dist/mcp/tools.js +5 -3
  384. package/dist/objects/customer-notes.d.ts +7 -42
  385. package/dist/objects/customer-notes.js +7 -48
  386. package/dist/objects/decisions.d.ts +12 -50
  387. package/dist/objects/decisions.js +15 -53
  388. package/dist/objects/incidents.d.ts +7 -38
  389. package/dist/objects/incidents.js +7 -41
  390. package/dist/objects/policies.d.ts +11 -89
  391. package/dist/objects/policies.js +11 -98
  392. package/dist/objects/processes.d.ts +7 -52
  393. package/dist/objects/processes.js +7 -61
  394. package/dist/objects/project-briefs.d.ts +11 -55
  395. package/dist/objects/project-briefs.js +14 -75
  396. package/dist/objects/skills.d.ts +7 -42
  397. package/dist/objects/skills.js +8 -54
  398. package/dist/postinstall.js +6 -19
  399. package/dist/predictions/planning-fallacy.d.ts +11 -34
  400. package/dist/rerankers/clef.js +3 -31
  401. package/dist/rerankers/cross-encoder.js +4 -6
  402. package/dist/rerankers/jev.js +9 -6
  403. package/dist/rerankers/llm.d.ts +2 -11
  404. package/dist/rerankers/llm.js +14 -14
  405. package/dist/rerankers/outage-warning.d.ts +2 -1
  406. package/dist/rerankers/outage-warning.js +2 -1
  407. package/dist/rerankers/remote.d.ts +1 -0
  408. package/dist/rerankers/remote.js +2 -0
  409. package/dist/rerankers/types.d.ts +2 -14
  410. package/dist/search/boosts.d.ts +0 -2
  411. package/dist/search/boosts.js +2 -2
  412. package/dist/search/goal-boost.d.ts +23 -0
  413. package/dist/search/goal-boost.js +90 -0
  414. package/dist/search/hybrid.d.ts +2 -0
  415. package/dist/search/multihop.js +2 -3
  416. package/dist/search/path-context.d.ts +5 -18
  417. package/dist/search/path-context.js +5 -18
  418. package/dist/search/physics-search.js +11 -8
  419. package/dist/search/rrf.d.ts +7 -35
  420. package/dist/search/rrf.js +5 -30
  421. package/dist/search/vector.d.ts +7 -0
  422. package/dist/search/vector.js +35 -5
  423. package/dist/server/auth.d.ts +9 -28
  424. package/dist/server/auth.js +32 -25
  425. package/dist/server/boot.d.ts +2 -21
  426. package/dist/server/boot.js +63 -96
  427. package/dist/server/client-ip.d.ts +3 -19
  428. package/dist/server/client-ip.js +5 -28
  429. package/dist/server/defaults.d.ts +3 -0
  430. package/dist/server/defaults.js +4 -0
  431. package/dist/server/key-check-bounds.d.ts +2 -1
  432. package/dist/server/lifecycle.d.ts +5 -4
  433. package/dist/server/lifecycle.js +19 -4
  434. package/dist/server/mcp-http.js +10 -44
  435. package/dist/server/rate-limit.d.ts +5 -18
  436. package/dist/server/rate-limit.js +4 -13
  437. package/dist/server/request.d.ts +4 -8
  438. package/dist/server/request.js +9 -17
  439. package/dist/server/route-table.js +42 -49
  440. package/dist/server/routes/admin.js +22 -28
  441. package/dist/server/routes/customer-notes.js +7 -12
  442. package/dist/server/routes/decisions.js +10 -17
  443. package/dist/server/routes/incidents.js +12 -20
  444. package/dist/server/routes/memories.js +12 -32
  445. package/dist/server/routes/object-routes.d.ts +0 -5
  446. package/dist/server/routes/object-routes.js +7 -15
  447. package/dist/server/routes/policies.js +10 -18
  448. package/dist/server/routes/predictions.js +13 -25
  449. package/dist/server/routes/processes.js +16 -26
  450. package/dist/server/routes/project-briefs.js +9 -16
  451. package/dist/server/routes/recall.js +10 -35
  452. package/dist/server/routes/skills.js +8 -18
  453. package/dist/server/server-detect.d.ts +9 -53
  454. package/dist/server/server-detect.js +24 -90
  455. package/dist/server/sleep-offload.js +4 -1
  456. package/dist/server/types.d.ts +12 -10
  457. package/dist/server/validation.d.ts +3 -1
  458. package/dist/server/validation.js +10 -23
  459. package/dist/server.d.ts +2 -2
  460. package/dist/server.js +3 -2
  461. package/dist/sharing/global-store.d.ts +19 -0
  462. package/dist/sharing/global-store.js +75 -0
  463. package/dist/sharing/global-sync.d.ts +6 -0
  464. package/dist/sharing/global-sync.js +80 -0
  465. package/dist/sharing/project-merge.d.ts +4 -5
  466. package/dist/sharing/project-merge.js +9 -7
  467. package/dist/sharing/scope.d.ts +4 -11
  468. package/dist/sharing/scope.js +4 -11
  469. package/dist/sharing/search-both.d.ts +60 -0
  470. package/dist/sharing/search-both.js +138 -0
  471. package/dist/sharing/share.d.ts +38 -0
  472. package/dist/sharing/share.js +226 -0
  473. package/dist/store/ambient.js +4 -9
  474. package/dist/store/audit-event.d.ts +4 -12
  475. package/dist/store/audit-event.js +4 -12
  476. package/dist/store/audit.d.ts +2 -5
  477. package/dist/store/audit.js +4 -12
  478. package/dist/store/auth.d.ts +6 -6
  479. package/dist/store/auth.js +10 -9
  480. package/dist/store/candidates.d.ts +20 -3
  481. package/dist/store/candidates.js +77 -48
  482. package/dist/store/card-detail.d.ts +2 -1
  483. package/dist/store/card-detail.js +2 -1
  484. package/dist/store/cards.d.ts +14 -9
  485. package/dist/store/cards.js +72 -126
  486. package/dist/store/conflicts.d.ts +4 -21
  487. package/dist/store/conflicts.js +71 -150
  488. package/dist/store/connectors/github.d.ts +10 -10
  489. package/dist/store/connectors/github.js +10 -10
  490. package/dist/store/dashboard-reads.js +4 -8
  491. package/dist/store/delete-and-batch.d.ts +11 -31
  492. package/dist/store/delete-and-batch.js +48 -64
  493. package/dist/store/delivery-recorder.d.ts +8 -4
  494. package/dist/store/delivery-recorder.js +25 -15
  495. package/dist/store/diagnostics.js +6 -13
  496. package/dist/store/dormant.d.ts +7 -29
  497. package/dist/store/dormant.js +15 -56
  498. package/dist/store/embeddings/index.d.ts +11 -80
  499. package/dist/store/embeddings/index.js +71 -207
  500. package/dist/store/embeddings/local.js +15 -32
  501. package/dist/store/embeddings/provider.d.ts +16 -53
  502. package/dist/store/embeddings/provider.js +41 -69
  503. package/dist/store/entry-reads.d.ts +21 -57
  504. package/dist/store/entry-reads.js +65 -126
  505. package/dist/store/entry-row.d.ts +6 -35
  506. package/dist/store/entry-row.js +9 -37
  507. package/dist/store/entry-writes.d.ts +10 -16
  508. package/dist/store/entry-writes.js +17 -35
  509. package/dist/store/goals.d.ts +3 -40
  510. package/dist/store/goals.js +21 -160
  511. package/dist/store/graph-queue.d.ts +6 -22
  512. package/dist/store/graph-queue.js +14 -45
  513. package/dist/store/graph-reads.d.ts +11 -35
  514. package/dist/store/graph-reads.js +20 -58
  515. package/dist/store/graph-rows.d.ts +3 -6
  516. package/dist/store/graph-rows.js +6 -9
  517. package/dist/store/graph-view-rows.d.ts +2 -1
  518. package/dist/store/graph-view-rows.js +2 -1
  519. package/dist/store/graph-writes.d.ts +6 -31
  520. package/dist/store/graph-writes.js +13 -37
  521. package/dist/store/half-life.d.ts +2 -1
  522. package/dist/store/half-life.js +14 -16
  523. package/dist/store/handoffs.d.ts +5 -11
  524. package/dist/store/handoffs.js +16 -34
  525. package/dist/store/index-and-stats.d.ts +6 -19
  526. package/dist/store/index-and-stats.js +34 -82
  527. package/dist/store/markdown.d.ts +2 -6
  528. package/dist/store/markdown.js +21 -20
  529. package/dist/store/mirrors.d.ts +2 -6
  530. package/dist/store/mirrors.js +14 -23
  531. package/dist/store/open.js +6 -13
  532. package/dist/store/planning-fallacy-evidence.d.ts +2 -30
  533. package/dist/store/planning-fallacy-evidence.js +8 -37
  534. package/dist/store/port.d.ts +82 -79
  535. package/dist/store/predictions.d.ts +11 -51
  536. package/dist/store/predictions.js +38 -119
  537. package/dist/{cli → store}/quality-repair.js +15 -31
  538. package/dist/store/raw-archive.d.ts +4 -16
  539. package/dist/store/raw-archive.js +14 -29
  540. package/dist/store/recall-scope.d.ts +19 -79
  541. package/dist/store/recall-scope.js +21 -82
  542. package/dist/store/recall-trace.d.ts +10 -77
  543. package/dist/store/recall-trace.js +19 -95
  544. package/dist/store/rejected-values.js +7 -19
  545. package/dist/store/rejection.d.ts +12 -58
  546. package/dist/store/rejection.js +13 -65
  547. package/dist/store/report-reads.d.ts +6 -0
  548. package/dist/store/report-reads.js +29 -0
  549. package/dist/store/rows.d.ts +9 -19
  550. package/dist/store/rows.js +36 -34
  551. package/dist/store/rule-sql.d.ts +5 -0
  552. package/dist/store/rule-sql.js +37 -0
  553. package/dist/store/search-rows.d.ts +7 -38
  554. package/dist/store/search-rows.js +14 -50
  555. package/dist/store/sessions.d.ts +10 -47
  556. package/dist/store/sessions.js +17 -73
  557. package/dist/store/sqlite/connector-events-group.js +2 -2
  558. package/dist/store/sqlite/entry-writes-group.js +2 -2
  559. package/dist/store/sqlite/error-codec.js +4 -2
  560. package/dist/store/sqlite/executor.d.ts +2 -1
  561. package/dist/store/sqlite/executor.js +2 -1
  562. package/dist/store/sqlite/local.d.ts +3 -3
  563. package/dist/store/sqlite/local.js +1 -0
  564. package/dist/store/sqlite/object-rows.js +6 -3
  565. package/dist/store/sqlite/objects-group.js +4 -2
  566. package/dist/store/sqlite/quarantine-group.js +2 -2
  567. package/dist/store/sqlite/store.d.ts +1 -4
  568. package/dist/store/sqlite/store.js +2 -3
  569. package/dist/store/sqlite/vector-reads-group.js +2 -2
  570. package/dist/store/sqlite/worker-jobs.js +1 -1
  571. package/dist/store/sqlite/worker-ops.d.ts +13 -2
  572. package/dist/store/sqlite/worker-ops.js +13 -2
  573. package/dist/store/sqlite/worker-store.js +5 -2
  574. package/dist/store/summaries.d.ts +10 -62
  575. package/dist/store/summaries.js +34 -146
  576. package/dist/store/summary-dirty.js +1 -1
  577. package/dist/store/tenant-lookup.d.ts +6 -1
  578. package/dist/store/tenant-lookup.js +7 -0
  579. package/dist/store/tenant.d.ts +2 -16
  580. package/dist/store/tenant.js +4 -19
  581. package/dist/store/token-ledger.d.ts +13 -43
  582. package/dist/store/token-ledger.js +19 -50
  583. package/dist/store/usage-reports.js +5 -13
  584. package/dist/store/vector-index.d.ts +46 -0
  585. package/dist/store/vector-index.js +170 -0
  586. package/dist/store/working-memory.d.ts +6 -25
  587. package/dist/store/working-memory.js +18 -52
  588. package/dist/store/yaml.d.ts +1 -5
  589. package/dist/store/yaml.js +2 -6
  590. package/dist/support-bundle.js +7 -5
  591. package/dist/trust/reject-flow.js +1 -3
  592. package/dist/util/anthropic-messages.js +14 -2
  593. package/dist/util/atomic-write.d.ts +2 -1
  594. package/dist/util/atomic-write.js +35 -4
  595. package/dist/util/capped-json.d.ts +6 -0
  596. package/dist/util/capped-json.js +46 -0
  597. package/dist/util/crash-handlers.d.ts +8 -1
  598. package/dist/util/crash-handlers.js +52 -10
  599. package/dist/util/env.d.ts +13 -6
  600. package/dist/util/env.js +14 -7
  601. package/dist/util/home-path.d.ts +2 -1
  602. package/dist/util/home-path.js +4 -2
  603. package/dist/util/http-retry.d.ts +3 -1
  604. package/dist/util/http-retry.js +26 -5
  605. package/dist/util/log.d.ts +3 -2
  606. package/dist/util/log.js +25 -9
  607. package/dist/util/request-scope.d.ts +2 -1
  608. package/dist/util/request-scope.js +2 -1
  609. package/dist/util/secret-detect.d.ts +5 -30
  610. package/dist/util/secret-detect.js +13 -39
  611. package/dist/util/stored-json.d.ts +1 -1
  612. package/dist/util/stored-json.js +1 -1
  613. package/dist/util/token-text.d.ts +1 -4
  614. package/dist/util/token-text.js +1 -4
  615. package/dist/util/transcript-tail.d.ts +2 -0
  616. package/dist/util/transcript-tail.js +24 -23
  617. package/dist/util/version.d.ts +5 -20
  618. package/dist/util/version.js +5 -20
  619. package/extensions/openclaw-plugin/index.ts +1 -1
  620. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  621. package/extensions/openclaw-plugin/package.json +1 -1
  622. package/openclaw.plugin.json +1 -1
  623. package/package.json +1 -1
  624. package/dist/connectors/github/cli-impl.d.ts +0 -25
  625. package/dist/sharing/shared.d.ts +0 -187
  626. package/dist/sharing/shared.js +0 -563
  627. package/dist/store/vector-writes.d.ts +0 -13
  628. package/dist/store/vector-writes.js +0 -89
  629. /package/dist/{cli → store}/quality-repair.d.ts +0 -0
@@ -2,32 +2,29 @@
2
2
  import { envAnthropicApiKey } from '../util/env.js';
3
3
  import { evalNow } from '../core/ablation.js';
4
4
  import * as fs from 'fs';
5
- import { createMemory, createSuccessor, calculateStrength, calculateRewardFactor, confidenceFacets, confidenceLabel, Layer, } from '../core/memory.js';
5
+ import { calculateStrength, calculateRewardFactor, confidenceFacets, confidenceLabel, Layer, } from '../core/memory.js';
6
+ import * as api from '../api/index.js';
7
+ import { getMemory } from '../api/memories.js';
8
+ import { ConflictError, NotFoundError } from '../core/api-errors.js';
6
9
  import { isInitialized } from '../store/open.js';
7
- import { writeEntry } from '../store/entry-writes.js';
8
- import { readEntry, loadAllEntries } from '../store/entry-reads.js';
9
- import { loadNewestEntries, schemaFitInStore } from '../store/candidates.js';
10
- import { updateStats } from '../store/index-and-stats.js';
11
10
  import { listMemoryConflicts } from '../store/conflicts.js';
12
11
  import { RejectedValueError } from '../store/rejection.js';
13
12
  import { renderTraceContent, parseSteps } from '../consolidate/trace.js';
14
- import { embedMemory } from '../store/embeddings/index.js';
15
- import { loadConfig } from '../core/config.js';
16
13
  import { extractPathTags } from '../search/path-context.js';
17
14
  import { detectScope } from '../sharing/scope.js';
18
15
  import { assertClientScope } from '../store/recall-scope.js';
19
- import { getGlobalRoot, initGlobal } from '../sharing/shared.js';
16
+ import { getGlobalRoot, initGlobal } from '../sharing/global-store.js';
20
17
  import { vetSecrets } from '../util/secret-detect.js';
21
18
  import * as client from './client.js';
22
- import { resolveTenantId } from '../store/tenant.js';
23
- import { computeSalience } from '../core/salience.js';
19
+ import { cliApiContext } from './api-context.js';
24
20
  import { validateOwner, isStrictOwnerEnv } from './owner-validation.js';
25
21
  import { printError } from './output.js';
26
- import { emitCliAudit, requireInit, runViaServerIfAvailable } from './shared.js';
22
+ import { requireInit, runViaServerIfAvailable } from './shared.js';
27
23
  import { fmt } from './print.js';
28
- import { boolFlag, flagIsTrue, stringFlag } from './flag-values.js';
24
+ import { boolFlag, flagIsTrue, isOneOf, stringFlag, stringListFlag } from './flag-values.js';
29
25
  import { DAY_MS } from '../util/time.js';
30
26
  import { errorMessage } from '../util/log.js';
27
+ import { CliExit } from './exit.js';
31
28
  const PARENT_PREVIEW_CHARS = 70;
32
29
  const DETAIL_CONTENT_CHARS = 160;
33
30
  // Shared by the direct write and the routed request so both store the same tags.
@@ -60,19 +57,16 @@ function rememberConfidence(flags) {
60
57
  confidence = 'verified';
61
58
  return confidence;
62
59
  }
60
+ const USER_VISIBLE_KINDS = ['distilled', 'superseded'];
63
61
  function parseKindFlag(flags) {
64
62
  const kindFlagRaw = stringFlag(flags, 'kind');
65
63
  const kindFlag = kindFlagRaw === undefined ? undefined : kindFlagRaw.toLowerCase();
66
- // CLI surface intentionally restricted: 'raw' is reserved for ingestion connectors
67
- // that route deletions through archiveRawMemory. Existing
68
- // forget/consolidate/conflict-resolve paths abort on kind='raw' via the append-only
69
- // trigger, so exposing --kind raw here would create unforgettable memories.
70
- // 'archived' is an internal sentinel set only inside archiveRawMemory's transaction.
71
- const userVisibleKinds = ['distilled', 'superseded'];
72
- if (kindFlag !== undefined && !userVisibleKinds.includes(kindFlag)) {
73
- printError(`Invalid --kind: "${kindFlagRaw}". Must be one of: ${userVisibleKinds.join(', ')}`);
64
+ // 'raw' is reserved for ingestion connectors (deletions go through archiveRawMemory); the append-only trigger aborts forget/consolidate on raw rows,
65
+ // so exposing --kind raw would create unforgettable memories. 'archived' is an internal sentinel set only in that transaction.
66
+ if (kindFlag !== undefined && !isOneOf(USER_VISIBLE_KINDS, kindFlag)) {
67
+ printError(`Invalid --kind: "${kindFlagRaw}". Must be one of: ${USER_VISIBLE_KINDS.join(', ')}`);
74
68
  printError(`(kind='raw' is reserved for ingestion connectors; kind='archived' is internal.)`);
75
- process.exit(1);
69
+ throw new CliExit(1);
76
70
  }
77
71
  return kindFlag;
78
72
  }
@@ -82,7 +76,7 @@ function parseRememberEnvelope(flags) {
82
76
  const ownerCheck = validateOwner(ownerRaw, { strict: isStrictOwnerEnv() });
83
77
  if (!ownerCheck.ok) {
84
78
  printError(ownerCheck.message);
85
- process.exit(1);
79
+ throw new CliExit(1);
86
80
  }
87
81
  if (ownerCheck.message)
88
82
  printError(ownerCheck.message);
@@ -92,7 +86,7 @@ function parseRememberEnvelope(flags) {
92
86
  assertClientScope(scope);
93
87
  return { kind, owner, artifactRef, scope };
94
88
  }
95
- async function cmdRemember(hippoRoot, text, flags) {
89
+ async function cmdRemember(hippoRoot, tenantId, text, flags) {
96
90
  const useGlobal = boolFlag(flags, 'global');
97
91
  const targetRoot = useGlobal ? getGlobalRoot() : hippoRoot;
98
92
  if (useGlobal) {
@@ -102,60 +96,33 @@ async function cmdRemember(hippoRoot, text, flags) {
102
96
  requireInit(hippoRoot);
103
97
  }
104
98
  const { requested: requestedTags, all: allTags } = rememberTags(flags, process.cwd());
105
- const confidence = rememberConfidence(flags);
106
- // Schema fit needs the store, which the routed request has no access to, so it stays here.
107
- const schemaFit = schemaFitInStore(targetRoot, resolveTenantId({}), text, requestedTags);
108
99
  const envelope = parseRememberEnvelope(flags);
109
- // Stamp tenant_id from env (HIPPO_TENANT) so recall isolation can filter on this row; unauthenticated CLI gets 'default'.
110
- const tenantId = resolveTenantId({});
111
- const rememberConfig = loadConfig(targetRoot);
112
- const entry = createMemory(text, {
113
- layer: Layer.Episodic,
100
+ const ctx = cliApiContext(targetRoot, tenantId);
101
+ const outcome = api.rememberLocally(ctx, {
102
+ content: text,
103
+ kind: envelope.kind,
104
+ scope: envelope.scope ?? undefined,
105
+ owner: envelope.owner ?? undefined,
106
+ artifactRef: envelope.artifactRef ?? undefined,
114
107
  tags: allTags,
108
+ // Schema fit is scored on the tags the caller typed, without the path and scope tags added from this process.
109
+ fitTags: requestedTags,
110
+ layer: Layer.Episodic,
115
111
  pinned: boolFlag(flags, 'pin'),
116
112
  source: useGlobal ? 'cli-global' : 'cli',
117
- confidence,
118
- schema_fit: schemaFit,
119
- kind: envelope.kind,
120
- scope: envelope.scope,
121
- owner: envelope.owner,
122
- artifact_ref: envelope.artifactRef,
123
- tenantId,
124
- baseHalfLifeDays: rememberConfig.defaultHalfLifeDays,
113
+ confidence: rememberConfidence(flags),
114
+ force: boolFlag(flags, 'force'),
125
115
  });
126
- if (!passesSalienceGate(entry, text, targetRoot, rememberConfig, flags))
116
+ if (outcome.status === 'skipped') {
117
+ console.log(`Skipped (salience: ${outcome.reason}, score ${outcome.score.toFixed(2)})`);
127
118
  return;
128
- writeEntry(targetRoot, entry);
129
- updateStats(targetRoot, { remembered: 1 });
130
- printRemembered(entry, useGlobal);
131
- void embedMemory(targetRoot, entry);
132
- await extractRememberFacts(targetRoot, entry, flags);
133
- }
134
- /** False when the gate skips the write; a start_weak verdict weakens `entry` in place. */
135
- function passesSalienceGate(entry, text, targetRoot, rememberConfig, flags) {
136
- if (!rememberConfig.salience.enabled || boolFlag(flags, 'pin') || boolFlag(flags, 'force'))
137
- return true;
138
- // computeSalience compares against the last `recentWindow` rows only; below 1 its slice takes every row, so that case still loads them all.
139
- const window = Math.trunc(rememberConfig.salience.recentWindow);
140
- const recent = Number.isSafeInteger(window) && window >= 1
141
- ? loadNewestEntries(targetRoot, entry.tenantId, window)
142
- : loadAllEntries(targetRoot, entry.tenantId);
143
- const salienceResult = computeSalience(text, entry.tags, recent, {
144
- recentWindow: rememberConfig.salience.recentWindow,
145
- overlapThreshold: rememberConfig.salience.overlapThreshold,
146
- minContentLength: rememberConfig.salience.minContentLength,
147
- maxRepeatErrors: rememberConfig.salience.maxRepeatErrors,
148
- });
149
- if (salienceResult.decision === 'skip') {
150
- console.log(`Skipped (salience: ${salienceResult.reason}, score ${salienceResult.score.toFixed(2)})`);
151
- return false;
152
- }
153
- if (salienceResult.decision === 'start_weak') {
154
- entry.strength = salienceResult.score;
155
- entry.half_life_days = Math.max(1, entry.half_life_days * 0.5);
156
- console.log(`Weakened (salience: ${salienceResult.reason}, strength ${salienceResult.score.toFixed(2)})`);
157
119
  }
158
- return true;
120
+ const weak = outcome.startedWeak;
121
+ if (weak)
122
+ console.log(`Weakened (salience: ${weak.reason}, strength ${weak.strength.toFixed(2)})`);
123
+ printRemembered(outcome.entry, useGlobal);
124
+ const request = { requested: boolFlag(flags, 'extract'), apiKey: envAnthropicApiKey() };
125
+ printExtraction(await api.extractRememberedFacts(ctx, outcome.entry, request));
159
126
  }
160
127
  function printRemembered(entry, useGlobal) {
161
128
  const prefix = useGlobal ? '[global] ' : '';
@@ -168,80 +135,59 @@ function printRemembered(entry, useGlobal) {
168
135
  for (const w of vetSecrets(entry.content, entry.tags, false).warnings)
169
136
  printError(`Warning: ${w}`);
170
137
  }
171
- async function extractRememberFacts(targetRoot, entry, flags) {
172
- const config = loadConfig(targetRoot);
173
- const shouldExtract = flags['extract'] || config.extraction.enabled === true;
174
- const apiKey = envAnthropicApiKey() ?? '';
175
- if (shouldExtract && apiKey) {
176
- try {
177
- const { extractFacts, storeExtractedFacts } = await import('../learn/extract.js');
178
- const facts = await extractFacts(entry.content, {
179
- apiKey,
180
- model: config.extraction.model,
181
- onError: (msg) => printError(` (extraction failed: ${msg})`),
182
- });
183
- if (facts.length > 0) {
184
- storeExtractedFacts(targetRoot, entry, facts);
185
- printError(` extracted ${facts.length} fact(s)`);
186
- }
187
- }
188
- catch (err) {
189
- // Extraction is best-effort: report it, never block remember.
190
- printError(` (extraction failed: ${errorMessage(err)})`);
191
- }
192
- }
193
- else if (shouldExtract && !apiKey) {
138
+ function printExtraction(extraction) {
139
+ if (extraction.status === 'no_key')
194
140
  printError(' (extraction skipped: ANTHROPIC_API_KEY not set)');
195
- }
141
+ if (extraction.status !== 'ran')
142
+ return;
143
+ for (const failure of extraction.failures)
144
+ printError(` (extraction failed: ${failure})`);
145
+ if (extraction.facts > 0)
146
+ printError(` extracted ${extraction.facts} fact(s)`);
196
147
  }
197
148
  function supersedeTags(flags) {
198
- const rawTags = flags['tag'];
199
- return Array.isArray(rawTags)
200
- ? rawTags.map((t) => String(t))
201
- : typeof rawTags === 'string'
202
- ? rawTags.split(',').map((t) => t.trim()).filter(Boolean)
203
- : undefined;
149
+ return stringListFlag(flags, 'tag');
204
150
  }
205
- function writeSuccessor(hippoRoot, newEntry) {
206
- try {
207
- writeEntry(hippoRoot, newEntry);
208
- }
209
- catch (err) {
210
- if (err instanceof RejectedValueError) {
211
- printError(`Error: ${err.message}`);
212
- process.exit(1);
213
- }
214
- throw err;
151
+ /** The api's conflict text differs by which writer lost; the row itself names its successor either way. */
152
+ async function alreadySupersededLine(hippoRoot, oldId, tenantId, conflict) {
153
+ const by = (await getMemory(cliApiContext(hippoRoot, tenantId), oldId))?.superseded_by;
154
+ return by ? `Error: memory ${oldId} is already superseded by ${by}. Supersede that one instead.` : `Error: ${conflict.message}`;
155
+ }
156
+ function parseLayerFlag(flags) {
157
+ const raw = stringFlag(flags, 'layer');
158
+ if (raw === undefined)
159
+ return undefined;
160
+ const layer = Object.values(Layer).find((l) => l === raw);
161
+ if (layer === undefined) {
162
+ printError(`Invalid --layer: "${raw}". Must be one of: ${Object.values(Layer).join(', ')}`);
163
+ throw new CliExit(1);
215
164
  }
165
+ return layer;
216
166
  }
217
- function cmdSupersede(hippoRoot, oldId, newContent, flags) {
167
+ async function cmdSupersede(hippoRoot, tenantId, oldId, newContent, flags) {
218
168
  requireInit(hippoRoot);
219
- const old = readEntry(hippoRoot, oldId, resolveTenantId({}));
220
- if (!old) {
221
- printError(`Error: memory ${oldId} not found.`);
222
- process.exit(1);
169
+ const overrides = {
170
+ layer: parseLayerFlag(flags),
171
+ tags: supersedeTags(flags),
172
+ // Without --pin the successor keeps the old row's pin.
173
+ pinned: flagIsTrue(flags, 'pin') ? true : undefined,
174
+ };
175
+ let newId;
176
+ try {
177
+ ({ newId } = api.supersede(cliApiContext(hippoRoot, tenantId), oldId, newContent, overrides));
223
178
  }
224
- if (old.superseded_by) {
225
- printError(`Error: memory ${oldId} is already superseded by ${old.superseded_by}. Supersede that one instead.`);
226
- process.exit(1);
179
+ catch (err) {
180
+ if (err instanceof NotFoundError)
181
+ printError(`Error: memory ${oldId} not found.`);
182
+ else if (err instanceof RejectedValueError)
183
+ printError(`Error: ${err.message}`);
184
+ else if (err instanceof ConflictError)
185
+ printError(await alreadySupersededLine(hippoRoot, oldId, tenantId, err));
186
+ else
187
+ throw err;
188
+ throw new CliExit(1);
227
189
  }
228
- const layer = stringFlag(flags, 'layer');
229
- const tags = supersedeTags(flags);
230
- const pinned = flagIsTrue(flags, 'pin') || old.pinned;
231
- const newEntry = createSuccessor(old, newContent, {
232
- tenantId: old.tenantId,
233
- baseHalfLifeDays: loadConfig(hippoRoot).defaultHalfLifeDays,
234
- layer,
235
- tags,
236
- pinned,
237
- });
238
- // Write the SUCCESSOR first: a rejection-guard refusal then mutates nothing, and an old-row failure leaves an
239
- // orphan successor rather than a dangling pointer. Unlike api.supersede this path is two non-atomic writes.
240
- writeSuccessor(hippoRoot, newEntry);
241
- old.superseded_by = newEntry.id;
242
- writeEntry(hippoRoot, old);
243
- emitCliAudit(hippoRoot, 'supersede', oldId, { newId: newEntry.id });
244
- console.log(`Superseded ${oldId} → ${newEntry.id}`);
190
+ console.log(`Superseded ${oldId} → ${newId}`);
245
191
  }
246
192
  function parseStepsOrExit(stepsJson) {
247
193
  try {
@@ -249,7 +195,7 @@ function parseStepsOrExit(stepsJson) {
249
195
  }
250
196
  catch (err) {
251
197
  printError(errorMessage(err));
252
- process.exit(1);
198
+ throw new CliExit(1);
253
199
  }
254
200
  }
255
201
  function traceTags(flags) {
@@ -260,7 +206,7 @@ function traceTags(flags) {
260
206
  ? [String(rawTags)]
261
207
  : [];
262
208
  }
263
- function cmdTraceRecord(hippoRoot, flags) {
209
+ function cmdTraceRecord(hippoRoot, tenantId, flags) {
264
210
  requireInit(hippoRoot);
265
211
  const task = String(flags['task'] ?? '').trim();
266
212
  const stepsJson = String(flags['steps'] ?? '').trim();
@@ -268,11 +214,11 @@ function cmdTraceRecord(hippoRoot, flags) {
268
214
  const validOutcomes = ['success', 'failure', 'partial'];
269
215
  if (!task || !stepsJson || !outcome) {
270
216
  printError('Usage: hippo trace record --task <t> --steps <json> --outcome <success|failure|partial> [--session <id>] [--tag <t>]');
271
- process.exit(1);
217
+ throw new CliExit(1);
272
218
  }
273
- if (!validOutcomes.includes(outcome)) {
219
+ if (!isOneOf(validOutcomes, outcome)) {
274
220
  printError(`Invalid outcome: "${outcome}". Must be one of: ${validOutcomes.join(', ')}.`);
275
- process.exit(1);
221
+ throw new CliExit(1);
276
222
  }
277
223
  const steps = parseStepsOrExit(stepsJson);
278
224
  const sessionId = String(flags['session'] ?? '').trim() || null;
@@ -280,40 +226,39 @@ function cmdTraceRecord(hippoRoot, flags) {
280
226
  const content = renderTraceContent({
281
227
  task,
282
228
  steps,
283
- outcome: outcome,
229
+ outcome,
284
230
  });
285
- const entry = createMemory(content, {
286
- layer: Layer.Trace,
231
+ const { id } = api.remember(cliApiContext(hippoRoot, tenantId), {
232
+ content,
287
233
  tags,
288
- source: String(flags['source'] ?? 'cli'),
289
- trace_outcome: outcome,
290
- source_session_id: sessionId,
291
- tenantId: resolveTenantId({}),
292
- baseHalfLifeDays: loadConfig(hippoRoot).defaultHalfLifeDays,
234
+ local: {
235
+ layer: Layer.Trace,
236
+ source: String(flags['source'] ?? 'cli'),
237
+ traceOutcome: outcome,
238
+ sourceSessionId: sessionId,
239
+ },
293
240
  });
294
- writeEntry(hippoRoot, entry);
295
- console.log(`Recorded trace ${entry.id} (outcome=${outcome}, ${steps.length} steps)`);
241
+ console.log(`Recorded trace ${id} (outcome=${outcome}, ${steps.length} steps)`);
296
242
  }
297
- function cmdTrace(hippoRoot, id, flags) {
243
+ async function cmdTrace(hippoRoot, tenantId, id, flags) {
298
244
  requireInit(hippoRoot);
299
245
  const asJson = boolFlag(flags, 'json');
300
- const tenantId = resolveTenantId({});
301
246
  // Look in local store first, then global.
302
- let entry = readEntry(hippoRoot, id, tenantId);
247
+ let entry = await getMemory(cliApiContext(hippoRoot, tenantId), id);
303
248
  let sourceLabel = 'local';
304
249
  const globalRoot = getGlobalRoot();
305
250
  if (!entry && isInitialized(globalRoot)) {
306
- entry = readEntry(globalRoot, id, tenantId);
251
+ entry = await getMemory(cliApiContext(globalRoot, tenantId), id);
307
252
  sourceLabel = 'global';
308
253
  }
309
254
  if (!entry) {
310
255
  printError(`Memory not found: ${id}`);
311
- process.exit(1);
256
+ throw new CliExit(1);
312
257
  }
313
258
  const t = {
314
259
  entry, id, sourceLabel,
315
260
  ...traceStats(entry),
316
- ...traceLineage(hippoRoot, globalRoot, entry, id, tenantId),
261
+ ...(await traceLineage(hippoRoot, globalRoot, entry, id, tenantId)),
317
262
  };
318
263
  if (asJson) {
319
264
  printTraceJson(t);
@@ -337,13 +282,15 @@ function traceStats(entry) {
337
282
  const projectedAt = (days) => calculateStrength(entry, new Date(now.getTime() + days * DAY_MS));
338
283
  return { strength, halfLife, rewardFactor, effHalfLife, ageDays, sinceLast, facets, conf, projectedAt };
339
284
  }
340
- function traceLineage(hippoRoot, globalRoot, entry, id, tenantId) {
285
+ async function traceLineage(hippoRoot, globalRoot, entry, id, tenantId) {
341
286
  // Parents (consolidation lineage) — schema v9 field.
342
287
  const parents = Array.isArray(entry.parents) ? entry.parents : [];
343
- const parentPreviews = parents.map((pid) => {
344
- const p = readEntry(hippoRoot, pid, tenantId) ?? (isInitialized(globalRoot) ? readEntry(globalRoot, pid, tenantId) : null);
345
- return { id: pid, content: p ? p.content.replace(/\s+/g, ' ').slice(0, PARENT_PREVIEW_CHARS) : '(not found)' };
346
- });
288
+ const parentPreviews = [];
289
+ for (const pid of parents) {
290
+ const p = (await getMemory(cliApiContext(hippoRoot, tenantId), pid))
291
+ ?? (isInitialized(globalRoot) ? await getMemory(cliApiContext(globalRoot, tenantId), pid) : null);
292
+ parentPreviews.push({ id: pid, content: p ? p.content.replace(/\s+/g, ' ').slice(0, PARENT_PREVIEW_CHARS) : '(not found)' });
293
+ }
347
294
  // Open conflicts involving this memory.
348
295
  const allConflicts = [
349
296
  ...listMemoryConflicts(hippoRoot, 'open', tenantId),
@@ -418,7 +365,7 @@ function printTraceText(t) {
418
365
  }
419
366
  }
420
367
  }
421
- export async function handleRemember({ hippoRoot, args, flags }) {
368
+ export async function handleRemember({ hippoRoot, tenantId, args, flags }) {
422
369
  let text;
423
370
  if (args.length === 1 && args[0] === '-') {
424
371
  text = fs.readFileSync(0, 'utf-8').trim();
@@ -428,25 +375,20 @@ export async function handleRemember({ hippoRoot, args, flags }) {
428
375
  }
429
376
  if (!text || text.length < 3) {
430
377
  printError('Memory content too short (minimum 3 characters).');
431
- process.exit(1);
378
+ throw new CliExit(1);
432
379
  }
433
- // Thin-client routing. When a server is up, simple `remember` calls go
434
- // over HTTP so the daemon stays single-writer (footgun #2). Rich CLI
435
- // flags (--pin, --layer, --extract, --global) still need the direct
436
- // path; we only intercept the minimal envelope. The salience gate is
437
- // NOT in richFlag and the route does not apply it, so a routed remember
438
- // stores what a direct one would skip; do not read this list as covering salience.
380
+ // Thin-client routing: simple `remember` calls go over HTTP so the daemon stays the single writer; rich flags need the direct path.
381
+ // The salience gate is not in richFlag and the route does not apply it, so a routed remember stores what a direct one would skip.
439
382
  const richFlag = flags['pin'] || flags['global'] || flags['extract'] || flags['force'] ||
440
383
  flags['observed'] || flags['inferred'] || flags['verified'] ||
441
384
  flags['layer'] !== undefined;
442
385
  if (!richFlag && await rememberViaThinClient(hippoRoot, text, flags))
443
386
  return;
444
- await cmdRemember(hippoRoot, text, flags);
387
+ await cmdRemember(hippoRoot, tenantId, text, flags);
445
388
  }
446
389
  async function rememberViaThinClient(hippoRoot, text, flags) {
447
390
  const rememberKindRaw = stringFlag(flags, 'kind')?.toLowerCase();
448
- const rememberKindAllowed = ['distilled', 'superseded'];
449
- if (rememberKindRaw !== undefined && !rememberKindAllowed.includes(rememberKindRaw))
391
+ if (rememberKindRaw !== undefined && !isOneOf(USER_VISIBLE_KINDS, rememberKindRaw))
450
392
  return false;
451
393
  const tags = rememberTags(flags, process.cwd()).all;
452
394
  // Validate --owner on the thin-client path too, so validation is the same whether or not a server is up.
@@ -454,7 +396,7 @@ async function rememberViaThinClient(hippoRoot, text, flags) {
454
396
  const thinOwnerCheck = validateOwner(thinOwnerRaw, { strict: isStrictOwnerEnv() });
455
397
  if (!thinOwnerCheck.ok) {
456
398
  printError(thinOwnerCheck.message);
457
- process.exit(1);
399
+ throw new CliExit(1);
458
400
  }
459
401
  if (thinOwnerCheck.message)
460
402
  printError(thinOwnerCheck.message);
@@ -473,25 +415,25 @@ async function rememberViaThinClient(hippoRoot, text, flags) {
473
415
  printError(`Warning: ${w}`);
474
416
  });
475
417
  }
476
- export function handleSupersede({ hippoRoot, args, flags }) {
418
+ export async function handleSupersede({ hippoRoot, tenantId, args, flags }) {
477
419
  const oldId = args[0];
478
420
  const newContent = args.slice(1).join(' ').trim();
479
421
  if (!oldId || !newContent) {
480
422
  printError('Usage: hippo supersede <old-id> "<new content>" [--layer L] [--tag T] [--pin]');
481
- process.exit(1);
423
+ throw new CliExit(1);
482
424
  }
483
- cmdSupersede(hippoRoot, oldId, newContent, flags);
425
+ await cmdSupersede(hippoRoot, tenantId, oldId, newContent, flags);
484
426
  }
485
- export function handleTrace({ hippoRoot, args, flags }) {
427
+ export async function handleTrace({ hippoRoot, tenantId, args, flags }) {
486
428
  const sub = args[0] ? String(args[0]) : '';
487
429
  if (sub === 'record') {
488
- cmdTraceRecord(hippoRoot, flags);
430
+ cmdTraceRecord(hippoRoot, tenantId, flags);
489
431
  return;
490
432
  }
491
433
  if (!sub) {
492
434
  printError('Usage: hippo trace <memory-id> | hippo trace record --task <t> --steps <json> --outcome <o>');
493
- process.exit(1);
435
+ throw new CliExit(1);
494
436
  }
495
- cmdTrace(hippoRoot, sub, flags);
437
+ await cmdTrace(hippoRoot, tenantId, sub, flags);
496
438
  }
497
439
  //# sourceMappingURL=remember.js.map
@@ -1,30 +1,15 @@
1
- import * as fs from 'fs';
2
1
  export declare const DAILY_TASK_NAME = "hippo-daily-runner";
3
2
  interface WorkspaceRegistry {
4
3
  version: 1;
5
4
  workspaces: string[];
6
5
  }
7
- /**
8
- * Dependency-injection seam for tests. Production code always uses the real
9
- * `fs` functions imported above; tests override this via
10
- * __setSchedulerFsDeps to substitute fakes instead of `vi.mock`ing the
11
- * built-in `fs` module. Never called outside tests -- this module's public
12
- * behavior is unaffected when it's never invoked.
13
- */
14
- export interface SchedulerFsDeps {
15
- existsSync: typeof fs.existsSync;
16
- readFileSync: typeof fs.readFileSync;
17
- mkdirSync: typeof fs.mkdirSync;
18
- writeFile: (file: string, text: string) => void;
19
- renameSync: typeof fs.renameSync;
20
- }
21
- /** Test-only override. Not part of this module's public API surface. */
22
- export declare function __setSchedulerFsDeps(overrides: Partial<SchedulerFsDeps>): void;
23
6
  export declare function workspaceRegistryPath(globalRoot: string): string;
24
7
  export declare function loadWorkspaceRegistry(globalRoot: string): WorkspaceRegistry;
25
8
  export declare function saveWorkspaceRegistry(globalRoot: string, registry: WorkspaceRegistry): void;
26
9
  export declare function registerWorkspace(globalRoot: string, projectDir: string): WorkspaceRegistry;
27
10
  export declare function listRegisteredWorkspaces(globalRoot: string): string[];
11
+ /** True when a runner path holds a character that would break the quoted command or split the crontab line. */
12
+ export declare function hasUnsafeRunnerPathChars(runnerDir: string, platform: NodeJS.Platform): boolean;
28
13
  export declare function buildDailyRunnerCommand(projectDir: string, platform?: NodeJS.Platform): string;
29
14
  /** What the Windows task runs. A plain `cmd /c` task opens a visible console every morning. */
30
15
  export declare function buildWindowsTaskRun(cmd: string): string;
@@ -3,18 +3,6 @@ import * as path from 'path';
3
3
  import { errorMessage, log } from '../util/log.js';
4
4
  import { writeFileAtomic } from '../util/atomic-write.js';
5
5
  export const DAILY_TASK_NAME = 'hippo-daily-runner';
6
- let fsDeps = {
7
- existsSync: fs.existsSync,
8
- readFileSync: fs.readFileSync,
9
- mkdirSync: fs.mkdirSync,
10
- // One rename, so a crash mid-save cannot leave a truncated registry that reads as corrupt.
11
- writeFile: writeFileAtomic,
12
- renameSync: fs.renameSync,
13
- };
14
- /** Test-only override. Not part of this module's public API surface. */
15
- export function __setSchedulerFsDeps(overrides) {
16
- fsDeps = { ...fsDeps, ...overrides };
17
- }
18
6
  function defaultRegistry() {
19
7
  return {
20
8
  version: 1,
@@ -29,11 +17,11 @@ function normalizeWorkspace(projectDir) {
29
17
  }
30
18
  export function loadWorkspaceRegistry(globalRoot) {
31
19
  const registryPath = workspaceRegistryPath(globalRoot);
32
- if (!fsDeps.existsSync(registryPath))
20
+ if (!fs.existsSync(registryPath))
33
21
  return defaultRegistry();
34
22
  let text;
35
23
  try {
36
- text = fsDeps.readFileSync(registryPath, 'utf8');
24
+ text = fs.readFileSync(registryPath, 'utf8');
37
25
  }
38
26
  catch (err) {
39
27
  log.warn(`workspace registry ${registryPath} could not be read (${errorMessage(err)}); starting with no workspaces`);
@@ -59,7 +47,7 @@ function setAsideCorruptRegistry(registryPath, err) {
59
47
  const reason = errorMessage(err);
60
48
  const aside = `${registryPath}.corrupt-${new Date().toISOString().replace(/[:.]/g, '-')}`;
61
49
  try {
62
- fsDeps.renameSync(registryPath, aside);
50
+ fs.renameSync(registryPath, aside);
63
51
  log.warn(`workspace registry ${registryPath} is corrupt (${reason}); moved it to ${aside} and starting with no workspaces`);
64
52
  }
65
53
  catch (renameErr) {
@@ -67,8 +55,8 @@ function setAsideCorruptRegistry(registryPath, err) {
67
55
  }
68
56
  }
69
57
  export function saveWorkspaceRegistry(globalRoot, registry) {
70
- fsDeps.mkdirSync(globalRoot, { recursive: true, mode: 0o700 });
71
- fsDeps.writeFile(workspaceRegistryPath(globalRoot), JSON.stringify({
58
+ fs.mkdirSync(globalRoot, { recursive: true, mode: 0o700 });
59
+ writeFileAtomic(workspaceRegistryPath(globalRoot), JSON.stringify({
72
60
  version: 1,
73
61
  workspaces: [...new Set(registry.workspaces.map(normalizeWorkspace))].sort(),
74
62
  }, null, 2) + '\n');
@@ -82,6 +70,12 @@ export function registerWorkspace(globalRoot, projectDir) {
82
70
  export function listRegisteredWorkspaces(globalRoot) {
83
71
  return loadWorkspaceRegistry(globalRoot).workspaces;
84
72
  }
73
+ // Crontab reads % as a newline and both shells expand $ and backtick; a backslash is a path separator on Windows only.
74
+ const UNSAFE_RUNNER_PATH_CHARS = /["`$%\n\r]/;
75
+ /** True when a runner path holds a character that would break the quoted command or split the crontab line. */
76
+ export function hasUnsafeRunnerPathChars(runnerDir, platform) {
77
+ return UNSAFE_RUNNER_PATH_CHARS.test(runnerDir) || (platform !== 'win32' && runnerDir.includes('\\'));
78
+ }
85
79
  export function buildDailyRunnerCommand(projectDir, platform = process.platform) {
86
80
  if (platform === 'win32') {
87
81
  const resolved = path.win32.resolve(projectDir).replace(/\\/g, '/');
@@ -105,7 +99,7 @@ export function buildSchtasksCreateArgs(taskName, cmd) {
105
99
  export function runDailyMaintenance(workspaces, runCommand) {
106
100
  for (const workspace of workspaces) {
107
101
  const resolved = normalizeWorkspace(workspace);
108
- if (!fsDeps.existsSync(path.join(resolved, '.hippo')))
102
+ if (!fs.existsSync(path.join(resolved, '.hippo')))
109
103
  continue;
110
104
  runCommand(resolved, ['learn', '--git', '--days', '1']);
111
105
  runCommand(resolved, ['sleep']);