@vellumai/assistant 0.8.10 → 0.8.11-staging.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/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +2 -1
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the workspace tool loader (workspace-tools/loader.ts).
|
|
3
|
+
*
|
|
4
|
+
* Each test gets its own per-pid+timestamp+counter tempdir so ESM import
|
|
5
|
+
* caching cannot bleed between cases — bun caches dynamic-imported modules
|
|
6
|
+
* by absolute URL, so two tests cannot reuse the same `<name>.ts` path and
|
|
7
|
+
* still see fresh module evaluation.
|
|
8
|
+
*
|
|
9
|
+
* `VELLUM_WORKSPACE_DIR` is rewritten before each test so
|
|
10
|
+
* `getWorkspaceToolsDir()` walks the isolated tree.
|
|
11
|
+
*
|
|
12
|
+
* Covers:
|
|
13
|
+
* - Loading a well-formed workspace tool from `<name>.ts` adds a net-new entry.
|
|
14
|
+
* - Loading a workspace tool whose name matches a core tool overrides it
|
|
15
|
+
* and stashes the original.
|
|
16
|
+
* - `<name>.js` wins over `<name>.ts` (compiled-binary semantics) and the
|
|
17
|
+
* ignored extension is logged at warn.
|
|
18
|
+
* - `<name>.json` loads as a declarative spec — execute defaults to an
|
|
19
|
+
* error result since JSON has no function type.
|
|
20
|
+
* - `<name>.removed` strips a same-named core tool from the registry
|
|
21
|
+
* without substituting a replacement; restoring the file restores the
|
|
22
|
+
* core tool on next scan.
|
|
23
|
+
* - A file whose import throws is logged + skipped without crashing.
|
|
24
|
+
* - A missing `<workspaceDir>/tools/` directory is a no-op.
|
|
25
|
+
* - A filename stem that fails `isProviderSafeToolName` is logged at error
|
|
26
|
+
* and skipped (no silent provider-safe rewrite — operator must rename).
|
|
27
|
+
* - Multiple workspace tools register in a single batch.
|
|
28
|
+
*/
|
|
29
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
30
|
+
import { tmpdir } from "node:os";
|
|
31
|
+
import { join } from "node:path";
|
|
32
|
+
import { afterAll, beforeEach, describe, expect, test } from "bun:test";
|
|
33
|
+
|
|
34
|
+
import { RiskLevel } from "../permissions/types.js";
|
|
35
|
+
import {
|
|
36
|
+
__clearRegistryForTesting,
|
|
37
|
+
getCoreToolOverride,
|
|
38
|
+
getStrippedCoreToolNames,
|
|
39
|
+
getTool,
|
|
40
|
+
getToolOwner,
|
|
41
|
+
getWorkspaceToolNames,
|
|
42
|
+
registerTool,
|
|
43
|
+
} from "../tools/registry.js";
|
|
44
|
+
import type { Tool, ToolContext, ToolExecutionResult } from "../tools/types.js";
|
|
45
|
+
import { loadWorkspaceTools } from "../tools/workspace-tools/loader.js";
|
|
46
|
+
|
|
47
|
+
// Per-test counter so each writeTool() call lands in a unique tempdir,
|
|
48
|
+
// defeating bun's per-URL ESM cache between tests. Without this, a
|
|
49
|
+
// second test that writes the same tool name would reuse the first
|
|
50
|
+
// test's already-evaluated module body.
|
|
51
|
+
let testCaseCounter = 0;
|
|
52
|
+
let currentWorkspaceDir: string;
|
|
53
|
+
const TEST_BASE_DIR = join(
|
|
54
|
+
tmpdir(),
|
|
55
|
+
`vellum-workspace-tool-loader-test-${process.pid}-${Date.now()}`,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
function freshWorkspace(): string {
|
|
59
|
+
testCaseCounter += 1;
|
|
60
|
+
const dir = join(TEST_BASE_DIR, `case-${testCaseCounter}`);
|
|
61
|
+
mkdirSync(dir, { recursive: true });
|
|
62
|
+
process.env.VELLUM_WORKSPACE_DIR = dir;
|
|
63
|
+
currentWorkspaceDir = dir;
|
|
64
|
+
return dir;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Materialize `<workspaceDir>/tools/<name>.<ext>` with the supplied body.
|
|
69
|
+
* `ext` defaults to `.ts`; pass `.js` or `.json` to exercise the
|
|
70
|
+
* extension precedence and JSON-spec paths.
|
|
71
|
+
*
|
|
72
|
+
* If the body does not include `export default` (for `.ts`/`.js`), the
|
|
73
|
+
* test author is expected to know they're exercising a "missing default
|
|
74
|
+
* export" path — the loader logs an error and skips the entry rather
|
|
75
|
+
* than throwing.
|
|
76
|
+
*/
|
|
77
|
+
function writeTool(name: string, body: string, ext = ".ts"): void {
|
|
78
|
+
const toolsDir = join(currentWorkspaceDir, "tools");
|
|
79
|
+
mkdirSync(toolsDir, { recursive: true });
|
|
80
|
+
writeFileSync(join(toolsDir, `${name}${ext}`), body);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Write a `<name>.removed` sentinel under `<workspaceDir>/tools/`. */
|
|
84
|
+
function writeRemovedSentinel(name: string): void {
|
|
85
|
+
const toolsDir = join(currentWorkspaceDir, "tools");
|
|
86
|
+
mkdirSync(toolsDir, { recursive: true });
|
|
87
|
+
writeFileSync(join(toolsDir, `${name}.removed`), "");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function makeFakeCoreTool(name: string): Tool {
|
|
91
|
+
return {
|
|
92
|
+
name,
|
|
93
|
+
description: `Core ${name}`,
|
|
94
|
+
category: "test",
|
|
95
|
+
defaultRiskLevel: RiskLevel.Low,
|
|
96
|
+
executionTarget: "sandbox",
|
|
97
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
98
|
+
async execute(
|
|
99
|
+
_input: Record<string, unknown>,
|
|
100
|
+
_context: ToolContext,
|
|
101
|
+
): Promise<ToolExecutionResult> {
|
|
102
|
+
return { content: "core", isError: false };
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const WELL_FORMED_BODY = `
|
|
108
|
+
export default {
|
|
109
|
+
description: "from workspace",
|
|
110
|
+
defaultRiskLevel: "low",
|
|
111
|
+
input_schema: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: { greeting: { type: "string" } },
|
|
114
|
+
required: [],
|
|
115
|
+
},
|
|
116
|
+
async execute() {
|
|
117
|
+
return { content: "workspace-hello", isError: false };
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
const JS_BODY = `
|
|
123
|
+
export default {
|
|
124
|
+
description: "from workspace js",
|
|
125
|
+
defaultRiskLevel: "low",
|
|
126
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
127
|
+
async execute() {
|
|
128
|
+
return { content: "workspace-js", isError: false };
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
describe("workspace tool loader", () => {
|
|
134
|
+
beforeEach(() => {
|
|
135
|
+
__clearRegistryForTesting();
|
|
136
|
+
freshWorkspace();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
afterAll(() => {
|
|
140
|
+
rmSync(TEST_BASE_DIR, { recursive: true, force: true });
|
|
141
|
+
delete process.env.VELLUM_WORKSPACE_DIR;
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("registers a net-new tool from <workspaceDir>/tools/<name>.ts", async () => {
|
|
145
|
+
writeTool("hello_workspace", WELL_FORMED_BODY);
|
|
146
|
+
|
|
147
|
+
await loadWorkspaceTools();
|
|
148
|
+
|
|
149
|
+
const tool = getTool("hello_workspace");
|
|
150
|
+
expect(tool).toBeDefined();
|
|
151
|
+
expect(getToolOwner("hello_workspace")?.kind).toBe("workspace");
|
|
152
|
+
expect(tool?.description).toBe("from workspace");
|
|
153
|
+
expect(getWorkspaceToolNames()).toContain("hello_workspace");
|
|
154
|
+
expect(getCoreToolOverride("hello_workspace")).toBeUndefined();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("workspace tool with same name as core tool overrides and stashes the original", async () => {
|
|
158
|
+
const core = makeFakeCoreTool("override_me");
|
|
159
|
+
registerTool(core);
|
|
160
|
+
|
|
161
|
+
writeTool("override_me", WELL_FORMED_BODY);
|
|
162
|
+
|
|
163
|
+
await loadWorkspaceTools();
|
|
164
|
+
|
|
165
|
+
const live = getTool("override_me");
|
|
166
|
+
expect(live).toBeDefined();
|
|
167
|
+
expect(getToolOwner("override_me")?.kind).toBe("workspace");
|
|
168
|
+
expect(live?.description).toBe("from workspace");
|
|
169
|
+
expect(getCoreToolOverride("override_me")).toEqual(core);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test(".js wins over .ts for the same stem (compiled-binary semantics)", async () => {
|
|
173
|
+
writeTool("dual_ext", WELL_FORMED_BODY, ".ts");
|
|
174
|
+
writeTool("dual_ext", JS_BODY, ".js");
|
|
175
|
+
|
|
176
|
+
await loadWorkspaceTools();
|
|
177
|
+
|
|
178
|
+
const tool = getTool("dual_ext");
|
|
179
|
+
expect(tool).toBeDefined();
|
|
180
|
+
// JS wins — body said "from workspace js"
|
|
181
|
+
expect(tool?.description).toBe("from workspace js");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test(".json declarative spec loads with default error executor", async () => {
|
|
185
|
+
writeTool(
|
|
186
|
+
"data_only",
|
|
187
|
+
JSON.stringify({
|
|
188
|
+
description: "json spec",
|
|
189
|
+
defaultRiskLevel: "low",
|
|
190
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
191
|
+
}),
|
|
192
|
+
".json",
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
await loadWorkspaceTools();
|
|
196
|
+
|
|
197
|
+
const tool = getTool("data_only");
|
|
198
|
+
expect(tool).toBeDefined();
|
|
199
|
+
expect(getToolOwner("data_only")?.kind).toBe("workspace");
|
|
200
|
+
expect(tool?.description).toBe("json spec");
|
|
201
|
+
// JSON specs always pick up the default error executor — calling
|
|
202
|
+
// it returns isError=true with a "no execute implementation" message.
|
|
203
|
+
const result = await tool!.execute(
|
|
204
|
+
{},
|
|
205
|
+
{} as unknown as Parameters<Tool["execute"]>[1],
|
|
206
|
+
);
|
|
207
|
+
expect(result.isError).toBe(true);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test(".removed sentinel strips a core tool from the registry", async () => {
|
|
211
|
+
const core = makeFakeCoreTool("strip_me");
|
|
212
|
+
registerTool(core);
|
|
213
|
+
expect(getTool("strip_me")).toBeDefined();
|
|
214
|
+
|
|
215
|
+
writeRemovedSentinel("strip_me");
|
|
216
|
+
|
|
217
|
+
await loadWorkspaceTools();
|
|
218
|
+
|
|
219
|
+
expect(getTool("strip_me")).toBeUndefined();
|
|
220
|
+
expect(getStrippedCoreToolNames()).toContain("strip_me");
|
|
221
|
+
// The stashed core tool is preserved for later restoration.
|
|
222
|
+
expect(getCoreToolOverride("strip_me")).toEqual(core);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test(".removed sentinel for a non-existent name is a no-op", async () => {
|
|
226
|
+
writeRemovedSentinel("never_was_a_tool");
|
|
227
|
+
|
|
228
|
+
await loadWorkspaceTools();
|
|
229
|
+
|
|
230
|
+
expect(getTool("never_was_a_tool")).toBeUndefined();
|
|
231
|
+
expect(getStrippedCoreToolNames()).not.toContain("never_was_a_tool");
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test("per-tool isolation: one bad tool does not block the rest", async () => {
|
|
235
|
+
writeTool(
|
|
236
|
+
"broken_at_import",
|
|
237
|
+
`
|
|
238
|
+
throw new Error("boom at import time");
|
|
239
|
+
`,
|
|
240
|
+
);
|
|
241
|
+
writeTool("good_one", WELL_FORMED_BODY);
|
|
242
|
+
|
|
243
|
+
await loadWorkspaceTools();
|
|
244
|
+
|
|
245
|
+
expect(getTool("broken_at_import")).toBeUndefined();
|
|
246
|
+
expect(getTool("good_one")).toBeDefined();
|
|
247
|
+
expect(getToolOwner("good_one")?.kind).toBe("workspace");
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
test("missing default export logs + skips without crashing", async () => {
|
|
251
|
+
writeTool(
|
|
252
|
+
"no_default",
|
|
253
|
+
`
|
|
254
|
+
export const named = { description: "wrong shape" };
|
|
255
|
+
`,
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
await loadWorkspaceTools();
|
|
259
|
+
|
|
260
|
+
expect(getTool("no_default")).toBeUndefined();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test("non-object default export logs + skips without crashing", async () => {
|
|
264
|
+
writeTool(
|
|
265
|
+
"wrong_type",
|
|
266
|
+
`
|
|
267
|
+
export default 42;
|
|
268
|
+
`,
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
await loadWorkspaceTools();
|
|
272
|
+
|
|
273
|
+
expect(getTool("wrong_type")).toBeUndefined();
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
test("no <workspaceDir>/tools/ directory is a no-op", async () => {
|
|
277
|
+
// `freshWorkspace()` does not create a tools/ dir — the loader must
|
|
278
|
+
// complete without throwing and register nothing.
|
|
279
|
+
await loadWorkspaceTools();
|
|
280
|
+
|
|
281
|
+
expect(getWorkspaceToolNames()).toEqual([]);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test("filename stems that fail provider-safe validation are skipped", async () => {
|
|
285
|
+
// Provider-safe names match /^[a-zA-Z0-9_-]{1,64}$/. A stem with a
|
|
286
|
+
// space embeds an LLM-provider-incompatible character. The loader
|
|
287
|
+
// refuses to rewrite the name (which would produce an unfindable
|
|
288
|
+
// hash suffix); the operator must rename the file.
|
|
289
|
+
const toolsDir = join(currentWorkspaceDir, "tools");
|
|
290
|
+
mkdirSync(toolsDir, { recursive: true });
|
|
291
|
+
writeFileSync(join(toolsDir, "has space.ts"), WELL_FORMED_BODY);
|
|
292
|
+
|
|
293
|
+
await loadWorkspaceTools();
|
|
294
|
+
|
|
295
|
+
expect(getWorkspaceToolNames()).toEqual([]);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("dotfile stems (starting with .) are excluded", async () => {
|
|
299
|
+
// `.gitignore`, `.DS_Store`, etc. must not register as tools.
|
|
300
|
+
const toolsDir = join(currentWorkspaceDir, "tools");
|
|
301
|
+
mkdirSync(toolsDir, { recursive: true });
|
|
302
|
+
writeFileSync(join(toolsDir, ".gitignore"), "node_modules");
|
|
303
|
+
|
|
304
|
+
await loadWorkspaceTools();
|
|
305
|
+
|
|
306
|
+
expect(getWorkspaceToolNames()).toEqual([]);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
test("multiple tools register in a single batch", async () => {
|
|
310
|
+
writeTool("alpha", WELL_FORMED_BODY);
|
|
311
|
+
writeTool("beta", WELL_FORMED_BODY);
|
|
312
|
+
writeTool("gamma", WELL_FORMED_BODY);
|
|
313
|
+
|
|
314
|
+
await loadWorkspaceTools();
|
|
315
|
+
|
|
316
|
+
const names = getWorkspaceToolNames().sort();
|
|
317
|
+
expect(names).toEqual(["alpha", "beta", "gamma"]);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests that the `workspace-tools-watcher` feature flag gates the dynamic
|
|
3
|
+
* hot-reload watcher in `WorkspaceToolsWatcher.start()`.
|
|
4
|
+
*
|
|
5
|
+
* The initial disk scan (`loadWorkspaceTools()`) is unconditional and lives
|
|
6
|
+
* elsewhere; this suite only covers whether the live `fs.watch` loop mounts.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
12
|
+
|
|
13
|
+
import { clearFeatureFlagOverridesCache } from "../config/assistant-feature-flags.js";
|
|
14
|
+
import { WorkspaceToolsWatcher } from "../daemon/workspace-tools-watcher.js";
|
|
15
|
+
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
16
|
+
|
|
17
|
+
const FLAG = "workspace-tools-watcher";
|
|
18
|
+
const TEST_BASE_DIR = join(
|
|
19
|
+
tmpdir(),
|
|
20
|
+
`vellum-workspace-tools-watcher-flag-test-${process.pid}-${Date.now()}`,
|
|
21
|
+
);
|
|
22
|
+
let caseCounter = 0;
|
|
23
|
+
|
|
24
|
+
function freshWorkspaceWithToolsDir(): void {
|
|
25
|
+
caseCounter += 1;
|
|
26
|
+
const dir = join(TEST_BASE_DIR, `case-${caseCounter}`);
|
|
27
|
+
mkdirSync(join(dir, "tools"), { recursive: true });
|
|
28
|
+
process.env.VELLUM_WORKSPACE_DIR = dir;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
WorkspaceToolsWatcher.resetForTests();
|
|
33
|
+
clearFeatureFlagOverridesCache();
|
|
34
|
+
freshWorkspaceWithToolsDir();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
WorkspaceToolsWatcher.resetForTests();
|
|
39
|
+
clearFeatureFlagOverridesCache();
|
|
40
|
+
delete process.env.VELLUM_WORKSPACE_DIR;
|
|
41
|
+
rmSync(TEST_BASE_DIR, { recursive: true, force: true });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("WorkspaceToolsWatcher feature-flag gate", () => {
|
|
45
|
+
test("does not mount the watch loop when the flag is off", () => {
|
|
46
|
+
// GIVEN the workspace tools directory exists
|
|
47
|
+
// AND the watcher flag is disabled
|
|
48
|
+
setOverridesForTesting({ [FLAG]: false });
|
|
49
|
+
|
|
50
|
+
// WHEN the watcher starts
|
|
51
|
+
const watcher = WorkspaceToolsWatcher.getInstance();
|
|
52
|
+
watcher.start();
|
|
53
|
+
|
|
54
|
+
// THEN no fs.watch loop is mounted
|
|
55
|
+
expect(watcher.isWatchingForTests()).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("mounts the watch loop when the flag is on", () => {
|
|
59
|
+
// GIVEN the workspace tools directory exists
|
|
60
|
+
// AND the watcher flag is enabled
|
|
61
|
+
setOverridesForTesting({ [FLAG]: true });
|
|
62
|
+
|
|
63
|
+
// WHEN the watcher starts
|
|
64
|
+
const watcher = WorkspaceToolsWatcher.getInstance();
|
|
65
|
+
watcher.start();
|
|
66
|
+
|
|
67
|
+
// THEN a live fs.watch loop is mounted
|
|
68
|
+
expect(watcher.isWatchingForTests()).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
});
|