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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport chalk from 'chalk';\nimport { parse as parseYaml } from 'yaml';\nimport type { DomainData } from '@workos-inc/node';\nimport { createWorkOSClient, type WorkOSCLIClient } from '../lib/workos-client.js';\nimport { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';\n\nconst STATE_FILE = '.workos-seed-state.json';\n\ninterface SeedConfig {\n organizations?: Array<{ name: string; domains?: string[] }>;\n permissions?: Array<{ name: string; slug: string; description?: string }>;\n roles?: Array<{ name: string; slug: string; description?: string; permissions?: string[] }>;\n config?: {\n redirect_uris?: string[];\n cors_origins?: string[];\n homepage_url?: string;\n };\n}\n\ninterface SeedState {\n permissions: Array<{ slug: string }>;\n roles: Array<{ slug: string }>;\n organizations: Array<{ id: string; name: string }>;\n createdAt: string;\n}\n\nfunction loadState(): SeedState | null {\n if (!existsSync(STATE_FILE)) return null;\n try {\n return JSON.parse(readFileSync(STATE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction saveState(state: SeedState): void {\n writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));\n}\n\nconst DEFAULT_SEED_FILE = 'workos-seed.yml';\n\nconst SEED_TEMPLATE = `# WorkOS seed file — provision resources with \\`workos seed --file=${DEFAULT_SEED_FILE}\\`\n# Resources are created in dependency order: permissions → roles → organizations → config.\n# Existing resources are skipped (idempotent). Run \\`workos seed --clean\\` to tear down.\n\npermissions:\n - name: Read Posts\n slug: posts:read\n - name: Write Posts\n slug: posts:write\n description: Create and edit posts\n\nroles:\n - name: Admin\n slug: admin\n description: Full access\n permissions:\n - posts:read\n - posts:write\n - name: Viewer\n slug: viewer\n permissions:\n - posts:read\n\norganizations:\n - name: Acme Corp\n domains:\n - acme.com\n\nconfig:\n redirect_uris:\n - http://localhost:3000/auth/callback\n cors_origins:\n - http://localhost:3000\n homepage_url: http://localhost:3000\n`;\n\nexport function runSeedInit(): void {\n if (existsSync(DEFAULT_SEED_FILE)) {\n if (isJsonMode()) {\n outputJson({ status: 'exists', message: `${DEFAULT_SEED_FILE} already exists`, file: DEFAULT_SEED_FILE });\n } else {\n console.log(chalk.yellow(`${DEFAULT_SEED_FILE} already exists — not overwriting.`));\n }\n return;\n }\n\n writeFileSync(DEFAULT_SEED_FILE, SEED_TEMPLATE);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: `Created ${DEFAULT_SEED_FILE}`, file: DEFAULT_SEED_FILE });\n } else {\n console.log(chalk.green(`Created ${DEFAULT_SEED_FILE}`));\n console.log(chalk.dim('Edit the file, then run: workos seed --file=workos-seed.yml'));\n }\n}\n\nexport async function runSeed(\n options: { file?: string; clean?: boolean; init?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (options.init) {\n runSeedInit();\n return;\n }\n\n if (options.clean) {\n await runSeedClean(apiKey, baseUrl);\n return;\n }\n\n if (!options.file) {\n return exitWithError({\n code: 'missing_args',\n message:\n 'Provide a seed file: workos seed --file=workos-seed.yml\\nRun workos seed --init to create an example seed file.',\n });\n }\n\n if (!existsSync(options.file)) {\n return exitWithError({\n code: 'file_not_found',\n message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \\`workos seed\\` without --file for interactive mode.`,\n });\n }\n\n const raw = readFileSync(options.file, 'utf-8');\n let seedConfig: SeedConfig;\n try {\n seedConfig = parseYaml(raw) as SeedConfig;\n } catch (error) {\n exitWithError({\n code: 'invalid_yaml',\n message: `Failed to parse seed file: ${error instanceof Error ? error.message : 'Invalid YAML'}`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n const state: SeedState = { permissions: [], roles: [], organizations: [], createdAt: new Date().toISOString() };\n\n try {\n // 1. Create permissions\n if (seedConfig.permissions) {\n for (const perm of seedConfig.permissions) {\n try {\n await client.sdk.authorization.createPermission({\n slug: perm.slug,\n name: perm.name,\n ...(perm.description && { description: perm.description }),\n });\n state.permissions.push({ slug: perm.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created permission: ${perm.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Permission exists: ${perm.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 2. Create roles + assign permissions\n if (seedConfig.roles) {\n for (const role of seedConfig.roles) {\n try {\n await client.sdk.authorization.createEnvironmentRole({\n slug: role.slug,\n name: role.name,\n ...(role.description && { description: role.description }),\n });\n state.roles.push({ slug: role.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created role: ${role.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Role exists: ${role.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n\n if (role.permissions?.length) {\n try {\n await client.sdk.authorization.setEnvironmentRolePermissions(role.slug, {\n permissions: role.permissions,\n });\n if (!isJsonMode())\n console.log(chalk.green(` Set permissions on ${role.slug}: ${role.permissions.join(', ')}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Failed to set permissions on ${role.slug}`));\n }\n }\n }\n }\n\n // 3. Create organizations\n if (seedConfig.organizations) {\n for (const org of seedConfig.organizations) {\n try {\n const created = await client.sdk.organizations.createOrganization({\n name: org.name,\n ...(org.domains?.length && {\n domainData: org.domains.map((d) => ({ domain: d, state: 'verified' as DomainData['state'] })),\n }),\n });\n state.organizations.push({ id: created.id, name: created.name });\n if (!isJsonMode()) console.log(chalk.green(` Created org: ${created.name} (${created.id})`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Org may exist: ${org.name} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 4. Configure redirect URIs, CORS, homepage\n if (seedConfig.config) {\n await applyConfig(client, seedConfig.config);\n }\n\n saveState(state);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: 'Seed complete', state });\n } else {\n console.log(chalk.green('\\nSeed complete.'));\n console.log(chalk.dim(`State saved to ${STATE_FILE}`));\n }\n } catch (error) {\n // Partial failure — save what was created so --clean can tear down\n saveState(state);\n exitWithError({\n code: 'seed_failed',\n message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \\`workos seed --clean\\` to tear down.`,\n details: state,\n });\n }\n}\n\nasync function runSeedClean(apiKey: string, baseUrl?: string): Promise<void> {\n const state = loadState();\n if (!state) {\n return exitWithError({\n code: 'no_state',\n message: `No seed state found (${STATE_FILE}). Nothing to clean.`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n // Delete in reverse order: orgs → roles → permissions\n for (const org of state.organizations.reverse()) {\n try {\n await client.sdk.organizations.deleteOrganization(org.id);\n if (!isJsonMode()) console.log(chalk.green(` Deleted org: ${org.name} (${org.id})`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete org ${org.id}`));\n }\n }\n\n for (const role of state.roles.reverse()) {\n try {\n // Env roles can't be deleted via SDK — skip silently\n if (!isJsonMode()) console.log(chalk.dim(` Env role ${role.slug}: skipped (env roles cannot be deleted)`));\n } catch {\n // ignore\n }\n }\n\n for (const perm of state.permissions.reverse()) {\n try {\n await client.sdk.authorization.deletePermission(perm.slug);\n if (!isJsonMode()) console.log(chalk.green(` Deleted permission: ${perm.slug}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete permission ${perm.slug}`));\n }\n }\n\n unlinkSync(STATE_FILE);\n outputSuccess('Seed cleanup complete', { stateFile: STATE_FILE });\n}\n\nasync function applyConfig(client: WorkOSCLIClient, config: NonNullable<SeedConfig['config']>): Promise<void> {\n if (config.redirect_uris) {\n for (const uri of config.redirect_uris) {\n const result = await client.redirectUris.add(uri);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` Redirect URI exists: ${uri}`)\n : chalk.green(` Added redirect URI: ${uri}`),\n );\n }\n }\n }\n\n if (config.cors_origins) {\n for (const origin of config.cors_origins) {\n const result = await client.corsOrigins.add(origin);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` CORS origin exists: ${origin}`)\n : chalk.green(` Added CORS origin: ${origin}`),\n );\n }\n }\n }\n\n if (config.homepage_url) {\n await client.homepageUrl.set(config.homepage_url);\n if (!isJsonMode()) console.log(chalk.green(` Set homepage URL: ${config.homepage_url}`));\n }\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n return msg.includes('already exists') || msg.includes('conflict') || msg.includes('duplicate');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAwB,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,MAAM,UAAU,GAAG,yBAAyB,CAAC;AAoB7C,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB;IACjC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C,MAAM,aAAa,GAAG,sEAAsE,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkC5G,CAAC;AAEF,MAAM,UAAU,WAAW;IACzB,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClC,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,iBAAiB,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC5G,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,iBAAiB,oCAAoC,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,OAAO;IACT,CAAC;IAED,aAAa,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;IAEhD,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,iBAAiB,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACjG,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,iBAAiB,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,mBAAmB,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3G,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAA2D,EAC3D,MAAc,EACd,OAAgB;IAEhB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,WAAW,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;YACnB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,wBAAwB,mBAAmB,CAAC,6BAA6B,CAAC,SAAS,mBAAmB,CAAC,aAAa,CAAC,kCAAkC;SACjK,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,aAAa,CAAC;YACnB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,wBAAwB,OAAO,CAAC,IAAI,qCAAqC,mBAAmB,CAAC,MAAM,CAAC,yCAAyC;SACvJ,CAAC,CAAC;IACL,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,UAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,UAAU,GAAG,SAAS,CAAC,GAAG,CAAe,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,CAAC;YACZ,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,8BAA8B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE;SACjG,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,KAAK,GAAc,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAEhH,IAAI,CAAC;QACH,wBAAwB;QACxB,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;gBAC1C,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,gBAAgB,CAAC;wBAC9C,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;qBAC3D,CAAC,CAAC;oBACH,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC5C,IAAI,CAAC,UAAU,EAAE;wBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACpF,CAAC;gBAAC,OAAO,KAAc,EAAE,CAAC;oBACxB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,UAAU,EAAE;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;oBAC3F,CAAC;yBAAM,CAAC;wBACN,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,qBAAqB,CAAC;wBACnD,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;qBAC3D,CAAC,CAAC;oBACH,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBACtC,IAAI,CAAC,UAAU,EAAE;wBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC9E,CAAC;gBAAC,OAAO,KAAc,EAAE,CAAC;oBACxB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,UAAU,EAAE;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;oBACrF,CAAC;yBAAM,CAAC;wBACN,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;gBAED,IAAI,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;oBAC7B,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI,EAAE;4BACtE,WAAW,EAAE,IAAI,CAAC,WAAW;yBAC9B,CAAC,CAAC;wBACH,IAAI,CAAC,UAAU,EAAE;4BACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;oBAClG,CAAC;oBAAC,MAAM,CAAC;wBACP,IAAI,CAAC,UAAU,EAAE;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2CAA2C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBACvG,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,UAAU,CAAC,aAAa,EAAE,CAAC;YAC7B,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,aAAa,EAAE,CAAC;gBAC3C,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,kBAAkB,CAAC;wBAChE,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI;4BACzB,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,UAAiC,EAAE,CAAC,CAAC;yBAC9F,CAAC;qBACH,CAAC,CAAC;oBACH,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;oBACjE,IAAI,CAAC,UAAU,EAAE;wBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;gBAChG,CAAC;gBAAC,OAAO,KAAc,EAAE,CAAC;oBACxB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,UAAU,EAAE;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;oBACtF,CAAC;yBAAM,CAAC;wBACN,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC;QAED,SAAS,CAAC,KAAK,CAAC,CAAC;QAEjB,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,UAAU,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mEAAmE;QACnE,SAAS,CAAC,KAAK,CAAC,CAAC;QACjB,aAAa,CAAC;YACZ,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,4BAA4B,UAAU,WAAW,mBAAmB,CAAC,cAAc,CAAC,kBAAkB;YACvL,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,OAAgB;IAC1D,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,aAAa,CAAC;YACnB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,wBAAwB,UAAU,sBAAsB;SAClE,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnD,sDAAsD;IACtD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,UAAU,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mCAAmC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,qDAAqD;YACrD,IAAI,CAAC,UAAU,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,IAAI,yCAAyC,CAAC,CAAC,CAAC;QAC9G,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,UAAU,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,UAAU,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAED,UAAU,CAAC,UAAU,CAAC,CAAC;IACvB,aAAa,CAAC,uBAAuB,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAuB,EAAE,MAAyC;IAC3F,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,aAAa;oBAClB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,GAAG,EAAE,CAAC;oBAC5C,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAChD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,aAAa;oBAClB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,MAAM,EAAE,CAAC;oBAC9C,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAClD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,EAAE;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACjG,CAAC","sourcesContent":["import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport chalk from 'chalk';\nimport { parse as parseYaml } from 'yaml';\nimport type { DomainData } from '@workos-inc/node';\nimport { createWorkOSClient, type WorkOSCLIClient } from '../lib/workos-client.js';\nimport { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nconst STATE_FILE = '.workos-seed-state.json';\n\ninterface SeedConfig {\n organizations?: Array<{ name: string; domains?: string[] }>;\n permissions?: Array<{ name: string; slug: string; description?: string }>;\n roles?: Array<{ name: string; slug: string; description?: string; permissions?: string[] }>;\n config?: {\n redirect_uris?: string[];\n cors_origins?: string[];\n homepage_url?: string;\n };\n}\n\ninterface SeedState {\n permissions: Array<{ slug: string }>;\n roles: Array<{ slug: string }>;\n organizations: Array<{ id: string; name: string }>;\n createdAt: string;\n}\n\nfunction loadState(): SeedState | null {\n if (!existsSync(STATE_FILE)) return null;\n try {\n return JSON.parse(readFileSync(STATE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction saveState(state: SeedState): void {\n writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));\n}\n\nconst DEFAULT_SEED_FILE = 'workos-seed.yml';\n\nconst SEED_TEMPLATE = `# WorkOS seed file — provision resources with \\`workos seed --file=${DEFAULT_SEED_FILE}\\`\n# Resources are created in dependency order: permissions → roles → organizations → config.\n# Existing resources are skipped (idempotent). Run \\`workos seed --clean\\` to tear down.\n\npermissions:\n - name: Read Posts\n slug: posts:read\n - name: Write Posts\n slug: posts:write\n description: Create and edit posts\n\nroles:\n - name: Admin\n slug: admin\n description: Full access\n permissions:\n - posts:read\n - posts:write\n - name: Viewer\n slug: viewer\n permissions:\n - posts:read\n\norganizations:\n - name: Acme Corp\n domains:\n - acme.com\n\nconfig:\n redirect_uris:\n - http://localhost:3000/auth/callback\n cors_origins:\n - http://localhost:3000\n homepage_url: http://localhost:3000\n`;\n\nexport function runSeedInit(): void {\n if (existsSync(DEFAULT_SEED_FILE)) {\n if (isJsonMode()) {\n outputJson({ status: 'exists', message: `${DEFAULT_SEED_FILE} already exists`, file: DEFAULT_SEED_FILE });\n } else {\n console.log(chalk.yellow(`${DEFAULT_SEED_FILE} already exists — not overwriting.`));\n }\n return;\n }\n\n writeFileSync(DEFAULT_SEED_FILE, SEED_TEMPLATE);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: `Created ${DEFAULT_SEED_FILE}`, file: DEFAULT_SEED_FILE });\n } else {\n console.log(chalk.green(`Created ${DEFAULT_SEED_FILE}`));\n console.log(chalk.dim(`Edit the file, then run: ${formatWorkOSCommand('seed --file=workos-seed.yml')}`));\n }\n}\n\nexport async function runSeed(\n options: { file?: string; clean?: boolean; init?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (options.init) {\n runSeedInit();\n return;\n }\n\n if (options.clean) {\n await runSeedClean(apiKey, baseUrl);\n return;\n }\n\n if (!options.file) {\n return exitWithError({\n code: 'missing_args',\n message: `Provide a seed file: ${formatWorkOSCommand('seed --file=workos-seed.yml')}\\nRun ${formatWorkOSCommand('seed --init')} to create an example seed file.`,\n });\n }\n\n if (!existsSync(options.file)) {\n return exitWithError({\n code: 'file_not_found',\n message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \\`${formatWorkOSCommand('seed')}\\` without --file for interactive mode.`,\n });\n }\n\n const raw = readFileSync(options.file, 'utf-8');\n let seedConfig: SeedConfig;\n try {\n seedConfig = parseYaml(raw) as SeedConfig;\n } catch (error) {\n exitWithError({\n code: 'invalid_yaml',\n message: `Failed to parse seed file: ${error instanceof Error ? error.message : 'Invalid YAML'}`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n const state: SeedState = { permissions: [], roles: [], organizations: [], createdAt: new Date().toISOString() };\n\n try {\n // 1. Create permissions\n if (seedConfig.permissions) {\n for (const perm of seedConfig.permissions) {\n try {\n await client.sdk.authorization.createPermission({\n slug: perm.slug,\n name: perm.name,\n ...(perm.description && { description: perm.description }),\n });\n state.permissions.push({ slug: perm.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created permission: ${perm.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Permission exists: ${perm.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 2. Create roles + assign permissions\n if (seedConfig.roles) {\n for (const role of seedConfig.roles) {\n try {\n await client.sdk.authorization.createEnvironmentRole({\n slug: role.slug,\n name: role.name,\n ...(role.description && { description: role.description }),\n });\n state.roles.push({ slug: role.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created role: ${role.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Role exists: ${role.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n\n if (role.permissions?.length) {\n try {\n await client.sdk.authorization.setEnvironmentRolePermissions(role.slug, {\n permissions: role.permissions,\n });\n if (!isJsonMode())\n console.log(chalk.green(` Set permissions on ${role.slug}: ${role.permissions.join(', ')}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Failed to set permissions on ${role.slug}`));\n }\n }\n }\n }\n\n // 3. Create organizations\n if (seedConfig.organizations) {\n for (const org of seedConfig.organizations) {\n try {\n const created = await client.sdk.organizations.createOrganization({\n name: org.name,\n ...(org.domains?.length && {\n domainData: org.domains.map((d) => ({ domain: d, state: 'verified' as DomainData['state'] })),\n }),\n });\n state.organizations.push({ id: created.id, name: created.name });\n if (!isJsonMode()) console.log(chalk.green(` Created org: ${created.name} (${created.id})`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Org may exist: ${org.name} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 4. Configure redirect URIs, CORS, homepage\n if (seedConfig.config) {\n await applyConfig(client, seedConfig.config);\n }\n\n saveState(state);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: 'Seed complete', state });\n } else {\n console.log(chalk.green('\\nSeed complete.'));\n console.log(chalk.dim(`State saved to ${STATE_FILE}`));\n }\n } catch (error) {\n // Partial failure — save what was created so --clean can tear down\n saveState(state);\n exitWithError({\n code: 'seed_failed',\n message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \\`${formatWorkOSCommand('seed --clean')}\\` to tear down.`,\n details: state,\n });\n }\n}\n\nasync function runSeedClean(apiKey: string, baseUrl?: string): Promise<void> {\n const state = loadState();\n if (!state) {\n return exitWithError({\n code: 'no_state',\n message: `No seed state found (${STATE_FILE}). Nothing to clean.`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n // Delete in reverse order: orgs → roles → permissions\n for (const org of state.organizations.reverse()) {\n try {\n await client.sdk.organizations.deleteOrganization(org.id);\n if (!isJsonMode()) console.log(chalk.green(` Deleted org: ${org.name} (${org.id})`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete org ${org.id}`));\n }\n }\n\n for (const role of state.roles.reverse()) {\n try {\n // Env roles can't be deleted via SDK — skip silently\n if (!isJsonMode()) console.log(chalk.dim(` Env role ${role.slug}: skipped (env roles cannot be deleted)`));\n } catch {\n // ignore\n }\n }\n\n for (const perm of state.permissions.reverse()) {\n try {\n await client.sdk.authorization.deletePermission(perm.slug);\n if (!isJsonMode()) console.log(chalk.green(` Deleted permission: ${perm.slug}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete permission ${perm.slug}`));\n }\n }\n\n unlinkSync(STATE_FILE);\n outputSuccess('Seed cleanup complete', { stateFile: STATE_FILE });\n}\n\nasync function applyConfig(client: WorkOSCLIClient, config: NonNullable<SeedConfig['config']>): Promise<void> {\n if (config.redirect_uris) {\n for (const uri of config.redirect_uris) {\n const result = await client.redirectUris.add(uri);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` Redirect URI exists: ${uri}`)\n : chalk.green(` Added redirect URI: ${uri}`),\n );\n }\n }\n }\n\n if (config.cors_origins) {\n for (const origin of config.cors_origins) {\n const result = await client.corsOrigins.add(origin);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` CORS origin exists: ${origin}`)\n : chalk.green(` Added CORS origin: ${origin}`),\n );\n }\n }\n }\n\n if (config.homepage_url) {\n await client.homepageUrl.set(config.homepage_url);\n if (!isJsonMode()) console.log(chalk.green(` Set homepage URL: ${config.homepage_url}`));\n }\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n return msg.includes('already exists') || msg.includes('conflict') || msg.includes('duplicate');\n}\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `workos setup` — the consolidated, consented agent-setup moment.
|
|
3
|
+
*
|
|
4
|
+
* Owns BOTH surfaces that used to nag independently:
|
|
5
|
+
* - skills auto-install (previously silent + unconditional on login/install)
|
|
6
|
+
* - the MCP server offer (previously a separate prompt at end of `install`)
|
|
7
|
+
*
|
|
8
|
+
* One prompt, one place. It is called three ways:
|
|
9
|
+
* - trigger 'login' / 'install' → `maybeRunSetupAfter`, a best-effort hook that
|
|
10
|
+
* can never block or fail the parent flow, gated so it stays silent in
|
|
11
|
+
* agent/CI/non-TTY/JSON and never re-asks after a decline or completion.
|
|
12
|
+
* - trigger 'command' → the top-level `workos setup`, always runnable, with
|
|
13
|
+
* flags for granular / non-interactive use.
|
|
14
|
+
*
|
|
15
|
+
* The consent contract is the whole point: nothing is written to a coding agent
|
|
16
|
+
* unless the user says yes (or passes --yes). This replaces the auto-install
|
|
17
|
+
* that a customer called "prompt injection malware".
|
|
18
|
+
*/
|
|
19
|
+
export type SetupTrigger = 'login' | 'install' | 'command';
|
|
20
|
+
export interface RunSetupOptions {
|
|
21
|
+
trigger: SetupTrigger;
|
|
22
|
+
/** Restrict to specific agent keys (e.g. claude-code, cursor). */
|
|
23
|
+
agents?: string[];
|
|
24
|
+
skillsOnly?: boolean;
|
|
25
|
+
mcpOnly?: boolean;
|
|
26
|
+
/** Skip the confirm and install directly (for non-interactive `workos setup --yes`). */
|
|
27
|
+
assumeYes?: boolean;
|
|
28
|
+
/** Clear a prior decline so automatic offers resume, then return. */
|
|
29
|
+
reset?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Run the consolidated setup flow. Behavior branches on `trigger`:
|
|
33
|
+
* - automatic (login/install): self-gates on mode + decline/complete, prompts,
|
|
34
|
+
* records an absolute decline on "no".
|
|
35
|
+
* - command: always runs; a "no" does NOT record a permanent decline.
|
|
36
|
+
*/
|
|
37
|
+
export declare function runSetup(opts: RunSetupOptions): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Best-effort setup offer after a successful `login` / `install`.
|
|
40
|
+
*
|
|
41
|
+
* Never throws into, wedges, or fails the parent flow — a try/catch swallows any
|
|
42
|
+
* error. The offer is only ever shown to a present human in an interactive TTY
|
|
43
|
+
* (runSetup early-returns in every machine/non-interactive context), so the
|
|
44
|
+
* confirm is NOT time-bounded: a question that auto-dismisses while the user is
|
|
45
|
+
* reading it is exactly the "it asked but moved on" bug. @inquirer already
|
|
46
|
+
* handles ctrl-c, and detection/install are internally time-bounded, so there is
|
|
47
|
+
* nothing left to race. The parent flow has already succeeded by the time this
|
|
48
|
+
* runs. Any failure is reported to telemetry before being swallowed.
|
|
49
|
+
*/
|
|
50
|
+
export declare function maybeRunSetupAfter(trigger: 'login' | 'install'): Promise<void>;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `workos setup` — the consolidated, consented agent-setup moment.
|
|
3
|
+
*
|
|
4
|
+
* Owns BOTH surfaces that used to nag independently:
|
|
5
|
+
* - skills auto-install (previously silent + unconditional on login/install)
|
|
6
|
+
* - the MCP server offer (previously a separate prompt at end of `install`)
|
|
7
|
+
*
|
|
8
|
+
* One prompt, one place. It is called three ways:
|
|
9
|
+
* - trigger 'login' / 'install' → `maybeRunSetupAfter`, a best-effort hook that
|
|
10
|
+
* can never block or fail the parent flow, gated so it stays silent in
|
|
11
|
+
* agent/CI/non-TTY/JSON and never re-asks after a decline or completion.
|
|
12
|
+
* - trigger 'command' → the top-level `workos setup`, always runnable, with
|
|
13
|
+
* flags for granular / non-interactive use.
|
|
14
|
+
*
|
|
15
|
+
* The consent contract is the whole point: nothing is written to a coding agent
|
|
16
|
+
* unless the user says yes (or passes --yes). This replaces the auto-install
|
|
17
|
+
* that a customer called "prompt injection malware".
|
|
18
|
+
*/
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import ui, { isCancel } from '../utils/ui.js';
|
|
21
|
+
import { outputSuccess, exitWithError, isJsonMode } from '../utils/output.js';
|
|
22
|
+
import { ExitCode, exitWithCode } from '../utils/exit-codes.js';
|
|
23
|
+
import { CliExit } from '../utils/cli-exit.js';
|
|
24
|
+
import { isPromptAllowed } from '../utils/interaction-mode.js';
|
|
25
|
+
import { isSetupDeclined, isSetupCompleted, recordSetupDeclined, recordSetupCompleted, clearSetupDecline, } from '../lib/preferences.js';
|
|
26
|
+
import { createAgents, detectAgents, refreshWorkOSSkills } from './install-skill.js';
|
|
27
|
+
import { detectMcpClients, MCP_AGENT_KEYS, MCP_OUTCOME_LABELS, } from '../lib/mcp-clients.js';
|
|
28
|
+
import { analytics } from '../utils/analytics.js';
|
|
29
|
+
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
30
|
+
/** Validate an --agents filter against the known keys; exit with a structured error on unknown. */
|
|
31
|
+
function validateAgentFilter(agents, known) {
|
|
32
|
+
if (!agents || agents.length === 0)
|
|
33
|
+
return undefined;
|
|
34
|
+
const unknown = agents.filter((a) => !known.includes(a));
|
|
35
|
+
if (unknown.length > 0) {
|
|
36
|
+
exitWithError({
|
|
37
|
+
code: 'unknown_agent',
|
|
38
|
+
message: `Unknown agent(s): ${unknown.join(', ')}. Supported: ${known.join(', ')}.`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return agents;
|
|
42
|
+
}
|
|
43
|
+
/** Distinct display names across skill agents + MCP targets, for the offer copy. */
|
|
44
|
+
function detectedNames(skillAgents, mcpTargets) {
|
|
45
|
+
return Array.from(new Set([...skillAgents.map((a) => a.displayName), ...mcpTargets.map((t) => t.displayName)]));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run the consolidated setup flow. Behavior branches on `trigger`:
|
|
49
|
+
* - automatic (login/install): self-gates on mode + decline/complete, prompts,
|
|
50
|
+
* records an absolute decline on "no".
|
|
51
|
+
* - command: always runs; a "no" does NOT record a permanent decline.
|
|
52
|
+
*/
|
|
53
|
+
export async function runSetup(opts) {
|
|
54
|
+
if (opts.reset) {
|
|
55
|
+
clearSetupDecline();
|
|
56
|
+
if (isJsonMode()) {
|
|
57
|
+
outputSuccess('Setup offers re-enabled', { reset: true });
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
ui.log.success(`Setup offers re-enabled. Run \`${formatWorkOSCommand('setup')}\` to configure your agents.`);
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const isCommand = opts.trigger === 'command';
|
|
65
|
+
const agents = createAgents(homedir()); // cheap (path construction, no IO); built once
|
|
66
|
+
const agentFilter = isCommand
|
|
67
|
+
? validateAgentFilter(opts.agents, [...Object.keys(agents), ...MCP_AGENT_KEYS])
|
|
68
|
+
: opts.agents;
|
|
69
|
+
// Gate BEFORE any agent detection — detectMcpClients shells out to `claude mcp
|
|
70
|
+
// list` etc., so a machine / declined / completed run must pay nothing.
|
|
71
|
+
if (!isCommand) {
|
|
72
|
+
// Automatic (login/install): silent in machine/non-interactive contexts, and
|
|
73
|
+
// never after a decline or a prior completion.
|
|
74
|
+
if (isJsonMode() || !isPromptAllowed())
|
|
75
|
+
return;
|
|
76
|
+
if (isSetupDeclined() || isSetupCompleted())
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
else if ((!isPromptAllowed() || isJsonMode()) && !opts.assumeYes) {
|
|
80
|
+
// Explicit `workos setup` can't prompt in a non-interactive context, nor
|
|
81
|
+
// under --json — output mode is JSON while interaction mode stays human, so
|
|
82
|
+
// isPromptAllowed() is still true and a confirm would pollute the
|
|
83
|
+
// machine-readable stdout stream. Require --yes in both cases.
|
|
84
|
+
exitWithError({
|
|
85
|
+
code: 'confirmation_required',
|
|
86
|
+
message: `Setup can't prompt here (non-interactive or --json). Re-run \`${formatWorkOSCommand('setup --yes')}\` to install without a prompt.`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const wantSkills = !opts.mcpOnly;
|
|
90
|
+
const wantMcp = !opts.skillsOnly;
|
|
91
|
+
const skillAgents = wantSkills ? detectAgents(agents, agentFilter) : [];
|
|
92
|
+
const mcpTargets = wantMcp ? await detectMcpClients(agentFilter) : [];
|
|
93
|
+
const names = detectedNames(skillAgents, mcpTargets);
|
|
94
|
+
// Nothing to install to. Surface it only for an explicit invocation.
|
|
95
|
+
if (names.length === 0) {
|
|
96
|
+
if (isCommand) {
|
|
97
|
+
if (isJsonMode()) {
|
|
98
|
+
outputSuccess('No supported coding agents detected', { agents: [] });
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
ui.log.info('No supported coding agents detected (looked for Claude Code, Codex, Cursor, Goose).');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const startedAt = Date.now();
|
|
107
|
+
// The offer.
|
|
108
|
+
if (!opts.assumeYes) {
|
|
109
|
+
ui.heading('Set up your coding agent');
|
|
110
|
+
const what = wantSkills && wantMcp ? 'WorkOS skills and the MCP server' : wantMcp ? 'the WorkOS MCP server' : 'WorkOS skills';
|
|
111
|
+
ui.note(`Add ${what} to ${names.join(', ')} so your coding agent can\n` +
|
|
112
|
+
`scaffold auth and manage WorkOS resources. Nothing is written until you confirm.`);
|
|
113
|
+
const answer = await ui.confirm({ message: 'Set up now?', initialValue: true });
|
|
114
|
+
// Cancel (ctrl-c) is not a decline — skip silently and ask again next time,
|
|
115
|
+
// but record it so the cut-off is observable in telemetry.
|
|
116
|
+
if (isCancel(answer)) {
|
|
117
|
+
emitSetupEvent(opts.trigger, startedAt, 'cancelled', { skills: [], mcpInstalled: [], mcpFailed: [] });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (!answer) {
|
|
121
|
+
if (!isCommand)
|
|
122
|
+
recordSetupDeclined();
|
|
123
|
+
emitSetupEvent(opts.trigger, startedAt, 'declined', { skills: [], mcpInstalled: [], mcpFailed: [] });
|
|
124
|
+
ui.log.hint(`No problem. Run \`${formatWorkOSCommand('setup')}\` anytime.`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Install.
|
|
129
|
+
await installAndReport(opts, skillAgents, mcpTargets, startedAt);
|
|
130
|
+
}
|
|
131
|
+
async function installAndReport(opts, skillAgents, mcpTargets, startedAt) {
|
|
132
|
+
// Skills (local fs) and MCP (shell-outs to `claude mcp add` etc., which can
|
|
133
|
+
// each block toward a 10s timeout) are independent — run them concurrently,
|
|
134
|
+
// and run the per-agent MCP adds in parallel too. Empty inputs (skillsOnly /
|
|
135
|
+
// mcpOnly) resolve to null / [] without work. `target.add()` never rejects.
|
|
136
|
+
const [skillResult, mcpResults] = await Promise.all([
|
|
137
|
+
skillAgents.length > 0 ? refreshWorkOSSkills({ agents: skillAgents }) : Promise.resolve(null),
|
|
138
|
+
Promise.all(mcpTargets.map((target) => target.add())),
|
|
139
|
+
]);
|
|
140
|
+
const skillAgentNames = skillResult?.agents.map((a) => a.displayName) ?? [];
|
|
141
|
+
const mcpInstalled = mcpResults
|
|
142
|
+
.filter((r) => r.outcome === 'installed' || r.outcome === 'already-installed')
|
|
143
|
+
.map((r) => r.agent);
|
|
144
|
+
const failedResults = mcpResults.filter((r) => r.outcome === 'failed');
|
|
145
|
+
const mcpFailed = failedResults.map((r) => r.agent);
|
|
146
|
+
// Carry a bounded, agent-tagged reason so the MCP-install failure CAUSE (not
|
|
147
|
+
// just the count) is observable in telemetry. Already user-safe — the same
|
|
148
|
+
// text is shown via ui.log.error.
|
|
149
|
+
const mcpFailedReasons = failedResults.map((r) => `${r.agent}:${(r.error ?? '').slice(0, 120)}`).join('; ');
|
|
150
|
+
// Only mark setup complete when something actually landed. A run where every
|
|
151
|
+
// attempted install failed (e.g. transient `claude mcp add` timeouts, with no
|
|
152
|
+
// skills to fall back on) must NOT be treated as done: isSetupCompleted()
|
|
153
|
+
// suppresses every future automatic offer, so persisting completion here would
|
|
154
|
+
// strand the user after a transient failure. Leave the pref unset so the next
|
|
155
|
+
// login/install re-offers.
|
|
156
|
+
if (skillAgentNames.length > 0 || mcpInstalled.length > 0) {
|
|
157
|
+
recordSetupCompleted();
|
|
158
|
+
}
|
|
159
|
+
emitSetupEvent(opts.trigger, startedAt, 'accepted', {
|
|
160
|
+
skills: skillResult?.agents.map((a) => a.name) ?? [],
|
|
161
|
+
mcpInstalled,
|
|
162
|
+
mcpFailed,
|
|
163
|
+
mcpFailedReasons,
|
|
164
|
+
});
|
|
165
|
+
reportResults(skillResult ? { agents: skillAgentNames, count: skillResult.skills.length } : null, mcpResults);
|
|
166
|
+
}
|
|
167
|
+
/** Emit the outcome in both output modes; exit non-zero if any MCP install failed. */
|
|
168
|
+
function reportResults(skills, mcp) {
|
|
169
|
+
if (isJsonMode()) {
|
|
170
|
+
outputSuccess('Setup complete', { skills, mcp });
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
if (skills && skills.agents.length > 0) {
|
|
174
|
+
const word = skills.count === 1 ? 'skill' : 'skills';
|
|
175
|
+
ui.log.success(`${skills.count} ${word} installed for ${skills.agents.join(', ')}`);
|
|
176
|
+
}
|
|
177
|
+
for (const r of mcp) {
|
|
178
|
+
const line = `MCP server: ${r.displayName} — ${MCP_OUTCOME_LABELS[r.outcome]}`;
|
|
179
|
+
if (r.outcome === 'failed') {
|
|
180
|
+
ui.log.error(r.error ? `${line} (${r.error})` : line);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
ui.log.success(line);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (mcp.some((r) => r.outcome === 'installed' || r.outcome === 'already-installed')) {
|
|
187
|
+
ui.log.hint('Your agent will authorize WorkOS via OAuth on first MCP use.');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (mcp.some((r) => r.outcome === 'failed')) {
|
|
191
|
+
exitWithCode(ExitCode.GENERAL_ERROR);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function emitSetupEvent(trigger, startedAt, outcome, agents) {
|
|
195
|
+
analytics.emitCommandEvent('setup offer', Date.now() - startedAt, agents.mcpFailed.length === 0, {
|
|
196
|
+
extraAttributes: {
|
|
197
|
+
'setup.trigger': trigger,
|
|
198
|
+
// `accepted` kept for back-compat dashboards; `outcome` distinguishes a
|
|
199
|
+
// deliberate "no" (declined) from a walk-away/ctrl-c (cancelled).
|
|
200
|
+
'setup.accepted': outcome === 'accepted',
|
|
201
|
+
'setup.outcome': outcome,
|
|
202
|
+
'setup.skills_agents': agents.skills.join(','),
|
|
203
|
+
'setup.mcp_installed': agents.mcpInstalled.join(','),
|
|
204
|
+
'setup.mcp_failed': agents.mcpFailed.join(','),
|
|
205
|
+
...(agents.mcpFailedReasons ? { 'setup.mcp_failed_reasons': agents.mcpFailedReasons } : {}),
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Best-effort setup offer after a successful `login` / `install`.
|
|
211
|
+
*
|
|
212
|
+
* Never throws into, wedges, or fails the parent flow — a try/catch swallows any
|
|
213
|
+
* error. The offer is only ever shown to a present human in an interactive TTY
|
|
214
|
+
* (runSetup early-returns in every machine/non-interactive context), so the
|
|
215
|
+
* confirm is NOT time-bounded: a question that auto-dismisses while the user is
|
|
216
|
+
* reading it is exactly the "it asked but moved on" bug. @inquirer already
|
|
217
|
+
* handles ctrl-c, and detection/install are internally time-bounded, so there is
|
|
218
|
+
* nothing left to race. The parent flow has already succeeded by the time this
|
|
219
|
+
* runs. Any failure is reported to telemetry before being swallowed.
|
|
220
|
+
*/
|
|
221
|
+
export async function maybeRunSetupAfter(trigger) {
|
|
222
|
+
try {
|
|
223
|
+
await runSetup({ trigger });
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
// reportResults exits non-zero via CliExit on a failed MCP add — that's an
|
|
227
|
+
// intentional exit for the standalone command, not an exception to report
|
|
228
|
+
// (and it stays swallowed here so it never fails the parent login/install).
|
|
229
|
+
if (error instanceof CliExit)
|
|
230
|
+
return;
|
|
231
|
+
// Setup must never fail or block login / install — but don't drop the signal.
|
|
232
|
+
analytics.captureException(error instanceof Error ? error : new Error(String(error)), {
|
|
233
|
+
'setup.trigger': trigger,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `workos setup` — the consolidated, consented agent-setup moment.\n *\n * Owns BOTH surfaces that used to nag independently:\n * - skills auto-install (previously silent + unconditional on login/install)\n * - the MCP server offer (previously a separate prompt at end of `install`)\n *\n * One prompt, one place. It is called three ways:\n * - trigger 'login' / 'install' → `maybeRunSetupAfter`, a best-effort hook that\n * can never block or fail the parent flow, gated so it stays silent in\n * agent/CI/non-TTY/JSON and never re-asks after a decline or completion.\n * - trigger 'command' → the top-level `workos setup`, always runnable, with\n * flags for granular / non-interactive use.\n *\n * The consent contract is the whole point: nothing is written to a coding agent\n * unless the user says yes (or passes --yes). This replaces the auto-install\n * that a customer called \"prompt injection malware\".\n */\n\nimport { homedir } from 'node:os';\nimport ui, { isCancel } from '../utils/ui.js';\nimport { outputSuccess, exitWithError, isJsonMode } from '../utils/output.js';\nimport { ExitCode, exitWithCode } from '../utils/exit-codes.js';\nimport { CliExit } from '../utils/cli-exit.js';\nimport { isPromptAllowed } from '../utils/interaction-mode.js';\nimport {\n isSetupDeclined,\n isSetupCompleted,\n recordSetupDeclined,\n recordSetupCompleted,\n clearSetupDecline,\n} from '../lib/preferences.js';\nimport { createAgents, detectAgents, refreshWorkOSSkills, type AgentConfig } from './install-skill.js';\nimport {\n detectMcpClients,\n MCP_AGENT_KEYS,\n MCP_OUTCOME_LABELS,\n type McpClientResult,\n type McpClientTarget,\n} from '../lib/mcp-clients.js';\nimport { analytics } from '../utils/analytics.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nexport type SetupTrigger = 'login' | 'install' | 'command';\n\nexport interface RunSetupOptions {\n trigger: SetupTrigger;\n /** Restrict to specific agent keys (e.g. claude-code, cursor). */\n agents?: string[];\n skillsOnly?: boolean;\n mcpOnly?: boolean;\n /** Skip the confirm and install directly (for non-interactive `workos setup --yes`). */\n assumeYes?: boolean;\n /** Clear a prior decline so automatic offers resume, then return. */\n reset?: boolean;\n}\n\n/** Validate an --agents filter against the known keys; exit with a structured error on unknown. */\nfunction validateAgentFilter(agents: string[] | undefined, known: string[]): string[] | undefined {\n if (!agents || agents.length === 0) return undefined;\n const unknown = agents.filter((a) => !known.includes(a));\n if (unknown.length > 0) {\n exitWithError({\n code: 'unknown_agent',\n message: `Unknown agent(s): ${unknown.join(', ')}. Supported: ${known.join(', ')}.`,\n });\n }\n return agents;\n}\n\n/** Distinct display names across skill agents + MCP targets, for the offer copy. */\nfunction detectedNames(skillAgents: AgentConfig[], mcpTargets: McpClientTarget[]): string[] {\n return Array.from(new Set([...skillAgents.map((a) => a.displayName), ...mcpTargets.map((t) => t.displayName)]));\n}\n\n/**\n * Run the consolidated setup flow. Behavior branches on `trigger`:\n * - automatic (login/install): self-gates on mode + decline/complete, prompts,\n * records an absolute decline on \"no\".\n * - command: always runs; a \"no\" does NOT record a permanent decline.\n */\nexport async function runSetup(opts: RunSetupOptions): Promise<void> {\n if (opts.reset) {\n clearSetupDecline();\n if (isJsonMode()) {\n outputSuccess('Setup offers re-enabled', { reset: true });\n } else {\n ui.log.success(`Setup offers re-enabled. Run \\`${formatWorkOSCommand('setup')}\\` to configure your agents.`);\n }\n return;\n }\n\n const isCommand = opts.trigger === 'command';\n const agents = createAgents(homedir()); // cheap (path construction, no IO); built once\n const agentFilter = isCommand\n ? validateAgentFilter(opts.agents, [...Object.keys(agents), ...MCP_AGENT_KEYS])\n : opts.agents;\n\n // Gate BEFORE any agent detection — detectMcpClients shells out to `claude mcp\n // list` etc., so a machine / declined / completed run must pay nothing.\n if (!isCommand) {\n // Automatic (login/install): silent in machine/non-interactive contexts, and\n // never after a decline or a prior completion.\n if (isJsonMode() || !isPromptAllowed()) return;\n if (isSetupDeclined() || isSetupCompleted()) return;\n } else if ((!isPromptAllowed() || isJsonMode()) && !opts.assumeYes) {\n // Explicit `workos setup` can't prompt in a non-interactive context, nor\n // under --json — output mode is JSON while interaction mode stays human, so\n // isPromptAllowed() is still true and a confirm would pollute the\n // machine-readable stdout stream. Require --yes in both cases.\n exitWithError({\n code: 'confirmation_required',\n message: `Setup can't prompt here (non-interactive or --json). Re-run \\`${formatWorkOSCommand('setup --yes')}\\` to install without a prompt.`,\n });\n }\n\n const wantSkills = !opts.mcpOnly;\n const wantMcp = !opts.skillsOnly;\n const skillAgents: AgentConfig[] = wantSkills ? detectAgents(agents, agentFilter) : [];\n const mcpTargets: McpClientTarget[] = wantMcp ? await detectMcpClients(agentFilter) : [];\n const names = detectedNames(skillAgents, mcpTargets);\n\n // Nothing to install to. Surface it only for an explicit invocation.\n if (names.length === 0) {\n if (isCommand) {\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, Goose).');\n }\n }\n return;\n }\n\n const startedAt = Date.now();\n\n // The offer.\n if (!opts.assumeYes) {\n ui.heading('Set up your coding agent');\n const what =\n wantSkills && wantMcp ? 'WorkOS skills and the MCP server' : wantMcp ? 'the WorkOS MCP server' : 'WorkOS skills';\n ui.note(\n `Add ${what} to ${names.join(', ')} so your coding agent can\\n` +\n `scaffold auth and manage WorkOS resources. Nothing is written until you confirm.`,\n );\n\n const answer = await ui.confirm({ message: 'Set up now?', initialValue: true });\n // Cancel (ctrl-c) is not a decline — skip silently and ask again next time,\n // but record it so the cut-off is observable in telemetry.\n if (isCancel(answer)) {\n emitSetupEvent(opts.trigger, startedAt, 'cancelled', { skills: [], mcpInstalled: [], mcpFailed: [] });\n return;\n }\n if (!answer) {\n if (!isCommand) recordSetupDeclined();\n emitSetupEvent(opts.trigger, startedAt, 'declined', { skills: [], mcpInstalled: [], mcpFailed: [] });\n ui.log.hint(`No problem. Run \\`${formatWorkOSCommand('setup')}\\` anytime.`);\n return;\n }\n }\n\n // Install.\n await installAndReport(opts, skillAgents, mcpTargets, startedAt);\n}\n\nasync function installAndReport(\n opts: RunSetupOptions,\n skillAgents: AgentConfig[],\n mcpTargets: McpClientTarget[],\n startedAt: number,\n): Promise<void> {\n // Skills (local fs) and MCP (shell-outs to `claude mcp add` etc., which can\n // each block toward a 10s timeout) are independent — run them concurrently,\n // and run the per-agent MCP adds in parallel too. Empty inputs (skillsOnly /\n // mcpOnly) resolve to null / [] without work. `target.add()` never rejects.\n const [skillResult, mcpResults] = await Promise.all([\n skillAgents.length > 0 ? refreshWorkOSSkills({ agents: skillAgents }) : Promise.resolve(null),\n Promise.all(mcpTargets.map((target) => target.add())),\n ]);\n const skillAgentNames = skillResult?.agents.map((a) => a.displayName) ?? [];\n\n const mcpInstalled = mcpResults\n .filter((r) => r.outcome === 'installed' || r.outcome === 'already-installed')\n .map((r) => r.agent);\n const failedResults = mcpResults.filter((r) => r.outcome === 'failed');\n const mcpFailed = failedResults.map((r) => r.agent);\n // Carry a bounded, agent-tagged reason so the MCP-install failure CAUSE (not\n // just the count) is observable in telemetry. Already user-safe — the same\n // text is shown via ui.log.error.\n const mcpFailedReasons = failedResults.map((r) => `${r.agent}:${(r.error ?? '').slice(0, 120)}`).join('; ');\n\n // Only mark setup complete when something actually landed. A run where every\n // attempted install failed (e.g. transient `claude mcp add` timeouts, with no\n // skills to fall back on) must NOT be treated as done: isSetupCompleted()\n // suppresses every future automatic offer, so persisting completion here would\n // strand the user after a transient failure. Leave the pref unset so the next\n // login/install re-offers.\n if (skillAgentNames.length > 0 || mcpInstalled.length > 0) {\n recordSetupCompleted();\n }\n\n emitSetupEvent(opts.trigger, startedAt, 'accepted', {\n skills: skillResult?.agents.map((a) => a.name) ?? [],\n mcpInstalled,\n mcpFailed,\n mcpFailedReasons,\n });\n\n reportResults(skillResult ? { agents: skillAgentNames, count: skillResult.skills.length } : null, mcpResults);\n}\n\ninterface SkillSummary {\n agents: string[];\n count: number;\n}\n\n/** Emit the outcome in both output modes; exit non-zero if any MCP install failed. */\nfunction reportResults(skills: SkillSummary | null, mcp: McpClientResult[]): void {\n if (isJsonMode()) {\n outputSuccess('Setup complete', { skills, mcp });\n } else {\n if (skills && skills.agents.length > 0) {\n const word = skills.count === 1 ? 'skill' : 'skills';\n ui.log.success(`${skills.count} ${word} installed for ${skills.agents.join(', ')}`);\n }\n for (const r of mcp) {\n const line = `MCP server: ${r.displayName} — ${MCP_OUTCOME_LABELS[r.outcome]}`;\n if (r.outcome === 'failed') {\n ui.log.error(r.error ? `${line} (${r.error})` : line);\n } else {\n ui.log.success(line);\n }\n }\n if (mcp.some((r) => r.outcome === 'installed' || r.outcome === 'already-installed')) {\n ui.log.hint('Your agent will authorize WorkOS via OAuth on first MCP use.');\n }\n }\n\n if (mcp.some((r) => r.outcome === 'failed')) {\n exitWithCode(ExitCode.GENERAL_ERROR);\n }\n}\n\n/**\n * Queued adoption event (NOT capture()): setup runs as a sub-step after the\n * installer session has ended, so folded session tags would never ship. A queued\n * command event rides the CLI's final flush (the same pattern the old\n * standalone MCP offer used).\n */\ntype SetupOutcome = 'accepted' | 'declined' | 'cancelled';\n\nfunction emitSetupEvent(\n trigger: SetupTrigger,\n startedAt: number,\n outcome: SetupOutcome,\n agents: { skills: string[]; mcpInstalled: string[]; mcpFailed: string[]; mcpFailedReasons?: string },\n): void {\n analytics.emitCommandEvent('setup offer', Date.now() - startedAt, agents.mcpFailed.length === 0, {\n extraAttributes: {\n 'setup.trigger': trigger,\n // `accepted` kept for back-compat dashboards; `outcome` distinguishes a\n // deliberate \"no\" (declined) from a walk-away/ctrl-c (cancelled).\n 'setup.accepted': outcome === 'accepted',\n 'setup.outcome': outcome,\n 'setup.skills_agents': agents.skills.join(','),\n 'setup.mcp_installed': agents.mcpInstalled.join(','),\n 'setup.mcp_failed': agents.mcpFailed.join(','),\n ...(agents.mcpFailedReasons ? { 'setup.mcp_failed_reasons': agents.mcpFailedReasons } : {}),\n },\n });\n}\n\n/**\n * Best-effort setup offer after a successful `login` / `install`.\n *\n * Never throws into, wedges, or fails the parent flow — a try/catch swallows any\n * error. The offer is only ever shown to a present human in an interactive TTY\n * (runSetup early-returns in every machine/non-interactive context), so the\n * confirm is NOT time-bounded: a question that auto-dismisses while the user is\n * reading it is exactly the \"it asked but moved on\" bug. @inquirer already\n * handles ctrl-c, and detection/install are internally time-bounded, so there is\n * nothing left to race. The parent flow has already succeeded by the time this\n * runs. Any failure is reported to telemetry before being swallowed.\n */\nexport async function maybeRunSetupAfter(trigger: 'login' | 'install'): Promise<void> {\n try {\n await runSetup({ trigger });\n } catch (error) {\n // reportResults exits non-zero via CliExit on a failed MCP add — that's an\n // intentional exit for the standalone command, not an exception to report\n // (and it stays swallowed here so it never fails the parent login/install).\n if (error instanceof CliExit) return;\n // Setup must never fail or block login / install — but don't drop the signal.\n analytics.captureException(error instanceof Error ? error : new Error(String(error)), {\n 'setup.trigger': trigger,\n });\n }\n}\n"]}
|
|
@@ -5,6 +5,7 @@ import { createApiErrorHandler } from '../lib/api-error-handler.js';
|
|
|
5
5
|
import { isJsonMode, outputJson, exitWithError } from '../utils/output.js';
|
|
6
6
|
import { formatTable } from '../utils/table.js';
|
|
7
7
|
import { SPAWN_OPTS, IS_WINDOWS } from '../utils/platform.js';
|
|
8
|
+
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
8
9
|
const handleApiError = createApiErrorHandler('Vault');
|
|
9
10
|
export function parseSecretMappings(secrets) {
|
|
10
11
|
if (!secrets || secrets.length === 0) {
|
|
@@ -67,7 +68,7 @@ async function resolveRunApiKey(envName, flagApiKey) {
|
|
|
67
68
|
if (!env || !env.apiKey) {
|
|
68
69
|
exitWithError({
|
|
69
70
|
code: 'env_not_found',
|
|
70
|
-
message: `Environment '${envName}' not found or has no API key. Run '
|
|
71
|
+
message: `Environment '${envName}' not found or has no API key. Run '${formatWorkOSCommand('env list')}' to see available environments.`,
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
return env.apiKey;
|
|
@@ -169,7 +170,7 @@ export async function runVaultRun(options, flagApiKey) {
|
|
|
169
170
|
if (!options.command || options.command.length === 0) {
|
|
170
171
|
exitWithError({
|
|
171
172
|
code: 'missing_command',
|
|
172
|
-
message:
|
|
173
|
+
message: `No command specified. Usage: ${formatWorkOSCommand('vault run --secret ENV=name -- command')}`,
|
|
173
174
|
});
|
|
174
175
|
}
|
|
175
176
|
const apiKey = await resolveRunApiKey(options.env, flagApiKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-run.js","sourceRoot":"","sources":["../../src/commands/vault-run.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport chalk from 'chalk';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { formatTable } from '../utils/table.js';\nimport { SPAWN_OPTS, IS_WINDOWS } from '../utils/platform.js';\n\nconst handleApiError = createApiErrorHandler('Vault');\n\nexport interface SecretMapping {\n envVar: string;\n vaultName: string;\n}\n\nexport interface VaultRunOptions {\n secrets: string[];\n command: string[];\n env?: string;\n dryRun?: boolean;\n}\n\nexport function parseSecretMappings(secrets: string[]): SecretMapping[] {\n if (!secrets || secrets.length === 0) {\n exitWithError({\n code: 'missing_secrets',\n message: 'At least one --secret ENV=name mapping is required',\n });\n }\n\n const result: SecretMapping[] = [];\n const seen = new Set<string>();\n\n for (const raw of secrets) {\n const eqIndex = raw.indexOf('=');\n if (eqIndex <= 0 || eqIndex === raw.length - 1) {\n exitWithError({\n code: 'invalid_secret_format',\n message: `Invalid secret mapping '${raw}'. Expected format: ENV_VAR=vault-name`,\n });\n }\n\n const envVar = raw.slice(0, eqIndex);\n const vaultName = raw.slice(eqIndex + 1);\n\n if (seen.has(envVar)) {\n exitWithError({\n code: 'duplicate_env_var',\n message: `Duplicate environment variable '${envVar}' in --secret mappings`,\n });\n }\n seen.add(envVar);\n\n result.push({ envVar, vaultName });\n }\n\n return result;\n}\n\nexport async function fetchSecrets(\n mappings: SecretMapping[],\n apiKey: string,\n baseUrl?: string,\n): Promise<Map<string, string>> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n const entries = await Promise.all(\n mappings.map(async ({ envVar, vaultName }): Promise<[string, string]> => {\n let obj: { value?: unknown };\n try {\n obj = await client.sdk.vault.readObjectByName(vaultName);\n } catch (error) {\n return handleApiError(error, vaultName);\n }\n if (typeof obj.value !== 'string') {\n exitWithError({\n code: 'vault_value_missing',\n message: `Vault object '${vaultName}' has no readable value`,\n });\n }\n return [envVar, obj.value];\n }),\n );\n\n return new Map(entries);\n}\n\nasync function resolveRunApiKey(envName: string | undefined, flagApiKey?: string): Promise<string> {\n if (!envName) {\n const { resolveApiKey } = await import('../lib/api-key.js');\n return resolveApiKey({ apiKey: flagApiKey });\n }\n\n const { getConfig } = await import('../lib/config-store.js');\n const config = getConfig();\n const env = config?.environments[envName];\n if (!env || !env.apiKey) {\n exitWithError({\n code: 'env_not_found',\n message: `Environment '${envName}' not found or has no API key. Run 'workos env list' to see available environments.`,\n });\n }\n return env.apiKey;\n}\n\nasync function resolveRunBaseUrl(envName: string | undefined): Promise<string> {\n if (envName) {\n const { getConfig } = await import('../lib/config-store.js');\n const config = getConfig();\n const env = config?.environments[envName];\n // Use the named env's endpoint, or the default. Never fall through to\n // the active env's endpoint -- that would send the wrong API key to\n // the wrong host when active != selected.\n return env?.endpoint ?? 'https://api.workos.com';\n }\n const { resolveApiBaseUrl } = await import('../lib/api-key.js');\n return resolveApiBaseUrl();\n}\n\nfunction printDryRun(mappings: SecretMapping[], envName?: string): void {\n if (isJsonMode()) {\n outputJson({\n dryRun: true,\n env: envName ?? null,\n mappings: mappings.map(({ envVar, vaultName }) => ({ envVar, vaultName })),\n });\n return;\n }\n\n console.log(chalk.dim('Dry run (no secrets will be fetched and no child process will be spawned).'));\n if (envName) console.log(chalk.dim(`Environment: ${envName}`));\n console.log();\n const rows = mappings.map(({ envVar, vaultName }) => [envVar, vaultName]);\n console.log(formatTable([{ header: 'Environment Variable' }, { header: 'Vault Object' }], rows));\n}\n\nfunction spawnChild(command: string, args: string[], childEnv: NodeJS.ProcessEnv): Promise<number> {\n return new Promise((resolve, reject) => {\n let child: ChildProcess;\n try {\n child = spawn(command, args, {\n stdio: 'inherit',\n env: childEnv,\n ...SPAWN_OPTS,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n exitWithError({\n code: 'spawn_failed',\n message: `Failed to start: ${command}: ${message}`,\n });\n }\n\n child.on('error', (err) => {\n try {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n exitWithError({ code: 'command_not_found', message: `Command not found: ${command}` });\n }\n exitWithError({ code: 'spawn_error', message: `Failed to start: ${command}: ${err.message}` });\n } catch (e) {\n reject(e);\n }\n });\n\n const forward = (signal: NodeJS.Signals) => {\n if (!child.killed) child.kill(signal);\n };\n process.once('SIGINT', () => forward('SIGINT'));\n process.once('SIGTERM', () => forward('SIGTERM'));\n if (IS_WINDOWS) {\n process.once('SIGBREAK', () => forward('SIGINT'));\n }\n\n child.on('exit', (code, signal) => {\n if (signal) {\n const num = signalToNumber(signal);\n resolve(num ? 128 + num : 1);\n } else {\n resolve(code ?? 0);\n }\n });\n });\n}\n\nfunction signalToNumber(signal: NodeJS.Signals): number {\n const map: Record<string, number> = {\n SIGHUP: 1,\n SIGINT: 2,\n SIGQUIT: 3,\n SIGKILL: 9,\n SIGTERM: 15,\n };\n return map[signal] ?? 0;\n}\n\nexport async function runVaultRun(options: VaultRunOptions, flagApiKey?: string): Promise<number | void> {\n const mappings = parseSecretMappings(options.secrets);\n\n if (options.dryRun) {\n printDryRun(mappings, options.env);\n return;\n }\n\n if (!options.command || options.command.length === 0) {\n exitWithError({\n code: 'missing_command',\n message: 'No command specified. Usage: workos vault run --secret ENV=name -- command',\n });\n }\n\n const apiKey = await resolveRunApiKey(options.env, flagApiKey);\n const baseUrl = await resolveRunBaseUrl(options.env);\n const secretValues = await fetchSecrets(mappings, apiKey, baseUrl);\n\n // Metadata to stderr so the child process owns stdout.\n if (isJsonMode()) {\n console.error(\n JSON.stringify({\n status: 'ok',\n message: 'Injected secrets into child process',\n env: options.env ?? null,\n injected: mappings.map(({ envVar, vaultName }) => ({ envVar, vaultName })),\n }),\n );\n }\n\n const childEnv: NodeJS.ProcessEnv = { ...process.env };\n for (const [envVar, value] of secretValues) {\n childEnv[envVar] = value;\n }\n\n const [cmd, ...args] = options.command;\n return spawnChild(cmd, args, childEnv);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"vault-run.js","sourceRoot":"","sources":["../../src/commands/vault-run.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport chalk from 'chalk';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { formatTable } from '../utils/table.js';\nimport { SPAWN_OPTS, IS_WINDOWS } from '../utils/platform.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nconst handleApiError = createApiErrorHandler('Vault');\n\nexport interface SecretMapping {\n envVar: string;\n vaultName: string;\n}\n\nexport interface VaultRunOptions {\n secrets: string[];\n command: string[];\n env?: string;\n dryRun?: boolean;\n}\n\nexport function parseSecretMappings(secrets: string[]): SecretMapping[] {\n if (!secrets || secrets.length === 0) {\n exitWithError({\n code: 'missing_secrets',\n message: 'At least one --secret ENV=name mapping is required',\n });\n }\n\n const result: SecretMapping[] = [];\n const seen = new Set<string>();\n\n for (const raw of secrets) {\n const eqIndex = raw.indexOf('=');\n if (eqIndex <= 0 || eqIndex === raw.length - 1) {\n exitWithError({\n code: 'invalid_secret_format',\n message: `Invalid secret mapping '${raw}'. Expected format: ENV_VAR=vault-name`,\n });\n }\n\n const envVar = raw.slice(0, eqIndex);\n const vaultName = raw.slice(eqIndex + 1);\n\n if (seen.has(envVar)) {\n exitWithError({\n code: 'duplicate_env_var',\n message: `Duplicate environment variable '${envVar}' in --secret mappings`,\n });\n }\n seen.add(envVar);\n\n result.push({ envVar, vaultName });\n }\n\n return result;\n}\n\nexport async function fetchSecrets(\n mappings: SecretMapping[],\n apiKey: string,\n baseUrl?: string,\n): Promise<Map<string, string>> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n const entries = await Promise.all(\n mappings.map(async ({ envVar, vaultName }): Promise<[string, string]> => {\n let obj: { value?: unknown };\n try {\n obj = await client.sdk.vault.readObjectByName(vaultName);\n } catch (error) {\n return handleApiError(error, vaultName);\n }\n if (typeof obj.value !== 'string') {\n exitWithError({\n code: 'vault_value_missing',\n message: `Vault object '${vaultName}' has no readable value`,\n });\n }\n return [envVar, obj.value];\n }),\n );\n\n return new Map(entries);\n}\n\nasync function resolveRunApiKey(envName: string | undefined, flagApiKey?: string): Promise<string> {\n if (!envName) {\n const { resolveApiKey } = await import('../lib/api-key.js');\n return resolveApiKey({ apiKey: flagApiKey });\n }\n\n const { getConfig } = await import('../lib/config-store.js');\n const config = getConfig();\n const env = config?.environments[envName];\n if (!env || !env.apiKey) {\n exitWithError({\n code: 'env_not_found',\n message: `Environment '${envName}' not found or has no API key. Run '${formatWorkOSCommand('env list')}' to see available environments.`,\n });\n }\n return env.apiKey;\n}\n\nasync function resolveRunBaseUrl(envName: string | undefined): Promise<string> {\n if (envName) {\n const { getConfig } = await import('../lib/config-store.js');\n const config = getConfig();\n const env = config?.environments[envName];\n // Use the named env's endpoint, or the default. Never fall through to\n // the active env's endpoint -- that would send the wrong API key to\n // the wrong host when active != selected.\n return env?.endpoint ?? 'https://api.workos.com';\n }\n const { resolveApiBaseUrl } = await import('../lib/api-key.js');\n return resolveApiBaseUrl();\n}\n\nfunction printDryRun(mappings: SecretMapping[], envName?: string): void {\n if (isJsonMode()) {\n outputJson({\n dryRun: true,\n env: envName ?? null,\n mappings: mappings.map(({ envVar, vaultName }) => ({ envVar, vaultName })),\n });\n return;\n }\n\n console.log(chalk.dim('Dry run (no secrets will be fetched and no child process will be spawned).'));\n if (envName) console.log(chalk.dim(`Environment: ${envName}`));\n console.log();\n const rows = mappings.map(({ envVar, vaultName }) => [envVar, vaultName]);\n console.log(formatTable([{ header: 'Environment Variable' }, { header: 'Vault Object' }], rows));\n}\n\nfunction spawnChild(command: string, args: string[], childEnv: NodeJS.ProcessEnv): Promise<number> {\n return new Promise((resolve, reject) => {\n let child: ChildProcess;\n try {\n child = spawn(command, args, {\n stdio: 'inherit',\n env: childEnv,\n ...SPAWN_OPTS,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n exitWithError({\n code: 'spawn_failed',\n message: `Failed to start: ${command}: ${message}`,\n });\n }\n\n child.on('error', (err) => {\n try {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n exitWithError({ code: 'command_not_found', message: `Command not found: ${command}` });\n }\n exitWithError({ code: 'spawn_error', message: `Failed to start: ${command}: ${err.message}` });\n } catch (e) {\n reject(e);\n }\n });\n\n const forward = (signal: NodeJS.Signals) => {\n if (!child.killed) child.kill(signal);\n };\n process.once('SIGINT', () => forward('SIGINT'));\n process.once('SIGTERM', () => forward('SIGTERM'));\n if (IS_WINDOWS) {\n process.once('SIGBREAK', () => forward('SIGINT'));\n }\n\n child.on('exit', (code, signal) => {\n if (signal) {\n const num = signalToNumber(signal);\n resolve(num ? 128 + num : 1);\n } else {\n resolve(code ?? 0);\n }\n });\n });\n}\n\nfunction signalToNumber(signal: NodeJS.Signals): number {\n const map: Record<string, number> = {\n SIGHUP: 1,\n SIGINT: 2,\n SIGQUIT: 3,\n SIGKILL: 9,\n SIGTERM: 15,\n };\n return map[signal] ?? 0;\n}\n\nexport async function runVaultRun(options: VaultRunOptions, flagApiKey?: string): Promise<number | void> {\n const mappings = parseSecretMappings(options.secrets);\n\n if (options.dryRun) {\n printDryRun(mappings, options.env);\n return;\n }\n\n if (!options.command || options.command.length === 0) {\n exitWithError({\n code: 'missing_command',\n message: `No command specified. Usage: ${formatWorkOSCommand('vault run --secret ENV=name -- command')}`,\n });\n }\n\n const apiKey = await resolveRunApiKey(options.env, flagApiKey);\n const baseUrl = await resolveRunBaseUrl(options.env);\n const secretValues = await fetchSecrets(mappings, apiKey, baseUrl);\n\n // Metadata to stderr so the child process owns stdout.\n if (isJsonMode()) {\n console.error(\n JSON.stringify({\n status: 'ok',\n message: 'Injected secrets into child process',\n env: options.env ?? null,\n injected: mappings.map(({ envVar, vaultName }) => ({ envVar, vaultName })),\n }),\n );\n }\n\n const childEnv: NodeJS.ProcessEnv = { ...process.env };\n for (const [envVar, value] of secretValues) {\n childEnv[envVar] = value;\n }\n\n const [cmd, ...args] = options.command;\n return spawnChild(cmd, args, childEnv);\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* verify-login: prove the AuthKit login loop end-to-end against the active
|
|
3
|
+
* environment, headlessly (no browser, no email/OTP retrieval).
|
|
4
|
+
*
|
|
5
|
+
* The command creates a throwaway user, authenticates it with the password
|
|
6
|
+
* grant, asserts access + refresh tokens come back, and deletes the user in a
|
|
7
|
+
* `finally` block so cleanup always runs. It refuses to touch a production
|
|
8
|
+
* environment (unconditional, no override) because it mutates real users.
|
|
9
|
+
*/
|
|
10
|
+
export type VerifyLoginMethod = 'password';
|
|
11
|
+
export interface VerifyLoginOptions {
|
|
12
|
+
/** Already resolved by bin.ts via resolveApiKey (exits 4 if none). */
|
|
13
|
+
apiKey: string;
|
|
14
|
+
/** --client-id ?? activeEnv.clientId. */
|
|
15
|
+
clientId?: string;
|
|
16
|
+
/** resolveApiBaseUrl(). */
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
/** activeEnv.type — drives the production refusal. */
|
|
19
|
+
envType?: 'production' | 'sandbox' | 'unclaimed' | null;
|
|
20
|
+
/** activeEnv.name — display only. */
|
|
21
|
+
envName?: string;
|
|
22
|
+
/** Authentication method to verify (default 'password'). */
|
|
23
|
+
method?: VerifyLoginMethod;
|
|
24
|
+
}
|
|
25
|
+
export declare function runVerifyLogin(options: VerifyLoginOptions): Promise<void>;
|