@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
|
@@ -14,9 +14,15 @@ import { loadSkillCatalog } from "../../config/skills.js";
|
|
|
14
14
|
import { normalizeActivationKey } from "../../daemon/handlers/config-voice.js";
|
|
15
15
|
import { orchestrateOAuthConnect } from "../../oauth/connect-orchestrator.js";
|
|
16
16
|
import {
|
|
17
|
-
|
|
17
|
+
getApp,
|
|
18
|
+
getConnectionByProvider,
|
|
19
|
+
getMostRecentAppByProvider,
|
|
20
|
+
getProvider,
|
|
21
|
+
} from "../../oauth/oauth-store.js";
|
|
22
|
+
import {
|
|
23
|
+
getProviderBehavior,
|
|
18
24
|
resolveService,
|
|
19
|
-
} from "../../oauth/provider-
|
|
25
|
+
} from "../../oauth/provider-behaviors.js";
|
|
20
26
|
import {
|
|
21
27
|
check,
|
|
22
28
|
classifyRisk,
|
|
@@ -25,17 +31,23 @@ import {
|
|
|
25
31
|
} from "../../permissions/checker.js";
|
|
26
32
|
import { getSecureKey } from "../../security/secure-keys.js";
|
|
27
33
|
import { parseToolManifestFile } from "../../skills/tool-manifest.js";
|
|
28
|
-
import { assertMetadataWritable } from "../../tools/credentials/metadata-store.js";
|
|
29
34
|
import {
|
|
30
35
|
type ManifestOverride,
|
|
31
36
|
resolveExecutionTarget,
|
|
32
37
|
} from "../../tools/execution-target.js";
|
|
33
38
|
import { getAllTools, getTool } from "../../tools/registry.js";
|
|
39
|
+
import {
|
|
40
|
+
injectReasonField,
|
|
41
|
+
REASON_SKIP_SET,
|
|
42
|
+
} from "../../tools/schema-transforms.js";
|
|
34
43
|
import { isSideEffectTool } from "../../tools/side-effects.js";
|
|
35
44
|
import { setAvatarTool } from "../../tools/system/avatar-generator.js";
|
|
36
45
|
import { pathExists } from "../../util/fs.js";
|
|
37
46
|
import { getLogger } from "../../util/logger.js";
|
|
38
47
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
48
|
+
import { buildAssistantEvent } from "../assistant-event.js";
|
|
49
|
+
import { assistantEventHub } from "../assistant-event-hub.js";
|
|
50
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
39
51
|
import { httpError } from "../http-errors.js";
|
|
40
52
|
import type { RouteDefinition } from "../http-router.js";
|
|
41
53
|
import { resolveWorkspacePath } from "./workspace-utils.js";
|
|
@@ -128,43 +140,39 @@ function sanitizeOAuthError(message: string): string {
|
|
|
128
140
|
return "OAuth authentication failed. Please try again.";
|
|
129
141
|
}
|
|
130
142
|
|
|
131
|
-
/** Resolve client_secret from the keychain, checking canonical then alias service name. */
|
|
132
|
-
function getClientSecret(
|
|
133
|
-
resolvedService: string,
|
|
134
|
-
rawService: string,
|
|
135
|
-
): string | undefined {
|
|
136
|
-
return (
|
|
137
|
-
getSecureKey(`credential:${resolvedService}:client_secret`) ??
|
|
138
|
-
(resolvedService !== rawService
|
|
139
|
-
? getSecureKey(`credential:${rawService}:client_secret`)
|
|
140
|
-
: undefined) ??
|
|
141
|
-
undefined
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
143
|
async function handleOAuthConnectStart(body: {
|
|
146
144
|
service?: string;
|
|
147
145
|
requestedScopes?: string[];
|
|
148
146
|
}): Promise<Response> {
|
|
149
|
-
try {
|
|
150
|
-
assertMetadataWritable();
|
|
151
|
-
} catch {
|
|
152
|
-
return httpError(
|
|
153
|
-
"UNPROCESSABLE_ENTITY",
|
|
154
|
-
"Credential metadata file has an unrecognized version. Cannot store OAuth credentials.",
|
|
155
|
-
422,
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
147
|
if (!body.service) {
|
|
160
148
|
return httpError("BAD_REQUEST", "Missing required field: service", 400);
|
|
161
149
|
}
|
|
162
150
|
|
|
163
151
|
const resolvedService = resolveService(body.service);
|
|
164
152
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
153
|
+
// Resolve client_id and client_secret from oauth-store.
|
|
154
|
+
let clientId: string | undefined;
|
|
155
|
+
let clientSecret: string | undefined;
|
|
156
|
+
|
|
157
|
+
// Try existing connection first (re-auth flow)
|
|
158
|
+
const conn = getConnectionByProvider(resolvedService);
|
|
159
|
+
if (conn) {
|
|
160
|
+
const app = getApp(conn.oauthAppId);
|
|
161
|
+
if (app) {
|
|
162
|
+
clientId = app.clientId;
|
|
163
|
+
clientSecret = getSecureKey(`oauth_app/${app.id}/client_secret`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Fall back to most recent app for this provider (first-time connect with stored app)
|
|
168
|
+
if (!clientId) {
|
|
169
|
+
const dbApp = getMostRecentAppByProvider(resolvedService);
|
|
170
|
+
if (dbApp) {
|
|
171
|
+
clientId = dbApp.clientId;
|
|
172
|
+
if (!clientSecret) {
|
|
173
|
+
clientSecret = getSecureKey(`oauth_app/${dbApp.id}/client_secret`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
if (!clientId) {
|
|
@@ -175,12 +183,11 @@ async function handleOAuthConnectStart(body: {
|
|
|
175
183
|
);
|
|
176
184
|
}
|
|
177
185
|
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
const profile = getProviderProfile(resolvedService);
|
|
186
|
+
const behavior = getProviderBehavior(resolvedService);
|
|
187
|
+
const providerRow = getProvider(resolvedService);
|
|
181
188
|
const requiresSecret =
|
|
182
|
-
|
|
183
|
-
!!(
|
|
189
|
+
behavior?.setup?.requiresClientSecret ??
|
|
190
|
+
!!(providerRow?.tokenEndpointAuthMethod || providerRow?.extraParams);
|
|
184
191
|
if (requiresSecret && !clientSecret) {
|
|
185
192
|
return httpError(
|
|
186
193
|
"BAD_REQUEST",
|
|
@@ -203,6 +210,45 @@ async function handleOAuthConnectStart(body: {
|
|
|
203
210
|
openUrl: (url: string) => {
|
|
204
211
|
authUrl = url;
|
|
205
212
|
},
|
|
213
|
+
onDeferredComplete: (deferredResult) => {
|
|
214
|
+
// Prefer accountInfo from oauth-store when available.
|
|
215
|
+
let accountInfo = deferredResult.accountInfo;
|
|
216
|
+
try {
|
|
217
|
+
const conn = getConnectionByProvider(resolvedService);
|
|
218
|
+
if (conn?.accountInfo) accountInfo = conn.accountInfo;
|
|
219
|
+
} catch {
|
|
220
|
+
// DB not ready — use orchestrator value
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Emit oauth_connect_result to all connected SSE clients so the
|
|
224
|
+
// UI can update immediately when the deferred browser flow completes.
|
|
225
|
+
assistantEventHub
|
|
226
|
+
.publish(
|
|
227
|
+
buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
|
|
228
|
+
type: "oauth_connect_result",
|
|
229
|
+
success: deferredResult.success,
|
|
230
|
+
service: deferredResult.service,
|
|
231
|
+
accountInfo,
|
|
232
|
+
error: deferredResult.error,
|
|
233
|
+
}),
|
|
234
|
+
)
|
|
235
|
+
.catch((err) => {
|
|
236
|
+
log.warn(
|
|
237
|
+
{ err, service: deferredResult.service },
|
|
238
|
+
"Failed to publish oauth_connect_result event",
|
|
239
|
+
);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
if (!deferredResult.success) {
|
|
243
|
+
log.warn(
|
|
244
|
+
{
|
|
245
|
+
service: deferredResult.service,
|
|
246
|
+
err: deferredResult.error,
|
|
247
|
+
},
|
|
248
|
+
"Deferred OAuth connect failed",
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
},
|
|
206
252
|
});
|
|
207
253
|
|
|
208
254
|
if (!result.success) {
|
|
@@ -225,10 +271,19 @@ async function handleOAuthConnectStart(body: {
|
|
|
225
271
|
});
|
|
226
272
|
}
|
|
227
273
|
|
|
274
|
+
// Prefer accountInfo from oauth-store when available.
|
|
275
|
+
let responseAccountInfo = result.accountInfo;
|
|
276
|
+
try {
|
|
277
|
+
const conn = getConnectionByProvider(resolvedService);
|
|
278
|
+
if (conn?.accountInfo) responseAccountInfo = conn.accountInfo;
|
|
279
|
+
} catch {
|
|
280
|
+
// DB not ready — use orchestrator value
|
|
281
|
+
}
|
|
282
|
+
|
|
228
283
|
return Response.json({
|
|
229
284
|
ok: true,
|
|
230
285
|
grantedScopes: result.grantedScopes,
|
|
231
|
-
accountInfo:
|
|
286
|
+
accountInfo: responseAccountInfo,
|
|
232
287
|
...(authUrl ? { authUrl } : {}),
|
|
233
288
|
});
|
|
234
289
|
} catch (err) {
|
|
@@ -309,23 +364,34 @@ function resolveManifestOverride(
|
|
|
309
364
|
function handleToolNamesList(): Response {
|
|
310
365
|
const tools = getAllTools();
|
|
311
366
|
const nameSet = new Set(tools.map((t) => t.name));
|
|
312
|
-
|
|
313
|
-
string
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
367
|
+
type SchemaShape = {
|
|
368
|
+
type: string;
|
|
369
|
+
properties?: Record<string, unknown>;
|
|
370
|
+
required?: string[];
|
|
371
|
+
};
|
|
372
|
+
const schemas: Record<string, SchemaShape> = {};
|
|
373
|
+
|
|
374
|
+
// Collect raw definitions from the registry so we can transform them.
|
|
375
|
+
const rawDefs: import("../../providers/types.js").ToolDefinition[] = [];
|
|
320
376
|
for (const tool of tools) {
|
|
321
377
|
try {
|
|
322
|
-
|
|
323
|
-
schemas[tool.name] = def.input_schema as (typeof schemas)[string];
|
|
378
|
+
rawDefs.push(tool.getDefinition());
|
|
324
379
|
} catch {
|
|
325
380
|
// Skip tools whose definitions can't be resolved
|
|
326
381
|
}
|
|
327
382
|
}
|
|
328
383
|
|
|
384
|
+
// Apply reason injection so settings/debug schemas match runtime behavior.
|
|
385
|
+
const transformedDefs = injectReasonField(rawDefs, REASON_SKIP_SET);
|
|
386
|
+
for (const def of transformedDefs) {
|
|
387
|
+
schemas[def.name] = def.input_schema as SchemaShape;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Skill manifest schemas are served raw (untransformed). Unlike runtime tool
|
|
391
|
+
// schemas which have `reason` injected via injectReasonField(), skill manifests
|
|
392
|
+
// reflect the original TOOLS.json content. This is intentional: skill tools are
|
|
393
|
+
// invoked through skill_execute (which has its own reason field), so their
|
|
394
|
+
// individual schemas are never sent to the LLM directly.
|
|
329
395
|
try {
|
|
330
396
|
const catalog = loadSkillCatalog();
|
|
331
397
|
for (const skill of catalog) {
|
|
@@ -337,8 +403,7 @@ function handleToolNamesList(): Response {
|
|
|
337
403
|
for (const entry of manifest.tools) {
|
|
338
404
|
if (nameSet.has(entry.name)) continue;
|
|
339
405
|
nameSet.add(entry.name);
|
|
340
|
-
schemas[entry.name] =
|
|
341
|
-
entry.input_schema as unknown as (typeof schemas)[string];
|
|
406
|
+
schemas[entry.name] = entry.input_schema as unknown as SchemaShape;
|
|
342
407
|
}
|
|
343
408
|
} catch {
|
|
344
409
|
// Skip skills whose manifests can't be parsed
|
|
@@ -10,7 +10,7 @@ import type { RouteDefinition } from "../http-router.js";
|
|
|
10
10
|
|
|
11
11
|
const log = getLogger("surface-action-routes");
|
|
12
12
|
|
|
13
|
-
/** Any object that can handle a surface action
|
|
13
|
+
/** Any object that can handle a surface action. */
|
|
14
14
|
interface SurfaceActionTarget {
|
|
15
15
|
handleSurfaceAction(
|
|
16
16
|
surfaceId: string,
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP route handler for watch (ambient observation) functionality.
|
|
3
|
+
*
|
|
4
|
+
* Decoupled from computer-use routes so that the watch endpoint has
|
|
5
|
+
* zero dependency on CU session state.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { getLogger } from "../../util/logger.js";
|
|
9
|
+
import { httpError } from "../http-errors.js";
|
|
10
|
+
import type { RouteDefinition } from "../http-router.js";
|
|
11
|
+
|
|
12
|
+
const log = getLogger("watch-routes");
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Dependency injection interface
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Minimal interface for watch observation handling.
|
|
20
|
+
* The daemon wires a concrete implementation at startup.
|
|
21
|
+
*/
|
|
22
|
+
export interface WatchDeps {
|
|
23
|
+
/** Handle a watch observation. */
|
|
24
|
+
handleWatchObservation: (params: {
|
|
25
|
+
watchId: string;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
ocrText: string;
|
|
28
|
+
appName?: string;
|
|
29
|
+
windowTitle?: string;
|
|
30
|
+
bundleIdentifier?: string;
|
|
31
|
+
timestamp: number;
|
|
32
|
+
captureIndex: number;
|
|
33
|
+
totalExpected: number;
|
|
34
|
+
}) => Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Route handler
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* POST /v1/computer-use/watch — send a watch observation.
|
|
43
|
+
*
|
|
44
|
+
* Body: { watchId, sessionId, ocrText, appName?, windowTitle?,
|
|
45
|
+
* bundleIdentifier?, timestamp, captureIndex, totalExpected }
|
|
46
|
+
*/
|
|
47
|
+
async function handleWatchObservationRoute(
|
|
48
|
+
req: Request,
|
|
49
|
+
deps: WatchDeps,
|
|
50
|
+
): Promise<Response> {
|
|
51
|
+
const body = (await req.json()) as {
|
|
52
|
+
watchId?: string;
|
|
53
|
+
sessionId?: string;
|
|
54
|
+
ocrText?: string;
|
|
55
|
+
appName?: string;
|
|
56
|
+
windowTitle?: string;
|
|
57
|
+
bundleIdentifier?: string;
|
|
58
|
+
timestamp?: number;
|
|
59
|
+
captureIndex?: number;
|
|
60
|
+
totalExpected?: number;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (!body.watchId || typeof body.watchId !== "string") {
|
|
64
|
+
return httpError("BAD_REQUEST", "watchId is required", 400);
|
|
65
|
+
}
|
|
66
|
+
if (!body.sessionId || typeof body.sessionId !== "string") {
|
|
67
|
+
return httpError("BAD_REQUEST", "sessionId is required", 400);
|
|
68
|
+
}
|
|
69
|
+
if (!body.ocrText || typeof body.ocrText !== "string") {
|
|
70
|
+
return httpError("BAD_REQUEST", "ocrText is required", 400);
|
|
71
|
+
}
|
|
72
|
+
if (typeof body.timestamp !== "number") {
|
|
73
|
+
return httpError("BAD_REQUEST", "timestamp is required", 400);
|
|
74
|
+
}
|
|
75
|
+
if (typeof body.captureIndex !== "number") {
|
|
76
|
+
return httpError("BAD_REQUEST", "captureIndex is required", 400);
|
|
77
|
+
}
|
|
78
|
+
if (typeof body.totalExpected !== "number") {
|
|
79
|
+
return httpError("BAD_REQUEST", "totalExpected is required", 400);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
await deps.handleWatchObservation({
|
|
84
|
+
watchId: body.watchId,
|
|
85
|
+
sessionId: body.sessionId,
|
|
86
|
+
ocrText: body.ocrText,
|
|
87
|
+
appName: body.appName,
|
|
88
|
+
windowTitle: body.windowTitle,
|
|
89
|
+
bundleIdentifier: body.bundleIdentifier,
|
|
90
|
+
timestamp: body.timestamp,
|
|
91
|
+
captureIndex: body.captureIndex,
|
|
92
|
+
totalExpected: body.totalExpected,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return Response.json({ ok: true });
|
|
96
|
+
} catch (err) {
|
|
97
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
98
|
+
log.error(
|
|
99
|
+
{ err, watchId: body.watchId },
|
|
100
|
+
"Failed to handle watch observation via HTTP",
|
|
101
|
+
);
|
|
102
|
+
return httpError("INTERNAL_ERROR", message, 500);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Route definitions
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
export function watchRouteDefinitions(deps: {
|
|
111
|
+
getWatchDeps?: () => WatchDeps;
|
|
112
|
+
}): RouteDefinition[] {
|
|
113
|
+
const getDeps = (): WatchDeps => {
|
|
114
|
+
if (!deps.getWatchDeps) {
|
|
115
|
+
throw new Error("Watch deps not available");
|
|
116
|
+
}
|
|
117
|
+
return deps.getWatchDeps();
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return [
|
|
121
|
+
{
|
|
122
|
+
endpoint: "computer-use/watch",
|
|
123
|
+
method: "POST",
|
|
124
|
+
policyKey: "computer-use/watch",
|
|
125
|
+
handler: async ({ req }) => handleWatchObservationRoute(req, getDeps()),
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { hasTwilioCredentials } from "../calls/twilio-rest.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getConnectionByProvider,
|
|
4
|
+
isProviderConnected,
|
|
5
|
+
} from "../oauth/oauth-store.js";
|
|
3
6
|
|
|
4
7
|
interface IntegrationProbe {
|
|
5
8
|
name: string;
|
|
@@ -12,14 +15,12 @@ const INTEGRATION_PROBES: IntegrationProbe[] = [
|
|
|
12
15
|
{
|
|
13
16
|
name: "Gmail",
|
|
14
17
|
category: "email",
|
|
15
|
-
isConnected: () =>
|
|
16
|
-
!!getSecureKey("credential:integration:gmail:access_token"),
|
|
18
|
+
isConnected: () => isProviderConnected("integration:gmail"),
|
|
17
19
|
},
|
|
18
20
|
{
|
|
19
21
|
name: "Slack",
|
|
20
22
|
category: "messaging",
|
|
21
|
-
isConnected: () =>
|
|
22
|
-
!!getSecureKey("credential:integration:slack:access_token"),
|
|
23
|
+
isConnected: () => isProviderConnected("integration:slack"),
|
|
23
24
|
},
|
|
24
25
|
{
|
|
25
26
|
name: "Twilio",
|
|
@@ -29,9 +30,10 @@ const INTEGRATION_PROBES: IntegrationProbe[] = [
|
|
|
29
30
|
{
|
|
30
31
|
name: "Telegram",
|
|
31
32
|
category: "messaging",
|
|
32
|
-
isConnected: () =>
|
|
33
|
-
|
|
34
|
-
!!
|
|
33
|
+
isConnected: () => {
|
|
34
|
+
const conn = getConnectionByProvider("telegram");
|
|
35
|
+
return !!(conn && conn.status === "active");
|
|
36
|
+
},
|
|
35
37
|
},
|
|
36
38
|
];
|
|
37
39
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for credential key format in the secure store.
|
|
3
|
+
*
|
|
4
|
+
* Keys follow the pattern: credential/{service}/{field}
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Build a credential key for the secure store.
|
|
9
|
+
*
|
|
10
|
+
* @returns A key of the form `credential/{service}/{field}`
|
|
11
|
+
*/
|
|
12
|
+
export function credentialKey(service: string, field: string): string {
|
|
13
|
+
return `credential/${service}/${field}`;
|
|
14
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* provides a graceful-fallback interface: every public method returns a
|
|
7
7
|
* safe default on failure and never throws.
|
|
8
8
|
*
|
|
9
|
-
* Socket path:
|
|
9
|
+
* Socket path: derived from getRootDir() as `~/.vellum/keychain-broker.sock`.
|
|
10
10
|
* Auth token: read from ~/.vellum/protected/keychain-broker.token on first
|
|
11
11
|
* connection, cached for process lifetime.
|
|
12
12
|
*/
|
|
@@ -70,8 +70,8 @@ function getTokenPath(): string {
|
|
|
70
70
|
return join(getRootDir(), "protected", "keychain-broker.token");
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function getSocketPath(): string
|
|
74
|
-
return
|
|
73
|
+
function getSocketPath(): string {
|
|
74
|
+
return join(getRootDir(), "keychain-broker.sock");
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// ---------------------------------------------------------------------------
|
|
@@ -172,7 +172,7 @@ export function createBrokerClient(): KeychainBrokerClient {
|
|
|
172
172
|
function connect(): Promise<Socket> {
|
|
173
173
|
return new Promise((resolve, reject) => {
|
|
174
174
|
const socketPath = getSocketPath();
|
|
175
|
-
if (!socketPath) {
|
|
175
|
+
if (!pathExists(socketPath)) {
|
|
176
176
|
reject(new Error("No socket path"));
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
@@ -328,8 +328,7 @@ export function createBrokerClient(): KeychainBrokerClient {
|
|
|
328
328
|
return {
|
|
329
329
|
isAvailable(): boolean {
|
|
330
330
|
if (permanentlyUnavailable) return false;
|
|
331
|
-
|
|
332
|
-
if (!socketPath) return false;
|
|
331
|
+
if (!pathExists(getSocketPath())) return false;
|
|
333
332
|
return pathExists(getTokenPath());
|
|
334
333
|
},
|
|
335
334
|
|
package/src/security/oauth2.ts
CHANGED
|
@@ -691,7 +691,7 @@ export async function startOAuth2Flow(
|
|
|
691
691
|
if (transport === "gateway") {
|
|
692
692
|
if (!hasPublicUrl) {
|
|
693
693
|
throw new Error(
|
|
694
|
-
"Gateway transport requires a public ingress URL. Set ingress.publicBaseUrl
|
|
694
|
+
"Gateway transport requires a public ingress URL. Set ingress.publicBaseUrl, or use loopback transport.",
|
|
695
695
|
);
|
|
696
696
|
}
|
|
697
697
|
log.debug({ transport: "gateway" }, "OAuth2 flow starting");
|