@vellumai/assistant 0.7.1 → 0.7.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/ARCHITECTURE.md +32 -49
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +39 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +9 -0
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +565 -12
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +374 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +109 -2
- package/src/__tests__/assistant-event.test.ts +10 -0
- package/src/__tests__/assistant-events-sse-hardening.test.ts +7 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -7
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-readiness-service.test.ts +59 -1
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +90 -155
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +5 -12
- package/src/__tests__/cu-unified-flow.test.ts +185 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-service.test.ts +718 -1
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +602 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +246 -47
- package/src/__tests__/host-bash-routes.test.ts +294 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +41 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
- package/src/__tests__/host-file-proxy.test.ts +37 -43
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +262 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +583 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/prechat-onboarding-contract.test.ts +3 -1
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +10 -6
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/bundler/app-bundler.ts +51 -3
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -1
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +73 -0
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +15 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +296 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +0 -18
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +67 -10
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -12
- package/src/config/feature-flag-registry.json +21 -133
- package/src/config/loader.ts +73 -99
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +7 -4
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/heartbeat.ts +63 -0
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +5 -10
- package/src/config/schemas/memory-lifecycle.ts +77 -24
- package/src/config/schemas/memory-v2.ts +48 -4
- package/src/config/schemas/platform.ts +6 -0
- package/src/config/schemas/services.ts +1 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/contacts/contact-store.ts +0 -30
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +126 -5
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +4 -3
- package/src/daemon/conversation-agent-loop-handlers.ts +21 -3
- package/src/daemon/conversation-agent-loop.ts +32 -28
- package/src/daemon/conversation-lifecycle.ts +8 -1
- package/src/daemon/conversation-process.ts +16 -11
- package/src/daemon/conversation-runtime-assembly.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +125 -4
- package/src/daemon/conversation-tool-setup.ts +16 -55
- package/src/daemon/conversation.ts +21 -2
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +293 -0
- package/src/daemon/host-bash-proxy.ts +84 -74
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +81 -86
- package/src/daemon/host-file-proxy.ts +93 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +247 -129
- package/src/daemon/lifecycle.ts +115 -117
- package/src/daemon/message-protocol.ts +3 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +11 -8
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +15 -7
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
- package/src/heartbeat/heartbeat-run-store.ts +236 -0
- package/src/heartbeat/heartbeat-service.ts +280 -49
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +14 -1
- package/src/ipc/cli-client.ts +32 -1
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +32 -7
- package/src/memory/context-search/sources/memory-v2.ts +17 -5
- package/src/memory/conversation-crud.ts +1 -1
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +4 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -4
- package/src/memory/graph/conversation-graph-memory.ts +1 -24
- package/src/memory/graph/graph-search.ts +8 -0
- package/src/memory/graph/retriever.ts +28 -0
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +66 -22
- package/src/memory/jobs-worker.ts +112 -63
- package/src/memory/memory-v2-activation-log-store.ts +1 -1
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +50 -20
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +7 -0
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/v2/__tests__/activation.test.ts +77 -95
- package/src/memory/v2/__tests__/injection.test.ts +43 -21
- package/src/memory/v2/__tests__/sim.test.ts +166 -6
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +0 -1
- package/src/memory/v2/activation.ts +69 -88
- package/src/memory/v2/consolidation-job.ts +3 -5
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +86 -53
- package/src/memory/v2/prompts/consolidation.ts +312 -91
- package/src/memory/v2/qdrant.ts +99 -1
- package/src/memory/v2/sim.ts +126 -16
- package/src/memory/v2/skill-qdrant.ts +12 -3
- package/src/memory/v2/skill-store.ts +16 -1
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +6 -5
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/oauth/connect-orchestrator.ts +4 -0
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/system-prompt.ts +3 -18
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/runtime/assistant-event-hub.ts +118 -96
- package/src/runtime/assistant-event.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +19 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +35 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +1 -0
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +30 -13
- package/src/runtime/routes/document-pdf-renderer.ts +165 -0
- package/src/runtime/routes/documents-routes.ts +30 -0
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +12 -6
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +36 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +44 -14
- package/src/runtime/routes/host-file-routes.ts +33 -10
- package/src/runtime/routes/host-transfer-routes.ts +64 -24
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +15 -43
- package/src/runtime/routes/inbound-message-handler.ts +1 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +441 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +63 -38
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +5 -5
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.ts +26 -0
- package/src/tools/host-filesystem/read.ts +26 -0
- package/src/tools/host-filesystem/transfer.ts +31 -1
- package/src/tools/host-filesystem/write.ts +26 -0
- package/src/tools/host-terminal/host-shell.ts +58 -0
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/tool-approval-handler.ts +1 -5
- package/src/tools/types.ts +4 -0
- package/src/usage/pricing.ts +1 -1
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -292,11 +292,7 @@ export class ToolApprovalHandler {
|
|
|
292
292
|
executionTarget,
|
|
293
293
|
);
|
|
294
294
|
|
|
295
|
-
if (
|
|
296
|
-
isUntrustedTrustClass(context.trustClass) &&
|
|
297
|
-
guardianApprovalRequired &&
|
|
298
|
-
context.trustClass !== "trusted_contact"
|
|
299
|
-
) {
|
|
295
|
+
if (isUntrustedTrustClass(context.trustClass) && guardianApprovalRequired) {
|
|
300
296
|
const inputDigest = computeToolApprovalDigest(name, input);
|
|
301
297
|
needsGrantConsumption = true;
|
|
302
298
|
deferredConsumeParams = {
|
package/src/tools/types.ts
CHANGED
|
@@ -138,6 +138,10 @@ export interface ToolExecutedEvent {
|
|
|
138
138
|
riskLevel: string;
|
|
139
139
|
/** ID of the trust rule that matched this invocation (if any). */
|
|
140
140
|
matchedTrustRuleId?: string;
|
|
141
|
+
/** How the approval decision was reached. Copied from PermissionDecision for analytics consumers. */
|
|
142
|
+
approvalMode?: string;
|
|
143
|
+
/** Why the approval decision was reached (stable enum). Copied from PermissionDecision for analytics consumers. */
|
|
144
|
+
approvalReason?: string;
|
|
141
145
|
decision: string;
|
|
142
146
|
durationMs: number;
|
|
143
147
|
result: ToolExecutionResult;
|
package/src/usage/pricing.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
|
|
14
14
|
const log = getLogger("usage-pricing");
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
function normalizeTokenCount(value: number | null | undefined): number {
|
|
17
17
|
if (typeof value !== "number" || !Number.isFinite(value)) return 0;
|
|
18
18
|
return Math.max(value, 0);
|
|
19
19
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { getDataDir } from "../util/platform.js";
|
|
5
|
+
|
|
6
|
+
const HATCHED_SIDECAR_FILENAME = "hatched.json";
|
|
7
|
+
|
|
8
|
+
export function getHatchedSidecarPath(): string {
|
|
9
|
+
return join(getDataDir(), HATCHED_SIDECAR_FILENAME);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function normalizeHatchedAt(value: unknown): string | undefined {
|
|
13
|
+
if (typeof value !== "string") return undefined;
|
|
14
|
+
|
|
15
|
+
const parsedTime = Date.parse(value);
|
|
16
|
+
if (isNaN(parsedTime) || parsedTime <= 0) return undefined;
|
|
17
|
+
|
|
18
|
+
return new Date(parsedTime).toISOString();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function readHatchedAtSidecar(): string | undefined {
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(
|
|
24
|
+
readFileSync(getHatchedSidecarPath(), "utf-8"),
|
|
25
|
+
) as { hatchedAt?: unknown };
|
|
26
|
+
return normalizeHatchedAt(parsed.hatchedAt);
|
|
27
|
+
} catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function writeHatchedAtSidecar(hatchedAt: string): void {
|
|
33
|
+
const normalized = normalizeHatchedAt(hatchedAt);
|
|
34
|
+
if (!normalized) return;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
mkdirSync(getDataDir(), { recursive: true });
|
|
38
|
+
writeFileSync(
|
|
39
|
+
getHatchedSidecarPath(),
|
|
40
|
+
JSON.stringify({ hatchedAt: normalized }, null, 2),
|
|
41
|
+
"utf-8",
|
|
42
|
+
);
|
|
43
|
+
} catch {
|
|
44
|
+
// Best-effort stability; callers still return a valid timestamp.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function selectHatchedAtFromStats(stats: {
|
|
49
|
+
birthtime: Date;
|
|
50
|
+
mtime: Date;
|
|
51
|
+
}): Date | undefined {
|
|
52
|
+
const candidates = [stats.birthtime, stats.mtime];
|
|
53
|
+
return candidates.find((candidate) => candidate.getTime() > 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function readIdentityFileHatchedAt(identityPath: string): string | undefined {
|
|
57
|
+
try {
|
|
58
|
+
return selectHatchedAtFromStats(statSync(identityPath))?.toISOString();
|
|
59
|
+
} catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function resolveHatchedAtReadOnly(
|
|
65
|
+
identityPath: string,
|
|
66
|
+
now: Date = new Date(),
|
|
67
|
+
): string {
|
|
68
|
+
return (
|
|
69
|
+
readHatchedAtSidecar() ??
|
|
70
|
+
readIdentityFileHatchedAt(identityPath) ??
|
|
71
|
+
now.toISOString()
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function resolveAndPersistHatchedAt(
|
|
76
|
+
identityPath: string,
|
|
77
|
+
now: Date = new Date(),
|
|
78
|
+
): string {
|
|
79
|
+
const sidecarHatchedAt = readHatchedAtSidecar();
|
|
80
|
+
if (sidecarHatchedAt) return sidecarHatchedAt;
|
|
81
|
+
|
|
82
|
+
const hatchedAt =
|
|
83
|
+
readIdentityFileHatchedAt(identityPath) ?? now.toISOString();
|
|
84
|
+
writeHatchedAtSidecar(hatchedAt);
|
|
85
|
+
return hatchedAt;
|
|
86
|
+
}
|
|
@@ -45,7 +45,7 @@ export const seedDeviceIdMigration: WorkspaceMigration = {
|
|
|
45
45
|
|
|
46
46
|
// b. Read the lockfile to find an existing installationId.
|
|
47
47
|
// The lockfile is always under the user's home directory, never under
|
|
48
|
-
//
|
|
48
|
+
// Check both the current and legacy filenames.
|
|
49
49
|
const home = homedir();
|
|
50
50
|
const lockCandidates = [
|
|
51
51
|
join(home, ".vellum.lock.json"),
|
|
@@ -37,8 +37,9 @@ export const servicesConfigMigration: WorkspaceMigration = {
|
|
|
37
37
|
|
|
38
38
|
// Skip if no legacy fields remain — either already migrated or a fresh install
|
|
39
39
|
// where schema defaults are correct. We check for legacy fields instead of
|
|
40
|
-
// services existence because
|
|
41
|
-
// services object
|
|
40
|
+
// services existence because legacy daemons (before defaults were applied
|
|
41
|
+
// only in-memory) may have written a default services object to disk
|
|
42
|
+
// before migrations run.
|
|
42
43
|
const hasLegacyFields =
|
|
43
44
|
"provider" in config ||
|
|
44
45
|
"model" in config ||
|
|
@@ -46,7 +47,8 @@ export const servicesConfigMigration: WorkspaceMigration = {
|
|
|
46
47
|
"webSearchProvider" in config;
|
|
47
48
|
if (!hasLegacyFields) return;
|
|
48
49
|
|
|
49
|
-
// Start from existing services (may have
|
|
50
|
+
// Start from existing services (legacy daemons may have written a
|
|
51
|
+
// schema-default services object to disk before this migration runs)
|
|
50
52
|
// so we don't discard any non-default values already written there.
|
|
51
53
|
const existingServices =
|
|
52
54
|
config.services != null &&
|
|
@@ -96,8 +98,9 @@ export const servicesConfigMigration: WorkspaceMigration = {
|
|
|
96
98
|
// Legacy top-level fields (provider, model) are the user's actual
|
|
97
99
|
// configuration from before the services structure existed. If they're
|
|
98
100
|
// present as strings they take precedence over any `existingServices`
|
|
99
|
-
// values, which
|
|
100
|
-
// The spread preserves any extra keys that
|
|
101
|
+
// values, which on legacy daemons may just be schema defaults that an
|
|
102
|
+
// older loader wrote to disk. The spread preserves any extra keys that
|
|
103
|
+
// legacy daemons may have written alongside.
|
|
101
104
|
services.inference = {
|
|
102
105
|
...(existingServices.inference ?? {}),
|
|
103
106
|
mode: inferenceMode,
|
|
@@ -7,16 +7,10 @@ import {
|
|
|
7
7
|
unlinkSync,
|
|
8
8
|
writeFileSync,
|
|
9
9
|
} from "node:fs";
|
|
10
|
-
import { homedir } from "node:os";
|
|
11
10
|
import { join } from "node:path";
|
|
12
11
|
|
|
13
12
|
import type { WorkspaceMigration } from "./types.js";
|
|
14
|
-
|
|
15
|
-
/** Inlined from platform.ts to satisfy migration self-containment rule (AGENTS.md). */
|
|
16
|
-
function getRootDir(): string {
|
|
17
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
18
|
-
return join(base, ".vellum");
|
|
19
|
-
}
|
|
13
|
+
import { getVellumRoot } from "./utils.js";
|
|
20
14
|
|
|
21
15
|
export const extractFeatureFlagsToProtectedMigration: WorkspaceMigration = {
|
|
22
16
|
id: "016-extract-feature-flags-to-protected",
|
|
@@ -26,7 +20,7 @@ export const extractFeatureFlagsToProtectedMigration: WorkspaceMigration = {
|
|
|
26
20
|
down(workspaceDir: string): void {
|
|
27
21
|
// Reverse: read feature flags from protected directory and write them
|
|
28
22
|
// back to config.json as assistantFeatureFlagValues.
|
|
29
|
-
const protectedDir = join(
|
|
23
|
+
const protectedDir = join(getVellumRoot(), "protected");
|
|
30
24
|
const featureFlagsPath = join(protectedDir, "feature-flags.json");
|
|
31
25
|
|
|
32
26
|
if (!existsSync(featureFlagsPath)) return;
|
|
@@ -111,7 +105,7 @@ export const extractFeatureFlagsToProtectedMigration: WorkspaceMigration = {
|
|
|
111
105
|
}
|
|
112
106
|
|
|
113
107
|
// Write feature flags to protected directory
|
|
114
|
-
const protectedDir = join(
|
|
108
|
+
const protectedDir = join(getVellumRoot(), "protected");
|
|
115
109
|
mkdirSync(protectedDir, { recursive: true });
|
|
116
110
|
|
|
117
111
|
const featureFlagsPath = join(protectedDir, "feature-flags.json");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workspace migration 021: Move signals directory from root to workspace.
|
|
3
3
|
*
|
|
4
|
-
* Previously, `~/.vellum/signals/` lived directly under
|
|
4
|
+
* Previously, `~/.vellum/signals/` lived directly under the Vellum root. This
|
|
5
5
|
* migration moves any existing signal files into `~/.vellum/workspace/signals/`
|
|
6
6
|
* so that getSignalsDir() resolves correctly under the workspace.
|
|
7
7
|
*
|
|
@@ -13,23 +13,17 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { existsSync, mkdirSync, readdirSync, renameSync } from "node:fs";
|
|
16
|
-
import { homedir } from "node:os";
|
|
17
16
|
import { join } from "node:path";
|
|
18
17
|
|
|
19
18
|
import type { WorkspaceMigration } from "./types.js";
|
|
20
|
-
|
|
21
|
-
/** Inlined from platform.ts to satisfy migration self-containment rule (AGENTS.md). */
|
|
22
|
-
function getRootDir(): string {
|
|
23
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
24
|
-
return join(base, ".vellum");
|
|
25
|
-
}
|
|
19
|
+
import { getVellumRoot } from "./utils.js";
|
|
26
20
|
|
|
27
21
|
export const moveSignalsToWorkspaceMigration: WorkspaceMigration = {
|
|
28
22
|
id: "021-move-signals-to-workspace",
|
|
29
23
|
description: "Move signals directory from root to workspace",
|
|
30
24
|
|
|
31
25
|
run(workspaceDir: string): void {
|
|
32
|
-
const oldSignalsDir = join(
|
|
26
|
+
const oldSignalsDir = join(getVellumRoot(), "signals");
|
|
33
27
|
const newSignalsDir = join(workspaceDir, "signals");
|
|
34
28
|
|
|
35
29
|
mkdirSync(newSignalsDir, { recursive: true });
|
|
@@ -56,7 +50,7 @@ export const moveSignalsToWorkspaceMigration: WorkspaceMigration = {
|
|
|
56
50
|
},
|
|
57
51
|
|
|
58
52
|
down(workspaceDir: string): void {
|
|
59
|
-
const oldSignalsDir = join(
|
|
53
|
+
const oldSignalsDir = join(getVellumRoot(), "signals");
|
|
60
54
|
const newSignalsDir = join(workspaceDir, "signals");
|
|
61
55
|
|
|
62
56
|
mkdirSync(oldSignalsDir, { recursive: true });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workspace migration 022: Move hooks directory from root to workspace.
|
|
3
3
|
*
|
|
4
|
-
* Previously, `~/.vellum/hooks/` lived directly under
|
|
4
|
+
* Previously, `~/.vellum/hooks/` lived directly under the Vellum root. This
|
|
5
5
|
* migration moves existing hook directories and files into
|
|
6
6
|
* `~/.vellum/workspace/hooks/` so that getWorkspaceHooksDir() resolves
|
|
7
7
|
* correctly under the workspace.
|
|
@@ -19,23 +19,17 @@ import {
|
|
|
19
19
|
renameSync,
|
|
20
20
|
rmSync,
|
|
21
21
|
} from "node:fs";
|
|
22
|
-
import { homedir } from "node:os";
|
|
23
22
|
import { join } from "node:path";
|
|
24
23
|
|
|
25
24
|
import type { WorkspaceMigration } from "./types.js";
|
|
26
|
-
|
|
27
|
-
/** Inlined from platform.ts to satisfy migration self-containment rule (AGENTS.md). */
|
|
28
|
-
function getRootDir(): string {
|
|
29
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
30
|
-
return join(base, ".vellum");
|
|
31
|
-
}
|
|
25
|
+
import { getVellumRoot } from "./utils.js";
|
|
32
26
|
|
|
33
27
|
export const moveHooksToWorkspaceMigration: WorkspaceMigration = {
|
|
34
28
|
id: "022-move-hooks-to-workspace",
|
|
35
29
|
description: "Move hooks directory from root to workspace",
|
|
36
30
|
|
|
37
31
|
run(workspaceDir: string): void {
|
|
38
|
-
const oldHooksDir = join(
|
|
32
|
+
const oldHooksDir = join(getVellumRoot(), "hooks");
|
|
39
33
|
const newHooksDir = join(workspaceDir, "hooks");
|
|
40
34
|
|
|
41
35
|
mkdirSync(newHooksDir, { recursive: true });
|
|
@@ -65,7 +59,7 @@ export const moveHooksToWorkspaceMigration: WorkspaceMigration = {
|
|
|
65
59
|
},
|
|
66
60
|
|
|
67
61
|
down(workspaceDir: string): void {
|
|
68
|
-
const oldHooksDir = join(
|
|
62
|
+
const oldHooksDir = join(getVellumRoot(), "hooks");
|
|
69
63
|
const newHooksDir = join(workspaceDir, "hooks");
|
|
70
64
|
|
|
71
65
|
mkdirSync(oldHooksDir, { recursive: true });
|
|
@@ -2,23 +2,16 @@
|
|
|
2
2
|
* Workspace migration 023: Move config/state JSON files from root to workspace.
|
|
3
3
|
*
|
|
4
4
|
* Previously, dictation-profiles.json, email-guardrails.json, and
|
|
5
|
-
* active-call-leases.json lived directly under
|
|
5
|
+
* active-call-leases.json lived directly under the Vellum root (~/.vellum/).
|
|
6
6
|
* This migration moves them into the workspace directory so they follow
|
|
7
7
|
* the workspace convention for organizational consistency.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { existsSync, renameSync, unlinkSync } from "node:fs";
|
|
11
|
-
import { homedir } from "node:os";
|
|
12
11
|
import { join } from "node:path";
|
|
13
12
|
|
|
14
13
|
import type { WorkspaceMigration } from "./types.js";
|
|
15
|
-
|
|
16
|
-
/** Inlined from platform.ts to satisfy migration self-containment rule (AGENTS.md). */
|
|
17
|
-
function getRootDir(): string {
|
|
18
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
19
|
-
return join(base, ".vellum");
|
|
20
|
-
}
|
|
21
|
-
|
|
14
|
+
import { getVellumRoot } from "./utils.js";
|
|
22
15
|
/** Files to move from root → workspace. */
|
|
23
16
|
const CONFIG_FILES = [
|
|
24
17
|
"dictation-profiles.json",
|
|
@@ -32,7 +25,7 @@ export const moveConfigFilesToWorkspaceMigration: WorkspaceMigration = {
|
|
|
32
25
|
"Move dictation-profiles, email-guardrails, and active-call-leases from root to workspace",
|
|
33
26
|
|
|
34
27
|
run(workspaceDir: string): void {
|
|
35
|
-
const rootDir =
|
|
28
|
+
const rootDir = getVellumRoot();
|
|
36
29
|
|
|
37
30
|
for (const file of CONFIG_FILES) {
|
|
38
31
|
const oldPath = join(rootDir, file);
|
|
@@ -60,7 +53,7 @@ export const moveConfigFilesToWorkspaceMigration: WorkspaceMigration = {
|
|
|
60
53
|
},
|
|
61
54
|
|
|
62
55
|
down(workspaceDir: string): void {
|
|
63
|
-
const rootDir =
|
|
56
|
+
const rootDir = getVellumRoot();
|
|
64
57
|
|
|
65
58
|
for (const file of CONFIG_FILES) {
|
|
66
59
|
const newPath = join(workspaceDir, file);
|
|
@@ -25,17 +25,10 @@ import {
|
|
|
25
25
|
renameSync,
|
|
26
26
|
unlinkSync,
|
|
27
27
|
} from "node:fs";
|
|
28
|
-
import { homedir } from "node:os";
|
|
29
28
|
import { join } from "node:path";
|
|
30
29
|
|
|
31
30
|
import type { WorkspaceMigration } from "./types.js";
|
|
32
|
-
|
|
33
|
-
/** Inlined from platform.ts to satisfy migration self-containment rule (AGENTS.md). */
|
|
34
|
-
function getRootDir(): string {
|
|
35
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
36
|
-
return join(base, ".vellum");
|
|
37
|
-
}
|
|
38
|
-
|
|
31
|
+
import { getVellumRoot } from "./utils.js";
|
|
39
32
|
/** Individual files to move from root → workspace (with optional subdirectory). */
|
|
40
33
|
const FILE_MOVES: Array<{ name: string; subdir?: string }> = [
|
|
41
34
|
{ name: "daemon-stderr.log", subdir: "logs" },
|
|
@@ -93,7 +86,7 @@ export const moveRuntimeFilesToWorkspaceMigration: WorkspaceMigration = {
|
|
|
93
86
|
"Move daemon-stderr.log, daemon-startup.lock, embed-worker.pid, external/, and bin/ from root to workspace",
|
|
94
87
|
|
|
95
88
|
run(workspaceDir: string): void {
|
|
96
|
-
const rootDir =
|
|
89
|
+
const rootDir = getVellumRoot();
|
|
97
90
|
|
|
98
91
|
// Move individual files
|
|
99
92
|
for (const { name, subdir } of FILE_MOVES) {
|
|
@@ -110,7 +103,7 @@ export const moveRuntimeFilesToWorkspaceMigration: WorkspaceMigration = {
|
|
|
110
103
|
},
|
|
111
104
|
|
|
112
105
|
down(workspaceDir: string): void {
|
|
113
|
-
const rootDir =
|
|
106
|
+
const rootDir = getVellumRoot();
|
|
114
107
|
|
|
115
108
|
// Move individual files back
|
|
116
109
|
for (const { name, subdir } of FILE_MOVES) {
|
|
@@ -22,8 +22,9 @@ import type { WorkspaceMigration } from "./types.js";
|
|
|
22
22
|
* 2. **Fresh install** (config.json absent): write a minimal starter
|
|
23
23
|
* config with just the callSite seeds, using the default provider
|
|
24
24
|
* (anthropic — same as the schema default). `loadConfig()` runs
|
|
25
|
-
* after migrations and
|
|
26
|
-
*
|
|
25
|
+
* after migrations and applies schema defaults only to the
|
|
26
|
+
* in-memory config (disk is left untouched), so our seeded
|
|
27
|
+
* callSites are preserved verbatim.
|
|
27
28
|
*
|
|
28
29
|
* Without the fresh-install branch, new users permanently fall through
|
|
29
30
|
* to `llm.default` (opus + max effort) because `LLMSchema.callSites`
|
|
@@ -12,7 +12,8 @@ import type { WorkspaceMigration } from "./types.js";
|
|
|
12
12
|
* `llm.callSites` without overwriting a user-defined override.
|
|
13
13
|
* 2. **Fresh install** (config.json absent): write a minimal starter
|
|
14
14
|
* config with just this seed. `loadConfig()` runs after migrations
|
|
15
|
-
* and
|
|
15
|
+
* and applies schema defaults to the in-memory config without
|
|
16
|
+
* rewriting disk, so the seeded callSite is preserved as-is.
|
|
16
17
|
*
|
|
17
18
|
* Applied only when:
|
|
18
19
|
* - the resolved provider is Anthropic (other providers own their
|
|
@@ -7,22 +7,17 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { existsSync, renameSync, unlinkSync } from "node:fs";
|
|
10
|
-
import { homedir } from "node:os";
|
|
11
10
|
import { join } from "node:path";
|
|
12
11
|
|
|
13
12
|
import type { WorkspaceMigration } from "./types.js";
|
|
14
|
-
|
|
15
|
-
function getRootDir(): string {
|
|
16
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
17
|
-
return join(base, ".vellum");
|
|
18
|
-
}
|
|
13
|
+
import { getVellumRoot } from "./utils.js";
|
|
19
14
|
|
|
20
15
|
export const movePidToWorkspaceMigration: WorkspaceMigration = {
|
|
21
16
|
id: "059-move-pid-to-workspace",
|
|
22
17
|
description: "Move vellum.pid from root to workspace",
|
|
23
18
|
|
|
24
19
|
run(workspaceDir: string): void {
|
|
25
|
-
const oldPath = join(
|
|
20
|
+
const oldPath = join(getVellumRoot(), "vellum.pid");
|
|
26
21
|
const newPath = join(workspaceDir, "vellum.pid");
|
|
27
22
|
if (!existsSync(oldPath)) return;
|
|
28
23
|
if (existsSync(newPath)) {
|
|
@@ -37,7 +32,7 @@ export const movePidToWorkspaceMigration: WorkspaceMigration = {
|
|
|
37
32
|
},
|
|
38
33
|
|
|
39
34
|
down(workspaceDir: string): void {
|
|
40
|
-
const oldPath = join(
|
|
35
|
+
const oldPath = join(getVellumRoot(), "vellum.pid");
|
|
41
36
|
const newPath = join(workspaceDir, "vellum.pid");
|
|
42
37
|
if (!existsSync(newPath)) return;
|
|
43
38
|
if (existsSync(oldPath)) {
|
|
@@ -11,22 +11,17 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { copyFileSync, existsSync, unlinkSync } from "node:fs";
|
|
14
|
-
import { homedir } from "node:os";
|
|
15
14
|
import { join } from "node:path";
|
|
16
15
|
|
|
17
16
|
import type { WorkspaceMigration } from "./types.js";
|
|
18
|
-
|
|
19
|
-
function getRootDir(): string {
|
|
20
|
-
const base = process.env.BASE_DATA_DIR?.trim() || homedir();
|
|
21
|
-
return join(base, ".vellum");
|
|
22
|
-
}
|
|
17
|
+
import { getVellumRoot } from "./utils.js";
|
|
23
18
|
|
|
24
19
|
export const moveBackupKeyToWorkspaceMigration: WorkspaceMigration = {
|
|
25
20
|
id: "061-move-backup-key-to-workspace",
|
|
26
21
|
description: "Move backup.key from protected/ to workspace",
|
|
27
22
|
|
|
28
23
|
run(workspaceDir: string): void {
|
|
29
|
-
const oldPath = join(
|
|
24
|
+
const oldPath = join(getVellumRoot(), "protected", "backup.key");
|
|
30
25
|
const newPath = join(workspaceDir, ".backup.key");
|
|
31
26
|
if (!existsSync(oldPath)) return;
|
|
32
27
|
if (existsSync(newPath)) {
|
|
@@ -42,7 +37,7 @@ export const moveBackupKeyToWorkspaceMigration: WorkspaceMigration = {
|
|
|
42
37
|
},
|
|
43
38
|
|
|
44
39
|
down(workspaceDir: string): void {
|
|
45
|
-
const oldPath = join(
|
|
40
|
+
const oldPath = join(getVellumRoot(), "protected", "backup.key");
|
|
46
41
|
const newPath = join(workspaceDir, ".backup.key");
|
|
47
42
|
if (!existsSync(newPath)) return;
|
|
48
43
|
if (existsSync(oldPath)) {
|
|
@@ -6,6 +6,6 @@ Each migration file must be **fully self-contained**. All helper functions, cons
|
|
|
6
6
|
|
|
7
7
|
- **No external exports.** Migration files must not export anything other than the single `WorkspaceMigration` object. Other code must never import from a migration file.
|
|
8
8
|
- **Duplicate rather than share.** If two migrations need the same helper, duplicate it in both files. Migrations are write-once code — they run once per assistant and are never modified after release. Duplication is preferable to coupling.
|
|
9
|
-
- **Allowed imports:** `./types.js` (for the `WorkspaceMigration` interface), `../../util/logger.js` (for structured logging), and Node/Bun runtime built-ins (`node:fs`, `node:path`, `node:crypto`, `bun:sqlite`, etc.). All other dependencies — both project-internal modules and third-party npm packages — must be inlined. Do not import from shared modules like `../../memory/` or `../../config/`, and do not add npm dependencies.
|
|
9
|
+
- **Allowed imports:** `./types.js` (for the `WorkspaceMigration` interface), `./utils.js` (for shared path-resolution helpers like `getVellumRoot()`), `../../util/logger.js` (for structured logging), and Node/Bun runtime built-ins (`node:fs`, `node:path`, `node:crypto`, `bun:sqlite`, etc.). All other dependencies — both project-internal modules and third-party npm packages — must be inlined. Do not import from shared modules like `../../memory/` or `../../config/`, and do not add npm dependencies.
|
|
10
10
|
- **Graceful on all platforms.** Migrations run on macOS, Linux, and in Docker. Platform-specific operations must no-op gracefully on unsupported platforms — never throw.
|
|
11
11
|
- **Idempotent.** Migrations must be safe to re-run if interrupted. The runner checkpoints state as `"started"` before execution and `"completed"` after, so a crash mid-migration triggers a re-run on next startup.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Workspace migration: Migrate workspace data from /data to /workspace volume.
|
|
3
3
|
*
|
|
4
4
|
* In the old Docker volume layout, workspace data lived at
|
|
5
|
-
*
|
|
5
|
+
* `<vellumRoot>/workspace`. In the new layout, VELLUM_WORKSPACE_DIR points
|
|
6
6
|
* to a dedicated volume (e.g. `/workspace`). On first boot with the new layout,
|
|
7
7
|
* this migration copies existing workspace data from the old location to the
|
|
8
8
|
* new volume so nothing is lost.
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import { join } from "node:path";
|
|
25
25
|
|
|
26
26
|
import type { WorkspaceMigration } from "./types.js";
|
|
27
|
+
import { getVellumRoot } from "./utils.js";
|
|
27
28
|
|
|
28
29
|
const SENTINEL_FILENAME = ".workspace-volume-migrated";
|
|
29
30
|
|
|
@@ -68,15 +69,8 @@ export const migrateToWorkspaceVolumeMigration: WorkspaceMigration = {
|
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
// Resolve the old workspace location:
|
|
72
|
-
const
|
|
73
|
-
if (!baseDataDir) {
|
|
74
|
-
// No BASE_DATA_DIR means there's no old location to migrate from
|
|
75
|
-
writeSentinel(sentinelPath);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const oldWorkspaceDir = join(baseDataDir, ".vellum", "workspace");
|
|
72
|
+
// Resolve the old workspace location: <vellumRoot>/workspace
|
|
73
|
+
const oldWorkspaceDir = join(getVellumRoot(), "workspace");
|
|
80
74
|
|
|
81
75
|
// If the old workspace doesn't exist or is empty, nothing to migrate
|
|
82
76
|
if (!existsSync(oldWorkspaceDir)) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the legacy Vellum root directory (~/.vellum).
|
|
6
|
+
*
|
|
7
|
+
* Resolution order:
|
|
8
|
+
* 1. Parent of VELLUM_WORKSPACE_DIR — e.g. /data/.vellum/workspace → /data/.vellum
|
|
9
|
+
* 2. If that parent is "/" (workspace at top level, e.g. /workspace), fall back
|
|
10
|
+
* to homedir()/.vellum
|
|
11
|
+
*
|
|
12
|
+
* This replaces the old inlined `getRootDir()` pattern used by individual migrations.
|
|
13
|
+
*/
|
|
14
|
+
export function getVellumRoot(): string {
|
|
15
|
+
const workspaceDir = process.env.VELLUM_WORKSPACE_DIR?.trim();
|
|
16
|
+
if (workspaceDir) {
|
|
17
|
+
const parent = dirname(workspaceDir);
|
|
18
|
+
if (parent !== "/") return parent;
|
|
19
|
+
}
|
|
20
|
+
return join(homedir(), ".vellum");
|
|
21
|
+
}
|