@ouro.bot/cli 0.1.0-alpha.99 → 0.1.0-alpha.990

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 (772) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -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 +6251 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/INSTALL.md +64 -0
  18. package/deploy/unraid/README.txt +2997 -0
  19. package/deploy/unraid/audit-container-spec.sh +4 -0
  20. package/deploy/unraid/container-runtime.json +1 -0
  21. package/deploy/unraid/credit-gateway.md +95 -0
  22. package/deploy/unraid/docker-man-template-transaction.mjs +727 -0
  23. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  24. package/deploy/unraid/install.sh +274 -0
  25. package/deploy/unraid/migrate-sanctuary-bundle.mjs +63 -0
  26. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  27. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  28. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  29. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  30. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  31. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  32. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  33. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  34. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  35. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  36. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1499 -0
  37. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  38. package/deploy/unraid/sanctuary-replay-gate.mjs +2114 -0
  39. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  40. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2088 -0
  41. package/deploy/unraid/sanctuary-unit16-run.sh +570 -0
  42. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  43. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  44. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  45. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  46. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  47. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  48. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2255 -0
  49. package/deploy/unraid/sanctuary.ouro/product/PRODUCT.md +13 -0
  50. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  52. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +7 -0
  53. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +7 -0
  54. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +15 -0
  55. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +3 -0
  56. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  57. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  58. package/deploy/unraid/sanctuary.xml +29 -0
  59. package/dist/a2a/card.js +57 -0
  60. package/dist/a2a/client.js +290 -0
  61. package/dist/a2a/config.js +50 -0
  62. package/dist/a2a/delegated-command-grants.js +93 -0
  63. package/dist/a2a/delegated-command.js +197 -0
  64. package/dist/a2a/delegation-stores.js +56 -0
  65. package/dist/a2a/did-resolution.js +205 -0
  66. package/dist/a2a/escalation-grants.js +84 -0
  67. package/dist/a2a/escalation-wiring.js +60 -0
  68. package/dist/a2a/identity.js +258 -0
  69. package/dist/a2a/inbound-share.js +131 -0
  70. package/dist/a2a/mission-result-wire.js +265 -0
  71. package/dist/a2a/onboarding.js +133 -0
  72. package/dist/a2a/operator-trust.js +399 -0
  73. package/dist/a2a/outbox-client.js +59 -0
  74. package/dist/a2a/outbox-store.js +188 -0
  75. package/dist/a2a/outbox-wire.js +106 -0
  76. package/dist/a2a/pin-store.js +167 -0
  77. package/dist/a2a/refusals.js +53 -0
  78. package/dist/a2a/relay-client.js +106 -0
  79. package/dist/a2a/relay-config-vault.js +64 -0
  80. package/dist/a2a/relay-contacts.js +120 -0
  81. package/dist/a2a/relay-inbox.js +360 -0
  82. package/dist/a2a/relay-retirements.js +89 -0
  83. package/dist/a2a/replay-grant-holders.js +33 -0
  84. package/dist/a2a/replay-harness.js +188 -0
  85. package/dist/a2a/resolution-proof.js +53 -0
  86. package/dist/a2a/sealed-chat.js +114 -0
  87. package/dist/a2a/seen-ledger.js +214 -0
  88. package/dist/a2a/server.js +808 -0
  89. package/dist/a2a/task-store.js +69 -0
  90. package/dist/a2a/transport.js +100 -0
  91. package/dist/a2a/trust-commands.js +203 -0
  92. package/dist/a2a/trusted-files.js +185 -0
  93. package/dist/a2a/types.js +3 -0
  94. package/dist/arc/attention-types.js +8 -0
  95. package/dist/arc/cares.js +360 -0
  96. package/dist/arc/episodes.js +118 -0
  97. package/dist/arc/evolution.js +490 -0
  98. package/dist/arc/flight-recorder.js +1034 -0
  99. package/dist/arc/intentions.js +134 -0
  100. package/dist/arc/json-store.js +117 -0
  101. package/dist/arc/obligations.js +386 -0
  102. package/dist/arc/packets.js +336 -0
  103. package/dist/arc/presence.js +185 -0
  104. package/dist/arc/task-lifecycle.js +57 -0
  105. package/dist/commerce/store.js +755 -0
  106. package/dist/commerce/types.js +3 -0
  107. package/dist/gateway/keys.js +117 -0
  108. package/dist/gateway/server.js +429 -0
  109. package/dist/heart/active-work.js +798 -40
  110. package/dist/heart/agent-entry.js +252 -3
  111. package/dist/heart/approval-files.js +113 -0
  112. package/dist/heart/approval-store.js +960 -0
  113. package/dist/heart/attachments/image-normalize.js +201 -0
  114. package/dist/heart/attachments/materialize.js +97 -0
  115. package/dist/heart/attachments/originals.js +88 -0
  116. package/dist/heart/attachments/render.js +29 -0
  117. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  118. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  119. package/dist/heart/attachments/sources/index.js +18 -0
  120. package/dist/heart/attachments/sources/telegram.js +71 -0
  121. package/dist/heart/attachments/store.js +132 -0
  122. package/dist/heart/attachments/types.js +93 -0
  123. package/dist/heart/auth/auth-flow.js +511 -0
  124. package/dist/heart/autonomy-budget.js +478 -0
  125. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  126. package/dist/heart/awaiting/await-alert.js +152 -0
  127. package/dist/heart/awaiting/await-expiry.js +143 -0
  128. package/dist/heart/awaiting/await-loader.js +91 -0
  129. package/dist/heart/awaiting/await-parser.js +152 -0
  130. package/dist/heart/awaiting/await-runtime-state.js +130 -0
  131. package/dist/heart/awaiting/await-scheduler.js +391 -0
  132. package/dist/heart/background-operations.js +281 -0
  133. package/dist/heart/bluebubbles-host-account.js +78 -0
  134. package/dist/heart/bridges/manager.js +137 -17
  135. package/dist/heart/bridges/store.js +14 -2
  136. package/dist/heart/bundle-state.js +168 -0
  137. package/dist/heart/commitments.js +44 -18
  138. package/dist/heart/config-registry.js +331 -0
  139. package/dist/heart/config.js +178 -131
  140. package/dist/heart/context-loss-gauntlet.js +387 -0
  141. package/dist/heart/context-loss-sentinel.js +1204 -0
  142. package/dist/heart/core.js +2378 -586
  143. package/dist/heart/cross-chat-delivery.js +9 -22
  144. package/dist/heart/daemon/agent-config-check.js +474 -0
  145. package/dist/heart/daemon/agent-discovery.js +283 -3
  146. package/dist/heart/daemon/agent-home.js +319 -0
  147. package/dist/heart/daemon/agent-service.js +542 -0
  148. package/dist/heart/daemon/agentic-repair.js +547 -0
  149. package/dist/heart/daemon/await-private-wake.js +59 -0
  150. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  151. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  152. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  153. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  154. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  155. package/dist/heart/daemon/cadence.js +180 -0
  156. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  157. package/dist/heart/daemon/cli-defaults.js +881 -0
  158. package/dist/heart/daemon/cli-desk.js +331 -0
  159. package/dist/heart/daemon/cli-exec.js +9280 -0
  160. package/dist/heart/daemon/cli-help.js +754 -0
  161. package/dist/heart/daemon/cli-parse.js +3329 -0
  162. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  163. package/dist/heart/daemon/cli-render.js +819 -0
  164. package/dist/heart/daemon/cli-types.js +8 -0
  165. package/dist/heart/daemon/connect-bay.js +323 -0
  166. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  167. package/dist/heart/daemon/container-healthcheck.js +112 -0
  168. package/dist/heart/daemon/container-runtime.js +97 -0
  169. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  170. package/dist/heart/daemon/container-spec-auditor.js +241 -0
  171. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  172. package/dist/heart/daemon/daemon-cli.js +29 -2373
  173. package/dist/heart/daemon/daemon-entry.js +953 -11
  174. package/dist/heart/daemon/daemon-health.js +186 -0
  175. package/dist/heart/daemon/daemon-rollup.js +57 -0
  176. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  177. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  178. package/dist/heart/daemon/daemon.js +2110 -104
  179. package/dist/heart/daemon/desk-admin.js +420 -0
  180. package/dist/heart/daemon/dns-workflow.js +394 -0
  181. package/dist/heart/daemon/doctor-types.js +8 -0
  182. package/dist/heart/daemon/doctor.js +1766 -0
  183. package/dist/heart/daemon/freshness.js +345 -0
  184. package/dist/heart/daemon/habit-private-wake.js +61 -0
  185. package/dist/heart/daemon/health-monitor.js +154 -11
  186. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  187. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  188. package/dist/heart/daemon/http-health-probe.js +80 -0
  189. package/dist/heart/daemon/human-command-screens.js +234 -0
  190. package/dist/heart/daemon/human-readiness.js +114 -0
  191. package/dist/heart/daemon/inner-status.js +78 -0
  192. package/dist/heart/daemon/interactive-repair.js +394 -0
  193. package/dist/heart/daemon/launchd.js +37 -8
  194. package/dist/heart/daemon/log-tailer.js +79 -10
  195. package/dist/heart/daemon/logs-prune.js +132 -0
  196. package/dist/heart/daemon/mcp-canary.js +524 -0
  197. package/dist/heart/daemon/message-router.js +65 -5
  198. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  199. package/dist/heart/daemon/os-cron-deps.js +135 -0
  200. package/dist/heart/daemon/os-cron.js +22 -14
  201. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  202. package/dist/heart/daemon/ouro-entry.js +9 -3
  203. package/dist/heart/daemon/plugin-cli.js +432 -0
  204. package/dist/heart/daemon/process-manager.js +760 -61
  205. package/dist/heart/daemon/provider-discovery.js +137 -0
  206. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  207. package/dist/heart/daemon/prunable-bundle.js +144 -0
  208. package/dist/heart/daemon/pulse.js +511 -0
  209. package/dist/heart/daemon/readiness-repair.js +365 -0
  210. package/dist/heart/daemon/run-hooks.js +2 -0
  211. package/dist/heart/daemon/runtime-logging.js +47 -14
  212. package/dist/heart/daemon/runtime-metadata.js +2 -30
  213. package/dist/heart/daemon/runtime-mode.js +13 -2
  214. package/dist/heart/daemon/safe-mode.js +161 -0
  215. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2662 -0
  216. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1832 -0
  217. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  218. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +956 -0
  219. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  220. package/dist/heart/daemon/sanctuary-authority-epoch.js +291 -0
  221. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  222. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  223. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1332 -0
  224. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  225. package/dist/heart/daemon/sanctuary-bundle-migration.js +878 -0
  226. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  227. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  228. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  229. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  230. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  231. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  232. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  233. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  234. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  235. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  236. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  237. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  238. package/dist/heart/daemon/sense-manager.js +786 -48
  239. package/dist/heart/daemon/session-id-resolver.js +131 -0
  240. package/dist/heart/daemon/skill-management-installer.js +1 -1
  241. package/dist/heart/daemon/socket-client.js +180 -12
  242. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  243. package/dist/heart/daemon/startup-tui.js +339 -0
  244. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  245. package/dist/heart/daemon/task-scheduler.js +117 -39
  246. package/dist/heart/daemon/terminal-ui.js +503 -0
  247. package/dist/heart/daemon/thoughts.js +138 -54
  248. package/dist/heart/daemon/up-progress.js +366 -0
  249. package/dist/heart/daemon/vault-items.js +56 -0
  250. package/dist/heart/delegation.js +1 -4
  251. package/dist/heart/external-events/router.js +1531 -0
  252. package/dist/heart/failure-reports.js +336 -0
  253. package/dist/heart/file-lock.js +109 -0
  254. package/dist/heart/frontend-approval-runtime.js +506 -0
  255. package/dist/heart/frontend-journal.js +215 -0
  256. package/dist/heart/frontend-session-service.js +271 -0
  257. package/dist/heart/frontend-socket-client.js +173 -0
  258. package/dist/heart/frontend-socket.js +434 -0
  259. package/dist/heart/frontend-turn-errors.js +20 -0
  260. package/dist/heart/habits/habit-cancel.js +810 -0
  261. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  262. package/dist/heart/habits/habit-migration.js +194 -0
  263. package/dist/heart/habits/habit-parser.js +278 -0
  264. package/dist/heart/habits/habit-runtime-state.js +93 -0
  265. package/dist/heart/habits/habit-scheduler.js +653 -0
  266. package/dist/heart/habits/habit-session-summary.js +318 -0
  267. package/dist/heart/habits/habit-session.js +636 -0
  268. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  269. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  270. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  271. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  272. package/dist/heart/identity.js +239 -59
  273. package/dist/heart/kept-notes.js +289 -0
  274. package/dist/heart/kicks.js +1 -1
  275. package/dist/heart/machine-identity.js +175 -0
  276. package/dist/heart/mail-import-discovery.js +356 -0
  277. package/dist/heart/mailbox/mailbox-http-hooks.js +99 -0
  278. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  279. package/dist/heart/mailbox/mailbox-http-routes.js +406 -0
  280. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  281. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  282. package/dist/heart/mailbox/mailbox-http.js +99 -0
  283. package/dist/heart/mailbox/mailbox-read.js +41 -0
  284. package/dist/heart/mailbox/mailbox-supervision.js +131 -0
  285. package/dist/heart/mailbox/mailbox-types.js +27 -0
  286. package/dist/heart/mailbox/mailbox-view.js +197 -0
  287. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  288. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  289. package/dist/heart/mailbox/readers/mail.js +375 -0
  290. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  291. package/dist/heart/mailbox/readers/sessions.js +231 -0
  292. package/dist/heart/mailbox/readers/shared.js +111 -0
  293. package/dist/heart/mcp/mcp-server.js +760 -0
  294. package/dist/heart/migrate-config.js +100 -0
  295. package/dist/heart/model-capabilities.js +83 -16
  296. package/dist/heart/orientation-frame.js +376 -0
  297. package/dist/heart/platform.js +81 -0
  298. package/dist/heart/primitives.js +1 -1
  299. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  300. package/dist/heart/private-runtime/index.js +18 -0
  301. package/dist/heart/private-runtime/ledger.js +221 -0
  302. package/dist/heart/private-runtime/policy.js +260 -0
  303. package/dist/heart/private-runtime/types.js +2 -0
  304. package/dist/heart/progress-story.js +1 -1
  305. package/dist/heart/provider-attempt.js +137 -0
  306. package/dist/heart/provider-binding-resolver.js +273 -0
  307. package/dist/heart/provider-credentials.js +449 -0
  308. package/dist/heart/provider-failover.js +311 -0
  309. package/dist/heart/provider-models.js +96 -0
  310. package/dist/heart/provider-ping.js +266 -0
  311. package/dist/heart/provider-readiness-cache.js +119 -0
  312. package/dist/heart/provider-visibility.js +188 -0
  313. package/dist/heart/providers/anthropic-token.js +131 -0
  314. package/dist/heart/providers/anthropic.js +248 -67
  315. package/dist/heart/providers/azure.js +23 -11
  316. package/dist/heart/providers/error-classification.js +129 -0
  317. package/dist/heart/providers/github-copilot.js +38 -39
  318. package/dist/heart/providers/minimax-vlm.js +189 -0
  319. package/dist/heart/providers/minimax.js +26 -8
  320. package/dist/heart/providers/openai-codex-token.js +349 -0
  321. package/dist/heart/providers/openai-codex.js +55 -40
  322. package/dist/heart/providers/openai-compatible.js +177 -0
  323. package/dist/heart/reach-channel.js +85 -0
  324. package/dist/heart/reply-style.js +52 -0
  325. package/dist/heart/run-ledger.js +247 -0
  326. package/dist/heart/runtime-capability-check.js +170 -0
  327. package/dist/heart/runtime-credentials.js +608 -0
  328. package/dist/heart/runtime-cwd.js +87 -0
  329. package/dist/heart/sense-truth.js +24 -4
  330. package/dist/heart/session-activity.js +94 -24
  331. package/dist/heart/session-events.js +1521 -0
  332. package/dist/heart/session-playback-cli-main.js +5 -0
  333. package/dist/heart/session-playback-cli.js +36 -0
  334. package/dist/heart/session-playback.js +231 -0
  335. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  336. package/dist/heart/session-redaction-repair.js +552 -0
  337. package/dist/heart/session-stats-cli-main.js +5 -0
  338. package/dist/heart/session-stats.js +183 -0
  339. package/dist/heart/session-transcript.js +133 -0
  340. package/dist/heart/shelf-claims.js +78 -0
  341. package/dist/heart/shepherd/custody-types.js +2 -0
  342. package/dist/heart/shepherd/mandates.js +352 -0
  343. package/dist/heart/shepherd/operation-commands.js +19 -0
  344. package/dist/heart/shepherd/operations.js +135 -0
  345. package/dist/heart/shepherd/supervision.js +114 -0
  346. package/dist/heart/shepherd/types.js +2 -0
  347. package/dist/heart/shepherd-config.js +123 -0
  348. package/dist/heart/source-grounding.js +313 -0
  349. package/dist/heart/start-of-turn-packet.js +372 -0
  350. package/dist/heart/steward-policy.js +656 -0
  351. package/dist/heart/streaming.js +631 -207
  352. package/dist/heart/structured-output.js +196 -0
  353. package/dist/heart/sync-classification.js +176 -0
  354. package/dist/heart/sync-health.js +152 -0
  355. package/dist/heart/sync.js +726 -0
  356. package/dist/heart/target-resolution.js +11 -7
  357. package/dist/heart/tempo.js +93 -0
  358. package/dist/heart/temporal-view.js +41 -0
  359. package/dist/heart/timeouts.js +101 -0
  360. package/dist/heart/tool-activity-callbacks.js +59 -0
  361. package/dist/heart/tool-approval.js +382 -0
  362. package/dist/heart/tool-description.js +155 -0
  363. package/dist/heart/tool-friction.js +55 -0
  364. package/dist/heart/tool-loop.js +206 -0
  365. package/dist/heart/tool-output-budget.js +41 -0
  366. package/dist/heart/turn-context.js +496 -0
  367. package/dist/heart/turn-execution-lease.js +30 -0
  368. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  369. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  370. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  371. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  372. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  373. package/dist/heart/versioning/release-sources.js +173 -0
  374. package/dist/heart/versioning/self-update-defaults.js +294 -0
  375. package/dist/heart/versioning/self-update.js +196 -0
  376. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  377. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  378. package/dist/heart/versioning/update-hooks.js +154 -0
  379. package/dist/heart/versioning/update-state.js +126 -0
  380. package/dist/heart/versioning/updater-launchd.js +150 -0
  381. package/dist/heart/versioning/version-intent.js +114 -0
  382. package/dist/heart/work-card.js +380 -0
  383. package/dist/mailbox-ui/assets/index-Dbska1tZ.js +1 -0
  384. package/dist/mailbox-ui/assets/index-DsiKaPyH.css +1 -0
  385. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  386. package/dist/mailbox-ui/index.html +16 -0
  387. package/dist/mailroom/attention.js +167 -0
  388. package/dist/mailroom/autonomy.js +209 -0
  389. package/dist/mailroom/blob-store.js +889 -0
  390. package/dist/mailroom/body-cache.js +61 -0
  391. package/dist/mailroom/cache-sync-cli.js +58 -0
  392. package/dist/mailroom/core.js +803 -0
  393. package/dist/mailroom/entry.js +160 -0
  394. package/dist/mailroom/file-store.js +568 -0
  395. package/dist/mailroom/hosted-cache-sync.js +384 -0
  396. package/dist/mailroom/mbox-import.js +393 -0
  397. package/dist/mailroom/migration.js +164 -0
  398. package/dist/mailroom/outbound.js +380 -0
  399. package/dist/mailroom/policy.js +263 -0
  400. package/dist/mailroom/reader.js +292 -0
  401. package/dist/mailroom/search-cache.js +513 -0
  402. package/dist/mailroom/search-relevance.js +319 -0
  403. package/dist/mailroom/smtp-ingress.js +176 -0
  404. package/dist/mailroom/source-state.js +176 -0
  405. package/dist/mailroom/thread.js +109 -0
  406. package/dist/mailroom/travel-extract.js +89 -0
  407. package/dist/mind/bundle-manifest.js +25 -2
  408. package/dist/mind/context.js +328 -139
  409. package/dist/mind/desk-section.js +362 -0
  410. package/dist/mind/diary-integrity.js +60 -0
  411. package/dist/mind/{memory.js → diary.js} +68 -77
  412. package/dist/mind/embedding-provider.js +60 -0
  413. package/dist/mind/file-state.js +179 -0
  414. package/dist/mind/friend-link-codes.js +209 -0
  415. package/dist/mind/friend-merge.js +336 -0
  416. package/dist/mind/house-names.js +43 -0
  417. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  418. package/dist/mind/obligation-steering.js +199 -3
  419. package/dist/mind/outbound-record.js +168 -0
  420. package/dist/mind/pending.js +36 -10
  421. package/dist/mind/prompt-budget.js +479 -0
  422. package/dist/mind/prompt-refresh.js +3 -2
  423. package/dist/mind/prompt.js +1152 -206
  424. package/dist/mind/provenance-trust.js +26 -0
  425. package/dist/mind/record-paths.js +312 -0
  426. package/dist/mind/scrutiny.js +173 -0
  427. package/dist/mind/session-transaction.js +622 -0
  428. package/dist/nerves/cli-logging.js +7 -1
  429. package/dist/nerves/coverage/audit-rules.js +15 -6
  430. package/dist/nerves/coverage/audit.js +28 -2
  431. package/dist/nerves/coverage/cli.js +1 -1
  432. package/dist/nerves/coverage/contract.js +5 -5
  433. package/dist/nerves/coverage/file-completeness.js +143 -5
  434. package/dist/nerves/coverage/run-artifacts.js +55 -35
  435. package/dist/nerves/coverage/source-scanner.js +4 -4
  436. package/dist/nerves/event-buffer.js +111 -0
  437. package/dist/nerves/index.js +293 -9
  438. package/dist/nerves/observation.js +20 -0
  439. package/dist/nerves/redact.js +79 -0
  440. package/dist/nerves/review/cli-main.js +5 -0
  441. package/dist/nerves/review/cli.js +156 -0
  442. package/dist/nerves/review/core.js +159 -0
  443. package/dist/nerves/runtime.js +17 -1
  444. package/dist/repertoire/ado-client.js +15 -56
  445. package/dist/repertoire/ado-semantic.js +16 -10
  446. package/dist/repertoire/api-client.js +97 -0
  447. package/dist/repertoire/bitwarden-store.js +1199 -0
  448. package/dist/repertoire/bundle-templates.js +71 -0
  449. package/dist/repertoire/bw-installer.js +231 -0
  450. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  451. package/dist/repertoire/coding/context-pack.js +331 -0
  452. package/dist/repertoire/coding/feedback.js +146 -34
  453. package/dist/repertoire/coding/index.js +15 -3
  454. package/dist/repertoire/coding/manager.js +159 -10
  455. package/dist/repertoire/coding/spawner.js +40 -11
  456. package/dist/repertoire/coding/tools.js +182 -18
  457. package/dist/repertoire/coding/workbench-client.js +272 -0
  458. package/dist/repertoire/coding/workbench-manager.js +346 -0
  459. package/dist/repertoire/commerce-errors.js +109 -0
  460. package/dist/repertoire/commerce-self-test.js +156 -0
  461. package/dist/repertoire/credential-access.js +183 -0
  462. package/dist/repertoire/desk/classifier.js +362 -0
  463. package/dist/repertoire/duffel-client.js +185 -0
  464. package/dist/repertoire/github-client.js +14 -55
  465. package/dist/repertoire/graph-client.js +11 -52
  466. package/dist/repertoire/guardrails.js +1196 -20
  467. package/dist/repertoire/house-sweep.js +471 -0
  468. package/dist/repertoire/mcp-client.js +58 -5
  469. package/dist/repertoire/mcp-manager.js +427 -139
  470. package/dist/repertoire/mcp-tools.js +132 -0
  471. package/dist/repertoire/mcp-write-guard.js +46 -0
  472. package/dist/repertoire/plugin-mcp.js +175 -0
  473. package/dist/repertoire/plugins.js +253 -0
  474. package/dist/repertoire/relationship-authorization.js +322 -0
  475. package/dist/repertoire/sanctuary-container-policy.js +50 -0
  476. package/dist/repertoire/shell-sessions.js +134 -0
  477. package/dist/repertoire/skills.js +48 -4
  478. package/dist/repertoire/stripe-client.js +131 -0
  479. package/dist/repertoire/tool-arguments.js +182 -0
  480. package/dist/repertoire/tool-results.js +29 -0
  481. package/dist/repertoire/tools-a2a.js +742 -0
  482. package/dist/repertoire/tools-attachments.js +322 -0
  483. package/dist/repertoire/tools-awaiting.js +897 -0
  484. package/dist/repertoire/tools-base.js +83 -1168
  485. package/dist/repertoire/tools-bluebubbles.js +2 -0
  486. package/dist/repertoire/tools-bridge.js +144 -0
  487. package/dist/repertoire/tools-bundle.js +995 -0
  488. package/dist/repertoire/tools-commerce.js +253 -0
  489. package/dist/repertoire/tools-config.js +186 -0
  490. package/dist/repertoire/tools-continuity.js +588 -0
  491. package/dist/repertoire/tools-credential.js +383 -0
  492. package/dist/repertoire/tools-escalation.js +84 -0
  493. package/dist/repertoire/tools-evolution.js +527 -0
  494. package/dist/repertoire/tools-files.js +362 -0
  495. package/dist/repertoire/tools-flight.js +290 -0
  496. package/dist/repertoire/tools-flow.js +119 -0
  497. package/dist/repertoire/tools-friend-link.js +57 -0
  498. package/dist/repertoire/tools-github.js +3 -8
  499. package/dist/repertoire/tools-habits.js +103 -0
  500. package/dist/repertoire/tools-house-care.js +174 -0
  501. package/dist/repertoire/tools-mail.js +1828 -0
  502. package/dist/repertoire/tools-notes.js +501 -0
  503. package/dist/repertoire/tools-obligations.js +182 -0
  504. package/dist/repertoire/tools-orientation.js +31 -0
  505. package/dist/repertoire/tools-record.js +482 -0
  506. package/dist/repertoire/tools-rsvp.js +139 -0
  507. package/dist/repertoire/tools-runtime.js +238 -0
  508. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  509. package/dist/repertoire/tools-session.js +1141 -0
  510. package/dist/repertoire/tools-shell.js +154 -0
  511. package/dist/repertoire/tools-shepherd-guidance.js +171 -0
  512. package/dist/repertoire/tools-shepherd.js +325 -0
  513. package/dist/repertoire/tools-steward-policy.js +147 -0
  514. package/dist/repertoire/tools-stripe.js +224 -0
  515. package/dist/repertoire/tools-surface.js +369 -0
  516. package/dist/repertoire/tools-teams.js +50 -39
  517. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  518. package/dist/repertoire/tools-travel.js +125 -0
  519. package/dist/repertoire/tools-trip.js +982 -0
  520. package/dist/repertoire/tools-unraid.js +556 -0
  521. package/dist/repertoire/tools-user-profile.js +146 -0
  522. package/dist/repertoire/tools-vault.js +40 -0
  523. package/dist/repertoire/tools-voice-local.js +198 -0
  524. package/dist/repertoire/tools-voice.js +145 -0
  525. package/dist/repertoire/tools.js +519 -156
  526. package/dist/repertoire/travel-api-client.js +360 -0
  527. package/dist/repertoire/unraid-client.js +155 -0
  528. package/dist/repertoire/unraid-restart.js +339 -0
  529. package/dist/repertoire/user-profile.js +131 -0
  530. package/dist/repertoire/vault-setup.js +246 -0
  531. package/dist/repertoire/vault-unlock.js +686 -0
  532. package/dist/rsvp/aisleplanner-client.js +354 -0
  533. package/dist/rsvp/cli.js +936 -0
  534. package/dist/rsvp/config.js +327 -0
  535. package/dist/rsvp/cutover.js +453 -0
  536. package/dist/rsvp/diagnostics.js +232 -0
  537. package/dist/rsvp/diff-renderer.js +176 -0
  538. package/dist/rsvp/habit-policy.js +110 -0
  539. package/dist/rsvp/habit-stage.js +123 -0
  540. package/dist/rsvp/incident-bundle.js +97 -0
  541. package/dist/rsvp/migration.js +204 -0
  542. package/dist/rsvp/native-habit-runner.js +630 -0
  543. package/dist/rsvp/outbound-state.js +628 -0
  544. package/dist/rsvp/query.js +118 -0
  545. package/dist/rsvp/replay.js +233 -0
  546. package/dist/rsvp/snapshot.js +232 -0
  547. package/dist/rsvp/spend-ledger.js +175 -0
  548. package/dist/scripts/claude-code-hook.js +41 -0
  549. package/dist/scripts/claude-code-stop-hook.js +47 -0
  550. package/dist/senses/a2a-entry.js +140 -0
  551. package/dist/senses/acp-server.js +386 -0
  552. package/dist/senses/attention-queue.js +186 -0
  553. package/dist/senses/await-turn-message.js +65 -0
  554. package/dist/senses/bluebubbles/active-turns.js +216 -0
  555. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  556. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  557. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +393 -43
  558. package/dist/senses/bluebubbles/context-packet.js +207 -0
  559. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  560. package/dist/senses/bluebubbles/entry.js +90 -0
  561. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  562. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  563. package/dist/senses/bluebubbles/index.js +4054 -0
  564. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  565. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  566. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  567. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  568. package/dist/senses/bluebubbles/outbound-state.js +335 -0
  569. package/dist/senses/bluebubbles/processed-log.js +133 -0
  570. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  571. package/dist/senses/bluebubbles/replay.js +284 -0
  572. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  573. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  574. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  575. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  576. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  577. package/dist/senses/cli/bracketed-paste.js +82 -0
  578. package/dist/senses/cli/image-paste.js +287 -0
  579. package/dist/senses/cli/image-ref-navigation.js +75 -0
  580. package/dist/senses/cli/ink-app.js +156 -0
  581. package/dist/senses/cli/inline-diff.js +64 -0
  582. package/dist/senses/cli/input-keys.js +174 -0
  583. package/dist/senses/cli/kill-ring.js +86 -0
  584. package/dist/senses/cli/message-list.js +51 -0
  585. package/dist/senses/cli/ouro-tui.js +607 -0
  586. package/dist/senses/cli/spinner-imperative.js +135 -0
  587. package/dist/senses/cli/spinner.js +101 -0
  588. package/dist/senses/cli/status-line.js +60 -0
  589. package/dist/senses/cli/streaming-markdown.js +526 -0
  590. package/dist/senses/cli/tool-display.js +85 -0
  591. package/dist/senses/cli/tool-render.js +85 -0
  592. package/dist/senses/cli/tui-store.js +241 -0
  593. package/dist/senses/cli/virtual-list.js +35 -0
  594. package/dist/senses/cli-entry.js +60 -8
  595. package/dist/senses/cli.js +570 -309
  596. package/dist/senses/commands.js +66 -3
  597. package/dist/senses/context-packet-ledger.js +371 -0
  598. package/dist/senses/context-packets.js +154 -0
  599. package/dist/senses/habit-lifecycle-guard.js +24 -0
  600. package/dist/senses/habit-turn-message.js +160 -0
  601. package/dist/senses/ingress-evidence.js +2 -0
  602. package/dist/senses/mail-entry.js +66 -0
  603. package/dist/senses/mail.js +524 -0
  604. package/dist/senses/pipeline.js +1158 -204
  605. package/dist/senses/private-runtime-worker.js +857 -0
  606. package/dist/senses/private-runtime.js +1627 -0
  607. package/dist/senses/proactive-content-guard.js +51 -0
  608. package/dist/senses/root-host-approval-port.js +345 -0
  609. package/dist/senses/root-host-approval-runtime.js +393 -0
  610. package/dist/senses/sanctuary-authority-resident.js +102 -0
  611. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  612. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  613. package/dist/senses/sanctuary-grounding.js +118 -0
  614. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  615. package/dist/senses/sanctuary-health-acceptance-probe.js +786 -0
  616. package/dist/senses/sanctuary-health-runner.js +106 -0
  617. package/dist/senses/sanctuary-health.js +442 -0
  618. package/dist/senses/sanctuary-house.js +97 -0
  619. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  620. package/dist/senses/sanctuary-interactive-control.js +410 -0
  621. package/dist/senses/sanctuary-media-catalog-contract.js +268 -0
  622. package/dist/senses/sanctuary-media-optimization.js +517 -0
  623. package/dist/senses/sanctuary-runtime.js +390 -0
  624. package/dist/senses/sanctuary-sab.js +85 -0
  625. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  626. package/dist/senses/shared-turn.js +832 -0
  627. package/dist/senses/shepherd/agent-presentation.js +88 -0
  628. package/dist/senses/shepherd/attention-page.js +166 -0
  629. package/dist/senses/shepherd/attention-sidebar.js +76 -0
  630. package/dist/senses/shepherd/attention.js +295 -0
  631. package/dist/senses/shepherd/checkin-config.js +76 -0
  632. package/dist/senses/shepherd/checkin-store.js +386 -0
  633. package/dist/senses/shepherd/client.js +196 -0
  634. package/dist/senses/shepherd/cmux.js +483 -0
  635. package/dist/senses/shepherd/composer.js +336 -0
  636. package/dist/senses/shepherd/copilot-app.js +648 -0
  637. package/dist/senses/shepherd/feedback-reply.js +108 -0
  638. package/dist/senses/shepherd/feedback-source.js +20 -0
  639. package/dist/senses/shepherd/feedback-store.js +331 -0
  640. package/dist/senses/shepherd/feedback-submit.js +182 -0
  641. package/dist/senses/shepherd/feedback-worker.js +208 -0
  642. package/dist/senses/shepherd/guidance.js +273 -0
  643. package/dist/senses/shepherd/herdr.js +427 -0
  644. package/dist/senses/shepherd/host.js +17 -0
  645. package/dist/senses/shepherd/human-decision-guard.js +29 -0
  646. package/dist/senses/shepherd/judge-evaluation-command.js +183 -0
  647. package/dist/senses/shepherd/judge-evaluation-entry.js +13 -0
  648. package/dist/senses/shepherd/judge-evaluation.js +155 -0
  649. package/dist/senses/shepherd/judge.js +210 -0
  650. package/dist/senses/shepherd/notice-outbox.js +262 -0
  651. package/dist/senses/shepherd/observation-publisher.js +320 -0
  652. package/dist/senses/shepherd/operations-defaults.js +86 -0
  653. package/dist/senses/shepherd/operations.js +159 -0
  654. package/dist/senses/shepherd/owner-notice.js +489 -0
  655. package/dist/senses/shepherd/prompt-state.js +60 -0
  656. package/dist/senses/shepherd/recovery.js +543 -0
  657. package/dist/senses/shepherd/redact.js +66 -0
  658. package/dist/senses/shepherd/returns.js +79 -0
  659. package/dist/senses/shepherd/sense.js +849 -0
  660. package/dist/senses/shepherd/shepherd-judge-corpus-v1.json +170 -0
  661. package/dist/senses/shepherd/surface.js +123 -0
  662. package/dist/senses/shepherd/target-binding.js +13 -0
  663. package/dist/senses/shepherd/terminal-process.js +147 -0
  664. package/dist/senses/shepherd-entry.js +98 -0
  665. package/dist/senses/surface-tool.js +109 -0
  666. package/dist/senses/teams-entry.js +68 -8
  667. package/dist/senses/teams-image.js +119 -0
  668. package/dist/senses/teams.js +998 -337
  669. package/dist/senses/telegram-admission.js +718 -0
  670. package/dist/senses/telegram-approval-runtime.js +793 -0
  671. package/dist/senses/telegram-attachments.js +186 -0
  672. package/dist/senses/telegram-audit-ledger.js +220 -0
  673. package/dist/senses/telegram-authority-transport.js +231 -0
  674. package/dist/senses/telegram-client.js +1755 -0
  675. package/dist/senses/telegram-effect-adapter.js +904 -0
  676. package/dist/senses/telegram-entry.js +83 -0
  677. package/dist/senses/telegram-handoff.js +154 -0
  678. package/dist/senses/telegram.js +2474 -0
  679. package/dist/senses/trust-gate.js +104 -9
  680. package/dist/senses/voice/audio-playback.js +237 -0
  681. package/dist/senses/voice/audio-routing.js +119 -0
  682. package/dist/senses/voice/call-auth.js +250 -0
  683. package/dist/senses/voice/elevenlabs.js +202 -0
  684. package/dist/senses/voice/floor-control.js +431 -0
  685. package/dist/senses/voice/floor-controller.js +115 -0
  686. package/dist/senses/voice/golden-path.js +116 -0
  687. package/dist/senses/voice/index.js +29 -0
  688. package/dist/senses/voice/local-audio-control.js +344 -0
  689. package/dist/senses/voice/local-audio-devices.js +516 -0
  690. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  691. package/dist/senses/voice/local-audio-identity.js +103 -0
  692. package/dist/senses/voice/local-audio-join.js +325 -0
  693. package/dist/senses/voice/local-audio-mute.js +199 -0
  694. package/dist/senses/voice/local-audio-notify.js +124 -0
  695. package/dist/senses/voice/local-audio-prompts.js +116 -0
  696. package/dist/senses/voice/local-audio-transport.js +427 -0
  697. package/dist/senses/voice/local-audio.js +281 -0
  698. package/dist/senses/voice/local-media-stream.js +145 -0
  699. package/dist/senses/voice/meeting.js +113 -0
  700. package/dist/senses/voice/outbound.js +190 -0
  701. package/dist/senses/voice/phone.js +33 -0
  702. package/dist/senses/voice/playback.js +139 -0
  703. package/dist/senses/voice/process-guards.js +51 -0
  704. package/dist/senses/voice/realtime-eval.js +496 -0
  705. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  706. package/dist/senses/voice/realtime-trace.js +531 -0
  707. package/dist/senses/voice/transcript.js +70 -0
  708. package/dist/senses/voice/turn.js +191 -0
  709. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  710. package/dist/senses/voice/twilio-phone.js +5454 -0
  711. package/dist/senses/voice/types.js +2 -0
  712. package/dist/senses/voice/whisper.js +161 -0
  713. package/dist/senses/voice-entry.js +83 -0
  714. package/dist/senses/voice-realtime-eval-command.js +99 -0
  715. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  716. package/dist/senses/voice-twilio-entry.js +87 -0
  717. package/dist/trips/core.js +138 -0
  718. package/dist/trips/store.js +265 -0
  719. package/dist/util/frontmatter.js +69 -0
  720. package/npm-shrinkwrap.json +8342 -0
  721. package/package.json +76 -13
  722. package/skills/agent-commerce.md +113 -0
  723. package/skills/browser-navigation.md +117 -0
  724. package/skills/commerce-setup-guide.md +116 -0
  725. package/skills/commerce-setup.md +84 -0
  726. package/skills/configure-dev-tools.md +99 -0
  727. package/skills/travel-planning.md +138 -0
  728. package/dist/heart/daemon/auth-flow.js +0 -430
  729. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  730. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  731. package/dist/heart/daemon/update-hooks.js +0 -138
  732. package/dist/heart/obligations.js +0 -191
  733. package/dist/heart/safe-workspace.js +0 -381
  734. package/dist/heart/session-recall.js +0 -116
  735. package/dist/mind/friends/channel.js +0 -84
  736. package/dist/mind/friends/group-context.js +0 -144
  737. package/dist/mind/friends/resolver.js +0 -84
  738. package/dist/mind/friends/store-file.js +0 -190
  739. package/dist/mind/friends/store.js +0 -4
  740. package/dist/mind/friends/tokens.js +0 -26
  741. package/dist/mind/friends/trust-explanation.js +0 -74
  742. package/dist/mind/friends/types.js +0 -29
  743. package/dist/repertoire/tasks/board.js +0 -134
  744. package/dist/repertoire/tasks/index.js +0 -224
  745. package/dist/repertoire/tasks/lifecycle.js +0 -80
  746. package/dist/repertoire/tasks/middleware.js +0 -65
  747. package/dist/repertoire/tasks/parser.js +0 -173
  748. package/dist/repertoire/tasks/scanner.js +0 -132
  749. package/dist/repertoire/tasks/transitions.js +0 -144
  750. package/dist/senses/bluebubbles-entry.js +0 -13
  751. package/dist/senses/bluebubbles.js +0 -1181
  752. package/dist/senses/debug-activity.js +0 -154
  753. package/dist/senses/inner-dialog-worker.js +0 -90
  754. package/dist/senses/inner-dialog.js +0 -525
  755. package/subagents/README.md +0 -7
  756. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  757. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  758. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  759. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  760. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  761. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  762. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  763. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  764. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  765. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  766. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  767. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  768. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  769. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  770. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  771. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  772. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OUTBOX_ERROR_INVALID = exports.OUTBOX_ERROR_REFUSED = exports.OUTBOX_METHODS = void 0;
