@ouro.bot/cli 0.1.0-alpha.9 → 0.1.0-alpha.900

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 (712) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -176
  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/SerpentGuide.ouro/agent.json +83 -0
  11. package/SerpentGuide.ouro/psyche/SOUL.md +25 -0
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
  13. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  14. package/assets/bluebubbles-host +264 -0
  15. package/assets/ouroboros.png +0 -0
  16. package/assets/sanctuary-host-launcher.sh +16 -0
  17. package/changelog.json +6224 -0
  18. package/deploy/unraid/Dockerfile +58 -0
  19. package/deploy/unraid/README.txt +2997 -0
  20. package/deploy/unraid/audit-container-spec.sh +4 -0
  21. package/deploy/unraid/container-runtime.json +1 -0
  22. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  23. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  24. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  25. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  26. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  27. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  28. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  29. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  30. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  31. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  32. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  33. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  34. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  35. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1254 -0
  36. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  37. package/deploy/unraid/sanctuary-replay-gate.mjs +1614 -0
  38. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  39. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  40. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  41. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  42. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  43. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  44. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  45. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  46. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  47. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  48. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +27 -0
  52. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  53. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  54. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  55. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  56. package/deploy/unraid/sanctuary.xml +30 -0
  57. package/dist/a2a/card.js +57 -0
  58. package/dist/a2a/client.js +250 -0
  59. package/dist/a2a/config.js +50 -0
  60. package/dist/a2a/delegated-command-grants.js +93 -0
  61. package/dist/a2a/delegated-command.js +197 -0
  62. package/dist/a2a/delegation-stores.js +56 -0
  63. package/dist/a2a/did-resolution.js +93 -0
  64. package/dist/a2a/escalation-grants.js +84 -0
  65. package/dist/a2a/escalation-wiring.js +60 -0
  66. package/dist/a2a/identity.js +258 -0
  67. package/dist/a2a/inbound-share.js +110 -0
  68. package/dist/a2a/mission-result-wire.js +196 -0
  69. package/dist/a2a/onboarding.js +133 -0
  70. package/dist/a2a/operator-trust.js +382 -0
  71. package/dist/a2a/outbox-client.js +57 -0
  72. package/dist/a2a/outbox-store.js +188 -0
  73. package/dist/a2a/outbox-wire.js +95 -0
  74. package/dist/a2a/pin-store.js +132 -0
  75. package/dist/a2a/replay-grant-holders.js +33 -0
  76. package/dist/a2a/replay-harness.js +188 -0
  77. package/dist/a2a/resolution-proof.js +53 -0
  78. package/dist/a2a/sealed-chat.js +113 -0
  79. package/dist/a2a/seen-ledger.js +120 -0
  80. package/dist/a2a/server.js +771 -0
  81. package/dist/a2a/task-store.js +69 -0
  82. package/dist/a2a/transport.js +45 -0
  83. package/dist/a2a/trust-commands.js +203 -0
  84. package/dist/a2a/trusted-files.js +185 -0
  85. package/dist/a2a/types.js +3 -0
  86. package/dist/arc/attention-types.js +8 -0
  87. package/dist/arc/cares.js +360 -0
  88. package/dist/arc/episodes.js +118 -0
  89. package/dist/arc/evolution.js +490 -0
  90. package/dist/arc/flight-recorder.js +1034 -0
  91. package/dist/arc/intentions.js +134 -0
  92. package/dist/arc/json-store.js +117 -0
  93. package/dist/arc/obligations.js +386 -0
  94. package/dist/arc/packets.js +336 -0
  95. package/dist/arc/presence.js +185 -0
  96. package/dist/arc/task-lifecycle.js +57 -0
  97. package/dist/commerce/store.js +755 -0
  98. package/dist/commerce/types.js +3 -0
  99. package/dist/heart/active-work.js +1009 -0
  100. package/dist/heart/agent-entry.js +252 -3
  101. package/dist/heart/approval-files.js +113 -0
  102. package/dist/heart/approval-store.js +960 -0
  103. package/dist/heart/attachments/image-normalize.js +194 -0
  104. package/dist/heart/attachments/materialize.js +97 -0
  105. package/dist/heart/attachments/originals.js +88 -0
  106. package/dist/heart/attachments/render.js +29 -0
  107. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  108. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  109. package/dist/heart/attachments/sources/index.js +18 -0
  110. package/dist/heart/attachments/sources/telegram.js +71 -0
  111. package/dist/heart/attachments/store.js +132 -0
  112. package/dist/heart/attachments/types.js +93 -0
  113. package/dist/heart/auth/auth-flow.js +495 -0
  114. package/dist/heart/autonomy-budget.js +478 -0
  115. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  116. package/dist/heart/awaiting/await-alert.js +152 -0
  117. package/dist/heart/awaiting/await-expiry.js +143 -0
  118. package/dist/heart/awaiting/await-loader.js +91 -0
  119. package/dist/heart/awaiting/await-parser.js +152 -0
  120. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  121. package/dist/heart/awaiting/await-scheduler.js +391 -0
  122. package/dist/heart/background-operations.js +281 -0
  123. package/dist/heart/bridges/manager.js +478 -0
  124. package/dist/heart/bridges/state-machine.js +135 -0
  125. package/dist/heart/bridges/store.js +135 -0
  126. package/dist/heart/bundle-state.js +168 -0
  127. package/dist/heart/commitments.js +135 -0
  128. package/dist/heart/config-registry.js +331 -0
  129. package/dist/heart/config.js +225 -137
  130. package/dist/heart/context-loss-gauntlet.js +387 -0
  131. package/dist/heart/context-loss-sentinel.js +1157 -0
  132. package/dist/heart/core.js +2442 -343
  133. package/dist/heart/cross-chat-delivery.js +133 -0
  134. package/dist/heart/daemon/agent-config-check.js +451 -0
  135. package/dist/heart/daemon/agent-discovery.js +355 -0
  136. package/dist/heart/daemon/agent-home.js +319 -0
  137. package/dist/heart/daemon/agent-service.js +542 -0
  138. package/dist/heart/daemon/agentic-repair.js +547 -0
  139. package/dist/heart/daemon/await-private-wake.js +59 -0
  140. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  141. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  142. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  143. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  144. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  145. package/dist/heart/daemon/cadence.js +180 -0
  146. package/dist/heart/daemon/cli-defaults.js +859 -0
  147. package/dist/heart/daemon/cli-desk.js +322 -0
  148. package/dist/heart/daemon/cli-exec.js +9003 -0
  149. package/dist/heart/daemon/cli-help.js +729 -0
  150. package/dist/heart/daemon/cli-parse.js +3140 -0
  151. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  152. package/dist/heart/daemon/cli-render.js +804 -0
  153. package/dist/heart/daemon/cli-types.js +8 -0
  154. package/dist/heart/daemon/connect-bay.js +323 -0
  155. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  156. package/dist/heart/daemon/container-healthcheck.js +112 -0
  157. package/dist/heart/daemon/container-runtime.js +97 -0
  158. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  159. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  160. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  161. package/dist/heart/daemon/daemon-cli.js +30 -882
  162. package/dist/heart/daemon/daemon-entry.js +1002 -13
  163. package/dist/heart/daemon/daemon-health.js +186 -0
  164. package/dist/heart/daemon/daemon-rollup.js +57 -0
  165. package/dist/heart/daemon/daemon-runtime-sync.js +287 -0
  166. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  167. package/dist/heart/daemon/daemon.js +2213 -28
  168. package/dist/heart/daemon/dns-workflow.js +394 -0
  169. package/dist/heart/daemon/doctor-types.js +8 -0
  170. package/dist/heart/daemon/doctor.js +1755 -0
  171. package/dist/heart/daemon/freshness.js +345 -0
  172. package/dist/heart/daemon/habit-private-wake.js +61 -0
  173. package/dist/heart/daemon/health-monitor.js +142 -11
  174. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  175. package/dist/heart/daemon/hooks/bundle-meta.js +226 -0
  176. package/dist/heart/daemon/http-health-probe.js +80 -0
  177. package/dist/heart/daemon/human-command-screens.js +234 -0
  178. package/dist/heart/daemon/human-readiness.js +114 -0
  179. package/dist/heart/daemon/inner-status.js +78 -0
  180. package/dist/heart/daemon/interactive-repair.js +394 -0
  181. package/dist/heart/daemon/launchd.js +188 -0
  182. package/dist/heart/daemon/log-tailer.js +82 -12
  183. package/dist/heart/daemon/logs-prune.js +132 -0
  184. package/dist/heart/daemon/mcp-canary.js +524 -0
  185. package/dist/heart/daemon/message-router.js +80 -11
  186. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  187. package/dist/heart/daemon/os-cron-deps.js +135 -0
  188. package/dist/heart/daemon/os-cron.js +22 -14
  189. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  190. package/dist/heart/daemon/ouro-entry.js +3 -1
  191. package/dist/heart/daemon/plugin-cli.js +432 -0
  192. package/dist/heart/daemon/process-manager.js +766 -54
  193. package/dist/heart/daemon/provider-discovery.js +137 -0
  194. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  195. package/dist/heart/daemon/prunable-bundle.js +144 -0
  196. package/dist/heart/daemon/pulse.js +511 -0
  197. package/dist/heart/daemon/readiness-repair.js +365 -0
  198. package/dist/heart/daemon/run-hooks.js +39 -0
  199. package/dist/heart/daemon/runtime-logging.js +92 -16
  200. package/dist/heart/daemon/runtime-metadata.js +191 -0
  201. package/dist/{repertoire/tasks/lifecycle.js → heart/daemon/runtime-mode.js} +37 -39
  202. package/dist/heart/daemon/safe-mode.js +161 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  206. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  207. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  208. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  209. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  210. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  211. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  212. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  213. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  214. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  215. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  216. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  217. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  219. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  220. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  222. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  225. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  226. package/dist/heart/daemon/sense-manager.js +975 -0
  227. package/dist/heart/daemon/session-id-resolver.js +131 -0
  228. package/dist/heart/daemon/skill-management-installer.js +94 -0
  229. package/dist/heart/daemon/socket-client.js +370 -0
  230. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  231. package/dist/heart/daemon/startup-tui.js +339 -0
  232. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  233. package/dist/heart/daemon/task-scheduler.js +117 -39
  234. package/dist/heart/daemon/terminal-ui.js +499 -0
  235. package/dist/heart/daemon/thoughts.js +591 -0
  236. package/dist/heart/daemon/up-progress.js +366 -0
  237. package/dist/heart/daemon/vault-items.js +56 -0
  238. package/dist/heart/delegation.js +59 -0
  239. package/dist/heart/external-events/router.js +1516 -0
  240. package/dist/heart/failure-reports.js +335 -0
  241. package/dist/heart/file-lock.js +109 -0
  242. package/dist/heart/frontend-approval-runtime.js +506 -0
  243. package/dist/heart/frontend-journal.js +215 -0
  244. package/dist/heart/frontend-session-service.js +237 -0
  245. package/dist/heart/frontend-socket-client.js +164 -0
  246. package/dist/heart/frontend-socket.js +400 -0
  247. package/dist/heart/habits/habit-cancel.js +810 -0
  248. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  249. package/dist/heart/habits/habit-migration.js +194 -0
  250. package/dist/heart/habits/habit-parser.js +278 -0
  251. package/dist/heart/habits/habit-runtime-state.js +93 -0
  252. package/dist/heart/habits/habit-scheduler.js +653 -0
  253. package/dist/heart/habits/habit-session-summary.js +318 -0
  254. package/dist/heart/habits/habit-session.js +636 -0
  255. package/dist/heart/{daemon → hatch}/hatch-animation.js +10 -3
  256. package/dist/heart/{daemon → hatch}/hatch-flow.js +57 -139
  257. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  258. package/dist/heart/hatch/specialist-orchestrator.js +129 -0
  259. package/dist/heart/hatch/specialist-prompt.js +102 -0
  260. package/dist/heart/hatch/specialist-tools.js +318 -0
  261. package/dist/heart/identity.js +312 -67
  262. package/dist/heart/kept-notes.js +289 -0
  263. package/dist/heart/kicks.js +2 -20
  264. package/dist/heart/machine-identity.js +175 -0
  265. package/dist/heart/mail-import-discovery.js +356 -0
  266. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  267. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  268. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  269. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  270. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  271. package/dist/heart/mailbox/mailbox-http.js +99 -0
  272. package/dist/heart/mailbox/mailbox-read.js +39 -0
  273. package/dist/heart/mailbox/mailbox-types.js +27 -0
  274. package/dist/heart/mailbox/mailbox-view.js +197 -0
  275. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  276. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  277. package/dist/heart/mailbox/readers/mail.js +375 -0
  278. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  279. package/dist/heart/mailbox/readers/sessions.js +231 -0
  280. package/dist/heart/mailbox/readers/shared.js +111 -0
  281. package/dist/heart/mcp/mcp-server.js +696 -0
  282. package/dist/heart/migrate-config.js +100 -0
  283. package/dist/heart/model-capabilities.js +59 -0
  284. package/dist/heart/orientation-frame.js +345 -0
  285. package/dist/heart/platform.js +81 -0
  286. package/dist/heart/primitives.js +1 -1
  287. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  288. package/dist/heart/private-runtime/index.js +18 -0
  289. package/dist/heart/private-runtime/ledger.js +221 -0
  290. package/dist/heart/private-runtime/policy.js +260 -0
  291. package/dist/heart/private-runtime/types.js +2 -0
  292. package/dist/heart/progress-story.js +42 -0
  293. package/dist/heart/provider-attempt.js +137 -0
  294. package/dist/heart/provider-binding-resolver.js +273 -0
  295. package/dist/heart/provider-credentials.js +449 -0
  296. package/dist/heart/provider-failover.js +311 -0
  297. package/dist/heart/provider-models.js +96 -0
  298. package/dist/heart/provider-ping.js +265 -0
  299. package/dist/heart/provider-readiness-cache.js +119 -0
  300. package/dist/heart/provider-visibility.js +188 -0
  301. package/dist/heart/providers/anthropic-token.js +131 -0
  302. package/dist/heart/providers/anthropic.js +236 -58
  303. package/dist/heart/providers/azure.js +104 -13
  304. package/dist/heart/providers/error-classification.js +127 -0
  305. package/dist/heart/providers/github-copilot.js +145 -0
  306. package/dist/heart/providers/minimax-vlm.js +189 -0
  307. package/dist/heart/providers/minimax.js +29 -7
  308. package/dist/heart/providers/openai-codex-token.js +349 -0
  309. package/dist/heart/providers/openai-codex.js +63 -39
  310. package/dist/heart/providers/openai-compatible.js +177 -0
  311. package/dist/heart/reply-style.js +56 -0
  312. package/dist/heart/run-ledger.js +247 -0
  313. package/dist/heart/runtime-capability-check.js +170 -0
  314. package/dist/heart/runtime-credentials.js +607 -0
  315. package/dist/heart/runtime-cwd.js +87 -0
  316. package/dist/heart/sense-truth.js +81 -0
  317. package/dist/heart/session-activity.js +237 -0
  318. package/dist/heart/session-events.js +1504 -0
  319. package/dist/heart/session-playback-cli-main.js +5 -0
  320. package/dist/heart/session-playback-cli.js +36 -0
  321. package/dist/heart/session-playback.js +231 -0
  322. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  323. package/dist/heart/session-redaction-repair.js +552 -0
  324. package/dist/heart/session-stats-cli-main.js +5 -0
  325. package/dist/heart/session-stats.js +183 -0
  326. package/dist/heart/session-transcript.js +133 -0
  327. package/dist/heart/shepherd-config.js +113 -0
  328. package/dist/heart/source-grounding.js +283 -0
  329. package/dist/heart/start-of-turn-packet.js +372 -0
  330. package/dist/heart/steward-policy.js +656 -0
  331. package/dist/heart/streaming.js +682 -207
  332. package/dist/heart/structured-output.js +196 -0
  333. package/dist/heart/sync-classification.js +176 -0
  334. package/dist/heart/sync.js +505 -0
  335. package/dist/heart/target-resolution.js +127 -0
  336. package/dist/heart/tempo.js +93 -0
  337. package/dist/heart/temporal-view.js +41 -0
  338. package/dist/heart/timeouts.js +101 -0
  339. package/dist/heart/tool-activity-callbacks.js +59 -0
  340. package/dist/heart/tool-approval.js +382 -0
  341. package/dist/heart/tool-description.js +155 -0
  342. package/dist/heart/tool-friction.js +55 -0
  343. package/dist/heart/tool-loop.js +206 -0
  344. package/dist/heart/turn-context.js +494 -0
  345. package/dist/heart/turn-coordinator.js +28 -0
  346. package/dist/heart/turn-execution-lease.js +30 -0
  347. package/dist/heart/versioning/ouro-bot-global-installer.js +129 -0
  348. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  349. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  350. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  351. package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
  352. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  353. package/dist/heart/versioning/staged-restart.js +146 -0
  354. package/dist/heart/versioning/update-checker.js +116 -0
  355. package/dist/heart/versioning/update-hooks.js +154 -0
  356. package/dist/heart/versioning/version-intent.js +114 -0
  357. package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
  358. package/dist/heart/work-card.js +380 -0
  359. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  360. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  361. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  362. package/dist/mailbox-ui/index.html +16 -0
  363. package/dist/mailroom/attention.js +167 -0
  364. package/dist/mailroom/autonomy.js +209 -0
  365. package/dist/mailroom/blob-store.js +889 -0
  366. package/dist/mailroom/body-cache.js +61 -0
  367. package/dist/mailroom/cache-sync-cli.js +58 -0
  368. package/dist/mailroom/core.js +803 -0
  369. package/dist/mailroom/entry.js +160 -0
  370. package/dist/mailroom/file-store.js +568 -0
  371. package/dist/mailroom/hosted-cache-sync.js +384 -0
  372. package/dist/mailroom/mbox-import.js +393 -0
  373. package/dist/mailroom/migration.js +164 -0
  374. package/dist/mailroom/outbound.js +380 -0
  375. package/dist/mailroom/policy.js +263 -0
  376. package/dist/mailroom/reader.js +292 -0
  377. package/dist/mailroom/search-cache.js +513 -0
  378. package/dist/mailroom/search-relevance.js +319 -0
  379. package/dist/mailroom/smtp-ingress.js +176 -0
  380. package/dist/mailroom/source-state.js +176 -0
  381. package/dist/mailroom/thread.js +109 -0
  382. package/dist/mailroom/travel-extract.js +89 -0
  383. package/dist/mind/bundle-manifest.js +93 -1
  384. package/dist/mind/context.js +318 -104
  385. package/dist/mind/desk-section.js +362 -0
  386. package/dist/mind/diary-integrity.js +60 -0
  387. package/dist/mind/{memory.js → diary.js} +90 -98
  388. package/dist/mind/embedding-provider.js +60 -0
  389. package/dist/mind/file-state.js +179 -0
  390. package/dist/mind/first-impressions.js +16 -2
  391. package/dist/mind/{associative-recall.js → note-search.js} +61 -60
  392. package/dist/mind/obligation-steering.js +227 -0
  393. package/dist/mind/pending.js +103 -10
  394. package/dist/mind/phrases.js +1 -0
  395. package/dist/mind/prompt-budget.js +479 -0
  396. package/dist/mind/prompt-refresh.js +3 -2
  397. package/dist/mind/prompt.js +1417 -140
  398. package/dist/mind/provenance-trust.js +26 -0
  399. package/dist/mind/record-paths.js +312 -0
  400. package/dist/mind/scrutiny.js +173 -0
  401. package/dist/mind/session-transaction.js +564 -0
  402. package/dist/mind/token-estimate.js +8 -12
  403. package/dist/nerves/cli-logging.js +22 -3
  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 +56 -36
  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 +305 -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 +17 -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 +1191 -0
  423. package/dist/repertoire/bundle-templates.js +71 -0
  424. package/dist/repertoire/bw-installer.js +180 -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 +322 -0
  428. package/dist/repertoire/coding/index.js +18 -3
  429. package/dist/repertoire/coding/manager.js +228 -14
  430. package/dist/repertoire/coding/spawner.js +61 -14
  431. package/dist/repertoire/coding/tools.js +279 -12
  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 +182 -0
  437. package/dist/repertoire/data/ado-endpoints.json +188 -0
  438. package/dist/repertoire/desk/classifier.js +362 -0
  439. package/dist/repertoire/duffel-client.js +185 -0
  440. package/dist/repertoire/github-client.js +14 -55
  441. package/dist/repertoire/graph-client.js +11 -52
  442. package/dist/repertoire/guardrails.js +1232 -0
  443. package/dist/repertoire/house-sweep.js +469 -0
  444. package/dist/repertoire/mcp-client.js +307 -0
  445. package/dist/repertoire/mcp-manager.js +483 -0
  446. package/dist/repertoire/mcp-tools.js +132 -0
  447. package/dist/repertoire/mcp-write-guard.js +46 -0
  448. package/dist/repertoire/plugin-mcp.js +175 -0
  449. package/dist/repertoire/plugins.js +253 -0
  450. package/dist/repertoire/relationship-authorization.js +322 -0
  451. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  452. package/dist/repertoire/shell-sessions.js +134 -0
  453. package/dist/repertoire/skills.js +45 -24
  454. package/dist/repertoire/stripe-client.js +131 -0
  455. package/dist/repertoire/tool-arguments.js +182 -0
  456. package/dist/repertoire/tool-results.js +29 -0
  457. package/dist/repertoire/tools-a2a.js +699 -0
  458. package/dist/repertoire/tools-attachments.js +322 -0
  459. package/dist/repertoire/tools-awaiting.js +870 -0
  460. package/dist/repertoire/tools-base.js +84 -706
  461. package/dist/repertoire/tools-bluebubbles.js +95 -0
  462. package/dist/repertoire/tools-bridge.js +144 -0
  463. package/dist/repertoire/tools-bundle.js +993 -0
  464. package/dist/repertoire/tools-commerce.js +253 -0
  465. package/dist/repertoire/tools-config.js +186 -0
  466. package/dist/repertoire/tools-continuity.js +575 -0
  467. package/dist/repertoire/tools-credential.js +383 -0
  468. package/dist/repertoire/tools-escalation.js +84 -0
  469. package/dist/repertoire/tools-evolution.js +527 -0
  470. package/dist/repertoire/tools-files.js +344 -0
  471. package/dist/repertoire/tools-flight.js +290 -0
  472. package/dist/repertoire/tools-flow.js +119 -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 +180 -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 +67 -61
  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 +534 -123
  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 +926 -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 +799 -0
  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/inbound-log.js +127 -0
  536. package/dist/senses/bluebubbles/index.js +3841 -0
  537. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  538. package/dist/senses/bluebubbles/media.js +389 -0
  539. package/dist/senses/bluebubbles/model.js +392 -0
  540. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +57 -6
  541. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  542. package/dist/senses/bluebubbles/processed-log.js +133 -0
  543. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  544. package/dist/senses/bluebubbles/replay.js +284 -0
  545. package/dist/senses/bluebubbles/runtime-state.js +137 -0
  546. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  547. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  548. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  549. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  550. package/dist/senses/cli/bracketed-paste.js +82 -0
  551. package/dist/senses/cli/image-paste.js +287 -0
  552. package/dist/senses/cli/image-ref-navigation.js +75 -0
  553. package/dist/senses/cli/ink-app.js +156 -0
  554. package/dist/senses/cli/inline-diff.js +64 -0
  555. package/dist/senses/cli/input-keys.js +174 -0
  556. package/dist/senses/cli/kill-ring.js +86 -0
  557. package/dist/senses/cli/message-list.js +51 -0
  558. package/dist/senses/cli/ouro-tui.js +607 -0
  559. package/dist/senses/cli/spinner-imperative.js +135 -0
  560. package/dist/senses/cli/spinner.js +101 -0
  561. package/dist/senses/cli/status-line.js +60 -0
  562. package/dist/senses/cli/streaming-markdown.js +526 -0
  563. package/dist/senses/cli/tool-display.js +85 -0
  564. package/dist/senses/cli/tool-render.js +85 -0
  565. package/dist/senses/cli/tui-store.js +241 -0
  566. package/dist/senses/cli/virtual-list.js +35 -0
  567. package/dist/senses/cli-entry.js +60 -8
  568. package/dist/senses/cli-layout.js +187 -0
  569. package/dist/senses/cli.js +814 -281
  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/continuity.js +94 -0
  574. package/dist/senses/habit-lifecycle-guard.js +24 -0
  575. package/dist/senses/habit-turn-message.js +160 -0
  576. package/dist/senses/ingress-evidence.js +2 -0
  577. package/dist/senses/mail-entry.js +66 -0
  578. package/dist/senses/mail.js +524 -0
  579. package/dist/senses/pipeline.js +1236 -0
  580. package/dist/senses/private-runtime-worker.js +859 -0
  581. package/dist/senses/private-runtime.js +1627 -0
  582. package/dist/senses/proactive-content-guard.js +51 -0
  583. package/dist/senses/root-host-approval-port.js +345 -0
  584. package/dist/senses/root-host-approval-runtime.js +393 -0
  585. package/dist/senses/sanctuary-authority-resident.js +102 -0
  586. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  587. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  588. package/dist/senses/sanctuary-grounding.js +118 -0
  589. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  590. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  591. package/dist/senses/sanctuary-health-runner.js +104 -0
  592. package/dist/senses/sanctuary-health.js +422 -0
  593. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  594. package/dist/senses/sanctuary-interactive-control.js +410 -0
  595. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  596. package/dist/senses/sanctuary-media-optimization.js +514 -0
  597. package/dist/senses/sanctuary-runtime.js +369 -0
  598. package/dist/senses/sanctuary-sab.js +85 -0
  599. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  600. package/dist/senses/shared-turn.js +793 -0
  601. package/dist/senses/shepherd/client.js +196 -0
  602. package/dist/senses/shepherd/cmux.js +332 -0
  603. package/dist/senses/shepherd/herdr.js +311 -0
  604. package/dist/senses/shepherd/host.js +14 -0
  605. package/dist/senses/shepherd/judge.js +98 -0
  606. package/dist/senses/shepherd/redact.js +37 -0
  607. package/dist/senses/shepherd/returns.js +79 -0
  608. package/dist/senses/shepherd/sense.js +288 -0
  609. package/dist/senses/shepherd-entry.js +78 -0
  610. package/dist/senses/surface-tool.js +109 -0
  611. package/dist/senses/teams-entry.js +60 -8
  612. package/dist/senses/teams.js +956 -211
  613. package/dist/senses/telegram-admission.js +718 -0
  614. package/dist/senses/telegram-approval-runtime.js +793 -0
  615. package/dist/senses/telegram-attachments.js +186 -0
  616. package/dist/senses/telegram-audit-ledger.js +220 -0
  617. package/dist/senses/telegram-authority-transport.js +231 -0
  618. package/dist/senses/telegram-client.js +1749 -0
  619. package/dist/senses/telegram-effect-adapter.js +900 -0
  620. package/dist/senses/telegram-entry.js +83 -0
  621. package/dist/senses/telegram.js +2351 -0
  622. package/dist/senses/trust-gate.js +207 -2
  623. package/dist/senses/voice/audio-playback.js +237 -0
  624. package/dist/senses/voice/audio-routing.js +119 -0
  625. package/dist/senses/voice/call-auth.js +250 -0
  626. package/dist/senses/voice/elevenlabs.js +202 -0
  627. package/dist/senses/voice/floor-control.js +431 -0
  628. package/dist/senses/voice/floor-controller.js +115 -0
  629. package/dist/senses/voice/golden-path.js +116 -0
  630. package/dist/senses/voice/index.js +29 -0
  631. package/dist/senses/voice/local-audio-control.js +344 -0
  632. package/dist/senses/voice/local-audio-devices.js +516 -0
  633. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  634. package/dist/senses/voice/local-audio-identity.js +103 -0
  635. package/dist/senses/voice/local-audio-join.js +325 -0
  636. package/dist/senses/voice/local-audio-mute.js +199 -0
  637. package/dist/senses/voice/local-audio-notify.js +121 -0
  638. package/dist/senses/voice/local-audio-prompts.js +116 -0
  639. package/dist/senses/voice/local-audio-transport.js +427 -0
  640. package/dist/senses/voice/local-audio.js +281 -0
  641. package/dist/senses/voice/local-media-stream.js +145 -0
  642. package/dist/senses/voice/meeting.js +113 -0
  643. package/dist/senses/voice/outbound.js +190 -0
  644. package/dist/senses/voice/phone.js +33 -0
  645. package/dist/senses/voice/playback.js +139 -0
  646. package/dist/senses/voice/process-guards.js +51 -0
  647. package/dist/senses/voice/realtime-eval.js +496 -0
  648. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  649. package/dist/senses/voice/realtime-trace.js +531 -0
  650. package/dist/senses/voice/transcript.js +70 -0
  651. package/dist/senses/voice/turn.js +191 -0
  652. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  653. package/dist/senses/voice/twilio-phone.js +5454 -0
  654. package/dist/senses/voice/types.js +2 -0
  655. package/dist/senses/voice/whisper.js +161 -0
  656. package/dist/senses/voice-entry.js +83 -0
  657. package/dist/senses/voice-realtime-eval-command.js +99 -0
  658. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  659. package/dist/senses/voice-twilio-entry.js +87 -0
  660. package/dist/trips/core.js +138 -0
  661. package/dist/trips/store.js +265 -0
  662. package/dist/util/frontmatter.js +69 -0
  663. package/npm-shrinkwrap.json +8100 -0
  664. package/package.json +83 -12
  665. package/skills/agent-commerce.md +113 -0
  666. package/skills/browser-navigation.md +117 -0
  667. package/skills/commerce-setup-guide.md +116 -0
  668. package/skills/commerce-setup.md +84 -0
  669. package/skills/configure-dev-tools.md +99 -0
  670. package/skills/travel-planning.md +138 -0
  671. package/AdoptionSpecialist.ouro/agent.json +0 -20
  672. package/AdoptionSpecialist.ouro/psyche/SOUL.md +0 -22
  673. package/dist/heart/daemon/specialist-orchestrator.js +0 -160
  674. package/dist/heart/daemon/specialist-prompt.js +0 -47
  675. package/dist/heart/daemon/specialist-session.js +0 -142
  676. package/dist/heart/daemon/specialist-tools.js +0 -132
  677. package/dist/heart/daemon/subagent-installer.js +0 -125
  678. package/dist/inner-worker-entry.js +0 -4
  679. package/dist/mind/friends/channel.js +0 -49
  680. package/dist/mind/friends/resolver.js +0 -84
  681. package/dist/mind/friends/store-file.js +0 -171
  682. package/dist/mind/friends/store.js +0 -4
  683. package/dist/mind/friends/tokens.js +0 -26
  684. package/dist/mind/friends/types.js +0 -21
  685. package/dist/repertoire/tasks/board.js +0 -122
  686. package/dist/repertoire/tasks/index.js +0 -210
  687. package/dist/repertoire/tasks/middleware.js +0 -65
  688. package/dist/repertoire/tasks/parser.js +0 -173
  689. package/dist/repertoire/tasks/scanner.js +0 -132
  690. package/dist/repertoire/tasks/transitions.js +0 -145
  691. package/dist/senses/bluebubbles-client.js +0 -279
  692. package/dist/senses/bluebubbles-entry.js +0 -11
  693. package/dist/senses/bluebubbles-model.js +0 -253
  694. package/dist/senses/bluebubbles.js +0 -332
  695. package/dist/senses/inner-dialog-worker.js +0 -61
  696. package/dist/senses/inner-dialog.js +0 -231
  697. package/subagents/README.md +0 -73
  698. package/subagents/work-doer.md +0 -233
  699. package/subagents/work-merger.md +0 -624
  700. package/subagents/work-planner.md +0 -373
  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/nagini.md +0 -0
  707. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  708. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  709. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  710. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  711. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  712. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
