@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,69 @@
|
|
|
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.FileA2ATaskStore = 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 taskFileName(taskId, ownerScope) {
|
|
42
|
+
return `${(0, node_crypto_1.createHash)("sha256").update(`${ownerScope}\n${taskId}`).digest("hex")}.json`;
|
|
43
|
+
}
|
|
44
|
+
class FileA2ATaskStore {
|
|
45
|
+
dir;
|
|
46
|
+
constructor(agentRoot) {
|
|
47
|
+
this.dir = path.join(agentRoot, "state", "a2a", "tasks");
|
|
48
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
49
|
+
(0, runtime_1.emitNervesEvent)({
|
|
50
|
+
component: "channels",
|
|
51
|
+
event: "channel.a2a_task_store_init",
|
|
52
|
+
message: "initialized A2A task store",
|
|
53
|
+
meta: { dir: this.dir },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
put(task, ownerScope = "legacy") {
|
|
57
|
+
fs.writeFileSync(path.join(this.dir, taskFileName(task.id, ownerScope)), `${JSON.stringify(task, null, 2)}\n`, "utf-8");
|
|
58
|
+
}
|
|
59
|
+
get(taskId, ownerScope = "legacy") {
|
|
60
|
+
try {
|
|
61
|
+
const raw = fs.readFileSync(path.join(this.dir, taskFileName(taskId, ownerScope)), "utf-8");
|
|
62
|
+
return JSON.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.FileA2ATaskStore = FileA2ATaskStore;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeA2ATransport = makeA2ATransport;
|
|
4
|
+
const runtime_1 = require("../nerves/runtime");
|
|
5
|
+
const client_1 = require("./client");
|
|
6
|
+
/** The not-wired marker for the relay/mailbox rungs (the stubbed seam). */
|
|
7
|
+
const RELAY_NOT_WIRED = "A2A relay/mailbox transport is not wired — see ourostack/friends-relay";
|
|
8
|
+
/**
|
|
9
|
+
* Build the harness `A2ATransport` (the outbound delivery seam friends' `sendShare`
|
|
10
|
+
* calls). Only the `direct` rung is wired in this slice: it HTTP-POSTs the sealed,
|
|
11
|
+
* `wrapInDataPart`-wrapped message to the peer's `endpointUrl` (the `address`) as a
|
|
12
|
+
* JSON-RPC `message/send`, reusing the harness `client.ts` plumbing. The `relay` and
|
|
13
|
+
* `mailbox` rungs are a TYPED-but-STUBBED seam: they throw a clear not-wired error
|
|
14
|
+
* naming the `ourostack/friends-relay` dependency, so a future relay slice has an
|
|
15
|
+
* exact insertion point without this slice shipping an untrusted relay.
|
|
16
|
+
*/
|
|
17
|
+
function makeA2ATransport(input = {}) {
|
|
18
|
+
return {
|
|
19
|
+
async send(target, message) {
|
|
20
|
+
if (target.rung === "direct") {
|
|
21
|
+
(0, runtime_1.emitNervesEvent)({
|
|
22
|
+
component: "channels",
|
|
23
|
+
event: "channel.a2a_transport_direct_send",
|
|
24
|
+
message: "delivering sealed A2A message over the direct rung",
|
|
25
|
+
meta: { address: target.address },
|
|
26
|
+
});
|
|
27
|
+
await (0, client_1.postA2AMessageEnvelope)({
|
|
28
|
+
endpointUrl: target.address,
|
|
29
|
+
message,
|
|
30
|
+
...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}),
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// relay / mailbox: the typed-but-stubbed seam. Loud refusal (security-relevant:
|
|
35
|
+
// we never silently fall through to an untrusted relay).
|
|
36
|
+
(0, runtime_1.emitNervesEvent)({
|
|
37
|
+
component: "channels",
|
|
38
|
+
event: "channel.a2a_transport_not_wired",
|
|
39
|
+
message: "refused A2A transport over a non-direct rung (not wired)",
|
|
40
|
+
meta: { rung: target.rung, address: target.address, dependency: "ourostack/friends-relay" },
|
|
41
|
+
});
|
|
42
|
+
throw new Error(`${RELAY_NOT_WIRED} (rung: ${target.rung})`);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeDelegatedCommandsCommand = executeDelegatedCommandsCommand;
|
|
4
|
+
exports.executeEscalationCommand = executeEscalationCommand;
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
const delegated_command_grants_1 = require("./delegated-command-grants");
|
|
7
|
+
const escalation_grants_1 = require("./escalation-grants");
|
|
8
|
+
const replay_grant_holders_1 = require("./replay-grant-holders");
|
|
9
|
+
const operator_trust_1 = require("./operator-trust");
|
|
10
|
+
const resolution_proof_1 = require("./resolution-proof");
|
|
11
|
+
const NEEDS_ROOT = "refusing: this command writes root-owned files the agent cannot forge, so it must run as root on the agent's host (for example docker exec as root, or sudo). Nothing was written.";
|
|
12
|
+
function requireRoot(ctx) {
|
|
13
|
+
if (!ctx.isRoot)
|
|
14
|
+
throw new Error(NEEDS_ROOT);
|
|
15
|
+
}
|
|
16
|
+
async function requireFriend(ctx, friendId) {
|
|
17
|
+
const friend = await ctx.store.get(friendId);
|
|
18
|
+
if (!friend)
|
|
19
|
+
throw new Error(`friend not found: ${friendId}`);
|
|
20
|
+
return friend;
|
|
21
|
+
}
|
|
22
|
+
/** The --did rules shared by both grant commands. Returns the DID to pin (equal to the record's). */
|
|
23
|
+
function checkedDid(friend, did) {
|
|
24
|
+
if (!did || !did.startsWith("did:"))
|
|
25
|
+
throw new Error(`refusing: --did ${did ?? "(missing)"} is not a DID (it starts with did:). Copy it from the sender's own host with: ouro a2a identity --json. Nothing was written.`);
|
|
26
|
+
const recorded = (0, resolution_proof_1.friendDid)(friend);
|
|
27
|
+
if (!recorded)
|
|
28
|
+
throw new Error(`refusing: ${friend.name} has no DID on record, so there is nothing to check --did against. Onboard it with its DID first (ouro a2a onboard --did <did> --name "${friend.name}"). Nothing was written.`);
|
|
29
|
+
if (recorded !== did)
|
|
30
|
+
throw new Error(`refusing: --did ${did} does not match the DID on ${friend.name}'s record (${recorded}). If the sender's key really changed, onboard it again; otherwise you copied the wrong DID. Nothing was written.`);
|
|
31
|
+
return did;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The checks both grant commands share before they pin a DID. It may not be this agent's own, and it may not already be pinned by
|
|
35
|
+
* another holder's grant in the same file. When this agent's own DID cannot be read (a one-off root container has no vault) the
|
|
36
|
+
* own-DID check cannot run, so the command instead refuses any DID that a second friend record also carries (a sender's key is on
|
|
37
|
+
* exactly one record), and says so in its output.
|
|
38
|
+
*/
|
|
39
|
+
async function vetPinnedDid(ctx, friend, did, held) {
|
|
40
|
+
const own = await ctx.ownDid();
|
|
41
|
+
if (own === did)
|
|
42
|
+
throw new Error("refusing: that is this agent's own DID. A grant must pin the sender's key, not this agent's. Nothing was written.");
|
|
43
|
+
const holder = Object.entries(held).find(([id, existing]) => id !== friend.id && existing.did === did);
|
|
44
|
+
if (holder)
|
|
45
|
+
throw new Error(`refusing: that DID is already pinned by ${holder[0]}'s grant. Revoke it first if the sender really moved to a different friend record. Nothing was written.`);
|
|
46
|
+
if (own !== null)
|
|
47
|
+
return [];
|
|
48
|
+
// The own DID is not available from the machine config here. A DID the agent published in its bundle is only a hint (the agent can write
|
|
49
|
+
// that file), so the friend-record comparison always runs as well, and the published value is reported with its source.
|
|
50
|
+
const published = await ctx.publishedDid?.() ?? null;
|
|
51
|
+
const records = await ctx.store.listAll?.() ?? [];
|
|
52
|
+
const twin = records.find((record) => record.id !== friend.id && (0, resolution_proof_1.friendDid)(record) === did);
|
|
53
|
+
if (twin)
|
|
54
|
+
throw new Error(`refusing: this agent's own DID could not be read from its machine config here, and another friend record (${twin.name}, ${twin.id}) carries that same DID, so it may be this agent's own key. Check it with: ouro a2a identity --agent ${ctx.agentName} --json. Nothing was written.`);
|
|
55
|
+
const notes = ["note: could not read this agent's own DID from its machine config here, so the own-DID check was skipped; compared --did with every DID in the friend records instead, and no other record carries it"];
|
|
56
|
+
if (published === did)
|
|
57
|
+
notes.push("warning: --did equals the DID published in the agent's bundle (source: bundle-published, which the agent itself can write, so this is advisory). Granting it would pin the agent's own key; check with ouro a2a identity --agent " + ctx.agentName + " --json before relying on this grant");
|
|
58
|
+
else if (published !== null)
|
|
59
|
+
notes.push(`note: the DID published in the agent's bundle (source: bundle-published, advisory) is ${published}, which differs from --did`);
|
|
60
|
+
return notes;
|
|
61
|
+
}
|
|
62
|
+
function notActiveFamilyNote(friend, what) {
|
|
63
|
+
return friend.trustLevel === "family" && friend.admissionState === "active"
|
|
64
|
+
? []
|
|
65
|
+
: [`note: ${friend.name} is ${friend.trustLevel}, ${friend.admissionState}, so the grant stays suspended until it is active family${what}`];
|
|
66
|
+
}
|
|
67
|
+
function parseExpiry(expires, now) {
|
|
68
|
+
if (expires === undefined)
|
|
69
|
+
return undefined;
|
|
70
|
+
const at = Date.parse(expires);
|
|
71
|
+
if (!Number.isFinite(at) || at <= now.getTime())
|
|
72
|
+
throw new Error(`refusing: --expires ${expires} is not a time in the future (use an ISO date such as 2027-01-01T00:00:00Z). Nothing was written.`);
|
|
73
|
+
return new Date(at).toISOString();
|
|
74
|
+
}
|
|
75
|
+
async function executeDelegatedCommandsCommand(command, ctx) {
|
|
76
|
+
if (command.action === "list")
|
|
77
|
+
return listDelegatedCommands(ctx, command.json === true);
|
|
78
|
+
requireRoot(ctx);
|
|
79
|
+
if (command.action === "revoke")
|
|
80
|
+
return revokeDelegatedCommands(command.friendId, ctx);
|
|
81
|
+
const expiresAt = parseExpiry(command.expires, ctx.now);
|
|
82
|
+
const friend = await requireFriend(ctx, command.friendId);
|
|
83
|
+
if (expiresAt === undefined && (0, replay_grant_holders_1.isReplayGrantHolder)(ctx.agentRoot, friend.id))
|
|
84
|
+
throw new Error(`refusing: ${friend.name} is a replay peer (it is on the replay gate's list in ${(0, operator_trust_1.operatorTrustDir)(ctx.agentRoot)}), or that list is present but not trustworthy, and a replay peer's grant must expire. Pass --expires <ISO date>. Nothing was written.`);
|
|
85
|
+
const did = checkedDid(friend, command.did);
|
|
86
|
+
const selfNotes = await vetPinnedDid(ctx, friend, did, (0, delegated_command_grants_1.readDelegatedCommandGrants)(ctx.agentRoot));
|
|
87
|
+
const change = (0, delegated_command_grants_1.setDelegatedCommandGrant)(ctx.agentRoot, friend.id, { grant: true, did, source: command.source ?? `ouro a2a delegated-commands grant, ${ctx.now.toISOString()}`, ...(expiresAt ? { expiresAt } : {}) }, ctx.now);
|
|
88
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.a2a_trust_grant_changed", message: "operator changed a trust grant", meta: { action: "grant", scope: "delegated_commands" } });
|
|
89
|
+
return [
|
|
90
|
+
`granted delegated commands: ${friend.name} (${friend.id})${change.changed ? "" : " (no change)"}`,
|
|
91
|
+
`pinned DID: ${did}`,
|
|
92
|
+
`expires: ${expiresAt ?? "never"}`,
|
|
93
|
+
`trust directory: ${(0, operator_trust_1.operatorTrustDir)(ctx.agentRoot)}`,
|
|
94
|
+
...(change.backup ? [`backup: ${change.backup}`] : []),
|
|
95
|
+
...selfNotes,
|
|
96
|
+
...((0, delegated_command_grants_1.readDelegatedCommandGrants)(ctx.agentRoot)[friend.id] === undefined ? [`WARNING: the grant is written but will not be honoured: ${(0, delegated_command_grants_1.delegatedCommandGrantsPath)(ctx.agentRoot)} and every directory above it must be owned by root and writable by no one else. Run \`ouro a2a delegated-commands list\` for what the harness sees.`] : []),
|
|
97
|
+
...notActiveFamilyNote(friend, ""),
|
|
98
|
+
].join("\n");
|
|
99
|
+
}
|
|
100
|
+
/** The follow-up that clears the legacy record field as the resident user: the record is the Butler's own file, and this command runs as root, so it never writes it. */
|
|
101
|
+
function clearLegacyGrantCommand(agentRoot, friendId) {
|
|
102
|
+
const file = `${agentRoot}/friends/${friendId}.json`;
|
|
103
|
+
const script = `const fs=require("fs");const f=${JSON.stringify(file)};const r=JSON.parse(fs.readFileSync(f,"utf8"));delete r.delegationGrant;fs.writeFileSync(f,JSON.stringify(r,null,2)+"\\n")`;
|
|
104
|
+
return [
|
|
105
|
+
"REQUIRED FOLLOW-UP: the trusted grant is removed, but the legacy delegationGrant on the friend record is still there (friend records are never written as root). An older harness would honour it after a rollback. Clear it as the resident user:",
|
|
106
|
+
` docker exec -u 10001 ouro-butler node -e '${script}'`,
|
|
107
|
+
].join("\n");
|
|
108
|
+
}
|
|
109
|
+
async function revokeDelegatedCommands(friendId, ctx) {
|
|
110
|
+
const friend = await ctx.store.get(friendId);
|
|
111
|
+
const change = (0, delegated_command_grants_1.setDelegatedCommandGrant)(ctx.agentRoot, friendId, { grant: false }, ctx.now);
|
|
112
|
+
// A rollback to an older harness reads the legacy record grant. This command runs as root and must not write the Butler's friend record, so it prints the resident-user follow-up instead.
|
|
113
|
+
const legacyFollowUp = friend?.delegationGrant !== undefined ? clearLegacyGrantCommand(ctx.agentRoot, friend.id) : null;
|
|
114
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.a2a_trust_grant_changed", message: "operator changed a trust grant", meta: { action: "revoke", scope: "delegated_commands" } });
|
|
115
|
+
return [
|
|
116
|
+
`revoked delegated commands: ${friend ? `${friend.name} (${friend.id})` : `${friendId} (no friend record)`}${change.changed || legacyFollowUp ? "" : " (no change)"}`,
|
|
117
|
+
...(legacyFollowUp ? [legacyFollowUp] : []),
|
|
118
|
+
...(change.backup ? [`backup: ${change.backup}`] : []),
|
|
119
|
+
].join("\n");
|
|
120
|
+
}
|
|
121
|
+
function statusOf(friendId, grant, friend, ctx) {
|
|
122
|
+
if (!friend)
|
|
123
|
+
return { status: "not_honoured", reason: "no_friend_record", text: `no friend record for ${friendId}` };
|
|
124
|
+
const check = (0, delegated_command_grants_1.checkDelegatedCommandGrant)(ctx.agentRoot, friend, (0, resolution_proof_1.friendDid)(friend), ctx.now.getTime());
|
|
125
|
+
if (check.ok)
|
|
126
|
+
return { status: "honoured" };
|
|
127
|
+
switch (check.reason) {
|
|
128
|
+
case "not_family":
|
|
129
|
+
return { status: "suspended", reason: check.reason, text: `${friend.name} is trust ${friend.trustLevel}, admission ${friend.admissionState}; the grant is kept and applies again once it is family and active` };
|
|
130
|
+
case "grant_did_mismatch":
|
|
131
|
+
return { status: "not_honoured", reason: check.reason, text: `the friend record names ${(0, resolution_proof_1.friendDid)(friend) ?? "no DID"}, but the grant pins ${grant.did}` };
|
|
132
|
+
default:
|
|
133
|
+
return { status: "not_honoured", reason: check.reason, text: "the grant is not in force: it expired, this is a replay identity outside its window, or the grant file stopped being trusted" };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function listDelegatedCommands(ctx, json) {
|
|
137
|
+
const file = (0, delegated_command_grants_1.delegatedCommandGrantsPath)(ctx.agentRoot);
|
|
138
|
+
const view = (0, delegated_command_grants_1.viewDelegatedCommandGrants)(ctx.agentRoot);
|
|
139
|
+
const friends = await ctx.store.listAll?.() ?? [];
|
|
140
|
+
const byId = new Map(friends.map((friend) => [friend.id, friend]));
|
|
141
|
+
const entries = Object.entries(view.grants).map(([friendId, grant]) => {
|
|
142
|
+
const friend = byId.get(friendId) ?? null;
|
|
143
|
+
return { friendId, name: friend?.name ?? null, grant, ...statusOf(friendId, grant, friend, ctx) };
|
|
144
|
+
});
|
|
145
|
+
const legacy = friends.filter((friend) => friend.delegationGrant !== undefined);
|
|
146
|
+
if (json) {
|
|
147
|
+
return JSON.stringify({
|
|
148
|
+
agent: ctx.agentName,
|
|
149
|
+
file: { path: file, state: view.state, ...(view.state === "untrusted" ? { reason: view.reason } : {}) },
|
|
150
|
+
grants: entries.map(({ friendId, name, grant, ...status }) => ({ friendId, name, did: grant.did, grantedAt: grant.grantedAt, source: grant.source, expiresAt: grant.expiresAt ?? null, ...status })),
|
|
151
|
+
ignoredEntries: view.ignored,
|
|
152
|
+
legacyRecordGrants: legacy.map((friend) => ({ friendId: friend.id, name: friend.name })),
|
|
153
|
+
}, null, 2);
|
|
154
|
+
}
|
|
155
|
+
const header = view.state === "trusted" ? `trusted: ${file}` : view.state === "missing" ? `not present: ${file}` : `NOT TRUSTED: ${file} (${view.reason}); no grant in it is honoured`;
|
|
156
|
+
const lines = [`delegated-command grants for ${ctx.agentName}`, header];
|
|
157
|
+
if (entries.length === 0)
|
|
158
|
+
lines.push("no delegated-command grants");
|
|
159
|
+
for (const entry of entries) {
|
|
160
|
+
lines.push(`${entry.friendId} ${entry.name ?? "(no friend record)"}`, ` DID ${entry.grant.did}; granted ${entry.grant.grantedAt} (${entry.grant.source}); expires ${entry.grant.expiresAt ?? "never"}`, entry.status === "honoured" ? " HONOURED" : entry.status === "suspended" ? ` SUSPENDED: ${entry.text}` : ` NOT HONOURED: ${entry.text}`);
|
|
161
|
+
}
|
|
162
|
+
if (view.ignored.length > 0)
|
|
163
|
+
lines.push(`ignored (malformed) entries: ${view.ignored.join(", ")}`);
|
|
164
|
+
if (legacy.length > 0)
|
|
165
|
+
lines.push(`legacy friend-record grants (not honoured): ${legacy.map((friend) => `${friend.name} (${friend.id})`).join(", ")}`);
|
|
166
|
+
return lines.join("\n");
|
|
167
|
+
}
|
|
168
|
+
async function executeEscalationCommand(command, ctx) {
|
|
169
|
+
if (command.action === "list") {
|
|
170
|
+
const grants = Object.entries((0, escalation_grants_1.readEscalationGrants)(ctx.agentRoot));
|
|
171
|
+
const view = (0, escalation_grants_1.viewEscalationGrants)(ctx.agentRoot);
|
|
172
|
+
const note = view.state === "untrusted" ? `\nNOT TRUSTED: ${(0, escalation_grants_1.escalationGrantsPath)(ctx.agentRoot)} (${view.reason}); no grant in it is honoured` : "";
|
|
173
|
+
return (grants.length === 0 ? "no escalation grants" : grants.map(([id, grant]) => `${id} granted ${grant.grantedAt} ${grant.did} ${grant.source}`).join("\n")) + note;
|
|
174
|
+
}
|
|
175
|
+
requireRoot(ctx);
|
|
176
|
+
if (command.action === "revoke")
|
|
177
|
+
return revokeEscalation(command.friendId, ctx);
|
|
178
|
+
const friend = await requireFriend(ctx, command.friendId);
|
|
179
|
+
if ((0, replay_grant_holders_1.isReplayGrantHolder)(ctx.agentRoot, friend.id))
|
|
180
|
+
throw new Error(`refusing: ${friend.name} is a replay peer (it is on the replay gate's list in ${(0, operator_trust_1.operatorTrustDir)(ctx.agentRoot)}). Only the replay gate grants it escalation, and only while a run is open. Nothing was written.`);
|
|
181
|
+
const did = checkedDid(friend, command.did);
|
|
182
|
+
const selfNotes = await vetPinnedDid(ctx, friend, did, (0, escalation_grants_1.readEscalationGrants)(ctx.agentRoot));
|
|
183
|
+
const change = (0, escalation_grants_1.setEscalationGrant)(ctx.agentRoot, friend.id, { grant: true, source: command.source ?? `ouro a2a escalation grant, ${ctx.now.toISOString()}`, did }, ctx.now);
|
|
184
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.a2a_trust_grant_changed", message: "operator changed a trust grant", meta: { action: "grant", scope: "escalation" } });
|
|
185
|
+
return [
|
|
186
|
+
`granted escalation: ${friend.name} (${friend.id})${change.changed ? "" : " (no change)"}`,
|
|
187
|
+
`pinned DID: ${did}`,
|
|
188
|
+
...(change.backup ? [`backup: ${change.backup}`] : []),
|
|
189
|
+
...selfNotes,
|
|
190
|
+
...((0, escalation_grants_1.readEscalationGrants)(ctx.agentRoot)[friend.id] === undefined ? [`WARNING: the grant is written but will not be honoured: ${(0, escalation_grants_1.escalationGrantsPath)(ctx.agentRoot)} and every directory above it must be owned by root and writable by no one else.`] : []),
|
|
191
|
+
...(friend.trustLevel !== "family" || friend.admissionState !== "active" ? [`note: ${friend.name} only holds the grant while it is active family (now ${friend.trustLevel}, ${friend.admissionState})`] : []),
|
|
192
|
+
].join("\n");
|
|
193
|
+
}
|
|
194
|
+
/** Revoke needs no friend record: a grant for a friend that was deleted must still be removable by its id. */
|
|
195
|
+
async function revokeEscalation(friendId, ctx) {
|
|
196
|
+
const friend = await ctx.store.get(friendId);
|
|
197
|
+
const change = (0, escalation_grants_1.setEscalationGrant)(ctx.agentRoot, friendId, { grant: false }, ctx.now);
|
|
198
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.a2a_trust_grant_changed", message: "operator changed a trust grant", meta: { action: "revoke", scope: "escalation" } });
|
|
199
|
+
return [
|
|
200
|
+
`revoked escalation: ${friend ? `${friend.name} (${friend.id})` : `${friendId} (no friend record)`}${change.changed ? "" : " (no change)"}`,
|
|
201
|
+
...(change.backup ? [`backup: ${change.backup}`] : []),
|
|
202
|
+
].join("\n");
|
|
203
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
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.TRUSTED_UID = void 0;
|
|
37
|
+
exports.overrideTrustedUidForTests = overrideTrustedUidForTests;
|
|
38
|
+
exports.overrideTrustChainRootForTests = overrideTrustChainRootForTests;
|
|
39
|
+
exports.overrideOwnerForTests = overrideOwnerForTests;
|
|
40
|
+
exports.__resetRejectionRateLimitForTests = __resetRejectionRateLimitForTests;
|
|
41
|
+
exports.isTrustedDirectory = isTrustedDirectory;
|
|
42
|
+
exports.inspectTrustedDirectory = inspectTrustedDirectory;
|
|
43
|
+
exports.inspectTrustedJson = inspectTrustedJson;
|
|
44
|
+
exports.readTrustedJson = readTrustedJson;
|
|
45
|
+
const fs = __importStar(require("node:fs"));
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const runtime_1 = require("../nerves/runtime");
|
|
48
|
+
/**
|
|
49
|
+
* Operator-set state is only honoured when the agent's own process (and anything a prompt-injected model can run
|
|
50
|
+
* through its shell) cannot have written it. The rule is the one sshd calls StrictModes: the file and EVERY directory
|
|
51
|
+
* above it, up to `/`, must be real (no symlinks), owned by the trusted uid (root), and closed to group and other
|
|
52
|
+
* writes. A check on the file's own directory alone is not enough: an agent that owns the parent can rename the
|
|
53
|
+
* root-owned directory away and put one of its own making in its place (rename-then-rebless). Anything that fails reads
|
|
54
|
+
* as "not there", so every consumer fails closed.
|
|
55
|
+
*/
|
|
56
|
+
exports.TRUSTED_UID = 0;
|
|
57
|
+
let uidOverride;
|
|
58
|
+
let chainRootOverride;
|
|
59
|
+
let ownerOverride;
|
|
60
|
+
/** Only a test runner sets VITEST; the running Butler (and its prompt-injected shell) cannot reach this process's environment. */
|
|
61
|
+
const underTestRunner = () => process.env.VITEST !== undefined;
|
|
62
|
+
/** Tests run as an ordinary user, so they declare that user trusted. Refused outside a test runner, and ignored there too. */
|
|
63
|
+
function overrideTrustedUidForTests(uid) {
|
|
64
|
+
if (!underTestRunner())
|
|
65
|
+
throw new Error("overrideTrustedUidForTests is for tests only");
|
|
66
|
+
uidOverride = uid;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Tests keep their files under a private temp root whose ancestors (`/tmp`, `/private`) are not the test user's. A test
|
|
70
|
+
* names that root here, and the ancestor walk stops there (the root itself and everything above it are skipped).
|
|
71
|
+
*/
|
|
72
|
+
function overrideTrustChainRootForTests(root) {
|
|
73
|
+
if (!underTestRunner())
|
|
74
|
+
throw new Error("overrideTrustChainRootForTests is for tests only");
|
|
75
|
+
chainRootOverride = root;
|
|
76
|
+
}
|
|
77
|
+
/** Tests are not root, so they cannot hand a path to another owner: this reports the owner a test wants for a path (`undefined` keeps the real one). */
|
|
78
|
+
function overrideOwnerForTests(lookup) {
|
|
79
|
+
if (!underTestRunner())
|
|
80
|
+
throw new Error("overrideOwnerForTests is for tests only");
|
|
81
|
+
ownerOverride = lookup;
|
|
82
|
+
}
|
|
83
|
+
const ownerOf = (target, stat) => (underTestRunner() ? ownerOverride?.(target) : undefined) ?? stat.uid;
|
|
84
|
+
const effectiveTrustedUid = () => (underTestRunner() ? uidOverride : undefined) ?? exports.TRUSTED_UID;
|
|
85
|
+
const effectiveChainRoot = () => (underTestRunner() ? chainRootOverride : undefined);
|
|
86
|
+
const REJECTION_WINDOW_MS = 60_000;
|
|
87
|
+
const lastRejection = new Map();
|
|
88
|
+
/** Test hook: the rate limiter is module state. */
|
|
89
|
+
function __resetRejectionRateLimitForTests() {
|
|
90
|
+
lastRejection.clear();
|
|
91
|
+
}
|
|
92
|
+
/** One warn per target and reason per minute: a rejected file is re-read on every inbound message. */
|
|
93
|
+
function rejected(target, reason) {
|
|
94
|
+
const key = `${target}\u0000${reason}`;
|
|
95
|
+
const now = Date.now();
|
|
96
|
+
const last = lastRejection.get(key);
|
|
97
|
+
if (last !== undefined && now - last < REJECTION_WINDOW_MS)
|
|
98
|
+
return;
|
|
99
|
+
lastRejection.set(key, now);
|
|
100
|
+
(0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.a2a_trusted_file_rejected", message: "ignored operator-set state the agent could have written", meta: { target, reason } });
|
|
101
|
+
}
|
|
102
|
+
/** Every directory from `target` up to `/` (or the test chain root): a real directory, trusted owner, closed to group and other writes. */
|
|
103
|
+
function inspectChain(target, trustedUid) {
|
|
104
|
+
const stop = effectiveChainRoot();
|
|
105
|
+
let current = path.resolve(target);
|
|
106
|
+
for (;;) {
|
|
107
|
+
if (stop !== undefined && current === stop)
|
|
108
|
+
return { state: "trusted" };
|
|
109
|
+
let stat;
|
|
110
|
+
try {
|
|
111
|
+
stat = fs.lstatSync(current);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
return error.code === "ENOENT" || error.code === "ENOTDIR"
|
|
115
|
+
? { state: "missing" }
|
|
116
|
+
: { state: "untrusted", reason: `cannot inspect ${current}` };
|
|
117
|
+
}
|
|
118
|
+
if (stat.isSymbolicLink())
|
|
119
|
+
return { state: "untrusted", reason: `${current} is a symlink` };
|
|
120
|
+
if (!stat.isDirectory())
|
|
121
|
+
return { state: "untrusted", reason: `${current} is not a directory` };
|
|
122
|
+
if (ownerOf(current, stat) !== trustedUid)
|
|
123
|
+
return { state: "untrusted", reason: `${current} is not owned by the trusted uid` };
|
|
124
|
+
if ((stat.mode & 0o022) !== 0)
|
|
125
|
+
return { state: "untrusted", reason: `${current} is writable by group or other` };
|
|
126
|
+
const parent = path.dirname(current);
|
|
127
|
+
if (parent === current)
|
|
128
|
+
return { state: "trusted" };
|
|
129
|
+
current = parent;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** A real directory (no symlink) owned by the trusted uid and closed to group and other writes, with every ancestor up to `/` the same. */
|
|
133
|
+
function isTrustedDirectory(target, trustedUid = effectiveTrustedUid()) {
|
|
134
|
+
const result = inspectChain(target, trustedUid);
|
|
135
|
+
if (result.state === "trusted")
|
|
136
|
+
return true;
|
|
137
|
+
rejected(target, result.state === "missing" ? "directory does not exist" : result.reason);
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
/** Same chain check, without the warning: for callers that probe before they decide whether the state is wrong. */
|
|
141
|
+
function inspectTrustedDirectory(target, trustedUid = effectiveTrustedUid()) {
|
|
142
|
+
return inspectChain(target, trustedUid);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Reads a JSON file only if the whole chain above it is trusted and the file actually opened is trusted. The path is
|
|
146
|
+
* opened once with O_NOFOLLOW, then the descriptor itself is checked (regular file, trusted owner, not group- or
|
|
147
|
+
* other-writable) and read, so a rename loop cannot swap a different file in between the check and the read.
|
|
148
|
+
* `missing` means the file or a directory above it does not exist; everything else that fails is `untrusted`.
|
|
149
|
+
*/
|
|
150
|
+
function inspectTrustedJson(file, trustedUid = effectiveTrustedUid()) {
|
|
151
|
+
const chain = inspectChain(path.dirname(file), trustedUid);
|
|
152
|
+
if (chain.state === "missing")
|
|
153
|
+
return { state: "missing" };
|
|
154
|
+
if (chain.state === "untrusted") {
|
|
155
|
+
rejected(file, chain.reason);
|
|
156
|
+
return chain;
|
|
157
|
+
}
|
|
158
|
+
let fd;
|
|
159
|
+
try {
|
|
160
|
+
fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
161
|
+
const stat = fs.fstatSync(fd);
|
|
162
|
+
if (!stat.isFile() || ownerOf(file, stat) !== trustedUid || (stat.mode & 0o022) !== 0) {
|
|
163
|
+
const reason = "file is not a regular file owned by the trusted uid and closed to group and other writes";
|
|
164
|
+
rejected(file, reason);
|
|
165
|
+
return { state: "untrusted", reason };
|
|
166
|
+
}
|
|
167
|
+
return { state: "trusted", value: JSON.parse(fs.readFileSync(fd, "utf8")) };
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (error.code === "ENOENT")
|
|
171
|
+
return { state: "missing" };
|
|
172
|
+
const reason = error instanceof SyntaxError ? "file is not valid JSON" : "file could not be opened without following links";
|
|
173
|
+
rejected(file, reason);
|
|
174
|
+
return { state: "untrusted", reason };
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
if (fd !== undefined)
|
|
178
|
+
fs.closeSync(fd);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** The parsed JSON of a trusted file, or `undefined` for anything else. */
|
|
182
|
+
function readTrustedJson(file, trustedUid = effectiveTrustedUid()) {
|
|
183
|
+
const result = inspectTrustedJson(file, trustedUid);
|
|
184
|
+
return result.state === "trusted" ? result.value : undefined;
|
|
185
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared attention queue types.
|
|
4
|
+
*
|
|
5
|
+
* Canonical home for the AttentionItem interface — consumed by heart/, repertoire/, nerves/, and senses/.
|
|
6
|
+
* Placed in heart/ because attention is a turn-coordination concern.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|