@vellumai/assistant 0.4.37 → 0.4.41

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 (169) hide show
  1. package/ARCHITECTURE.md +3 -3
  2. package/README.md +13 -13
  3. package/bun.lock +80 -24
  4. package/docs/architecture/integrations.md +126 -128
  5. package/docs/runbook-trusted-contacts.md +1 -1
  6. package/docs/trusted-contact-access.md +12 -12
  7. package/package.json +3 -1
  8. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -14
  9. package/src/__tests__/app-bundler.test.ts +209 -0
  10. package/src/__tests__/app-compiler.test.ts +279 -0
  11. package/src/__tests__/app-executors.test.ts +293 -483
  12. package/src/__tests__/app-migration.test.ts +148 -0
  13. package/src/__tests__/app-routes-csp.test.ts +202 -0
  14. package/src/__tests__/avatar-e2e.test.ts +452 -0
  15. package/src/__tests__/avatar-generator.test.ts +193 -0
  16. package/src/__tests__/avatar-router.test.ts +186 -0
  17. package/src/__tests__/browser-download-timeout.test.ts +28 -0
  18. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +9 -9
  19. package/src/__tests__/call-domain.test.ts +3 -7
  20. package/src/__tests__/credential-security-e2e.test.ts +19 -12
  21. package/src/__tests__/credentials-cli.test.ts +30 -4
  22. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +1 -1
  23. package/src/__tests__/handlers-slack-config.test.ts +0 -72
  24. package/src/__tests__/handlers-telegram-config.test.ts +19 -12
  25. package/src/__tests__/handlers-twitter-config.test.ts +105 -48
  26. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  27. package/src/__tests__/integration-status.test.ts +15 -5
  28. package/src/__tests__/integrations-cli.test.ts +1 -1
  29. package/src/__tests__/invite-redemption-service.test.ts +62 -7
  30. package/src/__tests__/ipc-snapshot.test.ts +0 -8
  31. package/src/__tests__/managed-avatar-client.test.ts +280 -0
  32. package/src/__tests__/mcp-cli.test.ts +3 -3
  33. package/src/__tests__/oauth-cli.test.ts +203 -0
  34. package/src/__tests__/relay-server.test.ts +3 -3
  35. package/src/__tests__/secret-onetime-send.test.ts +19 -12
  36. package/src/__tests__/secure-keys.test.ts +78 -0
  37. package/src/__tests__/session-messaging-secret-redirect.test.ts +3 -0
  38. package/src/__tests__/slack-channel-config.test.ts +23 -16
  39. package/src/__tests__/slack-share-routes.test.ts +263 -0
  40. package/src/__tests__/sms-messaging-provider.test.ts +3 -1
  41. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +7 -7
  42. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  43. package/src/__tests__/trusted-contact-verification.test.ts +10 -10
  44. package/src/__tests__/twilio-config.test.ts +15 -36
  45. package/src/__tests__/twilio-provider.test.ts +4 -0
  46. package/src/__tests__/twitter-auth-handler.test.ts +27 -14
  47. package/src/__tests__/twitter-cli-error-shaping.test.ts +1 -1
  48. package/src/__tests__/twitter-cli-routing.test.ts +38 -53
  49. package/src/__tests__/twitter-oauth-client.test.ts +18 -47
  50. package/src/__tests__/voice-invite-redemption.test.ts +27 -3
  51. package/src/amazon/cart.ts +1 -1
  52. package/src/amazon/client.ts +89 -7
  53. package/src/approvals/guardian-request-resolvers.ts +2 -2
  54. package/src/bundler/app-bundler.ts +77 -32
  55. package/src/bundler/app-compiler.ts +195 -0
  56. package/src/bundler/manifest.ts +1 -1
  57. package/src/bundler/package-resolver.ts +185 -0
  58. package/src/calls/call-domain.ts +4 -14
  59. package/src/calls/relay-server.ts +2 -2
  60. package/src/calls/twilio-config.ts +5 -24
  61. package/src/calls/twilio-rest.ts +19 -5
  62. package/src/cli/amazon.ts +74 -249
  63. package/src/cli/audit.ts +2 -2
  64. package/src/cli/autonomy.ts +9 -9
  65. package/src/cli/channels.ts +5 -5
  66. package/src/cli/completions.ts +27 -27
  67. package/src/cli/config.ts +14 -14
  68. package/src/cli/contacts.ts +27 -27
  69. package/src/cli/credentials.ts +28 -28
  70. package/src/cli/dev.ts +2 -2
  71. package/src/cli/doctor.ts +2 -2
  72. package/src/cli/email.ts +82 -82
  73. package/src/cli/influencer.ts +13 -13
  74. package/src/cli/integrations.ts +19 -144
  75. package/src/cli/keys.ts +10 -10
  76. package/src/cli/map.ts +4 -4
  77. package/src/cli/mcp.ts +17 -17
  78. package/src/cli/memory.ts +18 -18
  79. package/src/cli/notifications.ts +13 -13
  80. package/src/cli/oauth.ts +77 -0
  81. package/src/cli/program.ts +2 -0
  82. package/src/cli/sequence.ts +27 -27
  83. package/src/cli/sessions.ts +12 -12
  84. package/src/cli/trust.ts +8 -8
  85. package/src/cli/twitter.ts +124 -70
  86. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  87. package/src/config/bundled-skills/agentmail/SKILL.md +34 -34
  88. package/src/config/bundled-skills/amazon/SKILL.md +54 -54
  89. package/src/config/bundled-skills/app-builder/SKILL.md +137 -3
  90. package/src/config/bundled-skills/app-builder/tools/app-create.ts +10 -4
  91. package/src/config/bundled-skills/configure-settings/SKILL.md +18 -18
  92. package/src/config/bundled-skills/contacts/SKILL.md +12 -12
  93. package/src/config/bundled-skills/doordash/lib/client.ts +7 -9
  94. package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
  95. package/src/config/bundled-skills/frontend-design/icon.svg +16 -0
  96. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +143 -162
  97. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +4 -4
  98. package/src/config/bundled-skills/influencer/SKILL.md +13 -13
  99. package/src/config/bundled-skills/mcp-setup/SKILL.md +11 -11
  100. package/src/config/bundled-skills/phone-calls/SKILL.md +48 -54
  101. package/src/config/bundled-skills/public-ingress/SKILL.md +6 -6
  102. package/src/config/bundled-skills/slack-app-setup/SKILL.md +1 -1
  103. package/src/config/bundled-skills/sms-setup/SKILL.md +3 -3
  104. package/src/config/bundled-skills/telegram-setup/SKILL.md +2 -2
  105. package/src/config/bundled-skills/twilio-setup/SKILL.md +136 -225
  106. package/src/config/bundled-skills/twitter/SKILL.md +68 -44
  107. package/src/config/bundled-skills/voice-setup/SKILL.md +2 -2
  108. package/src/config/core-schema.ts +26 -0
  109. package/src/config/env.ts +4 -0
  110. package/src/config/feature-flag-registry.json +9 -1
  111. package/src/config/schema.ts +8 -0
  112. package/src/config/system-prompt.ts +6 -3
  113. package/src/config/templates/BOOTSTRAP.md +7 -5
  114. package/src/contacts/contacts-write.ts +5 -1
  115. package/src/daemon/handlers/apps.ts +31 -4
  116. package/src/daemon/handlers/config-ingress.ts +3 -3
  117. package/src/daemon/handlers/config-integrations.ts +120 -49
  118. package/src/daemon/handlers/config-slack-channel.ts +26 -7
  119. package/src/daemon/handlers/config-slack.ts +1 -54
  120. package/src/daemon/handlers/config-telegram.ts +28 -10
  121. package/src/daemon/handlers/config.ts +1 -4
  122. package/src/daemon/handlers/twitter-auth.ts +11 -4
  123. package/src/daemon/ipc-contract/apps.ts +0 -13
  124. package/src/daemon/ipc-contract-inventory.json +0 -2
  125. package/src/daemon/lifecycle.ts +8 -1
  126. package/src/daemon/session-messaging.ts +2 -2
  127. package/src/daemon/tool-side-effects.ts +30 -0
  128. package/src/email/providers/agentmail.ts +1 -1
  129. package/src/email/providers/index.ts +1 -1
  130. package/src/email/service.ts +1 -1
  131. package/src/gallery/default-gallery.ts +538 -0
  132. package/src/gallery/gallery-manifest.ts +5 -1
  133. package/src/influencer/client.ts +8 -6
  134. package/src/mcp/client.ts +1 -1
  135. package/src/media/avatar-router.ts +99 -0
  136. package/src/media/avatar-types.ts +60 -0
  137. package/src/media/managed-avatar-client.ts +189 -0
  138. package/src/memory/app-migration.ts +114 -0
  139. package/src/memory/app-store.ts +11 -0
  140. package/src/memory/qdrant-client.ts +1 -1
  141. package/src/messaging/providers/slack/client.ts +12 -2
  142. package/src/messaging/providers/sms/adapter.ts +6 -10
  143. package/src/migrations/data-layout.ts +8 -1
  144. package/src/oauth/token-persistence.ts +9 -6
  145. package/src/runtime/assistant-scope.ts +5 -0
  146. package/src/runtime/auth/route-policy.ts +4 -0
  147. package/src/runtime/channel-readiness-service.ts +9 -4
  148. package/src/runtime/gateway-internal-client.ts +11 -3
  149. package/src/runtime/http-server.ts +2 -0
  150. package/src/runtime/invite-redemption-service.ts +23 -13
  151. package/src/runtime/middleware/twilio-validation.ts +2 -2
  152. package/src/runtime/routes/app-routes.ts +131 -3
  153. package/src/runtime/routes/inbound-stages/verification-intercept.ts +3 -3
  154. package/src/runtime/routes/integration-routes.ts +2 -2
  155. package/src/runtime/routes/slack-share-routes.ts +235 -0
  156. package/src/runtime/routes/twilio-routes.ts +47 -34
  157. package/src/schedule/integration-status.ts +2 -3
  158. package/src/security/token-manager.ts +11 -3
  159. package/src/tools/apps/executors.ts +116 -8
  160. package/src/tools/browser/browser-manager.ts +30 -2
  161. package/src/tools/browser/chrome-cdp.ts +31 -3
  162. package/src/tools/credentials/vault.ts +9 -7
  163. package/src/tools/executor.ts +4 -0
  164. package/src/tools/system/avatar-generator.ts +55 -34
  165. package/src/twitter/client.ts +1 -1
  166. package/src/twitter/oauth-client.ts +31 -43
  167. package/src/twitter/router.ts +25 -23
  168. package/src/util/platform.ts +5 -0
  169. package/src/slack/slack-webhook.ts +0 -66
