@vellumai/assistant 0.5.11 → 0.5.13

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 (209) hide show
  1. package/Dockerfile +42 -9
  2. package/docs/architecture/integrations.md +34 -32
  3. package/node_modules/@vellumai/ces-contracts/src/__tests__/grants.test.ts +7 -7
  4. package/node_modules/@vellumai/ces-contracts/src/handles.ts +5 -4
  5. package/node_modules/@vellumai/ces-contracts/src/index.ts +7 -0
  6. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +5 -0
  7. package/node_modules/@vellumai/credential-storage/src/index.ts +1 -1
  8. package/openapi.yaml +87 -9
  9. package/package.json +1 -1
  10. package/src/__tests__/catalog-cache.test.ts +164 -0
  11. package/src/__tests__/catalog-search.test.ts +61 -0
  12. package/src/__tests__/cli-command-risk-guard.test.ts +181 -6
  13. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +396 -0
  14. package/src/__tests__/conversation-error.test.ts +3 -2
  15. package/src/__tests__/credential-security-invariants.test.ts +9 -15
  16. package/src/__tests__/credential-vault-unit.test.ts +32 -34
  17. package/src/__tests__/credential-vault.test.ts +25 -33
  18. package/src/__tests__/credentials-cli.test.ts +3 -3
  19. package/src/__tests__/daemon-credential-client.test.ts +2 -2
  20. package/src/__tests__/first-greeting.test.ts +7 -0
  21. package/src/__tests__/host-bash-proxy.test.ts +79 -0
  22. package/src/__tests__/host-cu-proxy.test.ts +90 -0
  23. package/src/__tests__/host-file-proxy.test.ts +89 -0
  24. package/src/__tests__/integration-status.test.ts +5 -5
  25. package/src/__tests__/list-messages-attachments.test.ts +171 -0
  26. package/src/__tests__/mcp-abort-signal.test.ts +205 -0
  27. package/src/__tests__/messaging-send-tool.test.ts +5 -5
  28. package/src/__tests__/navigate-settings-tab.test.ts +6 -2
  29. package/src/__tests__/notification-telegram-adapter.test.ts +125 -0
  30. package/src/__tests__/oauth-cli.test.ts +126 -119
  31. package/src/__tests__/oauth-provider-profiles.test.ts +55 -20
  32. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  33. package/src/__tests__/onboarding-template-contract.test.ts +2 -2
  34. package/src/__tests__/platform.test.ts +3 -168
  35. package/src/__tests__/secret-routes-managed-proxy.test.ts +78 -0
  36. package/src/__tests__/secure-keys-managed-failover.test.ts +73 -0
  37. package/src/__tests__/skill-feature-flags.test.ts +8 -0
  38. package/src/__tests__/skill-secret-handling-guard.test.ts +212 -0
  39. package/src/__tests__/skills-uninstall.test.ts +2 -2
  40. package/src/__tests__/slack-messaging-token-resolution.test.ts +22 -24
  41. package/src/__tests__/slack-share-routes.test.ts +5 -5
  42. package/src/__tests__/system-prompt.test.ts +39 -0
  43. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -1
  44. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +5 -4
  45. package/src/cli/AGENTS.md +47 -7
  46. package/src/cli/commands/browser-relay.ts +2 -17
  47. package/src/cli/commands/contacts.ts +6 -4
  48. package/src/cli/commands/conversations.ts +13 -1
  49. package/src/cli/commands/credential-execution.ts +16 -1
  50. package/src/cli/commands/credentials.ts +2 -8
  51. package/src/cli/commands/oauth/__tests__/connect.test.ts +29 -108
  52. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +13 -87
  53. package/src/cli/commands/oauth/__tests__/mode.test.ts +22 -69
  54. package/src/cli/commands/oauth/__tests__/ping.test.ts +20 -79
  55. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +574 -0
  56. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +416 -0
  57. package/src/cli/commands/oauth/__tests__/status.test.ts +12 -40
  58. package/src/cli/commands/oauth/__tests__/token.test.ts +3 -50
  59. package/src/cli/commands/oauth/apps.ts +63 -44
  60. package/src/cli/commands/oauth/connect.ts +187 -155
  61. package/src/cli/commands/oauth/disconnect.ts +27 -75
  62. package/src/cli/commands/oauth/index.ts +36 -46
  63. package/src/cli/commands/oauth/mode.ts +22 -34
  64. package/src/cli/commands/oauth/ping.ts +19 -45
  65. package/src/cli/commands/oauth/providers.ts +569 -62
  66. package/src/cli/commands/oauth/request.ts +36 -48
  67. package/src/cli/commands/oauth/shared.ts +1 -19
  68. package/src/cli/commands/oauth/status.ts +14 -25
  69. package/src/cli/commands/oauth/token.ts +25 -34
  70. package/src/cli/commands/platform/__tests__/connect.test.ts +224 -0
  71. package/src/cli/commands/platform/__tests__/disconnect.test.ts +237 -0
  72. package/src/cli/commands/platform/__tests__/status.test.ts +246 -0
  73. package/src/cli/commands/platform/connect.ts +104 -0
  74. package/src/cli/commands/platform/disconnect.ts +118 -0
  75. package/src/cli/commands/{platform.ts → platform/index.ts} +108 -38
  76. package/src/cli/commands/sequence.ts +5 -4
  77. package/src/cli/commands/shotgun.ts +16 -0
  78. package/src/cli/commands/skills.ts +173 -41
  79. package/src/cli/commands/usage.ts +5 -11
  80. package/src/cli/lib/daemon-credential-client.ts +22 -38
  81. package/src/cli/program.ts +1 -1
  82. package/src/config/assistant-feature-flags.ts +3 -7
  83. package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
  84. package/src/config/bundled-skills/conversations/SKILL.md +20 -0
  85. package/src/config/bundled-skills/conversations/TOOLS.json +23 -0
  86. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +66 -0
  87. package/src/config/bundled-skills/gmail/SKILL.md +13 -13
  88. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +3 -3
  89. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +2 -2
  90. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +1 -1
  91. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +1 -1
  92. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +1 -1
  93. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +1 -1
  94. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +2 -2
  95. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +1 -1
  96. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +1 -1
  97. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  98. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +1 -1
  99. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +1 -1
  100. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +1 -1
  101. package/src/config/bundled-skills/google-calendar/SKILL.md +10 -4
  102. package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
  103. package/src/config/bundled-skills/messaging/SKILL.md +7 -7
  104. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -2
  105. package/src/config/bundled-skills/messaging/tools/shared.ts +5 -6
  106. package/src/config/bundled-skills/settings/TOOLS.json +5 -3
  107. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +4 -2
  108. package/src/config/bundled-tool-registry.ts +5 -0
  109. package/src/config/feature-flag-registry.json +2 -2
  110. package/src/credential-execution/client.ts +15 -3
  111. package/src/daemon/conversation-agent-loop.ts +2 -0
  112. package/src/daemon/conversation-error.ts +36 -6
  113. package/src/daemon/conversation-messaging.ts +9 -0
  114. package/src/daemon/conversation-runtime-assembly.ts +33 -0
  115. package/src/daemon/conversation-surfaces.ts +120 -14
  116. package/src/daemon/conversation.ts +5 -0
  117. package/src/daemon/first-greeting.ts +6 -1
  118. package/src/daemon/handlers/skills.ts +148 -3
  119. package/src/daemon/host-bash-proxy.ts +16 -0
  120. package/src/daemon/host-cu-proxy.ts +16 -0
  121. package/src/daemon/host-file-proxy.ts +16 -0
  122. package/src/daemon/lifecycle.ts +56 -5
  123. package/src/daemon/message-types/conversations.ts +1 -0
  124. package/src/daemon/message-types/guardian-actions.ts +2 -0
  125. package/src/daemon/message-types/host-bash.ts +6 -1
  126. package/src/daemon/message-types/host-cu.ts +6 -1
  127. package/src/daemon/message-types/host-file.ts +6 -1
  128. package/src/daemon/message-types/integrations.ts +0 -1
  129. package/src/daemon/server.ts +29 -2
  130. package/src/hooks/cli.ts +74 -0
  131. package/src/inbound/platform-callback-registration.ts +7 -12
  132. package/src/index.ts +0 -12
  133. package/src/mcp/client.ts +6 -1
  134. package/src/mcp/manager.ts +2 -1
  135. package/src/memory/conversation-crud.ts +92 -3
  136. package/src/memory/conversation-key-store.ts +26 -0
  137. package/src/memory/conversation-queries.ts +6 -6
  138. package/src/memory/db-init.ts +16 -0
  139. package/src/memory/journal-memory.ts +8 -2
  140. package/src/memory/migrations/196-messages-conversation-created-at-index.ts +9 -0
  141. package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +186 -0
  142. package/src/memory/migrations/197-oauth-providers-behavior-columns.ts +29 -0
  143. package/src/memory/migrations/198-drop-setup-skill-id-column.ts +11 -0
  144. package/src/memory/migrations/index.ts +4 -0
  145. package/src/memory/migrations/registry.ts +8 -0
  146. package/src/memory/schema/oauth.ts +11 -0
  147. package/src/messaging/provider.ts +13 -12
  148. package/src/messaging/providers/gmail/adapter.ts +44 -35
  149. package/src/messaging/providers/slack/adapter.ts +63 -33
  150. package/src/messaging/providers/telegram-bot/adapter.ts +6 -8
  151. package/src/messaging/providers/whatsapp/adapter.ts +6 -8
  152. package/src/notifications/adapters/telegram.ts +78 -2
  153. package/src/oauth/__tests__/identity-verifier.test.ts +464 -0
  154. package/src/oauth/byo-connection.test.ts +22 -24
  155. package/src/oauth/connect-orchestrator.ts +37 -76
  156. package/src/oauth/connect-types.ts +7 -65
  157. package/src/oauth/connection-resolver.test.ts +13 -13
  158. package/src/oauth/connection-resolver.ts +3 -4
  159. package/src/oauth/identity-verifier.ts +177 -0
  160. package/src/oauth/oauth-store.ts +228 -3
  161. package/src/oauth/platform-connection.test.ts +56 -6
  162. package/src/oauth/platform-connection.ts +8 -1
  163. package/src/oauth/seed-providers.ts +247 -34
  164. package/src/permissions/checker.ts +127 -1
  165. package/src/prompts/journal-context.ts +4 -1
  166. package/src/prompts/system-prompt.ts +54 -9
  167. package/src/prompts/templates/BOOTSTRAP.md +16 -5
  168. package/src/providers/anthropic/client.ts +2 -33
  169. package/src/runtime/guardian-action-service.ts +7 -2
  170. package/src/runtime/http-server.ts +12 -18
  171. package/src/runtime/http-types.ts +8 -1
  172. package/src/runtime/migrations/rebind-secrets-screen.ts +2 -2
  173. package/src/runtime/routes/conversation-management-routes.ts +31 -0
  174. package/src/runtime/routes/conversation-routes.ts +79 -4
  175. package/src/runtime/routes/guardian-action-routes.ts +15 -2
  176. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -8
  177. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  178. package/src/runtime/routes/oauth-apps.ts +2 -1
  179. package/src/runtime/routes/secret-routes.ts +45 -15
  180. package/src/runtime/routes/settings-routes.ts +12 -19
  181. package/src/runtime/routes/skills-routes.ts +45 -4
  182. package/src/schedule/integration-status.ts +2 -2
  183. package/src/security/ces-rpc-credential-backend.ts +19 -16
  184. package/src/security/oauth-completion-page.ts +153 -0
  185. package/src/security/oauth2.ts +3 -17
  186. package/src/security/secure-keys.ts +207 -7
  187. package/src/security/token-manager.ts +3 -6
  188. package/src/signals/bash.ts +6 -1
  189. package/src/skills/catalog-cache.ts +44 -0
  190. package/src/skills/catalog-search.ts +18 -0
  191. package/src/tools/browser/browser-manager.ts +2 -2
  192. package/src/tools/credentials/post-connect-hooks.ts +1 -1
  193. package/src/tools/credentials/vault.ts +34 -45
  194. package/src/tools/host-terminal/host-shell.ts +16 -3
  195. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  196. package/src/tools/skills/sandbox-runner.ts +16 -3
  197. package/src/tools/terminal/shell.ts +16 -3
  198. package/src/util/logger.ts +11 -1
  199. package/src/util/platform.ts +1 -91
  200. package/src/util/sentry-log-stream.ts +51 -0
  201. package/src/watcher/providers/github.ts +2 -2
  202. package/src/watcher/providers/gmail.ts +1 -1
  203. package/src/watcher/providers/google-calendar.ts +1 -1
  204. package/src/watcher/providers/linear.ts +2 -2
  205. package/src/workspace/migrations/011-backfill-installation-id.ts +5 -3
  206. package/src/workspace/migrations/020-rename-oauth-skill-dirs.ts +119 -0
  207. package/src/workspace/migrations/registry.ts +2 -0
  208. package/src/cli/commands/oauth/connections.ts +0 -255
  209. package/src/oauth/provider-behaviors.ts +0 -634
