workos 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -145
- package/dist/bin.js +129 -50
- package/dist/bin.js.map +1 -1
- package/dist/commands/api/index.js +18 -10
- package/dist/commands/api/index.js.map +1 -1
- package/dist/commands/api/interactive.js +11 -11
- package/dist/commands/api/interactive.js.map +1 -1
- package/dist/commands/claim.js +28 -16
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/connection.js +3 -3
- package/dist/commands/connection.js.map +1 -1
- package/dist/commands/debug.js +6 -6
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/dev.d.ts +7 -8
- package/dist/commands/dev.js +14 -14
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/directory.js +3 -3
- package/dist/commands/directory.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/emulate.d.ts +1 -0
- package/dist/commands/emulate.js +3 -2
- package/dist/commands/emulate.js.map +1 -1
- package/dist/commands/env.d.ts +10 -0
- package/dist/commands/env.js +94 -18
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/install.js +8 -13
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +25 -15
- package/dist/commands/login.js +126 -71
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +4 -4
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mcp.js +7 -16
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/migrations.js +2 -1
- package/dist/commands/migrations.js.map +1 -1
- package/dist/commands/seed.js +5 -4
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/setup.d.ts +50 -0
- package/dist/commands/setup.js +237 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/vault-run.js +3 -2
- package/dist/commands/vault-run.js.map +1 -1
- package/dist/commands/verify-login.d.ts +25 -0
- package/dist/commands/verify-login.js +158 -0
- package/dist/commands/verify-login.js.map +1 -0
- package/dist/doctor/issues.js +3 -2
- package/dist/doctor/issues.js.map +1 -1
- package/dist/doctor/output.js +2 -1
- package/dist/doctor/output.js.map +1 -1
- package/dist/integrations/dotnet/index.js +1 -1
- package/dist/integrations/dotnet/index.js.map +1 -1
- package/dist/integrations/elixir/index.js +1 -1
- package/dist/integrations/elixir/index.js.map +1 -1
- package/dist/integrations/go/index.js +1 -1
- package/dist/integrations/go/index.js.map +1 -1
- package/dist/integrations/nextjs/index.js +8 -5
- package/dist/integrations/nextjs/index.js.map +1 -1
- package/dist/integrations/nextjs/utils.d.ts +1 -1
- package/dist/integrations/nextjs/utils.js +21 -6
- package/dist/integrations/nextjs/utils.js.map +1 -1
- package/dist/integrations/react-router/index.js +5 -5
- package/dist/integrations/react-router/index.js.map +1 -1
- package/dist/integrations/react-router/utils.js +28 -12
- package/dist/integrations/react-router/utils.js.map +1 -1
- package/dist/integrations/ruby/index.js +1 -1
- package/dist/integrations/ruby/index.js.map +1 -1
- package/dist/lib/adapters/cli-adapter.d.ts +33 -4
- package/dist/lib/adapters/cli-adapter.js +251 -135
- package/dist/lib/adapters/cli-adapter.js.map +1 -1
- package/dist/lib/adapters/dashboard-adapter.js +3 -3
- package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
- package/dist/lib/adapters/headless-adapter.d.ts +7 -0
- package/dist/lib/adapters/headless-adapter.js +42 -5
- package/dist/lib/adapters/headless-adapter.js.map +1 -1
- package/dist/lib/agent-interface.js +15 -1
- package/dist/lib/agent-interface.js.map +1 -1
- package/dist/lib/agent-runner.js +1 -1
- package/dist/lib/agent-runner.js.map +1 -1
- package/dist/lib/api-key.js +2 -1
- package/dist/lib/api-key.js.map +1 -1
- package/dist/lib/completion-data.d.ts +33 -0
- package/dist/lib/completion-data.js +33 -0
- package/dist/lib/completion-data.js.map +1 -0
- package/dist/lib/config-store.d.ts +13 -0
- package/dist/lib/config-store.js +24 -0
- package/dist/lib/config-store.js.map +1 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +8 -0
- package/dist/lib/constants.js +8 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/events.d.ts +34 -1
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/framework-config.d.ts +6 -0
- package/dist/lib/framework-config.js.map +1 -1
- package/dist/lib/installer-core.d.ts +14 -1
- package/dist/lib/installer-core.js +24 -5
- package/dist/lib/installer-core.js.map +1 -1
- package/dist/lib/installer-core.types.d.ts +3 -1
- package/dist/lib/installer-core.types.js.map +1 -1
- package/dist/lib/mcp-clients.d.ts +6 -0
- package/dist/lib/mcp-clients.js +13 -0
- package/dist/lib/mcp-clients.js.map +1 -1
- package/dist/lib/port-detection.js +19 -13
- package/dist/lib/port-detection.js.map +1 -1
- package/dist/lib/preferences.d.ts +30 -2
- package/dist/lib/preferences.js +34 -8
- package/dist/lib/preferences.js.map +1 -1
- package/dist/lib/run-with-core.js +40 -3
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/telemetry-notice.d.ts +5 -5
- package/dist/lib/telemetry-notice.js +7 -8
- package/dist/lib/telemetry-notice.js.map +1 -1
- package/dist/lib/unclaimed-env-provision.js +15 -12
- package/dist/lib/unclaimed-env-provision.js.map +1 -1
- package/dist/lib/unclaimed-warning.js +4 -3
- package/dist/lib/unclaimed-warning.js.map +1 -1
- package/dist/lib/validation/security-checks.js +2 -1
- package/dist/lib/validation/security-checks.js.map +1 -1
- package/dist/lib/validation/validator.js +30 -3
- package/dist/lib/validation/validator.js.map +1 -1
- package/dist/lib/workos-management.js +26 -19
- package/dist/lib/workos-management.js.map +1 -1
- package/dist/run.d.ts +1 -0
- package/dist/run.js +5 -1
- package/dist/run.js.map +1 -1
- package/dist/steps/add-or-update-environment-variables.js +10 -10
- package/dist/steps/add-or-update-environment-variables.js.map +1 -1
- package/dist/steps/run-prettier.js +3 -3
- package/dist/steps/run-prettier.js.map +1 -1
- package/dist/steps/upload-environment-variables/index.js +15 -3
- package/dist/steps/upload-environment-variables/index.js.map +1 -1
- package/dist/steps/upload-environment-variables/providers/vercel.js +2 -2
- package/dist/steps/upload-environment-variables/providers/vercel.js.map +1 -1
- package/dist/utils/box.d.ts +6 -30
- package/dist/utils/box.js +8 -95
- package/dist/utils/box.js.map +1 -1
- package/dist/utils/cli-symbols.d.ts +14 -2
- package/dist/utils/cli-symbols.js +12 -0
- package/dist/utils/cli-symbols.js.map +1 -1
- package/dist/utils/debug.js +3 -3
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/environment.js +1 -1
- package/dist/utils/environment.js.map +1 -1
- package/dist/utils/help-json.js +115 -4
- package/dist/utils/help-json.js.map +1 -1
- package/dist/utils/package-manager.js +1 -1
- package/dist/utils/package-manager.js.map +1 -1
- package/dist/utils/recovery-hints.d.ts +5 -0
- package/dist/utils/recovery-hints.js +12 -0
- package/dist/utils/recovery-hints.js.map +1 -1
- package/dist/utils/summary-box.d.ts +8 -1
- package/dist/utils/summary-box.js +67 -4
- package/dist/utils/summary-box.js.map +1 -1
- package/dist/utils/types.d.ts +10 -0
- package/dist/utils/types.js.map +1 -1
- package/dist/utils/{clack-utils.d.ts → ui-utils.d.ts} +1 -1
- package/dist/utils/{clack-utils.js → ui-utils.js} +64 -37
- package/dist/utils/ui-utils.js.map +1 -0
- package/dist/utils/ui.d.ts +148 -0
- package/dist/utils/ui.js +368 -0
- package/dist/utils/ui.js.map +1 -0
- package/package.json +5 -13
- package/dist/check-coverage.ts +0 -237
- package/dist/emulate/core/id.d.ts +0 -48
- package/dist/emulate/core/id.js +0 -73
- package/dist/emulate/core/id.js.map +0 -1
- package/dist/emulate/core/index.d.ts +0 -8
- package/dist/emulate/core/index.js +0 -8
- package/dist/emulate/core/index.js.map +0 -1
- package/dist/emulate/core/jwt.d.ts +0 -28
- package/dist/emulate/core/jwt.js +0 -78
- package/dist/emulate/core/jwt.js.map +0 -1
- package/dist/emulate/core/middleware/auth.d.ts +0 -15
- package/dist/emulate/core/middleware/auth.js +0 -17
- package/dist/emulate/core/middleware/auth.js.map +0 -1
- package/dist/emulate/core/middleware/error-handler.d.ts +0 -22
- package/dist/emulate/core/middleware/error-handler.js +0 -72
- package/dist/emulate/core/middleware/error-handler.js.map +0 -1
- package/dist/emulate/core/pagination.d.ts +0 -27
- package/dist/emulate/core/pagination.js +0 -43
- package/dist/emulate/core/pagination.js.map +0 -1
- package/dist/emulate/core/plugin.d.ts +0 -15
- package/dist/emulate/core/plugin.js +0 -2
- package/dist/emulate/core/plugin.js.map +0 -1
- package/dist/emulate/core/server.d.ts +0 -17
- package/dist/emulate/core/server.js +0 -90
- package/dist/emulate/core/server.js.map +0 -1
- package/dist/emulate/core/store.d.ts +0 -44
- package/dist/emulate/core/store.js +0 -169
- package/dist/emulate/core/store.js.map +0 -1
- package/dist/emulate/index.d.ts +0 -25
- package/dist/emulate/index.js +0 -47
- package/dist/emulate/index.js.map +0 -1
- package/dist/emulate/workos/constants.d.ts +0 -56
- package/dist/emulate/workos/constants.js +0 -56
- package/dist/emulate/workos/constants.js.map +0 -1
- package/dist/emulate/workos/entities.d.ts +0 -360
- package/dist/emulate/workos/entities.js +0 -2
- package/dist/emulate/workos/entities.js.map +0 -1
- package/dist/emulate/workos/event-bus.d.ts +0 -17
- package/dist/emulate/workos/event-bus.js +0 -70
- package/dist/emulate/workos/event-bus.js.map +0 -1
- package/dist/emulate/workos/helpers.d.ts +0 -72
- package/dist/emulate/workos/helpers.js +0 -211
- package/dist/emulate/workos/helpers.js.map +0 -1
- package/dist/emulate/workos/index.d.ts +0 -93
- package/dist/emulate/workos/index.js +0 -326
- package/dist/emulate/workos/index.js.map +0 -1
- package/dist/emulate/workos/role-helpers.d.ts +0 -21
- package/dist/emulate/workos/role-helpers.js +0 -130
- package/dist/emulate/workos/role-helpers.js.map +0 -1
- package/dist/emulate/workos/routes/api-keys.d.ts +0 -2
- package/dist/emulate/workos/routes/api-keys.js +0 -32
- package/dist/emulate/workos/routes/api-keys.js.map +0 -1
- package/dist/emulate/workos/routes/audit-logs.d.ts +0 -2
- package/dist/emulate/workos/routes/audit-logs.js +0 -104
- package/dist/emulate/workos/routes/audit-logs.js.map +0 -1
- package/dist/emulate/workos/routes/auth-challenges.d.ts +0 -2
- package/dist/emulate/workos/routes/auth-challenges.js +0 -51
- package/dist/emulate/workos/routes/auth-challenges.js.map +0 -1
- package/dist/emulate/workos/routes/auth-factors.d.ts +0 -2
- package/dist/emulate/workos/routes/auth-factors.js +0 -51
- package/dist/emulate/workos/routes/auth-factors.js.map +0 -1
- package/dist/emulate/workos/routes/auth.d.ts +0 -2
- package/dist/emulate/workos/routes/auth.js +0 -350
- package/dist/emulate/workos/routes/auth.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-checks.d.ts +0 -10
- package/dist/emulate/workos/routes/authorization-checks.js +0 -123
- package/dist/emulate/workos/routes/authorization-checks.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-org-roles.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-org-roles.js +0 -64
- package/dist/emulate/workos/routes/authorization-org-roles.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-permissions.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-permissions.js +0 -67
- package/dist/emulate/workos/routes/authorization-permissions.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-resources.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-resources.js +0 -117
- package/dist/emulate/workos/routes/authorization-resources.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-roles.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-roles.js +0 -13
- package/dist/emulate/workos/routes/authorization-roles.js.map +0 -1
- package/dist/emulate/workos/routes/config.d.ts +0 -2
- package/dist/emulate/workos/routes/config.js +0 -57
- package/dist/emulate/workos/routes/config.js.map +0 -1
- package/dist/emulate/workos/routes/connect.d.ts +0 -2
- package/dist/emulate/workos/routes/connect.js +0 -65
- package/dist/emulate/workos/routes/connect.js.map +0 -1
- package/dist/emulate/workos/routes/connections.d.ts +0 -2
- package/dist/emulate/workos/routes/connections.js +0 -73
- package/dist/emulate/workos/routes/connections.js.map +0 -1
- package/dist/emulate/workos/routes/data-integrations.d.ts +0 -2
- package/dist/emulate/workos/routes/data-integrations.js +0 -55
- package/dist/emulate/workos/routes/data-integrations.js.map +0 -1
- package/dist/emulate/workos/routes/directories.d.ts +0 -2
- package/dist/emulate/workos/routes/directories.js +0 -90
- package/dist/emulate/workos/routes/directories.js.map +0 -1
- package/dist/emulate/workos/routes/email-verification.d.ts +0 -2
- package/dist/emulate/workos/routes/email-verification.js +0 -49
- package/dist/emulate/workos/routes/email-verification.js.map +0 -1
- package/dist/emulate/workos/routes/events.d.ts +0 -2
- package/dist/emulate/workos/routes/events.js +0 -18
- package/dist/emulate/workos/routes/events.js.map +0 -1
- package/dist/emulate/workos/routes/feature-flags.d.ts +0 -2
- package/dist/emulate/workos/routes/feature-flags.js +0 -103
- package/dist/emulate/workos/routes/feature-flags.js.map +0 -1
- package/dist/emulate/workos/routes/invitations.d.ts +0 -2
- package/dist/emulate/workos/routes/invitations.js +0 -122
- package/dist/emulate/workos/routes/invitations.js.map +0 -1
- package/dist/emulate/workos/routes/legacy-mfa.d.ts +0 -2
- package/dist/emulate/workos/routes/legacy-mfa.js +0 -75
- package/dist/emulate/workos/routes/legacy-mfa.js.map +0 -1
- package/dist/emulate/workos/routes/magic-auth.d.ts +0 -2
- package/dist/emulate/workos/routes/magic-auth.js +0 -32
- package/dist/emulate/workos/routes/magic-auth.js.map +0 -1
- package/dist/emulate/workos/routes/memberships.d.ts +0 -2
- package/dist/emulate/workos/routes/memberships.js +0 -114
- package/dist/emulate/workos/routes/memberships.js.map +0 -1
- package/dist/emulate/workos/routes/organization-domains.d.ts +0 -2
- package/dist/emulate/workos/routes/organization-domains.js +0 -58
- package/dist/emulate/workos/routes/organization-domains.js.map +0 -1
- package/dist/emulate/workos/routes/organizations.d.ts +0 -2
- package/dist/emulate/workos/routes/organizations.js +0 -131
- package/dist/emulate/workos/routes/organizations.js.map +0 -1
- package/dist/emulate/workos/routes/password-reset.d.ts +0 -2
- package/dist/emulate/workos/routes/password-reset.js +0 -61
- package/dist/emulate/workos/routes/password-reset.js.map +0 -1
- package/dist/emulate/workos/routes/pipes.d.ts +0 -2
- package/dist/emulate/workos/routes/pipes.js +0 -82
- package/dist/emulate/workos/routes/pipes.js.map +0 -1
- package/dist/emulate/workos/routes/portal.d.ts +0 -2
- package/dist/emulate/workos/routes/portal.js +0 -18
- package/dist/emulate/workos/routes/portal.js.map +0 -1
- package/dist/emulate/workos/routes/radar.d.ts +0 -2
- package/dist/emulate/workos/routes/radar.js +0 -41
- package/dist/emulate/workos/routes/radar.js.map +0 -1
- package/dist/emulate/workos/routes/sessions.d.ts +0 -2
- package/dist/emulate/workos/routes/sessions.js +0 -51
- package/dist/emulate/workos/routes/sessions.js.map +0 -1
- package/dist/emulate/workos/routes/sso.d.ts +0 -2
- package/dist/emulate/workos/routes/sso.js +0 -161
- package/dist/emulate/workos/routes/sso.js.map +0 -1
- package/dist/emulate/workos/routes/user-features.d.ts +0 -2
- package/dist/emulate/workos/routes/user-features.js +0 -50
- package/dist/emulate/workos/routes/user-features.js.map +0 -1
- package/dist/emulate/workos/routes/users.d.ts +0 -2
- package/dist/emulate/workos/routes/users.js +0 -129
- package/dist/emulate/workos/routes/users.js.map +0 -1
- package/dist/emulate/workos/routes/webhook-endpoints.d.ts +0 -2
- package/dist/emulate/workos/routes/webhook-endpoints.js +0 -67
- package/dist/emulate/workos/routes/webhook-endpoints.js.map +0 -1
- package/dist/emulate/workos/routes/widgets.d.ts +0 -2
- package/dist/emulate/workos/routes/widgets.js +0 -27
- package/dist/emulate/workos/routes/widgets.js.map +0 -1
- package/dist/emulate/workos/store.d.ts +0 -48
- package/dist/emulate/workos/store.js +0 -102
- package/dist/emulate/workos/store.js.map +0 -1
- package/dist/emulate/workos/webhook-signer.d.ts +0 -1
- package/dist/emulate/workos/webhook-signer.js +0 -8
- package/dist/emulate/workos/webhook-signer.js.map +0 -1
- package/dist/gen-routes-lib.spec.ts +0 -659
- package/dist/gen-routes-lib.ts +0 -647
- package/dist/gen-routes.ts +0 -96
- package/dist/lib/mcp-notice.d.ts +0 -72
- package/dist/lib/mcp-notice.js +0 -275
- package/dist/lib/mcp-notice.js.map +0 -1
- package/dist/utils/clack-utils.js.map +0 -1
- package/dist/utils/clack.d.ts +0 -5
- package/dist/utils/clack.js +0 -34
- package/dist/utils/clack.js.map +0 -1
package/dist/gen-routes.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
/**
|
|
3
|
-
* Codegen script: reads a WorkOS OpenAPI spec and generates emulator TypeScript
|
|
4
|
-
* files (entities, store, helpers, route stubs).
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* pnpm gen:routes path/to/openapi.yaml [--out-dir src/emulate/workos/generated]
|
|
8
|
-
* pnpm gen:routes path/to/openapi.json --dry-run
|
|
9
|
-
*
|
|
10
|
-
* The generated code matches the hand-written patterns in src/emulate/workos/.
|
|
11
|
-
* Running twice on the same spec produces identical output (idempotent).
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
15
|
-
import { resolve, extname, join } from 'node:path';
|
|
16
|
-
import YAML from 'yaml';
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
type OpenAPISpec,
|
|
20
|
-
parseSpec,
|
|
21
|
-
generateEntities,
|
|
22
|
-
generateStore,
|
|
23
|
-
generateHelpers,
|
|
24
|
-
generateRoutes,
|
|
25
|
-
} from './gen-routes-lib.js';
|
|
26
|
-
|
|
27
|
-
function main(): void {
|
|
28
|
-
const args = process.argv.slice(2);
|
|
29
|
-
const flags = args.filter((a) => a.startsWith('--'));
|
|
30
|
-
const positional = args.filter((a) => !a.startsWith('--'));
|
|
31
|
-
|
|
32
|
-
const specPath = positional[0];
|
|
33
|
-
if (!specPath) {
|
|
34
|
-
console.error('Usage: gen-routes <openapi-spec> [--out-dir <dir>] [--dry-run]');
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const dryRun = flags.includes('--dry-run');
|
|
39
|
-
const outDirIdx = args.indexOf('--out-dir');
|
|
40
|
-
const outDir = outDirIdx !== -1 ? args[outDirIdx + 1] : 'src/emulate/workos/generated';
|
|
41
|
-
|
|
42
|
-
const resolvedSpec = resolve(specPath);
|
|
43
|
-
if (!existsSync(resolvedSpec)) {
|
|
44
|
-
console.error(`Spec file not found: ${resolvedSpec}`);
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const raw = readFileSync(resolvedSpec, 'utf-8');
|
|
49
|
-
const ext = extname(resolvedSpec).toLowerCase();
|
|
50
|
-
let spec: OpenAPISpec;
|
|
51
|
-
|
|
52
|
-
if (ext === '.yaml' || ext === '.yml') {
|
|
53
|
-
spec = YAML.parse(raw) as OpenAPISpec;
|
|
54
|
-
} else {
|
|
55
|
-
spec = JSON.parse(raw) as OpenAPISpec;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const parsed = parseSpec(spec);
|
|
59
|
-
const output = generateAll(parsed);
|
|
60
|
-
|
|
61
|
-
if (dryRun) {
|
|
62
|
-
for (const [filename, content] of Object.entries(output)) {
|
|
63
|
-
console.log(`--- ${filename} ---`);
|
|
64
|
-
console.log(content);
|
|
65
|
-
console.log('');
|
|
66
|
-
}
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const resolvedOutDir = resolve(outDir);
|
|
71
|
-
mkdirSync(resolvedOutDir, { recursive: true });
|
|
72
|
-
|
|
73
|
-
for (const [filename, content] of Object.entries(output)) {
|
|
74
|
-
const filePath = join(resolvedOutDir, filename);
|
|
75
|
-
writeFileSync(filePath, content, 'utf-8');
|
|
76
|
-
console.log(` wrote ${filePath}`);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
console.log(`\nGenerated ${Object.keys(output).length} files in ${resolvedOutDir}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function generateAll(parsed: ReturnType<typeof parseSpec>): Record<string, string> {
|
|
83
|
-
const output: Record<string, string> = {};
|
|
84
|
-
|
|
85
|
-
output['entities.ts'] = generateEntities(parsed.entities);
|
|
86
|
-
output['store.ts'] = generateStore(parsed.entities);
|
|
87
|
-
output['helpers.ts'] = generateHelpers(parsed.entities);
|
|
88
|
-
|
|
89
|
-
for (const route of parsed.routes) {
|
|
90
|
-
output[`routes/${route.filename}`] = generateRoutes(route);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return output;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
main();
|
package/dist/lib/mcp-notice.d.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP-install onboarding surfaces + their shared gate state.
|
|
3
|
-
*
|
|
4
|
-
* One module owns all automatic-ask state so the install-flow prompt and the
|
|
5
|
-
* one-time banner can't drift apart. The decline contract is absolute: any
|
|
6
|
-
* explicit "no" records `promptDeclined` and no automatic surface ever asks
|
|
7
|
-
* again — `workos mcp install` stays available manually.
|
|
8
|
-
*
|
|
9
|
-
* Mirrors telemetry-notice.ts: persisted shown/declined state in the plain
|
|
10
|
-
* prefs store, mode-gated display, and a never-throws contract so a notice can
|
|
11
|
-
* never block or fail a command. The mode gate is the CLI's interaction-mode
|
|
12
|
-
* system (isPromptAllowed / isHumanMode), which already folds in CI markers,
|
|
13
|
-
* agent markers, and TTY state — non-TTY safety comes from using it.
|
|
14
|
-
*/
|
|
15
|
-
export type McpAskState = {
|
|
16
|
-
declined: boolean;
|
|
17
|
-
bannerShown: boolean;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Ceiling on the whole install-flow offer so a wedged prompt can never hold up
|
|
21
|
-
* `workos install`. The deadline actively aborts the pending clack prompt (via
|
|
22
|
-
* AbortSignal) — clack's cancel path releases stdin and restores raw mode, so
|
|
23
|
-
* the process can actually exit; a race alone would leave the prompt's stdin
|
|
24
|
-
* handle keeping the event loop alive. Mirrors login.ts's
|
|
25
|
-
* SKILL_INSTALL_TIMEOUT_MS.
|
|
26
|
-
*/
|
|
27
|
-
export declare const MCP_OFFER_TIMEOUT_MS: number;
|
|
28
|
-
/**
|
|
29
|
-
* Read the persisted automatic-ask state. Never throws — a missing/corrupt
|
|
30
|
-
* prefs file degrades to "nothing recorded" so gating still works in-memory.
|
|
31
|
-
*/
|
|
32
|
-
export declare function getMcpAskState(): Promise<McpAskState>;
|
|
33
|
-
/**
|
|
34
|
-
* Record an explicit decline. Absolute and permanent for automatic surfaces.
|
|
35
|
-
* Write failures are swallowed: gating degrades to per-run memory, never
|
|
36
|
-
* crashes a command.
|
|
37
|
-
*/
|
|
38
|
-
export declare function recordMcpDeclined(): Promise<void>;
|
|
39
|
-
/** Record that the one-time banner was shown, stamping the current time. */
|
|
40
|
-
export declare function recordMcpBannerShown(): Promise<void>;
|
|
41
|
-
/**
|
|
42
|
-
* Would an automatic ask be appropriate right now? True only when the user has
|
|
43
|
-
* not declined AND at least one detected agent lacks the server. Does NOT gate
|
|
44
|
-
* on interaction mode — callers add that (isPromptAllowed for the prompt,
|
|
45
|
-
* isHumanMode for the banner). Checks `declined` first so declined machines
|
|
46
|
-
* never pay for the client shell-outs.
|
|
47
|
-
*/
|
|
48
|
-
export declare function isAutoAskEligible(): Promise<boolean>;
|
|
49
|
-
/**
|
|
50
|
-
* One-time stderr banner nudging the user toward `workos mcp install`. Shown at
|
|
51
|
-
* most once per machine, only on a normal human-mode run, and never when an
|
|
52
|
-
* earlier startup notice already fired this run (telemetry notice and unclaimed
|
|
53
|
-
* warning take precedence). Records `bannerShownAt` before printing —
|
|
54
|
-
* shown-once beats seen-once (a lost banner is fine; a nag loop is not). Never
|
|
55
|
-
* throws.
|
|
56
|
-
*/
|
|
57
|
-
export declare function maybeShowMcpNotice(): Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Offer to install the WorkOS MCP server at the end of `workos install`.
|
|
60
|
-
*
|
|
61
|
-
* Wraps offerMcpInstall best-effort: a try/catch AND a 30s deadline so the
|
|
62
|
-
* offer can never throw into, wedge, or fail the install flow. The deadline
|
|
63
|
-
* aborts the pending prompt (AbortSignal → clack cancel, which releases stdin);
|
|
64
|
-
* the race is a backstop in case the flow is wedged somewhere that can't be
|
|
65
|
-
* aborted (client shell-outs are separately bounded by their exec timeouts).
|
|
66
|
-
* `workos install` has already succeeded by the time this runs.
|
|
67
|
-
*/
|
|
68
|
-
export declare function maybeOfferMcpInstall(_opts: {
|
|
69
|
-
entryPoint: 'install-flow';
|
|
70
|
-
}): Promise<void>;
|
|
71
|
-
/** Reset per-session banner state (for testing). */
|
|
72
|
-
export declare function resetMcpNoticeState(): void;
|
package/dist/lib/mcp-notice.js
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP-install onboarding surfaces + their shared gate state.
|
|
3
|
-
*
|
|
4
|
-
* One module owns all automatic-ask state so the install-flow prompt and the
|
|
5
|
-
* one-time banner can't drift apart. The decline contract is absolute: any
|
|
6
|
-
* explicit "no" records `promptDeclined` and no automatic surface ever asks
|
|
7
|
-
* again — `workos mcp install` stays available manually.
|
|
8
|
-
*
|
|
9
|
-
* Mirrors telemetry-notice.ts: persisted shown/declined state in the plain
|
|
10
|
-
* prefs store, mode-gated display, and a never-throws contract so a notice can
|
|
11
|
-
* never block or fail a command. The mode gate is the CLI's interaction-mode
|
|
12
|
-
* system (isPromptAllowed / isHumanMode), which already folds in CI markers,
|
|
13
|
-
* agent markers, and TTY state — non-TTY safety comes from using it.
|
|
14
|
-
*/
|
|
15
|
-
import chalk from 'chalk';
|
|
16
|
-
import clack from '../utils/clack.js';
|
|
17
|
-
import { isHumanMode, isPromptAllowed } from '../utils/interaction-mode.js';
|
|
18
|
-
import { isJsonMode } from '../utils/output.js';
|
|
19
|
-
import { renderStderrBox } from '../utils/box.js';
|
|
20
|
-
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
21
|
-
import { analytics } from '../utils/analytics.js';
|
|
22
|
-
import { loadPreferences, savePreferences } from './preferences.js';
|
|
23
|
-
import { detectMcpClients } from './mcp-clients.js';
|
|
24
|
-
import { hasStartupNoticeShown, markStartupNoticeShown } from './startup-notice-gate.js';
|
|
25
|
-
/**
|
|
26
|
-
* Ceiling on the whole install-flow offer so a wedged prompt can never hold up
|
|
27
|
-
* `workos install`. The deadline actively aborts the pending clack prompt (via
|
|
28
|
-
* AbortSignal) — clack's cancel path releases stdin and restores raw mode, so
|
|
29
|
-
* the process can actually exit; a race alone would leave the prompt's stdin
|
|
30
|
-
* handle keeping the event loop alive. Mirrors login.ts's
|
|
31
|
-
* SKILL_INSTALL_TIMEOUT_MS.
|
|
32
|
-
*/
|
|
33
|
-
export const MCP_OFFER_TIMEOUT_MS = 30 * 1000;
|
|
34
|
-
let bannerShownThisSession = false;
|
|
35
|
-
/** Human phrasing for each install outcome shown in the accept matrix. */
|
|
36
|
-
const OUTCOME_LABEL = {
|
|
37
|
-
installed: 'installed',
|
|
38
|
-
'already-installed': 'already installed',
|
|
39
|
-
removed: 'removed',
|
|
40
|
-
'not-installed': 'not installed',
|
|
41
|
-
skipped: 'skipped',
|
|
42
|
-
failed: 'failed',
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Read the persisted automatic-ask state. Never throws — a missing/corrupt
|
|
46
|
-
* prefs file degrades to "nothing recorded" so gating still works in-memory.
|
|
47
|
-
*/
|
|
48
|
-
export async function getMcpAskState() {
|
|
49
|
-
try {
|
|
50
|
-
const prefs = await loadPreferences();
|
|
51
|
-
return {
|
|
52
|
-
declined: prefs.mcp?.promptDeclined === true,
|
|
53
|
-
bannerShown: Boolean(prefs.mcp?.bannerShownAt),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
return { declined: false, bannerShown: false };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Record an explicit decline. Absolute and permanent for automatic surfaces.
|
|
62
|
-
* Write failures are swallowed: gating degrades to per-run memory, never
|
|
63
|
-
* crashes a command.
|
|
64
|
-
*/
|
|
65
|
-
export async function recordMcpDeclined() {
|
|
66
|
-
try {
|
|
67
|
-
savePreferences({ mcp: { promptDeclined: true } });
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
// Swallow — a read-only prefs file must never break a command.
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
/** Record that the one-time banner was shown, stamping the current time. */
|
|
74
|
-
export async function recordMcpBannerShown() {
|
|
75
|
-
try {
|
|
76
|
-
savePreferences({ mcp: { bannerShownAt: new Date().toISOString() } });
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
// Swallow — see recordMcpDeclined.
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* The detected agents that would actually receive an install: available on this
|
|
84
|
-
* machine AND missing the WorkOS server. Empty when there is nothing to offer.
|
|
85
|
-
* Never throws — detection failure yields an empty set.
|
|
86
|
-
*/
|
|
87
|
-
async function detectInstallTargets() {
|
|
88
|
-
try {
|
|
89
|
-
const clients = await detectMcpClients();
|
|
90
|
-
if (clients.length === 0)
|
|
91
|
-
return [];
|
|
92
|
-
const installed = await Promise.all(clients.map((c) => c.isInstalled()));
|
|
93
|
-
return clients.filter((_, i) => !installed[i]);
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
return [];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Would an automatic ask be appropriate right now? True only when the user has
|
|
101
|
-
* not declined AND at least one detected agent lacks the server. Does NOT gate
|
|
102
|
-
* on interaction mode — callers add that (isPromptAllowed for the prompt,
|
|
103
|
-
* isHumanMode for the banner). Checks `declined` first so declined machines
|
|
104
|
-
* never pay for the client shell-outs.
|
|
105
|
-
*/
|
|
106
|
-
export async function isAutoAskEligible() {
|
|
107
|
-
const { declined } = await getMcpAskState();
|
|
108
|
-
if (declined)
|
|
109
|
-
return false;
|
|
110
|
-
const targets = await detectInstallTargets();
|
|
111
|
-
return targets.length > 0;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* One-time stderr banner nudging the user toward `workos mcp install`. Shown at
|
|
115
|
-
* most once per machine, only on a normal human-mode run, and never when an
|
|
116
|
-
* earlier startup notice already fired this run (telemetry notice and unclaimed
|
|
117
|
-
* warning take precedence). Records `bannerShownAt` before printing —
|
|
118
|
-
* shown-once beats seen-once (a lost banner is fine; a nag loop is not). Never
|
|
119
|
-
* throws.
|
|
120
|
-
*/
|
|
121
|
-
export async function maybeShowMcpNotice() {
|
|
122
|
-
try {
|
|
123
|
-
if (bannerShownThisSession)
|
|
124
|
-
return;
|
|
125
|
-
if (!isHumanMode())
|
|
126
|
-
return; // suppress in agent / CI / non-TTY
|
|
127
|
-
if (isJsonMode())
|
|
128
|
-
return; // never on the machine-readable path
|
|
129
|
-
if (hasStartupNoticeShown())
|
|
130
|
-
return; // one-notice-per-run cap; telemetry/unclaimed win
|
|
131
|
-
const { bannerShown } = await getMcpAskState();
|
|
132
|
-
if (bannerShown)
|
|
133
|
-
return; // already shown once, ever
|
|
134
|
-
if (!(await isAutoAskEligible()))
|
|
135
|
-
return; // declined, or nothing to offer
|
|
136
|
-
// Claim the slot + persist BEFORE printing: a lost banner beats a nag loop.
|
|
137
|
-
bannerShownThisSession = true;
|
|
138
|
-
markStartupNoticeShown();
|
|
139
|
-
await recordMcpBannerShown();
|
|
140
|
-
// Impression event. Queued (not capture()d) so it rides the CLI's final
|
|
141
|
-
// flush; capture() only folds session tags and no session exists here.
|
|
142
|
-
analytics.emitCommandEvent('mcp offer', 0, true, {
|
|
143
|
-
extraAttributes: { 'mcp.entry_point': 'banner', 'mcp.shown': true },
|
|
144
|
-
});
|
|
145
|
-
const cmd = chalk.cyan(formatWorkOSCommand('mcp install'));
|
|
146
|
-
const inner = ` ${chalk.cyan('ℹ')} New: connect your coding agent to WorkOS. Run ${cmd} to add the WorkOS MCP server (Claude Code, Codex, Cursor). `;
|
|
147
|
-
renderStderrBox(inner, chalk.cyan);
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
// Never block command startup.
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/** Emit the per-agent install matrix (human mode) without ever exiting. */
|
|
154
|
-
function printInstallMatrix(results) {
|
|
155
|
-
for (const r of results) {
|
|
156
|
-
const line = `${r.displayName}: ${OUTCOME_LABEL[r.outcome]}`;
|
|
157
|
-
if (r.outcome === 'failed') {
|
|
158
|
-
clack.log.error(r.error ? `${line} — ${r.error}` : line);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
clack.log.success(line);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* The real install-flow offer. Self-gating: renders nothing unless prompting is
|
|
167
|
-
* allowed, the user hasn't declined, and there is at least one agent to install
|
|
168
|
-
* to. On yes: install + print the matrix + emit the adoption event. On explicit
|
|
169
|
-
* no: record the decline + emit (a decline is an adoption signal). On cancel
|
|
170
|
-
* (ctrl-C): skip silently without recording — a cancel is not a decline.
|
|
171
|
-
*/
|
|
172
|
-
async function offerMcpInstall(signal) {
|
|
173
|
-
if (!isPromptAllowed())
|
|
174
|
-
return; // the entire mode gate (CI / agent / non-TTY)
|
|
175
|
-
if (isJsonMode())
|
|
176
|
-
return; // never prompt on the machine-readable path (e.g. `install --json` on a TTY)
|
|
177
|
-
const { declined } = await getMcpAskState();
|
|
178
|
-
if (declined)
|
|
179
|
-
return; // decline is absolute
|
|
180
|
-
const targets = await detectInstallTargets();
|
|
181
|
-
if (targets.length === 0)
|
|
182
|
-
return; // nothing to offer
|
|
183
|
-
const names = targets.map((t) => t.displayName).join(', ');
|
|
184
|
-
const offerStartedAt = Date.now();
|
|
185
|
-
// The deadline signal aborts a hung/unanswered prompt: clack resolves it as
|
|
186
|
-
// a cancel and releases stdin so the process can exit.
|
|
187
|
-
const answer = await clack.confirm({
|
|
188
|
-
message: `Add the WorkOS MCP server to ${names}? Your coding agent gets tools to manage WorkOS resources (you'll authorize via OAuth on first use).`,
|
|
189
|
-
signal,
|
|
190
|
-
});
|
|
191
|
-
// Cancel (ctrl-C or deadline abort) is not a decline — skip silently, ask
|
|
192
|
-
// again next time.
|
|
193
|
-
if (clack.isCancel(answer))
|
|
194
|
-
return;
|
|
195
|
-
// Adoption events are queued command events, NOT capture(): the installer
|
|
196
|
-
// session has already shut down by the time this offer runs (run-with-core
|
|
197
|
-
// fires session.end in its finally), so folded tags would never ship. A
|
|
198
|
-
// queued event rides the CLI's unconditional final flush (bin.ts) and the
|
|
199
|
-
// store-forward exit handler covers anything the flush misses.
|
|
200
|
-
if (!answer) {
|
|
201
|
-
// Record the decline BEFORE anything else so a later crash can't re-ask.
|
|
202
|
-
await recordMcpDeclined();
|
|
203
|
-
// A decline is a completed interaction, not an error: success stays true.
|
|
204
|
-
analytics.emitCommandEvent('mcp offer', Date.now() - offerStartedAt, true, {
|
|
205
|
-
extraAttributes: {
|
|
206
|
-
'mcp.entry_point': 'install-flow',
|
|
207
|
-
'mcp.accepted': false,
|
|
208
|
-
'mcp.agents_installed': '',
|
|
209
|
-
'mcp.agents_failed': '',
|
|
210
|
-
},
|
|
211
|
-
});
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
// The user submitted right as the deadline fired: the outer flow has already
|
|
215
|
-
// moved on, so don't start install work it will never report on.
|
|
216
|
-
if (signal.aborted)
|
|
217
|
-
return;
|
|
218
|
-
const results = [];
|
|
219
|
-
for (const target of targets) {
|
|
220
|
-
results.push(await target.add());
|
|
221
|
-
}
|
|
222
|
-
printInstallMatrix(results);
|
|
223
|
-
const installed = results
|
|
224
|
-
.filter((r) => r.outcome === 'installed' || r.outcome === 'already-installed')
|
|
225
|
-
.map((r) => r.agent);
|
|
226
|
-
const failed = results.filter((r) => r.outcome === 'failed').map((r) => r.agent);
|
|
227
|
-
// success=false when any agent failed, so the offer surfaces as an error
|
|
228
|
-
// span while mcp.agents_failed carries which ones.
|
|
229
|
-
analytics.emitCommandEvent('mcp offer', Date.now() - offerStartedAt, failed.length === 0, {
|
|
230
|
-
extraAttributes: {
|
|
231
|
-
'mcp.entry_point': 'install-flow',
|
|
232
|
-
'mcp.accepted': true,
|
|
233
|
-
'mcp.agents_installed': installed.join(','),
|
|
234
|
-
'mcp.agents_failed': failed.join(','),
|
|
235
|
-
},
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Offer to install the WorkOS MCP server at the end of `workos install`.
|
|
240
|
-
*
|
|
241
|
-
* Wraps offerMcpInstall best-effort: a try/catch AND a 30s deadline so the
|
|
242
|
-
* offer can never throw into, wedge, or fail the install flow. The deadline
|
|
243
|
-
* aborts the pending prompt (AbortSignal → clack cancel, which releases stdin);
|
|
244
|
-
* the race is a backstop in case the flow is wedged somewhere that can't be
|
|
245
|
-
* aborted (client shell-outs are separately bounded by their exec timeouts).
|
|
246
|
-
* `workos install` has already succeeded by the time this runs.
|
|
247
|
-
*/
|
|
248
|
-
export async function maybeOfferMcpInstall(_opts) {
|
|
249
|
-
let timeoutHandle;
|
|
250
|
-
const deadline = new AbortController();
|
|
251
|
-
try {
|
|
252
|
-
const timeout = new Promise((resolve) => {
|
|
253
|
-
timeoutHandle = setTimeout(() => {
|
|
254
|
-
deadline.abort();
|
|
255
|
-
resolve();
|
|
256
|
-
}, MCP_OFFER_TIMEOUT_MS);
|
|
257
|
-
// Don't keep the event loop alive on this timer — the process should exit
|
|
258
|
-
// as soon as everything else settles.
|
|
259
|
-
timeoutHandle.unref?.();
|
|
260
|
-
});
|
|
261
|
-
await Promise.race([offerMcpInstall(deadline.signal), timeout]);
|
|
262
|
-
}
|
|
263
|
-
catch {
|
|
264
|
-
// The MCP offer must never fail or block `workos install`.
|
|
265
|
-
}
|
|
266
|
-
finally {
|
|
267
|
-
if (timeoutHandle)
|
|
268
|
-
clearTimeout(timeoutHandle);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
/** Reset per-session banner state (for testing). */
|
|
272
|
-
export function resetMcpNoticeState() {
|
|
273
|
-
bannerShownThisSession = false;
|
|
274
|
-
}
|
|
275
|
-
//# sourceMappingURL=mcp-notice.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-notice.js","sourceRoot":"","sources":["../../src/lib/mcp-notice.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP-install onboarding surfaces + their shared gate state.\n *\n * One module owns all automatic-ask state so the install-flow prompt and the\n * one-time banner can't drift apart. The decline contract is absolute: any\n * explicit \"no\" records `promptDeclined` and no automatic surface ever asks\n * again — `workos mcp install` stays available manually.\n *\n * Mirrors telemetry-notice.ts: persisted shown/declined state in the plain\n * prefs store, mode-gated display, and a never-throws contract so a notice can\n * never block or fail a command. The mode gate is the CLI's interaction-mode\n * system (isPromptAllowed / isHumanMode), which already folds in CI markers,\n * agent markers, and TTY state — non-TTY safety comes from using it.\n */\n\nimport chalk from 'chalk';\nimport clack from '../utils/clack.js';\nimport { isHumanMode, isPromptAllowed } from '../utils/interaction-mode.js';\nimport { isJsonMode } from '../utils/output.js';\nimport { renderStderrBox } from '../utils/box.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\nimport { analytics } from '../utils/analytics.js';\nimport { loadPreferences, savePreferences } from './preferences.js';\nimport { detectMcpClients, type McpClientResult, type McpClientTarget } from './mcp-clients.js';\nimport { hasStartupNoticeShown, markStartupNoticeShown } from './startup-notice-gate.js';\n\nexport type McpAskState = { declined: boolean; bannerShown: boolean };\n\n/**\n * Ceiling on the whole install-flow offer so a wedged prompt can never hold up\n * `workos install`. The deadline actively aborts the pending clack prompt (via\n * AbortSignal) — clack's cancel path releases stdin and restores raw mode, so\n * the process can actually exit; a race alone would leave the prompt's stdin\n * handle keeping the event loop alive. Mirrors login.ts's\n * SKILL_INSTALL_TIMEOUT_MS.\n */\nexport const MCP_OFFER_TIMEOUT_MS = 30 * 1000;\n\nlet bannerShownThisSession = false;\n\n/** Human phrasing for each install outcome shown in the accept matrix. */\nconst OUTCOME_LABEL: Record<McpClientResult['outcome'], string> = {\n installed: 'installed',\n 'already-installed': 'already installed',\n removed: 'removed',\n 'not-installed': 'not installed',\n skipped: 'skipped',\n failed: 'failed',\n};\n\n/**\n * Read the persisted automatic-ask state. Never throws — a missing/corrupt\n * prefs file degrades to \"nothing recorded\" so gating still works in-memory.\n */\nexport async function getMcpAskState(): Promise<McpAskState> {\n try {\n const prefs = await loadPreferences();\n return {\n declined: prefs.mcp?.promptDeclined === true,\n bannerShown: Boolean(prefs.mcp?.bannerShownAt),\n };\n } catch {\n return { declined: false, bannerShown: false };\n }\n}\n\n/**\n * Record an explicit decline. Absolute and permanent for automatic surfaces.\n * Write failures are swallowed: gating degrades to per-run memory, never\n * crashes a command.\n */\nexport async function recordMcpDeclined(): Promise<void> {\n try {\n savePreferences({ mcp: { promptDeclined: true } });\n } catch {\n // Swallow — a read-only prefs file must never break a command.\n }\n}\n\n/** Record that the one-time banner was shown, stamping the current time. */\nexport async function recordMcpBannerShown(): Promise<void> {\n try {\n savePreferences({ mcp: { bannerShownAt: new Date().toISOString() } });\n } catch {\n // Swallow — see recordMcpDeclined.\n }\n}\n\n/**\n * The detected agents that would actually receive an install: available on this\n * machine AND missing the WorkOS server. Empty when there is nothing to offer.\n * Never throws — detection failure yields an empty set.\n */\nasync function detectInstallTargets(): Promise<McpClientTarget[]> {\n try {\n const clients = await detectMcpClients();\n if (clients.length === 0) return [];\n const installed = await Promise.all(clients.map((c) => c.isInstalled()));\n return clients.filter((_, i) => !installed[i]);\n } catch {\n return [];\n }\n}\n\n/**\n * Would an automatic ask be appropriate right now? True only when the user has\n * not declined AND at least one detected agent lacks the server. Does NOT gate\n * on interaction mode — callers add that (isPromptAllowed for the prompt,\n * isHumanMode for the banner). Checks `declined` first so declined machines\n * never pay for the client shell-outs.\n */\nexport async function isAutoAskEligible(): Promise<boolean> {\n const { declined } = await getMcpAskState();\n if (declined) return false;\n const targets = await detectInstallTargets();\n return targets.length > 0;\n}\n\n/**\n * One-time stderr banner nudging the user toward `workos mcp install`. Shown at\n * most once per machine, only on a normal human-mode run, and never when an\n * earlier startup notice already fired this run (telemetry notice and unclaimed\n * warning take precedence). Records `bannerShownAt` before printing —\n * shown-once beats seen-once (a lost banner is fine; a nag loop is not). Never\n * throws.\n */\nexport async function maybeShowMcpNotice(): Promise<void> {\n try {\n if (bannerShownThisSession) return;\n if (!isHumanMode()) return; // suppress in agent / CI / non-TTY\n if (isJsonMode()) return; // never on the machine-readable path\n if (hasStartupNoticeShown()) return; // one-notice-per-run cap; telemetry/unclaimed win\n const { bannerShown } = await getMcpAskState();\n if (bannerShown) return; // already shown once, ever\n if (!(await isAutoAskEligible())) return; // declined, or nothing to offer\n\n // Claim the slot + persist BEFORE printing: a lost banner beats a nag loop.\n bannerShownThisSession = true;\n markStartupNoticeShown();\n await recordMcpBannerShown();\n\n // Impression event. Queued (not capture()d) so it rides the CLI's final\n // flush; capture() only folds session tags and no session exists here.\n analytics.emitCommandEvent('mcp offer', 0, true, {\n extraAttributes: { 'mcp.entry_point': 'banner', 'mcp.shown': true },\n });\n\n const cmd = chalk.cyan(formatWorkOSCommand('mcp install'));\n const inner = ` ${chalk.cyan('ℹ')} New: connect your coding agent to WorkOS. Run ${cmd} to add the WorkOS MCP server (Claude Code, Codex, Cursor). `;\n renderStderrBox(inner, chalk.cyan);\n } catch {\n // Never block command startup.\n }\n}\n\n/** Emit the per-agent install matrix (human mode) without ever exiting. */\nfunction printInstallMatrix(results: McpClientResult[]): void {\n for (const r of results) {\n const line = `${r.displayName}: ${OUTCOME_LABEL[r.outcome]}`;\n if (r.outcome === 'failed') {\n clack.log.error(r.error ? `${line} — ${r.error}` : line);\n } else {\n clack.log.success(line);\n }\n }\n}\n\n/**\n * The real install-flow offer. Self-gating: renders nothing unless prompting is\n * allowed, the user hasn't declined, and there is at least one agent to install\n * to. On yes: install + print the matrix + emit the adoption event. On explicit\n * no: record the decline + emit (a decline is an adoption signal). On cancel\n * (ctrl-C): skip silently without recording — a cancel is not a decline.\n */\nasync function offerMcpInstall(signal: AbortSignal): Promise<void> {\n if (!isPromptAllowed()) return; // the entire mode gate (CI / agent / non-TTY)\n if (isJsonMode()) return; // never prompt on the machine-readable path (e.g. `install --json` on a TTY)\n const { declined } = await getMcpAskState();\n if (declined) return; // decline is absolute\n const targets = await detectInstallTargets();\n if (targets.length === 0) return; // nothing to offer\n\n const names = targets.map((t) => t.displayName).join(', ');\n const offerStartedAt = Date.now();\n // The deadline signal aborts a hung/unanswered prompt: clack resolves it as\n // a cancel and releases stdin so the process can exit.\n const answer = await clack.confirm({\n message: `Add the WorkOS MCP server to ${names}? Your coding agent gets tools to manage WorkOS resources (you'll authorize via OAuth on first use).`,\n signal,\n });\n\n // Cancel (ctrl-C or deadline abort) is not a decline — skip silently, ask\n // again next time.\n if (clack.isCancel(answer)) return;\n\n // Adoption events are queued command events, NOT capture(): the installer\n // session has already shut down by the time this offer runs (run-with-core\n // fires session.end in its finally), so folded tags would never ship. A\n // queued event rides the CLI's unconditional final flush (bin.ts) and the\n // store-forward exit handler covers anything the flush misses.\n if (!answer) {\n // Record the decline BEFORE anything else so a later crash can't re-ask.\n await recordMcpDeclined();\n // A decline is a completed interaction, not an error: success stays true.\n analytics.emitCommandEvent('mcp offer', Date.now() - offerStartedAt, true, {\n extraAttributes: {\n 'mcp.entry_point': 'install-flow',\n 'mcp.accepted': false,\n 'mcp.agents_installed': '',\n 'mcp.agents_failed': '',\n },\n });\n return;\n }\n\n // The user submitted right as the deadline fired: the outer flow has already\n // moved on, so don't start install work it will never report on.\n if (signal.aborted) return;\n\n const results: McpClientResult[] = [];\n for (const target of targets) {\n results.push(await target.add());\n }\n printInstallMatrix(results);\n\n const installed = results\n .filter((r) => r.outcome === 'installed' || r.outcome === 'already-installed')\n .map((r) => r.agent);\n const failed = results.filter((r) => r.outcome === 'failed').map((r) => r.agent);\n // success=false when any agent failed, so the offer surfaces as an error\n // span while mcp.agents_failed carries which ones.\n analytics.emitCommandEvent('mcp offer', Date.now() - offerStartedAt, failed.length === 0, {\n extraAttributes: {\n 'mcp.entry_point': 'install-flow',\n 'mcp.accepted': true,\n 'mcp.agents_installed': installed.join(','),\n 'mcp.agents_failed': failed.join(','),\n },\n });\n}\n\n/**\n * Offer to install the WorkOS MCP server at the end of `workos install`.\n *\n * Wraps offerMcpInstall best-effort: a try/catch AND a 30s deadline so the\n * offer can never throw into, wedge, or fail the install flow. The deadline\n * aborts the pending prompt (AbortSignal → clack cancel, which releases stdin);\n * the race is a backstop in case the flow is wedged somewhere that can't be\n * aborted (client shell-outs are separately bounded by their exec timeouts).\n * `workos install` has already succeeded by the time this runs.\n */\nexport async function maybeOfferMcpInstall(_opts: { entryPoint: 'install-flow' }): Promise<void> {\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const deadline = new AbortController();\n try {\n const timeout = new Promise<void>((resolve) => {\n timeoutHandle = setTimeout(() => {\n deadline.abort();\n resolve();\n }, MCP_OFFER_TIMEOUT_MS);\n // Don't keep the event loop alive on this timer — the process should exit\n // as soon as everything else settles.\n timeoutHandle.unref?.();\n });\n await Promise.race([offerMcpInstall(deadline.signal), timeout]);\n } catch {\n // The MCP offer must never fail or block `workos install`.\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n}\n\n/** Reset per-session banner state (for testing). */\nexport function resetMcpNoticeState(): void {\n bannerShownThisSession = false;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clack-utils.js","sourceRoot":"","sources":["../../src/utils/clack-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport { join } from 'node:path';\n\nimport chalk from 'chalk';\nimport { traceStep } from '../telemetry.js';\nimport { debug } from './debug.js';\nimport { parseEnvFile } from './env-parser.js';\nimport { type PackageDotJson, hasPackageInstalled } from './package-json.js';\nimport { type PackageManager, detectAllPackageManagers, packageManagers, NPM as npm } from './package-manager.js';\nimport { fulfillsVersionRange } from './semver.js';\nimport type { InstallerOptions } from './types.js';\nimport { getPackageVersion } from './package-json.js';\nimport { ISSUES_URL, type Integration } from '../lib/constants.js';\nimport { analytics } from './analytics.js';\nimport clack from './clack.js';\nimport { INTEGRATION_CONFIG } from '../lib/config.js';\nimport { SPAWN_OPTS } from './platform.js';\n\n/**\n * Redact sensitive info (API keys, client secrets) from a string.\n */\nexport function redactSensitiveInfo(str: string): string {\n // Redact WorkOS API keys (sk_...), client secrets, etc.\n return str.replace(/sk_[a-zA-Z0-9]+/g, 'sk_***').replace(/client_[a-zA-Z0-9]{20,}/g, 'client_***');\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n gitignore: boolean;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n\n likelyAlreadyHasUrl?(contents: string): boolean;\n urlContent?(url: string): string;\n}\n\nexport interface CliSetupConfigContent {\n authToken: string;\n org?: string;\n project?: string;\n url?: string;\n}\n\nexport async function abort(message?: string, status?: number): Promise<never> {\n await analytics.shutdown('cancelled');\n\n clack.outro(message ?? 'Installer setup cancelled.');\n return process.exit(status ?? 1);\n}\n\nexport async function abortIfCancelled<T>(\n input: T | Promise<T>,\n integration?: Integration,\n): Promise<Exclude<T, symbol>> {\n await analytics.shutdown('cancelled');\n const resolvedInput = await input;\n\n if (\n clack.isCancel(resolvedInput) ||\n (typeof resolvedInput === 'symbol' && resolvedInput.description === 'clack:cancel')\n ) {\n const docsUrl = integration ? INTEGRATION_CONFIG[integration].docsUrl : 'https://workos.com/docs/user-management';\n\n clack.cancel(\n `Installer setup cancelled. You can read the documentation for ${\n integration ?? 'WorkOS AuthKit'\n } at ${chalk.cyan(docsUrl)} to continue with the setup manually.`,\n );\n process.exit(0);\n } else {\n return input as Exclude<T, symbol>;\n }\n}\n\nexport function printWelcome(options: { wizardName: string; message?: string }): void {\n // eslint-disable-next-line no-console\n console.log('');\n clack.intro(chalk.inverse(` ${options.wizardName} `));\n\n const welcomeText =\n options.message ||\n `The ${options.wizardName} will help you set up WorkOS AuthKit for your application.\\nThank you for using WorkOS AuthKit :)`;\n\n clack.note(welcomeText);\n}\n\nexport async function confirmContinueIfNoOrDirtyGitRepo(options: Pick<InstallerOptions, 'ci'>): Promise<void> {\n return traceStep('check-git-status', async () => {\n if (!isInGitRepo()) {\n // CI mode: auto-continue without git\n const continueWithoutGit = options.ci\n ? true\n : await abortIfCancelled(\n clack.confirm({\n message:\n 'You are not inside a git repository. The installer will create and update files. Do you want to continue anyway?',\n }),\n );\n\n analytics.setTag('continue-without-git', continueWithoutGit);\n\n if (!continueWithoutGit) {\n await abort(undefined, 0);\n }\n // return early to avoid checking for uncommitted files\n return;\n }\n\n const uncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles();\n if (uncommittedOrUntrackedFiles.length) {\n // CI mode: auto-continue with dirty repo\n if (options.ci) {\n clack.log.info(`CI mode: continuing with uncommitted/untracked files in repo`);\n analytics.setTag('continue-with-dirty-repo', true);\n return;\n }\n\n clack.log.warn(\n `You have uncommitted or untracked files in your repo:\n\n${uncommittedOrUntrackedFiles.join('\\n')}\n\nThe installer will create and update files.`,\n );\n const continueWithDirtyRepo = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n\n analytics.setTag('continue-with-dirty-repo', continueWithDirtyRepo);\n\n if (!continueWithDirtyRepo) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport function isInGitRepo() {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getUncommittedOrUntrackedFiles(): string[] {\n try {\n const gitStatus = childProcess\n .execSync('git status --porcelain=v1', {\n // we only care about stdout\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString();\n\n const files = gitStatus\n .split(os.EOL)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((f) => `- ${f.split(/\\s+/)[1]}`);\n\n return files;\n } catch {\n return [];\n }\n}\n\nexport async function askForItemSelection(items: string[], message: string): Promise<{ value: string; index: number }> {\n const selection = await abortIfCancelled<{ value: string; index: number } | symbol>(\n clack.select({\n maxItems: 12,\n message: message,\n options: items.map((item, index) => {\n return {\n value: { value: item, index: index },\n label: item,\n };\n }),\n }),\n );\n\n return selection as { value: string; index: number };\n}\n\nexport async function confirmContinueIfPackageVersionNotSupported({\n packageId,\n packageName,\n packageVersion,\n acceptableVersions,\n note,\n}: {\n packageId: string;\n packageName: string;\n packageVersion: string;\n acceptableVersions: string;\n note?: string;\n}): Promise<void> {\n return traceStep(`check-package-version`, async () => {\n analytics.setTag(`${packageName.toLowerCase()}-version`, packageVersion);\n const isSupportedVersion = fulfillsVersionRange({\n acceptableVersions,\n version: packageVersion,\n canBeLatest: true,\n });\n\n if (isSupportedVersion) {\n analytics.setTag(`${packageName.toLowerCase()}-supported`, true);\n return;\n }\n\n clack.log.warn(\n `You have an unsupported version of ${packageName} installed:\n\n ${packageId}@${packageVersion}`,\n );\n\n clack.note(note ?? `Please upgrade to ${acceptableVersions} if you wish to use the WorkOS AuthKit installer.`);\n const continueWithUnsupportedVersion = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n analytics.setTag(`${packageName.toLowerCase()}-continue-with-unsupported-version`, continueWithUnsupportedVersion);\n\n if (!continueWithUnsupportedVersion) {\n await abort(undefined, 0);\n }\n });\n}\n\nexport async function isReact19Installed({ installDir }: Pick<InstallerOptions, 'installDir'>): Promise<boolean> {\n try {\n const packageJson = await getPackageDotJson({ installDir });\n const reactVersion = getPackageVersion('react', packageJson);\n\n if (!reactVersion) {\n return false;\n }\n\n return fulfillsVersionRange({\n version: reactVersion,\n acceptableVersions: '>=19.0.0',\n canBeLatest: true,\n });\n } catch {\n return false;\n }\n}\n\n/**\n * Installs or updates a package with the user's package manager.\n *\n * IMPORTANT: This function modifies the `package.json`! Be sure to re-read\n * it if you make additional modifications to it after calling this function!\n */\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n askBeforeUpdating = true,\n packageNameDisplayLabel,\n packageManager,\n forceInstall = false,\n integration,\n installDir,\n}: {\n /** The string that is passed to the package manager CLI as identifier to install (e.g. `@workos-inc/authkit-nextjs`, or `@workos-inc/authkit-nextjs@^2.0.0`) */\n packageName: string;\n alreadyInstalled: boolean;\n askBeforeUpdating?: boolean;\n /** Overrides what is shown in the installation logs in place of the `packageName` option. Useful if the `packageName` is ugly */\n packageNameDisplayLabel?: string;\n packageManager?: PackageManager;\n /** Add force install flag to command to skip install precondition fails */\n forceInstall?: boolean;\n /** The integration that is being used */\n integration?: string;\n /** The directory to install the package in */\n installDir: string;\n}): Promise<{ packageManager?: PackageManager }> {\n return traceStep('install-package', async () => {\n if (alreadyInstalled && askBeforeUpdating) {\n const shouldUpdatePackage = await abortIfCancelled(\n clack.confirm({\n message: `The ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} package is already installed. Do you want to update it to the latest version?`,\n }),\n );\n\n if (!shouldUpdatePackage) {\n return {};\n }\n }\n\n const sdkInstallSpinner = clack.spinner();\n\n const pkgManager = packageManager || (await getPackageManager({ installDir }));\n\n // Most packages aren't compatible with React 19 yet, skip strict peer dependency checks if needed.\n const isReact19 = await isReact19Installed({ installDir });\n const legacyPeerDepsFlag = isReact19 && pkgManager.name === 'npm' ? '--legacy-peer-deps' : '';\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n try {\n await new Promise<void>((resolve, reject) => {\n const [cmd, ...baseArgs] = pkgManager.installCommand.split(' ');\n const args = [\n ...baseArgs,\n packageName,\n ...pkgManager.flags.split(/\\s+/).filter(Boolean),\n ...(forceInstall && pkgManager.forceInstallFlag ? pkgManager.forceInstallFlag.split(/\\s+/) : []),\n ...(legacyPeerDepsFlag ? [legacyPeerDepsFlag] : []),\n ];\n const proc = childProcess.spawn(cmd, args, { cwd: installDir, ...SPAWN_OPTS });\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n proc.on('close', (code) => {\n if (code !== 0) {\n fs.writeFileSync(\n join(process.cwd(), `workos-installation-error-${Date.now()}.log`),\n JSON.stringify({\n stdout: redactSensitiveInfo(stdout),\n stderr: redactSensitiveInfo(stderr),\n }),\n { encoding: 'utf8' },\n );\n reject(new Error(`${cmd} exited with code ${code}\\n${stderr}`));\n } else {\n resolve();\n }\n });\n proc.on('error', reject);\n });\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n `The installer has created an \\`workos-installation-error-*.log\\` file. If you think this issue is caused by the WorkOS AuthKit installer, create an issue on GitHub and include the log file's content:\\n${ISSUES_URL}`,\n )}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n analytics.capture('installer interaction', {\n action: 'package installed',\n package_name: packageName,\n package_manager: pkgManager.name,\n integration,\n });\n\n return { packageManager: pkgManager };\n });\n}\n\n/**\n * Checks if @param packageId is listed as a dependency in @param packageJson.\n * If not, it will ask users if they want to continue without the package.\n *\n * Use this function to check if e.g. a the framework of the SDK is installed\n *\n * @param packageJson the package.json object\n * @param packageId the npm name of the package\n * @param packageName a human readable name of the package\n */\nexport async function ensurePackageIsInstalled(\n packageJson: PackageDotJson,\n packageId: string,\n packageName: string,\n options?: Pick<InstallerOptions, 'dashboard'>,\n): Promise<void> {\n return traceStep('ensure-package-installed', async () => {\n const installed = hasPackageInstalled(packageId, packageJson);\n\n analytics.setTag(`${packageName.toLowerCase()}-installed`, installed);\n\n if (!installed) {\n // In dashboard mode, auto-continue (integration was already detected)\n if (options?.dashboard) {\n return;\n }\n\n const continueWithoutPackage = await abortIfCancelled(\n clack.confirm({\n message: `${packageName} does not seem to be installed. Do you still want to continue?`,\n initialValue: false,\n }),\n );\n\n if (!continueWithoutPackage) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport async function getPackageDotJson({ installDir }: Pick<InstallerOptions, 'installDir'>): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises.readFile(join(installDir, 'package.json'), 'utf8').catch(() => {\n clack.log.error('Could not find package.json. Make sure to run the installer in the root of your app!');\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n clack.log.error(`Unable to parse your ${chalk.cyan('package.json')}. Make sure it has a valid format!`);\n\n await abort();\n }\n\n return packageJson || {};\n}\n\nexport async function updatePackageDotJson(\n packageDotJson: PackageDotJson,\n { installDir }: Pick<InstallerOptions, 'installDir'>,\n): Promise<void> {\n try {\n await fs.promises.writeFile(\n join(installDir, 'package.json'),\n // TODO: maybe figure out the original indentation\n JSON.stringify(packageDotJson, null, 2),\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n } catch {\n clack.log.error(`Unable to update your ${chalk.cyan('package.json')}.`);\n\n await abort();\n }\n}\n\nexport async function getPackageManager(\n options: Pick<InstallerOptions, 'installDir'> & { ci?: boolean },\n): Promise<PackageManager> {\n const detectedPackageManagers = detectAllPackageManagers({\n installDir: options.installDir,\n });\n\n // If exactly one package manager detected, use it automatically\n if (detectedPackageManagers.length === 1) {\n const detectedPackageManager = detectedPackageManagers[0];\n analytics.setTag('package-manager', detectedPackageManager.name);\n return detectedPackageManager;\n }\n\n // CI mode: auto-select first detected or npm\n if (options.ci) {\n const selectedPackageManager = detectedPackageManagers.length > 0 ? detectedPackageManagers[0] : npm;\n clack.log.info(`CI mode: auto-selected package manager: ${selectedPackageManager.label}`);\n analytics.setTag('package-manager', selectedPackageManager.name);\n return selectedPackageManager;\n }\n\n // If multiple or no package managers detected, prompt user to select\n const pkgOptions = detectedPackageManagers.length > 0 ? detectedPackageManagers : packageManagers;\n\n const message =\n detectedPackageManagers.length > 1\n ? 'Multiple package managers detected. Please select one:'\n : 'Please select your package manager.';\n\n const selectedPackageManager = await abortIfCancelled<PackageManager | symbol>(\n clack.select({\n message,\n options: pkgOptions.map((packageManager) => ({\n value: packageManager,\n label: packageManager.label,\n })),\n }),\n );\n\n analytics.setTag('package-manager', (selectedPackageManager as PackageManager).name);\n return selectedPackageManager as PackageManager;\n}\n\nexport function isUsingTypeScript({ installDir }: Pick<InstallerOptions, 'installDir'>) {\n try {\n return fs.existsSync(join(installDir, 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Get WorkOS credentials (API Key and Client ID) from user or CLI options\n * @param requireApiKey - Whether API key is needed (false for client-only SDKs like React, Vanilla JS)\n */\nexport async function getOrAskForWorkOSCredentials(\n _options: Pick<InstallerOptions, 'ci' | 'apiKey' | 'clientId' | 'installDir' | 'dashboard'>,\n requireApiKey: boolean = true,\n): Promise<{\n apiKey: string;\n clientId: string;\n}> {\n let apiKey = _options.apiKey;\n let clientId = _options.clientId;\n\n // If credentials provided via CLI (e.g., CI mode or dashboard mode), use them\n if ((!requireApiKey || apiKey) && clientId) {\n // Only log in non-dashboard mode\n if (!_options.dashboard) {\n clack.log.info('Using provided WorkOS credentials');\n }\n return { apiKey: apiKey || '', clientId };\n }\n\n // Check if credentials already exist in .env.local\n const envPath = join(_options.installDir, '.env.local');\n if (fs.existsSync(envPath)) {\n try {\n const envContent = fs.readFileSync(envPath, 'utf-8');\n const envVars = parseEnvFile(envContent);\n\n const existingApiKey = envVars.WORKOS_API_KEY;\n const existingClientId = envVars.WORKOS_CLIENT_ID;\n\n // Use existing credentials if both are present (or API key not required)\n if (existingClientId && (!requireApiKey || existingApiKey)) {\n if (!_options.dashboard) {\n clack.log.success(`Found existing WorkOS credentials in .env.local`);\n }\n return {\n apiKey: existingApiKey || '',\n clientId: existingClientId,\n };\n }\n } catch (error) {\n // If we can't read/parse .env.local, just continue to prompt\n debug('Failed to read .env.local:', error);\n }\n }\n\n // Otherwise, prompt user for credentials\n clack.log.step(`Get your credentials from ${chalk.cyan('https://dashboard.workos.com')}`);\n\n if (requireApiKey && !apiKey) {\n clack.log.info(`${chalk.dim('ℹ️ Your API key will be hidden for security and saved to .env.local')}`);\n apiKey = (await abortIfCancelled(\n clack.password({\n message: 'Enter your WorkOS API Key',\n validate: (value) => {\n if (!value) return 'API Key is required';\n if (!value.startsWith('sk_')) {\n return 'API Key should start with sk_';\n }\n return undefined;\n },\n }),\n )) as string;\n } else if (!requireApiKey) {\n clack.log.info(`${chalk.dim('ℹ️ Client-only SDK - API key not required')}`);\n }\n\n if (!clientId) {\n clientId = (await abortIfCancelled(\n clack.text({\n message: 'Enter your WorkOS Client ID',\n placeholder: 'client_...',\n validate: (value) => {\n if (!value) return 'Client ID is required';\n if (!value.startsWith('client_')) {\n return 'Client ID should start with client_';\n }\n return undefined;\n },\n }),\n )) as string;\n }\n\n return { apiKey: apiKey || '', clientId };\n}\n\n/**\n * Fetch project data using a personal API key (for CI mode)\n */\n"]}
|
package/dist/utils/clack.d.ts
DELETED
package/dist/utils/clack.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as clack from '@clack/prompts';
|
|
2
|
-
// Dashboard mode flag - when true, suppress console output
|
|
3
|
-
let dashboardMode = false;
|
|
4
|
-
export function setDashboardMode(enabled) {
|
|
5
|
-
dashboardMode = enabled;
|
|
6
|
-
}
|
|
7
|
-
export function isDashboardMode() {
|
|
8
|
-
return dashboardMode;
|
|
9
|
-
}
|
|
10
|
-
// Create a proxy that suppresses log output in dashboard mode
|
|
11
|
-
const clackProxy = new Proxy(clack, {
|
|
12
|
-
get(target, prop) {
|
|
13
|
-
const value = target[prop];
|
|
14
|
-
// Suppress log methods in dashboard mode
|
|
15
|
-
if (prop === 'log' && dashboardMode) {
|
|
16
|
-
return {
|
|
17
|
-
info: () => { },
|
|
18
|
-
success: () => { },
|
|
19
|
-
warn: () => { },
|
|
20
|
-
warning: () => { },
|
|
21
|
-
error: () => { },
|
|
22
|
-
step: () => { },
|
|
23
|
-
message: () => { },
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
// Suppress intro/outro in dashboard mode
|
|
27
|
-
if ((prop === 'intro' || prop === 'outro') && dashboardMode) {
|
|
28
|
-
return () => { };
|
|
29
|
-
}
|
|
30
|
-
return value;
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
export default clackProxy;
|
|
34
|
-
//# sourceMappingURL=clack.js.map
|
package/dist/utils/clack.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clack.js","sourceRoot":"","sources":["../../src/utils/clack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AAExC,2DAA2D;AAC3D,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,aAAa,GAAG,OAAO,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE;IAClC,GAAG,CAAC,MAAM,EAAE,IAAI;QACd,MAAM,KAAK,GAAG,MAAM,CAAC,IAA0B,CAAC,CAAC;QAEjD,yCAAyC;QACzC,IAAI,IAAI,KAAK,KAAK,IAAI,aAAa,EAAE,CAAC;YACpC,OAAO;gBACL,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;gBACd,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;gBACjB,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;gBACd,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;gBACjB,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;gBACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;gBACd,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;aAClB,CAAC;QACJ,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,aAAa,EAAE,CAAC;YAC5D,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC,CAAC;AAEH,eAAe,UAAU,CAAC","sourcesContent":["import * as clack from '@clack/prompts';\n\n// Dashboard mode flag - when true, suppress console output\nlet dashboardMode = false;\n\nexport function setDashboardMode(enabled: boolean): void {\n dashboardMode = enabled;\n}\n\nexport function isDashboardMode(): boolean {\n return dashboardMode;\n}\n\n// Create a proxy that suppresses log output in dashboard mode\nconst clackProxy = new Proxy(clack, {\n get(target, prop) {\n const value = target[prop as keyof typeof clack];\n\n // Suppress log methods in dashboard mode\n if (prop === 'log' && dashboardMode) {\n return {\n info: () => {},\n success: () => {},\n warn: () => {},\n warning: () => {},\n error: () => {},\n step: () => {},\n message: () => {},\n };\n }\n\n // Suppress intro/outro in dashboard mode\n if ((prop === 'intro' || prop === 'outro') && dashboardMode) {\n return () => {};\n }\n\n return value;\n },\n});\n\nexport default clackProxy;\n"]}
|