@vellumai/assistant 0.6.1 → 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/docker-entrypoint.sh +12 -2
- package/docs/architecture/memory.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +7 -9
- 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__/assistant-event-hub.test.ts +30 -0
- 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__/checker.test.ts +104 -170
- package/src/__tests__/cli-command-risk-guard.test.ts +1 -1
- 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 +21 -6
- 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 +169 -0
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
- package/src/__tests__/conversation-directories-parse.test.ts +105 -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 -3
- 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__/init-feature-flag-overrides.test.ts +167 -0
- package/src/__tests__/inline-command-runner.test.ts +7 -5
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/log-export-workspace.test.ts +190 -0
- package/src/__tests__/managed-credential-catalog-cli.test.ts +12 -14
- 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__/navigate-settings-tab.test.ts +14 -1
- package/src/__tests__/notification-broadcaster.test.ts +65 -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 +74 -55
- 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__/pkb-autoinject.test.ts +96 -0
- 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 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +1 -32
- 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-sandbox.test.ts +1 -1
- package/src/__tests__/terminal-tools.test.ts +11 -5
- package/src/__tests__/test-preload.ts +14 -0
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -8
- package/src/__tests__/tool-executor.test.ts +0 -1
- 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 +62 -0
- package/src/__tests__/trust-store.test.ts +4 -4
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/__tests__/workspace-migration-030-seed-pkb-autoinject.test.ts +168 -0
- package/src/__tests__/workspace-policy.test.ts +2 -7
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/loop.ts +12 -35
- 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 +55 -0
- package/src/cli/__tests__/run-assistant-command.ts +34 -7
- package/src/cli/__tests__/unknown-command.test.ts +33 -0
- package/src/cli/commands/browser-relay.ts +339 -409
- package/src/cli/commands/credentials.ts +3 -3
- package/src/cli/commands/default-action.ts +68 -1
- 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 +68 -41
- 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 +16 -2
- 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/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +1 -1
- 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 +10 -3
- package/src/config/assistant-feature-flags.ts +59 -55
- package/src/config/bundled-skills/app-builder/SKILL.md +33 -173
- 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 +12 -7
- package/src/config/bundled-skills/gmail/TOOLS.json +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -1
- package/src/config/bundled-skills/outlook/SKILL.md +7 -0
- package/src/config/bundled-skills/settings/TOOLS.json +1 -1
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +8 -3
- 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 +46 -7
- 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 +16 -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 -16
- package/src/credential-execution/managed-catalog.ts +3 -7
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +6 -2
- package/src/daemon/context-overflow-approval.ts +5 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
- package/src/daemon/conversation-agent-loop.ts +74 -19
- package/src/daemon/conversation-attachments.ts +40 -1
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +66 -3
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +159 -20
- package/src/daemon/conversation-surfaces.ts +78 -12
- package/src/daemon/conversation-tool-setup.ts +74 -11
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +227 -11
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/conversations.ts +9 -139
- package/src/daemon/handlers/shared.ts +65 -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 +86 -12
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/conversations.ts +59 -13
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/messages.ts +5 -6
- package/src/daemon/message-types/notifications.ts +12 -0
- package/src/daemon/message-types/settings.ts +12 -0
- package/src/daemon/message-types/skills.ts +10 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/server.ts +112 -35
- package/src/daemon/tool-side-effects.ts +6 -0
- package/src/daemon/transport-hints.ts +14 -0
- package/src/inbound/platform-callback-registration.ts +18 -17
- package/src/index.ts +1 -1
- package/src/mcp/client.ts +59 -24
- package/src/memory/app-store.ts +31 -1
- package/src/memory/conversation-crud.ts +38 -10
- package/src/memory/conversation-directories.ts +39 -0
- package/src/memory/conversation-group-migration.ts +65 -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 +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 +177 -18
- package/src/memory/graph/capability-seed.ts +3 -5
- 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/group-crud.ts +25 -9
- 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/messaging/provider.ts +1 -1
- package/src/notifications/broadcaster.ts +6 -0
- package/src/notifications/conversation-pairing.ts +12 -4
- package/src/notifications/emit-signal.ts +14 -0
- package/src/notifications/signal.ts +11 -0
- 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 +5 -5
- 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 +127 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +3 -3
- package/src/permissions/defaults.ts +7 -8
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/platform/client.ts +1 -1
- package/src/prompts/system-prompt.ts +18 -21
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -96
- package/src/prompts/templates/SOUL.md +11 -11
- 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 +24 -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/auth/token-service.ts +8 -0
- 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 +18 -5
- package/src/runtime/routes/conversation-management-routes.ts +108 -0
- package/src/runtime/routes/conversation-routes.ts +308 -28
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/group-routes.ts +22 -8
- 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/AGENTS.md +104 -0
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +103 -0
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +716 -0
- package/src/runtime/routes/log-export/workspace-allowlist.ts +458 -0
- package/src/runtime/routes/log-export-routes.ts +60 -25
- 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/skills/inline-command-runner.ts +12 -14
- 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 -100
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -1
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/skills/sandbox-runner.ts +3 -6
- 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/sandbox-diagnostics.ts +4 -4
- package/src/tools/terminal/sandbox.ts +4 -1
- package/src/tools/terminal/shell.ts +24 -21
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/types.ts +2 -3
- package/src/util/platform.ts +14 -19
- package/src/watcher/provider-types.ts +1 -1
- package/src/workspace/migrations/029-seed-pkb.ts +1 -0
- package/src/workspace/migrations/030-seed-pkb-autoinject.ts +73 -0
- package/src/workspace/migrations/registry.ts +2 -0
- 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
|
@@ -312,7 +312,7 @@ Examples:
|
|
|
312
312
|
});
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
// Build a lookup of oauth connections keyed by
|
|
315
|
+
// Build a lookup of oauth connections keyed by provider for enrichment.
|
|
316
316
|
// listConnections() returns rows in no guaranteed order, so we compare
|
|
317
317
|
// createdAt to keep the most recent active connection per provider —
|
|
318
318
|
// matching the behaviour of getConnectionByProvider() used by inspect.
|
|
@@ -320,9 +320,9 @@ Examples:
|
|
|
320
320
|
const connectionsByProvider = new Map<string, OAuthConnectionRow>();
|
|
321
321
|
for (const conn of allConnections) {
|
|
322
322
|
if (conn.status !== "active") continue;
|
|
323
|
-
const existing = connectionsByProvider.get(conn.
|
|
323
|
+
const existing = connectionsByProvider.get(conn.provider);
|
|
324
324
|
if (!existing || conn.createdAt > existing.createdAt) {
|
|
325
|
-
connectionsByProvider.set(conn.
|
|
325
|
+
connectionsByProvider.set(conn.provider, conn);
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
328
|
|
|
@@ -5,10 +5,77 @@ import { shouldAutoStartDaemon } from "../../daemon/connection-policy.js";
|
|
|
5
5
|
import { ensureDaemonRunning } from "../../daemon/lifecycle.js";
|
|
6
6
|
|
|
7
7
|
export function registerDefaultAction(program: Command): void {
|
|
8
|
-
program.action(async () => {
|
|
8
|
+
program.action(async (_options: unknown, cmd: Command) => {
|
|
9
|
+
// Commander routes unknown subcommands to the root action as positional
|
|
10
|
+
// args instead of raising an error. Detect this case and fail with a
|
|
11
|
+
// helpful message so users don't silently get the interactive CLI when
|
|
12
|
+
// they mistype a command name.
|
|
13
|
+
if (cmd.args.length > 0) {
|
|
14
|
+
const unknown = cmd.args[0];
|
|
15
|
+
const available = cmd.commands.map((c) => c.name());
|
|
16
|
+
const suggestion = findClosestCommand(unknown, available);
|
|
17
|
+
const lines = [`unknown command '${unknown}'`];
|
|
18
|
+
if (suggestion) {
|
|
19
|
+
lines.push(`(Did you mean '${suggestion}'?)`);
|
|
20
|
+
}
|
|
21
|
+
lines.push(`Run 'assistant --help' to see a list of available commands.`);
|
|
22
|
+
cmd.error(lines.join("\n"), {
|
|
23
|
+
code: "commander.unknownCommand",
|
|
24
|
+
exitCode: 1,
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
9
29
|
if (shouldAutoStartDaemon()) {
|
|
10
30
|
await ensureDaemonRunning();
|
|
11
31
|
}
|
|
12
32
|
await startCli();
|
|
13
33
|
});
|
|
14
34
|
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Find the closest matching command name using Levenshtein distance.
|
|
38
|
+
* Returns the best match if the distance is ≤ 40% of the longer string's
|
|
39
|
+
* length, otherwise returns undefined.
|
|
40
|
+
*/
|
|
41
|
+
function findClosestCommand(
|
|
42
|
+
input: string,
|
|
43
|
+
candidates: string[],
|
|
44
|
+
): string | undefined {
|
|
45
|
+
let best: string | undefined;
|
|
46
|
+
let bestDist = Infinity;
|
|
47
|
+
|
|
48
|
+
for (const name of candidates) {
|
|
49
|
+
const dist = levenshtein(input.toLowerCase(), name.toLowerCase());
|
|
50
|
+
if (dist < bestDist) {
|
|
51
|
+
bestDist = dist;
|
|
52
|
+
best = name;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Only suggest if the edit distance is at most 40% of the longer string
|
|
57
|
+
const maxLen = Math.max(input.length, best?.length ?? 0);
|
|
58
|
+
if (best && bestDist <= Math.ceil(maxLen * 0.4)) {
|
|
59
|
+
return best;
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function levenshtein(a: string, b: string): number {
|
|
65
|
+
const m = a.length;
|
|
66
|
+
const n = b.length;
|
|
67
|
+
const dp: number[][] = Array.from({ length: m + 1 }, () =>
|
|
68
|
+
Array(n + 1).fill(0),
|
|
69
|
+
);
|
|
70
|
+
for (let i = 0; i <= m; i++) dp[i][0] = i;
|
|
71
|
+
for (let j = 0; j <= n; j++) dp[0][j] = j;
|
|
72
|
+
for (let i = 1; i <= m; i++) {
|
|
73
|
+
for (let j = 1; j <= n; j++) {
|
|
74
|
+
dp[i][j] =
|
|
75
|
+
a[i - 1] === b[j - 1]
|
|
76
|
+
? dp[i - 1][j - 1]
|
|
77
|
+
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return dp[m][n];
|
|
81
|
+
}
|
|
@@ -2,6 +2,7 @@ import { readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
|
|
3
3
|
import type { Command } from "commander";
|
|
4
4
|
|
|
5
|
+
import { getAssistantDomain } from "../../config/env.js";
|
|
5
6
|
import { VellumPlatformClient } from "../../platform/client.js";
|
|
6
7
|
import { getCliLogger } from "../logger.js";
|
|
7
8
|
import { shouldOutputJson, writeOutput } from "../output.js";
|
|
@@ -9,15 +10,19 @@ import { shouldOutputJson, writeOutput } from "../output.js";
|
|
|
9
10
|
const log = getCliLogger("email");
|
|
10
11
|
|
|
11
12
|
export function registerEmailCommand(program: Command): void {
|
|
13
|
+
const domain = getAssistantDomain();
|
|
12
14
|
const email = program
|
|
13
15
|
.command("email")
|
|
14
|
-
.description(
|
|
16
|
+
.description(
|
|
17
|
+
`Get your own email address (@${domain}) — register, send, receive, and manage email natively`,
|
|
18
|
+
)
|
|
15
19
|
.option("--json", "Machine-readable compact JSON output");
|
|
16
20
|
|
|
17
21
|
email.addHelpText(
|
|
18
22
|
"after",
|
|
19
23
|
`
|
|
20
|
-
|
|
24
|
+
Set up and manage this assistant's native email address on the Vellum
|
|
25
|
+
platform. No third-party email provider or browser sign-up needed.
|
|
21
26
|
|
|
22
27
|
Examples:
|
|
23
28
|
$ assistant email register mybot
|
|
@@ -30,12 +35,12 @@ Examples:
|
|
|
30
35
|
|
|
31
36
|
email
|
|
32
37
|
.command("register <username>")
|
|
33
|
-
.description(
|
|
38
|
+
.description(`Register an @${domain} email address for this assistant`)
|
|
34
39
|
.addHelpText(
|
|
35
40
|
"after",
|
|
36
41
|
`
|
|
37
42
|
Arguments:
|
|
38
|
-
username The local part of the email address (e.g. "mybot" → mybot
|
|
43
|
+
username The local part of the email address (e.g. "mybot" → mybot@${domain})
|
|
39
44
|
|
|
40
45
|
Registers a new email address on the Vellum platform for the current
|
|
41
46
|
assistant. Each assistant can have one email address. The address is
|
|
@@ -43,10 +48,10 @@ immediately active for receiving inbound email.
|
|
|
43
48
|
|
|
44
49
|
Examples:
|
|
45
50
|
$ assistant email register mybot
|
|
46
|
-
✓ Registered mybot
|
|
51
|
+
✓ Registered mybot@${domain}
|
|
47
52
|
|
|
48
53
|
$ assistant email register support --json
|
|
49
|
-
{"address":"support
|
|
54
|
+
{"address":"support@${domain}","id":"...","created_at":"..."}`,
|
|
50
55
|
)
|
|
51
56
|
.action(async (username: string, _opts: unknown, cmd: Command) => {
|
|
52
57
|
try {
|
|
@@ -122,14 +127,14 @@ immediately available for reuse.
|
|
|
122
127
|
|
|
123
128
|
Examples:
|
|
124
129
|
$ assistant email unregister
|
|
125
|
-
Remove mybot
|
|
126
|
-
✓ Unregistered mybot
|
|
130
|
+
Remove mybot@${domain}? (y/N) y
|
|
131
|
+
✓ Unregistered mybot@${domain}
|
|
127
132
|
|
|
128
133
|
$ assistant email unregister --confirm
|
|
129
|
-
✓ Unregistered mybot
|
|
134
|
+
✓ Unregistered mybot@${domain}
|
|
130
135
|
|
|
131
136
|
$ assistant email unregister --json
|
|
132
|
-
{"unregistered":"mybot
|
|
137
|
+
{"unregistered":"mybot@${domain}"}`,
|
|
133
138
|
)
|
|
134
139
|
.action(async (_opts: { confirm?: boolean }, cmd: Command) => {
|
|
135
140
|
try {
|
|
@@ -222,12 +227,12 @@ current usage and quota information from the platform.
|
|
|
222
227
|
|
|
223
228
|
Examples:
|
|
224
229
|
$ assistant email status
|
|
225
|
-
Address: mybot
|
|
230
|
+
Address: mybot@${domain}
|
|
226
231
|
Status: active
|
|
227
232
|
Sent: 12 / 100 (daily)
|
|
228
233
|
|
|
229
234
|
$ assistant email status --json
|
|
230
|
-
{"address":"mybot
|
|
235
|
+
{"address":"mybot@${domain}","status":"active","usage":{"sent_today":12,"daily_limit":100}}`,
|
|
231
236
|
)
|
|
232
237
|
.action(async (_opts: unknown, cmd: Command) => {
|
|
233
238
|
try {
|
|
@@ -446,7 +451,7 @@ or --format json for the full message object.
|
|
|
446
451
|
Examples:
|
|
447
452
|
$ assistant email download msg_abc123
|
|
448
453
|
From: user@example.com
|
|
449
|
-
To: mybot
|
|
454
|
+
To: mybot@${domain}
|
|
450
455
|
Subject: Hello
|
|
451
456
|
Date: 2026-04-05 12:00:00
|
|
452
457
|
|
package/src/cli/commands/mcp.ts
CHANGED
|
@@ -34,13 +34,25 @@ export async function checkServerHealth(
|
|
|
34
34
|
}),
|
|
35
35
|
]);
|
|
36
36
|
|
|
37
|
-
if (
|
|
38
|
-
|
|
37
|
+
if (client.isConnected) {
|
|
38
|
+
await client.disconnect();
|
|
39
|
+
return "\u2713 Connected";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// connect() swallows errors — check lastError to distinguish auth from
|
|
43
|
+
// transport failures (DNS, TLS, 500, stdio crash, etc.).
|
|
44
|
+
const err = client.lastError;
|
|
45
|
+
if (err) {
|
|
46
|
+
const message = err.message;
|
|
47
|
+
if (message.includes("timeout")) {
|
|
48
|
+
return "\u2717 Timed out";
|
|
49
|
+
}
|
|
50
|
+
return `\u2717 Error: ${message}`;
|
|
39
51
|
}
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
return "\u2713 Connected";
|
|
53
|
+
return "! Needs authentication";
|
|
43
54
|
} catch (err) {
|
|
55
|
+
// Only the external timeout Promise can throw here (connect() never does).
|
|
44
56
|
try {
|
|
45
57
|
await client.disconnect();
|
|
46
58
|
} catch {
|
|
@@ -264,9 +264,9 @@ describe("assistant oauth connect", () => {
|
|
|
264
264
|
|
|
265
265
|
test("managed mode with --no-browser: prints connect URL", async () => {
|
|
266
266
|
mockGetProvider = () => ({
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
provider: "google",
|
|
268
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
269
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
270
270
|
managedServiceConfigKey: "google-oauth",
|
|
271
271
|
});
|
|
272
272
|
mockIsManagedMode = () => true;
|
|
@@ -301,9 +301,9 @@ describe("assistant oauth connect", () => {
|
|
|
301
301
|
|
|
302
302
|
test("managed mode default: opens browser and polls for new connection", async () => {
|
|
303
303
|
mockGetProvider = () => ({
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
304
|
+
provider: "google",
|
|
305
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
306
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
307
307
|
managedServiceConfigKey: "google-oauth",
|
|
308
308
|
});
|
|
309
309
|
mockIsManagedMode = () => true;
|
|
@@ -357,9 +357,9 @@ describe("assistant oauth connect", () => {
|
|
|
357
357
|
|
|
358
358
|
test("BYO mode with --no-browser: prints auth URL", async () => {
|
|
359
359
|
mockGetProvider = () => ({
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
360
|
+
provider: "google",
|
|
361
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
362
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
363
363
|
managedServiceConfigKey: null,
|
|
364
364
|
});
|
|
365
365
|
mockIsManagedMode = () => false;
|
|
@@ -368,7 +368,7 @@ describe("assistant oauth connect", () => {
|
|
|
368
368
|
id: "app-1",
|
|
369
369
|
clientId: "byo-client-id",
|
|
370
370
|
clientSecretCredentialPath: "oauth_app/app-1/client_secret",
|
|
371
|
-
|
|
371
|
+
provider: "google",
|
|
372
372
|
createdAt: 0,
|
|
373
373
|
updatedAt: 0,
|
|
374
374
|
});
|
|
@@ -376,7 +376,7 @@ describe("assistant oauth connect", () => {
|
|
|
376
376
|
mockOrchestrateOAuthConnect = async () => ({
|
|
377
377
|
success: true,
|
|
378
378
|
deferred: true,
|
|
379
|
-
|
|
379
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth?state=abc",
|
|
380
380
|
state: "abc",
|
|
381
381
|
service: "google",
|
|
382
382
|
});
|
|
@@ -403,9 +403,9 @@ describe("assistant oauth connect", () => {
|
|
|
403
403
|
|
|
404
404
|
test("BYO mode default calls orchestrator with isInteractive: true", async () => {
|
|
405
405
|
mockGetProvider = () => ({
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
406
|
+
provider: "google",
|
|
407
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
408
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
409
409
|
managedServiceConfigKey: null,
|
|
410
410
|
});
|
|
411
411
|
mockIsManagedMode = () => false;
|
|
@@ -414,7 +414,7 @@ describe("assistant oauth connect", () => {
|
|
|
414
414
|
id: "app-1",
|
|
415
415
|
clientId: "test-id",
|
|
416
416
|
clientSecretCredentialPath: "oauth_app/app-1/client_secret",
|
|
417
|
-
|
|
417
|
+
provider: "google",
|
|
418
418
|
createdAt: 0,
|
|
419
419
|
updatedAt: 0,
|
|
420
420
|
});
|
|
@@ -455,9 +455,9 @@ describe("assistant oauth connect", () => {
|
|
|
455
455
|
|
|
456
456
|
test("BYO mode: missing app with --client-id returns error with hint", async () => {
|
|
457
457
|
mockGetProvider = () => ({
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
458
|
+
provider: "google",
|
|
459
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
460
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
461
461
|
managedServiceConfigKey: null,
|
|
462
462
|
});
|
|
463
463
|
mockIsManagedMode = () => false;
|
|
@@ -483,9 +483,9 @@ describe("assistant oauth connect", () => {
|
|
|
483
483
|
|
|
484
484
|
test("BYO mode: no client_id found returns error with hint", async () => {
|
|
485
485
|
mockGetProvider = () => ({
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
486
|
+
provider: "google",
|
|
487
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
488
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
489
489
|
managedServiceConfigKey: null,
|
|
490
490
|
});
|
|
491
491
|
mockIsManagedMode = () => false;
|
|
@@ -509,9 +509,9 @@ describe("assistant oauth connect", () => {
|
|
|
509
509
|
|
|
510
510
|
test("--client-id is silently ignored in managed mode", async () => {
|
|
511
511
|
mockGetProvider = () => ({
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
512
|
+
provider: "google",
|
|
513
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
514
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
515
515
|
managedServiceConfigKey: "google-oauth",
|
|
516
516
|
});
|
|
517
517
|
mockIsManagedMode = () => true;
|
|
@@ -547,9 +547,9 @@ describe("assistant oauth connect", () => {
|
|
|
547
547
|
|
|
548
548
|
test("JSON output for deferred case includes ok, deferred, authUrl, service", async () => {
|
|
549
549
|
mockGetProvider = () => ({
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
provider: "slack",
|
|
551
|
+
authorizeUrl: "https://slack.com/oauth/v2/authorize",
|
|
552
|
+
tokenExchangeUrl: "https://slack.com/api/oauth.v2.access",
|
|
553
553
|
managedServiceConfigKey: null,
|
|
554
554
|
});
|
|
555
555
|
mockIsManagedMode = () => false;
|
|
@@ -558,7 +558,7 @@ describe("assistant oauth connect", () => {
|
|
|
558
558
|
id: "app-slack",
|
|
559
559
|
clientId: "slack-client-id",
|
|
560
560
|
clientSecretCredentialPath: "oauth_app/app-slack/client_secret",
|
|
561
|
-
|
|
561
|
+
provider: "slack",
|
|
562
562
|
createdAt: 0,
|
|
563
563
|
updatedAt: 0,
|
|
564
564
|
});
|
|
@@ -566,7 +566,7 @@ describe("assistant oauth connect", () => {
|
|
|
566
566
|
mockOrchestrateOAuthConnect = async () => ({
|
|
567
567
|
success: true,
|
|
568
568
|
deferred: true,
|
|
569
|
-
|
|
569
|
+
authorizeUrl: "https://slack.com/oauth/v2/authorize?state=xyz",
|
|
570
570
|
state: "xyz",
|
|
571
571
|
service: "slack",
|
|
572
572
|
});
|
|
@@ -591,9 +591,9 @@ describe("assistant oauth connect", () => {
|
|
|
591
591
|
|
|
592
592
|
test("JSON output for completed case includes ok, grantedScopes, accountInfo", async () => {
|
|
593
593
|
mockGetProvider = () => ({
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
594
|
+
provider: "google",
|
|
595
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
596
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
597
597
|
managedServiceConfigKey: null,
|
|
598
598
|
});
|
|
599
599
|
mockIsManagedMode = () => false;
|
|
@@ -602,7 +602,7 @@ describe("assistant oauth connect", () => {
|
|
|
602
602
|
id: "app-1",
|
|
603
603
|
clientId: "completed-client-id",
|
|
604
604
|
clientSecretCredentialPath: "oauth_app/app-1/client_secret",
|
|
605
|
-
|
|
605
|
+
provider: "google",
|
|
606
606
|
createdAt: 0,
|
|
607
607
|
updatedAt: 0,
|
|
608
608
|
});
|
|
@@ -635,9 +635,9 @@ describe("assistant oauth connect", () => {
|
|
|
635
635
|
|
|
636
636
|
test("BYO mode: client_secret required but missing returns error with hint", async () => {
|
|
637
637
|
mockGetProvider = () => ({
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
638
|
+
provider: "google",
|
|
639
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
640
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
641
641
|
tokenEndpointAuthMethod: "client_secret_post",
|
|
642
642
|
managedServiceConfigKey: null,
|
|
643
643
|
requiresClientSecret: 1,
|
|
@@ -648,7 +648,7 @@ describe("assistant oauth connect", () => {
|
|
|
648
648
|
id: "app-1",
|
|
649
649
|
clientId: "test-id",
|
|
650
650
|
clientSecretCredentialPath: "oauth_app/app-1/client_secret",
|
|
651
|
-
|
|
651
|
+
provider: "google",
|
|
652
652
|
createdAt: 0,
|
|
653
653
|
updatedAt: 0,
|
|
654
654
|
});
|
|
@@ -668,15 +668,42 @@ describe("assistant oauth connect", () => {
|
|
|
668
668
|
expect(parsed.error).toContain("apps upsert");
|
|
669
669
|
});
|
|
670
670
|
|
|
671
|
+
// -------------------------------------------------------------------------
|
|
672
|
+
// Manual-token providers (slack_channel, telegram)
|
|
673
|
+
// -------------------------------------------------------------------------
|
|
674
|
+
|
|
675
|
+
test("manual-token provider returns error directing to credentials command", async () => {
|
|
676
|
+
mockGetProvider = () => ({
|
|
677
|
+
provider: "slack_channel",
|
|
678
|
+
authorizeUrl: "urn:manual-token",
|
|
679
|
+
tokenExchangeUrl: "urn:manual-token",
|
|
680
|
+
managedServiceConfigKey: null,
|
|
681
|
+
});
|
|
682
|
+
mockIsManagedMode = () => false;
|
|
683
|
+
|
|
684
|
+
const { exitCode, stdout } = await runCommand([
|
|
685
|
+
"connect",
|
|
686
|
+
"slack_channel",
|
|
687
|
+
"--json",
|
|
688
|
+
]);
|
|
689
|
+
expect(exitCode).toBe(1);
|
|
690
|
+
const parsed = JSON.parse(stdout);
|
|
691
|
+
expect(parsed.ok).toBe(false);
|
|
692
|
+
expect(parsed.error).toContain("manual token configuration");
|
|
693
|
+
expect(parsed.error).toContain("assistant credentials set");
|
|
694
|
+
expect(parsed.error).toContain("--service");
|
|
695
|
+
expect(parsed.error).toContain("--field");
|
|
696
|
+
});
|
|
697
|
+
|
|
671
698
|
// -------------------------------------------------------------------------
|
|
672
699
|
// Orchestrator error propagation
|
|
673
700
|
// -------------------------------------------------------------------------
|
|
674
701
|
|
|
675
702
|
test("BYO mode: orchestrator error propagates correctly", async () => {
|
|
676
703
|
mockGetProvider = () => ({
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
704
|
+
provider: "google",
|
|
705
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
706
|
+
tokenExchangeUrl: "https://oauth2.googleapis.com/token",
|
|
680
707
|
managedServiceConfigKey: null,
|
|
681
708
|
});
|
|
682
709
|
mockIsManagedMode = () => false;
|
|
@@ -685,7 +712,7 @@ describe("assistant oauth connect", () => {
|
|
|
685
712
|
id: "app-1",
|
|
686
713
|
clientId: "client-id",
|
|
687
714
|
clientSecretCredentialPath: "oauth_app/app-1/client_secret",
|
|
688
|
-
|
|
715
|
+
provider: "google",
|
|
689
716
|
createdAt: 0,
|
|
690
717
|
updatedAt: 0,
|
|
691
718
|
});
|
|
@@ -15,19 +15,19 @@ let mockGetConnection: (
|
|
|
15
15
|
) => Record<string, unknown> | undefined = () => undefined;
|
|
16
16
|
|
|
17
17
|
let mockGetActiveConnection: (
|
|
18
|
-
|
|
18
|
+
provider: string,
|
|
19
19
|
opts?: { account?: string },
|
|
20
20
|
) => Record<string, unknown> | undefined = () => undefined;
|
|
21
21
|
|
|
22
22
|
let mockListActiveConnectionsByProvider: (
|
|
23
|
-
|
|
23
|
+
provider: string,
|
|
24
24
|
) => Array<Record<string, unknown>> = () => [];
|
|
25
25
|
|
|
26
26
|
let mockDisconnectOAuthProviderResult: "disconnected" | "not-found" | "error" =
|
|
27
27
|
"disconnected";
|
|
28
28
|
|
|
29
29
|
let mockDisconnectOAuthProviderCalls: Array<{
|
|
30
|
-
|
|
30
|
+
provider: string;
|
|
31
31
|
account: string | undefined;
|
|
32
32
|
connectionId: string | undefined;
|
|
33
33
|
}> = [];
|
|
@@ -64,17 +64,17 @@ mock.module("../../../../config/loader.js", () => ({
|
|
|
64
64
|
mock.module("../../../../oauth/oauth-store.js", () => ({
|
|
65
65
|
getProvider: (key: string) => mockGetProvider(key),
|
|
66
66
|
getConnection: (id: string) => mockGetConnection(id),
|
|
67
|
-
getActiveConnection: (
|
|
68
|
-
mockGetActiveConnection(
|
|
69
|
-
listActiveConnectionsByProvider: (
|
|
70
|
-
mockListActiveConnectionsByProvider(
|
|
67
|
+
getActiveConnection: (provider: string, opts?: { account?: string }) =>
|
|
68
|
+
mockGetActiveConnection(provider, opts),
|
|
69
|
+
listActiveConnectionsByProvider: (provider: string) =>
|
|
70
|
+
mockListActiveConnectionsByProvider(provider),
|
|
71
71
|
disconnectOAuthProvider: async (
|
|
72
|
-
|
|
72
|
+
provider: string,
|
|
73
73
|
account?: string,
|
|
74
74
|
connectionId?: string,
|
|
75
75
|
) => {
|
|
76
76
|
mockDisconnectOAuthProviderCalls.push({
|
|
77
|
-
|
|
77
|
+
provider,
|
|
78
78
|
account,
|
|
79
79
|
connectionId,
|
|
80
80
|
});
|
|
@@ -295,7 +295,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
295
295
|
|
|
296
296
|
test("both --account and --connection-id returns error", async () => {
|
|
297
297
|
mockGetProvider = () => ({
|
|
298
|
-
|
|
298
|
+
provider: "google",
|
|
299
299
|
managedServiceConfigKey: null,
|
|
300
300
|
});
|
|
301
301
|
|
|
@@ -323,7 +323,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
323
323
|
describe("managed mode", () => {
|
|
324
324
|
beforeEach(() => {
|
|
325
325
|
mockGetProvider = () => ({
|
|
326
|
-
|
|
326
|
+
provider: "google",
|
|
327
327
|
managedServiceConfigKey: "google-oauth",
|
|
328
328
|
});
|
|
329
329
|
mockIsManagedMode = () => true;
|
|
@@ -484,7 +484,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
484
484
|
describe("BYO mode", () => {
|
|
485
485
|
beforeEach(() => {
|
|
486
486
|
mockGetProvider = () => ({
|
|
487
|
-
|
|
487
|
+
provider: "google",
|
|
488
488
|
managedServiceConfigKey: null,
|
|
489
489
|
});
|
|
490
490
|
mockIsManagedMode = () => false;
|
|
@@ -494,7 +494,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
494
494
|
mockListActiveConnectionsByProvider = () => [
|
|
495
495
|
{
|
|
496
496
|
id: "conn-1",
|
|
497
|
-
|
|
497
|
+
provider: "google",
|
|
498
498
|
accountInfo: "user@gmail.com",
|
|
499
499
|
status: "active",
|
|
500
500
|
},
|
|
@@ -514,16 +514,16 @@ describe("assistant oauth disconnect", () => {
|
|
|
514
514
|
|
|
515
515
|
// Verify disconnectOAuthProvider was called
|
|
516
516
|
expect(mockDisconnectOAuthProviderCalls).toHaveLength(1);
|
|
517
|
-
expect(mockDisconnectOAuthProviderCalls[0].
|
|
517
|
+
expect(mockDisconnectOAuthProviderCalls[0].provider).toBe("google");
|
|
518
518
|
expect(mockDisconnectOAuthProviderCalls[0].connectionId).toBe("conn-1");
|
|
519
519
|
});
|
|
520
520
|
|
|
521
521
|
test("--account matches accountInfo", async () => {
|
|
522
|
-
mockGetActiveConnection = (
|
|
522
|
+
mockGetActiveConnection = (_provider, opts) => {
|
|
523
523
|
if (opts?.account === "user@gmail.com") {
|
|
524
524
|
return {
|
|
525
525
|
id: "conn-1",
|
|
526
|
-
|
|
526
|
+
provider: "google",
|
|
527
527
|
accountInfo: "user@gmail.com",
|
|
528
528
|
status: "active",
|
|
529
529
|
};
|
|
@@ -567,7 +567,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
567
567
|
if (id === "conn-123") {
|
|
568
568
|
return {
|
|
569
569
|
id: "conn-123",
|
|
570
|
-
|
|
570
|
+
provider: "google",
|
|
571
571
|
accountInfo: "user@gmail.com",
|
|
572
572
|
status: "active",
|
|
573
573
|
};
|
|
@@ -593,7 +593,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
593
593
|
if (id === "conn-slack") {
|
|
594
594
|
return {
|
|
595
595
|
id: "conn-slack",
|
|
596
|
-
|
|
596
|
+
provider: "slack",
|
|
597
597
|
accountInfo: null,
|
|
598
598
|
status: "active",
|
|
599
599
|
};
|
|
@@ -619,13 +619,13 @@ describe("assistant oauth disconnect", () => {
|
|
|
619
619
|
mockListActiveConnectionsByProvider = () => [
|
|
620
620
|
{
|
|
621
621
|
id: "conn-1",
|
|
622
|
-
|
|
622
|
+
provider: "google",
|
|
623
623
|
accountInfo: "user1@gmail.com",
|
|
624
624
|
status: "active",
|
|
625
625
|
},
|
|
626
626
|
{
|
|
627
627
|
id: "conn-2",
|
|
628
|
-
|
|
628
|
+
provider: "google",
|
|
629
629
|
accountInfo: "user2@gmail.com",
|
|
630
630
|
status: "active",
|
|
631
631
|
},
|
|
@@ -666,7 +666,7 @@ describe("assistant oauth disconnect", () => {
|
|
|
666
666
|
mockListActiveConnectionsByProvider = () => [
|
|
667
667
|
{
|
|
668
668
|
id: "conn-1",
|
|
669
|
-
|
|
669
|
+
provider: "google",
|
|
670
670
|
accountInfo: null,
|
|
671
671
|
status: "active",
|
|
672
672
|
},
|