@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
@@ -89,20 +89,6 @@ mock.module("../../../../oauth/oauth-store.js", () => ({
89
89
  deleteConnection: () => false,
90
90
  }));
91
91
 
92
- mock.module("../../../../oauth/provider-behaviors.js", () => ({
93
- resolveService: (service: string) => {
94
- const aliases: Record<string, string> = {
95
- gmail: "integration:google",
96
- google: "integration:google",
97
- slack: "integration:slack",
98
- };
99
- if (aliases[service]) return aliases[service];
100
- if (!service.includes(":")) return `integration:${service}`;
101
- return service;
102
- },
103
- getProviderBehavior: () => undefined,
104
- }));
105
-
106
92
  mock.module("../../../../platform/client.js", () => ({
107
93
  VellumPlatformClient: {
108
94
  create: async () => mockPlatformClientResult,
@@ -131,16 +117,6 @@ mock.module("../../../lib/daemon-credential-client.js", () => ({
131
117
 
132
118
  // Mock shared.js helpers
133
119
  mock.module("../shared.js", () => ({
134
- resolveService: (service: string) => {
135
- const aliases: Record<string, string> = {
136
- gmail: "integration:google",
137
- google: "integration:google",
138
- slack: "integration:slack",
139
- };
140
- if (aliases[service]) return aliases[service];
141
- if (!service.includes(":")) return `integration:${service}`;
142
- return service;
143
- },
144
120
  isManagedMode: () => false,
145
121
  getManagedServiceConfigKey: (key: string) =>
146
122
  mockGetManagedServiceConfigKey(key),
@@ -193,10 +169,6 @@ mock.module("../shared.js", () => ({
193
169
  if (!result.ok) return null;
194
170
  return result.body as Array<Record<string, unknown>>;
195
171
  },
196
- toBareProvider: (provider: string): string =>
197
- provider.startsWith("integration:")
198
- ? provider.slice("integration:".length)
199
- : provider,
200
172
  }));
201
173
 
202
174
  // ---------------------------------------------------------------------------
@@ -295,28 +267,9 @@ describe("assistant oauth mode", () => {
295
267
  expect(parsed.error).toContain("providers list");
296
268
  });
297
269
 
298
- test("provider alias resolution: gmail resolves to integration:google", async () => {
299
- let capturedProviderKey: string | undefined;
300
-
301
- mockGetProvider = (key: string) => {
302
- capturedProviderKey = key;
303
- return {
304
- providerKey: key,
305
- managedServiceConfigKey: "google-oauth",
306
- };
307
- };
308
- mockGetManagedServiceConfigKey = () => "google-oauth";
309
- mockConfigServices = {
310
- "google-oauth": { mode: "managed" },
311
- };
312
-
313
- await runCommand(["mode", "gmail", "--json"]);
314
- expect(capturedProviderKey).toBe("integration:google");
315
- });
316
-
317
270
  test("provider without managedServiceConfigKey returns your-own with managedModeSupported: false", async () => {
318
271
  mockGetProvider = () => ({
319
- providerKey: "integration:slack",
272
+ providerKey: "slack",
320
273
  managedServiceConfigKey: null,
321
274
  });
322
275
  mockGetManagedServiceConfigKey = () => null;
@@ -329,14 +282,14 @@ describe("assistant oauth mode", () => {
329
282
  expect(exitCode).toBe(0);
330
283
  const parsed = JSON.parse(stdout);
331
284
  expect(parsed.ok).toBe(true);
332
- expect(parsed.provider).toBe("integration:slack");
285
+ expect(parsed.provider).toBe("slack");
333
286
  expect(parsed.mode).toBe("your-own");
334
287
  expect(parsed.managedModeSupported).toBe(false);
335
288
  });
336
289
 
337
290
  test("provider in managed mode returns mode: managed with managedModeSupported: true", async () => {
338
291
  mockGetProvider = () => ({
339
- providerKey: "integration:google",
292
+ providerKey: "google",
340
293
  managedServiceConfigKey: "google-oauth",
341
294
  });
342
295
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -352,14 +305,14 @@ describe("assistant oauth mode", () => {
352
305
  expect(exitCode).toBe(0);
353
306
  const parsed = JSON.parse(stdout);
354
307
  expect(parsed.ok).toBe(true);
355
- expect(parsed.provider).toBe("integration:google");
308
+ expect(parsed.provider).toBe("google");
356
309
  expect(parsed.mode).toBe("managed");
357
310
  expect(parsed.managedModeSupported).toBe(true);
358
311
  });
359
312
 
360
313
  test("provider in your-own mode returns mode: your-own with managedModeSupported: true", async () => {
361
314
  mockGetProvider = () => ({
362
- providerKey: "integration:google",
315
+ providerKey: "google",
363
316
  managedServiceConfigKey: "google-oauth",
364
317
  });
365
318
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -375,7 +328,7 @@ describe("assistant oauth mode", () => {
375
328
  expect(exitCode).toBe(0);
376
329
  const parsed = JSON.parse(stdout);
377
330
  expect(parsed.ok).toBe(true);
378
- expect(parsed.provider).toBe("integration:google");
331
+ expect(parsed.provider).toBe("google");
379
332
  expect(parsed.mode).toBe("your-own");
380
333
  expect(parsed.managedModeSupported).toBe(true);
381
334
  });
@@ -388,7 +341,7 @@ describe("assistant oauth mode", () => {
388
341
  describe("set mode", () => {
389
342
  test("invalid mode value returns error listing valid values", async () => {
390
343
  mockGetProvider = () => ({
391
- providerKey: "integration:google",
344
+ providerKey: "google",
392
345
  managedServiceConfigKey: "google-oauth",
393
346
  });
394
347
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -410,7 +363,7 @@ describe("assistant oauth mode", () => {
410
363
 
411
364
  test("provider without managedServiceConfigKey returns error about managed mode not available when --set managed", async () => {
412
365
  mockGetProvider = () => ({
413
- providerKey: "integration:slack",
366
+ providerKey: "slack",
414
367
  managedServiceConfigKey: null,
415
368
  });
416
369
  mockGetManagedServiceConfigKey = () => null;
@@ -426,12 +379,12 @@ describe("assistant oauth mode", () => {
426
379
  const parsed = JSON.parse(stdout);
427
380
  expect(parsed.ok).toBe(false);
428
381
  expect(parsed.error).toContain("Managed mode is not available");
429
- expect(parsed.error).toContain("integration:slack");
382
+ expect(parsed.error).toContain("slack");
430
383
  });
431
384
 
432
385
  test("provider without managedServiceConfigKey treats --set your-own as successful no-op", async () => {
433
386
  mockGetProvider = () => ({
434
- providerKey: "integration:slack",
387
+ providerKey: "slack",
435
388
  managedServiceConfigKey: null,
436
389
  });
437
390
  mockGetManagedServiceConfigKey = () => null;
@@ -446,7 +399,7 @@ describe("assistant oauth mode", () => {
446
399
  expect(exitCode).toBe(0);
447
400
  const parsed = JSON.parse(stdout);
448
401
  expect(parsed.ok).toBe(true);
449
- expect(parsed.provider).toBe("integration:slack");
402
+ expect(parsed.provider).toBe("slack");
450
403
  expect(parsed.mode).toBe("your-own");
451
404
  expect(parsed.changed).toBe(false);
452
405
  expect(parsed.managedModeSupported).toBe(false);
@@ -454,7 +407,7 @@ describe("assistant oauth mode", () => {
454
407
 
455
408
  test("set to same mode returns changed: false", async () => {
456
409
  mockGetProvider = () => ({
457
- providerKey: "integration:google",
410
+ providerKey: "google",
458
411
  managedServiceConfigKey: "google-oauth",
459
412
  });
460
413
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -472,7 +425,7 @@ describe("assistant oauth mode", () => {
472
425
  expect(exitCode).toBe(0);
473
426
  const parsed = JSON.parse(stdout);
474
427
  expect(parsed.ok).toBe(true);
475
- expect(parsed.provider).toBe("integration:google");
428
+ expect(parsed.provider).toBe("google");
476
429
  expect(parsed.mode).toBe("managed");
477
430
  expect(parsed.changed).toBe(false);
478
431
  expect(parsed.managedModeSupported).toBe(true);
@@ -480,7 +433,7 @@ describe("assistant oauth mode", () => {
480
433
 
481
434
  test("switch managed -> your-own with active managed connections and no BYO connections includes hint", async () => {
482
435
  mockGetProvider = () => ({
483
- providerKey: "integration:google",
436
+ providerKey: "google",
484
437
  managedServiceConfigKey: "google-oauth",
485
438
  });
486
439
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -512,7 +465,7 @@ describe("assistant oauth mode", () => {
512
465
  expect(exitCode).toBe(0);
513
466
  const parsed = JSON.parse(stdout);
514
467
  expect(parsed.ok).toBe(true);
515
- expect(parsed.provider).toBe("integration:google");
468
+ expect(parsed.provider).toBe("google");
516
469
  expect(parsed.mode).toBe("your-own");
517
470
  expect(parsed.changed).toBe(true);
518
471
  expect(parsed.managedModeSupported).toBe(true);
@@ -523,7 +476,7 @@ describe("assistant oauth mode", () => {
523
476
 
524
477
  test("switch your-own -> managed with active BYO connections and no managed connections includes hint", async () => {
525
478
  mockGetProvider = () => ({
526
- providerKey: "integration:google",
479
+ providerKey: "google",
527
480
  managedServiceConfigKey: "google-oauth",
528
481
  });
529
482
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -536,7 +489,7 @@ describe("assistant oauth mode", () => {
536
489
  mockListActiveConnectionsByProvider = () => [
537
490
  {
538
491
  id: "conn-local-1",
539
- providerKey: "integration:google",
492
+ providerKey: "google",
540
493
  status: "active",
541
494
  },
542
495
  ];
@@ -555,7 +508,7 @@ describe("assistant oauth mode", () => {
555
508
  expect(exitCode).toBe(0);
556
509
  const parsed = JSON.parse(stdout);
557
510
  expect(parsed.ok).toBe(true);
558
- expect(parsed.provider).toBe("integration:google");
511
+ expect(parsed.provider).toBe("google");
559
512
  expect(parsed.mode).toBe("managed");
560
513
  expect(parsed.changed).toBe(true);
561
514
  expect(parsed.managedModeSupported).toBe(true);
@@ -566,7 +519,7 @@ describe("assistant oauth mode", () => {
566
519
 
567
520
  test("switch mode with connections on both sides has no hint", async () => {
568
521
  mockGetProvider = () => ({
569
- providerKey: "integration:google",
522
+ providerKey: "google",
570
523
  managedServiceConfigKey: "google-oauth",
571
524
  });
572
525
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -589,7 +542,7 @@ describe("assistant oauth mode", () => {
589
542
  mockListActiveConnectionsByProvider = () => [
590
543
  {
591
544
  id: "conn-local-1",
592
- providerKey: "integration:google",
545
+ providerKey: "google",
593
546
  status: "active",
594
547
  },
595
548
  ];
@@ -611,7 +564,7 @@ describe("assistant oauth mode", () => {
611
564
 
612
565
  test("switch mode with no connections on either side has no hint", async () => {
613
566
  mockGetProvider = () => ({
614
- providerKey: "integration:google",
567
+ providerKey: "google",
615
568
  managedServiceConfigKey: "google-oauth",
616
569
  });
617
570
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -644,7 +597,7 @@ describe("assistant oauth mode", () => {
644
597
 
645
598
  test("saveRawConfig is called with the correct nested path", async () => {
646
599
  mockGetProvider = () => ({
647
- providerKey: "integration:google",
600
+ providerKey: "google",
648
601
  managedServiceConfigKey: "google-oauth",
649
602
  });
650
603
  mockGetManagedServiceConfigKey = () => "google-oauth";
@@ -51,20 +51,6 @@ mock.module("../../../../oauth/oauth-store.js", () => ({
51
51
  deleteConnection: () => false,
52
52
  }));
53
53
 
54
- mock.module("../../../../oauth/provider-behaviors.js", () => ({
55
- resolveService: (service: string) => {
56
- const aliases: Record<string, string> = {
57
- gmail: "integration:google",
58
- google: "integration:google",
59
- slack: "integration:slack",
60
- };
61
- if (aliases[service]) return aliases[service];
62
- if (!service.includes(":")) return `integration:${service}`;
63
- return service;
64
- },
65
- getProviderBehavior: () => undefined,
66
- }));
67
-
68
54
  mock.module("../../../../oauth/connection-resolver.js", () => ({
69
55
  resolveOAuthConnection: async (
70
56
  providerKey: string,
@@ -101,23 +87,9 @@ mock.module("../../../../util/logger.js", () => ({
101
87
 
102
88
  // Mock shared.js helpers
103
89
  mock.module("../shared.js", () => ({
104
- resolveService: (service: string) => {
105
- const aliases: Record<string, string> = {
106
- gmail: "integration:google",
107
- google: "integration:google",
108
- slack: "integration:slack",
109
- };
110
- if (aliases[service]) return aliases[service];
111
- if (!service.includes(":")) return `integration:${service}`;
112
- return service;
113
- },
114
90
  isManagedMode: () => false,
115
91
  requirePlatformClient: async () => null,
116
92
  fetchActiveConnections: async () => [],
117
- toBareProvider: (provider: string): string =>
118
- provider.startsWith("integration:")
119
- ? provider.slice("integration:".length)
120
- : provider,
121
93
  }));
122
94
 
123
95
  // ---------------------------------------------------------------------------
@@ -214,7 +186,7 @@ describe("assistant oauth ping", () => {
214
186
 
215
187
  test("no ping URL configured returns error", async () => {
216
188
  mockGetProvider = () => ({
217
- providerKey: "integration:google",
189
+ providerKey: "google",
218
190
  pingUrl: null,
219
191
  });
220
192
 
@@ -226,37 +198,6 @@ describe("assistant oauth ping", () => {
226
198
  expect(parsed.error).toContain("providers register --ping-url");
227
199
  });
228
200
 
229
- // -------------------------------------------------------------------------
230
- // Provider alias resolution
231
- // -------------------------------------------------------------------------
232
-
233
- test("resolves provider alias (gmail -> integration:google)", async () => {
234
- mockGetProvider = () => ({
235
- providerKey: "integration:google",
236
- pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
237
- });
238
-
239
- mockResolveOAuthConnectionResult = {
240
- request: async () => ({
241
- status: 200,
242
- headers: {},
243
- body: { ok: true },
244
- }),
245
- };
246
-
247
- const { exitCode, stdout } = await runCommand(["ping", "gmail", "--json"]);
248
- expect(exitCode).toBe(0);
249
- const parsed = JSON.parse(stdout);
250
- expect(parsed.ok).toBe(true);
251
- expect(parsed.provider).toBe("integration:google");
252
-
253
- // Verify resolveOAuthConnection was called with resolved key
254
- expect(mockResolveOAuthConnectionCalls).toHaveLength(1);
255
- expect(mockResolveOAuthConnectionCalls[0].providerKey).toBe(
256
- "integration:google",
257
- );
258
- });
259
-
260
201
  // =========================================================================
261
202
  // BYO mode tests
262
203
  // =========================================================================
@@ -264,7 +205,7 @@ describe("assistant oauth ping", () => {
264
205
  describe("BYO mode", () => {
265
206
  beforeEach(() => {
266
207
  mockGetProvider = () => ({
267
- providerKey: "integration:google",
208
+ providerKey: "google",
268
209
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
269
210
  managedServiceConfigKey: null,
270
211
  });
@@ -287,7 +228,7 @@ describe("assistant oauth ping", () => {
287
228
  expect(exitCode).toBe(0);
288
229
  const parsed = JSON.parse(stdout);
289
230
  expect(parsed.ok).toBe(true);
290
- expect(parsed.provider).toBe("integration:google");
231
+ expect(parsed.provider).toBe("google");
291
232
  expect(parsed.status).toBe(200);
292
233
  });
293
234
 
@@ -308,7 +249,7 @@ describe("assistant oauth ping", () => {
308
249
  expect(exitCode).toBe(1);
309
250
  const parsed = JSON.parse(stdout);
310
251
  expect(parsed.ok).toBe(false);
311
- expect(parsed.provider).toBe("integration:google");
252
+ expect(parsed.provider).toBe("google");
312
253
  expect(parsed.status).toBe(500);
313
254
  expect(parsed.error).toContain("Ping failed with HTTP 500");
314
255
  });
@@ -366,7 +307,7 @@ describe("assistant oauth ping", () => {
366
307
  describe("managed mode", () => {
367
308
  beforeEach(() => {
368
309
  mockGetProvider = () => ({
369
- providerKey: "integration:google",
310
+ providerKey: "google",
370
311
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
371
312
  managedServiceConfigKey: "google-oauth",
372
313
  });
@@ -389,7 +330,7 @@ describe("assistant oauth ping", () => {
389
330
  expect(exitCode).toBe(0);
390
331
  const parsed = JSON.parse(stdout);
391
332
  expect(parsed.ok).toBe(true);
392
- expect(parsed.provider).toBe("integration:google");
333
+ expect(parsed.provider).toBe("google");
393
334
  expect(parsed.status).toBe(200);
394
335
  });
395
336
 
@@ -410,7 +351,7 @@ describe("assistant oauth ping", () => {
410
351
  expect(exitCode).toBe(1);
411
352
  const parsed = JSON.parse(stdout);
412
353
  expect(parsed.ok).toBe(false);
413
- expect(parsed.provider).toBe("integration:google");
354
+ expect(parsed.provider).toBe("google");
414
355
  expect(parsed.status).toBe(502);
415
356
  expect(parsed.error).toContain("Ping failed with HTTP 502");
416
357
  });
@@ -422,12 +363,12 @@ describe("assistant oauth ping", () => {
422
363
 
423
364
  test("connection resolution failure (no active connection) with recovery hint", async () => {
424
365
  mockGetProvider = () => ({
425
- providerKey: "integration:google",
366
+ providerKey: "google",
426
367
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
427
368
  });
428
369
 
429
370
  mockResolveOAuthConnectionResult = new Error(
430
- 'No active OAuth connection found for "integration:google". Connect the service first with oauth2_connect.',
371
+ 'No active OAuth connection found for "google". Connect the service first with oauth2_connect.',
431
372
  );
432
373
 
433
374
  const { exitCode, stdout } = await runCommand(["ping", "google", "--json"]);
@@ -445,7 +386,7 @@ describe("assistant oauth ping", () => {
445
386
 
446
387
  test("--account option passed through to connection resolution", async () => {
447
388
  mockGetProvider = () => ({
448
- providerKey: "integration:google",
389
+ providerKey: "google",
449
390
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
450
391
  });
451
392
 
@@ -478,7 +419,7 @@ describe("assistant oauth ping", () => {
478
419
 
479
420
  test("--client-id option passed through to connection resolution", async () => {
480
421
  mockGetProvider = () => ({
481
- providerKey: "integration:google",
422
+ providerKey: "google",
482
423
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
483
424
  });
484
425
 
@@ -511,7 +452,7 @@ describe("assistant oauth ping", () => {
511
452
 
512
453
  test("JSON output mode returns structured response", async () => {
513
454
  mockGetProvider = () => ({
514
- providerKey: "integration:google",
455
+ providerKey: "google",
515
456
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
516
457
  });
517
458
 
@@ -529,7 +470,7 @@ describe("assistant oauth ping", () => {
529
470
 
530
471
  // Verify JSON structure
531
472
  expect(parsed).toHaveProperty("ok", true);
532
- expect(parsed).toHaveProperty("provider", "integration:google");
473
+ expect(parsed).toHaveProperty("provider", "google");
533
474
  expect(parsed).toHaveProperty("status", 200);
534
475
  });
535
476
 
@@ -539,7 +480,7 @@ describe("assistant oauth ping", () => {
539
480
 
540
481
  test("human output mode logs to stderr on success", async () => {
541
482
  mockGetProvider = () => ({
542
- providerKey: "integration:google",
483
+ providerKey: "google",
543
484
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
544
485
  });
545
486
 
@@ -558,7 +499,7 @@ describe("assistant oauth ping", () => {
558
499
  // In human mode, output is still written via writeOutput
559
500
  const parsed = JSON.parse(stdout);
560
501
  expect(parsed.ok).toBe(true);
561
- expect(parsed.provider).toBe("integration:google");
502
+ expect(parsed.provider).toBe("google");
562
503
  });
563
504
 
564
505
  // =========================================================================
@@ -567,7 +508,7 @@ describe("assistant oauth ping", () => {
567
508
 
568
509
  test("uses configured pingMethod for POST providers", async () => {
569
510
  mockGetProvider = () => ({
570
- providerKey: "integration:dropbox",
511
+ providerKey: "dropbox",
571
512
  pingUrl: "https://api.dropboxapi.com/2/users/get_current_account",
572
513
  pingMethod: "POST",
573
514
  pingHeaders: null,
@@ -589,7 +530,7 @@ describe("assistant oauth ping", () => {
589
530
 
590
531
  test("uses configured pingHeaders", async () => {
591
532
  mockGetProvider = () => ({
592
- providerKey: "integration:notion",
533
+ providerKey: "notion",
593
534
  pingUrl: "https://api.notion.com/v1/users/me",
594
535
  pingMethod: null,
595
536
  pingHeaders: '{"Notion-Version":"2022-06-28"}',
@@ -613,7 +554,7 @@ describe("assistant oauth ping", () => {
613
554
 
614
555
  test("uses configured pingBody for GraphQL providers", async () => {
615
556
  mockGetProvider = () => ({
616
- providerKey: "integration:linear",
557
+ providerKey: "linear",
617
558
  pingUrl: "https://api.linear.app/graphql",
618
559
  pingMethod: "POST",
619
560
  pingHeaders: '{"Content-Type":"application/json"}',
@@ -641,7 +582,7 @@ describe("assistant oauth ping", () => {
641
582
 
642
583
  test("defaults to GET with no extra headers/body when ping config is null", async () => {
643
584
  mockGetProvider = () => ({
644
- providerKey: "integration:google",
585
+ providerKey: "google",
645
586
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
646
587
  pingMethod: null,
647
588
  pingHeaders: null,
@@ -669,7 +610,7 @@ describe("assistant oauth ping", () => {
669
610
 
670
611
  test("network failure returns error with recovery hint", async () => {
671
612
  mockGetProvider = () => ({
672
- providerKey: "integration:google",
613
+ providerKey: "google",
673
614
  pingUrl: "https://www.googleapis.com/oauth2/v1/tokeninfo",
674
615
  });
675
616