4
+ exports.isOutboxMethod = isOutboxMethod;
5
+ exports.encodeOutboxCommand = encodeOutboxCommand;
6
+ exports.parseOutboxCommand = parseOutboxCommand;
7
+ exports.handleOutboxCommand = handleOutboxCommand;
8
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
9
+ const escalation_grants_1 = require("./escalation-grants");
10
+ const resolution_proof_1 = require("./resolution-proof");
11
+ const outbox_store_1 = require("./outbox-store");
12
+ const failure_reports_1 = require("../heart/failure-reports");
13
+ const runtime_1 = require("../nerves/runtime");
14
+ /**
15
+ * The outbox methods ride the same sealed, signed chat envelope as `a2a message`: the request is a `message` whose
16
+ * signed text is `{"ouro":"a2a-method","method":...,"params":...}`, posted under the JSON-RPC method of the same name.
17
+ * The server verifies the sender exactly as it does for a chat (unseal, pinned key, signature, replay guard, friend
18
+ * record), requires the signed method to equal the JSON-RPC method, and then decides access itself from the verified
19
+ * friend record. A sender can only ever name its own outbox: no parameter selects another peer's.
20
+ *
21
+ * outbox/list { since?: string, limit?: number } -> { entries, nextCursor, more } any active friend, own outbox
22
+ * outbox/ack { ids: string[] } -> { acked, unknown } any active friend, own outbox
23
+ * report/resolve { id, version, note, resolvedAt, proof } -> { id, status: "resolved" } escalation holders, own reports
24
+ * relay/contact {} -> { contact: { url, handle, sendCredential } | null } active friend or family
25
+ */
26
+ exports.OUTBOX_METHODS = ["outbox/list", "outbox/ack", "report/resolve", "relay/contact"];
27
+ exports.OUTBOX_ERROR_REFUSED = -32003;
28
+ exports.OUTBOX_ERROR_INVALID = -32602;
29
+ const MAX_ACK_IDS = 100;
30
+ function isOutboxMethod(method) {
31
+ return typeof method === "string" && exports.OUTBOX_METHODS.includes(method);
32
+ }
33
+ function encodeOutboxCommand(method, params) {
34
+ return JSON.stringify({ ouro: "a2a-method", method, params });
35
+ }
36
+ function parseOutboxCommand(text) {
37
+ let parsed;
38
+ try {
39
+ parsed = JSON.parse(text);
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
45
+ return null;
46
+ const command = parsed;
47
+ if (command.ouro !== "a2a-method" || !isOutboxMethod(command.method))
48
+ return null;
49
+ const params = command.params === undefined ? {} : command.params;
50
+ if (!params || typeof params !== "object" || Array.isArray(params))
51
+ return null;
52
+ return { method: command.method, params: params };
53
+ }
54
+ const refuse = (message) => ({ ok: false, code: exports.OUTBOX_ERROR_REFUSED, message });
55
+ const invalid = (message) => ({ ok: false, code: exports.OUTBOX_ERROR_INVALID, message });
56
+ /** Runs one verified outbox command for `friend`. `friend` must be the record found by the signed sender DID. */
57
+ async function handleOutboxCommand(input) {
58
+ const { agentRoot, friend, method, params } = input;
59
+ if (!friend || friend.admissionState !== "active") {
60
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_outbox_refused", message: "refused an outbox call from a peer that is not an active friend", meta: { method, friendId: friend?.id ?? null } });
61
+ return refuse("only an active friend can use its outbox");
62
+ }
63
+ if (method === "relay/contact") {
64
+ // The send credential lets its holder queue messages here, so only peers trusted as friend or family get it.
65
+ if (friend.trustLevel !== "friend" && friend.trustLevel !== "family") {
66
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_relay_contact_refused", message: "refused relay/contact to a peer below friend trust", meta: { friendId: friend.id, trustLevel: friend.trustLevel ?? null } });
67
+ return refuse("relay/contact needs friend or family trust");
68
+ }
69
+ const contact = input.relayContact ?? null;
70
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.a2a_relay_contact_shared", message: "answered relay/contact", meta: { friendId: friend.id, hasRelay: contact !== null } });
71
+ return { ok: true, result: { contact: contact ? { url: contact.url, handle: contact.handle, sendCredential: contact.sendCredential } : null } };
72
+ }
73
+ const outbox = new outbox_store_1.FileOutboxStore(agentRoot);
74
+ if (method === "outbox/list") {
75
+ const { since, limit } = params;
76
+ if (since !== undefined && typeof since !== "string")
77
+ return invalid("since must be a string cursor");
78
+ if (limit !== undefined && (typeof limit !== "number" || !Number.isFinite(limit)))
79
+ return invalid("limit must be a number");
80
+ return { ok: true, result: { ...outbox.list(friend.id, { ...(since !== undefined ? { since } : {}), ...(limit !== undefined ? { limit: Math.min(limit, outbox_store_1.OUTBOX_LIST_MAX_LIMIT) } : {}) }) } };
81
+ }
82
+ if (method === "outbox/ack") {
83
+ const { ids } = params;
84
+ if (!Array.isArray(ids) || ids.length === 0 || ids.length > MAX_ACK_IDS || ids.some((id) => typeof id !== "string"))
85
+ return invalid(`ids must be 1 to ${MAX_ACK_IDS} strings`);
86
+ return { ok: true, result: { ...outbox.ack(friend.id, ids) } };
87
+ }
88
+ if (!(0, escalation_grants_1.holdsEscalation)(agentRoot, friend, input.now)) {
89
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_report_resolve_refused", message: "refused report/resolve from a peer without the escalation grant", meta: { friendId: friend.id } });
90
+ return refuse("report/resolve needs the escalation grant");
91
+ }
92
+ const { id, version, note, resolvedAt, proof } = params;
93
+ if (typeof id !== "string" || typeof version !== "string" || typeof note !== "string" || typeof resolvedAt !== "string")
94
+ return invalid("id, version, note and resolvedAt must be strings");
95
+ // The key is the DID the operator pinned in the root-owned grant, never the friend record; and the A2A-verified caller must be that same DID.
96
+ const holderDid = (0, escalation_grants_1.pinnedHolderDid)(agentRoot, friend.id, input.now);
97
+ if (!holderDid || input.verifiedDid !== holderDid) {
98
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_report_resolve_refused", message: "refused report/resolve from a caller whose verified DID is not the pinned holder DID", meta: { friendId: friend.id } });
99
+ return refuse("report not resolved: the caller is not the pinned escalation holder");
100
+ }
101
+ const checked = (0, resolution_proof_1.verifyResolution)({ sodium: await (0, a2a_client_1.ready)(), claim: { reportId: id, version, note, resolvedAt }, proof, holderDid });
102
+ if (!checked.ok)
103
+ return refuse(`report not resolved: the resolution is not signed by your key (${checked.reason})`);
104
+ const resolved = await (0, failure_reports_1.resolveFailureReport)(agentRoot, { id, version, note, byFriendId: friend.id, resolvedAt, proof }, input.now);
105
+ return resolved.ok ? { ok: true, result: { id: resolved.id, status: resolved.status } } : refuse(`report not resolved: ${resolved.reason}`);
106
+ }
@@ -0,0 +1,167 @@
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.FileA2APinStore = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const node_crypto_1 = require("node:crypto");
40
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
41
+ const runtime_1 = require("../nerves/runtime");
42
+ function pinFileName(fromAgentId) {
43
+ return `${(0, node_crypto_1.createHash)("sha256").update(fromAgentId).digest("hex")}.json`;
44
+ }
45
+ function pinnedFromStored(stored, ed25519Pub) {
46
+ return {
47
+ did: stored.did,
48
+ ed25519Pub,
49
+ ...(typeof stored.rotatedAt === "string" ? { rotatedAt: stored.rotatedAt } : {}),
50
+ ...(typeof stored.retiredBy === "string" ? { retiredBy: stored.retiredBy } : {}),
51
+ };
52
+ }
53
+ class FileA2APinStore {
54
+ dir;
55
+ cache = new Map();
56
+ constructor(agentRoot) {
57
+ this.dir = path.join(agentRoot, "state", "a2a", "pins");
58
+ fs.mkdirSync(this.dir, { recursive: true });
59
+ this.loadExisting();
60
+ (0, runtime_1.emitNervesEvent)({
61
+ component: "channels",
62
+ event: "channel.a2a_pin_store_init",
63
+ message: "initialized durable A2A pin store",
64
+ meta: { dir: this.dir, pins: this.cache.size },
65
+ });
66
+ }
67
+ get size() {
68
+ return this.cache.size;
69
+ }
70
+ get(fromAgentId) {
71
+ if (!fromAgentId)
72
+ return undefined;
73
+ const pinned = this.cache.get(fromAgentId);
74
+ if (!pinned)
75
+ return undefined;
76
+ (0, runtime_1.emitNervesEvent)({
77
+ component: "channels",
78
+ event: "channel.a2a_pin_hit",
79
+ message: "A2A pin hit",
80
+ meta: { fromAgentId, did: pinned.did },
81
+ });
82
+ return pinned;
83
+ }
84
+ set(fromAgentId, pinned) {
85
+ // An empty-string DID is never a matchable key (security: it can never index a
86
+ // pin). Stay inert rather than writing an unkeyed pin file.
87
+ if (!fromAgentId)
88
+ return;
89
+ const existed = this.cache.has(fromAgentId);
90
+ this.write(fromAgentId, pinned);
91
+ (0, runtime_1.emitNervesEvent)({
92
+ component: "channels",
93
+ event: "channel.a2a_pin_set",
94
+ message: "set durable A2A pin",
95
+ meta: { fromAgentId, did: pinned.did, rotated: existed },
96
+ });
97
+ }
98
+ /** Keep a tombstone under `fromAgentId`: the old DID and key, marked retired in favour of `retiredBy`. friends
99
+ * calls this after it moves the pin to the successor DID; `receiveShare` then refuses the old DID as `retired_pin`. */
100
+ retire(fromAgentId, retiredBy, rotatedAt) {
101
+ const pinned = this.cache.get(fromAgentId);
102
+ if (!fromAgentId || !pinned)
103
+ return;
104
+ this.write(fromAgentId, { ...pinned, retiredBy, rotatedAt });
105
+ (0, runtime_1.emitNervesEvent)({
106
+ level: "warn",
107
+ component: "channels",
108
+ event: "channel.a2a_pin_retired",
109
+ message: "retired an A2A pin after a verified rotation",
110
+ meta: { fromAgentId, retiredBy, rotatedAt },
111
+ });
112
+ }
113
+ /** The DID whose retired pin names `did` as its successor, if any (a rotation chain followed backwards). */
114
+ predecessorOf(did) {
115
+ for (const [fromAgentId, pinned] of this.cache) {
116
+ if (pinned.retiredBy === did)
117
+ return fromAgentId;
118
+ }
119
+ return undefined;
120
+ }
121
+ /** Persist a pin (its DID, which may differ from fromAgentId, its key, and the rotation fields) and cache it. */
122
+ write(fromAgentId, pinned) {
123
+ const stored = {
124
+ fromAgentId,
125
+ did: pinned.did,
126
+ pinnedKey: (0, a2a_client_1.base58btcEncode)(pinned.ed25519Pub),
127
+ ...(pinned.rotatedAt !== undefined ? { rotatedAt: pinned.rotatedAt } : {}),
128
+ ...(pinned.retiredBy !== undefined ? { retiredBy: pinned.retiredBy } : {}),
129
+ };
130
+ fs.writeFileSync(path.join(this.dir, pinFileName(fromAgentId)), `${JSON.stringify(stored, null, 2)}\n`, "utf-8");
131
+ this.cache.set(fromAgentId, pinnedFromStored(stored, pinned.ed25519Pub));
132
+ }
133
+ /** Reload every persisted pin from disk into the in-memory cache (the restart
134
+ * replay). Corrupt/undecodable files are skipped so one bad file can never
135
+ * wedge the store. */
136
+ loadExisting() {
137
+ let entries;
138
+ try {
139
+ entries = fs.readdirSync(this.dir);
140
+ }
141
+ catch {
142
+ /* v8 ignore next -- the constructor mkdirSync's the dir before this runs; unreadable dir is unreachable in practice @preserve */
143
+ return;
144
+ }
145
+ for (const name of entries) {
146
+ if (!name.endsWith(".json"))
147
+ continue;
148
+ let stored;
149
+ try {
150
+ stored = JSON.parse(fs.readFileSync(path.join(this.dir, name), "utf-8"));
151
+ }
152
+ catch {
153
+ continue;
154
+ }
155
+ // `fromAgentId` is the cache key; fall back to `did` for any pre-rotation
156
+ // file written before the key/did split (back-compat).
157
+ const key = stored.fromAgentId ?? stored.did;
158
+ if (!key || !stored.did || !stored.pinnedKey)
159
+ continue;
160
+ const ed25519Pub = (0, a2a_client_1.base58btcDecode)(stored.pinnedKey);
161
+ if (!ed25519Pub)
162
+ continue;
163
+ this.cache.set(key, pinnedFromStored(stored, ed25519Pub));
164
+ }
165
+ }
166
+ }
167
+ exports.FileA2APinStore = FileA2APinStore;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.receiveRefusal = receiveRefusal;
4
+ exports.receiveRefusalError = receiveRefusalError;
5
+ exports.isRetryableReceiveRefusal = isRetryableReceiveRefusal;
6
+ const runtime_1 = require("../nerves/runtime");
7
+ const UPGRADE = "Upgrade the sending agent's harness (ouro) and send again.";
8
+ const RESEND = "Send it again as a new message.";
9
+ const REFUSALS = {
10
+ malformed_message: { message: "the message is not a sealed A2A data part", next: UPGRADE, retry: false },
11
+ malformed_plaintext: { message: "the sealed message did not open to a valid envelope", next: UPGRADE, retry: false },
12
+ unseal_failed: { message: "the message could not be opened with this agent's key", next: "Fetch this agent's card again (its key may have changed) and resend.", retry: false },
13
+ recipient_mismatch: { message: "the message was sealed to a different agent", next: "Check the recipient's DID and resend.", retry: false },
14
+ signed_recipient_mismatch: { message: "the signed envelope names a different recipient", next: "Check the recipient's DID and resend.", retry: false },
15
+ signed_kind_mismatch: { message: "the signed envelope's kind does not match how it was sealed", next: UPGRADE, retry: false },
16
+ sender_binding_mismatch: { message: "the claimed sender does not match the signer", next: "Send from the identity the message claims.", retry: false },
17
+ malformed_binding: { message: "the envelope's signed binding is malformed", next: UPGRADE, retry: false },
18
+ unbound_envelope: { message: "the envelope has no signed binding (the sender runs an older harness)", next: UPGRADE, retry: false },
19
+ unbound_delegation: { message: "the delegated command has no signed binding (the sender runs an older harness)", next: UPGRADE, retry: false },
20
+ stale_envelope: { message: "the envelope is more than 7 days old or dated in the future", next: `Check the sender's clock. ${RESEND}`, retry: false },
21
+ stale_delegation: { message: "the delegated command is more than 10 minutes old", next: `Check the sender's clock. ${RESEND}`, retry: false },
22
+ replayed: { message: "this message was already received", next: `Nothing to do if it was delivered; otherwise ${RESEND.toLowerCase()}`, retry: false },
23
+ in_flight: { message: "the same message is being handled right now", next: "Retry in a moment.", retry: true },
24
+ resolve_failed: { message: "the sender's DID could not be resolved or pinned (it is not a did:key, its pinned key differs, or a key rotation was refused)", next: "Send from the identity this agent knows you by, or ask the operator to re-link you.", retry: false },
25
+ retired_pin: { message: "the sender's DID was rotated to a successor and no longer verifies", next: "Send from the successor identity.", retry: false },
26
+ bad_signature: { message: "the signature does not verify against the sender's pinned key", next: "Send from the key this agent pinned for you, or ask the operator to re-link you.", retry: false },
27
+ untrusted_source: { message: "this agent does not trust the sender enough for this kind of message", next: "Ask the operator to connect you as a friend.", retry: false },
28
+ import_failed: { message: "the message verified but could not be stored", next: RESEND, retry: false },
29
+ // Mission results (the harness result wire).
30
+ no_mission: { message: "this agent has no mission with that key", next: "Check the mission key; the delegator may have dropped the mission.", retry: false },
31
+ no_delegation: { message: "this agent delegated no task with that request id", next: "Check the request id the delegation gave you.", retry: false },
32
+ assignee_mismatch: { message: "the task was delegated to a different agent", next: "Only the assignee can send this result.", retry: false },
33
+ };
34
+ const UNKNOWN = { message: "the message was refused", next: "Check the agent's logs.", retry: false };
35
+ /** The wording for one refusal reason (an unknown reason gets a generic line). */
36
+ function receiveRefusal(reason) {
37
+ return Object.hasOwn(REFUSALS, reason) ? REFUSALS[reason] : UNKNOWN;
38
+ }
39
+ /** Every `data` object `receiveRefusalError` made in this process, so a caller can tell a real receive refusal from an
40
+ * error that only looks like one (a delegated-command refusal also carries `retry`). */
41
+ const ISSUED = new WeakSet();
42
+ /** The JSON-RPC error text and data for a refused inbound message: `A2A <what> rejected: <reason>. <message>. Next: <next>`. */
43
+ function receiveRefusalError(what, reason) {
44
+ const refusal = receiveRefusal(reason);
45
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_receive_refused", message: "refused an inbound A2A message", meta: { what, reason, retry: refusal.retry } });
46
+ const data = { reason, retry: refusal.retry, next: refusal.next };
47
+ ISSUED.add(data);
48
+ return { message: `A2A ${what} rejected: ${reason}. ${refusal.message}. Next: ${refusal.next}`, data };
49
+ }
50
+ /** True only for the `data` of a refusal made here that says the same message can succeed later (such as `in_flight`). */
51
+ function isRetryableReceiveRefusal(data) {
52
+ return typeof data === "object" && data !== null && ISSUED.has(data) && data.retry === true;
53
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RELAY_REQUEST_TIMEOUT_MS = exports.RelayHttpError = void 0;
4
+ exports.relayRegister = relayRegister;
5
+ exports.relaySend = relaySend;
6
+ exports.relayPull = relayPull;
7
+ exports.relayAck = relayAck;
8
+ exports.relayDeregister = relayDeregister;
9
+ const runtime_1 = require("../nerves/runtime");
10
+ /**
11
+ * The four friends-relay calls the harness makes (ourostack/friends-relay `src/server/http.ts`): register a handle,
12
+ * send an opaque sealed message to a handle, pull a handle's inbox and ack one queued message. The relay is untrusted
13
+ * and content-blind: it only ever carries the sealed A2A message, byte for byte. Every non-2xx answer throws a
14
+ * `RelayHttpError` carrying the relay's status and error code. A 2xx answer that is not a JSON object (the relay
15
+ * always answers one), and a request with no answer within `RELAY_REQUEST_TIMEOUT_MS`, throw too.
16
+ */
17
+ class RelayHttpError extends Error {
18
+ status;
19
+ code;
20
+ /** The answer was the relay's own JSON error (`{ error: "<code>" }`), not a proxy's or a load balancer's page. */
21
+ fromRelay;
22
+ constructor(status, code, fromRelay = false) {
23
+ super(`relay ${status} ${code}`);
24
+ this.status = status;
25
+ this.code = code;
26
+ this.fromRelay = fromRelay;
27
+ }
28
+ }
29
+ exports.RelayHttpError = RelayHttpError;
30
+ exports.RELAY_REQUEST_TIMEOUT_MS = 30_000;
31
+ async function relayRequest(input) {
32
+ const fetchImpl = input.fetchImpl ?? fetch;
33
+ const headers = { "content-type": "application/json" };
34
+ if (input.bearer)
35
+ headers.authorization = `Bearer ${input.bearer}`;
36
+ const response = await fetchImpl(`${input.url.replace(/\/+$/, "")}${input.path}`, {
37
+ method: input.method,
38
+ headers,
39
+ ...(input.body === undefined ? {} : { body: JSON.stringify(input.body) }),
40
+ signal: AbortSignal.timeout(input.timeoutMs ?? exports.RELAY_REQUEST_TIMEOUT_MS),
41
+ });
42
+ const parsed = await response.json().catch(() => undefined);
43
+ const payload = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : undefined;
44
+ if (!response.ok) {
45
+ const fromRelay = typeof payload?.error === "string";
46
+ const code = fromRelay ? payload.error : "error";
47
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "channels", event: "channel.a2a_relay_http_error", message: "the A2A relay refused a request", meta: { path: input.path.split("/")[1], status: response.status, code } });
48
+ throw new RelayHttpError(response.status, code, fromRelay);
49
+ }
50
+ if (!payload)
51
+ throw new Error(`the relay answered ${response.status} without its JSON body`);
52
+ return payload;
53
+ }
54
+ /** Register (or re-register, which rotates both credentials) `handle` for `did`. */
55
+ async function relayRegister(input) {
56
+ const grant = await relayRequest({
57
+ ...input,
58
+ method: "POST",
59
+ path: "/register",
60
+ body: { handle: input.handle, did: input.did, agentCard: input.agentCard, ...(input.inviteToken ? { inviteToken: input.inviteToken } : {}) },
61
+ });
62
+ if (typeof grant.inboxAuth !== "string" || typeof grant.sendCredential !== "string")
63
+ throw new Error("relay registration returned no credentials");
64
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_relay_registered", message: "registered an A2A relay inbox", meta: { relayUrl: input.url } });
65
+ return { handle: input.handle, inboxAuth: grant.inboxAuth, sendCredential: grant.sendCredential };
66
+ }
67
+ /** Queue `message` (already sealed and signed) in `handle`'s inbox. Returns the relay's queue id. */
68
+ async function relaySend(input) {
69
+ const result = await relayRequest({ ...input, method: "POST", path: `/a2a/${encodeURIComponent(input.handle)}`, bearer: input.sendCredential, body: input.message });
70
+ // Something other than the relay (a captive portal, a proxy) can answer 2xx; only a queue id means it was queued.
71
+ if (typeof result.taskId !== "string")
72
+ throw new Error("the relay did not confirm the message was queued");
73
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_relay_sent", message: "queued a sealed A2A message at the relay", meta: { relayUrl: input.url } });
74
+ return result.taskId;
75
+ }
76
+ /**
77
+ * The queued messages in `handle`'s inbox (still sealed). An answer with no message list throws: it is not the relay's,
78
+ * so it says nothing about the inbox. An entry without a queue id cannot be acked, so it is logged
79
+ * (without its content) and skipped, and the rest of the queue is still handled. The relay has no way to drop an entry
80
+ * without its id, so a skipped entry stays queued until the relay's own expiry removes it.
81
+ */
82
+ async function relayPull(input) {
83
+ const result = await relayRequest({ ...input, method: "GET", path: `/inbox/${encodeURIComponent(input.handle)}`, bearer: input.inboxAuth });
84
+ if (!Array.isArray(result.messages))
85
+ throw new Error("the relay's inbox answer has no message list");
86
+ const entries = result.messages;
87
+ const valid = [];
88
+ entries.forEach((entry, position) => {
89
+ const queueId = entry?.queueId;
90
+ if (entry && typeof entry === "object" && typeof queueId === "string" && queueId.length > 0) {
91
+ valid.push({ queueId, message: entry.message });
92
+ return;
93
+ }
94
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "channels", event: "channel.a2a_relay_entry_skipped", message: "skipped a relay inbox entry with no queue id; it cannot be acked and stays at the relay until it expires", meta: { relayUrl: input.url, position } });
95
+ });
96
+ return valid;
97
+ }
98
+ /** Remove one delivered message from `handle`'s inbox. Re-acking is harmless. */
99
+ async function relayAck(input) {
100
+ await relayRequest({ ...input, method: "POST", path: `/inbox/${encodeURIComponent(input.handle)}/ack/${encodeURIComponent(input.queueId)}`, bearer: input.inboxAuth });
101
+ }
102
+ /** Remove `handle` and its queue from the relay (used when the agent moves to another relay). */
103
+ async function relayDeregister(input) {
104
+ await relayRequest({ ...input, method: "DELETE", path: `/register/${encodeURIComponent(input.handle)}`, bearer: input.inboxAuth });
105
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_relay_deregistered", message: "deregistered an A2A relay inbox", meta: { relayUrl: input.url } });
106
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.relayConfigFrom = relayConfigFrom;
4
+ exports.vaultRelayConfigStore = vaultRelayConfigStore;
5
+ const runtime_1 = require("../nerves/runtime");
6
+ const runtime_credentials_1 = require("../heart/runtime-credentials");
7
+ function record(value) {
8
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
9
+ }
10
+ function text(value) {
11
+ return typeof value === "string" && value.length > 0 ? value : undefined;
12
+ }
13
+ function registrationFrom(value) {
14
+ const r = record(value);
15
+ const relayUrl = text(r?.relayUrl);
16
+ const handle = text(r?.handle);
17
+ const inboxAuth = text(r?.inboxAuth);
18
+ const sendCredential = text(r?.sendCredential);
19
+ return relayUrl && handle && inboxAuth && sendCredential ? { relayUrl, handle, inboxAuth, sendCredential } : undefined;
20
+ }
21
+ /** The `a2a.relay` settings in a machine runtime config, keeping only well-formed fields. */
22
+ function relayConfigFrom(config) {
23
+ const relay = record(record(config.a2a)?.relay);
24
+ if (!relay)
25
+ return {};
26
+ const url = text(relay.url);
27
+ const inviteToken = text(relay.inviteToken);
28
+ const registration = registrationFrom(relay.registration);
29
+ const pending = record(relay.pendingRegistration);
30
+ const pendingRelayUrl = text(pending?.relayUrl);
31
+ const pendingHandle = text(pending?.handle);
32
+ const previousRegistrations = (Array.isArray(relay.previousRegistrations) ? relay.previousRegistrations : [])
33
+ .map(registrationFrom)
34
+ .filter((registration) => registration !== undefined);
35
+ return {
36
+ ...(url ? { url } : {}),
37
+ ...(inviteToken ? { inviteToken } : {}),
38
+ ...(registration ? { registration } : {}),
39
+ ...(pendingRelayUrl && pendingHandle ? { pendingRegistration: { relayUrl: pendingRelayUrl, handle: pendingHandle } } : {}),
40
+ ...(previousRegistrations.length > 0 ? { previousRegistrations } : {}),
41
+ };
42
+ }
43
+ /**
44
+ * The relay settings, read from and written to this machine's runtime config in the vault (beside the A2A identity
45
+ * seed). Every read goes to the vault, so a write decided on a fresh read (clearing the invite only if it is unchanged)
46
+ * sees an operator's newer value. A patch merges into `a2a.relay`; a key set to `undefined` is dropped when the merged
47
+ * config is serialized.
48
+ */
49
+ function vaultRelayConfigStore(agentName, machineId) {
50
+ return {
51
+ async read() {
52
+ const result = await (0, runtime_credentials_1.refreshMachineRuntimeCredentialConfig)(agentName, machineId);
53
+ if (result.ok)
54
+ return relayConfigFrom(result.config);
55
+ if (result.reason === "missing")
56
+ return {};
57
+ throw new Error(`cannot read the A2A relay settings at ${result.itemPath}: ${result.error}`);
58
+ },
59
+ async write(patch) {
60
+ await (0, runtime_credentials_1.mergeMachineRuntimeCredentialConfig)(agentName, machineId, { a2a: { relay: patch } });
61
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_relay_config_saved", message: "saved A2A relay settings to the vault", meta: { agentName, keys: Object.keys(patch) } });
62
+ },
63
+ };
64
+ }
@@ -0,0 +1,120 @@
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.RELAY_CONTACT_FETCH_TIMEOUT_MS = exports.RELAY_CONTACT_REFRESH_MS = void 0;
37
+ exports.readRelayContact = readRelayContact;
38
+ exports.writeRelayContact = writeRelayContact;
39
+ exports.markRelayContactStale = markRelayContactStale;
40
+ exports.relayContactNeedsRefresh = relayContactNeedsRefresh;
41
+ exports.refreshRelayContact = refreshRelayContact;
42
+ const node_crypto_1 = require("node:crypto");
43
+ const fs = __importStar(require("node:fs"));
44
+ const path = __importStar(require("node:path"));
45
+ const runtime_1 = require("../nerves/runtime");
46
+ const outbox_client_1 = require("./outbox-client");
47
+ exports.RELAY_CONTACT_REFRESH_MS = 24 * 60 * 60 * 1000;
48
+ function contactFile(agentRoot, did) {
49
+ return path.join(agentRoot, "state", "a2a", "relay-contacts", `${(0, node_crypto_1.createHash)("sha256").update(did).digest("hex")}.json`);
50
+ }
51
+ function isContact(value) {
52
+ const c = value;
53
+ return !!c && typeof c === "object" && typeof c.url === "string" && typeof c.handle === "string" && typeof c.sendCredential === "string";
54
+ }
55
+ function readRelayContact(agentRoot, did) {
56
+ let parsed;
57
+ try {
58
+ parsed = JSON.parse(fs.readFileSync(contactFile(agentRoot, did), "utf8"));
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ if (!parsed || parsed.did !== did || typeof parsed.fetchedAt !== "string")
64
+ return null;
65
+ return {
66
+ did,
67
+ fetchedAt: parsed.fetchedAt,
68
+ ...(isContact(parsed.contact) ? { contact: { url: parsed.contact.url, handle: parsed.contact.handle, sendCredential: parsed.contact.sendCredential } } : {}),
69
+ ...(parsed.stale === true ? { stale: true } : {}),
70
+ ...(typeof parsed.attemptedAt === "string" ? { attemptedAt: parsed.attemptedAt } : {}),
71
+ };
72
+ }
73
+ function writeRelayContact(agentRoot, entry) {
74
+ const file = contactFile(agentRoot, entry.did);
75
+ fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
76
+ const temp = `${file}.${(0, node_crypto_1.randomBytes)(6).toString("hex")}.tmp`;
77
+ fs.writeFileSync(temp, `${JSON.stringify(entry)}\n`, { mode: 0o600 });
78
+ fs.renameSync(temp, file);
79
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_relay_contact_saved", message: "saved a peer's A2A relay contact", meta: { peerDid: entry.did, hasRelay: entry.contact !== undefined, stale: entry.stale === true } });
80
+ }
81
+ function markRelayContactStale(agentRoot, did) {
82
+ const entry = readRelayContact(agentRoot, did);
83
+ if (!entry)
84
+ return;
85
+ // A new refusal asks again at the next direct send, even if a refresh failed earlier today.
86
+ writeRelayContact(agentRoot, { did: entry.did, fetchedAt: entry.fetchedAt, ...(entry.contact ? { contact: entry.contact } : {}), stale: true });
87
+ }
88
+ /** True when the entry is missing, or its last fetch or failed attempt is more than a day old (at once when stale and not yet retried). */
89
+ function relayContactNeedsRefresh(entry, now) {
90
+ if (!entry)
91
+ return true;
92
+ const attemptedAt = entry.attemptedAt === undefined ? Number.NaN : Date.parse(entry.attemptedAt);
93
+ if (entry.stale && !Number.isFinite(attemptedAt))
94
+ return true;
95
+ const fetchedAt = Date.parse(entry.fetchedAt);
96
+ const last = Math.max(Number.isFinite(fetchedAt) ? fetchedAt : -Infinity, Number.isFinite(attemptedAt) ? attemptedAt : -Infinity);
97
+ return now - last > exports.RELAY_CONTACT_REFRESH_MS;
98
+ }
99
+ exports.RELAY_CONTACT_FETCH_TIMEOUT_MS = 10_000;
100
+ /**
101
+ * Ask a peer, over the sealed `relay/contact` method, where to queue messages for it while it is offline, and cache the
102
+ * answer. Runs after a successful direct send (the peer is online then), at most once a day per peer. A failure never
103
+ * throws: it keeps a contact already cached and records when it tried, and otherwise records "no relay", so either
104
+ * way the peer is not asked again today (a peer on an older harness answers "unknown method").
105
+ */
106
+ async function refreshRelayContact(input) {
107
+ const fetchedAt = new Date(input.now ?? Date.now()).toISOString();
108
+ const baseFetch = input.fetchImpl ?? fetch;
109
+ const fetchImpl = ((url, init) => baseFetch(url, { ...init, signal: AbortSignal.timeout(exports.RELAY_CONTACT_FETCH_TIMEOUT_MS) }));
110
+ try {
111
+ const result = await (0, outbox_client_1.callOutboxMethod)({ cardUrl: input.cardUrl, method: "relay/contact", params: {}, identity: input.identity, fetchImpl, expectedDid: input.peerDid });
112
+ writeRelayContact(input.agentRoot, { did: input.peerDid, fetchedAt, ...(isContact(result.contact) ? { contact: { url: result.contact.url, handle: result.contact.handle, sendCredential: result.contact.sendCredential } } : {}) });
113
+ }
114
+ catch (error) {
115
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "channels", event: "channel.a2a_relay_contact_refresh_failed", message: "could not fetch a peer's relay contact", meta: { peerDid: input.peerDid, error: error instanceof Error ? error.message : /* v8 ignore next -- the outbox client only throws Error instances @preserve */ String(error) } });
116
+ // Keep a cached contact (it may still work) but record the attempt, so a failing peer is asked at most once a day.
117
+ const existing = readRelayContact(input.agentRoot, input.peerDid);
118
+ writeRelayContact(input.agentRoot, existing?.contact ? { ...existing, attemptedAt: fetchedAt } : { did: input.peerDid, fetchedAt });
119
+ }
120
+ }