@vellumai/assistant 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +6 -7
- package/Dockerfile +1 -0
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
- package/bun.lock +3 -0
- package/docs/architecture/security.md +18 -16
- package/knip.json +1 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/openapi.yaml +294 -107
- package/package.json +4 -2
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +6 -17
- package/src/__tests__/assistant-event-hub.test.ts +126 -77
- package/src/__tests__/assistant-event.test.ts +0 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
- package/src/__tests__/background-shell-host-bash.test.ts +34 -43
- package/src/__tests__/call-controller.test.ts +1 -1
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/checker.test.ts +20 -34
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-watcher.test.ts +12 -0
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-lifecycle.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
- package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -4
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/cu-unified-flow.test.ts +33 -16
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +4 -1
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +289 -7
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-bash-proxy.test.ts +46 -122
- package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
- package/src/__tests__/host-browser-proxy.test.ts +111 -185
- package/src/__tests__/host-browser-routes.test.ts +45 -75
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
- package/src/__tests__/host-cu-proxy.test.ts +56 -111
- package/src/__tests__/host-file-proxy.test.ts +44 -98
- package/src/__tests__/host-file-read-tool.test.ts +42 -21
- package/src/__tests__/host-shell-tool.test.ts +33 -68
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy.test.ts +43 -53
- package/src/__tests__/http-user-message-parity.test.ts +0 -6
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -66
- package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +66 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
- package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +331 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -22
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +3 -12
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +0 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +9 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt.test.ts +115 -13
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
- package/src/__tests__/tool-executor.test.ts +12 -19
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/backup-worker.test.ts +36 -8
- package/src/backup/__tests__/paths.test.ts +2 -2
- package/src/backup/__tests__/restore.test.ts +45 -28
- package/src/backup/backup-worker.ts +36 -2
- package/src/backup/paths.ts +9 -6
- package/src/browser-session/events.ts +0 -9
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +0 -24
- package/src/calls/twilio-rest.ts +0 -38
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +1 -36
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/backup.ts +4 -4
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +63 -5
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +231 -76
- package/src/cli/commands/keys.ts +4 -1
- package/src/cli/commands/memory-v2.ts +24 -52
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +14 -0
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
- package/src/config/env-registry.ts +12 -2
- package/src/config/env.ts +3 -14
- package/src/config/feature-flag-registry.json +30 -30
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +3 -3
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -5
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +31 -3
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +9 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +6 -6
- package/src/config/schemas/skills.ts +5 -5
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -17
- package/src/contacts/contacts-write.ts +1 -105
- package/src/context/window-manager.ts +44 -5
- package/src/credential-execution/process-manager.ts +34 -10
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
- package/src/daemon/conversation-agent-loop.ts +277 -36
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +83 -163
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +22 -28
- package/src/daemon/conversation-tool-setup.ts +3 -33
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +117 -233
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +23 -71
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-bash-proxy.ts +67 -45
- package/src/daemon/host-browser-proxy.ts +65 -27
- package/src/daemon/host-cu-proxy.ts +40 -39
- package/src/daemon/host-file-proxy.ts +58 -37
- package/src/daemon/host-transfer-proxy.ts +84 -46
- package/src/daemon/lifecycle.ts +49 -15
- package/src/daemon/message-types/conversations.ts +7 -0
- package/src/daemon/message-types/host-bash.ts +1 -0
- package/src/daemon/message-types/host-cu.ts +1 -0
- package/src/daemon/message-types/host-file.ts +1 -0
- package/src/daemon/message-types/host-transfer.ts +1 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +102 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -2
- package/src/daemon/tool-side-effects.ts +125 -107
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +3 -1
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
- package/src/heartbeat/heartbeat-service.ts +23 -5
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/relationship-state-writer.ts +16 -3
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +3 -10
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/manager.ts +0 -5
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/context-search/sources/memory-v2.ts +578 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +29 -4
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +3 -21
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
- package/src/memory/graph/conversation-graph-memory.ts +35 -13
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs-store.ts +0 -1
- package/src/memory/jobs-worker.ts +2 -16
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +14 -0
- package/src/memory/migrations/registry.ts +24 -0
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +25 -0
- package/src/memory/search/semantic.ts +5 -16
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +289 -90
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +384 -15
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/static-context.test.ts +153 -0
- package/src/memory/v2/activation.ts +168 -97
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +14 -12
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +182 -58
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +118 -42
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/skill-store.ts +55 -7
- package/src/memory/v2/static-context.ts +62 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +122 -21
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +97 -0
- package/src/oauth/manual-token-connection.ts +30 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/config.ts +0 -74
- package/src/outbound-proxy/health.ts +0 -44
- package/src/outbound-proxy/index.ts +0 -22
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.ts +4 -1
- package/src/permissions/gateway-threshold-reader.ts +4 -1
- package/src/permissions/prompter.ts +9 -2
- package/src/permissions/secret-prompter.ts +21 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/system-prompt.ts +34 -70
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +541 -45
- package/src/runtime/assistant-event.ts +1 -6
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -1
- package/src/runtime/auth/route-policy.ts +11 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +22 -82
- package/src/runtime/http-types.ts +5 -0
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
- package/src/runtime/migrations/migration-transport.ts +46 -13
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +133 -79
- package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
- package/src/runtime/migrations/vbundle-importer.ts +7 -7
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
- package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
- package/src/runtime/migrations/vbundle-validator.ts +214 -41
- package/src/runtime/pending-interactions.ts +13 -4
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +45 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +120 -8
- package/src/runtime/routes/conversation-routes.ts +44 -528
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/documents-routes.ts +53 -18
- package/src/runtime/routes/events-routes.ts +59 -91
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/host-bash-routes.ts +3 -2
- package/src/runtime/routes/host-browser-routes.ts +9 -33
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +3 -2
- package/src/runtime/routes/host-transfer-routes.ts +11 -15
- package/src/runtime/routes/identity-routes.ts +78 -6
- package/src/runtime/routes/inbound-message-handler.ts +580 -137
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/index.ts +4 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/memory-v2-routes.ts +10 -15
- package/src/runtime/routes/migration-routes.ts +188 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +3 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/schedule/schedule-store.ts +0 -16
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +6 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
- package/src/telemetry/usage-telemetry-reporter.ts +3 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
- package/src/tools/browser/cdp-client/factory.ts +48 -76
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/executor.ts +44 -31
- package/src/tools/host-filesystem/edit.ts +3 -2
- package/src/tools/host-filesystem/read.ts +3 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +4 -3
- package/src/tools/host-filesystem/write.ts +3 -2
- package/src/tools/host-terminal/host-shell.ts +4 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/types.ts +12 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -1,518 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import type { ServerMessage } from "../../daemon/message-protocol.js";
|
|
4
|
-
import {
|
|
5
|
-
__resetChromeExtensionRegistryForTests,
|
|
6
|
-
type ChromeExtensionConnection,
|
|
7
|
-
ChromeExtensionRegistry,
|
|
8
|
-
getChromeExtensionRegistry,
|
|
9
|
-
} from "../chrome-extension-registry.js";
|
|
10
|
-
|
|
11
|
-
// Minimal structural stand-in for Bun's ServerWebSocket. Only the methods
|
|
12
|
-
// the registry touches (`send`, `close`) are modeled; the rest of the Bun
|
|
13
|
-
// ServerWebSocket API is out of scope for these unit tests.
|
|
14
|
-
interface FakeWs {
|
|
15
|
-
send: (data: string) => number;
|
|
16
|
-
close: (code?: number, reason?: string) => void;
|
|
17
|
-
sent: string[];
|
|
18
|
-
closed: { code?: number; reason?: string }[];
|
|
19
|
-
sendShouldThrow?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function makeFakeWs(): FakeWs {
|
|
23
|
-
const sent: string[] = [];
|
|
24
|
-
const closed: { code?: number; reason?: string }[] = [];
|
|
25
|
-
const ws: FakeWs = {
|
|
26
|
-
sent,
|
|
27
|
-
closed,
|
|
28
|
-
send(data: string) {
|
|
29
|
-
if (ws.sendShouldThrow) {
|
|
30
|
-
throw new Error("simulated ws.send failure");
|
|
31
|
-
}
|
|
32
|
-
sent.push(data);
|
|
33
|
-
return data.length;
|
|
34
|
-
},
|
|
35
|
-
close(code?: number, reason?: string) {
|
|
36
|
-
closed.push({ code, reason });
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
return ws;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function makeConnection(
|
|
43
|
-
guardianId: string,
|
|
44
|
-
id?: string,
|
|
45
|
-
clientInstanceId?: string,
|
|
46
|
-
): { conn: ChromeExtensionConnection; fakeWs: FakeWs } {
|
|
47
|
-
const fakeWs = makeFakeWs();
|
|
48
|
-
const now = Date.now();
|
|
49
|
-
const conn: ChromeExtensionConnection = {
|
|
50
|
-
id: id ?? crypto.randomUUID(),
|
|
51
|
-
guardianId,
|
|
52
|
-
clientInstanceId,
|
|
53
|
-
ws: fakeWs as unknown as ChromeExtensionConnection["ws"],
|
|
54
|
-
connectedAt: now,
|
|
55
|
-
lastActiveAt: now,
|
|
56
|
-
};
|
|
57
|
-
return { conn, fakeWs };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
describe("ChromeExtensionRegistry", () => {
|
|
61
|
-
beforeEach(() => {
|
|
62
|
-
__resetChromeExtensionRegistryForTests();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test("register stores the connection under the guardianId", () => {
|
|
66
|
-
const registry = new ChromeExtensionRegistry();
|
|
67
|
-
const { conn } = makeConnection("guardian-alpha");
|
|
68
|
-
registry.register(conn);
|
|
69
|
-
expect(registry.get("guardian-alpha")).toBe(conn);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test("unregister removes the connection", () => {
|
|
73
|
-
const registry = new ChromeExtensionRegistry();
|
|
74
|
-
const { conn } = makeConnection("guardian-alpha");
|
|
75
|
-
registry.register(conn);
|
|
76
|
-
registry.unregister(conn.id);
|
|
77
|
-
expect(registry.get("guardian-alpha")).toBeUndefined();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test("unregister is a no-op when the connectionId is unknown", () => {
|
|
81
|
-
const registry = new ChromeExtensionRegistry();
|
|
82
|
-
// Should not throw even though nothing is registered.
|
|
83
|
-
expect(() => registry.unregister("unknown-connection")).not.toThrow();
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test("registering a second connection for the same guardianId + instance closes the prior one", () => {
|
|
87
|
-
const registry = new ChromeExtensionRegistry();
|
|
88
|
-
const { conn: conn1, fakeWs: fakeWs1 } = makeConnection(
|
|
89
|
-
"guardian-alpha",
|
|
90
|
-
"conn-1",
|
|
91
|
-
"install-A",
|
|
92
|
-
);
|
|
93
|
-
const { conn: conn2 } = makeConnection(
|
|
94
|
-
"guardian-alpha",
|
|
95
|
-
"conn-2",
|
|
96
|
-
"install-A",
|
|
97
|
-
);
|
|
98
|
-
registry.register(conn1);
|
|
99
|
-
registry.register(conn2);
|
|
100
|
-
// Prior connection (same instance) should have been closed with code 1000.
|
|
101
|
-
expect(fakeWs1.closed).toHaveLength(1);
|
|
102
|
-
expect(fakeWs1.closed[0].code).toBe(1000);
|
|
103
|
-
// Registry should hold the new connection for that instance.
|
|
104
|
-
expect(registry.getInstance("guardian-alpha", "install-A")).toBe(conn2);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test("registering the same connection id twice is idempotent and does not close itself", () => {
|
|
108
|
-
const registry = new ChromeExtensionRegistry();
|
|
109
|
-
const { conn, fakeWs } = makeConnection("guardian-alpha", "conn-1");
|
|
110
|
-
registry.register(conn);
|
|
111
|
-
registry.register(conn);
|
|
112
|
-
expect(fakeWs.closed).toHaveLength(0);
|
|
113
|
-
expect(registry.get("guardian-alpha")).toBe(conn);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test("send returns false when no connection exists for the guardian", () => {
|
|
117
|
-
const registry = new ChromeExtensionRegistry();
|
|
118
|
-
const msg: ServerMessage = {
|
|
119
|
-
type: "host_browser_cancel",
|
|
120
|
-
requestId: "req-1",
|
|
121
|
-
} as ServerMessage;
|
|
122
|
-
expect(registry.send("missing-guardian", msg)).toBe(false);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test("send returns true and forwards the JSON-serialized message when a connection exists", () => {
|
|
126
|
-
const registry = new ChromeExtensionRegistry();
|
|
127
|
-
const { conn, fakeWs } = makeConnection("guardian-alpha");
|
|
128
|
-
registry.register(conn);
|
|
129
|
-
const msg: ServerMessage = {
|
|
130
|
-
type: "host_browser_cancel",
|
|
131
|
-
requestId: "req-1",
|
|
132
|
-
} as ServerMessage;
|
|
133
|
-
const ok = registry.send("guardian-alpha", msg);
|
|
134
|
-
expect(ok).toBe(true);
|
|
135
|
-
expect(fakeWs.sent).toHaveLength(1);
|
|
136
|
-
const parsed = JSON.parse(fakeWs.sent[0]);
|
|
137
|
-
expect(parsed.type).toBe("host_browser_cancel");
|
|
138
|
-
expect(parsed.requestId).toBe("req-1");
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
test("send returns false when ws.send throws (best-effort delivery)", () => {
|
|
142
|
-
const registry = new ChromeExtensionRegistry();
|
|
143
|
-
const { conn, fakeWs } = makeConnection("guardian-alpha");
|
|
144
|
-
fakeWs.sendShouldThrow = true;
|
|
145
|
-
registry.register(conn);
|
|
146
|
-
const msg: ServerMessage = {
|
|
147
|
-
type: "host_browser_cancel",
|
|
148
|
-
requestId: "req-1",
|
|
149
|
-
} as ServerMessage;
|
|
150
|
-
expect(registry.send("guardian-alpha", msg)).toBe(false);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
test("getChromeExtensionRegistry returns a module-level singleton", () => {
|
|
154
|
-
const first = getChromeExtensionRegistry();
|
|
155
|
-
const second = getChromeExtensionRegistry();
|
|
156
|
-
expect(first).toBe(second);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
test("unregister after supersession does not remove the new connection", () => {
|
|
160
|
-
// When a new connection supersedes an older one, the close handler for
|
|
161
|
-
// the older socket will fire later and call unregister with the OLD id.
|
|
162
|
-
// That must not clobber the newer registration.
|
|
163
|
-
const registry = new ChromeExtensionRegistry();
|
|
164
|
-
const { conn: old } = makeConnection(
|
|
165
|
-
"guardian-alpha",
|
|
166
|
-
"old-id",
|
|
167
|
-
"install-A",
|
|
168
|
-
);
|
|
169
|
-
const { conn: fresh } = makeConnection(
|
|
170
|
-
"guardian-alpha",
|
|
171
|
-
"fresh-id",
|
|
172
|
-
"install-A",
|
|
173
|
-
);
|
|
174
|
-
registry.register(old);
|
|
175
|
-
registry.register(fresh);
|
|
176
|
-
registry.unregister("old-id");
|
|
177
|
-
expect(registry.getInstance("guardian-alpha", "install-A")).toBe(fresh);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// ── Multi-instance routing ──────────────────────────────────────────
|
|
181
|
-
//
|
|
182
|
-
// A single guardian may have multiple parallel extension installs
|
|
183
|
-
// connected at once (two Chrome profiles, two desktops sharing a sync
|
|
184
|
-
// identity). The registry keys inner entries by (guardianId,
|
|
185
|
-
// clientInstanceId) so sibling installs don't evict each other on
|
|
186
|
-
// register/unregister, and the default `send()` path routes to
|
|
187
|
-
// whichever instance has the most recent activity.
|
|
188
|
-
describe("multi-instance routing", () => {
|
|
189
|
-
test("two concurrent instances under the same guardian coexist", () => {
|
|
190
|
-
const registry = new ChromeExtensionRegistry();
|
|
191
|
-
const { conn: connA } = makeConnection(
|
|
192
|
-
"guardian-alpha",
|
|
193
|
-
"conn-A",
|
|
194
|
-
"install-A",
|
|
195
|
-
);
|
|
196
|
-
const { conn: connB } = makeConnection(
|
|
197
|
-
"guardian-alpha",
|
|
198
|
-
"conn-B",
|
|
199
|
-
"install-B",
|
|
200
|
-
);
|
|
201
|
-
registry.register(connA);
|
|
202
|
-
registry.register(connB);
|
|
203
|
-
// Both instances remain registered — neither should have been
|
|
204
|
-
// closed by the other's registration.
|
|
205
|
-
expect(registry.getInstance("guardian-alpha", "install-A")).toBe(connA);
|
|
206
|
-
expect(registry.getInstance("guardian-alpha", "install-B")).toBe(connB);
|
|
207
|
-
expect(registry.listInstances("guardian-alpha")).toHaveLength(2);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
test("registering a new instance does not close sibling instances", () => {
|
|
211
|
-
const registry = new ChromeExtensionRegistry();
|
|
212
|
-
const { conn: connA, fakeWs: fakeWsA } = makeConnection(
|
|
213
|
-
"guardian-alpha",
|
|
214
|
-
"conn-A",
|
|
215
|
-
"install-A",
|
|
216
|
-
);
|
|
217
|
-
const { conn: connB, fakeWs: fakeWsB } = makeConnection(
|
|
218
|
-
"guardian-alpha",
|
|
219
|
-
"conn-B",
|
|
220
|
-
"install-B",
|
|
221
|
-
);
|
|
222
|
-
registry.register(connA);
|
|
223
|
-
registry.register(connB);
|
|
224
|
-
// Neither socket should have been closed by the sibling's
|
|
225
|
-
// registration.
|
|
226
|
-
expect(fakeWsA.closed).toHaveLength(0);
|
|
227
|
-
expect(fakeWsB.closed).toHaveLength(0);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test("unregister of one instance leaves the sibling in place", () => {
|
|
231
|
-
const registry = new ChromeExtensionRegistry();
|
|
232
|
-
const { conn: connA } = makeConnection(
|
|
233
|
-
"guardian-alpha",
|
|
234
|
-
"conn-A",
|
|
235
|
-
"install-A",
|
|
236
|
-
);
|
|
237
|
-
const { conn: connB } = makeConnection(
|
|
238
|
-
"guardian-alpha",
|
|
239
|
-
"conn-B",
|
|
240
|
-
"install-B",
|
|
241
|
-
);
|
|
242
|
-
registry.register(connA);
|
|
243
|
-
registry.register(connB);
|
|
244
|
-
registry.unregister("conn-A");
|
|
245
|
-
expect(
|
|
246
|
-
registry.getInstance("guardian-alpha", "install-A"),
|
|
247
|
-
).toBeUndefined();
|
|
248
|
-
expect(registry.getInstance("guardian-alpha", "install-B")).toBe(connB);
|
|
249
|
-
// Guardian bucket should still exist because install-B is active.
|
|
250
|
-
expect(registry.listInstances("guardian-alpha")).toHaveLength(1);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
test("default send routes to the most recently active instance", () => {
|
|
254
|
-
const registry = new ChromeExtensionRegistry();
|
|
255
|
-
const { conn: connA, fakeWs: fakeWsA } = makeConnection(
|
|
256
|
-
"guardian-alpha",
|
|
257
|
-
"conn-A",
|
|
258
|
-
"install-A",
|
|
259
|
-
);
|
|
260
|
-
const { conn: connB, fakeWs: fakeWsB } = makeConnection(
|
|
261
|
-
"guardian-alpha",
|
|
262
|
-
"conn-B",
|
|
263
|
-
"install-B",
|
|
264
|
-
);
|
|
265
|
-
// Use a fake clock so A's register timestamp is strictly less
|
|
266
|
-
// than B's, ensuring B becomes the "most recently active"
|
|
267
|
-
// instance regardless of host-clock resolution.
|
|
268
|
-
const originalNow = Date.now;
|
|
269
|
-
let fakeNow = originalNow();
|
|
270
|
-
Date.now = () => fakeNow;
|
|
271
|
-
try {
|
|
272
|
-
registry.register(connA);
|
|
273
|
-
fakeNow += 10;
|
|
274
|
-
registry.register(connB);
|
|
275
|
-
const msg: ServerMessage = {
|
|
276
|
-
type: "host_browser_cancel",
|
|
277
|
-
requestId: "req-1",
|
|
278
|
-
} as ServerMessage;
|
|
279
|
-
expect(registry.send("guardian-alpha", msg)).toBe(true);
|
|
280
|
-
} finally {
|
|
281
|
-
Date.now = originalNow;
|
|
282
|
-
}
|
|
283
|
-
// Default send should have landed on instance B, not A.
|
|
284
|
-
expect(fakeWsA.sent).toHaveLength(0);
|
|
285
|
-
expect(fakeWsB.sent).toHaveLength(1);
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
test("default send follows activity — later sendToInstance flips the default", () => {
|
|
289
|
-
const registry = new ChromeExtensionRegistry();
|
|
290
|
-
const { conn: connA, fakeWs: fakeWsA } = makeConnection(
|
|
291
|
-
"guardian-alpha",
|
|
292
|
-
"conn-A",
|
|
293
|
-
"install-A",
|
|
294
|
-
);
|
|
295
|
-
const { conn: connB, fakeWs: fakeWsB } = makeConnection(
|
|
296
|
-
"guardian-alpha",
|
|
297
|
-
"conn-B",
|
|
298
|
-
"install-B",
|
|
299
|
-
);
|
|
300
|
-
registry.register(connA);
|
|
301
|
-
registry.register(connB);
|
|
302
|
-
// B was registered last so it starts as the default. Force a
|
|
303
|
-
// send to A via sendToInstance — that bumps A's lastActiveAt and
|
|
304
|
-
// should make it the new default target.
|
|
305
|
-
const msg: ServerMessage = {
|
|
306
|
-
type: "host_browser_cancel",
|
|
307
|
-
requestId: "req-1",
|
|
308
|
-
} as ServerMessage;
|
|
309
|
-
// Nudge the clock forward so A's lastActiveAt strictly exceeds
|
|
310
|
-
// B's register-time stamp even on hosts where Date.now() has
|
|
311
|
-
// millisecond resolution.
|
|
312
|
-
const originalNow = Date.now;
|
|
313
|
-
let fakeNow = originalNow() + 10;
|
|
314
|
-
Date.now = () => fakeNow;
|
|
315
|
-
try {
|
|
316
|
-
expect(
|
|
317
|
-
registry.sendToInstance("guardian-alpha", "install-A", msg),
|
|
318
|
-
).toBe(true);
|
|
319
|
-
fakeNow += 10;
|
|
320
|
-
// Default send should now route to A.
|
|
321
|
-
expect(registry.send("guardian-alpha", msg)).toBe(true);
|
|
322
|
-
} finally {
|
|
323
|
-
Date.now = originalNow;
|
|
324
|
-
}
|
|
325
|
-
// A received one explicit send and one default send.
|
|
326
|
-
expect(fakeWsA.sent).toHaveLength(2);
|
|
327
|
-
// B only received the initial register (no sends).
|
|
328
|
-
expect(fakeWsB.sent).toHaveLength(0);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
test("sendToInstance returns false for an unknown instance", () => {
|
|
332
|
-
const registry = new ChromeExtensionRegistry();
|
|
333
|
-
const { conn } = makeConnection("guardian-alpha", "conn-A", "install-A");
|
|
334
|
-
registry.register(conn);
|
|
335
|
-
const msg: ServerMessage = {
|
|
336
|
-
type: "host_browser_cancel",
|
|
337
|
-
requestId: "req-1",
|
|
338
|
-
} as ServerMessage;
|
|
339
|
-
expect(
|
|
340
|
-
registry.sendToInstance("guardian-alpha", "install-missing", msg),
|
|
341
|
-
).toBe(false);
|
|
342
|
-
expect(
|
|
343
|
-
registry.sendToInstance("guardian-missing", "install-A", msg),
|
|
344
|
-
).toBe(false);
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
test("get returns undefined after the last instance unregisters", () => {
|
|
348
|
-
const registry = new ChromeExtensionRegistry();
|
|
349
|
-
const { conn } = makeConnection("guardian-alpha", "conn-A", "install-A");
|
|
350
|
-
registry.register(conn);
|
|
351
|
-
registry.unregister("conn-A");
|
|
352
|
-
expect(registry.get("guardian-alpha")).toBeUndefined();
|
|
353
|
-
expect(registry.listInstances("guardian-alpha")).toHaveLength(0);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
test("ties on lastActiveAt are broken by registrationSeq (newest wins)", () => {
|
|
357
|
-
// Freeze Date.now so both instances stamp the exact same
|
|
358
|
-
// lastActiveAt. Without the registrationSeq tiebreaker, the
|
|
359
|
-
// strict `>` comparison in get() would keep whichever entry
|
|
360
|
-
// Map#values() yields first — i.e. the earlier-inserted one,
|
|
361
|
-
// which is the opposite of the "most recently registered"
|
|
362
|
-
// semantics a caller would expect.
|
|
363
|
-
const registry = new ChromeExtensionRegistry();
|
|
364
|
-
const { conn: connA, fakeWs: fakeWsA } = makeConnection(
|
|
365
|
-
"guardian-alpha",
|
|
366
|
-
"conn-A",
|
|
367
|
-
"install-A",
|
|
368
|
-
);
|
|
369
|
-
const { conn: connB, fakeWs: fakeWsB } = makeConnection(
|
|
370
|
-
"guardian-alpha",
|
|
371
|
-
"conn-B",
|
|
372
|
-
"install-B",
|
|
373
|
-
);
|
|
374
|
-
const originalNow = Date.now;
|
|
375
|
-
const frozenNow = originalNow();
|
|
376
|
-
Date.now = () => frozenNow;
|
|
377
|
-
try {
|
|
378
|
-
registry.register(connA);
|
|
379
|
-
registry.register(connB);
|
|
380
|
-
// Both should hold the same lastActiveAt because Date.now is frozen.
|
|
381
|
-
expect(connA.lastActiveAt).toBe(connB.lastActiveAt);
|
|
382
|
-
// connB registered second, so its registrationSeq must be higher.
|
|
383
|
-
expect(connB.registrationSeq).toBeGreaterThan(
|
|
384
|
-
connA.registrationSeq ?? 0,
|
|
385
|
-
);
|
|
386
|
-
const msg: ServerMessage = {
|
|
387
|
-
type: "host_browser_cancel",
|
|
388
|
-
requestId: "req-1",
|
|
389
|
-
} as ServerMessage;
|
|
390
|
-
expect(registry.send("guardian-alpha", msg)).toBe(true);
|
|
391
|
-
} finally {
|
|
392
|
-
Date.now = originalNow;
|
|
393
|
-
}
|
|
394
|
-
// Default send should have landed on the newer instance (B),
|
|
395
|
-
// not the older insertion-order winner (A).
|
|
396
|
-
expect(fakeWsA.sent).toHaveLength(0);
|
|
397
|
-
expect(fakeWsB.sent).toHaveLength(1);
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
test("registrationSeq is monotonically increasing across registrations", () => {
|
|
401
|
-
// Sanity check on the counter itself — new registrations should
|
|
402
|
-
// always stamp a strictly greater sequence number than anything
|
|
403
|
-
// that came before, including re-registrations of the same
|
|
404
|
-
// instance after a supersede.
|
|
405
|
-
const registry = new ChromeExtensionRegistry();
|
|
406
|
-
const { conn: connA } = makeConnection(
|
|
407
|
-
"guardian-alpha",
|
|
408
|
-
"conn-A",
|
|
409
|
-
"install-A",
|
|
410
|
-
);
|
|
411
|
-
const { conn: connB } = makeConnection(
|
|
412
|
-
"guardian-alpha",
|
|
413
|
-
"conn-B",
|
|
414
|
-
"install-B",
|
|
415
|
-
);
|
|
416
|
-
const { conn: connC } = makeConnection(
|
|
417
|
-
"guardian-alpha",
|
|
418
|
-
"conn-C",
|
|
419
|
-
"install-A",
|
|
420
|
-
);
|
|
421
|
-
registry.register(connA);
|
|
422
|
-
registry.register(connB);
|
|
423
|
-
registry.register(connC); // supersedes install-A → conn-A closes
|
|
424
|
-
expect(connA.registrationSeq).toBeDefined();
|
|
425
|
-
expect(connB.registrationSeq).toBeDefined();
|
|
426
|
-
expect(connC.registrationSeq).toBeDefined();
|
|
427
|
-
expect(connB.registrationSeq!).toBeGreaterThan(connA.registrationSeq!);
|
|
428
|
-
expect(connC.registrationSeq!).toBeGreaterThan(connB.registrationSeq!);
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
test("same-millisecond supersede leaves the new connection as default", () => {
|
|
432
|
-
// Re-registering the same install within the same millisecond
|
|
433
|
-
// window must still promote the new connection to the default
|
|
434
|
-
// target — the tie-breaker should apply to re-registrations of
|
|
435
|
-
// the same instance just as it applies to sibling instances.
|
|
436
|
-
const registry = new ChromeExtensionRegistry();
|
|
437
|
-
const { conn: old } = makeConnection(
|
|
438
|
-
"guardian-alpha",
|
|
439
|
-
"old-id",
|
|
440
|
-
"install-A",
|
|
441
|
-
);
|
|
442
|
-
const { conn: fresh, fakeWs: fakeWsFresh } = makeConnection(
|
|
443
|
-
"guardian-alpha",
|
|
444
|
-
"fresh-id",
|
|
445
|
-
"install-A",
|
|
446
|
-
);
|
|
447
|
-
const originalNow = Date.now;
|
|
448
|
-
const frozenNow = originalNow();
|
|
449
|
-
Date.now = () => frozenNow;
|
|
450
|
-
try {
|
|
451
|
-
registry.register(old);
|
|
452
|
-
registry.register(fresh);
|
|
453
|
-
const msg: ServerMessage = {
|
|
454
|
-
type: "host_browser_cancel",
|
|
455
|
-
requestId: "req-1",
|
|
456
|
-
} as ServerMessage;
|
|
457
|
-
expect(registry.send("guardian-alpha", msg)).toBe(true);
|
|
458
|
-
} finally {
|
|
459
|
-
Date.now = originalNow;
|
|
460
|
-
}
|
|
461
|
-
// The fresh connection must receive the default send even though
|
|
462
|
-
// both entries stamped the exact same lastActiveAt.
|
|
463
|
-
expect(fakeWsFresh.sent).toHaveLength(1);
|
|
464
|
-
});
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
// ── Backwards compatibility ─────────────────────────────────────────
|
|
468
|
-
//
|
|
469
|
-
// Connections without a clientInstanceId (older extension builds or
|
|
470
|
-
// dev-bypass paths) synthesize a connection-scoped key so each one
|
|
471
|
-
// lives in its own slot. This gives sibling instances for the same
|
|
472
|
-
// guardian independent lifecycles even without explicit client ids.
|
|
473
|
-
describe("backwards compatibility when clientInstanceId is absent", () => {
|
|
474
|
-
test("two legacy connections under the same guardian coexist", () => {
|
|
475
|
-
const registry = new ChromeExtensionRegistry();
|
|
476
|
-
const { conn: connA } = makeConnection(
|
|
477
|
-
"guardian-alpha",
|
|
478
|
-
"conn-A",
|
|
479
|
-
// clientInstanceId intentionally omitted
|
|
480
|
-
);
|
|
481
|
-
const { conn: connB } = makeConnection(
|
|
482
|
-
"guardian-alpha",
|
|
483
|
-
"conn-B",
|
|
484
|
-
// clientInstanceId intentionally omitted
|
|
485
|
-
);
|
|
486
|
-
registry.register(connA);
|
|
487
|
-
registry.register(connB);
|
|
488
|
-
expect(registry.listInstances("guardian-alpha")).toHaveLength(2);
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
test("legacy unregister does not clobber a newer legacy sibling", () => {
|
|
492
|
-
const registry = new ChromeExtensionRegistry();
|
|
493
|
-
const { conn: oldConn } = makeConnection("guardian-alpha", "old-id");
|
|
494
|
-
const { conn: freshConn } = makeConnection("guardian-alpha", "fresh-id");
|
|
495
|
-
registry.register(oldConn);
|
|
496
|
-
registry.register(freshConn);
|
|
497
|
-
registry.unregister("old-id");
|
|
498
|
-
expect(registry.listInstances("guardian-alpha")).toHaveLength(1);
|
|
499
|
-
// The surviving entry is the newer connection.
|
|
500
|
-
const remaining = registry.listInstances("guardian-alpha");
|
|
501
|
-
expect(remaining[0]).toBe(freshConn);
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
test("legacy and instance-id connections can coexist under the same guardian", () => {
|
|
505
|
-
const registry = new ChromeExtensionRegistry();
|
|
506
|
-
const { conn: legacy } = makeConnection("guardian-alpha", "legacy-id");
|
|
507
|
-
const { conn: modern } = makeConnection(
|
|
508
|
-
"guardian-alpha",
|
|
509
|
-
"modern-id",
|
|
510
|
-
"install-A",
|
|
511
|
-
);
|
|
512
|
-
registry.register(legacy);
|
|
513
|
-
registry.register(modern);
|
|
514
|
-
expect(registry.listInstances("guardian-alpha")).toHaveLength(2);
|
|
515
|
-
expect(registry.getInstance("guardian-alpha", "install-A")).toBe(modern);
|
|
516
|
-
});
|
|
517
|
-
});
|
|
518
|
-
});
|