@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
|
@@ -57,13 +57,13 @@ mock.module("../config/env.js", () => ({
|
|
|
57
57
|
getRuntimeGatewayOriginSecret: () => undefined,
|
|
58
58
|
}));
|
|
59
59
|
|
|
60
|
+
import { defaultV1Options } from "../runtime/migrations/__tests__/v1-test-helpers.js";
|
|
60
61
|
import { validateVBundle } from "../runtime/migrations/vbundle-validator.js";
|
|
61
62
|
import {
|
|
62
63
|
handleMigrationExport,
|
|
63
64
|
handleMigrationValidate,
|
|
64
65
|
} from "../runtime/routes/migration-routes.js";
|
|
65
66
|
import { callHandler } from "./helpers/call-route-handler.js";
|
|
66
|
-
|
|
67
67
|
// Test fixture data: a minimal SQLite header to simulate a real database file
|
|
68
68
|
const SQLITE_HEADER = new Uint8Array([
|
|
69
69
|
0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
|
|
@@ -143,7 +143,7 @@ describe("handleMigrationExport", () => {
|
|
|
143
143
|
);
|
|
144
144
|
expect(res.headers.get("Content-Length")).toBeDefined();
|
|
145
145
|
expect(Number(res.headers.get("Content-Length"))).toBeGreaterThan(0);
|
|
146
|
-
expect(res.headers.get("X-Vbundle-Schema-Version")).toBe("1
|
|
146
|
+
expect(res.headers.get("X-Vbundle-Schema-Version")).toBe("1");
|
|
147
147
|
expect(res.headers.get("X-Vbundle-Manifest-Sha256")).toBeDefined();
|
|
148
148
|
expect(res.headers.get("X-Vbundle-Manifest-Sha256")!.length).toBe(64);
|
|
149
149
|
});
|
|
@@ -176,25 +176,25 @@ describe("handleMigrationExport", () => {
|
|
|
176
176
|
const validationResult = validateVBundle(archiveData);
|
|
177
177
|
const manifest = validationResult.manifest!;
|
|
178
178
|
|
|
179
|
-
expect(manifest.schema_version).toBe(
|
|
180
|
-
expect(manifest.
|
|
179
|
+
expect(manifest.schema_version).toBe(1);
|
|
180
|
+
expect(manifest.bundle_id).toBeDefined();
|
|
181
181
|
expect(manifest.created_at).toBeDefined();
|
|
182
|
-
expect(manifest.
|
|
182
|
+
expect(manifest.checksum).toBeDefined();
|
|
183
183
|
|
|
184
184
|
// Verify file entries — workspace walk uses workspace/ prefix
|
|
185
|
-
const filePaths = manifest.
|
|
185
|
+
const filePaths = manifest.contents.map((f) => f.path);
|
|
186
186
|
expect(filePaths).toContain("workspace/data/db/assistant.db");
|
|
187
187
|
expect(filePaths).toContain("workspace/config.json");
|
|
188
188
|
|
|
189
189
|
// Verify each file entry has proper sha256 and size
|
|
190
|
-
for (const file of manifest.
|
|
190
|
+
for (const file of manifest.contents) {
|
|
191
191
|
expect(file.sha256).toBeDefined();
|
|
192
192
|
expect(file.sha256.length).toBe(64);
|
|
193
|
-
expect(file.
|
|
193
|
+
expect(file.size_bytes).toBeGreaterThanOrEqual(0);
|
|
194
194
|
}
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
-
test("custom description
|
|
197
|
+
test("custom description in JSON body is accepted but no longer surfaced in manifest", async () => {
|
|
198
198
|
const req = new Request("http://localhost/v1/migrations/export", {
|
|
199
199
|
method: "POST",
|
|
200
200
|
headers: { "Content-Type": "application/json" },
|
|
@@ -206,9 +206,9 @@ describe("handleMigrationExport", () => {
|
|
|
206
206
|
const archiveData = new Uint8Array(arrayBuffer);
|
|
207
207
|
|
|
208
208
|
const validationResult = validateVBundle(archiveData);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
expect(validationResult.is_valid).toBe(true);
|
|
210
|
+
// v1 manifests intentionally drop the legacy `description` field —
|
|
211
|
+
// assert the export still succeeds even though the body carried one.
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
test("invalid JSON body is gracefully handled with defaults", async () => {
|
|
@@ -312,20 +312,20 @@ describe("export data population", () => {
|
|
|
312
312
|
const validationResult = validateVBundle(archiveData);
|
|
313
313
|
const manifest = validationResult.manifest!;
|
|
314
314
|
|
|
315
|
-
const dbFile = manifest.
|
|
315
|
+
const dbFile = manifest.contents.find(
|
|
316
316
|
(f) => f.path === "workspace/data/db/assistant.db",
|
|
317
317
|
);
|
|
318
318
|
expect(dbFile).toBeDefined();
|
|
319
|
-
expect(dbFile!.
|
|
319
|
+
expect(dbFile!.size_bytes).toBe(SQLITE_HEADER.length);
|
|
320
320
|
|
|
321
|
-
const configFile = manifest.
|
|
321
|
+
const configFile = manifest.contents.find(
|
|
322
322
|
(f) => f.path === "workspace/config.json",
|
|
323
323
|
);
|
|
324
324
|
expect(configFile).toBeDefined();
|
|
325
325
|
const expectedConfigSize = Buffer.byteLength(
|
|
326
326
|
JSON.stringify(TEST_CONFIG, null, 2) + "\n",
|
|
327
327
|
);
|
|
328
|
-
expect(configFile!.
|
|
328
|
+
expect(configFile!.size_bytes).toBe(expectedConfigSize);
|
|
329
329
|
});
|
|
330
330
|
|
|
331
331
|
test("manifest checksums match actual file content", async () => {
|
|
@@ -340,7 +340,7 @@ describe("export data population", () => {
|
|
|
340
340
|
const validationResult = validateVBundle(archiveData);
|
|
341
341
|
const manifest = validationResult.manifest!;
|
|
342
342
|
|
|
343
|
-
for (const fileEntry of manifest.
|
|
343
|
+
for (const fileEntry of manifest.contents) {
|
|
344
344
|
const tarEntry = entries.find((e) => e.name === fileEntry.path);
|
|
345
345
|
expect(tarEntry).toBeDefined();
|
|
346
346
|
expect(sha256Hex(tarEntry!.data)).toBe(fileEntry.sha256);
|
|
@@ -358,12 +358,12 @@ describe("export data population", () => {
|
|
|
358
358
|
const validationResult = validateVBundle(archiveData);
|
|
359
359
|
const manifest = validationResult.manifest!;
|
|
360
360
|
|
|
361
|
-
const dbFile = manifest.
|
|
361
|
+
const dbFile = manifest.contents.find(
|
|
362
362
|
(f) => f.path === "workspace/data/db/assistant.db",
|
|
363
363
|
);
|
|
364
364
|
expect(dbFile).toBeDefined();
|
|
365
365
|
// The skeleton used size 0 — real export should have actual content
|
|
366
|
-
expect(dbFile!.
|
|
366
|
+
expect(dbFile!.size_bytes).toBeGreaterThan(0);
|
|
367
367
|
});
|
|
368
368
|
|
|
369
369
|
test("config content is real JSON (not empty object placeholder)", async () => {
|
|
@@ -390,17 +390,23 @@ describe("export data population", () => {
|
|
|
390
390
|
// ---------------------------------------------------------------------------
|
|
391
391
|
|
|
392
392
|
describe("export graceful fallback", () => {
|
|
393
|
-
test("nonexistent workspace produces
|
|
393
|
+
test("nonexistent workspace produces archive that fails the v1 contents refine", async () => {
|
|
394
394
|
const { buildExportVBundle } =
|
|
395
395
|
await import("../runtime/migrations/vbundle-builder.js");
|
|
396
396
|
|
|
397
397
|
const result = buildExportVBundle({
|
|
398
398
|
workspaceDir: join(testDir, "nonexistent-workspace"),
|
|
399
|
+
...defaultV1Options(),
|
|
399
400
|
});
|
|
400
401
|
|
|
402
|
+
// Under v1, every bundle MUST declare a `data/db/assistant.db` (or
|
|
403
|
+
// `workspace/data/db/assistant.db`) entry. A nonexistent workspace
|
|
404
|
+
// produces an empty contents array, which the validator's `.refine()`
|
|
405
|
+
// rejects. Documenting this so a future regression on the workspace
|
|
406
|
+
// walk doesn't silently produce a structurally-empty bundle.
|
|
401
407
|
const validationResult = validateVBundle(result.archive);
|
|
402
|
-
expect(validationResult.is_valid).toBe(
|
|
403
|
-
expect(result.manifest.
|
|
408
|
+
expect(validationResult.is_valid).toBe(false);
|
|
409
|
+
expect(result.manifest.contents).toHaveLength(0);
|
|
404
410
|
});
|
|
405
411
|
|
|
406
412
|
test("workspace walk includes db and config under workspace/ prefix", async () => {
|
|
@@ -409,22 +415,23 @@ describe("export graceful fallback", () => {
|
|
|
409
415
|
|
|
410
416
|
const result = buildExportVBundle({
|
|
411
417
|
workspaceDir: testDir,
|
|
418
|
+
...defaultV1Options(),
|
|
412
419
|
});
|
|
413
420
|
|
|
414
421
|
const validationResult = validateVBundle(result.archive);
|
|
415
422
|
expect(validationResult.is_valid).toBe(true);
|
|
416
423
|
|
|
417
|
-
const dbFile = result.manifest.
|
|
424
|
+
const dbFile = result.manifest.contents.find(
|
|
418
425
|
(f) => f.path === "workspace/data/db/assistant.db",
|
|
419
426
|
);
|
|
420
427
|
expect(dbFile).toBeDefined();
|
|
421
|
-
expect(dbFile!.
|
|
428
|
+
expect(dbFile!.size_bytes).toBeGreaterThan(0);
|
|
422
429
|
|
|
423
|
-
const configFile = result.manifest.
|
|
430
|
+
const configFile = result.manifest.contents.find(
|
|
424
431
|
(f) => f.path === "workspace/config.json",
|
|
425
432
|
);
|
|
426
433
|
expect(configFile).toBeDefined();
|
|
427
|
-
expect(configFile!.
|
|
434
|
+
expect(configFile!.size_bytes).toBeGreaterThan(0);
|
|
428
435
|
});
|
|
429
436
|
});
|
|
430
437
|
|
|
@@ -55,12 +55,12 @@ mock.module("../config/env.js", () => ({
|
|
|
55
55
|
setIngressPublicBaseUrl: () => {},
|
|
56
56
|
}));
|
|
57
57
|
|
|
58
|
+
import { defaultV1Options } from "../runtime/migrations/__tests__/v1-test-helpers.js";
|
|
58
59
|
import {
|
|
59
60
|
buildExportVBundle,
|
|
60
61
|
streamExportVBundle,
|
|
61
62
|
} from "../runtime/migrations/vbundle-builder.js";
|
|
62
63
|
import { validateVBundle } from "../runtime/migrations/vbundle-validator.js";
|
|
63
|
-
|
|
64
64
|
// Test fixture data: a minimal SQLite header to simulate a real database file
|
|
65
65
|
const SQLITE_HEADER = new Uint8Array([
|
|
66
66
|
0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
|
|
@@ -146,6 +146,7 @@ describe("streamExportVBundle", () => {
|
|
|
146
146
|
test("returns a temp file that exists on disk", async () => {
|
|
147
147
|
const result = await streamExportVBundle({
|
|
148
148
|
workspaceDir: testDir,
|
|
149
|
+
...defaultV1Options(),
|
|
149
150
|
});
|
|
150
151
|
|
|
151
152
|
try {
|
|
@@ -159,13 +160,14 @@ describe("streamExportVBundle", () => {
|
|
|
159
160
|
test("manifest contains correct SHA-256 checksums for all files", async () => {
|
|
160
161
|
const result = await streamExportVBundle({
|
|
161
162
|
workspaceDir: testDir,
|
|
163
|
+
...defaultV1Options(),
|
|
162
164
|
});
|
|
163
165
|
|
|
164
166
|
try {
|
|
165
167
|
const archiveData = new Uint8Array(readFileSync(result.tempPath));
|
|
166
168
|
const entries = parseTarEntries(archiveData);
|
|
167
169
|
|
|
168
|
-
for (const fileEntry of result.manifest.
|
|
170
|
+
for (const fileEntry of result.manifest.contents) {
|
|
169
171
|
const tarEntry = entries.find((e) => e.name === fileEntry.path);
|
|
170
172
|
expect(tarEntry).toBeDefined();
|
|
171
173
|
expect(sha256Hex(tarEntry!.data)).toBe(fileEntry.sha256);
|
|
@@ -178,11 +180,13 @@ describe("streamExportVBundle", () => {
|
|
|
178
180
|
test("decompressed archive produces same files as buildExportVBundle", async () => {
|
|
179
181
|
const streamResult = await streamExportVBundle({
|
|
180
182
|
workspaceDir: testDir,
|
|
183
|
+
...defaultV1Options(),
|
|
181
184
|
});
|
|
182
185
|
|
|
183
186
|
try {
|
|
184
187
|
const syncResult = buildExportVBundle({
|
|
185
188
|
workspaceDir: testDir,
|
|
189
|
+
...defaultV1Options(),
|
|
186
190
|
});
|
|
187
191
|
|
|
188
192
|
const streamArchiveData = new Uint8Array(
|
|
@@ -212,10 +216,10 @@ describe("streamExportVBundle", () => {
|
|
|
212
216
|
}
|
|
213
217
|
|
|
214
218
|
// Same manifest file entries (excluding timing fields)
|
|
215
|
-
const streamManifestFiles = streamResult.manifest.
|
|
219
|
+
const streamManifestFiles = streamResult.manifest.contents
|
|
216
220
|
.slice()
|
|
217
221
|
.sort((a, b) => a.path.localeCompare(b.path));
|
|
218
|
-
const syncManifestFiles = syncResult.manifest.
|
|
222
|
+
const syncManifestFiles = syncResult.manifest.contents
|
|
219
223
|
.slice()
|
|
220
224
|
.sort((a, b) => a.path.localeCompare(b.path));
|
|
221
225
|
|
|
@@ -225,8 +229,8 @@ describe("streamExportVBundle", () => {
|
|
|
225
229
|
expect(streamManifestFiles.map((f) => f.sha256)).toEqual(
|
|
226
230
|
syncManifestFiles.map((f) => f.sha256),
|
|
227
231
|
);
|
|
228
|
-
expect(streamManifestFiles.map((f) => f.
|
|
229
|
-
syncManifestFiles.map((f) => f.
|
|
232
|
+
expect(streamManifestFiles.map((f) => f.size_bytes)).toEqual(
|
|
233
|
+
syncManifestFiles.map((f) => f.size_bytes),
|
|
230
234
|
);
|
|
231
235
|
} finally {
|
|
232
236
|
await streamResult.cleanup();
|
|
@@ -236,6 +240,7 @@ describe("streamExportVBundle", () => {
|
|
|
236
240
|
test("cleanup removes the temp file", async () => {
|
|
237
241
|
const result = await streamExportVBundle({
|
|
238
242
|
workspaceDir: testDir,
|
|
243
|
+
...defaultV1Options(),
|
|
239
244
|
});
|
|
240
245
|
|
|
241
246
|
expect(existsSync(result.tempPath)).toBe(true);
|
|
@@ -252,6 +257,7 @@ describe("streamExportVBundle round-trip", () => {
|
|
|
252
257
|
test("streaming archive passes validateVBundle with matching manifest", async () => {
|
|
253
258
|
const result = await streamExportVBundle({
|
|
254
259
|
workspaceDir: testDir,
|
|
260
|
+
...defaultV1Options(),
|
|
255
261
|
});
|
|
256
262
|
|
|
257
263
|
try {
|
|
@@ -266,15 +272,15 @@ describe("streamExportVBundle round-trip", () => {
|
|
|
266
272
|
expect(validationResult.manifest!.schema_version).toBe(
|
|
267
273
|
result.manifest.schema_version,
|
|
268
274
|
);
|
|
269
|
-
expect(validationResult.manifest!.
|
|
270
|
-
result.manifest.
|
|
275
|
+
expect(validationResult.manifest!.checksum).toBe(
|
|
276
|
+
result.manifest.checksum,
|
|
271
277
|
);
|
|
272
278
|
|
|
273
279
|
// Verify file entries match
|
|
274
280
|
const validatedFiles = validationResult
|
|
275
|
-
.manifest!.
|
|
281
|
+
.manifest!.contents.slice()
|
|
276
282
|
.sort((a, b) => a.path.localeCompare(b.path));
|
|
277
|
-
const resultFiles = result.manifest.
|
|
283
|
+
const resultFiles = result.manifest.contents
|
|
278
284
|
.slice()
|
|
279
285
|
.sort((a, b) => a.path.localeCompare(b.path));
|
|
280
286
|
|
|
@@ -316,6 +322,7 @@ describe("streamExportVBundle config sanitization", () => {
|
|
|
316
322
|
|
|
317
323
|
const result = await streamExportVBundle({
|
|
318
324
|
workspaceDir: testDir,
|
|
325
|
+
...defaultV1Options(),
|
|
319
326
|
});
|
|
320
327
|
|
|
321
328
|
try {
|
|
@@ -359,6 +366,7 @@ describe("streamExportVBundle cleanup", () => {
|
|
|
359
366
|
test("calling cleanup twice does not throw", async () => {
|
|
360
367
|
const result = await streamExportVBundle({
|
|
361
368
|
workspaceDir: testDir,
|
|
369
|
+
...defaultV1Options(),
|
|
362
370
|
});
|
|
363
371
|
|
|
364
372
|
await result.cleanup();
|
|
@@ -242,7 +242,12 @@ describe("handleMigrationExportToGcs — happy path", () => {
|
|
|
242
242
|
}),
|
|
243
243
|
});
|
|
244
244
|
|
|
245
|
-
const res = await callHandler(
|
|
245
|
+
const res = await callHandler(
|
|
246
|
+
handleMigrationExportToGcs,
|
|
247
|
+
req,
|
|
248
|
+
undefined,
|
|
249
|
+
202,
|
|
250
|
+
);
|
|
246
251
|
expect(res.status).toBe(202);
|
|
247
252
|
|
|
248
253
|
const body = (await res.json()) as AcceptedResponse;
|
|
@@ -275,7 +280,7 @@ describe("handleMigrationExportToGcs — happy path", () => {
|
|
|
275
280
|
const validation = validateVBundle(new Uint8Array(capturedBody!));
|
|
276
281
|
expect(validation.is_valid).toBe(true);
|
|
277
282
|
expect(validation.errors).toHaveLength(0);
|
|
278
|
-
expect(validation.manifest?.
|
|
283
|
+
expect(validation.manifest?.checksum).toBe(result.sha256);
|
|
279
284
|
} finally {
|
|
280
285
|
await fixture.close();
|
|
281
286
|
}
|
|
@@ -319,7 +324,12 @@ describe("handleMigrationExportToGcs — concurrency", () => {
|
|
|
319
324
|
}),
|
|
320
325
|
},
|
|
321
326
|
);
|
|
322
|
-
const firstRes = await callHandler(
|
|
327
|
+
const firstRes = await callHandler(
|
|
328
|
+
handleMigrationExportToGcs,
|
|
329
|
+
firstReq,
|
|
330
|
+
undefined,
|
|
331
|
+
202,
|
|
332
|
+
);
|
|
323
333
|
expect(firstRes.status).toBe(202);
|
|
324
334
|
const firstBody = (await firstRes.json()) as AcceptedResponse;
|
|
325
335
|
|
|
@@ -338,7 +348,12 @@ describe("handleMigrationExportToGcs — concurrency", () => {
|
|
|
338
348
|
}),
|
|
339
349
|
},
|
|
340
350
|
);
|
|
341
|
-
const secondRes = await callHandler(
|
|
351
|
+
const secondRes = await callHandler(
|
|
352
|
+
handleMigrationExportToGcs,
|
|
353
|
+
secondReq,
|
|
354
|
+
undefined,
|
|
355
|
+
202,
|
|
356
|
+
);
|
|
342
357
|
expect(secondRes.status).toBe(409);
|
|
343
358
|
const secondBody = (await secondRes.json()) as ErrorEnvelope;
|
|
344
359
|
expect(secondBody.error.code).toBe("export_in_progress");
|
|
@@ -375,7 +390,12 @@ describe("handleMigrationExportToGcs — upload failure", () => {
|
|
|
375
390
|
}),
|
|
376
391
|
});
|
|
377
392
|
|
|
378
|
-
const res = await callHandler(
|
|
393
|
+
const res = await callHandler(
|
|
394
|
+
handleMigrationExportToGcs,
|
|
395
|
+
req,
|
|
396
|
+
undefined,
|
|
397
|
+
202,
|
|
398
|
+
);
|
|
379
399
|
expect(res.status).toBe(202);
|
|
380
400
|
const body = (await res.json()) as AcceptedResponse;
|
|
381
401
|
|
|
@@ -419,7 +439,12 @@ describe("handleMigrationExportToGcs — redirect handling", () => {
|
|
|
419
439
|
}),
|
|
420
440
|
});
|
|
421
441
|
|
|
422
|
-
const res = await callHandler(
|
|
442
|
+
const res = await callHandler(
|
|
443
|
+
handleMigrationExportToGcs,
|
|
444
|
+
req,
|
|
445
|
+
undefined,
|
|
446
|
+
202,
|
|
447
|
+
);
|
|
423
448
|
expect(res.status).toBe(202);
|
|
424
449
|
const body = (await res.json()) as AcceptedResponse;
|
|
425
450
|
|
|
@@ -446,7 +471,12 @@ describe("handleMigrationExportToGcs — URL validation", () => {
|
|
|
446
471
|
upload_url: "http://storage.googleapis.com/b/o?X-Goog-Signature=fake",
|
|
447
472
|
}),
|
|
448
473
|
});
|
|
449
|
-
const res = await callHandler(
|
|
474
|
+
const res = await callHandler(
|
|
475
|
+
handleMigrationExportToGcs,
|
|
476
|
+
req,
|
|
477
|
+
undefined,
|
|
478
|
+
202,
|
|
479
|
+
);
|
|
450
480
|
expect(res.status).toBe(400);
|
|
451
481
|
const body = (await res.json()) as ErrorEnvelope;
|
|
452
482
|
expect(body.error.code).toBe("invalid_upload_url");
|
|
@@ -466,7 +496,12 @@ describe("handleMigrationExportToGcs — URL validation", () => {
|
|
|
466
496
|
upload_url: "https://evil.example.com/bucket/obj?X-Goog-Signature=fake",
|
|
467
497
|
}),
|
|
468
498
|
});
|
|
469
|
-
const res = await callHandler(
|
|
499
|
+
const res = await callHandler(
|
|
500
|
+
handleMigrationExportToGcs,
|
|
501
|
+
req,
|
|
502
|
+
undefined,
|
|
503
|
+
202,
|
|
504
|
+
);
|
|
470
505
|
expect(res.status).toBe(400);
|
|
471
506
|
const body = (await res.json()) as ErrorEnvelope;
|
|
472
507
|
expect(body.error.code).toBe("invalid_upload_url");
|
|
@@ -482,7 +517,12 @@ describe("handleMigrationExportToGcs — URL validation", () => {
|
|
|
482
517
|
"https://storage.googleapis.com/bucket/..%2Fother?X-Goog-Signature=fake",
|
|
483
518
|
}),
|
|
484
519
|
});
|
|
485
|
-
const res = await callHandler(
|
|
520
|
+
const res = await callHandler(
|
|
521
|
+
handleMigrationExportToGcs,
|
|
522
|
+
req,
|
|
523
|
+
undefined,
|
|
524
|
+
202,
|
|
525
|
+
);
|
|
486
526
|
expect(res.status).toBe(400);
|
|
487
527
|
const body = (await res.json()) as ErrorEnvelope;
|
|
488
528
|
expect(body.error.code).toBe("invalid_upload_url");
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - Auth: route policy enforcement (settings.write scope required)
|
|
12
12
|
* - Integration: existing routes are unaffected by the new endpoint
|
|
13
13
|
*/
|
|
14
|
-
import { createHash } from "node:crypto";
|
|
14
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
15
15
|
import {
|
|
16
16
|
existsSync,
|
|
17
17
|
mkdirSync,
|
|
@@ -237,41 +237,85 @@ interface VBundleFile {
|
|
|
237
237
|
data: Uint8Array;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Build a v1-shape vbundle archive for HTTP/import tests.
|
|
242
|
+
*
|
|
243
|
+
* Mirrors the v1 ten-field manifest that `buildVBundle()` produces, so the
|
|
244
|
+
* fixtures here pass the same `ManifestSchema` zod validation the real
|
|
245
|
+
* importer applies. The manifest's `checksum` is computed against the
|
|
246
|
+
* canonical JSON with `checksum` set to "" (matches `computeManifestChecksum`
|
|
247
|
+
* in vbundle-validator.ts).
|
|
248
|
+
*
|
|
249
|
+
* Adds a synthetic `data/db/assistant.db` entry to `contents` when the caller
|
|
250
|
+
* doesn't supply one, satisfying the schema's `.refine()` constraint that
|
|
251
|
+
* every bundle must reference an assistant.db file.
|
|
252
|
+
*/
|
|
240
253
|
function createValidVBundle(
|
|
241
254
|
files?: VBundleFile[],
|
|
242
255
|
overrides?: Partial<{
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
256
|
+
bundle_id: string;
|
|
257
|
+
origin_mode: "managed" | "self-hosted-remote" | "self-hosted-local";
|
|
258
|
+
secrets_redacted: boolean;
|
|
246
259
|
}>,
|
|
247
260
|
): Uint8Array {
|
|
248
261
|
const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
|
|
249
262
|
const bundleFiles = files ?? [{ path: "data/db/assistant.db", data: dbData }];
|
|
250
263
|
|
|
251
|
-
|
|
264
|
+
// v1 schema requires contents to include data/db/assistant.db (legacy) or
|
|
265
|
+
// workspace/data/db/assistant.db (current). If the caller's files don't
|
|
266
|
+
// satisfy that refine, inject a synthetic legacy-path db entry — this
|
|
267
|
+
// matches the pattern used in vbundle-streaming-importer.test.ts.
|
|
268
|
+
const hasDbEntry = bundleFiles.some(
|
|
269
|
+
(f) =>
|
|
270
|
+
f.path === "data/db/assistant.db" ||
|
|
271
|
+
f.path === "workspace/data/db/assistant.db",
|
|
272
|
+
);
|
|
273
|
+
const allFiles: VBundleFile[] = hasDbEntry
|
|
274
|
+
? bundleFiles
|
|
275
|
+
: [
|
|
276
|
+
{ path: "data/db/assistant.db", data: new Uint8Array() },
|
|
277
|
+
...bundleFiles,
|
|
278
|
+
];
|
|
279
|
+
|
|
280
|
+
const contents = allFiles.map((f) => ({
|
|
252
281
|
path: f.path,
|
|
253
282
|
sha256: sha256Hex(f.data),
|
|
254
|
-
|
|
283
|
+
size_bytes: f.data.length,
|
|
255
284
|
}));
|
|
256
285
|
|
|
257
286
|
const manifestWithoutChecksum = {
|
|
258
|
-
schema_version:
|
|
287
|
+
schema_version: 1 as const,
|
|
288
|
+
bundle_id: overrides?.bundle_id ?? randomUUID(),
|
|
259
289
|
created_at: new Date().toISOString(),
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
290
|
+
assistant: {
|
|
291
|
+
id: "self",
|
|
292
|
+
name: "Test",
|
|
293
|
+
runtime_version: "0.0.0-test",
|
|
294
|
+
},
|
|
295
|
+
origin: {
|
|
296
|
+
mode: overrides?.origin_mode ?? "self-hosted-local",
|
|
297
|
+
},
|
|
298
|
+
compatibility: {
|
|
299
|
+
min_runtime_version: "0.0.0-test",
|
|
300
|
+
max_runtime_version: null,
|
|
301
|
+
},
|
|
302
|
+
contents,
|
|
303
|
+
checksum: "",
|
|
304
|
+
secrets_redacted: overrides?.secrets_redacted ?? false,
|
|
305
|
+
export_options: {
|
|
306
|
+
include_logs: false,
|
|
307
|
+
include_browser_state: false,
|
|
308
|
+
include_memory_vectors: false,
|
|
309
|
+
},
|
|
263
310
|
};
|
|
264
311
|
|
|
265
|
-
const
|
|
266
|
-
const manifest = {
|
|
267
|
-
...manifestWithoutChecksum,
|
|
268
|
-
manifest_sha256: manifestSha256,
|
|
269
|
-
};
|
|
312
|
+
const checksum = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
|
|
313
|
+
const manifest = { ...manifestWithoutChecksum, checksum };
|
|
270
314
|
const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
|
|
271
315
|
|
|
272
316
|
const tarEntries = [
|
|
273
317
|
{ name: "manifest.json", data: manifestData },
|
|
274
|
-
...
|
|
318
|
+
...allFiles.map((f) => ({ name: f.path, data: f.data })),
|
|
275
319
|
];
|
|
276
320
|
|
|
277
321
|
const tar = createTarArchive(tarEntries);
|
|
@@ -445,9 +489,9 @@ describe("handleMigrationImport", () => {
|
|
|
445
489
|
});
|
|
446
490
|
|
|
447
491
|
test("includes manifest in response", async () => {
|
|
492
|
+
const fixedBundleId = "11111111-2222-4333-8444-555555555555";
|
|
448
493
|
const vbundle = createValidVBundle(undefined, {
|
|
449
|
-
|
|
450
|
-
description: "Test import commit",
|
|
494
|
+
bundle_id: fixedBundleId,
|
|
451
495
|
});
|
|
452
496
|
const req = new Request("http://localhost/v1/migrations/import", {
|
|
453
497
|
method: "POST",
|
|
@@ -459,9 +503,10 @@ describe("handleMigrationImport", () => {
|
|
|
459
503
|
const body = (await res.json()) as ImportCommitResponse;
|
|
460
504
|
|
|
461
505
|
expect(body.manifest).toBeDefined();
|
|
462
|
-
expect(body.manifest.schema_version).toBe(
|
|
463
|
-
expect(body.manifest.
|
|
464
|
-
expect(body.manifest.
|
|
506
|
+
expect(body.manifest.schema_version).toBe(1);
|
|
507
|
+
expect(body.manifest.bundle_id).toBe(fixedBundleId);
|
|
508
|
+
expect(body.manifest.assistant).toBeDefined();
|
|
509
|
+
expect(body.manifest.origin).toEqual({ mode: "self-hosted-local" });
|
|
465
510
|
});
|
|
466
511
|
|
|
467
512
|
test("POST with multipart form data works", async () => {
|
|
@@ -109,6 +109,7 @@ mock.module("../config/env.js", () => ({
|
|
|
109
109
|
// Imports (after mocks so module-level code picks up the stubs)
|
|
110
110
|
// ---------------------------------------------------------------------------
|
|
111
111
|
|
|
112
|
+
import { defaultV1Options } from "../runtime/migrations/__tests__/v1-test-helpers.js";
|
|
112
113
|
import {
|
|
113
114
|
type MigrationJob,
|
|
114
115
|
migrationJobs,
|
|
@@ -119,7 +120,6 @@ import {
|
|
|
119
120
|
handleMigrationImportFromGcs,
|
|
120
121
|
} from "../runtime/routes/migration-routes.js";
|
|
121
122
|
import { callHandler } from "./helpers/call-route-handler.js";
|
|
122
|
-
|
|
123
123
|
// ---------------------------------------------------------------------------
|
|
124
124
|
// Local http fixture server
|
|
125
125
|
// ---------------------------------------------------------------------------
|
|
@@ -191,6 +191,7 @@ function makeSmallValidBundlePath(parent: string): string {
|
|
|
191
191
|
),
|
|
192
192
|
},
|
|
193
193
|
],
|
|
194
|
+
...defaultV1Options(),
|
|
194
195
|
});
|
|
195
196
|
const bundlePath = join(parent, "fixture-small.vbundle");
|
|
196
197
|
writeFileSync(bundlePath, archive);
|
|
@@ -313,7 +314,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
313
314
|
},
|
|
314
315
|
);
|
|
315
316
|
|
|
316
|
-
const res = await callHandler(
|
|
317
|
+
const res = await callHandler(
|
|
318
|
+
handleMigrationImportFromGcs,
|
|
319
|
+
req,
|
|
320
|
+
undefined,
|
|
321
|
+
202,
|
|
322
|
+
);
|
|
317
323
|
expect(res.status).toBe(202);
|
|
318
324
|
const body = (await res.json()) as AcceptedResponse;
|
|
319
325
|
expect(body.type).toBe("import");
|
|
@@ -368,7 +374,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
368
374
|
},
|
|
369
375
|
);
|
|
370
376
|
|
|
371
|
-
const res = await callHandler(
|
|
377
|
+
const res = await callHandler(
|
|
378
|
+
handleMigrationImportFromGcs,
|
|
379
|
+
req,
|
|
380
|
+
undefined,
|
|
381
|
+
202,
|
|
382
|
+
);
|
|
372
383
|
expect(res.status).toBe(202);
|
|
373
384
|
const body = (await res.json()) as AcceptedResponse;
|
|
374
385
|
|
|
@@ -399,7 +410,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
399
410
|
},
|
|
400
411
|
);
|
|
401
412
|
|
|
402
|
-
const res = await callHandler(
|
|
413
|
+
const res = await callHandler(
|
|
414
|
+
handleMigrationImportFromGcs,
|
|
415
|
+
req,
|
|
416
|
+
undefined,
|
|
417
|
+
202,
|
|
418
|
+
);
|
|
403
419
|
expect(res.status).toBe(202);
|
|
404
420
|
const body = (await res.json()) as AcceptedResponse;
|
|
405
421
|
|
|
@@ -437,7 +453,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
437
453
|
body: JSON.stringify({ bundle_url: makeFakeSignedUrl(fixture.port) }),
|
|
438
454
|
},
|
|
439
455
|
);
|
|
440
|
-
const firstRes = await callHandler(
|
|
456
|
+
const firstRes = await callHandler(
|
|
457
|
+
handleMigrationImportFromGcs,
|
|
458
|
+
firstReq,
|
|
459
|
+
undefined,
|
|
460
|
+
202,
|
|
461
|
+
);
|
|
441
462
|
expect(firstRes.status).toBe(202);
|
|
442
463
|
const firstBody = (await firstRes.json()) as AcceptedResponse;
|
|
443
464
|
firstJobId = firstBody.job_id;
|
|
@@ -450,7 +471,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
450
471
|
body: JSON.stringify({ bundle_url: makeFakeSignedUrl(fixture.port) }),
|
|
451
472
|
},
|
|
452
473
|
);
|
|
453
|
-
const secondRes = await callHandler(
|
|
474
|
+
const secondRes = await callHandler(
|
|
475
|
+
handleMigrationImportFromGcs,
|
|
476
|
+
secondReq,
|
|
477
|
+
undefined,
|
|
478
|
+
202,
|
|
479
|
+
);
|
|
454
480
|
expect(secondRes.status).toBe(409);
|
|
455
481
|
const secondBody = (await secondRes.json()) as ConflictResponse;
|
|
456
482
|
expect(secondBody.error.code).toBe("import_in_progress");
|
|
@@ -484,7 +510,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
484
510
|
}),
|
|
485
511
|
},
|
|
486
512
|
);
|
|
487
|
-
const badRes = await callHandler(
|
|
513
|
+
const badRes = await callHandler(
|
|
514
|
+
handleMigrationImportFromGcs,
|
|
515
|
+
badReq,
|
|
516
|
+
undefined,
|
|
517
|
+
202,
|
|
518
|
+
);
|
|
488
519
|
expect(badRes.status).toBe(400);
|
|
489
520
|
const badBody = (await badRes.json()) as InvalidBundleUrlResponse;
|
|
490
521
|
expect(badBody.error.code).toBe("invalid_bundle_url");
|
|
@@ -507,7 +538,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
507
538
|
body: JSON.stringify({ bundle_url: makeFakeSignedUrl(fixture.port) }),
|
|
508
539
|
},
|
|
509
540
|
);
|
|
510
|
-
const goodRes = await callHandler(
|
|
541
|
+
const goodRes = await callHandler(
|
|
542
|
+
handleMigrationImportFromGcs,
|
|
543
|
+
goodReq,
|
|
544
|
+
undefined,
|
|
545
|
+
202,
|
|
546
|
+
);
|
|
511
547
|
expect(goodRes.status).toBe(202);
|
|
512
548
|
const goodBody = (await goodRes.json()) as AcceptedResponse;
|
|
513
549
|
expect(goodBody.type).toBe("import");
|
|
@@ -525,7 +561,12 @@ describe("POST /v1/migrations/import-from-gcs", () => {
|
|
|
525
561
|
headers: { "Content-Type": "application/json" },
|
|
526
562
|
body: JSON.stringify({}),
|
|
527
563
|
});
|
|
528
|
-
const res = await callHandler(
|
|
564
|
+
const res = await callHandler(
|
|
565
|
+
handleMigrationImportFromGcs,
|
|
566
|
+
req,
|
|
567
|
+
undefined,
|
|
568
|
+
202,
|
|
569
|
+
);
|
|
529
570
|
expect(res.status).toBe(400);
|
|
530
571
|
const body = (await res.json()) as BadRequestResponse;
|
|
531
572
|
expect(body.error.code).toBe("BAD_REQUEST");
|