workos 0.18.0 → 0.19.0
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/README.md +8 -145
- package/dist/bin.js +129 -50
- package/dist/bin.js.map +1 -1
- package/dist/commands/api/index.js +18 -10
- package/dist/commands/api/index.js.map +1 -1
- package/dist/commands/api/interactive.js +11 -11
- package/dist/commands/api/interactive.js.map +1 -1
- package/dist/commands/claim.js +28 -16
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/connection.js +3 -3
- package/dist/commands/connection.js.map +1 -1
- package/dist/commands/debug.js +6 -6
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/dev.d.ts +7 -8
- package/dist/commands/dev.js +14 -14
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/directory.js +3 -3
- package/dist/commands/directory.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/emulate.d.ts +1 -0
- package/dist/commands/emulate.js +3 -2
- package/dist/commands/emulate.js.map +1 -1
- package/dist/commands/env.d.ts +10 -0
- package/dist/commands/env.js +94 -18
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/install.js +8 -13
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +25 -15
- package/dist/commands/login.js +126 -71
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +4 -4
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mcp.js +7 -16
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/migrations.js +2 -1
- package/dist/commands/migrations.js.map +1 -1
- package/dist/commands/seed.js +5 -4
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/setup.d.ts +50 -0
- package/dist/commands/setup.js +237 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/vault-run.js +3 -2
- package/dist/commands/vault-run.js.map +1 -1
- package/dist/commands/verify-login.d.ts +25 -0
- package/dist/commands/verify-login.js +158 -0
- package/dist/commands/verify-login.js.map +1 -0
- package/dist/doctor/issues.js +3 -2
- package/dist/doctor/issues.js.map +1 -1
- package/dist/doctor/output.js +2 -1
- package/dist/doctor/output.js.map +1 -1
- package/dist/integrations/dotnet/index.js +1 -1
- package/dist/integrations/dotnet/index.js.map +1 -1
- package/dist/integrations/elixir/index.js +1 -1
- package/dist/integrations/elixir/index.js.map +1 -1
- package/dist/integrations/go/index.js +1 -1
- package/dist/integrations/go/index.js.map +1 -1
- package/dist/integrations/nextjs/index.js +8 -5
- package/dist/integrations/nextjs/index.js.map +1 -1
- package/dist/integrations/nextjs/utils.d.ts +1 -1
- package/dist/integrations/nextjs/utils.js +21 -6
- package/dist/integrations/nextjs/utils.js.map +1 -1
- package/dist/integrations/react-router/index.js +5 -5
- package/dist/integrations/react-router/index.js.map +1 -1
- package/dist/integrations/react-router/utils.js +28 -12
- package/dist/integrations/react-router/utils.js.map +1 -1
- package/dist/integrations/ruby/index.js +1 -1
- package/dist/integrations/ruby/index.js.map +1 -1
- package/dist/lib/adapters/cli-adapter.d.ts +33 -4
- package/dist/lib/adapters/cli-adapter.js +251 -135
- package/dist/lib/adapters/cli-adapter.js.map +1 -1
- package/dist/lib/adapters/dashboard-adapter.js +3 -3
- package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
- package/dist/lib/adapters/headless-adapter.d.ts +7 -0
- package/dist/lib/adapters/headless-adapter.js +42 -5
- package/dist/lib/adapters/headless-adapter.js.map +1 -1
- package/dist/lib/agent-interface.js +15 -1
- package/dist/lib/agent-interface.js.map +1 -1
- package/dist/lib/agent-runner.js +1 -1
- package/dist/lib/agent-runner.js.map +1 -1
- package/dist/lib/api-key.js +2 -1
- package/dist/lib/api-key.js.map +1 -1
- package/dist/lib/completion-data.d.ts +33 -0
- package/dist/lib/completion-data.js +33 -0
- package/dist/lib/completion-data.js.map +1 -0
- package/dist/lib/config-store.d.ts +13 -0
- package/dist/lib/config-store.js +24 -0
- package/dist/lib/config-store.js.map +1 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +8 -0
- package/dist/lib/constants.js +8 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/events.d.ts +34 -1
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/framework-config.d.ts +6 -0
- package/dist/lib/framework-config.js.map +1 -1
- package/dist/lib/installer-core.d.ts +14 -1
- package/dist/lib/installer-core.js +24 -5
- package/dist/lib/installer-core.js.map +1 -1
- package/dist/lib/installer-core.types.d.ts +3 -1
- package/dist/lib/installer-core.types.js.map +1 -1
- package/dist/lib/mcp-clients.d.ts +6 -0
- package/dist/lib/mcp-clients.js +13 -0
- package/dist/lib/mcp-clients.js.map +1 -1
- package/dist/lib/port-detection.js +19 -13
- package/dist/lib/port-detection.js.map +1 -1
- package/dist/lib/preferences.d.ts +30 -2
- package/dist/lib/preferences.js +34 -8
- package/dist/lib/preferences.js.map +1 -1
- package/dist/lib/run-with-core.js +40 -3
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/telemetry-notice.d.ts +5 -5
- package/dist/lib/telemetry-notice.js +7 -8
- package/dist/lib/telemetry-notice.js.map +1 -1
- package/dist/lib/unclaimed-env-provision.js +15 -12
- package/dist/lib/unclaimed-env-provision.js.map +1 -1
- package/dist/lib/unclaimed-warning.js +4 -3
- package/dist/lib/unclaimed-warning.js.map +1 -1
- package/dist/lib/validation/security-checks.js +2 -1
- package/dist/lib/validation/security-checks.js.map +1 -1
- package/dist/lib/validation/validator.js +30 -3
- package/dist/lib/validation/validator.js.map +1 -1
- package/dist/lib/workos-management.js +26 -19
- package/dist/lib/workos-management.js.map +1 -1
- package/dist/run.d.ts +1 -0
- package/dist/run.js +5 -1
- package/dist/run.js.map +1 -1
- package/dist/steps/add-or-update-environment-variables.js +10 -10
- package/dist/steps/add-or-update-environment-variables.js.map +1 -1
- package/dist/steps/run-prettier.js +3 -3
- package/dist/steps/run-prettier.js.map +1 -1
- package/dist/steps/upload-environment-variables/index.js +15 -3
- package/dist/steps/upload-environment-variables/index.js.map +1 -1
- package/dist/steps/upload-environment-variables/providers/vercel.js +2 -2
- package/dist/steps/upload-environment-variables/providers/vercel.js.map +1 -1
- package/dist/utils/box.d.ts +6 -30
- package/dist/utils/box.js +8 -95
- package/dist/utils/box.js.map +1 -1
- package/dist/utils/cli-symbols.d.ts +14 -2
- package/dist/utils/cli-symbols.js +12 -0
- package/dist/utils/cli-symbols.js.map +1 -1
- package/dist/utils/debug.js +3 -3
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/environment.js +1 -1
- package/dist/utils/environment.js.map +1 -1
- package/dist/utils/help-json.js +115 -4
- package/dist/utils/help-json.js.map +1 -1
- package/dist/utils/package-manager.js +1 -1
- package/dist/utils/package-manager.js.map +1 -1
- package/dist/utils/recovery-hints.d.ts +5 -0
- package/dist/utils/recovery-hints.js +12 -0
- package/dist/utils/recovery-hints.js.map +1 -1
- package/dist/utils/summary-box.d.ts +8 -1
- package/dist/utils/summary-box.js +67 -4
- package/dist/utils/summary-box.js.map +1 -1
- package/dist/utils/types.d.ts +10 -0
- package/dist/utils/types.js.map +1 -1
- package/dist/utils/{clack-utils.d.ts → ui-utils.d.ts} +1 -1
- package/dist/utils/{clack-utils.js → ui-utils.js} +64 -37
- package/dist/utils/ui-utils.js.map +1 -0
- package/dist/utils/ui.d.ts +148 -0
- package/dist/utils/ui.js +368 -0
- package/dist/utils/ui.js.map +1 -0
- package/package.json +5 -13
- package/dist/check-coverage.ts +0 -237
- package/dist/emulate/core/id.d.ts +0 -48
- package/dist/emulate/core/id.js +0 -73
- package/dist/emulate/core/id.js.map +0 -1
- package/dist/emulate/core/index.d.ts +0 -8
- package/dist/emulate/core/index.js +0 -8
- package/dist/emulate/core/index.js.map +0 -1
- package/dist/emulate/core/jwt.d.ts +0 -28
- package/dist/emulate/core/jwt.js +0 -78
- package/dist/emulate/core/jwt.js.map +0 -1
- package/dist/emulate/core/middleware/auth.d.ts +0 -15
- package/dist/emulate/core/middleware/auth.js +0 -17
- package/dist/emulate/core/middleware/auth.js.map +0 -1
- package/dist/emulate/core/middleware/error-handler.d.ts +0 -22
- package/dist/emulate/core/middleware/error-handler.js +0 -72
- package/dist/emulate/core/middleware/error-handler.js.map +0 -1
- package/dist/emulate/core/pagination.d.ts +0 -27
- package/dist/emulate/core/pagination.js +0 -43
- package/dist/emulate/core/pagination.js.map +0 -1
- package/dist/emulate/core/plugin.d.ts +0 -15
- package/dist/emulate/core/plugin.js +0 -2
- package/dist/emulate/core/plugin.js.map +0 -1
- package/dist/emulate/core/server.d.ts +0 -17
- package/dist/emulate/core/server.js +0 -90
- package/dist/emulate/core/server.js.map +0 -1
- package/dist/emulate/core/store.d.ts +0 -44
- package/dist/emulate/core/store.js +0 -169
- package/dist/emulate/core/store.js.map +0 -1
- package/dist/emulate/index.d.ts +0 -25
- package/dist/emulate/index.js +0 -47
- package/dist/emulate/index.js.map +0 -1
- package/dist/emulate/workos/constants.d.ts +0 -56
- package/dist/emulate/workos/constants.js +0 -56
- package/dist/emulate/workos/constants.js.map +0 -1
- package/dist/emulate/workos/entities.d.ts +0 -360
- package/dist/emulate/workos/entities.js +0 -2
- package/dist/emulate/workos/entities.js.map +0 -1
- package/dist/emulate/workos/event-bus.d.ts +0 -17
- package/dist/emulate/workos/event-bus.js +0 -70
- package/dist/emulate/workos/event-bus.js.map +0 -1
- package/dist/emulate/workos/helpers.d.ts +0 -72
- package/dist/emulate/workos/helpers.js +0 -211
- package/dist/emulate/workos/helpers.js.map +0 -1
- package/dist/emulate/workos/index.d.ts +0 -93
- package/dist/emulate/workos/index.js +0 -326
- package/dist/emulate/workos/index.js.map +0 -1
- package/dist/emulate/workos/role-helpers.d.ts +0 -21
- package/dist/emulate/workos/role-helpers.js +0 -130
- package/dist/emulate/workos/role-helpers.js.map +0 -1
- package/dist/emulate/workos/routes/api-keys.d.ts +0 -2
- package/dist/emulate/workos/routes/api-keys.js +0 -32
- package/dist/emulate/workos/routes/api-keys.js.map +0 -1
- package/dist/emulate/workos/routes/audit-logs.d.ts +0 -2
- package/dist/emulate/workos/routes/audit-logs.js +0 -104
- package/dist/emulate/workos/routes/audit-logs.js.map +0 -1
- package/dist/emulate/workos/routes/auth-challenges.d.ts +0 -2
- package/dist/emulate/workos/routes/auth-challenges.js +0 -51
- package/dist/emulate/workos/routes/auth-challenges.js.map +0 -1
- package/dist/emulate/workos/routes/auth-factors.d.ts +0 -2
- package/dist/emulate/workos/routes/auth-factors.js +0 -51
- package/dist/emulate/workos/routes/auth-factors.js.map +0 -1
- package/dist/emulate/workos/routes/auth.d.ts +0 -2
- package/dist/emulate/workos/routes/auth.js +0 -350
- package/dist/emulate/workos/routes/auth.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-checks.d.ts +0 -10
- package/dist/emulate/workos/routes/authorization-checks.js +0 -123
- package/dist/emulate/workos/routes/authorization-checks.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-org-roles.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-org-roles.js +0 -64
- package/dist/emulate/workos/routes/authorization-org-roles.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-permissions.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-permissions.js +0 -67
- package/dist/emulate/workos/routes/authorization-permissions.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-resources.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-resources.js +0 -117
- package/dist/emulate/workos/routes/authorization-resources.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-roles.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-roles.js +0 -13
- package/dist/emulate/workos/routes/authorization-roles.js.map +0 -1
- package/dist/emulate/workos/routes/config.d.ts +0 -2
- package/dist/emulate/workos/routes/config.js +0 -57
- package/dist/emulate/workos/routes/config.js.map +0 -1
- package/dist/emulate/workos/routes/connect.d.ts +0 -2
- package/dist/emulate/workos/routes/connect.js +0 -65
- package/dist/emulate/workos/routes/connect.js.map +0 -1
- package/dist/emulate/workos/routes/connections.d.ts +0 -2
- package/dist/emulate/workos/routes/connections.js +0 -73
- package/dist/emulate/workos/routes/connections.js.map +0 -1
- package/dist/emulate/workos/routes/data-integrations.d.ts +0 -2
- package/dist/emulate/workos/routes/data-integrations.js +0 -55
- package/dist/emulate/workos/routes/data-integrations.js.map +0 -1
- package/dist/emulate/workos/routes/directories.d.ts +0 -2
- package/dist/emulate/workos/routes/directories.js +0 -90
- package/dist/emulate/workos/routes/directories.js.map +0 -1
- package/dist/emulate/workos/routes/email-verification.d.ts +0 -2
- package/dist/emulate/workos/routes/email-verification.js +0 -49
- package/dist/emulate/workos/routes/email-verification.js.map +0 -1
- package/dist/emulate/workos/routes/events.d.ts +0 -2
- package/dist/emulate/workos/routes/events.js +0 -18
- package/dist/emulate/workos/routes/events.js.map +0 -1
- package/dist/emulate/workos/routes/feature-flags.d.ts +0 -2
- package/dist/emulate/workos/routes/feature-flags.js +0 -103
- package/dist/emulate/workos/routes/feature-flags.js.map +0 -1
- package/dist/emulate/workos/routes/invitations.d.ts +0 -2
- package/dist/emulate/workos/routes/invitations.js +0 -122
- package/dist/emulate/workos/routes/invitations.js.map +0 -1
- package/dist/emulate/workos/routes/legacy-mfa.d.ts +0 -2
- package/dist/emulate/workos/routes/legacy-mfa.js +0 -75
- package/dist/emulate/workos/routes/legacy-mfa.js.map +0 -1
- package/dist/emulate/workos/routes/magic-auth.d.ts +0 -2
- package/dist/emulate/workos/routes/magic-auth.js +0 -32
- package/dist/emulate/workos/routes/magic-auth.js.map +0 -1
- package/dist/emulate/workos/routes/memberships.d.ts +0 -2
- package/dist/emulate/workos/routes/memberships.js +0 -114
- package/dist/emulate/workos/routes/memberships.js.map +0 -1
- package/dist/emulate/workos/routes/organization-domains.d.ts +0 -2
- package/dist/emulate/workos/routes/organization-domains.js +0 -58
- package/dist/emulate/workos/routes/organization-domains.js.map +0 -1
- package/dist/emulate/workos/routes/organizations.d.ts +0 -2
- package/dist/emulate/workos/routes/organizations.js +0 -131
- package/dist/emulate/workos/routes/organizations.js.map +0 -1
- package/dist/emulate/workos/routes/password-reset.d.ts +0 -2
- package/dist/emulate/workos/routes/password-reset.js +0 -61
- package/dist/emulate/workos/routes/password-reset.js.map +0 -1
- package/dist/emulate/workos/routes/pipes.d.ts +0 -2
- package/dist/emulate/workos/routes/pipes.js +0 -82
- package/dist/emulate/workos/routes/pipes.js.map +0 -1
- package/dist/emulate/workos/routes/portal.d.ts +0 -2
- package/dist/emulate/workos/routes/portal.js +0 -18
- package/dist/emulate/workos/routes/portal.js.map +0 -1
- package/dist/emulate/workos/routes/radar.d.ts +0 -2
- package/dist/emulate/workos/routes/radar.js +0 -41
- package/dist/emulate/workos/routes/radar.js.map +0 -1
- package/dist/emulate/workos/routes/sessions.d.ts +0 -2
- package/dist/emulate/workos/routes/sessions.js +0 -51
- package/dist/emulate/workos/routes/sessions.js.map +0 -1
- package/dist/emulate/workos/routes/sso.d.ts +0 -2
- package/dist/emulate/workos/routes/sso.js +0 -161
- package/dist/emulate/workos/routes/sso.js.map +0 -1
- package/dist/emulate/workos/routes/user-features.d.ts +0 -2
- package/dist/emulate/workos/routes/user-features.js +0 -50
- package/dist/emulate/workos/routes/user-features.js.map +0 -1
- package/dist/emulate/workos/routes/users.d.ts +0 -2
- package/dist/emulate/workos/routes/users.js +0 -129
- package/dist/emulate/workos/routes/users.js.map +0 -1
- package/dist/emulate/workos/routes/webhook-endpoints.d.ts +0 -2
- package/dist/emulate/workos/routes/webhook-endpoints.js +0 -67
- package/dist/emulate/workos/routes/webhook-endpoints.js.map +0 -1
- package/dist/emulate/workos/routes/widgets.d.ts +0 -2
- package/dist/emulate/workos/routes/widgets.js +0 -27
- package/dist/emulate/workos/routes/widgets.js.map +0 -1
- package/dist/emulate/workos/store.d.ts +0 -48
- package/dist/emulate/workos/store.js +0 -102
- package/dist/emulate/workos/store.js.map +0 -1
- package/dist/emulate/workos/webhook-signer.d.ts +0 -1
- package/dist/emulate/workos/webhook-signer.js +0 -8
- package/dist/emulate/workos/webhook-signer.js.map +0 -1
- package/dist/gen-routes-lib.spec.ts +0 -659
- package/dist/gen-routes-lib.ts +0 -647
- package/dist/gen-routes.ts +0 -96
- package/dist/lib/mcp-notice.d.ts +0 -72
- package/dist/lib/mcp-notice.js +0 -275
- package/dist/lib/mcp-notice.js.map +0 -1
- package/dist/utils/clack-utils.js.map +0 -1
- package/dist/utils/clack.d.ts +0 -5
- package/dist/utils/clack.js +0 -34
- package/dist/utils/clack.js.map +0 -1
package/dist/commands/login.js
CHANGED
|
@@ -1,82 +1,91 @@
|
|
|
1
1
|
import open from 'open';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import
|
|
3
|
+
import ui from '../utils/ui.js';
|
|
4
4
|
import { saveCredentials, getCredentials, getAccessToken, isTokenExpired, updateTokens } from '../lib/credentials.js';
|
|
5
5
|
import { getCliAuthClientId, getAuthkitDomain } from '../lib/settings.js';
|
|
6
6
|
import { refreshAccessToken } from '../lib/token-refresh-client.js';
|
|
7
7
|
import { logInfo, logError } from '../utils/debug.js';
|
|
8
|
-
import { fetchStagingCredentials } from '../lib/staging-api.js';
|
|
9
|
-
import {
|
|
8
|
+
import { fetchStagingCredentials, StagingApiError } from '../lib/staging-api.js';
|
|
9
|
+
import { analytics } from '../utils/analytics.js';
|
|
10
|
+
import { getConfig, saveConfig, getActiveEnvironment, setActiveEnvironment, freshEnvKey } from '../lib/config-store.js';
|
|
10
11
|
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
11
|
-
import {
|
|
12
|
-
import { isJsonMode } from '../utils/output.js';
|
|
13
|
-
import { isAgentMode, isCiMode } from '../utils/interaction-mode.js';
|
|
12
|
+
import { maybeRunSetupAfter } from './setup.js';
|
|
13
|
+
import { isJsonMode, outputJson } from '../utils/output.js';
|
|
14
|
+
import { isAgentMode, isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';
|
|
14
15
|
import { ExitCode, exitWithAuthRequired, exitWithCode } from '../utils/exit-codes.js';
|
|
15
16
|
import { requestDeviceCode, pollForToken, DeviceAuthTimeoutError } from '../lib/device-auth.js';
|
|
16
17
|
import { observeHostFailure } from '../lib/host-probe.js';
|
|
17
18
|
/**
|
|
18
|
-
*
|
|
19
|
+
* Does the just-authenticated account differ from the account that owns `prior`?
|
|
19
20
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* Extracted from runLogin so it can be unit-tested without standing up the
|
|
26
|
-
* device-auth polling loop.
|
|
21
|
+
* Email comparison wins when both sides have it (human-readable, survives a
|
|
22
|
+
* clientId reissue); otherwise fall back to clientId. When neither is available
|
|
23
|
+
* we cannot tell — return false and let the always-on "Now using" line protect
|
|
24
|
+
* the user.
|
|
27
25
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
timeoutHandle.unref?.();
|
|
37
|
-
});
|
|
38
|
-
const result = await Promise.race([autoInstallSkills(), timeout]);
|
|
39
|
-
if (result && !isJsonMode()) {
|
|
40
|
-
const skillWord = result.skills.length === 1 ? 'skill' : 'skills';
|
|
41
|
-
clack.log.info(`Installed ${result.skills.length} WorkOS ${skillWord} for ${result.agents.join(', ')}.`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
// Skill install must never fail login.
|
|
46
|
-
}
|
|
47
|
-
finally {
|
|
48
|
-
if (timeoutHandle)
|
|
49
|
-
clearTimeout(timeoutHandle);
|
|
50
|
-
}
|
|
26
|
+
function isMismatch(prior, account, staging) {
|
|
27
|
+
if (!prior)
|
|
28
|
+
return false;
|
|
29
|
+
if (prior.ownerEmail && account.email)
|
|
30
|
+
return prior.ownerEmail !== account.email;
|
|
31
|
+
if (prior.clientId)
|
|
32
|
+
return prior.clientId !== staging.clientId;
|
|
33
|
+
return false;
|
|
51
34
|
}
|
|
52
35
|
/**
|
|
53
36
|
* Auto-provision a staging environment after login.
|
|
54
37
|
*
|
|
55
|
-
* Fetches staging credentials
|
|
56
|
-
*
|
|
57
|
-
*
|
|
38
|
+
* Fetches staging credentials for the just-authenticated account and stores
|
|
39
|
+
* them. On a detected cross-account mismatch, the new account's Staging is
|
|
40
|
+
* written under a DISTINCT key rather than clobbering the active slot, and the
|
|
41
|
+
* active pointer is left alone — only a login onto an empty config auto-assigns
|
|
42
|
+
* the active env. Non-fatal — logs a hint on failure instead of throwing.
|
|
58
43
|
*/
|
|
59
|
-
export async function provisionStagingEnvironment(accessToken) {
|
|
44
|
+
export async function provisionStagingEnvironment(accessToken, account) {
|
|
60
45
|
try {
|
|
61
46
|
const staging = await fetchStagingCredentials(accessToken);
|
|
62
47
|
const config = getConfig() ?? { environments: {} };
|
|
63
|
-
const
|
|
64
|
-
config.environments[
|
|
65
|
-
|
|
48
|
+
const priorName = config.activeEnvironment;
|
|
49
|
+
const prior = priorName ? config.environments[priorName] : undefined; // capture BEFORE write
|
|
50
|
+
const mismatch = isMismatch(prior, account, staging);
|
|
51
|
+
// Never overwrite a DIFFERENT account's 'staging' slot in place.
|
|
52
|
+
const stagingSlot = config.environments['staging'];
|
|
53
|
+
const slotMismatch = isMismatch(stagingSlot, account, staging);
|
|
54
|
+
const key = slotMismatch ? freshEnvKey(config, 'staging') : 'staging';
|
|
55
|
+
config.environments[key] = {
|
|
56
|
+
name: key,
|
|
66
57
|
type: 'sandbox',
|
|
67
58
|
apiKey: staging.apiKey,
|
|
68
59
|
clientId: staging.clientId,
|
|
60
|
+
...(account.email && { ownerEmail: account.email }),
|
|
61
|
+
ownerUserId: account.userId,
|
|
69
62
|
};
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
// Only auto-assign active when there is NO valid prior active env.
|
|
64
|
+
if (!prior) {
|
|
65
|
+
config.activeEnvironment = key;
|
|
72
66
|
}
|
|
73
67
|
saveConfig(config);
|
|
74
|
-
logInfo('[login] Staging environment
|
|
75
|
-
return
|
|
68
|
+
logInfo('[login] Staging environment provisioned');
|
|
69
|
+
return {
|
|
70
|
+
provisioned: true,
|
|
71
|
+
activeEnvironment: config.activeEnvironment,
|
|
72
|
+
envName: key,
|
|
73
|
+
mismatch,
|
|
74
|
+
priorEnvName: priorName,
|
|
75
|
+
priorAccount: prior ? { email: prior.ownerEmail, clientId: prior.clientId } : undefined,
|
|
76
|
+
};
|
|
76
77
|
}
|
|
77
78
|
catch (error) {
|
|
78
|
-
logError('[login] Failed to
|
|
79
|
-
|
|
79
|
+
logError('[login] Failed to provision staging environment:', error instanceof Error ? error.message : error);
|
|
80
|
+
// Best-effort, but the failure rate of this onboarding step must be visible:
|
|
81
|
+
// a silent failure here leaves the user with no active environment for every
|
|
82
|
+
// later command, indistinguishable in telemetry from a healthy setup.
|
|
83
|
+
analytics.captureException(error instanceof Error ? error : new Error(String(error)), {
|
|
84
|
+
command: 'auth.login',
|
|
85
|
+
phase: 'provision-staging',
|
|
86
|
+
statusCode: error instanceof StagingApiError ? error.statusCode : undefined,
|
|
87
|
+
});
|
|
88
|
+
return { provisioned: false, mismatch: false };
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
91
|
export async function runLogin() {
|
|
@@ -101,35 +110,44 @@ export async function runLogin() {
|
|
|
101
110
|
console.log(chalk.dim(`Run \`${formatWorkOSCommand('auth logout')}\` to log out`));
|
|
102
111
|
return;
|
|
103
112
|
}
|
|
113
|
+
// Refresh returned no token — record why before falling through to fresh
|
|
114
|
+
// login. A spike here surfaces token revocation / refresh-endpoint outages
|
|
115
|
+
// that self-heal into a browser login and would otherwise be invisible.
|
|
116
|
+
analytics.capture('token_refresh_failed', { errorType: result.errorType ?? 'unknown' });
|
|
104
117
|
}
|
|
105
|
-
catch {
|
|
106
|
-
|
|
118
|
+
catch (error) {
|
|
119
|
+
analytics.capture('token_refresh_failed', { errorType: error instanceof Error ? error.name : 'unknown' });
|
|
120
|
+
// Refresh failed, proceed with fresh login.
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
if (isCiMode()) {
|
|
110
124
|
exitWithAuthRequired('Browser authentication is not available in CI mode. Set WORKOS_API_KEY or configure credentials before running in CI.');
|
|
111
125
|
}
|
|
112
126
|
const authkitDomain = getAuthkitDomain();
|
|
113
|
-
|
|
127
|
+
ui.log.step('Starting authentication...');
|
|
114
128
|
let deviceAuth;
|
|
115
129
|
try {
|
|
116
130
|
deviceAuth = await requestDeviceCode({ clientId, authkitDomain });
|
|
117
131
|
}
|
|
118
132
|
catch (error) {
|
|
119
133
|
const msg = error instanceof Error ? error.message : String(error);
|
|
120
|
-
|
|
134
|
+
ui.log.error(`Failed to start authentication: ${msg}`);
|
|
135
|
+
analytics.captureException(error instanceof Error ? error : new Error(msg), {
|
|
136
|
+
command: 'auth.login',
|
|
137
|
+
phase: 'device-code',
|
|
138
|
+
});
|
|
121
139
|
exitWithCode(ExitCode.GENERAL_ERROR);
|
|
122
140
|
}
|
|
123
|
-
|
|
141
|
+
ui.log.info(`\nOpen this URL in your browser:\n`);
|
|
124
142
|
console.log(` ${deviceAuth.verification_uri}`);
|
|
125
143
|
console.log(`\nEnter code: ${deviceAuth.user_code}\n`);
|
|
126
144
|
try {
|
|
127
145
|
await open(deviceAuth.verification_uri_complete, { wait: false });
|
|
128
146
|
if (isAgentMode()) {
|
|
129
|
-
|
|
147
|
+
ui.log.info('Browser launch attempted. If it did not open on the host, use the manual URL and code above.');
|
|
130
148
|
}
|
|
131
149
|
else {
|
|
132
|
-
|
|
150
|
+
ui.log.info('Browser opened automatically');
|
|
133
151
|
}
|
|
134
152
|
}
|
|
135
153
|
catch (error) {
|
|
@@ -138,9 +156,9 @@ export async function runLogin() {
|
|
|
138
156
|
target: deviceAuth.verification_uri_complete,
|
|
139
157
|
label: 'auth login browser',
|
|
140
158
|
});
|
|
141
|
-
|
|
159
|
+
ui.log.info('Could not open browser — open the URL above manually.');
|
|
142
160
|
}
|
|
143
|
-
const spinner =
|
|
161
|
+
const spinner = ui.spinner();
|
|
144
162
|
spinner.start('Waiting for authentication...');
|
|
145
163
|
try {
|
|
146
164
|
const result = await pollForToken(deviceAuth.device_code, {
|
|
@@ -157,27 +175,64 @@ export async function runLogin() {
|
|
|
157
175
|
refreshToken: result.refreshToken,
|
|
158
176
|
});
|
|
159
177
|
spinner.stop('Authentication successful!');
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
178
|
+
ui.log.success(`Logged in as ${result.email || result.userId}`);
|
|
179
|
+
ui.log.info(`Token expires in ${expiresInSec} seconds`);
|
|
180
|
+
const account = { email: result.email, userId: result.userId };
|
|
181
|
+
const provision = await provisionStagingEnvironment(result.accessToken, account);
|
|
182
|
+
if (isJsonMode()) {
|
|
183
|
+
outputJson({
|
|
184
|
+
status: 'ok',
|
|
185
|
+
account: { email: account.email ?? null, userId: account.userId },
|
|
186
|
+
activeEnvironment: provision.activeEnvironment ?? null,
|
|
187
|
+
mismatch: provision.mismatch,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else if (provision.provisioned) {
|
|
191
|
+
if (provision.mismatch) {
|
|
192
|
+
const priorLabel = provision.priorAccount?.email ?? provision.priorAccount?.clientId ?? provision.priorEnvName;
|
|
193
|
+
if (isPromptAllowed()) {
|
|
194
|
+
const answer = await ui.confirm({
|
|
195
|
+
message: `You were using ${provision.priorEnvName} (${priorLabel}, a different account). Switch active environment to ${account.email ?? account.userId}'s Staging?`,
|
|
196
|
+
initialValue: false, // default: keep current
|
|
197
|
+
});
|
|
198
|
+
if (!ui.isCancel(answer) && answer && provision.envName) {
|
|
199
|
+
setActiveEnvironment(provision.envName);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
ui.log.warn(`Logged in as ${account.email ?? account.userId}, but the active environment "${provision.priorEnvName}" belongs to a different account (${priorLabel}). Keeping it active. Run \`${formatWorkOSCommand('env switch')}\` to change environments.`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const active = getActiveEnvironment();
|
|
207
|
+
if (active) {
|
|
208
|
+
ui.log.success(`Now using: ${active.name} (${active.type}) — ${account.email ?? account.userId}`);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
ui.log.info(chalk.dim(`Run \`${formatWorkOSCommand('env add')}\` to configure an environment manually`));
|
|
212
|
+
}
|
|
165
213
|
}
|
|
166
214
|
else {
|
|
167
|
-
|
|
215
|
+
ui.log.info(chalk.dim(`Run \`${formatWorkOSCommand('env add')}\` to configure an environment manually`));
|
|
168
216
|
}
|
|
169
|
-
await
|
|
217
|
+
await maybeRunSetupAfter('login');
|
|
170
218
|
}
|
|
171
219
|
catch (error) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
220
|
+
const isTimeout = error instanceof DeviceAuthTimeoutError;
|
|
221
|
+
if (isTimeout) {
|
|
222
|
+
spinner.stop('Authentication timed out', 1);
|
|
223
|
+
ui.log.error('Authentication timed out. Please try again.');
|
|
175
224
|
}
|
|
176
225
|
else {
|
|
177
|
-
spinner.stop('Authentication failed');
|
|
226
|
+
spinner.stop('Authentication failed', 1);
|
|
178
227
|
const msg = error instanceof Error ? error.message : String(error);
|
|
179
|
-
|
|
228
|
+
ui.log.error(`Authentication error: ${msg}`);
|
|
180
229
|
}
|
|
230
|
+
// Deliver the real cause to telemetry (the command event alone can't
|
|
231
|
+
// distinguish a timeout from a network/server auth failure).
|
|
232
|
+
analytics.captureException(error instanceof Error ? error : new Error(String(error)), {
|
|
233
|
+
command: 'auth.login',
|
|
234
|
+
phase: isTimeout ? 'timeout' : 'poll',
|
|
235
|
+
});
|
|
181
236
|
exitWithCode(ExitCode.GENERAL_ERROR);
|
|
182
237
|
}
|
|
183
238
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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","sourcesContent":["import open from 'open';\nimport chalk from 'chalk';\nimport clack from '../utils/clack.js';\nimport { saveCredentials, getCredentials, getAccessToken, isTokenExpired, updateTokens } from '../lib/credentials.js';\nimport { getCliAuthClientId, getAuthkitDomain } from '../lib/settings.js';\nimport { refreshAccessToken } from '../lib/token-refresh-client.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { fetchStagingCredentials } from '../lib/staging-api.js';\nimport { getConfig, saveConfig } from '../lib/config-store.js';\nimport type { CliConfig } from '../lib/config-store.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\nimport { autoInstallSkills } from './install-skill.js';\nimport { isJsonMode } from '../utils/output.js';\nimport { isAgentMode, isCiMode } from '../utils/interaction-mode.js';\nimport { ExitCode, exitWithAuthRequired, exitWithCode } from '../utils/exit-codes.js';\nimport { requestDeviceCode, pollForToken, DeviceAuthTimeoutError } from '../lib/device-auth.js';\nimport { observeHostFailure } from '../lib/host-probe.js';\n\n/**\n * Best-effort skill install after a successful auth-login.\n *\n * Mirrors the install.ts hook copy, but wraps `autoInstallSkills` in its own\n * try/catch AND a 30s timeout so a skill install hang (e.g. blocked filesystem\n * call) never blocks login completion. Login already succeeded by the time\n * this runs — the user having a working session is the contract that must hold.\n *\n * Extracted from runLogin so it can be unit-tested without standing up the\n * device-auth polling loop.\n */\nexport const SKILL_INSTALL_TIMEOUT_MS = 30 * 1000;\n\nexport async function installSkillsAfterLogin(): Promise<void> {\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n try {\n const timeout = new Promise<null>((resolve) => {\n timeoutHandle = setTimeout(() => resolve(null), SKILL_INSTALL_TIMEOUT_MS);\n // Don't keep the event loop alive on this timer — process should exit\n // immediately if everything else has resolved.\n timeoutHandle.unref?.();\n });\n const result = await Promise.race([autoInstallSkills(), timeout]);\n if (result && !isJsonMode()) {\n const skillWord = result.skills.length === 1 ? 'skill' : 'skills';\n clack.log.info(`Installed ${result.skills.length} WorkOS ${skillWord} for ${result.agents.join(', ')}.`);\n }\n } catch {\n // Skill install must never fail login.\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n}\n\n/**\n * Auto-provision a staging environment after login.\n *\n * Fetches staging credentials using the access token, then saves them\n * as a \"staging\" environment in the config store. Non-fatal — logs a\n * hint on failure instead of throwing.\n */\nexport async function provisionStagingEnvironment(accessToken: string): Promise<boolean> {\n try {\n const staging = await fetchStagingCredentials(accessToken);\n\n const config: CliConfig = getConfig() ?? { environments: {} };\n const isFirst = Object.keys(config.environments).length === 0;\n\n config.environments['staging'] = {\n name: 'staging',\n type: 'sandbox',\n apiKey: staging.apiKey,\n clientId: staging.clientId,\n };\n\n if (isFirst || !config.activeEnvironment) {\n config.activeEnvironment = 'staging';\n }\n\n saveConfig(config);\n logInfo('[login] Staging environment auto-provisioned');\n return true;\n } catch (error) {\n logError('[login] Failed to auto-provision staging environment:', error instanceof Error ? error.message : error);\n return false;\n }\n}\n\nexport async function runLogin(): Promise<void> {\n const clientId = getCliAuthClientId();\n\n // Check if already logged in with valid token\n if (getAccessToken()) {\n const creds = getCredentials();\n console.log(chalk.green(`Already logged in as ${creds?.email ?? 'unknown'}`));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth logout')}\\` to log out`));\n return;\n }\n\n // Try to refresh if we have expired credentials with a refresh token\n const existingCreds = getCredentials();\n if (existingCreds?.refreshToken && isTokenExpired(existingCreds)) {\n try {\n const authkitDomain = getAuthkitDomain();\n const result = await refreshAccessToken(authkitDomain, clientId);\n if (result.accessToken && result.expiresAt) {\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n logInfo('[login] Session refreshed via refresh token');\n console.log(chalk.green(`Already logged in as ${existingCreds.email ?? 'unknown'}`));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth logout')}\\` to log out`));\n return;\n }\n } catch {\n // Refresh failed, proceed with fresh login\n }\n }\n\n if (isCiMode()) {\n exitWithAuthRequired(\n 'Browser authentication is not available in CI mode. Set WORKOS_API_KEY or configure credentials before running in CI.',\n );\n }\n\n const authkitDomain = getAuthkitDomain();\n\n clack.log.step('Starting authentication...');\n\n let deviceAuth;\n try {\n deviceAuth = await requestDeviceCode({ clientId, authkitDomain });\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n clack.log.error(`Failed to start authentication: ${msg}`);\n exitWithCode(ExitCode.GENERAL_ERROR);\n }\n\n clack.log.info(`\\nOpen this URL in your browser:\\n`);\n console.log(` ${deviceAuth.verification_uri}`);\n console.log(`\\nEnter code: ${deviceAuth.user_code}\\n`);\n\n try {\n await open(deviceAuth.verification_uri_complete, { wait: false });\n if (isAgentMode()) {\n clack.log.info('Browser launch attempted. If it did not open on the host, use the manual URL and code above.');\n } else {\n clack.log.info('Browser opened automatically');\n }\n } catch (error) {\n observeHostFailure('browser-launch', error, {\n operation: 'open',\n target: deviceAuth.verification_uri_complete,\n label: 'auth login browser',\n });\n clack.log.info('Could not open browser — open the URL above manually.');\n }\n\n const spinner = clack.spinner();\n spinner.start('Waiting for authentication...');\n\n try {\n const result = await pollForToken(deviceAuth.device_code, {\n clientId,\n authkitDomain,\n interval: deviceAuth.interval,\n });\n\n const expiresInSec = Math.round((result.expiresAt - Date.now()) / 1000);\n\n saveCredentials({\n accessToken: result.accessToken,\n expiresAt: result.expiresAt,\n userId: result.userId,\n email: result.email,\n refreshToken: result.refreshToken,\n });\n\n spinner.stop('Authentication successful!');\n clack.log.success(`Logged in as ${result.email || result.userId}`);\n clack.log.info(`Token expires in ${expiresInSec} seconds`);\n\n const provisioned = await provisionStagingEnvironment(result.accessToken);\n if (provisioned) {\n clack.log.success('Staging environment configured automatically');\n } else {\n clack.log.info(chalk.dim('Run `workos env add` to configure an environment manually'));\n }\n\n await installSkillsAfterLogin();\n } catch (error) {\n if (error instanceof DeviceAuthTimeoutError) {\n spinner.stop('Authentication timed out');\n clack.log.error('Authentication timed out. Please try again.');\n } else {\n spinner.stop('Authentication failed');\n const msg = error instanceof Error ? error.message : String(error);\n clack.log.error(`Authentication error: ${msg}`);\n }\n exitWithCode(ExitCode.GENERAL_ERROR);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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","sourcesContent":["import open from 'open';\nimport chalk from 'chalk';\nimport ui from '../utils/ui.js';\nimport { saveCredentials, getCredentials, getAccessToken, isTokenExpired, updateTokens } from '../lib/credentials.js';\nimport { getCliAuthClientId, getAuthkitDomain } from '../lib/settings.js';\nimport { refreshAccessToken } from '../lib/token-refresh-client.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { fetchStagingCredentials, StagingApiError } from '../lib/staging-api.js';\nimport { analytics } from '../utils/analytics.js';\nimport { getConfig, saveConfig, getActiveEnvironment, setActiveEnvironment, freshEnvKey } from '../lib/config-store.js';\nimport type { CliConfig, EnvironmentConfig } from '../lib/config-store.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\nimport { maybeRunSetupAfter } from './setup.js';\nimport { isJsonMode, outputJson } from '../utils/output.js';\nimport { isAgentMode, isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';\nimport { ExitCode, exitWithAuthRequired, exitWithCode } from '../utils/exit-codes.js';\nimport { requestDeviceCode, pollForToken, DeviceAuthTimeoutError } from '../lib/device-auth.js';\nimport { observeHostFailure } from '../lib/host-probe.js';\n\n/**\n * Result of a post-login staging provision. Carries enough context for\n * `runLogin` to detect a cross-account switch and decide how to surface it\n * without ever silently repointing the active environment.\n */\nexport interface StagingProvisionResult {\n provisioned: boolean;\n /** Active env name AFTER provisioning (unchanged unless there was no prior active env). */\n activeEnvironment?: string;\n /** Key the new Staging env was written under ('staging' or a fresh 'staging-N'). */\n envName?: string;\n mismatch: boolean;\n priorEnvName?: string;\n priorAccount?: { email?: string; clientId?: string };\n}\n\n/**\n * Does the just-authenticated account differ from the account that owns `prior`?\n *\n * Email comparison wins when both sides have it (human-readable, survives a\n * clientId reissue); otherwise fall back to clientId. When neither is available\n * we cannot tell — return false and let the always-on \"Now using\" line protect\n * the user.\n */\nfunction isMismatch(\n prior: EnvironmentConfig | undefined,\n account: { email?: string },\n staging: { clientId: string },\n): boolean {\n if (!prior) return false;\n if (prior.ownerEmail && account.email) return prior.ownerEmail !== account.email;\n if (prior.clientId) return prior.clientId !== staging.clientId;\n return false;\n}\n\n/**\n * Auto-provision a staging environment after login.\n *\n * Fetches staging credentials for the just-authenticated account and stores\n * them. On a detected cross-account mismatch, the new account's Staging is\n * written under a DISTINCT key rather than clobbering the active slot, and the\n * active pointer is left alone — only a login onto an empty config auto-assigns\n * the active env. Non-fatal — logs a hint on failure instead of throwing.\n */\nexport async function provisionStagingEnvironment(\n accessToken: string,\n account: { email?: string; userId: string },\n): Promise<StagingProvisionResult> {\n try {\n const staging = await fetchStagingCredentials(accessToken);\n\n const config: CliConfig = getConfig() ?? { environments: {} };\n\n const priorName = config.activeEnvironment;\n const prior = priorName ? config.environments[priorName] : undefined; // capture BEFORE write\n const mismatch = isMismatch(prior, account, staging);\n\n // Never overwrite a DIFFERENT account's 'staging' slot in place.\n const stagingSlot = config.environments['staging'];\n const slotMismatch = isMismatch(stagingSlot, account, staging);\n const key = slotMismatch ? freshEnvKey(config, 'staging') : 'staging';\n\n config.environments[key] = {\n name: key,\n type: 'sandbox',\n apiKey: staging.apiKey,\n clientId: staging.clientId,\n ...(account.email && { ownerEmail: account.email }),\n ownerUserId: account.userId,\n };\n\n // Only auto-assign active when there is NO valid prior active env.\n if (!prior) {\n config.activeEnvironment = key;\n }\n\n saveConfig(config);\n logInfo('[login] Staging environment provisioned');\n\n return {\n provisioned: true,\n activeEnvironment: config.activeEnvironment,\n envName: key,\n mismatch,\n priorEnvName: priorName,\n priorAccount: prior ? { email: prior.ownerEmail, clientId: prior.clientId } : undefined,\n };\n } catch (error) {\n logError('[login] Failed to provision staging environment:', error instanceof Error ? error.message : error);\n // Best-effort, but the failure rate of this onboarding step must be visible:\n // a silent failure here leaves the user with no active environment for every\n // later command, indistinguishable in telemetry from a healthy setup.\n analytics.captureException(error instanceof Error ? error : new Error(String(error)), {\n command: 'auth.login',\n phase: 'provision-staging',\n statusCode: error instanceof StagingApiError ? error.statusCode : undefined,\n });\n return { provisioned: false, mismatch: false };\n }\n}\n\nexport async function runLogin(): Promise<void> {\n const clientId = getCliAuthClientId();\n\n // Check if already logged in with valid token\n if (getAccessToken()) {\n const creds = getCredentials();\n console.log(chalk.green(`Already logged in as ${creds?.email ?? 'unknown'}`));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth logout')}\\` to log out`));\n return;\n }\n\n // Try to refresh if we have expired credentials with a refresh token\n const existingCreds = getCredentials();\n if (existingCreds?.refreshToken && isTokenExpired(existingCreds)) {\n try {\n const authkitDomain = getAuthkitDomain();\n const result = await refreshAccessToken(authkitDomain, clientId);\n if (result.accessToken && result.expiresAt) {\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n logInfo('[login] Session refreshed via refresh token');\n console.log(chalk.green(`Already logged in as ${existingCreds.email ?? 'unknown'}`));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth logout')}\\` to log out`));\n return;\n }\n // Refresh returned no token — record why before falling through to fresh\n // login. A spike here surfaces token revocation / refresh-endpoint outages\n // that self-heal into a browser login and would otherwise be invisible.\n analytics.capture('token_refresh_failed', { errorType: result.errorType ?? 'unknown' });\n } catch (error) {\n analytics.capture('token_refresh_failed', { errorType: error instanceof Error ? error.name : 'unknown' });\n // Refresh failed, proceed with fresh login.\n }\n }\n\n if (isCiMode()) {\n exitWithAuthRequired(\n 'Browser authentication is not available in CI mode. Set WORKOS_API_KEY or configure credentials before running in CI.',\n );\n }\n\n const authkitDomain = getAuthkitDomain();\n\n ui.log.step('Starting authentication...');\n\n let deviceAuth;\n try {\n deviceAuth = await requestDeviceCode({ clientId, authkitDomain });\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n ui.log.error(`Failed to start authentication: ${msg}`);\n analytics.captureException(error instanceof Error ? error : new Error(msg), {\n command: 'auth.login',\n phase: 'device-code',\n });\n exitWithCode(ExitCode.GENERAL_ERROR);\n }\n\n ui.log.info(`\\nOpen this URL in your browser:\\n`);\n console.log(` ${deviceAuth.verification_uri}`);\n console.log(`\\nEnter code: ${deviceAuth.user_code}\\n`);\n\n try {\n await open(deviceAuth.verification_uri_complete, { wait: false });\n if (isAgentMode()) {\n ui.log.info('Browser launch attempted. If it did not open on the host, use the manual URL and code above.');\n } else {\n ui.log.info('Browser opened automatically');\n }\n } catch (error) {\n observeHostFailure('browser-launch', error, {\n operation: 'open',\n target: deviceAuth.verification_uri_complete,\n label: 'auth login browser',\n });\n ui.log.info('Could not open browser — open the URL above manually.');\n }\n\n const spinner = ui.spinner();\n spinner.start('Waiting for authentication...');\n\n try {\n const result = await pollForToken(deviceAuth.device_code, {\n clientId,\n authkitDomain,\n interval: deviceAuth.interval,\n });\n\n const expiresInSec = Math.round((result.expiresAt - Date.now()) / 1000);\n\n saveCredentials({\n accessToken: result.accessToken,\n expiresAt: result.expiresAt,\n userId: result.userId,\n email: result.email,\n refreshToken: result.refreshToken,\n });\n\n spinner.stop('Authentication successful!');\n ui.log.success(`Logged in as ${result.email || result.userId}`);\n ui.log.info(`Token expires in ${expiresInSec} seconds`);\n\n const account = { email: result.email, userId: result.userId };\n const provision = await provisionStagingEnvironment(result.accessToken, account);\n\n if (isJsonMode()) {\n outputJson({\n status: 'ok',\n account: { email: account.email ?? null, userId: account.userId },\n activeEnvironment: provision.activeEnvironment ?? null,\n mismatch: provision.mismatch,\n });\n } else if (provision.provisioned) {\n if (provision.mismatch) {\n const priorLabel = provision.priorAccount?.email ?? provision.priorAccount?.clientId ?? provision.priorEnvName;\n if (isPromptAllowed()) {\n const answer = await ui.confirm({\n message: `You were using ${provision.priorEnvName} (${priorLabel}, a different account). Switch active environment to ${account.email ?? account.userId}'s Staging?`,\n initialValue: false, // default: keep current\n });\n if (!ui.isCancel(answer) && answer && provision.envName) {\n setActiveEnvironment(provision.envName);\n }\n } else {\n ui.log.warn(\n `Logged in as ${account.email ?? account.userId}, but the active environment \"${provision.priorEnvName}\" belongs to a different account (${priorLabel}). Keeping it active. Run \\`${formatWorkOSCommand('env switch')}\\` to change environments.`,\n );\n }\n }\n const active = getActiveEnvironment();\n if (active) {\n ui.log.success(`Now using: ${active.name} (${active.type}) — ${account.email ?? account.userId}`);\n } else {\n ui.log.info(chalk.dim(`Run \\`${formatWorkOSCommand('env add')}\\` to configure an environment manually`));\n }\n } else {\n ui.log.info(chalk.dim(`Run \\`${formatWorkOSCommand('env add')}\\` to configure an environment manually`));\n }\n\n await maybeRunSetupAfter('login');\n } catch (error) {\n const isTimeout = error instanceof DeviceAuthTimeoutError;\n if (isTimeout) {\n spinner.stop('Authentication timed out', 1);\n ui.log.error('Authentication timed out. Please try again.');\n } else {\n spinner.stop('Authentication failed', 1);\n const msg = error instanceof Error ? error.message : String(error);\n ui.log.error(`Authentication error: ${msg}`);\n }\n // Deliver the real cause to telemetry (the command event alone can't\n // distinguish a timeout from a network/server auth failure).\n analytics.captureException(error instanceof Error ? error : new Error(String(error)), {\n command: 'auth.login',\n phase: isTimeout ? 'timeout' : 'poll',\n });\n exitWithCode(ExitCode.GENERAL_ERROR);\n }\n}\n"]}
|
package/dist/commands/logout.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ui from '../utils/ui.js';
|
|
2
2
|
import { clearCredentials, hasCredentials, getCredentials } from '../lib/credentials.js';
|
|
3
3
|
export async function runLogout() {
|
|
4
4
|
if (!hasCredentials()) {
|
|
5
|
-
|
|
5
|
+
ui.log.info('Not logged in');
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
8
|
const creds = getCredentials();
|
|
9
9
|
clearCredentials();
|
|
10
10
|
if (creds?.email) {
|
|
11
|
-
|
|
11
|
+
ui.log.success(`Logged out from ${creds.email}`);
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
|
|
14
|
+
ui.log.success('Logged out successfully');
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=logout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEzF,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,gBAAgB,EAAE,CAAC;IAEnB,IAAI,KAAK,EAAE,KAAK,EAAE,CAAC;QACjB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC","sourcesContent":["import ui from '../utils/ui.js';\nimport { clearCredentials, hasCredentials, getCredentials } from '../lib/credentials.js';\n\nexport async function runLogout(): Promise<void> {\n if (!hasCredentials()) {\n ui.log.info('Not logged in');\n return;\n }\n\n const creds = getCredentials();\n clearCredentials();\n\n if (creds?.email) {\n ui.log.success(`Logged out from ${creds.email}`);\n } else {\n ui.log.success('Logged out successfully');\n }\n}\n"]}
|
package/dist/commands/mcp.js
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ui from '../utils/ui.js';
|
|
2
2
|
import { outputSuccess, outputJson, outputTable, exitWithError, isJsonMode } from '../utils/output.js';
|
|
3
3
|
import { ExitCode, exitWithCode } from '../utils/exit-codes.js';
|
|
4
|
-
import { createMcpClients, detectMcpClients, MCP_AGENT_KEYS, } from '../lib/mcp-clients.js';
|
|
5
|
-
/** Human phrasing for each outcome (JSON mode emits the raw `outcome` value). */
|
|
6
|
-
const OUTCOME_LABEL = {
|
|
7
|
-
installed: 'installed',
|
|
8
|
-
'already-installed': 'already installed',
|
|
9
|
-
removed: 'removed',
|
|
10
|
-
'not-installed': 'not installed',
|
|
11
|
-
skipped: 'skipped',
|
|
12
|
-
failed: 'failed',
|
|
13
|
-
};
|
|
4
|
+
import { createMcpClients, detectMcpClients, MCP_AGENT_KEYS, MCP_OUTCOME_LABELS, } from '../lib/mcp-clients.js';
|
|
14
5
|
/**
|
|
15
6
|
* Validate `--agent` values against known keys. Unknown values exit with a
|
|
16
7
|
* structured `unknown_agent` error. Returns undefined (no filter) when none
|
|
@@ -34,7 +25,7 @@ function reportNoAgents() {
|
|
|
34
25
|
outputSuccess('No supported coding agents detected', { agents: [] });
|
|
35
26
|
}
|
|
36
27
|
else {
|
|
37
|
-
|
|
28
|
+
ui.log.info('No supported coding agents detected (looked for Claude Code, Codex, Cursor).');
|
|
38
29
|
}
|
|
39
30
|
}
|
|
40
31
|
/**
|
|
@@ -47,15 +38,15 @@ function reportResults(message, results) {
|
|
|
47
38
|
}
|
|
48
39
|
else {
|
|
49
40
|
for (const r of results) {
|
|
50
|
-
const line = `${r.displayName}: ${
|
|
41
|
+
const line = `${r.displayName}: ${MCP_OUTCOME_LABELS[r.outcome]}`;
|
|
51
42
|
if (r.outcome === 'failed') {
|
|
52
|
-
|
|
43
|
+
ui.log.error(r.error ? `${line} — ${r.error}` : line);
|
|
53
44
|
}
|
|
54
45
|
else if (r.outcome === 'installed' || r.outcome === 'removed' || r.outcome === 'already-installed') {
|
|
55
|
-
|
|
46
|
+
ui.log.success(line);
|
|
56
47
|
}
|
|
57
48
|
else {
|
|
58
|
-
|
|
49
|
+
ui.log.info(line);
|
|
59
50
|
}
|
|
60
51
|
}
|
|
61
52
|
}
|
package/dist/commands/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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","sourcesContent":["import ui from '../utils/ui.js';\nimport { outputSuccess, outputJson, outputTable, exitWithError, isJsonMode } from '../utils/output.js';\nimport { ExitCode, exitWithCode } from '../utils/exit-codes.js';\nimport {\n createMcpClients,\n detectMcpClients,\n MCP_AGENT_KEYS,\n MCP_OUTCOME_LABELS,\n type McpAgentKey,\n type McpClientResult,\n} from '../lib/mcp-clients.js';\n\n/**\n * `workos mcp install | remove | status` handlers.\n *\n * Thin callers over `lib/mcp-clients.ts`: detect the clients, run the\n * operation, and format the per-agent matrix in both output modes. No prompts\n * (non-TTY-safe by construction) and no auth guard — the WorkOS MCP server is\n * secret-free, so configuring it never needs an API key.\n */\n\nexport interface McpCommandOptions {\n agent?: string[];\n}\n\n/**\n * Validate `--agent` values against known keys. Unknown values exit with a\n * structured `unknown_agent` error. Returns undefined (no filter) when none\n * were passed, so callers act on all detected agents.\n */\nfunction resolveAgentFilter(agent?: string[]): McpAgentKey[] | undefined {\n if (!agent || agent.length === 0) return undefined;\n const unknown = agent.filter((a) => !MCP_AGENT_KEYS.includes(a as McpAgentKey));\n if (unknown.length > 0) {\n exitWithError({\n code: 'unknown_agent',\n message: `Unknown agent(s): ${unknown.join(', ')}. Supported: ${MCP_AGENT_KEYS.join(', ')}.`,\n });\n }\n return agent as McpAgentKey[];\n}\n\n/** Zero detected agents: same message + exit 0 for both install and remove. */\nfunction reportNoAgents(): void {\n if (isJsonMode()) {\n outputSuccess('No supported coding agents detected', { agents: [] });\n } else {\n ui.log.info('No supported coding agents detected (looked for Claude Code, Codex, Cursor).');\n }\n}\n\n/**\n * Emit the per-agent matrix, then exit non-zero if any agent failed. The full\n * matrix is always emitted first so partial success is still fully reported.\n */\nfunction reportResults(message: string, results: McpClientResult[]): void {\n if (isJsonMode()) {\n outputSuccess(message, { agents: results });\n } else {\n for (const r of results) {\n const line = `${r.displayName}: ${MCP_OUTCOME_LABELS[r.outcome]}`;\n if (r.outcome === 'failed') {\n ui.log.error(r.error ? `${line} — ${r.error}` : line);\n } else if (r.outcome === 'installed' || r.outcome === 'removed' || r.outcome === 'already-installed') {\n ui.log.success(line);\n } else {\n ui.log.info(line);\n }\n }\n }\n\n if (results.some((r) => r.outcome === 'failed')) {\n exitWithCode(ExitCode.GENERAL_ERROR);\n }\n}\n\nexport async function runMcpInstall(options: McpCommandOptions = {}): Promise<void> {\n const filter = resolveAgentFilter(options.agent);\n const clients = await detectMcpClients(filter);\n if (clients.length === 0) {\n reportNoAgents();\n return;\n }\n const results: McpClientResult[] = [];\n for (const client of clients) {\n results.push(await client.add());\n }\n reportResults('Configured WorkOS MCP server', results);\n}\n\nexport async function runMcpRemove(options: McpCommandOptions = {}): Promise<void> {\n const filter = resolveAgentFilter(options.agent);\n const clients = await detectMcpClients(filter);\n if (clients.length === 0) {\n reportNoAgents();\n return;\n }\n const results: McpClientResult[] = [];\n for (const client of clients) {\n results.push(await client.remove());\n }\n reportResults('Removed WorkOS MCP server', results);\n}\n\nexport async function runMcpStatus(): Promise<void> {\n // Status lists every known agent (not just available ones) with its\n // availability + install flags, so `createMcpClients()` — not\n // `detectMcpClients()` — is the right source here.\n const clients = createMcpClients();\n const agents = await Promise.all(\n clients.map(async (client) => {\n const available = await client.isAvailable();\n const installed = available ? await client.isInstalled() : false;\n return { agent: client.key, displayName: client.displayName, available, installed };\n }),\n );\n\n if (isJsonMode()) {\n outputJson({ data: { agents } });\n return;\n }\n\n outputTable(\n [{ header: 'Agent' }, { header: 'Available' }, { header: 'Installed' }],\n agents.map((a) => [a.displayName, a.available ? 'yes' : 'no', a.installed ? 'yes' : 'no']),\n );\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getWorkOSCommand } from '../utils/command-invocation.js';
|
|
1
2
|
const workosOnlyMigrationsFlags = new Map([
|
|
2
3
|
['--api-key', true],
|
|
3
4
|
['--insecure-storage', false],
|
|
@@ -43,7 +44,7 @@ export async function runMigrations(args, apiKey, apiBaseUrl) {
|
|
|
43
44
|
process.env.WORKOS_API_URL = apiBaseUrl;
|
|
44
45
|
}
|
|
45
46
|
const { program } = (await import('@workos/migrations/dist/cli/index.js'));
|
|
46
|
-
program.name(
|
|
47
|
+
program.name(`${getWorkOSCommand()} migrations`);
|
|
47
48
|
await program.parseAsync(args, { from: 'user' });
|
|
48
49
|
}
|
|
49
50
|
//# sourceMappingURL=migrations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/commands/migrations.ts"],"names":[],"mappings":"AAAA,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IACxC,CAAC,WAAW,EAAE,IAAI,CAAC;IACnB,CAAC,oBAAoB,EAAE,KAAK,CAAC;IAC7B,CAAC,QAAQ,EAAE,KAAK,CAAC;IACjB,CAAC,QAAQ,EAAE,IAAI,CAAC;CACjB,CAAC,CAAC;AAEH,MAAM,UAAU,4BAA4B,CAAC,OAAiB;IAC5D,IAAI,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;YACzB,aAAa,GAAG,CAAC,CAAC;YAClB,MAAM;QACR,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,MAAe,EAAE,UAAmB;IACtF,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,MAAM,CAAC;IACzC,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAKxE,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/commands/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IACxC,CAAC,WAAW,EAAE,IAAI,CAAC;IACnB,CAAC,oBAAoB,EAAE,KAAK,CAAC;IAC7B,CAAC,QAAQ,EAAE,KAAK,CAAC;IACjB,CAAC,QAAQ,EAAE,IAAI,CAAC;CACjB,CAAC,CAAC;AAEH,MAAM,UAAU,4BAA4B,CAAC,OAAiB;IAC5D,IAAI,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;YACzB,aAAa,GAAG,CAAC,CAAC;YAClB,MAAM;QACR,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,MAAe,EAAE,UAAmB;IACtF,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,MAAM,CAAC;IACzC,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAKxE,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,EAAE,aAAa,CAAC,CAAC;IACjD,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACnD,CAAC","sourcesContent":["import { getWorkOSCommand } from '../utils/command-invocation.js';\n\nconst workosOnlyMigrationsFlags = new Map([\n ['--api-key', true],\n ['--insecure-storage', false],\n ['--json', false],\n ['--mode', true],\n]);\n\nexport function getMigrationsPassthroughArgs(rawArgs: string[]): string[] {\n let migrationsIdx = rawArgs.indexOf('migrations');\n\n for (let i = 0; i < rawArgs.length; i++) {\n const arg = rawArgs[i];\n const key = arg.split('=')[0];\n const takesValue = workosOnlyMigrationsFlags.get(key);\n\n if (takesValue !== undefined) {\n if (takesValue && !arg.includes('=')) i++;\n continue;\n }\n\n if (arg === 'migrations') {\n migrationsIdx = i;\n break;\n }\n }\n\n const after = rawArgs.slice(migrationsIdx + 1);\n const passthrough: string[] = [];\n\n for (let i = 0; i < after.length; i++) {\n const arg = after[i];\n const key = arg.split('=')[0];\n const takesValue = workosOnlyMigrationsFlags.get(key);\n\n if (takesValue !== undefined) {\n if (takesValue && !arg.includes('=')) i++;\n continue;\n }\n\n passthrough.push(arg);\n }\n\n return passthrough;\n}\n\nexport async function runMigrations(args: string[], apiKey?: string, apiBaseUrl?: string): Promise<void> {\n if (apiKey) {\n process.env.WORKOS_SECRET_KEY = apiKey;\n }\n if (apiBaseUrl) {\n process.env.WORKOS_API_URL = apiBaseUrl;\n }\n\n const { program } = (await import('@workos/migrations/dist/cli/index.js')) as {\n program: {\n name(str: string): unknown;\n parseAsync(argv: string[], options?: { from: 'user' }): Promise<unknown>;\n };\n };\n\n program.name(`${getWorkOSCommand()} migrations`);\n await program.parseAsync(args, { from: 'user' });\n}\n"]}
|
package/dist/commands/seed.js
CHANGED
|
@@ -3,6 +3,7 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { parse as parseYaml } from 'yaml';
|
|
4
4
|
import { createWorkOSClient } from '../lib/workos-client.js';
|
|
5
5
|
import { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';
|
|
6
|
+
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
6
7
|
const STATE_FILE = '.workos-seed-state.json';
|
|
7
8
|
function loadState() {
|
|
8
9
|
if (!existsSync(STATE_FILE))
|
|
@@ -69,7 +70,7 @@ export function runSeedInit() {
|
|
|
69
70
|
}
|
|
70
71
|
else {
|
|
71
72
|
console.log(chalk.green(`Created ${DEFAULT_SEED_FILE}`));
|
|
72
|
-
console.log(chalk.dim(
|
|
73
|
+
console.log(chalk.dim(`Edit the file, then run: ${formatWorkOSCommand('seed --file=workos-seed.yml')}`));
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
export async function runSeed(options, apiKey, baseUrl) {
|
|
@@ -84,13 +85,13 @@ export async function runSeed(options, apiKey, baseUrl) {
|
|
|
84
85
|
if (!options.file) {
|
|
85
86
|
return exitWithError({
|
|
86
87
|
code: 'missing_args',
|
|
87
|
-
message:
|
|
88
|
+
message: `Provide a seed file: ${formatWorkOSCommand('seed --file=workos-seed.yml')}\nRun ${formatWorkOSCommand('seed --init')} to create an example seed file.`,
|
|
88
89
|
});
|
|
89
90
|
}
|
|
90
91
|
if (!existsSync(options.file)) {
|
|
91
92
|
return exitWithError({
|
|
92
93
|
code: 'file_not_found',
|
|
93
|
-
message: `Seed file not found: ${options.file}. Create workos-seed.yml or run
|
|
94
|
+
message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \`${formatWorkOSCommand('seed')}\` without --file for interactive mode.`,
|
|
94
95
|
});
|
|
95
96
|
}
|
|
96
97
|
const raw = readFileSync(options.file, 'utf-8');
|
|
@@ -211,7 +212,7 @@ export async function runSeed(options, apiKey, baseUrl) {
|
|
|
211
212
|
saveState(state);
|
|
212
213
|
exitWithError({
|
|
213
214
|
code: 'seed_failed',
|
|
214
|
-
message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run
|
|
215
|
+
message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \`${formatWorkOSCommand('seed --clean')}\` to tear down.`,
|
|
215
216
|
details: state,
|
|
216
217
|
});
|
|
217
218
|
}
|