@vellumai/assistant 0.12.1 → 0.12.2-staging.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/AGENTS.md +4 -0
- package/ARCHITECTURE.md +20 -21
- package/docs/architecture/turn-actor.md +15 -8
- package/docs/guardian-request-flow.md +16 -0
- 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 +360 -51
- package/package.json +3 -1
- package/scripts/smoke-desktop-window-theme.ts +186 -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__/assistant-event-hub-machine-name.test.ts +6 -7
- package/src/__tests__/assistant-event-hub.test.ts +44 -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 +28 -29
- package/src/__tests__/config-watcher.test.ts +23 -8
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- 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 +28 -0
- 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-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__/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__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/git-porcelain.test.ts +47 -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 +596 -0
- 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__/list-messages-camera-frame.test.ts +121 -0
- package/src/__tests__/llm-catalog-parity.test.ts +25 -0
- package/src/__tests__/mcp-auth-routes.test.ts +6 -9
- package/src/__tests__/mcp-config-secret-boundary.test.ts +78 -136
- package/src/__tests__/mcp-health-check.test.ts +8 -11
- package/src/__tests__/mcp-list-plugin-servers.test.ts +8 -10
- 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-commands-routes.test.ts +168 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +18 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +22 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-provider.test.ts +1 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- 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 +14 -0
- package/src/__tests__/qdrant-manager.test.ts +132 -0
- package/src/__tests__/resolve-app.test.ts +135 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +229 -6
- package/src/__tests__/script-proxy-certs.test.ts +35 -0
- package/src/__tests__/secret-routes-acp-guard.test.ts +59 -1
- 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 +9 -4
- package/src/__tests__/source-fingerprint.test.ts +184 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +70 -3
- package/src/__tests__/subagent-tools.test.ts +3 -2
- package/src/__tests__/telephony-tts-guard.test.ts +38 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/ui-channel-variants.test.ts +1 -56
- package/src/__tests__/unicode.test.ts +13 -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/types.ts +50 -5
- package/src/agent/loop.ts +1 -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/notification-intent.ts +2 -0
- package/src/api/events/user-message-echo.ts +7 -1
- package/src/api/index.ts +6 -0
- package/src/api/responses/conversation-message.ts +5 -0
- package/src/apps/app-store.ts +1 -1
- 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/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 +4 -4
- package/src/{live-voice → calls}/__tests__/progress-phrases.test.ts +1 -1
- package/src/calls/__tests__/voice-control-protocol.test.ts +120 -25
- 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 +56 -1
- 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 +2 -2
- 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 +155 -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 +92 -72
- 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__/roadmap.help.test.ts +19 -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 +8 -13
- package/src/cli/commands/bash.ts +7 -25
- 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 +6 -2
- 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/status.ts +5 -0
- package/src/cli/commands/roadmap.help.ts +5 -1
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +103 -90
- package/src/config/__tests__/default-profile-catalog.test.ts +22 -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/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 +22 -14
- package/src/config/bundled-skills/acp/TOOLS.json +5 -1
- 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 +29 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +99 -0
- 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 +3 -4
- package/src/config/bundled-skills/screen-annotation/SKILL.md +8 -1
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +4 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +6 -2
- 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 +2 -0
- 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/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/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +10 -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/credential-execution/process-manager.test.ts +18 -19
- package/src/credential-health/credential-health-service.ts +11 -17
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -121
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +4 -1
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +133 -0
- package/src/daemon/app-change-notify.ts +45 -0
- package/src/daemon/config-watcher.ts +13 -194
- 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 +20 -7
- 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 +45 -59
- package/src/daemon/conversation.ts +0 -3
- 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 +224 -19
- package/src/daemon/host-file-proxy.ts +8 -10
- package/src/daemon/host-proxy-preactivation.ts +2 -1
- package/src/daemon/host-transfer-proxy.ts +14 -18
- package/src/daemon/lifecycle.ts +0 -5
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/orphan-reaper.ts +1 -1
- package/src/daemon/providers-setup.ts +1 -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-side-effects.ts +7 -18
- package/src/desktop/__tests__/fake-desktop.ts +122 -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.ts +37 -0
- package/src/desktop/desktop-dependencies.test.ts +102 -0
- package/src/desktop/desktop-dependencies.ts +308 -0
- package/src/desktop/desktop-feature.test.ts +18 -0
- package/src/desktop/desktop-feature.ts +19 -0
- package/src/desktop/desktop-panel-config.test.ts +135 -0
- package/src/desktop/desktop-panel-config.ts +149 -0
- package/src/desktop/desktop-session-manager.test.ts +730 -0
- package/src/desktop/desktop-session-manager.ts +850 -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/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 +108 -0
- package/src/i18n/index.ts +16 -0
- package/src/i18n/locales.ts +93 -0
- package/src/i18n/messages.ts +61 -0
- package/src/i18n/title.ts +25 -0
- package/src/inbound/platform-callback-registration.ts +4 -5
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +121 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +8 -7
- 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-sight-frame-echo.test.ts +238 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/live-voice/__tests__/protocol.test.ts +39 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
- package/src/live-voice/__tests__/session-controls.test.ts +79 -0
- package/src/live-voice/live-voice-photo.ts +25 -6
- package/src/live-voice/live-voice-session.ts +297 -699
- package/src/live-voice/protocol.ts +60 -2
- package/src/live-voice/session-controls.ts +111 -0
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +135 -0
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +29 -45
- package/src/mcp/spec-schema.ts +111 -0
- package/src/mcp/startup.ts +8 -4
- package/src/mcp/workspace-mcp-config.ts +188 -0
- 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__/workspace-git-heartbeat.test.ts +8 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +55 -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/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 +66 -22
- package/src/oauth/AGENTS.md +2 -0
- 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/provider-serializer.ts +9 -0
- package/src/oauth/scope-utils.ts +24 -0
- package/src/oauth/seed-providers.ts +314 -27
- package/src/outbound-proxy/certs.ts +3 -5
- package/src/permissions/checker.test.ts +11 -6
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +71 -63
- package/src/persistence/conversation-lineage.ts +12 -4
- 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/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/__tests__/157-invite-contact-id.test.ts +149 -0
- package/src/persistence/schema/memory-core.ts +5 -0
- 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/index.ts +1 -0
- package/src/plugin-api/types.ts +2 -0
- package/src/plugins/defaults/index.ts +2 -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 +20 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +5 -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__/shutdown-hook.test.ts +4 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +3 -2
- package/src/plugins/defaults/memory/context-search/format.ts +3 -2
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +6 -3
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +3 -2
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -7
- 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/host-utils.ts +10 -0
- 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 +12 -3
- 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/skill-md-mtime-poll.ts +9 -0
- package/src/plugins/defaults/memory/startup.ts +28 -2
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +7 -9
- package/src/plugins/defaults/memory/substrate/page-index.ts +6 -1
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +4 -1
- package/src/plugins/defaults/memory/v2/reranker.ts +6 -1
- package/src/plugins/defaults/memory/v3/__tests__/card.test.ts +24 -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 +30 -0
- package/src/plugins/defaults/memory/v3/card.ts +3 -2
- package/src/plugins/defaults/memory/v3/pool-select.ts +5 -3
- package/src/plugins/defaults/memory/v3/sections.ts +9 -3
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +5 -2
- package/src/plugins/defaults/memory/worker.ts +6 -0
- package/src/plugins/mcp-servers.ts +15 -75
- 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 +42 -3
- package/src/providers/inference/auth.ts +2 -3
- package/src/providers/inference/connection-availability.ts +27 -8
- package/src/providers/inference/endpoint-probe.ts +10 -1
- package/src/providers/inference/resolve-auth.ts +22 -4
- package/src/providers/inference/service-account-token.ts +248 -0
- package/src/providers/model-catalog.ts +34 -0
- 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/opencode/client.test.ts +73 -4
- package/src/providers/opencode/client.ts +60 -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 +3 -1
- package/src/runtime/__tests__/channel-send.test.ts +443 -0
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +89 -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 +2 -1
- 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/host-observe.ts +11 -1
- package/src/runtime/http-server.ts +160 -151
- package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +16 -5
- package/src/runtime/routes/__tests__/acp-routes.test.ts +159 -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__/mcp-add-default-risk.test.ts +16 -12
- 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 +72 -9
- package/src/runtime/routes/app-management-routes.ts +90 -2
- package/src/runtime/routes/app-routes.ts +1 -1
- 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 +16 -3
- package/src/runtime/routes/credential-routes.ts +20 -14
- package/src/runtime/routes/desktop-setup-routes.test.ts +74 -0
- package/src/runtime/routes/desktop-setup-routes.ts +35 -0
- package/src/runtime/routes/diagnostics-routes.ts +61 -4
- package/src/runtime/routes/events-routes.ts +4 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -0
- package/src/runtime/routes/index.ts +4 -2
- package/src/runtime/routes/log-export-routes.ts +2 -0
- package/src/runtime/routes/mcp-auth-routes.ts +39 -47
- package/src/runtime/routes/migration-routes.ts +6 -20
- package/src/runtime/routes/oauth-commands-routes.ts +50 -0
- package/src/runtime/routes/oauth-providers.ts +7 -0
- package/src/runtime/routes/platform-routes.ts +18 -15
- 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 +2 -1
- package/src/schedule/run-script.ts +2 -1
- package/src/schedule/schedule-store.ts +9 -2
- package/src/schedule/worker.ts +1 -1
- 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/untrusted-content.ts +3 -1
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +60 -0
- 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 +94 -0
- package/src/tools/acp/status.ts +40 -3
- package/src/tools/app-control/skill-proxy-bridge.ts +2 -1
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +9 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +2 -1
- 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 +121 -2
- 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 +4 -20
- package/src/tools/network/web-search.ts +6 -1
- package/src/tools/policy-context.ts +6 -7
- package/src/tools/skills/scaffold-managed.ts +61 -3
- package/src/tools/subagent/spawn.ts +5 -8
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +57 -0
- package/src/tools/terminal/sanitized-bash.ts +105 -0
- 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/ca-bundle.ts +13 -0
- package/src/util/language-subtag.ts +16 -0
- package/src/util/platform.ts +8 -0
- package/src/util/unicode.ts +15 -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
package/src/cli/commands/bash.ts
CHANGED
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `assistant bash`
|
|
3
|
-
*
|
|
2
|
+
* `assistant bash` runs a shell command with the same sanitized environment
|
|
3
|
+
* the bash tool forwards to tool-call subprocesses.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Command } from "commander";
|
|
7
7
|
|
|
8
|
-
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
9
8
|
import { applyCommandHelp, commandSpec } from "../lib/cli-command-help.js";
|
|
10
9
|
import { registerCommand } from "../lib/register-command.js";
|
|
11
10
|
import { log } from "../logger.js";
|
|
12
11
|
import { bashHelp } from "./bash.help.js";
|
|
13
12
|
|
|
14
|
-
interface DebugBashResult {
|
|
15
|
-
stdout: string;
|
|
16
|
-
stderr: string;
|
|
17
|
-
exitCode: number | null;
|
|
18
|
-
timedOut: boolean;
|
|
19
|
-
error?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
13
|
export function registerBashCommand(program: Command): void {
|
|
23
14
|
registerCommand(program, {
|
|
24
15
|
name: commandSpec(bashHelp),
|
|
25
|
-
transport: "
|
|
16
|
+
transport: "local",
|
|
26
17
|
description: bashHelp.description,
|
|
27
18
|
build: (cmd) => {
|
|
28
19
|
applyCommandHelp(cmd, bashHelp);
|
|
@@ -34,19 +25,10 @@ export function registerBashCommand(program: Command): void {
|
|
|
34
25
|
return;
|
|
35
26
|
}
|
|
36
27
|
|
|
37
|
-
const
|
|
38
|
-
"
|
|
39
|
-
{ body: { command, timeoutMs } },
|
|
40
|
-
{ timeoutMs: timeoutMs + 10_000 },
|
|
28
|
+
const { runSanitizedBash } = await import(
|
|
29
|
+
"../../tools/terminal/sanitized-bash.js"
|
|
41
30
|
);
|
|
42
|
-
|
|
43
|
-
if (!result.ok) {
|
|
44
|
-
log.error(result.error ?? "Failed to reach the assistant.");
|
|
45
|
-
process.exitCode = 1;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const data = result.result!;
|
|
31
|
+
const data = await runSanitizedBash(command, timeoutMs);
|
|
50
32
|
|
|
51
33
|
if (data.error) {
|
|
52
34
|
log.error(data.error);
|
|
@@ -69,7 +51,7 @@ export function registerBashCommand(program: Command): void {
|
|
|
69
51
|
}
|
|
70
52
|
|
|
71
53
|
if (data.timedOut) {
|
|
72
|
-
log.info(
|
|
54
|
+
log.info("Command timed out.");
|
|
73
55
|
}
|
|
74
56
|
|
|
75
57
|
if (data.exitCode != null && data.exitCode !== 0) {
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
// The command is a door onto the daemon's one send implementation, so what
|
|
4
|
+
// matters is the request it hands the route and what it does with the
|
|
5
|
+
// answer. IPC is stubbed to capture that request; the exit-code helper
|
|
6
|
+
// stays real, so the tests assert the mapping that ships.
|
|
7
|
+
|
|
8
|
+
const ipcCalls: Array<{
|
|
9
|
+
method: string;
|
|
10
|
+
params: Record<string, unknown>;
|
|
11
|
+
opts?: Record<string, unknown>;
|
|
12
|
+
}> = [];
|
|
13
|
+
let ipcResult: Record<string, unknown> = {
|
|
14
|
+
ok: true,
|
|
15
|
+
result: {
|
|
16
|
+
channel: "slack",
|
|
17
|
+
chatId: "C0123456789",
|
|
18
|
+
messageIds: ["1700000000.000100"],
|
|
19
|
+
lastMessageId: "1700000000.000100",
|
|
20
|
+
recordedIn: "conv-home",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const actualCliClient = await import("../../../../ipc/cli-client.js");
|
|
25
|
+
mock.module("../../../../ipc/cli-client.js", () => ({
|
|
26
|
+
...actualCliClient,
|
|
27
|
+
cliIpcCall: async (
|
|
28
|
+
method: string,
|
|
29
|
+
params: Record<string, unknown>,
|
|
30
|
+
opts?: Record<string, unknown>,
|
|
31
|
+
) => {
|
|
32
|
+
ipcCalls.push({ method, params, ...(opts ? { opts } : {}) });
|
|
33
|
+
return ipcResult;
|
|
34
|
+
},
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
// Imported after the mock is installed, so the command module under test
|
|
38
|
+
// binds the stubbed IPC call rather than the real one.
|
|
39
|
+
const { runCliCommand } = await import("../../__tests__/cli-test-harness.js");
|
|
40
|
+
const { registerChannelsCommand } = await import("../index.js");
|
|
41
|
+
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
ipcCalls.length = 0;
|
|
44
|
+
ipcResult = {
|
|
45
|
+
ok: true,
|
|
46
|
+
result: {
|
|
47
|
+
channel: "slack",
|
|
48
|
+
chatId: "C0123456789",
|
|
49
|
+
messageIds: ["1700000000.000100"],
|
|
50
|
+
lastMessageId: "1700000000.000100",
|
|
51
|
+
recordedIn: "conv-home",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// The shipped registration as-is: `send` declares its own `--json`, which is
|
|
57
|
+
// why the program's global leaf-option pass skips it.
|
|
58
|
+
function runSend(args: string[]) {
|
|
59
|
+
return runCliCommand(registerChannelsCommand, ["channels", "send", ...args]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The body the command handed the route on its one call. */
|
|
63
|
+
function sentBody(): Record<string, unknown> {
|
|
64
|
+
expect(ipcCalls).toHaveLength(1);
|
|
65
|
+
expect(ipcCalls[0]!.method).toBe("channels_send_post");
|
|
66
|
+
return ipcCalls[0]!.params.body as Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
describe("the request the command makes", () => {
|
|
70
|
+
test("names the chat and asks for the channel's rich rendering", async () => {
|
|
71
|
+
const r = await runSend([
|
|
72
|
+
"slack",
|
|
73
|
+
"C0123456789",
|
|
74
|
+
"--text",
|
|
75
|
+
"deploy is green",
|
|
76
|
+
]);
|
|
77
|
+
expect(r.exitCode).toBe(0);
|
|
78
|
+
expect(sentBody()).toEqual({
|
|
79
|
+
channel: "slack",
|
|
80
|
+
target: { kind: "chat", chatId: "C0123456789" },
|
|
81
|
+
text: "deploy is green",
|
|
82
|
+
renderRichly: true,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("carries a named thread as the target's thread", async () => {
|
|
87
|
+
await runSend([
|
|
88
|
+
"slack",
|
|
89
|
+
"C0123456789",
|
|
90
|
+
"--thread",
|
|
91
|
+
"1700000000.000001",
|
|
92
|
+
"--text",
|
|
93
|
+
"and the smoke tests passed",
|
|
94
|
+
]);
|
|
95
|
+
expect(sentBody().target).toEqual({
|
|
96
|
+
kind: "chat",
|
|
97
|
+
chatId: "C0123456789",
|
|
98
|
+
threadId: "1700000000.000001",
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("--plain asks for the text verbatim", async () => {
|
|
103
|
+
await runSend(["telegram", "123456789", "--text", "morning", "--plain"]);
|
|
104
|
+
const body = sentBody();
|
|
105
|
+
expect(body.renderRichly).toBeUndefined();
|
|
106
|
+
expect(body.channel).toBe("telegram");
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("sends the text as the caller wrote it, whitespace included", async () => {
|
|
110
|
+
await runSend([
|
|
111
|
+
"slack",
|
|
112
|
+
"C0123456789",
|
|
113
|
+
"--text",
|
|
114
|
+
" indented ",
|
|
115
|
+
"--plain",
|
|
116
|
+
]);
|
|
117
|
+
expect(sentBody().text).toBe(" indented ");
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("waits longer than the IPC default, since the send itself retries", async () => {
|
|
121
|
+
await runSend(["slack", "C0123456789", "--text", "hi"]);
|
|
122
|
+
expect(ipcCalls[0]!.opts).toMatchObject({ timeoutMs: 120_000 });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("refuses an empty text before it sends anything", async () => {
|
|
126
|
+
for (const args of [
|
|
127
|
+
["slack", "C0123456789"],
|
|
128
|
+
["slack", "C0123456789", "--text", " "],
|
|
129
|
+
]) {
|
|
130
|
+
ipcCalls.length = 0;
|
|
131
|
+
const r = await runSend(args);
|
|
132
|
+
expect(r.exitCode).toBe(1);
|
|
133
|
+
expect(r.stderr).toContain("--text is required");
|
|
134
|
+
expect(ipcCalls).toEqual([]);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
describe("what the command reports", () => {
|
|
140
|
+
test("names where the post landed and the conversation it was recorded in", async () => {
|
|
141
|
+
const r = await runSend(["slack", "C0123456789", "--text", "hello"]);
|
|
142
|
+
expect(r.stdout).toContain("C0123456789");
|
|
143
|
+
expect(r.stdout).toContain("1700000000.000100");
|
|
144
|
+
expect(r.stdout).toContain("conv-home");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("says so when the channel split the text", async () => {
|
|
148
|
+
ipcResult = {
|
|
149
|
+
ok: true,
|
|
150
|
+
result: {
|
|
151
|
+
channel: "telegram",
|
|
152
|
+
chatId: "123456789",
|
|
153
|
+
messageIds: ["10", "11", "12"],
|
|
154
|
+
lastMessageId: "12",
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
const r = await runSend(["telegram", "123456789", "--text", "a long one"]);
|
|
158
|
+
expect(r.stdout).toContain("3 posts");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("--json answers with the route's own result", async () => {
|
|
162
|
+
const r = await runSend([
|
|
163
|
+
"slack",
|
|
164
|
+
"C0123456789",
|
|
165
|
+
"--text",
|
|
166
|
+
"hello",
|
|
167
|
+
"--json",
|
|
168
|
+
]);
|
|
169
|
+
expect(JSON.parse(r.stdout)).toEqual({
|
|
170
|
+
channel: "slack",
|
|
171
|
+
chatId: "C0123456789",
|
|
172
|
+
messageIds: ["1700000000.000100"],
|
|
173
|
+
lastMessageId: "1700000000.000100",
|
|
174
|
+
recordedIn: "conv-home",
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("a refused send reports the route's reason and its exit code", async () => {
|
|
179
|
+
ipcResult = {
|
|
180
|
+
ok: false,
|
|
181
|
+
error: 'Channel "email" is not addressable',
|
|
182
|
+
statusCode: 400,
|
|
183
|
+
};
|
|
184
|
+
const r = await runSend(["email", "someone", "--text", "hello"]);
|
|
185
|
+
expect(r.exitCode).toBe(
|
|
186
|
+
actualCliClient.exitCodeFromIpcResult({ statusCode: 400 }),
|
|
187
|
+
);
|
|
188
|
+
expect(r.stderr).toContain("not addressable");
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("a timeout is reported as an unknown outcome, not a failure to retry", async () => {
|
|
192
|
+
ipcResult = { ok: false, error: "Request timed out", timedOut: true };
|
|
193
|
+
const r = await runSend(["slack", "C0123456789", "--text", "hello"]);
|
|
194
|
+
expect(r.stderr).toContain("may still be in flight");
|
|
195
|
+
expect(r.stderr).toContain("before sending again");
|
|
196
|
+
expect(r.stderr).not.toContain("The send failed");
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("a refusal in --json mode is a JSON error envelope", async () => {
|
|
200
|
+
ipcResult = {
|
|
201
|
+
ok: false,
|
|
202
|
+
error: 'Channel "slack" did not acknowledge the send',
|
|
203
|
+
statusCode: 502,
|
|
204
|
+
};
|
|
205
|
+
const r = await runSend([
|
|
206
|
+
"slack",
|
|
207
|
+
"C0123456789",
|
|
208
|
+
"--text",
|
|
209
|
+
"hello",
|
|
210
|
+
"--json",
|
|
211
|
+
]);
|
|
212
|
+
expect(JSON.parse(r.stdout)).toEqual({
|
|
213
|
+
ok: false,
|
|
214
|
+
error: 'Channel "slack" did not acknowledge the send',
|
|
215
|
+
});
|
|
216
|
+
expect(r.exitCode).toBe(3);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
@@ -36,9 +36,14 @@ assistant's own bot on that channel (${BOT_CHANNELS}), resolving the bot
|
|
|
36
36
|
credential from the channel id so no token is handled. Acting as a person
|
|
37
37
|
through their OAuth integration is 'assistant oauth request'.
|
|
38
38
|
|
|
39
|
+
To say something in a chat, use 'send' rather than 'request': it goes
|
|
40
|
+
through the channel's transport, so the post is threaded and rendered like
|
|
41
|
+
every other message the assistant sends there, and it is recorded.
|
|
42
|
+
|
|
39
43
|
Examples:
|
|
40
44
|
$ assistant channels list
|
|
41
45
|
$ assistant channels get slack
|
|
46
|
+
$ assistant channels send slack C0123456789 --text 'deploy is green'
|
|
42
47
|
$ assistant channels request slack /auth.test --json
|
|
43
48
|
$ assistant channels request slack -X POST \\
|
|
44
49
|
-d '{"channel":"D0123456789","limit":20}' /conversations.history --json`,
|
|
@@ -65,8 +70,9 @@ This command can do anything the bot's API allows, including sending,
|
|
|
65
70
|
editing, deleting, uploading, and reacting, so it is classified high risk
|
|
66
71
|
and asks for approval like any action with irreversible effects. Reads are
|
|
67
72
|
not distinguished from writes: the effect is the endpoint's. To send a
|
|
68
|
-
message, use
|
|
69
|
-
through this command
|
|
73
|
+
message, use 'assistant channels send', which posts through the channel's
|
|
74
|
+
transport and records what it sent; a message posted through this command
|
|
75
|
+
reaches the platform directly and leaves no record of what was said.
|
|
70
76
|
|
|
71
77
|
Arguments:
|
|
72
78
|
<channel> One of: ${BOT_CHANNELS}. A channel with no bot credential of
|
|
@@ -86,6 +92,68 @@ Examples:
|
|
|
86
92
|
$ assistant channels request slack -X POST \\
|
|
87
93
|
-d '{"channel":"D0123456789","limit":100}' /conversations.history --json
|
|
88
94
|
$ assistant channels request discord /users/@me --json`,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "send",
|
|
98
|
+
description:
|
|
99
|
+
"Post text to a chat on the channel, as the assistant's bot, recorded",
|
|
100
|
+
arguments: [
|
|
101
|
+
{
|
|
102
|
+
name: "<channel>",
|
|
103
|
+
description: `Channel to post on. One with a transport that can be addressed from a named chat; anything else is refused before the send.`,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "<chat-id>",
|
|
107
|
+
description:
|
|
108
|
+
"The chat in the channel's own id space (a Slack channel or DM id, a Telegram chat id, a Discord channel id, a WhatsApp number).",
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
options: [
|
|
112
|
+
{
|
|
113
|
+
flags: "--text <text>",
|
|
114
|
+
description: "The message text. Required.",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
flags: "--thread <id>",
|
|
118
|
+
description:
|
|
119
|
+
"Post inside this thread or topic, in the channel's own id space. Omit to post to the chat itself.",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
flags: "--plain",
|
|
123
|
+
description:
|
|
124
|
+
"Send the text verbatim instead of the channel's rich rendering.",
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
flags: "--json",
|
|
128
|
+
description: "Machine-readable compact JSON output",
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
helpText: `
|
|
132
|
+
Posts one message through the channel's own transport, the same path a
|
|
133
|
+
reply takes. Once the channel acknowledges it, the daemon records it in
|
|
134
|
+
the chat's conversation, which is what lets the assistant see later what
|
|
135
|
+
it said here and lets a reaction or an edit naming that post resolve back
|
|
136
|
+
to it. Recording is best effort and never fails a send that already went
|
|
137
|
+
out, so the result names the conversation only when the record was
|
|
138
|
+
written.
|
|
139
|
+
|
|
140
|
+
This sends a message people will read, so it is classified high risk and
|
|
141
|
+
asks for approval like any other action with effects nobody can take back.
|
|
142
|
+
|
|
143
|
+
The send fails, and records nothing, when the channel does not acknowledge
|
|
144
|
+
it or names no message id for it. A channel the assistant cannot address
|
|
145
|
+
from a named chat is refused before anything is sent. If the daemon does
|
|
146
|
+
not answer in time, the message may still go out: that is reported as an
|
|
147
|
+
unknown outcome rather than a failure, so check the chat before sending
|
|
148
|
+
again.
|
|
149
|
+
|
|
150
|
+
Attachments are not sent from here.
|
|
151
|
+
|
|
152
|
+
Examples:
|
|
153
|
+
$ assistant channels send slack C0123456789 --text 'deploy is green'
|
|
154
|
+
$ assistant channels send slack C0123456789 --thread 1700000000.000100 \
|
|
155
|
+
--text 'and the smoke tests passed'
|
|
156
|
+
$ assistant channels send telegram 123456789 --text 'morning' --json`,
|
|
89
157
|
},
|
|
90
158
|
{
|
|
91
159
|
name: "list",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `assistant channels`: inspect messaging channels, and act as their bots.
|
|
3
3
|
*
|
|
4
|
-
* list
|
|
5
|
-
* get <channel>
|
|
6
|
-
* request <channel> <url>
|
|
4
|
+
* list : overview of every channel + ready state
|
|
5
|
+
* get <channel> : detailed live snapshot of a single channel
|
|
6
|
+
* request <channel> <url> : call the channel's platform API as its bot
|
|
7
|
+
* send <channel> <chat-id> : post text to a chat, recorded
|
|
7
8
|
*
|
|
8
9
|
* `get` always re-runs remote probes (it invalidates the readiness cache
|
|
9
10
|
* before reading), so the CLI answer matches the live source-of-truth.
|
|
@@ -12,6 +13,11 @@
|
|
|
12
13
|
* channel's bot credential and makes the same authenticated request
|
|
13
14
|
* `oauth request` makes, without the caller naming a provider.
|
|
14
15
|
*
|
|
16
|
+
* `send` is the send door (see ./send.ts): it runs the daemon's one send
|
|
17
|
+
* implementation for the channel, so the post is threaded, rendered, and
|
|
18
|
+
* recorded like every other message the assistant sends there. Posting
|
|
19
|
+
* through `request` instead reaches the platform API and leaves no record.
|
|
20
|
+
*
|
|
15
21
|
* A mutating `refresh` verb (for reconnecting channels, e.g. supplying
|
|
16
22
|
* fresh Slack tokens) is intentionally not part of this group.
|
|
17
23
|
*/
|
|
@@ -26,6 +32,7 @@ import { log } from "../../logger.js";
|
|
|
26
32
|
import { shouldOutputJson, writeOutput } from "../../output.js";
|
|
27
33
|
import { CHANNELS_PLUGIN_SEARCH_HINT, channelsHelp } from "./index.help.js";
|
|
28
34
|
import { registerChannelsRequestCommand } from "./request.js";
|
|
35
|
+
import { registerChannelsSendCommand } from "./send.js";
|
|
29
36
|
|
|
30
37
|
// ---------------------------------------------------------------------------
|
|
31
38
|
// Snapshot shape
|
|
@@ -211,6 +218,12 @@ export function registerChannelsCommand(program: Command): void {
|
|
|
211
218
|
// -----------------------------------------------------------------------
|
|
212
219
|
|
|
213
220
|
registerChannelsRequestCommand(channels);
|
|
221
|
+
|
|
222
|
+
// -----------------------------------------------------------------------
|
|
223
|
+
// send: post text to a chat, through the channel's transport
|
|
224
|
+
// -----------------------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
registerChannelsSendCommand(channels);
|
|
214
227
|
},
|
|
215
228
|
});
|
|
216
229
|
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `assistant channels send`: post text to a chat on a channel, as the
|
|
3
|
+
* assistant's own bot.
|
|
4
|
+
*
|
|
5
|
+
* The send door. It runs the daemon function the messaging tool runs
|
|
6
|
+
* (`sendChannelText`, over `POST /v1/channels/send`), so a send from the
|
|
7
|
+
* command line reaches the chat through the channel's transport and leaves
|
|
8
|
+
* the same record: threaded where a thread is named, rendered the way the
|
|
9
|
+
* channel renders a reply, and written to the chat's conversation only once
|
|
10
|
+
* the channel has acknowledged it.
|
|
11
|
+
*
|
|
12
|
+
* Posting the same text through `channels request` reaches the platform API
|
|
13
|
+
* directly and leaves no record of what was said, which is why this command
|
|
14
|
+
* exists beside it. Both act as the bot and both carry the same rating: the
|
|
15
|
+
* effect is a message either way.
|
|
16
|
+
*
|
|
17
|
+
* A channel whose transport cannot be addressed from a named chat is
|
|
18
|
+
* refused by the route before anything is sent.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { Command } from "commander";
|
|
22
|
+
|
|
23
|
+
import { cliIpcCall, exitCodeFromIpcResult } from "../../../ipc/cli-client.js";
|
|
24
|
+
import { subcommand } from "../../lib/cli-command-help.js";
|
|
25
|
+
import { log } from "../../logger.js";
|
|
26
|
+
import { shouldOutputJson, writeError, writeOutput } from "../../output.js";
|
|
27
|
+
|
|
28
|
+
/** What the channel acknowledged, and where the post was recorded. */
|
|
29
|
+
interface ChannelSendResponse {
|
|
30
|
+
channel: string;
|
|
31
|
+
chatId: string;
|
|
32
|
+
threadId?: string;
|
|
33
|
+
messageIds: string[];
|
|
34
|
+
lastMessageId: string;
|
|
35
|
+
recordedIn?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface ChannelSendOptions {
|
|
39
|
+
text?: string;
|
|
40
|
+
thread?: string;
|
|
41
|
+
plain?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* How long to wait for the daemon before giving up on an answer.
|
|
46
|
+
*
|
|
47
|
+
* Longer than the IPC default because the work behind this call is a
|
|
48
|
+
* platform request that retries: a rate-limited Slack send sleeps for the
|
|
49
|
+
* `Retry-After` Slack names and tries again up to three times
|
|
50
|
+
* (`MAX_RATE_LIMIT_RETRIES`, providers/slack/web-api-transport.ts), and the
|
|
51
|
+
* other channels back off similarly. Waiting past that is better than
|
|
52
|
+
* abandoning a send that is still being made, because giving up tells the
|
|
53
|
+
* caller nothing about whether the message went out.
|
|
54
|
+
*/
|
|
55
|
+
const SEND_CALL_TIMEOUT_MS = 120_000;
|
|
56
|
+
|
|
57
|
+
export function registerChannelsSendCommand(channels: Command): void {
|
|
58
|
+
subcommand(channels, "send").action(
|
|
59
|
+
async (
|
|
60
|
+
channel: string,
|
|
61
|
+
chatId: string,
|
|
62
|
+
opts: ChannelSendOptions,
|
|
63
|
+
cmd: Command,
|
|
64
|
+
) => {
|
|
65
|
+
// Trimmed only to reject a blank message: the text goes out as the
|
|
66
|
+
// caller wrote it, which `--plain` in particular promises.
|
|
67
|
+
const text = opts.text;
|
|
68
|
+
if (!text?.trim()) {
|
|
69
|
+
writeError(cmd, "--text is required and cannot be empty.");
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const threadId = opts.thread?.trim();
|
|
75
|
+
const r = await cliIpcCall<ChannelSendResponse>(
|
|
76
|
+
"channels_send_post",
|
|
77
|
+
{
|
|
78
|
+
body: {
|
|
79
|
+
channel,
|
|
80
|
+
target: {
|
|
81
|
+
kind: "chat",
|
|
82
|
+
chatId,
|
|
83
|
+
...(threadId ? { threadId } : {}),
|
|
84
|
+
},
|
|
85
|
+
text,
|
|
86
|
+
// Rich unless asked otherwise, so a send from here reads like
|
|
87
|
+
// the assistant's other posts in that chat rather than like a
|
|
88
|
+
// different sender.
|
|
89
|
+
...(opts.plain ? {} : { renderRichly: true }),
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{ timeoutMs: SEND_CALL_TIMEOUT_MS },
|
|
93
|
+
);
|
|
94
|
+
if (!r.ok) {
|
|
95
|
+
// A timeout is not a failure: closing the client socket does not
|
|
96
|
+
// stop the daemon, so the message may still go out. Saying so is
|
|
97
|
+
// what keeps a retry from posting it twice.
|
|
98
|
+
const message = r.timedOut
|
|
99
|
+
? `The daemon did not answer within ${Math.round(SEND_CALL_TIMEOUT_MS / 1000)}s. The send may still be in flight, so it may or may not have gone out. Check the chat before sending again.`
|
|
100
|
+
: (r.error ?? "The send failed.");
|
|
101
|
+
// Reported rather than exited, so `--json` gets an error envelope
|
|
102
|
+
// like every other answer this command gives.
|
|
103
|
+
writeError(cmd, message);
|
|
104
|
+
process.exitCode = exitCodeFromIpcResult({
|
|
105
|
+
statusCode: r.statusCode,
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const sent = r.result!;
|
|
111
|
+
if (shouldOutputJson(cmd)) {
|
|
112
|
+
writeOutput(cmd, sent);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const where = sent.threadId
|
|
117
|
+
? `${sent.chatId}, thread ${sent.threadId}`
|
|
118
|
+
: sent.chatId;
|
|
119
|
+
log.info(`Sent to ${channel} ${where} (id: ${sent.lastMessageId})`);
|
|
120
|
+
if (sent.messageIds.length > 1) {
|
|
121
|
+
log.info(`The channel split it into ${sent.messageIds.length} posts`);
|
|
122
|
+
}
|
|
123
|
+
if (sent.recordedIn) {
|
|
124
|
+
log.info(`Recorded in conversation ${sent.recordedIn}`);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -45,8 +45,12 @@ Examples:
|
|
|
45
45
|
},
|
|
46
46
|
],
|
|
47
47
|
helpText: `
|
|
48
|
-
Lists
|
|
49
|
-
|
|
48
|
+
Lists credentials from the live credential vault. Each entry includes the same
|
|
49
|
+
fields as inspect: scrubbed value, timestamps, policy, and metadata.
|
|
50
|
+
|
|
51
|
+
Fails immediately with an error if the credential vault is unreachable. An
|
|
52
|
+
empty list means the vault answered and has no matching credentials, not that
|
|
53
|
+
the store is down.
|
|
50
54
|
|
|
51
55
|
The --search flag filters results by case-insensitive substring match against
|
|
52
56
|
the credential's service name, field name, label, or description. For example, --search
|
|
@@ -343,8 +343,8 @@ export function registerCredentialsCommand(program: Command): void {
|
|
|
343
343
|
} else {
|
|
344
344
|
printCredentialHuman(output);
|
|
345
345
|
if (output.brokerUnreachable) {
|
|
346
|
-
log.
|
|
347
|
-
"
|
|
346
|
+
log.warn(
|
|
347
|
+
" Credential store is unreachable. Retry in a moment, or check that the credential vault is running.",
|
|
348
348
|
);
|
|
349
349
|
}
|
|
350
350
|
}
|
|
@@ -7,8 +7,8 @@ export const mcpHelp: CliCommandHelp = {
|
|
|
7
7
|
description: "Manage MCP (Model Context Protocol) servers",
|
|
8
8
|
helpText: `
|
|
9
9
|
MCP servers extend the assistant's capabilities with external tools. Servers
|
|
10
|
-
are configured in the assistant's
|
|
11
|
-
|
|
10
|
+
are configured in the assistant's mcp.json, or declared by an installed
|
|
11
|
+
plugin in its root mcp.json. Each
|
|
12
12
|
server uses one of three transport types:
|
|
13
13
|
|
|
14
14
|
stdio Local process communicating over stdin/stdout
|
|
@@ -30,8 +30,8 @@ Examples:
|
|
|
30
30
|
options: [{ flags: "--json", description: "Output as JSON" }],
|
|
31
31
|
helpText: `
|
|
32
32
|
Shows each MCP server with its current status and configuration. Servers come
|
|
33
|
-
from two places: the mcp.
|
|
34
|
-
|
|
33
|
+
from two places: the workspace mcp.json, and the root mcp.json of any
|
|
34
|
+
installed plugin that declares one.
|
|
35
35
|
|
|
36
36
|
Name The server identifier
|
|
37
37
|
Status Health check result for workspace servers:
|
|
@@ -43,7 +43,7 @@ any installed plugin that declares one.
|
|
|
43
43
|
health-checked, so no stored credential can reach a URL a
|
|
44
44
|
plugin chose.
|
|
45
45
|
Source Shown only for plugin-declared servers, naming the plugin.
|
|
46
|
-
Servers from
|
|
46
|
+
Servers from workspace mcp.json print no Source line.
|
|
47
47
|
Transport stdio, sse, or streamable-http
|
|
48
48
|
URL/Command The server URL (sse/streamable-http) or command (stdio)
|
|
49
49
|
|
|
@@ -64,7 +64,7 @@ on their next turn automatically. The assistant must be running.
|
|
|
64
64
|
|
|
65
65
|
Examples:
|
|
66
66
|
$ vellum mcp reload
|
|
67
|
-
$ vellum mcp reload # after editing
|
|
67
|
+
$ vellum mcp reload # after editing mcp.json to add a new server
|
|
68
68
|
$ vellum mcp reload # after running "vellum mcp auth <server>"`,
|
|
69
69
|
},
|
|
70
70
|
{
|
|
@@ -95,7 +95,7 @@ Examples:
|
|
|
95
95
|
],
|
|
96
96
|
helpText: `
|
|
97
97
|
Arguments:
|
|
98
|
-
name Unique identifier for the server (used as the key in
|
|
98
|
+
name Unique identifier for the server (used as the key in mcp.json)
|
|
99
99
|
|
|
100
100
|
Transport-specific requirements:
|
|
101
101
|
stdio Requires --command (and optional --args for arguments)
|
|
@@ -149,7 +149,7 @@ Examples:
|
|
|
149
149
|
Arguments:
|
|
150
150
|
name Name of the MCP server to remove
|
|
151
151
|
|
|
152
|
-
Removes the server entry from
|
|
152
|
+
Removes the server entry from mcp.json and performs best-effort cleanup of
|
|
153
153
|
any stored OAuth credentials (tokens, client info, discovery metadata) for
|
|
154
154
|
sse/streamable-http servers. If no OAuth credentials exist, the cleanup is
|
|
155
155
|
silently skipped.
|
package/src/cli/commands/mcp.ts
CHANGED
|
@@ -20,7 +20,7 @@ interface McpServerEntry {
|
|
|
20
20
|
command?: string;
|
|
21
21
|
args?: string[];
|
|
22
22
|
};
|
|
23
|
-
/** Workspace `
|
|
23
|
+
/** Workspace `mcp.json` or a plugin's `mcp.json`. */
|
|
24
24
|
source?: "workspace" | "plugin";
|
|
25
25
|
/** Plugin that declared the server, when `source` is `plugin`. */
|
|
26
26
|
pluginName?: string;
|
|
@@ -40,6 +40,8 @@ interface ConnectionSummary {
|
|
|
40
40
|
status: string;
|
|
41
41
|
expiresAt?: string | null;
|
|
42
42
|
hasRefreshToken?: boolean;
|
|
43
|
+
/** Values the provider scopes the connection by (QuickBooks' realm id). */
|
|
44
|
+
providerParams?: Record<string, string>;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
interface OAuthStatusResponse {
|
|
@@ -92,6 +94,9 @@ function formatConnection(c: ConnectionSummary, mode: string): string {
|
|
|
92
94
|
} else {
|
|
93
95
|
lines.push(` Granted scopes: (none)`);
|
|
94
96
|
}
|
|
97
|
+
for (const [key, value] of Object.entries(c.providerParams ?? {})) {
|
|
98
|
+
lines.push(` ${key}: ${value}`);
|
|
99
|
+
}
|
|
95
100
|
if (mode === "byo") {
|
|
96
101
|
if (c.expiresAt) {
|
|
97
102
|
lines.push(` Expires: ${c.expiresAt}`);
|
|
@@ -4,8 +4,12 @@ import type { CliCommandHelp } from "../lib/cli-command-help.js";
|
|
|
4
4
|
|
|
5
5
|
export const roadmapHelp: CliCommandHelp = {
|
|
6
6
|
name: "roadmap",
|
|
7
|
-
description:
|
|
7
|
+
description:
|
|
8
|
+
"Read and file public feature proposals as the assistant. For bugs and support, instruct the user to join the Discord community at https://vellum.ai/community",
|
|
8
9
|
helpText: `
|
|
10
|
+
Items created here must be public feature proposals. For bugs and support
|
|
11
|
+
concerns, instruct the user to join the Discord community at https://vellum.ai/community.
|
|
12
|
+
|
|
9
13
|
Items, upvotes, and comments filed here are attributed to the assistant, not
|
|
10
14
|
to its owner: the assistant signs these calls with its own platform API key.
|
|
11
15
|
The owner's own roadmap identity lives on \`vellum roadmap\`.
|