@ouro.bot/cli 0.1.0-alpha.48 → 0.1.0-alpha.481

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 (358) hide show
  1. package/README.md +132 -19
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  4. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  5. package/changelog.json +3069 -0
  6. package/dist/arc/attention-types.js +8 -0
  7. package/dist/arc/cares.js +140 -0
  8. package/dist/arc/episodes.js +117 -0
  9. package/dist/arc/intentions.js +133 -0
  10. package/dist/arc/json-store.js +117 -0
  11. package/dist/arc/obligations.js +237 -0
  12. package/dist/arc/packets.js +193 -0
  13. package/dist/arc/presence.js +185 -0
  14. package/dist/arc/task-lifecycle.js +65 -0
  15. package/dist/heart/active-work.js +857 -0
  16. package/dist/heart/agent-entry.js +58 -3
  17. package/dist/heart/attachments/image-normalize.js +194 -0
  18. package/dist/heart/attachments/materialize.js +97 -0
  19. package/dist/heart/attachments/originals.js +88 -0
  20. package/dist/heart/attachments/render.js +29 -0
  21. package/dist/heart/attachments/sources/adapter.js +2 -0
  22. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  23. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  24. package/dist/heart/attachments/sources/index.js +16 -0
  25. package/dist/heart/attachments/store.js +103 -0
  26. package/dist/heart/attachments/types.js +93 -0
  27. package/dist/heart/auth/auth-flow.js +426 -0
  28. package/dist/heart/background-operations.js +234 -0
  29. package/dist/heart/bridges/manager.js +358 -0
  30. package/dist/heart/bridges/state-machine.js +135 -0
  31. package/dist/heart/bridges/store.js +123 -0
  32. package/dist/heart/bundle-state.js +168 -0
  33. package/dist/heart/commitments.js +111 -0
  34. package/dist/heart/config-registry.js +304 -0
  35. package/dist/heart/config.js +110 -128
  36. package/dist/heart/core.js +745 -227
  37. package/dist/heart/cross-chat-delivery.js +131 -0
  38. package/dist/heart/daemon/agent-config-check.js +490 -0
  39. package/dist/heart/daemon/agent-discovery.js +79 -3
  40. package/dist/heart/daemon/agent-service.js +360 -0
  41. package/dist/heart/daemon/agentic-repair.js +216 -0
  42. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  43. package/dist/heart/daemon/cadence.js +70 -0
  44. package/dist/heart/daemon/cli-defaults.js +640 -0
  45. package/dist/heart/daemon/cli-exec.js +6933 -0
  46. package/dist/heart/daemon/cli-help.js +487 -0
  47. package/dist/heart/daemon/cli-parse.js +1527 -0
  48. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  49. package/dist/heart/daemon/cli-render.js +561 -0
  50. package/dist/heart/daemon/cli-types.js +8 -0
  51. package/dist/heart/daemon/connect-bay.js +323 -0
  52. package/dist/heart/daemon/daemon-cli.js +29 -1616
  53. package/dist/heart/daemon/daemon-entry.js +345 -3
  54. package/dist/heart/daemon/daemon-health.js +141 -0
  55. package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
  56. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  57. package/dist/heart/daemon/daemon.js +677 -58
  58. package/dist/heart/daemon/dns-workflow.js +394 -0
  59. package/dist/heart/daemon/doctor-types.js +8 -0
  60. package/dist/heart/daemon/doctor.js +486 -0
  61. package/dist/heart/daemon/health-monitor.js +92 -1
  62. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  63. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  64. package/dist/heart/daemon/http-health-probe.js +80 -0
  65. package/dist/heart/daemon/human-command-screens.js +234 -0
  66. package/dist/heart/daemon/human-readiness.js +114 -0
  67. package/dist/heart/daemon/inner-status.js +89 -0
  68. package/dist/heart/daemon/interactive-repair.js +394 -0
  69. package/dist/heart/daemon/launchd.js +25 -5
  70. package/dist/heart/daemon/log-tailer.js +82 -12
  71. package/dist/heart/daemon/logs-prune.js +110 -0
  72. package/dist/heart/daemon/message-router.js +2 -2
  73. package/dist/heart/daemon/os-cron-deps.js +134 -0
  74. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  75. package/dist/heart/daemon/ouro-entry.js +3 -1
  76. package/dist/heart/daemon/process-manager.js +214 -0
  77. package/dist/heart/daemon/provider-discovery.js +137 -0
  78. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  79. package/dist/heart/daemon/pulse.js +475 -0
  80. package/dist/heart/daemon/readiness-repair.js +365 -0
  81. package/dist/heart/daemon/run-hooks.js +2 -0
  82. package/dist/heart/daemon/runtime-logging.js +67 -16
  83. package/dist/heart/daemon/runtime-metadata.js +73 -0
  84. package/dist/heart/daemon/runtime-mode.js +67 -0
  85. package/dist/heart/daemon/safe-mode.js +161 -0
  86. package/dist/heart/daemon/sense-manager.js +178 -37
  87. package/dist/heart/daemon/session-id-resolver.js +131 -0
  88. package/dist/heart/daemon/skill-management-installer.js +94 -0
  89. package/dist/heart/daemon/socket-client.js +109 -4
  90. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  91. package/dist/heart/daemon/startup-tui.js +264 -0
  92. package/dist/heart/daemon/task-scheduler.js +3 -25
  93. package/dist/heart/daemon/terminal-ui.js +499 -0
  94. package/dist/heart/daemon/thoughts.js +149 -10
  95. package/dist/heart/daemon/up-progress.js +366 -0
  96. package/dist/heart/daemon/vault-items.js +56 -0
  97. package/dist/heart/delegation.js +62 -0
  98. package/dist/heart/habits/habit-migration.js +189 -0
  99. package/dist/heart/habits/habit-parser.js +140 -0
  100. package/dist/heart/habits/habit-runtime-state.js +100 -0
  101. package/dist/heart/habits/habit-scheduler.js +372 -0
  102. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  103. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  104. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  105. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  106. package/dist/heart/identity.js +201 -66
  107. package/dist/heart/kept-notes.js +357 -0
  108. package/dist/heart/kicks.js +1 -1
  109. package/dist/heart/machine-identity.js +161 -0
  110. package/dist/heart/mcp/mcp-server.js +653 -0
  111. package/dist/heart/migrate-config.js +100 -0
  112. package/dist/heart/model-capabilities.js +59 -0
  113. package/dist/heart/outlook/outlook-http-hooks.js +66 -0
  114. package/dist/heart/outlook/outlook-http-response.js +7 -0
  115. package/dist/heart/outlook/outlook-http-routes.js +244 -0
  116. package/dist/heart/outlook/outlook-http-static.js +99 -0
  117. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  118. package/dist/heart/outlook/outlook-http.js +99 -0
  119. package/dist/heart/outlook/outlook-read.js +31 -0
  120. package/dist/heart/outlook/outlook-types.js +27 -0
  121. package/dist/heart/outlook/outlook-view.js +195 -0
  122. package/dist/heart/outlook/readers/agent-machine.js +359 -0
  123. package/dist/heart/outlook/readers/continuity-readers.js +332 -0
  124. package/dist/heart/outlook/readers/mail.js +362 -0
  125. package/dist/heart/outlook/readers/runtime-readers.js +644 -0
  126. package/dist/heart/outlook/readers/sessions.js +232 -0
  127. package/dist/heart/outlook/readers/shared.js +111 -0
  128. package/dist/heart/platform.js +81 -0
  129. package/dist/heart/progress-story.js +42 -0
  130. package/dist/heart/provider-attempt.js +134 -0
  131. package/dist/heart/provider-binding-resolver.js +255 -0
  132. package/dist/heart/provider-credentials.js +424 -0
  133. package/dist/heart/provider-failover.js +266 -0
  134. package/dist/heart/provider-models.js +81 -0
  135. package/dist/heart/provider-ping.js +262 -0
  136. package/dist/heart/provider-state.js +216 -0
  137. package/dist/heart/provider-visibility.js +188 -0
  138. package/dist/heart/providers/anthropic-token.js +131 -0
  139. package/dist/heart/providers/anthropic.js +193 -55
  140. package/dist/heart/providers/azure.js +103 -12
  141. package/dist/heart/providers/error-classification.js +63 -0
  142. package/dist/heart/providers/github-copilot.js +145 -0
  143. package/dist/heart/providers/minimax-vlm.js +189 -0
  144. package/dist/heart/providers/minimax.js +29 -7
  145. package/dist/heart/providers/openai-codex.js +62 -38
  146. package/dist/heart/runtime-capability-check.js +170 -0
  147. package/dist/heart/runtime-credentials.js +260 -0
  148. package/dist/heart/sense-truth.js +11 -4
  149. package/dist/heart/session-activity.js +190 -0
  150. package/dist/heart/session-events.js +855 -0
  151. package/dist/heart/session-transcript.js +167 -0
  152. package/dist/heart/start-of-turn-packet.js +345 -0
  153. package/dist/heart/streaming.js +36 -27
  154. package/dist/heart/sync.js +332 -0
  155. package/dist/heart/target-resolution.js +127 -0
  156. package/dist/heart/tempo.js +93 -0
  157. package/dist/heart/temporal-view.js +41 -0
  158. package/dist/heart/tool-activity-callbacks.js +36 -0
  159. package/dist/heart/tool-description.js +135 -0
  160. package/dist/heart/tool-friction.js +55 -0
  161. package/dist/heart/tool-loop.js +200 -0
  162. package/dist/heart/turn-context.js +361 -0
  163. package/dist/heart/turn-coordinator.js +24 -1
  164. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  165. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  166. package/dist/heart/versioning/ouro-path-installer.js +425 -0
  167. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  168. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  169. package/dist/heart/{daemon → versioning}/update-checker.js +5 -1
  170. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  171. package/dist/mailroom/attention.js +167 -0
  172. package/dist/mailroom/autonomy.js +209 -0
  173. package/dist/mailroom/blob-store.js +573 -0
  174. package/dist/mailroom/core.js +658 -0
  175. package/dist/mailroom/entry.js +160 -0
  176. package/dist/mailroom/file-store.js +400 -0
  177. package/dist/mailroom/mbox-import.js +341 -0
  178. package/dist/mailroom/outbound.js +380 -0
  179. package/dist/mailroom/policy.js +263 -0
  180. package/dist/mailroom/reader.js +197 -0
  181. package/dist/mailroom/smtp-ingress.js +176 -0
  182. package/dist/mailroom/source-state.js +176 -0
  183. package/dist/mailroom/travel-extract.js +89 -0
  184. package/dist/mind/bundle-manifest.js +7 -1
  185. package/dist/mind/context.js +132 -93
  186. package/dist/mind/diary-integrity.js +60 -0
  187. package/dist/mind/{memory.js → diary.js} +74 -93
  188. package/dist/mind/embedding-provider.js +60 -0
  189. package/dist/mind/file-state.js +179 -0
  190. package/dist/mind/friends/channel.js +30 -0
  191. package/dist/mind/friends/group-context.js +144 -0
  192. package/dist/mind/friends/resolver.js +38 -1
  193. package/dist/mind/friends/store-file.js +39 -3
  194. package/dist/mind/friends/trust-explanation.js +74 -0
  195. package/dist/mind/friends/types.js +2 -2
  196. package/dist/mind/journal-index.js +161 -0
  197. package/dist/mind/note-search.js +268 -0
  198. package/dist/mind/obligation-steering.js +221 -0
  199. package/dist/mind/pending.js +66 -7
  200. package/dist/mind/prompt-refresh.js +3 -2
  201. package/dist/mind/prompt.js +978 -169
  202. package/dist/mind/provenance-trust.js +26 -0
  203. package/dist/mind/scrutiny.js +173 -0
  204. package/dist/nerves/cli-logging.js +7 -1
  205. package/dist/nerves/coverage/audit-rules.js +15 -6
  206. package/dist/nerves/coverage/audit.js +28 -2
  207. package/dist/nerves/coverage/cli.js +1 -1
  208. package/dist/nerves/coverage/contract.js +5 -5
  209. package/dist/nerves/coverage/file-completeness.js +84 -5
  210. package/dist/nerves/coverage/run-artifacts.js +1 -1
  211. package/dist/nerves/event-buffer.js +111 -0
  212. package/dist/nerves/index.js +224 -4
  213. package/dist/nerves/observation.js +20 -0
  214. package/dist/nerves/redact.js +79 -0
  215. package/dist/nerves/runtime.js +5 -1
  216. package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
  217. package/dist/outlook-ui/assets/index-CPfhbn13.js +61 -0
  218. package/dist/outlook-ui/index.html +15 -0
  219. package/dist/repertoire/ado-client.js +15 -56
  220. package/dist/repertoire/ado-semantic.js +11 -10
  221. package/dist/repertoire/api-client.js +97 -0
  222. package/dist/repertoire/bitwarden-store.js +774 -0
  223. package/dist/repertoire/bundle-templates.js +72 -0
  224. package/dist/repertoire/bw-installer.js +180 -0
  225. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  226. package/dist/repertoire/coding/context-pack.js +330 -0
  227. package/dist/repertoire/coding/feedback.js +197 -30
  228. package/dist/repertoire/coding/manager.js +158 -9
  229. package/dist/repertoire/coding/spawner.js +55 -9
  230. package/dist/repertoire/coding/tools.js +170 -7
  231. package/dist/repertoire/commerce-errors.js +109 -0
  232. package/dist/repertoire/commerce-self-test.js +156 -0
  233. package/dist/repertoire/credential-access.js +111 -0
  234. package/dist/repertoire/duffel-client.js +185 -0
  235. package/dist/repertoire/github-client.js +14 -55
  236. package/dist/repertoire/graph-client.js +11 -52
  237. package/dist/repertoire/guardrails.js +396 -0
  238. package/dist/repertoire/mcp-client.js +255 -0
  239. package/dist/repertoire/mcp-manager.js +305 -0
  240. package/dist/repertoire/mcp-tools.js +63 -0
  241. package/dist/repertoire/shell-sessions.js +133 -0
  242. package/dist/repertoire/skills.js +15 -24
  243. package/dist/repertoire/stripe-client.js +131 -0
  244. package/dist/repertoire/tasks/board.js +43 -5
  245. package/dist/repertoire/tasks/fix.js +182 -0
  246. package/dist/repertoire/tasks/index.js +37 -4
  247. package/dist/repertoire/tasks/lifecycle.js +2 -2
  248. package/dist/repertoire/tasks/parser.js +3 -2
  249. package/dist/repertoire/tasks/scanner.js +194 -37
  250. package/dist/repertoire/tasks/transitions.js +16 -78
  251. package/dist/repertoire/tool-results.js +29 -0
  252. package/dist/repertoire/tools-attachments.js +317 -0
  253. package/dist/repertoire/tools-base.js +44 -740
  254. package/dist/repertoire/tools-bluebubbles.js +1 -0
  255. package/dist/repertoire/tools-bridge.js +141 -0
  256. package/dist/repertoire/tools-bundle.js +984 -0
  257. package/dist/repertoire/tools-config.js +185 -0
  258. package/dist/repertoire/tools-continuity.js +248 -0
  259. package/dist/repertoire/tools-credential.js +381 -0
  260. package/dist/repertoire/tools-files.js +342 -0
  261. package/dist/repertoire/tools-flight.js +224 -0
  262. package/dist/repertoire/tools-flow.js +105 -0
  263. package/dist/repertoire/tools-github.js +1 -7
  264. package/dist/repertoire/tools-mail.js +896 -0
  265. package/dist/repertoire/tools-notes.js +376 -0
  266. package/dist/repertoire/tools-session.js +746 -0
  267. package/dist/repertoire/tools-shell.js +120 -0
  268. package/dist/repertoire/tools-stripe.js +180 -0
  269. package/dist/repertoire/tools-surface.js +243 -0
  270. package/dist/repertoire/tools-teams.js +9 -39
  271. package/dist/repertoire/tools-travel.js +125 -0
  272. package/dist/repertoire/tools-user-profile.js +144 -0
  273. package/dist/repertoire/tools-vault.js +40 -0
  274. package/dist/repertoire/tools.js +144 -113
  275. package/dist/repertoire/travel-api-client.js +360 -0
  276. package/dist/repertoire/user-profile.js +131 -0
  277. package/dist/repertoire/vault-setup.js +246 -0
  278. package/dist/repertoire/vault-unlock.js +561 -0
  279. package/dist/scripts/claude-code-hook.js +41 -0
  280. package/dist/scripts/claude-code-stop-hook.js +47 -0
  281. package/dist/senses/attention-queue.js +116 -0
  282. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  283. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  284. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  285. package/dist/senses/bluebubbles/entry.js +73 -0
  286. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +7 -3
  287. package/dist/senses/{bluebubbles.js → bluebubbles/index.js} +705 -116
  288. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  289. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  290. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  291. package/dist/senses/bluebubbles/replay.js +129 -0
  292. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -2
  293. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  294. package/dist/senses/cli/bracketed-paste.js +82 -0
  295. package/dist/senses/cli/image-paste.js +287 -0
  296. package/dist/senses/cli/image-ref-navigation.js +75 -0
  297. package/dist/senses/cli/ink-app.js +156 -0
  298. package/dist/senses/cli/inline-diff.js +64 -0
  299. package/dist/senses/cli/input-keys.js +174 -0
  300. package/dist/senses/cli/kill-ring.js +86 -0
  301. package/dist/senses/cli/message-list.js +51 -0
  302. package/dist/senses/cli/ouro-tui.js +605 -0
  303. package/dist/senses/cli/spinner-imperative.js +135 -0
  304. package/dist/senses/cli/spinner.js +101 -0
  305. package/dist/senses/cli/status-line.js +60 -0
  306. package/dist/senses/cli/streaming-markdown.js +526 -0
  307. package/dist/senses/cli/tool-display.js +83 -0
  308. package/dist/senses/cli/tool-render.js +85 -0
  309. package/dist/senses/cli/tui-store.js +240 -0
  310. package/dist/senses/cli/virtual-list.js +35 -0
  311. package/dist/senses/cli-entry.js +60 -8
  312. package/dist/senses/cli-layout.js +187 -0
  313. package/dist/senses/cli.js +516 -211
  314. package/dist/senses/commands.js +66 -3
  315. package/dist/senses/habit-turn-message.js +108 -0
  316. package/dist/senses/inner-dialog-worker.js +97 -17
  317. package/dist/senses/inner-dialog.js +404 -14
  318. package/dist/senses/mail-entry.js +66 -0
  319. package/dist/senses/mail.js +232 -0
  320. package/dist/senses/pipeline.js +533 -72
  321. package/dist/senses/proactive-content-guard.js +51 -0
  322. package/dist/senses/shared-turn.js +205 -0
  323. package/dist/senses/surface-tool.js +68 -0
  324. package/dist/senses/teams-entry.js +60 -8
  325. package/dist/senses/teams.js +413 -163
  326. package/dist/senses/trust-gate.js +5 -5
  327. package/package.json +37 -7
  328. package/skills/agent-commerce.md +106 -0
  329. package/skills/browser-navigation.md +117 -0
  330. package/skills/commerce-setup-guide.md +116 -0
  331. package/skills/commerce-setup.md +84 -0
  332. package/skills/configure-dev-tools.md +101 -0
  333. package/skills/travel-planning.md +138 -0
  334. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  335. package/dist/heart/daemon/subagent-installer.js +0 -166
  336. package/dist/mind/associative-recall.js +0 -209
  337. package/dist/senses/bluebubbles-entry.js +0 -13
  338. package/dist/senses/debug-activity.js +0 -127
  339. package/subagents/README.md +0 -86
  340. package/subagents/work-doer.md +0 -237
  341. package/subagents/work-merger.md +0 -618
  342. package/subagents/work-planner.md +0 -390
  343. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  344. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  345. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  346. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  347. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  348. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  349. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  350. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  351. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  352. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  353. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  354. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  355. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  356. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  357. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  358. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -33,18 +33,26 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateSessionMessages = exports.repairSessionMessages = exports.migrateToolNames = void 0;
