@ouro.bot/cli 0.1.0-alpha.73 → 0.1.0-alpha.731

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 (530) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/assets/bluebubbles-host +264 -0
  14. package/changelog.json +4645 -14
  15. package/dist/a2a/card.js +57 -0
  16. package/dist/a2a/client.js +180 -0
  17. package/dist/a2a/config.js +50 -0
  18. package/dist/a2a/delegation-stores.js +56 -0
  19. package/dist/a2a/did-resolution.js +93 -0
  20. package/dist/a2a/identity.js +170 -0
  21. package/dist/a2a/inbound-share.js +107 -0
  22. package/dist/a2a/mission-result-wire.js +196 -0
  23. package/dist/a2a/onboarding.js +115 -0
  24. package/dist/a2a/pin-store.js +132 -0
  25. package/dist/a2a/seen-ledger.js +120 -0
  26. package/dist/a2a/server.js +604 -0
  27. package/dist/a2a/task-store.js +69 -0
  28. package/dist/a2a/transport.js +45 -0
  29. package/dist/a2a/types.js +3 -0
  30. package/dist/arc/attention-types.js +8 -0
  31. package/dist/arc/cares.js +144 -0
  32. package/dist/arc/episodes.js +118 -0
  33. package/dist/arc/evolution.js +490 -0
  34. package/dist/arc/flight-recorder.js +1034 -0
  35. package/dist/arc/intentions.js +134 -0
  36. package/dist/arc/json-store.js +117 -0
  37. package/dist/arc/obligations.js +348 -0
  38. package/dist/arc/packets.js +336 -0
  39. package/dist/arc/presence.js +185 -0
  40. package/dist/arc/task-lifecycle.js +57 -0
  41. package/dist/commerce/store.js +755 -0
  42. package/dist/commerce/types.js +3 -0
  43. package/dist/heart/active-work.js +874 -43
  44. package/dist/heart/agent-entry.js +190 -3
  45. package/dist/heart/approval-store.js +791 -0
  46. package/dist/heart/attachments/image-normalize.js +194 -0
  47. package/dist/heart/attachments/materialize.js +97 -0
  48. package/dist/heart/attachments/originals.js +88 -0
  49. package/dist/heart/attachments/render.js +29 -0
  50. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  51. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  52. package/dist/heart/attachments/sources/index.js +16 -0
  53. package/dist/heart/attachments/store.js +103 -0
  54. package/dist/heart/attachments/types.js +93 -0
  55. package/dist/heart/auth/auth-flow.js +479 -0
  56. package/dist/heart/autonomy-budget.js +434 -0
  57. package/dist/heart/awaiting/await-alert.js +146 -0
  58. package/dist/heart/awaiting/await-expiry.js +108 -0
  59. package/dist/heart/awaiting/await-loader.js +91 -0
  60. package/dist/heart/awaiting/await-parser.js +141 -0
  61. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  62. package/dist/heart/awaiting/await-scheduler.js +378 -0
  63. package/dist/heart/background-operations.js +281 -0
  64. package/dist/heart/bridges/manager.js +137 -17
  65. package/dist/heart/bridges/store.js +14 -2
  66. package/dist/heart/bundle-state.js +168 -0
  67. package/dist/heart/commitments.js +135 -0
  68. package/dist/heart/config-registry.js +331 -0
  69. package/dist/heart/config.js +120 -129
  70. package/dist/heart/context-loss-gauntlet.js +354 -0
  71. package/dist/heart/context-loss-sentinel.js +1155 -0
  72. package/dist/heart/core.js +1763 -320
  73. package/dist/heart/cross-chat-delivery.js +8 -22
  74. package/dist/heart/daemon/agent-config-check.js +451 -0
  75. package/dist/heart/daemon/agent-discovery.js +185 -3
  76. package/dist/heart/daemon/agent-service.js +542 -0
  77. package/dist/heart/daemon/agentic-repair.js +547 -0
  78. package/dist/heart/daemon/await-private-wake.js +59 -0
  79. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  80. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  81. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  82. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  83. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  84. package/dist/heart/daemon/cadence.js +180 -0
  85. package/dist/heart/daemon/cli-defaults.js +832 -0
  86. package/dist/heart/daemon/cli-desk.js +322 -0
  87. package/dist/heart/daemon/cli-exec.js +8620 -0
  88. package/dist/heart/daemon/cli-help.js +705 -0
  89. package/dist/heart/daemon/cli-parse.js +2712 -0
  90. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  91. package/dist/heart/daemon/cli-render.js +777 -0
  92. package/dist/heart/daemon/cli-types.js +8 -0
  93. package/dist/heart/daemon/connect-bay.js +323 -0
  94. package/dist/heart/daemon/daemon-cli.js +29 -2093
  95. package/dist/heart/daemon/daemon-entry.js +842 -10
  96. package/dist/heart/daemon/daemon-health.js +176 -0
  97. package/dist/heart/daemon/daemon-rollup.js +57 -0
  98. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  99. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  100. package/dist/heart/daemon/daemon.js +1610 -87
  101. package/dist/heart/daemon/dns-workflow.js +394 -0
  102. package/dist/heart/daemon/doctor-types.js +8 -0
  103. package/dist/heart/daemon/doctor.js +1689 -0
  104. package/dist/heart/daemon/freshness.js +345 -0
  105. package/dist/heart/daemon/habit-private-wake.js +61 -0
  106. package/dist/heart/daemon/health-monitor.js +142 -11
  107. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  108. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  109. package/dist/heart/daemon/http-health-probe.js +80 -0
  110. package/dist/heart/daemon/human-command-screens.js +234 -0
  111. package/dist/heart/daemon/human-readiness.js +114 -0
  112. package/dist/heart/daemon/inner-status.js +78 -0
  113. package/dist/heart/daemon/interactive-repair.js +394 -0
  114. package/dist/heart/daemon/launchd.js +37 -8
  115. package/dist/heart/daemon/log-tailer.js +79 -10
  116. package/dist/heart/daemon/logs-prune.js +132 -0
  117. package/dist/heart/daemon/mcp-canary.js +524 -0
  118. package/dist/heart/daemon/message-router.js +45 -5
  119. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  120. package/dist/heart/daemon/os-cron-deps.js +135 -0
  121. package/dist/heart/daemon/os-cron.js +22 -14
  122. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  123. package/dist/heart/daemon/ouro-entry.js +3 -1
  124. package/dist/heart/daemon/plugin-cli.js +432 -0
  125. package/dist/heart/daemon/process-manager.js +624 -61
  126. package/dist/heart/daemon/provider-discovery.js +137 -0
  127. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  128. package/dist/heart/daemon/prunable-bundle.js +144 -0
  129. package/dist/heart/daemon/pulse.js +511 -0
  130. package/dist/heart/daemon/readiness-repair.js +365 -0
  131. package/dist/heart/daemon/run-hooks.js +2 -0
  132. package/dist/heart/daemon/runtime-logging.js +41 -14
  133. package/dist/heart/daemon/runtime-metadata.js +2 -30
  134. package/dist/heart/daemon/safe-mode.js +161 -0
  135. package/dist/heart/daemon/sense-manager.js +670 -48
  136. package/dist/heart/daemon/session-id-resolver.js +131 -0
  137. package/dist/heart/daemon/skill-management-installer.js +1 -1
  138. package/dist/heart/daemon/socket-client.js +180 -12
  139. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  140. package/dist/heart/daemon/startup-tui.js +338 -0
  141. package/dist/heart/daemon/task-scheduler.js +117 -39
  142. package/dist/heart/daemon/terminal-ui.js +499 -0
  143. package/dist/heart/daemon/thoughts.js +255 -43
  144. package/dist/heart/daemon/up-progress.js +366 -0
  145. package/dist/heart/daemon/vault-items.js +56 -0
  146. package/dist/heart/delegation.js +1 -4
  147. package/dist/heart/external-events/router.js +121 -0
  148. package/dist/heart/habits/habit-cancel.js +810 -0
  149. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  150. package/dist/heart/habits/habit-migration.js +194 -0
  151. package/dist/heart/habits/habit-parser.js +278 -0
  152. package/dist/heart/habits/habit-runtime-state.js +93 -0
  153. package/dist/heart/habits/habit-scheduler.js +649 -0
  154. package/dist/heart/habits/habit-session-summary.js +318 -0
  155. package/dist/heart/habits/habit-session.js +636 -0
  156. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  157. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  158. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  159. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  160. package/dist/heart/identity.js +174 -59
  161. package/dist/heart/kept-notes.js +289 -0
  162. package/dist/heart/kicks.js +1 -1
  163. package/dist/heart/machine-identity.js +161 -0
  164. package/dist/heart/mail-import-discovery.js +353 -0
  165. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  166. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  167. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  168. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  169. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  170. package/dist/heart/mailbox/mailbox-http.js +99 -0
  171. package/dist/heart/mailbox/mailbox-read.js +39 -0
  172. package/dist/heart/mailbox/mailbox-types.js +27 -0
  173. package/dist/heart/mailbox/mailbox-view.js +197 -0
  174. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  175. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  176. package/dist/heart/mailbox/readers/mail.js +375 -0
  177. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  178. package/dist/heart/mailbox/readers/sessions.js +232 -0
  179. package/dist/heart/mailbox/readers/shared.js +111 -0
  180. package/dist/heart/mcp/mcp-server.js +696 -0
  181. package/dist/heart/migrate-config.js +100 -0
  182. package/dist/heart/model-capabilities.js +11 -0
  183. package/dist/heart/orientation-frame.js +345 -0
  184. package/dist/heart/platform.js +81 -0
  185. package/dist/heart/primitives.js +1 -1
  186. package/dist/heart/private-runtime/decision-renderer.js +156 -0
  187. package/dist/heart/private-runtime/index.js +18 -0
  188. package/dist/heart/private-runtime/ledger.js +218 -0
  189. package/dist/heart/private-runtime/policy.js +214 -0
  190. package/dist/heart/private-runtime/types.js +2 -0
  191. package/dist/heart/progress-story.js +1 -1
  192. package/dist/heart/provider-attempt.js +137 -0
  193. package/dist/heart/provider-binding-resolver.js +273 -0
  194. package/dist/heart/provider-credentials.js +441 -0
  195. package/dist/heart/provider-failover.js +311 -0
  196. package/dist/heart/provider-models.js +81 -0
  197. package/dist/heart/provider-ping.js +262 -0
  198. package/dist/heart/provider-readiness-cache.js +119 -0
  199. package/dist/heart/provider-visibility.js +188 -0
  200. package/dist/heart/providers/anthropic-token.js +131 -0
  201. package/dist/heart/providers/anthropic.js +173 -60
  202. package/dist/heart/providers/azure.js +23 -11
  203. package/dist/heart/providers/error-classification.js +127 -0
  204. package/dist/heart/providers/github-copilot.js +34 -38
  205. package/dist/heart/providers/minimax-vlm.js +189 -0
  206. package/dist/heart/providers/minimax.js +26 -8
  207. package/dist/heart/providers/openai-codex-token.js +349 -0
  208. package/dist/heart/providers/openai-codex.js +55 -40
  209. package/dist/heart/run-ledger.js +247 -0
  210. package/dist/heart/runtime-capability-check.js +170 -0
  211. package/dist/heart/runtime-credentials.js +398 -0
  212. package/dist/heart/runtime-cwd.js +87 -0
  213. package/dist/heart/sense-truth.js +20 -4
  214. package/dist/heart/session-activity.js +90 -24
  215. package/dist/heart/session-events.js +1300 -0
  216. package/dist/heart/session-playback-cli-main.js +5 -0
  217. package/dist/heart/session-playback-cli.js +36 -0
  218. package/dist/heart/session-playback.js +231 -0
  219. package/dist/heart/session-stats-cli-main.js +5 -0
  220. package/dist/heart/session-stats.js +182 -0
  221. package/dist/heart/session-transcript.js +133 -0
  222. package/dist/heart/start-of-turn-packet.js +368 -0
  223. package/dist/heart/streaming.js +604 -207
  224. package/dist/heart/structured-output.js +196 -0
  225. package/dist/heart/sync-classification.js +176 -0
  226. package/dist/heart/sync.js +449 -0
  227. package/dist/heart/target-resolution.js +11 -7
  228. package/dist/heart/tempo.js +93 -0
  229. package/dist/heart/temporal-view.js +41 -0
  230. package/dist/heart/timeouts.js +101 -0
  231. package/dist/heart/tool-activity-callbacks.js +59 -0
  232. package/dist/heart/tool-approval.js +339 -0
  233. package/dist/heart/tool-description.js +155 -0
  234. package/dist/heart/tool-friction.js +55 -0
  235. package/dist/heart/tool-loop.js +200 -0
  236. package/dist/heart/turn-context.js +472 -0
  237. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  238. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  239. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  240. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  241. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  242. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  243. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  244. package/dist/heart/versioning/update-hooks.js +154 -0
  245. package/dist/heart/versioning/version-intent.js +114 -0
  246. package/dist/heart/work-card.js +380 -0
  247. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  248. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  249. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  250. package/dist/mailbox-ui/index.html +16 -0
  251. package/dist/mailroom/attention.js +167 -0
  252. package/dist/mailroom/autonomy.js +209 -0
  253. package/dist/mailroom/blob-store.js +811 -0
  254. package/dist/mailroom/body-cache.js +61 -0
  255. package/dist/mailroom/cache-sync-cli.js +54 -0
  256. package/dist/mailroom/core.js +788 -0
  257. package/dist/mailroom/entry.js +160 -0
  258. package/dist/mailroom/file-store.js +568 -0
  259. package/dist/mailroom/hosted-cache-sync.js +249 -0
  260. package/dist/mailroom/mbox-import.js +393 -0
  261. package/dist/mailroom/migration.js +164 -0
  262. package/dist/mailroom/outbound.js +380 -0
  263. package/dist/mailroom/policy.js +263 -0
  264. package/dist/mailroom/reader.js +292 -0
  265. package/dist/mailroom/search-cache.js +404 -0
  266. package/dist/mailroom/search-relevance.js +319 -0
  267. package/dist/mailroom/smtp-ingress.js +176 -0
  268. package/dist/mailroom/source-state.js +176 -0
  269. package/dist/mailroom/thread.js +109 -0
  270. package/dist/mailroom/travel-extract.js +89 -0
  271. package/dist/mind/bundle-manifest.js +24 -2
  272. package/dist/mind/context.js +273 -111
  273. package/dist/mind/desk-section.js +362 -0
  274. package/dist/mind/diary-integrity.js +60 -0
  275. package/dist/mind/{memory.js → diary.js} +68 -77
  276. package/dist/mind/embedding-provider.js +60 -0
  277. package/dist/mind/file-state.js +179 -0
  278. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  279. package/dist/mind/obligation-steering.js +227 -0
  280. package/dist/mind/pending.js +13 -8
  281. package/dist/mind/prompt-budget.js +479 -0
  282. package/dist/mind/prompt-refresh.js +3 -2
  283. package/dist/mind/prompt.js +1058 -172
  284. package/dist/mind/provenance-trust.js +26 -0
  285. package/dist/mind/record-paths.js +312 -0
  286. package/dist/mind/scrutiny.js +173 -0
  287. package/dist/mind/session-transaction.js +379 -0
  288. package/dist/nerves/cli-logging.js +7 -1
  289. package/dist/nerves/coverage/audit-rules.js +15 -6
  290. package/dist/nerves/coverage/audit.js +28 -2
  291. package/dist/nerves/coverage/cli.js +1 -1
  292. package/dist/nerves/coverage/contract.js +5 -5
  293. package/dist/nerves/coverage/file-completeness.js +139 -5
  294. package/dist/nerves/coverage/run-artifacts.js +55 -35
  295. package/dist/nerves/event-buffer.js +111 -0
  296. package/dist/nerves/index.js +234 -4
  297. package/dist/nerves/observation.js +20 -0
  298. package/dist/nerves/redact.js +79 -0
  299. package/dist/nerves/review/cli-main.js +5 -0
  300. package/dist/nerves/review/cli.js +156 -0
  301. package/dist/nerves/review/core.js +159 -0
  302. package/dist/nerves/runtime.js +5 -1
  303. package/dist/repertoire/ado-client.js +15 -56
  304. package/dist/repertoire/ado-semantic.js +16 -10
  305. package/dist/repertoire/api-client.js +97 -0
  306. package/dist/repertoire/bitwarden-store.js +1045 -0
  307. package/dist/repertoire/bundle-templates.js +71 -0
  308. package/dist/repertoire/bw-installer.js +180 -0
  309. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  310. package/dist/repertoire/coding/context-pack.js +331 -0
  311. package/dist/repertoire/coding/feedback.js +218 -30
  312. package/dist/repertoire/coding/index.js +15 -3
  313. package/dist/repertoire/coding/manager.js +166 -10
  314. package/dist/repertoire/coding/spawner.js +58 -11
  315. package/dist/repertoire/coding/tools.js +242 -14
  316. package/dist/repertoire/coding/workbench-client.js +272 -0
  317. package/dist/repertoire/coding/workbench-manager.js +346 -0
  318. package/dist/repertoire/commerce-errors.js +109 -0
  319. package/dist/repertoire/commerce-self-test.js +156 -0
  320. package/dist/repertoire/credential-access.js +178 -0
  321. package/dist/repertoire/desk/classifier.js +362 -0
  322. package/dist/repertoire/duffel-client.js +185 -0
  323. package/dist/repertoire/github-client.js +14 -55
  324. package/dist/repertoire/graph-client.js +11 -52
  325. package/dist/repertoire/guardrails.js +812 -18
  326. package/dist/repertoire/mcp-client.js +44 -3
  327. package/dist/repertoire/mcp-manager.js +259 -20
  328. package/dist/repertoire/mcp-tools.js +83 -0
  329. package/dist/repertoire/plugin-mcp.js +175 -0
  330. package/dist/repertoire/plugins.js +253 -0
  331. package/dist/repertoire/shell-sessions.js +133 -0
  332. package/dist/repertoire/skills.js +48 -4
  333. package/dist/repertoire/stripe-client.js +131 -0
  334. package/dist/repertoire/tool-arguments.js +104 -0
  335. package/dist/repertoire/tool-results.js +29 -0
  336. package/dist/repertoire/tools-a2a.js +699 -0
  337. package/dist/repertoire/tools-attachments.js +317 -0
  338. package/dist/repertoire/tools-awaiting.js +372 -0
  339. package/dist/repertoire/tools-base.js +67 -1095
  340. package/dist/repertoire/tools-bluebubbles.js +2 -0
  341. package/dist/repertoire/tools-bridge.js +144 -0
  342. package/dist/repertoire/tools-bundle.js +993 -0
  343. package/dist/repertoire/tools-commerce.js +253 -0
  344. package/dist/repertoire/tools-config.js +186 -0
  345. package/dist/repertoire/tools-continuity.js +252 -0
  346. package/dist/repertoire/tools-credential.js +383 -0
  347. package/dist/repertoire/tools-evolution.js +527 -0
  348. package/dist/repertoire/tools-files.js +344 -0
  349. package/dist/repertoire/tools-flight.js +290 -0
  350. package/dist/repertoire/tools-flow.js +119 -0
  351. package/dist/repertoire/tools-github.js +3 -8
  352. package/dist/repertoire/tools-habits.js +103 -0
  353. package/dist/repertoire/tools-mail.js +1828 -0
  354. package/dist/repertoire/tools-notes.js +459 -0
  355. package/dist/repertoire/tools-obligations.js +182 -0
  356. package/dist/repertoire/tools-orientation.js +31 -0
  357. package/dist/repertoire/tools-record.js +482 -0
  358. package/dist/repertoire/tools-rsvp.js +139 -0
  359. package/dist/repertoire/tools-runtime.js +150 -0
  360. package/dist/repertoire/tools-session.js +881 -0
  361. package/dist/repertoire/tools-shell.js +133 -0
  362. package/dist/repertoire/tools-stripe.js +224 -0
  363. package/dist/repertoire/tools-surface.js +355 -0
  364. package/dist/repertoire/tools-teams.js +12 -39
  365. package/dist/repertoire/tools-travel.js +125 -0
  366. package/dist/repertoire/tools-trip.js +982 -0
  367. package/dist/repertoire/tools-user-profile.js +146 -0
  368. package/dist/repertoire/tools-vault.js +40 -0
  369. package/dist/repertoire/tools-voice.js +145 -0
  370. package/dist/repertoire/tools.js +258 -79
  371. package/dist/repertoire/travel-api-client.js +360 -0
  372. package/dist/repertoire/user-profile.js +131 -0
  373. package/dist/repertoire/vault-setup.js +246 -0
  374. package/dist/repertoire/vault-unlock.js +594 -0
  375. package/dist/rsvp/aisleplanner-client.js +354 -0
  376. package/dist/rsvp/cli.js +926 -0
  377. package/dist/rsvp/config.js +327 -0
  378. package/dist/rsvp/cutover.js +433 -0
  379. package/dist/rsvp/diagnostics.js +232 -0
  380. package/dist/rsvp/diff-renderer.js +176 -0
  381. package/dist/rsvp/habit-policy.js +110 -0
  382. package/dist/rsvp/habit-stage.js +123 -0
  383. package/dist/rsvp/incident-bundle.js +97 -0
  384. package/dist/rsvp/migration.js +204 -0
  385. package/dist/rsvp/native-habit-runner.js +630 -0
  386. package/dist/rsvp/outbound-state.js +628 -0
  387. package/dist/rsvp/query.js +118 -0
  388. package/dist/rsvp/replay.js +233 -0
  389. package/dist/rsvp/snapshot.js +232 -0
  390. package/dist/rsvp/spend-ledger.js +175 -0
  391. package/dist/scripts/claude-code-hook.js +41 -0
  392. package/dist/scripts/claude-code-stop-hook.js +47 -0
  393. package/dist/senses/a2a-entry.js +115 -0
  394. package/dist/senses/attention-queue.js +186 -0
  395. package/dist/senses/await-turn-message.js +58 -0
  396. package/dist/senses/bluebubbles/active-turns.js +216 -0
  397. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  398. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  399. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  400. package/dist/senses/bluebubbles/context-packet.js +207 -0
  401. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  402. package/dist/senses/bluebubbles/entry.js +90 -0
  403. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  404. package/dist/senses/bluebubbles/index.js +3839 -0
  405. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  406. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  407. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  408. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  409. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  410. package/dist/senses/bluebubbles/processed-log.js +133 -0
  411. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  412. package/dist/senses/bluebubbles/replay.js +284 -0
  413. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  414. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  415. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  416. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  417. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  418. package/dist/senses/cli/bracketed-paste.js +82 -0
  419. package/dist/senses/cli/image-paste.js +287 -0
  420. package/dist/senses/cli/image-ref-navigation.js +75 -0
  421. package/dist/senses/cli/ink-app.js +156 -0
  422. package/dist/senses/cli/inline-diff.js +64 -0
  423. package/dist/senses/cli/input-keys.js +174 -0
  424. package/dist/senses/cli/kill-ring.js +86 -0
  425. package/dist/senses/cli/message-list.js +51 -0
  426. package/dist/senses/cli/ouro-tui.js +607 -0
  427. package/dist/senses/cli/spinner-imperative.js +135 -0
  428. package/dist/senses/cli/spinner.js +101 -0
  429. package/dist/senses/cli/status-line.js +60 -0
  430. package/dist/senses/cli/streaming-markdown.js +526 -0
  431. package/dist/senses/cli/tool-display.js +85 -0
  432. package/dist/senses/cli/tool-render.js +85 -0
  433. package/dist/senses/cli/tui-store.js +241 -0
  434. package/dist/senses/cli/virtual-list.js +35 -0
  435. package/dist/senses/cli-entry.js +60 -8
  436. package/dist/senses/cli-layout.js +100 -0
  437. package/dist/senses/cli.js +640 -312
  438. package/dist/senses/commands.js +66 -3
  439. package/dist/senses/context-packet-ledger.js +371 -0
  440. package/dist/senses/context-packets.js +154 -0
  441. package/dist/senses/habit-lifecycle-guard.js +24 -0
  442. package/dist/senses/habit-turn-message.js +160 -0
  443. package/dist/senses/ingress-evidence.js +2 -0
  444. package/dist/senses/mail-entry.js +66 -0
  445. package/dist/senses/mail.js +524 -0
  446. package/dist/senses/pipeline.js +1075 -176
  447. package/dist/senses/private-runtime-worker.js +740 -0
  448. package/dist/senses/private-runtime.js +1212 -0
  449. package/dist/senses/proactive-content-guard.js +51 -0
  450. package/dist/senses/shared-turn.js +424 -0
  451. package/dist/senses/surface-tool.js +109 -0
  452. package/dist/senses/teams-entry.js +60 -8
  453. package/dist/senses/teams.js +515 -217
  454. package/dist/senses/trust-gate.js +104 -9
  455. package/dist/senses/voice/audio-playback.js +237 -0
  456. package/dist/senses/voice/audio-routing.js +119 -0
  457. package/dist/senses/voice/elevenlabs.js +202 -0
  458. package/dist/senses/voice/floor-control.js +431 -0
  459. package/dist/senses/voice/floor-controller.js +115 -0
  460. package/dist/senses/voice/golden-path.js +116 -0
  461. package/dist/senses/voice/index.js +29 -0
  462. package/dist/senses/voice/meeting.js +113 -0
  463. package/dist/senses/voice/outbound.js +190 -0
  464. package/dist/senses/voice/phone.js +33 -0
  465. package/dist/senses/voice/playback.js +139 -0
  466. package/dist/senses/voice/realtime-eval.js +496 -0
  467. package/dist/senses/voice/realtime-trace.js +531 -0
  468. package/dist/senses/voice/transcript.js +70 -0
  469. package/dist/senses/voice/turn.js +191 -0
  470. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  471. package/dist/senses/voice/twilio-phone.js +5081 -0
  472. package/dist/senses/voice/types.js +2 -0
  473. package/dist/senses/voice/whisper.js +161 -0
  474. package/dist/senses/voice-entry.js +81 -0
  475. package/dist/senses/voice-realtime-eval-command.js +99 -0
  476. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  477. package/dist/senses/voice-twilio-entry.js +87 -0
  478. package/dist/trips/core.js +138 -0
  479. package/dist/trips/store.js +265 -0
  480. package/dist/util/frontmatter.js +69 -0
  481. package/package.json +65 -12
  482. package/skills/agent-commerce.md +113 -0
  483. package/skills/browser-navigation.md +117 -0
  484. package/skills/commerce-setup-guide.md +116 -0
  485. package/skills/commerce-setup.md +84 -0
  486. package/skills/configure-dev-tools.md +99 -0
  487. package/skills/travel-planning.md +138 -0
  488. package/dist/heart/daemon/auth-flow.js +0 -430
  489. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  490. package/dist/heart/daemon/update-hooks.js +0 -138
  491. package/dist/heart/safe-workspace.js +0 -228
  492. package/dist/heart/session-recall.js +0 -116
  493. package/dist/mind/friends/channel.js +0 -84
  494. package/dist/mind/friends/group-context.js +0 -144
  495. package/dist/mind/friends/resolver.js +0 -84
  496. package/dist/mind/friends/store-file.js +0 -190
  497. package/dist/mind/friends/store.js +0 -4
  498. package/dist/mind/friends/tokens.js +0 -26
  499. package/dist/mind/friends/trust-explanation.js +0 -74
  500. package/dist/mind/friends/types.js +0 -29
  501. package/dist/repertoire/tasks/board.js +0 -134
  502. package/dist/repertoire/tasks/index.js +0 -224
  503. package/dist/repertoire/tasks/lifecycle.js +0 -80
  504. package/dist/repertoire/tasks/middleware.js +0 -65
  505. package/dist/repertoire/tasks/parser.js +0 -173
  506. package/dist/repertoire/tasks/scanner.js +0 -132
  507. package/dist/repertoire/tasks/transitions.js +0 -144
  508. package/dist/senses/bluebubbles-entry.js +0 -13
  509. package/dist/senses/bluebubbles.js +0 -1180
  510. package/dist/senses/debug-activity.js +0 -148
  511. package/dist/senses/inner-dialog-worker.js +0 -90
  512. package/dist/senses/inner-dialog.js +0 -480
  513. package/subagents/README.md +0 -7
  514. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  515. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  516. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  517. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  518. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  519. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  520. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  521. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  522. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  523. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  524. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  525. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  526. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  527. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  528. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  529. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  530. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mailSearchCacheDocumentMatchesRecord = mailSearchCacheDocumentMatchesRecord;
