@ouro.bot/cli 0.1.0-alpha.70 → 0.1.0-alpha.700

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 (501) hide show
  1. package/README.md +133 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +4454 -14
  13. package/dist/a2a/card.js +57 -0
  14. package/dist/a2a/client.js +180 -0
  15. package/dist/a2a/config.js +50 -0
  16. package/dist/a2a/delegation-stores.js +56 -0
  17. package/dist/a2a/did-resolution.js +93 -0
  18. package/dist/a2a/identity.js +170 -0
  19. package/dist/a2a/inbound-share.js +107 -0
  20. package/dist/a2a/mission-result-wire.js +196 -0
  21. package/dist/a2a/onboarding.js +115 -0
  22. package/dist/a2a/pin-store.js +132 -0
  23. package/dist/a2a/seen-ledger.js +120 -0
  24. package/dist/a2a/server.js +604 -0
  25. package/dist/a2a/task-store.js +69 -0
  26. package/dist/a2a/transport.js +45 -0
  27. package/dist/a2a/types.js +3 -0
  28. package/dist/arc/attention-types.js +8 -0
  29. package/dist/arc/cares.js +144 -0
  30. package/dist/arc/episodes.js +118 -0
  31. package/dist/arc/evolution.js +490 -0
  32. package/dist/arc/flight-recorder.js +928 -0
  33. package/dist/arc/intentions.js +134 -0
  34. package/dist/arc/json-store.js +117 -0
  35. package/dist/arc/obligations.js +348 -0
  36. package/dist/arc/packets.js +336 -0
  37. package/dist/arc/presence.js +185 -0
  38. package/dist/arc/task-lifecycle.js +57 -0
  39. package/dist/commerce/store.js +755 -0
  40. package/dist/commerce/types.js +3 -0
  41. package/dist/heart/active-work.js +867 -43
  42. package/dist/heart/agent-entry.js +190 -3
  43. package/dist/heart/attachments/image-normalize.js +194 -0
  44. package/dist/heart/attachments/materialize.js +97 -0
  45. package/dist/heart/attachments/originals.js +88 -0
  46. package/dist/heart/attachments/render.js +29 -0
  47. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  48. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  49. package/dist/heart/attachments/sources/index.js +16 -0
  50. package/dist/heart/attachments/store.js +103 -0
  51. package/dist/heart/attachments/types.js +93 -0
  52. package/dist/heart/auth/auth-flow.js +479 -0
  53. package/dist/heart/autonomy-budget.js +434 -0
  54. package/dist/heart/awaiting/await-alert.js +146 -0
  55. package/dist/heart/awaiting/await-expiry.js +108 -0
  56. package/dist/heart/awaiting/await-loader.js +91 -0
  57. package/dist/heart/awaiting/await-parser.js +141 -0
  58. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  59. package/dist/heart/awaiting/await-scheduler.js +378 -0
  60. package/dist/heart/background-operations.js +281 -0
  61. package/dist/heart/bridges/manager.js +137 -17
  62. package/dist/heart/bridges/store.js +14 -2
  63. package/dist/heart/bundle-state.js +168 -0
  64. package/dist/heart/commitments.js +135 -0
  65. package/dist/heart/config-registry.js +331 -0
  66. package/dist/heart/config.js +119 -127
  67. package/dist/heart/context-loss-gauntlet.js +354 -0
  68. package/dist/heart/context-loss-sentinel.js +1155 -0
  69. package/dist/heart/core.js +1306 -278
  70. package/dist/heart/cross-chat-delivery.js +8 -22
  71. package/dist/heart/daemon/agent-config-check.js +451 -0
  72. package/dist/heart/daemon/agent-discovery.js +185 -3
  73. package/dist/heart/daemon/agent-service.js +523 -0
  74. package/dist/heart/daemon/agentic-repair.js +547 -0
  75. package/dist/heart/daemon/await-private-wake.js +59 -0
  76. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  77. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  78. package/dist/heart/daemon/cadence.js +180 -0
  79. package/dist/heart/daemon/cli-defaults.js +780 -0
  80. package/dist/heart/daemon/cli-desk.js +322 -0
  81. package/dist/heart/daemon/cli-exec.js +8142 -0
  82. package/dist/heart/daemon/cli-help.js +675 -0
  83. package/dist/heart/daemon/cli-parse.js +2461 -0
  84. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  85. package/dist/heart/daemon/cli-render.js +770 -0
  86. package/dist/heart/daemon/cli-types.js +8 -0
  87. package/dist/heart/daemon/connect-bay.js +323 -0
  88. package/dist/heart/daemon/daemon-cli.js +29 -1930
  89. package/dist/heart/daemon/daemon-entry.js +822 -10
  90. package/dist/heart/daemon/daemon-health.js +176 -0
  91. package/dist/heart/daemon/daemon-rollup.js +57 -0
  92. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  93. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  94. package/dist/heart/daemon/daemon.js +1264 -84
  95. package/dist/heart/daemon/dns-workflow.js +394 -0
  96. package/dist/heart/daemon/doctor-types.js +8 -0
  97. package/dist/heart/daemon/doctor.js +1126 -0
  98. package/dist/heart/daemon/habit-private-wake.js +56 -0
  99. package/dist/heart/daemon/health-monitor.js +142 -11
  100. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  101. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  102. package/dist/heart/daemon/http-health-probe.js +80 -0
  103. package/dist/heart/daemon/human-command-screens.js +234 -0
  104. package/dist/heart/daemon/human-readiness.js +114 -0
  105. package/dist/heart/daemon/inner-status.js +78 -0
  106. package/dist/heart/daemon/interactive-repair.js +394 -0
  107. package/dist/heart/daemon/launchd.js +37 -8
  108. package/dist/heart/daemon/log-tailer.js +79 -10
  109. package/dist/heart/daemon/logs-prune.js +110 -0
  110. package/dist/heart/daemon/mcp-canary.js +297 -0
  111. package/dist/heart/daemon/message-router.js +45 -5
  112. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  113. package/dist/heart/daemon/os-cron-deps.js +135 -0
  114. package/dist/heart/daemon/os-cron.js +22 -14
  115. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  116. package/dist/heart/daemon/ouro-entry.js +3 -1
  117. package/dist/heart/daemon/plugin-cli.js +432 -0
  118. package/dist/heart/daemon/process-manager.js +519 -40
  119. package/dist/heart/daemon/provider-discovery.js +137 -0
  120. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  121. package/dist/heart/daemon/pulse.js +511 -0
  122. package/dist/heart/daemon/readiness-repair.js +365 -0
  123. package/dist/heart/daemon/run-hooks.js +2 -0
  124. package/dist/heart/daemon/runtime-logging.js +41 -14
  125. package/dist/heart/daemon/runtime-metadata.js +2 -30
  126. package/dist/heart/daemon/safe-mode.js +161 -0
  127. package/dist/heart/daemon/sense-manager.js +670 -48
  128. package/dist/heart/daemon/session-id-resolver.js +131 -0
  129. package/dist/heart/daemon/skill-management-installer.js +1 -1
  130. package/dist/heart/daemon/socket-client.js +171 -12
  131. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  132. package/dist/heart/daemon/startup-tui.js +338 -0
  133. package/dist/heart/daemon/task-scheduler.js +117 -39
  134. package/dist/heart/daemon/terminal-ui.js +499 -0
  135. package/dist/heart/daemon/thoughts.js +255 -43
  136. package/dist/heart/daemon/up-progress.js +366 -0
  137. package/dist/heart/daemon/vault-items.js +56 -0
  138. package/dist/heart/delegation.js +1 -4
  139. package/dist/heart/external-events/router.js +121 -0
  140. package/dist/heart/habits/habit-migration.js +189 -0
  141. package/dist/heart/habits/habit-parser.js +214 -0
  142. package/dist/heart/habits/habit-runtime-state.js +114 -0
  143. package/dist/heart/habits/habit-scheduler.js +431 -0
  144. package/dist/heart/habits/habit-session-summary.js +318 -0
  145. package/dist/heart/habits/habit-session.js +617 -0
  146. package/dist/heart/{daemon → hatch}/hatch-flow.js +51 -60
  147. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  148. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  149. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  150. package/dist/heart/identity.js +174 -59
  151. package/dist/heart/kept-notes.js +289 -0
  152. package/dist/heart/kicks.js +1 -1
  153. package/dist/heart/machine-identity.js +161 -0
  154. package/dist/heart/mail-import-discovery.js +353 -0
  155. package/dist/heart/mailbox/mailbox-http-hooks.js +96 -0
  156. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  157. package/dist/heart/mailbox/mailbox-http-routes.js +375 -0
  158. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  159. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  160. package/dist/heart/mailbox/mailbox-http.js +99 -0
  161. package/dist/heart/mailbox/mailbox-read.js +37 -0
  162. package/dist/heart/mailbox/mailbox-types.js +27 -0
  163. package/dist/heart/mailbox/mailbox-view.js +197 -0
  164. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  165. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  166. package/dist/heart/mailbox/readers/mail.js +375 -0
  167. package/dist/heart/mailbox/readers/runtime-readers.js +815 -0
  168. package/dist/heart/mailbox/readers/sessions.js +232 -0
  169. package/dist/heart/mailbox/readers/shared.js +111 -0
  170. package/dist/heart/mcp/mcp-server.js +696 -0
  171. package/dist/heart/migrate-config.js +100 -0
  172. package/dist/heart/model-capabilities.js +11 -0
  173. package/dist/heart/orientation-frame.js +217 -0
  174. package/dist/heart/platform.js +81 -0
  175. package/dist/heart/primitives.js +1 -1
  176. package/dist/heart/private-runtime/decision-renderer.js +156 -0
  177. package/dist/heart/private-runtime/index.js +18 -0
  178. package/dist/heart/private-runtime/ledger.js +218 -0
  179. package/dist/heart/private-runtime/policy.js +214 -0
  180. package/dist/heart/private-runtime/types.js +2 -0
  181. package/dist/heart/progress-story.js +1 -1
  182. package/dist/heart/provider-attempt.js +134 -0
  183. package/dist/heart/provider-binding-resolver.js +273 -0
  184. package/dist/heart/provider-credentials.js +441 -0
  185. package/dist/heart/provider-failover.js +311 -0
  186. package/dist/heart/provider-models.js +81 -0
  187. package/dist/heart/provider-ping.js +262 -0
  188. package/dist/heart/provider-readiness-cache.js +119 -0
  189. package/dist/heart/provider-visibility.js +188 -0
  190. package/dist/heart/providers/anthropic-token.js +131 -0
  191. package/dist/heart/providers/anthropic.js +139 -52
  192. package/dist/heart/providers/azure.js +23 -11
  193. package/dist/heart/providers/error-classification.js +127 -0
  194. package/dist/heart/providers/github-copilot.js +34 -38
  195. package/dist/heart/providers/minimax-vlm.js +189 -0
  196. package/dist/heart/providers/minimax.js +26 -8
  197. package/dist/heart/providers/openai-codex-token.js +349 -0
  198. package/dist/heart/providers/openai-codex.js +55 -40
  199. package/dist/heart/run-ledger.js +247 -0
  200. package/dist/heart/runtime-capability-check.js +170 -0
  201. package/dist/heart/runtime-credentials.js +398 -0
  202. package/dist/heart/runtime-cwd.js +87 -0
  203. package/dist/heart/sense-truth.js +20 -4
  204. package/dist/heart/session-activity.js +90 -24
  205. package/dist/heart/session-events.js +1133 -0
  206. package/dist/heart/session-playback-cli-main.js +5 -0
  207. package/dist/heart/session-playback-cli.js +36 -0
  208. package/dist/heart/session-playback.js +231 -0
  209. package/dist/heart/session-stats-cli-main.js +5 -0
  210. package/dist/heart/session-stats.js +182 -0
  211. package/dist/heart/session-transcript.js +133 -0
  212. package/dist/heart/start-of-turn-packet.js +365 -0
  213. package/dist/heart/streaming.js +44 -27
  214. package/dist/heart/structured-output.js +196 -0
  215. package/dist/heart/sync-classification.js +176 -0
  216. package/dist/heart/sync.js +449 -0
  217. package/dist/heart/target-resolution.js +11 -7
  218. package/dist/heart/tempo.js +93 -0
  219. package/dist/heart/temporal-view.js +41 -0
  220. package/dist/heart/timeouts.js +101 -0
  221. package/dist/heart/tool-activity-callbacks.js +59 -0
  222. package/dist/heart/tool-description.js +155 -0
  223. package/dist/heart/tool-friction.js +55 -0
  224. package/dist/heart/tool-loop.js +200 -0
  225. package/dist/heart/turn-context.js +472 -0
  226. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  227. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  228. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  229. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  230. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  231. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  232. package/dist/heart/versioning/update-hooks.js +154 -0
  233. package/dist/heart/work-card.js +380 -0
  234. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  235. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  236. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  237. package/dist/mailbox-ui/index.html +16 -0
  238. package/dist/mailroom/attention.js +167 -0
  239. package/dist/mailroom/autonomy.js +209 -0
  240. package/dist/mailroom/blob-store.js +715 -0
  241. package/dist/mailroom/body-cache.js +61 -0
  242. package/dist/mailroom/core.js +788 -0
  243. package/dist/mailroom/entry.js +160 -0
  244. package/dist/mailroom/file-store.js +568 -0
  245. package/dist/mailroom/mbox-import.js +393 -0
  246. package/dist/mailroom/migration.js +164 -0
  247. package/dist/mailroom/outbound.js +380 -0
  248. package/dist/mailroom/policy.js +263 -0
  249. package/dist/mailroom/reader.js +233 -0
  250. package/dist/mailroom/search-cache.js +334 -0
  251. package/dist/mailroom/search-relevance.js +319 -0
  252. package/dist/mailroom/smtp-ingress.js +176 -0
  253. package/dist/mailroom/source-state.js +176 -0
  254. package/dist/mailroom/thread.js +109 -0
  255. package/dist/mailroom/travel-extract.js +89 -0
  256. package/dist/mind/bundle-manifest.js +24 -2
  257. package/dist/mind/context.js +250 -101
  258. package/dist/mind/desk-section.js +362 -0
  259. package/dist/mind/diary-integrity.js +60 -0
  260. package/dist/mind/{memory.js → diary.js} +68 -77
  261. package/dist/mind/embedding-provider.js +60 -0
  262. package/dist/mind/file-state.js +179 -0
  263. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  264. package/dist/mind/obligation-steering.js +221 -0
  265. package/dist/mind/pending.js +13 -8
  266. package/dist/mind/prompt-budget.js +380 -0
  267. package/dist/mind/prompt-refresh.js +3 -2
  268. package/dist/mind/prompt.js +1028 -169
  269. package/dist/mind/provenance-trust.js +26 -0
  270. package/dist/mind/record-paths.js +312 -0
  271. package/dist/mind/scrutiny.js +173 -0
  272. package/dist/nerves/cli-logging.js +7 -1
  273. package/dist/nerves/coverage/audit-rules.js +15 -6
  274. package/dist/nerves/coverage/audit.js +28 -2
  275. package/dist/nerves/coverage/cli.js +1 -1
  276. package/dist/nerves/coverage/contract.js +5 -5
  277. package/dist/nerves/coverage/file-completeness.js +139 -5
  278. package/dist/nerves/event-buffer.js +111 -0
  279. package/dist/nerves/index.js +234 -4
  280. package/dist/nerves/observation.js +20 -0
  281. package/dist/nerves/redact.js +79 -0
  282. package/dist/nerves/review/cli-main.js +5 -0
  283. package/dist/nerves/review/cli.js +156 -0
  284. package/dist/nerves/review/core.js +152 -0
  285. package/dist/nerves/runtime.js +5 -1
  286. package/dist/repertoire/ado-client.js +15 -56
  287. package/dist/repertoire/ado-semantic.js +16 -10
  288. package/dist/repertoire/api-client.js +97 -0
  289. package/dist/repertoire/bitwarden-store.js +1042 -0
  290. package/dist/repertoire/bundle-templates.js +71 -0
  291. package/dist/repertoire/bw-installer.js +180 -0
  292. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  293. package/dist/repertoire/coding/context-pack.js +331 -0
  294. package/dist/repertoire/coding/feedback.js +218 -30
  295. package/dist/repertoire/coding/index.js +15 -3
  296. package/dist/repertoire/coding/manager.js +166 -10
  297. package/dist/repertoire/coding/spawner.js +58 -11
  298. package/dist/repertoire/coding/tools.js +242 -14
  299. package/dist/repertoire/coding/workbench-client.js +272 -0
  300. package/dist/repertoire/coding/workbench-manager.js +346 -0
  301. package/dist/repertoire/commerce-errors.js +109 -0
  302. package/dist/repertoire/commerce-self-test.js +156 -0
  303. package/dist/repertoire/credential-access.js +178 -0
  304. package/dist/repertoire/desk/classifier.js +362 -0
  305. package/dist/repertoire/duffel-client.js +185 -0
  306. package/dist/repertoire/github-client.js +14 -55
  307. package/dist/repertoire/graph-client.js +11 -52
  308. package/dist/repertoire/guardrails.js +156 -27
  309. package/dist/repertoire/mcp-client.js +44 -3
  310. package/dist/repertoire/mcp-manager.js +259 -20
  311. package/dist/repertoire/mcp-tools.js +83 -0
  312. package/dist/repertoire/plugin-mcp.js +175 -0
  313. package/dist/repertoire/plugins.js +253 -0
  314. package/dist/repertoire/shell-sessions.js +133 -0
  315. package/dist/repertoire/skills.js +48 -4
  316. package/dist/repertoire/stripe-client.js +131 -0
  317. package/dist/repertoire/tool-results.js +29 -0
  318. package/dist/repertoire/tools-a2a.js +699 -0
  319. package/dist/repertoire/tools-attachments.js +317 -0
  320. package/dist/repertoire/tools-awaiting.js +372 -0
  321. package/dist/repertoire/tools-base.js +65 -1095
  322. package/dist/repertoire/tools-bluebubbles.js +2 -0
  323. package/dist/repertoire/tools-bridge.js +144 -0
  324. package/dist/repertoire/tools-bundle.js +993 -0
  325. package/dist/repertoire/tools-commerce.js +253 -0
  326. package/dist/repertoire/tools-config.js +186 -0
  327. package/dist/repertoire/tools-continuity.js +252 -0
  328. package/dist/repertoire/tools-credential.js +383 -0
  329. package/dist/repertoire/tools-evolution.js +527 -0
  330. package/dist/repertoire/tools-files.js +344 -0
  331. package/dist/repertoire/tools-flight.js +290 -0
  332. package/dist/repertoire/tools-flow.js +119 -0
  333. package/dist/repertoire/tools-github.js +3 -8
  334. package/dist/repertoire/tools-mail.js +1975 -0
  335. package/dist/repertoire/tools-notes.js +459 -0
  336. package/dist/repertoire/tools-obligations.js +182 -0
  337. package/dist/repertoire/tools-orientation.js +31 -0
  338. package/dist/repertoire/tools-record.js +482 -0
  339. package/dist/repertoire/tools-rsvp.js +139 -0
  340. package/dist/repertoire/tools-runtime.js +150 -0
  341. package/dist/repertoire/tools-session.js +881 -0
  342. package/dist/repertoire/tools-shell.js +120 -0
  343. package/dist/repertoire/tools-stripe.js +224 -0
  344. package/dist/repertoire/tools-surface.js +355 -0
  345. package/dist/repertoire/tools-teams.js +12 -39
  346. package/dist/repertoire/tools-travel.js +125 -0
  347. package/dist/repertoire/tools-trip.js +982 -0
  348. package/dist/repertoire/tools-user-profile.js +146 -0
  349. package/dist/repertoire/tools-vault.js +40 -0
  350. package/dist/repertoire/tools-voice.js +145 -0
  351. package/dist/repertoire/tools.js +250 -80
  352. package/dist/repertoire/travel-api-client.js +360 -0
  353. package/dist/repertoire/user-profile.js +131 -0
  354. package/dist/repertoire/vault-setup.js +246 -0
  355. package/dist/repertoire/vault-unlock.js +594 -0
  356. package/dist/rsvp/aisleplanner-client.js +354 -0
  357. package/dist/rsvp/cli.js +704 -0
  358. package/dist/rsvp/config.js +327 -0
  359. package/dist/rsvp/cutover.js +431 -0
  360. package/dist/rsvp/diagnostics.js +222 -0
  361. package/dist/rsvp/diff-renderer.js +161 -0
  362. package/dist/rsvp/habit-policy.js +85 -0
  363. package/dist/rsvp/habit-stage.js +93 -0
  364. package/dist/rsvp/incident-bundle.js +97 -0
  365. package/dist/rsvp/migration.js +204 -0
  366. package/dist/rsvp/outbound-state.js +254 -0
  367. package/dist/rsvp/query.js +118 -0
  368. package/dist/rsvp/replay.js +233 -0
  369. package/dist/rsvp/snapshot.js +232 -0
  370. package/dist/scripts/claude-code-hook.js +41 -0
  371. package/dist/scripts/claude-code-stop-hook.js +47 -0
  372. package/dist/senses/a2a-entry.js +115 -0
  373. package/dist/senses/attention-queue.js +186 -0
  374. package/dist/senses/await-turn-message.js +58 -0
  375. package/dist/senses/bluebubbles/active-turns.js +216 -0
  376. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  377. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  378. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +226 -19
  379. package/dist/senses/bluebubbles/entry.js +77 -0
  380. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  381. package/dist/senses/bluebubbles/index.js +2937 -0
  382. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  383. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  384. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  385. package/dist/senses/bluebubbles/outbound-state.js +304 -0
  386. package/dist/senses/bluebubbles/processed-log.js +133 -0
  387. package/dist/senses/bluebubbles/replay.js +284 -0
  388. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  389. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  390. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  391. package/dist/senses/cli/bracketed-paste.js +82 -0
  392. package/dist/senses/cli/image-paste.js +287 -0
  393. package/dist/senses/cli/image-ref-navigation.js +75 -0
  394. package/dist/senses/cli/ink-app.js +156 -0
  395. package/dist/senses/cli/inline-diff.js +64 -0
  396. package/dist/senses/cli/input-keys.js +174 -0
  397. package/dist/senses/cli/kill-ring.js +86 -0
  398. package/dist/senses/cli/message-list.js +51 -0
  399. package/dist/senses/cli/ouro-tui.js +607 -0
  400. package/dist/senses/cli/spinner-imperative.js +135 -0
  401. package/dist/senses/cli/spinner.js +101 -0
  402. package/dist/senses/cli/status-line.js +60 -0
  403. package/dist/senses/cli/streaming-markdown.js +526 -0
  404. package/dist/senses/cli/tool-display.js +85 -0
  405. package/dist/senses/cli/tool-render.js +85 -0
  406. package/dist/senses/cli/tui-store.js +240 -0
  407. package/dist/senses/cli/virtual-list.js +35 -0
  408. package/dist/senses/cli-entry.js +60 -8
  409. package/dist/senses/cli-layout.js +100 -0
  410. package/dist/senses/cli.js +521 -214
  411. package/dist/senses/commands.js +66 -3
  412. package/dist/senses/context-packet-ledger.js +245 -0
  413. package/dist/senses/context-packets.js +154 -0
  414. package/dist/senses/habit-turn-message.js +160 -0
  415. package/dist/senses/mail-entry.js +66 -0
  416. package/dist/senses/mail.js +395 -0
  417. package/dist/senses/pipeline.js +952 -178
  418. package/dist/senses/private-runtime-worker.js +723 -0
  419. package/dist/senses/private-runtime.js +1157 -0
  420. package/dist/senses/proactive-content-guard.js +51 -0
  421. package/dist/senses/shared-turn.js +416 -0
  422. package/dist/senses/surface-tool.js +109 -0
  423. package/dist/senses/teams-entry.js +60 -8
  424. package/dist/senses/teams.js +397 -112
  425. package/dist/senses/trust-gate.js +104 -9
  426. package/dist/senses/voice/audio-playback.js +237 -0
  427. package/dist/senses/voice/audio-routing.js +119 -0
  428. package/dist/senses/voice/elevenlabs.js +202 -0
  429. package/dist/senses/voice/floor-control.js +431 -0
  430. package/dist/senses/voice/floor-controller.js +115 -0
  431. package/dist/senses/voice/golden-path.js +116 -0
  432. package/dist/senses/voice/index.js +29 -0
  433. package/dist/senses/voice/meeting.js +113 -0
  434. package/dist/senses/voice/outbound.js +190 -0
  435. package/dist/senses/voice/phone.js +33 -0
  436. package/dist/senses/voice/playback.js +139 -0
  437. package/dist/senses/voice/realtime-eval.js +496 -0
  438. package/dist/senses/voice/realtime-trace.js +531 -0
  439. package/dist/senses/voice/transcript.js +70 -0
  440. package/dist/senses/voice/turn.js +191 -0
  441. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  442. package/dist/senses/voice/twilio-phone.js +5081 -0
  443. package/dist/senses/voice/types.js +2 -0
  444. package/dist/senses/voice/whisper.js +161 -0
  445. package/dist/senses/voice-entry.js +81 -0
  446. package/dist/senses/voice-realtime-eval-command.js +99 -0
  447. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  448. package/dist/senses/voice-twilio-entry.js +87 -0
  449. package/dist/trips/core.js +138 -0
  450. package/dist/trips/store.js +265 -0
  451. package/dist/util/frontmatter.js +69 -0
  452. package/package.json +57 -12
  453. package/skills/agent-commerce.md +113 -0
  454. package/skills/browser-navigation.md +117 -0
  455. package/skills/commerce-setup-guide.md +116 -0
  456. package/skills/commerce-setup.md +84 -0
  457. package/skills/configure-dev-tools.md +99 -0
  458. package/skills/travel-planning.md +138 -0
  459. package/dist/heart/daemon/auth-flow.js +0 -409
  460. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  461. package/dist/heart/daemon/update-hooks.js +0 -138
  462. package/dist/heart/safe-workspace.js +0 -228
  463. package/dist/heart/session-recall.js +0 -116
  464. package/dist/mind/friends/channel.js +0 -84
  465. package/dist/mind/friends/group-context.js +0 -144
  466. package/dist/mind/friends/resolver.js +0 -84
  467. package/dist/mind/friends/store-file.js +0 -190
  468. package/dist/mind/friends/store.js +0 -4
  469. package/dist/mind/friends/tokens.js +0 -26
  470. package/dist/mind/friends/trust-explanation.js +0 -74
  471. package/dist/mind/friends/types.js +0 -29
  472. package/dist/repertoire/tasks/board.js +0 -134
  473. package/dist/repertoire/tasks/index.js +0 -224
  474. package/dist/repertoire/tasks/lifecycle.js +0 -80
  475. package/dist/repertoire/tasks/middleware.js +0 -65
  476. package/dist/repertoire/tasks/parser.js +0 -173
  477. package/dist/repertoire/tasks/scanner.js +0 -132
  478. package/dist/repertoire/tasks/transitions.js +0 -144
  479. package/dist/senses/bluebubbles-entry.js +0 -13
  480. package/dist/senses/bluebubbles.js +0 -1180
  481. package/dist/senses/debug-activity.js +0 -148
  482. package/dist/senses/inner-dialog-worker.js +0 -90
  483. package/dist/senses/inner-dialog.js +0 -480
  484. package/subagents/README.md +0 -7
  485. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  486. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  487. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  488. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  489. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  490. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  491. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  492. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  493. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  494. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  495. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  496. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  497. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  498. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  499. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  500. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  501. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.receiveInboundShare = receiveInboundShare;
