@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +0 -20
- package/docs/workspace-tools.md +33 -42
- package/eslint-rules/cli-no-daemon-internals.js +0 -6
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
- package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
- package/node_modules/@vellumai/service-contracts/package.json +0 -1
- package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
- package/openapi.yaml +0 -155
- package/package.json +1 -4
- package/scripts/test.sh +15 -36
- package/src/__tests__/actor-token-service.test.ts +14 -36
- package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
- package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
- package/src/__tests__/annotate-risk-options.test.ts +0 -2
- package/src/__tests__/approval-cascade.test.ts +0 -2
- package/src/__tests__/assistant-attachments.test.ts +0 -42
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -2
- package/src/__tests__/build-persisted-content.test.ts +0 -2
- package/src/__tests__/call-controller.test.ts +0 -19
- package/src/__tests__/channel-guardian.test.ts +58 -94
- package/src/__tests__/channel-reply-delivery.test.ts +0 -2
- package/src/__tests__/compaction-events.test.ts +0 -2
- package/src/__tests__/compaction.benchmark.test.ts +0 -2
- package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
- package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
- package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
- package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
- package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
- package/src/__tests__/config-loader-backfill.test.ts +10 -123
- package/src/__tests__/config-schema.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
- package/src/__tests__/contacts-relay-reads.test.ts +15 -13
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +0 -134
- package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
- package/src/__tests__/conversation-history-web-search.test.ts +0 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
- package/src/__tests__/conversation-pairing.test.ts +0 -2
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
- package/src/__tests__/conversation-process-callsite.test.ts +0 -2
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
- package/src/__tests__/conversation-queue.test.ts +0 -91
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
- package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
- package/src/__tests__/conversation-slash-queue.test.ts +0 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
- package/src/__tests__/conversation-speed-override.test.ts +0 -2
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
- package/src/__tests__/conversation-title-service.test.ts +0 -2
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/db-migration-rollback.test.ts +171 -205
- package/src/__tests__/db-test-helpers.ts +4 -5
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
- package/src/__tests__/disk-pressure-guard.test.ts +0 -41
- package/src/__tests__/dm-persistence.test.ts +0 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
- package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
- package/src/__tests__/exploration-drift-hook.test.ts +2 -3
- package/src/__tests__/filing-service.test.ts +0 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
- package/src/__tests__/guardian-dispatch.test.ts +1 -95
- package/src/__tests__/guardian-outbound-http.test.ts +0 -13
- package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
- package/src/__tests__/heartbeat-service.test.ts +0 -2
- package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
- package/src/__tests__/host-app-control-routes.test.ts +30 -24
- package/src/__tests__/host-bash-routes.test.ts +41 -31
- package/src/__tests__/host-browser-routes.test.ts +32 -26
- package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
- package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
- package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
- package/src/__tests__/http-user-message-parity.test.ts +8 -290
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
- package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/invite-redemption-service.test.ts +0 -198
- package/src/__tests__/llm-context-normalization.test.ts +0 -105
- package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
- package/src/__tests__/llm-usage-store.test.ts +0 -25
- package/src/__tests__/mcp-health-check.test.ts +1 -2
- package/src/__tests__/media-stream-server-integration.test.ts +0 -127
- package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
- package/src/__tests__/messaging-send-tool.test.ts +0 -2
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +5 -146
- package/src/__tests__/native-web-search.test.ts +0 -2
- package/src/__tests__/non-member-access-request.test.ts +17 -189
- package/src/__tests__/notification-broadcaster.test.ts +0 -4
- package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
- package/src/__tests__/notification-deep-link.test.ts +0 -6
- package/src/__tests__/notification-guardian-path.test.ts +0 -19
- package/src/__tests__/openai-provider.test.ts +12 -22
- package/src/__tests__/openai-responses-provider.test.ts +2 -12
- package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
- package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
- package/src/__tests__/plugin-bootstrap.test.ts +73 -3
- package/src/__tests__/plugin-route-contribution.test.ts +17 -4
- package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
- package/src/__tests__/plugin-types.test.ts +2 -0
- package/src/__tests__/process-message-background-slack.test.ts +0 -2
- package/src/__tests__/process-message-display-content.test.ts +0 -2
- package/src/__tests__/provider-error-scenarios.test.ts +4 -5
- package/src/__tests__/provider-usage-tracking.test.ts +0 -39
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
- package/src/__tests__/registry.test.ts +1 -4
- package/src/__tests__/relay-server.test.ts +25 -694
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -14
- package/src/__tests__/send-endpoint-busy.test.ts +8 -30
- package/src/__tests__/skills.test.ts +0 -44
- package/src/__tests__/slack-inbound-verification.test.ts +2 -47
- package/src/__tests__/stt-hints.test.ts +13 -44
- package/src/__tests__/subagent-detail.test.ts +0 -27
- package/src/__tests__/subagent-disposal.test.ts +0 -65
- package/src/__tests__/subagent-notify-parent.test.ts +0 -2
- package/src/__tests__/subagent-role-registry.test.ts +2 -7
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
- package/src/__tests__/subagent-tools.test.ts +0 -2
- package/src/__tests__/suggestion-routes.test.ts +0 -2
- package/src/__tests__/title-generate-hook.test.ts +0 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
- package/src/__tests__/tool-executor.test.ts +11 -16
- package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
- package/src/__tests__/tool-start-timestamp.test.ts +0 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
- package/src/__tests__/twilio-routes.test.ts +0 -96
- package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +0 -33
- package/src/__tests__/web-search-backend-failure.test.ts +0 -2
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
- package/src/__tests__/workspace-tool-loader.test.ts +2 -195
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +0 -56
- package/src/api/index.ts +1 -19
- package/src/api/responses/llm-request-log-entry.ts +0 -29
- package/src/api/responses/subagent-detail.ts +0 -17
- package/src/api/surfaces.ts +3 -39
- package/src/approvals/guardian-request-resolvers.ts +11 -1
- package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +8 -10
- package/src/calls/inbound-trust-reader.ts +1 -17
- package/src/calls/media-stream-server.ts +0 -21
- package/src/calls/relay-server.ts +50 -167
- package/src/calls/relay-setup-router.ts +7 -37
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +12 -9
- package/src/calls/twilio-routes.ts +4 -14
- package/src/channels/types.ts +20 -10
- package/src/cli/commands/__tests__/cache.test.ts +1 -8
- package/src/cli/commands/cache.ts +181 -194
- package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
- package/src/cli/commands/db/status.ts +1 -37
- package/src/cli/commands/mcp.ts +218 -252
- package/src/cli/commands/memory/index.ts +0 -2
- package/src/cli/commands/plugins.ts +3 -75
- package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
- package/src/cli/lib/list-installed-plugins.ts +1 -179
- package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
- package/src/config/bundled-skills/subagent/SKILL.md +1 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +5 -38
- package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
- package/src/config/schemas/memory-lifecycle.ts +0 -12
- package/src/config/schemas/memory-v3.ts +0 -7
- package/src/config/schemas/memory.ts +0 -4
- package/src/config/schemas/timeouts.ts +0 -8
- package/src/config/seed-inference-profiles.ts +11 -21
- package/src/config/skills.ts +5 -27
- package/src/config/sync-gated-profiles.ts +13 -12
- package/src/contacts/contacts-write.ts +0 -3
- package/src/daemon/assistant-attachments.ts +4 -27
- package/src/daemon/conversation-agent-loop.ts +0 -28
- package/src/daemon/conversation-process.ts +16 -35
- package/src/daemon/conversation-surfaces.ts +38 -111
- package/src/daemon/conversation-tool-setup.ts +16 -50
- package/src/daemon/conversation.ts +1 -13
- package/src/daemon/disk-pressure-guard.ts +2 -12
- package/src/daemon/event-loop-watchdog.ts +1 -28
- package/src/daemon/external-plugins-bootstrap.ts +34 -4
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
- package/src/daemon/handlers/config-a2a.ts +14 -6
- package/src/daemon/handlers/config-channels.ts +22 -78
- package/src/daemon/handlers/conversations.ts +0 -77
- package/src/daemon/lifecycle.ts +0 -4
- package/src/daemon/mcp-reload-service.ts +0 -10
- package/src/daemon/memory-v2-startup.test.ts +0 -72
- package/src/daemon/memory-v2-startup.ts +19 -87
- package/src/daemon/message-types/conversations.ts +0 -2
- package/src/daemon/message-types/surfaces.ts +12 -12
- package/src/daemon/server.ts +4 -0
- package/src/daemon/shutdown-handlers.ts +0 -20
- package/src/daemon/tool-setup-types.ts +0 -9
- package/src/daemon/workspace-tools-watcher.ts +328 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/client.ts +1 -15
- package/src/mcp/mcp-auth-orchestrator.ts +1 -6
- package/src/mcp/mcp-oauth-provider.ts +8 -19
- package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
- package/src/memory/conversation-crud.ts +0 -38
- package/src/memory/db-connection.ts +3 -22
- package/src/memory/db-init.ts +502 -36
- package/src/memory/db-singleton.ts +4 -6
- package/src/memory/jobs-worker.ts +0 -58
- package/src/memory/llm-request-log-store.ts +1 -26
- package/src/memory/llm-usage-store.ts +20 -48
- package/src/memory/memory-retrospective-job.ts +8 -9
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/registry.ts +573 -0
- package/src/memory/migrations/run-migrations.ts +6 -90
- package/src/memory/migrations/validate-migration-state.ts +66 -101
- package/src/memory/schema/conversations.ts +0 -9
- package/src/memory/schema/infrastructure.ts +0 -20
- package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
- package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
- package/src/memory/v2/cli-command-store.ts +38 -75
- package/src/memory/v2/prompts/consolidation.ts +82 -13
- package/src/memory/v2/prompts/router.ts +93 -21
- package/src/memory/v2/skill-store.ts +31 -68
- package/src/notifications/__tests__/broadcaster.test.ts +8 -16
- package/src/notifications/__tests__/decision-engine.test.ts +9 -78
- package/src/notifications/broadcaster.ts +1 -8
- package/src/notifications/decision-engine.ts +7 -15
- package/src/notifications/destination-resolver.ts +24 -68
- package/src/notifications/emit-signal.ts +14 -39
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +4 -7
- package/src/plugin-api/index.ts +6 -6
- package/src/plugin-api/types.ts +5 -3
- package/src/plugin-api/vision-support.test.ts +4 -28
- package/src/plugin-api/vision-support.ts +31 -66
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
- package/src/plugins/defaults/advisor/consult.ts +6 -110
- package/src/plugins/defaults/advisor/steering.ts +2 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
- package/src/plugins/mtime-cache.ts +291 -76
- package/src/plugins/pipeline.ts +13 -111
- package/src/plugins/types.ts +2 -0
- package/src/providers/anthropic/client.ts +0 -5
- package/src/providers/call-site-routing.ts +0 -4
- package/src/providers/model-catalog.ts +0 -16
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/chat-completions-provider.ts +83 -37
- package/src/providers/openai/responses-provider.ts +46 -50
- package/src/providers/openrouter/client.ts +0 -5
- package/src/providers/provider-send-message.ts +0 -4
- package/src/providers/ratelimit.ts +0 -4
- package/src/providers/retry.ts +0 -4
- package/src/providers/types.ts +0 -9
- package/src/providers/usage-tracking.ts +0 -4
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
- package/src/runtime/access-request-helper.ts +39 -19
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +2 -9
- package/src/runtime/auth/require-bound-guardian.ts +11 -21
- package/src/runtime/channel-verification-service.ts +31 -56
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +7 -66
- package/src/runtime/invite-redemption-service.ts +187 -198
- package/src/runtime/local-actor-identity.ts +11 -76
- package/src/runtime/pending-interactions.ts +1 -11
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +32 -8
- package/src/runtime/routes/conversation-cli-routes.ts +5 -4
- package/src/runtime/routes/conversation-list-routes.ts +7 -4
- package/src/runtime/routes/conversation-query-routes.ts +0 -72
- package/src/runtime/routes/conversation-routes.ts +85 -84
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -3
- package/src/runtime/routes/guardian-action-routes.ts +5 -4
- package/src/runtime/routes/host-app-control-routes.ts +4 -5
- package/src/runtime/routes/host-bash-routes.ts +4 -5
- package/src/runtime/routes/host-browser-routes.ts +11 -9
- package/src/runtime/routes/host-cu-routes.ts +4 -5
- package/src/runtime/routes/host-file-routes.ts +4 -5
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +2 -3
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
- package/src/runtime/routes/index.ts +0 -2
- package/src/runtime/routes/llm-context-normalization.ts +0 -83
- package/src/runtime/routes/mcp-auth-routes.ts +19 -171
- package/src/runtime/routes/migration-rollback-routes.ts +3 -4
- package/src/runtime/routes/migration-routes.ts +1 -4
- package/src/runtime/routes/subagents-routes.ts +0 -5
- package/src/runtime/routes/surface-action-routes.ts +56 -42
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
- package/src/runtime/services/conversation-serializer.ts +9 -7
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +9 -85
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +0 -16
- package/src/subagent/manager.ts +0 -9
- package/src/subagent/types.ts +3 -3
- package/src/telemetry/types.ts +1 -34
- package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
- package/src/telemetry/usage-telemetry-reporter.ts +3 -87
- package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
- package/src/tools/ask-question/ask-question-tool.ts +0 -13
- package/src/tools/executor.ts +4 -4
- package/src/tools/registry.ts +0 -18
- package/src/tools/shared/filesystem/path-policy.ts +5 -12
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +2 -9
- package/src/tools/tool-manifest.ts +0 -3
- package/src/tools/types.ts +2 -17
- package/src/tools/workspace-tools/loader.ts +244 -348
- package/src/util/errors.ts +1 -26
- package/src/util/platform.ts +0 -5
- package/src/workflows/library.test.ts +0 -140
- package/src/workflows/library.ts +28 -82
- package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
- package/src/workspace/migrations/registry.ts +0 -2
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
- package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
- package/src/__tests__/code-search-tool.test.ts +0 -585
- package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
- package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
- package/src/__tests__/plugin-pipeline.test.ts +0 -96
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
- package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
- package/src/agent/loop-exclusive-tool.test.ts +0 -150
- package/src/api/constants/sse-replay.ts +0 -41
- package/src/api/events/conversation-notice.ts +0 -26
- package/src/approvals/guardian-channel-delivery.ts +0 -30
- package/src/approvals/guardian-expiry-notifier.ts +0 -148
- package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
- package/src/cli/commands/memory/worker.ts +0 -175
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
- package/src/config/prune-seeded-callsite-defaults.ts +0 -110
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
- package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
- package/src/contacts/guardian-delivery-reader.ts +0 -223
- package/src/contacts/member-write-relay.ts +0 -189
- package/src/daemon/conversation-notices.ts +0 -60
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
- package/src/hooks/hook-loader.ts +0 -341
- package/src/mcp/mcp-header-store.ts +0 -134
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
- package/src/memory/__tests__/prompt-override.test.ts +0 -192
- package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
- package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
- package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
- package/src/memory/prompt-override.ts +0 -129
- package/src/memory/steps.ts +0 -573
- package/src/memory/watchdog-events-store.ts +0 -87
- package/src/memory/worker-control.ts +0 -118
- package/src/memory/worker-process.ts +0 -72
- package/src/notifications/__tests__/connected-channels.test.ts +0 -114
- package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
- package/src/onboarding/checkin-event.test.ts +0 -222
- package/src/onboarding/checkin-event.ts +0 -321
- package/src/onboarding/schedule-checkin.ts +0 -190
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
- package/src/plugins/defaults/advisor/context-pack.ts +0 -288
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
- package/src/plugins/surface-import.ts +0 -121
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
- package/src/providers/openai/api-error-normalization.ts +0 -270
- package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
- package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
- package/src/runtime/anchored-guardian.test.ts +0 -156
- package/src/runtime/anchored-guardian.ts +0 -135
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
- package/src/runtime/local-principal-trust.ts +0 -52
- package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
- package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
- package/src/tools/filesystem/search.ts +0 -543
- package/src/util/telemetry-db-path.ts +0 -24
- package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
|
@@ -95,7 +95,7 @@ afterAll(() => {
|
|
|
95
95
|
|
|
96
96
|
const handleHostBashResult = ROUTES.find(
|
|
97
97
|
(r) => r.endpoint === "host-bash-result",
|
|
98
|
-
)!.handler
|
|
98
|
+
)!.handler;
|
|
99
99
|
|
|
100
100
|
// ── Helpers ──────────────────────────────────────────────────────────
|
|
101
101
|
|
|
@@ -244,20 +244,22 @@ describe("handleHostBashResult", () => {
|
|
|
244
244
|
).toThrow(ForbiddenError);
|
|
245
245
|
});
|
|
246
246
|
|
|
247
|
-
test("interaction is NOT resolved on cross-actor 403 (still pending)",
|
|
247
|
+
test("interaction is NOT resolved on cross-actor 403 (still pending)", () => {
|
|
248
248
|
const requestId = "req-actor-mismatch-stays";
|
|
249
249
|
clientActorPrincipals.set("client-abc", "principal-victim");
|
|
250
250
|
registerPending(requestId, { targetClientId: "client-abc" });
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
252
|
+
try {
|
|
253
|
+
handleHostBashResult({
|
|
254
|
+
body: bashBody(requestId),
|
|
255
|
+
headers: {
|
|
256
|
+
"x-vellum-client-id": "client-abc",
|
|
257
|
+
"x-vellum-actor-principal-id": "principal-attacker",
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
} catch {
|
|
259
261
|
// expected
|
|
260
|
-
}
|
|
262
|
+
}
|
|
261
263
|
|
|
262
264
|
expect(resolvedIds).not.toContain(requestId);
|
|
263
265
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -276,17 +278,19 @@ describe("handleHostBashResult", () => {
|
|
|
276
278
|
).toThrow(ForbiddenError);
|
|
277
279
|
});
|
|
278
280
|
|
|
279
|
-
test("interaction is NOT resolved when submitting actor is missing (still pending)",
|
|
281
|
+
test("interaction is NOT resolved when submitting actor is missing (still pending)", () => {
|
|
280
282
|
const requestId = "req-actor-missing-stays";
|
|
281
283
|
clientActorPrincipals.set("client-abc", "principal-victim");
|
|
282
284
|
registerPending(requestId, { targetClientId: "client-abc" });
|
|
283
285
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
286
|
+
try {
|
|
287
|
+
handleHostBashResult({
|
|
288
|
+
body: bashBody(requestId),
|
|
289
|
+
headers: { "x-vellum-client-id": "client-abc" },
|
|
290
|
+
});
|
|
291
|
+
} catch {
|
|
288
292
|
// expected
|
|
289
|
-
}
|
|
293
|
+
}
|
|
290
294
|
|
|
291
295
|
expect(resolvedIds).not.toContain(requestId);
|
|
292
296
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -354,13 +358,15 @@ describe("handleHostBashResult", () => {
|
|
|
354
358
|
).toThrow(BadRequestError);
|
|
355
359
|
});
|
|
356
360
|
|
|
357
|
-
test("interaction is NOT resolved on 400 (still pending)",
|
|
361
|
+
test("interaction is NOT resolved on 400 (still pending)", () => {
|
|
358
362
|
const requestId = "req-targeted-no-header-stays";
|
|
359
363
|
registerPending(requestId, { targetClientId: "client-abc" });
|
|
360
364
|
|
|
361
|
-
|
|
365
|
+
try {
|
|
366
|
+
handleHostBashResult({ body: bashBody(requestId) });
|
|
367
|
+
} catch {
|
|
362
368
|
// expected
|
|
363
|
-
}
|
|
369
|
+
}
|
|
364
370
|
|
|
365
371
|
expect(resolvedIds).not.toContain(requestId);
|
|
366
372
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -382,17 +388,19 @@ describe("handleHostBashResult", () => {
|
|
|
382
388
|
).toThrow(ForbiddenError);
|
|
383
389
|
});
|
|
384
390
|
|
|
385
|
-
test("ForbiddenError message names both the submitting and expected client",
|
|
391
|
+
test("ForbiddenError message names both the submitting and expected client", () => {
|
|
386
392
|
const requestId = "req-targeted-mismatch-msg";
|
|
387
393
|
registerPending(requestId, { targetClientId: "client-abc" });
|
|
388
394
|
|
|
389
395
|
let caught: unknown;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
396
|
+
try {
|
|
397
|
+
handleHostBashResult({
|
|
398
|
+
body: bashBody(requestId),
|
|
399
|
+
headers: { "x-vellum-client-id": "client-xyz" },
|
|
400
|
+
});
|
|
401
|
+
} catch (e) {
|
|
394
402
|
caught = e;
|
|
395
|
-
}
|
|
403
|
+
}
|
|
396
404
|
|
|
397
405
|
expect(caught).toBeInstanceOf(ForbiddenError);
|
|
398
406
|
const msg = (caught as ForbiddenError).message;
|
|
@@ -400,16 +408,18 @@ describe("handleHostBashResult", () => {
|
|
|
400
408
|
expect(msg).toContain("client-abc");
|
|
401
409
|
});
|
|
402
410
|
|
|
403
|
-
test("interaction is NOT resolved on 403 (still pending)",
|
|
411
|
+
test("interaction is NOT resolved on 403 (still pending)", () => {
|
|
404
412
|
const requestId = "req-targeted-mismatch-stays";
|
|
405
413
|
registerPending(requestId, { targetClientId: "client-abc" });
|
|
406
414
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
415
|
+
try {
|
|
416
|
+
handleHostBashResult({
|
|
417
|
+
body: bashBody(requestId),
|
|
418
|
+
headers: { "x-vellum-client-id": "client-xyz" },
|
|
419
|
+
});
|
|
420
|
+
} catch {
|
|
411
421
|
// expected
|
|
412
|
-
}
|
|
422
|
+
}
|
|
413
423
|
|
|
414
424
|
expect(resolvedIds).not.toContain(requestId);
|
|
415
425
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -39,7 +39,7 @@ afterAll(() => {
|
|
|
39
39
|
|
|
40
40
|
const handleHostBrowserResult = ROUTES.find(
|
|
41
41
|
(r) => r.endpoint === "host-browser-result",
|
|
42
|
-
)!.handler
|
|
42
|
+
)!.handler;
|
|
43
43
|
|
|
44
44
|
// ── Tests ────────────────────────────────────────────────────────────
|
|
45
45
|
|
|
@@ -212,7 +212,7 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
212
212
|
).toThrow(BadRequestError);
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
-
test("interaction is NOT consumed on 400 (still pending)",
|
|
215
|
+
test("interaction is NOT consumed on 400 (still pending)", () => {
|
|
216
216
|
const requestId = "browser-req-targeted-no-header-stays";
|
|
217
217
|
pendingInteractions.register(requestId, {
|
|
218
218
|
conversationId: "conv-1",
|
|
@@ -221,11 +221,13 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
221
221
|
targetActorPrincipalId: "user-1",
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
try {
|
|
225
|
+
handleHostBrowserResult({
|
|
226
|
+
body: { requestId, content: "ok", isError: false },
|
|
227
|
+
});
|
|
228
|
+
} catch {
|
|
227
229
|
// expected
|
|
228
|
-
}
|
|
230
|
+
}
|
|
229
231
|
|
|
230
232
|
expect(pendingInteractions.get(requestId)).toBeDefined();
|
|
231
233
|
});
|
|
@@ -254,7 +256,7 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
254
256
|
).toThrow(ForbiddenError);
|
|
255
257
|
});
|
|
256
258
|
|
|
257
|
-
test("ForbiddenError message names both submitting and expected client",
|
|
259
|
+
test("ForbiddenError message names both submitting and expected client", () => {
|
|
258
260
|
const requestId = "browser-req-targeted-mismatch-msg";
|
|
259
261
|
pendingInteractions.register(requestId, {
|
|
260
262
|
conversationId: "conv-1",
|
|
@@ -265,7 +267,7 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
265
267
|
|
|
266
268
|
let caught: unknown;
|
|
267
269
|
try {
|
|
268
|
-
|
|
270
|
+
handleHostBrowserResult({
|
|
269
271
|
body: { requestId, content: "ok", isError: false },
|
|
270
272
|
headers: {
|
|
271
273
|
"x-vellum-client-id": "client-B",
|
|
@@ -282,7 +284,7 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
282
284
|
expect(msg).toContain("client-B");
|
|
283
285
|
});
|
|
284
286
|
|
|
285
|
-
test("interaction is NOT consumed on 403 (still pending)",
|
|
287
|
+
test("interaction is NOT consumed on 403 (still pending)", () => {
|
|
286
288
|
const requestId = "browser-req-targeted-mismatch-stays";
|
|
287
289
|
pendingInteractions.register(requestId, {
|
|
288
290
|
conversationId: "conv-1",
|
|
@@ -291,15 +293,17 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
291
293
|
targetActorPrincipalId: "user-1",
|
|
292
294
|
});
|
|
293
295
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
296
|
+
try {
|
|
297
|
+
handleHostBrowserResult({
|
|
298
|
+
body: { requestId, content: "ok", isError: false },
|
|
299
|
+
headers: {
|
|
300
|
+
"x-vellum-client-id": "client-B",
|
|
301
|
+
"x-vellum-actor-principal-id": "user-1",
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
} catch {
|
|
301
305
|
// expected
|
|
302
|
-
}
|
|
306
|
+
}
|
|
303
307
|
|
|
304
308
|
expect(pendingInteractions.get(requestId)).toBeDefined();
|
|
305
309
|
});
|
|
@@ -365,7 +369,7 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
365
369
|
).toThrow(ForbiddenError);
|
|
366
370
|
});
|
|
367
371
|
|
|
368
|
-
test("interaction NOT consumed on actor-mismatch 403",
|
|
372
|
+
test("interaction NOT consumed on actor-mismatch 403", () => {
|
|
369
373
|
const requestId = "browser-req-actor-mismatch-stays";
|
|
370
374
|
pendingInteractions.register(requestId, {
|
|
371
375
|
conversationId: "conv-1",
|
|
@@ -374,15 +378,17 @@ describe("handleHostBrowserResult — same-actor guard", () => {
|
|
|
374
378
|
targetActorPrincipalId: "user-1",
|
|
375
379
|
});
|
|
376
380
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
381
|
+
try {
|
|
382
|
+
handleHostBrowserResult({
|
|
383
|
+
body: { requestId, content: "ok", isError: false },
|
|
384
|
+
headers: {
|
|
385
|
+
"x-vellum-client-id": "client-A",
|
|
386
|
+
"x-vellum-actor-principal-id": "user-2",
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
} catch {
|
|
384
390
|
// expected
|
|
385
|
-
}
|
|
391
|
+
}
|
|
386
392
|
|
|
387
393
|
expect(pendingInteractions.get(requestId)).toBeDefined();
|
|
388
394
|
});
|
|
@@ -104,7 +104,7 @@ afterAll(() => {
|
|
|
104
104
|
|
|
105
105
|
const handleHostCuResult = ROUTES.find(
|
|
106
106
|
(r: { endpoint: string }) => r.endpoint === "host-cu-result",
|
|
107
|
-
)!.handler
|
|
107
|
+
)!.handler;
|
|
108
108
|
|
|
109
109
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
110
110
|
|
|
@@ -226,13 +226,15 @@ describe("handleHostCuResult — Phase 2 targetClientId guard", () => {
|
|
|
226
226
|
).toThrow(BadRequestError);
|
|
227
227
|
});
|
|
228
228
|
|
|
229
|
-
test("interaction is NOT resolved on 400 (still pending)",
|
|
229
|
+
test("interaction is NOT resolved on 400 (still pending)", () => {
|
|
230
230
|
const requestId = "req-cu-targeted-no-header-stays";
|
|
231
231
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
232
232
|
|
|
233
|
-
|
|
233
|
+
try {
|
|
234
|
+
handleHostCuResult({ body: cuBody(requestId) });
|
|
235
|
+
} catch {
|
|
234
236
|
// expected
|
|
235
|
-
}
|
|
237
|
+
}
|
|
236
238
|
|
|
237
239
|
expect(resolvedIds).not.toContain(requestId);
|
|
238
240
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -254,17 +256,19 @@ describe("handleHostCuResult — Phase 2 targetClientId guard", () => {
|
|
|
254
256
|
).toThrow(ForbiddenError);
|
|
255
257
|
});
|
|
256
258
|
|
|
257
|
-
test("ForbiddenError message names both submitting and expected client",
|
|
259
|
+
test("ForbiddenError message names both submitting and expected client", () => {
|
|
258
260
|
const requestId = "req-cu-targeted-mismatch-msg";
|
|
259
261
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
260
262
|
|
|
261
263
|
let caught: unknown;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
try {
|
|
265
|
+
handleHostCuResult({
|
|
266
|
+
body: cuBody(requestId),
|
|
267
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
268
|
+
});
|
|
269
|
+
} catch (e) {
|
|
266
270
|
caught = e;
|
|
267
|
-
}
|
|
271
|
+
}
|
|
268
272
|
|
|
269
273
|
expect(caught).toBeInstanceOf(ForbiddenError);
|
|
270
274
|
const msg = (caught as ForbiddenError).message;
|
|
@@ -272,16 +276,18 @@ describe("handleHostCuResult — Phase 2 targetClientId guard", () => {
|
|
|
272
276
|
expect(msg).toContain("client-A");
|
|
273
277
|
});
|
|
274
278
|
|
|
275
|
-
test("interaction is NOT consumed on 403 (pendingInteractions.get still returns it)",
|
|
279
|
+
test("interaction is NOT consumed on 403 (pendingInteractions.get still returns it)", () => {
|
|
276
280
|
const requestId = "req-cu-targeted-mismatch-stays";
|
|
277
281
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
278
282
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
+
try {
|
|
284
|
+
handleHostCuResult({
|
|
285
|
+
body: cuBody(requestId),
|
|
286
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
287
|
+
});
|
|
288
|
+
} catch {
|
|
283
289
|
// expected
|
|
284
|
-
}
|
|
290
|
+
}
|
|
285
291
|
|
|
286
292
|
expect(resolvedIds).not.toContain(requestId);
|
|
287
293
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -325,20 +331,22 @@ describe("handleHostCuResult — Phase 2 targetClientId guard", () => {
|
|
|
325
331
|
).toThrow(ForbiddenError);
|
|
326
332
|
});
|
|
327
333
|
|
|
328
|
-
test("interaction NOT consumed on 403 actor mismatch",
|
|
334
|
+
test("interaction NOT consumed on 403 actor mismatch", () => {
|
|
329
335
|
const requestId = "req-cu-actor-mismatch-stays";
|
|
330
336
|
actorPrincipalByClient.set("client-A", "user-1");
|
|
331
337
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
332
338
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
try {
|
|
340
|
+
handleHostCuResult({
|
|
341
|
+
body: cuBody(requestId),
|
|
342
|
+
headers: {
|
|
343
|
+
"x-vellum-client-id": "client-A",
|
|
344
|
+
"x-vellum-actor-principal-id": "user-2",
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
} catch {
|
|
340
348
|
// expected
|
|
341
|
-
}
|
|
349
|
+
}
|
|
342
350
|
|
|
343
351
|
expect(resolvedIds).not.toContain(requestId);
|
|
344
352
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -87,7 +87,7 @@ afterAll(() => {
|
|
|
87
87
|
|
|
88
88
|
const handleHostFileResult = ROUTES.find(
|
|
89
89
|
(r) => r.endpoint === "host-file-result",
|
|
90
|
-
)!.handler
|
|
90
|
+
)!.handler;
|
|
91
91
|
|
|
92
92
|
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
93
93
|
|
|
@@ -189,13 +189,15 @@ describe("handleHostFileResult — targetClientId guard", () => {
|
|
|
189
189
|
).toThrow(BadRequestError);
|
|
190
190
|
});
|
|
191
191
|
|
|
192
|
-
test("interaction is NOT resolved on 400 (still pending)",
|
|
192
|
+
test("interaction is NOT resolved on 400 (still pending)", () => {
|
|
193
193
|
const requestId = "req-file-targeted-no-header-stays";
|
|
194
194
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
try {
|
|
197
|
+
handleHostFileResult({ body: fileBody(requestId) });
|
|
198
|
+
} catch {
|
|
197
199
|
// expected
|
|
198
|
-
}
|
|
200
|
+
}
|
|
199
201
|
|
|
200
202
|
expect(resolvedIds).not.toContain(requestId);
|
|
201
203
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -217,17 +219,19 @@ describe("handleHostFileResult — targetClientId guard", () => {
|
|
|
217
219
|
).toThrow(ForbiddenError);
|
|
218
220
|
});
|
|
219
221
|
|
|
220
|
-
test("ForbiddenError message names both submitting and expected client",
|
|
222
|
+
test("ForbiddenError message names both submitting and expected client", () => {
|
|
221
223
|
const requestId = "req-file-targeted-mismatch-msg";
|
|
222
224
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
223
225
|
|
|
224
226
|
let caught: unknown;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
try {
|
|
228
|
+
handleHostFileResult({
|
|
229
|
+
body: fileBody(requestId),
|
|
230
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
231
|
+
});
|
|
232
|
+
} catch (e) {
|
|
229
233
|
caught = e;
|
|
230
|
-
}
|
|
234
|
+
}
|
|
231
235
|
|
|
232
236
|
expect(caught).toBeInstanceOf(ForbiddenError);
|
|
233
237
|
const msg = (caught as ForbiddenError).message;
|
|
@@ -235,16 +239,18 @@ describe("handleHostFileResult — targetClientId guard", () => {
|
|
|
235
239
|
expect(msg).toContain("client-A");
|
|
236
240
|
});
|
|
237
241
|
|
|
238
|
-
test("interaction is NOT consumed on 403 (pendingInteractions.get still returns it)",
|
|
242
|
+
test("interaction is NOT consumed on 403 (pendingInteractions.get still returns it)", () => {
|
|
239
243
|
const requestId = "req-file-targeted-mismatch-stays";
|
|
240
244
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
241
245
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
try {
|
|
247
|
+
handleHostFileResult({
|
|
248
|
+
body: fileBody(requestId),
|
|
249
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
250
|
+
});
|
|
251
|
+
} catch {
|
|
246
252
|
// expected
|
|
247
|
-
}
|
|
253
|
+
}
|
|
248
254
|
|
|
249
255
|
expect(resolvedIds).not.toContain(requestId);
|
|
250
256
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -300,20 +306,22 @@ describe("handleHostFileResult — targetClientId guard", () => {
|
|
|
300
306
|
).toThrow(ForbiddenError);
|
|
301
307
|
});
|
|
302
308
|
|
|
303
|
-
test("interaction is NOT consumed on actor-mismatch 403",
|
|
309
|
+
test("interaction is NOT consumed on actor-mismatch 403", () => {
|
|
304
310
|
const requestId = "req-file-actor-mismatch-stays";
|
|
305
311
|
clientActors.set("client-A", "actor-1");
|
|
306
312
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
307
313
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
314
|
+
try {
|
|
315
|
+
handleHostFileResult({
|
|
316
|
+
body: fileBody(requestId),
|
|
317
|
+
headers: {
|
|
318
|
+
"x-vellum-client-id": "client-A",
|
|
319
|
+
"x-vellum-actor-principal-id": "actor-2",
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
} catch {
|
|
315
323
|
// expected
|
|
316
|
-
}
|
|
324
|
+
}
|
|
317
325
|
|
|
318
326
|
expect(resolvedIds).not.toContain(requestId);
|
|
319
327
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -352,17 +360,19 @@ describe("handleHostFileResult — targetClientId guard", () => {
|
|
|
352
360
|
).toThrow(ForbiddenError);
|
|
353
361
|
});
|
|
354
362
|
|
|
355
|
-
test("interaction is NOT consumed when submitting actor is missing",
|
|
363
|
+
test("interaction is NOT consumed when submitting actor is missing", () => {
|
|
356
364
|
const requestId = "req-file-actor-missing-stays";
|
|
357
365
|
clientActors.set("client-A", "actor-1");
|
|
358
366
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
359
367
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
368
|
+
try {
|
|
369
|
+
handleHostFileResult({
|
|
370
|
+
body: fileBody(requestId),
|
|
371
|
+
headers: { "x-vellum-client-id": "client-A" },
|
|
372
|
+
});
|
|
373
|
+
} catch {
|
|
364
374
|
// expected
|
|
365
|
-
}
|
|
375
|
+
}
|
|
366
376
|
|
|
367
377
|
expect(resolvedIds).not.toContain(requestId);
|
|
368
378
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -388,19 +398,21 @@ describe("handleHostFileResult — targetClientId guard", () => {
|
|
|
388
398
|
).toThrow(ForbiddenError);
|
|
389
399
|
});
|
|
390
400
|
|
|
391
|
-
test("interaction is NOT consumed when target client has no stored actor",
|
|
401
|
+
test("interaction is NOT consumed when target client has no stored actor", () => {
|
|
392
402
|
const requestId = "req-file-target-no-actor-stays";
|
|
393
403
|
registerPending(requestId, { targetClientId: "client-A" });
|
|
394
404
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
405
|
+
try {
|
|
406
|
+
handleHostFileResult({
|
|
407
|
+
body: fileBody(requestId),
|
|
408
|
+
headers: {
|
|
409
|
+
"x-vellum-client-id": "client-A",
|
|
410
|
+
"x-vellum-actor-principal-id": "actor-1",
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
} catch {
|
|
402
414
|
// expected
|
|
403
|
-
}
|
|
415
|
+
}
|
|
404
416
|
|
|
405
417
|
expect(resolvedIds).not.toContain(requestId);
|
|
406
418
|
expect(pendingStore.has(requestId)).toBe(true);
|
|
@@ -99,7 +99,7 @@ afterAll(() => {
|
|
|
99
99
|
|
|
100
100
|
const handleTransferContentGet = ROUTES.find(
|
|
101
101
|
(r) => r.endpoint === "transfers/:transferId/content" && r.method === "GET",
|
|
102
|
-
)!.handler
|
|
102
|
+
)!.handler;
|
|
103
103
|
|
|
104
104
|
const handleTransferContentPut = ROUTES.find(
|
|
105
105
|
(r) => r.endpoint === "transfers/:transferId/content" && r.method === "PUT",
|
|
@@ -107,7 +107,7 @@ const handleTransferContentPut = ROUTES.find(
|
|
|
107
107
|
|
|
108
108
|
const handleTransferResult = ROUTES.find(
|
|
109
109
|
(r) => r.endpoint === "host-transfer-result",
|
|
110
|
-
)!.handler
|
|
110
|
+
)!.handler;
|
|
111
111
|
|
|
112
112
|
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
113
113
|
|
|
@@ -186,13 +186,15 @@ describe("handleTransferContentGet — Phase 3 targetClientId guard", () => {
|
|
|
186
186
|
).toThrow(BadRequestError);
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
-
test("getTransferContent NOT called on 400",
|
|
189
|
+
test("getTransferContent NOT called on 400", () => {
|
|
190
190
|
stubTargetClientId = "client-A";
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
try {
|
|
192
|
+
handleTransferContentGet({
|
|
193
|
+
pathParams: { transferId: TEST_TRANSFER_ID },
|
|
194
|
+
});
|
|
195
|
+
} catch {
|
|
194
196
|
// expected
|
|
195
|
-
}
|
|
197
|
+
}
|
|
196
198
|
expect(getTransferContentCalls).toHaveLength(0);
|
|
197
199
|
});
|
|
198
200
|
});
|
|
@@ -210,14 +212,16 @@ describe("handleTransferContentGet — Phase 3 targetClientId guard", () => {
|
|
|
210
212
|
).toThrow(ForbiddenError);
|
|
211
213
|
});
|
|
212
214
|
|
|
213
|
-
test("getTransferContent NOT called on 403",
|
|
215
|
+
test("getTransferContent NOT called on 403", () => {
|
|
214
216
|
stubTargetClientId = "client-A";
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
try {
|
|
218
|
+
handleTransferContentGet({
|
|
219
|
+
pathParams: { transferId: TEST_TRANSFER_ID },
|
|
220
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
221
|
+
});
|
|
222
|
+
} catch {
|
|
219
223
|
// expected
|
|
220
|
-
}
|
|
224
|
+
}
|
|
221
225
|
expect(getTransferContentCalls).toHaveLength(0);
|
|
222
226
|
});
|
|
223
227
|
});
|
|
@@ -522,19 +526,23 @@ describe("handleTransferResult — Phase 3 targetClientId guard", () => {
|
|
|
522
526
|
);
|
|
523
527
|
});
|
|
524
528
|
|
|
525
|
-
test("resolveTransferResult NOT called on 400",
|
|
529
|
+
test("resolveTransferResult NOT called on 400", () => {
|
|
526
530
|
registerHostTransferPending("client-A");
|
|
527
|
-
|
|
531
|
+
try {
|
|
532
|
+
handleTransferResult({ body: resultBody() });
|
|
533
|
+
} catch {
|
|
528
534
|
// expected
|
|
529
|
-
}
|
|
535
|
+
}
|
|
530
536
|
expect(resolveTransferResultCalls).toHaveLength(0);
|
|
531
537
|
});
|
|
532
538
|
|
|
533
|
-
test("pending interaction still present after 400",
|
|
539
|
+
test("pending interaction still present after 400", () => {
|
|
534
540
|
registerHostTransferPending("client-A");
|
|
535
|
-
|
|
541
|
+
try {
|
|
542
|
+
handleTransferResult({ body: resultBody() });
|
|
543
|
+
} catch {
|
|
536
544
|
// expected
|
|
537
|
-
}
|
|
545
|
+
}
|
|
538
546
|
expect(pendingStore.has(TEST_REQUEST_ID)).toBe(true);
|
|
539
547
|
});
|
|
540
548
|
});
|
|
@@ -552,25 +560,29 @@ describe("handleTransferResult — Phase 3 targetClientId guard", () => {
|
|
|
552
560
|
).toThrow(ForbiddenError);
|
|
553
561
|
});
|
|
554
562
|
|
|
555
|
-
test("resolveTransferResult NOT called on 403",
|
|
563
|
+
test("resolveTransferResult NOT called on 403", () => {
|
|
556
564
|
registerHostTransferPending("client-A");
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
565
|
+
try {
|
|
566
|
+
handleTransferResult({
|
|
567
|
+
body: resultBody(),
|
|
568
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
569
|
+
});
|
|
570
|
+
} catch {
|
|
561
571
|
// expected
|
|
562
|
-
}
|
|
572
|
+
}
|
|
563
573
|
expect(resolveTransferResultCalls).toHaveLength(0);
|
|
564
574
|
});
|
|
565
575
|
|
|
566
|
-
test("pending interaction still present after 403",
|
|
576
|
+
test("pending interaction still present after 403", () => {
|
|
567
577
|
registerHostTransferPending("client-A");
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
578
|
+
try {
|
|
579
|
+
handleTransferResult({
|
|
580
|
+
body: resultBody(),
|
|
581
|
+
headers: { "x-vellum-client-id": "client-B" },
|
|
582
|
+
});
|
|
583
|
+
} catch {
|
|
572
584
|
// expected
|
|
573
|
-
}
|
|
585
|
+
}
|
|
574
586
|
expect(pendingStore.has(TEST_REQUEST_ID)).toBe(true);
|
|
575
587
|
});
|
|
576
588
|
});
|