@vellumai/assistant 0.5.6 → 0.5.8

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.
Files changed (442) hide show
  1. package/.env.example +16 -2
  2. package/ARCHITECTURE.md +6 -75
  3. package/Dockerfile +3 -2
  4. package/README.md +0 -2
  5. package/bun.lock +0 -414
  6. package/docker-entrypoint.sh +9 -0
  7. package/docs/architecture/keychain-broker.md +45 -240
  8. package/docs/architecture/memory.md +13 -11
  9. package/docs/architecture/security.md +0 -17
  10. package/docs/credential-execution-service.md +2 -2
  11. package/node_modules/@vellumai/ces-contracts/package.json +1 -0
  12. package/node_modules/@vellumai/ces-contracts/src/error.ts +1 -1
  13. package/node_modules/@vellumai/ces-contracts/src/grants.ts +1 -1
  14. package/node_modules/@vellumai/ces-contracts/src/handles.ts +1 -1
  15. package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -1
  16. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +120 -1
  17. package/node_modules/@vellumai/credential-storage/package.json +1 -0
  18. package/node_modules/@vellumai/egress-proxy/package.json +1 -0
  19. package/package.json +2 -3
  20. package/src/__tests__/actor-token-service.test.ts +0 -114
  21. package/src/__tests__/approval-cascade.test.ts +0 -1
  22. package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
  23. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  24. package/src/__tests__/browser-skill-endstate.test.ts +6 -5
  25. package/src/__tests__/btw-routes.test.ts +0 -39
  26. package/src/__tests__/call-controller.test.ts +0 -1
  27. package/src/__tests__/call-domain.test.ts +0 -128
  28. package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
  29. package/src/__tests__/ces-startup-timeout.test.ts +40 -0
  30. package/src/__tests__/channel-approval-routes.test.ts +0 -5
  31. package/src/__tests__/channel-readiness-service.test.ts +1 -60
  32. package/src/__tests__/checker.test.ts +4 -2
  33. package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
  34. package/src/__tests__/config-schema-cmd.test.ts +0 -2
  35. package/src/__tests__/config-schema.test.ts +3 -1
  36. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -1
  37. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
  38. package/src/__tests__/conversation-agent-loop.test.ts +2 -4
  39. package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
  40. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -1
  41. package/src/__tests__/conversation-error.test.ts +15 -1
  42. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  43. package/src/__tests__/conversation-messaging-secret-redirect.test.ts +1 -1
  44. package/src/__tests__/conversation-pre-run-repair.test.ts +0 -1
  45. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -1
  46. package/src/__tests__/conversation-queue.test.ts +0 -1
  47. package/src/__tests__/conversation-skill-tools.test.ts +0 -54
  48. package/src/__tests__/conversation-slash-queue.test.ts +0 -1
  49. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  50. package/src/__tests__/conversation-title-service.test.ts +87 -0
  51. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  52. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  53. package/src/__tests__/credential-execution-client.test.ts +5 -2
  54. package/src/__tests__/credential-execution-feature-gates.test.ts +59 -30
  55. package/src/__tests__/credential-execution-managed-contract.test.ts +35 -20
  56. package/src/__tests__/credential-security-e2e.test.ts +1 -67
  57. package/src/__tests__/credential-security-invariants.test.ts +6 -50
  58. package/src/__tests__/credentials-cli.test.ts +82 -3
  59. package/src/__tests__/daemon-credential-client.test.ts +123 -0
  60. package/src/__tests__/db-migration-rollback.test.ts +2015 -1
  61. package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -0
  62. package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
  63. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
  64. package/src/__tests__/gateway-client-managed-outbound.test.ts +79 -1
  65. package/src/__tests__/guardian-routing-state.test.ts +0 -5
  66. package/src/__tests__/host-shell-tool.test.ts +6 -7
  67. package/src/__tests__/http-user-message-parity.test.ts +3 -103
  68. package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
  69. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
  70. package/src/__tests__/intent-routing.test.ts +0 -13
  71. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
  72. package/src/__tests__/journal-context.test.ts +335 -0
  73. package/src/__tests__/keychain-broker-client.test.ts +161 -22
  74. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -3
  75. package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
  76. package/src/__tests__/memory-lifecycle-e2e.test.ts +70 -25
  77. package/src/__tests__/memory-recall-quality.test.ts +48 -17
  78. package/src/__tests__/memory-regressions.test.ts +408 -363
  79. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -3
  80. package/src/__tests__/migration-export-http.test.ts +2 -2
  81. package/src/__tests__/migration-import-commit-http.test.ts +2 -2
  82. package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
  83. package/src/__tests__/migration-validate-http.test.ts +2 -2
  84. package/src/__tests__/non-member-access-request.test.ts +2 -7
  85. package/src/__tests__/notification-decision-fallback.test.ts +4 -0
  86. package/src/__tests__/notification-decision-identity.test.ts +4 -0
  87. package/src/__tests__/notification-decision-strategy.test.ts +71 -0
  88. package/src/__tests__/oauth-cli.test.ts +5 -1
  89. package/src/__tests__/permission-types.test.ts +1 -0
  90. package/src/__tests__/provider-commit-message-generator.test.ts +0 -37
  91. package/src/__tests__/provider-error-scenarios.test.ts +0 -267
  92. package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
  93. package/src/__tests__/provider-streaming.benchmark.test.ts +2 -81
  94. package/src/__tests__/qdrant-manager.test.ts +28 -2
  95. package/src/__tests__/registry.test.ts +0 -6
  96. package/src/__tests__/relay-server.test.ts +1 -2
  97. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
  98. package/src/__tests__/script-proxy-injection-runtime.test.ts +1 -1
  99. package/src/__tests__/secret-onetime-send.test.ts +1 -1
  100. package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
  101. package/src/__tests__/secure-keys.test.ts +95 -272
  102. package/src/__tests__/shell-identity.test.ts +96 -6
  103. package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
  104. package/src/__tests__/skill-feature-flags.test.ts +46 -45
  105. package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
  106. package/src/__tests__/skill-load-inline-command.test.ts +8 -12
  107. package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
  108. package/src/__tests__/skill-load-tool.test.ts +0 -2
  109. package/src/__tests__/skill-memory.test.ts +17 -3
  110. package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
  111. package/src/__tests__/skills.test.ts +0 -2
  112. package/src/__tests__/slack-inbound-verification.test.ts +0 -4
  113. package/src/__tests__/stale-approval-dedup.test.ts +171 -0
  114. package/src/__tests__/stt-hints.test.ts +437 -0
  115. package/src/__tests__/suggestion-routes.test.ts +1 -32
  116. package/src/__tests__/system-prompt.test.ts +0 -1
  117. package/src/__tests__/task-memory-cleanup.test.ts +14 -0
  118. package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
  119. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
  120. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
  121. package/src/__tests__/twilio-routes-twiml.test.ts +139 -1
  122. package/src/__tests__/update-bulletin.test.ts +0 -2
  123. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
  124. package/src/__tests__/voice-quality.test.ts +58 -0
  125. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -7
  126. package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
  127. package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +220 -0
  128. package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
  129. package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
  130. package/src/acp/agent-process.ts +9 -1
  131. package/src/agent/loop.ts +1 -1
  132. package/src/approvals/guardian-request-resolvers.ts +164 -38
  133. package/src/calls/__tests__/tts-text-sanitizer.test.ts +254 -0
  134. package/src/calls/audio-store.test.ts +97 -0
  135. package/src/calls/audio-store.ts +205 -0
  136. package/src/calls/call-controller.ts +90 -8
  137. package/src/calls/call-domain.ts +3 -0
  138. package/src/calls/call-store.ts +10 -3
  139. package/src/calls/fish-audio-client.ts +129 -0
  140. package/src/calls/relay-server.ts +27 -0
  141. package/src/calls/stt-hints.ts +189 -0
  142. package/src/calls/tts-text-sanitizer.ts +61 -0
  143. package/src/calls/twilio-routes.ts +34 -5
  144. package/src/calls/types.ts +1 -0
  145. package/src/calls/voice-ingress-preflight.ts +0 -42
  146. package/src/calls/voice-quality.ts +38 -5
  147. package/src/calls/voice-session-bridge.ts +7 -12
  148. package/src/cli/commands/avatar.ts +2 -2
  149. package/src/cli/commands/config.ts +1 -4
  150. package/src/cli/commands/credentials.ts +128 -82
  151. package/src/cli/commands/doctor.ts +2 -2
  152. package/src/cli/commands/keys.ts +7 -7
  153. package/src/cli/commands/memory.ts +1 -1
  154. package/src/cli/commands/oauth/connections.ts +11 -29
  155. package/src/cli/commands/oauth/index.ts +7 -0
  156. package/src/cli/commands/oauth/platform.ts +525 -0
  157. package/src/cli/commands/platform.ts +3 -3
  158. package/src/cli/lib/daemon-credential-client.ts +284 -0
  159. package/src/cli.ts +1 -1
  160. package/src/config/assistant-feature-flags.ts +186 -5
  161. package/src/config/bundled-skills/AGENTS.md +34 -0
  162. package/src/config/bundled-skills/acp/SKILL.md +10 -0
  163. package/src/config/bundled-skills/app-builder/SKILL.md +0 -4
  164. package/src/config/bundled-skills/messaging/SKILL.md +5 -5
  165. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
  166. package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
  167. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -0
  168. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -0
  169. package/src/config/bundled-skills/settings/SKILL.md +15 -2
  170. package/src/config/bundled-skills/settings/TOOLS.json +47 -2
  171. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +59 -0
  172. package/src/config/bundled-skills/settings/tools/avatar-update.ts +80 -0
  173. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
  174. package/src/config/bundled-skills/slack/SKILL.md +1 -1
  175. package/src/config/bundled-tool-registry.ts +5 -11
  176. package/src/config/defaults.ts +0 -2
  177. package/src/config/env-registry.ts +5 -5
  178. package/src/config/env.ts +21 -14
  179. package/src/config/feature-flag-registry.json +49 -9
  180. package/src/config/loader.ts +106 -42
  181. package/src/config/schema.ts +9 -29
  182. package/src/config/schemas/calls.ts +30 -0
  183. package/src/config/schemas/fish-audio.ts +39 -0
  184. package/src/config/schemas/inference.ts +2 -2
  185. package/src/config/schemas/journal.ts +16 -0
  186. package/src/config/schemas/memory-processing.ts +2 -2
  187. package/src/config/schemas/security.ts +0 -4
  188. package/src/config/types.ts +1 -1
  189. package/src/contacts/contact-store.ts +39 -0
  190. package/src/contacts/types.ts +2 -0
  191. package/src/credential-execution/approval-bridge.ts +1 -0
  192. package/src/credential-execution/executable-discovery.ts +28 -4
  193. package/src/credential-execution/feature-gates.ts +16 -0
  194. package/src/credential-execution/process-manager.ts +38 -0
  195. package/src/credential-execution/startup-timeout.ts +36 -0
  196. package/src/daemon/approval-generators.ts +3 -9
  197. package/src/daemon/assistant-attachments.ts +9 -0
  198. package/src/daemon/config-watcher.ts +5 -0
  199. package/src/daemon/conversation-error.ts +13 -1
  200. package/src/daemon/conversation-memory.ts +1 -2
  201. package/src/daemon/conversation-process.ts +18 -1
  202. package/src/daemon/conversation-surfaces.ts +30 -1
  203. package/src/daemon/conversation-tool-setup.ts +0 -105
  204. package/src/daemon/conversation.ts +21 -1
  205. package/src/daemon/guardian-action-generators.ts +3 -9
  206. package/src/daemon/handlers/config-vercel.ts +92 -0
  207. package/src/daemon/handlers/skills.ts +2 -15
  208. package/src/daemon/install-symlink.ts +195 -0
  209. package/src/daemon/lifecycle.ts +234 -51
  210. package/src/daemon/message-types/conversations.ts +4 -4
  211. package/src/daemon/message-types/diagnostics.ts +3 -22
  212. package/src/daemon/message-types/messages.ts +0 -2
  213. package/src/daemon/message-types/upgrades.ts +8 -0
  214. package/src/daemon/server.ts +32 -95
  215. package/src/events/domain-events.ts +2 -1
  216. package/src/inbound/platform-callback-registration.ts +3 -3
  217. package/src/instrument.ts +8 -5
  218. package/src/memory/app-store.ts +31 -0
  219. package/src/memory/conversation-title-service.ts +50 -1
  220. package/src/memory/db-init.ts +16 -0
  221. package/src/memory/indexer.ts +19 -10
  222. package/src/memory/items-extractor.ts +328 -321
  223. package/src/memory/job-handlers/conversation-starters.ts +4 -1
  224. package/src/memory/job-handlers/summarization.ts +26 -16
  225. package/src/memory/jobs-store.ts +63 -6
  226. package/src/memory/jobs-worker.ts +31 -7
  227. package/src/memory/journal-memory.ts +214 -0
  228. package/src/memory/migrations/001-job-deferrals.ts +19 -0
  229. package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
  230. package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
  231. package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
  232. package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
  233. package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
  234. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
  235. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
  236. package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
  237. package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
  238. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
  239. package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
  240. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
  241. package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
  242. package/src/memory/migrations/116-messages-fts.ts +106 -1
  243. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
  244. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
  245. package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
  246. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
  247. package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
  248. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
  249. package/src/memory/migrations/141-rename-verification-table.ts +54 -0
  250. package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
  251. package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
  252. package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
  253. package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
  254. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
  255. package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
  256. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
  257. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
  258. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
  259. package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
  260. package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
  261. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
  262. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
  263. package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
  264. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
  265. package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
  266. package/src/memory/migrations/193-add-source-type-columns.ts +81 -0
  267. package/src/memory/migrations/index.ts +5 -0
  268. package/src/memory/migrations/registry.ts +98 -0
  269. package/src/memory/migrations/validate-migration-state.ts +137 -11
  270. package/src/memory/qdrant-circuit-breaker.ts +9 -0
  271. package/src/memory/qdrant-manager.ts +64 -7
  272. package/src/memory/retriever.test.ts +37 -25
  273. package/src/memory/retriever.ts +24 -49
  274. package/src/memory/schema/calls.ts +1 -0
  275. package/src/memory/schema/contacts.ts +1 -0
  276. package/src/memory/schema/memory-core.ts +2 -0
  277. package/src/memory/search/formatting.ts +7 -44
  278. package/src/memory/search/staleness.ts +4 -0
  279. package/src/memory/search/tier-classifier.ts +10 -2
  280. package/src/memory/search/types.ts +2 -5
  281. package/src/memory/task-memory-cleanup.ts +4 -3
  282. package/src/notifications/adapters/slack.ts +168 -6
  283. package/src/notifications/broadcaster.ts +1 -0
  284. package/src/notifications/copy-composer.ts +59 -2
  285. package/src/notifications/decision-engine.ts +4 -1
  286. package/src/notifications/signal.ts +2 -0
  287. package/src/notifications/types.ts +2 -0
  288. package/src/oauth/connection-resolver.ts +6 -4
  289. package/src/permissions/checker.ts +0 -38
  290. package/src/permissions/shell-identity.ts +76 -22
  291. package/src/permissions/types.ts +4 -2
  292. package/src/platform/client.ts +35 -7
  293. package/src/prompts/journal-context.ts +133 -0
  294. package/src/prompts/persona-resolver.ts +194 -0
  295. package/src/prompts/system-prompt.ts +44 -4
  296. package/src/prompts/templates/SOUL.md +10 -0
  297. package/src/prompts/templates/users/default.md +1 -0
  298. package/src/providers/provider-send-message.ts +3 -32
  299. package/src/providers/registry.ts +29 -179
  300. package/src/providers/types.ts +1 -1
  301. package/src/runtime/access-request-helper.ts +4 -0
  302. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  303. package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
  304. package/src/runtime/auth/__tests__/guard-tests.test.ts +9 -50
  305. package/src/runtime/auth/external-assistant-id.ts +13 -59
  306. package/src/runtime/auth/route-policy.ts +17 -1
  307. package/src/runtime/auth/token-service.ts +43 -138
  308. package/src/runtime/channel-readiness-service.ts +1 -16
  309. package/src/runtime/gateway-client.ts +47 -4
  310. package/src/runtime/guardian-decision-types.ts +45 -4
  311. package/src/runtime/http-server.ts +31 -3
  312. package/src/runtime/middleware/error-handler.ts +1 -9
  313. package/src/runtime/routes/access-request-decision.ts +2 -2
  314. package/src/runtime/routes/app-management-routes.ts +2 -1
  315. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +219 -30
  316. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +37 -14
  317. package/src/runtime/routes/audio-routes.ts +40 -0
  318. package/src/runtime/routes/btw-routes.ts +0 -17
  319. package/src/runtime/routes/channel-readiness-routes.ts +9 -4
  320. package/src/runtime/routes/conversation-query-routes.ts +63 -1
  321. package/src/runtime/routes/conversation-routes.ts +4 -44
  322. package/src/runtime/routes/debug-routes.ts +12 -9
  323. package/src/runtime/routes/diagnostics-routes.ts +1 -477
  324. package/src/runtime/routes/guardian-approval-interception.ts +168 -11
  325. package/src/runtime/routes/guardian-approval-prompt.ts +6 -1
  326. package/src/runtime/routes/guardian-approval-reply-helpers.ts +103 -21
  327. package/src/runtime/routes/identity-routes.ts +19 -30
  328. package/src/runtime/routes/inbound-message-handler.ts +31 -1
  329. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +64 -5
  330. package/src/runtime/routes/inbound-stages/background-dispatch.ts +52 -40
  331. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
  332. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  333. package/src/runtime/routes/integrations/twilio.ts +52 -10
  334. package/src/runtime/routes/integrations/vercel.ts +89 -0
  335. package/src/runtime/routes/log-export-routes.ts +5 -0
  336. package/src/runtime/routes/memory-item-routes.test.ts +3 -3
  337. package/src/runtime/routes/memory-item-routes.ts +46 -14
  338. package/src/runtime/routes/migration-rollback-routes.ts +209 -0
  339. package/src/runtime/routes/migration-routes.ts +17 -1
  340. package/src/runtime/routes/notification-routes.ts +58 -0
  341. package/src/runtime/routes/schedule-routes.ts +65 -0
  342. package/src/runtime/routes/secret-routes.ts +141 -10
  343. package/src/runtime/routes/settings-routes.ts +41 -1
  344. package/src/runtime/routes/tts-routes.ts +96 -0
  345. package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
  346. package/src/runtime/routes/workspace-commit-routes.ts +62 -0
  347. package/src/runtime/routes/workspace-routes.test.ts +22 -1
  348. package/src/runtime/routes/workspace-routes.ts +1 -1
  349. package/src/runtime/routes/workspace-utils.ts +86 -2
  350. package/src/security/ces-credential-client.ts +75 -29
  351. package/src/security/ces-rpc-credential-backend.ts +86 -0
  352. package/src/security/credential-backend.ts +22 -92
  353. package/src/security/keychain-broker-client.ts +10 -2
  354. package/src/security/secure-keys.ts +113 -115
  355. package/src/skills/catalog-install.ts +6 -32
  356. package/src/skills/skill-memory.ts +1 -0
  357. package/src/subagent/manager.ts +2 -5
  358. package/src/telemetry/usage-telemetry-reporter.ts +4 -2
  359. package/src/tools/acp/spawn.ts +78 -1
  360. package/src/tools/calls/call-start.ts +1 -0
  361. package/src/tools/credentials/vault.ts +5 -3
  362. package/src/tools/executor.ts +0 -4
  363. package/src/tools/memory/definitions.ts +3 -2
  364. package/src/tools/memory/handlers.ts +10 -7
  365. package/src/tools/network/script-proxy/session-manager.ts +19 -4
  366. package/src/tools/network/web-fetch.ts +3 -1
  367. package/src/tools/skills/execute.ts +1 -1
  368. package/src/tools/terminal/safe-env.ts +1 -0
  369. package/src/tools/types.ts +0 -8
  370. package/src/util/browser.ts +15 -0
  371. package/src/util/errors.ts +0 -12
  372. package/src/util/platform.ts +4 -51
  373. package/src/workspace/git-service.ts +5 -2
  374. package/src/workspace/migrations/001-avatar-rename.ts +15 -0
  375. package/src/workspace/migrations/003-seed-device-id.ts +17 -1
  376. package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
  377. package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
  378. package/src/workspace/migrations/006-services-config.ts +49 -0
  379. package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
  380. package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
  381. package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
  382. package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
  383. package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
  384. package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
  385. package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
  386. package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
  387. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
  388. package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
  389. package/src/workspace/migrations/017-seed-persona-dirs.ts +96 -0
  390. package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +184 -0
  391. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +103 -0
  392. package/src/workspace/migrations/migrate-to-workspace-volume.ts +27 -5
  393. package/src/workspace/migrations/registry.ts +12 -0
  394. package/src/workspace/migrations/runner.ts +106 -2
  395. package/src/workspace/migrations/types.ts +4 -0
  396. package/src/workspace/provider-commit-message-generator.ts +12 -21
  397. package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
  398. package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
  399. package/src/__tests__/diagnostics-export.test.ts +0 -288
  400. package/src/__tests__/local-gateway-health.test.ts +0 -209
  401. package/src/__tests__/provider-fail-open-selection.test.ts +0 -271
  402. package/src/__tests__/provider-failover-actual-provider.test.ts +0 -66
  403. package/src/__tests__/secret-ingress-handler.test.ts +0 -120
  404. package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
  405. package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
  406. package/src/__tests__/swarm-orchestrator.test.ts +0 -463
  407. package/src/__tests__/swarm-plan-validator.test.ts +0 -384
  408. package/src/__tests__/swarm-recursion.test.ts +0 -197
  409. package/src/__tests__/swarm-router-planner.test.ts +0 -234
  410. package/src/__tests__/swarm-tool.test.ts +0 -185
  411. package/src/__tests__/swarm-worker-backend.test.ts +0 -144
  412. package/src/__tests__/swarm-worker-runner.test.ts +0 -288
  413. package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
  414. package/src/commands/cc-command-registry.ts +0 -248
  415. package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
  416. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
  417. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
  418. package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
  419. package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
  420. package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
  421. package/src/config/schemas/swarm.ts +0 -82
  422. package/src/logfire.ts +0 -135
  423. package/src/memory/search/lexical.ts +0 -48
  424. package/src/providers/failover.ts +0 -186
  425. package/src/runtime/local-gateway-health.ts +0 -275
  426. package/src/security/secret-ingress.ts +0 -68
  427. package/src/swarm/backend-claude-code.ts +0 -225
  428. package/src/swarm/checkpoint.ts +0 -137
  429. package/src/swarm/graph-utils.ts +0 -53
  430. package/src/swarm/index.ts +0 -55
  431. package/src/swarm/limits.ts +0 -66
  432. package/src/swarm/orchestrator.ts +0 -424
  433. package/src/swarm/plan-validator.ts +0 -117
  434. package/src/swarm/router-planner.ts +0 -162
  435. package/src/swarm/router-prompts.ts +0 -39
  436. package/src/swarm/synthesizer.ts +0 -81
  437. package/src/swarm/types.ts +0 -72
  438. package/src/swarm/worker-backend.ts +0 -131
  439. package/src/swarm/worker-prompts.ts +0 -80
  440. package/src/swarm/worker-runner.ts +0 -170
  441. package/src/tools/claude-code/claude-code.ts +0 -610
  442. package/src/tools/swarm/delegate.ts +0 -205
