@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.921

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 (717) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/assets/bluebubbles-host +264 -0
  14. package/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5826 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2997 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1254 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1564 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  38. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  39. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  40. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  41. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  42. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  43. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  44. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  45. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  46. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  52. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  53. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  54. package/deploy/unraid/sanctuary.xml +30 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +250 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command-grants.js +93 -0
  59. package/dist/a2a/delegated-command.js +197 -0
  60. package/dist/a2a/delegation-stores.js +56 -0
  61. package/dist/a2a/did-resolution.js +93 -0
  62. package/dist/a2a/escalation-grants.js +84 -0
  63. package/dist/a2a/escalation-wiring.js +60 -0
  64. package/dist/a2a/identity.js +258 -0
  65. package/dist/a2a/inbound-share.js +110 -0
  66. package/dist/a2a/mission-result-wire.js +196 -0
  67. package/dist/a2a/onboarding.js +133 -0
  68. package/dist/a2a/operator-trust.js +382 -0
  69. package/dist/a2a/outbox-client.js +57 -0
  70. package/dist/a2a/outbox-store.js +188 -0
  71. package/dist/a2a/outbox-wire.js +95 -0
  72. package/dist/a2a/pin-store.js +132 -0
  73. package/dist/a2a/replay-grant-holders.js +33 -0
  74. package/dist/a2a/replay-harness.js +188 -0
  75. package/dist/a2a/resolution-proof.js +53 -0
  76. package/dist/a2a/sealed-chat.js +113 -0
  77. package/dist/a2a/seen-ledger.js +120 -0
  78. package/dist/a2a/server.js +771 -0
  79. package/dist/a2a/task-store.js +69 -0
  80. package/dist/a2a/transport.js +45 -0
  81. package/dist/a2a/trust-commands.js +203 -0
  82. package/dist/a2a/trusted-files.js +185 -0
  83. package/dist/a2a/types.js +3 -0
  84. package/dist/arc/attention-types.js +8 -0
  85. package/dist/arc/cares.js +360 -0
  86. package/dist/arc/episodes.js +118 -0
  87. package/dist/arc/evolution.js +490 -0
  88. package/dist/arc/flight-recorder.js +1034 -0
  89. package/dist/arc/intentions.js +134 -0
  90. package/dist/arc/json-store.js +117 -0
  91. package/dist/arc/obligations.js +386 -0
  92. package/dist/arc/packets.js +336 -0
  93. package/dist/arc/presence.js +185 -0
  94. package/dist/arc/task-lifecycle.js +57 -0
  95. package/dist/commerce/store.js +755 -0
  96. package/dist/commerce/types.js +3 -0
  97. package/dist/heart/active-work.js +798 -40
  98. package/dist/heart/agent-entry.js +252 -3
  99. package/dist/heart/approval-files.js +113 -0
  100. package/dist/heart/approval-store.js +960 -0
  101. package/dist/heart/attachments/image-normalize.js +194 -0
  102. package/dist/heart/attachments/materialize.js +97 -0
  103. package/dist/heart/attachments/originals.js +88 -0
  104. package/dist/heart/attachments/render.js +29 -0
  105. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  106. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  107. package/dist/heart/attachments/sources/index.js +18 -0
  108. package/dist/heart/attachments/sources/telegram.js +71 -0
  109. package/dist/heart/attachments/store.js +132 -0
  110. package/dist/heart/attachments/types.js +93 -0
  111. package/dist/heart/auth/auth-flow.js +495 -0
  112. package/dist/heart/autonomy-budget.js +478 -0
  113. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  114. package/dist/heart/awaiting/await-alert.js +152 -0
  115. package/dist/heart/awaiting/await-expiry.js +143 -0
  116. package/dist/heart/awaiting/await-loader.js +91 -0
  117. package/dist/heart/awaiting/await-parser.js +152 -0
  118. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  119. package/dist/heart/awaiting/await-scheduler.js +391 -0
  120. package/dist/heart/background-operations.js +281 -0
  121. package/dist/heart/bluebubbles-host-account.js +78 -0
  122. package/dist/heart/bridges/manager.js +137 -17
  123. package/dist/heart/bridges/store.js +14 -2
  124. package/dist/heart/bundle-state.js +168 -0
  125. package/dist/heart/commitments.js +44 -18
  126. package/dist/heart/config-registry.js +331 -0
  127. package/dist/heart/config.js +174 -131
  128. package/dist/heart/context-loss-gauntlet.js +387 -0
  129. package/dist/heart/context-loss-sentinel.js +1159 -0
  130. package/dist/heart/core.js +2364 -578
  131. package/dist/heart/cross-chat-delivery.js +9 -22
  132. package/dist/heart/daemon/agent-config-check.js +451 -0
  133. package/dist/heart/daemon/agent-discovery.js +283 -3
  134. package/dist/heart/daemon/agent-home.js +319 -0
  135. package/dist/heart/daemon/agent-service.js +542 -0
  136. package/dist/heart/daemon/agentic-repair.js +547 -0
  137. package/dist/heart/daemon/await-private-wake.js +59 -0
  138. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  139. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  140. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  141. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  142. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  143. package/dist/heart/daemon/cadence.js +180 -0
  144. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  145. package/dist/heart/daemon/cli-defaults.js +876 -0
  146. package/dist/heart/daemon/cli-desk.js +322 -0
  147. package/dist/heart/daemon/cli-exec.js +9199 -0
  148. package/dist/heart/daemon/cli-help.js +735 -0
  149. package/dist/heart/daemon/cli-parse.js +3211 -0
  150. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  151. package/dist/heart/daemon/cli-render.js +819 -0
  152. package/dist/heart/daemon/cli-types.js +8 -0
  153. package/dist/heart/daemon/connect-bay.js +323 -0
  154. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  155. package/dist/heart/daemon/container-healthcheck.js +112 -0
  156. package/dist/heart/daemon/container-runtime.js +97 -0
  157. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  158. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  159. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  160. package/dist/heart/daemon/daemon-cli.js +29 -2350
  161. package/dist/heart/daemon/daemon-entry.js +953 -11
  162. package/dist/heart/daemon/daemon-health.js +186 -0
  163. package/dist/heart/daemon/daemon-rollup.js +57 -0
  164. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  165. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  166. package/dist/heart/daemon/daemon.js +2084 -105
  167. package/dist/heart/daemon/dns-workflow.js +394 -0
  168. package/dist/heart/daemon/doctor-types.js +8 -0
  169. package/dist/heart/daemon/doctor.js +1766 -0
  170. package/dist/heart/daemon/freshness.js +345 -0
  171. package/dist/heart/daemon/habit-private-wake.js +61 -0
  172. package/dist/heart/daemon/health-monitor.js +154 -11
  173. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  174. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  175. package/dist/heart/daemon/http-health-probe.js +80 -0
  176. package/dist/heart/daemon/human-command-screens.js +234 -0
  177. package/dist/heart/daemon/human-readiness.js +114 -0
  178. package/dist/heart/daemon/inner-status.js +78 -0
  179. package/dist/heart/daemon/interactive-repair.js +394 -0
  180. package/dist/heart/daemon/launchd.js +37 -8
  181. package/dist/heart/daemon/log-tailer.js +79 -10
  182. package/dist/heart/daemon/logs-prune.js +132 -0
  183. package/dist/heart/daemon/mcp-canary.js +524 -0
  184. package/dist/heart/daemon/message-router.js +65 -5
  185. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  186. package/dist/heart/daemon/os-cron-deps.js +135 -0
  187. package/dist/heart/daemon/os-cron.js +22 -14
  188. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  189. package/dist/heart/daemon/ouro-entry.js +5 -2
  190. package/dist/heart/daemon/plugin-cli.js +432 -0
  191. package/dist/heart/daemon/process-manager.js +760 -61
  192. package/dist/heart/daemon/provider-discovery.js +137 -0
  193. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  194. package/dist/heart/daemon/prunable-bundle.js +144 -0
  195. package/dist/heart/daemon/pulse.js +511 -0
  196. package/dist/heart/daemon/readiness-repair.js +365 -0
  197. package/dist/heart/daemon/run-hooks.js +2 -0
  198. package/dist/heart/daemon/runtime-logging.js +47 -14
  199. package/dist/heart/daemon/runtime-metadata.js +2 -30
  200. package/dist/heart/daemon/runtime-mode.js +13 -2
  201. package/dist/heart/daemon/safe-mode.js +161 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  206. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  207. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  208. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  209. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  210. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  211. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  212. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  213. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  214. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  215. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  216. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  217. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  219. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  220. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  225. package/dist/heart/daemon/sense-manager.js +733 -48
  226. package/dist/heart/daemon/session-id-resolver.js +131 -0
  227. package/dist/heart/daemon/skill-management-installer.js +1 -1
  228. package/dist/heart/daemon/socket-client.js +180 -12
  229. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  230. package/dist/heart/daemon/startup-tui.js +339 -0
  231. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  232. package/dist/heart/daemon/task-scheduler.js +117 -39
  233. package/dist/heart/daemon/terminal-ui.js +503 -0
  234. package/dist/heart/daemon/thoughts.js +138 -54
  235. package/dist/heart/daemon/up-progress.js +366 -0
  236. package/dist/heart/daemon/vault-items.js +56 -0
  237. package/dist/heart/delegation.js +1 -4
  238. package/dist/heart/external-events/router.js +1516 -0
  239. package/dist/heart/failure-reports.js +336 -0
  240. package/dist/heart/file-lock.js +109 -0
  241. package/dist/heart/frontend-approval-runtime.js +506 -0
  242. package/dist/heart/frontend-journal.js +215 -0
  243. package/dist/heart/frontend-session-service.js +237 -0
  244. package/dist/heart/frontend-socket-client.js +164 -0
  245. package/dist/heart/frontend-socket.js +400 -0
  246. package/dist/heart/habits/habit-cancel.js +810 -0
  247. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  248. package/dist/heart/habits/habit-migration.js +194 -0
  249. package/dist/heart/habits/habit-parser.js +278 -0
  250. package/dist/heart/habits/habit-runtime-state.js +93 -0
  251. package/dist/heart/habits/habit-scheduler.js +653 -0
  252. package/dist/heart/habits/habit-session-summary.js +318 -0
  253. package/dist/heart/habits/habit-session.js +636 -0
  254. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  255. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  256. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  257. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  258. package/dist/heart/identity.js +230 -59
  259. package/dist/heart/kept-notes.js +289 -0
  260. package/dist/heart/kicks.js +1 -1
  261. package/dist/heart/machine-identity.js +175 -0
  262. package/dist/heart/mail-import-discovery.js +356 -0
  263. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  264. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  265. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  266. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  267. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  268. package/dist/heart/mailbox/mailbox-http.js +99 -0
  269. package/dist/heart/mailbox/mailbox-read.js +39 -0
  270. package/dist/heart/mailbox/mailbox-types.js +27 -0
  271. package/dist/heart/mailbox/mailbox-view.js +197 -0
  272. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  273. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  274. package/dist/heart/mailbox/readers/mail.js +375 -0
  275. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  276. package/dist/heart/mailbox/readers/sessions.js +231 -0
  277. package/dist/heart/mailbox/readers/shared.js +111 -0
  278. package/dist/heart/mcp/mcp-server.js +696 -0
  279. package/dist/heart/migrate-config.js +100 -0
  280. package/dist/heart/model-capabilities.js +83 -16
  281. package/dist/heart/orientation-frame.js +345 -0
  282. package/dist/heart/platform.js +81 -0
  283. package/dist/heart/primitives.js +1 -1
  284. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  285. package/dist/heart/private-runtime/index.js +18 -0
  286. package/dist/heart/private-runtime/ledger.js +221 -0
  287. package/dist/heart/private-runtime/policy.js +260 -0
  288. package/dist/heart/private-runtime/types.js +2 -0
  289. package/dist/heart/progress-story.js +1 -1
  290. package/dist/heart/provider-attempt.js +137 -0
  291. package/dist/heart/provider-binding-resolver.js +273 -0
  292. package/dist/heart/provider-credentials.js +449 -0
  293. package/dist/heart/provider-failover.js +311 -0
  294. package/dist/heart/provider-models.js +96 -0
  295. package/dist/heart/provider-ping.js +265 -0
  296. package/dist/heart/provider-readiness-cache.js +119 -0
  297. package/dist/heart/provider-visibility.js +188 -0
  298. package/dist/heart/providers/anthropic-token.js +131 -0
  299. package/dist/heart/providers/anthropic.js +173 -60
  300. package/dist/heart/providers/azure.js +23 -11
  301. package/dist/heart/providers/error-classification.js +127 -0
  302. package/dist/heart/providers/github-copilot.js +38 -39
  303. package/dist/heart/providers/minimax-vlm.js +189 -0
  304. package/dist/heart/providers/minimax.js +26 -8
  305. package/dist/heart/providers/openai-codex-token.js +349 -0
  306. package/dist/heart/providers/openai-codex.js +55 -40
  307. package/dist/heart/providers/openai-compatible.js +177 -0
  308. package/dist/heart/reply-style.js +52 -0
  309. package/dist/heart/run-ledger.js +247 -0
  310. package/dist/heart/runtime-capability-check.js +170 -0
  311. package/dist/heart/runtime-credentials.js +607 -0
  312. package/dist/heart/runtime-cwd.js +87 -0
  313. package/dist/heart/sense-truth.js +24 -4
  314. package/dist/heart/session-activity.js +92 -24
  315. package/dist/heart/session-events.js +1504 -0
  316. package/dist/heart/session-playback-cli-main.js +5 -0
  317. package/dist/heart/session-playback-cli.js +36 -0
  318. package/dist/heart/session-playback.js +231 -0
  319. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  320. package/dist/heart/session-redaction-repair.js +552 -0
  321. package/dist/heart/session-stats-cli-main.js +5 -0
  322. package/dist/heart/session-stats.js +183 -0
  323. package/dist/heart/session-transcript.js +133 -0
  324. package/dist/heart/shelf-claims.js +78 -0
  325. package/dist/heart/shepherd-config.js +113 -0
  326. package/dist/heart/source-grounding.js +297 -0
  327. package/dist/heart/start-of-turn-packet.js +372 -0
  328. package/dist/heart/steward-policy.js +656 -0
  329. package/dist/heart/streaming.js +609 -207
  330. package/dist/heart/structured-output.js +196 -0
  331. package/dist/heart/sync-classification.js +176 -0
  332. package/dist/heart/sync-health.js +152 -0
  333. package/dist/heart/sync.js +726 -0
  334. package/dist/heart/target-resolution.js +11 -7
  335. package/dist/heart/tempo.js +93 -0
  336. package/dist/heart/temporal-view.js +41 -0
  337. package/dist/heart/timeouts.js +101 -0
  338. package/dist/heart/tool-activity-callbacks.js +59 -0
  339. package/dist/heart/tool-approval.js +382 -0
  340. package/dist/heart/tool-description.js +155 -0
  341. package/dist/heart/tool-friction.js +55 -0
  342. package/dist/heart/tool-loop.js +206 -0
  343. package/dist/heart/turn-context.js +496 -0
  344. package/dist/heart/turn-execution-lease.js +30 -0
  345. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  346. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  347. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  348. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  349. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  350. package/dist/heart/versioning/release-sources.js +173 -0
  351. package/dist/heart/versioning/self-update-defaults.js +294 -0
  352. package/dist/heart/versioning/self-update.js +196 -0
  353. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  354. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  355. package/dist/heart/versioning/update-hooks.js +154 -0
  356. package/dist/heart/versioning/update-state.js +126 -0
  357. package/dist/heart/versioning/updater-launchd.js +150 -0
  358. package/dist/heart/versioning/version-intent.js +114 -0
  359. package/dist/heart/work-card.js +380 -0
  360. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  361. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  362. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  363. package/dist/mailbox-ui/index.html +16 -0
  364. package/dist/mailroom/attention.js +167 -0
  365. package/dist/mailroom/autonomy.js +209 -0
  366. package/dist/mailroom/blob-store.js +889 -0
  367. package/dist/mailroom/body-cache.js +61 -0
  368. package/dist/mailroom/cache-sync-cli.js +58 -0
  369. package/dist/mailroom/core.js +803 -0
  370. package/dist/mailroom/entry.js +160 -0
  371. package/dist/mailroom/file-store.js +568 -0
  372. package/dist/mailroom/hosted-cache-sync.js +384 -0
  373. package/dist/mailroom/mbox-import.js +393 -0
  374. package/dist/mailroom/migration.js +164 -0
  375. package/dist/mailroom/outbound.js +380 -0
  376. package/dist/mailroom/policy.js +263 -0
  377. package/dist/mailroom/reader.js +292 -0
  378. package/dist/mailroom/search-cache.js +513 -0
  379. package/dist/mailroom/search-relevance.js +319 -0
  380. package/dist/mailroom/smtp-ingress.js +176 -0
  381. package/dist/mailroom/source-state.js +176 -0
  382. package/dist/mailroom/thread.js +109 -0
  383. package/dist/mailroom/travel-extract.js +89 -0
  384. package/dist/mind/bundle-manifest.js +24 -2
  385. package/dist/mind/context.js +307 -139
  386. package/dist/mind/desk-section.js +362 -0
  387. package/dist/mind/diary-integrity.js +60 -0
  388. package/dist/mind/{memory.js → diary.js} +68 -77
  389. package/dist/mind/embedding-provider.js +60 -0
  390. package/dist/mind/file-state.js +179 -0
  391. package/dist/mind/friend-link-codes.js +209 -0
  392. package/dist/mind/friend-merge.js +330 -0
  393. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  394. package/dist/mind/obligation-steering.js +199 -3
  395. package/dist/mind/pending.js +36 -10
  396. package/dist/mind/prompt-budget.js +479 -0
  397. package/dist/mind/prompt-refresh.js +3 -2
  398. package/dist/mind/prompt.js +1085 -198
  399. package/dist/mind/provenance-trust.js +26 -0
  400. package/dist/mind/record-paths.js +312 -0
  401. package/dist/mind/scrutiny.js +173 -0
  402. package/dist/mind/session-transaction.js +564 -0
  403. package/dist/nerves/cli-logging.js +7 -1
  404. package/dist/nerves/coverage/audit-rules.js +15 -6
  405. package/dist/nerves/coverage/audit.js +28 -2
  406. package/dist/nerves/coverage/cli.js +1 -1
  407. package/dist/nerves/coverage/contract.js +5 -5
  408. package/dist/nerves/coverage/file-completeness.js +139 -5
  409. package/dist/nerves/coverage/run-artifacts.js +55 -35
  410. package/dist/nerves/coverage/source-scanner.js +4 -4
  411. package/dist/nerves/event-buffer.js +111 -0
  412. package/dist/nerves/index.js +293 -9
  413. package/dist/nerves/observation.js +20 -0
  414. package/dist/nerves/redact.js +79 -0
  415. package/dist/nerves/review/cli-main.js +5 -0
  416. package/dist/nerves/review/cli.js +156 -0
  417. package/dist/nerves/review/core.js +159 -0
  418. package/dist/nerves/runtime.js +17 -1
  419. package/dist/repertoire/ado-client.js +15 -56
  420. package/dist/repertoire/ado-semantic.js +16 -10
  421. package/dist/repertoire/api-client.js +97 -0
  422. package/dist/repertoire/bitwarden-store.js +1201 -0
  423. package/dist/repertoire/bundle-templates.js +71 -0
  424. package/dist/repertoire/bw-installer.js +231 -0
  425. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  426. package/dist/repertoire/coding/context-pack.js +331 -0
  427. package/dist/repertoire/coding/feedback.js +174 -32
  428. package/dist/repertoire/coding/index.js +15 -3
  429. package/dist/repertoire/coding/manager.js +159 -10
  430. package/dist/repertoire/coding/spawner.js +40 -11
  431. package/dist/repertoire/coding/tools.js +182 -18
  432. package/dist/repertoire/coding/workbench-client.js +272 -0
  433. package/dist/repertoire/coding/workbench-manager.js +346 -0
  434. package/dist/repertoire/commerce-errors.js +109 -0
  435. package/dist/repertoire/commerce-self-test.js +156 -0
  436. package/dist/repertoire/credential-access.js +183 -0
  437. package/dist/repertoire/desk/classifier.js +362 -0
  438. package/dist/repertoire/duffel-client.js +185 -0
  439. package/dist/repertoire/github-client.js +14 -55
  440. package/dist/repertoire/graph-client.js +11 -52
  441. package/dist/repertoire/guardrails.js +968 -20
  442. package/dist/repertoire/house-sweep.js +469 -0
  443. package/dist/repertoire/mcp-client.js +58 -5
  444. package/dist/repertoire/mcp-manager.js +427 -139
  445. package/dist/repertoire/mcp-tools.js +132 -0
  446. package/dist/repertoire/mcp-write-guard.js +46 -0
  447. package/dist/repertoire/plugin-mcp.js +175 -0
  448. package/dist/repertoire/plugins.js +253 -0
  449. package/dist/repertoire/relationship-authorization.js +322 -0
  450. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  451. package/dist/repertoire/shell-sessions.js +134 -0
  452. package/dist/repertoire/skills.js +48 -4
  453. package/dist/repertoire/stripe-client.js +131 -0
  454. package/dist/repertoire/tool-arguments.js +182 -0
  455. package/dist/repertoire/tool-results.js +29 -0
  456. package/dist/repertoire/tools-a2a.js +699 -0
  457. package/dist/repertoire/tools-attachments.js +322 -0
  458. package/dist/repertoire/tools-awaiting.js +872 -0
  459. package/dist/repertoire/tools-base.js +83 -1168
  460. package/dist/repertoire/tools-bluebubbles.js +2 -0
  461. package/dist/repertoire/tools-bridge.js +144 -0
  462. package/dist/repertoire/tools-bundle.js +995 -0
  463. package/dist/repertoire/tools-commerce.js +253 -0
  464. package/dist/repertoire/tools-config.js +186 -0
  465. package/dist/repertoire/tools-continuity.js +575 -0
  466. package/dist/repertoire/tools-credential.js +383 -0
  467. package/dist/repertoire/tools-escalation.js +84 -0
  468. package/dist/repertoire/tools-evolution.js +527 -0
  469. package/dist/repertoire/tools-files.js +344 -0
  470. package/dist/repertoire/tools-flight.js +290 -0
  471. package/dist/repertoire/tools-flow.js +119 -0
  472. package/dist/repertoire/tools-friend-link.js +57 -0
  473. package/dist/repertoire/tools-github.js +3 -8
  474. package/dist/repertoire/tools-habits.js +103 -0
  475. package/dist/repertoire/tools-house-care.js +174 -0
  476. package/dist/repertoire/tools-mail.js +1828 -0
  477. package/dist/repertoire/tools-notes.js +496 -0
  478. package/dist/repertoire/tools-obligations.js +182 -0
  479. package/dist/repertoire/tools-orientation.js +31 -0
  480. package/dist/repertoire/tools-record.js +482 -0
  481. package/dist/repertoire/tools-rsvp.js +139 -0
  482. package/dist/repertoire/tools-runtime.js +238 -0
  483. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  484. package/dist/repertoire/tools-session.js +1133 -0
  485. package/dist/repertoire/tools-shell.js +149 -0
  486. package/dist/repertoire/tools-shepherd.js +262 -0
  487. package/dist/repertoire/tools-steward-policy.js +147 -0
  488. package/dist/repertoire/tools-stripe.js +224 -0
  489. package/dist/repertoire/tools-surface.js +369 -0
  490. package/dist/repertoire/tools-teams.js +12 -39
  491. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  492. package/dist/repertoire/tools-travel.js +125 -0
  493. package/dist/repertoire/tools-trip.js +982 -0
  494. package/dist/repertoire/tools-unraid.js +556 -0
  495. package/dist/repertoire/tools-user-profile.js +146 -0
  496. package/dist/repertoire/tools-vault.js +40 -0
  497. package/dist/repertoire/tools-voice-local.js +198 -0
  498. package/dist/repertoire/tools-voice.js +145 -0
  499. package/dist/repertoire/tools.js +514 -156
  500. package/dist/repertoire/travel-api-client.js +360 -0
  501. package/dist/repertoire/unraid-client.js +155 -0
  502. package/dist/repertoire/unraid-restart.js +339 -0
  503. package/dist/repertoire/user-profile.js +131 -0
  504. package/dist/repertoire/vault-setup.js +246 -0
  505. package/dist/repertoire/vault-unlock.js +686 -0
  506. package/dist/rsvp/aisleplanner-client.js +354 -0
  507. package/dist/rsvp/cli.js +936 -0
  508. package/dist/rsvp/config.js +327 -0
  509. package/dist/rsvp/cutover.js +433 -0
  510. package/dist/rsvp/diagnostics.js +232 -0
  511. package/dist/rsvp/diff-renderer.js +176 -0
  512. package/dist/rsvp/habit-policy.js +110 -0
  513. package/dist/rsvp/habit-stage.js +123 -0
  514. package/dist/rsvp/incident-bundle.js +97 -0
  515. package/dist/rsvp/migration.js +204 -0
  516. package/dist/rsvp/native-habit-runner.js +630 -0
  517. package/dist/rsvp/outbound-state.js +628 -0
  518. package/dist/rsvp/query.js +118 -0
  519. package/dist/rsvp/replay.js +233 -0
  520. package/dist/rsvp/snapshot.js +232 -0
  521. package/dist/rsvp/spend-ledger.js +175 -0
  522. package/dist/scripts/claude-code-hook.js +41 -0
  523. package/dist/scripts/claude-code-stop-hook.js +47 -0
  524. package/dist/senses/a2a-entry.js +132 -0
  525. package/dist/senses/acp-server.js +386 -0
  526. package/dist/senses/attention-queue.js +186 -0
  527. package/dist/senses/await-turn-message.js +65 -0
  528. package/dist/senses/bluebubbles/active-turns.js +216 -0
  529. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  530. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  531. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +379 -41
  532. package/dist/senses/bluebubbles/context-packet.js +207 -0
  533. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  534. package/dist/senses/bluebubbles/entry.js +90 -0
  535. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  536. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  537. package/dist/senses/bluebubbles/index.js +3878 -0
  538. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  539. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  540. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  541. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  542. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  543. package/dist/senses/bluebubbles/processed-log.js +133 -0
  544. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  545. package/dist/senses/bluebubbles/replay.js +284 -0
  546. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  547. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  548. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  549. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  550. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  551. package/dist/senses/cli/bracketed-paste.js +82 -0
  552. package/dist/senses/cli/image-paste.js +287 -0
  553. package/dist/senses/cli/image-ref-navigation.js +75 -0
  554. package/dist/senses/cli/ink-app.js +156 -0
  555. package/dist/senses/cli/inline-diff.js +64 -0
  556. package/dist/senses/cli/input-keys.js +174 -0
  557. package/dist/senses/cli/kill-ring.js +86 -0
  558. package/dist/senses/cli/message-list.js +51 -0
  559. package/dist/senses/cli/ouro-tui.js +607 -0
  560. package/dist/senses/cli/spinner-imperative.js +135 -0
  561. package/dist/senses/cli/spinner.js +101 -0
  562. package/dist/senses/cli/status-line.js +60 -0
  563. package/dist/senses/cli/streaming-markdown.js +526 -0
  564. package/dist/senses/cli/tool-display.js +85 -0
  565. package/dist/senses/cli/tool-render.js +85 -0
  566. package/dist/senses/cli/tui-store.js +241 -0
  567. package/dist/senses/cli/virtual-list.js +35 -0
  568. package/dist/senses/cli-entry.js +60 -8
  569. package/dist/senses/cli.js +601 -304
  570. package/dist/senses/commands.js +66 -3
  571. package/dist/senses/context-packet-ledger.js +371 -0
  572. package/dist/senses/context-packets.js +154 -0
  573. package/dist/senses/habit-lifecycle-guard.js +24 -0
  574. package/dist/senses/habit-turn-message.js +160 -0
  575. package/dist/senses/ingress-evidence.js +2 -0
  576. package/dist/senses/mail-entry.js +66 -0
  577. package/dist/senses/mail.js +524 -0
  578. package/dist/senses/pipeline.js +1158 -204
  579. package/dist/senses/private-runtime-worker.js +859 -0
  580. package/dist/senses/private-runtime.js +1627 -0
  581. package/dist/senses/proactive-content-guard.js +51 -0
  582. package/dist/senses/root-host-approval-port.js +345 -0
  583. package/dist/senses/root-host-approval-runtime.js +393 -0
  584. package/dist/senses/sanctuary-authority-resident.js +102 -0
  585. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  586. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  587. package/dist/senses/sanctuary-grounding.js +118 -0
  588. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  589. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  590. package/dist/senses/sanctuary-health-runner.js +104 -0
  591. package/dist/senses/sanctuary-health.js +422 -0
  592. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  593. package/dist/senses/sanctuary-interactive-control.js +410 -0
  594. package/dist/senses/sanctuary-media-catalog-contract.js +259 -0
  595. package/dist/senses/sanctuary-media-optimization.js +514 -0
  596. package/dist/senses/sanctuary-runtime.js +369 -0
  597. package/dist/senses/sanctuary-sab.js +85 -0
  598. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  599. package/dist/senses/shared-turn.js +793 -0
  600. package/dist/senses/shepherd/client.js +196 -0
  601. package/dist/senses/shepherd/cmux.js +352 -0
  602. package/dist/senses/shepherd/herdr.js +315 -0
  603. package/dist/senses/shepherd/host.js +14 -0
  604. package/dist/senses/shepherd/judge.js +137 -0
  605. package/dist/senses/shepherd/owner-notice.js +251 -0
  606. package/dist/senses/shepherd/redact.js +66 -0
  607. package/dist/senses/shepherd/returns.js +79 -0
  608. package/dist/senses/shepherd/sense.js +310 -0
  609. package/dist/senses/shepherd/terminal-process.js +99 -0
  610. package/dist/senses/shepherd-entry.js +78 -0
  611. package/dist/senses/surface-tool.js +109 -0
  612. package/dist/senses/teams-entry.js +68 -8
  613. package/dist/senses/teams.js +598 -233
  614. package/dist/senses/telegram-admission.js +718 -0
  615. package/dist/senses/telegram-approval-runtime.js +793 -0
  616. package/dist/senses/telegram-attachments.js +186 -0
  617. package/dist/senses/telegram-audit-ledger.js +220 -0
  618. package/dist/senses/telegram-authority-transport.js +231 -0
  619. package/dist/senses/telegram-client.js +1749 -0
  620. package/dist/senses/telegram-effect-adapter.js +900 -0
  621. package/dist/senses/telegram-entry.js +83 -0
  622. package/dist/senses/telegram-handoff.js +80 -0
  623. package/dist/senses/telegram.js +2405 -0
  624. package/dist/senses/trust-gate.js +104 -9
  625. package/dist/senses/voice/audio-playback.js +237 -0
  626. package/dist/senses/voice/audio-routing.js +119 -0
  627. package/dist/senses/voice/call-auth.js +250 -0
  628. package/dist/senses/voice/elevenlabs.js +202 -0
  629. package/dist/senses/voice/floor-control.js +431 -0
  630. package/dist/senses/voice/floor-controller.js +115 -0
  631. package/dist/senses/voice/golden-path.js +116 -0
  632. package/dist/senses/voice/index.js +29 -0
  633. package/dist/senses/voice/local-audio-control.js +344 -0
  634. package/dist/senses/voice/local-audio-devices.js +516 -0
  635. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  636. package/dist/senses/voice/local-audio-identity.js +103 -0
  637. package/dist/senses/voice/local-audio-join.js +325 -0
  638. package/dist/senses/voice/local-audio-mute.js +199 -0
  639. package/dist/senses/voice/local-audio-notify.js +121 -0
  640. package/dist/senses/voice/local-audio-prompts.js +116 -0
  641. package/dist/senses/voice/local-audio-transport.js +427 -0
  642. package/dist/senses/voice/local-audio.js +281 -0
  643. package/dist/senses/voice/local-media-stream.js +145 -0
  644. package/dist/senses/voice/meeting.js +113 -0
  645. package/dist/senses/voice/outbound.js +190 -0
  646. package/dist/senses/voice/phone.js +33 -0
  647. package/dist/senses/voice/playback.js +139 -0
  648. package/dist/senses/voice/process-guards.js +51 -0
  649. package/dist/senses/voice/realtime-eval.js +496 -0
  650. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  651. package/dist/senses/voice/realtime-trace.js +531 -0
  652. package/dist/senses/voice/transcript.js +70 -0
  653. package/dist/senses/voice/turn.js +191 -0
  654. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  655. package/dist/senses/voice/twilio-phone.js +5454 -0
  656. package/dist/senses/voice/types.js +2 -0
  657. package/dist/senses/voice/whisper.js +161 -0
  658. package/dist/senses/voice-entry.js +83 -0
  659. package/dist/senses/voice-realtime-eval-command.js +99 -0
  660. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  661. package/dist/senses/voice-twilio-entry.js +87 -0
  662. package/dist/trips/core.js +138 -0
  663. package/dist/trips/store.js +265 -0
  664. package/dist/util/frontmatter.js +69 -0
  665. package/npm-shrinkwrap.json +8100 -0
  666. package/package.json +74 -13
  667. package/skills/agent-commerce.md +113 -0
  668. package/skills/browser-navigation.md +117 -0
  669. package/skills/commerce-setup-guide.md +116 -0
  670. package/skills/commerce-setup.md +84 -0
  671. package/skills/configure-dev-tools.md +99 -0
  672. package/skills/travel-planning.md +138 -0
  673. package/dist/heart/daemon/auth-flow.js +0 -430
  674. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  675. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  676. package/dist/heart/daemon/update-hooks.js +0 -138
  677. package/dist/heart/obligations.js +0 -191
  678. package/dist/heart/safe-workspace.js +0 -362
  679. package/dist/heart/session-recall.js +0 -116
  680. package/dist/mind/friends/channel.js +0 -84
  681. package/dist/mind/friends/group-context.js +0 -144
  682. package/dist/mind/friends/resolver.js +0 -84
  683. package/dist/mind/friends/store-file.js +0 -190
  684. package/dist/mind/friends/store.js +0 -4
  685. package/dist/mind/friends/tokens.js +0 -26
  686. package/dist/mind/friends/trust-explanation.js +0 -74
  687. package/dist/mind/friends/types.js +0 -29
  688. package/dist/repertoire/tasks/board.js +0 -134
  689. package/dist/repertoire/tasks/index.js +0 -224
  690. package/dist/repertoire/tasks/lifecycle.js +0 -80
  691. package/dist/repertoire/tasks/middleware.js +0 -65
  692. package/dist/repertoire/tasks/parser.js +0 -173
  693. package/dist/repertoire/tasks/scanner.js +0 -132
  694. package/dist/repertoire/tasks/transitions.js +0 -144
  695. package/dist/senses/bluebubbles-entry.js +0 -13
  696. package/dist/senses/bluebubbles.js +0 -1181
  697. package/dist/senses/debug-activity.js +0 -154
  698. package/dist/senses/inner-dialog-worker.js +0 -90
  699. package/dist/senses/inner-dialog.js +0 -525
  700. package/subagents/README.md +0 -7
  701. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  702. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  703. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  704. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  705. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  706. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  707. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  708. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  709. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  710. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  711. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  712. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  713. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  714. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  715. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  716. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  717. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.A2ARpcError = void 0;
