@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
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry mapping guardianId → active Chrome extension WebSocket connections.
|
|
3
|
+
*
|
|
4
|
+
* Populated by the `/v1/browser-relay` WebSocket upgrade handler when a
|
|
5
|
+
* chrome-extension client connects; drained on close. Used by
|
|
6
|
+
* conversation-routes.ts to route `host_browser_request` frames to the
|
|
7
|
+
* connected extension for the appropriate guardian.
|
|
8
|
+
*
|
|
9
|
+
* This is the chrome-extension counterpart to the SSE hub used by the macOS
|
|
10
|
+
* client for the same purpose.
|
|
11
|
+
*
|
|
12
|
+
* A single guardian may have multiple simultaneous extension connections —
|
|
13
|
+
* e.g. the same guardian signed in on two Chrome profiles, two desktops
|
|
14
|
+
* sharing a sync identity, or a power user with parallel installs for
|
|
15
|
+
* testing. Each install generates a stable `clientInstanceId` on first
|
|
16
|
+
* run and sends it on every handshake; the registry keys inner entries by
|
|
17
|
+
* that id so sibling instances don't evict each other on register/unregister.
|
|
18
|
+
*
|
|
19
|
+
* Routing semantics:
|
|
20
|
+
* - When a caller does not pin a specific instance, the registry picks
|
|
21
|
+
* the "most recently active" instance for the guardian (highest
|
|
22
|
+
* `lastActiveAt` timestamp). `lastActiveAt` is bumped on register and
|
|
23
|
+
* on every successful `send()`, which is a good enough stand-in for
|
|
24
|
+
* WebSocket heartbeats under the current load profile.
|
|
25
|
+
* - When no `clientInstanceId` is present on the handshake (older
|
|
26
|
+
* extension builds, dev bypass paths), we synthesize a placeholder
|
|
27
|
+
* `legacy:<connectionId>` key. The send/lookup path treats it the
|
|
28
|
+
* same as any other instance so the call site stays uniform. The
|
|
29
|
+
* synthesized key is deliberately connection-scoped so a stale
|
|
30
|
+
* legacy unregister can never evict a newer entry.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { ServerWebSocket } from "bun";
|
|
34
|
+
|
|
35
|
+
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
36
|
+
import { getLogger } from "../util/logger.js";
|
|
37
|
+
|
|
38
|
+
const log = getLogger("chrome-extension-registry");
|
|
39
|
+
|
|
40
|
+
/** Prefix applied to synthesized instance ids for connections that did not
|
|
41
|
+
* provide a client-supplied `clientInstanceId` at handshake time. Kept
|
|
42
|
+
* distinct from any plausible client-generated value so it never collides
|
|
43
|
+
* with a real install id. */
|
|
44
|
+
const LEGACY_INSTANCE_PREFIX = "legacy:";
|
|
45
|
+
|
|
46
|
+
export interface ChromeExtensionConnection {
|
|
47
|
+
/** Stable identifier for this WebSocket connection (used for unregister). */
|
|
48
|
+
id: string;
|
|
49
|
+
/** Guardian identity this connection is authenticated as. */
|
|
50
|
+
guardianId: string;
|
|
51
|
+
/**
|
|
52
|
+
* Stable per-extension-install identifier (persists across browser
|
|
53
|
+
* restarts, survives service-worker teardown). Absent on older
|
|
54
|
+
* extension builds and on dev-bypass paths — the registry synthesizes
|
|
55
|
+
* a `legacy:<connectionId>` key in that case so sibling multi-instance
|
|
56
|
+
* semantics degrade gracefully to single-instance behavior.
|
|
57
|
+
*/
|
|
58
|
+
clientInstanceId?: string;
|
|
59
|
+
/** Underlying Bun WebSocket. */
|
|
60
|
+
ws: ServerWebSocket<unknown>;
|
|
61
|
+
/** Wall-clock timestamp (ms) when the connection was registered. */
|
|
62
|
+
connectedAt: number;
|
|
63
|
+
/**
|
|
64
|
+
* Wall-clock timestamp (ms) of the most recent activity on this
|
|
65
|
+
* connection — updated on register and on each successful `send()`.
|
|
66
|
+
* Used by the default-send routing path to pick the "most recently
|
|
67
|
+
* active" instance when the caller does not pin a specific one.
|
|
68
|
+
*/
|
|
69
|
+
lastActiveAt: number;
|
|
70
|
+
/**
|
|
71
|
+
* Monotonic registration sequence number assigned by the registry
|
|
72
|
+
* on each `register()` call. Used as a tuple-secondary tiebreaker
|
|
73
|
+
* after `lastActiveAt` when picking the default active instance, so
|
|
74
|
+
* two sibling instances that share the same millisecond timestamp
|
|
75
|
+
* deterministically resolve to the most recently registered entry.
|
|
76
|
+
*
|
|
77
|
+
* Not used when the registry routes to an explicit instance via
|
|
78
|
+
* `sendToInstance` / `getInstance`. Clients should treat this as an
|
|
79
|
+
* internal field — it's assigned by `register()` and callers don't
|
|
80
|
+
* need to populate it when constructing a connection.
|
|
81
|
+
*/
|
|
82
|
+
registrationSeq?: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Module-level registry of active chrome-extension connections keyed by
|
|
87
|
+
* guardianId, then by clientInstanceId. Multiple concurrent connections
|
|
88
|
+
* under the same guardian are supported; reconnects of the *same* install
|
|
89
|
+
* supersede the prior entry for that instance only, leaving sibling
|
|
90
|
+
* instances untouched.
|
|
91
|
+
*/
|
|
92
|
+
export class ChromeExtensionRegistry {
|
|
93
|
+
private byGuardian = new Map<
|
|
94
|
+
string,
|
|
95
|
+
Map<string, ChromeExtensionConnection>
|
|
96
|
+
>();
|
|
97
|
+
/**
|
|
98
|
+
* Monotonic counter stamped onto each registration as
|
|
99
|
+
* `registrationSeq`, used as a secondary tiebreaker after
|
|
100
|
+
* `lastActiveAt` in the default routing path. Starts at 0 and
|
|
101
|
+
* increments before stamping so the first registered connection has
|
|
102
|
+
* `registrationSeq === 1`.
|
|
103
|
+
*
|
|
104
|
+
* This exists because `lastActiveAt` is `Date.now()`, which has
|
|
105
|
+
* millisecond resolution at best; two sibling instances that
|
|
106
|
+
* register (or transmit) in the same millisecond would otherwise
|
|
107
|
+
* resolve ties via insertion order of `Map#values()`, which is
|
|
108
|
+
* technically well-defined but is not the "most recently registered"
|
|
109
|
+
* behavior a caller would expect. A monotonic counter fixes that
|
|
110
|
+
* deterministically.
|
|
111
|
+
*/
|
|
112
|
+
private seqCounter = 0;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Resolve the effective instance key for a connection. Prefers the
|
|
116
|
+
* client-supplied `clientInstanceId`; falls back to a
|
|
117
|
+
* connection-scoped `legacy:<connectionId>` placeholder when absent
|
|
118
|
+
* so older clients get stable single-instance semantics without
|
|
119
|
+
* clobbering sibling instances for the same guardian.
|
|
120
|
+
*/
|
|
121
|
+
private keyFor(conn: ChromeExtensionConnection): string {
|
|
122
|
+
return conn.clientInstanceId ?? `${LEGACY_INSTANCE_PREFIX}${conn.id}`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Register a chrome-extension WebSocket for a guardian + instance.
|
|
127
|
+
* If a prior connection already exists for the same guardianId AND
|
|
128
|
+
* clientInstanceId (i.e. the same install reconnecting), it is closed
|
|
129
|
+
* and replaced with the new one. Sibling instances for the same
|
|
130
|
+
* guardian are left untouched.
|
|
131
|
+
*/
|
|
132
|
+
register(conn: ChromeExtensionConnection): void {
|
|
133
|
+
let instances = this.byGuardian.get(conn.guardianId);
|
|
134
|
+
if (!instances) {
|
|
135
|
+
instances = new Map();
|
|
136
|
+
this.byGuardian.set(conn.guardianId, instances);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const instanceKey = this.keyFor(conn);
|
|
140
|
+
const prior = instances.get(instanceKey);
|
|
141
|
+
if (prior && prior.id !== conn.id) {
|
|
142
|
+
try {
|
|
143
|
+
prior.ws.close(1000, "superseded by new connection");
|
|
144
|
+
} catch {
|
|
145
|
+
// Best-effort — the prior socket may already be closed.
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Stamp lastActiveAt on (re-)register so the "most recently active"
|
|
149
|
+
// routing heuristic treats a fresh connection as the current default
|
|
150
|
+
// target for its guardian. Stamp a monotonic registrationSeq
|
|
151
|
+
// alongside it so two registrations that land in the same
|
|
152
|
+
// millisecond resolve deterministically to the newer one.
|
|
153
|
+
conn.lastActiveAt = Date.now();
|
|
154
|
+
conn.registrationSeq = ++this.seqCounter;
|
|
155
|
+
instances.set(instanceKey, conn);
|
|
156
|
+
log.info(
|
|
157
|
+
{
|
|
158
|
+
guardianId: conn.guardianId,
|
|
159
|
+
connectionId: conn.id,
|
|
160
|
+
clientInstanceId: conn.clientInstanceId,
|
|
161
|
+
registrationSeq: conn.registrationSeq,
|
|
162
|
+
instanceCount: instances.size,
|
|
163
|
+
},
|
|
164
|
+
"chrome extension registered",
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Remove the entry with the given connectionId. No-op if no connection
|
|
170
|
+
* with that id is currently registered — the entry may already have been
|
|
171
|
+
* superseded by a newer registration for the same instance, or the
|
|
172
|
+
* guardian may have zero active instances remaining.
|
|
173
|
+
*
|
|
174
|
+
* Importantly, this does not evict sibling instances under the same
|
|
175
|
+
* guardian — multi-instance routing depends on keeping them alive
|
|
176
|
+
* across single-instance reconnects.
|
|
177
|
+
*/
|
|
178
|
+
unregister(connectionId: string): void {
|
|
179
|
+
for (const [guardianId, instances] of this.byGuardian) {
|
|
180
|
+
for (const [instanceKey, conn] of instances) {
|
|
181
|
+
if (conn.id === connectionId) {
|
|
182
|
+
instances.delete(instanceKey);
|
|
183
|
+
if (instances.size === 0) {
|
|
184
|
+
this.byGuardian.delete(guardianId);
|
|
185
|
+
}
|
|
186
|
+
log.info(
|
|
187
|
+
{
|
|
188
|
+
guardianId,
|
|
189
|
+
connectionId,
|
|
190
|
+
clientInstanceId: conn.clientInstanceId,
|
|
191
|
+
remaining: instances.size,
|
|
192
|
+
},
|
|
193
|
+
"chrome extension unregistered",
|
|
194
|
+
);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Return the default "active" connection for a guardian — the
|
|
203
|
+
* instance with the most recent `lastActiveAt` timestamp. Ties on
|
|
204
|
+
* `lastActiveAt` (common when two sibling instances register or
|
|
205
|
+
* transmit within the same millisecond) are broken by the monotonic
|
|
206
|
+
* `registrationSeq` counter, which deterministically prefers the
|
|
207
|
+
* most recently registered instance. Returns `undefined` when no
|
|
208
|
+
* instances are registered for the guardian.
|
|
209
|
+
*
|
|
210
|
+
* Callers that want to pin a specific instance should use
|
|
211
|
+
* {@link getInstance} instead.
|
|
212
|
+
*/
|
|
213
|
+
get(guardianId: string): ChromeExtensionConnection | undefined {
|
|
214
|
+
const instances = this.byGuardian.get(guardianId);
|
|
215
|
+
if (!instances || instances.size === 0) return undefined;
|
|
216
|
+
let best: ChromeExtensionConnection | undefined;
|
|
217
|
+
for (const conn of instances.values()) {
|
|
218
|
+
if (!best) {
|
|
219
|
+
best = conn;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (conn.lastActiveAt > best.lastActiveAt) {
|
|
223
|
+
best = conn;
|
|
224
|
+
} else if (
|
|
225
|
+
conn.lastActiveAt === best.lastActiveAt &&
|
|
226
|
+
(conn.registrationSeq ?? 0) > (best.registrationSeq ?? 0)
|
|
227
|
+
) {
|
|
228
|
+
best = conn;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return best;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Return the connection for an explicit (guardianId, clientInstanceId)
|
|
236
|
+
* pair, or `undefined` if no such instance is registered. Used by
|
|
237
|
+
* routing callers that need to target a specific extension install
|
|
238
|
+
* (e.g. sending a follow-up frame to the same instance that produced
|
|
239
|
+
* the prior result).
|
|
240
|
+
*/
|
|
241
|
+
getInstance(
|
|
242
|
+
guardianId: string,
|
|
243
|
+
clientInstanceId: string,
|
|
244
|
+
): ChromeExtensionConnection | undefined {
|
|
245
|
+
return this.byGuardian.get(guardianId)?.get(clientInstanceId);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Return all currently registered connections for a guardian. Order
|
|
250
|
+
* is insertion order of the inner map — callers that care about
|
|
251
|
+
* recency should sort by `lastActiveAt` themselves.
|
|
252
|
+
*/
|
|
253
|
+
listInstances(guardianId: string): ChromeExtensionConnection[] {
|
|
254
|
+
const instances = this.byGuardian.get(guardianId);
|
|
255
|
+
if (!instances) return [];
|
|
256
|
+
return Array.from(instances.values());
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Send a ServerMessage to the default active chrome-extension
|
|
261
|
+
* connection for the given guardian. The "default active" instance
|
|
262
|
+
* is the one with the most recent `lastActiveAt` timestamp — i.e.
|
|
263
|
+
* the install the user is currently driving.
|
|
264
|
+
*
|
|
265
|
+
* Returns `true` when a connection exists and the send succeeds;
|
|
266
|
+
* `false` when no connection is registered or when the underlying
|
|
267
|
+
* `ws.send` throws. On a successful send, the connection's
|
|
268
|
+
* `lastActiveAt` is bumped so subsequent default sends stay on the
|
|
269
|
+
* same instance unless another sibling becomes more recent.
|
|
270
|
+
*/
|
|
271
|
+
send(guardianId: string, msg: ServerMessage): boolean {
|
|
272
|
+
const conn = this.get(guardianId);
|
|
273
|
+
if (!conn) return false;
|
|
274
|
+
return this.sendTo(conn, msg);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Send a ServerMessage to an explicit (guardianId, clientInstanceId)
|
|
279
|
+
* pair. Returns `false` when no matching instance is registered or
|
|
280
|
+
* when the underlying `ws.send` throws.
|
|
281
|
+
*/
|
|
282
|
+
sendToInstance(
|
|
283
|
+
guardianId: string,
|
|
284
|
+
clientInstanceId: string,
|
|
285
|
+
msg: ServerMessage,
|
|
286
|
+
): boolean {
|
|
287
|
+
const conn = this.getInstance(guardianId, clientInstanceId);
|
|
288
|
+
if (!conn) return false;
|
|
289
|
+
return this.sendTo(conn, msg);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Low-level send helper — writes to the socket and bumps
|
|
294
|
+
* `lastActiveAt` on success. Callers should use {@link send} or
|
|
295
|
+
* {@link sendToInstance} unless they already hold a resolved
|
|
296
|
+
* connection handle.
|
|
297
|
+
*/
|
|
298
|
+
private sendTo(conn: ChromeExtensionConnection, msg: ServerMessage): boolean {
|
|
299
|
+
try {
|
|
300
|
+
conn.ws.send(JSON.stringify(msg));
|
|
301
|
+
conn.lastActiveAt = Date.now();
|
|
302
|
+
return true;
|
|
303
|
+
} catch (err) {
|
|
304
|
+
log.warn(
|
|
305
|
+
{
|
|
306
|
+
guardianId: conn.guardianId,
|
|
307
|
+
connectionId: conn.id,
|
|
308
|
+
clientInstanceId: conn.clientInstanceId,
|
|
309
|
+
err,
|
|
310
|
+
},
|
|
311
|
+
"failed to send to chrome extension",
|
|
312
|
+
);
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ── Module-level singleton (same pattern as assistant-event-hub) ──────────
|
|
319
|
+
let instance: ChromeExtensionRegistry | null = null;
|
|
320
|
+
|
|
321
|
+
export function getChromeExtensionRegistry(): ChromeExtensionRegistry {
|
|
322
|
+
if (!instance) instance = new ChromeExtensionRegistry();
|
|
323
|
+
return instance;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Test helper: reset the module-level singleton so each test starts with a
|
|
328
|
+
* fresh registry. Not exported from any public index — test-only.
|
|
329
|
+
*/
|
|
330
|
+
export function __resetChromeExtensionRegistryForTests(): void {
|
|
331
|
+
instance = null;
|
|
332
|
+
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from "../memory/canonical-guardian-store.js";
|
|
20
20
|
import { emitNotificationSignal } from "../notifications/emit-signal.js";
|
|
21
21
|
import type { NotificationSourceChannel } from "../notifications/signal.js";
|
|
22
|
+
import { isPermissionControlsV2Enabled } from "../permissions/v2-consent-policy.js";
|
|
22
23
|
import { canonicalizeInboundIdentity } from "../util/canonicalize-identity.js";
|
|
23
24
|
import { getLogger } from "../util/logger.js";
|
|
24
25
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "./assistant-scope.js";
|
|
@@ -49,6 +50,7 @@ export type BridgeConfirmationRequestResult =
|
|
|
49
50
|
skipped: true;
|
|
50
51
|
reason:
|
|
51
52
|
| "not_trusted_contact"
|
|
53
|
+
| "v2_model_mediated"
|
|
52
54
|
| "no_guardian_binding"
|
|
53
55
|
| "missing_guardian_identity"
|
|
54
56
|
| "binding_identity_mismatch";
|
|
@@ -84,6 +86,10 @@ export function bridgeConfirmationRequestToGuardian(
|
|
|
84
86
|
return { skipped: true, reason: "not_trusted_contact" };
|
|
85
87
|
}
|
|
86
88
|
|
|
89
|
+
if (isPermissionControlsV2Enabled()) {
|
|
90
|
+
return { skipped: true, reason: "v2_model_mediated" };
|
|
91
|
+
}
|
|
92
|
+
|
|
87
93
|
if (!trustContext.guardianExternalUserId) {
|
|
88
94
|
log.debug(
|
|
89
95
|
{ conversationId, sourceChannel: trustContext.sourceChannel },
|
|
@@ -79,6 +79,13 @@ export const GUARDIAN_DECISION_ACTIONS = {
|
|
|
79
79
|
reject: { action: "reject", label: "Reject", description: "Deny this call" },
|
|
80
80
|
} as const satisfies Record<string, GuardianDecisionAction>;
|
|
81
81
|
|
|
82
|
+
export function buildOneTimeDecisionActions(): GuardianDecisionAction[] {
|
|
83
|
+
return [
|
|
84
|
+
GUARDIAN_DECISION_ACTIONS.approve_once,
|
|
85
|
+
GUARDIAN_DECISION_ACTIONS.reject,
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
|
|
82
89
|
/**
|
|
83
90
|
* Build the set of `GuardianDecisionAction` items appropriate for a prompt,
|
|
84
91
|
* respecting whether persistent decisions (approve_always) are allowed.
|