@@ -0,0 +1,525 @@
1
+ import type { Command } from "commander";
2
+
3
+ import { getConfig } from "../../../config/loader.js";
4
+ import {
5
+ type Services,
6
+ ServicesSchema,
7
+ } from "../../../config/schemas/services.js";
8
+ import { getProvider } from "../../../oauth/oauth-store.js";
9
+ import { VellumPlatformClient } from "../../../platform/client.js";
10
+ import { openInBrowser } from "../../../util/browser.js";
11
+ import { getCliLogger } from "../../logger.js";
12
+ import { shouldOutputJson, writeOutput } from "../../output.js";
13
+
14
+ const log = getCliLogger("cli");
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Shared types
18
+ // ---------------------------------------------------------------------------
19
+
20
+ interface PlatformConnectionEntry {
21
+ id: string;
22
+ account_label?: string;
23
+ scopes_granted?: string[];
24
+ status?: string;
25
+ }
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Shared helpers
29
+ // ---------------------------------------------------------------------------
30
+
31
+ /**
32
+ * Normalize a bare provider name (e.g. "google") into the canonical provider
33
+ * key used internally (e.g. "integration:google").
34
+ */
35
+ function toProviderKey(provider: string): string {
36
+ return provider.startsWith("integration:")
37
+ ? provider
38
+ : `integration:${provider}`;
39
+ }
40
+
41
+ /**
42
+ * Extract the bare provider slug (e.g. "google") from either a raw CLI
43
+ * argument or a canonical provider key (e.g. "integration:google").
44
+ * Platform API paths expect the bare slug, not the internal key.
45
+ */
46
+ function toBareProvider(provider: string): string {
47
+ return provider.startsWith("integration:")
48
+ ? provider.slice("integration:".length)
49
+ : provider;
50
+ }
51
+
52
+ /**
53
+ * Validate that a provider supports managed OAuth (has a managedServiceConfigKey).
54
+ * Does NOT check whether managed mode is currently enabled — use this for
55
+ * operations that should work regardless of the current mode (e.g. disconnect).
56
+ * Returns the managed config key on success, or writes an error and returns null.
57
+ */
58
+ function requireManagedCapableProvider(
59
+ provider: string,
60
+ cmd: Command,
61
+ ): string | null {
62
+ const providerKey = toProviderKey(provider);
63
+ const providerRow = getProvider(providerKey);
64
+
65
+ const managedKey = providerRow?.managedServiceConfigKey;
66
+ if (!managedKey || !(managedKey in ServicesSchema.shape)) {
67
+ writeOutput(cmd, {
68
+ ok: false,
69
+ error: `Provider "${provider}" does not support platform-managed OAuth`,
70
+ });
71
+ process.exitCode = 1;
72
+ return null;
73
+ }
74
+
75
+ return managedKey;
76
+ }
77
+
78
+ /**
79
+ * Validate that a provider supports managed OAuth AND that managed mode is
80
+ * currently enabled. Use this for operations that require active managed
81
+ * mode (e.g. connect). Returns the managed config key on success, or writes
82
+ * an error and returns null.
83
+ */
84
+ function requireManagedProvider(provider: string, cmd: Command): string | null {
85
+ const managedKey = requireManagedCapableProvider(provider, cmd);
86
+ if (!managedKey) return null;
87
+
88
+ const services: Services = getConfig().services;
89
+ const managedEnabled =
90
+ services[managedKey as keyof Services].mode === "managed";
91
+
92
+ if (!managedEnabled) {
93
+ writeOutput(cmd, {
94
+ ok: false,
95
+ error: `Provider "${provider}" supports managed OAuth but is set to "your-own" mode`,
96
+ });
97
+ process.exitCode = 1;
98
+ return null;
99
+ }
100
+
101
+ return managedKey;
102
+ }
103
+
104
+ /**
105
+ * Create an authenticated platform client, or write an error and return null.
106
+ */
107
+ async function requirePlatformClient(
108
+ cmd: Command,
109
+ ): Promise<VellumPlatformClient | null> {
110
+ const client = await VellumPlatformClient.create();
111
+ if (!client || !client.platformAssistantId) {
112
+ writeOutput(cmd, {
113
+ ok: false,
114
+ error:
115
+ "Platform prerequisites not met (not logged in or missing assistant ID)",
116
+ });
117
+ process.exitCode = 1;
118
+ return null;
119
+ }
120
+ return client;
121
+ }
122
+
123
+ /**
124
+ * Fetch active platform connections for a provider. Returns the parsed entries
125
+ * or writes an error and returns null.
126
+ */
127
+ async function fetchActiveConnections(
128
+ client: VellumPlatformClient,
129
+ provider: string,
130
+ cmd: Command,
131
+ ): Promise<PlatformConnectionEntry[] | null> {
132
+ const params = new URLSearchParams();
133
+ params.set("provider", toBareProvider(provider));
134
+ params.set("status", "ACTIVE");
135
+
136
+ const path = `/v1/assistants/${encodeURIComponent(client.platformAssistantId)}/oauth/connections/?${params.toString()}`;
137
+ const response = await client.fetch(path);
138
+
139
+ if (!response.ok) {
140
+ writeOutput(cmd, {
141
+ ok: false,
142
+ error: `Platform returned HTTP ${response.status}`,
143
+ });
144
+ process.exitCode = 1;
145
+ return null;
146
+ }
147
+
148
+ const body = (await response.json()) as unknown;
149
+
150
+ // The platform returns either a flat array or a {results: [...]} wrapper.
151
+ return (
152
+ Array.isArray(body)
153
+ ? body
154
+ : ((body as Record<string, unknown>).results ?? [])
155
+ ) as PlatformConnectionEntry[];
156
+ }
157
+
158
+ // ---------------------------------------------------------------------------
159
+ // Command registration
160
+ // ---------------------------------------------------------------------------
161
+
162
+ export function registerPlatformCommands(oauth: Command): void {
163
+ const platform = oauth
164
+ .command("platform")
165
+ .description(
166
+ "Manage platform-managed OAuth provider status and connections",
167
+ );
168
+
169
+ registerStatusCommand(platform);
170
+ registerConnectCommand(platform);
171
+ registerDisconnectCommand(platform);
172
+ }
173
+
174
+ // ---------------------------------------------------------------------------
175
+ // platform status <provider>
176
+ // ---------------------------------------------------------------------------
177
+
178
+ function registerStatusCommand(platform: Command): void {
179
+ platform
180
+ .command("status <provider>")
181
+ .description(
182
+ "Check whether a provider supports managed OAuth and list the user's active connections",
183
+ )
184
+ .addHelpText(
185
+ "after",
186
+ `
187
+ Arguments:
188
+ provider Provider name (e.g. google, slack, twitter)
189
+
190
+ Checks whether the platform offers managed OAuth for the given provider,
191
+ whether managed mode is currently enabled, and lists any active connections
192
+ the user has set up on the platform.
193
+
194
+ Examples:
195
+ $ assistant oauth platform status google
196
+ $ assistant oauth platform status slack --json`,
197
+ )
198
+ .action(
199
+ async (
200
+ provider: string,
201
+ _opts: Record<string, unknown>,
202
+ cmd: Command,
203
+ ) => {
204
+ try {
205
+ const providerKey = toProviderKey(provider);
206
+ const providerRow = getProvider(providerKey);
207
+
208
+ // 1. Check if the provider even supports managed mode
209
+ const managedKey = providerRow?.managedServiceConfigKey;
210
+ if (!managedKey || !(managedKey in ServicesSchema.shape)) {
211
+ writeOutput(cmd, {
212
+ ok: true,
213
+ provider,
214
+ managedAvailable: false,
215
+ managedEnabled: false,
216
+ connections: [],
217
+ });
218
+ if (!shouldOutputJson(cmd)) {
219
+ log.info(
220
+ `Provider "${provider}" does not support platform-managed OAuth`,
221
+ );
222
+ }
223
+ return;
224
+ }
225
+
226
+ // 2. Check if managed mode is enabled in the services config
227
+ const services: Services = getConfig().services;
228
+ const managedEnabled =
229
+ services[managedKey as keyof Services].mode === "managed";
230
+
231
+ if (!managedEnabled) {
232
+ writeOutput(cmd, {
233
+ ok: true,
234
+ provider,
235
+ managedAvailable: true,
236
+ managedEnabled: false,
237
+ connections: [],
238
+ });
239
+ if (!shouldOutputJson(cmd)) {
240
+ log.info(
241
+ `Provider "${provider}" supports managed OAuth but is set to "your-own" mode`,
242
+ );
243
+ }
244
+ return;
245
+ }
246
+
247
+ // 3. Fetch active connections from the platform
248
+ const client = await requirePlatformClient(cmd);
249
+ if (!client) return;
250
+
251
+ const rawEntries = await fetchActiveConnections(
252
+ client,
253
+ provider,
254
+ cmd,
255
+ );
256
+ if (!rawEntries) return;
257
+
258
+ const connections = rawEntries.map((c) => ({
259
+ id: c.id,
260
+ accountLabel: c.account_label ?? null,
261
+ scopesGranted: c.scopes_granted ?? [],
262
+ status: c.status ?? "ACTIVE",
263
+ }));
264
+
265
+ writeOutput(cmd, {
266
+ ok: true,
267
+ provider,
268
+ managedAvailable: true,
269
+ managedEnabled: true,
270
+ connections,
271
+ });
272
+
273
+ if (!shouldOutputJson(cmd)) {
274
+ if (connections.length === 0) {
275
+ log.info(
276
+ `Provider "${provider}" is managed but has no active connections`,
277
+ );
278
+ } else {
279
+ log.info(
280
+ `Provider "${provider}": ${connections.length} active connection(s)`,
281
+ );
282
+ }
283
+ }
284
+ } catch (err) {
285
+ const message = err instanceof Error ? err.message : String(err);
286
+ writeOutput(cmd, { ok: false, error: message });
287
+ process.exitCode = 1;
288
+ }
289
+ },
290
+ );
291
+ }
292
+
293
+ // ---------------------------------------------------------------------------
294
+ // platform connect <provider>
295
+ // ---------------------------------------------------------------------------
296
+
297
+ function registerConnectCommand(platform: Command): void {
298
+ platform
299
+ .command("connect <provider>")
300
+ .description(
301
+ "Initiate a platform-managed OAuth flow for a provider and open the browser",
302
+ )
303
+ .option(
304
+ "--scopes <scopes...>",
305
+ "Exact OAuth scopes to request (must be a subset of the provider's allowed scopes)",
306
+ )
307
+ .addHelpText(
308
+ "after",
309
+ `
310
+ Arguments:
311
+ provider Provider name (e.g. google, slack, twitter)
312
+
313
+ Starts a platform-managed OAuth authorization flow by calling the platform's
314
+ /start/ endpoint, then opens the returned authorization URL in the user's
315
+ browser. The user completes consent in the browser; the platform handles the
316
+ callback, token exchange, and credential storage.
317
+
318
+ The provider must support managed OAuth and managed mode must be enabled in
319
+ the services config.
320
+
321
+ Scope behavior:
322
+ Without --scopes, the platform requests ALL of the provider's allowed scopes.
323
+ With --scopes, only the specified scopes are requested (no merging with
324
+ defaults). Each scope must be in the provider's allowed set or the platform
325
+ will reject it. Use full scope URLs where required (e.g. Google scopes use
326
+ https://www.googleapis.com/auth/... format).
327
+
328
+ Examples:
329
+ $ assistant oauth platform connect google
330
+ $ assistant oauth platform connect google --scopes https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events
331
+ $ assistant oauth platform connect google --json`,
332
+ )
333
+ .action(
334
+ async (provider: string, opts: { scopes?: string[] }, cmd: Command) => {
335
+ try {
336
+ if (!requireManagedProvider(provider, cmd)) return;
337
+
338
+ const client = await requirePlatformClient(cmd);
339
+ if (!client) return;
340
+
341
+ // Call the platform's OAuth start endpoint
342
+ const startPath = `/v1/assistants/${encodeURIComponent(client.platformAssistantId)}/oauth/${encodeURIComponent(toBareProvider(provider))}/start/`;
343
+
344
+ const body: Record<string, unknown> = {};
345
+ if (opts.scopes && opts.scopes.length > 0) {
346
+ body.requested_scopes = opts.scopes;
347
+ }
348
+
349
+ const response = await client.fetch(startPath, {
350
+ method: "POST",
351
+ headers: { "Content-Type": "application/json" },
352
+ body: JSON.stringify(body),
353
+ });
354
+
355
+ if (!response.ok) {
356
+ const errorText = await response.text().catch(() => "");
357
+ writeOutput(cmd, {
358
+ ok: false,
359
+ error: `Platform returned HTTP ${response.status}${errorText ? `: ${errorText}` : ""}`,
360
+ });
361
+ process.exitCode = 1;
362
+ return;
363
+ }
364
+
365
+ const result = (await response.json()) as {
366
+ connect_url?: string;
367
+ };
368
+
369
+ if (!result.connect_url) {
370
+ writeOutput(cmd, {
371
+ ok: false,
372
+ error:
373
+ "Platform did not return a connect URL — the OAuth flow could not be started",
374
+ });
375
+ process.exitCode = 1;
376
+ return;
377
+ }
378
+
379
+ openInBrowser(result.connect_url);
380
+
381
+ writeOutput(cmd, {
382
+ ok: true,
383
+ deferred: true,
384
+ provider,
385
+ connectUrl: result.connect_url,
386
+ });
387
+
388
+ if (!shouldOutputJson(cmd)) {
389
+ log.info(
390
+ `Opening browser to connect ${provider}. Complete the authorization in your browser.`,
391
+ );
392
+ }
393
+ } catch (err) {
394
+ const message = err instanceof Error ? err.message : String(err);
395
+ writeOutput(cmd, { ok: false, error: message });
396
+ process.exitCode = 1;
397
+ }
398
+ },
399
+ );
400
+ }
401
+
402
+ // ---------------------------------------------------------------------------
403
+ // platform disconnect <provider>
404
+ // ---------------------------------------------------------------------------
405
+
406
+ function registerDisconnectCommand(platform: Command): void {
407
+ platform
408
+ .command("disconnect <provider>")
409
+ .description(
410
+ "Disconnect a platform-managed OAuth connection for a provider",
411
+ )
412
+ .option(
413
+ "--connection-id <id>",
414
+ "Specific connection ID to disconnect (required when multiple active connections exist)",
415
+ )
416
+ .addHelpText(
417
+ "after",
418
+ `
419
+ Arguments:
420
+ provider Provider name (e.g. google, slack, twitter)
421
+
422
+ Disconnects a platform-managed OAuth connection by calling the platform's
423
+ /disconnect/ endpoint, which revokes the connection.
424
+
425
+ If the provider has multiple active connections, use --connection-id to specify
426
+ which one to disconnect. Without --connection-id, the command disconnects the
427
+ sole active connection or fails with a list of active connections if there are
428
+ multiple.
429
+
430
+ Examples:
431
+ $ assistant oauth platform disconnect google
432
+ $ assistant oauth platform disconnect google --connection-id conn_abc123
433
+ $ assistant oauth platform disconnect google --json`,
434
+ )
435
+ .action(
436
+ async (
437
+ provider: string,
438
+ opts: { connectionId?: string },
439
+ cmd: Command,
440
+ ) => {
441
+ try {
442
+ if (!requireManagedCapableProvider(provider, cmd)) return;
443
+
444
+ const client = await requirePlatformClient(cmd);
445
+ if (!client) return;
446
+
447
+ // Always fetch active connections for the provider so we can
448
+ // verify --connection-id belongs to it (prevents cross-provider
449
+ // disconnects from typos or stale IDs).
450
+ const entries = await fetchActiveConnections(client, provider, cmd);
451
+ if (!entries) return;
452
+
453
+ let connectionId = opts.connectionId;
454
+
455
+ if (connectionId) {
456
+ // Verify the supplied ID belongs to this provider
457
+ if (!entries.some((c) => c.id === connectionId)) {
458
+ writeOutput(cmd, {
459
+ ok: false,
460
+ error: `Connection "${connectionId}" is not an active ${provider} connection`,
461
+ });
462
+ process.exitCode = 1;
463
+ return;
464
+ }
465
+ } else {
466
+ if (entries.length === 0) {
467
+ writeOutput(cmd, {
468
+ ok: false,
469
+ error: `No active connections found for provider "${provider}"`,
470
+ });
471
+ process.exitCode = 1;
472
+ return;
473
+ }
474
+
475
+ if (entries.length > 1) {
476
+ const connectionList = entries.map((c) => ({
477
+ id: c.id,
478
+ accountLabel: c.account_label ?? null,
479
+ }));
480
+ writeOutput(cmd, {
481
+ ok: false,
482
+ error: `Multiple active connections for "${provider}". Use --connection-id to specify which one to disconnect.`,
483
+ connections: connectionList,
484
+ });
485
+ process.exitCode = 1;
486
+ return;
487
+ }
488
+
489
+ connectionId = entries[0].id;
490
+ }
491
+
492
+ // Disconnect the connection
493
+ const disconnectPath = `/v1/assistants/${encodeURIComponent(client.platformAssistantId)}/oauth/connections/${encodeURIComponent(connectionId)}/disconnect/`;
494
+ const disconnectResponse = await client.fetch(disconnectPath, {
495
+ method: "POST",
496
+ headers: { "Content-Type": "application/json" },
497
+ });
498
+
499
+ if (!disconnectResponse.ok) {
500
+ const errorText = await disconnectResponse.text().catch(() => "");
501
+ writeOutput(cmd, {
502
+ ok: false,
503
+ error: `Platform returned HTTP ${disconnectResponse.status}${errorText ? `: ${errorText}` : ""}`,
504
+ });
505
+ process.exitCode = 1;
506
+ return;
507
+ }
508
+
509
+ writeOutput(cmd, {
510
+ ok: true,
511
+ provider,
512
+ connectionId,
513
+ });
514
+
515
+ if (!shouldOutputJson(cmd)) {
516
+ log.info(`Disconnected ${provider} connection ${connectionId}`);
517
+ }
518
+ } catch (err) {
519
+ const message = err instanceof Error ? err.message : String(err);
520
+ writeOutput(cmd, { ok: false, error: message });
521
+ process.exitCode = 1;
522
+ }
523
+ },
524
+ );
525
+ }
@@ -24,7 +24,7 @@ export function registerPlatformCommand(program: Command): void {
24
24
  `
25
25
  The platform subsystem manages callback routing, containerized deployment
26
26
  context, and webhook forwarding for assistants running inside platform
27
- containers. When IS_CONTAINERIZED=true with a configured PLATFORM_BASE_URL
27
+ containers. When IS_CONTAINERIZED=true with a configured VELLUM_PLATFORM_URL
28
28
  and PLATFORM_ASSISTANT_ID, external service callbacks (Telegram webhooks,
29
29
  Twilio webhooks, OAuth redirects) route through the platform's gateway proxy
30
30
  instead of hitting the assistant directly.
@@ -51,7 +51,7 @@ running.
51
51
 
52
52
  Fields:
53
53
  containerized Whether IS_CONTAINERIZED is set (boolean)
54
- baseUrl PLATFORM_BASE_URL — the platform gateway base URL
54
+ baseUrl VELLUM_PLATFORM_URL — the platform gateway base URL
55
55
  assistantId PLATFORM_ASSISTANT_ID — this assistant's platform UUID
56
56
  hasInternalApiKey Whether PLATFORM_INTERNAL_API_KEY is set (boolean,
57
57
  value not disclosed)
@@ -136,7 +136,7 @@ Known callback path/type combinations:
136
136
  --path oauth/callback --type oauth
137
137
 
138
138
  Requires a containerized environment (IS_CONTAINERIZED=true) with
139
- PLATFORM_BASE_URL and PLATFORM_ASSISTANT_ID configured. Returns the
139
+ VELLUM_PLATFORM_URL and PLATFORM_ASSISTANT_ID configured. Returns the
140
140
  platform-provided stable callback URL that external services should use.
141
141
 
142
142
  Examples: