@vellumai/assistant 0.4.46 → 0.4.49
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/ARCHITECTURE.md +7 -7
- package/README.md +2 -23
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/architecture/security.md +5 -5
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/anthropic-provider.test.ts +156 -0
- package/src/__tests__/approval-cascade.test.ts +810 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-fill-credential.test.ts +5 -2
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +35 -25
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +9 -29
- package/src/__tests__/cli.test.ts +23 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
- package/src/__tests__/credential-broker-server-use.test.ts +22 -21
- package/src/__tests__/credential-broker.test.ts +2 -1
- package/src/__tests__/credential-metadata-store.test.ts +239 -26
- package/src/__tests__/credential-resolve.test.ts +5 -4
- package/src/__tests__/credential-security-e2e.test.ts +8 -8
- package/src/__tests__/credential-security-invariants.test.ts +111 -7
- package/src/__tests__/credential-vault-unit.test.ts +287 -54
- package/src/__tests__/credential-vault.test.ts +406 -12
- package/src/__tests__/credentials-cli.test.ts +82 -6
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-image-service.test.ts +75 -45
- package/src/__tests__/gemini-provider.test.ts +9 -6
- package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
- package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
- package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-grant-minting.test.ts +35 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-cu-proxy.test.ts +629 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +38 -25
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +11 -43
- package/src/__tests__/managed-proxy-context.test.ts +5 -3
- package/src/__tests__/media-generate-image.test.ts +63 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
- package/src/__tests__/messaging-send-tool.test.ts +4 -6
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +373 -14
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +756 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/schema-transforms.test.ts +226 -0
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
- package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/secret-onetime-send.test.ts +5 -3
- package/src/__tests__/send-endpoint-busy.test.ts +21 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-uninstall.test.ts +3 -3
- package/src/__tests__/skills.test.ts +3 -12
- package/src/__tests__/slack-channel-config.test.ts +76 -11
- package/src/__tests__/slack-share-routes.test.ts +17 -14
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +1 -22
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +2 -1
- package/src/__tests__/twilio-provider.test.ts +4 -2
- package/src/__tests__/twilio-routes.test.ts +5 -20
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +235 -0
- package/src/agent/loop.ts +76 -130
- package/src/calls/call-domain.ts +8 -10
- package/src/calls/relay-server.ts +9 -13
- package/src/calls/twilio-config.ts +4 -8
- package/src/calls/twilio-provider.ts +2 -1
- package/src/calls/twilio-rest.ts +2 -1
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +46 -15
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +110 -23
- package/src/cli/commands/oauth/apps.ts +255 -0
- package/src/cli/commands/oauth/connections.ts +299 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +242 -0
- package/src/cli/commands/skills.ts +4 -338
- package/src/cli/program.ts +1 -5
- package/src/cli/reference.ts +1 -3
- package/src/cli.ts +3 -2
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
- package/src/config/bundled-skills/gmail/SKILL.md +4 -4
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
- package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
- package/src/config/bundled-skills/messaging/SKILL.md +6 -6
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
- package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/schema.ts +3 -1
- package/src/config/skills.ts +21 -2
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +49 -10
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/guardian-action-generators.ts +4 -5
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +76 -56
- package/src/daemon/handlers/config-telegram.ts +53 -24
- package/src/daemon/handlers/sessions.ts +10 -24
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/host-cu-proxy.ts +401 -0
- package/src/daemon/lifecycle.ts +39 -63
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +2 -119
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/integrations.ts +1 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/server.ts +14 -21
- package/src/daemon/session-agent-loop-handlers.ts +2 -0
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-messaging.ts +3 -1
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +40 -28
- package/src/daemon/session-tool-setup.ts +20 -11
- package/src/daemon/session.ts +139 -16
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/email/providers/index.ts +2 -1
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/instrument.ts +15 -1
- package/src/logfire.ts +16 -5
- package/src/media/app-icon-generator.ts +30 -4
- package/src/media/avatar-router.ts +26 -3
- package/src/media/gemini-image-service.ts +28 -2
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/guardian-action-store.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +60 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/guardian.ts +1 -1
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/oauth.ts +65 -0
- package/src/messaging/provider.ts +19 -13
- package/src/messaging/providers/gmail/adapter.ts +40 -23
- package/src/messaging/providers/gmail/client.ts +283 -122
- package/src/messaging/providers/gmail/people-client.ts +32 -24
- package/src/messaging/providers/slack/adapter.ts +29 -19
- package/src/messaging/providers/slack/client.ts +265 -78
- package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
- package/src/messaging/providers/whatsapp/adapter.ts +17 -11
- package/src/messaging/registry.ts +2 -31
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +537 -0
- package/src/oauth/byo-connection.ts +128 -0
- package/src/oauth/connect-orchestrator.ts +139 -56
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +58 -0
- package/src/oauth/connection.ts +38 -0
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +496 -0
- package/src/oauth/platform-connection.test.ts +192 -0
- package/src/oauth/platform-connection.ts +111 -0
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +161 -0
- package/src/oauth/token-persistence.ts +74 -78
- package/src/permissions/checker.ts +8 -4
- package/src/permissions/defaults.ts +0 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +13 -0
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +70 -45
- package/src/providers/anthropic/client.ts +133 -24
- package/src/providers/gemini/client.ts +15 -6
- package/src/providers/managed-proxy/constants.ts +2 -2
- package/src/providers/managed-proxy/context.ts +5 -1
- package/src/providers/ratelimit.ts +17 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +1 -27
- package/src/runtime/AGENTS.md +17 -0
- package/src/runtime/auth/route-policy.ts +0 -3
- package/src/runtime/channel-invite-transports/telegram.ts +2 -1
- package/src/runtime/channel-readiness-service.ts +168 -195
- package/src/runtime/channel-readiness-types.ts +4 -0
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/guardian-action-conversation-turn.ts +1 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-message-composer.ts +3 -23
- package/src/runtime/http-server.ts +17 -10
- package/src/runtime/http-types.ts +2 -3
- package/src/runtime/middleware/rate-limiter.ts +74 -20
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/channel-readiness-routes.ts +2 -0
- package/src/runtime/routes/conversation-routes.ts +73 -19
- package/src/runtime/routes/diagnostics-routes.ts +11 -9
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/guardian-approval-interception.ts +20 -5
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -6
- package/src/runtime/routes/integrations/twilio.ts +6 -5
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/secret-routes.ts +3 -2
- package/src/runtime/routes/settings-routes.ts +113 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/schedule/integration-status.ts +10 -8
- package/src/security/credential-key.ts +14 -0
- package/src/security/keychain-broker-client.ts +5 -6
- package/src/security/oauth2.ts +1 -1
- package/src/security/token-manager.ts +145 -43
- package/src/skills/catalog-install.ts +358 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/apps/definitions.ts +0 -5
- package/src/tools/assets/materialize.ts +0 -5
- package/src/tools/assets/search.ts +0 -5
- package/src/tools/browser/headless-browser.ts +1 -67
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/claude-code/claude-code.ts +0 -5
- package/src/tools/computer-use/definitions.ts +46 -11
- package/src/tools/computer-use/registry.ts +4 -5
- package/src/tools/credentials/broker.ts +5 -4
- package/src/tools/credentials/metadata-store.ts +22 -74
- package/src/tools/credentials/resolve.ts +2 -1
- package/src/tools/credentials/vault.ts +139 -151
- package/src/tools/filesystem/edit.ts +1 -6
- package/src/tools/filesystem/read.ts +0 -5
- package/src/tools/filesystem/write.ts +1 -6
- package/src/tools/host-filesystem/edit.ts +1 -6
- package/src/tools/host-filesystem/read.ts +1 -6
- package/src/tools/host-filesystem/write.ts +1 -6
- package/src/tools/mcp/mcp-tool-factory.ts +18 -1
- package/src/tools/memory/definitions.ts +0 -5
- package/src/tools/network/web-fetch.ts +0 -5
- package/src/tools/network/web-search.ts +0 -5
- package/src/tools/registry.ts +2 -7
- package/src/tools/schema-transforms.ts +99 -0
- package/src/tools/skills/load.ts +62 -8
- package/src/tools/swarm/delegate.ts +0 -5
- package/src/tools/system/avatar-generator.ts +0 -5
- package/src/tools/ui-surface/definitions.ts +0 -15
- package/src/tools/watch/screen-watch.ts +0 -5
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/version.ts +10 -0
- package/src/watcher/providers/github.ts +51 -52
- package/src/watcher/providers/gmail.ts +88 -80
- package/src/watcher/providers/google-calendar.ts +94 -86
- package/src/watcher/providers/linear.ts +87 -93
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
- package/src/daemon/computer-use-session.ts +0 -1020
- package/src/daemon/ride-shotgun-handler.ts +0 -567
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
- package/src/runtime/telegram-streaming-delivery.ts +0 -383
- package/src/tools/computer-use/request-computer-control.ts +0 -61
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Read the Telegram bot username from config
|
|
5
|
-
* TELEGRAM_BOT_USERNAME env var.
|
|
4
|
+
* Read the Telegram bot username from config.
|
|
6
5
|
*/
|
|
7
6
|
export function getTelegramBotUsername(): string | undefined {
|
|
8
7
|
const value = getConfig().telegram.botUsername;
|
|
9
8
|
if (value.trim().length > 0) {
|
|
10
9
|
return value.trim();
|
|
11
10
|
}
|
|
12
|
-
return
|
|
11
|
+
return undefined;
|
|
13
12
|
}
|
|
@@ -51,11 +51,6 @@ const appOpenTool: Tool = {
|
|
|
51
51
|
description:
|
|
52
52
|
"Display mode. 'preview' shows an inline preview card in chat. 'workspace' opens the full app in a workspace panel. Defaults to 'workspace'.",
|
|
53
53
|
},
|
|
54
|
-
reason: {
|
|
55
|
-
type: "string",
|
|
56
|
-
description:
|
|
57
|
-
"Brief non-technical explanation of what you are opening and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
58
|
-
},
|
|
59
54
|
},
|
|
60
55
|
required: ["app_id"],
|
|
61
56
|
},
|
|
@@ -95,11 +95,6 @@ const definition: ToolDefinition = {
|
|
|
95
95
|
description:
|
|
96
96
|
"Path where the file should be written, relative to (or inside) the sandbox working directory.",
|
|
97
97
|
},
|
|
98
|
-
reason: {
|
|
99
|
-
type: "string",
|
|
100
|
-
description:
|
|
101
|
-
"Brief non-technical explanation of what you are saving and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
102
|
-
},
|
|
103
98
|
},
|
|
104
99
|
required: ["attachment_id", "destination_path"],
|
|
105
100
|
},
|
|
@@ -298,11 +298,6 @@ const definition: ToolDefinition = {
|
|
|
298
298
|
type: "number",
|
|
299
299
|
description: `Maximum results to return (default ${DEFAULT_LIMIT}, max ${MAX_RESULTS}).`,
|
|
300
300
|
},
|
|
301
|
-
reason: {
|
|
302
|
-
type: "string",
|
|
303
|
-
description:
|
|
304
|
-
"Brief non-technical explanation of what you are searching for and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
305
|
-
},
|
|
306
301
|
},
|
|
307
302
|
required: [],
|
|
308
303
|
},
|
|
@@ -44,11 +44,6 @@ class BrowserNavigateTool implements Tool {
|
|
|
44
44
|
description:
|
|
45
45
|
"If true, allows navigation to localhost/private-network hosts. Disabled by default for SSRF safety.",
|
|
46
46
|
},
|
|
47
|
-
reason: {
|
|
48
|
-
type: "string",
|
|
49
|
-
description:
|
|
50
|
-
"Brief non-technical explanation of what you are navigating to and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
51
|
-
},
|
|
52
47
|
},
|
|
53
48
|
required: ["url"],
|
|
54
49
|
},
|
|
@@ -80,13 +75,7 @@ class BrowserSnapshotTool implements Tool {
|
|
|
80
75
|
description: this.description,
|
|
81
76
|
input_schema: {
|
|
82
77
|
type: "object",
|
|
83
|
-
properties: {
|
|
84
|
-
reason: {
|
|
85
|
-
type: "string",
|
|
86
|
-
description:
|
|
87
|
-
"Brief non-technical explanation of what you are inspecting and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
88
|
-
},
|
|
89
|
-
},
|
|
78
|
+
properties: {},
|
|
90
79
|
},
|
|
91
80
|
};
|
|
92
81
|
}
|
|
@@ -122,11 +111,6 @@ class BrowserScreenshotTool implements Tool {
|
|
|
122
111
|
description:
|
|
123
112
|
"Capture the full scrollable page instead of just the viewport.",
|
|
124
113
|
},
|
|
125
|
-
reason: {
|
|
126
|
-
type: "string",
|
|
127
|
-
description:
|
|
128
|
-
"Brief non-technical explanation of what you are capturing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
129
|
-
},
|
|
130
114
|
},
|
|
131
115
|
},
|
|
132
116
|
};
|
|
@@ -163,11 +147,6 @@ class BrowserCloseTool implements Tool {
|
|
|
163
147
|
description:
|
|
164
148
|
"If true, close all browser pages and the browser context. Default: false (close only the current session page).",
|
|
165
149
|
},
|
|
166
|
-
reason: {
|
|
167
|
-
type: "string",
|
|
168
|
-
description:
|
|
169
|
-
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
170
|
-
},
|
|
171
150
|
},
|
|
172
151
|
},
|
|
173
152
|
};
|
|
@@ -214,11 +193,6 @@ class BrowserClickTool implements Tool {
|
|
|
214
193
|
description:
|
|
215
194
|
"Max time in ms to wait for the element to be clickable (default: 10000).",
|
|
216
195
|
},
|
|
217
|
-
reason: {
|
|
218
|
-
type: "string",
|
|
219
|
-
description:
|
|
220
|
-
"Brief non-technical explanation of what you are clicking and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
221
|
-
},
|
|
222
196
|
},
|
|
223
197
|
},
|
|
224
198
|
};
|
|
@@ -273,11 +247,6 @@ class BrowserTypeTool implements Tool {
|
|
|
273
247
|
type: "boolean",
|
|
274
248
|
description: "If true, press Enter after typing the text.",
|
|
275
249
|
},
|
|
276
|
-
reason: {
|
|
277
|
-
type: "string",
|
|
278
|
-
description:
|
|
279
|
-
"Brief non-technical explanation of what you are typing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
280
|
-
},
|
|
281
250
|
},
|
|
282
251
|
required: ["text"],
|
|
283
252
|
},
|
|
@@ -323,11 +292,6 @@ class BrowserPressKeyTool implements Tool {
|
|
|
323
292
|
type: "string",
|
|
324
293
|
description: "Optional CSS selector to target.",
|
|
325
294
|
},
|
|
326
|
-
reason: {
|
|
327
|
-
type: "string",
|
|
328
|
-
description:
|
|
329
|
-
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
330
|
-
},
|
|
331
295
|
},
|
|
332
296
|
required: ["key"],
|
|
333
297
|
},
|
|
@@ -378,11 +342,6 @@ class BrowserScrollTool implements Tool {
|
|
|
378
342
|
type: "string",
|
|
379
343
|
description: "Optional CSS selector of element to scroll within.",
|
|
380
344
|
},
|
|
381
|
-
reason: {
|
|
382
|
-
type: "string",
|
|
383
|
-
description:
|
|
384
|
-
"Brief non-technical explanation of what you are scrolling to see and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
385
|
-
},
|
|
386
345
|
},
|
|
387
346
|
required: ["direction"],
|
|
388
347
|
},
|
|
@@ -437,11 +396,6 @@ class BrowserSelectOptionTool implements Tool {
|
|
|
437
396
|
type: "number",
|
|
438
397
|
description: "The zero-based index of the <option> to select.",
|
|
439
398
|
},
|
|
440
|
-
reason: {
|
|
441
|
-
type: "string",
|
|
442
|
-
description:
|
|
443
|
-
"Brief non-technical explanation of what you are selecting and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
444
|
-
},
|
|
445
399
|
},
|
|
446
400
|
},
|
|
447
401
|
};
|
|
@@ -483,11 +437,6 @@ class BrowserHoverTool implements Tool {
|
|
|
483
437
|
description:
|
|
484
438
|
"A CSS selector to target. Used as fallback when element_id is not available.",
|
|
485
439
|
},
|
|
486
|
-
reason: {
|
|
487
|
-
type: "string",
|
|
488
|
-
description:
|
|
489
|
-
"Brief non-technical explanation of what you are hovering over and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
490
|
-
},
|
|
491
440
|
},
|
|
492
441
|
},
|
|
493
442
|
};
|
|
@@ -537,11 +486,6 @@ class BrowserWaitForTool implements Tool {
|
|
|
537
486
|
description:
|
|
538
487
|
"Maximum wait time in milliseconds (default and max: 30000).",
|
|
539
488
|
},
|
|
540
|
-
reason: {
|
|
541
|
-
type: "string",
|
|
542
|
-
description:
|
|
543
|
-
"Brief non-technical explanation of what you are waiting for and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
544
|
-
},
|
|
545
489
|
},
|
|
546
490
|
},
|
|
547
491
|
};
|
|
@@ -578,11 +522,6 @@ class BrowserExtractTool implements Tool {
|
|
|
578
522
|
description:
|
|
579
523
|
"If true, include a list of links found on the page (up to 200).",
|
|
580
524
|
},
|
|
581
|
-
reason: {
|
|
582
|
-
type: "string",
|
|
583
|
-
description:
|
|
584
|
-
"Brief non-technical explanation of what you are extracting and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
585
|
-
},
|
|
586
525
|
},
|
|
587
526
|
},
|
|
588
527
|
};
|
|
@@ -634,11 +573,6 @@ class BrowserFillCredentialTool implements Tool {
|
|
|
634
573
|
type: "boolean",
|
|
635
574
|
description: "Press Enter after filling",
|
|
636
575
|
},
|
|
637
|
-
reason: {
|
|
638
|
-
type: "string",
|
|
639
|
-
description:
|
|
640
|
-
"Brief non-technical explanation of what you are filling in and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
641
|
-
},
|
|
642
576
|
},
|
|
643
577
|
required: ["service", "field"],
|
|
644
578
|
},
|
|
@@ -123,11 +123,6 @@ export const claudeCodeTool: Tool = {
|
|
|
123
123
|
description:
|
|
124
124
|
"Worker profile that scopes tool access. Defaults to general (backward compatible).",
|
|
125
125
|
},
|
|
126
|
-
reason: {
|
|
127
|
-
type: "string",
|
|
128
|
-
description:
|
|
129
|
-
"Brief non-technical explanation of what you are delegating and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
130
|
-
},
|
|
131
126
|
},
|
|
132
127
|
},
|
|
133
128
|
};
|
|
@@ -34,7 +34,7 @@ const reasonProperty = {
|
|
|
34
34
|
export const computerUseClickTool: Tool = {
|
|
35
35
|
name: "computer_use_click",
|
|
36
36
|
description:
|
|
37
|
-
"Click
|
|
37
|
+
"Click an element on screen. Prefer element_id (from the accessibility tree) over x/y coordinates.",
|
|
38
38
|
category: "computer-use",
|
|
39
39
|
defaultRiskLevel: RiskLevel.Low,
|
|
40
40
|
executionMode: "proxy",
|
|
@@ -86,7 +86,7 @@ export const computerUseClickTool: Tool = {
|
|
|
86
86
|
export const computerUseTypeTextTool: Tool = {
|
|
87
87
|
name: "computer_use_type_text",
|
|
88
88
|
description:
|
|
89
|
-
"Type text at the current cursor position.
|
|
89
|
+
"Type text at the current cursor position. First click a text field (by element_id) to focus it, then call this tool. If a field shows 'FOCUSED', skip the click.",
|
|
90
90
|
category: "computer-use",
|
|
91
91
|
defaultRiskLevel: RiskLevel.Low,
|
|
92
92
|
executionMode: "proxy",
|
|
@@ -352,13 +352,7 @@ export const computerUseOpenAppTool: Tool = {
|
|
|
352
352
|
export const computerUseRunAppleScriptTool: Tool = {
|
|
353
353
|
name: "computer_use_run_applescript",
|
|
354
354
|
description:
|
|
355
|
-
"
|
|
356
|
-
"Use this for operations that are more reliable through scripting than UI interaction: " +
|
|
357
|
-
"setting a browser URL directly, navigating Finder to a path, querying app state " +
|
|
358
|
-
"(tab count, window titles, document status), or clicking deeply nested menu items. " +
|
|
359
|
-
"The script's return value (if any) will be reported back. " +
|
|
360
|
-
'NEVER use "do shell script" — it is blocked for security. ' +
|
|
361
|
-
"Keep scripts short and targeted to a single operation.",
|
|
355
|
+
"Run an AppleScript command. Prefer this over click/type when possible — it doesn't move the cursor or interrupt the user. Never use 'do shell script' inside AppleScript (blocked for security).",
|
|
362
356
|
category: "computer-use",
|
|
363
357
|
defaultRiskLevel: RiskLevel.Low,
|
|
364
358
|
executionMode: "proxy",
|
|
@@ -395,7 +389,8 @@ export const computerUseRunAppleScriptTool: Tool = {
|
|
|
395
389
|
|
|
396
390
|
export const computerUseDoneTool: Tool = {
|
|
397
391
|
name: "computer_use_done",
|
|
398
|
-
description:
|
|
392
|
+
description:
|
|
393
|
+
"Signal that the computer use task is complete. Provide a summary of what was accomplished. This ends the computer use session.",
|
|
399
394
|
category: "computer-use",
|
|
400
395
|
defaultRiskLevel: RiskLevel.Low,
|
|
401
396
|
executionMode: "proxy",
|
|
@@ -428,7 +423,7 @@ export const computerUseDoneTool: Tool = {
|
|
|
428
423
|
export const computerUseRespondTool: Tool = {
|
|
429
424
|
name: "computer_use_respond",
|
|
430
425
|
description:
|
|
431
|
-
"Respond
|
|
426
|
+
"Respond to the user with a text answer instead of performing computer actions. Use this when you can answer directly without interacting with the screen.",
|
|
432
427
|
category: "computer-use",
|
|
433
428
|
defaultRiskLevel: RiskLevel.Low,
|
|
434
429
|
executionMode: "proxy",
|
|
@@ -458,11 +453,41 @@ export const computerUseRespondTool: Tool = {
|
|
|
458
453
|
execute: proxyExecute,
|
|
459
454
|
};
|
|
460
455
|
|
|
456
|
+
// ---------------------------------------------------------------------------
|
|
457
|
+
// observe
|
|
458
|
+
// ---------------------------------------------------------------------------
|
|
459
|
+
|
|
460
|
+
export const computerUseObserveTool: Tool = {
|
|
461
|
+
name: "computer_use_observe",
|
|
462
|
+
description:
|
|
463
|
+
"Capture the current screen state. Returns the accessibility tree with [ID] element references and optionally a screenshot.\n\nThe accessibility tree shows interactive elements like [3] AXButton 'Save' or [17] AXTextField 'Search'. Use element_id to target these elements in subsequent actions — this is much more reliable than pixel coordinates.\n\nCall this before your first computer use action, or to check screen state without acting.",
|
|
464
|
+
category: "computer-use",
|
|
465
|
+
defaultRiskLevel: RiskLevel.Low,
|
|
466
|
+
executionMode: "proxy",
|
|
467
|
+
|
|
468
|
+
getDefinition(): ToolDefinition {
|
|
469
|
+
return {
|
|
470
|
+
name: this.name,
|
|
471
|
+
description: this.description,
|
|
472
|
+
input_schema: {
|
|
473
|
+
type: "object",
|
|
474
|
+
properties: {
|
|
475
|
+
reason: reasonProperty,
|
|
476
|
+
},
|
|
477
|
+
required: ["reason"],
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
execute: proxyExecute,
|
|
483
|
+
};
|
|
484
|
+
|
|
461
485
|
// ---------------------------------------------------------------------------
|
|
462
486
|
// All tools exported as array for convenience
|
|
463
487
|
// ---------------------------------------------------------------------------
|
|
464
488
|
|
|
465
489
|
export const allComputerUseTools: Tool[] = [
|
|
490
|
+
computerUseObserveTool,
|
|
466
491
|
computerUseClickTool,
|
|
467
492
|
computerUseTypeTextTool,
|
|
468
493
|
computerUseKeyTool,
|
|
@@ -474,3 +499,13 @@ export const allComputerUseTools: Tool[] = [
|
|
|
474
499
|
computerUseDoneTool,
|
|
475
500
|
computerUseRespondTool,
|
|
476
501
|
];
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Tools safe for the legacy fallback path (no skill projection).
|
|
505
|
+
*
|
|
506
|
+
* Excludes `computer_use_observe` because the macOS client doesn't handle it
|
|
507
|
+
* in the legacy code path — it falls back to `.done` which skips sending an
|
|
508
|
+
* observation, causing the daemon to block on `pendingObservation` until timeout.
|
|
509
|
+
*/
|
|
510
|
+
export const legacyFallbackComputerUseTools: Tool[] =
|
|
511
|
+
allComputerUseTools.filter((t) => t.name !== "computer_use_observe");
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Registers computer-use tools with the daemon's tool registry.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* normal startup.
|
|
4
|
+
* The computer_use_* action tools are now provided by the bundled
|
|
5
|
+
* computer-use skill. This module retains registerComputerUseActionTools()
|
|
6
|
+
* for backward compatibility (used by tests), but it is no longer called
|
|
7
|
+
* during normal startup.
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
import { registerTool } from "../registry.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
|
|
3
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
3
4
|
import { getSecureKey } from "../../security/secure-keys.js";
|
|
4
5
|
import { getLogger } from "../../util/logger.js";
|
|
5
6
|
import type {
|
|
@@ -46,7 +47,7 @@ export class CredentialBroker {
|
|
|
46
47
|
* browserFill or consume call for this service/field pair, then discarded.
|
|
47
48
|
*/
|
|
48
49
|
injectTransient(service: string, field: string, value: string): void {
|
|
49
|
-
const key =
|
|
50
|
+
const key = credentialKey(service, field);
|
|
50
51
|
this.transientValues.set(key, { value });
|
|
51
52
|
log.info(
|
|
52
53
|
{ service, field },
|
|
@@ -123,7 +124,7 @@ export class CredentialBroker {
|
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
token.consumed = true;
|
|
126
|
-
const storageKey =
|
|
127
|
+
const storageKey = credentialKey(token.service, token.field);
|
|
127
128
|
// Check for transient value first (one-time send) — consume and return the value
|
|
128
129
|
// directly since transient values are never persisted to secure storage.
|
|
129
130
|
const transient = this.transientValues.get(storageKey);
|
|
@@ -211,7 +212,7 @@ export class CredentialBroker {
|
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
|
|
214
|
-
const storageKey =
|
|
215
|
+
const storageKey = credentialKey(request.service, request.field);
|
|
215
216
|
// Check transient values first (one-time send), then fall back to keychain.
|
|
216
217
|
// Deletion is deferred until after a successful fill so the value survives
|
|
217
218
|
// transient failures (e.g. stale element, page navigation, Playwright timeout).
|
|
@@ -299,7 +300,7 @@ export class CredentialBroker {
|
|
|
299
300
|
};
|
|
300
301
|
}
|
|
301
302
|
|
|
302
|
-
const storageKey =
|
|
303
|
+
const storageKey = credentialKey(request.service, request.field);
|
|
303
304
|
const transient = this.transientValues.get(storageKey);
|
|
304
305
|
const value = transient?.value ?? getSecureKey(storageKey);
|
|
305
306
|
if (!value) {
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* Persists non-secret metadata about credentials (policy, timestamps, IDs)
|
|
5
5
|
* in a versioned JSON file under protected storage. Secret values remain
|
|
6
6
|
* in the secure key backend only.
|
|
7
|
+
*
|
|
8
|
+
* OAuth-specific fields (expiresAt, grantedScopes, oauth2TokenUrl,
|
|
9
|
+
* oauth2ClientId, oauth2TokenEndpointAuthMethod, hasRefreshToken) are now
|
|
10
|
+
* exclusively managed by the SQLite oauth-store and have been removed
|
|
11
|
+
* from this interface as of v5.
|
|
7
12
|
*/
|
|
8
13
|
|
|
9
14
|
import { randomUUID } from "node:crypto";
|
|
@@ -21,16 +26,6 @@ export interface CredentialMetadata {
|
|
|
21
26
|
allowedTools: string[];
|
|
22
27
|
allowedDomains: string[];
|
|
23
28
|
usageDescription?: string;
|
|
24
|
-
expiresAt?: number;
|
|
25
|
-
grantedScopes?: string[];
|
|
26
|
-
/** OAuth2 token endpoint — enables autonomous token refresh without an IntegrationDefinition. */
|
|
27
|
-
oauth2TokenUrl?: string;
|
|
28
|
-
/** OAuth2 client ID — paired with oauth2TokenUrl for refresh. */
|
|
29
|
-
oauth2ClientId?: string;
|
|
30
|
-
/** OAuth2 client secret — for providers that require it (e.g. Slack). Stored in metadata for autonomous refresh. */
|
|
31
|
-
oauth2ClientSecret?: string;
|
|
32
|
-
/** How the client authenticates at the token endpoint (client_secret_basic or client_secret_post). */
|
|
33
|
-
oauth2TokenEndpointAuthMethod?: string;
|
|
34
29
|
/** Human-friendly name for this credential (e.g. "fal-primary"). */
|
|
35
30
|
alias?: string;
|
|
36
31
|
/** Templates describing how to inject this credential into proxied requests. */
|
|
@@ -40,7 +35,7 @@ export interface CredentialMetadata {
|
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
/** Current on-disk schema version. */
|
|
43
|
-
const CURRENT_VERSION =
|
|
38
|
+
const CURRENT_VERSION = 5;
|
|
44
39
|
|
|
45
40
|
interface MetadataFile {
|
|
46
41
|
version: typeof CURRENT_VERSION;
|
|
@@ -88,9 +83,10 @@ function isValidCredentialRecord(
|
|
|
88
83
|
}
|
|
89
84
|
|
|
90
85
|
/**
|
|
91
|
-
* Migrate
|
|
86
|
+
* Migrate any record to v5 by stripping OAuth-specific fields that are
|
|
87
|
+
* now exclusively managed by the SQLite oauth-store.
|
|
92
88
|
*/
|
|
93
|
-
function
|
|
89
|
+
function migrateRecordToV5(
|
|
94
90
|
record: Record<string, unknown>,
|
|
95
91
|
): CredentialMetadata {
|
|
96
92
|
return {
|
|
@@ -107,27 +103,6 @@ function migrateRecordV1toV2(
|
|
|
107
103
|
typeof record.usageDescription === "string"
|
|
108
104
|
? record.usageDescription
|
|
109
105
|
: undefined,
|
|
110
|
-
expiresAt:
|
|
111
|
-
typeof record.expiresAt === "number" ? record.expiresAt : undefined,
|
|
112
|
-
grantedScopes: Array.isArray(record.grantedScopes)
|
|
113
|
-
? (record.grantedScopes as string[])
|
|
114
|
-
: undefined,
|
|
115
|
-
oauth2TokenUrl:
|
|
116
|
-
typeof record.oauth2TokenUrl === "string"
|
|
117
|
-
? record.oauth2TokenUrl
|
|
118
|
-
: undefined,
|
|
119
|
-
oauth2ClientId:
|
|
120
|
-
typeof record.oauth2ClientId === "string"
|
|
121
|
-
? record.oauth2ClientId
|
|
122
|
-
: undefined,
|
|
123
|
-
oauth2ClientSecret:
|
|
124
|
-
typeof record.oauth2ClientSecret === "string"
|
|
125
|
-
? record.oauth2ClientSecret
|
|
126
|
-
: undefined,
|
|
127
|
-
oauth2TokenEndpointAuthMethod:
|
|
128
|
-
typeof record.oauth2TokenEndpointAuthMethod === "string"
|
|
129
|
-
? record.oauth2TokenEndpointAuthMethod
|
|
130
|
-
: undefined,
|
|
131
106
|
alias: typeof record.alias === "string" ? record.alias : undefined,
|
|
132
107
|
injectionTemplates: Array.isArray(record.injectionTemplates)
|
|
133
108
|
? (record.injectionTemplates as CredentialInjectionTemplate[])
|
|
@@ -148,7 +123,13 @@ function loadFile(): LoadResult {
|
|
|
148
123
|
return { version: CURRENT_VERSION, credentials: [] };
|
|
149
124
|
}
|
|
150
125
|
const fileVersion = typeof data.version === "number" ? data.version : 1;
|
|
151
|
-
if (
|
|
126
|
+
if (
|
|
127
|
+
fileVersion !== 1 &&
|
|
128
|
+
fileVersion !== 2 &&
|
|
129
|
+
fileVersion !== 3 &&
|
|
130
|
+
fileVersion !== 4 &&
|
|
131
|
+
fileVersion !== 5
|
|
132
|
+
) {
|
|
152
133
|
// Unrecognized version (future, fractional, negative, zero) — refuse to touch it
|
|
153
134
|
return { unknownVersion: true };
|
|
154
135
|
}
|
|
@@ -159,8 +140,12 @@ function loadFile(): LoadResult {
|
|
|
159
140
|
const validRecords = rawCredentials.filter(isValidCredentialRecord);
|
|
160
141
|
|
|
161
142
|
if (fileVersion < CURRENT_VERSION) {
|
|
162
|
-
// Migrate
|
|
163
|
-
|
|
143
|
+
// Migrate all older versions to v5 by stripping OAuth-specific fields
|
|
144
|
+
// and removing ghost refresh_token records
|
|
145
|
+
const filtered = validRecords.filter(
|
|
146
|
+
(r) => (r as Record<string, unknown>).field !== "refresh_token",
|
|
147
|
+
);
|
|
148
|
+
const credentials = filtered.map(migrateRecordToV5);
|
|
164
149
|
const migrated: MetadataFile = { version: CURRENT_VERSION, credentials };
|
|
165
150
|
try {
|
|
166
151
|
saveFile(migrated);
|
|
@@ -214,14 +199,6 @@ export function upsertCredentialMetadata(
|
|
|
214
199
|
allowedTools?: string[];
|
|
215
200
|
allowedDomains?: string[];
|
|
216
201
|
usageDescription?: string;
|
|
217
|
-
/** Pass `null` to explicitly clear a previously-set expiry. */
|
|
218
|
-
expiresAt?: number | null;
|
|
219
|
-
grantedScopes?: string[];
|
|
220
|
-
oauth2TokenUrl?: string;
|
|
221
|
-
oauth2ClientId?: string;
|
|
222
|
-
/** Pass `null` to explicitly clear a previously-set client secret. */
|
|
223
|
-
oauth2ClientSecret?: string | null;
|
|
224
|
-
oauth2TokenEndpointAuthMethod?: string;
|
|
225
202
|
/** Pass `null` to explicitly clear a previously-set alias. */
|
|
226
203
|
alias?: string | null;
|
|
227
204
|
/** Pass `null` to explicitly clear injection templates. */
|
|
@@ -248,29 +225,6 @@ export function upsertCredentialMetadata(
|
|
|
248
225
|
existing.allowedDomains = policy.allowedDomains;
|
|
249
226
|
if (policy?.usageDescription !== undefined)
|
|
250
227
|
existing.usageDescription = policy.usageDescription;
|
|
251
|
-
if (policy?.expiresAt !== undefined) {
|
|
252
|
-
if (policy.expiresAt == null) {
|
|
253
|
-
delete existing.expiresAt;
|
|
254
|
-
} else {
|
|
255
|
-
existing.expiresAt = policy.expiresAt;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
if (policy?.grantedScopes !== undefined)
|
|
259
|
-
existing.grantedScopes = policy.grantedScopes;
|
|
260
|
-
if (policy?.oauth2TokenUrl !== undefined)
|
|
261
|
-
existing.oauth2TokenUrl = policy.oauth2TokenUrl;
|
|
262
|
-
if (policy?.oauth2ClientId !== undefined)
|
|
263
|
-
existing.oauth2ClientId = policy.oauth2ClientId;
|
|
264
|
-
if (policy?.oauth2ClientSecret !== undefined) {
|
|
265
|
-
if (policy.oauth2ClientSecret == null) {
|
|
266
|
-
delete existing.oauth2ClientSecret;
|
|
267
|
-
} else {
|
|
268
|
-
existing.oauth2ClientSecret = policy.oauth2ClientSecret;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
if (policy?.oauth2TokenEndpointAuthMethod !== undefined)
|
|
272
|
-
existing.oauth2TokenEndpointAuthMethod =
|
|
273
|
-
policy.oauth2TokenEndpointAuthMethod;
|
|
274
228
|
if (policy?.alias !== undefined) {
|
|
275
229
|
if (policy.alias == null) {
|
|
276
230
|
delete existing.alias;
|
|
@@ -297,12 +251,6 @@ export function upsertCredentialMetadata(
|
|
|
297
251
|
allowedTools: policy?.allowedTools ?? [],
|
|
298
252
|
allowedDomains: policy?.allowedDomains ?? [],
|
|
299
253
|
usageDescription: policy?.usageDescription,
|
|
300
|
-
expiresAt: policy?.expiresAt ?? undefined,
|
|
301
|
-
grantedScopes: policy?.grantedScopes,
|
|
302
|
-
oauth2TokenUrl: policy?.oauth2TokenUrl,
|
|
303
|
-
oauth2ClientId: policy?.oauth2ClientId,
|
|
304
|
-
oauth2ClientSecret: policy?.oauth2ClientSecret ?? undefined,
|
|
305
|
-
oauth2TokenEndpointAuthMethod: policy?.oauth2TokenEndpointAuthMethod,
|
|
306
254
|
alias: policy?.alias ?? undefined,
|
|
307
255
|
injectionTemplates: policy?.injectionTemplates ?? undefined,
|
|
308
256
|
createdAt: now,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* secure key naming convention.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
9
10
|
import { matchHostPattern } from "./host-pattern-match.js";
|
|
10
11
|
import {
|
|
11
12
|
type CredentialMetadata,
|
|
@@ -33,7 +34,7 @@ function toResolved(metadata: CredentialMetadata): ResolvedCredential {
|
|
|
33
34
|
credentialId: metadata.credentialId,
|
|
34
35
|
service: metadata.service,
|
|
35
36
|
field: metadata.field,
|
|
36
|
-
storageKey:
|
|
37
|
+
storageKey: credentialKey(metadata.service, metadata.field),
|
|
37
38
|
alias: metadata.alias,
|
|
38
39
|
injectionTemplates: metadata.injectionTemplates ?? [],
|
|
39
40
|
metadata,
|