@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.921
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +154 -23
- package/RepairGuide.ouro/agent.json +5 -0
- package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
- package/RepairGuide.ouro/psyche/SOUL.md +55 -0
- package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
- package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
- package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/assets/bluebubbles-host +264 -0
- package/assets/sanctuary-host-launcher.sh +16 -0
- package/changelog.json +5826 -16
- package/deploy/unraid/Dockerfile +58 -0
- package/deploy/unraid/README.txt +2997 -0
- package/deploy/unraid/audit-container-spec.sh +4 -0
- package/deploy/unraid/container-runtime.json +1 -0
- package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
- package/deploy/unraid/docker-man-template-xml.cjs +105 -0
- package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
- package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
- package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
- package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
- package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
- package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
- package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
- package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
- package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
- package/deploy/unraid/sanctuary-authority-installation.json +36 -0
- package/deploy/unraid/sanctuary-authority-service.sh +30 -0
- package/deploy/unraid/sanctuary-butler-upgrade.mjs +1254 -0
- package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
- package/deploy/unraid/sanctuary-replay-gate.mjs +1564 -0
- package/deploy/unraid/sanctuary-safe-rename.py +24 -0
- package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
- package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
- package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
- package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
- package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
- package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
- package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
- package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
- package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
- package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
- package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
- package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
- package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
- package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
- package/deploy/unraid/sanctuary.xml +30 -0
- package/dist/a2a/card.js +57 -0
- package/dist/a2a/client.js +250 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/delegated-command-grants.js +93 -0
- package/dist/a2a/delegated-command.js +197 -0
- package/dist/a2a/delegation-stores.js +56 -0
- package/dist/a2a/did-resolution.js +93 -0
- package/dist/a2a/escalation-grants.js +84 -0
- package/dist/a2a/escalation-wiring.js +60 -0
- package/dist/a2a/identity.js +258 -0
- package/dist/a2a/inbound-share.js +110 -0
- package/dist/a2a/mission-result-wire.js +196 -0
- package/dist/a2a/onboarding.js +133 -0
- package/dist/a2a/operator-trust.js +382 -0
- package/dist/a2a/outbox-client.js +57 -0
- package/dist/a2a/outbox-store.js +188 -0
- package/dist/a2a/outbox-wire.js +95 -0
- package/dist/a2a/pin-store.js +132 -0
- package/dist/a2a/replay-grant-holders.js +33 -0
- package/dist/a2a/replay-harness.js +188 -0
- package/dist/a2a/resolution-proof.js +53 -0
- package/dist/a2a/sealed-chat.js +113 -0
- package/dist/a2a/seen-ledger.js +120 -0
- package/dist/a2a/server.js +771 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/transport.js +45 -0
- package/dist/a2a/trust-commands.js +203 -0
- package/dist/a2a/trusted-files.js +185 -0
- package/dist/a2a/types.js +3 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +360 -0
- package/dist/arc/episodes.js +118 -0
- package/dist/arc/evolution.js +490 -0
- package/dist/arc/flight-recorder.js +1034 -0
- package/dist/arc/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +386 -0
- package/dist/arc/packets.js +336 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +57 -0
- package/dist/commerce/store.js +755 -0
- package/dist/commerce/types.js +3 -0
- package/dist/heart/active-work.js +798 -40
- package/dist/heart/agent-entry.js +252 -3
- package/dist/heart/approval-files.js +113 -0
- package/dist/heart/approval-store.js +960 -0
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +18 -0
- package/dist/heart/attachments/sources/telegram.js +71 -0
- package/dist/heart/attachments/store.js +132 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +495 -0
- package/dist/heart/autonomy-budget.js +478 -0
- package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
- package/dist/heart/awaiting/await-alert.js +152 -0
- package/dist/heart/awaiting/await-expiry.js +143 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +152 -0
- package/dist/heart/awaiting/await-runtime-state.js +111 -0
- package/dist/heart/awaiting/await-scheduler.js +391 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bluebubbles-host-account.js +78 -0
- package/dist/heart/bridges/manager.js +137 -17
- package/dist/heart/bridges/store.js +14 -2
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +44 -18
- package/dist/heart/config-registry.js +331 -0
- package/dist/heart/config.js +174 -131
- package/dist/heart/context-loss-gauntlet.js +387 -0
- package/dist/heart/context-loss-sentinel.js +1159 -0
- package/dist/heart/core.js +2364 -578
- package/dist/heart/cross-chat-delivery.js +9 -22
- package/dist/heart/daemon/agent-config-check.js +451 -0
- package/dist/heart/daemon/agent-discovery.js +283 -3
- package/dist/heart/daemon/agent-home.js +319 -0
- package/dist/heart/daemon/agent-service.js +542 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/await-private-wake.js +59 -0
- package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
- package/dist/heart/daemon/bluebubbles-host.js +273 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +180 -0
- package/dist/heart/daemon/cli-arg-redaction.js +26 -0
- package/dist/heart/daemon/cli-defaults.js +876 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +9199 -0
- package/dist/heart/daemon/cli-help.js +735 -0
- package/dist/heart/daemon/cli-parse.js +3211 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +819 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
- package/dist/heart/daemon/container-healthcheck.js +112 -0
- package/dist/heart/daemon/container-runtime.js +97 -0
- package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
- package/dist/heart/daemon/container-spec-auditor.js +235 -0
- package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
- package/dist/heart/daemon/daemon-cli.js +29 -2350
- package/dist/heart/daemon/daemon-entry.js +953 -11
- package/dist/heart/daemon/daemon-health.js +186 -0
- package/dist/heart/daemon/daemon-rollup.js +57 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +2084 -105
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +1766 -0
- package/dist/heart/daemon/freshness.js +345 -0
- package/dist/heart/daemon/habit-private-wake.js +61 -0
- package/dist/heart/daemon/health-monitor.js +154 -11
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +78 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +79 -10
- package/dist/heart/daemon/logs-prune.js +132 -0
- package/dist/heart/daemon/mcp-canary.js +524 -0
- package/dist/heart/daemon/message-router.js +65 -5
- package/dist/heart/daemon/migrate-to-desk.js +848 -0
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +22 -14
- package/dist/heart/daemon/ouro-bot-entry.js +6 -3
- package/dist/heart/daemon/ouro-entry.js +5 -2
- package/dist/heart/daemon/plugin-cli.js +432 -0
- package/dist/heart/daemon/process-manager.js +760 -61
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/prunable-bundle.js +144 -0
- package/dist/heart/daemon/pulse.js +511 -0
- package/dist/heart/daemon/readiness-repair.js +365 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +47 -14
- package/dist/heart/daemon/runtime-metadata.js +2 -30
- package/dist/heart/daemon/runtime-mode.js +13 -2
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
- package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
- package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
- package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
- package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
- package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
- package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
- package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
- package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
- package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
- package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
- package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
- package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
- package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
- package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
- package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
- package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
- package/dist/heart/daemon/sanctuary-package-management.js +103 -0
- package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
- package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
- package/dist/heart/daemon/sense-manager.js +733 -48
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +1 -1
- package/dist/heart/daemon/socket-client.js +180 -12
- package/dist/heart/daemon/stale-bundle-prune.js +113 -0
- package/dist/heart/daemon/startup-tui.js +339 -0
- package/dist/heart/daemon/supercronic-supervisor.js +282 -0
- package/dist/heart/daemon/task-scheduler.js +117 -39
- package/dist/heart/daemon/terminal-ui.js +503 -0
- package/dist/heart/daemon/thoughts.js +138 -54
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -4
- package/dist/heart/external-events/router.js +1516 -0
- package/dist/heart/failure-reports.js +336 -0
- package/dist/heart/file-lock.js +109 -0
- package/dist/heart/frontend-approval-runtime.js +506 -0
- package/dist/heart/frontend-journal.js +215 -0
- package/dist/heart/frontend-session-service.js +237 -0
- package/dist/heart/frontend-socket-client.js +164 -0
- package/dist/heart/frontend-socket.js +400 -0
- package/dist/heart/habits/habit-cancel.js +810 -0
- package/dist/heart/habits/habit-lifecycle.js +1327 -0
- package/dist/heart/habits/habit-migration.js +194 -0
- package/dist/heart/habits/habit-parser.js +278 -0
- package/dist/heart/habits/habit-runtime-state.js +93 -0
- package/dist/heart/habits/habit-scheduler.js +653 -0
- package/dist/heart/habits/habit-session-summary.js +318 -0
- package/dist/heart/habits/habit-session.js +636 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
- package/dist/heart/identity.js +230 -59
- package/dist/heart/kept-notes.js +289 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +175 -0
- package/dist/heart/mail-import-discovery.js +356 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +39 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +197 -0
- package/dist/heart/mailbox/readers/agent-machine.js +428 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
- package/dist/heart/mailbox/readers/sessions.js +231 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +696 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +83 -16
- package/dist/heart/orientation-frame.js +345 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/primitives.js +1 -1
- package/dist/heart/private-runtime/decision-renderer.js +158 -0
- package/dist/heart/private-runtime/index.js +18 -0
- package/dist/heart/private-runtime/ledger.js +221 -0
- package/dist/heart/private-runtime/policy.js +260 -0
- package/dist/heart/private-runtime/types.js +2 -0
- package/dist/heart/progress-story.js +1 -1
- package/dist/heart/provider-attempt.js +137 -0
- package/dist/heart/provider-binding-resolver.js +273 -0
- package/dist/heart/provider-credentials.js +449 -0
- package/dist/heart/provider-failover.js +311 -0
- package/dist/heart/provider-models.js +96 -0
- package/dist/heart/provider-ping.js +265 -0
- package/dist/heart/provider-readiness-cache.js +119 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +173 -60
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +38 -39
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex-token.js +349 -0
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/providers/openai-compatible.js +177 -0
- package/dist/heart/reply-style.js +52 -0
- package/dist/heart/run-ledger.js +247 -0
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +607 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +24 -4
- package/dist/heart/session-activity.js +92 -24
- package/dist/heart/session-events.js +1504 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-redaction-repair-cli-main.js +31 -0
- package/dist/heart/session-redaction-repair.js +552 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +183 -0
- package/dist/heart/session-transcript.js +133 -0
- package/dist/heart/shelf-claims.js +78 -0
- package/dist/heart/shepherd-config.js +113 -0
- package/dist/heart/source-grounding.js +297 -0
- package/dist/heart/start-of-turn-packet.js +372 -0
- package/dist/heart/steward-policy.js +656 -0
- package/dist/heart/streaming.js +609 -207
- package/dist/heart/structured-output.js +196 -0
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync-health.js +152 -0
- package/dist/heart/sync.js +726 -0
- package/dist/heart/target-resolution.js +11 -7
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-approval.js +382 -0
- package/dist/heart/tool-description.js +155 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +206 -0
- package/dist/heart/turn-context.js +496 -0
- package/dist/heart/turn-execution-lease.js +30 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
- package/dist/heart/versioning/ouro-path-installer.js +432 -0
- package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
- package/dist/heart/versioning/ouro-version-manager.js +432 -0
- package/dist/heart/versioning/release-sources.js +173 -0
- package/dist/heart/versioning/self-update-defaults.js +294 -0
- package/dist/heart/versioning/self-update.js +196 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/versioning/update-hooks.js +154 -0
- package/dist/heart/versioning/update-state.js +126 -0
- package/dist/heart/versioning/updater-launchd.js +150 -0
- package/dist/heart/versioning/version-intent.js +114 -0
- package/dist/heart/work-card.js +380 -0
- package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
- package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
- package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
- package/dist/mailbox-ui/index.html +16 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +889 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/cache-sync-cli.js +58 -0
- package/dist/mailroom/core.js +803 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +568 -0
- package/dist/mailroom/hosted-cache-sync.js +384 -0
- package/dist/mailroom/mbox-import.js +393 -0
- package/dist/mailroom/migration.js +164 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +292 -0
- package/dist/mailroom/search-cache.js +513 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +24 -2
- package/dist/mind/context.js +307 -139
- package/dist/mind/desk-section.js +362 -0
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +68 -77
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friend-link-codes.js +209 -0
- package/dist/mind/friend-merge.js +330 -0
- package/dist/mind/{associative-recall.js → note-search.js} +47 -58
- package/dist/mind/obligation-steering.js +199 -3
- package/dist/mind/pending.js +36 -10
- package/dist/mind/prompt-budget.js +479 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1085 -198
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/record-paths.js +312 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/session-transaction.js +564 -0
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +139 -5
- package/dist/nerves/coverage/run-artifacts.js +55 -35
- package/dist/nerves/coverage/source-scanner.js +4 -4
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +293 -9
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +159 -0
- package/dist/nerves/runtime.js +17 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +16 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +1201 -0
- package/dist/repertoire/bundle-templates.js +71 -0
- package/dist/repertoire/bw-installer.js +231 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +331 -0
- package/dist/repertoire/coding/feedback.js +174 -32
- package/dist/repertoire/coding/index.js +15 -3
- package/dist/repertoire/coding/manager.js +159 -10
- package/dist/repertoire/coding/spawner.js +40 -11
- package/dist/repertoire/coding/tools.js +182 -18
- package/dist/repertoire/coding/workbench-client.js +272 -0
- package/dist/repertoire/coding/workbench-manager.js +346 -0
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +183 -0
- package/dist/repertoire/desk/classifier.js +362 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +968 -20
- package/dist/repertoire/house-sweep.js +469 -0
- package/dist/repertoire/mcp-client.js +58 -5
- package/dist/repertoire/mcp-manager.js +427 -139
- package/dist/repertoire/mcp-tools.js +132 -0
- package/dist/repertoire/mcp-write-guard.js +46 -0
- package/dist/repertoire/plugin-mcp.js +175 -0
- package/dist/repertoire/plugins.js +253 -0
- package/dist/repertoire/relationship-authorization.js +322 -0
- package/dist/repertoire/sanctuary-container-policy.js +46 -0
- package/dist/repertoire/shell-sessions.js +134 -0
- package/dist/repertoire/skills.js +48 -4
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tool-arguments.js +182 -0
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-a2a.js +699 -0
- package/dist/repertoire/tools-attachments.js +322 -0
- package/dist/repertoire/tools-awaiting.js +872 -0
- package/dist/repertoire/tools-base.js +83 -1168
- package/dist/repertoire/tools-bluebubbles.js +2 -0
- package/dist/repertoire/tools-bridge.js +144 -0
- package/dist/repertoire/tools-bundle.js +995 -0
- package/dist/repertoire/tools-commerce.js +253 -0
- package/dist/repertoire/tools-config.js +186 -0
- package/dist/repertoire/tools-continuity.js +575 -0
- package/dist/repertoire/tools-credential.js +383 -0
- package/dist/repertoire/tools-escalation.js +84 -0
- package/dist/repertoire/tools-evolution.js +527 -0
- package/dist/repertoire/tools-files.js +344 -0
- package/dist/repertoire/tools-flight.js +290 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-friend-link.js +57 -0
- package/dist/repertoire/tools-github.js +3 -8
- package/dist/repertoire/tools-habits.js +103 -0
- package/dist/repertoire/tools-house-care.js +174 -0
- package/dist/repertoire/tools-mail.js +1828 -0
- package/dist/repertoire/tools-notes.js +496 -0
- package/dist/repertoire/tools-obligations.js +182 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +482 -0
- package/dist/repertoire/tools-rsvp.js +139 -0
- package/dist/repertoire/tools-runtime.js +238 -0
- package/dist/repertoire/tools-sanctuary-host.js +202 -0
- package/dist/repertoire/tools-session.js +1133 -0
- package/dist/repertoire/tools-shell.js +149 -0
- package/dist/repertoire/tools-shepherd.js +262 -0
- package/dist/repertoire/tools-steward-policy.js +147 -0
- package/dist/repertoire/tools-stripe.js +224 -0
- package/dist/repertoire/tools-surface.js +369 -0
- package/dist/repertoire/tools-teams.js +12 -39
- package/dist/repertoire/tools-telegram-contacts.js +37 -0
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +982 -0
- package/dist/repertoire/tools-unraid.js +556 -0
- package/dist/repertoire/tools-user-profile.js +146 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice-local.js +198 -0
- package/dist/repertoire/tools-voice.js +145 -0
- package/dist/repertoire/tools.js +514 -156
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/unraid-client.js +155 -0
- package/dist/repertoire/unraid-restart.js +339 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +686 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +936 -0
- package/dist/rsvp/config.js +327 -0
- package/dist/rsvp/cutover.js +433 -0
- package/dist/rsvp/diagnostics.js +232 -0
- package/dist/rsvp/diff-renderer.js +176 -0
- package/dist/rsvp/habit-policy.js +110 -0
- package/dist/rsvp/habit-stage.js +123 -0
- package/dist/rsvp/incident-bundle.js +97 -0
- package/dist/rsvp/migration.js +204 -0
- package/dist/rsvp/native-habit-runner.js +630 -0
- package/dist/rsvp/outbound-state.js +628 -0
- package/dist/rsvp/query.js +118 -0
- package/dist/rsvp/replay.js +233 -0
- package/dist/rsvp/snapshot.js +232 -0
- package/dist/rsvp/spend-ledger.js +175 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/a2a-entry.js +132 -0
- package/dist/senses/acp-server.js +386 -0
- package/dist/senses/attention-queue.js +186 -0
- package/dist/senses/await-turn-message.js +65 -0
- package/dist/senses/bluebubbles/active-turns.js +216 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +379 -41
- package/dist/senses/bluebubbles/context-packet.js +207 -0
- package/dist/senses/bluebubbles/context-smoke.js +144 -0
- package/dist/senses/bluebubbles/entry.js +90 -0
- package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
- package/dist/senses/bluebubbles/index.js +3878 -0
- package/dist/senses/bluebubbles/latest-turn.js +311 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
- package/dist/senses/bluebubbles/outbound-state.js +308 -0
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/reaction-policy.js +47 -0
- package/dist/senses/bluebubbles/replay.js +284 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/bluebubbles/webhook-registration.js +257 -0
- package/dist/senses/bluebubbles-meta-guard.js +39 -0
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +607 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +85 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +241 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli.js +601 -304
- package/dist/senses/commands.js +66 -3
- package/dist/senses/context-packet-ledger.js +371 -0
- package/dist/senses/context-packets.js +154 -0
- package/dist/senses/habit-lifecycle-guard.js +24 -0
- package/dist/senses/habit-turn-message.js +160 -0
- package/dist/senses/ingress-evidence.js +2 -0
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +524 -0
- package/dist/senses/pipeline.js +1158 -204
- package/dist/senses/private-runtime-worker.js +859 -0
- package/dist/senses/private-runtime.js +1627 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/root-host-approval-port.js +345 -0
- package/dist/senses/root-host-approval-runtime.js +393 -0
- package/dist/senses/sanctuary-authority-resident.js +102 -0
- package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
- package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
- package/dist/senses/sanctuary-grounding.js +118 -0
- package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
- package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
- package/dist/senses/sanctuary-health-runner.js +104 -0
- package/dist/senses/sanctuary-health.js +422 -0
- package/dist/senses/sanctuary-install-state-contract.js +169 -0
- package/dist/senses/sanctuary-interactive-control.js +410 -0
- package/dist/senses/sanctuary-media-catalog-contract.js +259 -0
- package/dist/senses/sanctuary-media-optimization.js +514 -0
- package/dist/senses/sanctuary-runtime.js +369 -0
- package/dist/senses/sanctuary-sab.js +85 -0
- package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
- package/dist/senses/shared-turn.js +793 -0
- package/dist/senses/shepherd/client.js +196 -0
- package/dist/senses/shepherd/cmux.js +352 -0
- package/dist/senses/shepherd/herdr.js +315 -0
- package/dist/senses/shepherd/host.js +14 -0
- package/dist/senses/shepherd/judge.js +137 -0
- package/dist/senses/shepherd/owner-notice.js +251 -0
- package/dist/senses/shepherd/redact.js +66 -0
- package/dist/senses/shepherd/returns.js +79 -0
- package/dist/senses/shepherd/sense.js +310 -0
- package/dist/senses/shepherd/terminal-process.js +99 -0
- package/dist/senses/shepherd-entry.js +78 -0
- package/dist/senses/surface-tool.js +109 -0
- package/dist/senses/teams-entry.js +68 -8
- package/dist/senses/teams.js +598 -233
- package/dist/senses/telegram-admission.js +718 -0
- package/dist/senses/telegram-approval-runtime.js +793 -0
- package/dist/senses/telegram-attachments.js +186 -0
- package/dist/senses/telegram-audit-ledger.js +220 -0
- package/dist/senses/telegram-authority-transport.js +231 -0
- package/dist/senses/telegram-client.js +1749 -0
- package/dist/senses/telegram-effect-adapter.js +900 -0
- package/dist/senses/telegram-entry.js +83 -0
- package/dist/senses/telegram-handoff.js +80 -0
- package/dist/senses/telegram.js +2405 -0
- package/dist/senses/trust-gate.js +104 -9
- package/dist/senses/voice/audio-playback.js +237 -0
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/call-auth.js +250 -0
- package/dist/senses/voice/elevenlabs.js +202 -0
- package/dist/senses/voice/floor-control.js +431 -0
- package/dist/senses/voice/floor-controller.js +115 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +29 -0
- package/dist/senses/voice/local-audio-control.js +344 -0
- package/dist/senses/voice/local-audio-devices.js +516 -0
- package/dist/senses/voice/local-audio-disclosure.js +174 -0
- package/dist/senses/voice/local-audio-identity.js +103 -0
- package/dist/senses/voice/local-audio-join.js +325 -0
- package/dist/senses/voice/local-audio-mute.js +199 -0
- package/dist/senses/voice/local-audio-notify.js +121 -0
- package/dist/senses/voice/local-audio-prompts.js +116 -0
- package/dist/senses/voice/local-audio-transport.js +427 -0
- package/dist/senses/voice/local-audio.js +281 -0
- package/dist/senses/voice/local-media-stream.js +145 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/outbound.js +190 -0
- package/dist/senses/voice/phone.js +33 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/process-guards.js +51 -0
- package/dist/senses/voice/realtime-eval.js +496 -0
- package/dist/senses/voice/realtime-tool-schema.js +195 -0
- package/dist/senses/voice/realtime-trace.js +531 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +191 -0
- package/dist/senses/voice/twilio-phone-runtime.js +836 -0
- package/dist/senses/voice/twilio-phone.js +5454 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +83 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/dist/util/frontmatter.js +69 -0
- package/npm-shrinkwrap.json +8100 -0
- package/package.json +74 -13
- package/skills/agent-commerce.md +113 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -430
- package/dist/heart/daemon/ouro-path-installer.js +0 -260
- package/dist/heart/daemon/ouro-version-manager.js +0 -171
- package/dist/heart/daemon/update-hooks.js +0 -138
- package/dist/heart/obligations.js +0 -191
- package/dist/heart/safe-workspace.js +0 -362
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/friends/channel.js +0 -84
- package/dist/mind/friends/group-context.js +0 -144
- package/dist/mind/friends/resolver.js +0 -84
- package/dist/mind/friends/store-file.js +0 -190
- package/dist/mind/friends/store.js +0 -4
- package/dist/mind/friends/tokens.js +0 -26
- package/dist/mind/friends/trust-explanation.js +0 -74
- package/dist/mind/friends/types.js +0 -29
- package/dist/repertoire/tasks/board.js +0 -134
- package/dist/repertoire/tasks/index.js +0 -224
- package/dist/repertoire/tasks/lifecycle.js +0 -80
- package/dist/repertoire/tasks/middleware.js +0 -65
- package/dist/repertoire/tasks/parser.js +0 -173
- package/dist/repertoire/tasks/scanner.js +0 -132
- package/dist/repertoire/tasks/transitions.js +0 -144
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1181
- package/dist/senses/debug-activity.js +0 -154
- package/dist/senses/inner-dialog-worker.js +0 -90
- package/dist/senses/inner-dialog.js +0 -525
- package/subagents/README.md +0 -7
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /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
|
+
}
|