@ouro.bot/cli 0.1.0-alpha.88 → 0.1.0-alpha.880
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 +5601 -16
- package/deploy/unraid/Dockerfile +58 -0
- package/deploy/unraid/README.txt +2995 -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 +1197 -0
- package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
- package/deploy/unraid/sanctuary-replay-gate.mjs +1127 -0
- package/deploy/unraid/sanctuary-safe-rename.py +24 -0
- package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2085 -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 +27 -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 +29 -0
- package/dist/a2a/card.js +57 -0
- package/dist/a2a/client.js +238 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/delegated-command.js +151 -0
- package/dist/a2a/delegation-stores.js +56 -0
- package/dist/a2a/did-resolution.js +93 -0
- package/dist/a2a/escalation-grants.js +122 -0
- package/dist/a2a/escalation-wiring.js +60 -0
- package/dist/a2a/identity.js +204 -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/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-harness.js +175 -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 +766 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/transport.js +45 -0
- package/dist/a2a/trusted-files.js +98 -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 +382 -0
- package/dist/heart/background-operations.js +281 -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 +1157 -0
- package/dist/heart/core.js +2286 -580
- 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 +185 -3
- 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-defaults.js +854 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +8951 -0
- package/dist/heart/daemon/cli-help.js +716 -0
- package/dist/heart/daemon/cli-parse.js +2941 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +777 -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 +232 -0
- package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
- package/dist/heart/daemon/daemon-cli.js +29 -2349
- package/dist/heart/daemon/daemon-entry.js +932 -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 +1755 -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 +142 -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 +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/plugin-cli.js +432 -0
- package/dist/heart/daemon/process-manager.js +733 -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 +1310 -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 +699 -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 +499 -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 +335 -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 +196 -59
- package/dist/heart/kept-notes.js +289 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -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 +11 -0
- 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 +252 -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 +34 -38
- 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 +56 -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 +22 -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/source-grounding.js +194 -0
- package/dist/heart/start-of-turn-packet.js +372 -0
- package/dist/heart/steward-policy.js +656 -0
- package/dist/heart/streaming.js +604 -207
- package/dist/heart/structured-output.js +196 -0
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +505 -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 +487 -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 +1 -1
- 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 +409 -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/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/{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 +1048 -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 +1045 -0
- package/dist/repertoire/bundle-templates.js +71 -0
- package/dist/repertoire/bw-installer.js +180 -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 +58 -11
- package/dist/repertoire/coding/tools.js +221 -15
- 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 +178 -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 +873 -19
- package/dist/repertoire/house-sweep.js +466 -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/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 +870 -0
- package/dist/repertoire/tools-base.js +79 -1168
- package/dist/repertoire/tools-bluebubbles.js +2 -0
- package/dist/repertoire/tools-bridge.js +144 -0
- package/dist/repertoire/tools-bundle.js +993 -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-github.js +3 -8
- package/dist/repertoire/tools-habits.js +103 -0
- package/dist/repertoire/tools-house-care.js +138 -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-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.js +145 -0
- package/dist/repertoire/tools.js +509 -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 +628 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +926 -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 +131 -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} +355 -40
- 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-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
- package/dist/senses/bluebubbles/index.js +3841 -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 +228 -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 +1115 -204
- package/dist/senses/private-runtime-worker.js +859 -0
- package/dist/senses/private-runtime.js +1619 -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 +297 -0
- package/dist/senses/sanctuary-media-optimization.js +514 -0
- package/dist/senses/sanctuary-runtime.js +347 -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 +789 -0
- package/dist/senses/surface-tool.js +109 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +519 -218
- 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.js +2349 -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/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/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/realtime-eval.js +496 -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 +807 -0
- package/dist/senses/voice/twilio-phone.js +5031 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -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 +73 -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,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FileA2APinStore = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const node_crypto_1 = require("node:crypto");
|
|
40
|
+
const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
|
|
41
|
+
const runtime_1 = require("../nerves/runtime");
|
|
42
|
+
function pinFileName(fromAgentId) {
|
|
43
|
+
return `${(0, node_crypto_1.createHash)("sha256").update(fromAgentId).digest("hex")}.json`;
|
|
44
|
+
}
|
|
45
|
+
class FileA2APinStore {
|
|
46
|
+
dir;
|
|
47
|
+
cache = new Map();
|
|
48
|
+
constructor(agentRoot) {
|
|
49
|
+
this.dir = path.join(agentRoot, "state", "a2a", "pins");
|
|
50
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
51
|
+
this.loadExisting();
|
|
52
|
+
(0, runtime_1.emitNervesEvent)({
|
|
53
|
+
component: "channels",
|
|
54
|
+
event: "channel.a2a_pin_store_init",
|
|
55
|
+
message: "initialized durable A2A pin store",
|
|
56
|
+
meta: { dir: this.dir, pins: this.cache.size },
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
get size() {
|
|
60
|
+
return this.cache.size;
|
|
61
|
+
}
|
|
62
|
+
get(fromAgentId) {
|
|
63
|
+
if (!fromAgentId)
|
|
64
|
+
return undefined;
|
|
65
|
+
const pinned = this.cache.get(fromAgentId);
|
|
66
|
+
if (!pinned)
|
|
67
|
+
return undefined;
|
|
68
|
+
(0, runtime_1.emitNervesEvent)({
|
|
69
|
+
component: "channels",
|
|
70
|
+
event: "channel.a2a_pin_hit",
|
|
71
|
+
message: "A2A pin hit",
|
|
72
|
+
meta: { fromAgentId, did: pinned.did },
|
|
73
|
+
});
|
|
74
|
+
return pinned;
|
|
75
|
+
}
|
|
76
|
+
set(fromAgentId, pinned) {
|
|
77
|
+
// An empty-string DID is never a matchable key (security: it can never index a
|
|
78
|
+
// pin). Stay inert rather than writing an unkeyed pin file.
|
|
79
|
+
if (!fromAgentId)
|
|
80
|
+
return;
|
|
81
|
+
const existed = this.cache.has(fromAgentId);
|
|
82
|
+
// Faithfully persist the pinned identity's DID (which may differ from
|
|
83
|
+
// fromAgentId after a rotation), not fromAgentId itself.
|
|
84
|
+
const stored = {
|
|
85
|
+
fromAgentId,
|
|
86
|
+
did: pinned.did,
|
|
87
|
+
pinnedKey: (0, a2a_client_1.base58btcEncode)(pinned.ed25519Pub),
|
|
88
|
+
};
|
|
89
|
+
fs.writeFileSync(path.join(this.dir, pinFileName(fromAgentId)), `${JSON.stringify(stored, null, 2)}\n`, "utf-8");
|
|
90
|
+
this.cache.set(fromAgentId, { did: pinned.did, ed25519Pub: pinned.ed25519Pub });
|
|
91
|
+
(0, runtime_1.emitNervesEvent)({
|
|
92
|
+
component: "channels",
|
|
93
|
+
event: "channel.a2a_pin_set",
|
|
94
|
+
message: "set durable A2A pin",
|
|
95
|
+
meta: { fromAgentId, did: pinned.did, rotated: existed },
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** Reload every persisted pin from disk into the in-memory cache (the restart
|
|
99
|
+
* replay). Corrupt/undecodable files are skipped so one bad file can never
|
|
100
|
+
* wedge the store. */
|
|
101
|
+
loadExisting() {
|
|
102
|
+
let entries;
|
|
103
|
+
try {
|
|
104
|
+
entries = fs.readdirSync(this.dir);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
/* v8 ignore next -- the constructor mkdirSync's the dir before this runs; unreadable dir is unreachable in practice @preserve */
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
for (const name of entries) {
|
|
111
|
+
if (!name.endsWith(".json"))
|
|
112
|
+
continue;
|
|
113
|
+
let stored;
|
|
114
|
+
try {
|
|
115
|
+
stored = JSON.parse(fs.readFileSync(path.join(this.dir, name), "utf-8"));
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// `fromAgentId` is the cache key; fall back to `did` for any pre-rotation
|
|
121
|
+
// file written before the key/did split (back-compat).
|
|
122
|
+
const key = stored.fromAgentId ?? stored.did;
|
|
123
|
+
if (!key || !stored.did || !stored.pinnedKey)
|
|
124
|
+
continue;
|
|
125
|
+
const ed25519Pub = (0, a2a_client_1.base58btcDecode)(stored.pinnedKey);
|
|
126
|
+
if (!ed25519Pub)
|
|
127
|
+
continue;
|
|
128
|
+
this.cache.set(key, { did: stored.did, ed25519Pub });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.FileA2APinStore = FileA2APinStore;
|
|
@@ -0,0 +1,175 @@
|
|
|
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.REPLAY_WINDOW_MAX_MS = void 0;
|
|
37
|
+
exports.replayWindowPath = replayWindowPath;
|
|
38
|
+
exports.replaySinkPath = replaySinkPath;
|
|
39
|
+
exports.replayIdentitiesPath = replayIdentitiesPath;
|
|
40
|
+
exports.isReplayIdentity = isReplayIdentity;
|
|
41
|
+
exports.isReplayWindowOpen = isReplayWindowOpen;
|
|
42
|
+
exports.appendReplayNotice = appendReplayNotice;
|
|
43
|
+
exports.replayNoticeRecorded = replayNoticeRecorded;
|
|
44
|
+
const fs = __importStar(require("node:fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const runtime_1 = require("../nerves/runtime");
|
|
47
|
+
/**
|
|
48
|
+
* The replay gate drives the Butler over its real A2A path to check its behaviour after an upgrade. Every delegated
|
|
49
|
+
* command and every A2A-filed await would otherwise post to the owner's Telegram chat. While the host's gate holds a
|
|
50
|
+
* replay window open for a peer, those notices are appended to a local sink instead.
|
|
51
|
+
*
|
|
52
|
+
* The window narrows where a notice goes, never whether a command is authorized: the grant, family trust, sole owner
|
|
53
|
+
* and notify-before-run checks are unchanged, and "notify" means "the sink write succeeded". The window file lives
|
|
54
|
+
* under the bundle's state directory, is written by the host's gate and cleared when its run ends, and every entry
|
|
55
|
+
* expires on its own (and is ignored if it claims to last longer than the cap).
|
|
56
|
+
*/
|
|
57
|
+
exports.REPLAY_WINDOW_MAX_MS = 2 * 60 * 60 * 1000;
|
|
58
|
+
function replayDir(agentRoot) {
|
|
59
|
+
return path.join(agentRoot, "state", "replay");
|
|
60
|
+
}
|
|
61
|
+
function replayWindowPath(agentRoot) {
|
|
62
|
+
return path.join(replayDir(agentRoot), "window.json");
|
|
63
|
+
}
|
|
64
|
+
function replaySinkPath(agentRoot) {
|
|
65
|
+
return path.join(replayDir(agentRoot), "notices.ndjson");
|
|
66
|
+
}
|
|
67
|
+
/** Permanent registry of replay identities, written by the host's provisioning and never cleared. */
|
|
68
|
+
function replayIdentitiesPath(agentRoot) {
|
|
69
|
+
return path.join(replayDir(agentRoot), "identities.json");
|
|
70
|
+
}
|
|
71
|
+
function listsFriend(file, friendId) {
|
|
72
|
+
let parsed;
|
|
73
|
+
try {
|
|
74
|
+
parsed = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// A missing file lists nobody; a file that exists but cannot be read or parsed fails closed.
|
|
78
|
+
return error.code !== "ENOENT";
|
|
79
|
+
}
|
|
80
|
+
const friends = parsed?.friends;
|
|
81
|
+
return !!friends && typeof friends === "object" && Object.hasOwn(friends, friendId);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* True when `friendId` is a replay identity: listed in the permanent registry, or holding any window entry (open or
|
|
85
|
+
* expired). Unlike the window check this needs no trusted-owner proof, because the marker only ever restricts: forging
|
|
86
|
+
* an entry can block a friend from writing owner policy, never grant anything. Owner policy writes refuse these identities.
|
|
87
|
+
*/
|
|
88
|
+
function isReplayIdentity(agentRoot, friendId) {
|
|
89
|
+
return listsFriend(replayIdentitiesPath(agentRoot), friendId) || listsFriend(replayWindowPath(agentRoot), friendId);
|
|
90
|
+
}
|
|
91
|
+
/** A root-controlled directory: a real directory (no symlink), owned by the trusted uid, writable by neither group nor other. */
|
|
92
|
+
function isTrustedDirectory(target, trustedUid) {
|
|
93
|
+
try {
|
|
94
|
+
const stat = fs.lstatSync(target);
|
|
95
|
+
return stat.isDirectory() && !stat.isSymbolicLink() && stat.uid === trustedUid && (stat.mode & 0o022) === 0;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Reads the window file only if the file actually opened is trusted. The path is opened once with O_NOFOLLOW, then the
|
|
103
|
+
* descriptor itself is checked (regular file, trusted owner, not group- or other-writable) and read, so a rename loop on
|
|
104
|
+
* the Butler's own state directory cannot swap a different file in between the check and the read. Any error is "no window".
|
|
105
|
+
*/
|
|
106
|
+
function readTrustedWindow(file, trustedUid) {
|
|
107
|
+
let fd;
|
|
108
|
+
try {
|
|
109
|
+
fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
110
|
+
const stat = fs.fstatSync(fd);
|
|
111
|
+
if (!stat.isFile() || stat.uid !== trustedUid || (stat.mode & 0o022) !== 0)
|
|
112
|
+
return undefined;
|
|
113
|
+
return JSON.parse(fs.readFileSync(fd, "utf8"));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
if (fd !== undefined)
|
|
120
|
+
fs.closeSync(fd);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* True only when the window file lists `friendId` with an expiry that is in the future and within the cap. Any unreadable or malformed file means "closed".
|
|
125
|
+
* The state directory is the Butler's own, so it could swap in a directory and window of its own making: only a replay
|
|
126
|
+
* directory and window file that root owns, and nobody else can write, count; anything else fails toward Telegram.
|
|
127
|
+
*/
|
|
128
|
+
function isReplayWindowOpen(agentRoot, friendId, now = Date.now(), trustedUid = 0) {
|
|
129
|
+
if (!isTrustedDirectory(replayDir(agentRoot), trustedUid))
|
|
130
|
+
return false;
|
|
131
|
+
const parsed = readTrustedWindow(replayWindowPath(agentRoot), trustedUid);
|
|
132
|
+
const friends = parsed?.friends;
|
|
133
|
+
if (!friends || typeof friends !== "object")
|
|
134
|
+
return false;
|
|
135
|
+
const entry = friends[friendId];
|
|
136
|
+
const expiresAt = typeof entry?.expiresAt === "string"
|
|
137
|
+
? Date.parse(entry.expiresAt)
|
|
138
|
+
: Number.NaN;
|
|
139
|
+
return Number.isFinite(expiresAt) && expiresAt > now && expiresAt <= now + exports.REPLAY_WINDOW_MAX_MS;
|
|
140
|
+
}
|
|
141
|
+
/** Appends one notice to the sink, once per notice id and friend (a retry after a crash adds nothing); throws when it cannot be written, so the caller refuses exactly as a failed Telegram send does. */
|
|
142
|
+
function appendReplayNotice(agentRoot, notice, now = Date.now()) {
|
|
143
|
+
if (replayNoticeRecorded(agentRoot, notice.noticeId, notice.friendId))
|
|
144
|
+
return;
|
|
145
|
+
fs.mkdirSync(replayDir(agentRoot), { recursive: true });
|
|
146
|
+
const line = JSON.stringify({ at: new Date(now).toISOString(), ...notice });
|
|
147
|
+
fs.appendFileSync(replaySinkPath(agentRoot), `${line}\n`, { mode: 0o600 });
|
|
148
|
+
(0, runtime_1.emitNervesEvent)({
|
|
149
|
+
component: "senses",
|
|
150
|
+
event: "senses.a2a_replay_notice_sunk",
|
|
151
|
+
message: "wrote an owner notice to the replay sink instead of Telegram",
|
|
152
|
+
meta: { noticeId: notice.noticeId, friendId: notice.friendId },
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/** True when the sink holds a notice with this id for this friend (a missing sink is "no"). The sink is Butler-writable: callers must also require a trusted window. */
|
|
156
|
+
function replayNoticeRecorded(agentRoot, noticeId, friendId) {
|
|
157
|
+
let raw;
|
|
158
|
+
try {
|
|
159
|
+
raw = fs.readFileSync(replaySinkPath(agentRoot), "utf8");
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return raw.split("\n").some((line) => {
|
|
165
|
+
if (!line)
|
|
166
|
+
return false;
|
|
167
|
+
try {
|
|
168
|
+
const entry = JSON.parse(line);
|
|
169
|
+
return entry.noticeId === noticeId && entry.friendId === friendId;
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.signResolution = signResolution;
|
|
4
|
+
exports.friendDid = friendDid;
|
|
5
|
+
exports.verifyResolution = verifyResolution;
|
|
6
|
+
const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
|
|
7
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
8
|
+
const runtime_1 = require("../nerves/runtime");
|
|
9
|
+
/**
|
|
10
|
+
* The proof that an escalation holder, and nobody who can write the Butler's files, said a failure report is fixed.
|
|
11
|
+
* The holder signs `{reportId, version, note, resolvedAt}` with its DID key (canonical JSON, detached Ed25519), and
|
|
12
|
+
* the Butler keeps the signature next to the resolution. The holder's private key never leaves the holder's machine,
|
|
13
|
+
* so a forged report file cannot carry a valid one.
|
|
14
|
+
*/
|
|
15
|
+
const PURPOSE = "ouro.report-resolve.v1";
|
|
16
|
+
function envelopeOf(claim) {
|
|
17
|
+
return { purpose: PURPOSE, reportId: claim.reportId, version: claim.version, note: claim.note, resolvedAt: claim.resolvedAt };
|
|
18
|
+
}
|
|
19
|
+
function signResolution(input) {
|
|
20
|
+
const { claim } = input;
|
|
21
|
+
return (0, a2a_client_1.signEnvelope)({
|
|
22
|
+
sodium: input.sodium,
|
|
23
|
+
envelope: envelopeOf(claim),
|
|
24
|
+
signerEd25519Priv: input.identity.ed25519Priv,
|
|
25
|
+
signerDid: input.identity.did,
|
|
26
|
+
signerKeyId: input.identity.keyId,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** The DID a friend record names. Used only by the operator command that pins it into the grant; never to verify a resolution. */
|
|
30
|
+
function friendDid(friend) {
|
|
31
|
+
return (0, friends_1.resolveAgentIdentity)(friend.agentMeta).did ?? null;
|
|
32
|
+
}
|
|
33
|
+
function verifyResolution(input) {
|
|
34
|
+
const fail = (reason) => {
|
|
35
|
+
(0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_resolution_proof_rejected", message: "rejected a report resolution without a valid holder signature", meta: { reportId: input.claim.reportId, reason } });
|
|
36
|
+
return { ok: false, reason };
|
|
37
|
+
};
|
|
38
|
+
const proof = input.proof;
|
|
39
|
+
if (!proof || typeof proof !== "object" || Array.isArray(proof))
|
|
40
|
+
return fail("no_proof");
|
|
41
|
+
if (!input.holderDid)
|
|
42
|
+
return fail("no_holder_did");
|
|
43
|
+
const parsed = (0, a2a_client_1.parseDidKey)(input.holderDid);
|
|
44
|
+
if (!parsed || proof.signerDid !== input.holderDid)
|
|
45
|
+
return fail("wrong_signer");
|
|
46
|
+
const valid = (0, a2a_client_1.verifyEnvelopeSignature)({
|
|
47
|
+
sodium: input.sodium,
|
|
48
|
+
envelope: envelopeOf(input.claim),
|
|
49
|
+
proof: proof,
|
|
50
|
+
signerEd25519Pub: parsed.ed25519Pub,
|
|
51
|
+
});
|
|
52
|
+
return valid ? { ok: true } : fail("bad_signature");
|
|
53
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EMPTY_CHAT_REPLY = void 0;
|
|
4
|
+
exports.sealChatMessage = sealChatMessage;
|
|
5
|
+
exports.openChatMessage = openChatMessage;
|
|
6
|
+
/**
|
|
7
|
+
* Sealed agent-to-agent chat over A2A (friends `message` kind).
|
|
8
|
+
*
|
|
9
|
+
* Both directions use the same primitive: the text is signed by the sender and
|
|
10
|
+
* sealed to the recipient inside ONE friends DataPart, so a message is confidential
|
|
11
|
+
* and tamper-evident over any transport (tailnet, LAN, relay). The network is a
|
|
12
|
+
* pipe, not the lock.
|
|
13
|
+
*
|
|
14
|
+
* - `sealChatMessage` builds the single-DataPart A2A message for a recipient whose
|
|
15
|
+
* Ed25519 key the sender already trusts (a pinned DID, or a did:key card).
|
|
16
|
+
* - `openChatMessage` opens one through the SAME `receiveShare` pipeline every
|
|
17
|
+
* friends kind uses (unseal, sender binding, pinned-key signature, replay guard,
|
|
18
|
+
* trust floor), pinned to the sender the opener expects. There is no second,
|
|
19
|
+
* hand-rolled verification path.
|
|
20
|
+
*/
|
|
21
|
+
const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
|
|
22
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
23
|
+
const runtime_1 = require("../nerves/runtime");
|
|
24
|
+
/** What an agent replies when its turn produced no text; sealed like any reply. */
|
|
25
|
+
exports.EMPTY_CHAT_REPLY = "(no reply)";
|
|
26
|
+
/** Seal `text` from `from` to the recipient as a single friends DataPart. Returns
|
|
27
|
+
* the harness-shaped A2A message; callers add role/messageId/contextId. */
|
|
28
|
+
function sealChatMessage(input) {
|
|
29
|
+
const text = input.text.trim() === "" ? exports.EMPTY_CHAT_REPLY : input.text.slice(0, friends_1.MAX_MESSAGE_TEXT_CHARS);
|
|
30
|
+
const prepared = (0, friends_1.prepareMessage)({
|
|
31
|
+
fromAgentId: input.from.did,
|
|
32
|
+
text,
|
|
33
|
+
...(input.conversationId !== undefined ? { conversationId: input.conversationId } : {}),
|
|
34
|
+
...(input.onBehalfOf ? { onBehalfOf: input.onBehalfOf } : {}),
|
|
35
|
+
});
|
|
36
|
+
/* v8 ignore next -- the text is normalized above and the sender DID comes from a real identity @preserve */
|
|
37
|
+
if (!prepared.ok)
|
|
38
|
+
throw new Error(`cannot prepare chat message: ${prepared.status}`);
|
|
39
|
+
const sealed = (0, a2a_client_1.sealEnvelope)({
|
|
40
|
+
sodium: input.sodium,
|
|
41
|
+
envelope: prepared.envelope,
|
|
42
|
+
friendsKind: "message",
|
|
43
|
+
fromIdentity: input.from,
|
|
44
|
+
recipientDid: input.recipientDid,
|
|
45
|
+
recipientX25519Pub: (0, a2a_client_1.keyAgreementFromDidKey)({ sodium: input.sodium, ed25519Pub: input.recipientEd25519Pub }),
|
|
46
|
+
});
|
|
47
|
+
const wrapped = (0, a2a_client_1.wrapInDataPart)({ sealedEnvelope: sealed, recipientDid: input.recipientDid });
|
|
48
|
+
(0, runtime_1.emitNervesEvent)({
|
|
49
|
+
component: "channels",
|
|
50
|
+
event: "channel.a2a_chat_sealed",
|
|
51
|
+
message: "sealed an A2A chat message",
|
|
52
|
+
meta: { recipientDid: input.recipientDid, chars: text.length },
|
|
53
|
+
});
|
|
54
|
+
return { parts: wrapped.parts };
|
|
55
|
+
}
|
|
56
|
+
class MemorySeenLedger {
|
|
57
|
+
seen = new Set();
|
|
58
|
+
isSeen(nonce) { return this.seen.has(nonce); }
|
|
59
|
+
markSeen(nonce) { this.seen.add(nonce); }
|
|
60
|
+
}
|
|
61
|
+
/** A `message` receipt imports nothing, so the stores must never be reached. */
|
|
62
|
+
function unreachableStore(name) {
|
|
63
|
+
return new Proxy({}, { get() { throw new Error(`sealed chat must not touch the ${name}`); } });
|
|
64
|
+
}
|
|
65
|
+
/** Open a sealed chat message from an expected sender through `receiveShare`. */
|
|
66
|
+
async function openChatMessage(input) {
|
|
67
|
+
const pinStore = new a2a_client_1.MemoryPinStore();
|
|
68
|
+
(0, a2a_client_1.pinOnFirstContact)({ pinStore, fromAgentId: input.senderDid, did: input.senderDid, ed25519Pub: input.senderEd25519Pub });
|
|
69
|
+
const result = await (0, a2a_client_1.receiveShare)({
|
|
70
|
+
sodium: input.sodium,
|
|
71
|
+
store: unreachableStore("friend store"),
|
|
72
|
+
missionStore: unreachableStore("mission store"),
|
|
73
|
+
pinStore,
|
|
74
|
+
// Only the pre-pinned sender can verify: any other signer resolves to nothing.
|
|
75
|
+
didResolution: {
|
|
76
|
+
async resolveAndPin({ fromAgentId }) {
|
|
77
|
+
const pinned = pinStore.get(fromAgentId);
|
|
78
|
+
return pinned ? { ed25519Pub: pinned.ed25519Pub } : null;
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
seen: new MemorySeenLedger(),
|
|
82
|
+
a2aMessage: input.message,
|
|
83
|
+
recipientDid: input.self.did,
|
|
84
|
+
recipientIdentity: { x25519Priv: input.self.x25519Priv, x25519Pub: input.self.x25519Pub },
|
|
85
|
+
// The opener chose this sender; the signature, not this level, is the gate.
|
|
86
|
+
trustOfSource: "family",
|
|
87
|
+
});
|
|
88
|
+
if (result.state === "rejected") {
|
|
89
|
+
(0, runtime_1.emitNervesEvent)({
|
|
90
|
+
level: "warn",
|
|
91
|
+
component: "channels",
|
|
92
|
+
event: "channel.a2a_chat_open_rejected",
|
|
93
|
+
message: "refused a sealed A2A chat message",
|
|
94
|
+
meta: { senderDid: input.senderDid, reason: result.reason },
|
|
95
|
+
});
|
|
96
|
+
return { ok: false, reason: result.reason };
|
|
97
|
+
}
|
|
98
|
+
/* v8 ignore next -- any other kind reaches a store, and these stores throw: only a message can complete here @preserve */
|
|
99
|
+
if (result.friendsKind !== "message" || !result.message)
|
|
100
|
+
return { ok: false, reason: "not_a_message" };
|
|
101
|
+
(0, runtime_1.emitNervesEvent)({
|
|
102
|
+
component: "channels",
|
|
103
|
+
event: "channel.a2a_chat_opened",
|
|
104
|
+
message: "opened a verified A2A chat message",
|
|
105
|
+
meta: { senderDid: input.senderDid, chars: result.message.text.length },
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
ok: true,
|
|
109
|
+
text: result.message.text,
|
|
110
|
+
...(result.message.conversationId !== undefined ? { conversationId: result.message.conversationId } : {}),
|
|
111
|
+
issuedAt: result.message.issuedAt,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FileA2ASeenLedger = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const node_crypto_1 = require("node:crypto");
|
|
40
|
+
const runtime_1 = require("../nerves/runtime");
|
|
41
|
+
function nonceFileName(nonce) {
|
|
42
|
+
return `${(0, node_crypto_1.createHash)("sha256").update(nonce).digest("hex")}.json`;
|
|
43
|
+
}
|
|
44
|
+
class FileA2ASeenLedger {
|
|
45
|
+
dir;
|
|
46
|
+
cache = new Set();
|
|
47
|
+
constructor(agentRoot) {
|
|
48
|
+
this.dir = path.join(agentRoot, "state", "a2a", "seen");
|
|
49
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
50
|
+
this.loadExisting();
|
|
51
|
+
(0, runtime_1.emitNervesEvent)({
|
|
52
|
+
component: "channels",
|
|
53
|
+
event: "channel.a2a_seen_ledger_init",
|
|
54
|
+
message: "initialized durable A2A seen ledger",
|
|
55
|
+
meta: { dir: this.dir, seen: this.cache.size },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
get size() {
|
|
59
|
+
return this.cache.size;
|
|
60
|
+
}
|
|
61
|
+
isSeen(nonce) {
|
|
62
|
+
if (!nonce)
|
|
63
|
+
return false;
|
|
64
|
+
const seen = this.cache.has(nonce);
|
|
65
|
+
if (seen) {
|
|
66
|
+
// A nonce we already processed is arriving again — for a seal nonce this is
|
|
67
|
+
// a replay. Loud security signal.
|
|
68
|
+
(0, runtime_1.emitNervesEvent)({
|
|
69
|
+
component: "channels",
|
|
70
|
+
event: "channel.a2a_replay_rejected",
|
|
71
|
+
message: "A2A replay rejected (nonce already seen)",
|
|
72
|
+
meta: { nonceHash: nonceFileName(nonce).slice(0, 16) },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return seen;
|
|
76
|
+
}
|
|
77
|
+
markSeen(nonce) {
|
|
78
|
+
// An empty-string nonce is never a matchable key — stay inert.
|
|
79
|
+
if (!nonce)
|
|
80
|
+
return;
|
|
81
|
+
if (this.cache.has(nonce))
|
|
82
|
+
return;
|
|
83
|
+
fs.writeFileSync(path.join(this.dir, nonceFileName(nonce)), `${JSON.stringify({ nonce, markedAt: new Date().toISOString() }, null, 2)}\n`, "utf-8");
|
|
84
|
+
this.cache.add(nonce);
|
|
85
|
+
(0, runtime_1.emitNervesEvent)({
|
|
86
|
+
component: "channels",
|
|
87
|
+
event: "channel.a2a_seen_marked",
|
|
88
|
+
message: "marked A2A seal nonce as seen (first sight)",
|
|
89
|
+
meta: { nonceHash: nonceFileName(nonce).slice(0, 16) },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Reload every persisted nonce from disk into the in-memory set (the restart
|
|
93
|
+
* replay defense). Corrupt/unreadable artifacts are skipped so one bad file can
|
|
94
|
+
* never reopen the replay window for the rest. */
|
|
95
|
+
loadExisting() {
|
|
96
|
+
let entries;
|
|
97
|
+
try {
|
|
98
|
+
entries = fs.readdirSync(this.dir);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* v8 ignore next -- the constructor mkdirSync's the dir before this runs; unreadable dir is unreachable in practice @preserve */
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
for (const name of entries) {
|
|
105
|
+
if (!name.endsWith(".json"))
|
|
106
|
+
continue;
|
|
107
|
+
let record;
|
|
108
|
+
try {
|
|
109
|
+
record = JSON.parse(fs.readFileSync(path.join(this.dir, name), "utf-8"));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (typeof record.nonce === "string" && record.nonce.length > 0) {
|
|
115
|
+
this.cache.add(record.nonce);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.FileA2ASeenLedger = FileA2ASeenLedger;
|