@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
@@ -0,0 +1,197 @@
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.parseMailroomConfig = parseMailroomConfig;
37
+ exports.readMailroomRegistry = readMailroomRegistry;
38
+ exports.resolveMailroomReader = resolveMailroomReader;
39
+ const fs = __importStar(require("node:fs"));
40
+ const path = __importStar(require("node:path"));
41
+ const storage_blob_1 = require("@azure/storage-blob");
42
+ const identity_1 = require("@azure/identity");
43
+ const runtime_1 = require("../nerves/runtime");
44
+ const identity_2 = require("../heart/identity");
45
+ const runtime_credentials_1 = require("../heart/runtime-credentials");
46
+ const blob_store_1 = require("./blob-store");
47
+ const file_store_1 = require("./file-store");
48
+ function isRecord(value) {
49
+ return !!value && typeof value === "object" && !Array.isArray(value);
50
+ }
51
+ function textField(value, key) {
52
+ const raw = value[key];
53
+ return typeof raw === "string" && raw.trim() ? raw.trim() : undefined;
54
+ }
55
+ function numberField(value, key) {
56
+ const raw = value[key];
57
+ return typeof raw === "number" && Number.isFinite(raw) ? raw : undefined;
58
+ }
59
+ function parseMailroomConfig(value) {
60
+ if (!isRecord(value))
61
+ return null;
62
+ const mailboxAddress = textField(value, "mailboxAddress");
63
+ if (!mailboxAddress)
64
+ return null;
65
+ if (!isRecord(value.privateKeys))
66
+ return null;
67
+ const privateKeys = Object.fromEntries(Object.entries(value.privateKeys).filter((entry) => {
68
+ return typeof entry[0] === "string" && typeof entry[1] === "string" && entry[1].trim().length > 0;
69
+ }));
70
+ if (Object.keys(privateKeys).length === 0)
71
+ return null;
72
+ const registryPath = textField(value, "registryPath");
73
+ const storePath = textField(value, "storePath");
74
+ const azureAccountUrl = textField(value, "azureAccountUrl");
75
+ const azureContainer = textField(value, "azureContainer");
76
+ const registryAzureAccountUrl = textField(value, "registryAzureAccountUrl");
77
+ const registryContainer = textField(value, "registryContainer");
78
+ const registryBlob = textField(value, "registryBlob");
79
+ const azureManagedIdentityClientId = textField(value, "azureManagedIdentityClientId");
80
+ const smtpPort = numberField(value, "smtpPort");
81
+ const httpPort = numberField(value, "httpPort");
82
+ const host = textField(value, "host");
83
+ const attentionIntervalMs = numberField(value, "attentionIntervalMs");
84
+ const outbound = isRecord(value.outbound) ? { ...value.outbound } : undefined;
85
+ const autonomousSendPolicy = isRecord(value.autonomousSendPolicy)
86
+ ? { ...value.autonomousSendPolicy }
87
+ : undefined;
88
+ return {
89
+ mailboxAddress,
90
+ ...(registryPath ? { registryPath } : {}),
91
+ ...(storePath ? { storePath } : {}),
92
+ ...(azureAccountUrl ? { azureAccountUrl } : {}),
93
+ ...(azureContainer ? { azureContainer } : {}),
94
+ ...(registryAzureAccountUrl ? { registryAzureAccountUrl } : {}),
95
+ ...(registryContainer ? { registryContainer } : {}),
96
+ ...(registryBlob ? { registryBlob } : {}),
97
+ ...(azureManagedIdentityClientId ? { azureManagedIdentityClientId } : {}),
98
+ ...(smtpPort !== undefined ? { smtpPort } : {}),
99
+ ...(httpPort !== undefined ? { httpPort } : {}),
100
+ ...(host ? { host } : {}),
101
+ ...(attentionIntervalMs !== undefined ? { attentionIntervalMs } : {}),
102
+ ...(outbound ? { outbound } : {}),
103
+ ...(autonomousSendPolicy ? { autonomousSendPolicy } : {}),
104
+ privateKeys,
105
+ };
106
+ }
107
+ function createBlobCredential(config) {
108
+ return config.azureManagedIdentityClientId
109
+ ? new identity_1.DefaultAzureCredential({ managedIdentityClientId: config.azureManagedIdentityClientId })
110
+ : new identity_1.DefaultAzureCredential();
111
+ }
112
+ function createMailroomStore(config, agentName) {
113
+ if (config.azureAccountUrl) {
114
+ const containerName = config.azureContainer ?? "mailroom";
115
+ return {
116
+ store: new blob_store_1.AzureBlobMailroomStore({
117
+ serviceClient: new storage_blob_1.BlobServiceClient(config.azureAccountUrl, createBlobCredential(config)),
118
+ containerName,
119
+ }),
120
+ storeKind: "azure-blob",
121
+ storeLabel: `${config.azureAccountUrl}/${containerName}`,
122
+ };
123
+ }
124
+ const storePath = config.storePath ?? path.join((0, identity_2.getAgentRoot)(agentName), "state", "mailroom");
125
+ return {
126
+ store: new file_store_1.FileMailroomStore({ rootDir: storePath }),
127
+ storeKind: "file",
128
+ storeLabel: storePath,
129
+ };
130
+ }
131
+ async function readMailroomRegistry(config) {
132
+ if (config.registryPath) {
133
+ return JSON.parse(fs.readFileSync(config.registryPath, "utf-8"));
134
+ }
135
+ const registryAzureAccountUrl = config.registryAzureAccountUrl ?? config.azureAccountUrl;
136
+ const registryContainer = config.registryContainer ?? config.azureContainer ?? "mailroom";
137
+ const registryBlob = config.registryBlob;
138
+ if (!registryAzureAccountUrl || !registryBlob) {
139
+ throw new Error("mailroom config is missing registryPath or hosted registry coordinates");
140
+ }
141
+ const serviceClient = new storage_blob_1.BlobServiceClient(registryAzureAccountUrl, createBlobCredential(config));
142
+ const blobClient = serviceClient.getContainerClient(registryContainer).getBlockBlobClient(registryBlob);
143
+ if (!await blobClient.exists()) {
144
+ throw new Error(`mailroom registry blob not found: ${registryAzureAccountUrl}/${registryContainer}/${registryBlob}`);
145
+ }
146
+ return JSON.parse((await blobClient.downloadToBuffer()).toString("utf-8"));
147
+ }
148
+ function resolveMailroomReader(agentName = (0, identity_2.getAgentName)()) {
149
+ const runtime = (0, runtime_credentials_1.readRuntimeCredentialConfig)(agentName);
150
+ if (!runtime.ok) {
151
+ const result = {
152
+ ok: false,
153
+ agentName,
154
+ reason: "auth-required",
155
+ error: `AUTH_REQUIRED:mailroom -- Mail is not available because ${runtime.itemPath} is ${runtime.reason}. Agent-runnable repair after vault unlock: 'ouro connect mail --agent ${agentName}'.`,
156
+ };
157
+ (0, runtime_1.emitNervesEvent)({
158
+ component: "senses",
159
+ event: "senses.mail_reader_resolved",
160
+ message: "mailroom reader resolved",
161
+ meta: { agentName, status: result.reason },
162
+ });
163
+ return result;
164
+ }
165
+ const config = parseMailroomConfig(runtime.config.mailroom);
166
+ if (!config) {
167
+ const result = {
168
+ ok: false,
169
+ agentName,
170
+ reason: "misconfigured",
171
+ error: `AUTH_REQUIRED:mailroom -- Missing mailroom mailbox/private key config in vault runtime/config for ${agentName}.`,
172
+ };
173
+ (0, runtime_1.emitNervesEvent)({
174
+ component: "senses",
175
+ event: "senses.mail_reader_resolved",
176
+ message: "mailroom reader resolved",
177
+ meta: { agentName, status: result.reason },
178
+ });
179
+ return result;
180
+ }
181
+ const store = createMailroomStore(config, agentName);
182
+ const result = {
183
+ ok: true,
184
+ agentName,
185
+ config,
186
+ store: store.store,
187
+ storeKind: store.storeKind,
188
+ storeLabel: store.storeLabel,
189
+ };
190
+ (0, runtime_1.emitNervesEvent)({
191
+ component: "senses",
192
+ event: "senses.mail_reader_resolved",
193
+ message: "mailroom reader resolved",
194
+ meta: { agentName, status: "ready", mailboxAddress: config.mailboxAddress, storeKind: store.storeKind },
195
+ });
196
+ return result;
197
+ }
@@ -0,0 +1,176 @@
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.createMailroomSmtpServer = createMailroomSmtpServer;
37
+ exports.createMailroomHealthServer = createMailroomHealthServer;
38
+ exports.startMailroomIngress = startMailroomIngress;
39
+ const http = __importStar(require("node:http"));
40
+ const smtp_server_1 = require("smtp-server");
41
+ const runtime_1 = require("../nerves/runtime");
42
+ const core_1 = require("./core");
43
+ const file_store_1 = require("./file-store");
44
+ function collectStream(stream, maxBytes) {
45
+ return new Promise((resolve, reject) => {
46
+ const chunks = [];
47
+ let total = 0;
48
+ stream.on("data", (chunk) => {
49
+ total += chunk.byteLength;
50
+ if (total > maxBytes) {
51
+ reject(new Error(`message exceeds max size ${maxBytes}`));
52
+ stream.destroy();
53
+ return;
54
+ }
55
+ chunks.push(chunk);
56
+ });
57
+ stream.on("error", reject);
58
+ stream.on("end", () => resolve(Buffer.concat(chunks)));
59
+ });
60
+ }
61
+ function sessionRecipients(session) {
62
+ /* v8 ignore next -- smtp-server supplies rcptTo during DATA; fallback is a defensive harness edge. @preserve */
63
+ return (session.envelope.rcptTo ?? []).map((address) => (0, core_1.normalizeMailAddress)(address.address));
64
+ }
65
+ function createMailroomSmtpServer(options) {
66
+ const maxMessageBytes = options.maxMessageBytes ?? 25 * 1024 * 1024;
67
+ const server = new smtp_server_1.SMTPServer({
68
+ disabledCommands: ["AUTH", "STARTTLS"],
69
+ logger: false,
70
+ onRcptTo(address, _session, callback) {
71
+ const normalized = (0, core_1.normalizeMailAddress)(address.address);
72
+ const resolved = (0, core_1.resolveMailAddress)(options.registry, normalized);
73
+ if (!resolved) {
74
+ (0, runtime_1.emitNervesEvent)({
75
+ component: "senses",
76
+ event: "senses.mail_smtp_recipient_rejected",
77
+ message: "smtp recipient rejected",
78
+ meta: { address: normalized },
79
+ });
80
+ const error = new Error(`unknown recipient ${normalized}`);
81
+ error.responseCode = 550;
82
+ callback(error);
83
+ return;
84
+ }
85
+ (0, runtime_1.emitNervesEvent)({
86
+ component: "senses",
87
+ event: "senses.mail_smtp_recipient_accepted",
88
+ message: "smtp recipient accepted",
89
+ meta: { address: normalized, agentId: resolved.agentId },
90
+ });
91
+ callback();
92
+ },
93
+ async onData(stream, session, callback) {
94
+ try {
95
+ const raw = await collectStream(stream, maxMessageBytes);
96
+ const mailFrom = session.envelope.mailFrom;
97
+ /* v8 ignore next -- smtp-server exposes normal and null senders as address objects; false/undefined are defensive direct-call states. @preserve */
98
+ const rawMailFrom = mailFrom === false ? "" : mailFrom?.address ?? "";
99
+ const envelope = {
100
+ mailFrom: rawMailFrom ? (0, core_1.normalizeMailAddress)(rawMailFrom) : "",
101
+ rcptTo: sessionRecipients(session),
102
+ /* v8 ignore next -- smtp-server network sessions carry remoteAddress; fallback is a defensive direct-call edge. @preserve */
103
+ ...(session.remoteAddress ? { remoteAddress: session.remoteAddress } : {}),
104
+ };
105
+ const result = await (0, file_store_1.ingestRawMailToStore)({
106
+ registry: options.registry,
107
+ store: options.store,
108
+ envelope,
109
+ rawMime: raw,
110
+ });
111
+ (0, runtime_1.emitNervesEvent)({
112
+ component: "senses",
113
+ event: "senses.mail_smtp_data_stored",
114
+ message: "smtp data stored",
115
+ meta: { accepted: result.accepted.length, rejected: result.rejectedRecipients.length },
116
+ });
117
+ callback();
118
+ }
119
+ catch (error) {
120
+ (0, runtime_1.emitNervesEvent)({
121
+ level: "error",
122
+ component: "senses",
123
+ event: "senses.mail_smtp_data_error",
124
+ message: "smtp data handling failed",
125
+ meta: { error: error instanceof Error ? error.message : String(error) },
126
+ });
127
+ callback(error instanceof Error ? error : new Error(String(error)));
128
+ }
129
+ },
130
+ });
131
+ (0, runtime_1.emitNervesEvent)({
132
+ component: "senses",
133
+ event: "senses.mail_smtp_server_created",
134
+ message: "mailroom smtp server created",
135
+ meta: { maxMessageBytes },
136
+ });
137
+ return server;
138
+ }
139
+ function createMailroomHealthServer(registry) {
140
+ const server = http.createServer((_request, response) => {
141
+ const body = JSON.stringify({
142
+ ok: true,
143
+ service: "ouro-mailroom",
144
+ domain: registry.domain,
145
+ mailboxes: registry.mailboxes.length,
146
+ sourceGrants: registry.sourceGrants.length,
147
+ });
148
+ response.writeHead(200, {
149
+ "content-type": "application/json",
150
+ "content-length": Buffer.byteLength(body),
151
+ });
152
+ response.end(body);
153
+ });
154
+ (0, runtime_1.emitNervesEvent)({
155
+ component: "senses",
156
+ event: "senses.mail_health_server_created",
157
+ message: "mailroom health server created",
158
+ meta: { domain: registry.domain },
159
+ });
160
+ return server;
161
+ }
162
+ function startMailroomIngress(options) {
163
+ const smtp = createMailroomSmtpServer(options);
164
+ const health = createMailroomHealthServer(options.registry);
165
+ /* v8 ignore next -- production/container entrypoints may omit host; unit tests bind loopback explicitly. @preserve */
166
+ const host = options.host ?? "0.0.0.0";
167
+ smtp.listen(options.smtpPort, host);
168
+ health.listen(options.httpPort, host);
169
+ (0, runtime_1.emitNervesEvent)({
170
+ component: "senses",
171
+ event: "senses.mail_ingress_started",
172
+ message: "mailroom ingress started",
173
+ meta: { smtpPort: options.smtpPort, httpPort: options.httpPort, host },
174
+ });
175
+ return { smtp, health };
176
+ }
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDelegatedMailSourceState = createDelegatedMailSourceState;
4
+ exports.markMboxBackfillComplete = markMboxBackfillComplete;
5
+ exports.markForwardingProbeResult = markForwardingProbeResult;
6
+ exports.renderDelegatedMailSourceNextStep = renderDelegatedMailSourceNextStep;
7
+ const runtime_1 = require("../nerves/runtime");
8
+ const core_1 = require("./core");
9
+ const HUMAN_REQUIRED = [
10
+ "browser_auth",
11
+ "mfa_or_captcha",
12
+ "export_download",
13
+ "forwarding_confirmation",
14
+ ];
15
+ function normalizedSource(source) {
16
+ const value = source.trim().toLowerCase();
17
+ return value || "hey";
18
+ }
19
+ function normalizedAgentId(agentId) {
20
+ return agentId.trim().toLowerCase();
21
+ }
22
+ function createDelegatedMailSourceState(input) {
23
+ const aliasAddress = (0, core_1.normalizeMailAddress)(input.aliasAddress);
24
+ const state = {
25
+ schemaVersion: 1,
26
+ agentId: normalizedAgentId(input.agentId),
27
+ ownerEmail: (0, core_1.normalizeMailAddress)(input.ownerEmail),
28
+ source: normalizedSource(input.source),
29
+ aliasAddress,
30
+ backfill: {
31
+ status: "not_started",
32
+ },
33
+ forwarding: {
34
+ status: "blocked_by_human",
35
+ targetAlias: aliasAddress,
36
+ browserAutomationOwner: "agent",
37
+ humanRequired: [...HUMAN_REQUIRED],
38
+ },
39
+ };
40
+ (0, runtime_1.emitNervesEvent)({
41
+ component: "senses",
42
+ event: "senses.mail_delegated_source_state_created",
43
+ message: "delegated mail source setup state created",
44
+ meta: {
45
+ agentId: state.agentId,
46
+ source: state.source,
47
+ forwardingStatus: state.forwarding.status,
48
+ backfillStatus: state.backfill.status,
49
+ },
50
+ });
51
+ return state;
52
+ }
53
+ function markMboxBackfillComplete(state, input) {
54
+ const nextState = {
55
+ ...state,
56
+ backfill: {
57
+ status: "ready",
58
+ scanned: input.scanned,
59
+ imported: input.imported,
60
+ duplicates: input.duplicates,
61
+ sourceFreshThrough: input.sourceFreshThrough,
62
+ completedAt: input.completedAt,
63
+ },
64
+ };
65
+ (0, runtime_1.emitNervesEvent)({
66
+ component: "senses",
67
+ event: "senses.mail_delegated_source_backfill_ready",
68
+ message: "delegated mail source archive backfill marked ready",
69
+ meta: {
70
+ agentId: nextState.agentId,
71
+ source: nextState.source,
72
+ scanned: input.scanned,
73
+ imported: input.imported,
74
+ duplicates: input.duplicates,
75
+ sourceFreshThroughKnown: input.sourceFreshThrough !== null,
76
+ },
77
+ });
78
+ return nextState;
79
+ }
80
+ function markForwardingProbeResult(state, input) {
81
+ const expectedRecipient = (0, core_1.normalizeMailAddress)(state.forwarding.targetAlias);
82
+ if (!input.observedRecipient) {
83
+ const nextState = {
84
+ ...state,
85
+ forwarding: {
86
+ ...state.forwarding,
87
+ status: "pending_propagation",
88
+ observedRecipient: null,
89
+ expectedRecipient,
90
+ recoveryAction: "Wait briefly, then have Slugger re-check the delegated source alias before asking the human to change HEY again.",
91
+ },
92
+ };
93
+ (0, runtime_1.emitNervesEvent)({
94
+ component: "senses",
95
+ event: "senses.mail_delegated_source_forwarding_probe",
96
+ message: "delegated mail source forwarding probe checked",
97
+ meta: {
98
+ agentId: nextState.agentId,
99
+ source: nextState.source,
100
+ status: nextState.forwarding.status,
101
+ observedRecipientPresent: false,
102
+ expectedRecipientDomain: expectedRecipient.split("@")[1],
103
+ messageIdPresent: Boolean(input.messageId),
104
+ },
105
+ });
106
+ return nextState;
107
+ }
108
+ const observedRecipient = (0, core_1.normalizeMailAddress)(input.observedRecipient);
109
+ if (observedRecipient !== expectedRecipient) {
110
+ const nextState = {
111
+ ...state,
112
+ forwarding: {
113
+ ...state.forwarding,
114
+ status: "failed_recoverable",
115
+ observedRecipient,
116
+ expectedRecipient,
117
+ ...(input.messageId ? { lastProbeMessageId: input.messageId } : {}),
118
+ recoveryAction: `HEY is forwarding to ${observedRecipient}. Slugger must correct the HEY forwarding target to ${expectedRecipient}; do not import or label that probe as delegated Ari HEY mail.`,
119
+ },
120
+ };
121
+ (0, runtime_1.emitNervesEvent)({
122
+ component: "senses",
123
+ event: "senses.mail_delegated_source_forwarding_probe",
124
+ message: "delegated mail source forwarding probe checked",
125
+ meta: {
126
+ agentId: nextState.agentId,
127
+ source: nextState.source,
128
+ status: nextState.forwarding.status,
129
+ observedRecipientPresent: true,
130
+ observedRecipientMatches: false,
131
+ expectedRecipientDomain: expectedRecipient.split("@")[1],
132
+ observedRecipientDomain: observedRecipient.split("@")[1],
133
+ messageIdPresent: Boolean(input.messageId),
134
+ },
135
+ });
136
+ return nextState;
137
+ }
138
+ const nextState = {
139
+ ...state,
140
+ forwarding: {
141
+ ...state.forwarding,
142
+ status: "ready",
143
+ observedRecipient,
144
+ expectedRecipient,
145
+ verifiedAt: input.checkedAt,
146
+ ...(input.messageId ? { lastProbeMessageId: input.messageId } : {}),
147
+ },
148
+ };
149
+ (0, runtime_1.emitNervesEvent)({
150
+ component: "senses",
151
+ event: "senses.mail_delegated_source_forwarding_probe",
152
+ message: "delegated mail source forwarding probe checked",
153
+ meta: {
154
+ agentId: nextState.agentId,
155
+ source: nextState.source,
156
+ status: nextState.forwarding.status,
157
+ observedRecipientPresent: true,
158
+ observedRecipientMatches: true,
159
+ expectedRecipientDomain: expectedRecipient.split("@")[1],
160
+ observedRecipientDomain: observedRecipient.split("@")[1],
161
+ messageIdPresent: Boolean(input.messageId),
162
+ },
163
+ });
164
+ return nextState;
165
+ }
166
+ function renderDelegatedMailSourceNextStep(state) {
167
+ if (state.forwarding.status === "ready") {
168
+ return `${state.source} forwarding is verified for ${state.aliasAddress}.`;
169
+ }
170
+ return [
171
+ `Slugger should continue ${state.source.toUpperCase()} setup with browser automation where it is safe.`,
172
+ "The human remains at the keyboard for login, MFA/CAPTCHA, export download, and final forwarding confirmation.",
173
+ `Forward ${state.ownerEmail}'s ${state.source} mailbox to ${state.aliasAddress}.`,
174
+ "Do not use the native agent mailbox as the forwarding target.",
175
+ ].join(" ");
176
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractTravelFactsFromMail = extractTravelFactsFromMail;
4
+ const runtime_1 = require("../nerves/runtime");
5
+ function firstMatch(text, pattern) {
6
+ const match = pattern.exec(text);
7
+ return match?.[1]?.trim() ?? null;
8
+ }
9
+ function flightFact(message) {
10
+ const text = `${message.private.subject}\n${message.private.text}`;
11
+ const flightNumber = firstMatch(text, /\bflight\s+([A-Z]{2}\s?\d{1,4})\b/i);
12
+ const routeMatch = /\b([A-Z]{3})\s*(?:->|to)\s*([A-Z]{3})\b/.exec(text);
13
+ const confirmationCode = firstMatch(text, /confirmation code:\s*([A-Z0-9-]+)/i);
14
+ const departure = firstMatch(text, /departure:\s*([^\n]+)/i);
15
+ if (!flightNumber && !routeMatch && !departure)
16
+ return null;
17
+ const fields = {};
18
+ if (flightNumber)
19
+ fields.flightNumber = flightNumber.toUpperCase().replace(/\s+/, " ");
20
+ if (routeMatch)
21
+ fields.route = `${routeMatch[1]} -> ${routeMatch[2]}`;
22
+ if (departure)
23
+ fields.departure = departure;
24
+ if (confirmationCode)
25
+ fields.confirmationCode = confirmationCode;
26
+ return {
27
+ kind: "flight",
28
+ messageId: message.id,
29
+ subject: message.private.subject,
30
+ source: message.source ?? null,
31
+ ownerEmail: message.ownerEmail ?? null,
32
+ summary: [
33
+ fields.flightNumber ? `flight ${fields.flightNumber}` : "flight",
34
+ fields.route ? fields.route : null,
35
+ fields.departure ? `departing ${fields.departure}` : null,
36
+ ].filter(Boolean).join(" "),
37
+ fields,
38
+ };
39
+ }
40
+ function lodgingFact(message) {
41
+ const text = `${message.private.subject}\n${message.private.text}`;
42
+ const hotel = firstMatch(text, /hotel:\s*([^\n]+)/i);
43
+ const checkIn = firstMatch(text, /check-?in:\s*([^\n]+)/i);
44
+ const checkOut = firstMatch(text, /check-?out:\s*([^\n]+)/i);
45
+ const confirmationCode = firstMatch(text, /confirmation code:\s*([A-Z0-9-]+)/i);
46
+ if (!hotel && !checkIn && !/hotel|lodging|booking/i.test(message.private.subject))
47
+ return null;
48
+ const fields = {};
49
+ if (hotel)
50
+ fields.hotel = hotel;
51
+ if (checkIn)
52
+ fields.checkIn = checkIn;
53
+ if (checkOut)
54
+ fields.checkOut = checkOut;
55
+ if (confirmationCode)
56
+ fields.confirmationCode = confirmationCode;
57
+ return {
58
+ kind: "lodging",
59
+ messageId: message.id,
60
+ subject: message.private.subject,
61
+ source: message.source ?? null,
62
+ ownerEmail: message.ownerEmail ?? null,
63
+ summary: [
64
+ hotel ?? "lodging",
65
+ checkIn ? `check-in ${checkIn}` : null,
66
+ checkOut ? `check-out ${checkOut}` : null,
67
+ ].filter(Boolean).join(" "),
68
+ fields,
69
+ };
70
+ }
71
+ function extractTravelFactsFromMail(messages) {
72
+ const facts = messages.flatMap((message) => {
73
+ const results = [];
74
+ const flight = flightFact(message);
75
+ if (flight)
76
+ results.push(flight);
77
+ const lodging = lodgingFact(message);
78
+ if (lodging)
79
+ results.push(lodging);
80
+ return results;
81
+ });
82
+ (0, runtime_1.emitNervesEvent)({
83
+ component: "senses",
84
+ event: "senses.mail_travel_facts_extracted",
85
+ message: "travel facts extracted from mail",
86
+ meta: { messages: messages.length, facts: facts.length },
87
+ });
88
+ return facts;
89
+ }
@@ -52,7 +52,13 @@ exports.CANONICAL_BUNDLE_MANIFEST = [
52
52
  { path: "psyche/LORE.md", kind: "file" },
53
53
  { path: "psyche/TACIT.md", kind: "file" },
54
54
  { path: "psyche/ASPIRATIONS.md", kind: "file" },
55
- { path: "psyche/memory", kind: "dir" },
55
+ { path: "arc", kind: "dir" },
56
+ { path: "arc/episodes", kind: "dir" },
57
+ { path: "arc/obligations", kind: "dir" },
58
+ { path: "arc/cares", kind: "dir" },
59
+ { path: "arc/intentions", kind: "dir" },
60
+ { path: "diary", kind: "dir" },
61
+ { path: "journal", kind: "dir" },
56
62
  { path: "friends", kind: "dir" },
57
63
  { path: "state", kind: "dir" },
58
64
  { path: "tasks", kind: "dir" },