4
+ exports.syncHostedMailSearchCache = syncHostedMailSearchCache;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const runtime_1 = require("../nerves/runtime");
7
+ const blob_store_1 = require("./blob-store");
8
+ const core_1 = require("./core");
9
+ const search_cache_1 = require("./search-cache");
10
+ function filtersFor(input) {
11
+ return {
12
+ agentId: input.agentId,
13
+ ...(input.placement ? { placement: input.placement } : {}),
14
+ ...(input.scope ? { compartmentKind: input.scope } : {}),
15
+ ...(input.source ? { source: input.source } : {}),
16
+ };
17
+ }
18
+ function recordFor(message) {
19
+ return {
20
+ schemaVersion: 1,
21
+ id: message.id,
22
+ agentId: message.agentId,
23
+ compartmentKind: message.compartmentKind,
24
+ placement: message.placement,
25
+ ...(message.source ? { source: message.source } : {}),
26
+ receivedAt: message.receivedAt,
27
+ };
28
+ }
29
+ function sameOptionalText(left, right) {
30
+ return (left ?? "").toLowerCase() === (right ?? "").toLowerCase();
31
+ }
32
+ function mailSearchCacheDocumentMatchesRecord(document, record, requireKeyProvenance) {
33
+ return document.schemaVersion === 1
34
+ && document.agentId === record.agentId
35
+ && document.messageId === record.id
36
+ && document.receivedAt === record.receivedAt
37
+ && document.placement === record.placement
38
+ && document.compartmentKind === record.compartmentKind
39
+ && sameOptionalText(document.source, record.source)
40
+ && document.textProjectionVersion === search_cache_1.MAIL_SEARCH_TEXT_PROJECTION_VERSION
41
+ && (!requireKeyProvenance || typeof document.decryptionKeyId === "string");
42
+ }
43
+ function messageMatchesRecord(message, record) {
44
+ return message.id === record.id
45
+ && message.agentId === record.agentId
46
+ && message.receivedAt === record.receivedAt
47
+ && message.placement === record.placement
48
+ && message.compartmentKind === record.compartmentKind
49
+ && sameOptionalText(message.source, record.source);
50
+ }
51
+ async function scopedRecords(input) {
52
+ const filters = filtersFor(input);
53
+ const indexed = await input.store.listMessageIndexRecords?.(filters);
54
+ if (indexed)
55
+ return indexed;
56
+ return (await input.store.listMessages(filters)).map(recordFor);
57
+ }
58
+ async function fetchIndexedMessage(store, id) {
59
+ return store.getIndexedMessageById
60
+ ? store.getIndexedMessageById(id)
61
+ : store.getMessage(id);
62
+ }
63
+ function removeCanonicalIfPresent(agentId, messageId, options) {
64
+ return (0, search_cache_1.removeMailSearchCacheDocument)(agentId, messageId, options) ? 1 : 0;
65
+ }
66
+ function missingPrivateKeyId(error) {
67
+ if (!(error instanceof Error))
68
+ return null;
69
+ const keyId = error.keyId;
70
+ return typeof keyId === "string" && keyId.length > 0 ? keyId : null;
71
+ }
72
+ /**
73
+ * Converge a local decrypted cache against hosted index authority, or perform
74
+ * the legacy bounded upsert used by the in-agent refresh tool. This core never
75
+ * writes remote mail state and never records access; adapters own audit policy.
76
+ */
77
+ async function performHostedMailSearchCacheSync(input) {
78
+ let authority = null;
79
+ let records;
80
+ if (input.mode === "full-convergence") {
81
+ const observer = input.authority ?? input.store;
82
+ if (!observer.observeMessageIndexAuthority) {
83
+ throw new Error("hosted mail authority observer is unavailable");
84
+ }
85
+ authority = await observer.observeMessageIndexAuthority(input.agentId);
86
+ if (authority.parseFailureCount > 0 || authority.duplicateIds.length > 0) {
87
+ throw new Error(`hosted mail authority is ambiguous: ${authority.parseFailureCount} malformed index name(s), ${authority.duplicateIds.length} duplicate message id(s)`);
88
+ }
89
+ if (authority.records.length === 0) {
90
+ throw new Error("hosted mail authority is empty and cannot safely drive full convergence");
91
+ }
92
+ records = authority.records;
93
+ }
94
+ else {
95
+ records = await scopedRecords(input);
96
+ }
97
+ const recordsById = new Map(records.map((record) => [record.id, record]));
98
+ const canonicalDocuments = new Map();
99
+ let removed = 0;
100
+ if (input.mode === "full-convergence") {
101
+ for (const inspected of (0, search_cache_1.inspectMailSearchCacheFiles)(input.agentId, input.cacheOptions)) {
102
+ const document = inspected.document;
103
+ const canonicalName = document ? `${document.messageId}.json` : null;
104
+ const record = document ? recordsById.get(document.messageId) : undefined;
105
+ if (!document || inspected.fileName !== canonicalName || document.agentId !== input.agentId || !record) {
106
+ removed += Number((0, search_cache_1.removeMailSearchCacheFile)(input.agentId, inspected.fileName, input.cacheOptions));
107
+ continue;
108
+ }
109
+ canonicalDocuments.set(document.messageId, document);
110
+ }
111
+ }
112
+ else {
113
+ for (const document of (0, search_cache_1.searchMailSearchCache)({
114
+ agentId: input.agentId,
115
+ placement: input.placement,
116
+ compartmentKind: input.scope,
117
+ source: input.source,
118
+ }, input.cacheOptions)) {
119
+ canonicalDocuments.set(document.messageId, document);
120
+ }
121
+ }
122
+ let fetched = 0;
123
+ let alreadyCached = 0;
124
+ let skipped = 0;
125
+ const failures = [];
126
+ for (const record of records) {
127
+ const cached = canonicalDocuments.get(record.id);
128
+ if (cached && input.mode === "full-convergence" && cached.decryptionKeyId && !input.privateKeys[cached.decryptionKeyId]) {
129
+ removed += removeCanonicalIfPresent(input.agentId, record.id, input.cacheOptions);
130
+ skipped += 1;
131
+ continue;
132
+ }
133
+ if (cached && mailSearchCacheDocumentMatchesRecord(cached, record, input.mode === "full-convergence")) {
134
+ alreadyCached += 1;
135
+ continue;
136
+ }
137
+ try {
138
+ const message = await fetchIndexedMessage(input.store, record.id);
139
+ if (!message)
140
+ throw new Error("indexed message was not retrievable");
141
+ fetched += 1;
142
+ if (!messageMatchesRecord(message, record)) {
143
+ throw new Error(`indexed message metadata did not match authority for ${record.id}`);
144
+ }
145
+ const decrypted = (0, core_1.readDecryptedMailMessage)(message, input.privateKeys);
146
+ (0, search_cache_1.upsertMailSearchCacheDocument)(message, decrypted.private, input.cacheOptions, {
147
+ ...(message.bodyForm === "encrypted" ? { decryptionKeyId: message.privateEnvelope.keyId } : {}),
148
+ });
149
+ }
150
+ catch (error) {
151
+ if (input.mode === "full-convergence" || missingPrivateKeyId(error)) {
152
+ removed += removeCanonicalIfPresent(input.agentId, record.id, input.cacheOptions);
153
+ skipped += 1;
154
+ }
155
+ else {
156
+ failures.push({ id: record.id, error: error instanceof Error ? error.message : String(error) });
157
+ }
158
+ }
159
+ }
160
+ if (failures.length > 0) {
161
+ const sample = failures.slice(0, 3).map((entry) => `${entry.id}: ${entry.error}`).join("; ");
162
+ throw new Error(`mail search index refresh incomplete; ${failures.length} fetch failed. first failure(s): ${sample}`);
163
+ }
164
+ const cachedIds = new Set((0, search_cache_1.searchMailSearchCache)({
165
+ agentId: input.agentId,
166
+ placement: input.placement,
167
+ compartmentKind: input.scope,
168
+ source: input.source,
169
+ }, input.cacheOptions).filter((document) => recordsById.has(document.messageId)).map((document) => document.messageId));
170
+ const snapshot = authority?.snapshot ?? (0, blob_store_1.canonicalMailIndexRecordSnapshot)(records);
171
+ const coverage = (0, search_cache_1.writeMailSearchCoverageRecord)({
172
+ schemaVersion: 1,
173
+ agentId: input.agentId,
174
+ storeKind: input.storeKind,
175
+ ...(input.placement ? { placement: input.placement } : {}),
176
+ ...(input.scope ? { compartmentKind: input.scope } : {}),
177
+ ...(input.source ? { source: input.source } : {}),
178
+ indexedAt: new Date().toISOString(),
179
+ visibleMessageCount: records.length,
180
+ cachedMessageCount: cachedIds.size,
181
+ decryptableMessageCount: cachedIds.size,
182
+ skippedMessageCount: skipped,
183
+ messageIndexFingerprint: snapshot.messageIndexFingerprint,
184
+ textProjectionVersion: search_cache_1.MAIL_SEARCH_TEXT_PROJECTION_VERSION,
185
+ ...(snapshot.oldestReceivedAt ? { oldestReceivedAt: snapshot.oldestReceivedAt } : {}),
186
+ ...(snapshot.newestReceivedAt ? { newestReceivedAt: snapshot.newestReceivedAt } : {}),
187
+ }, input.cacheOptions);
188
+ (0, runtime_1.emitNervesEvent)({
189
+ component: "senses",
190
+ event: "senses.mail_search_cache_synced",
191
+ message: "hosted mail search cache synchronized",
192
+ meta: {
193
+ agentId: input.agentId,
194
+ mode: input.mode,
195
+ visible: records.length,
196
+ fetched,
197
+ alreadyCached,
198
+ removed,
199
+ skipped,
200
+ },
201
+ });
202
+ return { coverage, fetched, alreadyCached, removed, skipped };
203
+ }
204
+ async function syncHostedMailSearchCache(input) {
205
+ const traceId = (0, node_crypto_1.randomUUID)();
206
+ (0, runtime_1.emitNervesEvent)({
207
+ component: "senses",
208
+ event: "senses.mail_search_cache_sync_start",
209
+ trace_id: traceId,
210
+ message: "synchronizing hosted mail search cache",
211
+ meta: { agentId: input.agentId, mode: input.mode, storeKind: input.storeKind },
212
+ });
213
+ try {
214
+ const result = await performHostedMailSearchCacheSync(input);
215
+ (0, runtime_1.emitNervesEvent)({
216
+ component: "senses",
217
+ event: "senses.mail_search_cache_sync_end",
218
+ trace_id: traceId,
219
+ message: "hosted mail search cache synchronization completed",
220
+ meta: {
221
+ agentId: input.agentId,
222
+ mode: input.mode,
223
+ storeKind: input.storeKind,
224
+ visible: result.coverage.visibleMessageCount,
225
+ fetched: result.fetched,
226
+ alreadyCached: result.alreadyCached,
227
+ removed: result.removed,
228
+ skipped: result.skipped,
229
+ },
230
+ });
231
+ return result;
232
+ }
233
+ catch (error) {
234
+ (0, runtime_1.emitNervesEvent)({
235
+ component: "senses",
236
+ event: "senses.mail_search_cache_sync_error",
237
+ trace_id: traceId,
238
+ level: "error",
239
+ message: "hosted mail search cache synchronization failed",
240
+ meta: {
241
+ agentId: input.agentId,
242
+ mode: input.mode,
243
+ storeKind: input.storeKind,
244
+ error: String(error),
245
+ },
246
+ });
247
+ throw error;
248
+ }
249
+ }
@@ -0,0 +1,393 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.splitMboxMessages = splitMboxMessages;
37
+ exports.importMboxToStore = importMboxToStore;
38
+ exports.importMboxFileToStore = importMboxFileToStore;
39
+ exports.cacheMatchingMailSearchDocumentsFromMboxFile = cacheMatchingMailSearchDocumentsFromMboxFile;
40
+ const fs = __importStar(require("node:fs"));
41
+ const runtime_1 = require("../nerves/runtime");
42
+ const core_1 = require("./core");
43
+ const search_cache_1 = require("./search-cache");
44
+ const search_relevance_1 = require("./search-relevance");
45
+ function splitMboxMessages(rawMbox) {
46
+ const text = rawMbox.toString("utf-8");
47
+ const separators = [...text.matchAll(/^From [^\r\n]*(?:\r?\n)/gm)];
48
+ if (separators.length === 0) {
49
+ const trimmed = text.trim();
50
+ return trimmed ? [Buffer.from(text, "utf-8")] : [];
51
+ }
52
+ const messages = separators
53
+ .map((match, index) => {
54
+ const start = match.index + match[0].length;
55
+ const end = index + 1 < separators.length ? separators[index + 1].index : text.length;
56
+ return text.slice(start, end).replace(/\r?\n$/, "");
57
+ })
58
+ .filter((message) => message.trim().length > 0)
59
+ .map((message) => Buffer.from(message, "utf-8"));
60
+ (0, runtime_1.emitNervesEvent)({
61
+ component: "senses",
62
+ event: "senses.mail_mbox_split",
63
+ message: "mbox payload split into messages",
64
+ meta: { messages: messages.length },
65
+ });
66
+ return messages;
67
+ }
68
+ function trimTrailingLineEnding(message) {
69
+ if (message.length >= 2 && message[message.length - 2] === 0x0d && message[message.length - 1] === 0x0a) {
70
+ return message.subarray(0, -2);
71
+ }
72
+ if (message.length >= 1 && message[message.length - 1] === 0x0a) {
73
+ return message.subarray(0, -1);
74
+ }
75
+ return message;
76
+ }
77
+ function isSeparatorLine(line) {
78
+ return line.length >= 5 &&
79
+ line[0] === 0x46 &&
80
+ line[1] === 0x72 &&
81
+ line[2] === 0x6f &&
82
+ line[3] === 0x6d &&
83
+ line[4] === 0x20;
84
+ }
85
+ async function* streamMboxMessagesFromFile(filePath) {
86
+ const stream = fs.createReadStream(filePath);
87
+ let pending = Buffer.alloc(0);
88
+ let currentParts = [];
89
+ const flushCurrent = () => {
90
+ if (currentParts.length === 0)
91
+ return null;
92
+ const message = trimTrailingLineEnding(Buffer.concat(currentParts));
93
+ currentParts = [];
94
+ return message;
95
+ };
96
+ for await (const chunk of stream) {
97
+ pending = pending.length > 0 ? Buffer.concat([pending, chunk]) : Buffer.from(chunk);
98
+ let newlineIndex = pending.indexOf(0x0a);
99
+ while (newlineIndex >= 0) {
100
+ const line = pending.subarray(0, newlineIndex + 1);
101
+ pending = pending.subarray(newlineIndex + 1);
102
+ if (isSeparatorLine(line)) {
103
+ const message = flushCurrent();
104
+ if (message && message.length > 0)
105
+ yield message;
106
+ }
107
+ else {
108
+ currentParts.push(Buffer.from(line));
109
+ }
110
+ newlineIndex = pending.indexOf(0x0a);
111
+ }
112
+ }
113
+ if (pending.length > 0) {
114
+ if (isSeparatorLine(pending)) {
115
+ const message = flushCurrent();
116
+ if (message && message.length > 0)
117
+ yield message;
118
+ }
119
+ else {
120
+ currentParts.push(Buffer.from(pending));
121
+ }
122
+ }
123
+ const finalMessage = flushCurrent();
124
+ if (finalMessage && finalMessage.length > 0)
125
+ yield finalMessage;
126
+ }
127
+ function findSourceGrant(input) {
128
+ const ownerEmail = input.ownerEmail ? (0, core_1.normalizeMailAddress)(input.ownerEmail) : undefined;
129
+ const source = input.source?.trim().toLowerCase();
130
+ const grants = input.registry.sourceGrants.filter((grant) => {
131
+ if (!grant.enabled || grant.agentId !== input.agentId)
132
+ return false;
133
+ if (ownerEmail && (0, core_1.normalizeMailAddress)(grant.ownerEmail) !== ownerEmail)
134
+ return false;
135
+ if (source && grant.source.toLowerCase() !== source)
136
+ return false;
137
+ return true;
138
+ });
139
+ if (grants.length === 0) {
140
+ throw new Error(`No enabled Mailroom source grant found for ${input.agentId}${ownerEmail ? ` owner ${ownerEmail}` : ""}${source ? ` source ${source}` : ""}`);
141
+ }
142
+ if (grants.length > 1 && !ownerEmail && !source) {
143
+ throw new Error(`Multiple source grants found for ${input.agentId}; pass --owner-email or --source to choose one`);
144
+ }
145
+ return grants[0];
146
+ }
147
+ function parseMboxMessage(rawMessage, grant) {
148
+ const mailFrom = extractHeaderAddress(rawMessage, "from");
149
+ const messageDate = extractHeaderDate(rawMessage, "date");
150
+ return {
151
+ rawMessage,
152
+ envelope: {
153
+ mailFrom: mailFrom ? (0, core_1.normalizeMailAddress)(mailFrom) : "",
154
+ rcptTo: [(0, core_1.normalizeMailAddress)(grant.aliasAddress)],
155
+ remoteAddress: "mbox-import",
156
+ },
157
+ ...(messageDate ? { messageDate } : {}),
158
+ };
159
+ }
160
+ function latestMessageDate(messages) {
161
+ const timestamps = messages
162
+ .map((message) => message.messageDate?.getTime())
163
+ .filter((timestamp) => typeof timestamp === "number" && Number.isFinite(timestamp));
164
+ if (timestamps.length === 0)
165
+ return null;
166
+ return new Date(Math.max(...timestamps)).toISOString();
167
+ }
168
+ function readHeaderBlock(rawMessage) {
169
+ const crlfBoundary = rawMessage.indexOf("\r\n\r\n");
170
+ if (crlfBoundary >= 0) {
171
+ return rawMessage.subarray(0, crlfBoundary).toString("utf-8");
172
+ }
173
+ const lfBoundary = rawMessage.indexOf("\n\n");
174
+ if (lfBoundary >= 0) {
175
+ return rawMessage.subarray(0, lfBoundary).toString("utf-8");
176
+ }
177
+ return rawMessage.toString("utf-8");
178
+ }
179
+ function extractHeaderValue(rawMessage, headerName) {
180
+ const target = `${headerName.toLowerCase()}:`;
181
+ let currentHeader = "";
182
+ const unfoldedHeaders = [];
183
+ for (const line of readHeaderBlock(rawMessage).split(/\r?\n/)) {
184
+ if (/^[ \t]/.test(line) && currentHeader) {
185
+ currentHeader += ` ${line.trim()}`;
186
+ continue;
187
+ }
188
+ if (currentHeader)
189
+ unfoldedHeaders.push(currentHeader);
190
+ currentHeader = line;
191
+ }
192
+ if (currentHeader)
193
+ unfoldedHeaders.push(currentHeader);
194
+ const match = unfoldedHeaders.find((line) => line.toLowerCase().startsWith(target));
195
+ return match ? match.slice(target.length).trim() : "";
196
+ }
197
+ function extractHeaderAddress(rawMessage, headerName) {
198
+ const value = extractHeaderValue(rawMessage, headerName);
199
+ if (!value)
200
+ return "";
201
+ const bracketed = value.match(/<([^>]+)>/);
202
+ if (bracketed?.[1])
203
+ return bracketed[1];
204
+ const plain = value.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i);
205
+ return plain?.[0] ?? "";
206
+ }
207
+ function extractHeaderDate(rawMessage, headerName) {
208
+ const value = extractHeaderValue(rawMessage, headerName);
209
+ if (!value)
210
+ return undefined;
211
+ const parsed = new Date(value);
212
+ return Number.isFinite(parsed.getTime()) ? parsed : undefined;
213
+ }
214
+ function normalizeSearchTerms(queryTerms) {
215
+ return queryTerms
216
+ .map((term) => term.trim().toLowerCase())
217
+ .filter((term) => term.length > 0);
218
+ }
219
+ function historicalImportClassification(resolvedPlacement, sourceGrant) {
220
+ return {
221
+ placement: resolvedPlacement,
222
+ candidate: false,
223
+ trustReason: `delegated source grant ${sourceGrant.source} historical mbox import`,
224
+ };
225
+ }
226
+ async function importParsedMessagesToStore(input) {
227
+ let imported = 0;
228
+ let duplicates = 0;
229
+ const messages = [];
230
+ let scanned = 0;
231
+ const importedAt = (input.importedAt ?? new Date()).toISOString();
232
+ const sourceFreshThrough = input.sourceFreshThrough ?? null;
233
+ const maxConcurrency = Math.max(1, input.maxConcurrency ?? 1);
234
+ const inFlight = new Set();
235
+ const enqueue = (parsedMessage) => {
236
+ const task = (async () => {
237
+ const result = await input.store.putRawMessage({
238
+ resolved: input.resolved,
239
+ envelope: parsedMessage.envelope,
240
+ rawMime: parsedMessage.rawMessage,
241
+ receivedAt: parsedMessage.messageDate ?? input.importedAt,
242
+ ingest: {
243
+ schemaVersion: 1,
244
+ kind: "mbox-import",
245
+ importedAt,
246
+ sourceFreshThrough,
247
+ attentionSuppressed: true,
248
+ },
249
+ classification: historicalImportClassification(input.resolved.defaultPlacement, input.sourceGrant),
250
+ });
251
+ if (input.collectMessages !== false)
252
+ messages.push(result.message);
253
+ if (result.created)
254
+ imported += 1;
255
+ else
256
+ duplicates += 1;
257
+ input.onProgress?.({ scanned, imported, duplicates });
258
+ })().finally(() => {
259
+ inFlight.delete(task);
260
+ });
261
+ inFlight.add(task);
262
+ return task;
263
+ };
264
+ for await (const parsedMessage of input.parsedMessages) {
265
+ scanned += 1;
266
+ input.onProgress?.({ scanned, imported, duplicates });
267
+ enqueue(parsedMessage);
268
+ if (inFlight.size >= maxConcurrency) {
269
+ await Promise.race(inFlight);
270
+ }
271
+ }
272
+ await Promise.all(inFlight);
273
+ (0, runtime_1.emitNervesEvent)({
274
+ component: "senses",
275
+ event: "senses.mail_mbox_imported",
276
+ message: "mbox mail imported",
277
+ meta: { agentId: input.sourceGrant.agentId.toLowerCase(), scanned, imported, duplicates, grantId: input.sourceGrant.grantId },
278
+ });
279
+ return {
280
+ agentId: input.sourceGrant.agentId.toLowerCase(),
281
+ sourceGrant: input.sourceGrant,
282
+ scanned,
283
+ imported,
284
+ duplicates,
285
+ sourceFreshThrough,
286
+ messages,
287
+ };
288
+ }
289
+ async function scanMboxFileFreshness(filePath, sourceGrant) {
290
+ let latestTimestamp = Number.NEGATIVE_INFINITY;
291
+ for await (const rawMessage of streamMboxMessagesFromFile(filePath)) {
292
+ const parsedMessage = parseMboxMessage(rawMessage, sourceGrant);
293
+ if (parsedMessage.messageDate) {
294
+ latestTimestamp = Math.max(latestTimestamp, parsedMessage.messageDate.getTime());
295
+ }
296
+ }
297
+ return Number.isFinite(latestTimestamp) ? new Date(latestTimestamp).toISOString() : null;
298
+ }
299
+ function resolveImportTarget(input) {
300
+ const agentId = input.agentId.toLowerCase();
301
+ const sourceGrant = findSourceGrant({
302
+ registry: input.registry,
303
+ agentId,
304
+ ownerEmail: input.ownerEmail,
305
+ source: input.source,
306
+ });
307
+ const resolved = (0, core_1.resolveMailAddress)(input.registry, sourceGrant.aliasAddress);
308
+ /* v8 ignore start -- findSourceGrant and resolveMailAddress share the same registry; this is a corruption guard. @preserve */
309
+ if (!resolved) {
310
+ throw new Error(`Source grant alias ${sourceGrant.aliasAddress} is not resolvable`);
311
+ }
312
+ /* v8 ignore stop */
313
+ return { agentId, sourceGrant, resolved };
314
+ }
315
+ async function importMboxToStore(input) {
316
+ const target = resolveImportTarget(input);
317
+ const rawMessages = splitMboxMessages(input.rawMbox);
318
+ const parsedMessages = rawMessages.map((rawMessage) => parseMboxMessage(rawMessage, target.sourceGrant));
319
+ const sourceFreshThrough = latestMessageDate(parsedMessages);
320
+ return importParsedMessagesToStore({
321
+ sourceGrant: target.sourceGrant,
322
+ resolved: target.resolved,
323
+ store: input.store,
324
+ parsedMessages,
325
+ importedAt: input.importedAt,
326
+ collectMessages: true,
327
+ sourceFreshThrough,
328
+ });
329
+ }
330
+ async function importMboxFileToStore(input) {
331
+ const target = resolveImportTarget(input);
332
+ const sourceFreshThrough = await scanMboxFileFreshness(input.filePath, target.sourceGrant);
333
+ async function* parsedMessages() {
334
+ for await (const rawMessage of streamMboxMessagesFromFile(input.filePath)) {
335
+ yield parseMboxMessage(rawMessage, target.sourceGrant);
336
+ }
337
+ }
338
+ return importParsedMessagesToStore({
339
+ sourceGrant: target.sourceGrant,
340
+ resolved: target.resolved,
341
+ store: input.store,
342
+ parsedMessages: parsedMessages(),
343
+ importedAt: input.importedAt,
344
+ collectMessages: false,
345
+ sourceFreshThrough,
346
+ maxConcurrency: 8,
347
+ onProgress: input.onProgress,
348
+ });
349
+ }
350
+ async function cacheMatchingMailSearchDocumentsFromMboxFile(input) {
351
+ const target = resolveImportTarget(input);
352
+ const queryTerms = normalizeSearchTerms(input.queryTerms);
353
+ if (queryTerms.length === 0 || input.limit <= 0)
354
+ return [];
355
+ const matches = [];
356
+ for await (const rawMessage of streamMboxMessagesFromFile(input.filePath)) {
357
+ const parsedMessage = parseMboxMessage(rawMessage, target.sourceGrant);
358
+ const { privateEnvelope, metadata } = await (0, core_1.buildStoredMailMessageMetadata)({
359
+ resolved: target.resolved,
360
+ envelope: parsedMessage.envelope,
361
+ rawMime: parsedMessage.rawMessage,
362
+ receivedAt: parsedMessage.messageDate,
363
+ ingest: {
364
+ schemaVersion: 1,
365
+ kind: "mbox-import",
366
+ attentionSuppressed: true,
367
+ },
368
+ classification: historicalImportClassification(target.resolved.defaultPlacement, target.sourceGrant),
369
+ });
370
+ // Projection-only: we need a `StoredMailMessage` shape for buildMailSearchCacheDocument
371
+ // but never persist this view; the live import (via store.putRawMessage) is
372
+ // what writes the durable record.
373
+ const { rawObjectStem, ...rest } = metadata;
374
+ const message = {
375
+ ...rest,
376
+ rawObject: `${rawObjectStem}.eml`,
377
+ bodyForm: "plaintext",
378
+ private: privateEnvelope,
379
+ };
380
+ const document = (0, search_cache_1.buildMailSearchCacheDocument)(message, privateEnvelope);
381
+ if (!queryTerms.some((term) => document.searchText.includes(term)))
382
+ continue;
383
+ (0, search_cache_1.upsertMailSearchCacheDocument)(message, privateEnvelope);
384
+ matches.push(document);
385
+ matches.sort((left, right) => (0, search_relevance_1.compareByRelevanceThenRecency)({ document: left, relevance: (0, search_relevance_1.scoreMailSearchDocument)(left, queryTerms) }, { document: right, relevance: (0, search_relevance_1.scoreMailSearchDocument)(right, queryTerms) }));
386
+ if (matches.length > input.limit)
387
+ matches.length = input.limit;
388
+ }
389
+ return matches
390
+ .map((document) => ({ document, relevance: (0, search_relevance_1.scoreMailSearchDocument)(document, queryTerms) }))
391
+ .sort(search_relevance_1.compareByRelevanceThenRecency)
392
+ .map((entry) => entry.document);
393
+ }