@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.
- package/Dockerfile +42 -9
- package/docs/architecture/integrations.md +34 -32
- package/node_modules/@vellumai/ces-contracts/src/__tests__/grants.test.ts +7 -7
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +5 -4
- package/node_modules/@vellumai/ces-contracts/src/index.ts +7 -0
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +5 -0
- package/node_modules/@vellumai/credential-storage/src/index.ts +1 -1
- package/openapi.yaml +87 -9
- package/package.json +1 -1
- package/src/__tests__/catalog-cache.test.ts +164 -0
- package/src/__tests__/catalog-search.test.ts +61 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +181 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +396 -0
- package/src/__tests__/conversation-error.test.ts +3 -2
- package/src/__tests__/credential-security-invariants.test.ts +9 -15
- package/src/__tests__/credential-vault-unit.test.ts +32 -34
- package/src/__tests__/credential-vault.test.ts +25 -33
- package/src/__tests__/credentials-cli.test.ts +3 -3
- package/src/__tests__/daemon-credential-client.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +7 -0
- package/src/__tests__/host-bash-proxy.test.ts +79 -0
- package/src/__tests__/host-cu-proxy.test.ts +90 -0
- package/src/__tests__/host-file-proxy.test.ts +89 -0
- package/src/__tests__/integration-status.test.ts +5 -5
- package/src/__tests__/list-messages-attachments.test.ts +171 -0
- package/src/__tests__/mcp-abort-signal.test.ts +205 -0
- package/src/__tests__/messaging-send-tool.test.ts +5 -5
- package/src/__tests__/navigate-settings-tab.test.ts +6 -2
- package/src/__tests__/notification-telegram-adapter.test.ts +125 -0
- package/src/__tests__/oauth-cli.test.ts +126 -119
- package/src/__tests__/oauth-provider-profiles.test.ts +55 -20
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/onboarding-template-contract.test.ts +2 -2
- package/src/__tests__/platform.test.ts +3 -168
- package/src/__tests__/secret-routes-managed-proxy.test.ts +78 -0
- package/src/__tests__/secure-keys-managed-failover.test.ts +73 -0
- package/src/__tests__/skill-feature-flags.test.ts +8 -0
- package/src/__tests__/skill-secret-handling-guard.test.ts +212 -0
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/slack-messaging-token-resolution.test.ts +22 -24
- package/src/__tests__/slack-share-routes.test.ts +5 -5
- package/src/__tests__/system-prompt.test.ts +39 -0
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -1
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +5 -4
- package/src/cli/AGENTS.md +47 -7
- package/src/cli/commands/browser-relay.ts +2 -17
- package/src/cli/commands/contacts.ts +6 -4
- package/src/cli/commands/conversations.ts +13 -1
- package/src/cli/commands/credential-execution.ts +16 -1
- package/src/cli/commands/credentials.ts +2 -8
- package/src/cli/commands/oauth/__tests__/connect.test.ts +29 -108
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +13 -87
- package/src/cli/commands/oauth/__tests__/mode.test.ts +22 -69
- package/src/cli/commands/oauth/__tests__/ping.test.ts +20 -79
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +574 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +416 -0
- package/src/cli/commands/oauth/__tests__/status.test.ts +12 -40
- package/src/cli/commands/oauth/__tests__/token.test.ts +3 -50
- package/src/cli/commands/oauth/apps.ts +63 -44
- package/src/cli/commands/oauth/connect.ts +187 -155
- package/src/cli/commands/oauth/disconnect.ts +27 -75
- package/src/cli/commands/oauth/index.ts +36 -46
- package/src/cli/commands/oauth/mode.ts +22 -34
- package/src/cli/commands/oauth/ping.ts +19 -45
- package/src/cli/commands/oauth/providers.ts +569 -62
- package/src/cli/commands/oauth/request.ts +36 -48
- package/src/cli/commands/oauth/shared.ts +1 -19
- package/src/cli/commands/oauth/status.ts +14 -25
- package/src/cli/commands/oauth/token.ts +25 -34
- package/src/cli/commands/platform/__tests__/connect.test.ts +224 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +237 -0
- package/src/cli/commands/platform/__tests__/status.test.ts +246 -0
- package/src/cli/commands/platform/connect.ts +104 -0
- package/src/cli/commands/platform/disconnect.ts +118 -0
- package/src/cli/commands/{platform.ts → platform/index.ts} +108 -38
- package/src/cli/commands/sequence.ts +5 -4
- package/src/cli/commands/shotgun.ts +16 -0
- package/src/cli/commands/skills.ts +173 -41
- package/src/cli/commands/usage.ts +5 -11
- package/src/cli/lib/daemon-credential-client.ts +22 -38
- package/src/cli/program.ts +1 -1
- package/src/config/assistant-feature-flags.ts +3 -7
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
- package/src/config/bundled-skills/conversations/SKILL.md +20 -0
- package/src/config/bundled-skills/conversations/TOOLS.json +23 -0
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +66 -0
- package/src/config/bundled-skills/gmail/SKILL.md +13 -13
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +3 -3
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +2 -2
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +2 -2
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +1 -1
- package/src/config/bundled-skills/google-calendar/SKILL.md +10 -4
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +7 -7
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +5 -6
- package/src/config/bundled-skills/settings/TOOLS.json +5 -3
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +4 -2
- package/src/config/bundled-tool-registry.ts +5 -0
- package/src/config/feature-flag-registry.json +2 -2
- package/src/credential-execution/client.ts +15 -3
- package/src/daemon/conversation-agent-loop.ts +2 -0
- package/src/daemon/conversation-error.ts +36 -6
- package/src/daemon/conversation-messaging.ts +9 -0
- package/src/daemon/conversation-runtime-assembly.ts +33 -0
- package/src/daemon/conversation-surfaces.ts +120 -14
- package/src/daemon/conversation.ts +5 -0
- package/src/daemon/first-greeting.ts +6 -1
- package/src/daemon/handlers/skills.ts +148 -3
- package/src/daemon/host-bash-proxy.ts +16 -0
- package/src/daemon/host-cu-proxy.ts +16 -0
- package/src/daemon/host-file-proxy.ts +16 -0
- package/src/daemon/lifecycle.ts +56 -5
- package/src/daemon/message-types/conversations.ts +1 -0
- package/src/daemon/message-types/guardian-actions.ts +2 -0
- package/src/daemon/message-types/host-bash.ts +6 -1
- package/src/daemon/message-types/host-cu.ts +6 -1
- package/src/daemon/message-types/host-file.ts +6 -1
- package/src/daemon/message-types/integrations.ts +0 -1
- package/src/daemon/server.ts +29 -2
- package/src/hooks/cli.ts +74 -0
- package/src/inbound/platform-callback-registration.ts +7 -12
- package/src/index.ts +0 -12
- package/src/mcp/client.ts +6 -1
- package/src/mcp/manager.ts +2 -1
- package/src/memory/conversation-crud.ts +92 -3
- package/src/memory/conversation-key-store.ts +26 -0
- package/src/memory/conversation-queries.ts +6 -6
- package/src/memory/db-init.ts +16 -0
- package/src/memory/journal-memory.ts +8 -2
- package/src/memory/migrations/196-messages-conversation-created-at-index.ts +9 -0
- package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +186 -0
- package/src/memory/migrations/197-oauth-providers-behavior-columns.ts +29 -0
- package/src/memory/migrations/198-drop-setup-skill-id-column.ts +11 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/oauth.ts +11 -0
- package/src/messaging/provider.ts +13 -12
- package/src/messaging/providers/gmail/adapter.ts +44 -35
- package/src/messaging/providers/slack/adapter.ts +63 -33
- package/src/messaging/providers/telegram-bot/adapter.ts +6 -8
- package/src/messaging/providers/whatsapp/adapter.ts +6 -8
- package/src/notifications/adapters/telegram.ts +78 -2
- package/src/oauth/__tests__/identity-verifier.test.ts +464 -0
- package/src/oauth/byo-connection.test.ts +22 -24
- package/src/oauth/connect-orchestrator.ts +37 -76
- package/src/oauth/connect-types.ts +7 -65
- package/src/oauth/connection-resolver.test.ts +13 -13
- package/src/oauth/connection-resolver.ts +3 -4
- package/src/oauth/identity-verifier.ts +177 -0
- package/src/oauth/oauth-store.ts +228 -3
- package/src/oauth/platform-connection.test.ts +56 -6
- package/src/oauth/platform-connection.ts +8 -1
- package/src/oauth/seed-providers.ts +247 -34
- package/src/permissions/checker.ts +127 -1
- package/src/prompts/journal-context.ts +4 -1
- package/src/prompts/system-prompt.ts +54 -9
- package/src/prompts/templates/BOOTSTRAP.md +16 -5
- package/src/providers/anthropic/client.ts +2 -33
- package/src/runtime/guardian-action-service.ts +7 -2
- package/src/runtime/http-server.ts +12 -18
- package/src/runtime/http-types.ts +8 -1
- package/src/runtime/migrations/rebind-secrets-screen.ts +2 -2
- package/src/runtime/routes/conversation-management-routes.ts +31 -0
- package/src/runtime/routes/conversation-routes.ts +79 -4
- package/src/runtime/routes/guardian-action-routes.ts +15 -2
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -8
- package/src/runtime/routes/integrations/slack/share.ts +1 -1
- package/src/runtime/routes/oauth-apps.ts +2 -1
- package/src/runtime/routes/secret-routes.ts +45 -15
- package/src/runtime/routes/settings-routes.ts +12 -19
- package/src/runtime/routes/skills-routes.ts +45 -4
- package/src/schedule/integration-status.ts +2 -2
- package/src/security/ces-rpc-credential-backend.ts +19 -16
- package/src/security/oauth-completion-page.ts +153 -0
- package/src/security/oauth2.ts +3 -17
- package/src/security/secure-keys.ts +207 -7
- package/src/security/token-manager.ts +3 -6
- package/src/signals/bash.ts +6 -1
- package/src/skills/catalog-cache.ts +44 -0
- package/src/skills/catalog-search.ts +18 -0
- package/src/tools/browser/browser-manager.ts +2 -2
- package/src/tools/credentials/post-connect-hooks.ts +1 -1
- package/src/tools/credentials/vault.ts +34 -45
- package/src/tools/host-terminal/host-shell.ts +16 -3
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/skills/sandbox-runner.ts +16 -3
- package/src/tools/terminal/shell.ts +16 -3
- package/src/util/logger.ts +11 -1
- package/src/util/platform.ts +1 -91
- package/src/util/sentry-log-stream.ts +51 -0
- package/src/watcher/providers/github.ts +2 -2
- package/src/watcher/providers/gmail.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +1 -1
- package/src/watcher/providers/linear.ts +2 -2
- package/src/workspace/migrations/011-backfill-installation-id.ts +5 -3
- package/src/workspace/migrations/020-rename-oauth-skill-dirs.ts +119 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/cli/commands/oauth/connections.ts +0 -255
- 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
|
|
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
|
-
"
|
|
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
|
-
|
|
118
|
-
OAuth
|
|
119
|
-
|
|
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
|
|
130
|
-
$ assistant oauth request --provider
|
|
131
|
-
$ assistant oauth request --provider
|
|
132
|
-
$ assistant oauth request --provider
|
|
133
|
-
$ assistant oauth request --provider
|
|
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(
|
|
180
|
+
const providerRow = getProvider(opts.provider);
|
|
185
181
|
if (!providerRow) {
|
|
186
182
|
writeError(
|
|
187
|
-
`Error: Unknown provider "${
|
|
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(
|
|
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 "${
|
|
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
|
-
|
|
205
|
+
opts.provider,
|
|
210
206
|
opts.clientId,
|
|
211
207
|
);
|
|
212
208
|
if (!app) {
|
|
213
209
|
writeError(
|
|
214
|
-
`Error: No registered OAuth app found for "${
|
|
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",
|
|
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 "${
|
|
250
|
-
`Run 'assistant oauth status ${
|
|
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(
|
|
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 "${
|
|
269
|
-
`Run 'assistant oauth status ${
|
|
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
|
-
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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(
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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",
|
|
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
|
|
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
|
|
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
|
-
//
|
|
47
|
+
// Validate provider
|
|
58
48
|
// -----------------------------------------------------------------
|
|
59
|
-
const
|
|
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(
|
|
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
|
-
|
|
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:
|
|
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 ${
|
|
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: ${
|
|
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(
|
|
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:
|
|
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 ${
|
|
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: ${
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
67
|
-
|
|
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
|
|
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.
|
|
84
|
-
// ---------------------------------------------------------------
|
|
85
|
-
const providerKey = resolveService(provider);
|
|
86
|
-
|
|
87
|
-
// ---------------------------------------------------------------
|
|
88
|
-
// 2. Check managed mode
|
|
79
|
+
// 1. Check managed mode
|
|
89
80
|
// ---------------------------------------------------------------
|
|
90
|
-
if (isManagedMode(
|
|
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 ${
|
|
96
|
-
`To make authenticated requests, use 'assistant oauth request --provider ${
|
|
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(
|
|
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 "${
|
|
133
|
-
`Connect first with 'assistant oauth connect ${
|
|
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
|
-
|
|
133
|
+
provider,
|
|
143
134
|
async (t) => t,
|
|
144
135
|
tokenOpts,
|
|
145
136
|
);
|