36
37
  exports.trimMessages = trimMessages;
37
- exports.validateSessionMessages = validateSessionMessages;
38
- exports.repairSessionMessages = repairSessionMessages;
39
38
  exports.saveSession = saveSession;
39
+ exports.appendSyntheticAssistantMessage = appendSyntheticAssistantMessage;
40
40
  exports.loadSession = loadSession;
41
41
  exports.postTurn = postTurn;
42
+ exports.postTurnTrim = postTurnTrim;
43
+ exports.postTurnPersist = postTurnPersist;
44
+ exports.deferPostTurnPersist = deferPostTurnPersist;
42
45
  exports.deleteSession = deleteSession;
43
46
  const config_1 = require("../heart/config");
47
+ const session_events_1 = require("../heart/session-events");
44
48
  const runtime_1 = require("../nerves/runtime");
45
49
  const fs = __importStar(require("fs"));
46
50
  const path = __importStar(require("path"));
47
51
  const token_estimate_1 = require("./token-estimate");
52
+ var session_events_2 = require("../heart/session-events");
53
+ Object.defineProperty(exports, "migrateToolNames", { enumerable: true, get: function () { return session_events_2.migrateToolNames; } });
54
+ Object.defineProperty(exports, "repairSessionMessages", { enumerable: true, get: function () { return session_events_2.repairSessionMessages; } });
55
+ Object.defineProperty(exports, "validateSessionMessages", { enumerable: true, get: function () { return session_events_2.validateSessionMessages; } });
48
56
  function buildTrimmableBlocks(messages) {
49
57
  const blocks = [];
50
58
  let i = 0;
@@ -173,114 +181,94 @@ function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
173
181
  * user → assistant (with optional tool calls/results) → user → assistant...
174
182
  * Never assistant → assistant without a user in between.
175
183
  */
176
- function validateSessionMessages(messages) {
177
- const violations = [];
178
- let prevNonToolRole = null;
179
- let prevAssistantHadToolCalls = false;
180
- let sawToolResultSincePrevAssistant = false;
181
- for (let i = 0; i < messages.length; i++) {
182
- const msg = messages[i];
183
- if (msg.role === "system")
184
- continue;
185
- if (msg.role === "tool") {
186
- sawToolResultSincePrevAssistant = true;
187
- continue;
188
- }
189
- if (msg.role === "assistant" && prevNonToolRole === "assistant") {
190
- // assistant → tool(s) → assistant is valid (tool call flow)
191
- if (!(prevAssistantHadToolCalls && sawToolResultSincePrevAssistant)) {
192
- violations.push(`back-to-back assistant at index ${i}`);
193
- }
194
- }
195
- prevAssistantHadToolCalls = msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0;
196
- sawToolResultSincePrevAssistant = false;
197
- prevNonToolRole = msg.role;
198
- }
199
- return violations;
184
+ function denormalizeContinuityState(state) {
185
+ if (!state.mustResolveBeforeHandoff && typeof state.lastFriendActivityAt !== "string")
186
+ return undefined;
187
+ return {
188
+ ...(state.mustResolveBeforeHandoff ? { mustResolveBeforeHandoff: true } : {}),
189
+ ...(typeof state.lastFriendActivityAt === "string" ? { lastFriendActivityAt: state.lastFriendActivityAt } : {}),
190
+ };
200
191
  }
201
- /**
202
- * Repairs session invariant violations by merging consecutive assistant messages.
203
- */
204
- function repairSessionMessages(messages) {
205
- const violations = validateSessionMessages(messages);
206
- if (violations.length === 0)
207
- return messages;
208
- const result = [];
209
- for (const msg of messages) {
210
- if (msg.role === "assistant" && result.length > 0) {
211
- const prev = result[result.length - 1];
212
- if (prev.role === "assistant" && !("tool_calls" in prev)) {
213
- const prevContent = typeof prev.content === "string" ? prev.content : "";
214
- const curContent = typeof msg.content === "string" ? msg.content : "";
215
- prev.content = `${prevContent}\n\n${curContent}`;
216
- continue;
217
- }
218
- }
219
- result.push(msg);
220
- }
221
- (0, runtime_1.emitNervesEvent)({
222
- level: "warn",
223
- event: "mind.session_invariant_repair",
224
- component: "mind",
225
- message: "repaired session invariant violations",
226
- meta: { violations },
227
- });
228
- return result;
192
+ function writeSessionEnvelope(filePath, envelope) {
193
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
194
+ fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
229
195
  }
230
196
  function saveSession(filePath, messages, lastUsage, state) {
231
- const violations = validateSessionMessages(messages);
232
- if (violations.length > 0) {
197
+ const existing = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
198
+ const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
199
+ const currentIngressTimes = messages.map(session_events_1.getIngressTime);
200
+ const sanitized = (0, session_events_1.sanitizeProviderMessages)(messages);
201
+ const { envelope } = (0, session_events_1.buildCanonicalSessionEnvelope)({
202
+ existing,
203
+ previousMessages,
204
+ currentMessages: sanitized,
205
+ trimmedMessages: sanitized,
206
+ currentIngressTimes,
207
+ recordedAt: new Date().toISOString(),
208
+ lastUsage: lastUsage ?? null,
209
+ state,
210
+ projectionBasis: {
211
+ maxTokens: null,
212
+ contextMargin: null,
213
+ inputTokens: lastUsage?.input_tokens ?? null,
214
+ },
215
+ });
216
+ writeSessionEnvelope(filePath, envelope);
217
+ }
218
+ function appendSyntheticAssistantMessage(filePath, content) {
219
+ try {
220
+ if (!fs.existsSync(filePath))
221
+ return false;
222
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
223
+ if (!envelope)
224
+ return false;
225
+ const updated = (0, session_events_1.appendSyntheticAssistantEvent)(envelope, content, new Date().toISOString());
226
+ writeSessionEnvelope(filePath, updated);
233
227
  (0, runtime_1.emitNervesEvent)({
234
- level: "warn",
235
- event: "mind.session_invariant_violation",
236
228
  component: "mind",
237
- message: "session invariant violated on save",
238
- meta: { path: filePath, violations },
229
+ event: "mind.session_synthetic_message_appended",
230
+ message: "appended synthetic assistant message to session",
231
+ meta: { path: filePath, contentLength: content.length },
239
232
  });
240
- messages = repairSessionMessages(messages);
233
+ return true;
241
234
  }
242
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
243
- const envelope = { version: 1, messages };
244
- if (lastUsage)
245
- envelope.lastUsage = lastUsage;
246
- if (state?.mustResolveBeforeHandoff === true) {
247
- envelope.state = { mustResolveBeforeHandoff: true };
235
+ catch {
236
+ return false;
248
237
  }
249
- fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
250
238
  }
251
239
  function loadSession(filePath) {
252
240
  try {
253
- const raw = fs.readFileSync(filePath, "utf-8");
254
- const data = JSON.parse(raw);
255
- if (data.version !== 1)
241
+ const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
242
+ if (!envelope)
256
243
  return null;
257
- let messages = data.messages;
258
- const violations = validateSessionMessages(messages);
259
- if (violations.length > 0) {
260
- (0, runtime_1.emitNervesEvent)({
261
- level: "warn",
262
- event: "mind.session_invariant_violation",
263
- component: "mind",
264
- message: "session invariant violated on load",
265
- meta: { path: filePath, violations },
266
- });
267
- messages = repairSessionMessages(messages);
268
- }
269
- const state = data?.state && typeof data.state === "object" && data.state !== null
270
- && typeof data.state.mustResolveBeforeHandoff === "boolean"
271
- && data.state.mustResolveBeforeHandoff === true
272
- ? { mustResolveBeforeHandoff: true }
273
- : undefined;
274
- return { messages, lastUsage: data.lastUsage, state };
244
+ return {
245
+ messages: (0, session_events_1.annotateMessageTimestamps)(envelope, (0, session_events_1.projectProviderMessages)(envelope)),
246
+ events: envelope.events,
247
+ lastUsage: envelope.lastUsage ?? undefined,
248
+ state: denormalizeContinuityState(envelope.state),
249
+ };
275
250
  }
276
251
  catch {
277
252
  return null;
278
253
  }
279
254
  }
255
+ /**
256
+ * Synchronous post-turn: sanitize, trim (mutates messages in place), and persist to disk.
257
+ * For non-blocking persist, use postTurnTrim() + deferPostTurnPersist() instead.
258
+ */
280
259
  function postTurn(messages, sessPath, usage, hooks, state) {
260
+ const prepared = postTurnTrim(messages, usage, hooks);
261
+ postTurnPersist(sessPath, prepared, usage, state);
262
+ }
263
+ /**
264
+ * Synchronous phase: run hooks, sanitize, trim, and mutate the messages array in place.
265
+ * Returns the data needed by postTurnPersist / deferPostTurnPersist.
266
+ */
267
+ function postTurnTrim(messages, usage, hooks) {
268
+ const preTrimMessages = [...messages];
281
269
  if (hooks?.beforeTrim) {
282
270
  try {
283
- hooks.beforeTrim([...messages]);
271
+ hooks.beforeTrim(preTrimMessages);
284
272
  }
285
273
  catch (error) {
286
274
  (0, runtime_1.emitNervesEvent)({
@@ -295,9 +283,60 @@ function postTurn(messages, sessPath, usage, hooks, state) {
295
283
  }
296
284
  }
297
285
  const { maxTokens, contextMargin } = (0, config_1.getContextConfig)();
298
- const trimmed = trimMessages(messages, maxTokens, contextMargin, usage?.input_tokens);
299
- messages.splice(0, messages.length, ...trimmed);
300
- saveSession(sessPath, messages, usage, state);
286
+ const currentIngressTimes = messages.map(session_events_1.getIngressTime);
287
+ const currentMessages = (0, session_events_1.sanitizeProviderMessages)(messages);
288
+ const trimmedMessages = trimMessages(currentMessages, maxTokens, contextMargin, usage?.input_tokens);
289
+ messages.splice(0, messages.length, ...trimmedMessages);
290
+ return { currentMessages, trimmedMessages, currentIngressTimes, maxTokens, contextMargin };
291
+ }
292
+ /**
293
+ * Synchronous persist: load existing envelope, build canonical envelope, write to disk.
294
+ */
295
+ function postTurnPersist(sessPath, prepared, usage, state) {
296
+ const existing = (0, session_events_1.loadSessionEnvelopeFile)(sessPath);
297
+ const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
298
+ const { envelope, evictedEvents } = (0, session_events_1.buildCanonicalSessionEnvelope)({
299
+ existing,
300
+ previousMessages,
301
+ currentMessages: prepared.currentMessages,
302
+ trimmedMessages: prepared.trimmedMessages,
303
+ currentIngressTimes: prepared.currentIngressTimes,
304
+ recordedAt: new Date().toISOString(),
305
+ lastUsage: usage ?? null,
306
+ state,
307
+ projectionBasis: {
308
+ maxTokens: prepared.maxTokens,
309
+ contextMargin: prepared.contextMargin,
310
+ inputTokens: usage?.input_tokens ?? null,
311
+ },
312
+ });
313
+ (0, session_events_1.appendEvictedToArchive)(sessPath, evictedEvents);
314
+ writeSessionEnvelope(sessPath, envelope);
315
+ return envelope.events;
316
+ }
317
+ /**
318
+ * Deferred persist: same as postTurnPersist but runs on the next event loop tick.
319
+ * Returns a promise that resolves when the persist completes.
320
+ */
321
+ function deferPostTurnPersist(sessPath, prepared, usage, state) {
322
+ return new Promise((resolve) => {
323
+ setImmediate(() => {
324
+ try {
325
+ const events = postTurnPersist(sessPath, prepared, usage, state);
326
+ resolve(events);
327
+ }
328
+ catch (err) {
329
+ (0, runtime_1.emitNervesEvent)({
330
+ level: "warn",
331
+ component: "mind",
332
+ event: "mind.deferred_persist_error",
333
+ message: "deferred session persist failed",
334
+ meta: { error: err instanceof Error ? err.message : String(err) },
335
+ });
336
+ resolve([]);
337
+ }
338
+ });
339
+ });
301
340
  }
302
341
  function deleteSession(filePath) {
303
342
  try {
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectSuspiciousContent = detectSuspiciousContent;
4
+ const PATTERN_CATEGORIES = [
5
+ {
6
+ name: "instruction_framing",
7
+ patterns: [
8
+ /\byou are (?:a|an) (?:ai|assistant|language model|helpful assistant)\b/i,
9
+ /\byour (?:new )?instructions are\b/i,
10
+ /\bsystem\s*:/i,
11
+ /\bignore (?:all |my )?previous instructions\b/i,
12
+ /\bdo not reveal\b/i,
13
+ ],
14
+ },
15
+ {
16
+ name: "override_language",
17
+ patterns: [
18
+ /\bdisregard\b/i,
19
+ /\bforget everything\b/i,
20
+ /\bnew instructions:/i,
21
+ /\boverride (?:all |any |previous )?instructions\b/i,
22
+ ],
23
+ },
24
+ {
25
+ name: "role_injection",
26
+ patterns: [
27
+ /\bas (?:a|an) (?:ai|language model)\b/i,
28
+ /\byou must always\b/i,
29
+ /\byou are now\b/i,
30
+ ],
31
+ },
32
+ {
33
+ name: "boundary_markers",
34
+ patterns: [
35
+ /```system/i,
36
+ /<<SYS>>/i,
37
+ /\[INST\]/i,
38
+ /<\/?system>/i,
39
+ /\[system\]/i,
40
+ ],
41
+ },
42
+ ];
43
+ function detectSuspiciousContent(text) {
44
+ if (!text) {
45
+ return { suspicious: false, patterns: [] };
46
+ }
47
+ const matched = new Set();
48
+ for (const category of PATTERN_CATEGORIES) {
49
+ for (const pattern of category.patterns) {
50
+ if (pattern.test(text)) {
51
+ matched.add(category.name);
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ return {
57
+ suspicious: matched.size > 0,
58
+ patterns: [...matched],
59
+ };
60
+ }
@@ -33,52 +33,25 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.__memoryTestUtils = void 0;
37
- exports.ensureMemoryStorePaths = ensureMemoryStorePaths;
38
- exports.appendFactsWithDedup = appendFactsWithDedup;
39
- exports.readMemoryFacts = readMemoryFacts;
40
- exports.saveMemoryFact = saveMemoryFact;
36
+ exports.ensureDiaryStorePaths = ensureDiaryStorePaths;
37
+ exports.appendEntriesWithDedup = appendEntriesWithDedup;
38
+ exports.resolveDiaryRoot = resolveDiaryRoot;
39
+ exports.readDiaryEntries = readDiaryEntries;
40
+ exports.saveDiaryEntry = saveDiaryEntry;
41
41
  exports.backfillEmbeddings = backfillEmbeddings;
42
- exports.searchMemoryFacts = searchMemoryFacts;
42
+ exports.searchDiaryEntries = searchDiaryEntries;
43
43
  const fs = __importStar(require("fs"));
44
44
  const path = __importStar(require("path"));
45
45
  const crypto_1 = require("crypto");
46
- const config_1 = require("../heart/config");
47
46
  const identity_1 = require("../heart/identity");
48
47
  const runtime_1 = require("../nerves/runtime");
48
+ const note_search_1 = require("./note-search");
49
+ const diary_integrity_1 = require("./diary-integrity");
50
+ const embedding_provider_1 = require("./embedding-provider");
49
51
  const DEDUP_THRESHOLD = 0.6;
52
+ const SEMANTIC_DEDUP_THRESHOLD = 0.95;
50
53
  const ENTITY_TOKEN = /[a-z0-9]+/g;
51
- const DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small";
52
- class OpenAIEmbeddingProvider {
53
- apiKey;
54
- model;
55
- constructor(apiKey, model = DEFAULT_EMBEDDING_MODEL) {
56
- this.apiKey = apiKey;
57
- this.model = model;
58
- }
59
- async embed(texts) {
60
- const response = await fetch("https://api.openai.com/v1/embeddings", {
61
- method: "POST",
62
- headers: {
63
- Authorization: `Bearer ${this.apiKey}`,
64
- "Content-Type": "application/json",
65
- },
66
- body: JSON.stringify({
67
- model: this.model,
68
- input: texts,
69
- }),
70
- });
71
- if (!response.ok) {
72
- throw new Error(`embedding request failed: ${response.status} ${response.statusText}`);
73
- }
74
- const payload = (await response.json());
75
- if (!payload.data || payload.data.length !== texts.length) {
76
- throw new Error("embedding response missing expected vectors");
77
- }
78
- return payload.data.map((entry) => entry.embedding);
79
- }
80
- }
81
- function ensureMemoryStorePaths(rootDir) {
54
+ function ensureDiaryStorePaths(rootDir) {
82
55
  const factsPath = path.join(rootDir, "facts.jsonl");
83
56
  const entitiesPath = path.join(rootDir, "entities.json");
84
57
  const dailyDir = path.join(rootDir, "daily");
@@ -90,8 +63,8 @@ function ensureMemoryStorePaths(rootDir) {
90
63
  fs.writeFileSync(entitiesPath, "{}\n", "utf8");
91
64
  (0, runtime_1.emitNervesEvent)({
92
65
  component: "mind",
93
- event: "mind.memory_paths_ready",
94
- message: "memory store paths ready",
66
+ event: "mind.diary_paths_ready",
67
+ message: "diary store paths ready",
95
68
  meta: { rootDir },
96
69
  });
97
70
  return { rootDir, factsPath, entitiesPath, dailyDir };
@@ -114,7 +87,7 @@ function overlapScore(left, right) {
114
87
  }
115
88
  return common / Math.min(leftWords.size, rightWords.size);
116
89
  }
117
- function readExistingFacts(factsPath) {
90
+ function readExistingEntries(factsPath) {
118
91
  if (!fs.existsSync(factsPath))
119
92
  return [];
120
93
  const raw = fs.readFileSync(factsPath, "utf8").trim();
@@ -177,13 +150,24 @@ function appendDailyFact(dailyDir, fact) {
177
150
  const dayPath = path.join(dailyDir, `${day}.jsonl`);
178
151
  fs.appendFileSync(dayPath, `${JSON.stringify(fact)}\n`, "utf8");
179
152
  }
180
- function appendFactsWithDedup(stores, incoming) {
181
- const existing = readExistingFacts(stores.factsPath);
153
+ function appendEntriesWithDedup(stores, incoming, options) {
154
+ const existing = readExistingEntries(stores.factsPath);
182
155
  const all = [...existing];
183
156
  let added = 0;
184
157
  let skipped = 0;
158
+ const semanticThreshold = options?.semanticThreshold;
185
159
  for (const fact of incoming) {
186
- const duplicate = all.some((prior) => overlapScore(prior.text, fact.text) > DEDUP_THRESHOLD);
160
+ const duplicate = all.some((prior) => {
161
+ if (overlapScore(prior.text, fact.text) > DEDUP_THRESHOLD)
162
+ return true;
163
+ if (semanticThreshold !== undefined &&
164
+ Array.isArray(fact.embedding) && fact.embedding.length > 0 &&
165
+ Array.isArray(prior.embedding) && prior.embedding.length > 0 &&
166
+ fact.embedding.length === prior.embedding.length) {
167
+ return (0, note_search_1.cosineSimilarity)(fact.embedding, prior.embedding) > semanticThreshold;
168
+ }
169
+ return false;
170
+ });
187
171
  if (duplicate) {
188
172
  skipped++;
189
173
  continue;
@@ -196,44 +180,20 @@ function appendFactsWithDedup(stores, incoming) {
196
180
  }
197
181
  (0, runtime_1.emitNervesEvent)({
198
182
  component: "mind",
199
- event: "mind.memory_write",
200
- message: "memory write completed",
183
+ event: "mind.diary_write",
184
+ message: "diary write completed",
201
185
  meta: { added, skipped },
202
186
  });
203
187
  return { added, skipped };
204
188
  }
205
- function cosineSimilarity(left, right) {
206
- if (left.length === 0 || right.length === 0 || left.length !== right.length)
207
- return 0;
208
- let dot = 0;
209
- let leftNorm = 0;
210
- let rightNorm = 0;
211
- for (let i = 0; i < left.length; i += 1) {
212
- dot += left[i] * right[i];
213
- leftNorm += left[i] * left[i];
214
- rightNorm += right[i] * right[i];
215
- }
216
- if (leftNorm === 0 || rightNorm === 0)
217
- return 0;
218
- return dot / (Math.sqrt(leftNorm) * Math.sqrt(rightNorm));
219
- }
220
- exports.__memoryTestUtils = {
221
- cosineSimilarity,
222
- };
223
- function createDefaultEmbeddingProvider() {
224
- const apiKey = (0, config_1.getOpenAIEmbeddingsApiKey)().trim();
225
- if (!apiKey)
226
- return null;
227
- return new OpenAIEmbeddingProvider(apiKey);
228
- }
229
189
  async function buildEmbedding(text, embeddingProvider) {
230
- const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
190
+ const provider = embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
231
191
  if (!provider) {
232
192
  (0, runtime_1.emitNervesEvent)({
233
193
  level: "warn",
234
194
  component: "mind",
235
- event: "mind.memory_embedding_unavailable",
236
- message: "embedding provider unavailable for memory write",
195
+ event: "mind.diary_embedding_unavailable",
196
+ message: "embedding provider unavailable for diary write",
237
197
  meta: { reason: "missing_openai_embeddings_key" },
238
198
  });
239
199
  return [];
@@ -246,8 +206,8 @@ async function buildEmbedding(text, embeddingProvider) {
246
206
  (0, runtime_1.emitNervesEvent)({
247
207
  level: "warn",
248
208
  component: "mind",
249
- event: "mind.memory_embedding_unavailable",
250
- message: "embedding provider unavailable for memory write",
209
+ event: "mind.diary_embedding_unavailable",
210
+ message: "embedding provider unavailable for diary write",
251
211
  meta: {
252
212
  reason: error instanceof Error ? error.message : String(error),
253
213
  },
@@ -255,13 +215,19 @@ async function buildEmbedding(text, embeddingProvider) {
255
215
  return [];
256
216
  }
257
217
  }
258
- function readMemoryFacts(memoryRoot = path.join((0, identity_1.getAgentRoot)(), "psyche", "memory")) {
259
- return readExistingFacts(path.join(memoryRoot, "facts.jsonl"));
218
+ function resolveDiaryRoot(explicitRoot) {
219
+ if (explicitRoot)
220
+ return explicitRoot;
221
+ const agentRoot = (0, identity_1.getAgentRoot)();
222
+ return path.join(agentRoot, "diary");
260
223
  }
261
- async function saveMemoryFact(options) {
224
+ function readDiaryEntries(diaryRoot) {
225
+ return readExistingEntries(path.join(resolveDiaryRoot(diaryRoot), "facts.jsonl"));
226
+ }
227
+ async function saveDiaryEntry(options) {
262
228
  const text = options.text.trim();
263
- const memoryRoot = options.memoryRoot ?? path.join((0, identity_1.getAgentRoot)(), "psyche", "memory");
264
- const stores = ensureMemoryStorePaths(memoryRoot);
229
+ const diaryRoot = resolveDiaryRoot(options.diaryRoot);
230
+ const stores = ensureDiaryStorePaths(diaryRoot);
265
231
  const embedding = await buildEmbedding(text, options.embeddingProvider);
266
232
  const fact = {
267
233
  id: options.idFactory ? options.idFactory() : (0, crypto_1.randomUUID)(),
@@ -270,24 +236,39 @@ async function saveMemoryFact(options) {
270
236
  about: options.about?.trim() || undefined,
271
237
  createdAt: (options.now ?? (() => new Date()))().toISOString(),
272
238
  embedding,
239
+ ...(options.provenance ? { provenance: options.provenance } : {}),
273
240
  };
274
- return appendFactsWithDedup(stores, [fact]);
241
+ const integrity = (0, diary_integrity_1.detectSuspiciousContent)(text);
242
+ if (integrity.suspicious) {
243
+ (0, runtime_1.emitNervesEvent)({
244
+ level: "warn",
245
+ component: "mind",
246
+ event: "mind.diary_integrity_warning",
247
+ message: "suspicious content detected in diary entry",
248
+ meta: {
249
+ patterns: integrity.patterns,
250
+ textPreview: text.slice(0, 200),
251
+ entryId: fact.id,
252
+ },
253
+ });
254
+ }
255
+ return appendEntriesWithDedup(stores, [fact], { semanticThreshold: SEMANTIC_DEDUP_THRESHOLD });
275
256
  }
276
257
  async function backfillEmbeddings(options) {
277
- const memoryRoot = options?.memoryRoot ?? path.join((0, identity_1.getAgentRoot)(), "psyche", "memory");
278
- const factsPath = path.join(memoryRoot, "facts.jsonl");
258
+ const diaryRoot = resolveDiaryRoot(options?.diaryRoot);
259
+ const factsPath = path.join(diaryRoot, "facts.jsonl");
279
260
  if (!fs.existsSync(factsPath))
280
261
  return { total: 0, backfilled: 0, failed: 0 };
281
- const facts = readExistingFacts(factsPath);
262
+ const facts = readExistingEntries(factsPath);
282
263
  const needsEmbedding = facts.filter((f) => !Array.isArray(f.embedding) || f.embedding.length === 0);
283
264
  if (needsEmbedding.length === 0)
284
265
  return { total: facts.length, backfilled: 0, failed: 0 };
285
- const provider = options?.embeddingProvider ?? createDefaultEmbeddingProvider();
266
+ const provider = options?.embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
286
267
  if (!provider) {
287
268
  (0, runtime_1.emitNervesEvent)({
288
269
  level: "warn",
289
270
  component: "mind",
290
- event: "mind.memory_backfill_skipped",
271
+ event: "mind.diary_backfill_skipped",
291
272
  message: "embedding provider unavailable for backfill",
292
273
  meta: { needsEmbedding: needsEmbedding.length },
293
274
  });
@@ -313,7 +294,7 @@ async function backfillEmbeddings(options) {
313
294
  (0, runtime_1.emitNervesEvent)({
314
295
  level: "warn",
315
296
  component: "mind",
316
- event: "mind.memory_backfill_batch_error",
297
+ event: "mind.diary_backfill_batch_error",
317
298
  message: "embedding backfill batch failed",
318
299
  meta: {
319
300
  batchStart: i,
@@ -328,7 +309,7 @@ async function backfillEmbeddings(options) {
328
309
  fs.writeFileSync(factsPath, lines, "utf8");
329
310
  (0, runtime_1.emitNervesEvent)({
330
311
  component: "mind",
331
- event: "mind.memory_backfill_complete",
312
+ event: "mind.diary_backfill_complete",
332
313
  message: "embedding backfill completed",
333
314
  meta: { total: facts.length, backfilled, failed },
334
315
  });
@@ -348,7 +329,7 @@ function uniqueFacts(facts) {
348
329
  }
349
330
  return unique;
350
331
  }
351
- async function searchMemoryFacts(query, facts, embeddingProvider) {
332
+ async function searchDiaryEntries(query, facts, embeddingProvider) {
352
333
  const trimmed = query.trim();
353
334
  if (!trimmed)
354
335
  return [];
@@ -358,7 +339,7 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
358
339
  if (embeddedFacts.length === 0) {
359
340
  return substringFallback();
360
341
  }
361
- const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
342
+ const provider = embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
362
343
  if (!provider) {
363
344
  return substringFallback();
364
345
  }
@@ -372,7 +353,7 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
372
353
  .filter((fact) => fact.embedding.length === queryEmbedding.length)
373
354
  .map((fact) => ({
374
355
  fact,
375
- score: cosineSimilarity(queryEmbedding, fact.embedding),
356
+ score: (0, note_search_1.cosineSimilarity)(queryEmbedding, fact.embedding),
376
357
  }))
377
358
  .filter((entry) => entry.score > 0)
378
359
  .sort((left, right) => right.score - left.score)
@@ -384,8 +365,8 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
384
365
  (0, runtime_1.emitNervesEvent)({
385
366
  level: "warn",
386
367
  component: "mind",
387
- event: "mind.memory_embedding_unavailable",
388
- message: "embedding provider unavailable for memory search",
368
+ event: "mind.diary_embedding_unavailable",
369
+ message: "embedding provider unavailable for diary search",
389
370
  meta: {
390
371
  reason: error instanceof Error ? error.message : String(error),
391
372
  },