@@ -14,7 +14,7 @@ import {
14
14
  } from "../../../oauth/oauth-store.js";
15
15
  import { VellumPlatformClient } from "../../../platform/client.js";
16
16
  import { shouldOutputJson, writeOutput } from "../../output.js";
17
- import { isManagedMode, resolveService, toBareProvider } from "./shared.js";
17
+ import { isManagedMode } from "./shared.js";
18
18
 
19
19
  // ---------------------------------------------------------------------------
20
20
  // Helpers
@@ -86,12 +86,9 @@ export function registerRequestCommand(oauth: Command): void {
86
86
  oauth
87
87
  .command("request <url>")
88
88
  .description(
89
- "Make an authenticated OAuth request (curl-like interface for LLM agents)",
90
- )
91
- .requiredOption(
92
- "--provider <key>",
93
- "Provider key (e.g. integration:google) or alias (e.g. gmail)",
89
+ "The recommended way to make an authenticated request to an OAuth provider (supports a curl-like interface)",
94
90
  )
91
+ .requiredOption("--provider <key>", "Provider name (e.g. google, slack)")
95
92
  .option("-X, --request <method>", "HTTP method (default: GET)")
96
93
  .option(
97
94
  "-H, --header <header>",
@@ -114,9 +111,13 @@ export function registerRequestCommand(oauth: Command): void {
114
111
  .addHelpText(
115
112
  "after",
116
113
  `
117
- Make authenticated HTTP requests through an OAuth provider. Resolves the
118
- OAuth connection automatically (platform-managed or BYO) and injects
119
- tokens transparently.
114
+ This is the first-class mechanism for making authenticated HTTP requests
115
+ to an OAuth provider. By using this CLI, you follow security best-practices
116
+ regarding how the OAuth token is used. This approach is preferred over retrieving
117
+ the token (using \`assistant oauth token\`) and making the request directly.
118
+
119
+ This command resolves the OAuth connection automatically (regardless of whether
120
+ the provider's mode is set to "managed" or "your-own") and injects tokens transparently.
120
121
 
121
122
  URL can be absolute (https://api.twitter.com/2/tweets) or relative (/2/tweets).
122
123
  Absolute URLs have their host extracted as a baseUrl override; relative paths
@@ -126,11 +127,11 @@ Note: The Authorization header is set automatically. User-supplied
126
127
  -H "Authorization: ..." will be overridden by the OAuth bearer token.
127
128
 
128
129
  Examples:
129
- $ assistant oauth request --provider integration:twitter https://api.x.com/2/tweets
130
- $ assistant oauth request --provider gmail /gmail/v1/users/me/messages -G
131
- $ assistant oauth request --provider integration:twitter -X POST -d '{"text":"Hello"}' https://api.x.com/2/tweets
132
- $ assistant oauth request --provider integration:google -d @body.json https://www.googleapis.com/calendar/v3/calendars
133
- $ assistant oauth request --provider integration:slack -H "Content-Type: application/json" -d '{"channel":"C123"}' /api/chat.postMessage --json`,
130
+ $ assistant oauth request --provider twitter https://api.x.com/2/tweets
131
+ $ assistant oauth request --provider google /gmail/v1/users/me/messages -G
132
+ $ assistant oauth request --provider twitter -X POST -d '{"text":"Hello"}' https://api.x.com/2/tweets
133
+ $ assistant oauth request --provider google -d @body.json https://www.googleapis.com/calendar/v3/calendars
134
+ $ assistant oauth request --provider slack -H "Content-Type: application/json" -d '{"channel":"C123"}' /api/chat.postMessage --json`,
134
135
  )
135
136
  .action(
136
137
  async (
@@ -173,18 +174,13 @@ Examples:
173
174
  };
174
175
 
175
176
  try {
176
- // -----------------------------------------------------------------
177
- // 1. Resolve provider key
178
- // -----------------------------------------------------------------
179
- const providerKey = resolveService(opts.provider);
180
-
181
177
  // -----------------------------------------------------------------
182
178
  // Pre-flight check 1: Provider not found
183
179
  // -----------------------------------------------------------------
184
- const providerRow = getProvider(providerKey);
180
+ const providerRow = getProvider(opts.provider);
185
181
  if (!providerRow) {
186
182
  writeError(
187
- `Error: Unknown provider "${providerKey}".\n\n` +
183
+ `Error: Unknown provider "${opts.provider}".\n\n` +
188
184
  `Run 'assistant oauth providers list' to see available providers.\n` +
189
185
  `If this is a custom provider, register it first with 'assistant oauth providers register --help'.`,
190
186
  );
@@ -194,7 +190,7 @@ Examples:
194
190
  // -----------------------------------------------------------------
195
191
  // Pre-flight check 2: Determine managed vs BYO mode
196
192
  // -----------------------------------------------------------------
197
- const managed = isManagedMode(providerKey);
193
+ const managed = isManagedMode(opts.provider);
198
194
 
199
195
  // -----------------------------------------------------------------
200
196
  // Pre-flight check 3: Client ID not found (BYO only)
@@ -202,16 +198,16 @@ Examples:
202
198
  if (opts.clientId) {
203
199
  if (managed) {
204
200
  writeInfo(
205
- `Warning: --client-id is ignored for platform-managed providers. The platform manages OAuth apps for "${providerKey}".`,
201
+ `Warning: --client-id is ignored for platform-managed providers. The platform manages OAuth apps for "${opts.provider}".`,
206
202
  );
207
203
  } else {
208
204
  const app = getAppByProviderAndClientId(
209
- providerKey,
205
+ opts.provider,
210
206
  opts.clientId,
211
207
  );
212
208
  if (!app) {
213
209
  writeError(
214
- `Error: No registered OAuth app found for "${providerKey}" with client ID "${opts.clientId}".\n\n` +
210
+ `Error: No registered OAuth app found for "${opts.provider}" with client ID "${opts.clientId}".\n\n` +
215
211
  `Run 'assistant oauth apps list' to see registered apps for this provider.\n` +
216
212
  `To register a new app, run 'assistant oauth apps upsert --help'.`,
217
213
  );
@@ -229,7 +225,7 @@ Examples:
229
225
  const client = await VellumPlatformClient.create();
230
226
  if (client && client.platformAssistantId) {
231
227
  const params = new URLSearchParams();
232
- params.set("provider", toBareProvider(providerKey));
228
+ params.set("provider", opts.provider);
233
229
  params.set("status", "ACTIVE");
234
230
  params.set("account_identifier", opts.account);
235
231
 
@@ -246,8 +242,8 @@ Examples:
246
242
 
247
243
  if (connections.length === 0) {
248
244
  writeError(
249
- `Error: No active platform connection found for "${providerKey}" with account "${opts.account}".\n\n` +
250
- `Run 'assistant oauth status ${providerKey}' to see connected accounts for this provider.\n` +
245
+ `Error: No active platform connection found for "${opts.provider}" with account "${opts.account}".\n\n` +
246
+ `Run 'assistant oauth status ${opts.provider}' to see connected accounts for this provider.\n` +
251
247
  `To connect a new account, run 'assistant oauth connect --help'.`,
252
248
  );
253
249
  return;
@@ -259,14 +255,14 @@ Examples:
259
255
  );
260
256
  }
261
257
  } else {
262
- const conn = getActiveConnection(providerKey, {
258
+ const conn = getActiveConnection(opts.provider, {
263
259
  clientId: opts.clientId,
264
260
  account: opts.account,
265
261
  });
266
262
  if (!conn) {
267
263
  writeError(
268
- `Error: No active OAuth connection found for "${providerKey}" with account "${opts.account}"${opts.clientId ? ` and client ID "${opts.clientId}"` : ""}.\n\n` +
269
- `Run 'assistant oauth status ${providerKey}' to see active connections.\n` +
264
+ `Error: No active OAuth connection found for "${opts.provider}" with account "${opts.account}"${opts.clientId ? ` and client ID "${opts.clientId}"` : ""}.\n\n` +
265
+ `Run 'assistant oauth status ${opts.provider}' to see active connections.\n` +
270
266
  `To connect a new account, run 'assistant oauth connect --help'.`,
271
267
  );
272
268
  return;
@@ -418,7 +414,7 @@ Examples:
418
414
  let connection;
419
415
  try {
420
416
  connection = await resolveOAuthConnection(
421
- providerKey,
417
+ opts.provider,
422
418
  resolveOptions,
423
419
  );
424
420
  } catch (resolveErr) {
@@ -434,13 +430,13 @@ Examples:
434
430
  if (managed) {
435
431
  writeError(
436
432
  `Error: ${resolveMessage}\n\n` +
437
- `Run 'assistant oauth status ${providerKey}' to check connection status.\n` +
433
+ `Run 'assistant oauth status ${opts.provider}' to check connection status.\n` +
438
434
  `To connect, run 'assistant oauth connect --help'.`,
439
435
  );
440
436
  } else {
441
437
  writeError(
442
438
  `Error: ${resolveMessage}\n\n` +
443
- `Run 'assistant oauth status ${providerKey}' to see active connections.\n` +
439
+ `Run 'assistant oauth status ${opts.provider}' to see active connections.\n` +
444
440
  `To connect, run 'assistant oauth connect --help'.`,
445
441
  );
446
442
  }
@@ -473,12 +469,12 @@ Examples:
473
469
  if (managed) {
474
470
  authHint =
475
471
  `Hint: Request returned HTTP ${response.status}. The OAuth token may be expired or revoked.\n\n` +
476
- `Run 'assistant oauth status ${providerKey}' to check connection health.\n` +
472
+ `Run 'assistant oauth status ${opts.provider}' to check connection health.\n` +
477
473
  `To reconnect, run 'assistant oauth connect --help'.`;
478
474
  } else {
479
475
  authHint =
480
476
  `Hint: Request returned HTTP ${response.status}. The OAuth token may be expired or revoked.\n\n` +
481
- `Run 'assistant oauth status ${providerKey}' to check connection status.\n` +
477
+ `Run 'assistant oauth status ${opts.provider}' to check connection status.\n` +
482
478
  `To reconnect, run 'assistant oauth connect --help'.`;
483
479
  }
484
480
  writeInfo(authHint);
@@ -535,14 +531,6 @@ Examples:
535
531
  // Error case 7: Generic/unexpected errors
536
532
  const message = err instanceof Error ? err.message : String(err);
537
533
 
538
- // Try to extract providerKey for the generic hint
539
- let providerKey: string;
540
- try {
541
- providerKey = resolveService(opts.provider);
542
- } catch {
543
- providerKey = opts.provider;
544
- }
545
-
546
534
  // BYO connections throw on persistent 401 (after refresh retry
547
535
  // exhaustion) with a `status` property. Detect this and show the
548
536
  // same auth hint that the response-level 401/403 check would give.
@@ -552,13 +540,13 @@ Examples:
552
540
  : undefined;
553
541
 
554
542
  if (errStatus === 401 || errStatus === 403) {
555
- const managed = isManagedMode(providerKey);
543
+ const managed = isManagedMode(opts.provider);
556
544
  const authHint = managed
557
545
  ? `Hint: Request returned HTTP ${errStatus}. The OAuth token may be expired or revoked.\n\n` +
558
- `Run 'assistant oauth status ${providerKey}' to check connection health.\n` +
546
+ `Run 'assistant oauth status ${opts.provider}' to check connection health.\n` +
559
547
  `To reconnect, run 'assistant oauth connect --help'.`
560
548
  : `Hint: Request returned HTTP ${errStatus}. The OAuth token may be expired or revoked.\n\n` +
561
- `Run 'assistant oauth status ${providerKey}' to check connection status.\n` +
549
+ `Run 'assistant oauth status ${opts.provider}' to check connection status.\n` +
562
550
  `To reconnect, run 'assistant oauth connect --help'.`;
563
551
 
564
552
  writeError(`Error: ${message}`, authHint);
@@ -568,7 +556,7 @@ Examples:
568
556
 
569
557
  writeError(
570
558
  `Error: ${message}\n\n` +
571
- `For provider diagnostics, run 'assistant oauth providers get ${providerKey}'.`,
559
+ `For provider diagnostics, run 'assistant oauth providers get ${opts.provider}'.`,
572
560
  );
573
561
  }
574
562
  },
@@ -6,16 +6,9 @@ import {
6
6
  ServicesSchema,
7
7
  } from "../../../config/schemas/services.js";
8
8
  import { getProvider } from "../../../oauth/oauth-store.js";
9
- import { resolveService } from "../../../oauth/provider-behaviors.js";
10
9
  import { VellumPlatformClient } from "../../../platform/client.js";
11
10
  import { writeOutput } from "../../output.js";
12
11
 
13
- // ---------------------------------------------------------------------------
14
- // Re-exports
15
- // ---------------------------------------------------------------------------
16
-
17
- export { resolveService };
18
-
19
12
  // ---------------------------------------------------------------------------
20
13
  // Shared types
21
14
  // ---------------------------------------------------------------------------
@@ -31,17 +24,6 @@ export interface PlatformConnectionEntry {
31
24
  // Shared helpers
32
25
  // ---------------------------------------------------------------------------
33
26
 
34
- /**
35
- * Extract the bare provider slug (e.g. "google") from either a raw CLI
36
- * argument or a canonical provider key (e.g. "integration:google").
37
- * Platform API paths expect the bare slug, not the internal key.
38
- */
39
- export function toBareProvider(provider: string): string {
40
- return provider.startsWith("integration:")
41
- ? provider.slice("integration:".length)
42
- : provider;
43
- }
44
-
45
27
  /**
46
28
  * Return the provider's `managedServiceConfigKey` if it exists and is a valid
47
29
  * key in `ServicesSchema.shape`, or `null` otherwise. This centralises the
@@ -104,7 +86,7 @@ export async function fetchActiveConnections(
104
86
  options?: { silent?: boolean },
105
87
  ): Promise<PlatformConnectionEntry[] | null> {
106
88
  const params = new URLSearchParams();
107
- params.set("provider", toBareProvider(provider));
89
+ params.set("provider", provider);
108
90
  params.set("status", "ACTIVE");
109
91
 
110
92
  const path = `/v1/assistants/${encodeURIComponent(client.platformAssistantId)}/oauth/connections/?${params.toString()}`;
@@ -7,7 +7,6 @@ import {
7
7
  fetchActiveConnections,
8
8
  isManagedMode,
9
9
  requirePlatformClient,
10
- resolveService,
11
10
  } from "./shared.js";
12
11
 
13
12
  const log = getCliLogger("cli");
@@ -19,15 +18,12 @@ const log = getCliLogger("cli");
19
18
  export function registerStatusCommand(oauth: Command): void {
20
19
  oauth
21
20
  .command("status <provider>")
22
- .description(
23
- "Show OAuth connection status for a provider (auto-detects managed vs BYO mode)",
24
- )
21
+ .description("Show OAuth connection status for a specified provider")
25
22
  .addHelpText(
26
23
  "after",
27
24
  `
28
25
  Arguments:
29
- provider Provider name or key. Accepts bare names (google, slack),
30
- canonical keys (integration:google), or aliases (gmail).
26
+ provider Provider name (e.g. google, slack).
31
27
  Run 'assistant oauth providers list' to see all available providers.
32
28
 
33
29
  The output includes connection IDs and account identifiers that can be used
@@ -36,15 +32,9 @@ as inputs to other commands:
36
32
  - 'assistant oauth request --provider <provider> --account <account>' to
37
33
  make authenticated requests as a specific account
38
34
 
39
- Mode detection:
40
- The command automatically detects whether the provider is configured in
41
- platform-managed mode or bring-your-own (BYO) mode based on the assistant's
42
- services config. Managed mode delegates OAuth to the Vellum platform; BYO
43
- mode uses locally stored tokens.
44
-
45
35
  Examples:
46
36
  $ assistant oauth status google
47
- $ assistant oauth status integration:google --json`,
37
+ $ assistant oauth status google --json`,
48
38
  )
49
39
  .action(
50
40
  async (
@@ -54,10 +44,9 @@ Examples:
54
44
  ) => {
55
45
  try {
56
46
  // -----------------------------------------------------------------
57
- // Resolve + validate provider
47
+ // Validate provider
58
48
  // -----------------------------------------------------------------
59
- const providerKey = resolveService(provider);
60
- const providerRow = getProvider(providerKey);
49
+ const providerRow = getProvider(provider);
61
50
 
62
51
  if (!providerRow) {
63
52
  writeOutput(cmd, {
@@ -73,7 +62,7 @@ Examples:
73
62
  // -----------------------------------------------------------------
74
63
  // Detect mode
75
64
  // -----------------------------------------------------------------
76
- const managed = isManagedMode(providerKey);
65
+ const managed = isManagedMode(provider);
77
66
 
78
67
  if (managed) {
79
68
  // ---------------------------------------------------------------
@@ -84,7 +73,7 @@ Examples:
84
73
 
85
74
  const rawEntries = await fetchActiveConnections(
86
75
  client,
87
- providerKey,
76
+ provider,
88
77
  cmd,
89
78
  );
90
79
  if (!rawEntries) return;
@@ -99,7 +88,7 @@ Examples:
99
88
  if (shouldOutputJson(cmd)) {
100
89
  writeOutput(cmd, {
101
90
  ok: true,
102
- provider: providerKey,
91
+ provider: provider,
103
92
  mode: "managed",
104
93
  connections,
105
94
  });
@@ -109,12 +98,12 @@ Examples:
109
98
  // Human output
110
99
  if (connections.length === 0) {
111
100
  log.info(
112
- `No active connections for ${providerKey}. Connect with 'assistant oauth connect ${providerKey}'.`,
101
+ `No active connections for ${provider}. Connect with 'assistant oauth connect ${provider}'.`,
113
102
  );
114
103
  return;
115
104
  }
116
105
 
117
- log.info(`Provider: ${providerKey} (managed)`);
106
+ log.info(`Provider: ${provider} (managed)`);
118
107
  log.info(`${connections.length} active connection(s):`);
119
108
  for (const c of connections) {
120
109
  const scopes =
@@ -129,7 +118,7 @@ Examples:
129
118
  // ---------------------------------------------------------------
130
119
  // BYO path
131
120
  // ---------------------------------------------------------------
132
- const allConnections = listConnections(providerKey);
121
+ const allConnections = listConnections(provider);
133
122
  const activeRows = allConnections.filter(
134
123
  (r) => r.status === "active",
135
124
  );
@@ -159,7 +148,7 @@ Examples:
159
148
  if (shouldOutputJson(cmd)) {
160
149
  writeOutput(cmd, {
161
150
  ok: true,
162
- provider: providerKey,
151
+ provider: provider,
163
152
  mode: "byo",
164
153
  connections,
165
154
  });
@@ -169,12 +158,12 @@ Examples:
169
158
  // Human output
170
159
  if (connections.length === 0) {
171
160
  log.info(
172
- `No active connections for ${providerKey}. Connect with 'assistant oauth connect ${providerKey}'.`,
161
+ `No active connections for ${provider}. Connect with 'assistant oauth connect ${provider}'.`,
173
162
  );
174
163
  return;
175
164
  }
176
165
 
177
- log.info(`Provider: ${providerKey} (byo)`);
166
+ log.info(`Provider: ${provider} (byo)`);
178
167
  log.info(`${connections.length} active connection(s):`);
179
168
  for (const c of connections) {
180
169
  const scopes =
@@ -3,7 +3,7 @@ import type { Command } from "commander";
3
3
  import { getActiveConnection } from "../../../oauth/oauth-store.js";
4
4
  import { withValidToken } from "../../../security/token-manager.js";
5
5
  import { shouldOutputJson, writeOutput } from "../../output.js";
6
- import { isManagedMode, resolveService } from "./shared.js";
6
+ import { isManagedMode } from "./shared.js";
7
7
 
8
8
  // ---------------------------------------------------------------------------
9
9
  // CES shell lockdown guard
@@ -31,44 +31,40 @@ export function registerTokenCommand(oauth: Command): void {
31
31
  oauth
32
32
  .command("token <provider>")
33
33
  .description(
34
- "Print a valid OAuth access token for a provider (BYO providers only)",
34
+ 'An escape hatch to retrieve a valid OAuth access token for a provider whose mode is "your-own" for direct use.',
35
35
  )
36
36
  .option(
37
37
  "--account <account>",
38
- "Account identifier for BYO disambiguation (e.g. user@gmail.com)",
38
+ "Account identifier for account disambiguation (e.g. user@gmail.com)",
39
39
  )
40
40
  .option(
41
41
  "--client-id <id>",
42
- "Filter by OAuth client ID when multiple apps exist for the provider",
42
+ "Filter by OAuth client ID when multiple OAuth apps exist for the provider",
43
43
  )
44
44
  .addHelpText(
45
45
  "after",
46
46
  `
47
47
  Arguments:
48
- provider Provider name or key. Accepts bare names (google, slack),
49
- canonical keys (integration:google), aliases (gmail), or
50
- provider IDs. Run 'assistant oauth providers list' to see
51
- all available providers.
52
-
53
- Options:
54
- --account <account> Select a specific account when multiple connections
55
- exist for the same provider. Uses the account label
56
- shown in 'assistant oauth status <provider>'.
57
- --client-id <id> Select a specific OAuth app when multiple apps exist
58
- for the same provider.
59
-
60
- Token retrieval is only supported for BYO (bring-your-own credentials)
61
- providers. Platform-managed providers handle tokens internally — use
48
+ provider Provider name (e.g. google, slack).
49
+ Run 'assistant oauth providers list' to see all available
50
+ providers.
51
+
52
+ This command is discouraged and should be used sparingly. Only use if you
53
+ need direct access to the token (i.e. \`assistant oauth request\` is
54
+ insufficient) and you are comfortable with the security implications.
55
+
56
+ Token retrieval is only supported for providers with mode set to "your-own".
57
+ Platform-managed providers handle tokens internally use
62
58
  'assistant oauth ping <provider>' to verify connectivity or
63
59
  'assistant oauth request --provider <provider> <url>' to make
64
60
  authenticated requests.
65
61
 
66
- CES shell lockdown: This command is blocked when running in an untrusted
67
- shell (VELLUM_UNTRUSTED_SHELL=1) to prevent token exfiltration.
62
+ Use 'assistant oauth status <provider>' to find account identifiers for
63
+ --account. Shell lockdown: blocked when VELLUM_UNTRUSTED_SHELL=1.
68
64
 
69
65
  Examples:
70
66
  $ assistant oauth token google
71
- $ assistant oauth token integration:twitter --json
67
+ $ assistant oauth token twitter --json
72
68
  $ assistant oauth token google --account user@gmail.com
73
69
  $ assistant oauth token google --client-id abc123`,
74
70
  )
@@ -80,20 +76,15 @@ Examples:
80
76
  ) => {
81
77
  try {
82
78
  // ---------------------------------------------------------------
83
- // 1. Resolve provider key
84
- // ---------------------------------------------------------------
85
- const providerKey = resolveService(provider);
86
-
87
- // ---------------------------------------------------------------
88
- // 2. Check managed mode
79
+ // 1. Check managed mode
89
80
  // ---------------------------------------------------------------
90
- if (isManagedMode(providerKey)) {
81
+ if (isManagedMode(provider)) {
91
82
  const message =
92
83
  "Token retrieval is not supported for platform-managed providers. " +
93
84
  "When a provider is in managed mode, Vellum handles OAuth tokens on your behalf — " +
94
85
  "they are not exposed directly.\n\n" +
95
- `To verify your connection is working, run 'assistant oauth ping ${providerKey}'.\n` +
96
- `To make authenticated requests, use 'assistant oauth request --provider ${providerKey} <url>'.`;
86
+ `To verify your connection is working, run 'assistant oauth ping ${provider}'.\n` +
87
+ `To make authenticated requests, use 'assistant oauth request --provider ${provider} <url>'.`;
97
88
  writeOutput(cmd, { ok: false, error: message });
98
89
  process.exitCode = 1;
99
90
  return;
@@ -118,7 +109,7 @@ Examples:
118
109
  let tokenOpts: string | { connectionId: string } | undefined;
119
110
 
120
111
  if (opts.account || opts.clientId) {
121
- const conn = getActiveConnection(providerKey, {
112
+ const conn = getActiveConnection(provider, {
122
113
  clientId: opts.clientId,
123
114
  account: opts.account,
124
115
  });
@@ -129,8 +120,8 @@ Examples:
129
120
  ? ` with client ID "${opts.clientId}"`
130
121
  : "";
131
122
  const message =
132
- `No active connection found for "${providerKey}"${hint}. ` +
133
- `Connect first with 'assistant oauth connect ${providerKey}'.`;
123
+ `No active connection found for "${provider}"${hint}. ` +
124
+ `Connect first with 'assistant oauth connect ${provider}'.`;
134
125
  writeOutput(cmd, { ok: false, error: message });
135
126
  process.exitCode = 1;
136
127
  return;
@@ -139,7 +130,7 @@ Examples:
139
130
  }
140
131
 
141
132
  const token = await withValidToken(
142
- providerKey,
133
+ provider,
143
134
  async (t) => t,
144
135
  tokenOpts,
145
136
  );