@vellumai/assistant 0.12.1 → 0.12.2-dev.202609162214.308bda0
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/.env.example +2 -0
- package/AGENTS.md +5 -1
- package/ARCHITECTURE.md +20 -21
- package/Dockerfile +7 -7
- package/docs/architecture/integrations.md +7 -0
- package/docs/architecture/memory.md +11 -2
- package/docs/architecture/turn-actor.md +15 -8
- package/docs/credential-execution-service.md +1 -1
- package/docs/desktop-browser-cli.md +35 -0
- package/docs/guardian-request-flow.md +16 -0
- package/node_modules/@vellumai/environments/src/shell.test.ts +21 -0
- package/node_modules/@vellumai/environments/src/shell.ts +24 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -2
- package/node_modules/@vellumai/slack-text/src/index.ts +13 -8
- package/node_modules/@vellumai/slack-text/src/label-resolution-entities.test.ts +95 -0
- package/openapi.yaml +564 -111
- package/package.json +7 -4
- package/scripts/bundled-plugin-packages.ts +154 -0
- package/scripts/generate-bundled-plugin-packages.ts +29 -0
- package/scripts/postinstall.ts +33 -0
- package/scripts/smoke-desktop-browser-cli.ts +280 -0
- package/scripts/smoke-desktop-window-theme.ts +186 -0
- package/scripts/sync-llm-catalog.ts +3 -0
- package/scripts/test.ts +15 -13
- package/scripts/voice-ttft-spike.ts +2 -2
- package/src/__tests__/agent-loop.test.ts +124 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +18 -10
- package/src/__tests__/anthropic-provider.test.ts +0 -63
- package/src/__tests__/app-compiler.test.ts +6 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +5 -2
- package/src/__tests__/app-dir-path-guard.test.ts +1 -3
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +6 -7
- package/src/__tests__/assistant-event-hub.test.ts +44 -0
- package/src/__tests__/attachments-store.test.ts +22 -3
- package/src/__tests__/channel-approval.test.ts +9 -14
- package/src/__tests__/channel-reply-delivery.test.ts +56 -0
- package/src/__tests__/computer-use-screenshot-attachments.test.ts +411 -0
- package/src/__tests__/computer-use-screenshot-selection.test.ts +50 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +5 -2
- package/src/__tests__/computer-use-tools.test.ts +19 -7
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +29 -30
- package/src/__tests__/config-sounds-sync.test.ts +23 -0
- package/src/__tests__/config-watcher.test.ts +23 -8
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +257 -6
- package/src/__tests__/conversation-attachments.test.ts +106 -0
- package/src/__tests__/conversation-error.test.ts +4 -1
- package/src/__tests__/conversation-fork-crud.test.ts +191 -0
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +26 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -10
- package/src/__tests__/conversation-queue.test.ts +48 -207
- package/src/__tests__/conversation-retry-discard.test.ts +54 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +33 -3
- package/src/__tests__/conversation-skill-tools.test.ts +27 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +8 -3
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-point-at-capability.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-title-service.test.ts +14 -10
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +3 -5
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +51 -0
- package/src/__tests__/credential-execution-client.test.ts +70 -53
- package/src/__tests__/credential-record-retire.test.ts +171 -1
- package/src/__tests__/credential-routes.test.ts +250 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/cu-unified-flow.test.ts +14 -4
- package/src/__tests__/db-conversation-tool-surface.test.ts +144 -0
- package/src/__tests__/document-sync-tags.test.ts +25 -0
- package/src/__tests__/drain-kick-guard.test.ts +0 -2
- package/src/__tests__/drain-requeue-on-contention.test.ts +0 -6
- package/src/__tests__/events-tail-route.test.ts +33 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/external-plugin-loader.test.ts +52 -0
- package/src/__tests__/git-porcelain.test.ts +47 -0
- package/src/__tests__/headless-browser-mode.test.ts +48 -0
- package/src/__tests__/heartbeat-service.test.ts +56 -40
- package/src/__tests__/helpers/set-workspace-mcp.ts +11 -0
- package/src/__tests__/host-bash-proxy.test.ts +26 -45
- package/src/__tests__/host-browser-proxy.test.ts +6 -17
- package/src/__tests__/host-cu-proxy.test.ts +712 -18
- package/src/__tests__/host-file-proxy-targeted.test.ts +23 -0
- package/src/__tests__/host-file-proxy.test.ts +11 -23
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +30 -9
- package/src/__tests__/inference-profile-session-handler.test.ts +26 -0
- package/src/__tests__/list-all-apps.test.ts +40 -8
- package/src/__tests__/list-messages-camera-frame.test.ts +121 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +85 -1
- package/src/__tests__/llm-catalog-parity.test.ts +51 -3
- package/src/__tests__/managed-store.test.ts +121 -0
- package/src/__tests__/mcp-auth-routes.test.ts +104 -8
- package/src/__tests__/mcp-client-auth.test.ts +54 -0
- package/src/__tests__/mcp-config-secret-boundary.test.ts +78 -136
- package/src/__tests__/mcp-health-check.test.ts +40 -43
- package/src/__tests__/mcp-list-plugin-servers.test.ts +85 -42
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +4 -2
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +119 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +91 -0
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +355 -548
- package/src/__tests__/model-intents.test.ts +3 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +85 -2
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-commands-routes.test.ts +282 -101
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +18 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +23 -0
- package/src/__tests__/oauth-providers-routes.test.ts +3 -0
- package/src/__tests__/openai-provider.test.ts +1 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/persist-media-references.test.ts +50 -0
- package/src/__tests__/platform-callback-registration.test.ts +8 -16
- package/src/__tests__/platform-client-verify-credential.test.ts +2 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +13 -0
- package/src/__tests__/qdrant-manager.test.ts +132 -0
- package/src/__tests__/resolve-app.test.ts +135 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +138 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +317 -6
- package/src/__tests__/schedule-routes.test.ts +20 -0
- package/src/__tests__/scheduler-result-notification.test.ts +23 -4
- package/src/__tests__/script-proxy-certs.test.ts +35 -0
- package/src/__tests__/secret-routes-acp-guard.test.ts +59 -1
- package/src/__tests__/secret-routes-platform-proxy.test.ts +86 -31
- package/src/__tests__/secret-routes-scrub.test.ts +22 -27
- package/src/__tests__/secure-keys-managed-failover.test.ts +8 -0
- package/src/__tests__/secure-keys.test.ts +7 -3
- package/src/__tests__/service-account-token.test.ts +247 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skills.test.ts +20 -4
- package/src/__tests__/source-fingerprint.test.ts +184 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +239 -3
- package/src/__tests__/subagent-tools.test.ts +3 -2
- package/src/__tests__/telephony-tts-guard.test.ts +38 -3
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +63 -0
- package/src/__tests__/ui-channel-variants.test.ts +1 -56
- package/src/__tests__/unicode.test.ts +49 -0
- package/src/__tests__/user-plugin-loader.test.ts +21 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +4 -0
- package/src/__tests__/watch-retro-tool-availability.test.ts +8 -17
- package/src/__tests__/workspace-git-service.test.ts +26 -0
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +336 -0
- package/src/acp/__tests__/acp-claude-oauth.test.ts +257 -6
- package/src/acp/__tests__/acp-credentials.test.ts +13 -0
- package/src/acp/__tests__/agent-process.test.ts +258 -4
- package/src/acp/__tests__/auth-required.test.ts +96 -0
- package/src/acp/__tests__/claude-token-refresh.test.ts +257 -0
- package/src/acp/__tests__/client-handler.test.ts +90 -2
- package/src/acp/__tests__/helpers/acp-model-option.ts +51 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +60 -1
- package/src/acp/__tests__/session-manager-persistence.test.ts +5 -1
- package/src/acp/__tests__/session-manager-resume.test.ts +270 -6
- package/src/acp/__tests__/session-manager-usage.test.ts +4 -2
- package/src/acp/__tests__/session-manager.test.ts +895 -4
- package/src/acp/acp-claude-oauth.ts +328 -14
- package/src/acp/acp-credentials.ts +19 -0
- package/src/acp/agent-process.test.ts +4 -1
- package/src/acp/agent-process.ts +96 -10
- package/src/acp/auth-required.ts +50 -1
- package/src/acp/auto-install.test.ts +9 -7
- package/src/acp/claude-token-refresh.ts +150 -0
- package/src/acp/client-handler.ts +16 -3
- package/src/acp/model-config.test.ts +166 -0
- package/src/acp/model-config.ts +138 -0
- package/src/acp/prepare-agent-env.ts +21 -6
- package/src/acp/resolve-agent.test.ts +220 -6
- package/src/acp/resolve-agent.ts +88 -23
- package/src/acp/session-manager.test.ts +196 -3
- package/src/acp/session-manager.ts +441 -18
- package/src/acp/session-snapshot.ts +260 -0
- package/src/acp/types.ts +50 -5
- package/src/agent/loop.ts +20 -0
- package/src/api/attachment-provenance.test.ts +68 -0
- package/src/api/computer-use-tool.test.ts +55 -0
- package/src/api/computer-use-tool.ts +27 -0
- package/src/api/events/acp-session-model-update.test.ts +88 -0
- package/src/api/events/acp-session-model-update.ts +46 -0
- package/src/api/events/app-files-changed.ts +4 -3
- package/src/api/events/assistant-outbound-attachment.ts +3 -0
- package/src/api/events/desktop-activity-changed.ts +10 -0
- package/src/api/events/notification-intent.ts +2 -0
- package/src/api/events/user-message-echo.ts +7 -1
- package/src/api/index.ts +17 -0
- package/src/api/responses/conversation-message.ts +8 -0
- package/src/approvals/approval-primitive.ts +5 -2
- package/src/approvals/scoped-approval-grants.ts +6 -2
- package/src/apps/app-store.ts +7 -6
- package/src/apps/resolve-app.ts +81 -0
- package/src/apps/source-fingerprint.ts +266 -0
- package/src/avatar/identity-avatar.ts +7 -2
- package/src/browser/operations.ts +2 -1
- package/src/browser/types.ts +7 -0
- package/src/browser/virtual-desktop-target.ts +34 -0
- package/src/bundler/app-compiler.ts +15 -0
- package/src/calls/__tests__/barge-in-guard.test.ts +81 -0
- package/src/{__tests__ → calls/__tests__}/call-controller.test.ts +503 -82
- package/src/{__tests__ → calls/__tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-output.test.ts +37 -8
- package/src/{__tests__ → calls/__tests__}/media-stream-parser.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-server-integration.test.ts +150 -57
- package/src/{__tests__ → calls/__tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{__tests__ → calls/__tests__}/media-turn-detector.test.ts +1 -1
- package/src/{live-voice → calls}/__tests__/progress-narration.test.ts +27 -4
- package/src/{live-voice → calls}/__tests__/progress-phrases.test.ts +1 -1
- package/src/calls/__tests__/voice-control-protocol.test.ts +151 -27
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +229 -0
- package/src/calls/__tests__/voice-progress-cadence.test.ts +274 -0
- package/src/{__tests__/voice-session-bridge.test.ts → calls/__tests__/voice-session-bridge-turn-flow.test.ts} +20 -12
- package/src/calls/__tests__/voice-session-bridge.test.ts +140 -3
- package/src/calls/__tests__/voice-triage-escalate.test.ts +105 -0
- package/src/calls/barge-in-guard.ts +118 -0
- package/src/calls/call-constants.ts +24 -4
- package/src/calls/call-controller.ts +499 -199
- package/src/calls/call-transport.ts +16 -0
- package/src/calls/media-stream-output.ts +32 -0
- package/src/calls/media-stream-server.ts +82 -30
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/{live-voice → calls}/progress-narration.ts +17 -4
- package/src/calls/resolve-call-tts-provider.ts +33 -2
- package/src/calls/tts-call-strategy.ts +9 -5
- package/src/calls/types.ts +2 -0
- package/src/calls/voice-control-protocol.ts +194 -21
- package/src/calls/voice-leg-coordinator.ts +189 -0
- package/src/calls/voice-progress-cadence.ts +423 -0
- package/src/calls/voice-session-bridge.ts +140 -76
- package/src/calls/voice-triage-escalate.ts +178 -59
- package/src/cli/commands/__tests__/apps.test.ts +245 -0
- package/src/cli/commands/__tests__/bash.test.ts +53 -0
- package/src/cli/commands/__tests__/browser.test.ts +84 -3
- package/src/cli/commands/__tests__/cli-test-harness.ts +21 -3
- package/src/cli/commands/__tests__/plugins.test.ts +85 -0
- package/src/cli/commands/__tests__/roadmap.help.test.ts +19 -0
- package/src/cli/commands/__tests__/schedules.test.ts +14 -0
- package/src/cli/commands/apps.help.ts +67 -13
- package/src/cli/commands/apps.ts +183 -0
- package/src/cli/commands/bash.help.ts +9 -13
- package/src/cli/commands/bash.ts +7 -25
- package/src/cli/commands/browser.help.ts +43 -0
- package/src/cli/commands/browser.ts +52 -8
- package/src/cli/commands/channels/__tests__/send.test.ts +218 -0
- package/src/cli/commands/channels/index.help.ts +70 -2
- package/src/cli/commands/channels/index.ts +16 -3
- package/src/cli/commands/channels/send.ts +128 -0
- package/src/cli/commands/credentials.help.ts +9 -5
- package/src/cli/commands/credentials.ts +2 -2
- package/src/cli/commands/mcp.help.ts +8 -8
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/oauth/index.help.ts +10 -0
- package/src/cli/commands/oauth/providers.ts +12 -0
- package/src/cli/commands/oauth/request.test.ts +179 -2
- package/src/cli/commands/oauth/request.ts +41 -10
- package/src/cli/commands/oauth/status.ts +5 -0
- package/src/cli/commands/plugins.ts +73 -23
- package/src/cli/commands/roadmap.help.ts +5 -1
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/commands/schedules.ts +2 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +219 -0
- package/src/cli/lib/__tests__/install-from-platform.test.ts +77 -2
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +45 -3
- package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +251 -0
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +65 -2
- package/src/cli/lib/__tests__/plugin-catalog-platform.test.ts +14 -0
- package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +27 -1
- package/src/cli/lib/__tests__/plugin-details.test.ts +35 -2
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +20 -0
- package/src/cli/lib/__tests__/plugins-install-offline.test.ts +43 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +31 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +122 -5
- package/src/cli/lib/bundled-marketplace.json +962 -81
- package/src/cli/lib/bundled-plugin-packages.json +786 -0
- package/src/cli/lib/bundled-plugin-packages.ts +87 -0
- package/src/cli/lib/diff-plugin.ts +1 -1
- package/src/cli/lib/inspect-plugin.ts +87 -12
- package/src/cli/lib/install-from-github.ts +150 -94
- package/src/cli/lib/install-from-platform.ts +14 -9
- package/src/cli/lib/list-installed-plugins.ts +21 -35
- package/src/cli/lib/plugin-catalog-cache.ts +22 -3
- package/src/cli/lib/plugin-catalog-local.ts +13 -3
- package/src/cli/lib/plugin-catalog-platform.ts +6 -1
- package/src/cli/lib/plugin-catalog-resolve.ts +20 -0
- package/src/cli/lib/plugin-details.ts +33 -8
- package/src/cli/lib/plugin-marketplace.ts +121 -21
- package/src/cli/lib/plugin-pin-history.ts +5 -2
- package/src/cli/lib/search-plugins.ts +58 -16
- package/src/cli/lib/uninstall-plugin.ts +59 -1
- package/src/cli/lib/upgrade-plugin.ts +61 -8
- package/src/cli/output.ts +18 -4
- package/src/config/__tests__/default-profile-catalog.test.ts +22 -0
- package/src/config/__tests__/default-provider.test.ts +4 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +15 -1
- package/src/config/__tests__/platform-identity.test.ts +255 -0
- package/src/config/__tests__/platform-rehydration.test.ts +99 -9
- package/src/config/__tests__/plugin-resident-skill-discovery.test.ts +21 -0
- package/src/config/acp-agent-write.ts +43 -0
- package/src/config/acp-defaults.test.ts +13 -3
- package/src/config/acp-defaults.ts +23 -6
- package/src/config/acp-schema.test.ts +81 -0
- package/src/config/acp-schema.ts +30 -2
- package/src/config/bundled-skills/acp/SKILL.md +23 -15
- package/src/config/bundled-skills/acp/TOOLS.json +7 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +12 -9
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +59 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +101 -2
- package/src/config/bundled-skills/computer-use/tools/computer-use-sequence.ts +12 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -1
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -1
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -1
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +67 -139
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -1
- package/src/config/bundled-skills/schedule/SKILL.md +7 -8
- package/src/config/bundled-skills/screen-annotation/SKILL.md +10 -3
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +4 -1
- package/src/config/bundled-skills/skill-management/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +13 -9
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +5 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +33 -13
- package/src/config/loader.ts +11 -17
- package/src/config/memory-v3-gate.test.ts +31 -0
- package/src/config/memory-v3-gate.ts +20 -16
- package/src/config/platform-identity.ts +201 -0
- package/src/config/platform-rehydration.ts +11 -27
- package/src/config/profile-text-generation.test.ts +51 -0
- package/src/config/profile-text-generation.ts +51 -0
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +8 -158
- package/src/config/schemas/__tests__/voice.test.ts +148 -0
- package/src/config/schemas/calls.ts +1 -28
- package/src/config/schemas/live-voice.ts +1 -173
- package/src/config/schemas/llm.ts +7 -2
- package/src/config/schemas/mcp.ts +15 -9
- package/src/config/schemas/memory-retrospective.ts +10 -0
- package/src/config/schemas/monitoring.ts +9 -0
- package/src/config/schemas/services.ts +18 -0
- package/src/config/schemas/skills.ts +0 -14
- package/src/config/schemas/voice.ts +150 -0
- package/src/config/skills.ts +13 -21
- package/src/credential-execution/ces-runtime.ts +2 -2
- package/src/credential-execution/executable-discovery.ts +36 -134
- package/src/credential-execution/process-manager.test.ts +37 -42
- package/src/credential-execution/process-manager.ts +24 -19
- package/src/credential-health/credential-health-service.ts +11 -17
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +47 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -121
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +5 -1
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +133 -0
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +36 -0
- package/src/daemon/app-change-notify.ts +45 -0
- package/src/daemon/assistant-attachments.ts +20 -12
- package/src/daemon/config-watcher.ts +13 -194
- package/src/daemon/conversation-agent-loop-handlers.ts +74 -3
- package/src/daemon/conversation-agent-loop.ts +12 -0
- package/src/daemon/conversation-attachments.ts +93 -12
- package/src/daemon/conversation-client-surface.ts +26 -0
- package/src/daemon/conversation-error.ts +3 -2
- package/src/daemon/conversation-media-retry.ts +2 -1
- package/src/daemon/conversation-process.ts +35 -64
- package/src/daemon/conversation-runtime-assembly.ts +21 -8
- package/src/daemon/conversation-skill-tools.ts +13 -31
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +21 -10
- package/src/daemon/conversation-tool-setup.ts +135 -109
- package/src/daemon/conversation-turn-finalize.ts +26 -13
- package/src/daemon/conversation.ts +17 -3
- package/src/daemon/daemon-control.ts +3 -7
- package/src/daemon/dictation-profile-store.ts +2 -1
- package/src/daemon/handlers/shared.ts +2 -1
- package/src/daemon/handlers/skills.ts +6 -3
- package/src/daemon/host-bash-proxy.ts +8 -12
- package/src/daemon/host-browser-proxy.ts +15 -1
- package/src/daemon/host-cu-proxy.ts +275 -45
- package/src/daemon/host-file-proxy.ts +8 -10
- package/src/daemon/host-proxy-preactivation.ts +4 -1
- package/src/daemon/host-transfer-proxy.ts +14 -18
- package/src/daemon/lifecycle.ts +4 -9
- package/src/daemon/mcp-reload-service.ts +13 -6
- package/src/daemon/message-types/shared.ts +1 -0
- package/src/daemon/message-types/sync.ts +2 -0
- package/src/daemon/orphan-reaper.ts +4 -3
- package/src/daemon/persist-media-references.ts +20 -3
- package/src/daemon/providers-setup.ts +5 -1
- package/src/daemon/reaction-history-render.ts +2 -1
- package/src/daemon/shutdown-handlers.ts +1 -9
- package/src/daemon/skill-memory-refresh.ts +64 -0
- package/src/daemon/tool-setup-types.ts +6 -0
- package/src/daemon/tool-side-effects.ts +7 -18
- package/src/daemon/wake-conversation-ops.ts +38 -15
- package/src/desktop/__tests__/fake-desktop.ts +123 -0
- package/src/desktop/desktop-automation-lease.test.ts +351 -0
- package/src/desktop/desktop-automation-lease.ts +306 -0
- package/src/desktop/desktop-browser-client.test.ts +413 -0
- package/src/desktop/desktop-browser-client.ts +430 -0
- package/src/desktop/desktop-browser-cursor.ts +40 -0
- package/src/desktop/desktop-browser-endpoint.test.ts +78 -0
- package/src/desktop/desktop-browser-endpoint.ts +145 -0
- package/src/desktop/desktop-browser-operations.ts +130 -0
- package/src/desktop/desktop-chrome-policy.test.ts +79 -0
- package/src/desktop/desktop-chrome-policy.ts +47 -0
- package/src/desktop/desktop-chrome-session.test.ts +48 -0
- package/src/desktop/desktop-chrome-session.ts +87 -0
- package/src/desktop/desktop-dependencies.test.ts +131 -0
- package/src/desktop/desktop-dependencies.ts +329 -0
- package/src/desktop/desktop-display.ts +9 -0
- package/src/desktop/desktop-panel-config.test.ts +135 -0
- package/src/desktop/desktop-panel-config.ts +162 -0
- package/src/desktop/desktop-session-manager.test.ts +813 -0
- package/src/desktop/desktop-session-manager.ts +970 -0
- package/src/desktop/desktop-stream-bridge.test.ts +395 -0
- package/src/desktop/desktop-stream-bridge.ts +214 -0
- package/src/desktop/desktop-wallpaper.test.ts +191 -0
- package/src/desktop/desktop-wallpaper.ts +113 -0
- package/src/desktop/desktop-window-drag.ts +177 -0
- package/src/desktop/desktop-window-manager-config.test.ts +230 -0
- package/src/desktop/desktop-window-manager-config.ts +238 -0
- package/src/desktop/desktop-window-theme.ts +170 -0
- package/src/desktop/virtual-desktop-feature.ts +18 -0
- package/src/desktop/virtual-desktop-platform.test.ts +61 -0
- package/src/heartbeat/heartbeat-service.ts +21 -3
- package/src/home/__tests__/feed-writer.test.ts +22 -0
- package/src/home/feed-writer.ts +11 -2
- package/src/hooks/types.ts +33 -0
- package/src/i18n/AGENTS.md +22 -0
- package/src/i18n/__tests__/i18n.test.ts +112 -0
- package/src/i18n/index.ts +16 -0
- package/src/i18n/locales.ts +93 -0
- package/src/i18n/messages.ts +70 -0
- package/src/i18n/title.ts +25 -0
- package/src/inbound/platform-callback-registration.ts +4 -5
- package/src/ipc/__tests__/browser-ipc.test.ts +230 -2
- package/src/ipc/__tests__/cancel-on-disconnect.test.ts +54 -0
- package/src/ipc/assistant-server.ts +15 -1
- package/src/ipc/cli-client.ts +13 -5
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +143 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +9 -7
- package/src/live-voice/__tests__/live-voice-look-follow-up.test.ts +374 -0
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +0 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +94 -15
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +19 -0
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +238 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +660 -5
- package/src/live-voice/__tests__/protocol.test.ts +95 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
- package/src/live-voice/__tests__/session-controls.test.ts +156 -0
- package/src/live-voice/live-voice-metrics.ts +9 -0
- package/src/live-voice/live-voice-photo.ts +25 -6
- package/src/live-voice/live-voice-session.ts +1081 -760
- package/src/live-voice/protocol.ts +89 -2
- package/src/live-voice/session-controls.ts +197 -0
- package/src/mcp/__tests__/credential-target.test.ts +59 -0
- package/src/mcp/__tests__/effective-config.test.ts +13 -2
- package/src/mcp/__tests__/manager-state.test.ts +128 -0
- package/src/mcp/__tests__/manager-tool-caps.test.ts +111 -0
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +20 -6
- package/src/mcp/__tests__/mcp-auth-state-target.test.ts +49 -0
- package/src/mcp/__tests__/plugin-mcp-oauth-cleanup.test.ts +107 -0
- package/src/mcp/__tests__/plugin-mcp-oauth-provider-isolation.test.ts +89 -0
- package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +63 -11
- package/src/mcp/__tests__/reload-signal-emission.test.ts +39 -2
- package/src/mcp/__tests__/startup.test.ts +30 -7
- package/src/mcp/__tests__/tool-caps.test.ts +107 -0
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +135 -0
- package/src/mcp/client.ts +64 -16
- package/src/mcp/credential-target.ts +105 -0
- package/src/mcp/effective-config.ts +45 -18
- package/src/mcp/manager.ts +201 -81
- package/src/mcp/mcp-auth-orchestrator.ts +17 -4
- package/src/mcp/mcp-auth-state.ts +38 -6
- package/src/mcp/mcp-header-store.ts +29 -45
- package/src/mcp/mcp-oauth-provider.ts +101 -33
- package/src/mcp/spec-schema.ts +111 -0
- package/src/mcp/startup.ts +41 -17
- package/src/mcp/tool-caps.ts +176 -0
- package/src/mcp/workspace-mcp-config.ts +188 -0
- package/src/messaging/provider-message-metadata.ts +3 -3
- package/src/messaging/provider.ts +10 -3
- package/src/messaging/providers/__tests__/proactive-address.test.ts +95 -0
- package/src/messaging/providers/callback-routing.ts +18 -0
- package/src/messaging/providers/channel-transport.ts +56 -0
- package/src/messaging/providers/discord/transport.ts +17 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +6 -17
- package/src/messaging/providers/slack/adapter.ts +7 -44
- package/src/messaging/providers/slack/transport.ts +16 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -48
- package/src/messaging/providers/telegram-bot/client.ts +0 -26
- package/src/messaging/providers/telegram-bot/transport.ts +20 -0
- package/src/messaging/providers/whatsapp/adapter.ts +1 -48
- package/src/messaging/providers/whatsapp/transport.ts +18 -0
- package/src/monitoring/__tests__/mount-watch.test.ts +236 -0
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +8 -0
- package/src/monitoring/mount-watch.ts +348 -0
- package/src/monitoring/plugin-auto-update.ts +6 -0
- package/src/monitoring/worker.ts +9 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +55 -0
- package/src/notifications/__tests__/copy-composer.test.ts +70 -0
- package/src/notifications/__tests__/decision-engine.test.ts +175 -0
- package/src/notifications/__tests__/guardian-feed-projection.test.ts +158 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +153 -3
- package/src/notifications/__tests__/schedule-result-producer.test.ts +99 -3
- package/src/notifications/adapters/macos.ts +3 -0
- package/src/notifications/assistant-reply-producer.ts +8 -3
- package/src/notifications/conversation-pairing.ts +36 -16
- package/src/notifications/copy-composer.ts +11 -3
- package/src/notifications/decision-engine.ts +43 -8
- package/src/notifications/delivered-post-record.ts +11 -1
- package/src/notifications/guardian-feed-projection.ts +125 -5
- package/src/notifications/home-feed-side-effect.ts +55 -7
- package/src/notifications/schedule-result-producer.ts +64 -22
- package/src/oauth/AGENTS.md +4 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +36 -1
- package/src/oauth/__tests__/seed-providers-managed.test.ts +149 -0
- package/src/oauth/byo-connection.test.ts +105 -0
- package/src/oauth/byo-connection.ts +36 -6
- package/src/oauth/connection-resolver.test.ts +100 -0
- package/src/oauth/connection-resolver.ts +120 -3
- package/src/oauth/identity-verifier.ts +24 -0
- package/src/oauth/oauth-store.ts +11 -1
- package/src/oauth/provider-serializer.ts +10 -0
- package/src/oauth/scope-utils.ts +24 -0
- package/src/oauth/seed-providers.ts +367 -27
- package/src/onboarding/checkin-event.ts +2 -1
- package/src/outbound-proxy/certs.ts +3 -5
- package/src/permissions/checker.test.ts +11 -6
- package/src/permissions/confirmation-guardian-request.test.ts +16 -0
- package/src/permissions/confirmation-guardian-request.ts +2 -3
- package/src/persistence/attachments-store.ts +84 -44
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +182 -83
- package/src/persistence/conversation-lineage.ts +12 -4
- package/src/persistence/conversation-plugin-facade.ts +13 -0
- package/src/persistence/conversation-queries.ts +2 -2
- package/src/persistence/conversation-title-placeholders.ts +23 -0
- package/src/persistence/conversation-title-service.ts +9 -26
- package/src/persistence/conversation-tool-surface.ts +86 -0
- package/src/persistence/conversation-types.test.ts +32 -0
- package/src/persistence/conversation-types.ts +26 -4
- package/src/persistence/embeddings/qdrant-manager.ts +163 -18
- package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
- package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
- package/src/persistence/message-cursor.ts +78 -0
- package/src/persistence/message-reads.ts +30 -0
- package/src/persistence/migrations/157-invite-contact-id.ts +18 -6
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.test.ts +78 -0
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.ts +29 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.test.ts +92 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.ts +32 -0
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +149 -0
- package/src/persistence/schema/conversation-tool-surfaces.ts +22 -0
- package/src/persistence/schema/index.ts +1 -0
- package/src/persistence/schema/memory-core.ts +5 -0
- package/src/persistence/schema/oauth.ts +1 -0
- package/src/persistence/steps.ts +15 -3
- package/src/platform/client.test.ts +4 -2
- package/src/platform/client.ts +2 -10
- package/src/plugin-api/constants.ts +2 -0
- package/src/plugin-api/conversation-turn.ts +31 -7
- package/src/plugin-api/index.ts +10 -1
- package/src/plugin-api/plugin-channel-turn-trust.test.ts +133 -0
- package/src/plugin-api/plugin-channel-turn-trust.ts +71 -0
- package/src/plugin-api/types.ts +2 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +14 -1
- package/src/plugins/__tests__/mcp-servers.test.ts +38 -8
- package/src/plugins/defaults/index.ts +2 -0
- package/src/plugins/defaults/memory/AGENTS.md +14 -2
- package/src/plugins/defaults/memory/__tests__/buffer-file.test.ts +365 -0
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +43 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/buffer-appender.ts +17 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +46 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +118 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +83 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +9 -5
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +66 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +20 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +219 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +31 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +63 -0
- package/src/plugins/defaults/memory/__tests__/memory-run-evidence.test.ts +161 -0
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +4 -0
- package/src/plugins/defaults/memory/buffer-file.ts +354 -0
- package/src/plugins/defaults/memory/buffer-format.ts +40 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +3 -3
- package/src/plugins/defaults/memory/context-search/format.ts +4 -2
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +7 -3
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +4 -2
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -8
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -42
- package/src/plugins/defaults/memory/hooks/init.ts +10 -0
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +21 -0
- package/src/plugins/defaults/memory/hooks/shutdown.ts +2 -0
- package/src/plugins/defaults/memory/injectors.ts +4 -3
- package/src/plugins/defaults/memory/jobs-worker.ts +13 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +34 -60
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +126 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +79 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +28 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +3 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +67 -184
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +312 -71
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +2 -1
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +5 -3
- package/src/plugins/defaults/memory/memory-run-evidence.ts +213 -0
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +9 -0
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +1 -1
- package/src/plugins/defaults/memory/startup.ts +28 -2
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +407 -99
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +10 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +107 -7
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +7 -9
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +307 -86
- package/src/plugins/defaults/memory/substrate/consolidation-tool-surface.ts +34 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +7 -1
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +89 -49
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +4 -1
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +4 -1
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +5 -0
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +5 -2
- package/src/plugins/defaults/memory/v2/reranker.ts +7 -1
- package/src/plugins/defaults/memory/v3/__tests__/card.test.ts +24 -0
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +81 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +87 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +125 -0
- package/src/plugins/defaults/memory/v3/__tests__/sections.test.ts +26 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +51 -0
- package/src/plugins/defaults/memory/v3/card.ts +4 -2
- package/src/plugins/defaults/memory/v3/injector.ts +212 -178
- package/src/plugins/defaults/memory/v3/orchestrate.ts +86 -22
- package/src/plugins/defaults/memory/v3/pool-select.ts +13 -8
- package/src/plugins/defaults/memory/v3/sections.ts +10 -3
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +13 -1
- package/src/plugins/defaults/memory/worker.ts +6 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +1 -46
- package/src/plugins/external-plugin-loader.ts +49 -86
- package/src/plugins/installed-plugin-dirs.ts +6 -4
- package/src/plugins/mcp-servers.ts +24 -90
- package/src/plugins/mtime-cache.ts +2 -1
- package/src/plugins/user-loader.ts +2 -1
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/__tests__/retry-callsite.test.ts +41 -0
- package/src/providers/__tests__/retry-outbound-sanitize.test.ts +176 -0
- package/src/providers/anthropic/client.ts +0 -47
- package/src/providers/gemini/client.ts +9 -23
- package/src/providers/gemini-thought-signature.test.ts +63 -0
- package/src/providers/gemini-thought-signature.ts +44 -0
- package/src/providers/inference/__tests__/endpoint-probe.test.ts +87 -3
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/auth.ts +2 -3
- package/src/providers/inference/connection-availability.ts +27 -8
- package/src/providers/inference/endpoint-probe.ts +36 -12
- package/src/providers/inference/resolve-auth.ts +22 -4
- package/src/providers/inference/service-account-token.ts +248 -0
- package/src/providers/jev/client.test.ts +260 -0
- package/src/providers/jev/client.ts +518 -0
- package/src/providers/model-catalog.ts +92 -3
- package/src/providers/model-intents.ts +10 -5
- package/src/providers/openai/__tests__/chat-completions-output-token-limit.test.ts +141 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +146 -18
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +613 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +235 -0
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +83 -1
- package/src/providers/openai/chat-completions-provider.ts +212 -79
- package/src/providers/openai/codex-models.ts +0 -4
- package/src/providers/openai/google-thought-signature.ts +320 -0
- package/src/providers/openai/responses-provider.ts +9 -2
- package/src/providers/opencode/client.test.ts +240 -4
- package/src/providers/opencode/client.ts +129 -3
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/outbound-request-sanitize.ts +96 -0
- package/src/providers/retry.ts +30 -19
- package/src/providers/unparseable-tool-args.ts +5 -1
- package/src/runtime/AGENTS.md +9 -3
- package/src/runtime/__tests__/agent-wake.test.ts +86 -1
- package/src/runtime/__tests__/channel-send.test.ts +443 -0
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +132 -0
- package/src/runtime/__tests__/host-observe.test.ts +40 -1
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +58 -0
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +72 -0
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +59 -0
- package/src/runtime/agent-wake.ts +22 -5
- package/src/runtime/assistant-event-hub.ts +21 -3
- package/src/runtime/auth/same-actor.ts +38 -3
- package/src/runtime/channel-send.ts +316 -0
- package/src/runtime/guardian-action-service.ts +2 -17
- package/src/runtime/guardian-reply-router.ts +1 -8
- package/src/runtime/host-observe.ts +11 -1
- package/src/runtime/http-server.ts +160 -151
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +89 -0
- package/src/runtime/migrations/vbundle-import-policy.ts +33 -11
- package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +16 -5
- package/src/runtime/routes/__tests__/acp-routes.test.ts +178 -4
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +275 -0
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +127 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +108 -1
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +107 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +24 -2
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +16 -12
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +127 -3
- package/src/runtime/routes/acp-claude-auth-routes.ts +11 -3
- package/src/runtime/routes/acp-routes.test.ts +15 -0
- package/src/runtime/routes/acp-routes.ts +84 -165
- package/src/runtime/routes/app-management-routes.ts +90 -2
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/browser-context.ts +39 -0
- package/src/runtime/routes/browser-routes.ts +16 -47
- package/src/runtime/routes/browser-tabs-routes.ts +72 -29
- package/src/runtime/routes/channel-route-shared.ts +1 -9
- package/src/runtime/routes/channel-send-routes.ts +85 -0
- package/src/runtime/routes/conversation-list-routes.ts +14 -3
- package/src/runtime/routes/conversation-query-routes.ts +40 -0
- package/src/runtime/routes/conversation-routes.ts +45 -7
- package/src/runtime/routes/credential-routes.ts +20 -14
- package/src/runtime/routes/desktop-setup-routes.test.ts +89 -0
- package/src/runtime/routes/desktop-setup-routes.ts +41 -0
- package/src/runtime/routes/diagnostics-routes.ts +61 -4
- package/src/runtime/routes/events-routes.ts +4 -0
- package/src/runtime/routes/guardian-approval-interception.ts +24 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -0
- package/src/runtime/routes/inbound-message-handler.ts +2 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +1 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -4
- package/src/runtime/routes/index.ts +4 -2
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -1
- package/src/runtime/routes/inference-profiles-routes.ts +9 -0
- package/src/runtime/routes/log-export-routes.ts +2 -0
- package/src/runtime/routes/mcp-auth-routes.ts +141 -137
- package/src/runtime/routes/migration-routes.ts +6 -20
- package/src/runtime/routes/oauth-commands-routes.ts +98 -45
- package/src/runtime/routes/oauth-providers.ts +11 -0
- package/src/runtime/routes/oauth-request-hints.test.ts +246 -0
- package/src/runtime/routes/oauth-request-hints.ts +149 -0
- package/src/runtime/routes/platform-routes.ts +18 -15
- package/src/runtime/routes/plugins-routes.ts +83 -50
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/secret-routes.ts +99 -119
- package/src/runtime/routes/workspace-routes.test.ts +55 -26
- package/src/runtime/routes/workspace-routes.ts +46 -63
- package/src/runtime/routes/workspace-tree-walk.test.ts +244 -0
- package/src/runtime/routes/workspace-tree-walk.ts +240 -0
- package/src/runtime/routes/workspace-utils.ts +17 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +16 -3
- package/src/runtime/sync/resource-sync-events.ts +6 -1
- package/src/schedule/__tests__/worker-mcp-bootstrap.test.ts +107 -0
- package/src/schedule/__tests__/worker-mcp-readiness.test.ts +173 -0
- package/src/schedule/__tests__/worker-mcp-tools.test.ts +13 -47
- package/src/schedule/run-script.ts +4 -3
- package/src/schedule/schedule-store.ts +9 -2
- package/src/schedule/scheduler.ts +47 -11
- package/src/schedule/tool-surface-readiness.ts +65 -0
- package/src/schedule/worker-mcp.ts +85 -0
- package/src/schedule/worker.ts +9 -31
- package/src/security/__tests__/ces-http-record-backend.test.ts +137 -0
- package/src/security/ces-http-record-backend.ts +120 -0
- package/src/security/ces-rpc-record-backend.ts +7 -0
- package/src/security/secure-keys.ts +60 -48
- package/src/security/untrusted-content.ts +3 -1
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +60 -0
- package/src/skills/managed-store.ts +153 -31
- package/src/skills/workspace-skill-md-signature.ts +50 -0
- package/src/subagent/consult-context.ts +12 -25
- package/src/tools/__tests__/side-effect-abort-guard.test.ts +1 -0
- package/src/tools/acp/list-agents.test.ts +3 -1
- package/src/tools/acp/spawn.test.ts +146 -11
- package/src/tools/acp/spawn.ts +21 -3
- package/src/tools/acp/status.test.ts +349 -0
- package/src/tools/acp/status.ts +112 -9
- package/src/tools/app-control/skill-proxy-bridge.ts +2 -1
- package/src/tools/browser/browser-execution.ts +45 -14
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +69 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +9 -3
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +1 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +2 -1
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +5 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +3 -2
- package/src/tools/browser/network-recorder.ts +2 -1
- package/src/tools/capability-offer.test.ts +22 -2
- package/src/tools/capability-offer.ts +16 -1
- package/src/tools/computer-use/definitions.ts +123 -5
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -1
- package/src/tools/credentials/metadata-store.ts +100 -0
- package/src/tools/filesystem/search.ts +2 -1
- package/src/tools/host-filesystem/edit.test.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +2 -1
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +2 -1
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +2 -1
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +16 -0
- package/src/tools/host-terminal/host-shell.ts +16 -26
- package/src/tools/network/web-search.ts +6 -1
- package/src/tools/policy-context.ts +6 -7
- package/src/tools/shared/filesystem/file-ops-service.ts +1 -31
- package/src/tools/shared/shell-output.test.ts +10 -0
- package/src/tools/shared/shell-output.ts +14 -2
- package/src/tools/skills/find-similar-skills.test.ts +214 -2
- package/src/tools/skills/find-similar-skills.ts +62 -9
- package/src/tools/skills/resolve-execute-invocation.ts +24 -0
- package/src/tools/skills/sandbox-runner.ts +13 -2
- package/src/tools/skills/scaffold-managed.ts +78 -16
- package/src/tools/subagent/spawn.ts +5 -8
- package/src/tools/terminal/__tests__/safe-env.test.ts +33 -4
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +43 -0
- package/src/tools/terminal/safe-env.ts +35 -24
- package/src/tools/terminal/sanitized-bash.ts +118 -0
- package/src/tools/terminal/shell-launch.test.ts +162 -0
- package/src/tools/terminal/shell.test.ts +29 -0
- package/src/tools/terminal/shell.ts +13 -7
- package/src/tools/ui-surface/channel-variants.ts +10 -59
- package/src/tools/watch/watch-retro-report.ts +0 -8
- package/src/types/host-capabilities.ts +5 -3
- package/src/util/__tests__/language-subtag.test.ts +23 -1
- package/src/util/abort-reasons.ts +12 -1
- package/src/util/ca-bundle.ts +13 -0
- package/src/util/host-process.test.ts +17 -1
- package/src/util/host-process.ts +24 -0
- package/src/util/language-subtag.ts +16 -0
- package/src/util/platform.ts +8 -0
- package/src/util/plugin-manifest.ts +203 -0
- package/src/util/unicode.ts +44 -1
- package/src/watch/watch-retro.ts +6 -8
- package/src/watch/watch-timeline.ts +2 -2
- package/src/workflows/run-manager.ts +2 -1
- package/src/workspace/git-porcelain.ts +66 -0
- package/src/workspace/git-service.ts +6 -55
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +258 -0
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +78 -0
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +214 -0
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +102 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +199 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/app-source-watcher.test.ts +0 -218
- package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -359
- package/src/__tests__/speaker-identification.test.ts +0 -56
- package/src/calls/speaker-identification.ts +0 -233
- package/src/daemon/app-source-watcher.ts +0 -218
- package/src/messaging/providers/whatsapp/client.ts +0 -29
- package/src/runtime/routes/debug-bash-routes.ts +0 -173
- package/src/util/fs-watcher-error.ts +0 -36
- /package/src/{live-voice → calls}/progress-phrases.ts +0 -0
|
@@ -38,23 +38,16 @@ import {
|
|
|
38
38
|
import { openInHostBrowser } from "../util/browser.js";
|
|
39
39
|
import { getLogger } from "../util/logger.js";
|
|
40
40
|
import { APP_VERSION } from "../version.js";
|
|
41
|
+
import {
|
|
42
|
+
MCP_OAUTH_CREDENTIAL_LEAVES,
|
|
43
|
+
mcpOAuthCredentialKey,
|
|
44
|
+
type McpOAuthCredentialTarget,
|
|
45
|
+
pluginMcpOAuthCredentialPrefix,
|
|
46
|
+
workspaceMcpOAuthCredentialTarget,
|
|
47
|
+
} from "./credential-target.js";
|
|
41
48
|
|
|
42
49
|
const log = getLogger("mcp-oauth");
|
|
43
50
|
|
|
44
|
-
// Credential store key helpers
|
|
45
|
-
function tokensKey(serverId: string): string {
|
|
46
|
-
return `mcp:${serverId}:tokens`;
|
|
47
|
-
}
|
|
48
|
-
function clientInfoKey(serverId: string): string {
|
|
49
|
-
return `mcp:${serverId}:client_info`;
|
|
50
|
-
}
|
|
51
|
-
function discoveryKey(serverId: string): string {
|
|
52
|
-
return `mcp:${serverId}:discovery`;
|
|
53
|
-
}
|
|
54
|
-
function clientBindingKey(serverId: string): string {
|
|
55
|
-
return `mcp:${serverId}:client_binding`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
51
|
/**
|
|
59
52
|
* Logo shown on an authorization server's consent screen.
|
|
60
53
|
*
|
|
@@ -91,12 +84,15 @@ export interface McpOAuthProviderOptions {
|
|
|
91
84
|
* URL to the IPC caller (CLI / web client).
|
|
92
85
|
*/
|
|
93
86
|
onAuthorizationUrl?: (url: string) => void;
|
|
87
|
+
/** Credential identity. Defaults to the legacy workspace server id. */
|
|
88
|
+
credentialTarget?: McpOAuthCredentialTarget;
|
|
94
89
|
}
|
|
95
90
|
|
|
96
91
|
export class McpOAuthProvider implements OAuthClientProvider {
|
|
97
92
|
private readonly serverId: string;
|
|
98
93
|
private readonly serverUrl: string;
|
|
99
94
|
private readonly interactive: boolean;
|
|
95
|
+
private readonly credentialTarget: McpOAuthCredentialTarget;
|
|
100
96
|
private _codeVerifier: string | undefined;
|
|
101
97
|
private _state: string | undefined;
|
|
102
98
|
private _redirectUrl: string | undefined;
|
|
@@ -121,6 +117,8 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
121
117
|
this.serverUrl = serverUrl;
|
|
122
118
|
this.interactive = interactive;
|
|
123
119
|
this._onAuthorizationUrl = options.onAuthorizationUrl;
|
|
120
|
+
this.credentialTarget =
|
|
121
|
+
options.credentialTarget ?? workspaceMcpOAuthCredentialTarget(serverId);
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
// --- redirectUrl ---
|
|
@@ -167,7 +165,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
167
165
|
// --- Tokens ---
|
|
168
166
|
|
|
169
167
|
async tokens(): Promise<OAuthTokens | undefined> {
|
|
170
|
-
const raw = await getSecureKeyAsync(
|
|
168
|
+
const raw = await getSecureKeyAsync(
|
|
169
|
+
mcpOAuthCredentialKey(this.credentialTarget, "tokens"),
|
|
170
|
+
);
|
|
171
171
|
if (!raw) {
|
|
172
172
|
return undefined;
|
|
173
173
|
}
|
|
@@ -191,7 +191,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
191
191
|
// the previous refresh_token when the incoming response omits one.
|
|
192
192
|
let toPersist: OAuthTokens = tokens;
|
|
193
193
|
if (!tokens.refresh_token) {
|
|
194
|
-
const previous = await getSecureKeyAsync(
|
|
194
|
+
const previous = await getSecureKeyAsync(
|
|
195
|
+
mcpOAuthCredentialKey(this.credentialTarget, "tokens"),
|
|
196
|
+
);
|
|
195
197
|
if (previous) {
|
|
196
198
|
try {
|
|
197
199
|
const parsed = JSON.parse(previous) as OAuthTokens;
|
|
@@ -204,7 +206,7 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
204
206
|
}
|
|
205
207
|
}
|
|
206
208
|
const ok = await setSecureKeyAsync(
|
|
207
|
-
|
|
209
|
+
mcpOAuthCredentialKey(this.credentialTarget, "tokens"),
|
|
208
210
|
JSON.stringify(toPersist),
|
|
209
211
|
);
|
|
210
212
|
if (!ok) {
|
|
@@ -263,7 +265,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
263
265
|
* fronts the resource.
|
|
264
266
|
*/
|
|
265
267
|
async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {
|
|
266
|
-
const raw = await getSecureKeyAsync(
|
|
268
|
+
const raw = await getSecureKeyAsync(
|
|
269
|
+
mcpOAuthCredentialKey(this.credentialTarget, "client_info"),
|
|
270
|
+
);
|
|
267
271
|
if (!raw) {
|
|
268
272
|
return undefined;
|
|
269
273
|
}
|
|
@@ -294,7 +298,7 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
294
298
|
info: OAuthClientInformationMixed,
|
|
295
299
|
): Promise<void> {
|
|
296
300
|
const ok = await setSecureKeyAsync(
|
|
297
|
-
|
|
301
|
+
mcpOAuthCredentialKey(this.credentialTarget, "client_info"),
|
|
298
302
|
JSON.stringify(info),
|
|
299
303
|
);
|
|
300
304
|
if (!ok) {
|
|
@@ -313,7 +317,7 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
313
317
|
redirectUri: this._redirectUrl,
|
|
314
318
|
};
|
|
315
319
|
const boundOk = await setSecureKeyAsync(
|
|
316
|
-
|
|
320
|
+
mcpOAuthCredentialKey(this.credentialTarget, "client_binding"),
|
|
317
321
|
JSON.stringify(binding),
|
|
318
322
|
);
|
|
319
323
|
if (!boundOk) {
|
|
@@ -349,7 +353,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
349
353
|
* redirect check already covers the case this plugin actually changes.
|
|
350
354
|
*/
|
|
351
355
|
private async describeStaleBinding(): Promise<string | null> {
|
|
352
|
-
const raw = await getSecureKeyAsync(
|
|
356
|
+
const raw = await getSecureKeyAsync(
|
|
357
|
+
mcpOAuthCredentialKey(this.credentialTarget, "client_binding"),
|
|
358
|
+
);
|
|
353
359
|
if (!raw) {
|
|
354
360
|
// Registered before the binding was recorded. Keep it: discarding
|
|
355
361
|
// every pre-existing registration would remake all of them at once.
|
|
@@ -410,7 +416,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
410
416
|
// --- Discovery State ---
|
|
411
417
|
|
|
412
418
|
async discoveryState(): Promise<OAuthDiscoveryState | undefined> {
|
|
413
|
-
const raw = await getSecureKeyAsync(
|
|
419
|
+
const raw = await getSecureKeyAsync(
|
|
420
|
+
mcpOAuthCredentialKey(this.credentialTarget, "discovery"),
|
|
421
|
+
);
|
|
414
422
|
if (!raw) {
|
|
415
423
|
return undefined;
|
|
416
424
|
}
|
|
@@ -423,7 +431,7 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
423
431
|
|
|
424
432
|
async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {
|
|
425
433
|
const ok = await setSecureKeyAsync(
|
|
426
|
-
|
|
434
|
+
mcpOAuthCredentialKey(this.credentialTarget, "discovery"),
|
|
427
435
|
JSON.stringify(state),
|
|
428
436
|
);
|
|
429
437
|
if (!ok) {
|
|
@@ -498,7 +506,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
498
506
|
);
|
|
499
507
|
|
|
500
508
|
if (scope === "all" || scope === "tokens") {
|
|
501
|
-
const result = await deleteSecureKeyAsync(
|
|
509
|
+
const result = await deleteSecureKeyAsync(
|
|
510
|
+
mcpOAuthCredentialKey(this.credentialTarget, "tokens"),
|
|
511
|
+
);
|
|
502
512
|
if (result === "error") {
|
|
503
513
|
log.warn(
|
|
504
514
|
{ serverId: this.serverId },
|
|
@@ -512,7 +522,9 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
512
522
|
}
|
|
513
523
|
}
|
|
514
524
|
if (scope === "all" || scope === "client") {
|
|
515
|
-
const result = await deleteSecureKeyAsync(
|
|
525
|
+
const result = await deleteSecureKeyAsync(
|
|
526
|
+
mcpOAuthCredentialKey(this.credentialTarget, "client_info"),
|
|
527
|
+
);
|
|
516
528
|
if (result === "error") {
|
|
517
529
|
log.warn(
|
|
518
530
|
{ serverId: this.serverId },
|
|
@@ -527,14 +539,18 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
527
539
|
// The binding describes the registration being dropped, so it goes
|
|
528
540
|
// with it. Leaving it would let a later registration inherit the
|
|
529
541
|
// previous one's issuer and redirect URI.
|
|
530
|
-
await deleteSecureKeyAsync(
|
|
542
|
+
await deleteSecureKeyAsync(
|
|
543
|
+
mcpOAuthCredentialKey(this.credentialTarget, "client_binding"),
|
|
544
|
+
);
|
|
531
545
|
}
|
|
532
546
|
if (scope === "all" || scope === "verifier") {
|
|
533
547
|
this._codeVerifier = undefined;
|
|
534
548
|
this._state = undefined;
|
|
535
549
|
}
|
|
536
550
|
if (scope === "all" || scope === "discovery") {
|
|
537
|
-
const result = await deleteSecureKeyAsync(
|
|
551
|
+
const result = await deleteSecureKeyAsync(
|
|
552
|
+
mcpOAuthCredentialKey(this.credentialTarget, "discovery"),
|
|
553
|
+
);
|
|
538
554
|
if (result === "error") {
|
|
539
555
|
log.warn(
|
|
540
556
|
{ serverId: this.serverId },
|
|
@@ -617,8 +633,10 @@ export class McpOAuthProvider implements OAuthClientProvider {
|
|
|
617
633
|
/**
|
|
618
634
|
* Check whether OAuth tokens exist in the credential store for a server.
|
|
619
635
|
*/
|
|
620
|
-
export async function hasMcpOAuthTokens(
|
|
621
|
-
|
|
636
|
+
export async function hasMcpOAuthTokens(
|
|
637
|
+
target: McpOAuthCredentialTarget,
|
|
638
|
+
): Promise<boolean> {
|
|
639
|
+
const raw = await getSecureKeyAsync(mcpOAuthCredentialKey(target, "tokens"));
|
|
622
640
|
return raw != null && raw.length > 0;
|
|
623
641
|
}
|
|
624
642
|
|
|
@@ -631,10 +649,14 @@ export async function deleteMcpOAuthCredentials(
|
|
|
631
649
|
): Promise<{ ok: boolean; failedKeys: string[] }> {
|
|
632
650
|
const [tokensResult, clientResult, bindingResult, discoveryResult] =
|
|
633
651
|
await Promise.all([
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
652
|
+
...MCP_OAUTH_CREDENTIAL_LEAVES.map((leaf) =>
|
|
653
|
+
deleteSecureKeyAsync(
|
|
654
|
+
mcpOAuthCredentialKey(
|
|
655
|
+
workspaceMcpOAuthCredentialTarget(serverId),
|
|
656
|
+
leaf,
|
|
657
|
+
),
|
|
658
|
+
),
|
|
659
|
+
),
|
|
638
660
|
]);
|
|
639
661
|
const results = [
|
|
640
662
|
{ key: "tokens", result: tokensResult },
|
|
@@ -660,3 +682,49 @@ export async function deleteMcpOAuthCredentials(
|
|
|
660
682
|
);
|
|
661
683
|
return { ok, failedKeys };
|
|
662
684
|
}
|
|
685
|
+
|
|
686
|
+
export interface PluginMcpOAuthCleanupResult {
|
|
687
|
+
readonly ok: boolean;
|
|
688
|
+
readonly unreachable: boolean;
|
|
689
|
+
readonly matchedKeys: string[];
|
|
690
|
+
readonly failedKeys: string[];
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/** Delete every endpoint-scoped MCP OAuth record owned by one plugin. */
|
|
694
|
+
export async function deletePluginMcpOAuthCredentials(
|
|
695
|
+
pluginName: string,
|
|
696
|
+
): Promise<PluginMcpOAuthCleanupResult> {
|
|
697
|
+
const { listSecureKeysAsync } = await import("../security/secure-keys.js");
|
|
698
|
+
const listed = await listSecureKeysAsync();
|
|
699
|
+
if (listed.unreachable) {
|
|
700
|
+
return {
|
|
701
|
+
ok: false,
|
|
702
|
+
unreachable: true,
|
|
703
|
+
matchedKeys: [],
|
|
704
|
+
failedKeys: [],
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
const prefix = pluginMcpOAuthCredentialPrefix(pluginName);
|
|
709
|
+
const matchedKeys = listed.accounts.filter((key) => key.startsWith(prefix));
|
|
710
|
+
const deletionResults = await Promise.all(
|
|
711
|
+
matchedKeys.map(async (key) => {
|
|
712
|
+
try {
|
|
713
|
+
return { key, result: await deleteSecureKeyAsync(key) };
|
|
714
|
+
} catch {
|
|
715
|
+
return { key, result: "error" as const };
|
|
716
|
+
}
|
|
717
|
+
}),
|
|
718
|
+
);
|
|
719
|
+
const failedKeys = deletionResults
|
|
720
|
+
.filter(({ result }) => result === "error")
|
|
721
|
+
.map(({ key }) => key);
|
|
722
|
+
const ok = failedKeys.length === 0;
|
|
723
|
+
if (!ok) {
|
|
724
|
+
log.warn(
|
|
725
|
+
{ pluginName, failedKeys },
|
|
726
|
+
"Some plugin MCP OAuth credentials could not be deleted",
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
return { ok, unreachable: false, matchedKeys, failedKeys };
|
|
730
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Plugins 1.0.0 `mcp.json` wire schema and projections onto the
|
|
3
|
+
* assistant's in-memory `McpTransport` union.
|
|
4
|
+
*
|
|
5
|
+
* Workspace `/workspace/mcp.json` and each plugin's root `mcp.json` share
|
|
6
|
+
* this document shape. Origin (`workspace` vs `plugin`) is resolved from
|
|
7
|
+
* which file was read, never from a field in the file.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
12
|
+
import type { McpTransport } from "../config/schemas/mcp.js";
|
|
13
|
+
|
|
14
|
+
/** Canonical `$schema` value for an Agent Plugins 1.0.0 MCP document. */
|
|
15
|
+
export const AGENT_PLUGINS_MCP_SCHEMA_URL =
|
|
16
|
+
"https://agent-plugins.org/schemas/1.0.0/mcp.schema.json";
|
|
17
|
+
|
|
18
|
+
const SpecStdioServerSchema = z.object({
|
|
19
|
+
type: z.literal("stdio"),
|
|
20
|
+
command: z.string().min(1),
|
|
21
|
+
args: z.array(z.string()).optional(),
|
|
22
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
23
|
+
cwd: z.string().optional(),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Remote MCP entry. Agent Plugins 1.0.0 requires `type` and names no
|
|
28
|
+
* default. MCP's current remote transport is Streamable HTTP, so this
|
|
29
|
+
* host fills omitted `type` and the Claude-style `http` alias as
|
|
30
|
+
* `streamable-http`. `sse` stays explicit.
|
|
31
|
+
*/
|
|
32
|
+
const SpecHttpServerSchema = z.object({
|
|
33
|
+
type: z
|
|
34
|
+
.union([
|
|
35
|
+
z.literal("streamable-http"),
|
|
36
|
+
z.literal("sse"),
|
|
37
|
+
z.literal("http").transform(() => "streamable-http" as const),
|
|
38
|
+
])
|
|
39
|
+
.default("streamable-http"),
|
|
40
|
+
url: z.string().min(1),
|
|
41
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const SpecMcpServerSchema = z.union([
|
|
45
|
+
SpecStdioServerSchema,
|
|
46
|
+
SpecHttpServerSchema,
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
export const SpecMcpDocumentSchema = z.object({
|
|
50
|
+
$schema: z.string().optional(),
|
|
51
|
+
mcpServers: z.record(z.string(), z.unknown()),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export type SpecMcpServer = z.infer<typeof SpecMcpServerSchema>;
|
|
55
|
+
export type SpecMcpDocument = z.infer<typeof SpecMcpDocumentSchema>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Project one spec-shaped entry onto the assistant's transport union. The
|
|
59
|
+
* two vocabularies already agree on type names and required fields, so this
|
|
60
|
+
* is a field copy plus an optional expander for plugin path variables.
|
|
61
|
+
*/
|
|
62
|
+
export function projectSpecServerToTransport(
|
|
63
|
+
entry: SpecMcpServer,
|
|
64
|
+
expand?: (value: string) => string,
|
|
65
|
+
): McpTransport {
|
|
66
|
+
if (entry.type === "stdio") {
|
|
67
|
+
const map = expand ?? ((value: string) => value);
|
|
68
|
+
return {
|
|
69
|
+
type: "stdio",
|
|
70
|
+
command: entry.command,
|
|
71
|
+
args: (entry.args ?? []).map(map),
|
|
72
|
+
...(entry.env && {
|
|
73
|
+
env: Object.fromEntries(
|
|
74
|
+
Object.entries(entry.env).map(([key, value]) => [key, map(value)]),
|
|
75
|
+
),
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
type: entry.type,
|
|
81
|
+
url: entry.url,
|
|
82
|
+
...(entry.headers && { headers: entry.headers }),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Project an in-memory transport onto a spec server entry. Headers are
|
|
88
|
+
* omitted: workspace secrets live in the credential store, and a write
|
|
89
|
+
* must not copy them into `mcp.json`.
|
|
90
|
+
*/
|
|
91
|
+
export function projectTransportToSpecServer(
|
|
92
|
+
transport: McpTransport,
|
|
93
|
+
): Record<string, unknown> {
|
|
94
|
+
if (transport.type === "stdio") {
|
|
95
|
+
const entry: Record<string, unknown> = {
|
|
96
|
+
type: "stdio",
|
|
97
|
+
command: transport.command,
|
|
98
|
+
};
|
|
99
|
+
if (transport.args && transport.args.length > 0) {
|
|
100
|
+
entry.args = transport.args;
|
|
101
|
+
}
|
|
102
|
+
if (transport.env) {
|
|
103
|
+
entry.env = transport.env;
|
|
104
|
+
}
|
|
105
|
+
return entry;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
type: transport.type,
|
|
109
|
+
url: transport.url,
|
|
110
|
+
};
|
|
111
|
+
}
|
package/src/mcp/startup.ts
CHANGED
|
@@ -13,13 +13,20 @@
|
|
|
13
13
|
* further process that starts hosting turns has one call to make.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import { invalidateConfigCache } from "../config/loader.js";
|
|
17
17
|
import type { McpConfig } from "../config/schemas/mcp.js";
|
|
18
18
|
import { createMcpToolsFromServer } from "../tools/mcp/mcp-tool-factory.js";
|
|
19
19
|
import { registerMcpTools, unregisterAllMcpTools } from "../tools/registry.js";
|
|
20
20
|
import { getLogger } from "../util/logger.js";
|
|
21
21
|
import { buildEffectiveMcpConfig } from "./effective-config.js";
|
|
22
22
|
import { getMcpServerManager, stopMcpServerManager } from "./manager.js";
|
|
23
|
+
import {
|
|
24
|
+
EMPTY_MCP_STARTUP_SNAPSHOT,
|
|
25
|
+
type McpStartupSnapshot,
|
|
26
|
+
} from "./tool-caps.js";
|
|
27
|
+
import { loadWorkspaceMcpConfig } from "./workspace-mcp-config.js";
|
|
28
|
+
|
|
29
|
+
export type { McpStartupSnapshot } from "./tool-caps.js";
|
|
23
30
|
|
|
24
31
|
const log = getLogger("mcp-startup");
|
|
25
32
|
|
|
@@ -36,22 +43,29 @@ const log = getLogger("mcp-startup");
|
|
|
36
43
|
* is a startup step in processes whose other work must not be held hostage to
|
|
37
44
|
* a third-party server being up.
|
|
38
45
|
*
|
|
39
|
-
* @param workspaceMcpConfig The
|
|
40
|
-
*
|
|
46
|
+
* @param workspaceMcpConfig The projected workspace MCP config. Callers
|
|
47
|
+
* that omit it read `/workspace/mcp.json`.
|
|
48
|
+
* @returns A count snapshot of configured/connected servers and the tools
|
|
49
|
+
* that reached this process's registry after caps.
|
|
41
50
|
*/
|
|
42
51
|
export async function startConfiguredMcpServers(
|
|
43
52
|
workspaceMcpConfig?: McpConfig,
|
|
44
|
-
): Promise<
|
|
45
|
-
let
|
|
53
|
+
): Promise<McpStartupSnapshot> {
|
|
54
|
+
let snapshot: McpStartupSnapshot = EMPTY_MCP_STARTUP_SNAPSHOT;
|
|
46
55
|
try {
|
|
47
|
-
const mcpConfig = buildEffectiveMcpConfig(
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
const mcpConfig = buildEffectiveMcpConfig(
|
|
57
|
+
workspaceMcpConfig ?? loadWorkspaceMcpConfig(),
|
|
58
|
+
);
|
|
59
|
+
const configuredServerCount = Object.keys(mcpConfig.servers).length;
|
|
60
|
+
snapshot = { ...EMPTY_MCP_STARTUP_SNAPSHOT, configuredServerCount };
|
|
61
|
+
if (configuredServerCount === 0) {
|
|
62
|
+
return snapshot;
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
const manager = getMcpServerManager();
|
|
53
|
-
const
|
|
54
|
-
|
|
66
|
+
const started = await manager.start(mcpConfig);
|
|
67
|
+
let registered = 0;
|
|
68
|
+
for (const { serverId, serverConfig, tools } of started.servers) {
|
|
55
69
|
const mcpTools = createMcpToolsFromServer(
|
|
56
70
|
tools,
|
|
57
71
|
serverId,
|
|
@@ -60,16 +74,26 @@ export async function startConfiguredMcpServers(
|
|
|
60
74
|
);
|
|
61
75
|
registered += registerMcpTools(serverId, mcpTools).length;
|
|
62
76
|
}
|
|
77
|
+
snapshot = {
|
|
78
|
+
configuredServerCount: started.configuredServerCount,
|
|
79
|
+
connectedServerCount: started.connectedServerCount,
|
|
80
|
+
discoveredToolCount: started.discoveredToolCount,
|
|
81
|
+
registeredToolCount: registered,
|
|
82
|
+
droppedToolCount: started.droppedToolCount,
|
|
83
|
+
truncatedServerIds: started.truncatedServerIds,
|
|
84
|
+
errorServerCount: started.errorServerCount,
|
|
85
|
+
needsAuthServerCount: started.needsAuthServerCount,
|
|
86
|
+
};
|
|
63
87
|
} catch (err) {
|
|
64
88
|
log.error(
|
|
65
|
-
{ err },
|
|
89
|
+
{ err, ...snapshot },
|
|
66
90
|
"MCP server initialization failed, continuing without MCP tools",
|
|
67
91
|
);
|
|
68
|
-
return
|
|
92
|
+
return snapshot;
|
|
69
93
|
}
|
|
70
94
|
|
|
71
|
-
log.info(
|
|
72
|
-
return
|
|
95
|
+
log.info(snapshot, "MCP tools registered");
|
|
96
|
+
return snapshot;
|
|
73
97
|
}
|
|
74
98
|
|
|
75
99
|
/**
|
|
@@ -87,9 +111,9 @@ export async function startConfiguredMcpServers(
|
|
|
87
111
|
* The window between the teardown and the reconnect has no MCP tools
|
|
88
112
|
* registered, so an `mcp__*` call landing inside it fails as an unknown tool.
|
|
89
113
|
*
|
|
90
|
-
* @returns
|
|
114
|
+
* @returns A count snapshot of the tools registered after the reconnect.
|
|
91
115
|
*/
|
|
92
|
-
export async function restartConfiguredMcpServers(): Promise<
|
|
116
|
+
export async function restartConfiguredMcpServers(): Promise<McpStartupSnapshot> {
|
|
93
117
|
try {
|
|
94
118
|
await stopMcpServerManager();
|
|
95
119
|
} catch (err) {
|
|
@@ -97,5 +121,5 @@ export async function restartConfiguredMcpServers(): Promise<number> {
|
|
|
97
121
|
}
|
|
98
122
|
unregisterAllMcpTools();
|
|
99
123
|
invalidateConfigCache();
|
|
100
|
-
return startConfiguredMcpServers(
|
|
124
|
+
return startConfiguredMcpServers(loadWorkspaceMcpConfig());
|
|
101
125
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code-owned MCP tool-count caps and the selection used when they bind.
|
|
3
|
+
*
|
|
4
|
+
* Caps live here, not in workspace config: migration 153 strips
|
|
5
|
+
* `maxTools` / `globalMaxTools` from `config.json`. The numbers are a
|
|
6
|
+
* context-window budget, not a permission gate. Allowlists and risk
|
|
7
|
+
* still decide what a turn may call.
|
|
8
|
+
*
|
|
9
|
+
* The global cap is applied by a deterministic round-robin across
|
|
10
|
+
* servers sorted by id. Insertion order must not empty a later server
|
|
11
|
+
* while earlier ones keep every tool.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
MCP_GLOBAL_MAX_TOOLS,
|
|
16
|
+
MCP_MAX_TOOLS_PER_SERVER,
|
|
17
|
+
} from "../config/schemas/mcp.js";
|
|
18
|
+
|
|
19
|
+
export interface McpServerToolSet<T> {
|
|
20
|
+
serverId: string;
|
|
21
|
+
tools: readonly T[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface McpToolCapDecision {
|
|
25
|
+
serverId: string;
|
|
26
|
+
discovered: number;
|
|
27
|
+
kept: number;
|
|
28
|
+
droppedByPerServerCap: number;
|
|
29
|
+
droppedByGlobalCap: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface McpToolCapResult<T> {
|
|
33
|
+
servers: Array<{ serverId: string; tools: T[] }>;
|
|
34
|
+
discoveredToolCount: number;
|
|
35
|
+
keptToolCount: number;
|
|
36
|
+
droppedToolCount: number;
|
|
37
|
+
globalCap: number;
|
|
38
|
+
perServerCap: number;
|
|
39
|
+
decisions: McpToolCapDecision[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function applyMcpToolCaps<T>(
|
|
43
|
+
servers: ReadonlyArray<McpServerToolSet<T>>,
|
|
44
|
+
options?: { globalMax?: number; perServerMax?: number },
|
|
45
|
+
): McpToolCapResult<T> {
|
|
46
|
+
const globalCap = options?.globalMax ?? MCP_GLOBAL_MAX_TOOLS;
|
|
47
|
+
const perServerCap = options?.perServerMax ?? MCP_MAX_TOOLS_PER_SERVER;
|
|
48
|
+
const discoveredToolCount = servers.reduce(
|
|
49
|
+
(sum, server) => sum + server.tools.length,
|
|
50
|
+
0,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const afterPerServer = servers.map((server) => {
|
|
54
|
+
const droppedByPerServerCap = Math.max(
|
|
55
|
+
0,
|
|
56
|
+
server.tools.length - perServerCap,
|
|
57
|
+
);
|
|
58
|
+
return {
|
|
59
|
+
serverId: server.serverId,
|
|
60
|
+
tools: server.tools.slice(0, perServerCap),
|
|
61
|
+
discovered: server.tools.length,
|
|
62
|
+
droppedByPerServerCap,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const afterPerServerCount = afterPerServer.reduce(
|
|
67
|
+
(sum, server) => sum + server.tools.length,
|
|
68
|
+
0,
|
|
69
|
+
);
|
|
70
|
+
if (afterPerServerCount <= globalCap) {
|
|
71
|
+
const decisions = afterPerServer.map((server) => ({
|
|
72
|
+
serverId: server.serverId,
|
|
73
|
+
discovered: server.discovered,
|
|
74
|
+
kept: server.tools.length,
|
|
75
|
+
droppedByPerServerCap: server.droppedByPerServerCap,
|
|
76
|
+
droppedByGlobalCap: 0,
|
|
77
|
+
}));
|
|
78
|
+
return {
|
|
79
|
+
servers: afterPerServer.map((server) => ({
|
|
80
|
+
serverId: server.serverId,
|
|
81
|
+
tools: [...server.tools],
|
|
82
|
+
})),
|
|
83
|
+
discoveredToolCount,
|
|
84
|
+
keptToolCount: afterPerServerCount,
|
|
85
|
+
droppedToolCount: discoveredToolCount - afterPerServerCount,
|
|
86
|
+
globalCap,
|
|
87
|
+
perServerCap,
|
|
88
|
+
decisions,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const order = [...afterPerServer].sort((a, b) =>
|
|
93
|
+
a.serverId.localeCompare(b.serverId),
|
|
94
|
+
);
|
|
95
|
+
const selected = new Map<string, T[]>(
|
|
96
|
+
order.map((server) => [server.serverId, []]),
|
|
97
|
+
);
|
|
98
|
+
const cursors = new Map<string, number>(
|
|
99
|
+
order.map((server) => [server.serverId, 0]),
|
|
100
|
+
);
|
|
101
|
+
let kept = 0;
|
|
102
|
+
let progressed = true;
|
|
103
|
+
while (kept < globalCap && progressed) {
|
|
104
|
+
progressed = false;
|
|
105
|
+
for (const server of order) {
|
|
106
|
+
if (kept >= globalCap) {
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
const cursor = cursors.get(server.serverId) ?? 0;
|
|
110
|
+
const tool = server.tools[cursor];
|
|
111
|
+
if (tool !== undefined) {
|
|
112
|
+
selected.get(server.serverId)?.push(tool);
|
|
113
|
+
cursors.set(server.serverId, cursor + 1);
|
|
114
|
+
kept += 1;
|
|
115
|
+
progressed = true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const decisions = afterPerServer.map((server) => {
|
|
121
|
+
const keptTools = selected.get(server.serverId) ?? [];
|
|
122
|
+
return {
|
|
123
|
+
serverId: server.serverId,
|
|
124
|
+
discovered: server.discovered,
|
|
125
|
+
kept: keptTools.length,
|
|
126
|
+
droppedByPerServerCap: server.droppedByPerServerCap,
|
|
127
|
+
droppedByGlobalCap: server.tools.length - keptTools.length,
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
servers: afterPerServer.map((server) => ({
|
|
133
|
+
serverId: server.serverId,
|
|
134
|
+
tools: [...(selected.get(server.serverId) ?? [])],
|
|
135
|
+
})),
|
|
136
|
+
discoveredToolCount,
|
|
137
|
+
keptToolCount: kept,
|
|
138
|
+
droppedToolCount: discoveredToolCount - kept,
|
|
139
|
+
globalCap,
|
|
140
|
+
perServerCap,
|
|
141
|
+
decisions,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface McpStartupSnapshot {
|
|
146
|
+
configuredServerCount: number;
|
|
147
|
+
connectedServerCount: number;
|
|
148
|
+
discoveredToolCount: number;
|
|
149
|
+
registeredToolCount: number;
|
|
150
|
+
droppedToolCount: number;
|
|
151
|
+
truncatedServerIds: string[];
|
|
152
|
+
errorServerCount: number;
|
|
153
|
+
needsAuthServerCount: number;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const EMPTY_MCP_STARTUP_SNAPSHOT: McpStartupSnapshot = {
|
|
157
|
+
configuredServerCount: 0,
|
|
158
|
+
connectedServerCount: 0,
|
|
159
|
+
discoveredToolCount: 0,
|
|
160
|
+
registeredToolCount: 0,
|
|
161
|
+
droppedToolCount: 0,
|
|
162
|
+
truncatedServerIds: [],
|
|
163
|
+
errorServerCount: 0,
|
|
164
|
+
needsAuthServerCount: 0,
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export function truncatedServerIdsFromCaps(
|
|
168
|
+
decisions: readonly McpToolCapDecision[],
|
|
169
|
+
): string[] {
|
|
170
|
+
return decisions
|
|
171
|
+
.filter(
|
|
172
|
+
(decision) =>
|
|
173
|
+
decision.droppedByPerServerCap > 0 || decision.droppedByGlobalCap > 0,
|
|
174
|
+
)
|
|
175
|
+
.map((decision) => decision.serverId);
|
|
176
|
+
}
|