@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
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
|
|
3
|
-
import { getAssistantDomain } from "../../config/env.js";
|
|
3
|
+
import { getApexDomain, getAssistantDomain } from "../../config/env.js";
|
|
4
|
+
import {
|
|
5
|
+
loadRawConfig,
|
|
6
|
+
saveRawConfig,
|
|
7
|
+
setNestedValue,
|
|
8
|
+
} from "../../config/loader.js";
|
|
4
9
|
import { VellumPlatformClient } from "../../platform/client.js";
|
|
5
10
|
import { getCliLogger } from "../logger.js";
|
|
6
11
|
import { shouldOutputJson, writeOutput } from "../output.js";
|
|
@@ -8,6 +13,7 @@ import { shouldOutputJson, writeOutput } from "../output.js";
|
|
|
8
13
|
const log = getCliLogger("domain");
|
|
9
14
|
|
|
10
15
|
export function registerDomainCommand(program: Command): void {
|
|
16
|
+
const apexDomain = getApexDomain();
|
|
11
17
|
const baseDomain = getAssistantDomain();
|
|
12
18
|
const domain = program
|
|
13
19
|
.command("domain")
|
|
@@ -97,17 +103,36 @@ Examples:
|
|
|
97
103
|
|
|
98
104
|
const data = (await response.json()) as {
|
|
99
105
|
id: string;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
106
|
+
subdomain?: string;
|
|
107
|
+
domain?: string;
|
|
108
|
+
status?: string;
|
|
109
|
+
verified?: boolean;
|
|
110
|
+
created_at?: string;
|
|
111
|
+
created?: string;
|
|
104
112
|
};
|
|
105
113
|
|
|
114
|
+
// Persist the subdomain to config so getAssistantDomain() can use it
|
|
115
|
+
const registeredSubdomain =
|
|
116
|
+
data.subdomain ??
|
|
117
|
+
data.domain?.replace(`.${apexDomain}`, "") ??
|
|
118
|
+
subdomain;
|
|
119
|
+
if (registeredSubdomain) {
|
|
120
|
+
const raw = loadRawConfig();
|
|
121
|
+
setNestedValue(raw, "platform.subdomain", registeredSubdomain);
|
|
122
|
+
saveRawConfig(raw);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const displayDomain =
|
|
126
|
+
data.domain ??
|
|
127
|
+
(registeredSubdomain
|
|
128
|
+
? `${registeredSubdomain}.${apexDomain}`
|
|
129
|
+
: "unknown");
|
|
130
|
+
|
|
106
131
|
if (shouldOutputJson(cmd)) {
|
|
107
132
|
writeOutput(cmd, data);
|
|
108
133
|
} else {
|
|
109
|
-
log.info(`✓ Registered ${
|
|
110
|
-
if (
|
|
134
|
+
log.info(`✓ Registered ${displayDomain}`);
|
|
135
|
+
if (data.verified === false) {
|
|
111
136
|
log.info(
|
|
112
137
|
" ⚠ Domain verification pending — this usually resolves within a few seconds.",
|
|
113
138
|
);
|
|
@@ -174,15 +199,33 @@ Examples:
|
|
|
174
199
|
const data = (await response.json()) as {
|
|
175
200
|
results: {
|
|
176
201
|
id: string;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
202
|
+
subdomain?: string;
|
|
203
|
+
domain?: string;
|
|
204
|
+
status?: string;
|
|
205
|
+
verified?: boolean;
|
|
206
|
+
created_at?: string;
|
|
207
|
+
created?: string;
|
|
181
208
|
}[];
|
|
182
209
|
};
|
|
183
210
|
|
|
184
211
|
const domains = data.results ?? [];
|
|
185
212
|
|
|
213
|
+
// Sync subdomain to config if not already cached
|
|
214
|
+
if (domains.length > 0) {
|
|
215
|
+
const first = domains[0];
|
|
216
|
+
const sub =
|
|
217
|
+
first.subdomain ?? first.domain?.replace(`.${apexDomain}`, "");
|
|
218
|
+
if (sub) {
|
|
219
|
+
const raw = loadRawConfig();
|
|
220
|
+
const existing = (raw as Record<string, Record<string, unknown>>)
|
|
221
|
+
.platform?.subdomain;
|
|
222
|
+
if (existing !== sub) {
|
|
223
|
+
setNestedValue(raw, "platform.subdomain", sub);
|
|
224
|
+
saveRawConfig(raw);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
186
229
|
if (shouldOutputJson(cmd)) {
|
|
187
230
|
writeOutput(cmd, data);
|
|
188
231
|
} else if (domains.length === 0) {
|
|
@@ -191,10 +234,18 @@ Examples:
|
|
|
191
234
|
);
|
|
192
235
|
} else {
|
|
193
236
|
for (const d of domains) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
237
|
+
const displayDomain =
|
|
238
|
+
d.domain ??
|
|
239
|
+
(d.subdomain ? `${d.subdomain}.${apexDomain}` : "unknown");
|
|
240
|
+
const createdRaw = d.created_at ?? d.created;
|
|
241
|
+
const createdDate = createdRaw
|
|
242
|
+
? createdRaw.split("T")[0]
|
|
243
|
+
: "unknown";
|
|
244
|
+
log.info(`Domain: ${displayDomain}`);
|
|
245
|
+
if (d.status != null) log.info(`Status: ${d.status}`);
|
|
246
|
+
if (d.verified != null)
|
|
247
|
+
log.info(`Verified: ${d.verified ? "yes" : "no"}`);
|
|
248
|
+
log.info(`Created: ${createdDate}`);
|
|
198
249
|
}
|
|
199
250
|
}
|
|
200
251
|
} catch (err) {
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `assistant gateway` CLI namespace.
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* logs tail — Show the last N gateway log entries via the daemon IPC proxy.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Command } from "commander";
|
|
9
|
+
|
|
10
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
11
|
+
import { log } from "../logger.js";
|
|
12
|
+
|
|
13
|
+
// -- Types --------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
interface PinoEntry {
|
|
16
|
+
time: number; // Unix ms timestamp
|
|
17
|
+
level: number; // pino numeric level
|
|
18
|
+
module?: string;
|
|
19
|
+
msg?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// -- Helpers ------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
function formatTime(ms: number): string {
|
|
26
|
+
const d = new Date(ms);
|
|
27
|
+
const pad = (n: number, w = 2) => String(n).padStart(w, "0");
|
|
28
|
+
const centis = String(Math.floor((ms % 1000) / 10)).padStart(2, "0");
|
|
29
|
+
return (
|
|
30
|
+
`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` +
|
|
31
|
+
`${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${centis}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const LEVEL_NAMES: Record<number, string> = {
|
|
36
|
+
10: "TRACE",
|
|
37
|
+
20: "DEBUG",
|
|
38
|
+
30: "INFO",
|
|
39
|
+
40: "WARN",
|
|
40
|
+
50: "ERROR",
|
|
41
|
+
60: "FATAL",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function levelName(n: number): string {
|
|
45
|
+
return LEVEL_NAMES[n] ?? String(n);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function colorLevel(name: string, levelNum: number): string {
|
|
49
|
+
if (!process.stdout.isTTY) return name;
|
|
50
|
+
if (levelNum >= 50) return `\x1b[31m${name}\x1b[0m`; // red: error/fatal
|
|
51
|
+
if (levelNum === 40) return `\x1b[33m${name}\x1b[0m`; // yellow: warn
|
|
52
|
+
if (levelNum <= 20) return `\x1b[2m${name}\x1b[0m`; // dim: debug/trace
|
|
53
|
+
return name;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// -- Registration -------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
export function registerGatewayCommand(program: Command): void {
|
|
59
|
+
const gateway = program.command("gateway").description("Gateway management");
|
|
60
|
+
|
|
61
|
+
gateway.addHelpText(
|
|
62
|
+
"after",
|
|
63
|
+
`
|
|
64
|
+
The gateway is the channel ingress layer — it handles inbound HTTP requests,
|
|
65
|
+
manages trust rules, routes traffic to the assistant, and records
|
|
66
|
+
structured logs for all inbound activity.
|
|
67
|
+
|
|
68
|
+
Examples:
|
|
69
|
+
$ assistant gateway logs tail
|
|
70
|
+
$ assistant gateway logs tail -n 50
|
|
71
|
+
$ assistant gateway logs tail --level warn
|
|
72
|
+
$ assistant gateway logs tail --module cors`,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const logs = gateway.command("logs").description("Gateway log operations");
|
|
76
|
+
|
|
77
|
+
logs.addHelpText(
|
|
78
|
+
"after",
|
|
79
|
+
`
|
|
80
|
+
Gateway logs are structured JSON (ndjson) entries emitted by the gateway
|
|
81
|
+
process. Each entry carries a timestamp, numeric pino log level, optional
|
|
82
|
+
module tag, and a message. Use 'tail' to inspect recent entries.
|
|
83
|
+
|
|
84
|
+
Examples:
|
|
85
|
+
$ assistant gateway logs tail
|
|
86
|
+
$ assistant gateway logs tail --level error --module cors`,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
logs
|
|
90
|
+
.command("tail")
|
|
91
|
+
.description("Show last N gateway log entries")
|
|
92
|
+
.option("-n <number>", "Number of lines (default: 10)")
|
|
93
|
+
.option("-q, --quiet", "Suppress column headers")
|
|
94
|
+
.option(
|
|
95
|
+
"--level <level>",
|
|
96
|
+
"Minimum log level (trace|debug|info|warn|error|fatal)",
|
|
97
|
+
"info",
|
|
98
|
+
)
|
|
99
|
+
.option("--module <name>", "Filter to exact module name")
|
|
100
|
+
.option("--raw", "Output raw ndjson (one JSON object per line)")
|
|
101
|
+
.addHelpText(
|
|
102
|
+
"after",
|
|
103
|
+
`
|
|
104
|
+
Arguments:
|
|
105
|
+
-n <number> Number of entries to return, clamped to 1–1000 (default: 10).
|
|
106
|
+
--level <level> Minimum log level to include. One of:
|
|
107
|
+
trace | debug | info | warn | error | fatal
|
|
108
|
+
Defaults to "info". Use "trace" or "debug" for verbose output.
|
|
109
|
+
--module <name> Filter to entries whose module tag exactly matches <name>.
|
|
110
|
+
Useful for isolating a specific subsystem (e.g. "cors", "trust").
|
|
111
|
+
--raw Emit raw ndjson — one JSON object per line — instead of the
|
|
112
|
+
formatted table. Useful for piping to jq or other JSON tools.
|
|
113
|
+
-q, --quiet Suppress the column-header line in table output.
|
|
114
|
+
|
|
115
|
+
Output format (default table):
|
|
116
|
+
TIME (24 chars) LEVEL (5 chars) MODULE (up to 12 chars) MESSAGE (truncated at 120 chars)
|
|
117
|
+
|
|
118
|
+
Truncation:
|
|
119
|
+
When more matching entries exist beyond the requested -n window, a dim
|
|
120
|
+
"(showing last N matching entries — earlier entries exist)" footer is printed.
|
|
121
|
+
|
|
122
|
+
Examples:
|
|
123
|
+
$ assistant gateway logs tail
|
|
124
|
+
$ assistant gateway logs tail -n 50 --level warn
|
|
125
|
+
$ assistant gateway logs tail --module cors --raw | jq .msg`,
|
|
126
|
+
)
|
|
127
|
+
.action(async (opts) => {
|
|
128
|
+
const n = Math.max(1, Math.min(1000, parseInt(opts.n ?? "10", 10) || 10));
|
|
129
|
+
const params: Record<string, unknown> = { n };
|
|
130
|
+
if (opts.level && opts.level !== "info") params.level = opts.level;
|
|
131
|
+
if (opts.module) params.module = opts.module;
|
|
132
|
+
|
|
133
|
+
const result = await cliIpcCall<{ lines: PinoEntry[]; truncated: boolean }>(
|
|
134
|
+
"gateway_logs_tail",
|
|
135
|
+
{ body: params },
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (!result.ok) {
|
|
139
|
+
log.error(result.error ?? "Failed to fetch gateway logs");
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const { lines, truncated } = result.result!;
|
|
145
|
+
|
|
146
|
+
if (opts.raw) {
|
|
147
|
+
for (const entry of lines) process.stdout.write(JSON.stringify(entry) + "\n");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (lines.length === 0) {
|
|
152
|
+
if (!opts.quiet) process.stdout.write("No log entries found.\n");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const moduleWidth = Math.min(
|
|
157
|
+
12,
|
|
158
|
+
Math.max(6, ...lines.map((l) => l.module?.length ?? 0)),
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
if (!opts.quiet) {
|
|
162
|
+
process.stdout.write(
|
|
163
|
+
`${"TIME".padEnd(24)} ${"LEVEL".padEnd(5)} ${"MODULE".padEnd(moduleWidth)} MESSAGE\n`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
for (const entry of lines) {
|
|
168
|
+
const time = formatTime(entry.time).padEnd(24);
|
|
169
|
+
const lvlName = levelName(entry.level).padEnd(5);
|
|
170
|
+
const lvlColored = colorLevel(lvlName, entry.level);
|
|
171
|
+
const mod = (entry.module ?? "").padEnd(moduleWidth);
|
|
172
|
+
const msg = entry.msg ?? "";
|
|
173
|
+
const msgTrunc = msg.length > 120 ? msg.slice(0, 120) + "…" : msg;
|
|
174
|
+
process.stdout.write(`${time} ${lvlColored} ${mod} ${msgTrunc}\n`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (truncated) {
|
|
178
|
+
const footer = `(showing last ${n} matching entries — earlier entries exist)`;
|
|
179
|
+
const dim = process.stdout.isTTY ? `\x1b[2m${footer}\x1b[0m` : footer;
|
|
180
|
+
process.stdout.write(dim + "\n");
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
package/src/cli/commands/keys.ts
CHANGED
|
@@ -102,10 +102,12 @@ Examples:
|
|
|
102
102
|
process.exit(1);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
const setResult = await setSecureKeyViaDaemon("api_key", provider, key);
|
|
106
|
+
if (setResult.ok) {
|
|
106
107
|
log.info(`Stored API key for "${provider}"`);
|
|
107
108
|
} else {
|
|
108
|
-
|
|
109
|
+
const detail = setResult.error ? `: ${setResult.error}` : "";
|
|
110
|
+
log.error(`Failed to store API key for "${provider}"${detail}`);
|
|
109
111
|
process.exit(1);
|
|
110
112
|
}
|
|
111
113
|
});
|
|
@@ -133,11 +135,12 @@ Examples:
|
|
|
133
135
|
process.exit(1);
|
|
134
136
|
}
|
|
135
137
|
|
|
136
|
-
const
|
|
137
|
-
if (result === "deleted") {
|
|
138
|
+
const delResult = await deleteSecureKeyViaDaemon("api_key", provider);
|
|
139
|
+
if (delResult.result === "deleted") {
|
|
138
140
|
log.info(`Deleted API key for "${provider}"`);
|
|
139
|
-
} else if (result === "error") {
|
|
140
|
-
|
|
141
|
+
} else if (delResult.result === "error") {
|
|
142
|
+
const detail = delResult.error ? `: ${delResult.error}` : "";
|
|
143
|
+
log.error(`Failed to delete API key for "${provider}"${detail}`);
|
|
141
144
|
process.exit(1);
|
|
142
145
|
} else {
|
|
143
146
|
log.error(`No API key found for "${provider}"`);
|
package/src/cli/commands/mcp.ts
CHANGED
|
@@ -1,24 +1,59 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
|
|
4
|
-
import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
5
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
6
|
-
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
7
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
8
1
|
import type { Command } from "commander";
|
|
9
2
|
|
|
10
3
|
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
11
4
|
import type { McpConfig, McpServerConfig } from "../../config/schemas/mcp.js";
|
|
5
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
12
6
|
import { McpClient } from "../../mcp/client.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
McpOAuthProvider,
|
|
16
|
-
} from "../../mcp/mcp-oauth-provider.js";
|
|
17
|
-
import { getSignalsDir } from "../../util/platform.js";
|
|
7
|
+
import { deleteMcpOAuthCredentials } from "../../mcp/mcp-oauth-provider.js";
|
|
8
|
+
import { openInHostBrowser } from "../../util/browser.js";
|
|
18
9
|
import { log } from "../logger.js";
|
|
19
10
|
|
|
20
11
|
const HEALTH_CHECK_TIMEOUT_MS = 10_000;
|
|
21
12
|
|
|
13
|
+
async function pollMcpAuthStatus(
|
|
14
|
+
serverId: string,
|
|
15
|
+
options: { intervalMs: number; timeoutMs: number },
|
|
16
|
+
): Promise<{ status: "complete" | "error"; error?: string }> {
|
|
17
|
+
const deadline = Date.now() + options.timeoutMs;
|
|
18
|
+
while (Date.now() < deadline) {
|
|
19
|
+
await new Promise<void>((resolve) =>
|
|
20
|
+
setTimeout(resolve, options.intervalMs),
|
|
21
|
+
);
|
|
22
|
+
const result = await cliIpcCall<{ status: string; error?: string }>(
|
|
23
|
+
"internal_mcp_auth_status",
|
|
24
|
+
{ pathParams: { serverId } },
|
|
25
|
+
);
|
|
26
|
+
if (result.ok && result.result?.status === "complete") {
|
|
27
|
+
return { status: "complete" };
|
|
28
|
+
}
|
|
29
|
+
if (result.ok && result.result?.status === "error") {
|
|
30
|
+
return { status: "error", error: result.result.error };
|
|
31
|
+
}
|
|
32
|
+
// The daemon returned an IPC-level error (ok: false) indicating the flow
|
|
33
|
+
// was not found — most likely because the daemon restarted mid-poll and
|
|
34
|
+
// lost the in-memory state. Surface this immediately instead of looping
|
|
35
|
+
// for the full 2.5 minutes and then reporting a generic timeout.
|
|
36
|
+
if (
|
|
37
|
+
!result.ok &&
|
|
38
|
+
result.error &&
|
|
39
|
+
result.error.includes("No active OAuth flow")
|
|
40
|
+
) {
|
|
41
|
+
return {
|
|
42
|
+
status: "error",
|
|
43
|
+
error: `OAuth flow was lost (assistant may have restarted). Run 'assistant mcp auth ${serverId}' to retry.`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Fail fast on any other real IPC error instead of looping for 2.5 minutes
|
|
47
|
+
if (!result.ok && result.error) {
|
|
48
|
+
return { status: "error", error: result.error };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
status: "error",
|
|
53
|
+
error: "OAuth authorization timed out after 2.5 minutes",
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
22
57
|
export async function checkServerHealth(
|
|
23
58
|
serverId: string,
|
|
24
59
|
config: McpServerConfig,
|
|
@@ -66,21 +101,6 @@ export async function checkServerHealth(
|
|
|
66
101
|
}
|
|
67
102
|
}
|
|
68
103
|
|
|
69
|
-
/**
|
|
70
|
-
* Write a signal file so the daemon's ConfigWatcher triggers an MCP reload.
|
|
71
|
-
* Used by `mcp reload`, `mcp auth`, and any operation that needs the daemon
|
|
72
|
-
* to reconnect MCP servers.
|
|
73
|
-
*/
|
|
74
|
-
function signalMcpReload(): void {
|
|
75
|
-
try {
|
|
76
|
-
const signalsDir = getSignalsDir();
|
|
77
|
-
mkdirSync(signalsDir, { recursive: true });
|
|
78
|
-
writeFileSync(join(signalsDir, "mcp-reload"), "");
|
|
79
|
-
} catch {
|
|
80
|
-
// Best-effort — the daemon may not be running or the directory may not exist.
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
104
|
export function registerMcpCommand(program: Command): void {
|
|
85
105
|
const mcp = program
|
|
86
106
|
.command("mcp")
|
|
@@ -290,11 +310,18 @@ Examples:
|
|
|
290
310
|
$ vellum mcp reload # after editing config.json to add a new server
|
|
291
311
|
$ vellum mcp reload # after running "vellum mcp auth <server>"`,
|
|
292
312
|
)
|
|
293
|
-
.action(() => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
313
|
+
.action(async () => {
|
|
314
|
+
const result = await cliIpcCall("internal_mcp_reload", { body: {} });
|
|
315
|
+
if (!result.ok) {
|
|
316
|
+
log.warn(
|
|
317
|
+
`Could not signal reload: ${result.error}. ` +
|
|
318
|
+
`Run 'assistant mcp reload' once the assistant is up.`,
|
|
319
|
+
);
|
|
320
|
+
} else {
|
|
321
|
+
log.info(
|
|
322
|
+
"MCP reload signal sent. The running assistant will reconnect servers shortly.",
|
|
323
|
+
);
|
|
324
|
+
}
|
|
298
325
|
});
|
|
299
326
|
|
|
300
327
|
mcp
|
|
@@ -337,7 +364,7 @@ Examples:
|
|
|
337
364
|
$ assistant mcp add legacy-sse -t sse -u https://old.example.com/events --disabled`,
|
|
338
365
|
)
|
|
339
366
|
.action(
|
|
340
|
-
(
|
|
367
|
+
async (
|
|
341
368
|
name: string,
|
|
342
369
|
opts: {
|
|
343
370
|
transportType: string;
|
|
@@ -411,10 +438,15 @@ Examples:
|
|
|
411
438
|
|
|
412
439
|
saveRawConfig(raw);
|
|
413
440
|
log.info(`Added MCP server "${name}" (${opts.transportType})`);
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
441
|
+
const reloadResult = await cliIpcCall("internal_mcp_reload", { body: {} });
|
|
442
|
+
if (!reloadResult.ok) {
|
|
443
|
+
log.warn(
|
|
444
|
+
`Could not signal reload: ${reloadResult.error}. ` +
|
|
445
|
+
`Run 'assistant mcp reload' once the assistant is up.`,
|
|
446
|
+
);
|
|
447
|
+
} else {
|
|
448
|
+
log.info("The running assistant is reloading MCP servers now.");
|
|
449
|
+
}
|
|
418
450
|
},
|
|
419
451
|
);
|
|
420
452
|
|
|
@@ -428,8 +460,8 @@ Arguments:
|
|
|
428
460
|
name Name of a configured MCP server to authenticate with
|
|
429
461
|
|
|
430
462
|
Only works with sse or streamable-http transports (stdio servers do not use
|
|
431
|
-
OAuth). Opens a browser for OAuth authorization with the remote server
|
|
432
|
-
|
|
463
|
+
OAuth). Opens a browser for OAuth authorization with the remote server. The
|
|
464
|
+
running assistant handles the OAuth callback and token exchange.
|
|
433
465
|
|
|
434
466
|
The command waits up to 2.5 minutes for the user to complete the browser-based
|
|
435
467
|
OAuth flow. If the server already has valid cached tokens, the command succeeds
|
|
@@ -466,141 +498,69 @@ Examples:
|
|
|
466
498
|
return;
|
|
467
499
|
}
|
|
468
500
|
|
|
469
|
-
//
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
process.exitCode = 1;
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
501
|
+
// IPC-first path — attempt daemon-orchestrated flow (works on hosted assistants)
|
|
502
|
+
const startResult = await cliIpcCall<{
|
|
503
|
+
auth_url: string;
|
|
504
|
+
state: string;
|
|
505
|
+
already_authenticated?: boolean;
|
|
506
|
+
}>("internal_mcp_auth_start", { body: { serverId: name } });
|
|
478
507
|
|
|
479
|
-
|
|
480
|
-
name,
|
|
481
|
-
transport.url,
|
|
482
|
-
/* interactive */ true,
|
|
483
|
-
);
|
|
484
|
-
// Clear stale client_info and discovery — the callback server uses a random port,
|
|
485
|
-
// so any previously cached client_info has a mismatched redirect_uri.
|
|
486
|
-
// Preserve tokens so they survive if this auth attempt fails.
|
|
487
|
-
await provider.invalidateCredentials("client");
|
|
488
|
-
await provider.invalidateCredentials("discovery");
|
|
489
|
-
const { codePromise } = await provider.startCallbackServer();
|
|
490
|
-
|
|
491
|
-
const OAUTH_TIMEOUT_MS = 150_000; // 2.5 min for browser interaction
|
|
492
|
-
const TransportClass =
|
|
493
|
-
transport.type === "sse"
|
|
494
|
-
? SSEClientTransport
|
|
495
|
-
: StreamableHTTPClientTransport;
|
|
496
|
-
const mcpTransport = new TransportClass(serverUrl, {
|
|
497
|
-
authProvider: provider,
|
|
498
|
-
requestInit: transport.headers
|
|
499
|
-
? { headers: transport.headers }
|
|
500
|
-
: undefined,
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
const client = new Client({ name: "vellum-assistant", version: "1.0.0" });
|
|
504
|
-
|
|
505
|
-
try {
|
|
506
|
-
// Try connecting — if tokens are already cached, this succeeds immediately
|
|
507
|
-
await client.connect(mcpTransport);
|
|
508
|
-
provider.stopCallbackServer();
|
|
509
|
-
await client.close();
|
|
508
|
+
if (startResult.ok && startResult.result?.already_authenticated) {
|
|
510
509
|
log.info(`Server "${name}" is already authenticated.`);
|
|
510
|
+
process.exit(0);
|
|
511
511
|
return;
|
|
512
|
-
} catch (err) {
|
|
513
|
-
if (!(err instanceof UnauthorizedError)) {
|
|
514
|
-
provider.stopCallbackServer();
|
|
515
|
-
try {
|
|
516
|
-
await client.close();
|
|
517
|
-
} catch {
|
|
518
|
-
/* ignore */
|
|
519
|
-
}
|
|
520
|
-
log.error(`Failed to connect to "${name}": ${err}`);
|
|
521
|
-
process.exitCode = 1;
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
512
|
}
|
|
525
513
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
514
|
+
if (startResult.ok && startResult.result?.auth_url) {
|
|
515
|
+
const authUrl = startResult.result.auth_url;
|
|
516
|
+
log.info(`Opening browser for "${name}" OAuth authorization...`);
|
|
517
|
+
await openInHostBrowser(authUrl);
|
|
518
|
+
log.info(`If the browser did not open, visit:\n${authUrl}`);
|
|
519
|
+
log.info(
|
|
520
|
+
"Waiting for authorization in browser... (press Ctrl+C to cancel)",
|
|
521
|
+
);
|
|
531
522
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
);
|
|
545
|
-
if (typeof oauthTimer === "object" && "unref" in oauthTimer)
|
|
546
|
-
oauthTimer.unref();
|
|
547
|
-
}),
|
|
548
|
-
]);
|
|
549
|
-
clearTimeout(oauthTimer);
|
|
550
|
-
} catch (err) {
|
|
551
|
-
clearTimeout(oauthTimer);
|
|
552
|
-
provider.stopCallbackServer();
|
|
553
|
-
try {
|
|
554
|
-
await client.close();
|
|
555
|
-
} catch {
|
|
556
|
-
/* ignore */
|
|
523
|
+
const finalStatus = await pollMcpAuthStatus(name, {
|
|
524
|
+
intervalMs: 2_000,
|
|
525
|
+
timeoutMs: 150_000, // matches existing OAUTH_TIMEOUT_MS
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
if (finalStatus.status === "complete") {
|
|
529
|
+
log.info(`Authentication successful for "${name}".`);
|
|
530
|
+
log.info(
|
|
531
|
+
"The running assistant has picked up this change automatically.",
|
|
532
|
+
);
|
|
533
|
+
process.exit(0);
|
|
534
|
+
return;
|
|
557
535
|
}
|
|
558
|
-
|
|
559
|
-
|
|
536
|
+
|
|
537
|
+
const errMsg = finalStatus.error ?? "Unknown error";
|
|
538
|
+
if (errMsg.includes("denied") || errMsg.includes("cancelled")) {
|
|
560
539
|
log.error(`Authorization cancelled for "${name}".`);
|
|
561
|
-
} else if (
|
|
540
|
+
} else if (errMsg.includes("timed out")) {
|
|
562
541
|
log.error(
|
|
563
542
|
`Authorization timed out for "${name}". Try again with: assistant mcp auth ${name}`,
|
|
564
543
|
);
|
|
565
544
|
} else {
|
|
566
|
-
log.error(`
|
|
567
|
-
}
|
|
568
|
-
process.exitCode = 1;
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
log.info("Authorization received. Exchanging token...");
|
|
573
|
-
|
|
574
|
-
// Exchange auth code for tokens
|
|
575
|
-
try {
|
|
576
|
-
await mcpTransport.finishAuth(code);
|
|
577
|
-
} catch (err) {
|
|
578
|
-
provider.stopCallbackServer();
|
|
579
|
-
try {
|
|
580
|
-
await client.close();
|
|
581
|
-
} catch {
|
|
582
|
-
/* ignore */
|
|
545
|
+
log.error(`OAuth failed for "${name}": ${errMsg}`);
|
|
583
546
|
}
|
|
584
|
-
log.error(`Token exchange failed for "${name}": ${err}`);
|
|
585
547
|
process.exitCode = 1;
|
|
586
548
|
return;
|
|
587
549
|
}
|
|
588
550
|
|
|
589
|
-
//
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
551
|
+
// Any !startResult.ok case: surface error and exit 1
|
|
552
|
+
const ipcErrMsg = startResult.error ?? "Unknown error";
|
|
553
|
+
if (
|
|
554
|
+
ipcErrMsg.startsWith("Could not connect to assistant daemon") ||
|
|
555
|
+
ipcErrMsg.startsWith("Unknown method:")
|
|
556
|
+
) {
|
|
557
|
+
log.error(
|
|
558
|
+
`MCP OAuth requires the assistant to be running. Is it running?`,
|
|
559
|
+
);
|
|
560
|
+
} else {
|
|
561
|
+
log.error(`MCP OAuth failed via assistant: ${ipcErrMsg}`);
|
|
594
562
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
log.info(`Authentication successful for "${name}".`);
|
|
598
|
-
log.info(
|
|
599
|
-
"The running assistant will pick up this change automatically. " +
|
|
600
|
-
"Or run 'vellum mcp reload' to apply now.",
|
|
601
|
-
);
|
|
602
|
-
signalMcpReload();
|
|
603
|
-
process.exit(0);
|
|
563
|
+
process.exitCode = 1;
|
|
604
564
|
});
|
|
605
565
|
|
|
606
566
|
mcp
|