@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
|
@@ -138,10 +138,11 @@ globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
|
138
138
|
import { type OAuth2Config, startOAuth2Flow } from "../security/oauth2.js";
|
|
139
139
|
|
|
140
140
|
const BASE_OAUTH_CONFIG: OAuth2Config = {
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
authorizeUrl: "https://provider.example.com/authorize",
|
|
142
|
+
tokenExchangeUrl: "https://provider.example.com/token",
|
|
143
143
|
scopes: ["read", "write"],
|
|
144
144
|
clientId: "test-client-id",
|
|
145
|
+
scopeSeparator: " ",
|
|
145
146
|
};
|
|
146
147
|
|
|
147
148
|
beforeEach(() => {
|
|
@@ -219,9 +220,9 @@ describe("OAuth2 gateway transport", () => {
|
|
|
219
220
|
expect(capturedAuthUrl).toContain(encodeURIComponent("/oauth/callback"));
|
|
220
221
|
|
|
221
222
|
// Extract the redirect_uri and simulate the callback
|
|
222
|
-
const
|
|
223
|
-
const redirectUri =
|
|
224
|
-
const state =
|
|
223
|
+
const authorizeUrl = new URL(capturedAuthUrl);
|
|
224
|
+
const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
|
|
225
|
+
const state = authorizeUrl.searchParams.get("state")!;
|
|
225
226
|
|
|
226
227
|
// Make a request to the loopback server with the auth code
|
|
227
228
|
const callbackUrl = `${redirectUri}?code=loopback-auth-code&state=${state}`;
|
|
@@ -282,9 +283,9 @@ describe("OAuth2 gateway transport", () => {
|
|
|
282
283
|
expect(capturedAuthUrl).not.toContain("gw.example.com");
|
|
283
284
|
|
|
284
285
|
// Simulate callback to loopback server
|
|
285
|
-
const
|
|
286
|
-
const redirectUri =
|
|
287
|
-
const state =
|
|
286
|
+
const authorizeUrl = new URL(capturedAuthUrl);
|
|
287
|
+
const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
|
|
288
|
+
const state = authorizeUrl.searchParams.get("state")!;
|
|
288
289
|
await fetch(`${redirectUri}?code=explicit-loopback-code&state=${state}`);
|
|
289
290
|
|
|
290
291
|
const result = await flowPromise;
|
|
@@ -405,9 +406,9 @@ describe("OAuth2 gateway transport", () => {
|
|
|
405
406
|
expect(capturedAuthUrl).toContain("code_challenge=");
|
|
406
407
|
expect(capturedAuthUrl).toContain("code_challenge_method=S256");
|
|
407
408
|
|
|
408
|
-
const
|
|
409
|
-
const redirectUri =
|
|
410
|
-
const state =
|
|
409
|
+
const authorizeUrl = new URL(capturedAuthUrl);
|
|
410
|
+
const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
|
|
411
|
+
const state = authorizeUrl.searchParams.get("state")!;
|
|
411
412
|
|
|
412
413
|
const resp = await fetch(
|
|
413
414
|
`${redirectUri}?code=loopback-code&state=${state}`,
|
|
@@ -440,9 +441,9 @@ describe("OAuth2 gateway transport", () => {
|
|
|
440
441
|
|
|
441
442
|
await urlReadyPromise;
|
|
442
443
|
|
|
443
|
-
const
|
|
444
|
-
const redirectUri =
|
|
445
|
-
const state =
|
|
444
|
+
const authorizeUrl = new URL(capturedAuthUrl);
|
|
445
|
+
const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
|
|
446
|
+
const state = authorizeUrl.searchParams.get("state")!;
|
|
446
447
|
|
|
447
448
|
// Fire callback without awaiting — immediately check flowPromise rejection
|
|
448
449
|
fetch(`${redirectUri}?error=access_denied&state=${state}`).catch(
|
|
@@ -473,8 +474,8 @@ describe("OAuth2 gateway transport", () => {
|
|
|
473
474
|
|
|
474
475
|
await urlReadyPromise;
|
|
475
476
|
|
|
476
|
-
const
|
|
477
|
-
const redirectUri =
|
|
477
|
+
const authorizeUrl = new URL(capturedAuthUrl);
|
|
478
|
+
const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
|
|
478
479
|
|
|
479
480
|
// Send callback with wrong state
|
|
480
481
|
const resp = await fetch(
|
|
@@ -484,7 +485,7 @@ describe("OAuth2 gateway transport", () => {
|
|
|
484
485
|
|
|
485
486
|
// The flow should still be waiting (not resolved)
|
|
486
487
|
// Send the correct callback to clean up
|
|
487
|
-
const state =
|
|
488
|
+
const state = authorizeUrl.searchParams.get("state")!;
|
|
488
489
|
await fetch(`${redirectUri}?code=correct-code&state=${state}`);
|
|
489
490
|
|
|
490
491
|
const result = await flowPromise;
|
|
@@ -516,9 +517,9 @@ describe("OAuth2 gateway transport", () => {
|
|
|
516
517
|
|
|
517
518
|
await urlReadyPromise;
|
|
518
519
|
|
|
519
|
-
const
|
|
520
|
-
const redirectUri =
|
|
521
|
-
const state =
|
|
520
|
+
const authorizeUrl = new URL(capturedAuthUrl);
|
|
521
|
+
const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
|
|
522
|
+
const state = authorizeUrl.searchParams.get("state")!;
|
|
522
523
|
|
|
523
524
|
// Fire callback without awaiting — immediately check flowPromise rejection
|
|
524
525
|
fetch(`${redirectUri}?code=code-that-fails&state=${state}`).catch(
|
|
@@ -653,4 +654,194 @@ describe("OAuth2 gateway transport", () => {
|
|
|
653
654
|
expect(lastTokenRequestBody!.has("client_secret")).toBe(false);
|
|
654
655
|
});
|
|
655
656
|
});
|
|
657
|
+
|
|
658
|
+
describe("scope separator", () => {
|
|
659
|
+
test("authorize URL joins scopes with space when scopeSeparator is ' '", async () => {
|
|
660
|
+
mockPublicBaseUrl = "https://gw.example.com";
|
|
661
|
+
|
|
662
|
+
let capturedAuthUrl = "";
|
|
663
|
+
const flowPromise = startOAuth2Flow(
|
|
664
|
+
BASE_OAUTH_CONFIG,
|
|
665
|
+
{
|
|
666
|
+
openUrl: (url) => {
|
|
667
|
+
capturedAuthUrl = url;
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
{ callbackTransport: "gateway" },
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
674
|
+
|
|
675
|
+
// URLSearchParams encodes spaces as '+' in query strings (application/x-www-form-urlencoded)
|
|
676
|
+
expect(capturedAuthUrl).toContain("scope=read+write");
|
|
677
|
+
|
|
678
|
+
const entries = Array.from(pendingCallbacks.entries());
|
|
679
|
+
entries[0][1].resolve("space-separator-code");
|
|
680
|
+
await flowPromise;
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
test("authorize URL joins scopes with comma when scopeSeparator is ','", async () => {
|
|
684
|
+
mockPublicBaseUrl = "https://gw.example.com";
|
|
685
|
+
|
|
686
|
+
const commaConfig: OAuth2Config = {
|
|
687
|
+
...BASE_OAUTH_CONFIG,
|
|
688
|
+
scopeSeparator: ",",
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
let capturedAuthUrl = "";
|
|
692
|
+
const flowPromise = startOAuth2Flow(
|
|
693
|
+
commaConfig,
|
|
694
|
+
{
|
|
695
|
+
openUrl: (url) => {
|
|
696
|
+
capturedAuthUrl = url;
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
{ callbackTransport: "gateway" },
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
703
|
+
|
|
704
|
+
// Comma-encoded scopes
|
|
705
|
+
expect(capturedAuthUrl).toContain("scope=read%2Cwrite");
|
|
706
|
+
|
|
707
|
+
const entries = Array.from(pendingCallbacks.entries());
|
|
708
|
+
entries[0][1].resolve("comma-separator-code");
|
|
709
|
+
await flowPromise;
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
test("token response with comma-separated scope splits into individual scopes when scopeSeparator is ','", async () => {
|
|
713
|
+
mockPublicBaseUrl = "https://gw.example.com";
|
|
714
|
+
mockTokenResponse = {
|
|
715
|
+
ok: true,
|
|
716
|
+
status: 200,
|
|
717
|
+
body: {
|
|
718
|
+
access_token: "test-access-token",
|
|
719
|
+
refresh_token: "test-refresh-token",
|
|
720
|
+
expires_in: 3600,
|
|
721
|
+
scope: "read,write,issues:create",
|
|
722
|
+
token_type: "Bearer",
|
|
723
|
+
},
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
const commaConfig: OAuth2Config = {
|
|
727
|
+
...BASE_OAUTH_CONFIG,
|
|
728
|
+
scopeSeparator: ",",
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
const flowPromise = startOAuth2Flow(
|
|
732
|
+
commaConfig,
|
|
733
|
+
{ openUrl: () => {} },
|
|
734
|
+
{ callbackTransport: "gateway" },
|
|
735
|
+
);
|
|
736
|
+
|
|
737
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
738
|
+
|
|
739
|
+
const entries = Array.from(pendingCallbacks.entries());
|
|
740
|
+
entries[0][1].resolve("comma-token-code");
|
|
741
|
+
|
|
742
|
+
const result = await flowPromise;
|
|
743
|
+
expect(result.grantedScopes).toEqual(["read", "write", "issues:create"]);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
test("token response with whitespace around comma separators is trimmed", async () => {
|
|
747
|
+
mockPublicBaseUrl = "https://gw.example.com";
|
|
748
|
+
mockTokenResponse = {
|
|
749
|
+
ok: true,
|
|
750
|
+
status: 200,
|
|
751
|
+
body: {
|
|
752
|
+
access_token: "test-access-token",
|
|
753
|
+
refresh_token: "test-refresh-token",
|
|
754
|
+
expires_in: 3600,
|
|
755
|
+
scope: " read , write ",
|
|
756
|
+
token_type: "Bearer",
|
|
757
|
+
},
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
const commaConfig: OAuth2Config = {
|
|
761
|
+
...BASE_OAUTH_CONFIG,
|
|
762
|
+
scopeSeparator: ",",
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
const flowPromise = startOAuth2Flow(
|
|
766
|
+
commaConfig,
|
|
767
|
+
{ openUrl: () => {} },
|
|
768
|
+
{ callbackTransport: "gateway" },
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
772
|
+
|
|
773
|
+
const entries = Array.from(pendingCallbacks.entries());
|
|
774
|
+
entries[0][1].resolve("comma-whitespace-code");
|
|
775
|
+
|
|
776
|
+
const result = await flowPromise;
|
|
777
|
+
expect(result.grantedScopes).toEqual(["read", "write"]);
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
test("default-space provider still parses comma-separated token response scopes (GitHub/Slack compat)", async () => {
|
|
781
|
+
// Providers like GitHub and Slack use space as their authorize-URL
|
|
782
|
+
// separator but return comma-separated scopes in token responses.
|
|
783
|
+
// The defensive split MUST tolerate that without requiring providers
|
|
784
|
+
// to opt into scopeSeparator: ",".
|
|
785
|
+
mockPublicBaseUrl = "https://gw.example.com";
|
|
786
|
+
mockTokenResponse = {
|
|
787
|
+
ok: true,
|
|
788
|
+
status: 200,
|
|
789
|
+
body: {
|
|
790
|
+
access_token: "test-access-token",
|
|
791
|
+
refresh_token: "test-refresh-token",
|
|
792
|
+
expires_in: 3600,
|
|
793
|
+
scope: "repo,read:user,notifications",
|
|
794
|
+
token_type: "Bearer",
|
|
795
|
+
},
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
// BASE_OAUTH_CONFIG uses the default " " separator.
|
|
799
|
+
const flowPromise = startOAuth2Flow(
|
|
800
|
+
BASE_OAUTH_CONFIG,
|
|
801
|
+
{ openUrl: () => {} },
|
|
802
|
+
{ callbackTransport: "gateway" },
|
|
803
|
+
);
|
|
804
|
+
|
|
805
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
806
|
+
|
|
807
|
+
const entries = Array.from(pendingCallbacks.entries());
|
|
808
|
+
entries[0][1].resolve("github-style-code");
|
|
809
|
+
|
|
810
|
+
const result = await flowPromise;
|
|
811
|
+
expect(result.grantedScopes).toEqual([
|
|
812
|
+
"repo",
|
|
813
|
+
"read:user",
|
|
814
|
+
"notifications",
|
|
815
|
+
]);
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
test("default-space provider parses space-separated token response scopes", async () => {
|
|
819
|
+
mockPublicBaseUrl = "https://gw.example.com";
|
|
820
|
+
mockTokenResponse = {
|
|
821
|
+
ok: true,
|
|
822
|
+
status: 200,
|
|
823
|
+
body: {
|
|
824
|
+
access_token: "test-access-token",
|
|
825
|
+
refresh_token: "test-refresh-token",
|
|
826
|
+
expires_in: 3600,
|
|
827
|
+
scope: "read write admin",
|
|
828
|
+
token_type: "Bearer",
|
|
829
|
+
},
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
const flowPromise = startOAuth2Flow(
|
|
833
|
+
BASE_OAUTH_CONFIG,
|
|
834
|
+
{ openUrl: () => {} },
|
|
835
|
+
{ callbackTransport: "gateway" },
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
839
|
+
|
|
840
|
+
const entries = Array.from(pendingCallbacks.entries());
|
|
841
|
+
entries[0][1].resolve("space-token-code");
|
|
842
|
+
|
|
843
|
+
const result = await flowPromise;
|
|
844
|
+
expect(result.grantedScopes).toEqual(["read", "write", "admin"]);
|
|
845
|
+
});
|
|
846
|
+
});
|
|
656
847
|
});
|
|
@@ -19,48 +19,17 @@ describe("onboarding template contracts", () => {
|
|
|
19
19
|
|
|
20
20
|
test("contains identity discovery prompts", () => {
|
|
21
21
|
const lower = bootstrap.toLowerCase();
|
|
22
|
-
expect(lower).toContain("
|
|
23
|
-
expect(lower).toContain("
|
|
22
|
+
expect(lower).toContain("identity");
|
|
23
|
+
expect(lower).toContain("infer");
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
test("
|
|
27
|
-
const lower = bootstrap.toLowerCase();
|
|
28
|
-
expect(lower).toContain("personality");
|
|
29
|
-
expect(lower).toContain("vibe");
|
|
30
|
-
// Personality arc should come before usefulness arc
|
|
31
|
-
const personalityIdx = lower.indexOf("oh, this has personality");
|
|
32
|
-
const usefulIdx = lower.indexOf("oh, this is useful");
|
|
33
|
-
expect(personalityIdx).toBeGreaterThan(-1);
|
|
34
|
-
expect(usefulIdx).toBeGreaterThan(-1);
|
|
35
|
-
expect(personalityIdx).toBeLessThan(usefulIdx);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("contains name selection with change-later instruction", () => {
|
|
39
|
-
const lower = bootstrap.toLowerCase();
|
|
40
|
-
expect(lower).toContain("what they want to call you");
|
|
41
|
-
expect(lower).toContain("change it later");
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test("name exchange happens before personality quiz", () => {
|
|
45
|
-
const nameIdx = bootstrap.indexOf("Step 1: Name Exchange");
|
|
46
|
-
const quizIdx = bootstrap.indexOf("Step 2: Personality Quiz");
|
|
47
|
-
expect(nameIdx).toBeGreaterThan(-1);
|
|
48
|
-
expect(quizIdx).toBeGreaterThan(-1);
|
|
49
|
-
expect(nameIdx).toBeLessThan(quizIdx);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("gathers user context: work role, hobbies, daily tools", () => {
|
|
26
|
+
test("gathers user context", () => {
|
|
53
27
|
const lower = bootstrap.toLowerCase();
|
|
54
28
|
expect(lower).toContain("work role");
|
|
55
|
-
expect(lower).toContain("
|
|
29
|
+
expect(lower).toContain("goals");
|
|
56
30
|
expect(lower).toContain("tools");
|
|
57
31
|
});
|
|
58
32
|
|
|
59
|
-
test("references ui_show payloads from BOOTSTRAP-REFERENCE.md", () => {
|
|
60
|
-
expect(bootstrap).toContain("ui_show");
|
|
61
|
-
expect(bootstrap).toContain("BOOTSTRAP-REFERENCE.md");
|
|
62
|
-
});
|
|
63
|
-
|
|
64
33
|
test("contains wrapping-up criteria with deletion instructions", () => {
|
|
65
34
|
const lower = bootstrap.toLowerCase();
|
|
66
35
|
expect(lower).toContain("wrapping up");
|
|
@@ -70,15 +39,12 @@ describe("onboarding template contracts", () => {
|
|
|
70
39
|
|
|
71
40
|
test("contains refusal policy", () => {
|
|
72
41
|
const lower = bootstrap.toLowerCase();
|
|
73
|
-
expect(lower).toContain("hard-required");
|
|
74
|
-
expect(lower).toContain("best-effort");
|
|
75
42
|
expect(lower).toContain("declined");
|
|
76
|
-
expect(lower).toContain("
|
|
43
|
+
expect(lower).toContain("constraints");
|
|
77
44
|
});
|
|
78
45
|
|
|
79
|
-
test("defines
|
|
46
|
+
test("defines field states as inferred or declined", () => {
|
|
80
47
|
const lower = bootstrap.toLowerCase();
|
|
81
|
-
expect(lower).toContain("resolved");
|
|
82
48
|
expect(lower).toContain("inferred");
|
|
83
49
|
expect(lower).toContain("declined");
|
|
84
50
|
});
|
|
@@ -91,6 +57,7 @@ describe("onboarding template contracts", () => {
|
|
|
91
57
|
});
|
|
92
58
|
|
|
93
59
|
test("includes budget constraint", () => {
|
|
60
|
+
expect(bootstrap).toContain("$2");
|
|
94
61
|
expect(bootstrap).toContain("$5");
|
|
95
62
|
});
|
|
96
63
|
|
|
@@ -98,29 +65,73 @@ describe("onboarding template contracts", () => {
|
|
|
98
65
|
expect(bootstrap).toContain("new colleague");
|
|
99
66
|
});
|
|
100
67
|
|
|
101
|
-
test("
|
|
102
|
-
|
|
103
|
-
expect(
|
|
104
|
-
expect(
|
|
68
|
+
test("contains numbered goals", () => {
|
|
69
|
+
const lower = bootstrap.toLowerCase();
|
|
70
|
+
expect(lower).toContain("establish mutual identity");
|
|
71
|
+
expect(lower).toContain("prove value fast");
|
|
72
|
+
expect(lower).toContain("infer, don't interrogate");
|
|
73
|
+
expect(lower).toContain("surface what you learned");
|
|
74
|
+
expect(lower).toContain("offer the next level");
|
|
75
|
+
expect(lower).toContain("write everything immediately");
|
|
76
|
+
expect(lower).toContain("clean up");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("contains constraints section", () => {
|
|
80
|
+
expect(bootstrap).toContain("## Constraints");
|
|
81
|
+
expect(bootstrap).toContain("$2");
|
|
82
|
+
expect(bootstrap).toContain("2 questions");
|
|
83
|
+
expect(bootstrap.toLowerCase()).toContain("don't block on setup");
|
|
84
|
+
expect(bootstrap).toContain("One-shot");
|
|
105
85
|
});
|
|
106
86
|
|
|
107
|
-
test("
|
|
87
|
+
test("contains 'what you own' section", () => {
|
|
108
88
|
const lower = bootstrap.toLowerCase();
|
|
109
|
-
expect(lower).toContain("
|
|
89
|
+
expect(lower).toContain("sequencing");
|
|
90
|
+
expect(lower).toContain("pacing");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("contains technical contract", () => {
|
|
94
|
+
expect(bootstrap).toContain("Technical Contract");
|
|
95
|
+
expect(bootstrap).toContain("prescribed");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("contains capability unlock pattern", () => {
|
|
99
|
+
const lower = bootstrap.toLowerCase();
|
|
100
|
+
expect(lower).toContain("email");
|
|
101
|
+
expect(lower).toContain("voice");
|
|
110
102
|
expect(lower).toContain("slack");
|
|
111
|
-
expect(lower).toContain("telegram");
|
|
112
103
|
});
|
|
113
|
-
});
|
|
114
104
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
expect(
|
|
118
|
-
expect(
|
|
119
|
-
expect(bootstrapRef).toContain("task_style");
|
|
120
|
-
expect(bootstrapRef).toContain("humor");
|
|
121
|
-
expect(bootstrapRef).toContain("depth");
|
|
105
|
+
test("contains tone guidance", () => {
|
|
106
|
+
expect(bootstrap).toContain("Not servile");
|
|
107
|
+
expect(bootstrap.toLowerCase()).toContain("match");
|
|
108
|
+
expect(bootstrap.toLowerCase()).toContain("energy");
|
|
122
109
|
});
|
|
123
110
|
|
|
111
|
+
test("contains pre-chat onboarding context section", () => {
|
|
112
|
+
const lower = bootstrap.toLowerCase();
|
|
113
|
+
expect(lower).toContain("onboarding");
|
|
114
|
+
expect(lower).toContain("json");
|
|
115
|
+
expect(lower).toContain("context");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("does not contain personality quiz references", () => {
|
|
119
|
+
// BOOTSTRAP.md says "No personality quiz" as part of goal 3,
|
|
120
|
+
// but should NOT contain instructions TO USE or SHOW a personality quiz
|
|
121
|
+
expect(bootstrap).not.toMatch(/show.*personality quiz/i);
|
|
122
|
+
expect(bootstrap).not.toMatch(/present.*personality quiz/i);
|
|
123
|
+
// "dropdown" only appears in "No dropdown forms" — that's a prohibition, not an instruction
|
|
124
|
+
expect(bootstrap).not.toMatch(/show.*dropdown/i);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("does not contain rigid step sequence", () => {
|
|
128
|
+
expect(bootstrap).not.toMatch(/Step 1:/);
|
|
129
|
+
expect(bootstrap).not.toMatch(/Step 2:/);
|
|
130
|
+
expect(bootstrap).not.toMatch(/Step 3:/);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("BOOTSTRAP-REFERENCE.md", () => {
|
|
124
135
|
test("contains email-not-connected task card variant", () => {
|
|
125
136
|
expect(bootstrapRef).toContain("Email Not Connected");
|
|
126
137
|
expect(bootstrapRef).toContain("Connect my email");
|
|
@@ -131,6 +142,14 @@ describe("onboarding template contracts", () => {
|
|
|
131
142
|
expect(bootstrapRef).toContain("Email Already Connected");
|
|
132
143
|
expect(bootstrapRef).toContain("Check my email");
|
|
133
144
|
});
|
|
145
|
+
|
|
146
|
+
test("does not contain personality form", () => {
|
|
147
|
+
expect(bootstrapRef).not.toContain('surface_type: "form"');
|
|
148
|
+
expect(bootstrapRef).not.toContain("communication_style");
|
|
149
|
+
expect(bootstrapRef).not.toContain("task_style");
|
|
150
|
+
expect(bootstrapRef).not.toContain("humor");
|
|
151
|
+
expect(bootstrapRef).not.toContain("depth");
|
|
152
|
+
});
|
|
134
153
|
});
|
|
135
154
|
|
|
136
155
|
describe("IDENTITY.md", () => {
|
|
@@ -653,10 +653,10 @@ describe("OpenAIProvider", () => {
|
|
|
653
653
|
[{ role: "user", content: [{ type: "text", text: "Hi" }] }],
|
|
654
654
|
undefined,
|
|
655
655
|
undefined,
|
|
656
|
-
{ config: { max_tokens:
|
|
656
|
+
{ config: { max_tokens: 64000 } },
|
|
657
657
|
);
|
|
658
658
|
|
|
659
|
-
expect(lastCreateParams!.max_completion_tokens).toBe(
|
|
659
|
+
expect(lastCreateParams!.max_completion_tokens).toBe(64000);
|
|
660
660
|
});
|
|
661
661
|
|
|
662
662
|
// -----------------------------------------------------------------------
|
|
@@ -15,7 +15,7 @@ const mockListMasterCategories = mock(() =>
|
|
|
15
15
|
}),
|
|
16
16
|
);
|
|
17
17
|
const mockResolveOAuthConnection = mock(() =>
|
|
18
|
-
Promise.resolve({ id: "conn-1",
|
|
18
|
+
Promise.resolve({ id: "conn-1", provider: "outlook" }),
|
|
19
19
|
);
|
|
20
20
|
|
|
21
21
|
mock.module("../messaging/providers/outlook/client.js", () => ({
|
|
@@ -25,7 +25,7 @@ function createMockConnection(
|
|
|
25
25
|
): OAuthConnection {
|
|
26
26
|
return {
|
|
27
27
|
id: "outlook-conn-1",
|
|
28
|
-
|
|
28
|
+
provider: "outlook",
|
|
29
29
|
accountInfo: "test@outlook.com",
|
|
30
30
|
request: mock(() =>
|
|
31
31
|
Promise.resolve({ status, headers: {}, body: responseBody }),
|
|
@@ -40,7 +40,7 @@ mock.module("../messaging/providers/outlook/client.js", () => ({
|
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
42
|
const mockResolveOAuthConnection =
|
|
43
|
-
mock<(
|
|
43
|
+
mock<(provider: string) => Promise<unknown>>();
|
|
44
44
|
|
|
45
45
|
mock.module("../oauth/connection-resolver.js", () => ({
|
|
46
46
|
resolveOAuthConnection: mockResolveOAuthConnection,
|
|
@@ -24,7 +24,7 @@ const mockListMessages = mock(() =>
|
|
|
24
24
|
}),
|
|
25
25
|
);
|
|
26
26
|
const mockResolveOAuthConnection = mock(() =>
|
|
27
|
-
Promise.resolve({ id: "conn-1",
|
|
27
|
+
Promise.resolve({ id: "conn-1", provider: "outlook" }),
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
mock.module("../messaging/providers/outlook/client.js", () => ({
|
|
@@ -164,7 +164,7 @@ import {
|
|
|
164
164
|
function createMockConnection(): OAuthConnection {
|
|
165
165
|
return {
|
|
166
166
|
id: "outlook-conn-1",
|
|
167
|
-
|
|
167
|
+
provider: "outlook",
|
|
168
168
|
accountInfo: "test@outlook.com",
|
|
169
169
|
request: mock(() =>
|
|
170
170
|
Promise.resolve({ status: 200, headers: {}, body: {} }),
|
|
@@ -884,7 +884,7 @@ describe("Outlook client functions", () => {
|
|
|
884
884
|
): OAuthConnection {
|
|
885
885
|
return {
|
|
886
886
|
id: "outlook-conn-1",
|
|
887
|
-
|
|
887
|
+
provider: "outlook",
|
|
888
888
|
accountInfo: "test@outlook.com",
|
|
889
889
|
request: mock(() =>
|
|
890
890
|
Promise.resolve({ status, headers: {}, body: responseBody }),
|
|
@@ -4,7 +4,7 @@ import { describe, expect, mock, test } from "bun:test";
|
|
|
4
4
|
|
|
5
5
|
const mockTrashMessage = mock(() => Promise.resolve({}));
|
|
6
6
|
const mockResolveOAuthConnection = mock(() =>
|
|
7
|
-
Promise.resolve({ id: "conn-1",
|
|
7
|
+
Promise.resolve({ id: "conn-1", provider: "outlook" }),
|
|
8
8
|
);
|
|
9
9
|
|
|
10
10
|
mock.module("../messaging/providers/outlook/client.js", () => ({
|
|
@@ -57,7 +57,7 @@ const { run } =
|
|
|
57
57
|
|
|
58
58
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
59
59
|
|
|
60
|
-
const fakeConnection = { id: "outlook-conn-1",
|
|
60
|
+
const fakeConnection = { id: "outlook-conn-1", provider: "outlook" };
|
|
61
61
|
|
|
62
62
|
function makeContext(overrides: Partial<ToolContext> = {}): ToolContext {
|
|
63
63
|
return {
|