@ouro.bot/cli 0.1.0-alpha.56 → 0.1.0-alpha.561
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/README.md +127 -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/changelog.json +3604 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +237 -0
- package/dist/arc/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +837 -26
- package/dist/heart/agent-entry.js +58 -3
- 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/adapter.js +2 -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 +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +479 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +114 -118
- package/dist/heart/core.js +913 -246
- package/dist/heart/cross-chat-delivery.js +3 -18
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +102 -3
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-exec.js +7457 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1592 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +763 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1698
- package/dist/heart/daemon/daemon-entry.js +387 -2
- package/dist/heart/daemon/daemon-health.js +176 -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 +796 -71
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +826 -0
- package/dist/heart/daemon/health-monitor.js +122 -1
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -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 +89 -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 +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/message-router.js +2 -2
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +375 -33
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/pulse.js +475 -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 +67 -16
- package/dist/heart/daemon/runtime-metadata.js +3 -31
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +389 -38
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +158 -11
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +330 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +162 -17
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -1
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
- 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 +35 -12
- package/dist/heart/identity.js +203 -57
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +362 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +683 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +267 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +139 -52
- package/dist/heart/providers/azure.js +97 -13
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +367 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +13 -4
- package/dist/heart/session-activity.js +43 -22
- package/dist/heart/session-events.js +1149 -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-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +44 -27
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +9 -5
- 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-description.js +139 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +389 -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 +426 -0
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +674 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +720 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +430 -0
- package/dist/mailroom/mbox-import.js +383 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +233 -0
- package/dist/mailroom/search-cache.js +256 -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 +7 -1
- package/dist/mind/context.js +165 -101
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +62 -75
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +39 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +4 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1011 -123
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -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 +129 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +224 -4
- 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 +152 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +963 -0
- package/dist/repertoire/bundle-templates.js +72 -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 +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +158 -9
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- 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/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 +396 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +362 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +31 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +16 -4
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +16 -78
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-base.js +47 -1075
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +142 -0
- package/dist/repertoire/tools-bundle.js +984 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1857 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-session.js +750 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +108 -100
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +116 -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} +219 -18
- package/dist/senses/bluebubbles/entry.js +77 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
- package/dist/senses/bluebubbles/index.js +2305 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/replay.js +137 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- 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 +240 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +520 -209
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +175 -21
- package/dist/senses/inner-dialog.js +330 -27
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +549 -181
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +251 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +387 -98
- package/dist/senses/trust-gate.js +100 -5
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/elevenlabs.js +178 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +26 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +85 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +80 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +146 -0
- package/package.json +38 -7
- package/skills/agent-commerce.md +106 -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 +101 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1177
- package/dist/senses/debug-activity.js +0 -148
- package/subagents/README.md +0 -86
- package/subagents/work-doer.md +0 -237
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -390
- /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/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,146 @@
|
|
|
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.TripNotFoundError = void 0;
|
|
37
|
+
exports.ensureAgentTripLedger = ensureAgentTripLedger;
|
|
38
|
+
exports.readAgentTripKeypair = readAgentTripKeypair;
|
|
39
|
+
exports.upsertTripRecord = upsertTripRecord;
|
|
40
|
+
exports.readTripRecord = readTripRecord;
|
|
41
|
+
exports.listTripIds = listTripIds;
|
|
42
|
+
const fs = __importStar(require("node:fs"));
|
|
43
|
+
const path = __importStar(require("node:path"));
|
|
44
|
+
const identity_1 = require("../heart/identity");
|
|
45
|
+
const runtime_1 = require("../nerves/runtime");
|
|
46
|
+
const core_1 = require("./core");
|
|
47
|
+
function tripsRoot(agentName) {
|
|
48
|
+
return path.join((0, identity_1.getAgentRoot)(agentName), "state", "trips");
|
|
49
|
+
}
|
|
50
|
+
function ledgerPath(agentName) {
|
|
51
|
+
return path.join(tripsRoot(agentName), "ledger.json");
|
|
52
|
+
}
|
|
53
|
+
function recordsDir(agentName) {
|
|
54
|
+
return path.join(tripsRoot(agentName), "records");
|
|
55
|
+
}
|
|
56
|
+
function recordPath(agentName, tripId) {
|
|
57
|
+
return path.join(recordsDir(agentName), `${tripId}.json`);
|
|
58
|
+
}
|
|
59
|
+
function readJsonFile(filePath) {
|
|
60
|
+
if (!fs.existsSync(filePath))
|
|
61
|
+
return null;
|
|
62
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
63
|
+
}
|
|
64
|
+
function writeJsonAtomic(filePath, value) {
|
|
65
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
66
|
+
const tmp = `${filePath}.tmp`;
|
|
67
|
+
fs.writeFileSync(tmp, JSON.stringify(value, null, 2), "utf-8");
|
|
68
|
+
fs.renameSync(tmp, filePath);
|
|
69
|
+
}
|
|
70
|
+
class TripNotFoundError extends Error {
|
|
71
|
+
statusCode = 404;
|
|
72
|
+
constructor(input) {
|
|
73
|
+
super(`trip not found: agent=${input.agentName} trip=${input.tripId}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.TripNotFoundError = TripNotFoundError;
|
|
77
|
+
/**
|
|
78
|
+
* Idempotent — if the agent already has a ledger on disk, return it; otherwise
|
|
79
|
+
* generate a fresh keypair and persist both halves.
|
|
80
|
+
*/
|
|
81
|
+
function ensureAgentTripLedger(input) {
|
|
82
|
+
const existing = readJsonFile(ledgerPath(input.agentName));
|
|
83
|
+
if (existing) {
|
|
84
|
+
return { ledger: existing.ledger, added: false };
|
|
85
|
+
}
|
|
86
|
+
const created = (0, core_1.newTripLedgerRecord)({
|
|
87
|
+
agentId: input.agentName,
|
|
88
|
+
...(input.label ? { label: input.label } : {}),
|
|
89
|
+
...(input.now ? { now: input.now } : {}),
|
|
90
|
+
});
|
|
91
|
+
const stored = {
|
|
92
|
+
schemaVersion: 1,
|
|
93
|
+
ledger: created.ledger,
|
|
94
|
+
privateKeyPem: created.keypair.privateKeyPem,
|
|
95
|
+
};
|
|
96
|
+
writeJsonAtomic(ledgerPath(input.agentName), stored);
|
|
97
|
+
(0, runtime_1.emitNervesEvent)({
|
|
98
|
+
component: "trips",
|
|
99
|
+
event: "trips.ledger_created",
|
|
100
|
+
message: "agent trip ledger keypair created",
|
|
101
|
+
meta: { agentId: input.agentName, ledgerId: created.ledger.ledgerId, keyId: created.ledger.keyId },
|
|
102
|
+
});
|
|
103
|
+
return { ledger: created.ledger, added: true };
|
|
104
|
+
}
|
|
105
|
+
function readLedgerOrThrow(agentName) {
|
|
106
|
+
const stored = readJsonFile(ledgerPath(agentName));
|
|
107
|
+
if (!stored) {
|
|
108
|
+
throw new Error(`no trip ledger for agent ${agentName} — call ensureAgentTripLedger first`);
|
|
109
|
+
}
|
|
110
|
+
return stored;
|
|
111
|
+
}
|
|
112
|
+
function readAgentTripKeypair(agentName) {
|
|
113
|
+
const stored = readLedgerOrThrow(agentName);
|
|
114
|
+
return {
|
|
115
|
+
keyId: stored.ledger.keyId,
|
|
116
|
+
publicKeyPem: stored.ledger.publicKeyPem,
|
|
117
|
+
privateKeyPem: stored.privateKeyPem,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function upsertTripRecord(agentName, trip) {
|
|
121
|
+
const stored = readLedgerOrThrow(agentName);
|
|
122
|
+
const payload = (0, core_1.encryptTripRecord)(trip, stored.ledger.publicKeyPem, stored.ledger.keyId);
|
|
123
|
+
writeJsonAtomic(recordPath(agentName, trip.tripId), payload);
|
|
124
|
+
(0, runtime_1.emitNervesEvent)({
|
|
125
|
+
component: "trips",
|
|
126
|
+
event: "trips.record_upserted",
|
|
127
|
+
message: "trip record upserted",
|
|
128
|
+
meta: { agentId: agentName, tripId: trip.tripId, legCount: trip.legs.length, status: trip.status },
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function readTripRecord(agentName, tripId) {
|
|
132
|
+
const payload = readJsonFile(recordPath(agentName, tripId));
|
|
133
|
+
if (!payload)
|
|
134
|
+
throw new TripNotFoundError({ agentName, tripId });
|
|
135
|
+
const stored = readLedgerOrThrow(agentName);
|
|
136
|
+
return (0, core_1.decryptTripRecord)(payload, stored.privateKeyPem);
|
|
137
|
+
}
|
|
138
|
+
function listTripIds(agentName) {
|
|
139
|
+
const dir = recordsDir(agentName);
|
|
140
|
+
if (!fs.existsSync(dir))
|
|
141
|
+
return [];
|
|
142
|
+
return fs.readdirSync(dir)
|
|
143
|
+
.filter((entry) => entry.endsWith(".json"))
|
|
144
|
+
.map((entry) => entry.slice(0, -".json".length))
|
|
145
|
+
.sort();
|
|
146
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.561",
|
|
4
4
|
"main": "dist/heart/daemon/ouro-entry.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cli": "dist/heart/daemon/ouro-bot-entry.js",
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
12
|
+
"SerpentGuide.ouro/",
|
|
13
|
+
"RepairGuide.ouro/",
|
|
14
|
+
"skills/",
|
|
14
15
|
"assets/",
|
|
15
16
|
"changelog.json"
|
|
16
17
|
],
|
|
@@ -19,36 +20,66 @@
|
|
|
19
20
|
"./runOuroCli": "./dist/heart/daemon/daemon-cli.js"
|
|
20
21
|
},
|
|
21
22
|
"scripts": {
|
|
22
|
-
"dev": "tsc && node dist/
|
|
23
|
+
"dev": "tsc && node dist/heart/daemon/ouro-bot-entry.js dev",
|
|
24
|
+
"cli": "tsc && node dist/senses/cli-entry.js",
|
|
23
25
|
"daemon": "tsc && node dist/heart/daemon/daemon-entry.js",
|
|
24
26
|
"ouro": "tsc && node dist/heart/daemon/ouro-entry.js",
|
|
25
27
|
"teams": "tsc && node dist/senses/teams-entry.js --agent ouroboros",
|
|
26
|
-
"bluebubbles": "tsc && node dist/senses/bluebubbles
|
|
28
|
+
"bluebubbles": "tsc && node dist/senses/bluebubbles/entry.js --agent ouroboros",
|
|
27
29
|
"test": "vitest run",
|
|
30
|
+
"test:integration": "npm run build && vitest run --config vitest.integration.config.ts",
|
|
31
|
+
"test:e2e:package": "npm run build && node scripts/package-e2e.cjs",
|
|
32
|
+
"test:e2e:real-smoke": "npm run build && node scripts/nightly-real-smoke.cjs",
|
|
33
|
+
"typecheck:mailbox-ui": "tsc --noEmit -p packages/mailbox-ui/tsconfig.json",
|
|
34
|
+
"test:mailbox-ui": "npm test --prefix packages/mailbox-ui",
|
|
28
35
|
"test:coverage:vitest": "vitest run --coverage",
|
|
29
36
|
"test:coverage": "node scripts/run-coverage-gate.cjs",
|
|
30
|
-
"build": "tsc",
|
|
37
|
+
"build": "node scripts/clean-dist.cjs && tsc && (cd packages/mailbox-ui && npm install --ignore-scripts 2>/dev/null && npm run build && cd ../.. && node scripts/copy-mailbox-ui.cjs) || echo 'mailbox-ui build skipped'",
|
|
31
38
|
"lint": "eslint src/",
|
|
39
|
+
"release:preflight": "node scripts/release-preflight.cjs",
|
|
40
|
+
"release:smoke": "node scripts/release-smoke.cjs",
|
|
32
41
|
"audit:nerves": "npm run build && node dist/nerves/coverage/cli-main.js"
|
|
33
42
|
},
|
|
34
43
|
"dependencies": {
|
|
35
44
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
45
|
+
"@azure/identity": "^4.13.0",
|
|
46
|
+
"@azure/storage-blob": "^12.31.0",
|
|
47
|
+
"@microsoft/teams.api": "2.0.5",
|
|
36
48
|
"@microsoft/teams.apps": "^2.0.5",
|
|
49
|
+
"@microsoft/teams.cards": "2.0.5",
|
|
50
|
+
"@microsoft/teams.common": "2.0.5",
|
|
37
51
|
"@microsoft/teams.dev": "^2.0.5",
|
|
52
|
+
"@microsoft/teams.graph": "2.0.5",
|
|
53
|
+
"@types/react": "^17.0.91",
|
|
38
54
|
"fast-glob": "^3.3.3",
|
|
55
|
+
"ink": "^3.2.0",
|
|
56
|
+
"mailparser": "^3.9.8",
|
|
39
57
|
"openai": "^6.27.0",
|
|
40
|
-
"
|
|
58
|
+
"react": "^17.0.2",
|
|
59
|
+
"semver": "^7.7.4",
|
|
60
|
+
"smtp-server": "^3.18.4",
|
|
61
|
+
"stripe": "^22.0.0"
|
|
41
62
|
},
|
|
42
63
|
"repository": {
|
|
43
64
|
"type": "git",
|
|
44
65
|
"url": "https://github.com/ouroborosbot/ouroboros"
|
|
45
66
|
},
|
|
46
67
|
"devDependencies": {
|
|
68
|
+
"@testing-library/react": "^16.3.2",
|
|
69
|
+
"@types/mailparser": "^3.4.6",
|
|
47
70
|
"@types/semver": "^7.7.1",
|
|
71
|
+
"@types/smtp-server": "^3.5.13",
|
|
48
72
|
"@vitest/coverage-v8": "^4.0.18",
|
|
49
73
|
"eslint": "^10.0.2",
|
|
74
|
+
"jsdom": "^29.0.2",
|
|
50
75
|
"typescript": "^5.7.0",
|
|
51
76
|
"typescript-eslint": "^8.56.1",
|
|
52
77
|
"vitest": "^4.0.18"
|
|
78
|
+
},
|
|
79
|
+
"overrides": {
|
|
80
|
+
"@testing-library/react": {
|
|
81
|
+
"react": "$react",
|
|
82
|
+
"@types/react": "$@types/react"
|
|
83
|
+
}
|
|
53
84
|
}
|
|
54
85
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Agent Commerce Skill
|
|
2
|
+
|
|
3
|
+
How to book, purchase, and pay for things on behalf of humans.
|
|
4
|
+
|
|
5
|
+
## Three Patterns
|
|
6
|
+
|
|
7
|
+
### Pattern A: API (Structured, Preferred)
|
|
8
|
+
|
|
9
|
+
For services with direct API access: Duffel flights, LiteAPI hotels.
|
|
10
|
+
|
|
11
|
+
1. Search using the API tool (`flight_search`, LiteAPI MCP)
|
|
12
|
+
2. Present options to the human with prices and details
|
|
13
|
+
3. Human approves a specific option and price
|
|
14
|
+
4. Book using the API tool with passenger data from `user_profile_get`
|
|
15
|
+
5. Create a single-use virtual card via `stripe_create_card`
|
|
16
|
+
6. Complete payment through the API
|
|
17
|
+
7. Deactivate the card via `stripe_deactivate_card`
|
|
18
|
+
8. Confirm booking to the human
|
|
19
|
+
|
|
20
|
+
**Key tools**: `flight_search`, `flight_book`, `flight_cancel`, `user_profile_get`, `user_profile_store`, `stripe_create_card`, `stripe_deactivate_card`, `stripe_list_cards`
|
|
21
|
+
|
|
22
|
+
### Pattern B: Browser (Best-Effort)
|
|
23
|
+
|
|
24
|
+
For sites without API access, use browser automation via Playwright MCP.
|
|
25
|
+
|
|
26
|
+
1. Navigate to the booking site
|
|
27
|
+
2. Search for the requested service
|
|
28
|
+
3. Fill forms using data from `user_profile_get`
|
|
29
|
+
4. Use a virtual card from `stripe_create_card` for payment
|
|
30
|
+
5. If blocked by anti-bot measures, fall back to Pattern C
|
|
31
|
+
6. Complete and confirm the booking
|
|
32
|
+
|
|
33
|
+
**Limitations**: Browser automation is fragile. Sites may block, layouts change, CAPTCHAs appear. Always have Pattern C as fallback.
|
|
34
|
+
|
|
35
|
+
### Pattern C: Link-Only (Primary for Hostile Sites)
|
|
36
|
+
|
|
37
|
+
For sites that block automation or require complex human interaction.
|
|
38
|
+
|
|
39
|
+
1. Research the best options using browser tools or API tools
|
|
40
|
+
2. Prepare a curated link with pre-filled parameters where possible
|
|
41
|
+
3. Send the link to the human with a summary of what to book
|
|
42
|
+
4. Human completes the booking in their own browser
|
|
43
|
+
|
|
44
|
+
**When to use**: Always use Pattern C as the primary approach for sites known to block automation (most airline direct sites, hotel chains, rental car sites). Pattern B is best-effort, not reliable.
|
|
45
|
+
|
|
46
|
+
## Payment autonomy Levels
|
|
47
|
+
|
|
48
|
+
- **Level 0**: No autonomous payments. Agent researches, human pays manually.
|
|
49
|
+
- **Level 1**: Agent creates virtual cards, human approves each transaction explicitly.
|
|
50
|
+
- **Level 2**: Agent can book pre-approved items (within budget, approved categories) without per-transaction approval.
|
|
51
|
+
- **Level 3**: Full delegation with spending limits. Agent manages a budget and books as needed.
|
|
52
|
+
|
|
53
|
+
Default is Level 1. Level changes require explicit human approval.
|
|
54
|
+
|
|
55
|
+
## Error Handling
|
|
56
|
+
|
|
57
|
+
### Price Change Guard
|
|
58
|
+
Before completing a booking, verify the final price matches the approved price within 5%. If the price changed more than 5%, stop and report to the human. Never pay a price the human didn't approve.
|
|
59
|
+
|
|
60
|
+
### Partial Failure Reporting
|
|
61
|
+
When booking involves multiple services (e.g., flight + hotel), each service may succeed or fail independently — this is a partial failure scenario. Report the status of each service separately. **Never auto-cancel a successful booking because a related booking failed.** Let the human decide.
|
|
62
|
+
|
|
63
|
+
Example: "Flight SFO-JFK booked (confirmation: ABC123). Hotel booking failed: no availability for those dates. Would you like me to search for alternative hotels?"
|
|
64
|
+
|
|
65
|
+
### Refund Flow
|
|
66
|
+
If a booking fails after card creation:
|
|
67
|
+
1. Deactivate the virtual card immediately
|
|
68
|
+
2. Report the failure to the human
|
|
69
|
+
3. If a charge was made, note it for the human to follow up with the provider
|
|
70
|
+
|
|
71
|
+
## CAPTCHA Handling
|
|
72
|
+
|
|
73
|
+
When a CAPTCHA appears during browser automation (Pattern B):
|
|
74
|
+
1. Take a screenshot and send it to the human
|
|
75
|
+
2. Explain what page you're on and what you were trying to do
|
|
76
|
+
3. Ask the human to solve the CAPTCHA in their own browser
|
|
77
|
+
4. Switch to Pattern C (link-only) for this transaction
|
|
78
|
+
|
|
79
|
+
Never attempt to solve CAPTCHAs programmatically.
|
|
80
|
+
|
|
81
|
+
## Card Number Isolation
|
|
82
|
+
|
|
83
|
+
Card numbers must NEVER appear in:
|
|
84
|
+
- Tool return values shown to the model
|
|
85
|
+
- Nerves events or logs
|
|
86
|
+
- Chat messages to the human
|
|
87
|
+
- Any stored state or written notes
|
|
88
|
+
|
|
89
|
+
The only place card numbers exist is inside the Stripe client's internal payment flow functions, scoped to a single function call. The model only ever sees card IDs and last-4 digits.
|
|
90
|
+
|
|
91
|
+
## Profile Data Usage
|
|
92
|
+
|
|
93
|
+
Access profile data only when needed for the current transaction:
|
|
94
|
+
- `user_profile_get` to retrieve specific fields (never dump full profile)
|
|
95
|
+
- Passport data only for international bookings
|
|
96
|
+
- Loyalty program numbers only when booking with that program
|
|
97
|
+
- Emergency contact only when the booking service requires it
|
|
98
|
+
|
|
99
|
+
## Self-Test
|
|
100
|
+
|
|
101
|
+
Before first use, run the commerce self-test to verify all services are configured:
|
|
102
|
+
- Stripe: creates and deactivates a test virtual card
|
|
103
|
+
- Duffel: runs a test flight search
|
|
104
|
+
- LiteAPI: verifies API key in vault
|
|
105
|
+
|
|
106
|
+
Report results to the human with actionable next steps for any failures.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Browser Navigation Skill
|
|
2
|
+
|
|
3
|
+
When to use browser tools and how to navigate effectively.
|
|
4
|
+
|
|
5
|
+
## When to Use Browser Tools
|
|
6
|
+
|
|
7
|
+
Use browser navigation when:
|
|
8
|
+
- The target site has no API (e.g., Airbnb, VRBO, travel blogs)
|
|
9
|
+
- Content is dynamic or requires JavaScript rendering
|
|
10
|
+
- Login-required pages need session-based access
|
|
11
|
+
- You need to verify visual content (screenshots, layouts)
|
|
12
|
+
- Price comparison requires real-time scraping
|
|
13
|
+
|
|
14
|
+
Do NOT use browser tools when:
|
|
15
|
+
- A dedicated API or MCP server exists (prefer `weather_lookup`, Duffel MCP, etc.)
|
|
16
|
+
- The data is available via a public JSON endpoint
|
|
17
|
+
- The task can be completed with `web_search`
|
|
18
|
+
|
|
19
|
+
## Stealth Browsing Best Practices
|
|
20
|
+
|
|
21
|
+
The `@playwright/mcp` server is configured with realistic user-agent and viewport settings. To avoid detection on travel sites:
|
|
22
|
+
|
|
23
|
+
- **Add delays between navigations**: Wait 2-5 seconds between page loads. Never hammer requests in rapid succession.
|
|
24
|
+
- **Vary timing**: Use random delays rather than fixed intervals (e.g., 2-5s, not exactly 3s every time).
|
|
25
|
+
- **Avoid predictable patterns**: Don't navigate the same path repeatedly in short succession.
|
|
26
|
+
- **Use realistic scroll behavior**: Scroll gradually through pages rather than jumping to specific elements.
|
|
27
|
+
- **Respect robots.txt**: Check for rate limits and crawling restrictions.
|
|
28
|
+
|
|
29
|
+
## Navigation Workflow
|
|
30
|
+
|
|
31
|
+
Follow this pattern for every page interaction:
|
|
32
|
+
|
|
33
|
+
1. **Navigate**: Use `browser_navigate` to load the page
|
|
34
|
+
2. **Wait**: Allow the page to fully load (use `browser_wait` if needed)
|
|
35
|
+
3. **Snapshot**: Take a `browser_snapshot` to understand the page structure
|
|
36
|
+
4. **Extract**: Parse the accessibility tree for relevant data
|
|
37
|
+
5. **Screenshot** (optional): Use `browser_screenshot` for visual confirmation
|
|
38
|
+
|
|
39
|
+
## Form Filling Patterns
|
|
40
|
+
|
|
41
|
+
### Login Flows
|
|
42
|
+
1. Navigate to the login page
|
|
43
|
+
2. Take a snapshot to identify form fields
|
|
44
|
+
3. Use `browser_type` for username/password fields
|
|
45
|
+
4. Use `browser_click` to submit
|
|
46
|
+
5. Wait for redirect, then verify login succeeded via snapshot
|
|
47
|
+
6. NEVER hardcode credentials -- use `credential_get` to retrieve login info
|
|
48
|
+
|
|
49
|
+
### Sign-up Flows
|
|
50
|
+
1. Use `credential_generate_password` to mint a strong password for the target domain
|
|
51
|
+
2. Fill the signup form with that password
|
|
52
|
+
3. If the site rejects the password policy, generate a new one that matches the site rules
|
|
53
|
+
4. Once the site accepts the exact password, call `credential_store` immediately
|
|
54
|
+
5. Do not claim a new credential is saved until `credential_store` succeeds
|
|
55
|
+
|
|
56
|
+
### Search Forms (Hotels, Flights, Rentals)
|
|
57
|
+
1. Navigate to the search page
|
|
58
|
+
2. Snapshot to identify input fields
|
|
59
|
+
3. Fill location/date fields with `browser_type`
|
|
60
|
+
4. Select options with `browser_select_option` or `browser_click`
|
|
61
|
+
5. Submit the search
|
|
62
|
+
6. Wait for results to load (travel sites often have loading animations)
|
|
63
|
+
7. Snapshot the results page to extract listings
|
|
64
|
+
|
|
65
|
+
### Booking Forms
|
|
66
|
+
1. **ALWAYS confirm with the user before proceeding to payment**
|
|
67
|
+
2. Fill traveler information
|
|
68
|
+
3. Use stored credentials for payment (via `credential_get` -- NEVER type raw card numbers)
|
|
69
|
+
4. Screenshot the final review page for user confirmation
|
|
70
|
+
5. Only click "Book" / "Confirm" after explicit user approval
|
|
71
|
+
|
|
72
|
+
## Anti-Bot Detection Avoidance
|
|
73
|
+
|
|
74
|
+
The stealth configuration handles most fingerprinting automatically. Additionally:
|
|
75
|
+
|
|
76
|
+
- **Don't access detection endpoints**: Avoid URLs containing "captcha", "challenge", "verify"
|
|
77
|
+
- **Handle CAPTCHAs**: If you encounter a CAPTCHA, pause and inform the user. Do not attempt automated solving.
|
|
78
|
+
- **Rotate viewport sizes occasionally**: Use different viewport sizes across sessions
|
|
79
|
+
- **Maintain cookies**: Use persistent `user-data-dir` to appear as a returning user
|
|
80
|
+
- **Avoid headless tells**: The user-agent is set to a real browser string
|
|
81
|
+
|
|
82
|
+
## Travel Site Patterns
|
|
83
|
+
|
|
84
|
+
### Airbnb / VRBO
|
|
85
|
+
1. Search by location + check-in/check-out dates + guests
|
|
86
|
+
2. Results load dynamically -- scroll to load more listings
|
|
87
|
+
3. Extract: title, price per night, total price, rating, number of reviews
|
|
88
|
+
4. For detailed info, click into each listing and snapshot
|
|
89
|
+
5. Compare top 3-5 options
|
|
90
|
+
|
|
91
|
+
### Hotel Sites (Booking.com, Hotels.com)
|
|
92
|
+
1. Search by destination + dates + guests + rooms
|
|
93
|
+
2. Filter by price range, star rating, amenities
|
|
94
|
+
3. Extract: name, price, location, rating, key amenities
|
|
95
|
+
4. Check cancellation policies (important for travel planning)
|
|
96
|
+
|
|
97
|
+
### Flight Comparison
|
|
98
|
+
1. Prefer Duffel MCP for flight search (structured API data)
|
|
99
|
+
2. Use browser only if Duffel doesn't cover the airline
|
|
100
|
+
3. Google Flights is useful for price comparison but requires careful navigation
|
|
101
|
+
|
|
102
|
+
## Error Handling
|
|
103
|
+
|
|
104
|
+
- **Page timeouts**: Retry once after 5 seconds. If still failing, inform the user.
|
|
105
|
+
- **CAPTCHAs**: Stop and ask the user to solve manually.
|
|
106
|
+
- **Stale elements**: Re-snapshot the page and retry the interaction.
|
|
107
|
+
- **Blocked/403**: The site may have detected automation. Wait 30 seconds and try with a different approach (e.g., direct URL instead of navigation).
|
|
108
|
+
- **Session expired**: Re-login using stored credentials.
|
|
109
|
+
|
|
110
|
+
## Human Confirmation Gates
|
|
111
|
+
|
|
112
|
+
**ALWAYS** confirm with the user before:
|
|
113
|
+
- Any booking or payment action
|
|
114
|
+
- Entering personal information (name, address, phone)
|
|
115
|
+
- Agreeing to terms of service
|
|
116
|
+
- Subscribing to any service
|
|
117
|
+
- Any action that creates a financial obligation
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Commerce Setup Guide
|
|
2
|
+
|
|
3
|
+
Human-facing guide for configuring the agent's commerce capabilities.
|
|
4
|
+
|
|
5
|
+
## Architecture Overview
|
|
6
|
+
|
|
7
|
+
The agent's commerce system has three pillars:
|
|
8
|
+
|
|
9
|
+
1. **User Profile**: Secure storage of personal data (name, passport, payment preferences) in Vaultwarden, accessed only when needed for specific transactions.
|
|
10
|
+
|
|
11
|
+
2. **Booking Delegation**: Direct API access to flight (Duffel) and hotel (LiteAPI) booking systems, plus browser automation fallback for sites without APIs.
|
|
12
|
+
|
|
13
|
+
3. **Payment**: Stripe Issuing virtual cards created per-transaction, with spend limits and merchant category restrictions. Card numbers never enter the model's context.
|
|
14
|
+
|
|
15
|
+
## Setup Steps
|
|
16
|
+
|
|
17
|
+
### 1. Stripe Issuing (Required for Payments)
|
|
18
|
+
|
|
19
|
+
- Create a Stripe account: https://dashboard.stripe.com
|
|
20
|
+
- Enable Stripe Issuing (requires business verification)
|
|
21
|
+
- Create a restricted API key: https://dashboard.stripe.com/apikeys
|
|
22
|
+
- Permissions needed: `issuing_cards:write`, `issuing_cards:read`
|
|
23
|
+
- Store in vault: `credential_store stripe.com --password <key>`
|
|
24
|
+
|
|
25
|
+
### 2. Duffel (Flights)
|
|
26
|
+
|
|
27
|
+
- Create a Duffel account: https://app.duffel.com
|
|
28
|
+
- Generate a sandbox token: https://app.duffel.com/tokens
|
|
29
|
+
- Store in vault: `credential_store duffel.com --password <token>`
|
|
30
|
+
|
|
31
|
+
### 3. LiteAPI (Hotels)
|
|
32
|
+
|
|
33
|
+
- Create a LiteAPI account: https://dashboard.liteapi.travel
|
|
34
|
+
- Get your sandbox API key
|
|
35
|
+
- Store in vault: `credential_store liteapi.travel --password <key>`
|
|
36
|
+
- Configure MCP server in agent.json (see commerce-setup.md skill for details)
|
|
37
|
+
|
|
38
|
+
### 4. User Profile
|
|
39
|
+
|
|
40
|
+
Store your travel profile with the agent:
|
|
41
|
+
```
|
|
42
|
+
user_profile_store '{"legalName":{"first":"...","last":"..."},"email":"...","phone":"...","preferences":{}}'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Tool Reference
|
|
46
|
+
|
|
47
|
+
### User Profile Tools
|
|
48
|
+
| Tool | Description | Trust Level |
|
|
49
|
+
|------|-------------|-------------|
|
|
50
|
+
| `user_profile_store` | Store/update profile fields | Family |
|
|
51
|
+
| `user_profile_get` | Retrieve a specific profile field | Family |
|
|
52
|
+
| `user_profile_delete` | Delete entire profile | Family |
|
|
53
|
+
|
|
54
|
+
### Payment Tools
|
|
55
|
+
| Tool | Description | Trust Level |
|
|
56
|
+
|------|-------------|-------------|
|
|
57
|
+
| `stripe_create_card` | Create a virtual card | Family |
|
|
58
|
+
| `stripe_deactivate_card` | Deactivate a card | Family |
|
|
59
|
+
| `stripe_list_cards` | List active cards | Family |
|
|
60
|
+
|
|
61
|
+
### Flight Tools
|
|
62
|
+
| Tool | Description | Trust Level |
|
|
63
|
+
|------|-------------|-------------|
|
|
64
|
+
| `flight_search` | Search for flights | Friend |
|
|
65
|
+
| `flight_hold` | Hold a flight offer | Family |
|
|
66
|
+
| `flight_book` | Book a flight | Family |
|
|
67
|
+
| `flight_cancel` | Cancel a booking | Family |
|
|
68
|
+
|
|
69
|
+
### Hotel Tools
|
|
70
|
+
Hotels are accessed through the LiteAPI MCP server. Tools are dynamically registered when the MCP server connects. Common tools include search, get rates, and book.
|
|
71
|
+
|
|
72
|
+
## Security Model
|
|
73
|
+
|
|
74
|
+
### Credential Gateway
|
|
75
|
+
All API keys are stored in the agent's Vaultwarden vault. They are never exposed as environment variables or stored in config files. MCP servers receive credentials at startup via `vault:` env resolution.
|
|
76
|
+
|
|
77
|
+
### Card Number Isolation
|
|
78
|
+
Virtual card numbers exist only within the Stripe client's internal functions during a payment flow. They are never:
|
|
79
|
+
- Returned to the model in tool outputs
|
|
80
|
+
- Included in nerves events or logs
|
|
81
|
+
- Stored in any persistent state
|
|
82
|
+
- Shown in chat messages
|
|
83
|
+
|
|
84
|
+
The model only sees card IDs (e.g., `ic_...`) and last-4 digits.
|
|
85
|
+
|
|
86
|
+
### Trust Gating
|
|
87
|
+
- **Family trust required**: All profile, payment, and booking tools
|
|
88
|
+
- **Friend trust sufficient**: Flight search (read-only, no payment)
|
|
89
|
+
- **Stranger/acquaintance**: No commerce access
|
|
90
|
+
|
|
91
|
+
### Vault Resolution Failures
|
|
92
|
+
When a `vault:` reference cannot be resolved for an MCP server:
|
|
93
|
+
- The specific server is skipped (not crashed)
|
|
94
|
+
- Other servers continue to start normally
|
|
95
|
+
- An error event is emitted with the specific resolution failure
|
|
96
|
+
- Error messages are actionable (e.g., "item not found", "field empty")
|
|
97
|
+
|
|
98
|
+
## Verification Tiers
|
|
99
|
+
|
|
100
|
+
### Tier 1: Real-Tested
|
|
101
|
+
- User profile vault CRUD (tested against live Vaultwarden)
|
|
102
|
+
- MCP credential injection (tested with real `vault:` env resolution)
|
|
103
|
+
- Tool registration and guardrail enforcement
|
|
104
|
+
|
|
105
|
+
### Tier 2: Mocked
|
|
106
|
+
- Stripe Issuing API calls (mocked SDK)
|
|
107
|
+
- Duffel flight API calls (mocked HTTP)
|
|
108
|
+
- LiteAPI hotel API calls (MCP config only)
|
|
109
|
+
- Full booking flow (profile -> search -> card -> book -> confirm -> deactivate)
|
|
110
|
+
- Card number leakage verification
|
|
111
|
+
|
|
112
|
+
### Post-Handoff
|
|
113
|
+
- Real Stripe Issuing card creation (requires live Stripe account with Issuing)
|
|
114
|
+
- Real Duffel booking (requires live API key)
|
|
115
|
+
- Real LiteAPI hotel search (requires live MCP server)
|
|
116
|
+
- Browser automation for Pattern B sites
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Commerce Setup Wizard
|
|
2
|
+
|
|
3
|
+
Step-by-step guide for setting up the agent's commerce infrastructure: payment, booking, and accommodation APIs.
|
|
4
|
+
|
|
5
|
+
last_verified: 2026-04-06
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Agent vault must be set up (run `vault_setup` tool if not done)
|
|
10
|
+
- Vault must be reachable at the configured server URL
|
|
11
|
+
|
|
12
|
+
## Step 1: Stripe Issuing (Payments)
|
|
13
|
+
|
|
14
|
+
1. Create a Stripe account at https://dashboard.stripe.com
|
|
15
|
+
2. Enable Stripe Issuing (requires business verification)
|
|
16
|
+
3. Create a restricted API key at https://dashboard.stripe.com/apikeys
|
|
17
|
+
- Enable only `issuing_cards:write` and `issuing_cards:read` permissions
|
|
18
|
+
4. Store the key in the vault: `credential_store stripe.com --password <restricted_key> --notes "Stripe Issuing restricted key"`
|
|
19
|
+
|
|
20
|
+
### Verification
|
|
21
|
+
Run `stripe_list_cards` to verify the key works. Expected: empty list or existing cards.
|
|
22
|
+
|
|
23
|
+
## Step 2: Duffel (Flights)
|
|
24
|
+
|
|
25
|
+
1. Create a Duffel account at https://app.duffel.com
|
|
26
|
+
2. Generate a sandbox API token at https://app.duffel.com/tokens
|
|
27
|
+
- Start with sandbox mode for testing
|
|
28
|
+
- Switch to live mode when ready for real bookings
|
|
29
|
+
3. Store the key in the vault: `credential_store duffel.com --password <api_token> --notes "Duffel API token (sandbox)"`
|
|
30
|
+
|
|
31
|
+
### Verification
|
|
32
|
+
Run `flight_search` with any route (e.g., SFO to JFK). Expected: list of flight offers.
|
|
33
|
+
|
|
34
|
+
## Step 3: LiteAPI (Hotels)
|
|
35
|
+
|
|
36
|
+
1. Create a LiteAPI account at https://dashboard.liteapi.travel
|
|
37
|
+
2. Get your sandbox API key from the dashboard
|
|
38
|
+
3. Store the key in the vault: `credential_store liteapi.travel --password <api_key> --notes "LiteAPI sandbox key"`
|
|
39
|
+
4. Configure the MCP server in agent.json:
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"liteapi": {
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["tsx", "src/index.ts"],
|
|
46
|
+
"cwd": "/path/to/liteapi-mcp-server",
|
|
47
|
+
"env": {
|
|
48
|
+
"LITEAPI_API_KEY": "vault:liteapi.travel/apiKey"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Verification
|
|
56
|
+
The LiteAPI MCP server will start automatically when the agent boots. Check agent logs for `mcp.connect_end` event for the liteapi server.
|
|
57
|
+
|
|
58
|
+
## Step 4: User Profile
|
|
59
|
+
|
|
60
|
+
Store the human's travel profile:
|
|
61
|
+
```
|
|
62
|
+
user_profile_store '{"legalName": {"first": "...", "last": "..."}, "email": "...", "phone": "...", "preferences": {}}'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Optional but recommended fields: dateOfBirth, passport, driverLicense, addresses, loyaltyPrograms.
|
|
66
|
+
|
|
67
|
+
## Self-Test
|
|
68
|
+
|
|
69
|
+
After setup, run the commerce self-test to verify all services:
|
|
70
|
+
- Stripe: creates and deactivates a test virtual card
|
|
71
|
+
- Duffel: runs a test flight search
|
|
72
|
+
- LiteAPI: verifies the API key is stored in the vault
|
|
73
|
+
|
|
74
|
+
The self-test reports per-service health with actionable error messages:
|
|
75
|
+
- "Flights working, hotels not yet -- LiteAPI key missing."
|
|
76
|
+
- "Your Duffel key returned 401. Verify it at app.duffel.com/tokens."
|
|
77
|
+
|
|
78
|
+
## Security Model
|
|
79
|
+
|
|
80
|
+
- All API keys stored in the agent's Vaultwarden vault (not env vars)
|
|
81
|
+
- Card numbers never appear in model context or logs
|
|
82
|
+
- Virtual cards are single-use by default, deactivated after each transaction
|
|
83
|
+
- User profile access requires family trust level
|
|
84
|
+
- Vault credentials are resolved at MCP server startup, not at runtime
|