@@ -205,21 +205,19 @@ export function registerIntegrationsCommand(program: Command): void {
205
205
  "after",
206
206
  `
207
207
  Reads integration configuration and status through the gateway API. The
208
- assistant must be running for most subcommands (telegram, twilio, guardian)
208
+ assistant must be running for most subcommands (telegram, guardian)
209
209
  since they query the gateway. Exceptions: "ingress config" and "voice config"
210
210
  read from the local config file and do not require the gateway.
211
211
 
212
212
  Integration categories:
213
213
  telegram Telegram bot configuration and webhook status
214
- twilio Twilio credentials, phone numbers, and SMS compliance
215
214
  guardian Guardian trust verification system for contacts
216
215
  ingress Public ingress URL and local gateway target (config-only)
217
216
  voice Voice/call readiness and ElevenLabs voice ID (config-only)
218
217
 
219
218
  Examples:
220
- $ vellum integrations telegram config
221
- $ vellum integrations twilio numbers
222
- $ vellum integrations guardian status --channel sms`,
219
+ $ assistant integrations telegram config
220
+ $ assistant integrations guardian status --channel sms`,
223
221
  );
224
222
 
225
223
  const telegram = integrations
@@ -233,8 +231,8 @@ Checks the Telegram bot configuration status through the gateway API.
233
231
  Requires the assistant to be running.
234
232
 
235
233
  Examples:
236
- $ vellum integrations telegram config
237
- $ vellum integrations telegram config --json`,
234
+ $ assistant integrations telegram config
235
+ $ assistant integrations telegram config --json`,
238
236
  );
239
237
 
240
238
  telegram
@@ -250,8 +248,8 @@ The response includes whether a bot token is configured, the current webhook
250
248
  endpoint, and the bot's Telegram username.
251
249
 
252
250
  Examples:
253
- $ vellum integrations telegram config
254
- $ vellum integrations telegram config --json`,
251
+ $ assistant integrations telegram config
252
+ $ assistant integrations telegram config --json`,
255
253
  )
256
254
  .action(async (_opts: unknown, cmd: Command) => {
257
255
  await runRead(cmd, async () =>
@@ -271,8 +269,8 @@ contacts on each channel have completed identity verification. Requires
271
269
  the assistant to be running.
272
270
 
273
271
  Examples:
274
- $ vellum integrations guardian status
275
- $ vellum integrations guardian status --channel voice`,
272
+ $ assistant integrations guardian status
273
+ $ assistant integrations guardian status --channel voice`,
276
274
  );
277
275
 
278
276
  guardian
@@ -290,10 +288,10 @@ not specified. The response includes whether guardian verification is active
290
288
  and the current verification state for that channel.
291
289
 
292
290
  Examples:
293
- $ vellum integrations guardian status
294
- $ vellum integrations guardian status --channel telegram
295
- $ vellum integrations guardian status --channel voice
296
- $ vellum integrations guardian status --channel sms --json`,
291
+ $ assistant integrations guardian status
292
+ $ assistant integrations guardian status --channel telegram
293
+ $ assistant integrations guardian status --channel voice
294
+ $ assistant integrations guardian status --channel sms --json`,
297
295
  )
298
296
  .action(async (opts: { channel?: GuardianChannel }, cmd: Command) => {
299
297
  const channel = opts.channel ?? "telegram";
@@ -304,129 +302,6 @@ Examples:
304
302
  );
305
303
  });
306
304
 
307
- const twilio = integrations
308
- .command("twilio")
309
- .description("Twilio integration status");
310
-
311
- twilio.addHelpText(
312
- "after",
313
- `
314
- Covers Twilio credential status, phone number management, and SMS regulatory
315
- compliance. All subcommands require the assistant to be running since they
316
- query the gateway API.
317
-
318
- Subcommands:
319
- config Check Twilio credential status and phone number configuration
320
- numbers List all Twilio incoming phone numbers
321
- sms compliance Check SMS regulatory compliance status
322
-
323
- Examples:
324
- $ vellum integrations twilio config
325
- $ vellum integrations twilio numbers
326
- $ vellum integrations twilio sms compliance`,
327
- );
328
-
329
- twilio
330
- .command("config")
331
- .description("Get Twilio credential and phone number status")
332
- .addHelpText(
333
- "after",
334
- `
335
- Checks the Twilio credential status and phone number configuration through
336
- the gateway. Requires the assistant to be running.
337
-
338
- The response includes whether the Twilio account SID and auth token are
339
- configured, and the currently assigned phone number.
340
-
341
- Examples:
342
- $ vellum integrations twilio config
343
- $ vellum integrations twilio config --json`,
344
- )
345
- .action(async (_opts: unknown, cmd: Command) => {
346
- await runRead(cmd, async () =>
347
- gatewayGet("/v1/integrations/twilio/config"),
348
- );
349
- });
350
-
351
- twilio
352
- .command("numbers")
353
- .description("List Twilio incoming phone numbers")
354
- .addHelpText(
355
- "after",
356
- `
357
- Lists all incoming phone numbers associated with the configured Twilio
358
- account. Requires the assistant to be running.
359
-
360
- Returns an array of phone number objects with their SID, phone number,
361
- friendly name, and capabilities.
362
-
363
- Examples:
364
- $ vellum integrations twilio numbers
365
- $ vellum integrations twilio numbers --json`,
366
- )
367
- .action(async (_opts: unknown, cmd: Command) => {
368
- await runRead(cmd, async () =>
369
- gatewayGet("/v1/integrations/twilio/numbers"),
370
- );
371
- });
372
-
373
- const twilioSms = twilio.command("sms").description("Twilio SMS status");
374
-
375
- twilioSms.addHelpText(
376
- "after",
377
- `
378
- Covers SMS regulatory compliance for the configured Twilio account. All
379
- subcommands require the assistant to be running since they query the gateway API.
380
-
381
- Subcommands:
382
- compliance Check SMS regulatory compliance status
383
-
384
- Examples:
385
- $ vellum integrations twilio sms compliance
386
- $ vellum integrations twilio sms compliance --json`,
387
- );
388
-
389
- twilioSms
390
- .command("compliance")
391
- .description("Get Twilio SMS compliance status")
392
- .addHelpText(
393
- "after",
394
- `
395
- Checks the SMS regulatory compliance status for the configured Twilio
396
- account. Requires the assistant to be running.
397
-
398
- Returns the current compliance state, including whether the account is
399
- approved for SMS messaging and any outstanding compliance requirements.
400
-
401
- Examples:
402
- $ vellum integrations twilio sms compliance
403
- $ vellum integrations twilio sms compliance --json`,
404
- )
405
- .action(async (_opts: unknown, cmd: Command) => {
406
- await runRead(cmd, async () =>
407
- gatewayGet("/v1/integrations/twilio/sms/compliance"),
408
- );
409
- });
410
-
411
- twilio
412
- .command("sms-compliance")
413
- .description('Alias for "vellum integrations twilio sms compliance"')
414
- .addHelpText(
415
- "after",
416
- `
417
- Shortcut alias for "vellum integrations twilio sms compliance". Prefer
418
- the canonical path for scripts and documentation.
419
-
420
- Examples:
421
- $ vellum integrations twilio sms-compliance
422
- $ vellum integrations twilio sms compliance # canonical form`,
423
- )
424
- .action(async (_opts: unknown, cmd: Command) => {
425
- await runRead(cmd, async () =>
426
- gatewayGet("/v1/integrations/twilio/sms/compliance"),
427
- );
428
- });
429
-
430
305
  const ingress = integrations