@@ -0,0 +1,483 @@
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.McpManager = void 0;
37
+ exports.getSharedMcpManager = getSharedMcpManager;
38
+ exports.releaseRuntimeMcpServers = releaseRuntimeMcpServers;
39
+ exports.shutdownSharedMcpManager = shutdownSharedMcpManager;
40
+ exports.resetSharedMcpManager = resetSharedMcpManager;
41
+ const path = __importStar(require("node:path"));
42
+ const mcp_client_1 = require("./mcp-client");
43
+ const identity_1 = require("../heart/identity");
44
+ const runtime_1 = require("../nerves/runtime");
45
+ const credential_access_1 = require("./credential-access");
46
+ const plugin_mcp_1 = require("./plugin-mcp");
47
+ const tool_arguments_1 = require("./tool-arguments");
48
+ const mcp_tools_1 = require("./mcp-tools");
49
+ const MAX_RESTART_RETRIES = 5;
50
+ const RESTART_DELAY_MS = 1000;
51
+ function isOwner(value) {
52
+ return typeof value === "object" && value !== null
53
+ && "agentName" in value && typeof value.agentName === "string" && value.agentName.length > 0
54
+ && "agentRoot" in value && typeof value.agentRoot === "string" && path.isAbsolute(value.agentRoot);
55
+ }
56
+ function captureOwner(owner) {
57
+ if (!isOwner(owner)) {
58
+ (0, runtime_1.emitNervesEvent)({
59
+ level: "warn", event: "mcp.owner_invalid", component: "repertoire",
60
+ message: "MCP requires an explicit owner", meta: { reason: "agent name and absolute root are required" },
61
+ });
62
+ throw new mcp_tools_1.McpCallRejectedError("MCP requires an explicit owner");
63
+ }
64
+ return Object.freeze({ agentName: owner.agentName, agentRoot: owner.agentRoot });
65
+ }
66
+ function sameOwner(left, right) {
67
+ return left.agentName === right.agentName && left.agentRoot === right.agentRoot;
68
+ }
69
+ function serverKey(owner, name) {
70
+ return JSON.stringify([owner.agentName, owner.agentRoot, name]);
71
+ }
72
+ function buildMergedServerConfig(owner, runtimeServers) {
73
+ const config = (0, identity_1.loadAgentConfig)(owner);
74
+ const desired = new Map();
75
+ for (const plugin of (0, plugin_mcp_1.listPluginMcpServers)(undefined, owner)) {
76
+ if (desired.has(plugin.serverName))
77
+ throw new mcp_tools_1.McpCallRejectedError(`MCP server name collision: ${plugin.serverName}`);
78
+ desired.set(plugin.serverName, {
79
+ config: (0, plugin_mcp_1.pluginMcpServerToConfig)(plugin), source: "plugin", pluginId: plugin.pluginId,
80
+ });
81
+ }
82
+ for (const [name, server] of Object.entries(config.mcpServers ?? {})) {
83
+ desired.set(name, { config: server, source: "builtin" });
84
+ }
85
+ for (const [name, server] of Object.entries(runtimeServers ?? {})) {
86
+ desired.set(name, { config: server, source: "runtime" });
87
+ }
88
+ return desired;
89
+ }
90
+ function configurationDigest(owner, desired) {
91
+ return (0, tool_arguments_1.digestJson)({
92
+ agentName: owner.agentName, agentRoot: owner.agentRoot,
93
+ source: desired.source, pluginId: desired.pluginId ?? null,
94
+ command: desired.config.command, args: desired.config.args ?? [],
95
+ env: desired.config.env ?? {}, cwd: desired.config.cwd ?? "",
96
+ });
97
+ }
98
+ class McpManager {
99
+ servers = new Map();
100
+ desiredGenerations = new Map();
101
+ nextGeneration = 0;
102
+ lifecycle = Promise.resolve();
103
+ shutdownPromise;
104
+ constructor() {
105
+ (0, runtime_1.emitNervesEvent)({
106
+ event: "mcp.manager_start", component: "repertoire",
107
+ message: "starting MCP manager", meta: { serverCount: 0 },
108
+ });
109
+ }
110
+ // One lifecycle tail; external tool and canary results do not hold it.
111
+ enqueue(operation) {
112
+ const result = this.lifecycle.then(operation);
113
+ this.lifecycle = result.then(() => undefined, () => undefined);
114
+ return result;
115
+ }
116
+ enqueueBackground(operation) {
117
+ void this.enqueue(operation).catch((error) => {
118
+ (0, runtime_1.emitNervesEvent)({
119
+ level: "error", event: "mcp.lifecycle_error", component: "repertoire",
120
+ message: "MCP background lifecycle operation failed",
121
+ meta: { reason: error instanceof Error ? error.message : String(error) },
122
+ });
123
+ });
124
+ }
125
+ async start(ownerInput, servers, pluginOrigins = {}) {
126
+ const owner = captureOwner(ownerInput);
127
+ const desired = new Map(Object.entries(structuredClone(servers)).map(([name, config]) => [
128
+ name, { config, source: pluginOrigins[name] ? "plugin" : "builtin", pluginId: pluginOrigins[name] },
129
+ ]));
130
+ return this.enqueue(async () => {
131
+ if (this.shutdownPromise)
132
+ return null;
133
+ await this.applyDesired(owner, desired);
134
+ return this.shutdownPromise ? null : this.freezeView(owner);
135
+ });
136
+ }
137
+ async reconcile(ownerInput, runtimeServers) {
138
+ const owner = captureOwner(ownerInput);
139
+ const runtime = runtimeServers ? structuredClone(runtimeServers) : undefined;
140
+ return this.enqueue(async () => {
141
+ if (this.shutdownPromise)
142
+ return null;
143
+ try {
144
+ const desired = buildMergedServerConfig(owner, runtime);
145
+ await this.applyDesired(owner, desired);
146
+ return this.shutdownPromise || desired.size === 0 ? null : this.freezeView(owner);
147
+ }
148
+ catch (error) {
149
+ (0, runtime_1.emitNervesEvent)({
150
+ level: "warn", event: "mcp.reconcile_error", component: "repertoire",
151
+ message: "failed to reconcile MCP servers",
152
+ meta: { reason: error instanceof Error ? error.message : String(error) },
153
+ });
154
+ for (const entry of this.ownedEntries(owner))
155
+ this.removeEntry(entry);
156
+ return null;
157
+ }
158
+ });
159
+ }
160
+ listAllTools(owner) {
161
+ captureOwner(owner);
162
+ return this.ownedEntries(owner).filter((entry) => this.isCurrentEntry(entry)).map((entry) => ({
163
+ server: entry.name, tools: structuredClone(entry.cachedTools), pluginId: entry.pluginId,
164
+ }));
165
+ }
166
+ async callTool(binding, args, ownerInput) {
167
+ const owner = captureOwner(ownerInput);
168
+ const call = await this.enqueue(async () => {
169
+ let entry = this.currentBinding(binding, owner);
170
+ if (!entry.client.isConnected()) {
171
+ await this.recoverStaleTransport(entry, "pre-call disconnected");
172
+ entry = this.currentBinding(binding, owner);
173
+ if (!entry.client.isConnected())
174
+ throw new mcp_tools_1.McpCallRejectedError(`Server "${entry.name}" is disconnected`);
175
+ }
176
+ return { entry, result: entry.client.callTool(binding.rawName, args) };
177
+ });
178
+ try {
179
+ return await call.result;
180
+ }
181
+ catch (error) {
182
+ if (!(0, mcp_client_1.isMcpTransportError)(error))
183
+ throw error;
184
+ const reason = error instanceof Error ? error.message : String(error);
185
+ // Recovery prepares later calls; the server may already have performed this one.
186
+ this.enqueueBackground(async () => {
187
+ if (this.isCurrentEntry(call.entry))
188
+ await this.recoverStaleTransport(call.entry, reason);
189
+ });
190
+ throw error;
191
+ }
192
+ }
193
+ async validateToolBinding(binding, ownerInput) {
194
+ const owner = captureOwner(ownerInput);
195
+ await this.enqueue(() => { this.currentBinding(binding, owner); });
196
+ }
197
+ async runCanaries(ownerInput) {
198
+ const owner = captureOwner(ownerInput);
199
+ const entries = await this.enqueue(() => this.ownedEntries(owner));
200
+ const results = [];
201
+ for (const entry of entries) {
202
+ let current = entry;
203
+ try {
204
+ const refresh = await this.enqueue(async () => {
205
+ if (!this.isCurrentEntry(entry))
206
+ return null;
207
+ if (!entry.client.isConnected())
208
+ await this.recoverStaleTransport(entry, "canary disconnected");
209
+ const recovered = this.servers.get(serverKey(owner, entry.name));
210
+ if (!recovered || !this.isCurrentEntry(recovered) || !recovered.client.isConnected())
211
+ return null;
212
+ current = recovered;
213
+ return { result: recovered.client.refreshTools() };
214
+ });
215
+ if (!refresh) {
216
+ results.push({ server: entry.name, ok: false, detail: "disconnected after recovery attempt" });
217
+ continue;
218
+ }
219
+ const tools = await refresh.result;
220
+ const updated = await this.enqueue(() => {
221
+ if (!this.isCurrentEntry(current))
222
+ return false;
223
+ current.cachedTools = structuredClone(tools);
224
+ current.consecutiveFailures = 0;
225
+ return true;
226
+ });
227
+ results.push({
228
+ server: entry.name, ok: updated,
229
+ detail: updated ? `${tools.length} tools listed` : "server changed during canary",
230
+ });
231
+ }
232
+ catch (error) {
233
+ const reason = error instanceof Error ? error.message : String(error);
234
+ if ((0, mcp_client_1.isMcpTransportError)(error)) {
235
+ await this.enqueue(async () => {
236
+ if (this.isCurrentEntry(current))
237
+ await this.recoverStaleTransport(current, reason);
238
+ });
239
+ }
240
+ results.push({ server: entry.name, ok: false, detail: reason });
241
+ }
242
+ }
243
+ return results;
244
+ }
245
+ shutdown() {
246
+ if (this.shutdownPromise)
247
+ return this.shutdownPromise;
248
+ // Publish closing before queued cleanup so pending network work cannot revive clients.
249
+ this.shutdownPromise = this.enqueue(() => {
250
+ (0, runtime_1.emitNervesEvent)({
251
+ event: "mcp.manager_end", component: "repertoire",
252
+ message: "shutting down MCP manager", meta: { serverCount: this.servers.size },
253
+ });
254
+ for (const entry of [...this.servers.values()])
255
+ this.removeEntry(entry);
256
+ this.desiredGenerations.clear();
257
+ });
258
+ return this.shutdownPromise;
259
+ }
260
+ ownedEntries(owner) {
261
+ return [...this.servers.values()].filter((entry) => sameOwner(entry.owner, owner));
262
+ }
263
+ isCurrentEntry(entry) {
264
+ const key = serverKey(entry.owner, entry.name);
265
+ return !this.shutdownPromise && this.servers.get(key) === entry
266
+ && this.desiredGenerations.get(key) === entry.generation;
267
+ }
268
+ freezeView(owner) {
269
+ const entries = this.ownedEntries(owner).filter((entry) => this.isCurrentEntry(entry)).map((entry) => Object.freeze({
270
+ server: entry.name, source: entry.source, pluginId: entry.pluginId,
271
+ configDigest: entry.configDigest, generation: entry.generation,
272
+ tools: (0, tool_arguments_1.freezeToolValue)(structuredClone(entry.cachedTools)),
273
+ }));
274
+ return Object.freeze({ manager: this, owner, entries: Object.freeze(entries) });
275
+ }
276
+ matchesBinding(entry, binding, owner) {
277
+ if (binding.manager !== this || !sameOwner(binding, owner) || !sameOwner(entry.owner, owner)
278
+ || !this.isCurrentEntry(entry) || entry.name !== binding.server
279
+ || entry.source !== binding.source || entry.pluginId !== binding.pluginId
280
+ || entry.configDigest !== binding.configDigest || entry.generation !== binding.generation)
281
+ return false;
282
+ const tools = entry.cachedTools.filter((tool) => tool.name === binding.rawName);
283
+ if (tools.length !== 1)
284
+ return false;
285
+ const schema = (0, mcp_tools_1.mcpToolSchema)({ server: entry.name, pluginId: entry.pluginId }, tools[0]);
286
+ return schema.function.name === binding.surfacedName && (0, tool_arguments_1.digestJson)(schema) === binding.schemaDigest;
287
+ }
288
+ currentBinding(binding, owner) {
289
+ const entry = this.servers.get(serverKey(owner, binding.server));
290
+ if (!entry || !this.matchesBinding(entry, binding, owner)) {
291
+ (0, runtime_1.emitNervesEvent)({
292
+ level: "warn", event: "mcp.tool_rejected", component: "repertoire",
293
+ message: "MCP tool binding is no longer current", meta: { reason: "stale or unavailable owned tool" },
294
+ });
295
+ throw new mcp_tools_1.McpCallRejectedError("MCP tool binding is stale or unavailable");
296
+ }
297
+ return entry;
298
+ }
299
+ removeEntry(entry) {
300
+ const key = serverKey(entry.owner, entry.name);
301
+ this.desiredGenerations.delete(key);
302
+ if (entry.restartTimer)
303
+ clearTimeout(entry.restartTimer);
304
+ entry.client.shutdown();
305
+ this.servers.delete(key);
306
+ }
307
+ async applyDesired(owner, desired) {
308
+ for (const [name, requested] of desired) {
309
+ if (this.shutdownPromise)
310
+ return;
311
+ const descriptor = { ...requested, config: structuredClone(requested.config) };
312
+ const configDigest = configurationDigest(owner, descriptor);
313
+ const current = this.servers.get(serverKey(owner, name));
314
+ if (current && this.isCurrentEntry(current) && current.configDigest === configDigest)
315
+ continue;
316
+ if (current) {
317
+ (0, runtime_1.emitNervesEvent)({
318
+ event: "mcp.server_changed", component: "repertoire",
319
+ message: `reconnecting changed MCP server: ${name}`, meta: { server: name },
320
+ });
321
+ this.removeEntry(current);
322
+ }
323
+ else {
324
+ (0, runtime_1.emitNervesEvent)({
325
+ event: "mcp.server_added", component: "repertoire",
326
+ message: `connecting new MCP server: ${name}`, meta: { server: name },
327
+ });
328
+ }
329
+ await this.connectServer({
330
+ ...descriptor, owner, name, configDigest, generation: ++this.nextGeneration, consecutiveFailures: 0,
331
+ });
332
+ }
333
+ for (const entry of this.ownedEntries(owner)) {
334
+ if (desired.has(entry.name))
335
+ continue;
336
+ (0, runtime_1.emitNervesEvent)({
337
+ event: "mcp.server_removed", component: "repertoire",
338
+ message: `disconnecting removed MCP server: ${entry.name}`, meta: { server: entry.name },
339
+ });
340
+ this.removeEntry(entry);
341
+ }
342
+ }
343
+ async resolveVaultEnv(env, owner) {
344
+ const resolved = { ...env };
345
+ if (!Object.values(resolved).some((value) => /^vault:/.test(value)))
346
+ return resolved;
347
+ const store = (0, credential_access_1.getCredentialStore)(owner.agentName);
348
+ for (const [key, value] of Object.entries(resolved)) {
349
+ const match = value.match(/^vault:([^/]+)\/(.+)$/);
350
+ if (!match)
351
+ continue;
352
+ const [, domain, field] = match;
353
+ try {
354
+ resolved[key] = await store.getRawSecret(domain, field);
355
+ }
356
+ catch (error) {
357
+ const reason = error instanceof Error ? error.message : String(error);
358
+ const classification = reason.includes("no credential found") ? "item not found"
359
+ : reason.includes("field") && reason.includes("not found") ? "field empty" : "vault unreachable";
360
+ throw new Error(`vault:${domain}/${field} could not be resolved: ${classification}`);
361
+ }
362
+ }
363
+ return resolved;
364
+ }
365
+ async connectServer(desired) {
366
+ const key = serverKey(desired.owner, desired.name);
367
+ this.desiredGenerations.set(key, desired.generation);
368
+ let config = desired.config;
369
+ if (config.env) {
370
+ try {
371
+ config = { ...config, env: await this.resolveVaultEnv(config.env, desired.owner) };
372
+ }
373
+ catch (error) {
374
+ const reason = error instanceof Error ? error.message : String(error);
375
+ (0, runtime_1.emitNervesEvent)({
376
+ level: "error", event: "mcp.vault_resolve_error", component: "repertoire",
377
+ message: `skipping MCP server "${desired.name}": ${reason}`, meta: { server: desired.name, reason },
378
+ });
379
+ this.desiredGenerations.delete(key);
380
+ return;
381
+ }
382
+ }
383
+ if (this.shutdownPromise || this.desiredGenerations.get(key) !== desired.generation)
384
+ return;
385
+ const client = new mcp_client_1.McpClient(config);
386
+ const entry = { ...desired, client, cachedTools: [] };
387
+ this.servers.set(key, entry);
388
+ client.onClose(() => { this.enqueueBackground(() => this.handleServerCrash(entry)); });
389
+ try {
390
+ await client.connect();
391
+ if (!this.isCurrentEntry(entry)) {
392
+ client.shutdown();
393
+ return;
394
+ }
395
+ const tools = await client.listTools();
396
+ if (!this.isCurrentEntry(entry)) {
397
+ client.shutdown();
398
+ return;
399
+ }
400
+ entry.cachedTools = structuredClone(tools);
401
+ }
402
+ catch (error) {
403
+ const reason = error instanceof Error ? error.message : String(error);
404
+ (0, runtime_1.emitNervesEvent)({
405
+ level: "error", event: "mcp.connect_error", component: "repertoire",
406
+ message: `failed to connect MCP server "${desired.name}"`,
407
+ meta: { server: desired.name, reason },
408
+ });
409
+ }
410
+ }
411
+ handleServerCrash(entry) {
412
+ if (!this.isCurrentEntry(entry) || entry.restartTimer)
413
+ return;
414
+ entry.consecutiveFailures++;
415
+ if (entry.consecutiveFailures > MAX_RESTART_RETRIES) {
416
+ (0, runtime_1.emitNervesEvent)({
417
+ level: "error", event: "mcp.connect_error", component: "repertoire",
418
+ message: `MCP server "${entry.name}" exceeded max restart retries`,
419
+ meta: { server: entry.name, failures: entry.consecutiveFailures },
420
+ });
421
+ return;
422
+ }
423
+ (0, runtime_1.emitNervesEvent)({
424
+ level: "warn", event: "mcp.server_restart", component: "repertoire",
425
+ message: `restarting crashed MCP server: ${entry.name}`,
426
+ meta: { server: entry.name, attempt: entry.consecutiveFailures },
427
+ });
428
+ entry.restartTimer = setTimeout(() => {
429
+ this.enqueueBackground(async () => {
430
+ if (!this.isCurrentEntry(entry))
431
+ return;
432
+ delete entry.restartTimer;
433
+ await this.restartServer(entry);
434
+ });
435
+ }, RESTART_DELAY_MS);
436
+ }
437
+ async restartServer(entry) {
438
+ this.removeEntry(entry);
439
+ await this.connectServer({
440
+ owner: entry.owner, name: entry.name, config: entry.config,
441
+ source: entry.source, pluginId: entry.pluginId,
442
+ configDigest: entry.configDigest, generation: entry.generation,
443
+ consecutiveFailures: entry.consecutiveFailures,
444
+ });
445
+ }
446
+ async recoverStaleTransport(entry, reason) {
447
+ (0, runtime_1.emitNervesEvent)({
448
+ level: "warn", event: "mcp.transport_recovery", component: "repertoire",
449
+ message: `recovering stale MCP transport: ${entry.name}`, meta: { server: entry.name, reason },
450
+ });
451
+ await this.restartServer(entry);
452
+ }
453
+ }
454
+ exports.McpManager = McpManager;
455
+ let _sharedManager = null;
456
+ /** Every caller applies its own desired state and freezes its own view in the shared manager's lifecycle tail. */
457
+ async function getSharedMcpManager(options) {
458
+ if (!isOwner(options)) {
459
+ (0, runtime_1.emitNervesEvent)({
460
+ level: "warn", event: "mcp.owner_invalid", component: "repertoire",
461
+ message: "MCP requires an explicit owner", meta: { reason: "agent name and absolute root are required" },
462
+ });
463
+ return null;
464
+ }
465
+ const manager = _sharedManager ??= new McpManager();
466
+ return manager.reconcile(options, options.runtimeServers);
467
+ }
468
+ async function releaseRuntimeMcpServers(owner) {
469
+ if (_sharedManager)
470
+ await _sharedManager.reconcile(owner);
471
+ }
472
+ async function shutdownSharedMcpManager() {
473
+ const manager = _sharedManager;
474
+ if (!manager)
475
+ return;
476
+ await manager.shutdown();
477
+ if (_sharedManager === manager)
478
+ _sharedManager = null;
479
+ }
480
+ /** Reset for testing only. */
481
+ async function resetSharedMcpManager() {
482
+ await shutdownSharedMcpManager();
483
+ }
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * First-class MCP tool integration — converts MCP server tools into ToolDefinitions
4
+ * so the model can call them directly without shell indirection.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.McpToolExecutionError = exports.McpCallRejectedError = void 0;
8
+ exports.mcpToolSchema = mcpToolSchema;
9
+ exports.mcpToolsAsDefinitions = mcpToolsAsDefinitions;
10
+ const runtime_1 = require("../nerves/runtime");
11
+ const tool_arguments_1 = require("./tool-arguments");
12
+ const mcp_write_guard_1 = require("./mcp-write-guard");
13
+ class McpCallRejectedError extends Error {
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = "McpCallRejectedError";
17
+ }
18
+ }
19
+ exports.McpCallRejectedError = McpCallRejectedError;
20
+ class McpToolExecutionError extends Error {
21
+ kind;
22
+ constructor(kind, message) {
23
+ super(message);
24
+ this.kind = kind;
25
+ this.name = "McpToolExecutionError";
26
+ }
27
+ }
28
+ exports.McpToolExecutionError = McpToolExecutionError;
29
+ function mcpToolSchema(entry, tool) {
30
+ return {
31
+ type: "function",
32
+ function: {
33
+ name: entry.pluginId
34
+ ? `mcp__${entry.server}__${tool.name}`
35
+ : tool.name.startsWith(`${entry.server}_`) || tool.name === entry.server
36
+ ? tool.name
37
+ : `${entry.server}_${tool.name}`,
38
+ description: tool.description || `MCP tool: ${tool.name} (server: ${entry.server})`,
39
+ parameters: tool.inputSchema ?? { type: "object", properties: {} },
40
+ },
41
+ };
42
+ }
43
+ /**
44
+ * Convert an owned frozen MCP view into ToolDefinition objects.
45
+ *
46
+ * Naming rules:
47
+ * - Builtin servers (agent.json `mcpServers`) — legacy `{server}_{tool}`
48
+ * shape (e.g., `browser_navigate`), with double-prefix avoidance when
49
+ * the tool already starts with the server name.
50
+ * - Plugin servers (from `<plugin>/.mcp.json`, W6 Unit 9) — Anthropic public
51
+ * convention `mcp__{server}__{tool}` (e.g., `mcp__desk__task_create`).
52
+ * This matches Claude Code's external naming and the on-prompt promise
53
+ * in `desk-section.ts` (`mcp__desk__*`).
54
+ *
55
+ * The handler carries the exact frozen binding to the manager's client fence.
56
+ */
57
+ function mcpToolsAsDefinitions(view) {
58
+ if (!view)
59
+ return [];
60
+ return view.entries.flatMap((entry) => entry.tools.map((tool) => {
61
+ const schema = mcpToolSchema(entry, tool);
62
+ const binding = Object.freeze({
63
+ manager: view.manager, ...view.owner, server: entry.server,
64
+ rawName: tool.name, surfacedName: schema.function.name,
65
+ source: entry.source, pluginId: entry.pluginId,
66
+ configDigest: entry.configDigest, generation: entry.generation,
67
+ schemaDigest: (0, tool_arguments_1.digestJson)(schema),
68
+ });
69
+ return {
70
+ tool: schema,
71
+ // A read-only hint is trusted only from the agent's own bundle (agent.json mcpServers),
72
+ // so an orientation hold still lets the agent inspect through those tools.
73
+ riskProfile: entry.source === "builtin" && tool.annotations?.readOnlyHint === true
74
+ ? { mutates: "none", risk: "low", reason: "read-only tool from the agent's own MCP server" }
75
+ : {
76
+ mutates: "external_side_effect",
77
+ risk: "high",
78
+ reason: "MCP tools may mutate external systems",
79
+ },
80
+ handler: async (args, ctx) => {
81
+ if (ctx?.agentName !== binding.agentName || ctx.agentRoot !== binding.agentRoot) {
82
+ (0, runtime_1.emitNervesEvent)({
83
+ level: "warn", event: "mcp.tool_rejected", component: "repertoire",
84
+ message: "MCP tool owner does not match its caller", meta: { reason: "owner mismatch" },
85
+ });
86
+ throw new McpCallRejectedError("MCP tool owner does not match its caller");
87
+ }
88
+ (0, runtime_1.emitNervesEvent)({
89
+ event: "mcp.tool_start",
90
+ component: "repertoire",
91
+ message: `calling MCP tool ${entry.server}/${tool.name}`,
92
+ meta: { server: entry.server, tool: tool.name },
93
+ });
94
+ const guarded = (0, mcp_write_guard_1.guardMcpArgs)({ toolName: tool.name, declaresDryRun: Object.hasOwn((tool.inputSchema?.properties ?? {}), "dry_run"), args, ctx });
95
+ if (guarded.rejected !== undefined)
96
+ throw new McpCallRejectedError(guarded.rejected);
97
+ try {
98
+ const result = await view.manager.callTool(binding, guarded.args, { agentName: ctx.agentName, agentRoot: ctx.agentRoot });
99
+ const text = result.content
100
+ .filter((c) => c.type === "text" && c.text)
101
+ .map((c) => c.text)
102
+ .join("");
103
+ if (result.isError === true) {
104
+ throw new McpToolExecutionError("handler_failed", `[mcp error] ${entry.server}/${tool.name}: ${text}`);
105
+ }
106
+ (0, runtime_1.emitNervesEvent)({
107
+ event: "mcp.tool_end",
108
+ component: "repertoire",
109
+ message: `MCP tool ${entry.server}/${tool.name} completed`,
110
+ meta: { server: entry.server, tool: tool.name },
111
+ });
112
+ return text;
113
+ }
114
+ catch (error) {
115
+ const reason = error instanceof Error ? error.message : String(error);
116
+ (0, runtime_1.emitNervesEvent)({
117
+ level: "error",
118
+ event: "mcp.tool_error",
119
+ component: "repertoire",
120
+ message: `MCP tool ${entry.server}/${tool.name} failed: ${reason}`,
121
+ meta: { server: entry.server, tool: tool.name, reason },
122
+ });
123
+ if (error instanceof McpCallRejectedError || error instanceof McpToolExecutionError)
124
+ throw error;
125
+ throw new McpToolExecutionError("handler_indeterminate", `[mcp error] ${entry.server}/${tool.name}: ${reason}`);
126
+ }
127
+ },
128
+ mcpServer: entry.server,
129
+ mcpBinding: binding,
130
+ };
131
+ }));
132
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REPLAY_REFUSED_WRITE_TOOLS = exports.OWNER_ONLY_WRITE_TOOLS = void 0;
4
+ exports.guardMcpArgs = guardMcpArgs;
5
+ /**
6
+ * Runtime guards on MCP tool arguments that the MCP server itself cannot enforce, because only the runtime knows who is calling.
7
+ *
8
+ * - A replay identity (the host's replay gate, src/a2a/replay-harness.ts) never applies a change: every tool that declares a
9
+ * `dry_run` argument is forced to a dry run for it, so a gate case can never alter the live house.
10
+ * - A replay identity may not call a write tool that has no dry run at all (see REPLAY_REFUSED_WRITE_TOOLS).
11
+ * - Some tools change settings only the owner may change: applying (dry_run false) is refused for any other caller, and the
12
+ * caller is stamped into the arguments so the tool's audit line names who asked.
13
+ */
14
+ const replay_harness_1 = require("../a2a/replay-harness");
15
+ const runtime_1 = require("../nerves/runtime");
16
+ /** MCP tools whose applied writes are owner-only. */
17
+ exports.OWNER_ONLY_WRITE_TOOLS = new Set(["media_quality_profile"]);
18
+ /** MCP tools that change the house and have no dry run: a replay identity may not call them at all. media_manual_import is a write only in `import` mode. */
19
+ exports.REPLAY_REFUSED_WRITE_TOOLS = new Set(["media_request", "media_search_now", "media_blocklist", "media_blocklist_stalled", "media_fill_missing", "media_release_grab", "media_manual_import"]);
20
+ const isWrite = (args) => (args.dry_run === false || args.dry_run === "false") && args.action !== "read";
21
+ function callerFriend(ctx) {
22
+ const friend = ctx?.context?.friend;
23
+ return { id: friend?.id ?? ctx?.relationshipAuthorization?.actor?.friendId, name: friend?.name };
24
+ }
25
+ function guardMcpArgs(input) {
26
+ const { toolName, declaresDryRun, ctx } = input;
27
+ let args = input.args;
28
+ const caller = callerFriend(ctx);
29
+ if (exports.OWNER_ONLY_WRITE_TOOLS.has(toolName)) {
30
+ if (isWrite(args) && ctx?.relationshipAuthorization?.profileId !== "sanctuary-owner") {
31
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "repertoire", event: "mcp.write_refused_non_owner", message: "an owner-only MCP write was refused", meta: { tool: toolName } });
32
+ return { rejected: `${toolName} changes settings only the owner may change. Show the owner the dry run and ask them to confirm; do not apply it for anyone else.` };
33
+ }
34
+ args = { ...args, caller: caller.id ? `${caller.id}${caller.name ? ` (${caller.name})` : ""}` : "unknown" };
35
+ }
36
+ const replay = Boolean(caller.id && ctx?.agentRoot && (0, replay_harness_1.isReplayIdentity)(ctx.agentRoot, caller.id));
37
+ if (replay && !declaresDryRun && exports.REPLAY_REFUSED_WRITE_TOOLS.has(toolName) && (toolName !== "media_manual_import" || args.mode === "import")) {
38
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "repertoire", event: "mcp.replay_write_refused", message: "a replay identity's MCP write with no dry run was refused", meta: { tool: toolName } });
39
+ return { rejected: `${toolName} changes the live house and has no dry run, so a replay identity may not call it. Describe what you would do instead.` };
40
+ }
41
+ if (replay && declaresDryRun && args.dry_run !== true) {
42
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "repertoire", event: "mcp.replay_forced_dry_run", message: "a replay identity's MCP call was forced to a dry run", meta: { tool: toolName } });
43
+ args = { ...args, dry_run: true };
44
+ }
45
+ return { args };
46
+ }