4
+ exports.cardDid = cardDid;
5
+ exports.endpointForCard = endpointForCard;
6
+ exports.fetchA2AAgentCard = fetchA2AAgentCard;
7
+ exports.postJsonRpc = postJsonRpc;
8
+ exports.sendA2AMessage = sendA2AMessage;
9
+ exports.postA2AMessageEnvelope = postA2AMessageEnvelope;
10
+ exports.getA2ATask = getA2ATask;
11
+ exports.sendSealedA2AChat = sendSealedA2AChat;
12
+ const node_crypto_1 = require("node:crypto");
13
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
14
+ const runtime_1 = require("../nerves/runtime");
15
+ const sealed_chat_1 = require("./sealed-chat");
16
+ /** The trimmed `did:key` a card serves, or undefined when the card is did-less. */
17
+ function cardDid(card) {
18
+ const did = card.did;
19
+ return typeof did === "string" && did.trim() ? did.trim() : undefined;
20
+ }
21
+ function endpointForCard(card) {
22
+ const jsonRpc = card.supportedInterfaces?.find((entry) => (entry.protocolBinding ?? entry.transport)?.toUpperCase() === "JSONRPC");
23
+ if (jsonRpc?.url)
24
+ return jsonRpc.url;
25
+ if (card.preferredTransport?.toUpperCase() === "JSONRPC" && card.url)
26
+ return card.url;
27
+ const legacyJsonRpc = card.additionalInterfaces?.find((entry) => entry.transport.toUpperCase() === "JSONRPC");
28
+ return legacyJsonRpc?.url ?? card.url;
29
+ }
30
+ async function fetchA2AAgentCard(cardUrl, fetchImpl = fetch) {
31
+ (0, runtime_1.emitNervesEvent)({
32
+ component: "channels",
33
+ event: "channel.a2a_card_fetch_start",
34
+ message: "fetching A2A agent card",
35
+ meta: { cardUrl },
36
+ });
37
+ const response = await fetchImpl(cardUrl);
38
+ if (!response.ok) {
39
+ throw new Error(`A2A card fetch failed (${response.status} ${response.statusText})`);
40
+ }
41
+ const parsed = await response.json();
42
+ const endpoint = endpointForCard(parsed);
43
+ if (!parsed || typeof parsed !== "object" || typeof endpoint !== "string" || typeof parsed.name !== "string") {
44
+ throw new Error("A2A card is missing required name or JSONRPC endpoint fields");
45
+ }
46
+ (0, runtime_1.emitNervesEvent)({
47
+ component: "channels",
48
+ event: "channel.a2a_card_fetch_end",
49
+ message: "fetched A2A agent card",
50
+ meta: { cardUrl, endpoint, name: parsed.name },
51
+ });
52
+ return parsed;
53
+ }
54
+ /** A JSON-RPC error answer from the peer. `data` carries the peer's structured detail (for a refused delegated command: reason, nothingRan, retry, next). */
55
+ class A2ARpcError extends Error {
56
+ code;
57
+ data;
58
+ constructor(error) {
59
+ super(`A2A error ${error.code}: ${error.message}`);
60
+ this.code = error.code;
61
+ this.data = error.data;
62
+ }
63
+ }
64
+ exports.A2ARpcError = A2ARpcError;
65
+ async function postJsonRpc(endpointUrl, request, fetchImpl, protocolVersion = "1.0") {
66
+ const response = await fetchImpl(endpointUrl, {
67
+ method: "POST",
68
+ headers: { "content-type": "application/json", "A2A-Version": protocolVersion },
69
+ body: JSON.stringify(request),
70
+ });
71
+ if (!response.ok) {
72
+ throw new Error(`A2A JSON-RPC request failed (${response.status} ${response.statusText})`);
73
+ }
74
+ return await response.json();
75
+ }
76
+ function methodNotFound(response) {
77
+ return "error" in response && response.error.code === -32601;
78
+ }
79
+ function senderMetadata(input) {
80
+ return {
81
+ ...(input.senderAgentId ? { senderAgentId: input.senderAgentId } : {}),
82
+ ...(input.senderName ? { senderName: input.senderName } : {}),
83
+ ...(input.senderCardUrl ? { senderCardUrl: input.senderCardUrl } : {}),
84
+ };
85
+ }
86
+ async function sendA2AMessage(input) {
87
+ const fetchImpl = input.fetchImpl ?? fetch;
88
+ const messageId = (0, node_crypto_1.randomUUID)();
89
+ const request = {
90
+ jsonrpc: "2.0",
91
+ id: (0, node_crypto_1.randomUUID)(),
92
+ method: "message/send",
93
+ params: {
94
+ message: {
95
+ kind: "message",
96
+ role: "user",
97
+ messageId,
98
+ ...(input.taskId ? { taskId: input.taskId } : {}),
99
+ contextId: input.sessionKey ?? "default",
100
+ parts: [{ kind: "text", text: input.message }],
101
+ metadata: senderMetadata(input),
102
+ },
103
+ ...(input.accessToken ? { accessToken: input.accessToken } : {}),
104
+ },
105
+ };
106
+ (0, runtime_1.emitNervesEvent)({
107
+ component: "channels",
108
+ event: "channel.a2a_message_send_start",
109
+ message: "sending A2A message",
110
+ meta: { endpointUrl: input.endpointUrl, messageId },
111
+ });
112
+ let rpc = await postJsonRpc(input.endpointUrl, request, fetchImpl, "0.3");
113
+ if (methodNotFound(rpc)) {
114
+ rpc = await postJsonRpc(input.endpointUrl, {
115
+ ...request,
116
+ method: "SendMessage",
117
+ params: {
118
+ ...request.params,
119
+ message: {
120
+ ...(request.params.message),
121
+ role: "ROLE_USER",
122
+ },
123
+ },
124
+ }, fetchImpl);
125
+ }
126
+ if ("error" in rpc) {
127
+ throw new A2ARpcError(rpc.error);
128
+ }
129
+ const result = rpc.result;
130
+ const task = "task" in result && result.task ? result.task : result;
131
+ (0, runtime_1.emitNervesEvent)({
132
+ component: "channels",
133
+ event: "channel.a2a_message_send_end",
134
+ message: "sent A2A message",
135
+ meta: { endpointUrl: input.endpointUrl, messageId, taskId: task.id },
136
+ });
137
+ return task;
138
+ }
139
+ /**
140
+ * POST a pre-built friends A2A message (a `wrapInDataPart` sealed-envelope message)
141
+ * to a peer endpoint as a JSON-RPC `message/send`. This is the `direct`-rung wire
142
+ * the harness `A2ATransport` uses: friends' `sendShare` builds the sealed message and
143
+ * hands it to the transport, which delivers it here. Unlike `sendA2AMessage` (which
144
+ * builds a text part), this carries the caller's exact `message` (the sealed DataPart)
145
+ * untouched. Throws on a non-2xx response (transport failure).
146
+ */
147
+ async function postA2AMessageEnvelope(input) {
148
+ const fetchImpl = input.fetchImpl ?? fetch;
149
+ const request = {
150
+ jsonrpc: "2.0",
151
+ id: (0, node_crypto_1.randomUUID)(),
152
+ method: "message/send",
153
+ params: { message: input.message },
154
+ };
155
+ (0, runtime_1.emitNervesEvent)({
156
+ component: "channels",
157
+ event: "channel.a2a_envelope_post_start",
158
+ message: "posting sealed A2A message envelope (direct rung)",
159
+ meta: { endpointUrl: input.endpointUrl },
160
+ });
161
+ let rpc = await postJsonRpc(input.endpointUrl, request, fetchImpl, "0.3");
162
+ if (methodNotFound(rpc)) {
163
+ rpc = await postJsonRpc(input.endpointUrl, { ...request, method: "SendMessage" }, fetchImpl);
164
+ }
165
+ if ("error" in rpc) {
166
+ throw new A2ARpcError(rpc.error);
167
+ }
168
+ (0, runtime_1.emitNervesEvent)({
169
+ component: "channels",
170
+ event: "channel.a2a_envelope_post_end",
171
+ message: "posted sealed A2A message envelope",
172
+ meta: { endpointUrl: input.endpointUrl },
173
+ });
174
+ }
175
+ async function getA2ATask(input) {
176
+ const fetchImpl = input.fetchImpl ?? fetch;
177
+ const metadata = senderMetadata(input);
178
+ const request = {
179
+ jsonrpc: "2.0",
180
+ id: (0, node_crypto_1.randomUUID)(),
181
+ method: "tasks/get",
182
+ params: {
183
+ id: input.taskId,
184
+ ...(input.accessToken ? { accessToken: input.accessToken } : {}),
185
+ ...(Object.keys(metadata).length > 0 ? { metadata } : {}),
186
+ },
187
+ };
188
+ (0, runtime_1.emitNervesEvent)({
189
+ component: "channels",
190
+ event: "channel.a2a_task_get",
191
+ message: "fetching A2A task",
192
+ meta: { endpointUrl: input.endpointUrl, taskId: input.taskId },
193
+ });
194
+ let rpc = await postJsonRpc(input.endpointUrl, request, fetchImpl, "0.3");
195
+ if (methodNotFound(rpc)) {
196
+ rpc = await postJsonRpc(input.endpointUrl, { ...request, method: "GetTask" }, fetchImpl);
197
+ }
198
+ if ("error" in rpc) {
199
+ throw new A2ARpcError(rpc.error);
200
+ }
201
+ return rpc.result;
202
+ }
203
+ /**
204
+ * Talk to an A2A agent as a verified friend: seal `text` to the agent's card DID,
205
+ * signed by `identity`, send it, and open the sealed reply. The card must serve a
206
+ * did:key bound to it (the same check onboarding applies), so the reply can only be
207
+ * accepted from that key. Neither direction ever travels in plaintext.
208
+ */
209
+ async function sendSealedA2AChat(input) {
210
+ const fetchImpl = input.fetchImpl ?? fetch;
211
+ const sodium = input.sodium ?? await (0, a2a_client_1.ready)();
212
+ const card = await fetchA2AAgentCard(input.cardUrl, fetchImpl);
213
+ const peerDid = cardDid(card);
214
+ if (!peerDid)
215
+ throw new Error(`A2A card ${input.cardUrl} serves no DID; sealed chat needs one`);
216
+ const parsed = (0, a2a_client_1.parseDidKey)(peerDid);
217
+ if (!parsed || !(0, a2a_client_1.verifyCardDidBinding)({ card: { did: peerDid, url: input.cardUrl }, did: peerDid, didDoc: null })) {
218
+ throw new Error(`A2A card↔DID binding failed for ${peerDid}`);
219
+ }
220
+ const endpointUrl = endpointForCard(card);
221
+ const conversationId = input.conversationId ?? (0, node_crypto_1.randomUUID)();
222
+ const sealed = (0, sealed_chat_1.sealChatMessage)({
223
+ sodium,
224
+ from: input.identity,
225
+ recipientDid: peerDid,
226
+ recipientEd25519Pub: parsed.ed25519Pub,
227
+ text: input.text,
228
+ conversationId,
229
+ ...(input.onBehalfOf ? { onBehalfOf: input.onBehalfOf } : {}),
230
+ });
231
+ const request = {
232
+ jsonrpc: "2.0",
233
+ id: (0, node_crypto_1.randomUUID)(),
234
+ method: "SendMessage",
235
+ params: { message: { kind: "message", role: "ROLE_USER", messageId: (0, node_crypto_1.randomUUID)(), contextId: conversationId, parts: sealed.parts } },
236
+ };
237
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_chat_send_start", message: "sending sealed A2A chat message", meta: { endpointUrl, peerDid } });
238
+ const rpc = await postJsonRpc(endpointUrl, request, fetchImpl);
239
+ if ("error" in rpc)
240
+ throw new A2ARpcError(rpc.error);
241
+ const task = rpc.result;
242
+ const replyMessage = task?.status?.message;
243
+ if (!replyMessage)
244
+ throw new Error("A2A chat returned no reply message");
245
+ const opened = await (0, sealed_chat_1.openChatMessage)({ sodium, self: input.identity, message: replyMessage, senderDid: peerDid, senderEd25519Pub: parsed.ed25519Pub });
246
+ if (!opened.ok)
247
+ throw new Error(`A2A chat reply rejected: ${opened.reason}`);
248
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_chat_send_end", message: "received sealed A2A chat reply", meta: { endpointUrl, peerDid, taskId: task.id } });
249
+ return { text: opened.text, conversationId, taskId: task.id, peerDid, peerName: card.name };
250
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.A2A_DEFAULT_PATH = exports.A2A_DEFAULT_HOST = exports.A2A_DEFAULT_PROTOCOL_VERSION = void 0;
4
+ exports.defaultA2APort = defaultA2APort;
5
+ exports.normalizeA2APath = normalizeA2APath;
6
+ exports.a2aEndpointFromBaseUrl = a2aEndpointFromBaseUrl;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const runtime_1 = require("../nerves/runtime");
9
+ exports.A2A_DEFAULT_PROTOCOL_VERSION = "1.0";
10
+ exports.A2A_DEFAULT_HOST = "127.0.0.1";
11
+ exports.A2A_DEFAULT_PATH = "/a2a";
12
+ function defaultA2APort(agentName) {
13
+ const digest = (0, node_crypto_1.createHash)("sha256").update(agentName).digest();
14
+ const port = 18920 + (digest[0] % 60);
15
+ (0, runtime_1.emitNervesEvent)({
16
+ component: "channels",
17
+ event: "channel.a2a_default_port",
18
+ message: "computed default A2A port",
19
+ meta: { agentName, port },
20
+ });
21
+ return port;
22
+ }
23
+ function normalizeA2APath(value) {
24
+ const trimmed = value?.trim();
25
+ const normalized = !trimmed
26
+ ? exports.A2A_DEFAULT_PATH
27
+ : trimmed.startsWith("/")
28
+ ? trimmed
29
+ : `/${trimmed}`;
30
+ (0, runtime_1.emitNervesEvent)({
31
+ component: "channels",
32
+ event: "channel.a2a_path_normalized",
33
+ message: "normalized A2A path",
34
+ meta: { normalized },
35
+ });
36
+ return normalized;
37
+ }
38
+ function a2aEndpointFromBaseUrl(baseUrl, a2aPath = exports.A2A_DEFAULT_PATH) {
39
+ const url = new URL(baseUrl);
40
+ url.pathname = normalizeA2APath(a2aPath);
41
+ url.search = "";
42
+ url.hash = "";
43
+ (0, runtime_1.emitNervesEvent)({
44
+ component: "channels",
45
+ event: "channel.a2a_endpoint_built",
46
+ message: "built A2A endpoint URL",
47
+ meta: { endpoint: url.toString() },
48
+ });
49
+ return url.toString();
50
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DELEGATED_COMMAND_GRANTS_FILE = void 0;
4
+ exports.delegatedCommandGrantsPath = delegatedCommandGrantsPath;
5
+ exports.viewDelegatedCommandGrants = viewDelegatedCommandGrants;
6
+ exports.readDelegatedCommandGrants = readDelegatedCommandGrants;
7
+ exports.checkDelegatedCommandGrant = checkDelegatedCommandGrant;
8
+ exports.setDelegatedCommandGrant = setDelegatedCommandGrant;
9
+ const runtime_1 = require("../nerves/runtime");
10
+ const operator_trust_1 = require("./operator-trust");
11
+ const replay_grant_holders_1 = require("./replay-grant-holders");
12
+ const replay_harness_1 = require("./replay-harness");
13
+ exports.DELEGATED_COMMAND_GRANTS_FILE = "delegated-command-grants.json";
14
+ function delegatedCommandGrantsPath(agentRoot) {
15
+ return (0, operator_trust_1.operatorTrustFile)(agentRoot, exports.DELEGATED_COMMAND_GRANTS_FILE);
16
+ }
17
+ function validGrant(value) {
18
+ if (!value || typeof value !== "object" || Array.isArray(value))
19
+ return false;
20
+ const grant = value;
21
+ const keys = Object.keys(grant).sort().join(",");
22
+ return (keys === "did,grantedAt,scope,source" || keys === "did,expiresAt,grantedAt,scope,source")
23
+ && grant.scope === "principal_commands"
24
+ && typeof grant.did === "string" && grant.did.startsWith("did:") && grant.did.length <= 512
25
+ && typeof grant.grantedAt === "string" && !Number.isNaN(Date.parse(grant.grantedAt))
26
+ && typeof grant.source === "string" && grant.source.trim().length > 0
27
+ && (grant.expiresAt === undefined || typeof grant.expiresAt === "string");
28
+ }
29
+ /** The file's trust state, every well-formed grant in it keyed by friend id, and the friend ids whose entries were dropped. */
30
+ function viewDelegatedCommandGrants(agentRoot) {
31
+ return (0, operator_trust_1.readGrantFile)(agentRoot, exports.DELEGATED_COMMAND_GRANTS_FILE, validGrant);
32
+ }
33
+ function readDelegatedCommandGrants(agentRoot) {
34
+ return viewDelegatedCommandGrants(agentRoot).grants;
35
+ }
36
+ /**
37
+ * The one answer to "may this friend relay the principal's commands right now?". Admission, the follow-up path and
38
+ * `list` all ask it, so they cannot disagree. `signerDid` is the DID the message was verified as: it must equal the
39
+ * DID the operator pinned. Order: file trusted, grant exists, DID matches, not expired (an expiry that is not a finite
40
+ * time counts as expired, and so does a replay identity whose root-owned window is closed), then family and active.
41
+ */
42
+ function checkDelegatedCommandGrant(agentRoot, friend, signerDid, now = Date.now()) {
43
+ const view = viewDelegatedCommandGrants(agentRoot);
44
+ if (view.state === "untrusted")
45
+ return { ok: false, reason: "grants_untrusted" };
46
+ const grant = view.grants[friend.id];
47
+ if (!grant)
48
+ return { ok: false, reason: "no_grant" };
49
+ if (grant.did !== signerDid)
50
+ return { ok: false, reason: "grant_did_mismatch" };
51
+ if (grant.expiresAt !== undefined) {
52
+ const expiresAt = Date.parse(grant.expiresAt);
53
+ if (!Number.isFinite(expiresAt) || expiresAt <= now)
54
+ return { ok: false, reason: "grant_expired" };
55
+ }
56
+ // A grant for a friend on the root-owned replay list must be time-bounded by the trusted file itself. The bundle's replay registry is the agent's to move aside, so it only ever adds the window check below.
57
+ if (grant.expiresAt === undefined && (0, replay_grant_holders_1.isReplayGrantHolder)(agentRoot, friend.id))
58
+ return { ok: false, reason: "grant_expired" };
59
+ // A replay identity is a test peer of the host's replay gate: its grant means something only while the root-owned window is open.
60
+ if ((0, replay_harness_1.isReplayIdentity)(agentRoot, friend.id) && !(0, replay_harness_1.isReplayWindowOpen)(agentRoot, friend.id, now))
61
+ return { ok: false, reason: "grant_expired" };
62
+ if (friend.trustLevel !== "family" || friend.admissionState !== "active")
63
+ return { ok: false, reason: "not_family" };
64
+ return { ok: true };
65
+ }
66
+ /** Writes or removes one grant. The previous file is kept beside it as a timestamped backup before the change. */
67
+ function setDelegatedCommandGrant(agentRoot, friendId, change, now = new Date()) {
68
+ return (0, operator_trust_1.withTrustedWriteLock)(agentRoot, () => setDelegatedCommandGrantLocked(agentRoot, friendId, change, now));
69
+ }
70
+ function setDelegatedCommandGrantLocked(agentRoot, friendId, change, now) {
71
+ const current = readDelegatedCommandGrants(agentRoot);
72
+ const had = current[friendId];
73
+ const next = { ...current };
74
+ if (change.grant) {
75
+ const entry = { scope: "principal_commands", did: change.did, grantedAt: now.toISOString(), source: change.source, ...(change.expiresAt ? { expiresAt: change.expiresAt } : {}) };
76
+ if (had && had.did === entry.did && had.source === entry.source && had.expiresAt === entry.expiresAt)
77
+ return { changed: false, backup: null };
78
+ next[friendId] = entry;
79
+ }
80
+ else {
81
+ if (had === undefined)
82
+ return { changed: false, backup: null };
83
+ delete next[friendId];
84
+ }
85
+ const { backup } = (0, operator_trust_1.writeTrustedFile)(agentRoot, exports.DELEGATED_COMMAND_GRANTS_FILE, `${JSON.stringify({ schemaVersion: 1, grants: next }, null, 2)}\n`, now);
86
+ (0, runtime_1.emitNervesEvent)({
87
+ component: "senses",
88
+ event: "senses.a2a_delegated_command_grant_changed",
89
+ message: change.grant ? "granted delegated commands to an A2A peer" : "revoked an A2A peer's delegated-command grant",
90
+ meta: { friendId, granted: change.grant },
91
+ });
92
+ return { changed: true, backup };
93
+ }
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DELEGATED_BANNER = exports.A2A_PRINCIPAL_PROFILE_ID = void 0;
37
+ exports.delegatedCommandWasNoticed = delegatedCommandWasNoticed;
38
+ exports.delegationRefusalGuidance = delegationRefusalGuidance;
39
+ exports.shieldDelegatedBanner = shieldDelegatedBanner;
40
+ exports.delegatedCommandNotice = delegatedCommandNotice;
41
+ exports.admitDelegatedCommand = admitDelegatedCommand;
42
+ const crypto_1 = require("crypto");
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const runtime_1 = require("../nerves/runtime");
46
+ const delegated_command_grants_1 = require("./delegated-command-grants");
47
+ const replay_harness_1 = require("./replay-harness");
48
+ const relationship_authorization_1 = require("../repertoire/relationship-authorization");
49
+ const NOTICE_EXCERPT_CHARS = 200;
50
+ /** The relationship profile that names the principal a delegated peer acts for. */
51
+ exports.A2A_PRINCIPAL_PROFILE_ID = "sanctuary-owner";
52
+ /**
53
+ * True when the owner was told about delegated command `commandId` in their own chat: admission only runs a command
54
+ * after that notice is delivered, and the Telegram effect journal keeps the notice under a key derived from the
55
+ * command id. A request id with no such record never came through a signed, owner-notified delegated command.
56
+ * A missing record is `false`; an unreadable or malformed one throws, so the caller retries instead of deciding.
57
+ */
58
+ function delegatedCommandWasNoticed(agentRoot, commandId, principalFriendId, delegateFriendId) {
59
+ const idempotencyKey = `owner-notice:delegated:${commandId}`;
60
+ const file = path.join(agentRoot, "state", "telegram", "effects", `${(0, crypto_1.createHash)("sha256").update(idempotencyKey).digest("hex")}.json`);
61
+ let raw;
62
+ try {
63
+ raw = fs.readFileSync(file, "utf8");
64
+ }
65
+ catch (error) {
66
+ if (error.code === "ENOENT")
67
+ return delegateFriendId !== undefined && (0, replay_harness_1.isReplayWindowOpen)(agentRoot, delegateFriendId) && (0, replay_harness_1.replayNoticeRecorded)(agentRoot, `delegated:${commandId}`, delegateFriendId);
68
+ throw error;
69
+ }
70
+ const artifact = JSON.parse(raw);
71
+ return artifact.idempotencyKey === idempotencyKey && artifact.authorClass === "butler" && artifact.target?.friendId === principalFriendId;
72
+ }
73
+ /**
74
+ * What a refused sender is told. Every refusal says that nothing ran and names the next step; the reason code stays
75
+ * first on the wire (`delegated command refused: <reason>`) because the replay gate and older CLIs match it.
76
+ */
77
+ function delegationRefusalGuidance(reason, hints) {
78
+ switch (reason) {
79
+ case "not_enabled":
80
+ return { message: "this agent does not accept delegated commands", next: "Send the message without --delegated, or ask the agent's operator to enable delegated commands.", retry: false };
81
+ case "no_grant":
82
+ return {
83
+ message: hints.legacyRecordGrant
84
+ ? "the operator has not granted you delegated commands; a grant on your friend record is not honoured, because the agent could have written it"
85
+ : "the operator has not granted you delegated commands",
86
+ next: `Ask the operator to run, as root on the agent's host: ouro a2a delegated-commands grant --friend <your friend id> --did <your DID> (your DID is in: ouro a2a identity --json).${hints.legacyRecordGrant ? " Grants live in the operator trust directory now, not on the friend record." : ""}`,
87
+ retry: false,
88
+ };
89
+ case "grants_untrusted":
90
+ return { message: "the agent cannot trust its grant file, so it honours no delegated-command grants", next: "Ask the operator to run: ouro a2a delegated-commands list, and fix the owner or mode it reports.", retry: false };
91
+ case "grant_did_mismatch":
92
+ return { message: "this message was signed by a different key than the one the operator granted", next: "Send from the host whose DID the operator pinned, or ask the operator to re-grant with your current DID: ouro a2a delegated-commands grant --friend <your friend id> --did <your DID>.", retry: false };
93
+ case "grant_expired":
94
+ return { message: "your delegated-command grant has expired or is not in force", next: "Ask the operator to re-grant: ouro a2a delegated-commands grant --friend <your friend id> --did <your DID> [--expires <ISO date>].", retry: false };
95
+ case "not_family":
96
+ return { message: "you are not active family on this agent's records, so the grant is suspended", next: "Ask the operator to restore your trust and admission, then try again.", retry: false };
97
+ case "principal_unresolved":
98
+ return { message: "the agent cannot tell whose command this is (its owner record is missing or ambiguous)", next: "Ask the operator to check the owner's friend record on the agent's host.", retry: false };
99
+ case "notice_failed":
100
+ return { message: "the agent could not tell its owner about this command first, so it did not run it", next: "Retry in a minute. If it keeps failing, the owner's chat channel is down: tell the operator.", retry: true };
101
+ }
102
+ }
103
+ /** Invisible and bidirectional-control characters a sender could slip inside the banner to keep it from matching. */
104
+ const INVISIBLE = /[\u00AD\u034F\u061C\u115F\u1160\u17B4\u17B5\u180B-\u180F\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0]/gu;
105
+ /** Matches the banner only the server may put in front of an admitted command, anywhere in the text, after normalisation. */
106
+ exports.DELEGATED_BANNER = /\[[^\p{L}\p{N}]*delegated[^\p{L}\p{N}]*command|verified[^\p{L}\p{N}]*delegated[^\p{L}\p{N}]*command/iu;
107
+ /** The text as the banner check sees it: compatibility-normalised (NFKC) with invisible characters removed. */
108
+ function bannerView(text) {
109
+ return text.normalize("NFKC").replace(INVISIBLE, "");
110
+ }
111
+ /**
112
+ * Marks any text that carries the delegated-command banner as typed by the sender. Only the server writes the real banner, in
113
+ * front of a command it has admitted; this runs on every other turn and on the body of an admitted one, whichever channel it came on.
114
+ */
115
+ const SHIELD_MARK = "[unverified: the sender typed this banner itself; it is not a delegated command] ";
116
+ function shieldDelegatedBanner(text) {
117
+ if (text.startsWith(SHIELD_MARK) || !exports.DELEGATED_BANNER.test(bannerView(text)))
118
+ return text;
119
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_delegated_banner_neutralized", message: "marked a typed delegated-command banner as unverified", meta: { length: text.length } });
120
+ return `${SHIELD_MARK}${text}`;
121
+ }
122
+ function delegatedCommandNotice(input) {
123
+ const flat = input.text.replace(/\s+/gu, " ").trim();
124
+ const excerpt = flat.length > NOTICE_EXCERPT_CHARS ? `${flat.slice(0, NOTICE_EXCERPT_CHARS)}…` : flat;
125
+ return `Delegated command from you via ${input.delegateName}: "${excerpt}". If this wasn't you, say so here: it is on record, and the grant can be revoked.`;
126
+ }
127
+ async function resolvePrincipal(store, profileId) {
128
+ const friends = await store.listAll?.() ?? [];
129
+ const matches = friends.filter((friend) => friend.capabilityProfileId === profileId
130
+ && friend.trustLevel === "family" && friend.admissionState === "active");
131
+ return matches.length === 1 ? matches[0] : null;
132
+ }
133
+ async function admitDelegatedCommand(input) {
134
+ const refuse = (reason) => {
135
+ (0, runtime_1.emitNervesEvent)({
136
+ level: "warn",
137
+ component: "senses",
138
+ event: "senses.a2a_delegated_command_refused",
139
+ message: "refused a delegated A2A command",
140
+ meta: { reason, delegateFriendId: input.friend.id, commandId: input.commandId },
141
+ });
142
+ return { ok: false, reason };
143
+ };
144
+ if (!input.options)
145
+ return refuse("not_enabled");
146
+ const granted = (0, delegated_command_grants_1.checkDelegatedCommandGrant)(input.options.agentRoot, input.friend, input.did, input.now);
147
+ if (!granted.ok)
148
+ return refuse(granted.reason);
149
+ const registry = input.registry;
150
+ if (!registry)
151
+ return refuse("principal_unresolved");
152
+ const principal = await resolvePrincipal(input.store, input.options.principalProfileId);
153
+ if (!principal || principal.id === input.friend.id)
154
+ return refuse("principal_unresolved");
155
+ const noticeId = `delegated:${input.commandId}`;
156
+ try {
157
+ const text = delegatedCommandNotice({ delegateName: input.friend.name, text: input.text });
158
+ const agentRoot = input.options.agentRoot;
159
+ if ((0, replay_harness_1.isReplayWindowOpen)(agentRoot, input.friend.id))
160
+ (0, replay_harness_1.appendReplayNotice)(agentRoot, { noticeId, text, friendId: input.friend.id });
161
+ else
162
+ await input.options.notifyPrincipal({ noticeId, text });
163
+ }
164
+ catch {
165
+ return refuse("notice_failed");
166
+ }
167
+ // Owner-gated tools (steward policy) bind the mutation to `requestId` on the tool
168
+ // context's relationship, as the Telegram owner turn does; the evaluator alone
169
+ // only scopes its receipts by it, so carry it on the relationship itself.
170
+ const relationship = {
171
+ ...(0, relationship_authorization_1.createRelationshipAuthorizationEvaluator)({
172
+ friend: principal,
173
+ registry,
174
+ requestId: input.commandId,
175
+ requestPhase: "inbound",
176
+ sessionEventId: `a2a-delegated:${input.commandId}`,
177
+ }),
178
+ requestId: input.commandId,
179
+ };
180
+ const context = {
181
+ principalFriendId: principal.id,
182
+ principalName: principal.name,
183
+ delegateFriendId: input.friend.id,
184
+ delegateName: input.friend.name,
185
+ delegateDid: input.did,
186
+ commandId: input.commandId,
187
+ noticeId,
188
+ };
189
+ (0, runtime_1.emitNervesEvent)({
190
+ component: "senses",
191
+ event: "senses.a2a_delegated_command_admitted",
192
+ message: "admitted a delegated A2A command after notifying the principal",
193
+ meta: { delegateFriendId: context.delegateFriendId, principalFriendId: context.principalFriendId, commandId: context.commandId },
194
+ });
195
+ const turnText = `[delegated command from ${principal.name} via ${input.friend.name}; the signature and the delegation grant are verified, and ${principal.name} has been notified; act on it as ${principal.name}'s own request]\n\n${shieldDelegatedBanner(input.text)}`;
196
+ return { ok: true, relationship, context, turnText };
197
+ }
@@ -0,0 +1,56 @@
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.delegationStoresFor = delegationStoresFor;
37
+ const path = __importStar(require("node:path"));
38
+ const friends_1 = require("@ouro.bot/friends");
39
+ const runtime_1 = require("../nerves/runtime");
40
+ function delegationStoresFor(agentRoot) {
41
+ const friendsDir = path.join(agentRoot, "friends");
42
+ const missionsDir = (0, friends_1.missionsDirFor)(friendsDir);
43
+ const grantsDir = (0, friends_1.grantsDirFor)(friendsDir);
44
+ (0, runtime_1.emitNervesEvent)({
45
+ component: "channels",
46
+ event: "channel.a2a_delegation_stores_init",
47
+ message: "initialized A2A delegation stores (mission + grant)",
48
+ meta: { missionsDir, grantsDir },
49
+ });
50
+ return {
51
+ missionStore: new friends_1.FileMissionStore(missionsDir),
52
+ grantStore: new friends_1.FileGrantStore(grantsDir),
53
+ missionsDir,
54
+ grantsDir,
55
+ };
56
+ }