431
306
  .command("ingress")
432
307
  .description("Trusted contact membership and invite status");
@@ -438,7 +313,7 @@ Shows the public ingress URL and local gateway target URL. Reads from the
438
313
  local config file and does not require the gateway to be running.
439
314
 
440
315
  Examples:
441
- $ vellum integrations ingress config`,
316
+ $ assistant integrations ingress config`,
442
317
  );
443
318
 
444
319
  ingress
@@ -455,8 +330,8 @@ URL (if any), and the local gateway target address. Ingress is considered
455
330
  enabled if explicitly set to true or if a publicBaseUrl is configured.
456
331
 
457
332
  Examples:
458
- $ vellum integrations ingress config
459
- $ vellum integrations ingress config --json`,
333
+ $ assistant integrations ingress config
334
+ $ assistant integrations ingress config --json`,
460
335
  )
461
336
  .action(async (_opts: unknown, cmd: Command) => {
462
337
  await runRead(cmd, async () => readIngressConfig());
@@ -471,7 +346,7 @@ Shows voice and call readiness configuration. Reads from the local config
471
346
  file and does not require the gateway to be running.
472
347
 
473
348
  Examples:
474
- $ vellum integrations voice config`,
349
+ $ assistant integrations voice config`,
475
350
  );
476
351
 
477
352
  voice
@@ -488,8 +363,8 @@ ID (falls back to default if not configured), whether a custom voice ID is
488
363
  set, and whether the default voice is in use.
489
364
 
490
365
  Examples:
491
- $ vellum integrations voice config
492
- $ vellum integrations voice config --json`,
366
+ $ assistant integrations voice config
367
+ $ assistant integrations voice config --json`,
493
368
  )
