workos 0.12.2 → 0.12.3
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 +15 -11
- package/dist/commands/auth-status.js +2 -1
- package/dist/commands/auth-status.js.map +1 -1
- package/dist/commands/claim.js +4 -3
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/login.js +3 -2
- package/dist/commands/login.js.map +1 -1
- package/dist/doctor/checks/ai-analysis.js +4 -3
- package/dist/doctor/checks/ai-analysis.js.map +1 -1
- package/dist/lib/adapters/cli-adapter.js +2 -1
- package/dist/lib/adapters/cli-adapter.js.map +1 -1
- package/dist/lib/agent-interface.js +38 -14
- package/dist/lib/agent-interface.js.map +1 -1
- package/dist/lib/credential-proxy.js +2 -1
- package/dist/lib/credential-proxy.js.map +1 -1
- package/dist/lib/device-auth.js +26 -10
- package/dist/lib/device-auth.js.map +1 -1
- package/dist/lib/ensure-auth.js +4 -3
- package/dist/lib/ensure-auth.js.map +1 -1
- package/dist/lib/installer-core.d.ts +3 -3
- package/dist/lib/resolve-install-credentials.js +4 -4
- package/dist/lib/resolve-install-credentials.js.map +1 -1
- package/dist/lib/run-with-core.js +3 -1
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/token-refresh-client.js +2 -1
- package/dist/lib/token-refresh-client.js.map +1 -1
- package/dist/lib/token-refresh.d.ts +1 -1
- package/dist/lib/token-refresh.js +3 -2
- package/dist/lib/token-refresh.js.map +1 -1
- package/dist/utils/command-invocation.d.ts +8 -0
- package/dist/utils/command-invocation.js +17 -0
- package/dist/utils/command-invocation.js.map +1 -0
- package/dist/utils/exit-codes.js +3 -1
- package/dist/utils/exit-codes.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,14 +5,18 @@ WorkOS CLI for installing AuthKit integrations and managing WorkOS resources.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
# Run directly with npx (recommended)
|
|
9
|
-
npx workos
|
|
8
|
+
# Run the installer directly with npx (recommended)
|
|
9
|
+
npx workos@latest install
|
|
10
10
|
|
|
11
11
|
# Or install globally
|
|
12
12
|
npm install -g workos
|
|
13
|
-
workos
|
|
13
|
+
workos install
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
`npx workos@latest install` is recommended because it bypasses stale global shims and older shell-resolved binaries.
|
|
17
|
+
If a global install reports `unknown command "install"`, run the npx command above or reinstall globally and clear your
|
|
18
|
+
shell command cache.
|
|
19
|
+
|
|
16
20
|
## Features
|
|
17
21
|
|
|
18
22
|
- **15 Framework Support:** Next.js, React Router, TanStack Start, React SPA, Vanilla JS, SvelteKit, Node.js (Express), Python (Django), Ruby (Rails), Go, .NET (ASP.NET Core), Kotlin (Spring Boot), Elixir (Phoenix), PHP (Laravel), PHP
|
|
@@ -93,7 +97,7 @@ When you run `workos install` without credentials, the CLI automatically provisi
|
|
|
93
97
|
|
|
94
98
|
```bash
|
|
95
99
|
# Install with zero setup — environment provisioned automatically
|
|
96
|
-
workos install
|
|
100
|
+
npx workos@latest install
|
|
97
101
|
|
|
98
102
|
# Check your environment
|
|
99
103
|
workos env list
|
|
@@ -560,13 +564,13 @@ workos install [options]
|
|
|
560
564
|
|
|
561
565
|
```bash
|
|
562
566
|
# Interactive (recommended)
|
|
563
|
-
npx workos
|
|
567
|
+
npx workos@latest install
|
|
564
568
|
|
|
565
569
|
# Specify framework
|
|
566
|
-
npx workos install --integration react-router
|
|
570
|
+
npx workos@latest install --integration react-router
|
|
567
571
|
|
|
568
572
|
# With visual dashboard (experimental)
|
|
569
|
-
npx workos dashboard
|
|
573
|
+
npx workos@latest dashboard
|
|
570
574
|
|
|
571
575
|
# JSON output (explicit)
|
|
572
576
|
workos org list --json --api-key sk_test_xxx
|
|
@@ -648,13 +652,13 @@ The CLI uses WorkOS Connect OAuth device flow for authentication:
|
|
|
648
652
|
|
|
649
653
|
```bash
|
|
650
654
|
# Login (opens browser for authentication)
|
|
651
|
-
workos auth login
|
|
655
|
+
npx workos@latest auth login
|
|
652
656
|
|
|
653
657
|
# Check current auth status
|
|
654
|
-
workos auth status
|
|
658
|
+
npx workos@latest auth status
|
|
655
659
|
|
|
656
660
|
# Logout (clears stored credentials)
|
|
657
|
-
workos auth logout
|
|
661
|
+
npx workos@latest auth logout
|
|
658
662
|
```
|
|
659
663
|
|
|
660
664
|
OAuth credentials are stored in the system keychain (with `~/.workos/credentials.json` fallback). Access tokens are not persisted long-term for security - users re-authenticate when tokens expire.
|
|
@@ -682,7 +686,7 @@ The installer collects anonymous usage telemetry to help improve the product:
|
|
|
682
686
|
No code, credentials, or personal data is collected. Disable with:
|
|
683
687
|
|
|
684
688
|
```bash
|
|
685
|
-
WORKOS_TELEMETRY=false npx workos
|
|
689
|
+
WORKOS_TELEMETRY=false npx workos@latest install
|
|
686
690
|
```
|
|
687
691
|
|
|
688
692
|
## Logs
|
|
@@ -2,6 +2,7 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { getCredentials, isTokenExpired } from '../lib/credentials.js';
|
|
3
3
|
import { getActiveEnvironment } from '../lib/config-store.js';
|
|
4
4
|
import { isJsonMode, outputJson } from '../utils/output.js';
|
|
5
|
+
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
5
6
|
function formatTimeRemaining(ms) {
|
|
6
7
|
if (ms <= 0)
|
|
7
8
|
return 'expired';
|
|
@@ -23,7 +24,7 @@ export async function runAuthStatus() {
|
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
26
|
console.log(chalk.yellow('Not logged in'));
|
|
26
|
-
console.log(chalk.dim(
|
|
27
|
+
console.log(chalk.dim(`Run \`${formatWorkOSCommand('auth login')}\` to authenticate`));
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
const expired = isTokenExpired(creds);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-status.js","sourceRoot":"","sources":["../../src/commands/auth-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-status.js","sourceRoot":"","sources":["../../src/commands/auth-status.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { getCredentials, isTokenExpired } from '../lib/credentials.js';\nimport { getActiveEnvironment } from '../lib/config-store.js';\nimport { isJsonMode, outputJson } from '../utils/output.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nfunction formatTimeRemaining(ms: number): string {\n if (ms <= 0) return 'expired';\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n if (hours > 0) return `${hours}h ${minutes % 60}m`;\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`;\n return `${seconds}s`;\n}\n\nexport async function runAuthStatus(): Promise<void> {\n const creds = getCredentials();\n const activeEnv = getActiveEnvironment();\n\n if (!creds) {\n if (isJsonMode()) {\n outputJson({ authenticated: false });\n return;\n }\n console.log(chalk.yellow('Not logged in'));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth login')}\\` to authenticate`));\n return;\n }\n\n const expired = isTokenExpired(creds);\n const timeRemaining = creds.expiresAt - Date.now();\n\n if (isJsonMode()) {\n outputJson({\n authenticated: true,\n email: creds.email ?? null,\n userId: creds.userId,\n tokenExpired: expired,\n tokenExpiresAt: new Date(creds.expiresAt).toISOString(),\n tokenExpiresIn: expired ? null : formatTimeRemaining(timeRemaining),\n hasRefreshToken: !!creds.refreshToken,\n activeEnvironment: activeEnv ? { name: activeEnv.name, type: activeEnv.type } : null,\n });\n return;\n }\n\n console.log(chalk.green(`Logged in as ${creds.email ?? creds.userId}`));\n\n if (expired) {\n console.log(chalk.yellow(`Token expired ${formatTimeRemaining(-timeRemaining)} ago`));\n } else {\n console.log(chalk.dim(`Token expires in ${formatTimeRemaining(timeRemaining)}`));\n }\n\n console.log(chalk.dim(`Refresh token: ${creds.refreshToken ? 'present' : 'absent'}`));\n\n if (activeEnv) {\n console.log(chalk.dim(`Environment: ${activeEnv.name} (${activeEnv.type})`));\n }\n}\n"]}
|
package/dist/commands/claim.js
CHANGED
|
@@ -12,6 +12,7 @@ import { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api
|
|
|
12
12
|
import { logInfo, logError } from '../utils/debug.js';
|
|
13
13
|
import { isJsonMode, outputJson, exitWithError } from '../utils/output.js';
|
|
14
14
|
import { sleep } from '../lib/helper-functions.js';
|
|
15
|
+
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
15
16
|
const POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
16
17
|
const POLL_INTERVAL_MS = 5_000; // 5 seconds
|
|
17
18
|
const MAX_CONSECUTIVE_FAILURES = 10;
|
|
@@ -41,7 +42,7 @@ export async function runClaim() {
|
|
|
41
42
|
}
|
|
42
43
|
else {
|
|
43
44
|
clack.log.success('Environment already claimed!');
|
|
44
|
-
clack.log.info(
|
|
45
|
+
clack.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
|
|
45
46
|
}
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
@@ -71,7 +72,7 @@ export async function runClaim() {
|
|
|
71
72
|
if (check.alreadyClaimed) {
|
|
72
73
|
spinner.stop('Environment claimed!');
|
|
73
74
|
markEnvironmentClaimed();
|
|
74
|
-
clack.log.info(
|
|
75
|
+
clack.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
|
|
75
76
|
return;
|
|
76
77
|
}
|
|
77
78
|
consecutiveFailures = 0;
|
|
@@ -83,7 +84,7 @@ export async function runClaim() {
|
|
|
83
84
|
// when the environment is claimed. Safe to promote to sandbox.
|
|
84
85
|
spinner.stop('Claim token is invalid or expired.');
|
|
85
86
|
markEnvironmentClaimed();
|
|
86
|
-
clack.log.warn(
|
|
87
|
+
clack.log.warn(`Run \`${formatWorkOSCommand('auth login')}\` to set up your environment.`);
|
|
87
88
|
return;
|
|
88
89
|
}
|
|
89
90
|
consecutiveFailures++;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claim.js","sourceRoot":"","sources":["../../src/commands/claim.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,KAAK,CAAC;AACvB,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC9G,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"claim.js","sourceRoot":"","sources":["../../src/commands/claim.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `workos env claim` — claim an unclaimed environment.\n *\n * Reads claim token from active environment, generates a nonce via\n * createClaimNonce(), opens browser to dashboard claim URL, and polls\n * until the environment is claimed.\n */\n\nimport open from 'opn';\nimport clack from '../utils/clack.js';\nimport { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';\nimport { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { sleep } from '../lib/helper-functions.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nconst POLL_INTERVAL_MS = 5_000; // 5 seconds\nconst MAX_CONSECUTIVE_FAILURES = 10;\n\n/**\n * Run the claim flow.\n */\nexport async function runClaim(): Promise<void> {\n const activeEnv = getActiveEnvironment();\n\n if (!activeEnv || !isUnclaimedEnvironment(activeEnv)) {\n if (isJsonMode()) {\n outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });\n } else {\n clack.log.info('No unclaimed environment found. Nothing to claim.');\n }\n return;\n }\n\n // claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig\n\n logInfo('[claim] Starting claim flow for environment:', activeEnv.name);\n\n try {\n clack.log.step('Generating claim link...');\n\n const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n\n if (result.alreadyClaimed) {\n markEnvironmentClaimed();\n if (isJsonMode()) {\n outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });\n } else {\n clack.log.success('Environment already claimed!');\n clack.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n }\n return;\n }\n\n const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;\n\n if (isJsonMode()) {\n outputJson({ status: 'claim_url', claimUrl, nonce: result.nonce });\n return;\n }\n\n clack.log.info(`Open this URL to claim your environment:\\n\\n ${claimUrl}`);\n\n try {\n open(claimUrl, { wait: false });\n clack.log.info('Browser opened automatically');\n } catch (openError) {\n logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));\n clack.log.info('Could not open browser — open the URL above manually.');\n }\n\n // Poll for claim completion\n const spinner = clack.spinner();\n spinner.start('Waiting for claim...');\n\n const startTime = Date.now();\n let consecutiveFailures = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(POLL_INTERVAL_MS);\n try {\n const check = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n if (check.alreadyClaimed) {\n spinner.stop('Environment claimed!');\n markEnvironmentClaimed();\n clack.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n return;\n }\n consecutiveFailures = 0;\n } catch (pollError) {\n const statusCode = pollError instanceof UnclaimedEnvApiError ? pollError.statusCode : undefined;\n if (statusCode === 401) {\n // 401 means the server invalidated the claim token — this happens\n // when the environment is claimed. Safe to promote to sandbox.\n spinner.stop('Claim token is invalid or expired.');\n markEnvironmentClaimed();\n clack.log.warn(`Run \\`${formatWorkOSCommand('auth login')}\\` to set up your environment.`);\n return;\n }\n consecutiveFailures++;\n logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');\n if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n spinner.stop('Too many connection failures');\n clack.log.error(\n `Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\\n` +\n `You can also complete the claim at: ${claimUrl}`,\n );\n return;\n }\n if (consecutiveFailures >= 3) {\n spinner.message('Still waiting... (connection issues detected)');\n }\n }\n }\n\n spinner.stop('Claim timed out');\n clack.log.info('Complete the claim in your browser, then run `workos env list` to verify.');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logError('[claim] Error:', message);\n exitWithError({ code: 'claim_failed', message: `Claim failed: ${message}` });\n }\n}\n"]}
|
package/dist/commands/login.js
CHANGED
|
@@ -7,6 +7,7 @@ import { refreshAccessToken } from '../lib/token-refresh-client.js';
|
|
|
7
7
|
import { logInfo, logError } from '../utils/debug.js';
|
|
8
8
|
import { fetchStagingCredentials } from '../lib/staging-api.js';
|
|
9
9
|
import { getConfig, saveConfig } from '../lib/config-store.js';
|
|
10
|
+
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
10
11
|
/**
|
|
11
12
|
* Parse JWT payload
|
|
12
13
|
*/
|
|
@@ -80,7 +81,7 @@ export async function runLogin() {
|
|
|
80
81
|
if (getAccessToken()) {
|
|
81
82
|
const creds = getCredentials();
|
|
82
83
|
console.log(chalk.green(`Already logged in as ${creds?.email ?? 'unknown'}`));
|
|
83
|
-
console.log(chalk.dim(
|
|
84
|
+
console.log(chalk.dim(`Run \`${formatWorkOSCommand('auth logout')}\` to log out`));
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
87
|
// Try to refresh if we have expired credentials with a refresh token
|
|
@@ -93,7 +94,7 @@ export async function runLogin() {
|
|
|
93
94
|
updateTokens(result.accessToken, result.expiresAt, result.refreshToken);
|
|
94
95
|
logInfo('[login] Session refreshed via refresh token');
|
|
95
96
|
console.log(chalk.green(`Already logged in as ${existingCreds.email ?? 'unknown'}`));
|
|
96
|
-
console.log(chalk.dim(
|
|
97
|
+
console.log(chalk.dim(`Run \`${formatWorkOSCommand('auth logout')}\` to log out`));
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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","sourcesContent":["import open from 'opn';\nimport chalk from 'chalk';\nimport clack from '../utils/clack.js';\nimport { saveCredentials, getCredentials, getAccessToken, isTokenExpired, updateTokens } from '../lib/credentials.js';\nimport { getCliAuthClientId, getAuthkitDomain } from '../lib/settings.js';\nimport { refreshAccessToken } from '../lib/token-refresh-client.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { fetchStagingCredentials } from '../lib/staging-api.js';\nimport { getConfig, saveConfig } from '../lib/config-store.js';\nimport type { CliConfig } from '../lib/config-store.js';\n\n/**\n * Parse JWT payload\n */\nfunction parseJwt(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n return JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));\n } catch {\n return null;\n }\n}\n\n/**\n * Extract expiry time from JWT token\n */\nfunction getJwtExpiry(token: string): number | null {\n const payload = parseJwt(token);\n if (!payload || typeof payload.exp !== 'number') return null;\n return payload.exp * 1000;\n}\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\n/**\n * Get Connect OAuth endpoints from AuthKit domain\n */\nfunction getConnectEndpoints() {\n const domain = getAuthkitDomain();\n return {\n deviceAuthorization: `${domain}/oauth2/device_authorization`,\n token: `${domain}/oauth2/token`,\n };\n}\n\ninterface DeviceAuthResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n expires_in: number;\n interval: number;\n}\n\ninterface ConnectTokenResponse {\n access_token: string;\n id_token: string;\n token_type: string;\n expires_in: number;\n refresh_token?: string;\n}\n\ninterface AuthErrorResponse {\n error: string;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Auto-provision a staging environment after login.\n *\n * Fetches staging credentials using the access token, then saves them\n * as a \"staging\" environment in the config store. Non-fatal — logs a\n * hint on failure instead of throwing.\n */\nexport async function provisionStagingEnvironment(accessToken: string): Promise<boolean> {\n try {\n const staging = await fetchStagingCredentials(accessToken);\n\n const config: CliConfig = getConfig() ?? { environments: {} };\n const isFirst = Object.keys(config.environments).length === 0;\n\n config.environments['staging'] = {\n name: 'staging',\n type: 'sandbox',\n apiKey: staging.apiKey,\n clientId: staging.clientId,\n };\n\n if (isFirst || !config.activeEnvironment) {\n config.activeEnvironment = 'staging';\n }\n\n saveConfig(config);\n logInfo('[login] Staging environment auto-provisioned');\n return true;\n } catch (error) {\n logError('[login] Failed to auto-provision staging environment:', error instanceof Error ? error.message : error);\n return false;\n }\n}\n\nexport async function runLogin(): Promise<void> {\n const clientId = getCliAuthClientId();\n\n // Check if already logged in with valid token\n if (getAccessToken()) {\n const creds = getCredentials();\n console.log(chalk.green(`Already logged in as ${creds?.email ?? 'unknown'}`));\n console.log(chalk.dim('Run `workos auth logout` to log out'));\n return;\n }\n\n // Try to refresh if we have expired credentials with a refresh token\n const existingCreds = getCredentials();\n if (existingCreds?.refreshToken && isTokenExpired(existingCreds)) {\n try {\n const authkitDomain = getAuthkitDomain();\n const result = await refreshAccessToken(authkitDomain, clientId);\n if (result.accessToken && result.expiresAt) {\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n logInfo('[login] Session refreshed via refresh token');\n console.log(chalk.green(`Already logged in as ${existingCreds.email ?? 'unknown'}`));\n console.log(chalk.dim('Run `workos auth logout` to log out'));\n return;\n }\n } catch {\n // Refresh failed, proceed with fresh login\n }\n }\n\n clack.log.step('Starting authentication...');\n\n const endpoints = getConnectEndpoints();\n\n const authResponse = await fetch(endpoints.deviceAuthorization, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n client_id: clientId,\n scope: 'openid email staging-environment:credentials:read offline_access',\n }),\n });\n\n if (!authResponse.ok) {\n clack.log.error(`Failed to start authentication: ${authResponse.status}`);\n process.exit(1);\n }\n\n const deviceAuth = (await authResponse.json()) as DeviceAuthResponse;\n const pollIntervalMs = (deviceAuth.interval || 5) * 1000;\n\n clack.log.info(`\\nOpen this URL in your browser:\\n`);\n console.log(` ${deviceAuth.verification_uri}`);\n console.log(`\\nEnter code: ${deviceAuth.user_code}\\n`);\n\n try {\n open(deviceAuth.verification_uri_complete);\n clack.log.info('Browser opened automatically');\n } catch {\n // User can open manually\n }\n\n const spinner = clack.spinner();\n spinner.start('Waiting for authentication...');\n\n const startTime = Date.now();\n let currentInterval = pollIntervalMs;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(currentInterval);\n\n try {\n const tokenResponse = await fetch(endpoints.token, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceAuth.device_code,\n client_id: clientId,\n }),\n });\n\n const data = await tokenResponse.json();\n\n if (tokenResponse.ok) {\n const result = data as ConnectTokenResponse;\n\n // Parse user info from id_token JWT\n const idTokenPayload = parseJwt(result.id_token);\n const userId = (idTokenPayload?.sub as string) || 'unknown';\n const email = (idTokenPayload?.email as string) || undefined;\n\n // Extract actual expiry from access token JWT, fallback to response or 15 min\n const jwtExpiry = getJwtExpiry(result.access_token);\n const expiresAt =\n jwtExpiry ?? (result.expires_in ? Date.now() + result.expires_in * 1000 : Date.now() + 15 * 60 * 1000);\n\n const expiresInSec = Math.round((expiresAt - Date.now()) / 1000);\n\n saveCredentials({\n accessToken: result.access_token,\n expiresAt,\n userId,\n email,\n refreshToken: result.refresh_token,\n });\n\n spinner.stop('Authentication successful!');\n clack.log.success(`Logged in as ${email || userId}`);\n clack.log.info(`Token expires in ${expiresInSec} seconds`);\n\n // Auto-provision staging environment\n const provisioned = await provisionStagingEnvironment(result.access_token);\n if (provisioned) {\n clack.log.success('Staging environment configured automatically');\n } else {\n clack.log.info(chalk.dim('Run `workos env add` to configure an environment manually'));\n }\n return;\n }\n\n const errorData = data as AuthErrorResponse;\n if (errorData.error === 'authorization_pending') continue;\n if (errorData.error === 'slow_down') {\n currentInterval += 5000;\n continue;\n }\n\n spinner.stop('Authentication failed');\n clack.log.error(`Authentication error: ${errorData.error}`);\n process.exit(1);\n } catch {\n continue;\n }\n }\n\n spinner.stop('Authentication timed out');\n clack.log.error('Authentication timed out. Please try again.');\n process.exit(1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,KAAK,CAAC;AACvB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACtH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAa;IAC7B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;AAC5B,CAAC;AAED,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAEnD;;GAEG;AACH,SAAS,mBAAmB;IAC1B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,OAAO;QACL,mBAAmB,EAAE,GAAG,MAAM,8BAA8B;QAC5D,KAAK,EAAE,GAAG,MAAM,eAAe;KAChC,CAAC;AACJ,CAAC;AAuBD,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,WAAmB;IACnE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAc,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAE9D,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG;YAC/B,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC;QAEF,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,CAAC,iBAAiB,GAAG,SAAS,CAAC;QACvC,CAAC;QAED,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,CAAC,8CAA8C,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,QAAQ,CAAC,uDAAuD,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAClH,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAEtC,8CAA8C;IAC9C,IAAI,cAAc,EAAE,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,mBAAmB,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;QACnF,OAAO;IACT,CAAC;IAED,qEAAqE;IACrE,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;IACvC,IAAI,aAAa,EAAE,YAAY,IAAI,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACjE,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3C,YAAY,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;gBACxE,OAAO,CAAC,6CAA6C,CAAC,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,aAAa,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;gBACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,mBAAmB,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;gBACnF,OAAO;YACT,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAE7C,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IAExC,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,mBAAmB,EAAE;QAC9D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,mCAAmC;SACpD;QACD,IAAI,EAAE,IAAI,eAAe,CAAC;YACxB,SAAS,EAAE,QAAQ;YACnB,KAAK,EAAE,kEAAkE;SAC1E,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,CAAuB,CAAC;IACrE,MAAM,cAAc,GAAG,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAEzD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,iBAAiB,UAAU,CAAC,SAAS,IAAI,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC;QAC3C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAE/C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,eAAe,GAAG,cAAc,CAAC;IAErC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;QAChD,MAAM,KAAK,CAAC,eAAe,CAAC,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE;gBACjD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,mCAAmC;iBACpD;gBACD,IAAI,EAAE,IAAI,eAAe,CAAC;oBACxB,UAAU,EAAE,8CAA8C;oBAC1D,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,SAAS,EAAE,QAAQ;iBACpB,CAAC;aACH,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;YAExC,IAAI,aAAa,CAAC,EAAE,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,IAA4B,CAAC;gBAE5C,oCAAoC;gBACpC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAI,cAAc,EAAE,GAAc,IAAI,SAAS,CAAC;gBAC5D,MAAM,KAAK,GAAI,cAAc,EAAE,KAAgB,IAAI,SAAS,CAAC;gBAE7D,8EAA8E;gBAC9E,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBACpD,MAAM,SAAS,GACb,SAAS,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;gBAEzG,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;gBAEjE,eAAe,CAAC;oBACd,WAAW,EAAE,MAAM,CAAC,YAAY;oBAChC,SAAS;oBACT,MAAM;oBACN,KAAK;oBACL,YAAY,EAAE,MAAM,CAAC,aAAa;iBACnC,CAAC,CAAC;gBAEH,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;gBAC3C,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;gBACrD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,YAAY,UAAU,CAAC,CAAC;gBAE3D,qCAAqC;gBACrC,MAAM,WAAW,GAAG,MAAM,2BAA2B,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAC3E,IAAI,WAAW,EAAE,CAAC;oBAChB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;gBACpE,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC,CAAC;gBACzF,CAAC;gBACD,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,IAAyB,CAAC;YAC5C,IAAI,SAAS,CAAC,KAAK,KAAK,uBAAuB;gBAAE,SAAS;YAC1D,IAAI,SAAS,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;gBACpC,eAAe,IAAI,IAAI,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACtC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACzC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC","sourcesContent":["import open from 'opn';\nimport chalk from 'chalk';\nimport clack from '../utils/clack.js';\nimport { saveCredentials, getCredentials, getAccessToken, isTokenExpired, updateTokens } from '../lib/credentials.js';\nimport { getCliAuthClientId, getAuthkitDomain } from '../lib/settings.js';\nimport { refreshAccessToken } from '../lib/token-refresh-client.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { fetchStagingCredentials } from '../lib/staging-api.js';\nimport { getConfig, saveConfig } from '../lib/config-store.js';\nimport type { CliConfig } from '../lib/config-store.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\n/**\n * Parse JWT payload\n */\nfunction parseJwt(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n return JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));\n } catch {\n return null;\n }\n}\n\n/**\n * Extract expiry time from JWT token\n */\nfunction getJwtExpiry(token: string): number | null {\n const payload = parseJwt(token);\n if (!payload || typeof payload.exp !== 'number') return null;\n return payload.exp * 1000;\n}\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\n/**\n * Get Connect OAuth endpoints from AuthKit domain\n */\nfunction getConnectEndpoints() {\n const domain = getAuthkitDomain();\n return {\n deviceAuthorization: `${domain}/oauth2/device_authorization`,\n token: `${domain}/oauth2/token`,\n };\n}\n\ninterface DeviceAuthResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n expires_in: number;\n interval: number;\n}\n\ninterface ConnectTokenResponse {\n access_token: string;\n id_token: string;\n token_type: string;\n expires_in: number;\n refresh_token?: string;\n}\n\ninterface AuthErrorResponse {\n error: string;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Auto-provision a staging environment after login.\n *\n * Fetches staging credentials using the access token, then saves them\n * as a \"staging\" environment in the config store. Non-fatal — logs a\n * hint on failure instead of throwing.\n */\nexport async function provisionStagingEnvironment(accessToken: string): Promise<boolean> {\n try {\n const staging = await fetchStagingCredentials(accessToken);\n\n const config: CliConfig = getConfig() ?? { environments: {} };\n const isFirst = Object.keys(config.environments).length === 0;\n\n config.environments['staging'] = {\n name: 'staging',\n type: 'sandbox',\n apiKey: staging.apiKey,\n clientId: staging.clientId,\n };\n\n if (isFirst || !config.activeEnvironment) {\n config.activeEnvironment = 'staging';\n }\n\n saveConfig(config);\n logInfo('[login] Staging environment auto-provisioned');\n return true;\n } catch (error) {\n logError('[login] Failed to auto-provision staging environment:', error instanceof Error ? error.message : error);\n return false;\n }\n}\n\nexport async function runLogin(): Promise<void> {\n const clientId = getCliAuthClientId();\n\n // Check if already logged in with valid token\n if (getAccessToken()) {\n const creds = getCredentials();\n console.log(chalk.green(`Already logged in as ${creds?.email ?? 'unknown'}`));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth logout')}\\` to log out`));\n return;\n }\n\n // Try to refresh if we have expired credentials with a refresh token\n const existingCreds = getCredentials();\n if (existingCreds?.refreshToken && isTokenExpired(existingCreds)) {\n try {\n const authkitDomain = getAuthkitDomain();\n const result = await refreshAccessToken(authkitDomain, clientId);\n if (result.accessToken && result.expiresAt) {\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n logInfo('[login] Session refreshed via refresh token');\n console.log(chalk.green(`Already logged in as ${existingCreds.email ?? 'unknown'}`));\n console.log(chalk.dim(`Run \\`${formatWorkOSCommand('auth logout')}\\` to log out`));\n return;\n }\n } catch {\n // Refresh failed, proceed with fresh login\n }\n }\n\n clack.log.step('Starting authentication...');\n\n const endpoints = getConnectEndpoints();\n\n const authResponse = await fetch(endpoints.deviceAuthorization, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n client_id: clientId,\n scope: 'openid email staging-environment:credentials:read offline_access',\n }),\n });\n\n if (!authResponse.ok) {\n clack.log.error(`Failed to start authentication: ${authResponse.status}`);\n process.exit(1);\n }\n\n const deviceAuth = (await authResponse.json()) as DeviceAuthResponse;\n const pollIntervalMs = (deviceAuth.interval || 5) * 1000;\n\n clack.log.info(`\\nOpen this URL in your browser:\\n`);\n console.log(` ${deviceAuth.verification_uri}`);\n console.log(`\\nEnter code: ${deviceAuth.user_code}\\n`);\n\n try {\n open(deviceAuth.verification_uri_complete);\n clack.log.info('Browser opened automatically');\n } catch {\n // User can open manually\n }\n\n const spinner = clack.spinner();\n spinner.start('Waiting for authentication...');\n\n const startTime = Date.now();\n let currentInterval = pollIntervalMs;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(currentInterval);\n\n try {\n const tokenResponse = await fetch(endpoints.token, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceAuth.device_code,\n client_id: clientId,\n }),\n });\n\n const data = await tokenResponse.json();\n\n if (tokenResponse.ok) {\n const result = data as ConnectTokenResponse;\n\n // Parse user info from id_token JWT\n const idTokenPayload = parseJwt(result.id_token);\n const userId = (idTokenPayload?.sub as string) || 'unknown';\n const email = (idTokenPayload?.email as string) || undefined;\n\n // Extract actual expiry from access token JWT, fallback to response or 15 min\n const jwtExpiry = getJwtExpiry(result.access_token);\n const expiresAt =\n jwtExpiry ?? (result.expires_in ? Date.now() + result.expires_in * 1000 : Date.now() + 15 * 60 * 1000);\n\n const expiresInSec = Math.round((expiresAt - Date.now()) / 1000);\n\n saveCredentials({\n accessToken: result.access_token,\n expiresAt,\n userId,\n email,\n refreshToken: result.refresh_token,\n });\n\n spinner.stop('Authentication successful!');\n clack.log.success(`Logged in as ${email || userId}`);\n clack.log.info(`Token expires in ${expiresInSec} seconds`);\n\n // Auto-provision staging environment\n const provisioned = await provisionStagingEnvironment(result.access_token);\n if (provisioned) {\n clack.log.success('Staging environment configured automatically');\n } else {\n clack.log.info(chalk.dim('Run `workos env add` to configure an environment manually'));\n }\n return;\n }\n\n const errorData = data as AuthErrorResponse;\n if (errorData.error === 'authorization_pending') continue;\n if (errorData.error === 'slow_down') {\n currentInterval += 5000;\n continue;\n }\n\n spinner.stop('Authentication failed');\n clack.log.error(`Authentication error: ${errorData.error}`);\n process.exit(1);\n } catch {\n continue;\n }\n }\n\n spinner.stop('Authentication timed out');\n clack.log.error('Authentication timed out. Please try again.');\n process.exit(1);\n}\n"]}
|
|
@@ -3,6 +3,7 @@ import { getLlmGatewayUrl, getAuthkitDomain, getCliAuthClientId, getConfig } fro
|
|
|
3
3
|
import { getCredentials, isTokenExpired, updateTokens, diagnoseCredentials } from '../../lib/credentials.js';
|
|
4
4
|
import { refreshAccessToken } from '../../lib/token-refresh-client.js';
|
|
5
5
|
import { buildDoctorPrompt } from '../agent-prompt.js';
|
|
6
|
+
import { formatWorkOSCommand } from '../../utils/command-invocation.js';
|
|
6
7
|
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
7
8
|
function startSpinner(message) {
|
|
8
9
|
let i = 0;
|
|
@@ -55,10 +56,10 @@ async function callModel(prompt, model) {
|
|
|
55
56
|
throw new Error('Not authenticated');
|
|
56
57
|
if (isTokenExpired(creds)) {
|
|
57
58
|
if (!creds.refreshToken)
|
|
58
|
-
throw new Error(
|
|
59
|
+
throw new Error(`Session expired — run \`${formatWorkOSCommand('auth login')}\` to re-authenticate`);
|
|
59
60
|
const result = await refreshAccessToken(getAuthkitDomain(), getCliAuthClientId());
|
|
60
61
|
if (!result.success || !result.accessToken || !result.expiresAt) {
|
|
61
|
-
throw new Error(
|
|
62
|
+
throw new Error(`Session expired — run \`${formatWorkOSCommand('auth login')}\` to re-authenticate`);
|
|
62
63
|
}
|
|
63
64
|
updateTokens(result.accessToken, result.expiresAt, result.refreshToken);
|
|
64
65
|
creds = getCredentials();
|
|
@@ -99,7 +100,7 @@ export async function checkAiAnalysis(context, options) {
|
|
|
99
100
|
process.stderr.write(` ${line}\n`);
|
|
100
101
|
}
|
|
101
102
|
process.stderr.write('\n');
|
|
102
|
-
return skippedResult(
|
|
103
|
+
return skippedResult(`Not authenticated — run \`${formatWorkOSCommand('auth login')}\` for AI-powered analysis`);
|
|
103
104
|
}
|
|
104
105
|
const startTime = Date.now();
|
|
105
106
|
const spinner = startSpinner('Analyzing project with AI...');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-analysis.js","sourceRoot":"","sources":["../../../src/doctor/checks/ai-analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic from '@anthropic-ai/sdk';\nimport { getLlmGatewayUrl, getAuthkitDomain, getCliAuthClientId, getConfig } from '../../lib/settings.js';\nimport { getCredentials, isTokenExpired, updateTokens, diagnoseCredentials } from '../../lib/credentials.js';\nimport { refreshAccessToken } from '../../lib/token-refresh-client.js';\nimport { buildDoctorPrompt, type AnalysisContext } from '../agent-prompt.js';\nimport type { AiAnalysis, AiFinding } from '../types.js';\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nfunction startSpinner(message: string): { stop: () => void } {\n let i = 0;\n const interval = setInterval(() => {\n process.stderr.write(`\\r ${SPINNER_FRAMES[i++ % SPINNER_FRAMES.length]} ${message}`);\n }, 80);\n return {\n stop: () => {\n clearInterval(interval);\n process.stderr.write(`\\r${' '.repeat(message.length + 6)}\\r`);\n },\n };\n}\n\nexport function parseAiResponse(text: string): { findings: AiFinding[]; summary: string } {\n const codeBlockMatch = text.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/);\n const jsonStr = codeBlockMatch ? codeBlockMatch[1] : text;\n\n try {\n const parsed = JSON.parse(jsonStr.trim());\n const findings = Array.isArray(parsed.findings)\n ? parsed.findings.map((f: Record<string, unknown>) => ({\n severity: (['error', 'warning', 'info'].includes(f.severity as string) ? f.severity : 'info') as\n | 'error'\n | 'warning'\n | 'info',\n title: String(f.title ?? ''),\n detail: String(f.detail ?? ''),\n remediation: String(f.remediation ?? ''),\n filePath: f.filePath ? String(f.filePath) : undefined,\n }))\n : [];\n return { findings, summary: String(parsed.summary ?? '') };\n } catch {\n const jsonMatch = text.match(/\\{[\\s\\S]*\"findings\"[\\s\\S]*\\}/);\n if (jsonMatch) {\n try {\n const parsed = JSON.parse(jsonMatch[0]);\n return {\n findings: Array.isArray(parsed.findings) ? parsed.findings : [],\n summary: String(parsed.summary ?? ''),\n };\n } catch {\n // give up\n }\n }\n return { findings: [], summary: text.slice(0, 500) };\n }\n}\n\nasync function callModel(prompt: string, model: string): Promise<string> {\n let creds = getCredentials();\n if (!creds) throw new Error('Not authenticated');\n\n if (isTokenExpired(creds)) {\n if (!creds.refreshToken) throw new Error('Session expired — run `workos auth login` to re-authenticate');\n const result = await refreshAccessToken(getAuthkitDomain(), getCliAuthClientId());\n if (!result.success || !result.accessToken || !result.expiresAt) {\n throw new Error('Session expired — run `workos auth login` to re-authenticate');\n }\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n creds = getCredentials()!;\n }\n\n const client = new Anthropic({\n baseURL: getLlmGatewayUrl(),\n apiKey: 'gateway',\n defaultHeaders: { Authorization: `Bearer ${creds.accessToken}` },\n });\n\n const response = await client.messages.create({\n model,\n max_tokens: 2048,\n messages: [{ role: 'user', content: prompt }],\n });\n\n const text = response.content[0];\n if (text.type === 'text') return text.text;\n throw new Error('Unexpected response format');\n}\n\nexport async function checkAiAnalysis(context: AnalysisContext, options: { skipAi?: boolean }): Promise<AiAnalysis> {\n const model = getConfig().doctorModel;\n\n const skippedResult = (reason: string): AiAnalysis => ({\n findings: [],\n summary: '',\n model,\n durationMs: 0,\n skipped: true,\n skipReason: reason,\n });\n\n if (options.skipAi) {\n return skippedResult('Skipped (--skip-ai flag)');\n }\n\n const creds = getCredentials();\n if (!creds) {\n const diag = diagnoseCredentials();\n process.stderr.write('\\n [credential-debug]\\n');\n for (const line of diag) {\n process.stderr.write(` ${line}\\n`);\n }\n process.stderr.write('\\n');\n return skippedResult('Not authenticated — run `workos auth login` for AI-powered analysis');\n }\n\n const startTime = Date.now();\n const spinner = startSpinner('Analyzing project with AI...');\n\n try {\n const prompt = await buildDoctorPrompt(context);\n const responseText = await callModel(prompt, model);\n const durationMs = Date.now() - startTime;\n const { findings, summary } = parseAiResponse(responseText);\n return { findings, summary, model, durationMs };\n } catch (error) {\n const durationMs = Date.now() - startTime;\n const errMsg = error instanceof Error ? error.message : 'Unknown error';\n return { ...skippedResult(`Analysis failed: ${errMsg}`), durationMs };\n } finally {\n spinner.stop();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ai-analysis.js","sourceRoot":"","sources":["../../../src/doctor/checks/ai-analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic from '@anthropic-ai/sdk';\nimport { getLlmGatewayUrl, getAuthkitDomain, getCliAuthClientId, getConfig } from '../../lib/settings.js';\nimport { getCredentials, isTokenExpired, updateTokens, diagnoseCredentials } from '../../lib/credentials.js';\nimport { refreshAccessToken } from '../../lib/token-refresh-client.js';\nimport { buildDoctorPrompt, type AnalysisContext } from '../agent-prompt.js';\nimport type { AiAnalysis, AiFinding } from '../types.js';\nimport { formatWorkOSCommand } from '../../utils/command-invocation.js';\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nfunction startSpinner(message: string): { stop: () => void } {\n let i = 0;\n const interval = setInterval(() => {\n process.stderr.write(`\\r ${SPINNER_FRAMES[i++ % SPINNER_FRAMES.length]} ${message}`);\n }, 80);\n return {\n stop: () => {\n clearInterval(interval);\n process.stderr.write(`\\r${' '.repeat(message.length + 6)}\\r`);\n },\n };\n}\n\nexport function parseAiResponse(text: string): { findings: AiFinding[]; summary: string } {\n const codeBlockMatch = text.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/);\n const jsonStr = codeBlockMatch ? codeBlockMatch[1] : text;\n\n try {\n const parsed = JSON.parse(jsonStr.trim());\n const findings = Array.isArray(parsed.findings)\n ? parsed.findings.map((f: Record<string, unknown>) => ({\n severity: (['error', 'warning', 'info'].includes(f.severity as string) ? f.severity : 'info') as\n | 'error'\n | 'warning'\n | 'info',\n title: String(f.title ?? ''),\n detail: String(f.detail ?? ''),\n remediation: String(f.remediation ?? ''),\n filePath: f.filePath ? String(f.filePath) : undefined,\n }))\n : [];\n return { findings, summary: String(parsed.summary ?? '') };\n } catch {\n const jsonMatch = text.match(/\\{[\\s\\S]*\"findings\"[\\s\\S]*\\}/);\n if (jsonMatch) {\n try {\n const parsed = JSON.parse(jsonMatch[0]);\n return {\n findings: Array.isArray(parsed.findings) ? parsed.findings : [],\n summary: String(parsed.summary ?? ''),\n };\n } catch {\n // give up\n }\n }\n return { findings: [], summary: text.slice(0, 500) };\n }\n}\n\nasync function callModel(prompt: string, model: string): Promise<string> {\n let creds = getCredentials();\n if (!creds) throw new Error('Not authenticated');\n\n if (isTokenExpired(creds)) {\n if (!creds.refreshToken)\n throw new Error(`Session expired — run \\`${formatWorkOSCommand('auth login')}\\` to re-authenticate`);\n const result = await refreshAccessToken(getAuthkitDomain(), getCliAuthClientId());\n if (!result.success || !result.accessToken || !result.expiresAt) {\n throw new Error(`Session expired — run \\`${formatWorkOSCommand('auth login')}\\` to re-authenticate`);\n }\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n creds = getCredentials()!;\n }\n\n const client = new Anthropic({\n baseURL: getLlmGatewayUrl(),\n apiKey: 'gateway',\n defaultHeaders: { Authorization: `Bearer ${creds.accessToken}` },\n });\n\n const response = await client.messages.create({\n model,\n max_tokens: 2048,\n messages: [{ role: 'user', content: prompt }],\n });\n\n const text = response.content[0];\n if (text.type === 'text') return text.text;\n throw new Error('Unexpected response format');\n}\n\nexport async function checkAiAnalysis(context: AnalysisContext, options: { skipAi?: boolean }): Promise<AiAnalysis> {\n const model = getConfig().doctorModel;\n\n const skippedResult = (reason: string): AiAnalysis => ({\n findings: [],\n summary: '',\n model,\n durationMs: 0,\n skipped: true,\n skipReason: reason,\n });\n\n if (options.skipAi) {\n return skippedResult('Skipped (--skip-ai flag)');\n }\n\n const creds = getCredentials();\n if (!creds) {\n const diag = diagnoseCredentials();\n process.stderr.write('\\n [credential-debug]\\n');\n for (const line of diag) {\n process.stderr.write(` ${line}\\n`);\n }\n process.stderr.write('\\n');\n return skippedResult(`Not authenticated — run \\`${formatWorkOSCommand('auth login')}\\` for AI-powered analysis`);\n }\n\n const startTime = Date.now();\n const spinner = startSpinner('Analyzing project with AI...');\n\n try {\n const prompt = await buildDoctorPrompt(context);\n const responseText = await callModel(prompt, model);\n const durationMs = Date.now() - startTime;\n const { findings, summary } = parseAiResponse(responseText);\n return { findings, summary, model, durationMs };\n } catch (error) {\n const durationMs = Date.now() - startTime;\n const errMsg = error instanceof Error ? error.message : 'Unknown error';\n return { ...skippedResult(`Analysis failed: ${errMsg}`), durationMs };\n } finally {\n spinner.stop();\n }\n}\n"]}
|
|
@@ -3,6 +3,7 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { getConfig } from '../settings.js';
|
|
4
4
|
import { ProgressTracker } from '../progress-tracker.js';
|
|
5
5
|
import { renderCompletionSummary } from '../../utils/summary-box.js';
|
|
6
|
+
import { formatWorkOSCommand } from '../../utils/command-invocation.js';
|
|
6
7
|
/**
|
|
7
8
|
* CLI adapter that renders wizard events via clack.
|
|
8
9
|
*
|
|
@@ -368,7 +369,7 @@ export class CLIAdapter {
|
|
|
368
369
|
}
|
|
369
370
|
// Add actionable hints for common errors
|
|
370
371
|
if (message.includes('authentication') || message.includes('auth')) {
|
|
371
|
-
clack.log.info(
|
|
372
|
+
clack.log.info(`Try running: ${formatWorkOSCommand('auth logout')} && ${formatWorkOSCommand('install')}`);
|
|
372
373
|
}
|
|
373
374
|
if (message.includes('ENOENT') || message.includes('not found')) {
|
|
374
375
|
clack.log.info('Ensure you are in a project directory');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-adapter.js","sourceRoot":"","sources":["../../../src/lib/adapters/cli-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InstallerAdapter, AdapterConfig } from './types.js';\nimport type { InstallerEventEmitter, InstallerEvents } from '../events.js';\nimport clack from '../../utils/clack.js';\nimport chalk from 'chalk';\nimport { getConfig } from '../settings.js';\nimport { ProgressTracker } from '../progress-tracker.js';\nimport { renderCompletionSummary } from '../../utils/summary-box.js';\n\n/**\n * CLI adapter that renders wizard events via clack.\n *\n * Subscribes to InstallerEventEmitter and translates events into\n * clack UI operations (logs, spinners, prompts).\n */\nexport class CLIAdapter implements InstallerAdapter {\n readonly emitter: InstallerEventEmitter;\n private sendEvent: AdapterConfig['sendEvent'];\n private debug: boolean;\n private spinner: ReturnType<typeof clack.spinner> | null = null;\n private isStarted = false;\n private progress = new ProgressTracker();\n\n // Store bound handlers for cleanup\n private handlers = new Map<string, (...args: unknown[]) => void>();\n\n // Queue for logs while prompt is active (parallel state issue)\n private isPromptActive = false;\n private pendingLogs: Array<() => void> = [];\n\n // SIGINT handler for cleanup\n private sigIntHandler: (() => void) | null = null;\n\n // Long-running agent update interval\n private agentUpdateInterval: NodeJS.Timeout | null = null;\n\n constructor(config: AdapterConfig) {\n this.emitter = config.emitter;\n this.sendEvent = config.sendEvent;\n this.debug = config.debug ?? false;\n }\n\n /**\n * Queue a log call if a prompt is active, otherwise execute immediately.\n */\n private queueableLog(logFn: () => void): void {\n if (this.isPromptActive) {\n this.pendingLogs.push(logFn);\n } else {\n logFn();\n }\n }\n\n /**\n * Flush any queued logs after prompt completes.\n */\n private flushPendingLogs(): void {\n const logs = this.pendingLogs.splice(0);\n logs.forEach((fn) => fn());\n }\n\n async start(): Promise<void> {\n if (this.isStarted) return;\n this.isStarted = true;\n\n // Show intro\n const config = getConfig();\n if (config.branding.showAsciiArt) {\n const art = config.branding.useCompact ? config.branding.compactAsciiArt : config.branding.asciiArt;\n console.log(chalk.cyan(art));\n console.log();\n } else {\n clack.intro('Welcome to the WorkOS AuthKit installer');\n }\n\n // Handle Ctrl+C gracefully\n const handleSigInt = () => {\n if (this.spinner) {\n this.spinner.stop('Cancelled');\n this.spinner = null;\n }\n this.stopAgentUpdates();\n clack.log.warn('Installer cancelled');\n clack.outro('Your project was not modified');\n process.exit(0);\n };\n process.on('SIGINT', handleSigInt);\n this.sigIntHandler = handleSigInt;\n\n // Subscribe to state events for progress tracking\n this.subscribe('state:enter', this.handleStateEnter);\n this.subscribe('state:exit', this.handleStateExit);\n\n // Subscribe to events that require UI rendering\n this.subscribe('auth:success', this.handleAuthSuccess);\n this.subscribe('auth:failure', this.handleAuthFailure);\n this.subscribe('detection:complete', this.handleDetectionComplete);\n this.subscribe('detection:none', this.handleDetectionNone);\n this.subscribe('git:dirty', this.handleGitDirty);\n this.subscribe('credentials:found', this.handleCredentialsFound);\n this.subscribe('credentials:request', this.handleCredentialsRequest);\n this.subscribe('credentials:env:prompt', this.handleEnvScanPrompt);\n this.subscribe('device:started', this.handleDeviceStarted);\n this.subscribe('device:success', this.handleDeviceSuccess);\n this.subscribe('staging:fetching', this.handleStagingFetching);\n this.subscribe('staging:success', this.handleStagingSuccess);\n this.subscribe('credentials:env:found', this.handleEnvCredentialsFound);\n this.subscribe('config:complete', this.handleConfigComplete);\n this.subscribe('agent:start', this.handleAgentStart);\n this.subscribe('agent:progress', this.handleAgentProgress);\n this.subscribe('validation:start', this.handleValidationStart);\n this.subscribe('validation:issues', this.handleValidationIssues);\n this.subscribe('validation:complete', this.handleValidationComplete);\n this.subscribe('complete', this.handleComplete);\n this.subscribe('error', this.handleError);\n // Branch check events\n this.subscribe('branch:prompt', this.handleBranchPrompt);\n this.subscribe('branch:created', this.handleBranchCreated);\n\n // Post-install events\n this.subscribe('postinstall:changes', this.handlePostInstallChanges);\n this.subscribe('postinstall:commit:prompt', this.handleCommitPrompt);\n this.subscribe('postinstall:commit:generating', this.handleCommitGenerating);\n this.subscribe('postinstall:commit:success', this.handleCommitSuccess);\n this.subscribe('postinstall:commit:failed', this.handleCommitFailed);\n this.subscribe('postinstall:pr:prompt', this.handlePrPrompt);\n this.subscribe('postinstall:pr:generating', this.handlePrGenerating);\n this.subscribe('postinstall:pr:pushing', this.handlePrPushing);\n this.subscribe('postinstall:pr:success', this.handlePrSuccess);\n this.subscribe('postinstall:pr:failed', this.handlePrFailed);\n this.subscribe('postinstall:push:failed', this.handlePushFailed);\n this.subscribe('postinstall:manual', this.handleManualInstructions);\n }\n\n async stop(): Promise<void> {\n if (!this.isStarted) return;\n\n // Remove SIGINT handler\n if (this.sigIntHandler) {\n process.off('SIGINT', this.sigIntHandler);\n this.sigIntHandler = null;\n }\n\n // Stop agent updates\n this.stopAgentUpdates();\n\n // Unsubscribe from all events\n for (const [event, handler] of this.handlers) {\n this.emitter.off(event as keyof InstallerEvents, handler as never);\n }\n this.handlers.clear();\n\n // Stop any active spinner\n this.spinner?.stop();\n this.spinner = null;\n\n this.isStarted = false;\n }\n\n private stopAgentUpdates = (): void => {\n if (this.agentUpdateInterval) {\n clearInterval(this.agentUpdateInterval);\n this.agentUpdateInterval = null;\n }\n };\n\n private stopSpinner(message: string): void {\n if (this.spinner) {\n this.spinner.stop(message);\n this.spinner = null;\n }\n }\n\n /** Debug logging - only outputs when debug mode is enabled */\n private debugLog = (message: string): void => {\n if (this.debug) {\n console.log(chalk.dim(`[debug] ${message}`));\n }\n };\n\n /**\n * Helper to subscribe and track handlers for cleanup.\n */\n private subscribe<K extends keyof InstallerEvents>(\n event: K,\n handler: (payload: InstallerEvents[K]) => void | Promise<void>,\n ): void {\n const boundHandler = handler.bind(this);\n this.handlers.set(event, boundHandler as (...args: unknown[]) => void);\n this.emitter.on(event, boundHandler);\n }\n\n // ===== Event Handlers =====\n\n private handleStateEnter = ({ state }: InstallerEvents['state:enter']): void => {\n this.progress.enterPhase(state);\n };\n\n private handleStateExit = ({ state }: InstallerEvents['state:exit']): void => {\n this.progress.exitPhase(state);\n };\n\n private handleAuthSuccess = (): void => {\n clack.log.success('Authenticated');\n };\n\n private handleAuthFailure = ({ message }: InstallerEvents['auth:failure']): void => {\n clack.log.error(`Auth failed: ${message}`);\n clack.log.info('Visit https://dashboard.workos.com to verify your account');\n };\n\n private handleDetectionComplete = ({ integration }: InstallerEvents['detection:complete']): void => {\n this.queueableLog(() => clack.log.success(`Detected ${chalk.bold(integration)}`));\n };\n\n private handleDetectionNone = (): void => {\n this.queueableLog(() => clack.log.warn('Could not detect framework automatically'));\n };\n\n private handleCredentialsFound = (): void => {\n clack.log.success('Found existing WorkOS credentials in .env.local');\n };\n\n private handleEnvScanPrompt = async ({ files }: InstallerEvents['credentials:env:prompt']): Promise<void> => {\n this.isPromptActive = true;\n const fileList = files.length === 1 ? files[0] : files.slice(0, 2).join(', ');\n const confirmed = await clack.confirm({\n message: `Found ${fileList}. Check for existing WorkOS credentials?`,\n initialValue: true,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'ENV_SCAN_DECLINED' : 'ENV_SCAN_APPROVED',\n });\n };\n\n private handleDeviceStarted = ({ verificationUri, userCode }: InstallerEvents['device:started']): void => {\n clack.log.info(`\\nOpen this URL in your browser:\\n`);\n console.log(` ${chalk.cyan(verificationUri)}`);\n console.log(`\\nEnter code: ${chalk.bold(userCode)}\\n`);\n\n this.spinner = clack.spinner();\n this.spinner.start('Waiting for authentication...');\n };\n\n private handleDeviceSuccess = (): void => {\n // Spinner will be stopped by handleStagingFetching\n };\n\n private handleStagingFetching = (): void => {\n if (this.spinner) {\n this.spinner.stop('Authenticated');\n }\n this.spinner = clack.spinner();\n this.spinner.start('Fetching your WorkOS credentials...');\n };\n\n private handleStagingSuccess = (): void => {\n this.stopSpinner('Credentials fetched');\n clack.log.success('WorkOS credentials retrieved automatically');\n };\n\n private handleEnvCredentialsFound = ({ sourcePath }: InstallerEvents['credentials:env:found']): void => {\n clack.log.success(`Found existing WorkOS credentials in ${sourcePath}`);\n };\n\n private handleGitDirty = async ({ files }: InstallerEvents['git:dirty']): Promise<void> => {\n clack.log.warn('You have uncommitted or untracked files:');\n files.slice(0, 5).forEach((f) => clack.log.info(chalk.dim(` ${f}`)));\n if (files.length > 5) {\n clack.log.info(chalk.dim(` ... and ${files.length - 5} more`));\n }\n\n this.isPromptActive = true;\n const confirmed = await clack.confirm({\n message: 'Continue anyway?',\n initialValue: false,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'GIT_CANCELLED' : 'GIT_CONFIRMED',\n });\n };\n\n private handleCredentialsRequest = async ({\n requiresApiKey,\n }: InstallerEvents['credentials:request']): Promise<void> => {\n clack.log.step(`Get your credentials from ${chalk.cyan('https://dashboard.workos.com')}`);\n\n const clientId = await clack.text({\n message: 'Enter your WorkOS Client ID:',\n placeholder: 'client_...',\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return 'Client ID is required';\n }\n if (!value.startsWith('client_')) {\n return 'Client ID should start with \"client_\"';\n }\n return undefined;\n },\n });\n\n if (clack.isCancel(clientId)) {\n this.sendEvent({ type: 'CANCEL' });\n return;\n }\n\n let apiKey = '';\n if (requiresApiKey) {\n clack.log.info(chalk.dim('ℹ️ Your API key will be hidden for security and saved to .env.local'));\n const apiKeyResult = await clack.password({\n message: 'Enter your WorkOS API Key:',\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return 'API Key is required';\n }\n if (!value.startsWith('sk_')) {\n return 'API Key should start with \"sk_\"';\n }\n return undefined;\n },\n });\n\n if (clack.isCancel(apiKeyResult)) {\n this.sendEvent({ type: 'CANCEL' });\n return;\n }\n apiKey = apiKeyResult as string;\n } else {\n clack.log.info(chalk.dim('ℹ️ Client-only SDK - API key not required'));\n }\n\n this.sendEvent({\n type: 'CREDENTIALS_SUBMITTED',\n apiKey,\n clientId: clientId as string,\n });\n };\n\n private handleConfigComplete = (): void => {\n clack.log.success('Environment configured');\n };\n\n private handleAgentStart = (): void => {\n this.spinner = clack.spinner();\n this.spinner.start('Running AI agent...');\n\n // Periodic status updates for long-running operations\n let dots = 0;\n this.agentUpdateInterval = setInterval(() => {\n dots = (dots + 1) % 4;\n const dotStr = '.'.repeat(dots + 1);\n this.spinner?.message(`Running AI agent${dotStr}`);\n }, 2000);\n };\n\n private handleAgentProgress = ({ step, detail }: InstallerEvents['agent:progress']): void => {\n const message = detail ? `${step}: ${detail}` : step;\n this.spinner?.message(message);\n };\n\n private handleValidationStart = (): void => {\n this.stopAgentUpdates();\n this.stopSpinner('Agent completed');\n };\n\n private handleValidationIssues = ({ issues }: InstallerEvents['validation:issues']): void => {\n for (const issue of issues) {\n if (issue.severity === 'error') {\n clack.log.error(issue.message);\n } else {\n clack.log.warn(issue.message);\n }\n if (issue.hint) {\n clack.log.info(`Hint: ${issue.hint}`);\n }\n }\n };\n\n private handleValidationComplete = ({ passed, issueCount }: InstallerEvents['validation:complete']): void => {\n if (passed) {\n clack.log.success('Validation passed');\n } else {\n clack.log.warn(`Validation found ${issueCount} issue(s)`);\n }\n };\n\n private handleComplete = ({ success, summary }: InstallerEvents['complete']): void => {\n this.stopAgentUpdates();\n this.stopSpinner(success ? 'Done' : 'Failed');\n\n console.log('');\n console.log(renderCompletionSummary(success, summary));\n console.log('');\n };\n\n private handleError = ({ message, stack }: InstallerEvents['error']): void => {\n this.stopSpinner('Error');\n this.stopAgentUpdates();\n\n // Rewrite raw API/SDK errors into user-friendly messages\n const isServiceError =\n /\\b50[0-9]\\b/.test(message) || /server_error|internal_error|overloaded|service.*unavailable/i.test(message);\n const isRateLimit = /\\b429\\b/.test(message) || /rate.limit/i.test(message);\n const isNetworkError = /ECONNREFUSED|ETIMEDOUT|ENOTFOUND|fetch failed/i.test(message);\n const isProcessExit = /process exited with code/i.test(message);\n\n if (isServiceError) {\n clack.log.error('The AI service is temporarily unavailable.');\n clack.log.info('This is usually resolved within a few minutes. Please try again shortly.');\n } else if (isRateLimit) {\n clack.log.error('The AI service is currently rate-limited.');\n clack.log.info('Please wait a minute and try again.');\n } else if (isNetworkError) {\n clack.log.error('Could not connect to the AI service.');\n clack.log.info('Check your internet connection and try again.');\n } else if (isProcessExit) {\n clack.log.error('The AI agent process exited unexpectedly.');\n clack.log.info('Try running again. If this persists, run with --debug for details.');\n } else {\n clack.log.error(message);\n }\n\n // Add actionable hints for common errors\n if (message.includes('authentication') || message.includes('auth')) {\n clack.log.info('Try running: workos auth logout && workos install');\n }\n if (message.includes('ENOENT') || message.includes('not found')) {\n clack.log.info('Ensure you are in a project directory');\n }\n\n if (stack && this.debug) {\n this.debugLog(stack);\n }\n };\n\n private handleBranchPrompt = async ({ branch }: InstallerEvents['branch:prompt']): Promise<void> => {\n this.isPromptActive = true;\n const choice = await clack.select({\n message: `You are on ${chalk.bold(branch)}. Create a feature branch?`,\n options: [\n { value: 'create', label: 'Create feat/add-workos-authkit' },\n { value: 'continue', label: 'Continue on current branch' },\n { value: 'cancel', label: 'Cancel' },\n ],\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n if (clack.isCancel(choice) || choice === 'cancel') {\n this.sendEvent({ type: 'BRANCH_CANCEL' });\n } else if (choice === 'create') {\n this.sendEvent({ type: 'BRANCH_CREATE' });\n } else {\n this.sendEvent({ type: 'BRANCH_CONTINUE' });\n }\n };\n\n private handleBranchCreated = ({ branch }: InstallerEvents['branch:created']): void => {\n this.queueableLog(() => clack.log.success(`Created branch ${chalk.bold(branch)}`));\n };\n\n // ===== Post-install Event Handlers =====\n\n private handlePostInstallChanges = ({ files }: InstallerEvents['postinstall:changes']): void => {\n this.debugLog(`Post-install: ${files.length} changed files detected`);\n };\n\n private handleCommitPrompt = async (): Promise<void> => {\n this.isPromptActive = true;\n const confirmed = await clack.confirm({\n message: 'Commit the changes?',\n initialValue: true,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'COMMIT_DECLINED' : 'COMMIT_APPROVED',\n });\n };\n\n private handleCommitGenerating = (): void => {\n this.spinner = clack.spinner();\n this.spinner.start('Generating commit message...');\n };\n\n private handleCommitSuccess = ({ message }: InstallerEvents['postinstall:commit:success']): void => {\n this.stopSpinner('Committed');\n clack.log.success(`Committed: ${chalk.dim(message)}`);\n };\n\n private handleCommitFailed = ({ error }: InstallerEvents['postinstall:commit:failed']): void => {\n this.stopSpinner('Commit failed');\n clack.log.error(`Commit failed: ${error}`);\n };\n\n private handlePrPrompt = async (): Promise<void> => {\n this.isPromptActive = true;\n const confirmed = await clack.confirm({\n message: 'Create a pull request?',\n initialValue: true,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'PR_DECLINED' : 'PR_APPROVED',\n });\n };\n\n private handlePrGenerating = (): void => {\n this.spinner = clack.spinner();\n this.spinner.start('Generating PR description...');\n };\n\n private handlePrPushing = (): void => {\n if (this.spinner) {\n this.spinner.message('Pushing to remote...');\n } else {\n this.spinner = clack.spinner();\n this.spinner.start('Pushing to remote...');\n }\n };\n\n private handlePrSuccess = ({ url }: InstallerEvents['postinstall:pr:success']): void => {\n this.stopSpinner('PR created');\n clack.log.success(`Pull request created: ${chalk.cyan(url)}`);\n };\n\n private handlePrFailed = ({ error }: InstallerEvents['postinstall:pr:failed']): void => {\n this.stopSpinner('PR creation failed');\n clack.log.error(`PR creation failed: ${error}`);\n };\n\n private handlePushFailed = ({ error }: InstallerEvents['postinstall:push:failed']): void => {\n this.stopSpinner('Push failed');\n clack.log.error(`Push failed: ${error}`);\n };\n\n private handleManualInstructions = ({ instructions }: InstallerEvents['postinstall:manual']): void => {\n clack.log.info('GitHub CLI not found. Manual steps:');\n console.log(chalk.dim(instructions));\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cli-adapter.js","sourceRoot":"","sources":["../../../src/lib/adapters/cli-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InstallerAdapter, AdapterConfig } from './types.js';\nimport type { InstallerEventEmitter, InstallerEvents } from '../events.js';\nimport clack from '../../utils/clack.js';\nimport chalk from 'chalk';\nimport { getConfig } from '../settings.js';\nimport { ProgressTracker } from '../progress-tracker.js';\nimport { renderCompletionSummary } from '../../utils/summary-box.js';\nimport { formatWorkOSCommand } from '../../utils/command-invocation.js';\n\n/**\n * CLI adapter that renders wizard events via clack.\n *\n * Subscribes to InstallerEventEmitter and translates events into\n * clack UI operations (logs, spinners, prompts).\n */\nexport class CLIAdapter implements InstallerAdapter {\n readonly emitter: InstallerEventEmitter;\n private sendEvent: AdapterConfig['sendEvent'];\n private debug: boolean;\n private spinner: ReturnType<typeof clack.spinner> | null = null;\n private isStarted = false;\n private progress = new ProgressTracker();\n\n // Store bound handlers for cleanup\n private handlers = new Map<string, (...args: unknown[]) => void>();\n\n // Queue for logs while prompt is active (parallel state issue)\n private isPromptActive = false;\n private pendingLogs: Array<() => void> = [];\n\n // SIGINT handler for cleanup\n private sigIntHandler: (() => void) | null = null;\n\n // Long-running agent update interval\n private agentUpdateInterval: NodeJS.Timeout | null = null;\n\n constructor(config: AdapterConfig) {\n this.emitter = config.emitter;\n this.sendEvent = config.sendEvent;\n this.debug = config.debug ?? false;\n }\n\n /**\n * Queue a log call if a prompt is active, otherwise execute immediately.\n */\n private queueableLog(logFn: () => void): void {\n if (this.isPromptActive) {\n this.pendingLogs.push(logFn);\n } else {\n logFn();\n }\n }\n\n /**\n * Flush any queued logs after prompt completes.\n */\n private flushPendingLogs(): void {\n const logs = this.pendingLogs.splice(0);\n logs.forEach((fn) => fn());\n }\n\n async start(): Promise<void> {\n if (this.isStarted) return;\n this.isStarted = true;\n\n // Show intro\n const config = getConfig();\n if (config.branding.showAsciiArt) {\n const art = config.branding.useCompact ? config.branding.compactAsciiArt : config.branding.asciiArt;\n console.log(chalk.cyan(art));\n console.log();\n } else {\n clack.intro('Welcome to the WorkOS AuthKit installer');\n }\n\n // Handle Ctrl+C gracefully\n const handleSigInt = () => {\n if (this.spinner) {\n this.spinner.stop('Cancelled');\n this.spinner = null;\n }\n this.stopAgentUpdates();\n clack.log.warn('Installer cancelled');\n clack.outro('Your project was not modified');\n process.exit(0);\n };\n process.on('SIGINT', handleSigInt);\n this.sigIntHandler = handleSigInt;\n\n // Subscribe to state events for progress tracking\n this.subscribe('state:enter', this.handleStateEnter);\n this.subscribe('state:exit', this.handleStateExit);\n\n // Subscribe to events that require UI rendering\n this.subscribe('auth:success', this.handleAuthSuccess);\n this.subscribe('auth:failure', this.handleAuthFailure);\n this.subscribe('detection:complete', this.handleDetectionComplete);\n this.subscribe('detection:none', this.handleDetectionNone);\n this.subscribe('git:dirty', this.handleGitDirty);\n this.subscribe('credentials:found', this.handleCredentialsFound);\n this.subscribe('credentials:request', this.handleCredentialsRequest);\n this.subscribe('credentials:env:prompt', this.handleEnvScanPrompt);\n this.subscribe('device:started', this.handleDeviceStarted);\n this.subscribe('device:success', this.handleDeviceSuccess);\n this.subscribe('staging:fetching', this.handleStagingFetching);\n this.subscribe('staging:success', this.handleStagingSuccess);\n this.subscribe('credentials:env:found', this.handleEnvCredentialsFound);\n this.subscribe('config:complete', this.handleConfigComplete);\n this.subscribe('agent:start', this.handleAgentStart);\n this.subscribe('agent:progress', this.handleAgentProgress);\n this.subscribe('validation:start', this.handleValidationStart);\n this.subscribe('validation:issues', this.handleValidationIssues);\n this.subscribe('validation:complete', this.handleValidationComplete);\n this.subscribe('complete', this.handleComplete);\n this.subscribe('error', this.handleError);\n // Branch check events\n this.subscribe('branch:prompt', this.handleBranchPrompt);\n this.subscribe('branch:created', this.handleBranchCreated);\n\n // Post-install events\n this.subscribe('postinstall:changes', this.handlePostInstallChanges);\n this.subscribe('postinstall:commit:prompt', this.handleCommitPrompt);\n this.subscribe('postinstall:commit:generating', this.handleCommitGenerating);\n this.subscribe('postinstall:commit:success', this.handleCommitSuccess);\n this.subscribe('postinstall:commit:failed', this.handleCommitFailed);\n this.subscribe('postinstall:pr:prompt', this.handlePrPrompt);\n this.subscribe('postinstall:pr:generating', this.handlePrGenerating);\n this.subscribe('postinstall:pr:pushing', this.handlePrPushing);\n this.subscribe('postinstall:pr:success', this.handlePrSuccess);\n this.subscribe('postinstall:pr:failed', this.handlePrFailed);\n this.subscribe('postinstall:push:failed', this.handlePushFailed);\n this.subscribe('postinstall:manual', this.handleManualInstructions);\n }\n\n async stop(): Promise<void> {\n if (!this.isStarted) return;\n\n // Remove SIGINT handler\n if (this.sigIntHandler) {\n process.off('SIGINT', this.sigIntHandler);\n this.sigIntHandler = null;\n }\n\n // Stop agent updates\n this.stopAgentUpdates();\n\n // Unsubscribe from all events\n for (const [event, handler] of this.handlers) {\n this.emitter.off(event as keyof InstallerEvents, handler as never);\n }\n this.handlers.clear();\n\n // Stop any active spinner\n this.spinner?.stop();\n this.spinner = null;\n\n this.isStarted = false;\n }\n\n private stopAgentUpdates = (): void => {\n if (this.agentUpdateInterval) {\n clearInterval(this.agentUpdateInterval);\n this.agentUpdateInterval = null;\n }\n };\n\n private stopSpinner(message: string): void {\n if (this.spinner) {\n this.spinner.stop(message);\n this.spinner = null;\n }\n }\n\n /** Debug logging - only outputs when debug mode is enabled */\n private debugLog = (message: string): void => {\n if (this.debug) {\n console.log(chalk.dim(`[debug] ${message}`));\n }\n };\n\n /**\n * Helper to subscribe and track handlers for cleanup.\n */\n private subscribe<K extends keyof InstallerEvents>(\n event: K,\n handler: (payload: InstallerEvents[K]) => void | Promise<void>,\n ): void {\n const boundHandler = handler.bind(this);\n this.handlers.set(event, boundHandler as (...args: unknown[]) => void);\n this.emitter.on(event, boundHandler);\n }\n\n // ===== Event Handlers =====\n\n private handleStateEnter = ({ state }: InstallerEvents['state:enter']): void => {\n this.progress.enterPhase(state);\n };\n\n private handleStateExit = ({ state }: InstallerEvents['state:exit']): void => {\n this.progress.exitPhase(state);\n };\n\n private handleAuthSuccess = (): void => {\n clack.log.success('Authenticated');\n };\n\n private handleAuthFailure = ({ message }: InstallerEvents['auth:failure']): void => {\n clack.log.error(`Auth failed: ${message}`);\n clack.log.info('Visit https://dashboard.workos.com to verify your account');\n };\n\n private handleDetectionComplete = ({ integration }: InstallerEvents['detection:complete']): void => {\n this.queueableLog(() => clack.log.success(`Detected ${chalk.bold(integration)}`));\n };\n\n private handleDetectionNone = (): void => {\n this.queueableLog(() => clack.log.warn('Could not detect framework automatically'));\n };\n\n private handleCredentialsFound = (): void => {\n clack.log.success('Found existing WorkOS credentials in .env.local');\n };\n\n private handleEnvScanPrompt = async ({ files }: InstallerEvents['credentials:env:prompt']): Promise<void> => {\n this.isPromptActive = true;\n const fileList = files.length === 1 ? files[0] : files.slice(0, 2).join(', ');\n const confirmed = await clack.confirm({\n message: `Found ${fileList}. Check for existing WorkOS credentials?`,\n initialValue: true,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'ENV_SCAN_DECLINED' : 'ENV_SCAN_APPROVED',\n });\n };\n\n private handleDeviceStarted = ({ verificationUri, userCode }: InstallerEvents['device:started']): void => {\n clack.log.info(`\\nOpen this URL in your browser:\\n`);\n console.log(` ${chalk.cyan(verificationUri)}`);\n console.log(`\\nEnter code: ${chalk.bold(userCode)}\\n`);\n\n this.spinner = clack.spinner();\n this.spinner.start('Waiting for authentication...');\n };\n\n private handleDeviceSuccess = (): void => {\n // Spinner will be stopped by handleStagingFetching\n };\n\n private handleStagingFetching = (): void => {\n if (this.spinner) {\n this.spinner.stop('Authenticated');\n }\n this.spinner = clack.spinner();\n this.spinner.start('Fetching your WorkOS credentials...');\n };\n\n private handleStagingSuccess = (): void => {\n this.stopSpinner('Credentials fetched');\n clack.log.success('WorkOS credentials retrieved automatically');\n };\n\n private handleEnvCredentialsFound = ({ sourcePath }: InstallerEvents['credentials:env:found']): void => {\n clack.log.success(`Found existing WorkOS credentials in ${sourcePath}`);\n };\n\n private handleGitDirty = async ({ files }: InstallerEvents['git:dirty']): Promise<void> => {\n clack.log.warn('You have uncommitted or untracked files:');\n files.slice(0, 5).forEach((f) => clack.log.info(chalk.dim(` ${f}`)));\n if (files.length > 5) {\n clack.log.info(chalk.dim(` ... and ${files.length - 5} more`));\n }\n\n this.isPromptActive = true;\n const confirmed = await clack.confirm({\n message: 'Continue anyway?',\n initialValue: false,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'GIT_CANCELLED' : 'GIT_CONFIRMED',\n });\n };\n\n private handleCredentialsRequest = async ({\n requiresApiKey,\n }: InstallerEvents['credentials:request']): Promise<void> => {\n clack.log.step(`Get your credentials from ${chalk.cyan('https://dashboard.workos.com')}`);\n\n const clientId = await clack.text({\n message: 'Enter your WorkOS Client ID:',\n placeholder: 'client_...',\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return 'Client ID is required';\n }\n if (!value.startsWith('client_')) {\n return 'Client ID should start with \"client_\"';\n }\n return undefined;\n },\n });\n\n if (clack.isCancel(clientId)) {\n this.sendEvent({ type: 'CANCEL' });\n return;\n }\n\n let apiKey = '';\n if (requiresApiKey) {\n clack.log.info(chalk.dim('ℹ️ Your API key will be hidden for security and saved to .env.local'));\n const apiKeyResult = await clack.password({\n message: 'Enter your WorkOS API Key:',\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return 'API Key is required';\n }\n if (!value.startsWith('sk_')) {\n return 'API Key should start with \"sk_\"';\n }\n return undefined;\n },\n });\n\n if (clack.isCancel(apiKeyResult)) {\n this.sendEvent({ type: 'CANCEL' });\n return;\n }\n apiKey = apiKeyResult as string;\n } else {\n clack.log.info(chalk.dim('ℹ️ Client-only SDK - API key not required'));\n }\n\n this.sendEvent({\n type: 'CREDENTIALS_SUBMITTED',\n apiKey,\n clientId: clientId as string,\n });\n };\n\n private handleConfigComplete = (): void => {\n clack.log.success('Environment configured');\n };\n\n private handleAgentStart = (): void => {\n this.spinner = clack.spinner();\n this.spinner.start('Running AI agent...');\n\n // Periodic status updates for long-running operations\n let dots = 0;\n this.agentUpdateInterval = setInterval(() => {\n dots = (dots + 1) % 4;\n const dotStr = '.'.repeat(dots + 1);\n this.spinner?.message(`Running AI agent${dotStr}`);\n }, 2000);\n };\n\n private handleAgentProgress = ({ step, detail }: InstallerEvents['agent:progress']): void => {\n const message = detail ? `${step}: ${detail}` : step;\n this.spinner?.message(message);\n };\n\n private handleValidationStart = (): void => {\n this.stopAgentUpdates();\n this.stopSpinner('Agent completed');\n };\n\n private handleValidationIssues = ({ issues }: InstallerEvents['validation:issues']): void => {\n for (const issue of issues) {\n if (issue.severity === 'error') {\n clack.log.error(issue.message);\n } else {\n clack.log.warn(issue.message);\n }\n if (issue.hint) {\n clack.log.info(`Hint: ${issue.hint}`);\n }\n }\n };\n\n private handleValidationComplete = ({ passed, issueCount }: InstallerEvents['validation:complete']): void => {\n if (passed) {\n clack.log.success('Validation passed');\n } else {\n clack.log.warn(`Validation found ${issueCount} issue(s)`);\n }\n };\n\n private handleComplete = ({ success, summary }: InstallerEvents['complete']): void => {\n this.stopAgentUpdates();\n this.stopSpinner(success ? 'Done' : 'Failed');\n\n console.log('');\n console.log(renderCompletionSummary(success, summary));\n console.log('');\n };\n\n private handleError = ({ message, stack }: InstallerEvents['error']): void => {\n this.stopSpinner('Error');\n this.stopAgentUpdates();\n\n // Rewrite raw API/SDK errors into user-friendly messages\n const isServiceError =\n /\\b50[0-9]\\b/.test(message) || /server_error|internal_error|overloaded|service.*unavailable/i.test(message);\n const isRateLimit = /\\b429\\b/.test(message) || /rate.limit/i.test(message);\n const isNetworkError = /ECONNREFUSED|ETIMEDOUT|ENOTFOUND|fetch failed/i.test(message);\n const isProcessExit = /process exited with code/i.test(message);\n\n if (isServiceError) {\n clack.log.error('The AI service is temporarily unavailable.');\n clack.log.info('This is usually resolved within a few minutes. Please try again shortly.');\n } else if (isRateLimit) {\n clack.log.error('The AI service is currently rate-limited.');\n clack.log.info('Please wait a minute and try again.');\n } else if (isNetworkError) {\n clack.log.error('Could not connect to the AI service.');\n clack.log.info('Check your internet connection and try again.');\n } else if (isProcessExit) {\n clack.log.error('The AI agent process exited unexpectedly.');\n clack.log.info('Try running again. If this persists, run with --debug for details.');\n } else {\n clack.log.error(message);\n }\n\n // Add actionable hints for common errors\n if (message.includes('authentication') || message.includes('auth')) {\n clack.log.info(`Try running: ${formatWorkOSCommand('auth logout')} && ${formatWorkOSCommand('install')}`);\n }\n if (message.includes('ENOENT') || message.includes('not found')) {\n clack.log.info('Ensure you are in a project directory');\n }\n\n if (stack && this.debug) {\n this.debugLog(stack);\n }\n };\n\n private handleBranchPrompt = async ({ branch }: InstallerEvents['branch:prompt']): Promise<void> => {\n this.isPromptActive = true;\n const choice = await clack.select({\n message: `You are on ${chalk.bold(branch)}. Create a feature branch?`,\n options: [\n { value: 'create', label: 'Create feat/add-workos-authkit' },\n { value: 'continue', label: 'Continue on current branch' },\n { value: 'cancel', label: 'Cancel' },\n ],\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n if (clack.isCancel(choice) || choice === 'cancel') {\n this.sendEvent({ type: 'BRANCH_CANCEL' });\n } else if (choice === 'create') {\n this.sendEvent({ type: 'BRANCH_CREATE' });\n } else {\n this.sendEvent({ type: 'BRANCH_CONTINUE' });\n }\n };\n\n private handleBranchCreated = ({ branch }: InstallerEvents['branch:created']): void => {\n this.queueableLog(() => clack.log.success(`Created branch ${chalk.bold(branch)}`));\n };\n\n // ===== Post-install Event Handlers =====\n\n private handlePostInstallChanges = ({ files }: InstallerEvents['postinstall:changes']): void => {\n this.debugLog(`Post-install: ${files.length} changed files detected`);\n };\n\n private handleCommitPrompt = async (): Promise<void> => {\n this.isPromptActive = true;\n const confirmed = await clack.confirm({\n message: 'Commit the changes?',\n initialValue: true,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'COMMIT_DECLINED' : 'COMMIT_APPROVED',\n });\n };\n\n private handleCommitGenerating = (): void => {\n this.spinner = clack.spinner();\n this.spinner.start('Generating commit message...');\n };\n\n private handleCommitSuccess = ({ message }: InstallerEvents['postinstall:commit:success']): void => {\n this.stopSpinner('Committed');\n clack.log.success(`Committed: ${chalk.dim(message)}`);\n };\n\n private handleCommitFailed = ({ error }: InstallerEvents['postinstall:commit:failed']): void => {\n this.stopSpinner('Commit failed');\n clack.log.error(`Commit failed: ${error}`);\n };\n\n private handlePrPrompt = async (): Promise<void> => {\n this.isPromptActive = true;\n const confirmed = await clack.confirm({\n message: 'Create a pull request?',\n initialValue: true,\n });\n this.isPromptActive = false;\n this.flushPendingLogs();\n\n this.sendEvent({\n type: clack.isCancel(confirmed) || !confirmed ? 'PR_DECLINED' : 'PR_APPROVED',\n });\n };\n\n private handlePrGenerating = (): void => {\n this.spinner = clack.spinner();\n this.spinner.start('Generating PR description...');\n };\n\n private handlePrPushing = (): void => {\n if (this.spinner) {\n this.spinner.message('Pushing to remote...');\n } else {\n this.spinner = clack.spinner();\n this.spinner.start('Pushing to remote...');\n }\n };\n\n private handlePrSuccess = ({ url }: InstallerEvents['postinstall:pr:success']): void => {\n this.stopSpinner('PR created');\n clack.log.success(`Pull request created: ${chalk.cyan(url)}`);\n };\n\n private handlePrFailed = ({ error }: InstallerEvents['postinstall:pr:failed']): void => {\n this.stopSpinner('PR creation failed');\n clack.log.error(`PR creation failed: ${error}`);\n };\n\n private handlePushFailed = ({ error }: InstallerEvents['postinstall:push:failed']): void => {\n this.stopSpinner('Push failed');\n clack.log.error(`Push failed: ${error}`);\n };\n\n private handleManualInstructions = ({ instructions }: InstallerEvents['postinstall:manual']): void => {\n clack.log.info('GitHub CLI not found. Manual steps:');\n console.log(chalk.dim(instructions));\n };\n}\n"]}
|