@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831

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 (647) 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/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5308 -16
  16. package/deploy/unraid/Dockerfile +54 -0
  17. package/deploy/unraid/README.txt +2983 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  34. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  35. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  36. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  37. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  38. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  39. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  40. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  41. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  42. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
  43. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
  49. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  50. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
  51. package/deploy/unraid/sanctuary.xml +28 -0
  52. package/dist/a2a/card.js +57 -0
  53. package/dist/a2a/client.js +180 -0
  54. package/dist/a2a/config.js +50 -0
  55. package/dist/a2a/delegation-stores.js +56 -0
  56. package/dist/a2a/did-resolution.js +93 -0
  57. package/dist/a2a/identity.js +170 -0
  58. package/dist/a2a/inbound-share.js +107 -0
  59. package/dist/a2a/mission-result-wire.js +196 -0
  60. package/dist/a2a/onboarding.js +115 -0
  61. package/dist/a2a/pin-store.js +132 -0
  62. package/dist/a2a/seen-ledger.js +120 -0
  63. package/dist/a2a/server.js +604 -0
  64. package/dist/a2a/task-store.js +69 -0
  65. package/dist/a2a/transport.js +45 -0
  66. package/dist/a2a/types.js +3 -0
  67. package/dist/arc/attention-types.js +8 -0
  68. package/dist/arc/cares.js +360 -0
  69. package/dist/arc/episodes.js +118 -0
  70. package/dist/arc/evolution.js +490 -0
  71. package/dist/arc/flight-recorder.js +1034 -0
  72. package/dist/arc/intentions.js +134 -0
  73. package/dist/arc/json-store.js +117 -0
  74. package/dist/arc/obligations.js +386 -0
  75. package/dist/arc/packets.js +336 -0
  76. package/dist/arc/presence.js +185 -0
  77. package/dist/arc/task-lifecycle.js +57 -0
  78. package/dist/commerce/store.js +755 -0
  79. package/dist/commerce/types.js +3 -0
  80. package/dist/heart/active-work.js +798 -40
  81. package/dist/heart/agent-entry.js +252 -3
  82. package/dist/heart/approval-files.js +113 -0
  83. package/dist/heart/approval-store.js +960 -0
  84. package/dist/heart/attachments/image-normalize.js +194 -0
  85. package/dist/heart/attachments/materialize.js +97 -0
  86. package/dist/heart/attachments/originals.js +88 -0
  87. package/dist/heart/attachments/render.js +29 -0
  88. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  89. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  90. package/dist/heart/attachments/sources/index.js +18 -0
  91. package/dist/heart/attachments/sources/telegram.js +71 -0
  92. package/dist/heart/attachments/store.js +132 -0
  93. package/dist/heart/attachments/types.js +93 -0
  94. package/dist/heart/auth/auth-flow.js +495 -0
  95. package/dist/heart/autonomy-budget.js +478 -0
  96. package/dist/heart/awaiting/await-alert.js +148 -0
  97. package/dist/heart/awaiting/await-expiry.js +143 -0
  98. package/dist/heart/awaiting/await-loader.js +91 -0
  99. package/dist/heart/awaiting/await-parser.js +149 -0
  100. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  101. package/dist/heart/awaiting/await-scheduler.js +382 -0
  102. package/dist/heart/background-operations.js +281 -0
  103. package/dist/heart/bridges/manager.js +137 -17
  104. package/dist/heart/bridges/store.js +14 -2
  105. package/dist/heart/bundle-state.js +168 -0
  106. package/dist/heart/commitments.js +44 -18
  107. package/dist/heart/config-registry.js +331 -0
  108. package/dist/heart/config.js +174 -131
  109. package/dist/heart/context-loss-gauntlet.js +387 -0
  110. package/dist/heart/context-loss-sentinel.js +1157 -0
  111. package/dist/heart/core.js +2169 -581
  112. package/dist/heart/cross-chat-delivery.js +9 -22
  113. package/dist/heart/daemon/agent-config-check.js +451 -0
  114. package/dist/heart/daemon/agent-discovery.js +185 -3
  115. package/dist/heart/daemon/agent-service.js +542 -0
  116. package/dist/heart/daemon/agentic-repair.js +547 -0
  117. package/dist/heart/daemon/await-private-wake.js +59 -0
  118. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  119. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  120. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  121. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  122. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  123. package/dist/heart/daemon/cadence.js +180 -0
  124. package/dist/heart/daemon/cli-defaults.js +854 -0
  125. package/dist/heart/daemon/cli-desk.js +322 -0
  126. package/dist/heart/daemon/cli-exec.js +8822 -0
  127. package/dist/heart/daemon/cli-help.js +716 -0
  128. package/dist/heart/daemon/cli-parse.js +2771 -0
  129. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  130. package/dist/heart/daemon/cli-render.js +777 -0
  131. package/dist/heart/daemon/cli-types.js +8 -0
  132. package/dist/heart/daemon/connect-bay.js +323 -0
  133. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  134. package/dist/heart/daemon/container-healthcheck.js +112 -0
  135. package/dist/heart/daemon/container-runtime.js +97 -0
  136. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  137. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  138. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  139. package/dist/heart/daemon/daemon-cli.js +29 -2349
  140. package/dist/heart/daemon/daemon-entry.js +930 -11
  141. package/dist/heart/daemon/daemon-health.js +186 -0
  142. package/dist/heart/daemon/daemon-rollup.js +57 -0
  143. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  144. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  145. package/dist/heart/daemon/daemon.js +2084 -105
  146. package/dist/heart/daemon/dns-workflow.js +394 -0
  147. package/dist/heart/daemon/doctor-types.js +8 -0
  148. package/dist/heart/daemon/doctor.js +1755 -0
  149. package/dist/heart/daemon/freshness.js +345 -0
  150. package/dist/heart/daemon/habit-private-wake.js +61 -0
  151. package/dist/heart/daemon/health-monitor.js +142 -11
  152. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  153. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  154. package/dist/heart/daemon/http-health-probe.js +80 -0
  155. package/dist/heart/daemon/human-command-screens.js +234 -0
  156. package/dist/heart/daemon/human-readiness.js +114 -0
  157. package/dist/heart/daemon/inner-status.js +78 -0
  158. package/dist/heart/daemon/interactive-repair.js +394 -0
  159. package/dist/heart/daemon/launchd.js +37 -8
  160. package/dist/heart/daemon/log-tailer.js +79 -10
  161. package/dist/heart/daemon/logs-prune.js +132 -0
  162. package/dist/heart/daemon/mcp-canary.js +524 -0
  163. package/dist/heart/daemon/message-router.js +65 -5
  164. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  165. package/dist/heart/daemon/os-cron-deps.js +135 -0
  166. package/dist/heart/daemon/os-cron.js +22 -14
  167. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  168. package/dist/heart/daemon/ouro-entry.js +3 -1
  169. package/dist/heart/daemon/plugin-cli.js +432 -0
  170. package/dist/heart/daemon/process-manager.js +733 -61
  171. package/dist/heart/daemon/provider-discovery.js +137 -0
  172. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  173. package/dist/heart/daemon/prunable-bundle.js +144 -0
  174. package/dist/heart/daemon/pulse.js +511 -0
  175. package/dist/heart/daemon/readiness-repair.js +365 -0
  176. package/dist/heart/daemon/run-hooks.js +2 -0
  177. package/dist/heart/daemon/runtime-logging.js +47 -14
  178. package/dist/heart/daemon/runtime-metadata.js +2 -30
  179. package/dist/heart/daemon/runtime-mode.js +13 -2
  180. package/dist/heart/daemon/safe-mode.js +161 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  185. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  186. package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
  187. package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
  188. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  189. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
  190. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  191. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  192. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  193. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
  194. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  195. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  196. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  197. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  198. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  199. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  200. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  201. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  202. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  203. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
  204. package/dist/heart/daemon/sense-manager.js +699 -48
  205. package/dist/heart/daemon/session-id-resolver.js +131 -0
  206. package/dist/heart/daemon/skill-management-installer.js +1 -1
  207. package/dist/heart/daemon/socket-client.js +180 -12
  208. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  209. package/dist/heart/daemon/startup-tui.js +339 -0
  210. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  211. package/dist/heart/daemon/task-scheduler.js +117 -39
  212. package/dist/heart/daemon/terminal-ui.js +499 -0
  213. package/dist/heart/daemon/thoughts.js +138 -54
  214. package/dist/heart/daemon/up-progress.js +366 -0
  215. package/dist/heart/daemon/vault-items.js +56 -0
  216. package/dist/heart/delegation.js +1 -4
  217. package/dist/heart/external-events/router.js +1430 -0
  218. package/dist/heart/frontend-approval-runtime.js +506 -0
  219. package/dist/heart/frontend-journal.js +215 -0
  220. package/dist/heart/frontend-session-service.js +237 -0
  221. package/dist/heart/frontend-socket-client.js +164 -0
  222. package/dist/heart/frontend-socket.js +400 -0
  223. package/dist/heart/habits/habit-cancel.js +810 -0
  224. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  225. package/dist/heart/habits/habit-migration.js +194 -0
  226. package/dist/heart/habits/habit-parser.js +278 -0
  227. package/dist/heart/habits/habit-runtime-state.js +93 -0
  228. package/dist/heart/habits/habit-scheduler.js +653 -0
  229. package/dist/heart/habits/habit-session-summary.js +318 -0
  230. package/dist/heart/habits/habit-session.js +636 -0
  231. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  232. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  233. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  234. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  235. package/dist/heart/identity.js +196 -59
  236. package/dist/heart/kept-notes.js +289 -0
  237. package/dist/heart/kicks.js +1 -1
  238. package/dist/heart/machine-identity.js +161 -0
  239. package/dist/heart/mail-import-discovery.js +356 -0
  240. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  241. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  242. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  243. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  244. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  245. package/dist/heart/mailbox/mailbox-http.js +99 -0
  246. package/dist/heart/mailbox/mailbox-read.js +39 -0
  247. package/dist/heart/mailbox/mailbox-types.js +27 -0
  248. package/dist/heart/mailbox/mailbox-view.js +197 -0
  249. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  250. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  251. package/dist/heart/mailbox/readers/mail.js +375 -0
  252. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  253. package/dist/heart/mailbox/readers/sessions.js +231 -0
  254. package/dist/heart/mailbox/readers/shared.js +111 -0
  255. package/dist/heart/mcp/mcp-server.js +696 -0
  256. package/dist/heart/migrate-config.js +100 -0
  257. package/dist/heart/model-capabilities.js +11 -0
  258. package/dist/heart/orientation-frame.js +345 -0
  259. package/dist/heart/platform.js +81 -0
  260. package/dist/heart/primitives.js +1 -1
  261. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  262. package/dist/heart/private-runtime/index.js +18 -0
  263. package/dist/heart/private-runtime/ledger.js +221 -0
  264. package/dist/heart/private-runtime/policy.js +252 -0
  265. package/dist/heart/private-runtime/types.js +2 -0
  266. package/dist/heart/progress-story.js +1 -1
  267. package/dist/heart/provider-attempt.js +137 -0
  268. package/dist/heart/provider-binding-resolver.js +273 -0
  269. package/dist/heart/provider-credentials.js +449 -0
  270. package/dist/heart/provider-failover.js +311 -0
  271. package/dist/heart/provider-models.js +96 -0
  272. package/dist/heart/provider-ping.js +265 -0
  273. package/dist/heart/provider-readiness-cache.js +119 -0
  274. package/dist/heart/provider-visibility.js +188 -0
  275. package/dist/heart/providers/anthropic-token.js +131 -0
  276. package/dist/heart/providers/anthropic.js +173 -60
  277. package/dist/heart/providers/azure.js +23 -11
  278. package/dist/heart/providers/error-classification.js +127 -0
  279. package/dist/heart/providers/github-copilot.js +34 -38
  280. package/dist/heart/providers/minimax-vlm.js +189 -0
  281. package/dist/heart/providers/minimax.js +26 -8
  282. package/dist/heart/providers/openai-codex-token.js +349 -0
  283. package/dist/heart/providers/openai-codex.js +55 -40
  284. package/dist/heart/providers/openai-compatible.js +177 -0
  285. package/dist/heart/run-ledger.js +247 -0
  286. package/dist/heart/runtime-capability-check.js +170 -0
  287. package/dist/heart/runtime-credentials.js +607 -0
  288. package/dist/heart/runtime-cwd.js +87 -0
  289. package/dist/heart/sense-truth.js +22 -4
  290. package/dist/heart/session-activity.js +92 -24
  291. package/dist/heart/session-events.js +1504 -0
  292. package/dist/heart/session-playback-cli-main.js +5 -0
  293. package/dist/heart/session-playback-cli.js +36 -0
  294. package/dist/heart/session-playback.js +231 -0
  295. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  296. package/dist/heart/session-redaction-repair.js +552 -0
  297. package/dist/heart/session-stats-cli-main.js +5 -0
  298. package/dist/heart/session-stats.js +183 -0
  299. package/dist/heart/session-transcript.js +133 -0
  300. package/dist/heart/start-of-turn-packet.js +372 -0
  301. package/dist/heart/steward-policy.js +618 -0
  302. package/dist/heart/streaming.js +604 -207
  303. package/dist/heart/structured-output.js +196 -0
  304. package/dist/heart/sync-classification.js +176 -0
  305. package/dist/heart/sync.js +449 -0
  306. package/dist/heart/target-resolution.js +11 -7
  307. package/dist/heart/tempo.js +93 -0
  308. package/dist/heart/temporal-view.js +41 -0
  309. package/dist/heart/timeouts.js +101 -0
  310. package/dist/heart/tool-activity-callbacks.js +59 -0
  311. package/dist/heart/tool-approval.js +382 -0
  312. package/dist/heart/tool-description.js +155 -0
  313. package/dist/heart/tool-friction.js +55 -0
  314. package/dist/heart/tool-loop.js +200 -0
  315. package/dist/heart/turn-context.js +482 -0
  316. package/dist/heart/turn-execution-lease.js +30 -0
  317. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  318. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  319. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  320. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  321. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  322. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  323. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  324. package/dist/heart/versioning/update-hooks.js +154 -0
  325. package/dist/heart/versioning/version-intent.js +114 -0
  326. package/dist/heart/work-card.js +380 -0
  327. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  328. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  329. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  330. package/dist/mailbox-ui/index.html +16 -0
  331. package/dist/mailroom/attention.js +167 -0
  332. package/dist/mailroom/autonomy.js +209 -0
  333. package/dist/mailroom/blob-store.js +889 -0
  334. package/dist/mailroom/body-cache.js +61 -0
  335. package/dist/mailroom/cache-sync-cli.js +58 -0
  336. package/dist/mailroom/core.js +803 -0
  337. package/dist/mailroom/entry.js +160 -0
  338. package/dist/mailroom/file-store.js +568 -0
  339. package/dist/mailroom/hosted-cache-sync.js +384 -0
  340. package/dist/mailroom/mbox-import.js +393 -0
  341. package/dist/mailroom/migration.js +164 -0
  342. package/dist/mailroom/outbound.js +380 -0
  343. package/dist/mailroom/policy.js +263 -0
  344. package/dist/mailroom/reader.js +292 -0
  345. package/dist/mailroom/search-cache.js +513 -0
  346. package/dist/mailroom/search-relevance.js +319 -0
  347. package/dist/mailroom/smtp-ingress.js +176 -0
  348. package/dist/mailroom/source-state.js +176 -0
  349. package/dist/mailroom/thread.js +109 -0
  350. package/dist/mailroom/travel-extract.js +89 -0
  351. package/dist/mind/bundle-manifest.js +24 -2
  352. package/dist/mind/context.js +309 -111
  353. package/dist/mind/desk-section.js +362 -0
  354. package/dist/mind/diary-integrity.js +60 -0
  355. package/dist/mind/{memory.js → diary.js} +68 -77
  356. package/dist/mind/embedding-provider.js +60 -0
  357. package/dist/mind/file-state.js +179 -0
  358. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  359. package/dist/mind/obligation-steering.js +199 -3
  360. package/dist/mind/pending.js +36 -10
  361. package/dist/mind/prompt-budget.js +479 -0
  362. package/dist/mind/prompt-refresh.js +3 -2
  363. package/dist/mind/prompt.js +1050 -189
  364. package/dist/mind/provenance-trust.js +26 -0
  365. package/dist/mind/record-paths.js +312 -0
  366. package/dist/mind/scrutiny.js +173 -0
  367. package/dist/mind/session-transaction.js +564 -0
  368. package/dist/nerves/cli-logging.js +7 -1
  369. package/dist/nerves/coverage/audit-rules.js +15 -6
  370. package/dist/nerves/coverage/audit.js +28 -2
  371. package/dist/nerves/coverage/cli.js +1 -1
  372. package/dist/nerves/coverage/contract.js +5 -5
  373. package/dist/nerves/coverage/file-completeness.js +139 -5
  374. package/dist/nerves/coverage/run-artifacts.js +55 -35
  375. package/dist/nerves/coverage/source-scanner.js +4 -4
  376. package/dist/nerves/event-buffer.js +111 -0
  377. package/dist/nerves/index.js +293 -9
  378. package/dist/nerves/observation.js +20 -0
  379. package/dist/nerves/redact.js +79 -0
  380. package/dist/nerves/review/cli-main.js +5 -0
  381. package/dist/nerves/review/cli.js +156 -0
  382. package/dist/nerves/review/core.js +159 -0
  383. package/dist/nerves/runtime.js +17 -1
  384. package/dist/repertoire/ado-client.js +15 -56
  385. package/dist/repertoire/ado-semantic.js +16 -10
  386. package/dist/repertoire/api-client.js +97 -0
  387. package/dist/repertoire/bitwarden-store.js +1045 -0
  388. package/dist/repertoire/bundle-templates.js +71 -0
  389. package/dist/repertoire/bw-installer.js +180 -0
  390. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  391. package/dist/repertoire/coding/context-pack.js +331 -0
  392. package/dist/repertoire/coding/feedback.js +174 -32
  393. package/dist/repertoire/coding/index.js +15 -3
  394. package/dist/repertoire/coding/manager.js +159 -10
  395. package/dist/repertoire/coding/spawner.js +58 -11
  396. package/dist/repertoire/coding/tools.js +221 -15
  397. package/dist/repertoire/coding/workbench-client.js +272 -0
  398. package/dist/repertoire/coding/workbench-manager.js +346 -0
  399. package/dist/repertoire/commerce-errors.js +109 -0
  400. package/dist/repertoire/commerce-self-test.js +156 -0
  401. package/dist/repertoire/credential-access.js +178 -0
  402. package/dist/repertoire/desk/classifier.js +362 -0
  403. package/dist/repertoire/duffel-client.js +185 -0
  404. package/dist/repertoire/github-client.js +14 -55
  405. package/dist/repertoire/graph-client.js +11 -52
  406. package/dist/repertoire/guardrails.js +811 -18
  407. package/dist/repertoire/mcp-client.js +44 -3
  408. package/dist/repertoire/mcp-manager.js +427 -139
  409. package/dist/repertoire/mcp-tools.js +124 -0
  410. package/dist/repertoire/plugin-mcp.js +175 -0
  411. package/dist/repertoire/plugins.js +253 -0
  412. package/dist/repertoire/relationship-authorization.js +322 -0
  413. package/dist/repertoire/shell-sessions.js +134 -0
  414. package/dist/repertoire/skills.js +48 -4
  415. package/dist/repertoire/stripe-client.js +131 -0
  416. package/dist/repertoire/tool-arguments.js +170 -0
  417. package/dist/repertoire/tool-results.js +29 -0
  418. package/dist/repertoire/tools-a2a.js +699 -0
  419. package/dist/repertoire/tools-attachments.js +322 -0
  420. package/dist/repertoire/tools-awaiting.js +575 -0
  421. package/dist/repertoire/tools-base.js +77 -1138
  422. package/dist/repertoire/tools-bluebubbles.js +2 -0
  423. package/dist/repertoire/tools-bridge.js +144 -0
  424. package/dist/repertoire/tools-bundle.js +993 -0
  425. package/dist/repertoire/tools-commerce.js +253 -0
  426. package/dist/repertoire/tools-config.js +186 -0
  427. package/dist/repertoire/tools-continuity.js +575 -0
  428. package/dist/repertoire/tools-credential.js +383 -0
  429. package/dist/repertoire/tools-evolution.js +527 -0
  430. package/dist/repertoire/tools-files.js +344 -0
  431. package/dist/repertoire/tools-flight.js +290 -0
  432. package/dist/repertoire/tools-flow.js +119 -0
  433. package/dist/repertoire/tools-github.js +3 -8
  434. package/dist/repertoire/tools-habits.js +103 -0
  435. package/dist/repertoire/tools-mail.js +1828 -0
  436. package/dist/repertoire/tools-notes.js +485 -0
  437. package/dist/repertoire/tools-obligations.js +182 -0
  438. package/dist/repertoire/tools-orientation.js +31 -0
  439. package/dist/repertoire/tools-record.js +482 -0
  440. package/dist/repertoire/tools-rsvp.js +139 -0
  441. package/dist/repertoire/tools-runtime.js +150 -0
  442. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  443. package/dist/repertoire/tools-session.js +1133 -0
  444. package/dist/repertoire/tools-shell.js +149 -0
  445. package/dist/repertoire/tools-steward-policy.js +119 -0
  446. package/dist/repertoire/tools-stripe.js +224 -0
  447. package/dist/repertoire/tools-surface.js +369 -0
  448. package/dist/repertoire/tools-teams.js +12 -39
  449. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  450. package/dist/repertoire/tools-travel.js +125 -0
  451. package/dist/repertoire/tools-trip.js +982 -0
  452. package/dist/repertoire/tools-unraid.js +531 -0
  453. package/dist/repertoire/tools-user-profile.js +146 -0
  454. package/dist/repertoire/tools-vault.js +40 -0
  455. package/dist/repertoire/tools-voice.js +145 -0
  456. package/dist/repertoire/tools.js +494 -148
  457. package/dist/repertoire/travel-api-client.js +360 -0
  458. package/dist/repertoire/unraid-client.js +155 -0
  459. package/dist/repertoire/unraid-restart.js +339 -0
  460. package/dist/repertoire/user-profile.js +131 -0
  461. package/dist/repertoire/vault-setup.js +246 -0
  462. package/dist/repertoire/vault-unlock.js +628 -0
  463. package/dist/rsvp/aisleplanner-client.js +354 -0
  464. package/dist/rsvp/cli.js +926 -0
  465. package/dist/rsvp/config.js +327 -0
  466. package/dist/rsvp/cutover.js +433 -0
  467. package/dist/rsvp/diagnostics.js +232 -0
  468. package/dist/rsvp/diff-renderer.js +176 -0
  469. package/dist/rsvp/habit-policy.js +110 -0
  470. package/dist/rsvp/habit-stage.js +123 -0
  471. package/dist/rsvp/incident-bundle.js +97 -0
  472. package/dist/rsvp/migration.js +204 -0
  473. package/dist/rsvp/native-habit-runner.js +630 -0
  474. package/dist/rsvp/outbound-state.js +628 -0
  475. package/dist/rsvp/query.js +118 -0
  476. package/dist/rsvp/replay.js +233 -0
  477. package/dist/rsvp/snapshot.js +232 -0
  478. package/dist/rsvp/spend-ledger.js +175 -0
  479. package/dist/scripts/claude-code-hook.js +41 -0
  480. package/dist/scripts/claude-code-stop-hook.js +47 -0
  481. package/dist/senses/a2a-entry.js +115 -0
  482. package/dist/senses/acp-server.js +386 -0
  483. package/dist/senses/attention-queue.js +186 -0
  484. package/dist/senses/await-turn-message.js +58 -0
  485. package/dist/senses/bluebubbles/active-turns.js +216 -0
  486. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  487. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  488. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  489. package/dist/senses/bluebubbles/context-packet.js +207 -0
  490. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  491. package/dist/senses/bluebubbles/entry.js +90 -0
  492. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  493. package/dist/senses/bluebubbles/index.js +3841 -0
  494. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  495. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  496. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  497. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  498. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  499. package/dist/senses/bluebubbles/processed-log.js +133 -0
  500. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  501. package/dist/senses/bluebubbles/replay.js +284 -0
  502. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  503. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  504. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  505. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  506. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  507. package/dist/senses/cli/bracketed-paste.js +82 -0
  508. package/dist/senses/cli/image-paste.js +287 -0
  509. package/dist/senses/cli/image-ref-navigation.js +75 -0
  510. package/dist/senses/cli/ink-app.js +156 -0
  511. package/dist/senses/cli/inline-diff.js +64 -0
  512. package/dist/senses/cli/input-keys.js +174 -0
  513. package/dist/senses/cli/kill-ring.js +86 -0
  514. package/dist/senses/cli/message-list.js +51 -0
  515. package/dist/senses/cli/ouro-tui.js +607 -0
  516. package/dist/senses/cli/spinner-imperative.js +135 -0
  517. package/dist/senses/cli/spinner.js +101 -0
  518. package/dist/senses/cli/status-line.js +60 -0
  519. package/dist/senses/cli/streaming-markdown.js +526 -0
  520. package/dist/senses/cli/tool-display.js +85 -0
  521. package/dist/senses/cli/tool-render.js +85 -0
  522. package/dist/senses/cli/tui-store.js +241 -0
  523. package/dist/senses/cli/virtual-list.js +35 -0
  524. package/dist/senses/cli-entry.js +60 -8
  525. package/dist/senses/cli.js +604 -320
  526. package/dist/senses/commands.js +66 -3
  527. package/dist/senses/context-packet-ledger.js +371 -0
  528. package/dist/senses/context-packets.js +154 -0
  529. package/dist/senses/habit-lifecycle-guard.js +24 -0
  530. package/dist/senses/habit-turn-message.js +160 -0
  531. package/dist/senses/ingress-evidence.js +2 -0
  532. package/dist/senses/mail-entry.js +66 -0
  533. package/dist/senses/mail.js +524 -0
  534. package/dist/senses/pipeline.js +1115 -204
  535. package/dist/senses/private-runtime-worker.js +859 -0
  536. package/dist/senses/private-runtime.js +1517 -0
  537. package/dist/senses/proactive-content-guard.js +51 -0
  538. package/dist/senses/root-host-approval-port.js +345 -0
  539. package/dist/senses/root-host-approval-runtime.js +393 -0
  540. package/dist/senses/sanctuary-authority-resident.js +102 -0
  541. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  542. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  543. package/dist/senses/sanctuary-grounding.js +118 -0
  544. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  545. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  546. package/dist/senses/sanctuary-health-runner.js +100 -0
  547. package/dist/senses/sanctuary-health.js +408 -0
  548. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  549. package/dist/senses/sanctuary-interactive-control.js +410 -0
  550. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  551. package/dist/senses/sanctuary-media-optimization.js +514 -0
  552. package/dist/senses/sanctuary-runtime.js +340 -0
  553. package/dist/senses/sanctuary-sab.js +85 -0
  554. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  555. package/dist/senses/shared-turn.js +772 -0
  556. package/dist/senses/surface-tool.js +109 -0
  557. package/dist/senses/teams-entry.js +60 -8
  558. package/dist/senses/teams.js +519 -218
  559. package/dist/senses/telegram-admission.js +718 -0
  560. package/dist/senses/telegram-approval-runtime.js +793 -0
  561. package/dist/senses/telegram-attachments.js +186 -0
  562. package/dist/senses/telegram-audit-ledger.js +220 -0
  563. package/dist/senses/telegram-authority-transport.js +231 -0
  564. package/dist/senses/telegram-client.js +1749 -0
  565. package/dist/senses/telegram-effect-adapter.js +896 -0
  566. package/dist/senses/telegram-entry.js +83 -0
  567. package/dist/senses/telegram.js +2324 -0
  568. package/dist/senses/trust-gate.js +104 -9
  569. package/dist/senses/voice/audio-playback.js +237 -0
  570. package/dist/senses/voice/audio-routing.js +119 -0
  571. package/dist/senses/voice/elevenlabs.js +202 -0
  572. package/dist/senses/voice/floor-control.js +431 -0
  573. package/dist/senses/voice/floor-controller.js +115 -0
  574. package/dist/senses/voice/golden-path.js +116 -0
  575. package/dist/senses/voice/index.js +29 -0
  576. package/dist/senses/voice/meeting.js +113 -0
  577. package/dist/senses/voice/outbound.js +190 -0
  578. package/dist/senses/voice/phone.js +33 -0
  579. package/dist/senses/voice/playback.js +139 -0
  580. package/dist/senses/voice/realtime-eval.js +496 -0
  581. package/dist/senses/voice/realtime-trace.js +531 -0
  582. package/dist/senses/voice/transcript.js +70 -0
  583. package/dist/senses/voice/turn.js +191 -0
  584. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  585. package/dist/senses/voice/twilio-phone.js +5031 -0
  586. package/dist/senses/voice/types.js +2 -0
  587. package/dist/senses/voice/whisper.js +161 -0
  588. package/dist/senses/voice-entry.js +81 -0
  589. package/dist/senses/voice-realtime-eval-command.js +99 -0
  590. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  591. package/dist/senses/voice-twilio-entry.js +87 -0
  592. package/dist/trips/core.js +138 -0
  593. package/dist/trips/store.js +265 -0
  594. package/dist/util/frontmatter.js +69 -0
  595. package/npm-shrinkwrap.json +8138 -0
  596. package/package.json +72 -13
  597. package/skills/agent-commerce.md +113 -0
  598. package/skills/browser-navigation.md +117 -0
  599. package/skills/commerce-setup-guide.md +116 -0
  600. package/skills/commerce-setup.md +84 -0
  601. package/skills/configure-dev-tools.md +99 -0
  602. package/skills/travel-planning.md +138 -0
  603. package/dist/heart/daemon/auth-flow.js +0 -430
  604. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  605. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  606. package/dist/heart/daemon/update-hooks.js +0 -138
  607. package/dist/heart/obligations.js +0 -191
  608. package/dist/heart/safe-workspace.js +0 -228
  609. package/dist/heart/session-recall.js +0 -116
  610. package/dist/mind/friends/channel.js +0 -84
  611. package/dist/mind/friends/group-context.js +0 -144
  612. package/dist/mind/friends/resolver.js +0 -84
  613. package/dist/mind/friends/store-file.js +0 -190
  614. package/dist/mind/friends/store.js +0 -4
  615. package/dist/mind/friends/tokens.js +0 -26
  616. package/dist/mind/friends/trust-explanation.js +0 -74
  617. package/dist/mind/friends/types.js +0 -29
  618. package/dist/repertoire/tasks/board.js +0 -134
  619. package/dist/repertoire/tasks/index.js +0 -224
  620. package/dist/repertoire/tasks/lifecycle.js +0 -80
  621. package/dist/repertoire/tasks/middleware.js +0 -65
  622. package/dist/repertoire/tasks/parser.js +0 -173
  623. package/dist/repertoire/tasks/scanner.js +0 -132
  624. package/dist/repertoire/tasks/transitions.js +0 -144
  625. package/dist/senses/bluebubbles-entry.js +0 -13
  626. package/dist/senses/bluebubbles.js +0 -1181
  627. package/dist/senses/debug-activity.js +0 -154
  628. package/dist/senses/inner-dialog-worker.js +0 -90
  629. package/dist/senses/inner-dialog.js +0 -525
  630. package/subagents/README.md +0 -7
  631. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  632. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  633. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  643. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  644. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  645. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  646. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  647. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,524 @@
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.scanMailImportDiscoveryAttention = scanMailImportDiscoveryAttention;
37
+ exports.startMailSenseApp = startMailSenseApp;
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const runtime_1 = require("../nerves/runtime");
41
+ const identity_1 = require("../heart/identity");
42
+ const runtime_credentials_1 = require("../heart/runtime-credentials");
43
+ const pending_1 = require("../mind/pending");
44
+ const socket_client_1 = require("../heart/daemon/socket-client");
45
+ const background_operations_1 = require("../heart/background-operations");
46
+ const mail_import_discovery_1 = require("../heart/mail-import-discovery");
47
+ const attention_1 = require("../mailroom/attention");
48
+ const reader_1 = require("../mailroom/reader");
49
+ const smtp_ingress_1 = require("../mailroom/smtp-ingress");
50
+ function readRegistry(registryPath) {
51
+ return JSON.parse(fs.readFileSync(registryPath, "utf-8"));
52
+ }
53
+ function isRecord(value) {
54
+ return !!value && typeof value === "object" && !Array.isArray(value);
55
+ }
56
+ function unverifiableCoverage(checkedAt, reason) {
57
+ return { status: "could-not-verify", declaredKeyIds: [], absentKeyIds: [], reason, checkedAt };
58
+ }
59
+ /**
60
+ * Key ids the registry says mail can currently be encrypted to for this agent.
61
+ *
62
+ * Filtered to this agent because the hosted registry is domain-wide: counting
63
+ * every agent's records would report another agent's keys as absent on every
64
+ * cycle, and a check that always fails is a check operators learn to ignore.
65
+ *
66
+ * The match is case-insensitive. The harness sends `agentId: agent` verbatim to
67
+ * hosted Mail Control while this repo's own hosted ensure-response fixture
68
+ * returns the lowercased form for that same request, so a registry record's
69
+ * agent id can differ from the sense's agent name by case alone. Case-sensitive
70
+ * matching would then declare nothing and report `could-not-verify` forever —
71
+ * the same silence this probe exists to end. Widening the match cannot produce
72
+ * a false `absent` unless two agents differ only by case, which the store and
73
+ * address resolvers could not tell apart either.
74
+ *
75
+ * Disabled source grants are excluded because `resolveMailAddress`
76
+ * (`mailroom/core.ts`) refuses their alias outright, so no new mail can be
77
+ * encrypted to their key and a missing private half is not a live gap.
78
+ */
79
+ function registryDeclaredKeyIds(registry, agentName) {
80
+ const wanted = agentName.toLowerCase();
81
+ const isThisAgent = (agentId) => agentId.toLowerCase() === wanted;
82
+ const declared = [
83
+ ...registry.mailboxes.filter((mailbox) => isThisAgent(mailbox.agentId)).map((mailbox) => mailbox.keyId),
84
+ ...registry.sourceGrants.filter((grant) => isThisAgent(grant.agentId) && grant.enabled).map((grant) => grant.keyId),
85
+ ];
86
+ return [...new Set(declared.filter((keyId) => keyId.trim().length > 0))];
87
+ }
88
+ /**
89
+ * Mail key ids the vault can actually decrypt with, read fresh rather than
90
+ * taken from the reader resolution captured at sense startup — a sense that has
91
+ * been up for days would otherwise measure a key set the vault has since
92
+ * changed, and report a rotation as a loss.
93
+ *
94
+ * Throws rather than returning empty when the read is untrustworthy, so the
95
+ * caller classifies it `could-not-verify` instead of `absent`. An empty-but-
96
+ * present `privateKeys` record is a real observation and is not a throw.
97
+ */
98
+ function vaultMailKeyIds(agentName) {
99
+ const runtime = (0, runtime_credentials_1.readRuntimeCredentialConfig)(agentName);
100
+ if (!runtime.ok)
101
+ throw new Error(`vault ${runtime.itemPath} read is ${runtime.reason}`);
102
+ const mailroom = runtime.config.mailroom;
103
+ const privateKeys = isRecord(mailroom) ? mailroom.privateKeys : undefined;
104
+ if (!isRecord(privateKeys))
105
+ throw new Error(`vault ${runtime.itemPath} has no mailroom.privateKeys record`);
106
+ return Object.entries(privateKeys)
107
+ .filter((entry) => typeof entry[1] === "string" && entry[1].trim().length > 0)
108
+ .map((entry) => entry[0]);
109
+ }
110
+ /**
111
+ * Never throws: every failure degrades to `could-not-verify`. `scan()` is
112
+ * awaited during sense startup, so a throw here would stop the mail sense from
113
+ * starting — an integrity probe must not be able to take mail down.
114
+ */
115
+ async function computeMailKeyCoverage(input) {
116
+ try {
117
+ const registry = await input.readRegistry(input.config);
118
+ const declaredKeyIds = registryDeclaredKeyIds(registry, input.agentName);
119
+ if (declaredKeyIds.length === 0) {
120
+ // Nothing to check against is not the same as nothing wrong: reporting
121
+ // `covered` for an empty declaration would turn an unprovisioned or
122
+ // wrong registry into a green light.
123
+ return unverifiableCoverage(input.checkedAt, `mailroom registry declares no mail keys for ${input.agentName}`);
124
+ }
125
+ const present = new Set(vaultMailKeyIds(input.agentName));
126
+ const absentKeyIds = declaredKeyIds.filter((keyId) => !present.has(keyId));
127
+ return {
128
+ status: absentKeyIds.length === 0 ? "covered" : "absent",
129
+ declaredKeyIds,
130
+ absentKeyIds,
131
+ reason: null,
132
+ checkedAt: input.checkedAt,
133
+ };
134
+ }
135
+ catch (error) {
136
+ return unverifiableCoverage(input.checkedAt, error instanceof Error ? error.message : String(error));
137
+ }
138
+ }
139
+ /**
140
+ * Coverage has to push, not wait to be asked. `ouro doctor` is on-demand — it
141
+ * has no scheduled invocation — so a doctor line alone leaves a gap invisible
142
+ * until someone happens to run it, which is how `mail_slugger-hey_6e7b4bfa34c0b826`
143
+ * stayed unnoticed for 23 hours while mail encrypted to it piled up unreadable.
144
+ */
145
+ function emitMailKeyCoverageEvents(agentName, coverage) {
146
+ (0, runtime_1.emitNervesEvent)({
147
+ component: "senses",
148
+ event: "senses.mail_key_coverage_recorded",
149
+ message: "mail key coverage recorded",
150
+ meta: {
151
+ agentName,
152
+ status: coverage.status,
153
+ declaredCount: coverage.declaredKeyIds.length,
154
+ absentCount: coverage.absentKeyIds.length,
155
+ reason: coverage.reason,
156
+ },
157
+ });
158
+ if (coverage.status !== "absent")
159
+ return;
160
+ (0, runtime_1.emitNervesEvent)({
161
+ level: "error",
162
+ component: "senses",
163
+ event: "senses.mail_key_coverage_absent",
164
+ message: `mailroom registry declares mail keys with no private half in ${agentName}'s vault: ${coverage.absentKeyIds.join(", ")}`,
165
+ meta: {
166
+ agentName,
167
+ absentKeyIds: coverage.absentKeyIds,
168
+ declaredKeyIds: coverage.declaredKeyIds,
169
+ },
170
+ });
171
+ }
172
+ function validPort(value) {
173
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 65535 ? value : 0;
174
+ }
175
+ function serverAddress(server) {
176
+ const direct = server;
177
+ if (typeof direct.address === "function")
178
+ return direct.address();
179
+ const wrapped = server;
180
+ if (typeof wrapped.server?.address === "function")
181
+ return wrapped.server.address();
182
+ return null;
183
+ }
184
+ function serverPort(server) {
185
+ const address = serverAddress(server);
186
+ if (!address || typeof address !== "object")
187
+ return null;
188
+ return typeof address.port === "number" ? address.port : null;
189
+ }
190
+ function listeningServer(server) {
191
+ const wrapped = server;
192
+ if (typeof wrapped.server?.once === "function")
193
+ return wrapped.server;
194
+ const direct = server;
195
+ return typeof direct.once === "function" ? direct : null;
196
+ }
197
+ function waitForListening(server) {
198
+ if (serverAddress(server))
199
+ return Promise.resolve();
200
+ const listening = listeningServer(server);
201
+ if (!listening)
202
+ return new Promise((resolve) => setImmediate(resolve));
203
+ if (listening.listening)
204
+ return Promise.resolve();
205
+ return new Promise((resolve) => listening.once?.("listening", resolve));
206
+ }
207
+ function runtimeStatePath(agentName) {
208
+ return path.join((0, identity_1.getAgentRoot)(agentName), "state", "senses", "mail", "runtime.json");
209
+ }
210
+ function attentionStatePath(agentName) {
211
+ return path.join((0, identity_1.getAgentRoot)(agentName), "state", "senses", "mail", "attention.json");
212
+ }
213
+ function importDiscoveryStatePath(agentName) {
214
+ return path.join((0, identity_1.getAgentRoot)(agentName), "state", "senses", "mail", "import-discovery.json");
215
+ }
216
+ function writeRuntimeState(filePath, state) {
217
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
218
+ fs.writeFileSync(filePath, `${JSON.stringify(state, null, 2)}\n`, "utf-8");
219
+ (0, runtime_1.emitNervesEvent)({
220
+ component: "senses",
221
+ event: "senses.mail_sense_runtime_state_written",
222
+ message: "mail sense runtime state written",
223
+ meta: { agentName: state.agentName, status: state.status, lastQueuedCount: state.lastQueuedCount },
224
+ });
225
+ }
226
+ function emptyImportDiscoveryState(updatedAt) {
227
+ return {
228
+ schemaVersion: 1,
229
+ lastNotifiedFingerprint: null,
230
+ updatedAt,
231
+ };
232
+ }
233
+ function readImportDiscoveryState(filePath, updatedAt) {
234
+ try {
235
+ const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8"));
236
+ return {
237
+ schemaVersion: 1,
238
+ lastNotifiedFingerprint: typeof parsed.lastNotifiedFingerprint === "string" && parsed.lastNotifiedFingerprint.trim().length > 0
239
+ ? parsed.lastNotifiedFingerprint
240
+ : null,
241
+ updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : updatedAt,
242
+ };
243
+ }
244
+ catch {
245
+ return emptyImportDiscoveryState(updatedAt);
246
+ }
247
+ }
248
+ function writeImportDiscoveryState(filePath, state) {
249
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
250
+ fs.writeFileSync(filePath, `${JSON.stringify(state, null, 2)}\n`, "utf-8");
251
+ }
252
+ function stringArray(value) {
253
+ if (!Array.isArray(value))
254
+ return [];
255
+ return value.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
256
+ }
257
+ function candidateDescriptors(value) {
258
+ if (!Array.isArray(value))
259
+ return [];
260
+ return value
261
+ .filter((entry) => !!entry && typeof entry === "object" && !Array.isArray(entry))
262
+ .map((entry) => ({
263
+ path: typeof entry.path === "string" ? entry.path : "",
264
+ originKind: typeof entry.originKind === "string" ? entry.originKind : undefined,
265
+ originLabel: typeof entry.originLabel === "string" ? entry.originLabel : undefined,
266
+ }))
267
+ .filter((entry) => entry.path.trim().length > 0);
268
+ }
269
+ function renderImportDiscoveryContent(candidatePaths, descriptors) {
270
+ const renderedCandidates = descriptors.length > 0
271
+ ? descriptors.map((descriptor) => `- [${descriptor.originLabel ?? descriptor.originKind ?? "filesystem"}] ${descriptor.path}`)
272
+ : candidatePaths.map((candidatePath) => `- ${candidatePath}`);
273
+ return [
274
+ "[Mail Import Ready]",
275
+ "A local MBOX archive is ready for delegated-mail backfill.",
276
+ "This may live in a worktree-local Playwright sandbox rather than ~/Downloads.",
277
+ "",
278
+ "recent candidates:",
279
+ ...renderedCandidates,
280
+ "",
281
+ "If this matches an expected mailbox backfill, run `ouro mail import-mbox --discover --owner-email <email> --source hey --agent <agent>` first so Ouro can pick the matching archive or report ambiguity.",
282
+ ].join("\n");
283
+ }
284
+ function buildMailImportDiscoveryPrivateWakeOptions(input) {
285
+ return {
286
+ reason: "mail import discovery private attention",
287
+ triggerSource: "mail-import-discovery",
288
+ budgetClass: "interactive",
289
+ idempotencyKey: `mail-import-discovery:${input.agentName}:${input.fingerprint}`,
290
+ originRefs: [
291
+ { kind: "mail-import-discovery", id: input.fingerprint },
292
+ ...input.candidatePaths.map((candidatePath) => ({ kind: "mail-import-candidate", id: candidatePath })),
293
+ ],
294
+ };
295
+ }
296
+ async function scanMailImportDiscoveryAttention(input) {
297
+ const nowMs = input.now?.() ?? Date.now();
298
+ const updatedAt = new Date(nowMs).toISOString();
299
+ const statePath = input.statePath ?? importDiscoveryStatePath(input.agentName);
300
+ const pendingDir = input.pendingDir ?? (0, pending_1.getPrivateRuntimePendingDir)(input.agentName);
301
+ const state = readImportDiscoveryState(statePath, updatedAt);
302
+ const existingOperations = (0, background_operations_1.listBackgroundOperations)({
303
+ agentName: input.agentName,
304
+ agentRoot: (0, identity_1.getAgentRoot)(input.agentName),
305
+ limit: 10,
306
+ });
307
+ const discovered = (0, mail_import_discovery_1.listAmbientMailImportOperations)({
308
+ agentName: input.agentName,
309
+ agentRoot: (0, identity_1.getAgentRoot)(input.agentName),
310
+ existingOperations,
311
+ repoRoot: (0, identity_1.getRepoRoot)(),
312
+ homeDir: process.env.HOME,
313
+ nowMs,
314
+ })[0] ?? null;
315
+ const fingerprint = typeof discovered?.spec?.fingerprint === "string" && discovered.spec.fingerprint.trim().length > 0
316
+ ? discovered.spec.fingerprint
317
+ : null;
318
+ const candidatePaths = stringArray(discovered?.spec?.candidatePaths);
319
+ const descriptors = candidateDescriptors(discovered?.spec?.candidateDescriptors);
320
+ const shouldQueue = Boolean(discovered && fingerprint && fingerprint !== state.lastNotifiedFingerprint);
321
+ if (shouldQueue && fingerprint) {
322
+ (0, pending_1.queuePendingMessage)(pendingDir, {
323
+ from: "mailroom",
324
+ friendId: "self",
325
+ channel: "mail",
326
+ key: "import-ready",
327
+ content: renderImportDiscoveryContent(candidatePaths, descriptors),
328
+ timestamp: nowMs,
329
+ mode: "reflect",
330
+ });
331
+ await (0, socket_client_1.requestPrivateWake)(input.agentName, undefined, buildMailImportDiscoveryPrivateWakeOptions({
332
+ agentName: input.agentName,
333
+ fingerprint,
334
+ candidatePaths,
335
+ })).catch(() => undefined);
336
+ }
337
+ writeImportDiscoveryState(statePath, {
338
+ schemaVersion: 1,
339
+ lastNotifiedFingerprint: shouldQueue ? fingerprint : state.lastNotifiedFingerprint,
340
+ updatedAt,
341
+ });
342
+ (0, runtime_1.emitNervesEvent)({
343
+ component: "senses",
344
+ event: "senses.mail_import_discovery_scanned",
345
+ message: "mail import discovery scanned",
346
+ meta: {
347
+ agentName: input.agentName,
348
+ queued: shouldQueue,
349
+ candidateCount: candidatePaths.length,
350
+ fingerprint,
351
+ },
352
+ });
353
+ return {
354
+ queued: shouldQueue,
355
+ fingerprint,
356
+ candidatePaths,
357
+ };
358
+ }
359
+ function closeServer(server) {
360
+ return new Promise((resolve) => {
361
+ server.close(resolve);
362
+ });
363
+ }
364
+ async function startMailSenseApp(options) {
365
+ const now = options.now ?? (() => Date.now());
366
+ /* v8 ignore next -- production wiring uses the default vault refresh; tests inject a deterministic refresh. @preserve */
367
+ const refreshRuntime = options.refreshRuntime ?? runtime_credentials_1.refreshRuntimeCredentialConfig;
368
+ await refreshRuntime(options.agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
369
+ const resolved = options.resolveReader
370
+ ? options.resolveReader(options.agentName)
371
+ : (0, reader_1.resolveMailroomReader)(options.agentName);
372
+ if (!resolved.ok) {
373
+ throw new Error(resolved.error);
374
+ }
375
+ const hostedReaderOnly = resolved.storeKind === "azure-blob" && !resolved.config.registryPath;
376
+ if (!resolved.config.registryPath && !hostedReaderOnly) {
377
+ throw new Error(`missing mailroom.registryPath for ${options.agentName}; agent-runnable repair: 'ouro connect mail --agent ${options.agentName}'`);
378
+ }
379
+ const host = resolved.config.host ?? "127.0.0.1";
380
+ const ingress = hostedReaderOnly
381
+ ? null
382
+ : (options.startIngress ?? smtp_ingress_1.startMailroomIngress)({
383
+ registry: readRegistry(resolved.config.registryPath),
384
+ store: resolved.store,
385
+ smtpPort: validPort(resolved.config.smtpPort),
386
+ httpPort: validPort(resolved.config.httpPort),
387
+ host,
388
+ });
389
+ if (ingress) {
390
+ await Promise.all([
391
+ waitForListening(ingress.smtp),
392
+ waitForListening(ingress.health),
393
+ ]);
394
+ }
395
+ const activeSmtpPort = () => ingress ? serverPort(ingress.smtp) : null;
396
+ const activeHttpPort = () => ingress ? serverPort(ingress.health) : null;
397
+ const runtimePath = runtimeStatePath(options.agentName);
398
+ const attentionPath = attentionStatePath(options.agentName);
399
+ const importDiscoveryPath = importDiscoveryStatePath(options.agentName);
400
+ let lastScanAt = null;
401
+ let lastQueuedCount = 0;
402
+ let lastKeyCoverage = unverifiableCoverage(new Date(now()).toISOString(), "mail key coverage not probed yet");
403
+ const scan = async () => {
404
+ const scanStartedAt = new Date(now()).toISOString();
405
+ let queuedCount = 0;
406
+ try {
407
+ const screener = await (0, attention_1.scanMailScreenerAttention)({
408
+ agentName: options.agentName,
409
+ store: resolved.store,
410
+ pendingDir: (0, pending_1.getPrivateRuntimePendingDir)(options.agentName),
411
+ statePath: attentionPath,
412
+ now,
413
+ });
414
+ queuedCount += screener.queued.length;
415
+ }
416
+ catch (error) {
417
+ (0, runtime_1.emitNervesEvent)({
418
+ level: "error",
419
+ component: "senses",
420
+ event: "senses.mail_sense_scan_error",
421
+ message: "mail sense attention scan failed",
422
+ meta: { agentName: options.agentName, error: error instanceof Error ? error.message : String(error) },
423
+ });
424
+ }
425
+ try {
426
+ const importDiscovery = await scanMailImportDiscoveryAttention({
427
+ agentName: options.agentName,
428
+ pendingDir: (0, pending_1.getPrivateRuntimePendingDir)(options.agentName),
429
+ statePath: importDiscoveryPath,
430
+ now,
431
+ });
432
+ if (importDiscovery.queued) {
433
+ queuedCount += 1;
434
+ }
435
+ }
436
+ catch (error) {
437
+ (0, runtime_1.emitNervesEvent)({
438
+ level: "error",
439
+ component: "senses",
440
+ event: "senses.mail_import_discovery_scan_error",
441
+ message: "mail import discovery scan failed",
442
+ meta: { agentName: options.agentName, error: error instanceof Error ? error.message : String(error) },
443
+ });
444
+ }
445
+ lastKeyCoverage = await computeMailKeyCoverage({
446
+ agentName: options.agentName,
447
+ config: resolved.config,
448
+ readRegistry: options.readRegistry ?? reader_1.readMailroomRegistry,
449
+ checkedAt: scanStartedAt,
450
+ });
451
+ emitMailKeyCoverageEvents(options.agentName, lastKeyCoverage);
452
+ lastScanAt = scanStartedAt;
453
+ lastQueuedCount = queuedCount;
454
+ writeRuntimeState(runtimePath, {
455
+ schemaVersion: 1,
456
+ agentName: options.agentName,
457
+ status: "running",
458
+ mailboxAddress: resolved.config.mailboxAddress,
459
+ smtpPort: activeSmtpPort(),
460
+ httpPort: activeHttpPort(),
461
+ host,
462
+ storeKind: resolved.storeKind,
463
+ storeLabel: resolved.storeLabel,
464
+ lastScanAt,
465
+ lastQueuedCount,
466
+ keyCoverage: lastKeyCoverage,
467
+ updatedAt: new Date(now()).toISOString(),
468
+ });
469
+ };
470
+ await scan();
471
+ const intervalMs = Math.max(5_000, resolved.config.attentionIntervalMs ?? 30_000);
472
+ const timer = (options.setIntervalFn ?? ((callback, ms) => setInterval(callback, ms)))(() => {
473
+ void scan();
474
+ }, intervalMs);
475
+ (0, runtime_1.emitNervesEvent)({
476
+ component: "senses",
477
+ event: "senses.mail_sense_started",
478
+ message: "mail sense started",
479
+ meta: {
480
+ agentName: options.agentName,
481
+ mailboxAddress: resolved.config.mailboxAddress,
482
+ smtpPort: activeSmtpPort(),
483
+ httpPort: activeHttpPort(),
484
+ intervalMs,
485
+ },
486
+ });
487
+ return {
488
+ runtimeStatePath: runtimePath,
489
+ attentionStatePath: attentionPath,
490
+ smtpPort: activeSmtpPort(),
491
+ httpPort: activeHttpPort(),
492
+ async stop() {
493
+ ;
494
+ (options.clearIntervalFn ?? ((activeTimer) => clearInterval(activeTimer)))(timer);
495
+ if (ingress) {
496
+ await Promise.all([
497
+ closeServer(ingress.smtp),
498
+ closeServer(ingress.health),
499
+ ]);
500
+ }
501
+ writeRuntimeState(runtimePath, {
502
+ schemaVersion: 1,
503
+ agentName: options.agentName,
504
+ status: "stopped",
505
+ mailboxAddress: resolved.config.mailboxAddress,
506
+ smtpPort: activeSmtpPort(),
507
+ httpPort: activeHttpPort(),
508
+ host,
509
+ storeKind: resolved.storeKind,
510
+ storeLabel: resolved.storeLabel,
511
+ lastScanAt,
512
+ lastQueuedCount,
513
+ keyCoverage: lastKeyCoverage,
514
+ updatedAt: new Date(now()).toISOString(),
515
+ });
516
+ (0, runtime_1.emitNervesEvent)({
517
+ component: "senses",
518
+ event: "senses.mail_sense_stopped",
519
+ message: "mail sense stopped",
520
+ meta: { agentName: options.agentName },
521
+ });
522
+ },
523
+ };
524
+ }