4
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
5
+ const friends_1 = require("@ouro.bot/friends");
6
+ const runtime_1 = require("../nerves/runtime");
7
+ /** Whether the inbound message carries a friends data part (kind:"data"). */
8
+ function hasDataPart(message) {
9
+ return Array.isArray(message.parts) && message.parts.some((p) => p && p.kind === "data");
10
+ }
11
+ /**
12
+ * Bridge an inbound A2A message through friends' `receiveShare`, keying the result
13
+ * on the VERIFIED sender DID.
14
+ *
15
+ * Ordering (the security-critical trap — `trustOfSource` is read from the store BY
16
+ * the just-verified DID, never defaulted, never from the envelope):
17
+ * 1. `unwrapDataPart` — no friends part ⇒ `not-a-share` (caller does text path).
18
+ * 2. `openSealedEnvelope` (pre-unseal) — extract the SIGNED sender DID. Unseal /
19
+ * recipient-mismatch failures ⇒ `rejected` (no turn). (This open does NOT
20
+ * verify the signature; the real auth gate is the `DidVerifier` inside
21
+ * `receiveShare`, so a forged-high-trust claim here is harmless — the forge is
22
+ * rejected by the verifier regardless of the trust we read.)
23
+ * 3. `findFriendByDid(store, verifiedDid)` — read trust off that record; an
24
+ * unknown DID ⇒ `stranger` (never a default-up).
25
+ * 4. `receiveShare({ ..., trustOfSource })` — re-unseal (deterministic) + resolve
26
+ * & pin + run `DidVerifier` (forge fails HERE) + replay-dedup + import.
27
+ * 5. Map the result. `completed` ⇒ run the turn at `verifiedDid`/`trust`.
28
+ */
29
+ async function receiveInboundShare(message, deps) {
30
+ const friendsMessage = message;
31
+ const payload = (0, a2a_client_1.unwrapDataPart)(friendsMessage);
32
+ if (!payload) {
33
+ // No (valid) friends part. If there was a data part at all, it was a malformed
34
+ // friends attempt → reject; otherwise it's a legacy text message → not-a-share.
35
+ if (hasDataPart(message)) {
36
+ (0, runtime_1.emitNervesEvent)({
37
+ component: "channels",
38
+ event: "channel.a2a_inbound_rejected",
39
+ message: "rejected malformed inbound A2A data part",
40
+ meta: { reason: "malformed_message" },
41
+ });
42
+ return { outcome: "rejected", reason: "malformed_message" };
43
+ }
44
+ return { outcome: "not-a-share" };
45
+ }
46
+ const recipientIdentity = {
47
+ x25519Priv: deps.identity.x25519Priv,
48
+ x25519Pub: deps.identity.x25519Pub,
49
+ };
50
+ // Pre-unseal to learn the SIGNED sender DID before we can read its trust.
51
+ const opened = (0, a2a_client_1.openSealedEnvelope)({
52
+ sodium: deps.sodium,
53
+ sealedEnvelope: { v: payload.v, sealed: payload.sealed },
54
+ recipientDid: deps.identity.did,
55
+ recipientIdentity,
56
+ });
57
+ if (!opened.ok) {
58
+ (0, runtime_1.emitNervesEvent)({
59
+ component: "channels",
60
+ event: "channel.a2a_inbound_rejected",
61
+ message: "rejected inbound A2A envelope (unseal/recipient)",
62
+ meta: { reason: opened.error },
63
+ });
64
+ return { outcome: "rejected", reason: opened.error };
65
+ }
66
+ const verifiedDid = opened.fromAgentId;
67
+ // Read trust from the friend store BY the verified DID — never defaulted, never
68
+ // from the envelope. Unknown (or empty) DID ⇒ stranger. `findFriendByDid` itself
69
+ // refuses a falsy did (never matches a did-less record), so this is safe to call
70
+ // unconditionally.
71
+ const record = await (0, friends_1.findFriendByDid)(deps.store, verifiedDid);
72
+ const trust = record?.trustLevel ?? "stranger";
73
+ const result = await (0, a2a_client_1.receiveShare)({
74
+ sodium: deps.sodium,
75
+ store: deps.store,
76
+ missionStore: deps.missionStore,
77
+ pinStore: deps.pinStore,
78
+ didResolution: deps.didResolution,
79
+ seen: deps.seen,
80
+ a2aMessage: friendsMessage,
81
+ recipientDid: deps.identity.did,
82
+ recipientIdentity,
83
+ trustOfSource: trust,
84
+ });
85
+ if (result.state === "completed") {
86
+ (0, runtime_1.emitNervesEvent)({
87
+ component: "channels",
88
+ event: "channel.a2a_inbound_verified",
89
+ message: "verified inbound A2A share; keying turn on sender DID",
90
+ meta: { verifiedDid, trust, friendsKind: result.friendsKind, status: result.status },
91
+ });
92
+ return {
93
+ outcome: "completed",
94
+ verifiedDid,
95
+ trust,
96
+ friendsKind: result.friendsKind,
97
+ status: result.status,
98
+ };
99
+ }
100
+ (0, runtime_1.emitNervesEvent)({
101
+ component: "channels",
102
+ event: "channel.a2a_inbound_rejected",
103
+ message: "rejected inbound A2A share",
104
+ meta: { reason: result.reason, verifiedDid, trust },
105
+ });
106
+ return { outcome: "rejected", reason: result.reason };
107
+ }
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wrapMissionResultDataPart = wrapMissionResultDataPart;
4
+ exports.isMissionResultDataPart = isMissionResultDataPart;
5
+ exports.receiveInboundMissionResult = receiveInboundMissionResult;
6
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
7
+ const friends_1 = require("@ouro.bot/friends");
8
+ const runtime_1 = require("../nerves/runtime");
9
+ /**
10
+ * THE HARNESS-OWNED RESULT WIRE.
11
+ *
12
+ * A mission RESULT is NOT a `FriendsKind` (`FriendsKind` = profile_share |
13
+ * mission_share | coordination) — `prepareMissionResult`/`importMissionResult` are
14
+ * transport-agnostic + store-only, and the result does NOT ride `sendShare`/
15
+ * `receiveShare`. So the HARNESS owns the wire: the result envelope is sealed (reusing
16
+ * the sign-then-seal crypto) and wrapped in a DataPart carrying a distinct `ouroKind:
17
+ * "mission_result"` discriminator. The inbound bridge recognizes that tag and routes
18
+ * it to `importMissionResult` — NEVER to `receiveShare`, which would mis-route a
19
+ * non-`FriendsKind` envelope. This is "a DataPart variant + an inbound route branch"
20
+ * (the carrier is the friends `unwrapDataPart` shape + one extra tag field — no
21
+ * structural change beyond that).
22
+ *
23
+ * SECURITY — the wire AUTHENTICATES the sender exactly like the share path
24
+ * (`receiveShare` in friends' `adapter.ts`). `openSealedEnvelope` does AEAD
25
+ * decryption ONLY — it does NOT verify the signature (its docstring names the
26
+ * adapter's `DidVerifier` as "the single authentication gate"). The decrypted
27
+ * `envelope.fromAgentId` is therefore attacker-controlled plaintext: the recipient's
28
+ * X25519 pubkey is public (derived from the published DID), so any party can SEAL a
29
+ * forged result to us. Authentication is the ONLY barrier. Before trusting the
30
+ * claimed sender we therefore replicate `receiveShare`'s gate:
31
+ * 1. binding check — `opened.signerDid === opened.fromAgentId` (and non-empty),
32
+ * 2. resolve + pin the sender DID (TOFU pin + signed-rotation evaluation),
33
+ * 3. hand `importMissionResult` a REAL `DidVerifier` bound to the pinned key, so
34
+ * `verifier.verify(fromAgentId, proof)` runs the Ed25519 signature check against
35
+ * the pinned key — NOT the no-op `tofuVerifier` the importer defaults to.
36
+ * Replay is deduped on the seal nonce (durable `SeenLedger`), matching the share path.
37
+ */
38
+ const OURO_RESULT_KIND = "mission_result";
39
+ /** Wrap a sealed result envelope into the harness-owned `mission_result` DataPart. */
40
+ function wrapMissionResultDataPart(input) {
41
+ return {
42
+ messageId: `result-${Math.random().toString(36).slice(2)}`,
43
+ role: "agent",
44
+ parts: [{
45
+ kind: "data",
46
+ data: {
47
+ v: input.sealedEnvelope.v,
48
+ sealed: input.sealedEnvelope.sealed,
49
+ recipientDid: input.recipientDid,
50
+ ouroKind: OURO_RESULT_KIND,
51
+ },
52
+ }],
53
+ };
54
+ }
55
+ /** Whether an inbound message carries the harness-owned `mission_result` DataPart. */
56
+ function isMissionResultDataPart(message) {
57
+ if (!Array.isArray(message.parts))
58
+ return false;
59
+ return message.parts.some((p) => p && p.kind === "data" && typeof p.data === "object" && p.data !== null
60
+ && p.data.ouroKind === OURO_RESULT_KIND);
61
+ }
62
+ /** Extract the sealed envelope from a `mission_result` DataPart, or null. */
63
+ function unwrapMissionResultDataPart(message) {
64
+ if (!Array.isArray(message.parts) || message.parts.length !== 1)
65
+ return null;
66
+ const part = message.parts[0];
67
+ if (!part || part.kind !== "data" || !part.data)
68
+ return null;
69
+ const data = part.data;
70
+ if (data.ouroKind !== OURO_RESULT_KIND)
71
+ return null;
72
+ if (typeof data.v !== "number" || typeof data.recipientDid !== "string" || !data.sealed)
73
+ return null;
74
+ return { sealed: { v: data.v, sealed: data.sealed }, recipientDid: data.recipientDid };
75
+ }
76
+ /**
77
+ * Route an inbound `mission_result` DataPart to `importMissionResult`, AUTHENTICATING
78
+ * the sender exactly like `receiveShare` does for every other inbound kind.
79
+ *
80
+ * Ordering (mirrors the share bridge's trust trap + authentication gate):
81
+ * 1. recognize + unwrap the harness `mission_result` carrier (else `not-a-result`).
82
+ * 2. replay dedup on the seal nonce (durable `SeenLedger`) — before any state change.
83
+ * 3. `openSealedEnvelope` → AEAD-decrypt only (unseal/recipient failures → reject).
84
+ * 4. binding check — reject unless `opened.signerDid === opened.fromAgentId` (and
85
+ * non-empty): the advisory `signerDid` (outer, unsigned) must match the claimed
86
+ * sender. A divergence is a forged/spoofed bundle (`sender_binding_mismatch`).
87
+ * 5. `resolveAndPin` the sender DID (TOFU pin / signed-rotation) → the pinned key
88
+ * (unresolvable/failed-binding/failed-rotation → `resolve_failed`).
89
+ * 6. build a `DidVerifier` bound to THIS envelope + the pinned key, mark the nonce
90
+ * seen, then call `importMissionResult({ envelope, fromAgentId: <signed DID>,
91
+ * trustOfSource }, { verifier })`. The verifier runs the REAL signature check
92
+ * against the pinned key — a result signed with a key that is not the pinned key
93
+ * for the claimed DID is rejected (`untrusted_source`). Every authorization gate
94
+ * (no_mission / no_delegation / assignee_mismatch, fail-closed on a legacy
95
+ * assignee-less delegation) is still enforced by the importer.
96
+ */
97
+ async function receiveInboundMissionResult(message, deps) {
98
+ const payload = unwrapMissionResultDataPart(message);
99
+ if (!payload)
100
+ return { outcome: "not-a-result" };
101
+ // Replay dedup BEFORE any state change, keyed on the seal nonce (matches receiveShare).
102
+ if (deps.seen.isSeen(payload.sealed.sealed.n)) {
103
+ (0, runtime_1.emitNervesEvent)({
104
+ component: "channels",
105
+ event: "channel.a2a_result_rejected",
106
+ message: "rejected inbound mission_result (replayed seal nonce)",
107
+ meta: { reason: "replayed" },
108
+ });
109
+ return { outcome: "rejected", reason: "replayed" };
110
+ }
111
+ const recipientIdentity = { x25519Priv: deps.identity.x25519Priv, x25519Pub: deps.identity.x25519Pub };
112
+ const opened = (0, a2a_client_1.openSealedEnvelope)({
113
+ sodium: deps.sodium,
114
+ sealedEnvelope: payload.sealed,
115
+ recipientDid: deps.identity.did,
116
+ recipientIdentity,
117
+ });
118
+ if (!opened.ok) {
119
+ (0, runtime_1.emitNervesEvent)({
120
+ component: "channels",
121
+ event: "channel.a2a_result_rejected",
122
+ message: "rejected inbound mission_result (unseal/recipient)",
123
+ meta: { reason: opened.error },
124
+ });
125
+ return { outcome: "rejected", reason: opened.error };
126
+ }
127
+ // SECURITY (binding): the trustworthy sender identity is the SIGNED `fromAgentId`.
128
+ // `openSealedEnvelope` does NOT verify the signature, so `fromAgentId` is untrusted
129
+ // until the DidVerifier confirms the pinned key signed THIS envelope. The advisory
130
+ // `signerDid` (from the outer, unsigned sealed plaintext) must match the claimed
131
+ // sender; a divergence is a forged/spoofed bundle (e.g. an attacker signing with its
132
+ // OWN key while claiming a victim's DID). Reject before resolving or importing.
133
+ const senderDid = opened.fromAgentId;
134
+ if (senderDid.length === 0 || opened.signerDid !== senderDid) {
135
+ (0, runtime_1.emitNervesEvent)({
136
+ component: "channels",
137
+ event: "channel.a2a_result_rejected",
138
+ message: "rejected inbound mission_result (sender binding mismatch — forged sender)",
139
+ meta: { reason: "sender_binding_mismatch", claimedDid: senderDid, signerDid: opened.signerDid },
140
+ });
141
+ return { outcome: "rejected", reason: "sender_binding_mismatch" };
142
+ }
143
+ // Read trust from the friend store BY the verified DID — never defaulted, never from
144
+ // the envelope. Unknown (or empty) DID ⇒ stranger.
145
+ const record = await (0, friends_1.findFriendByDid)(deps.store, senderDid);
146
+ const trust = record?.trustLevel ?? "stranger";
147
+ // Resolve + pin the SENDER's DID (async — BEFORE the sync verifier/importer).
148
+ const resolved = await deps.didResolution.resolveAndPin({
149
+ fromAgentId: senderDid,
150
+ did: senderDid,
151
+ pinStore: deps.pinStore,
152
+ trustOfSource: trust,
153
+ });
154
+ if (!resolved) {
155
+ (0, runtime_1.emitNervesEvent)({
156
+ component: "channels",
157
+ event: "channel.a2a_result_rejected",
158
+ message: "rejected inbound mission_result (sender DID resolve/pin failed)",
159
+ meta: { reason: "resolve_failed", verifiedDid: senderDid, trust },
160
+ });
161
+ return { outcome: "rejected", reason: "resolve_failed" };
162
+ }
163
+ // Build the sync verifier bound to THIS envelope + the pinned sender key. This is the
164
+ // single authentication gate (the importer would otherwise default to the no-op TOFU
165
+ // verifier). `verify` confirms the agentId===did binding AND the Ed25519 signature
166
+ // over the envelope against the pinned key.
167
+ const verifier = new a2a_client_1.DidVerifier({
168
+ sodium: deps.sodium,
169
+ pinnedEd25519Pub: resolved.ed25519Pub,
170
+ pinnedDid: senderDid,
171
+ envelope: opened.envelope,
172
+ });
173
+ // Mark seen now (idempotent imports + the replay guard above keep this safe).
174
+ deps.seen.markSeen(payload.sealed.sealed.n);
175
+ const result = await (0, friends_1.importMissionResult)(deps.missionStore, {
176
+ envelope: opened.envelope,
177
+ fromAgentId: senderDid,
178
+ trustOfSource: trust,
179
+ }, { verifier });
180
+ if (result.ok) {
181
+ (0, runtime_1.emitNervesEvent)({
182
+ component: "channels",
183
+ event: "channel.a2a_result_imported",
184
+ message: "imported inbound mission_result (authenticated, quarantined, attributed)",
185
+ meta: { verifiedDid: senderDid, trust, status: result.status },
186
+ });
187
+ return { outcome: "imported", verifiedDid: senderDid };
188
+ }
189
+ (0, runtime_1.emitNervesEvent)({
190
+ component: "channels",
191
+ event: "channel.a2a_result_rejected",
192
+ message: "rejected inbound mission_result (import gate)",
193
+ meta: { reason: result.status, verifiedDid: senderDid, trust },
194
+ });
195
+ return { outcome: "rejected", reason: result.status };
196
+ }
@@ -0,0 +1,115 @@
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.onboardA2APeer = onboardA2APeer;
37
+ const path = __importStar(require("node:path"));
38
+ const identity_1 = require("../heart/identity");
39
+ const runtime_1 = require("../nerves/runtime");
40
+ const friends_1 = require("@ouro.bot/friends");
41
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
42
+ const client_1 = require("./client");
43
+ function storeFor(options) {
44
+ if (options.store)
45
+ return options.store;
46
+ /* v8 ignore next -- default bundle root fallback is owned by identity path tests; CLI and onboarding tests inject explicit roots @preserve */
47
+ return new friends_1.FileFriendStore(path.join(options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)(), `${options.agentName}.ouro`, "friends"));
48
+ }
49
+ /** The normalized card URL (legacy URL-keyed identity for did-less cards). */
50
+ function urlAgentId(cardUrl) {
51
+ const parsed = new URL(cardUrl);
52
+ parsed.hash = "";
53
+ return parsed.toString();
54
+ }
55
+ /** The trimmed `did:key` a card serves, or undefined when the card is did-less. */
56
+ function cardDid(card) {
57
+ const did = card.did;
58
+ return typeof did === "string" && did.trim() ? did.trim() : undefined;
59
+ }
60
+ async function onboardA2APeer(options) {
61
+ // HTTP/URL glue stays harness-side: fetch the agent card, resolve its JSON-RPC
62
+ // endpoint, and derive the stable agentId. The record-shaping (mint/update the
63
+ // agent-peer friend) is delegated to @ouro.bot/friends' upsertAgentPeer.
64
+ const card = await (0, client_1.fetchA2AAgentCard)(options.cardUrl, options.fetchImpl);
65
+ const store = storeFor(options);
66
+ /* v8 ignore next -- fetchA2AAgentCard validates a usable endpoint or legacy url before returning a card @preserve */
67
+ const endpointUrl = (0, client_1.endpointForCard)(card) ?? options.cardUrl;
68
+ const protocolVersion = card.supportedInterfaces?.find((entry) => entry.url === endpointUrl)?.protocolVersion
69
+ ?? card.protocolVersion;
70
+ const name = options.name ?? card.name;
71
+ // THE FOOTGUN FIX: a DID-bearing card keys the record on its VERIFIED did:key
72
+ // (so an inbound sealed envelope — keyed on the signed DID — resolves to THIS
73
+ // record, not a stranger). A did-less (legacy) card keeps the URL-keyed identity
74
+ // unchanged (backward compatible). For did:key the binding is self-contained
75
+ // (`card.did === did`, `didDoc: null`); we ALSO require the served did:key to be a
76
+ // well-formed, parseable Ed25519 key (a malformed did:key could never key/verify
77
+ // an inbound envelope, so onboarding it would silently break the resolve later). A
78
+ // card whose DID is unparseable or fails the binding is REFUSED (no record
79
+ // written) — never TOFU-trust a mis-bound or malformed card.
80
+ const did = cardDid(card);
81
+ if (did) {
82
+ const parsed = (0, a2a_client_1.parseDidKey)(did);
83
+ const bound = parsed !== null && (0, a2a_client_1.verifyCardDidBinding)({ card: { did, url: options.cardUrl }, did, didDoc: null });
84
+ if (!bound) {
85
+ (0, runtime_1.emitNervesEvent)({
86
+ component: "friends",
87
+ event: "friends.a2a_card_binding_rejected",
88
+ message: "refused A2A onboarding: card↔DID binding failed",
89
+ meta: { agentName: options.agentName, cardUrl: options.cardUrl, did, parseable: parsed !== null },
90
+ });
91
+ throw new Error(`A2A card↔DID binding failed for ${did}`);
92
+ }
93
+ }
94
+ // DID-keyed when present (externalId === did, a2a.did === did), else URL-keyed.
95
+ const externalId = did ?? urlAgentId(options.cardUrl);
96
+ const record = await (0, friends_1.upsertAgentPeer)(store, {
97
+ name,
98
+ agentId: externalId,
99
+ ...(options.trustLevel ? { trustLevel: options.trustLevel } : {}),
100
+ a2a: {
101
+ cardUrl: options.cardUrl,
102
+ endpointUrl,
103
+ agentId: externalId,
104
+ protocolVersion,
105
+ ...(did ? { did } : {}),
106
+ },
107
+ });
108
+ (0, runtime_1.emitNervesEvent)({
109
+ component: "friends",
110
+ event: "friends.a2a_peer_onboarded",
111
+ message: "onboarded A2A peer into friend model",
112
+ meta: { agentName: options.agentName, friendId: record.id, peerName: record.name, trustLevel: record.trustLevel, ...(did ? { did } : {}) },
113
+ });
114
+ return record;
115
+ }
@@ -0,0 +1,132 @@
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
+ class FileA2APinStore {
46
+ dir;
47
+ cache = new Map();
48
+ constructor(agentRoot) {
49
+ this.dir = path.join(agentRoot, "state", "a2a", "pins");
50
+ fs.mkdirSync(this.dir, { recursive: true });
51
+ this.loadExisting();
52
+ (0, runtime_1.emitNervesEvent)({
53
+ component: "channels",
54
+ event: "channel.a2a_pin_store_init",
55
+ message: "initialized durable A2A pin store",
56
+ meta: { dir: this.dir, pins: this.cache.size },
57
+ });
58
+ }
59
+ get size() {
60
+ return this.cache.size;
61
+ }
62
+ get(fromAgentId) {
63
+ if (!fromAgentId)
64
+ return undefined;
65
+ const pinned = this.cache.get(fromAgentId);
66
+ if (!pinned)
67
+ return undefined;
68
+ (0, runtime_1.emitNervesEvent)({
69
+ component: "channels",
70
+ event: "channel.a2a_pin_hit",
71
+ message: "A2A pin hit",
72
+ meta: { fromAgentId, did: pinned.did },
73
+ });
74
+ return pinned;
75
+ }
76
+ set(fromAgentId, pinned) {
77
+ // An empty-string DID is never a matchable key (security: it can never index a
78
+ // pin). Stay inert rather than writing an unkeyed pin file.
79
+ if (!fromAgentId)
80
+ return;
81
+ const existed = this.cache.has(fromAgentId);
82
+ // Faithfully persist the pinned identity's DID (which may differ from
83
+ // fromAgentId after a rotation), not fromAgentId itself.
84
+ const stored = {
85
+ fromAgentId,
86
+ did: pinned.did,
87
+ pinnedKey: (0, a2a_client_1.base58btcEncode)(pinned.ed25519Pub),
88
+ };
89
+ fs.writeFileSync(path.join(this.dir, pinFileName(fromAgentId)), `${JSON.stringify(stored, null, 2)}\n`, "utf-8");
90
+ this.cache.set(fromAgentId, { did: pinned.did, ed25519Pub: pinned.ed25519Pub });
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
+ /** Reload every persisted pin from disk into the in-memory cache (the restart
99
+ * replay). Corrupt/undecodable files are skipped so one bad file can never
100
+ * wedge the store. */
101
+ loadExisting() {
102
+ let entries;
103
+ try {
104
+ entries = fs.readdirSync(this.dir);
105
+ }
106
+ catch {
107
+ /* v8 ignore next -- the constructor mkdirSync's the dir before this runs; unreadable dir is unreachable in practice @preserve */
108
+ return;
109
+ }
110
+ for (const name of entries) {
111
+ if (!name.endsWith(".json"))
112
+ continue;
113
+ let stored;
114
+ try {
115
+ stored = JSON.parse(fs.readFileSync(path.join(this.dir, name), "utf-8"));
116
+ }
117
+ catch {
118
+ continue;
119
+ }
120
+ // `fromAgentId` is the cache key; fall back to `did` for any pre-rotation
121
+ // file written before the key/did split (back-compat).
122
+ const key = stored.fromAgentId ?? stored.did;
123
+ if (!key || !stored.did || !stored.pinnedKey)
124
+ continue;
125
+ const ed25519Pub = (0, a2a_client_1.base58btcDecode)(stored.pinnedKey);
126
+ if (!ed25519Pub)
127
+ continue;
128
+ this.cache.set(key, { did: stored.did, ed25519Pub });
129
+ }
130
+ }
131
+ }
132
+ exports.FileA2APinStore = FileA2APinStore;
@@ -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.FileA2ASeenLedger = 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 runtime_1 = require("../nerves/runtime");
41
+ function nonceFileName(nonce) {
42
+ return `${(0, node_crypto_1.createHash)("sha256").update(nonce).digest("hex")}.json`;
43
+ }
44
+ class FileA2ASeenLedger {
45
+ dir;
46
+ cache = new Set();
47
+ constructor(agentRoot) {
48
+ this.dir = path.join(agentRoot, "state", "a2a", "seen");
49
+ fs.mkdirSync(this.dir, { recursive: true });
50
+ this.loadExisting();
51
+ (0, runtime_1.emitNervesEvent)({
52
+ component: "channels",
53
+ event: "channel.a2a_seen_ledger_init",
54
+ message: "initialized durable A2A seen ledger",
55
+ meta: { dir: this.dir, seen: this.cache.size },
56
+ });
57
+ }
58
+ get size() {
59
+ return this.cache.size;
60
+ }
61
+ isSeen(nonce) {
62
+ if (!nonce)
63
+ return false;
64
+ const seen = this.cache.has(nonce);
65
+ if (seen) {
66
+ // A nonce we already processed is arriving again — for a seal nonce this is
67
+ // a replay. Loud security signal.
68
+ (0, runtime_1.emitNervesEvent)({
69
+ component: "channels",
70
+ event: "channel.a2a_replay_rejected",
71
+ message: "A2A replay rejected (nonce already seen)",
72
+ meta: { nonceHash: nonceFileName(nonce).slice(0, 16) },
73
+ });
74
+ }
75
+ return seen;
76
+ }
77
+ markSeen(nonce) {
78
+ // An empty-string nonce is never a matchable key — stay inert.
79
+ if (!nonce)
80
+ return;
81
+ if (this.cache.has(nonce))
82
+ return;
83
+ fs.writeFileSync(path.join(this.dir, nonceFileName(nonce)), `${JSON.stringify({ nonce, markedAt: new Date().toISOString() }, null, 2)}\n`, "utf-8");
84
+ this.cache.add(nonce);
85
+ (0, runtime_1.emitNervesEvent)({
86
+ component: "channels",
87
+ event: "channel.a2a_seen_marked",
88
+ message: "marked A2A seal nonce as seen (first sight)",
89
+ meta: { nonceHash: nonceFileName(nonce).slice(0, 16) },
90
+ });
91
+ }
92
+ /** Reload every persisted nonce from disk into the in-memory set (the restart
93
+ * replay defense). Corrupt/unreadable artifacts are skipped so one bad file can
94
+ * never reopen the replay window for the rest. */
95
+ loadExisting() {
96
+ let entries;
97
+ try {
98
+ entries = fs.readdirSync(this.dir);
99
+ }
100
+ catch {
101
+ /* v8 ignore next -- the constructor mkdirSync's the dir before this runs; unreadable dir is unreachable in practice @preserve */
102
+ return;
103
+ }
104
+ for (const name of entries) {
105
+ if (!name.endsWith(".json"))
106
+ continue;
107
+ let record;
108
+ try {
109
+ record = JSON.parse(fs.readFileSync(path.join(this.dir, name), "utf-8"));
110
+ }
111
+ catch {
112
+ continue;
113
+ }
114
+ if (typeof record.nonce === "string" && record.nonce.length > 0) {
115
+ this.cache.add(record.nonce);
116
+ }
117
+ }
118
+ }
119
+ }
120
+ exports.FileA2ASeenLedger = FileA2ASeenLedger;