@vellumai/assistant 0.6.2 → 0.6.3
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/bun.lock +40 -40
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +184 -69
- package/package.json +41 -41
- package/scripts/generate-openapi.ts +1 -2
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/browser-fill-credential.test.ts +229 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/catalog-files.test.ts +862 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +125 -48
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +1 -1
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-queue.test.ts +45 -2
- package/src/__tests__/conversation-routes-disk-view.test.ts +5 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +269 -46
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +4 -4
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +2 -2
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +155 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +375 -0
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/gemini-provider.test.ts +2 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +707 -371
- package/src/__tests__/headless-browser-navigate.test.ts +389 -47
- package/src/__tests__/headless-browser-read-tools.test.ts +266 -103
- package/src/__tests__/headless-browser-snapshot.test.ts +240 -77
- package/src/__tests__/host-bash-proxy.test.ts +150 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +462 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +320 -0
- package/src/__tests__/host-cu-proxy.test.ts +171 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +61 -2
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +101 -1
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +17 -12
- package/src/__tests__/oauth-cli.test.ts +707 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +116 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +146 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +50 -14
- package/src/__tests__/oauth-store.test.ts +1386 -182
- package/src/__tests__/oauth2-gateway-transport.test.ts +211 -20
- package/src/__tests__/onboarding-template-contract.test.ts +75 -57
- package/src/__tests__/openai-provider.test.ts +2 -2
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +1 -1
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +296 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/skills-file-content-endpoint.test.ts +670 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +450 -0
- package/src/__tests__/slack-channel-config.test.ts +12 -15
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +72 -1
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/terminal-tools.test.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/loop.ts +12 -6
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +53 -3
- package/src/cli/commands/browser-relay.ts +339 -409
- package/src/cli/commands/credentials.ts +3 -3
- package/src/cli/commands/email.ts +18 -13
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +44 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +31 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +329 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +116 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/providers.ts +200 -36
- package/src/cli/commands/oauth/shared.ts +5 -5
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +259 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +105 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/contacts/SKILL.md +3 -0
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +1 -1
- package/src/config/bundled-skills/outlook/SKILL.md +7 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/env-registry.ts +14 -0
- package/src/config/env.ts +21 -0
- package/src/config/feature-flag-registry.json +44 -5
- package/src/config/loader.ts +56 -1
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +46 -5
- package/src/config/schemas/host-browser.ts +66 -0
- package/src/config/schemas/memory-lifecycle.ts +1 -1
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +8 -0
- package/src/config/types.ts +0 -1
- package/src/context/post-turn-tool-result-truncation.ts +176 -0
- package/src/context/window-manager.ts +19 -1
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
- package/src/daemon/conversation-agent-loop.ts +58 -24
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-process.ts +48 -1
- package/src/daemon/conversation-runtime-assembly.ts +118 -36
- package/src/daemon/conversation-surfaces.ts +37 -36
- package/src/daemon/conversation-tool-setup.ts +74 -8
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +226 -8
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/conversations.ts +9 -140
- package/src/daemon/handlers/shared.ts +58 -0
- package/src/daemon/handlers/skills.ts +232 -37
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +191 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +65 -11
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/conversations.ts +55 -13
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/messages.ts +5 -5
- package/src/daemon/message-types/skills.ts +10 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/server.ts +92 -12
- package/src/daemon/tool-side-effects.ts +6 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/inbound/platform-callback-registration.ts +18 -17
- package/src/mcp/client.ts +59 -24
- package/src/memory/app-store.ts +31 -1
- package/src/memory/conversation-crud.ts +23 -0
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +12 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/retriever.ts +40 -22
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/llm-usage-store.ts +45 -4
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +1 -0
- package/src/memory/schema/oauth.ts +18 -13
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +24 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +8 -8
- package/src/oauth/byo-connection.ts +7 -7
- package/src/oauth/connect-orchestrator.ts +23 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +16 -16
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +214 -100
- package/src/oauth/platform-connection.test.ts +3 -3
- package/src/oauth/platform-connection.ts +4 -4
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +126 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/prompts/system-prompt.ts +18 -21
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/providers/anthropic/client.ts +1 -0
- package/src/providers/types.ts +1 -1
- package/src/runtime/AGENTS.md +23 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +8 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +6 -7
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/chrome-extension-registry.ts +332 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +425 -70
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +162 -0
- package/src/runtime/migrations/migration-transport.ts +6 -0
- package/src/runtime/migrations/migration-wizard.ts +22 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +19 -0
- package/src/runtime/migrations/vbundle-importer.ts +55 -5
- package/src/runtime/pending-interactions.ts +29 -13
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/browser-cdp-routes.ts +229 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +497 -0
- package/src/runtime/routes/conversation-analysis-routes.ts +2 -1
- package/src/runtime/routes/conversation-management-routes.ts +108 -0
- package/src/runtime/routes/conversation-routes.ts +301 -27
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/host-browser-routes.ts +279 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-routes.ts +259 -16
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +87 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +9 -97
- package/src/runtime/routes/skills-routes.ts +52 -2
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/usage-routes.ts +8 -7
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/schedule/scheduler.ts +7 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +42 -25
- package/src/security/secure-keys.ts +118 -25
- package/src/security/token-manager.ts +23 -10
- package/src/skills/catalog-files.ts +492 -0
- package/src/subagent/manager.ts +131 -26
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +645 -340
- package/src/tools/browser/browser-manager.ts +36 -12
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +870 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +330 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +377 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +743 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +578 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +635 -0
- package/src/tools/browser/cdp-client/errors.ts +34 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +125 -0
- package/src/tools/browser/cdp-client/factory.ts +204 -0
- package/src/tools/browser/cdp-client/index.ts +14 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +52 -0
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/terminal/shell.ts +21 -16
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/types.ts +2 -0
- package/src/util/platform.ts +14 -19
- package/src/workspace/top-level-renderer.ts +19 -1
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { ServicesSchema } from "../../config/schemas/services.js";
|
|
4
|
+
import { PROVIDER_SEED_DATA } from "../seed-providers.js";
|
|
5
|
+
|
|
6
|
+
describe("PROVIDER_SEED_DATA managed mode wiring", () => {
|
|
7
|
+
test("github provider is wired up for managed mode", () => {
|
|
8
|
+
const github = PROVIDER_SEED_DATA.github;
|
|
9
|
+
expect(github).toBeDefined();
|
|
10
|
+
expect(github.managedServiceConfigKey).toBe("github-oauth");
|
|
11
|
+
expect("github-oauth" in ServicesSchema.shape).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("every managedServiceConfigKey resolves to a ServicesSchema key", () => {
|
|
15
|
+
// Cross-repo invariant: a provider with managedServiceConfigKey but no
|
|
16
|
+
// matching ServicesSchema entry silently falls back to BYO mode in
|
|
17
|
+
// connection-resolver.ts. This test guards against that drift.
|
|
18
|
+
const offenders: Array<{ provider: string; key: string }> = [];
|
|
19
|
+
for (const [provider, seed] of Object.entries(PROVIDER_SEED_DATA)) {
|
|
20
|
+
const key = seed.managedServiceConfigKey;
|
|
21
|
+
if (key && !(key in ServicesSchema.shape)) {
|
|
22
|
+
offenders.push({ provider, key });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
expect(offenders).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("github managed service schema defaults to your-own", () => {
|
|
29
|
+
const parsed = ServicesSchema.shape["github-oauth"].parse({});
|
|
30
|
+
expect(parsed.mode).toBe("your-own");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -72,7 +72,7 @@ const mockConnections = new Map<
|
|
|
72
72
|
string,
|
|
73
73
|
{
|
|
74
74
|
id: string;
|
|
75
|
-
|
|
75
|
+
provider: string;
|
|
76
76
|
oauthAppId: string;
|
|
77
77
|
expiresAt: number | null;
|
|
78
78
|
grantedScopes?: string;
|
|
@@ -83,7 +83,7 @@ const mockApps = new Map<
|
|
|
83
83
|
string,
|
|
84
84
|
{
|
|
85
85
|
id: string;
|
|
86
|
-
|
|
86
|
+
provider: string;
|
|
87
87
|
clientId: string;
|
|
88
88
|
clientSecretCredentialPath: string;
|
|
89
89
|
}
|
|
@@ -92,7 +92,7 @@ const mockProviders = new Map<
|
|
|
92
92
|
string,
|
|
93
93
|
{
|
|
94
94
|
key: string;
|
|
95
|
-
|
|
95
|
+
tokenExchangeUrl: string;
|
|
96
96
|
tokenEndpointAuthMethod?: string;
|
|
97
97
|
baseUrl?: string;
|
|
98
98
|
}
|
|
@@ -192,7 +192,7 @@ async function setupCredential(
|
|
|
192
192
|
const connId = `conn-${service}`;
|
|
193
193
|
mockProviders.set(service, {
|
|
194
194
|
key: service,
|
|
195
|
-
|
|
195
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
196
196
|
// Only well-known providers (gmail) have a baseUrl; custom services don't
|
|
197
197
|
baseUrl:
|
|
198
198
|
service === "google"
|
|
@@ -201,13 +201,13 @@ async function setupCredential(
|
|
|
201
201
|
});
|
|
202
202
|
mockApps.set(appId, {
|
|
203
203
|
id: appId,
|
|
204
|
-
|
|
204
|
+
provider: service,
|
|
205
205
|
clientId: "test-client-id",
|
|
206
206
|
clientSecretCredentialPath: `oauth_app/${appId}/client_secret`,
|
|
207
207
|
});
|
|
208
208
|
mockConnections.set(service, {
|
|
209
209
|
id: connId,
|
|
210
|
-
|
|
210
|
+
provider: service,
|
|
211
211
|
oauthAppId: appId,
|
|
212
212
|
expiresAt: opts?.expiresAt ?? Date.now() + 3600 * 1000,
|
|
213
213
|
grantedScopes: JSON.stringify(opts?.grantedScopes ?? ["read", "write"]),
|
|
@@ -233,7 +233,7 @@ async function setupCredential(
|
|
|
233
233
|
function createConnection(service = "google"): BYOOAuthConnection {
|
|
234
234
|
return new BYOOAuthConnection({
|
|
235
235
|
id: `conn-${service}`,
|
|
236
|
-
|
|
236
|
+
provider: service,
|
|
237
237
|
baseUrl: "https://gmail.googleapis.com/gmail/v1/users/me",
|
|
238
238
|
accountInfo: null,
|
|
239
239
|
});
|
|
@@ -497,7 +497,7 @@ describe("resolveOAuthConnection", () => {
|
|
|
497
497
|
const conn = await resolveOAuthConnection("google");
|
|
498
498
|
|
|
499
499
|
expect(conn).toBeInstanceOf(BYOOAuthConnection);
|
|
500
|
-
expect(conn.
|
|
500
|
+
expect(conn.provider).toBe("google");
|
|
501
501
|
});
|
|
502
502
|
|
|
503
503
|
test("throws when no credential metadata exists", async () => {
|
|
@@ -22,28 +22,28 @@ const REQUEST_TIMEOUT_MS = 30_000;
|
|
|
22
22
|
|
|
23
23
|
export interface BYOOAuthConnectionOptions {
|
|
24
24
|
id: string;
|
|
25
|
-
|
|
25
|
+
provider: string;
|
|
26
26
|
baseUrl: string;
|
|
27
27
|
accountInfo: string | null;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export class BYOOAuthConnection implements OAuthConnection {
|
|
31
31
|
readonly id: string;
|
|
32
|
-
readonly
|
|
32
|
+
readonly provider: string;
|
|
33
33
|
readonly accountInfo: string | null;
|
|
34
34
|
|
|
35
35
|
private readonly baseUrl: string;
|
|
36
36
|
|
|
37
37
|
constructor(opts: BYOOAuthConnectionOptions) {
|
|
38
38
|
this.id = opts.id;
|
|
39
|
-
this.
|
|
39
|
+
this.provider = opts.provider;
|
|
40
40
|
this.baseUrl = opts.baseUrl;
|
|
41
41
|
this.accountInfo = opts.accountInfo;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
async request(req: OAuthConnectionRequest): Promise<OAuthConnectionResponse> {
|
|
45
45
|
return withValidToken(
|
|
46
|
-
this.
|
|
46
|
+
this.provider,
|
|
47
47
|
async (token) => {
|
|
48
48
|
const effectiveBaseUrl = req.baseUrl ?? this.baseUrl;
|
|
49
49
|
let fullUrl = `${effectiveBaseUrl}${req.path}`;
|
|
@@ -61,7 +61,7 @@ export class BYOOAuthConnection implements OAuthConnection {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
log.debug(
|
|
64
|
-
{ method: req.method, url: fullUrl, provider: this.
|
|
64
|
+
{ method: req.method, url: fullUrl, provider: this.provider },
|
|
65
65
|
"Making authenticated request",
|
|
66
66
|
);
|
|
67
67
|
|
|
@@ -88,7 +88,7 @@ export class BYOOAuthConnection implements OAuthConnection {
|
|
|
88
88
|
if (resp.status === 401) {
|
|
89
89
|
// Throw with a status property so withValidToken detects the 401
|
|
90
90
|
// and triggers its refresh-and-retry logic.
|
|
91
|
-
const err = new Error(`HTTP 401 from ${this.
|
|
91
|
+
const err = new Error(`HTTP 401 from ${this.provider}`);
|
|
92
92
|
(err as Error & { status: number }).status = 401;
|
|
93
93
|
throw err;
|
|
94
94
|
}
|
|
@@ -100,7 +100,7 @@ export class BYOOAuthConnection implements OAuthConnection {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
async withToken<T>(fn: (token: string) => Promise<T>): Promise<T> {
|
|
103
|
-
return withValidToken(this.
|
|
103
|
+
return withValidToken(this.provider, fn, {
|
|
104
104
|
connectionId: this.id,
|
|
105
105
|
});
|
|
106
106
|
}
|
|
@@ -23,10 +23,7 @@
|
|
|
23
23
|
import type { TokenEndpointAuthMethod } from "../security/oauth2.js";
|
|
24
24
|
import { prepareOAuth2Flow, startOAuth2Flow } from "../security/oauth2.js";
|
|
25
25
|
import { getLogger } from "../util/logger.js";
|
|
26
|
-
import type {
|
|
27
|
-
OAuthConnectResult,
|
|
28
|
-
OAuthScopePolicy,
|
|
29
|
-
} from "./connect-types.js";
|
|
26
|
+
import type { OAuthConnectResult, OAuthScopePolicy } from "./connect-types.js";
|
|
30
27
|
import { verifyIdentity } from "./identity-verifier.js";
|
|
31
28
|
import { getProvider } from "./oauth-store.js";
|
|
32
29
|
import { resolveScopes } from "./scope-policy.js";
|
|
@@ -98,7 +95,7 @@ export interface OAuthConnectOptions {
|
|
|
98
95
|
*
|
|
99
96
|
* Returns a discriminated result:
|
|
100
97
|
* - Interactive success: `{ success: true, deferred: false, grantedScopes, accountInfo }`
|
|
101
|
-
* - Deferred success: `{ success: true, deferred: true,
|
|
98
|
+
* - Deferred success: `{ success: true, deferred: true, authorizeUrl, state, service }`
|
|
102
99
|
* - Error: `{ success: false, error }`
|
|
103
100
|
*/
|
|
104
101
|
export async function orchestrateOAuthConnect(
|
|
@@ -137,15 +134,15 @@ export async function orchestrateOAuthConnect(
|
|
|
137
134
|
forbiddenScopes: [],
|
|
138
135
|
},
|
|
139
136
|
);
|
|
140
|
-
const
|
|
141
|
-
providerRow.
|
|
137
|
+
const dbAuthorizeParams = safeJsonParse<Record<string, string> | undefined>(
|
|
138
|
+
providerRow.authorizeParams,
|
|
142
139
|
undefined,
|
|
143
140
|
);
|
|
144
141
|
|
|
145
142
|
// Resolve all protocol-level config from the DB
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const
|
|
143
|
+
const authorizeUrl = providerRow.authorizeUrl;
|
|
144
|
+
const tokenExchangeUrl = providerRow.tokenExchangeUrl;
|
|
145
|
+
const authorizeParams = dbAuthorizeParams;
|
|
149
146
|
const userinfoUrl = providerRow.userinfoUrl ?? undefined;
|
|
150
147
|
const tokenEndpointAuthMethod = providerRow.tokenEndpointAuthMethod as
|
|
151
148
|
| TokenEndpointAuthMethod
|
|
@@ -173,14 +170,14 @@ export async function orchestrateOAuthConnect(
|
|
|
173
170
|
}
|
|
174
171
|
const finalScopes = scopeResult.scopes;
|
|
175
172
|
|
|
176
|
-
if (!
|
|
173
|
+
if (!authorizeUrl) {
|
|
177
174
|
return {
|
|
178
175
|
success: false,
|
|
179
176
|
error: "auth_url is required (no well-known config for this service)",
|
|
180
177
|
safeError: true,
|
|
181
178
|
};
|
|
182
179
|
}
|
|
183
|
-
if (!
|
|
180
|
+
if (!tokenExchangeUrl) {
|
|
184
181
|
return {
|
|
185
182
|
success: false,
|
|
186
183
|
error: "token_url is required (no well-known config for this service)",
|
|
@@ -191,24 +188,25 @@ export async function orchestrateOAuthConnect(
|
|
|
191
188
|
log.info(
|
|
192
189
|
{
|
|
193
190
|
service: options.service,
|
|
194
|
-
|
|
195
|
-
|
|
191
|
+
authorizeUrl,
|
|
192
|
+
tokenExchangeUrl,
|
|
196
193
|
scopeCount: finalScopes.length,
|
|
197
194
|
callbackTransport,
|
|
198
195
|
loopbackPort,
|
|
199
|
-
|
|
196
|
+
hasSecret: !!options.clientSecret,
|
|
200
197
|
clientIdPrefix: options.clientId.substring(0, 12) + "…",
|
|
201
198
|
},
|
|
202
199
|
"orchestrateOAuthConnect: resolved provider config",
|
|
203
200
|
);
|
|
204
201
|
|
|
205
202
|
const oauthConfig = {
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
authorizeUrl,
|
|
204
|
+
tokenExchangeUrl,
|
|
208
205
|
scopes: finalScopes,
|
|
206
|
+
scopeSeparator: providerRow.scopeSeparator,
|
|
209
207
|
clientId: options.clientId,
|
|
210
208
|
clientSecret: options.clientSecret,
|
|
211
|
-
|
|
209
|
+
authorizeParams,
|
|
212
210
|
userinfoUrl,
|
|
213
211
|
tokenEndpointAuthMethod,
|
|
214
212
|
};
|
|
@@ -308,7 +306,7 @@ export async function orchestrateOAuthConnect(
|
|
|
308
306
|
return {
|
|
309
307
|
success: true,
|
|
310
308
|
deferred: true,
|
|
311
|
-
|
|
309
|
+
authorizeUrl: prepared.authorizeUrl,
|
|
312
310
|
state: prepared.state,
|
|
313
311
|
service: options.service,
|
|
314
312
|
};
|
|
@@ -344,14 +342,18 @@ export async function orchestrateOAuthConnect(
|
|
|
344
342
|
log.info("orchestrateOAuthConnect: using options.openUrl");
|
|
345
343
|
options.openUrl(url);
|
|
346
344
|
} else if (options.sendToClient) {
|
|
347
|
-
log.info(
|
|
345
|
+
log.info(
|
|
346
|
+
"orchestrateOAuthConnect: using sendToClient with open_url event",
|
|
347
|
+
);
|
|
348
348
|
options.sendToClient({
|
|
349
349
|
type: "open_url",
|
|
350
350
|
url,
|
|
351
351
|
title: `Connect ${options.service}`,
|
|
352
352
|
});
|
|
353
353
|
} else {
|
|
354
|
-
log.warn(
|
|
354
|
+
log.warn(
|
|
355
|
+
"orchestrateOAuthConnect: no openUrl or sendToClient available — auth URL will not reach the user",
|
|
356
|
+
);
|
|
355
357
|
}
|
|
356
358
|
},
|
|
357
359
|
},
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* These types are consumed by the token persistence module and the
|
|
5
5
|
* credential vault orchestrator.
|
|
6
6
|
*
|
|
7
|
-
* All provider configuration — protocol-level OAuth config (
|
|
8
|
-
*
|
|
7
|
+
* All provider configuration — protocol-level OAuth config (authorizeUrl,
|
|
8
|
+
* tokenExchangeUrl, scopes, etc.) as well as behavioral config (identity
|
|
9
9
|
* verification, injection templates, setup metadata) — is now stored
|
|
10
10
|
* exclusively in the `oauth_providers` SQLite table and seeded on
|
|
11
11
|
* startup via `seed-providers.ts`.
|
|
@@ -47,7 +47,7 @@ export interface OAuthConnectInteractiveResult {
|
|
|
47
47
|
export interface OAuthConnectDeferredResult {
|
|
48
48
|
success: true;
|
|
49
49
|
deferred: true;
|
|
50
|
-
|
|
50
|
+
authorizeUrl: string;
|
|
51
51
|
state: string;
|
|
52
52
|
service: string;
|
|
53
53
|
}
|
|
@@ -79,13 +79,13 @@ function makeMockClient() {
|
|
|
79
79
|
|
|
80
80
|
function setupDefaults(): void {
|
|
81
81
|
mockProvider = {
|
|
82
|
-
|
|
82
|
+
provider: "google",
|
|
83
83
|
baseUrl: "https://gmail.googleapis.com/gmail/v1/users/me",
|
|
84
84
|
managedServiceConfigKey: null,
|
|
85
85
|
};
|
|
86
86
|
mockConnection = {
|
|
87
87
|
id: "conn-1",
|
|
88
|
-
|
|
88
|
+
provider: "google",
|
|
89
89
|
oauthAppId: "app-1",
|
|
90
90
|
accountInfo: "user@example.com",
|
|
91
91
|
grantedScopes: JSON.stringify(["scope-a", "scope-b"]),
|
|
@@ -125,7 +125,7 @@ describe("resolveOAuthConnection", () => {
|
|
|
125
125
|
const result = await resolveOAuthConnection("google");
|
|
126
126
|
expect(result).toBeInstanceOf(BYOOAuthConnection);
|
|
127
127
|
expect(result.id).toBe("conn-1");
|
|
128
|
-
expect(result.
|
|
128
|
+
expect(result.provider).toBe("google");
|
|
129
129
|
});
|
|
130
130
|
|
|
131
131
|
test("returns PlatformOAuthConnection when managed mode is active", async () => {
|
|
@@ -134,7 +134,7 @@ describe("resolveOAuthConnection", () => {
|
|
|
134
134
|
const result = await resolveOAuthConnection("google");
|
|
135
135
|
expect(result).toBeInstanceOf(PlatformOAuthConnection);
|
|
136
136
|
expect(result.id).toBe("google");
|
|
137
|
-
expect(result.
|
|
137
|
+
expect(result.provider).toBe("google");
|
|
138
138
|
expect(result.accountInfo).toBeNull();
|
|
139
139
|
});
|
|
140
140
|
|
|
@@ -148,6 +148,19 @@ describe("resolveOAuthConnection", () => {
|
|
|
148
148
|
expect(result.accountInfo).toBe("user@example.com");
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
+
test("returns PlatformOAuthConnection when GitHub is in managed mode", async () => {
|
|
152
|
+
mockProvider!.provider = "github";
|
|
153
|
+
mockProvider!.managedServiceConfigKey = "github-oauth";
|
|
154
|
+
(mockConfig.services as Record<string, unknown>)["github-oauth"] = {
|
|
155
|
+
mode: "managed",
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const result = await resolveOAuthConnection("github");
|
|
159
|
+
expect(result).toBeInstanceOf(PlatformOAuthConnection);
|
|
160
|
+
expect(result.id).toBe("github");
|
|
161
|
+
expect(result.provider).toBe("github");
|
|
162
|
+
});
|
|
163
|
+
|
|
151
164
|
test("returns BYOOAuthConnection when service config mode is your-own", async () => {
|
|
152
165
|
mockProvider!.managedServiceConfigKey = "google-oauth";
|
|
153
166
|
(mockConfig.services as Record<string, unknown>)["google-oauth"] = {
|
|
@@ -29,7 +29,7 @@ export interface ResolveOAuthConnectionOptions {
|
|
|
29
29
|
* BYO providers resolve from the local SQLite oauth-store and require an
|
|
30
30
|
* active connection row and a stored access token.
|
|
31
31
|
*
|
|
32
|
-
* @param
|
|
32
|
+
* @param provider - Provider identifier (e.g. "google").
|
|
33
33
|
* Maps to the `provider_key` primary key in the `oauth_providers` table.
|
|
34
34
|
* @param options.clientId - Optional OAuth app client ID. When multiple BYO
|
|
35
35
|
* apps exist for the same provider, narrows the connection lookup to the
|
|
@@ -38,12 +38,12 @@ export interface ResolveOAuthConnectionOptions {
|
|
|
38
38
|
* multi-account connections.
|
|
39
39
|
*/
|
|
40
40
|
export async function resolveOAuthConnection(
|
|
41
|
-
|
|
41
|
+
provider: string,
|
|
42
42
|
options?: ResolveOAuthConnectionOptions,
|
|
43
43
|
): Promise<OAuthConnection> {
|
|
44
44
|
const { clientId, account } = options ?? {};
|
|
45
|
-
const
|
|
46
|
-
const managedKey =
|
|
45
|
+
const providerRow = getProvider(provider);
|
|
46
|
+
const managedKey = providerRow?.managedServiceConfigKey;
|
|
47
47
|
|
|
48
48
|
if (managedKey && managedKey in ServicesSchema.shape) {
|
|
49
49
|
const services: Services = getConfig().services;
|
|
@@ -54,31 +54,31 @@ export async function resolveOAuthConnection(
|
|
|
54
54
|
? "missing platform prerequisites"
|
|
55
55
|
: "missing assistant ID";
|
|
56
56
|
throw new Error(
|
|
57
|
-
`Platform-managed connection for "${
|
|
57
|
+
`Platform-managed connection for "${provider}" cannot be created: ${detail}. ` +
|
|
58
58
|
`Log in to the Vellum platform or switch to using your own OAuth app.`,
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const connectionId = await resolvePlatformConnectionId({
|
|
63
63
|
client,
|
|
64
|
-
provider
|
|
64
|
+
provider,
|
|
65
65
|
account,
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
return new PlatformOAuthConnection({
|
|
69
|
-
id:
|
|
70
|
-
|
|
71
|
-
externalId:
|
|
69
|
+
id: provider,
|
|
70
|
+
provider,
|
|
71
|
+
externalId: provider,
|
|
72
72
|
accountInfo: account ?? null,
|
|
73
73
|
client,
|
|
74
74
|
connectionId,
|
|
75
|
-
baseUrl:
|
|
75
|
+
baseUrl: providerRow?.baseUrl ?? undefined,
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// BYO path — requires a local connection row, access token, and base URL.
|
|
81
|
-
const conn = getActiveConnection(
|
|
81
|
+
const conn = getActiveConnection(provider, { clientId, account });
|
|
82
82
|
if (!conn) {
|
|
83
83
|
const filters = [
|
|
84
84
|
account && `account "${account}"`,
|
|
@@ -88,7 +88,7 @@ export async function resolveOAuthConnection(
|
|
|
88
88
|
? ` matching ${filters.join(" and ")}`
|
|
89
89
|
: "";
|
|
90
90
|
throw new Error(
|
|
91
|
-
`No active OAuth connection found for "${
|
|
91
|
+
`No active OAuth connection found for "${provider}"${qualifier}. Connect the service first with \`assistant oauth connect ${provider}\`.`,
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -97,20 +97,20 @@ export async function resolveOAuthConnection(
|
|
|
97
97
|
);
|
|
98
98
|
if (!accessToken) {
|
|
99
99
|
throw new Error(
|
|
100
|
-
`OAuth connection for "${
|
|
100
|
+
`OAuth connection for "${provider}" exists but has no access token. Re-authorize with \`assistant oauth connect ${provider}\`.`,
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
const baseUrl =
|
|
104
|
+
const baseUrl = providerRow?.baseUrl;
|
|
105
105
|
if (!baseUrl) {
|
|
106
106
|
throw new Error(
|
|
107
|
-
`OAuth provider "${
|
|
107
|
+
`OAuth provider "${provider}" has no base URL configured. Check provider setup.`,
|
|
108
108
|
);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
return new BYOOAuthConnection({
|
|
112
112
|
id: conn.id,
|
|
113
|
-
|
|
113
|
+
provider: conn.provider,
|
|
114
114
|
baseUrl,
|
|
115
115
|
accountInfo: conn.accountInfo,
|
|
116
116
|
});
|
package/src/oauth/connection.ts
CHANGED
|
@@ -25,14 +25,14 @@ const MANUAL_TOKEN_CLIENT_ID = "manual-config";
|
|
|
25
25
|
* Ensure an active oauth_connection row exists for the given manual-token
|
|
26
26
|
* provider. Creates the synthetic oauth_app row on first use.
|
|
27
27
|
*
|
|
28
|
-
* @param
|
|
28
|
+
* @param provider - The provider key (e.g. "slack_channel", "telegram")
|
|
29
29
|
* @param accountInfo - Optional account info to store (e.g. team name, bot username)
|
|
30
30
|
*/
|
|
31
31
|
export async function ensureManualTokenConnection(
|
|
32
|
-
|
|
32
|
+
provider: string,
|
|
33
33
|
accountInfo?: string,
|
|
34
34
|
): Promise<void> {
|
|
35
|
-
const existing = getConnectionByProvider(
|
|
35
|
+
const existing = getConnectionByProvider(provider);
|
|
36
36
|
if (existing) {
|
|
37
37
|
// Update account info if provided
|
|
38
38
|
if (accountInfo !== undefined) {
|
|
@@ -42,11 +42,11 @@ export async function ensureManualTokenConnection(
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// Create synthetic app + connection
|
|
45
|
-
const app = await upsertApp(
|
|
45
|
+
const app = await upsertApp(provider, MANUAL_TOKEN_CLIENT_ID);
|
|
46
46
|
|
|
47
47
|
createConnection({
|
|
48
48
|
oauthAppId: app.id,
|
|
49
|
-
|
|
49
|
+
provider,
|
|
50
50
|
accountInfo,
|
|
51
51
|
grantedScopes: [],
|
|
52
52
|
hasRefreshToken: false,
|
|
@@ -59,8 +59,8 @@ export async function ensureManualTokenConnection(
|
|
|
59
59
|
* Note: This only removes the oauth_connection row. The caller is still
|
|
60
60
|
* responsible for deleting the stored credentials separately.
|
|
61
61
|
*/
|
|
62
|
-
export function removeManualTokenConnection(
|
|
63
|
-
const conn = getConnectionByProvider(
|
|
62
|
+
export function removeManualTokenConnection(provider: string): void {
|
|
63
|
+
const conn = getConnectionByProvider(provider);
|
|
64
64
|
if (!conn) return;
|
|
65
65
|
deleteConnection(conn.id);
|
|
66
66
|
}
|
|
@@ -73,10 +73,10 @@ export function removeManualTokenConnection(providerKey: string): void {
|
|
|
73
73
|
* keep connection status in sync without duplicating per-provider rules.
|
|
74
74
|
*/
|
|
75
75
|
export async function syncManualTokenConnection(
|
|
76
|
-
|
|
76
|
+
provider: string,
|
|
77
77
|
accountInfo?: string,
|
|
78
78
|
): Promise<void> {
|
|
79
|
-
switch (
|
|
79
|
+
switch (provider) {
|
|
80
80
|
case "telegram": {
|
|
81
81
|
const hasBotToken = !!(await getSecureKeyAsync(
|
|
82
82
|
credentialKey("telegram", "bot_token"),
|
|
@@ -85,9 +85,9 @@ export async function syncManualTokenConnection(
|
|
|
85
85
|
credentialKey("telegram", "webhook_secret"),
|
|
86
86
|
));
|
|
87
87
|
if (hasBotToken && hasWebhookSecret) {
|
|
88
|
-
await ensureManualTokenConnection(
|
|
88
|
+
await ensureManualTokenConnection(provider, accountInfo);
|
|
89
89
|
} else {
|
|
90
|
-
removeManualTokenConnection(
|
|
90
|
+
removeManualTokenConnection(provider);
|
|
91
91
|
}
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
@@ -100,9 +100,9 @@ export async function syncManualTokenConnection(
|
|
|
100
100
|
credentialKey("slack_channel", "app_token"),
|
|
101
101
|
));
|
|
102
102
|
if (hasBotToken && hasAppToken) {
|
|
103
|
-
await ensureManualTokenConnection(
|
|
103
|
+
await ensureManualTokenConnection(provider, accountInfo);
|
|
104
104
|
} else {
|
|
105
|
-
removeManualTokenConnection(
|
|
105
|
+
removeManualTokenConnection(provider);
|
|
106
106
|
}
|
|
107
107
|
return;
|
|
108
108
|
}
|