@vellumai/assistant 0.6.2 → 0.6.4
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 +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +41 -49
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +1111 -86
- package/package.json +40 -42
- package/scripts/generate-openapi.ts +0 -2
- package/scripts/test.sh +73 -18
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- 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__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +240 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +1000 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -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 +1248 -224
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +99 -3
- 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 +290 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +12 -4
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +946 -62
- package/src/__tests__/conversation-routes-disk-view.test.ts +275 -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 +324 -46
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- 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-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +6 -3
- package/src/__tests__/credential-vault-unit.test.ts +383 -7
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +42 -18
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +2 -0
- package/src/__tests__/gemini-provider.test.ts +66 -2
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +738 -359
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +528 -49
- package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
- package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +145 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -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 +423 -0
- package/src/__tests__/host-cu-proxy.test.ts +166 -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__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +67 -8
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +109 -7
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +18 -12
- package/src/__tests__/oauth-cli.test.ts +709 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +52 -14
- package/src/__tests__/oauth-store.test.ts +1465 -176
- package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
- package/src/__tests__/onboarding-template-contract.test.ts +81 -70
- package/src/__tests__/openai-provider.test.ts +178 -2
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- 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 +32 -3
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- 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__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +8 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +801 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +576 -16
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- 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 +184 -27
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +25 -5
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -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__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +55 -9
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- 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/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +69 -3
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +3 -4
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +273 -16
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -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 +32 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -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/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +215 -36
- package/src/cli/commands/oauth/shared.ts +7 -6
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -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 +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -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/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +5 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +54 -8
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +9 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -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/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +38 -0
- package/src/config/env.ts +49 -4
- package/src/config/feature-flag-registry.json +85 -14
- package/src/config/loader.ts +82 -13
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +81 -15
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +112 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +52 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -1
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +177 -0
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +61 -10
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +195 -0
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
- package/src/daemon/conversation-agent-loop.ts +153 -42
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +622 -13
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +128 -36
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +131 -40
- package/src/daemon/conversation-tool-setup.ts +99 -8
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +292 -16
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -141
- package/src/daemon/handlers/shared.ts +80 -0
- package/src/daemon/handlers/skills.ts +483 -44
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +192 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +179 -28
- package/src/daemon/message-protocol.ts +13 -0
- package/src/daemon/message-types/conversations.ts +89 -14
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +19 -5
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +26 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +439 -14
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +30 -20
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/mcp/client.ts +59 -24
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +31 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +122 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +18 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -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/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +67 -40
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +137 -60
- 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/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/oauth.ts +21 -13
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +26 -9
- package/src/oauth/byo-connection.ts +10 -8
- package/src/oauth/connect-orchestrator.ts +25 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +22 -18
- package/src/oauth/connection.ts +3 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +223 -100
- package/src/oauth/platform-connection.test.ts +101 -3
- package/src/oauth/platform-connection.ts +56 -35
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +133 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +76 -38
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -60
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +10 -1
- package/src/runtime/AGENTS.md +65 -0
- package/src/runtime/__tests__/agent-wake.test.ts +831 -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/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -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 +48 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +33 -9
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +368 -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 +815 -75
- package/src/runtime/http-types.ts +6 -2
- 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 +198 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +7 -0
- package/src/runtime/migrations/migration-wizard.ts +23 -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 +96 -1
- package/src/runtime/migrations/vbundle-importer.ts +89 -5
- package/src/runtime/pending-interactions.ts +18 -13
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +556 -0
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -141
- package/src/runtime/routes/conversation-management-routes.ts +223 -0
- package/src/runtime/routes/conversation-routes.ts +598 -103
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +268 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +262 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +122 -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 +31 -102
- package/src/runtime/routes/skills-routes.ts +128 -9
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +38 -9
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- 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/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +57 -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 +68 -29
- package/src/security/secure-keys.ts +143 -27
- package/src/security/token-manager.ts +31 -10
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +554 -0
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +169 -40
- 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/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +1787 -342
- package/src/tools/browser/browser-manager.ts +81 -12
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- 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 +1263 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -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 +1007 -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 +744 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
- package/src/tools/browser/cdp-client/errors.ts +49 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
- package/src/tools/browser/cdp-client/factory.ts +914 -0
- package/src/tools/browser/cdp-client/index.ts +28 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +120 -0
- package/src/tools/credentials/vault.ts +35 -6
- 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/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- 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/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- 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 +15 -0
- package/src/tools/terminal/shell.ts +36 -20
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +19 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +63 -24
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +31 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- 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/cli/commands/browser-relay.ts +0 -536
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
package/src/oauth/oauth-store.ts
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Backed by Drizzle + SQLite. All JSON fields (default_scopes, scope_policy,
|
|
5
5
|
* extra_params, granted_scopes, metadata) are stored as serialized JSON strings.
|
|
6
|
+
*
|
|
7
|
+
* Note: TS field names use camelCase from the platform's naming
|
|
8
|
+
* (provider, authorizeUrl, tokenExchangeUrl, displayLabel, authorizeParams),
|
|
9
|
+
* while underlying SQL columns retain their original snake_case names
|
|
10
|
+
* (provider_key, auth_url, token_url, display_name, extra_params).
|
|
6
11
|
*/
|
|
7
12
|
|
|
8
13
|
import {
|
|
@@ -26,6 +31,7 @@ import {
|
|
|
26
31
|
setSecureKeyAsync,
|
|
27
32
|
} from "../security/secure-keys.js";
|
|
28
33
|
import { getLogger } from "../util/logger.js";
|
|
34
|
+
import { tryRevokeOAuthToken } from "./revoke.js";
|
|
29
35
|
|
|
30
36
|
const log = getLogger("oauth-store");
|
|
31
37
|
|
|
@@ -43,14 +49,16 @@ export type OAuthConnectionRow = typeof oauthConnections.$inferSelect;
|
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* Seed well-known provider profiles into the database. Uses INSERT … ON
|
|
46
|
-
* CONFLICT DO UPDATE so that implementation fields (
|
|
47
|
-
* tokenEndpointAuthMethod, userinfoUrl,
|
|
48
|
-
* pingUrl, pingMethod, pingHeaders, pingBody,
|
|
52
|
+
* CONFLICT DO UPDATE so that implementation fields (authorizeUrl, tokenExchangeUrl,
|
|
53
|
+
* refreshUrl, tokenEndpointAuthMethod, userinfoUrl, authorizeParams,
|
|
54
|
+
* pingUrl, pingMethod, pingHeaders, pingBody, revokeUrl, revokeBodyTemplate,
|
|
55
|
+
* managedServiceConfigKey,
|
|
49
56
|
* loopbackPort, injectionTemplates, appType, setupNotes,
|
|
50
57
|
* identityUrl, identityMethod, identityHeaders, identityBody,
|
|
51
|
-
* identityResponsePaths, identityFormat, identityOkField, featureFlag
|
|
52
|
-
*
|
|
53
|
-
*
|
|
58
|
+
* identityResponsePaths, identityFormat, identityOkField, featureFlag,
|
|
59
|
+
* scopeSeparator)
|
|
60
|
+
* and display metadata (displayLabel, description, dashboardUrl,
|
|
61
|
+
* clientIdPlaceholder, logoUrl, requiresClientSecret) propagate to existing
|
|
54
62
|
* installations on every startup, while user-customizable fields
|
|
55
63
|
* (defaultScopes, scopePolicy) are only written on the
|
|
56
64
|
* initial insert. baseUrl is backfilled from seed data when null
|
|
@@ -59,24 +67,30 @@ export type OAuthConnectionRow = typeof oauthConnections.$inferSelect;
|
|
|
59
67
|
*/
|
|
60
68
|
export function seedProviders(
|
|
61
69
|
profiles: Array<{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
provider: string;
|
|
71
|
+
authorizeUrl: string;
|
|
72
|
+
tokenExchangeUrl: string;
|
|
73
|
+
refreshUrl?: string;
|
|
65
74
|
tokenEndpointAuthMethod?: string;
|
|
75
|
+
tokenExchangeBodyFormat?: string;
|
|
66
76
|
userinfoUrl?: string;
|
|
67
77
|
pingUrl?: string;
|
|
68
78
|
pingMethod?: string;
|
|
69
79
|
pingHeaders?: Record<string, string>;
|
|
70
80
|
pingBody?: unknown;
|
|
81
|
+
revokeUrl?: string;
|
|
82
|
+
revokeBodyTemplate?: Record<string, string>;
|
|
71
83
|
baseUrl?: string;
|
|
72
84
|
defaultScopes: string[];
|
|
73
85
|
scopePolicy: Record<string, unknown>;
|
|
74
|
-
|
|
86
|
+
scopeSeparator?: string;
|
|
87
|
+
authorizeParams?: Record<string, string>;
|
|
75
88
|
managedServiceConfigKey?: string;
|
|
76
|
-
|
|
89
|
+
displayLabel?: string;
|
|
77
90
|
description?: string;
|
|
78
91
|
dashboardUrl?: string | null;
|
|
79
92
|
clientIdPlaceholder?: string | null;
|
|
93
|
+
logoUrl?: string | null;
|
|
80
94
|
requiresClientSecret?: boolean;
|
|
81
95
|
loopbackPort?: number;
|
|
82
96
|
injectionTemplates?: Array<{
|
|
@@ -100,24 +114,42 @@ export function seedProviders(
|
|
|
100
114
|
const db = getDb();
|
|
101
115
|
const now = Date.now();
|
|
102
116
|
for (const p of profiles) {
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
117
|
+
const authorizeUrl = p.authorizeUrl;
|
|
118
|
+
const tokenExchangeUrl = p.tokenExchangeUrl;
|
|
119
|
+
const refreshUrl = p.refreshUrl ?? null;
|
|
120
|
+
// Coerce undefined and empty string to the default. The schema declares
|
|
121
|
+
// this column as NOT NULL with default "client_secret_post"; passing null
|
|
122
|
+
// here would be a type error, and an empty string is never a valid OAuth
|
|
123
|
+
// token endpoint auth method.
|
|
124
|
+
const tokenEndpointAuthMethod =
|
|
125
|
+
p.tokenEndpointAuthMethod || "client_secret_post";
|
|
126
|
+
const tokenExchangeBodyFormat = p.tokenExchangeBodyFormat || "form";
|
|
106
127
|
const userinfoUrl = p.userinfoUrl ?? null;
|
|
107
128
|
const pingUrl = p.pingUrl ?? null;
|
|
108
129
|
const pingMethod = p.pingMethod ?? null;
|
|
109
130
|
const pingHeaders = p.pingHeaders ? JSON.stringify(p.pingHeaders) : null;
|
|
110
131
|
const pingBody =
|
|
111
132
|
p.pingBody !== undefined ? JSON.stringify(p.pingBody) : null;
|
|
133
|
+
const revokeUrl = p.revokeUrl ?? null;
|
|
134
|
+
const revokeBodyTemplate = p.revokeBodyTemplate
|
|
135
|
+
? JSON.stringify(p.revokeBodyTemplate)
|
|
136
|
+
: null;
|
|
112
137
|
const baseUrl = p.baseUrl ?? null;
|
|
113
138
|
const defaultScopes = JSON.stringify(p.defaultScopes);
|
|
114
139
|
const scopePolicy = JSON.stringify(p.scopePolicy);
|
|
115
|
-
|
|
140
|
+
// Coerce empty string to the default space separator. An empty separator
|
|
141
|
+
// would join scopes into a single concatenated token (e.g. "readwrite"),
|
|
142
|
+
// which is never a valid OAuth authorize URL value.
|
|
143
|
+
const scopeSeparator = p.scopeSeparator || " ";
|
|
144
|
+
const authorizeParams = p.authorizeParams
|
|
145
|
+
? JSON.stringify(p.authorizeParams)
|
|
146
|
+
: null;
|
|
116
147
|
const managedServiceConfigKey = p.managedServiceConfigKey ?? null;
|
|
117
|
-
const
|
|
148
|
+
const displayLabel = p.displayLabel ?? null;
|
|
118
149
|
const description = p.description ?? null;
|
|
119
150
|
const dashboardUrl = p.dashboardUrl ?? null;
|
|
120
151
|
const clientIdPlaceholder = p.clientIdPlaceholder ?? null;
|
|
152
|
+
const logoUrl = p.logoUrl ?? null;
|
|
121
153
|
const requiresClientSecret = p.requiresClientSecret !== false ? 1 : 0;
|
|
122
154
|
const loopbackPort = p.loopbackPort ?? null;
|
|
123
155
|
const injectionTemplates = p.injectionTemplates
|
|
@@ -141,24 +173,30 @@ export function seedProviders(
|
|
|
141
173
|
|
|
142
174
|
db.insert(oauthProviders)
|
|
143
175
|
.values({
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
176
|
+
provider: p.provider,
|
|
177
|
+
authorizeUrl,
|
|
178
|
+
tokenExchangeUrl,
|
|
179
|
+
refreshUrl,
|
|
147
180
|
tokenEndpointAuthMethod,
|
|
181
|
+
tokenExchangeBodyFormat,
|
|
148
182
|
userinfoUrl,
|
|
149
183
|
baseUrl,
|
|
150
184
|
defaultScopes,
|
|
151
185
|
scopePolicy,
|
|
152
|
-
|
|
186
|
+
scopeSeparator,
|
|
187
|
+
authorizeParams,
|
|
153
188
|
pingUrl,
|
|
154
189
|
pingMethod,
|
|
155
190
|
pingHeaders,
|
|
156
191
|
pingBody,
|
|
192
|
+
revokeUrl,
|
|
193
|
+
revokeBodyTemplate,
|
|
157
194
|
managedServiceConfigKey,
|
|
158
|
-
|
|
195
|
+
displayLabel,
|
|
159
196
|
description,
|
|
160
197
|
dashboardUrl,
|
|
161
198
|
clientIdPlaceholder,
|
|
199
|
+
logoUrl,
|
|
162
200
|
requiresClientSecret,
|
|
163
201
|
loopbackPort,
|
|
164
202
|
injectionTemplates,
|
|
@@ -176,23 +214,29 @@ export function seedProviders(
|
|
|
176
214
|
updatedAt: now,
|
|
177
215
|
})
|
|
178
216
|
.onConflictDoUpdate({
|
|
179
|
-
target: oauthProviders.
|
|
217
|
+
target: oauthProviders.provider,
|
|
180
218
|
set: {
|
|
181
|
-
|
|
182
|
-
|
|
219
|
+
authorizeUrl,
|
|
220
|
+
tokenExchangeUrl,
|
|
221
|
+
refreshUrl,
|
|
183
222
|
tokenEndpointAuthMethod,
|
|
223
|
+
tokenExchangeBodyFormat,
|
|
184
224
|
userinfoUrl,
|
|
185
225
|
baseUrl: sql`COALESCE(${oauthProviders.baseUrl}, ${baseUrl})`,
|
|
186
|
-
|
|
226
|
+
scopeSeparator,
|
|
227
|
+
authorizeParams,
|
|
187
228
|
pingUrl,
|
|
188
229
|
pingMethod,
|
|
189
230
|
pingHeaders,
|
|
190
231
|
pingBody,
|
|
232
|
+
revokeUrl,
|
|
233
|
+
revokeBodyTemplate,
|
|
191
234
|
managedServiceConfigKey,
|
|
192
|
-
|
|
235
|
+
displayLabel,
|
|
193
236
|
description,
|
|
194
237
|
dashboardUrl,
|
|
195
238
|
clientIdPlaceholder,
|
|
239
|
+
logoUrl,
|
|
196
240
|
requiresClientSecret,
|
|
197
241
|
loopbackPort,
|
|
198
242
|
injectionTemplates,
|
|
@@ -214,12 +258,12 @@ export function seedProviders(
|
|
|
214
258
|
}
|
|
215
259
|
|
|
216
260
|
/** Look up a provider by its primary key. */
|
|
217
|
-
export function getProvider(
|
|
261
|
+
export function getProvider(provider: string): OAuthProviderRow | undefined {
|
|
218
262
|
const db = getDb();
|
|
219
263
|
return db
|
|
220
264
|
.select()
|
|
221
265
|
.from(oauthProviders)
|
|
222
|
-
.where(eq(oauthProviders.
|
|
266
|
+
.where(eq(oauthProviders.provider, provider))
|
|
223
267
|
.get();
|
|
224
268
|
}
|
|
225
269
|
|
|
@@ -234,24 +278,30 @@ export function listProviders(): OAuthProviderRow[] {
|
|
|
234
278
|
* provider_key already exists.
|
|
235
279
|
*/
|
|
236
280
|
export function registerProvider(params: {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
281
|
+
provider: string;
|
|
282
|
+
authorizeUrl: string;
|
|
283
|
+
tokenExchangeUrl: string;
|
|
284
|
+
refreshUrl?: string;
|
|
240
285
|
tokenEndpointAuthMethod?: string;
|
|
286
|
+
tokenExchangeBodyFormat?: string;
|
|
241
287
|
userinfoUrl?: string;
|
|
242
288
|
pingUrl?: string;
|
|
243
289
|
pingMethod?: string;
|
|
244
290
|
pingHeaders?: Record<string, string>;
|
|
245
291
|
pingBody?: unknown;
|
|
292
|
+
revokeUrl?: string;
|
|
293
|
+
revokeBodyTemplate?: Record<string, string>;
|
|
246
294
|
baseUrl?: string;
|
|
247
295
|
defaultScopes: string[];
|
|
248
296
|
scopePolicy: Record<string, unknown>;
|
|
249
|
-
|
|
297
|
+
scopeSeparator?: string;
|
|
298
|
+
authorizeParams?: Record<string, string>;
|
|
250
299
|
managedServiceConfigKey?: string;
|
|
251
|
-
|
|
300
|
+
displayLabel?: string;
|
|
252
301
|
description?: string;
|
|
253
302
|
dashboardUrl?: string;
|
|
254
303
|
clientIdPlaceholder?: string;
|
|
304
|
+
logoUrl?: string | null;
|
|
255
305
|
requiresClientSecret?: number;
|
|
256
306
|
loopbackPort?: number;
|
|
257
307
|
injectionTemplates?: Array<{
|
|
@@ -274,31 +324,43 @@ export function registerProvider(params: {
|
|
|
274
324
|
const db = getDb();
|
|
275
325
|
const now = Date.now();
|
|
276
326
|
|
|
277
|
-
const existing = getProvider(params.
|
|
327
|
+
const existing = getProvider(params.provider);
|
|
278
328
|
if (existing) {
|
|
279
|
-
throw new Error(`OAuth provider already exists: ${params.
|
|
329
|
+
throw new Error(`OAuth provider already exists: ${params.provider}`);
|
|
280
330
|
}
|
|
281
331
|
|
|
282
332
|
const row = {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
333
|
+
provider: params.provider,
|
|
334
|
+
authorizeUrl: params.authorizeUrl,
|
|
335
|
+
tokenExchangeUrl: params.tokenExchangeUrl,
|
|
336
|
+
refreshUrl: params.refreshUrl ?? null,
|
|
337
|
+
tokenEndpointAuthMethod:
|
|
338
|
+
params.tokenEndpointAuthMethod || "client_secret_post",
|
|
339
|
+
tokenExchangeBodyFormat: params.tokenExchangeBodyFormat || "form",
|
|
287
340
|
userinfoUrl: params.userinfoUrl ?? null,
|
|
288
341
|
baseUrl: params.baseUrl ?? null,
|
|
289
342
|
defaultScopes: JSON.stringify(params.defaultScopes),
|
|
290
343
|
scopePolicy: JSON.stringify(params.scopePolicy),
|
|
291
|
-
|
|
344
|
+
// Coerce empty string to the default space separator (see seedProviders).
|
|
345
|
+
scopeSeparator: params.scopeSeparator || " ",
|
|
346
|
+
authorizeParams: params.authorizeParams
|
|
347
|
+
? JSON.stringify(params.authorizeParams)
|
|
348
|
+
: null,
|
|
292
349
|
pingUrl: params.pingUrl ?? null,
|
|
293
350
|
pingMethod: params.pingMethod ?? null,
|
|
294
351
|
pingHeaders: params.pingHeaders ? JSON.stringify(params.pingHeaders) : null,
|
|
295
352
|
pingBody:
|
|
296
353
|
params.pingBody !== undefined ? JSON.stringify(params.pingBody) : null,
|
|
354
|
+
revokeUrl: params.revokeUrl ?? null,
|
|
355
|
+
revokeBodyTemplate: params.revokeBodyTemplate
|
|
356
|
+
? JSON.stringify(params.revokeBodyTemplate)
|
|
357
|
+
: null,
|
|
297
358
|
managedServiceConfigKey: params.managedServiceConfigKey ?? null,
|
|
298
|
-
|
|
359
|
+
displayLabel: params.displayLabel ?? null,
|
|
299
360
|
description: params.description ?? null,
|
|
300
361
|
dashboardUrl: params.dashboardUrl ?? null,
|
|
301
362
|
clientIdPlaceholder: params.clientIdPlaceholder ?? null,
|
|
363
|
+
logoUrl: params.logoUrl ?? null,
|
|
302
364
|
requiresClientSecret: params.requiresClientSecret ?? 1,
|
|
303
365
|
loopbackPort: params.loopbackPort ?? null,
|
|
304
366
|
injectionTemplates: params.injectionTemplates
|
|
@@ -333,31 +395,37 @@ export function registerProvider(params: {
|
|
|
333
395
|
/**
|
|
334
396
|
* Update mutable fields on an existing provider. Only the fields explicitly
|
|
335
397
|
* provided (not `undefined`) are written; everything else is left unchanged.
|
|
336
|
-
* JSON fields (defaultScopes, scopePolicy,
|
|
398
|
+
* JSON fields (defaultScopes, scopePolicy, authorizeParams, pingHeaders, pingBody)
|
|
337
399
|
* are serialized with JSON.stringify before storage.
|
|
338
400
|
*
|
|
339
401
|
* Returns the updated provider row, or `undefined` if no provider with the
|
|
340
402
|
* given key exists.
|
|
341
403
|
*/
|
|
342
404
|
export function updateProvider(
|
|
343
|
-
|
|
405
|
+
provider: string,
|
|
344
406
|
params: Partial<{
|
|
345
|
-
|
|
346
|
-
|
|
407
|
+
authorizeUrl: string;
|
|
408
|
+
tokenExchangeUrl: string;
|
|
409
|
+
refreshUrl: string;
|
|
347
410
|
tokenEndpointAuthMethod: string;
|
|
411
|
+
tokenExchangeBodyFormat: string;
|
|
348
412
|
userinfoUrl: string;
|
|
349
413
|
pingUrl: string;
|
|
350
414
|
pingMethod: string;
|
|
351
415
|
pingHeaders: Record<string, string>;
|
|
352
416
|
pingBody: unknown;
|
|
417
|
+
revokeUrl: string | null;
|
|
418
|
+
revokeBodyTemplate: Record<string, string> | null;
|
|
353
419
|
baseUrl: string;
|
|
354
420
|
defaultScopes: string[];
|
|
355
421
|
scopePolicy: Record<string, unknown>;
|
|
356
|
-
|
|
357
|
-
|
|
422
|
+
scopeSeparator: string;
|
|
423
|
+
authorizeParams: Record<string, string>;
|
|
424
|
+
displayLabel: string;
|
|
358
425
|
description: string;
|
|
359
426
|
dashboardUrl: string;
|
|
360
427
|
clientIdPlaceholder: string;
|
|
428
|
+
logoUrl: string | null;
|
|
361
429
|
requiresClientSecret: boolean;
|
|
362
430
|
loopbackPort: number;
|
|
363
431
|
injectionTemplates: Array<{
|
|
@@ -378,16 +446,21 @@ export function updateProvider(
|
|
|
378
446
|
featureFlag: string;
|
|
379
447
|
}>,
|
|
380
448
|
): OAuthProviderRow | undefined {
|
|
381
|
-
const existing = getProvider(
|
|
449
|
+
const existing = getProvider(provider);
|
|
382
450
|
if (!existing) return undefined;
|
|
383
451
|
|
|
384
452
|
const db = getDb();
|
|
385
453
|
const set: Record<string, unknown> = { updatedAt: Date.now() };
|
|
386
454
|
|
|
387
|
-
if (params.
|
|
388
|
-
if (params.
|
|
455
|
+
if (params.authorizeUrl !== undefined) set.authorizeUrl = params.authorizeUrl;
|
|
456
|
+
if (params.tokenExchangeUrl !== undefined)
|
|
457
|
+
set.tokenExchangeUrl = params.tokenExchangeUrl;
|
|
458
|
+
if (params.refreshUrl !== undefined) set.refreshUrl = params.refreshUrl;
|
|
389
459
|
if (params.tokenEndpointAuthMethod !== undefined)
|
|
390
|
-
set.tokenEndpointAuthMethod =
|
|
460
|
+
set.tokenEndpointAuthMethod =
|
|
461
|
+
params.tokenEndpointAuthMethod || "client_secret_post";
|
|
462
|
+
if (params.tokenExchangeBodyFormat !== undefined)
|
|
463
|
+
set.tokenExchangeBodyFormat = params.tokenExchangeBodyFormat || "form";
|
|
391
464
|
if (params.userinfoUrl !== undefined) set.userinfoUrl = params.userinfoUrl;
|
|
392
465
|
if (params.pingUrl !== undefined) set.pingUrl = params.pingUrl;
|
|
393
466
|
if (params.pingMethod !== undefined) set.pingMethod = params.pingMethod;
|
|
@@ -395,18 +468,28 @@ export function updateProvider(
|
|
|
395
468
|
set.pingHeaders = JSON.stringify(params.pingHeaders);
|
|
396
469
|
if (params.pingBody !== undefined)
|
|
397
470
|
set.pingBody = JSON.stringify(params.pingBody);
|
|
471
|
+
if (params.revokeUrl !== undefined) set.revokeUrl = params.revokeUrl;
|
|
472
|
+
if (params.revokeBodyTemplate !== undefined)
|
|
473
|
+
set.revokeBodyTemplate =
|
|
474
|
+
params.revokeBodyTemplate === null
|
|
475
|
+
? null
|
|
476
|
+
: JSON.stringify(params.revokeBodyTemplate);
|
|
398
477
|
if (params.baseUrl !== undefined) set.baseUrl = params.baseUrl;
|
|
399
478
|
if (params.defaultScopes !== undefined)
|
|
400
479
|
set.defaultScopes = JSON.stringify(params.defaultScopes);
|
|
401
480
|
if (params.scopePolicy !== undefined)
|
|
402
481
|
set.scopePolicy = JSON.stringify(params.scopePolicy);
|
|
403
|
-
if (params.
|
|
404
|
-
|
|
405
|
-
|
|
482
|
+
if (params.scopeSeparator !== undefined)
|
|
483
|
+
// Coerce empty string to the default space separator (see seedProviders).
|
|
484
|
+
set.scopeSeparator = params.scopeSeparator || " ";
|
|
485
|
+
if (params.authorizeParams !== undefined)
|
|
486
|
+
set.authorizeParams = JSON.stringify(params.authorizeParams);
|
|
487
|
+
if (params.displayLabel !== undefined) set.displayLabel = params.displayLabel;
|
|
406
488
|
if (params.description !== undefined) set.description = params.description;
|
|
407
489
|
if (params.dashboardUrl !== undefined) set.dashboardUrl = params.dashboardUrl;
|
|
408
490
|
if (params.clientIdPlaceholder !== undefined)
|
|
409
491
|
set.clientIdPlaceholder = params.clientIdPlaceholder;
|
|
492
|
+
if (params.logoUrl !== undefined) set.logoUrl = params.logoUrl;
|
|
410
493
|
if (params.requiresClientSecret !== undefined)
|
|
411
494
|
set.requiresClientSecret = params.requiresClientSecret ? 1 : 0;
|
|
412
495
|
if (params.loopbackPort !== undefined) set.loopbackPort = params.loopbackPort;
|
|
@@ -432,10 +515,10 @@ export function updateProvider(
|
|
|
432
515
|
|
|
433
516
|
db.update(oauthProviders)
|
|
434
517
|
.set(set)
|
|
435
|
-
.where(eq(oauthProviders.
|
|
518
|
+
.where(eq(oauthProviders.provider, provider))
|
|
436
519
|
.run();
|
|
437
520
|
|
|
438
|
-
return getProvider(
|
|
521
|
+
return getProvider(provider);
|
|
439
522
|
}
|
|
440
523
|
|
|
441
524
|
/**
|
|
@@ -445,14 +528,12 @@ export function updateProvider(
|
|
|
445
528
|
* Note: SQLite enforces the foreign-key constraint from `oauth_apps.provider_key`,
|
|
446
529
|
* so deleting a provider that has existing apps will throw.
|
|
447
530
|
*/
|
|
448
|
-
export function deleteProvider(
|
|
449
|
-
const existing = getProvider(
|
|
531
|
+
export function deleteProvider(provider: string): boolean {
|
|
532
|
+
const existing = getProvider(provider);
|
|
450
533
|
if (!existing) return false;
|
|
451
534
|
|
|
452
535
|
const db = getDb();
|
|
453
|
-
db.delete(oauthProviders)
|
|
454
|
-
.where(eq(oauthProviders.providerKey, providerKey))
|
|
455
|
-
.run();
|
|
536
|
+
db.delete(oauthProviders).where(eq(oauthProviders.provider, provider)).run();
|
|
456
537
|
return rawChanges() > 0;
|
|
457
538
|
}
|
|
458
539
|
|
|
@@ -465,7 +546,7 @@ export function deleteProvider(providerKey: string): boolean {
|
|
|
465
546
|
* Generates a UUID on insert.
|
|
466
547
|
*/
|
|
467
548
|
export async function upsertApp(
|
|
468
|
-
|
|
549
|
+
provider: string,
|
|
469
550
|
clientId: string,
|
|
470
551
|
clientSecretOpts?: {
|
|
471
552
|
clientSecretValue?: string;
|
|
@@ -499,10 +580,7 @@ export async function upsertApp(
|
|
|
499
580
|
.select()
|
|
500
581
|
.from(oauthApps)
|
|
501
582
|
.where(
|
|
502
|
-
and(
|
|
503
|
-
eq(oauthApps.providerKey, providerKey),
|
|
504
|
-
eq(oauthApps.clientId, clientId),
|
|
505
|
-
),
|
|
583
|
+
and(eq(oauthApps.provider, provider), eq(oauthApps.clientId, clientId)),
|
|
506
584
|
)
|
|
507
585
|
.get();
|
|
508
586
|
|
|
@@ -549,7 +627,7 @@ export async function upsertApp(
|
|
|
549
627
|
|
|
550
628
|
const row = {
|
|
551
629
|
id,
|
|
552
|
-
|
|
630
|
+
provider,
|
|
553
631
|
clientId,
|
|
554
632
|
clientSecretCredentialPath: credPath,
|
|
555
633
|
createdAt: now,
|
|
@@ -597,7 +675,7 @@ export async function getAppClientSecret(
|
|
|
597
675
|
|
|
598
676
|
/** Look up an app by (provider_key, client_id). */
|
|
599
677
|
export function getAppByProviderAndClientId(
|
|
600
|
-
|
|
678
|
+
provider: string,
|
|
601
679
|
clientId: string,
|
|
602
680
|
): OAuthAppRow | undefined {
|
|
603
681
|
const db = getDb();
|
|
@@ -605,10 +683,7 @@ export function getAppByProviderAndClientId(
|
|
|
605
683
|
.select()
|
|
606
684
|
.from(oauthApps)
|
|
607
685
|
.where(
|
|
608
|
-
and(
|
|
609
|
-
eq(oauthApps.providerKey, providerKey),
|
|
610
|
-
eq(oauthApps.clientId, clientId),
|
|
611
|
-
),
|
|
686
|
+
and(eq(oauthApps.provider, provider), eq(oauthApps.clientId, clientId)),
|
|
612
687
|
)
|
|
613
688
|
.get();
|
|
614
689
|
}
|
|
@@ -618,13 +693,13 @@ export function getAppByProviderAndClientId(
|
|
|
618
693
|
* Returns undefined if no app exists for this provider.
|
|
619
694
|
*/
|
|
620
695
|
export function getMostRecentAppByProvider(
|
|
621
|
-
|
|
696
|
+
provider: string,
|
|
622
697
|
): OAuthAppRow | undefined {
|
|
623
698
|
const db = getDb();
|
|
624
699
|
return db
|
|
625
700
|
.select()
|
|
626
701
|
.from(oauthApps)
|
|
627
|
-
.where(eq(oauthApps.
|
|
702
|
+
.where(eq(oauthApps.provider, provider))
|
|
628
703
|
.orderBy(desc(oauthApps.createdAt))
|
|
629
704
|
.limit(1)
|
|
630
705
|
.get();
|
|
@@ -670,7 +745,7 @@ export async function deleteApp(id: string): Promise<boolean> {
|
|
|
670
745
|
*/
|
|
671
746
|
export function createConnection(params: {
|
|
672
747
|
oauthAppId: string;
|
|
673
|
-
|
|
748
|
+
provider: string;
|
|
674
749
|
accountInfo?: string;
|
|
675
750
|
grantedScopes: string[];
|
|
676
751
|
expiresAt?: number;
|
|
@@ -687,7 +762,7 @@ export function createConnection(params: {
|
|
|
687
762
|
const row = {
|
|
688
763
|
id,
|
|
689
764
|
oauthAppId: params.oauthAppId,
|
|
690
|
-
|
|
765
|
+
provider: params.provider,
|
|
691
766
|
accountInfo: params.accountInfo ?? null,
|
|
692
767
|
grantedScopes: JSON.stringify(params.grantedScopes),
|
|
693
768
|
expiresAt: params.expiresAt ?? null,
|
|
@@ -724,14 +799,14 @@ export function getConnection(id: string): OAuthConnectionRow | undefined {
|
|
|
724
799
|
* Returns `undefined` when no matching active connection exists.
|
|
725
800
|
*/
|
|
726
801
|
export function getActiveConnection(
|
|
727
|
-
|
|
802
|
+
provider: string,
|
|
728
803
|
options?: { clientId?: string; account?: string },
|
|
729
804
|
): OAuthConnectionRow | undefined {
|
|
730
805
|
const { clientId, account } = options ?? {};
|
|
731
806
|
const db = getDb();
|
|
732
807
|
|
|
733
808
|
const conditions = [
|
|
734
|
-
eq(oauthConnections.
|
|
809
|
+
eq(oauthConnections.provider, provider),
|
|
735
810
|
eq(oauthConnections.status, "active"),
|
|
736
811
|
];
|
|
737
812
|
|
|
@@ -740,7 +815,7 @@ export function getActiveConnection(
|
|
|
740
815
|
}
|
|
741
816
|
|
|
742
817
|
if (clientId) {
|
|
743
|
-
const app = getAppByProviderAndClientId(
|
|
818
|
+
const app = getAppByProviderAndClientId(provider, clientId);
|
|
744
819
|
if (!app) return undefined;
|
|
745
820
|
conditions.push(eq(oauthConnections.oauthAppId, app.id));
|
|
746
821
|
}
|
|
@@ -756,26 +831,26 @@ export function getActiveConnection(
|
|
|
756
831
|
|
|
757
832
|
/** @deprecated Use {@link getActiveConnection} instead. */
|
|
758
833
|
export function getConnectionByProvider(
|
|
759
|
-
|
|
834
|
+
provider: string,
|
|
760
835
|
clientId?: string,
|
|
761
836
|
): OAuthConnectionRow | undefined {
|
|
762
|
-
return getActiveConnection(
|
|
837
|
+
return getActiveConnection(provider, { clientId });
|
|
763
838
|
}
|
|
764
839
|
|
|
765
840
|
/** @deprecated Use {@link getActiveConnection} instead. */
|
|
766
841
|
export function getConnectionByProviderAndAccount(
|
|
767
|
-
|
|
842
|
+
provider: string,
|
|
768
843
|
accountInfo?: string,
|
|
769
844
|
clientId?: string,
|
|
770
845
|
): OAuthConnectionRow | undefined {
|
|
771
|
-
return getActiveConnection(
|
|
846
|
+
return getActiveConnection(provider, { clientId, account: accountInfo });
|
|
772
847
|
}
|
|
773
848
|
|
|
774
849
|
/**
|
|
775
850
|
* Get ALL active connections for a provider (supports multi-account).
|
|
776
851
|
*/
|
|
777
852
|
export function listActiveConnectionsByProvider(
|
|
778
|
-
|
|
853
|
+
provider: string,
|
|
779
854
|
): OAuthConnectionRow[] {
|
|
780
855
|
const db = getDb();
|
|
781
856
|
return db
|
|
@@ -783,7 +858,7 @@ export function listActiveConnectionsByProvider(
|
|
|
783
858
|
.from(oauthConnections)
|
|
784
859
|
.where(
|
|
785
860
|
and(
|
|
786
|
-
eq(oauthConnections.
|
|
861
|
+
eq(oauthConnections.provider, provider),
|
|
787
862
|
eq(oauthConnections.status, "active"),
|
|
788
863
|
),
|
|
789
864
|
)
|
|
@@ -799,10 +874,8 @@ export function listActiveConnectionsByProvider(
|
|
|
799
874
|
* but the secure-key write for the access token failed, which would make
|
|
800
875
|
* `resolveOAuthConnection()` throw at usage time.
|
|
801
876
|
*/
|
|
802
|
-
export async function isProviderConnected(
|
|
803
|
-
|
|
804
|
-
): Promise<boolean> {
|
|
805
|
-
const conn = getActiveConnection(providerKey);
|
|
877
|
+
export async function isProviderConnected(provider: string): Promise<boolean> {
|
|
878
|
+
const conn = getActiveConnection(provider);
|
|
806
879
|
if (!conn || conn.status !== "active") return false;
|
|
807
880
|
return (
|
|
808
881
|
(await getSecureKeyAsync(oauthConnectionAccessTokenPath(conn.id))) !==
|
|
@@ -853,24 +926,24 @@ export function updateConnection(
|
|
|
853
926
|
|
|
854
927
|
/** List connections, optionally filtered by provider key and/or client ID. */
|
|
855
928
|
export function listConnections(
|
|
856
|
-
|
|
929
|
+
provider?: string,
|
|
857
930
|
clientId?: string,
|
|
858
931
|
): OAuthConnectionRow[] {
|
|
859
932
|
const db = getDb();
|
|
860
933
|
|
|
861
934
|
let rows: OAuthConnectionRow[];
|
|
862
|
-
if (
|
|
935
|
+
if (provider) {
|
|
863
936
|
rows = db
|
|
864
937
|
.select()
|
|
865
938
|
.from(oauthConnections)
|
|
866
|
-
.where(eq(oauthConnections.
|
|
867
|
-
.orderBy(oauthConnections.
|
|
939
|
+
.where(eq(oauthConnections.provider, provider))
|
|
940
|
+
.orderBy(oauthConnections.provider, oauthConnections.id)
|
|
868
941
|
.all();
|
|
869
942
|
} else {
|
|
870
943
|
rows = db
|
|
871
944
|
.select()
|
|
872
945
|
.from(oauthConnections)
|
|
873
|
-
.orderBy(oauthConnections.
|
|
946
|
+
.orderBy(oauthConnections.provider, oauthConnections.id)
|
|
874
947
|
.all();
|
|
875
948
|
}
|
|
876
949
|
|
|
@@ -901,28 +974,78 @@ export function deleteConnection(id: string): boolean {
|
|
|
901
974
|
// ---------------------------------------------------------------------------
|
|
902
975
|
|
|
903
976
|
/**
|
|
904
|
-
* Fully disconnect an OAuth provider:
|
|
905
|
-
*
|
|
977
|
+
* Fully disconnect an OAuth provider:
|
|
978
|
+
* 1. Best-effort upstream token revoke when the provider has `revokeUrl`
|
|
979
|
+
* configured (mirrors platform's `try_revoke_token`).
|
|
980
|
+
* 2. Delete the new-format secure keys (access_token and refresh_token).
|
|
981
|
+
* 3. Remove the connection row from SQLite.
|
|
982
|
+
*
|
|
983
|
+
* The upstream revoke step is strictly best-effort: any failure (network
|
|
984
|
+
* error, non-2xx response, missing access token, etc.) is logged as a
|
|
985
|
+
* warning and the local cleanup proceeds anyway. The connection is always
|
|
986
|
+
* cleaned up locally regardless of whether the upstream call succeeds.
|
|
906
987
|
*
|
|
907
988
|
* When `connectionId` is provided, disconnects that specific connection
|
|
908
989
|
* (useful for multi-account providers). Otherwise falls back to the most
|
|
909
990
|
* recent active connection.
|
|
910
991
|
*
|
|
911
|
-
* Returns `"disconnected"` if a connection was found and cleaned up,
|
|
992
|
+
* Returns `"disconnected"` if a connection was found and locally cleaned up,
|
|
912
993
|
* `"not-found"` if no active connection existed for the given provider,
|
|
913
994
|
* or `"error"` if secure key deletion failed (connection row is preserved
|
|
914
995
|
* to avoid orphaning secrets).
|
|
915
996
|
*/
|
|
916
997
|
export async function disconnectOAuthProvider(
|
|
917
|
-
|
|
998
|
+
provider: string,
|
|
918
999
|
clientId?: string,
|
|
919
1000
|
connectionId?: string,
|
|
920
1001
|
): Promise<"disconnected" | "not-found" | "error"> {
|
|
921
1002
|
const conn = connectionId
|
|
922
1003
|
? getConnection(connectionId)
|
|
923
|
-
: getActiveConnection(
|
|
1004
|
+
: getActiveConnection(provider, { clientId });
|
|
924
1005
|
if (!conn) return "not-found";
|
|
925
1006
|
|
|
1007
|
+
// Best-effort upstream revoke. Mirrors platform's try_revoke_token in
|
|
1008
|
+
// django/app/assistant/oauth/providers/base.py. Failures here never
|
|
1009
|
+
// block local cleanup — the connection is always cleaned up locally
|
|
1010
|
+
// regardless of whether the upstream call succeeds.
|
|
1011
|
+
try {
|
|
1012
|
+
const providerRow = getProvider(conn.provider);
|
|
1013
|
+
if (providerRow?.revokeUrl) {
|
|
1014
|
+
const app = getApp(conn.oauthAppId);
|
|
1015
|
+
const accessToken = await getSecureKeyAsync(
|
|
1016
|
+
oauthConnectionAccessTokenPath(conn.id),
|
|
1017
|
+
);
|
|
1018
|
+
if (app && accessToken) {
|
|
1019
|
+
const bodyTemplate = providerRow.revokeBodyTemplate
|
|
1020
|
+
? (JSON.parse(providerRow.revokeBodyTemplate) as Record<
|
|
1021
|
+
string,
|
|
1022
|
+
unknown
|
|
1023
|
+
>)
|
|
1024
|
+
: null;
|
|
1025
|
+
await tryRevokeOAuthToken({
|
|
1026
|
+
provider: conn.provider,
|
|
1027
|
+
revokeUrl: providerRow.revokeUrl,
|
|
1028
|
+
bodyTemplate,
|
|
1029
|
+
accessToken,
|
|
1030
|
+
clientId: app.clientId,
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
} catch (err) {
|
|
1035
|
+
// tryRevokeOAuthToken already swallows fetch errors, but the lookups
|
|
1036
|
+
// (getProvider/getApp/getSecureKeyAsync/JSON.parse) could throw too.
|
|
1037
|
+
// Defense in depth: never let the local cleanup path die because of
|
|
1038
|
+
// anything in the revoke setup.
|
|
1039
|
+
log.warn(
|
|
1040
|
+
{
|
|
1041
|
+
provider: conn.provider,
|
|
1042
|
+
connectionId: conn.id,
|
|
1043
|
+
err: err instanceof Error ? err.message : String(err),
|
|
1044
|
+
},
|
|
1045
|
+
"Error preparing upstream OAuth revoke (best-effort, continuing local cleanup)",
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
926
1049
|
// Wrap the assistant's secure-key functions into the SecureKeyBackend
|
|
927
1050
|
// interface expected by the shared deleteOAuthTokens helper.
|
|
928
1051
|
const backend: SecureKeyBackend = {
|
|
@@ -945,7 +1068,7 @@ export async function disconnectOAuthProvider(
|
|
|
945
1068
|
// way to surface the failure.
|
|
946
1069
|
log.warn(
|
|
947
1070
|
{
|
|
948
|
-
|
|
1071
|
+
provider,
|
|
949
1072
|
connectionId: conn.id,
|
|
950
1073
|
accessTokenResult,
|
|
951
1074
|
refreshTokenResult,
|