494
369
  .action(async (_opts: unknown, cmd: Command) => {
495
370
  await runRead(cmd, async () => readVoiceConfig());
package/src/cli/keys.ts CHANGED
@@ -24,9 +24,9 @@ plaintext. Each key is identified by provider name.
24
24
  Known providers: ${API_KEY_PROVIDERS.join(", ")}
25
25
 
26
26
  Examples:
27
- $ vellum keys list
28
- $ vellum keys set anthropic sk-ant-...
29
- $ vellum keys delete openai`,
27
+ $ assistant keys list
28
+ $ assistant keys set anthropic sk-ant-...
29
+ $ assistant keys delete openai`,
30
30
  );
31
31
 
32
32
  keys
@@ -40,7 +40,7 @@ names of providers that have a stored key. Providers without a stored key are
40
40
  omitted from the output.
41
41
 
42
42
  Examples:
43
- $ vellum keys list`,
43
+ $ assistant keys list`,
44
44
  )
45
45
  .action(() => {
46
46
  const stored: string[] = [];
@@ -59,7 +59,7 @@ Examples:
59
59
 
60
60
  keys
61
61
  .command("set <provider> <key>")
62
- .description("Store an API key (e.g. vellum keys set anthropic sk-ant-...)")
62
+ .description("Store an API key (e.g. assistant keys set anthropic sk-ant-...)")
63
63
  .addHelpText(
64
64
  "after",
65
65
  `
@@ -70,9 +70,9 @@ Arguments:
70
70
  If a key already exists for the given provider, it is silently overwritten.
71
71
 
72
72
  Examples:
73
- $ vellum keys set anthropic sk-ant-abc123
74
- $ vellum keys set openai sk-proj-xyz789
75
- $ vellum keys set fireworks fw-abc123`,
73
+ $ assistant keys set anthropic sk-ant-abc123
74
+ $ assistant keys set openai sk-proj-xyz789
75
+ $ assistant keys set fireworks fw-abc123`,
76
76
  )
77
77
  .action((provider: string, key: string) => {
78
78
  if (setSecureKey(provider, key)) {
@@ -96,8 +96,8 @@ Removes the API key for the given provider from secure local storage. If
96
96
  no key exists for the provider, exits with an error.
97
97
 
98
98
  Examples:
99
- $ vellum keys delete openai
100
- $ vellum keys delete anthropic`,
99
+ $ assistant keys delete openai
100
+ $ assistant keys delete anthropic`,
101
101
  )
102
102
  .action((provider: string) => {
103
103
  const result = deleteSecureKey(provider);
package/src/cli/map.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * CLI command: `vellum map <domain>`
2
+ * CLI command: `assistant map <domain>`
3
3
  *
4
4
  * Launches Chrome with CDP, starts a Ride Shotgun learn session to auto-navigate
5
5
  * the given domain, then analyzes captured network traffic into a deduplicated API map.
@@ -309,9 +309,9 @@ How it works:
309
309
  The assistant must be running (the learn session is coordinated through it).
310
310
 
311
311
  Examples:
312
- $ vellum map example.com
313
- $ vellum map open.spotify.com --duration 180
314
- $ vellum map garmin.com --manual`,
312
+ $ assistant map example.com
313
+ $ assistant map open.spotify.com --duration 180
314
+ $ assistant map garmin.com --manual`,
315
315
  )
316
316
  .action(
317
317
  async (
package/src/cli/mcp.ts CHANGED
@@ -72,10 +72,10 @@ Changes to MCP server configuration require an assistant restart to take effect
72
72
  (vellum sleep && vellum wake).
73
73
 
74
74
  Examples:
75
- $ vellum mcp list
76
- $ vellum mcp add my-server -t stdio -c npx -a my-mcp-server
77
- $ vellum mcp auth my-server
78
- $ vellum mcp remove my-server`,
75
+ $ assistant mcp list
76
+ $ assistant mcp add my-server -t stdio -c npx -a my-mcp-server
77
+ $ assistant mcp auth my-server
78
+ $ assistant mcp remove my-server`,
79
79
  );
80
80
 
81
81
  mcp
@@ -103,8 +103,8 @@ In non-TTY mode (piped), checks run sequentially. With --json, outputs raw
103
103
  server config without running health checks.
104
104
 
105
105
  Examples:
106
- $ vellum mcp list
107
- $ vellum mcp list --json`,
106
+ $ assistant mcp list
107
+ $ assistant mcp list --json`,
108
108
  )
109
109
  .action(async (opts: { json?: boolean }) => {
110
110
  const raw = loadRawConfig();
@@ -278,12 +278,12 @@ The --risk flag sets the default risk level for all tools from this server
278
278
  --disabled is passed.
279
279
 
280
280
  If a server with the same name already exists, the command fails. Remove the
281
- existing server first with "vellum mcp remove <name>".
281
+ existing server first with "assistant mcp remove <name>".
282
282
 
283
283
  Examples:
284
- $ vellum mcp add my-server -t stdio -c npx -a my-mcp-server
285
- $ vellum mcp add remote-api -t streamable-http -u https://api.example.com/mcp -r medium
286
- $ vellum mcp add legacy-sse -t sse -u https://old.example.com/events --disabled`,
284
+ $ assistant mcp add my-server -t stdio -c npx -a my-mcp-server
285
+ $ assistant mcp add remote-api -t streamable-http -u https://api.example.com/mcp -r medium
286
+ $ assistant mcp add legacy-sse -t sse -u https://old.example.com/events --disabled`,
287
287
  )
288
288
  .action(
289
289
  (
@@ -305,7 +305,7 @@ Examples:
305
305
 
306
306
  if (servers[name]) {
307
307
  log.error(
308
- `MCP server "${name}" already exists. Remove it first with: vellum mcp remove ${name}`,
308
+ `MCP server "${name}" already exists. Remove it first with: assistant mcp remove ${name}`,
309
309
  );
310
310
  process.exitCode = 1;
311
311
  return;
@@ -388,8 +388,8 @@ After successful authentication, restart the assistant for changes to take effec
388
388
  (vellum sleep && vellum wake).
389
389
 
390
390
  Examples:
391
- $ vellum mcp auth my-server
392
- $ vellum mcp auth remote-api`,
391
+ $ assistant mcp auth my-server
392
+ $ assistant mcp auth remote-api`,
393
393
  )
394
394
  .action(async (name: string) => {
395
395
  const raw = loadRawConfig();
@@ -399,7 +399,7 @@ Examples:
399
399
 
400
400
  if (!serverConfig) {
401
401
  log.error(
402
- `MCP server "${name}" not found. Add it first with: vellum mcp add`,
402
+ `MCP server "${name}" not found. Add it first with: assistant mcp add`,
403
403
  );
404
404
  process.exitCode = 1;
405
405
  return;
@@ -508,7 +508,7 @@ Examples:
508
508
  log.error(`Authorization cancelled for "${name}".`);
509
509
  } else if (message.includes("timed out")) {
510
510
  log.error(
511
- `Authorization timed out for "${name}". Try again with: vellum mcp auth ${name}`,
511
+ `Authorization timed out for "${name}". Try again with: assistant mcp auth ${name}`,
512
512
  );
513
513
  } else {
514
514
  log.error(`Authorization failed for "${name}": ${message}`);
@@ -567,8 +567,8 @@ After removal, restart the assistant for changes to take effect
567
567
  (vellum sleep && vellum wake).
568
568
 
569
569
  Examples:
570
- $ vellum mcp remove my-server
571
- $ vellum mcp remove legacy-sse`,
570
+ $ assistant mcp remove my-server
571
+ $ assistant mcp remove legacy-sse`,
572
572
  )
573
573
  .action(async (name: string) => {
574
574
  const raw = loadRawConfig();
package/src/cli/memory.ts CHANGED
@@ -38,10 +38,10 @@ Key concepts:
38
38
  conflicts Pairs of contradictory statements awaiting resolution
39
39
 
40
40
  Examples:
41
- $ vellum memory status
42
- $ vellum memory query "What is the project deadline?"
43
- $ vellum memory backfill
44
- $ vellum memory dismiss-conflicts --all`,
41
+ $ assistant memory status
42
+ $ assistant memory query "What is the project deadline?"
43
+ $ assistant memory backfill
44
+ $ assistant memory dismiss-conflicts --all`,
45
45
  );
46
46
 
47
47
  memory
@@ -68,7 +68,7 @@ Fields shown:
68
68
  jobs Status of background jobs (backfill, cleanup, rebuild-index)
69
69
 
70
70
  Examples:
71
- $ vellum memory status`,
71
+ $ assistant memory status`,
72
72
  )
73
73
  .action(() => {
74
74
  initializeDb();
@@ -133,8 +133,8 @@ all segments regardless of whether they have already been indexed. This is
133
133
  useful after bulk imports or if the incremental state has become inconsistent.
134
134
 
135
135
  Examples:
136
- $ vellum memory backfill
137
- $ vellum memory backfill --force`,
136
+ $ assistant memory backfill
137
+ $ assistant memory backfill --force`,
138
138
  )
139
139
  .action((opts: { force?: boolean }) => {
140
140
  initializeDb();
@@ -165,8 +165,8 @@ record must have before it is eligible for cleanup. If omitted, the system
165
165
  default retention period is used.
166
166
 
167
167
  Examples:
168
- $ vellum memory cleanup
169
- $ vellum memory cleanup --retention-ms 86400000`,
168
+ $ assistant memory cleanup
169
+ $ assistant memory cleanup --retention-ms 86400000`,
170
170
  )
171
171
  .action((opts: { retentionMs?: string }) => {
172
172
  initializeDb();
@@ -207,9 +207,9 @@ The optional --session flag provides a conversation/session ID for
207
207
  context-aware recall. If omitted, the most recent conversation is used.
208
208
 
209
209
  Examples:
210
- $ vellum memory query "What is the project deadline?"
211
- $ vellum memory query "preferred communication style" --session conv_abc123
212
- $ vellum memory query "API rate limits"`,
210
+ $ assistant memory query "What is the project deadline?"
211
+ $ assistant memory query "preferred communication style" --session conv_abc123
212
+ $ assistant memory query "API rate limits"`,
213
213
  )
214
214
  .action(async (text: string, opts?: { session?: string }) => {
215
215
  initializeDb();
@@ -247,12 +247,12 @@ search) index and the vector embedding index. All existing index data is
247
247
  dropped and reconstructed from the source memory items.
248
248
 
249
249
  This is useful after schema changes, embedding model upgrades, or if index
250
- corruption is suspected. The rebuild runs asynchronously; use "vellum memory
250
+ corruption is suspected. The rebuild runs asynchronously; use "assistant memory
251
251
  status" to monitor job progress.
252
252
 
253
253
  Examples:
254
- $ vellum memory rebuild-index
255
- $ vellum memory status`,
254
+ $ assistant memory rebuild-index
255
+ $ assistant memory status`,
256
256
  )
257
257
  .action(() => {
258
258
  initializeDb();
@@ -286,9 +286,9 @@ omitted. The --dry-run flag previews which conflicts would be dismissed
286
286
  without actually modifying any records.
287
287
 
288
288
  Examples:
289
- $ vellum memory dismiss-conflicts --all
290
- $ vellum memory dismiss-conflicts --pattern "project deadline" --dry-run
291
- $ vellum memory dismiss-conflicts --pattern "^preferred\\b" --scope work`,
289
+ $ assistant memory dismiss-conflicts --all
290
+ $ assistant memory dismiss-conflicts --pattern "project deadline" --dry-run
291
+ $ assistant memory dismiss-conflicts --pattern "^preferred\\b" --scope work`,
292
292
  )
293
293
  .action(
294
294
  (opts: {
@@ -57,10 +57,10 @@ ${buildSourceChannelsHelpBlock()}
57
57
  ${buildSourceEventNamesHelpBlock()}
58
58
 
59
59
  Examples:
60
- $ vellum notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Build finished"
61
- $ vellum notifications send --source-channel scheduler --source-event-name reminder.fired --message "Stand-up in 5 minutes" --urgency high
62
- $ vellum notifications send --source-channel watcher --source-event-name watcher.notification --message "File changed" --no-requires-action --is-async-background
63
- $ vellum notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Deploy complete" --preferred-channels vellum,telegram --json`,
60
+ $ assistant notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Build finished"
61
+ $ assistant notifications send --source-channel scheduler --source-event-name reminder.fired --message "Stand-up in 5 minutes" --urgency high
62
+ $ assistant notifications send --source-channel watcher --source-event-name watcher.notification --message "File changed" --no-requires-action --is-async-background
63
+ $ assistant notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Deploy complete" --preferred-channels vellum,telegram --json`,
64
64
  );
65
65
 
66
66
  // -------------------------------------------------------------------------
@@ -131,8 +131,8 @@ Examples:
131
131
  "after",
132
132
  `
133
133
  Arguments:
134
- --source-channel One of the registered source channels (see "vellum notifications --help")
135
- --source-event-name One of the registered event names (see "vellum notifications --help")
134
+ --source-channel One of the registered source channels (see "assistant notifications --help")
135
+ --source-event-name One of the registered event names (see "assistant notifications --help")
136
136
  --message The notification body text (required, must be non-empty)
137
137
 
138
138
  Behavioral notes:
@@ -144,9 +144,9 @@ Behavioral notes:
144
144
  - --dedupe-key suppresses duplicate signals with the same key.
145
145
 
146
146
  Examples:
147
- $ vellum notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Task complete"
148
- $ vellum notifications send --source-channel scheduler --source-event-name reminder.fired --message "Meeting in 5 min" --urgency high --title "Reminder"
149
- $ vellum notifications send --source-channel watcher --source-event-name watcher.notification --message "Detected change" --no-requires-action --is-async-background --json`,
147
+ $ assistant notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Task complete"
148
+ $ assistant notifications send --source-channel scheduler --source-event-name reminder.fired --message "Meeting in 5 min" --urgency high --title "Reminder"
149
+ $ assistant notifications send --source-channel watcher --source-event-name watcher.notification --message "Detected change" --no-requires-action --is-async-background --json`,
150
150
  )
151
151
  .action(
152
152
  async (
@@ -318,10 +318,10 @@ notification pipeline.
318
318
  ${buildSourceEventNamesHelpBlock()}
319
319
 
320
320
  Examples:
321
- $ vellum notifications list
322
- $ vellum notifications list --limit 5
323
- $ vellum notifications list --source-event-name reminder.fired
324
- $ vellum notifications list --source-event-name reminder.fired --limit 10 --json`,
321
+ $ assistant notifications list
322
+ $ assistant notifications list --limit 5
323
+ $ assistant notifications list --source-event-name reminder.fired
324
+ $ assistant notifications list --source-event-name reminder.fired --limit 10 --json`,
325
325
  )
326
326
  .action(
327
327
  (
@@ -0,0 +1,77 @@
1
+ import type { Command } from "commander";
2
+
3
+ import { withValidToken } from "../security/token-manager.js";
4
+ import { shouldOutputJson, writeOutput } from "./integrations.js";
5
+
6
+ export function registerOAuthCommand(program: Command): void {
7
+ const oauth = program
8
+ .command("oauth")
9
+ .description("Manage OAuth tokens for connected integrations")
10
+ .option("--json", "Machine-readable compact JSON output");
11
+
12
+ oauth.addHelpText(
13
+ "after",
14
+ `
15
+ OAuth tokens are managed automatically — the "token" command returns a
16
+ guaranteed-valid access token, refreshing transparently if the stored token
17
+ is expired or near-expiry. Callers never need to handle refresh themselves.
18
+
19
+ The <service> argument is the short integration name (e.g. "twitter", "gmail",
20
+ "slack"). Internally this maps to credential:integration:<service>:access_token.
21
+
22
+ Examples:
23
+ $ assistant oauth token twitter
24
+ $ assistant oauth token twitter --json
25
+ $ TOKEN=$(assistant oauth token gmail)
26
+ $ curl -H "Authorization: Bearer $(assistant oauth token twitter)" https://api.x.com/2/tweets`,
27
+ );
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // token — return a guaranteed-valid access token
31
+ // ---------------------------------------------------------------------------
32
+
33
+ oauth
34
+ .command("token <service>")
35
+ .description(
36
+ "Print a valid OAuth access token for a service, refreshing if expired",
37
+ )
38
+ .addHelpText(
39
+ "after",
40
+ `
41
+ Arguments:
42
+ service Integration name without the "integration:" prefix
43
+ (e.g. "twitter", "gmail", "slack")
44
+
45
+ Returns a valid OAuth access token for the given service. If the stored token
46
+ is expired or near-expiry, it is refreshed automatically before being returned.
47
+ The refresh uses the stored refresh token and OAuth2 configuration from
48
+ credential metadata — no additional input is required.
49
+
50
+ In human mode, prints the bare token to stdout (suitable for shell substitution).
51
+ In JSON mode (--json), prints {"ok": true, "token": "..."}.
52
+
53
+ Exits with code 1 if no access token exists for the service, no refresh token
54
+ is available, or the token refresh fails (e.g. revoked credentials).
55
+
56
+ Examples:
57
+ $ assistant oauth token twitter
58
+ $ assistant oauth token gmail --json
59
+ $ export TOKEN=$(assistant oauth token twitter)`,
60
+ )
61
+ .action(async (service: string, _opts: unknown, cmd: Command) => {
62
+ try {
63
+ const qualifiedService = `integration:${service}`;
64
+ const token = await withValidToken(qualifiedService, async (t) => t);
65
+
66
+ if (shouldOutputJson(cmd)) {
67
+ writeOutput(cmd, { ok: true, token });
68
+ } else {
69
+ process.stdout.write(token + "\n");
70
+ }
71
+ } catch (err) {
72
+ const message = err instanceof Error ? err.message : String(err);
73
+ writeOutput(cmd, { ok: false, error: message });
74
+ process.exitCode = 1;
75
+ }
76
+ });
77
+ }
@@ -22,6 +22,7 @@ import { registerMapCommand } from "./map.js";
22
22
  import { registerMcpCommand } from "./mcp.js";
23
23
  import { registerMemoryCommand } from "./memory.js";
24
24
  import { registerNotificationsCommand } from "./notifications.js";
25
+ import { registerOAuthCommand } from "./oauth.js";
25
26
  import { registerSequenceCommand } from "./sequence.js";
26
27
  import { registerSessionsCommand } from "./sessions.js";
27
28
  import { registerTrustCommand } from "./trust.js";
@@ -55,6 +56,7 @@ export function buildCliProgram(): Command {
55
56
  registerAutonomyCommand(program);
56
57
  registerCompletionsCommand(program);
57
58
  registerNotificationsCommand(program);
59
+ registerOAuthCommand(program);
58
60
 
59
61
  registerTwitterCommand(program);
60
62
  registerMapCommand(program);