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

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 (716) 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 +5819 -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 +344 -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 +245 -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 +309 -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 +68 -8
  612. package/dist/senses/teams.js +598 -233
  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-handoff.js +80 -0
  622. package/dist/senses/telegram.js +2405 -0
  623. package/dist/senses/trust-gate.js +104 -9
  624. package/dist/senses/voice/audio-playback.js +237 -0
  625. package/dist/senses/voice/audio-routing.js +119 -0
  626. package/dist/senses/voice/call-auth.js +250 -0
  627. package/dist/senses/voice/elevenlabs.js +202 -0
  628. package/dist/senses/voice/floor-control.js +431 -0
  629. package/dist/senses/voice/floor-controller.js +115 -0
  630. package/dist/senses/voice/golden-path.js +116 -0
  631. package/dist/senses/voice/index.js +29 -0
  632. package/dist/senses/voice/local-audio-control.js +344 -0
  633. package/dist/senses/voice/local-audio-devices.js +516 -0
  634. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  635. package/dist/senses/voice/local-audio-identity.js +103 -0
  636. package/dist/senses/voice/local-audio-join.js +325 -0
  637. package/dist/senses/voice/local-audio-mute.js +199 -0
  638. package/dist/senses/voice/local-audio-notify.js +121 -0
  639. package/dist/senses/voice/local-audio-prompts.js +116 -0
  640. package/dist/senses/voice/local-audio-transport.js +427 -0
  641. package/dist/senses/voice/local-audio.js +281 -0
  642. package/dist/senses/voice/local-media-stream.js +145 -0
  643. package/dist/senses/voice/meeting.js +113 -0
  644. package/dist/senses/voice/outbound.js +190 -0
  645. package/dist/senses/voice/phone.js +33 -0
  646. package/dist/senses/voice/playback.js +139 -0
  647. package/dist/senses/voice/process-guards.js +51 -0
  648. package/dist/senses/voice/realtime-eval.js +496 -0
  649. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  650. package/dist/senses/voice/realtime-trace.js +531 -0
  651. package/dist/senses/voice/transcript.js +70 -0
  652. package/dist/senses/voice/turn.js +191 -0
  653. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  654. package/dist/senses/voice/twilio-phone.js +5454 -0
  655. package/dist/senses/voice/types.js +2 -0
  656. package/dist/senses/voice/whisper.js +161 -0
  657. package/dist/senses/voice-entry.js +83 -0
  658. package/dist/senses/voice-realtime-eval-command.js +99 -0
  659. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  660. package/dist/senses/voice-twilio-entry.js +87 -0
  661. package/dist/trips/core.js +138 -0
  662. package/dist/trips/store.js +265 -0
  663. package/dist/util/frontmatter.js +69 -0
  664. package/npm-shrinkwrap.json +8100 -0
  665. package/package.json +74 -13
  666. package/skills/agent-commerce.md +113 -0
  667. package/skills/browser-navigation.md +117 -0
  668. package/skills/commerce-setup-guide.md +116 -0
  669. package/skills/commerce-setup.md +84 -0
  670. package/skills/configure-dev-tools.md +99 -0
  671. package/skills/travel-planning.md +138 -0
  672. package/dist/heart/daemon/auth-flow.js +0 -430
  673. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  674. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  675. package/dist/heart/daemon/update-hooks.js +0 -138
  676. package/dist/heart/obligations.js +0 -191
  677. package/dist/heart/safe-workspace.js +0 -362
  678. package/dist/heart/session-recall.js +0 -116
  679. package/dist/mind/friends/channel.js +0 -84
  680. package/dist/mind/friends/group-context.js +0 -144
  681. package/dist/mind/friends/resolver.js +0 -84
  682. package/dist/mind/friends/store-file.js +0 -190
  683. package/dist/mind/friends/store.js +0 -4
  684. package/dist/mind/friends/tokens.js +0 -26
  685. package/dist/mind/friends/trust-explanation.js +0 -74
  686. package/dist/mind/friends/types.js +0 -29
  687. package/dist/repertoire/tasks/board.js +0 -134
  688. package/dist/repertoire/tasks/index.js +0 -224
  689. package/dist/repertoire/tasks/lifecycle.js +0 -80
  690. package/dist/repertoire/tasks/middleware.js +0 -65
  691. package/dist/repertoire/tasks/parser.js +0 -173
  692. package/dist/repertoire/tasks/scanner.js +0 -132
  693. package/dist/repertoire/tasks/transitions.js +0 -144
  694. package/dist/senses/bluebubbles-entry.js +0 -13
  695. package/dist/senses/bluebubbles.js +0 -1181
  696. package/dist/senses/debug-activity.js +0 -154
  697. package/dist/senses/inner-dialog-worker.js +0 -90
  698. package/dist/senses/inner-dialog.js +0 -525
  699. package/subagents/README.md +0 -7
  700. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  701. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  702. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  703. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  704. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  705. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.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
  713. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  714. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  715. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  716. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,103 @@
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.capLocalTrust = capLocalTrust;
37
+ exports.resolveLocalAudioFriend = resolveLocalAudioFriend;
38
+ const path = __importStar(require("path"));
39
+ const friends_1 = require("@ouro.bot/friends");
40
+ const runtime_1 = require("../../nerves/runtime");
41
+ const SAFE_FRIEND_ID = /^[A-Za-z0-9._-]{1,128}$/;
42
+ const LOCAL_ROOM_FRIEND_ID = "local-audio-room";
43
+ const TRUST_RANK = { stranger: 0, acquaintance: 1, friend: 2, family: 3 };
44
+ /**
45
+ * A local session runs at acquaintance unless the join says the room is the owner alone. The cap
46
+ * only lowers: a record already below acquaintance stays where it is, and an unrecorded trust is
47
+ * treated as acquaintance.
48
+ */
49
+ function capLocalTrust(recorded, ownerAlone) {
50
+ const effective = recorded ?? "acquaintance";
51
+ if (ownerAlone)
52
+ return effective;
53
+ return TRUST_RANK[effective] > TRUST_RANK.acquaintance ? "acquaintance" : effective;
54
+ }
55
+ function roomRecord() {
56
+ const now = new Date().toISOString();
57
+ return {
58
+ id: LOCAL_ROOM_FRIEND_ID,
59
+ name: "Local audio room",
60
+ trustLevel: "acquaintance",
61
+ externalIds: [],
62
+ tenantMemberships: [],
63
+ toolPreferences: {},
64
+ notes: {},
65
+ totalTokens: 0,
66
+ createdAt: now,
67
+ updatedAt: now,
68
+ schemaVersion: 1,
69
+ };
70
+ }
71
+ /**
72
+ * Resolves who a local audio session is with. `friendId` comes from the join request (a local
73
+ * pidfile/socket command or the family text tool), is validated as a safe id, and must match a
74
+ * record id exactly (never a display name). Anything else maps to one stable room record. The
75
+ * returned friend carries the capped effective trust for the whole session.
76
+ */
77
+ async function resolveLocalAudioFriend(options) {
78
+ const friendStore = new friends_1.FileFriendStore(path.join(options.agentRoot, "friends"));
79
+ const requested = options.friendId?.trim();
80
+ let friend = null;
81
+ if (requested && SAFE_FRIEND_ID.test(requested) && requested !== "." && requested !== "..") {
82
+ const existing = await friendStore.get(requested);
83
+ if (existing && existing.id === requested)
84
+ friend = existing;
85
+ }
86
+ // No identified friend: the room is a stable, unprivileged record. It is built in memory rather
87
+ // than resolved through FriendResolver, which would persist it (and treat the first friend ever
88
+ // seen in an empty store as family).
89
+ const identified = friend !== null;
90
+ friend ??= (await friendStore.get(LOCAL_ROOM_FRIEND_ID)) ?? roomRecord();
91
+ const trustLevel = capLocalTrust(friend.trustLevel, identified && options.ownerAlone);
92
+ (0, runtime_1.emitNervesEvent)({
93
+ component: "senses",
94
+ event: "senses.voice_local_identity_resolved",
95
+ message: "local audio session identity resolved",
96
+ meta: { friendId: friend.id, recordedTrust: String(friend.trustLevel), effectiveTrust: trustLevel, ownerAlone: options.ownerAlone },
97
+ });
98
+ return {
99
+ friendId: friend.id,
100
+ friendStore,
101
+ resolved: { friend: { ...friend, trustLevel }, channel: (0, friends_1.getChannelCapabilities)("voice") },
102
+ };
103
+ }
@@ -0,0 +1,325 @@
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.parseNotifySession = void 0;
37
+ exports.localAudioJoinArgs = localAudioJoinArgs;
38
+ exports.runLocalAudioJoin = runLocalAudioJoin;
39
+ exports.runLocalAudioLeave = runLocalAudioLeave;
40
+ exports.runLocalAudioStatus = runLocalAudioStatus;
41
+ exports.defaultLaunchSpawn = defaultLaunchSpawn;
42
+ exports.launchLocalAudioJoin = launchLocalAudioJoin;
43
+ exports.defaultLocalAudioJoinDeps = defaultLocalAudioJoinDeps;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const child_process_1 = require("child_process");
47
+ const identity_1 = require("../../heart/identity");
48
+ const runtime_1 = require("../../nerves/runtime");
49
+ const audio_routing_1 = require("./audio-routing");
50
+ const local_audio_control_1 = require("./local-audio-control");
51
+ Object.defineProperty(exports, "parseNotifySession", { enumerable: true, get: function () { return local_audio_control_1.parseNotifySession; } });
52
+ const local_audio_mute_1 = require("./local-audio-mute");
53
+ const local_audio_notify_1 = require("./local-audio-notify");
54
+ const local_audio_transport_1 = require("./local-audio-transport");
55
+ const twilio_phone_runtime_1 = require("./twilio-phone-runtime");
56
+ const NO_SESSION = "No local audio session is running.";
57
+ /** The CLI arguments that make `ouro voice join` reproduce this request. */
58
+ function localAudioJoinArgs(request) {
59
+ const args = ["voice", "join", "--agent", request.agentName];
60
+ const flag = (name, value) => {
61
+ if (value !== undefined)
62
+ args.push(name, String(value));
63
+ };
64
+ flag("--friend", request.friendId);
65
+ flag("--participants", request.participants);
66
+ flag("--occasion", request.occasion);
67
+ flag("--mode", request.mode);
68
+ if (request.ownerAlone)
69
+ args.push("--owner-alone");
70
+ flag("--owner-name", request.ownerName);
71
+ flag("--silent-consent", request.silentConsent);
72
+ if (request.notify)
73
+ flag("--notify-session", `${request.notify.friendId}:${request.notify.channel}:${request.notify.key}`);
74
+ flag("--input-file", request.files?.inputPath);
75
+ flag("--output-file", request.files?.outputPath);
76
+ flag("--idle-silence-ms", request.idleSilenceMs);
77
+ flag("--max-duration-ms", request.maxDurationMs);
78
+ return args;
79
+ }
80
+ const END_PHRASES = {
81
+ left: "I left the call on request",
82
+ session_ended: "the audio session ended",
83
+ capture_ended: "the capture device stopped",
84
+ playback_failed: "the playback device failed",
85
+ disclosure_failed: "I could not confirm I announced myself aloud within 20 seconds, so I left",
86
+ idle_silence: "the room went idle (long silence), so I left",
87
+ max_duration: "it reached the maximum call length, so I left",
88
+ };
89
+ function joinedNotice(request, callSid) {
90
+ const parts = [`I joined a local audio session (${callSid}) as ${request.agentName}.`];
91
+ if (request.participants)
92
+ parts.push(`Participants: ${request.participants}.`);
93
+ if (request.occasion)
94
+ parts.push(`Occasion: ${request.occasion}.`);
95
+ const consent = request.silentConsent?.trim();
96
+ parts.push(consent
97
+ ? `This is a silent join on your recorded consent: "${consent}".`
98
+ : "I am announcing myself aloud as an AI assistant that is transcribing; if I cannot confirm that announcement was spoken, I will leave and tell you.");
99
+ parts.push("Say leave, or run `ouro voice leave`, to end it.");
100
+ return parts.join(" ");
101
+ }
102
+ function endedNotice(summary) {
103
+ const seconds = Math.round(summary.durationMs / 1000);
104
+ return `Local audio session ${summary.callSid} ended after ${seconds}s: ${END_PHRASES[summary.reason] ?? summary.reason}.`;
105
+ }
106
+ async function runLocalAudioJoin(request, deps) {
107
+ const agentRoot = deps.agentRoot(request.agentName);
108
+ const paths = (0, local_audio_control_1.localAudioPaths)(agentRoot);
109
+ const refuse = (what) => {
110
+ throw new Error(`A local audio session is already running (${what}). Run \`ouro voice leave\` first.`);
111
+ };
112
+ // Only one join may run per agent. A refused join touches nothing of the running one.
113
+ const lock = (0, local_audio_control_1.acquireJoinLock)(paths);
114
+ if (!lock.ok) {
115
+ const running = await (0, local_audio_control_1.sendLocalAudioControl)(paths, "status", 2_000);
116
+ return refuse(running.ok ? running.status.callSid : `starting, process ${lock.holderPid ?? "unknown"}`);
117
+ }
118
+ let server;
119
+ let transport;
120
+ // Registered as soon as we hold the lock, so a stop signal at any point ends the call and releases the lock.
121
+ let stopRequested = false;
122
+ const stopListening = deps.onStopSignal(() => {
123
+ stopRequested = true;
124
+ if (transport)
125
+ void transport.leave("left");
126
+ });
127
+ try {
128
+ // A server from before the lock existed, or one that answers without owning the lock.
129
+ const legacy = await (0, local_audio_control_1.sendLocalAudioControl)(paths, "status", 2_000);
130
+ if (legacy.ok)
131
+ refuse(legacy.status.callSid);
132
+ (0, local_audio_control_1.writeJoinStatus)(paths, { state: "starting" });
133
+ try {
134
+ const openaiRealtime = await deps.resolveRealtime(request.agentName);
135
+ if (stopRequested)
136
+ return await endBeforeJoining(request, deps, paths);
137
+ const bridge = localBridgeOptions(request.agentName, agentRoot, paths, openaiRealtime);
138
+ transport = deps.createTransport(request, bridge);
139
+ const live = transport;
140
+ server = new local_audio_control_1.LocalAudioControlServer(paths, { status: () => live.status(), leave: () => live.leave("left") });
141
+ await server.start();
142
+ await live.start();
143
+ }
144
+ catch (error) {
145
+ await server?.close();
146
+ // A stop signal during startup makes the start fail; that is a cancelled join, not a failure.
147
+ if (stopRequested)
148
+ return await endBeforeJoining(request, deps, paths);
149
+ const reason = error instanceof Error ? error.message : String(error);
150
+ (0, local_audio_control_1.writeJoinStatus)(paths, { state: "failed", reason });
151
+ if (request.notify)
152
+ await deps.notifyOwner(request.agentName, request.notify, `I could not join the local audio session: ${reason}`);
153
+ throw error;
154
+ }
155
+ const { callSid, state } = transport.status();
156
+ // A leave or stop signal during startup cancels the start: it ended without ever joining.
157
+ const joined = state !== "ended";
158
+ if (joined) {
159
+ (0, local_audio_control_1.writeJoinStatus)(paths, { state: "joined", callSid });
160
+ deps.write(`Joined local audio session ${callSid} as ${request.agentName}. Run \`ouro voice leave\` to end it.\n`);
161
+ if (request.notify)
162
+ await deps.notifyOwner(request.agentName, request.notify, joinedNotice(request, callSid));
163
+ }
164
+ const summary = await transport.ended;
165
+ (0, local_audio_control_1.writeJoinStatus)(paths, { state: "ended", callSid, reason: summary.reason });
166
+ await server.close();
167
+ if (request.notify)
168
+ await deps.notifyOwner(request.agentName, request.notify, endedNotice(summary));
169
+ return summary;
170
+ }
171
+ finally {
172
+ stopListening();
173
+ lock.release();
174
+ }
175
+ }
176
+ async function endBeforeJoining(request, deps, paths) {
177
+ (0, local_audio_control_1.writeJoinStatus)(paths, { state: "ended", reason: "left" });
178
+ if (request.notify)
179
+ await deps.notifyOwner(request.agentName, request.notify, "I was told to stop before joining the local audio session, so I did not join.");
180
+ return { reason: "left", callSid: "not-joined", durationMs: 0 };
181
+ }
182
+ function localBridgeOptions(agentName, agentRoot, paths, openaiRealtime) {
183
+ const unused = (what) => async () => { throw new Error(`${what} is not used by local audio`); };
184
+ return {
185
+ agentName,
186
+ agentRoot,
187
+ publicBaseUrl: "https://local-audio.invalid",
188
+ outputDir: paths.dir,
189
+ transcriber: { transcribe: unused("the transcriber") },
190
+ tts: { synthesize: unused("text to speech") },
191
+ transportMode: "media-stream",
192
+ conversationEngine: "openai-realtime",
193
+ outboundConversationEngine: "openai-realtime",
194
+ openaiRealtime,
195
+ };
196
+ }
197
+ async function runLocalAudioLeave(agentName, deps) {
198
+ const paths = (0, local_audio_control_1.localAudioPaths)(deps.agentRoot(agentName));
199
+ const active = await (0, local_audio_control_1.inspectActiveJoin)(paths);
200
+ if (!active)
201
+ return NO_SESSION;
202
+ const reply = await (0, local_audio_control_1.sendLocalAudioControl)(paths, "leave");
203
+ if (!reply.ok && active.state === "starting") {
204
+ // The join has not opened its control socket yet; its stop-signal handler is already registered.
205
+ const pid = (0, local_audio_control_1.stopLockHolder)(paths);
206
+ if (pid !== null)
207
+ return `Told the local audio session that is still starting (process ${pid}) to stop.`;
208
+ }
209
+ if (!reply.ok)
210
+ return `Could not leave the local audio session: ${reply.error}`;
211
+ return `Left local audio session ${active.callSid}.`;
212
+ }
213
+ async function runLocalAudioStatus(agentName, deps) {
214
+ const active = await (0, local_audio_control_1.inspectActiveJoin)((0, local_audio_control_1.localAudioPaths)(deps.agentRoot(agentName)));
215
+ if (!active)
216
+ return NO_SESSION;
217
+ return `Local audio session ${active.callSid} is ${active.state}${active.startedAt ? ` (since ${active.startedAt})` : ""}.`;
218
+ }
219
+ /** A detached child with stdout and stderr appended to the join log. */
220
+ function defaultLaunchSpawn(paths) {
221
+ return (command, args) => {
222
+ fs.mkdirSync(paths.dir, { recursive: true, mode: 0o700 });
223
+ const log = fs.openSync(paths.logFile, "a", 0o600);
224
+ try {
225
+ return (0, child_process_1.spawn)(command, args, { detached: true, stdio: ["ignore", log, log] });
226
+ }
227
+ finally {
228
+ fs.closeSync(log);
229
+ }
230
+ };
231
+ }
232
+ const POLL_MS = 250;
233
+ /**
234
+ * The launcher gave up waiting, so the detached join must not be left running unsupervised. If it
235
+ * already opened its control socket it is asked to leave (a clean stop); otherwise its process group
236
+ * gets SIGTERM, which its stop handler turns into a clean end.
237
+ */
238
+ async function stopTimedOutJoin(paths, pid, kill) {
239
+ const reply = await (0, local_audio_control_1.sendLocalAudioControl)(paths, "leave", 10_000);
240
+ if (reply.ok)
241
+ return "I asked it to leave.";
242
+ if (pid === undefined)
243
+ return "I could not stop it (no process id), so check for a stray join.";
244
+ try {
245
+ kill(-pid, "SIGTERM");
246
+ return "I stopped it.";
247
+ }
248
+ catch {
249
+ return "I could not stop it, so check for a stray join.";
250
+ }
251
+ }
252
+ /** Starts `ouro voice join` as a detached process and waits for it to report joined or failed. */
253
+ async function launchLocalAudioJoin(request, deps) {
254
+ const paths = (0, local_audio_control_1.localAudioPaths)(deps.agentRoot(request.agentName));
255
+ const active = await (0, local_audio_control_1.inspectActiveJoin)(paths);
256
+ if (active)
257
+ return { ok: false, message: `A local audio session is already running (${active.callSid}). Run \`ouro voice leave\` first.` };
258
+ fs.rmSync(paths.statusFile, { force: true });
259
+ const child = deps.spawn(deps.execPath, [deps.cliEntry, ...localAudioJoinArgs(request)]);
260
+ let exitCode;
261
+ child.on("exit", (code) => { exitCode = code; });
262
+ child.unref();
263
+ (0, runtime_1.emitNervesEvent)({
264
+ component: "senses",
265
+ event: "senses.voice_local_launch",
266
+ message: "launched a detached local audio join",
267
+ meta: { agentName: request.agentName, pid: child.pid },
268
+ });
269
+ const deadline = deps.now() + deps.timeoutMs;
270
+ for (;;) {
271
+ const status = (0, local_audio_control_1.readJoinStatus)(paths);
272
+ if (status?.state === "joined") {
273
+ return { ok: true, callSid: status.callSid, message: `Joined local audio session ${status.callSid}.` };
274
+ }
275
+ if (status?.state === "failed")
276
+ return { ok: false, message: status.reason ?? "The local audio join failed." };
277
+ if (status?.state === "ended")
278
+ return { ok: false, message: `The local audio join ended before it finished starting (${status.reason ?? "no reason recorded"}).` };
279
+ if (exitCode !== undefined) {
280
+ return { ok: false, message: `The local audio join process exited (code ${exitCode}) before joining. See ${paths.logFile}.` };
281
+ }
282
+ if (deps.now() >= deadline) {
283
+ const outcome = await stopTimedOutJoin(paths, child.pid, deps.kill ?? process.kill.bind(process));
284
+ return { ok: false, message: `The local audio join did not report within ${Math.round(deps.timeoutMs / 1000)}s, so ${outcome} See ${paths.logFile}.` };
285
+ }
286
+ await deps.sleep(POLL_MS);
287
+ }
288
+ }
289
+ /** `OURO_LOCAL_AUDIO_OUTPUT_LATENCY_MS`: the owner's own estimate of speaker latency, in milliseconds. */
290
+ function configuredOutputLatencyMs() {
291
+ const value = Number(process.env.OURO_LOCAL_AUDIO_OUTPUT_LATENCY_MS);
292
+ return process.env.OURO_LOCAL_AUDIO_OUTPUT_LATENCY_MS !== undefined && Number.isFinite(value) && value >= 0 ? value : undefined;
293
+ }
294
+ function defaultLocalAudioJoinDeps(overrides = {}) {
295
+ const agentRoot = overrides.agentRoot ?? ((agentName) => (0, identity_1.getAgentRoot)(agentName));
296
+ return {
297
+ agentRoot,
298
+ resolveRealtime: (agentName) => (0, twilio_phone_runtime_1.resolveLocalAudioRealtimeOptions)(agentName),
299
+ createTransport: (request, bridge) => {
300
+ const paths = (0, local_audio_control_1.localAudioPaths)(bridge.agentRoot ?? agentRoot(request.agentName));
301
+ return new local_audio_transport_1.LocalAudioDeviceTransport(request, {
302
+ spawner: { spawn: (command, args, options) => (0, child_process_1.spawn)(command, args, { detached: options.detached, stdio: ["pipe", "pipe", "ignore"] }) },
303
+ bridgeOptions: bridge,
304
+ pidFile: paths.soxPidFile,
305
+ metadataDir: paths.callsDir,
306
+ inspectRouting: audio_routing_1.inspectVoiceAudioRouting,
307
+ queryMute: (0, local_audio_mute_1.createSwiftMuteQuery)({ dir: path.join(paths.dir, "tools") }),
308
+ outputLatencyMs: configuredOutputLatencyMs(),
309
+ });
310
+ },
311
+ notifyOwner: async (agentName, target, text) => {
312
+ await (0, local_audio_notify_1.notifyOwnerLive)(agentName, target, text, { agentRoot: agentRoot(agentName) });
313
+ },
314
+ write: (text) => { process.stdout.write(text); },
315
+ onStopSignal: (callback) => {
316
+ process.on("SIGINT", callback);
317
+ process.on("SIGTERM", callback);
318
+ return () => {
319
+ process.off("SIGINT", callback);
320
+ process.off("SIGTERM", callback);
321
+ };
322
+ },
323
+ ...overrides,
324
+ };
325
+ }
@@ -0,0 +1,199 @@
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.MUTE_PROBE_SWIFT = void 0;
37
+ exports.parseMuteProbeOutput = parseMuteProbeOutput;
38
+ exports.muteFixSteps = muteFixSteps;
39
+ exports.defaultRun = defaultRun;
40
+ exports.createSwiftMuteQuery = createSwiftMuteQuery;
41
+ const child_process_1 = require("child_process");
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
+ exports.MUTE_PROBE_SWIFT = `import CoreAudio
47
+ import Foundation
48
+
49
+ func deviceIds() -> [AudioObjectID] {
50
+ var addr = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDevices, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMain)
51
+ var size: UInt32 = 0
52
+ AudioObjectGetPropertyDataSize(AudioObjectID(kAudioObjectSystemObject), &addr, 0, nil, &size)
53
+ var ids = [AudioObjectID](repeating: 0, count: Int(size) / MemoryLayout<AudioObjectID>.size)
54
+ AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &addr, 0, nil, &size, &ids)
55
+ return ids
56
+ }
57
+
58
+ func deviceName(_ id: AudioObjectID) -> String {
59
+ var addr = AudioObjectPropertyAddress(mSelector: kAudioObjectPropertyName, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMain)
60
+ var name: Unmanaged<CFString>? = nil
61
+ var size = UInt32(MemoryLayout<Unmanaged<CFString>?>.size)
62
+ AudioObjectGetPropertyData(id, &addr, 0, nil, &size, &name)
63
+ return (name?.takeRetainedValue() as String?) ?? ""
64
+ }
65
+
66
+ func muteState(_ id: AudioObjectID, scope: AudioObjectPropertyScope) -> String {
67
+ var result: Bool? = nil
68
+ for element in [kAudioObjectPropertyElementMain, 1, 2] as [UInt32] {
69
+ var addr = AudioObjectPropertyAddress(mSelector: kAudioDevicePropertyMute, mScope: scope, mElement: element)
70
+ if !AudioObjectHasProperty(id, &addr) { continue }
71
+ var value: UInt32 = 0
72
+ var size = UInt32(MemoryLayout<UInt32>.size)
73
+ if AudioObjectGetPropertyData(id, &addr, 0, nil, &size, &value) == 0 { result = (result ?? false) || value != 0 }
74
+ }
75
+ guard let muted = result else { return "n/a" }
76
+ return muted ? "muted" : "unmuted"
77
+ }
78
+
79
+ let wanted = Set(CommandLine.arguments.dropFirst())
80
+ for id in deviceIds() {
81
+ let name = deviceName(id)
82
+ if wanted.contains(name) {
83
+ print("\\(name)\\tinput=\\(muteState(id, scope: kAudioObjectPropertyScopeInput))\\toutput=\\(muteState(id, scope: kAudioObjectPropertyScopeOutput))")
84
+ }
85
+ }
86
+ `;
87
+ function scopeState(text) {
88
+ const value = text.split("=")[1];
89
+ if (value === "muted")
90
+ return true;
91
+ if (value === "unmuted")
92
+ return false;
93
+ return null;
94
+ }
95
+ function parseMuteProbeOutput(text) {
96
+ const states = [];
97
+ for (const line of text.split("\n")) {
98
+ const [device = "", input = "", output = ""] = line.split("\t");
99
+ if (!device || !input.startsWith("input=") || !output.startsWith("output="))
100
+ continue;
101
+ states.push({ device, inputMuted: scopeState(input), outputMuted: scopeState(output) });
102
+ }
103
+ return states;
104
+ }
105
+ /** Exact steps for each device that is muted at the device level. */
106
+ function muteFixSteps(states) {
107
+ const steps = [];
108
+ for (const state of states) {
109
+ const scopes = [state.inputMuted ? "input" : "", state.outputMuted ? "output" : ""].filter(Boolean);
110
+ if (scopes.length === 0)
111
+ continue;
112
+ steps.push(`${state.device} is muted (${scopes.join(" and ")}), so it loops back pure silence. Unmute it: open Audio MIDI Setup, select ${state.device}, open the ${scopes.join(" and ")} tab${scopes.length > 1 ? "s" : ""}, and uncheck Mute on the Main channel.`);
113
+ }
114
+ return steps;
115
+ }
116
+ function defaultRun(command, args) {
117
+ return new Promise((resolve, reject) => {
118
+ (0, child_process_1.execFile)(command, args, { encoding: "utf8", timeout: 60_000 }, (error, stdout) => {
119
+ if (error)
120
+ reject(error);
121
+ else
122
+ resolve(stdout);
123
+ });
124
+ });
125
+ }
126
+ function privateDirectory(dir, uid) {
127
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
128
+ const stat = fs.lstatSync(dir);
129
+ if (!stat.isDirectory() || (uid !== undefined && stat.uid !== uid)) {
130
+ throw new Error(`mute probe directory ${dir} is not a directory owned by this user`);
131
+ }
132
+ if (stat.mode & 0o077)
133
+ fs.chmodSync(dir, 0o700);
134
+ }
135
+ /** A regular file (not a link), owned by us, executable, and writable by nobody else. */
136
+ function trustedBinary(file, uid) {
137
+ try {
138
+ const stat = fs.lstatSync(file);
139
+ return stat.isFile() && (uid === undefined || stat.uid === uid) && (stat.mode & 0o022) === 0 && (stat.mode & 0o100) !== 0;
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ }
145
+ /**
146
+ * Compiles the probe once with `swiftc` (a few seconds) into the agent's private directory and
147
+ * caches the binary, so later joins read mute state in milliseconds. The binary's name carries a
148
+ * hash of the script, the build writes only new exclusive files and renames the result into place,
149
+ * and the owner and mode are checked again before every run. Partial builds are deleted.
150
+ */
151
+ function createSwiftMuteQuery(options) {
152
+ const run = options.run ?? defaultRun;
153
+ const swiftcPath = options.swiftcPath ?? "swiftc";
154
+ const uid = options.uid ?? process.getuid?.();
155
+ const hash = (0, crypto_1.createHash)("sha256").update(exports.MUTE_PROBE_SWIFT).digest("hex").slice(0, 16);
156
+ const binaryPath = path.join(options.dir, `mute-probe-${hash}`);
157
+ const build = async () => {
158
+ const token = `${process.pid}.${(0, crypto_1.randomBytes)(4).toString("hex")}`;
159
+ const script = path.join(options.dir, `${hash}.${token}.swift`);
160
+ const output = path.join(options.dir, `${hash}.${token}.bin`);
161
+ try {
162
+ fs.writeFileSync(script, exports.MUTE_PROBE_SWIFT, { flag: "wx", mode: 0o600 });
163
+ await run(swiftcPath, ["-O", script, "-o", output]);
164
+ fs.chmodSync(output, 0o700);
165
+ fs.renameSync(output, binaryPath);
166
+ }
167
+ finally {
168
+ fs.rmSync(script, { force: true });
169
+ fs.rmSync(output, { force: true });
170
+ }
171
+ };
172
+ return async (devices) => {
173
+ try {
174
+ privateDirectory(options.dir, uid);
175
+ if (!trustedBinary(binaryPath, uid)) {
176
+ fs.rmSync(binaryPath, { force: true });
177
+ await build();
178
+ }
179
+ const states = parseMuteProbeOutput(await run(binaryPath, devices));
180
+ (0, runtime_1.emitNervesEvent)({
181
+ component: "senses",
182
+ event: "senses.voice_local_mute_checked",
183
+ message: "local audio device mute state read",
184
+ meta: { devices: devices.length, muted: states.filter((s) => s.inputMuted || s.outputMuted).length },
185
+ });
186
+ return states;
187
+ }
188
+ catch (error) {
189
+ (0, runtime_1.emitNervesEvent)({
190
+ level: "warn",
191
+ component: "senses",
192
+ event: "senses.voice_local_mute_check_unavailable",
193
+ message: "local audio device mute state could not be read",
194
+ meta: { error: error instanceof Error ? error.message : String(error) },
195
+ });
196
+ return null;
197
+ }
198
+ };
199
+ }