workos 0.8.1 → 0.9.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.
Files changed (52) hide show
  1. package/README.md +5 -2
  2. package/dist/bin.js +23 -13
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/auth-status.d.ts +1 -0
  5. package/dist/commands/auth-status.js +56 -0
  6. package/dist/commands/auth-status.js.map +1 -0
  7. package/dist/commands/login.js +7 -5
  8. package/dist/commands/login.js.map +1 -1
  9. package/dist/doctor/checks/ai-analysis.js +3 -3
  10. package/dist/doctor/checks/ai-analysis.js.map +1 -1
  11. package/dist/doctor/checks/auth-patterns.js +10 -5
  12. package/dist/doctor/checks/auth-patterns.js.map +1 -1
  13. package/dist/lib/adapters/cli-adapter.js +1 -1
  14. package/dist/lib/adapters/cli-adapter.js.map +1 -1
  15. package/dist/lib/agent-interface.js +5 -5
  16. package/dist/lib/agent-interface.js.map +1 -1
  17. package/dist/lib/config-store.js +8 -7
  18. package/dist/lib/config-store.js.map +1 -1
  19. package/dist/lib/credential-proxy.js +1 -1
  20. package/dist/lib/credential-proxy.js.map +1 -1
  21. package/dist/lib/credential-store.js +8 -2
  22. package/dist/lib/credential-store.js.map +1 -1
  23. package/dist/lib/ensure-auth.js +12 -24
  24. package/dist/lib/ensure-auth.js.map +1 -1
  25. package/dist/lib/run-with-core.js +1 -1
  26. package/dist/lib/run-with-core.js.map +1 -1
  27. package/dist/lib/token-refresh-client.js +1 -1
  28. package/dist/lib/token-refresh-client.js.map +1 -1
  29. package/dist/lib/token-refresh.js +1 -1
  30. package/dist/lib/token-refresh.js.map +1 -1
  31. package/dist/lib/version-check.js +2 -1
  32. package/dist/lib/version-check.js.map +1 -1
  33. package/dist/utils/exit-codes.js +1 -1
  34. package/dist/utils/exit-codes.js.map +1 -1
  35. package/dist/utils/help-json.js +7 -2
  36. package/dist/utils/help-json.js.map +1 -1
  37. package/package.json +1 -1
  38. package/skills/workos-authkit-nextjs/SKILL.md +1 -1
  39. package/skills/workos-authkit-react/SKILL.md +19 -10
  40. package/skills/workos-authkit-react-router/SKILL.md +18 -8
  41. package/skills/workos-authkit-sveltekit/SKILL.md +55 -7
  42. package/skills/workos-authkit-tanstack-start/SKILL.md +67 -16
  43. package/skills/workos-authkit-vanilla-js/SKILL.md +19 -10
  44. package/skills/workos-elixir/SKILL.md +37 -0
  45. package/skills/workos-go/SKILL.md +36 -1
  46. package/skills/workos-kotlin/SKILL.md +34 -0
  47. package/skills/workos-management/SKILL.md +1 -1
  48. package/skills/workos-node/SKILL.md +33 -0
  49. package/skills/workos-php/SKILL.md +34 -1
  50. package/skills/workos-php-laravel/SKILL.md +36 -1
  51. package/skills/workos-python/SKILL.md +34 -0
  52. package/skills/workos-ruby/SKILL.md +35 -0
@@ -1 +1 @@
1
- {"version":3,"file":"credential-proxy.js","sourceRoot":"","sources":["../../src/lib/credential-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lightweight HTTP proxy that injects credentials from file into requests.\n * Includes lazy token refresh - refreshes proactively when token is expiring soon.\n */\n\nimport http from 'node:http';\nimport https from 'node:https';\nimport { URL } from 'node:url';\nimport { logInfo, logError, logWarn } from '../utils/debug.js';\nimport { getCredentials, updateTokens, type Credentials } from './credentials.js';\nimport { analytics } from '../utils/analytics.js';\nimport { refreshAccessToken } from './token-refresh-client.js';\n\nexport interface RefreshConfig {\n /** AuthKit domain for refresh endpoint */\n authkitDomain: string;\n /** OAuth client ID */\n clientId: string;\n /** Threshold in ms - refresh when token expires within this window (default: 60000 = 1 min) */\n refreshThresholdMs?: number;\n /** Callback when refresh succeeds */\n onRefreshSuccess?: () => void;\n /** Callback when refresh fails permanently (token expired, invalid_grant) */\n onRefreshExpired?: () => void;\n}\n\nexport interface CredentialProxyOptions {\n /** Upstream URL to forward requests to */\n upstreamUrl: string;\n /** Optional: specific port to bind (default: random) */\n port?: number;\n /** Optional: refresh configuration for lazy token refresh */\n refresh?: RefreshConfig;\n}\n\nexport interface CredentialProxyHandle {\n /** Port the proxy is listening on */\n port: number;\n /** Full URL for the proxy (e.g., http://localhost:54321) */\n url: string;\n /** Stop the proxy server */\n stop: () => Promise<void>;\n}\n\n// Module-level state for lazy refresh\nlet refreshPromise: Promise<void> | null = null;\nlet refreshConfig: RefreshConfig | null = null;\nlet consecutiveFailures = 0;\nconst MAX_CONSECUTIVE_FAILURES = 3;\n\n/**\n * Perform token refresh, updating credentials file.\n * Returns true if refresh succeeded.\n */\nasync function doRefresh(): Promise<boolean> {\n if (!refreshConfig) {\n logError('[credential-proxy] No refresh config available');\n return false;\n }\n\n const { authkitDomain, clientId, onRefreshSuccess, onRefreshExpired } = refreshConfig;\n const startTime = Date.now();\n\n logInfo('[credential-proxy] Starting token refresh...');\n\n analytics.capture('installer.token.refresh', {\n action: 'refresh_attempt',\n trigger: 'lazy',\n });\n\n const result = await refreshAccessToken(authkitDomain, clientId);\n\n if (result.success && result.accessToken && result.expiresAt) {\n // Update credentials file atomically\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n\n consecutiveFailures = 0;\n const durationMs = Date.now() - startTime;\n\n logInfo(\n `[credential-proxy] Token refreshed in ${durationMs}ms, expires: ${new Date(result.expiresAt).toISOString()}`,\n );\n\n analytics.capture('installer.token.refresh', {\n action: 'refresh_success',\n duration_ms: durationMs,\n token_rotated: !!result.refreshToken,\n });\n\n onRefreshSuccess?.();\n return true;\n }\n\n consecutiveFailures++;\n\n logError(`[credential-proxy] Refresh failed: ${result.error}`);\n\n analytics.capture('installer.token.refresh', {\n action: 'refresh_failure',\n error_type: result.errorType || 'unknown',\n error_message: result.error || 'Unknown error',\n consecutive_failures: consecutiveFailures,\n });\n\n // Handle permanent failure\n if (result.errorType === 'invalid_grant' || consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n logError('[credential-proxy] Refresh token expired or too many failures');\n onRefreshExpired?.();\n }\n\n return false;\n}\n\n/**\n * Ensure we have valid credentials, refreshing if needed.\n * Uses a promise-based lock to prevent concurrent refreshes.\n *\n * @returns Credentials to use for request, or null if unavailable\n */\nasync function ensureValidCredentials(thresholdMs: number): Promise<Credentials | null> {\n const creds = getCredentials();\n\n if (!creds?.accessToken) {\n return null;\n }\n\n // No refresh token = can't refresh, just use what we have\n if (!creds.refreshToken || !refreshConfig) {\n return creds;\n }\n\n const timeUntilExpiry = creds.expiresAt - Date.now();\n\n if (timeUntilExpiry <= 0) {\n // Token expired - must wait for refresh\n logWarn('[credential-proxy] Token expired, waiting for refresh...');\n\n if (!refreshPromise) {\n refreshPromise = doRefresh()\n .then(() => {})\n .finally(() => {\n refreshPromise = null;\n });\n }\n\n await refreshPromise;\n return getCredentials(); // Return fresh credentials\n }\n\n if (timeUntilExpiry < thresholdMs) {\n // Token expiring soon - trigger background refresh, but use current token\n logInfo(`[credential-proxy] Token expires in ${Math.round(timeUntilExpiry / 1000)}s, triggering refresh`);\n\n if (!refreshPromise) {\n refreshPromise = doRefresh()\n .then(() => {})\n .finally(() => {\n refreshPromise = null;\n });\n }\n // Don't await - fire and forget, use current (still valid) token\n }\n\n return creds;\n}\n\n/**\n * Start the credential injector proxy with optional lazy refresh.\n */\nexport async function startCredentialProxy(options: CredentialProxyOptions): Promise<CredentialProxyHandle> {\n const upstream = new URL(options.upstreamUrl);\n const useHttps = upstream.protocol === 'https:';\n const thresholdMs = options.refresh?.refreshThresholdMs ?? 60_000;\n\n // Store refresh config for lazy refresh\n refreshConfig = options.refresh ?? null;\n consecutiveFailures = 0;\n\n const server = http.createServer(async (req, res) => {\n await handleRequest(req, res, upstream, useHttps, thresholdMs);\n });\n\n // Find available port\n const port = await new Promise<number>((resolve, reject) => {\n const tryPort = options.port ?? 0; // 0 = random available port\n let attempts = 0;\n const maxAttempts = 10;\n\n const tryListen = (p: number) => {\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE' && attempts < maxAttempts) {\n attempts++;\n tryListen(0); // Try random port\n } else {\n reject(err);\n }\n });\n\n server.listen(p, '127.0.0.1', () => {\n const addr = server.address();\n if (addr && typeof addr === 'object') {\n resolve(addr.port);\n } else {\n reject(new Error('Failed to get server address'));\n }\n });\n };\n\n tryListen(tryPort);\n });\n\n const url = `http://127.0.0.1:${port}`;\n logInfo(`[credential-proxy] Started on ${url}, forwarding to ${options.upstreamUrl}`);\n if (refreshConfig) {\n logInfo(`[credential-proxy] Lazy refresh enabled, threshold: ${thresholdMs}ms`);\n }\n\n // Telemetry for proxy start\n analytics.capture('installer.proxy', {\n action: 'start',\n port,\n refresh_enabled: !!refreshConfig,\n });\n\n return {\n port,\n url,\n stop: async () => {\n // Clear refresh state\n refreshConfig = null;\n refreshPromise = null;\n consecutiveFailures = 0;\n await stopServer(server);\n },\n };\n}\n\nasync function handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n upstream: URL,\n useHttps: boolean,\n thresholdMs: number,\n): Promise<void> {\n // Get valid credentials, potentially triggering refresh\n const creds = await ensureValidCredentials(thresholdMs);\n\n if (!creds?.accessToken) {\n logError('[credential-proxy] No credentials available');\n res.writeHead(401, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'credentials_unavailable',\n message: 'Not authenticated. Run `workos login` first.',\n }),\n );\n return;\n }\n\n // Build upstream request options\n // Concatenate paths properly - URL() would replace the base path with absolute paths\n const requestPath = req.url || '/';\n const basePath = upstream.pathname.replace(/\\/$/, ''); // Remove trailing slash\n const fullPath = basePath + requestPath;\n const upstreamUrl = new URL(fullPath, upstream.origin);\n\n const headers: http.OutgoingHttpHeaders = {};\n\n // Copy headers, excluding hop-by-hop headers\n const hopByHop = new Set([\n 'connection',\n 'keep-alive',\n 'proxy-authenticate',\n 'proxy-authorization',\n 'te',\n 'trailer',\n 'transfer-encoding',\n 'upgrade',\n ]);\n\n for (const [key, value] of Object.entries(req.headers)) {\n if (!hopByHop.has(key.toLowerCase()) && value !== undefined) {\n headers[key] = value;\n }\n }\n\n // Inject credentials\n headers['authorization'] = `Bearer ${creds.accessToken}`;\n headers['host'] = upstream.host;\n\n // Strip beta=true query param - WorkOS LLM gateway doesn't support it\n const searchParams = new URLSearchParams(upstreamUrl.search);\n searchParams.delete('beta');\n const queryString = searchParams.toString();\n const finalPath = upstreamUrl.pathname + (queryString ? `?${queryString}` : '');\n\n const requestOptions: http.RequestOptions = {\n hostname: upstream.hostname,\n port: upstream.port || (useHttps ? 443 : 80),\n path: finalPath,\n method: req.method,\n headers,\n timeout: 120_000, // 2 minute timeout\n };\n\n const transport = useHttps ? https : http;\n\n const proxyReq = transport.request(requestOptions, (proxyRes) => {\n // Copy response headers\n const responseHeaders: http.OutgoingHttpHeaders = {};\n for (const [key, value] of Object.entries(proxyRes.headers)) {\n if (!hopByHop.has(key.toLowerCase()) && value !== undefined) {\n responseHeaders[key] = value;\n }\n }\n\n res.writeHead(proxyRes.statusCode || 500, responseHeaders);\n proxyRes.pipe(res);\n });\n\n proxyReq.on('error', (err) => {\n logError('[credential-proxy] Upstream error:', err.message);\n\n if (!res.headersSent) {\n if ((err as NodeJS.ErrnoException).code === 'ECONNREFUSED') {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'upstream_unavailable',\n message: 'Could not connect to upstream server',\n }),\n );\n } else if ((err as NodeJS.ErrnoException).code === 'ETIMEDOUT') {\n res.writeHead(504, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'upstream_timeout',\n message: 'Upstream server timed out',\n }),\n );\n } else {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'proxy_error',\n message: err.message,\n }),\n );\n }\n }\n });\n\n proxyReq.on('timeout', () => {\n proxyReq.destroy();\n if (!res.headersSent) {\n res.writeHead(504, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'upstream_timeout',\n message: 'Upstream server timed out',\n }),\n );\n }\n });\n\n // Stream request body\n req.pipe(proxyReq);\n}\n\nfunction stopServer(server: http.Server): Promise<void> {\n return new Promise((resolve, reject) => {\n // Set a timeout for graceful shutdown\n const timeout = setTimeout(() => {\n logInfo('[credential-proxy] Force closing after timeout');\n server.closeAllConnections?.();\n resolve();\n }, 5000);\n\n server.close((err) => {\n clearTimeout(timeout);\n if (err) {\n logError('[credential-proxy] Error stopping server:', err);\n reject(err);\n } else {\n logInfo('[credential-proxy] Stopped');\n resolve();\n }\n });\n });\n}\n"]}
1
+ {"version":3,"file":"credential-proxy.js","sourceRoot":"","sources":["../../src/lib/credential-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lightweight HTTP proxy that injects credentials from file into requests.\n * Includes lazy token refresh - refreshes proactively when token is expiring soon.\n */\n\nimport http from 'node:http';\nimport https from 'node:https';\nimport { URL } from 'node:url';\nimport { logInfo, logError, logWarn } from '../utils/debug.js';\nimport { getCredentials, updateTokens, type Credentials } from './credentials.js';\nimport { analytics } from '../utils/analytics.js';\nimport { refreshAccessToken } from './token-refresh-client.js';\n\nexport interface RefreshConfig {\n /** AuthKit domain for refresh endpoint */\n authkitDomain: string;\n /** OAuth client ID */\n clientId: string;\n /** Threshold in ms - refresh when token expires within this window (default: 60000 = 1 min) */\n refreshThresholdMs?: number;\n /** Callback when refresh succeeds */\n onRefreshSuccess?: () => void;\n /** Callback when refresh fails permanently (token expired, invalid_grant) */\n onRefreshExpired?: () => void;\n}\n\nexport interface CredentialProxyOptions {\n /** Upstream URL to forward requests to */\n upstreamUrl: string;\n /** Optional: specific port to bind (default: random) */\n port?: number;\n /** Optional: refresh configuration for lazy token refresh */\n refresh?: RefreshConfig;\n}\n\nexport interface CredentialProxyHandle {\n /** Port the proxy is listening on */\n port: number;\n /** Full URL for the proxy (e.g., http://localhost:54321) */\n url: string;\n /** Stop the proxy server */\n stop: () => Promise<void>;\n}\n\n// Module-level state for lazy refresh\nlet refreshPromise: Promise<void> | null = null;\nlet refreshConfig: RefreshConfig | null = null;\nlet consecutiveFailures = 0;\nconst MAX_CONSECUTIVE_FAILURES = 3;\n\n/**\n * Perform token refresh, updating credentials file.\n * Returns true if refresh succeeded.\n */\nasync function doRefresh(): Promise<boolean> {\n if (!refreshConfig) {\n logError('[credential-proxy] No refresh config available');\n return false;\n }\n\n const { authkitDomain, clientId, onRefreshSuccess, onRefreshExpired } = refreshConfig;\n const startTime = Date.now();\n\n logInfo('[credential-proxy] Starting token refresh...');\n\n analytics.capture('installer.token.refresh', {\n action: 'refresh_attempt',\n trigger: 'lazy',\n });\n\n const result = await refreshAccessToken(authkitDomain, clientId);\n\n if (result.success && result.accessToken && result.expiresAt) {\n // Update credentials file atomically\n updateTokens(result.accessToken, result.expiresAt, result.refreshToken);\n\n consecutiveFailures = 0;\n const durationMs = Date.now() - startTime;\n\n logInfo(\n `[credential-proxy] Token refreshed in ${durationMs}ms, expires: ${new Date(result.expiresAt).toISOString()}`,\n );\n\n analytics.capture('installer.token.refresh', {\n action: 'refresh_success',\n duration_ms: durationMs,\n token_rotated: !!result.refreshToken,\n });\n\n onRefreshSuccess?.();\n return true;\n }\n\n consecutiveFailures++;\n\n logError(`[credential-proxy] Refresh failed: ${result.error}`);\n\n analytics.capture('installer.token.refresh', {\n action: 'refresh_failure',\n error_type: result.errorType || 'unknown',\n error_message: result.error || 'Unknown error',\n consecutive_failures: consecutiveFailures,\n });\n\n // Handle permanent failure\n if (result.errorType === 'invalid_grant' || consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n logError('[credential-proxy] Refresh token expired or too many failures');\n onRefreshExpired?.();\n }\n\n return false;\n}\n\n/**\n * Ensure we have valid credentials, refreshing if needed.\n * Uses a promise-based lock to prevent concurrent refreshes.\n *\n * @returns Credentials to use for request, or null if unavailable\n */\nasync function ensureValidCredentials(thresholdMs: number): Promise<Credentials | null> {\n const creds = getCredentials();\n\n if (!creds?.accessToken) {\n return null;\n }\n\n // No refresh token = can't refresh, just use what we have\n if (!creds.refreshToken || !refreshConfig) {\n return creds;\n }\n\n const timeUntilExpiry = creds.expiresAt - Date.now();\n\n if (timeUntilExpiry <= 0) {\n // Token expired - must wait for refresh\n logWarn('[credential-proxy] Token expired, waiting for refresh...');\n\n if (!refreshPromise) {\n refreshPromise = doRefresh()\n .then(() => {})\n .finally(() => {\n refreshPromise = null;\n });\n }\n\n await refreshPromise;\n return getCredentials(); // Return fresh credentials\n }\n\n if (timeUntilExpiry < thresholdMs) {\n // Token expiring soon - trigger background refresh, but use current token\n logInfo(`[credential-proxy] Token expires in ${Math.round(timeUntilExpiry / 1000)}s, triggering refresh`);\n\n if (!refreshPromise) {\n refreshPromise = doRefresh()\n .then(() => {})\n .finally(() => {\n refreshPromise = null;\n });\n }\n // Don't await - fire and forget, use current (still valid) token\n }\n\n return creds;\n}\n\n/**\n * Start the credential injector proxy with optional lazy refresh.\n */\nexport async function startCredentialProxy(options: CredentialProxyOptions): Promise<CredentialProxyHandle> {\n const upstream = new URL(options.upstreamUrl);\n const useHttps = upstream.protocol === 'https:';\n const thresholdMs = options.refresh?.refreshThresholdMs ?? 60_000;\n\n // Store refresh config for lazy refresh\n refreshConfig = options.refresh ?? null;\n consecutiveFailures = 0;\n\n const server = http.createServer(async (req, res) => {\n await handleRequest(req, res, upstream, useHttps, thresholdMs);\n });\n\n // Find available port\n const port = await new Promise<number>((resolve, reject) => {\n const tryPort = options.port ?? 0; // 0 = random available port\n let attempts = 0;\n const maxAttempts = 10;\n\n const tryListen = (p: number) => {\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE' && attempts < maxAttempts) {\n attempts++;\n tryListen(0); // Try random port\n } else {\n reject(err);\n }\n });\n\n server.listen(p, '127.0.0.1', () => {\n const addr = server.address();\n if (addr && typeof addr === 'object') {\n resolve(addr.port);\n } else {\n reject(new Error('Failed to get server address'));\n }\n });\n };\n\n tryListen(tryPort);\n });\n\n const url = `http://127.0.0.1:${port}`;\n logInfo(`[credential-proxy] Started on ${url}, forwarding to ${options.upstreamUrl}`);\n if (refreshConfig) {\n logInfo(`[credential-proxy] Lazy refresh enabled, threshold: ${thresholdMs}ms`);\n }\n\n // Telemetry for proxy start\n analytics.capture('installer.proxy', {\n action: 'start',\n port,\n refresh_enabled: !!refreshConfig,\n });\n\n return {\n port,\n url,\n stop: async () => {\n // Clear refresh state\n refreshConfig = null;\n refreshPromise = null;\n consecutiveFailures = 0;\n await stopServer(server);\n },\n };\n}\n\nasync function handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n upstream: URL,\n useHttps: boolean,\n thresholdMs: number,\n): Promise<void> {\n // Get valid credentials, potentially triggering refresh\n const creds = await ensureValidCredentials(thresholdMs);\n\n if (!creds?.accessToken) {\n logError('[credential-proxy] No credentials available');\n res.writeHead(401, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'credentials_unavailable',\n message: 'Not authenticated. Run `workos auth login` first.',\n }),\n );\n return;\n }\n\n // Build upstream request options\n // Concatenate paths properly - URL() would replace the base path with absolute paths\n const requestPath = req.url || '/';\n const basePath = upstream.pathname.replace(/\\/$/, ''); // Remove trailing slash\n const fullPath = basePath + requestPath;\n const upstreamUrl = new URL(fullPath, upstream.origin);\n\n const headers: http.OutgoingHttpHeaders = {};\n\n // Copy headers, excluding hop-by-hop headers\n const hopByHop = new Set([\n 'connection',\n 'keep-alive',\n 'proxy-authenticate',\n 'proxy-authorization',\n 'te',\n 'trailer',\n 'transfer-encoding',\n 'upgrade',\n ]);\n\n for (const [key, value] of Object.entries(req.headers)) {\n if (!hopByHop.has(key.toLowerCase()) && value !== undefined) {\n headers[key] = value;\n }\n }\n\n // Inject credentials\n headers['authorization'] = `Bearer ${creds.accessToken}`;\n headers['host'] = upstream.host;\n\n // Strip beta=true query param - WorkOS LLM gateway doesn't support it\n const searchParams = new URLSearchParams(upstreamUrl.search);\n searchParams.delete('beta');\n const queryString = searchParams.toString();\n const finalPath = upstreamUrl.pathname + (queryString ? `?${queryString}` : '');\n\n const requestOptions: http.RequestOptions = {\n hostname: upstream.hostname,\n port: upstream.port || (useHttps ? 443 : 80),\n path: finalPath,\n method: req.method,\n headers,\n timeout: 120_000, // 2 minute timeout\n };\n\n const transport = useHttps ? https : http;\n\n const proxyReq = transport.request(requestOptions, (proxyRes) => {\n // Copy response headers\n const responseHeaders: http.OutgoingHttpHeaders = {};\n for (const [key, value] of Object.entries(proxyRes.headers)) {\n if (!hopByHop.has(key.toLowerCase()) && value !== undefined) {\n responseHeaders[key] = value;\n }\n }\n\n res.writeHead(proxyRes.statusCode || 500, responseHeaders);\n proxyRes.pipe(res);\n });\n\n proxyReq.on('error', (err) => {\n logError('[credential-proxy] Upstream error:', err.message);\n\n if (!res.headersSent) {\n if ((err as NodeJS.ErrnoException).code === 'ECONNREFUSED') {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'upstream_unavailable',\n message: 'Could not connect to upstream server',\n }),\n );\n } else if ((err as NodeJS.ErrnoException).code === 'ETIMEDOUT') {\n res.writeHead(504, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'upstream_timeout',\n message: 'Upstream server timed out',\n }),\n );\n } else {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'proxy_error',\n message: err.message,\n }),\n );\n }\n }\n });\n\n proxyReq.on('timeout', () => {\n proxyReq.destroy();\n if (!res.headersSent) {\n res.writeHead(504, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'upstream_timeout',\n message: 'Upstream server timed out',\n }),\n );\n }\n });\n\n // Stream request body\n req.pipe(proxyReq);\n}\n\nfunction stopServer(server: http.Server): Promise<void> {\n return new Promise((resolve, reject) => {\n // Set a timeout for graceful shutdown\n const timeout = setTimeout(() => {\n logInfo('[credential-proxy] Force closing after timeout');\n server.closeAllConnections?.();\n resolve();\n }, 5000);\n\n server.close((err) => {\n clearTimeout(timeout);\n if (err) {\n logError('[credential-proxy] Error stopping server:', err);\n reject(err);\n } else {\n logInfo('[credential-proxy] Stopped');\n resolve();\n }\n });\n });\n}\n"]}
@@ -14,8 +14,10 @@ const SERVICE_NAME = 'workos-cli';
14
14
  const ACCOUNT_NAME = 'credentials';
15
15
  let fallbackWarningShown = false;
16
16
  let forceInsecureStorage = false;
17
+ let migrationAttempted = false;
17
18
  export function setInsecureStorage(value) {
18
19
  forceInsecureStorage = value;
20
+ migrationAttempted = false;
19
21
  }
20
22
  function getCredentialsDir() {
21
23
  return path.join(os.homedir(), '.workos');
@@ -115,7 +117,10 @@ export function getCredentials() {
115
117
  return keyringCreds;
116
118
  const fileCreds = readFromFile();
117
119
  if (fileCreds) {
118
- writeToKeyring(fileCreds);
120
+ if (!migrationAttempted) {
121
+ migrationAttempted = true;
122
+ writeToKeyring(fileCreds);
123
+ }
119
124
  return fileCreds;
120
125
  }
121
126
  return null;
@@ -123,14 +128,15 @@ export function getCredentials() {
123
128
  export function saveCredentials(creds) {
124
129
  if (forceInsecureStorage)
125
130
  return writeToFile(creds);
126
- writeToFile(creds);
127
131
  if (!writeToKeyring(creds)) {
128
132
  showFallbackWarning();
133
+ writeToFile(creds);
129
134
  }
130
135
  }
131
136
  export function clearCredentials() {
132
137
  deleteFromKeyring();
133
138
  deleteFile();
139
+ migrationAttempted = false;
134
140
  }
135
141
  export function updateTokens(accessToken, expiresAt, refreshToken) {
136
142
  const creds = getCredentials();
@@ -1 +1 @@
1
- {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/lib/credential-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential storage abstraction with keyring support and file fallback.\n *\n * Storage priority:\n * 1. If --insecure-storage: use file only\n * 2. Try keyring, fall back to file with warning if unavailable\n */\n\nimport { Entry } from '@napi-rs/keyring';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { logWarn } from '../utils/debug.js';\n\nexport interface StagingCache {\n clientId: string;\n apiKey: string;\n fetchedAt: number;\n}\n\nexport interface Credentials {\n accessToken: string;\n expiresAt: number;\n userId: string;\n email?: string;\n staging?: StagingCache;\n refreshToken?: string;\n}\n\nconst SERVICE_NAME = 'workos-cli';\nconst ACCOUNT_NAME = 'credentials';\n\nlet fallbackWarningShown = false;\nlet forceInsecureStorage = false;\n\nexport function setInsecureStorage(value: boolean): void {\n forceInsecureStorage = value;\n}\n\nfunction getCredentialsDir(): string {\n return path.join(os.homedir(), '.workos');\n}\n\nfunction getCredentialsPath(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nfunction fileExists(): boolean {\n return fs.existsSync(getCredentialsPath());\n}\n\nfunction readFromFile(): Credentials | null {\n if (!fileExists()) return null;\n try {\n const content = fs.readFileSync(getCredentialsPath(), 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n logWarn('Failed to read credentials file:', error);\n return null;\n }\n}\n\nfunction writeToFile(creds: Credentials): void {\n const dir = getCredentialsDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(getCredentialsPath(), JSON.stringify(creds, null, 2), {\n mode: 0o600,\n });\n}\n\nfunction deleteFile(): void {\n if (fileExists()) {\n fs.unlinkSync(getCredentialsPath());\n }\n}\n\nfunction getKeyringEntry(): Entry {\n return new Entry(SERVICE_NAME, ACCOUNT_NAME);\n}\n\nfunction readFromKeyring(): Credentials | null {\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (!data) {\n logWarn('[credential-store] keyring: entry exists but data is null/empty');\n return null;\n }\n return JSON.parse(data);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[credential-store] keyring read failed: ${msg}`);\n return null;\n }\n}\n\nfunction writeToKeyring(creds: Credentials): boolean {\n try {\n const entry = getKeyringEntry();\n entry.setPassword(JSON.stringify(creds));\n return true;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[credential-store] keyring write failed: ${msg}`);\n return false;\n }\n}\n\nfunction deleteFromKeyring(): void {\n try {\n const entry = getKeyringEntry();\n entry.deletePassword();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (!msg.includes('not found') && !msg.includes('No such')) {\n logWarn('Failed to delete from keyring:', error);\n }\n }\n}\n\nfunction showFallbackWarning(): void {\n if (fallbackWarningShown || forceInsecureStorage) return;\n fallbackWarningShown = true;\n logWarn(\n 'Unable to store credentials in system keyring. Using file storage.',\n 'Credentials saved to ~/.workos/credentials.json',\n 'Use --insecure-storage to suppress this warning.',\n );\n}\n\nexport function hasCredentials(): boolean {\n if (forceInsecureStorage) {\n return fileExists();\n }\n return readFromKeyring() !== null || fileExists();\n}\n\nexport function getCredentials(): Credentials | null {\n if (forceInsecureStorage) return readFromFile();\n\n const keyringCreds = readFromKeyring();\n if (keyringCreds) return keyringCreds;\n\n const fileCreds = readFromFile();\n if (fileCreds) {\n writeToKeyring(fileCreds);\n return fileCreds;\n }\n\n return null;\n}\n\nexport function saveCredentials(creds: Credentials): void {\n if (forceInsecureStorage) return writeToFile(creds);\n\n writeToFile(creds);\n if (!writeToKeyring(creds)) {\n showFallbackWarning();\n }\n}\n\nexport function clearCredentials(): void {\n deleteFromKeyring();\n deleteFile();\n}\n\nexport function updateTokens(accessToken: string, expiresAt: number, refreshToken?: string): void {\n const creds = getCredentials();\n if (!creds) {\n throw new Error('No existing credentials to update');\n }\n\n const updated: Credentials = {\n ...creds,\n accessToken,\n expiresAt,\n ...(refreshToken && { refreshToken }),\n };\n\n saveCredentials(updated);\n}\n\n/**\n * Diagnostic info about credential storage state — for debugging auth failures.\n */\nexport function diagnoseCredentials(): string[] {\n const lines: string[] = [];\n const filePath = getCredentialsPath();\n const filePresent = fileExists();\n\n lines.push(`file: ${filePath} (exists=${filePresent})`);\n\n if (filePresent) {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<Credentials>;\n const expired = parsed.expiresAt ? Date.now() >= parsed.expiresAt : 'unknown';\n lines.push(\n `file creds: userId=${parsed.userId ?? 'missing'}, expired=${expired}, hasRefreshToken=${!!parsed.refreshToken}`,\n );\n } catch (e) {\n lines.push(`file creds: parse error — ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (data) {\n const parsed = JSON.parse(data) as Partial<Credentials>;\n const expired = parsed.expiresAt ? Date.now() >= parsed.expiresAt : 'unknown';\n lines.push(\n `keyring: found, userId=${parsed.userId ?? 'missing'}, expired=${expired}, hasRefreshToken=${!!parsed.refreshToken}`,\n );\n } else {\n lines.push('keyring: empty (getPassword returned null)');\n }\n } catch (e) {\n lines.push(`keyring: error — ${e instanceof Error ? e.message : String(e)}`);\n }\n\n lines.push(`insecureStorage=${forceInsecureStorage}`);\n return lines;\n}\n\nexport { getCredentialsPath };\n"]}
1
+ {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/lib/credential-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential storage abstraction with keyring support and file fallback.\n *\n * Storage priority:\n * 1. If --insecure-storage: use file only\n * 2. Try keyring, fall back to file with warning if unavailable\n */\n\nimport { Entry } from '@napi-rs/keyring';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { logWarn } from '../utils/debug.js';\n\nexport interface StagingCache {\n clientId: string;\n apiKey: string;\n fetchedAt: number;\n}\n\nexport interface Credentials {\n accessToken: string;\n expiresAt: number;\n userId: string;\n email?: string;\n staging?: StagingCache;\n refreshToken?: string;\n}\n\nconst SERVICE_NAME = 'workos-cli';\nconst ACCOUNT_NAME = 'credentials';\n\nlet fallbackWarningShown = false;\nlet forceInsecureStorage = false;\nlet migrationAttempted = false;\n\nexport function setInsecureStorage(value: boolean): void {\n forceInsecureStorage = value;\n migrationAttempted = false;\n}\n\nfunction getCredentialsDir(): string {\n return path.join(os.homedir(), '.workos');\n}\n\nfunction getCredentialsPath(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nfunction fileExists(): boolean {\n return fs.existsSync(getCredentialsPath());\n}\n\nfunction readFromFile(): Credentials | null {\n if (!fileExists()) return null;\n try {\n const content = fs.readFileSync(getCredentialsPath(), 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n logWarn('Failed to read credentials file:', error);\n return null;\n }\n}\n\nfunction writeToFile(creds: Credentials): void {\n const dir = getCredentialsDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(getCredentialsPath(), JSON.stringify(creds, null, 2), {\n mode: 0o600,\n });\n}\n\nfunction deleteFile(): void {\n if (fileExists()) {\n fs.unlinkSync(getCredentialsPath());\n }\n}\n\nfunction getKeyringEntry(): Entry {\n return new Entry(SERVICE_NAME, ACCOUNT_NAME);\n}\n\nfunction readFromKeyring(): Credentials | null {\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (!data) {\n logWarn('[credential-store] keyring: entry exists but data is null/empty');\n return null;\n }\n return JSON.parse(data);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[credential-store] keyring read failed: ${msg}`);\n return null;\n }\n}\n\nfunction writeToKeyring(creds: Credentials): boolean {\n try {\n const entry = getKeyringEntry();\n entry.setPassword(JSON.stringify(creds));\n return true;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[credential-store] keyring write failed: ${msg}`);\n return false;\n }\n}\n\nfunction deleteFromKeyring(): void {\n try {\n const entry = getKeyringEntry();\n entry.deletePassword();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (!msg.includes('not found') && !msg.includes('No such')) {\n logWarn('Failed to delete from keyring:', error);\n }\n }\n}\n\nfunction showFallbackWarning(): void {\n if (fallbackWarningShown || forceInsecureStorage) return;\n fallbackWarningShown = true;\n logWarn(\n 'Unable to store credentials in system keyring. Using file storage.',\n 'Credentials saved to ~/.workos/credentials.json',\n 'Use --insecure-storage to suppress this warning.',\n );\n}\n\nexport function hasCredentials(): boolean {\n if (forceInsecureStorage) {\n return fileExists();\n }\n return readFromKeyring() !== null || fileExists();\n}\n\nexport function getCredentials(): Credentials | null {\n if (forceInsecureStorage) return readFromFile();\n\n const keyringCreds = readFromKeyring();\n if (keyringCreds) return keyringCreds;\n\n const fileCreds = readFromFile();\n if (fileCreds) {\n if (!migrationAttempted) {\n migrationAttempted = true;\n writeToKeyring(fileCreds);\n }\n return fileCreds;\n }\n\n return null;\n}\n\nexport function saveCredentials(creds: Credentials): void {\n if (forceInsecureStorage) return writeToFile(creds);\n\n if (!writeToKeyring(creds)) {\n showFallbackWarning();\n writeToFile(creds);\n }\n}\n\nexport function clearCredentials(): void {\n deleteFromKeyring();\n deleteFile();\n migrationAttempted = false;\n}\n\nexport function updateTokens(accessToken: string, expiresAt: number, refreshToken?: string): void {\n const creds = getCredentials();\n if (!creds) {\n throw new Error('No existing credentials to update');\n }\n\n const updated: Credentials = {\n ...creds,\n accessToken,\n expiresAt,\n ...(refreshToken && { refreshToken }),\n };\n\n saveCredentials(updated);\n}\n\n/**\n * Diagnostic info about credential storage state — for debugging auth failures.\n */\nexport function diagnoseCredentials(): string[] {\n const lines: string[] = [];\n const filePath = getCredentialsPath();\n const filePresent = fileExists();\n\n lines.push(`file: ${filePath} (exists=${filePresent})`);\n\n if (filePresent) {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<Credentials>;\n const expired = parsed.expiresAt ? Date.now() >= parsed.expiresAt : 'unknown';\n lines.push(\n `file creds: userId=${parsed.userId ?? 'missing'}, expired=${expired}, hasRefreshToken=${!!parsed.refreshToken}`,\n );\n } catch (e) {\n lines.push(`file creds: parse error — ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (data) {\n const parsed = JSON.parse(data) as Partial<Credentials>;\n const expired = parsed.expiresAt ? Date.now() >= parsed.expiresAt : 'unknown';\n lines.push(\n `keyring: found, userId=${parsed.userId ?? 'missing'}, expired=${expired}, hasRefreshToken=${!!parsed.refreshToken}`,\n );\n } else {\n lines.push('keyring: empty (getPassword returned null)');\n }\n } catch (e) {\n lines.push(`keyring: error — ${e instanceof Error ? e.message : String(e)}`);\n }\n\n lines.push(`insecureStorage=${forceInsecureStorage}`);\n return lines;\n}\n\nexport { getCredentialsPath };\n"]}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Startup auth guard - ensures valid authentication before command execution.
3
3
  */
4
- import { getCredentials, updateTokens, hasCredentials, isTokenExpired, clearCredentials } from './credentials.js';
4
+ import { getCredentials, updateTokens, isTokenExpired, clearCredentials } from './credentials.js';
5
5
  import { refreshAccessToken } from './token-refresh-client.js';
6
6
  import { getCliAuthClientId, getAuthkitDomain } from './settings.js';
7
7
  import { runLogin } from '../commands/login.js';
@@ -24,28 +24,17 @@ export async function ensureAuthenticated() {
24
24
  loginTriggered: false,
25
25
  tokenRefreshed: false,
26
26
  };
27
- // Case 1: No credentials at all
28
- if (!hasCredentials()) {
29
- if (isNonInteractiveEnvironment()) {
30
- exitWithAuthRequired();
31
- }
32
- logInfo('[ensure-auth] No credentials found, triggering login');
33
- await runLogin();
34
- result.loginTriggered = true;
35
- result.authenticated = hasCredentials();
36
- return result;
37
- }
27
+ // Case 1: No credentials or invalid credentials
38
28
  const creds = getCredentials();
39
29
  if (!creds) {
40
- // Credentials file exists but is invalid/empty — clear stale data
41
- clearCredentials();
30
+ clearCredentials(); // Clean up any corrupt/empty files
42
31
  if (isNonInteractiveEnvironment()) {
43
32
  exitWithAuthRequired();
44
33
  }
45
- logInfo('[ensure-auth] Invalid credentials file, triggering login');
34
+ logInfo('[ensure-auth] No valid credentials found, triggering login');
46
35
  await runLogin();
47
36
  result.loginTriggered = true;
48
- result.authenticated = hasCredentials();
37
+ result.authenticated = getCredentials() !== null;
49
38
  return result;
50
39
  }
51
40
  // Case 2: Access token still valid
@@ -70,35 +59,34 @@ export async function ensureAuthenticated() {
70
59
  if (refreshResult.errorType === 'invalid_grant') {
71
60
  clearCredentials();
72
61
  if (isNonInteractiveEnvironment()) {
73
- exitWithAuthRequired('Session expired. Run `workos login` in an interactive terminal to re-authenticate.');
62
+ exitWithAuthRequired('Session expired. Run `workos auth login` in an interactive terminal to re-authenticate.');
74
63
  }
75
64
  logInfo('[ensure-auth] Refresh token expired, triggering login');
76
65
  await runLogin();
77
66
  result.loginTriggered = true;
78
- result.authenticated = hasCredentials();
67
+ result.authenticated = getCredentials() !== null;
79
68
  return result;
80
69
  }
81
- // Network or server error - clear stale creds and try login as fallback
82
- clearCredentials();
70
+ // Network or server error - keep credentials intact for retry
83
71
  if (isNonInteractiveEnvironment()) {
84
- exitWithAuthRequired(`Authentication refresh failed (${refreshResult.errorType}). Run \`workos login\` in an interactive terminal.`);
72
+ exitWithAuthRequired(`Authentication refresh failed (${refreshResult.errorType}). Run \`workos auth login\` in an interactive terminal.`);
85
73
  }
86
74
  logInfo(`[ensure-auth] Refresh failed (${refreshResult.errorType}), triggering login`);
87
75
  await runLogin();
88
76
  result.loginTriggered = true;
89
- result.authenticated = hasCredentials();
77
+ result.authenticated = getCredentials() !== null;
90
78
  return result;
91
79
  }
92
80
  }
93
81
  // Case 4: No refresh token available — clear stale creds, must login
94
82
  clearCredentials();
95
83
  if (isNonInteractiveEnvironment()) {
96
- exitWithAuthRequired('Session expired. Run `workos login` in an interactive terminal to re-authenticate.');
84
+ exitWithAuthRequired('Session expired. Run `workos auth login` in an interactive terminal to re-authenticate.');
97
85
  }
98
86
  logInfo('[ensure-auth] No refresh token, triggering login');
99
87
  await runLogin();
100
88
  result.loginTriggered = true;
101
- result.authenticated = hasCredentials();
89
+ result.authenticated = getCredentials() !== null;
102
90
  return result;
103
91
  }
104
92
  //# sourceMappingURL=ensure-auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ensure-auth.js","sourceRoot":"","sources":["../../src/lib/ensure-auth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup auth guard - ensures valid authentication before command execution.\n */\n\nimport { getCredentials, updateTokens, hasCredentials, isTokenExpired, clearCredentials } from './credentials.js';\nimport { refreshAccessToken } from './token-refresh-client.js';\nimport { getCliAuthClientId, getAuthkitDomain } from './settings.js';\nimport { runLogin } from '../commands/login.js';\nimport { logInfo } from '../utils/debug.js';\nimport { isNonInteractiveEnvironment } from '../utils/environment.js';\nimport { exitWithAuthRequired } from '../utils/exit-codes.js';\n\nexport interface EnsureAuthResult {\n /** Whether auth is now valid */\n authenticated: boolean;\n /** Whether login flow was triggered */\n loginTriggered: boolean;\n /** Whether token was refreshed */\n tokenRefreshed: boolean;\n}\n\n/**\n * Ensure valid authentication before command execution.\n *\n * - No credentials: triggers login flow\n * - Expired access token (valid refresh): silently refreshes\n * - Expired refresh token: triggers login flow\n *\n * @returns Result indicating what actions were taken\n * @throws Error if login fails or refresh fails unexpectedly\n */\nexport async function ensureAuthenticated(): Promise<EnsureAuthResult> {\n const result: EnsureAuthResult = {\n authenticated: false,\n loginTriggered: false,\n tokenRefreshed: false,\n };\n\n // Case 1: No credentials at all\n if (!hasCredentials()) {\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired();\n }\n logInfo('[ensure-auth] No credentials found, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = hasCredentials();\n return result;\n }\n\n const creds = getCredentials();\n if (!creds) {\n // Credentials file exists but is invalid/empty — clear stale data\n clearCredentials();\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired();\n }\n logInfo('[ensure-auth] Invalid credentials file, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = hasCredentials();\n return result;\n }\n\n // Case 2: Access token still valid\n if (!isTokenExpired(creds)) {\n result.authenticated = true;\n return result;\n }\n\n // Case 3: Access token expired, try refresh\n if (creds.refreshToken) {\n logInfo('[ensure-auth] Access token expired, attempting refresh');\n\n const clientId = getCliAuthClientId();\n const authkitDomain = getAuthkitDomain();\n\n if (clientId && authkitDomain) {\n const refreshResult = await refreshAccessToken(authkitDomain, clientId);\n\n if (refreshResult.success && refreshResult.accessToken && refreshResult.expiresAt) {\n updateTokens(refreshResult.accessToken, refreshResult.expiresAt, refreshResult.refreshToken);\n result.tokenRefreshed = true;\n result.authenticated = true;\n return result;\n }\n\n // Refresh failed - check if it's recoverable\n if (refreshResult.errorType === 'invalid_grant') {\n clearCredentials();\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired('Session expired. Run `workos login` in an interactive terminal to re-authenticate.');\n }\n logInfo('[ensure-auth] Refresh token expired, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = hasCredentials();\n return result;\n }\n\n // Network or server error - clear stale creds and try login as fallback\n clearCredentials();\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired(\n `Authentication refresh failed (${refreshResult.errorType}). Run \\`workos login\\` in an interactive terminal.`,\n );\n }\n logInfo(`[ensure-auth] Refresh failed (${refreshResult.errorType}), triggering login`);\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = hasCredentials();\n return result;\n }\n }\n\n // Case 4: No refresh token available — clear stale creds, must login\n clearCredentials();\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired('Session expired. Run `workos login` in an interactive terminal to re-authenticate.');\n }\n logInfo('[ensure-auth] No refresh token, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = hasCredentials();\n return result;\n}\n"]}
1
+ {"version":3,"file":"ensure-auth.js","sourceRoot":"","sources":["../../src/lib/ensure-auth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup auth guard - ensures valid authentication before command execution.\n */\n\nimport { getCredentials, updateTokens, isTokenExpired, clearCredentials } from './credentials.js';\nimport { refreshAccessToken } from './token-refresh-client.js';\nimport { getCliAuthClientId, getAuthkitDomain } from './settings.js';\nimport { runLogin } from '../commands/login.js';\nimport { logInfo } from '../utils/debug.js';\nimport { isNonInteractiveEnvironment } from '../utils/environment.js';\nimport { exitWithAuthRequired } from '../utils/exit-codes.js';\n\nexport interface EnsureAuthResult {\n /** Whether auth is now valid */\n authenticated: boolean;\n /** Whether login flow was triggered */\n loginTriggered: boolean;\n /** Whether token was refreshed */\n tokenRefreshed: boolean;\n}\n\n/**\n * Ensure valid authentication before command execution.\n *\n * - No credentials: triggers login flow\n * - Expired access token (valid refresh): silently refreshes\n * - Expired refresh token: triggers login flow\n *\n * @returns Result indicating what actions were taken\n * @throws Error if login fails or refresh fails unexpectedly\n */\nexport async function ensureAuthenticated(): Promise<EnsureAuthResult> {\n const result: EnsureAuthResult = {\n authenticated: false,\n loginTriggered: false,\n tokenRefreshed: false,\n };\n\n // Case 1: No credentials or invalid credentials\n const creds = getCredentials();\n if (!creds) {\n clearCredentials(); // Clean up any corrupt/empty files\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired();\n }\n logInfo('[ensure-auth] No valid credentials found, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = getCredentials() !== null;\n return result;\n }\n\n // Case 2: Access token still valid\n if (!isTokenExpired(creds)) {\n result.authenticated = true;\n return result;\n }\n\n // Case 3: Access token expired, try refresh\n if (creds.refreshToken) {\n logInfo('[ensure-auth] Access token expired, attempting refresh');\n\n const clientId = getCliAuthClientId();\n const authkitDomain = getAuthkitDomain();\n\n if (clientId && authkitDomain) {\n const refreshResult = await refreshAccessToken(authkitDomain, clientId);\n\n if (refreshResult.success && refreshResult.accessToken && refreshResult.expiresAt) {\n updateTokens(refreshResult.accessToken, refreshResult.expiresAt, refreshResult.refreshToken);\n result.tokenRefreshed = true;\n result.authenticated = true;\n return result;\n }\n\n // Refresh failed - check if it's recoverable\n if (refreshResult.errorType === 'invalid_grant') {\n clearCredentials();\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired(\n 'Session expired. Run `workos auth login` in an interactive terminal to re-authenticate.',\n );\n }\n logInfo('[ensure-auth] Refresh token expired, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = getCredentials() !== null;\n return result;\n }\n\n // Network or server error - keep credentials intact for retry\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired(\n `Authentication refresh failed (${refreshResult.errorType}). Run \\`workos auth login\\` in an interactive terminal.`,\n );\n }\n logInfo(`[ensure-auth] Refresh failed (${refreshResult.errorType}), triggering login`);\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = getCredentials() !== null;\n return result;\n }\n }\n\n // Case 4: No refresh token available — clear stale creds, must login\n clearCredentials();\n if (isNonInteractiveEnvironment()) {\n exitWithAuthRequired('Session expired. Run `workos auth login` in an interactive terminal to re-authenticate.');\n }\n logInfo('[ensure-auth] No refresh token, triggering login');\n await runLogin();\n result.loginTriggered = true;\n result.authenticated = getCredentials() !== null;\n return result;\n}\n"]}
@@ -179,7 +179,7 @@ export async function runWithCore(options) {
179
179
  if (!token) {
180
180
  // This should rarely happen since bin.ts handles auth first
181
181
  // But keep as safety net for programmatic usage
182
- throw new Error('Not authenticated. Run `workos login` first.');
182
+ throw new Error('Not authenticated. Run `workos auth login` first.');
183
183
  }
184
184
  // Set telemetry from existing credentials
185
185
  const creds = getCredentials();
@@ -1 +1 @@
1
- {"version":3,"file":"run-with-core.js","sourceRoot":"","sources":["../../src/lib/run-with-core.ts"],"names":[],"mappings":"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","sourcesContent":["import { createActor, fromPromise } from 'xstate';\nimport open from 'opn';\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { installerMachine } from './installer-core.js';\nimport { createInstallerEventEmitter } from './events.js';\nimport { CLIAdapter } from './adapters/cli-adapter.js';\nimport { DashboardAdapter } from './adapters/dashboard-adapter.js';\nimport type { InstallerAdapter } from './adapters/types.js';\nimport type { InstallerOptions } from '../utils/types.js';\nimport { isNonInteractiveEnvironment } from '../utils/environment.js';\nimport type {\n InstallerMachineContext,\n DetectionOutput,\n GitCheckOutput,\n AgentOutput,\n BranchCheckOutput,\n} from './installer-core.types.js';\nimport type { Integration } from './constants.js';\nimport { parseEnvFile } from '../utils/env-parser.js';\nimport { enableDebugLogs, initLogFile, logInfo, logError } from '../utils/debug.js';\n\nimport {\n getAccessToken,\n getCredentials,\n saveCredentials,\n getStagingCredentials,\n saveStagingCredentials,\n} from './credentials.js';\nimport { getConfig, saveConfig, getActiveEnvironment } from './config-store.js';\nimport { checkForEnvFiles, discoverCredentials } from './credential-discovery.js';\nimport { requestDeviceCode, pollForToken } from './device-auth.js';\nimport { fetchStagingCredentials as fetchStagingCredentialsApi } from './staging-api.js';\nimport { getCliAuthClientId, getAuthkitDomain } from './settings.js';\nimport { analytics } from '../utils/analytics.js';\nimport { getVersion } from './settings.js';\nimport { getLlmGatewayUrlFromHost } from '../utils/urls.js';\nimport { isInGitRepo, getUncommittedOrUntrackedFiles } from '../utils/clack-utils.js';\nimport {\n getCurrentBranch,\n isProtectedBranch,\n createBranch as createGitBranch,\n branchExists,\n} from '../utils/git-utils.js';\nimport { detectChanges, stageAndCommit, pushBranch as pushGitBranch, createPullRequest } from './post-install.js';\nimport {\n generateCommitMessage as generateCommitMessageAi,\n generatePrDescription as generatePrDescriptionAi,\n} from './ai-content.js';\nimport { autoConfigureWorkOSEnvironment } from './workos-management.js';\nimport { detectPort, getCallbackPath } from './port-detection.js';\nimport { writeEnvLocal } from './env-writer.js';\nimport { getRegistry } from './registry.js';\n\nasync function runIntegrationInstallerFn(integration: Integration, options: InstallerOptions): Promise<string> {\n const registry = await getRegistry();\n const mod = registry.get(integration);\n if (!mod) {\n throw new Error(`Unknown integration: ${integration}`);\n }\n return mod.run(options);\n}\n\nfunction readExistingCredentials(installDir: string): { apiKey?: string; clientId?: string } {\n const envPath = join(installDir, '.env.local');\n if (!existsSync(envPath)) {\n return {};\n }\n\n try {\n const content = readFileSync(envPath, 'utf-8');\n const envVars = parseEnvFile(content);\n return {\n apiKey: envVars.WORKOS_API_KEY || undefined,\n clientId: envVars.WORKOS_CLIENT_ID || undefined,\n };\n } catch {\n return {};\n }\n}\n\nasync function detectIntegrationFn(options: Pick<InstallerOptions, 'installDir'>): Promise<Integration | undefined> {\n const registry = await getRegistry();\n const configs = registry.detectionOrder();\n\n for (const config of configs) {\n // Use the detect function from INTEGRATION_CONFIG in config.ts for JS integrations,\n // or fall back to checking if the framework package is installed\n const detected = await detectSingleIntegration(config.metadata.integration, options);\n if (detected) {\n return config.metadata.integration;\n }\n }\n return undefined;\n}\n\n/**\n * Detect if a single integration matches the project.\n * Uses package.json detection for JS integrations, manifest files for others.\n */\nasync function detectSingleIntegration(\n integration: string,\n options: Pick<InstallerOptions, 'installDir'>,\n): Promise<boolean> {\n const { getPackageDotJson } = await import('../utils/clack-utils.js');\n const { hasPackageInstalled } = await import('../utils/package-json.js');\n const { existsSync } = await import('node:fs');\n const { join } = await import('node:path');\n\n const registry = await getRegistry();\n const mod = registry.get(integration);\n if (!mod) return false;\n\n const config = mod.config;\n\n // For JS integrations, check package.json\n if (config.metadata.language === 'javascript') {\n const packageJson = await getPackageDotJson(options);\n\n switch (integration) {\n case 'nextjs':\n return hasPackageInstalled('next', packageJson);\n case 'tanstack-start':\n return hasPackageInstalled('@tanstack/react-start', packageJson);\n case 'react-router':\n return hasPackageInstalled('react-router', packageJson);\n case 'react': {\n const hasReact = hasPackageInstalled('react', packageJson);\n const hasNext = hasPackageInstalled('next', packageJson);\n const hasReactRouter = hasPackageInstalled('react-router', packageJson);\n const hasTanstack = hasPackageInstalled('@tanstack/react-start', packageJson);\n const hasSvelteKit = hasPackageInstalled('@sveltejs/kit', packageJson);\n return hasReact && !hasNext && !hasReactRouter && !hasTanstack && !hasSvelteKit;\n }\n case 'sveltekit':\n return hasPackageInstalled('@sveltejs/kit', packageJson);\n case 'node': {\n const hasExpress = hasPackageInstalled('express', packageJson);\n const hasFrontend =\n hasPackageInstalled('next', packageJson) ||\n hasPackageInstalled('@sveltejs/kit', packageJson) ||\n hasPackageInstalled('react', packageJson) ||\n hasPackageInstalled('@tanstack/react-start', packageJson);\n return hasExpress && !hasFrontend;\n }\n case 'vanilla-js':\n return true; // Fallback\n default:\n // Unknown JS integration — try package name detection\n return hasPackageInstalled(config.detection.packageName, packageJson);\n }\n }\n\n // For non-JS integrations, check manifest files\n if (config.metadata.manifestFile) {\n return existsSync(join(options.installDir, config.metadata.manifestFile));\n }\n\n return false;\n}\n\nexport async function runWithCore(options: InstallerOptions): Promise<void> {\n // Initialize debug/logging early so we capture all failures\n initLogFile();\n if (options.debug) {\n enableDebugLogs();\n }\n logInfo('Wizard starting with options:', {\n debug: options.debug,\n dashboard: options.dashboard,\n local: options.local,\n ci: options.ci,\n skipAuth: options.skipAuth,\n installDir: options.installDir,\n });\n\n // Configure telemetry endpoint (same URL as LLM gateway)\n const gatewayUrl = getLlmGatewayUrlFromHost();\n analytics.setGatewayUrl(gatewayUrl);\n\n const existingCreds = readExistingCredentials(options.installDir);\n const augmentedOptions: InstallerOptions = {\n ...options,\n apiKey: options.apiKey || existingCreds.apiKey,\n clientId: options.clientId || existingCreds.clientId,\n };\n\n const emitter = createInstallerEventEmitter();\n let actor: ReturnType<typeof createActor<typeof installerMachine>> | null = null;\n\n const sendEvent = (event: { type: string; [key: string]: unknown }) => {\n if (actor) {\n actor.send(event as Parameters<typeof actor.send>[0]);\n }\n };\n\n let adapter: InstallerAdapter;\n if (isNonInteractiveEnvironment()) {\n const { HeadlessAdapter } = await import('./adapters/headless-adapter.js');\n adapter = new HeadlessAdapter({\n emitter,\n sendEvent,\n debug: augmentedOptions.debug,\n options: {\n apiKey: augmentedOptions.apiKey,\n clientId: augmentedOptions.clientId,\n noBranch: augmentedOptions.noBranch,\n noCommit: augmentedOptions.noCommit,\n createPr: augmentedOptions.createPr,\n noGitCheck: augmentedOptions.noGitCheck,\n },\n });\n } else if (options.dashboard) {\n adapter = new DashboardAdapter({ emitter, sendEvent, debug: augmentedOptions.debug });\n } else {\n adapter = new CLIAdapter({ emitter, sendEvent, debug: augmentedOptions.debug });\n }\n\n const machineWithActors = installerMachine.provide({\n actors: {\n checkAuthentication: fromPromise(async () => {\n const token = getAccessToken();\n if (!token) {\n // This should rarely happen since bin.ts handles auth first\n // But keep as safety net for programmatic usage\n throw new Error('Not authenticated. Run `workos login` first.');\n }\n\n // Set telemetry from existing credentials\n const creds = getCredentials();\n if (creds) {\n analytics.setAccessToken(creds.accessToken);\n analytics.setDistinctId(creds.userId);\n }\n return true;\n }),\n\n detectIntegration: fromPromise<DetectionOutput, { options: InstallerOptions }>(async ({ input }) => {\n const integration = await detectIntegrationFn({ installDir: input.options.installDir });\n return { integration };\n }),\n\n checkGitStatus: fromPromise<GitCheckOutput, { installDir: string }>(async () => {\n if (!isInGitRepo()) {\n return { isClean: true, files: [] };\n }\n const files = getUncommittedOrUntrackedFiles();\n return { isClean: files.length === 0, files };\n }),\n\n configureEnvironment: fromPromise<void, { context: InstallerMachineContext }>(async ({ input }) => {\n const { context } = input;\n const { options: installerOptions, integration, credentials } = context;\n\n if (!integration || !credentials) {\n throw new Error('Missing integration or credentials');\n }\n\n const port = detectPort(integration, installerOptions.installDir);\n const callbackPath = getCallbackPath(integration);\n const redirectUri = installerOptions.redirectUri || `http://localhost:${port}${callbackPath}`;\n\n const requiresApiKey = ['nextjs', 'tanstack-start', 'react-router'].includes(integration);\n if (credentials.apiKey && requiresApiKey) {\n await autoConfigureWorkOSEnvironment(credentials.apiKey, integration, port, {\n homepageUrl: installerOptions.homepageUrl,\n redirectUri: installerOptions.redirectUri,\n });\n }\n\n const redirectUriKey = integration === 'nextjs' ? 'NEXT_PUBLIC_WORKOS_REDIRECT_URI' : 'WORKOS_REDIRECT_URI';\n\n writeEnvLocal(installerOptions.installDir, {\n ...(credentials.apiKey ? { WORKOS_API_KEY: credentials.apiKey } : {}),\n WORKOS_CLIENT_ID: credentials.clientId,\n [redirectUriKey]: redirectUri,\n });\n }),\n\n runAgent: fromPromise<AgentOutput, { context: InstallerMachineContext }>(async ({ input }) => {\n const { context } = input;\n const { options: installerOptions, integration, credentials } = context;\n\n if (!integration) {\n return { success: false, error: new Error('No integration specified') };\n }\n\n try {\n const agentOptions: InstallerOptions = {\n ...installerOptions,\n apiKey: credentials?.apiKey,\n clientId: credentials?.clientId,\n emitter: context.emitter,\n };\n const summary = await runIntegrationInstallerFn(integration, agentOptions);\n return {\n success: true,\n summary: summary || `Successfully installed WorkOS AuthKit for ${integration}!`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }),\n\n // Credential discovery actors\n detectEnvFiles: fromPromise(async ({ input }) => {\n return checkForEnvFiles(input.installDir);\n }),\n\n scanEnvFiles: fromPromise(async ({ input }) => {\n return discoverCredentials(input.installDir);\n }),\n\n checkStoredAuth: fromPromise(async () => {\n const token = getAccessToken();\n return token !== null;\n }),\n\n runDeviceAuth: fromPromise(async ({ input }) => {\n const clientId = getCliAuthClientId();\n const authkitDomain = getAuthkitDomain();\n\n if (!clientId) {\n throw new Error('CLI auth not configured. Set WORKOS_CLI_CLIENT_ID environment variable.');\n }\n\n const deviceAuth = await requestDeviceCode({\n clientId,\n authkitDomain,\n });\n\n // Emit device started event with verification info\n input.emitter.emit('device:started', {\n verificationUri: deviceAuth.verification_uri,\n verificationUriComplete: deviceAuth.verification_uri_complete,\n userCode: deviceAuth.user_code,\n });\n\n // Open browser\n try {\n const { default: openFn } = await import('opn');\n await openFn(deviceAuth.verification_uri_complete);\n } catch {\n // User can open manually\n }\n\n const result = await pollForToken(deviceAuth.device_code, {\n clientId,\n authkitDomain,\n interval: deviceAuth.interval,\n onPoll: () => input.emitter.emit('device:polling', {}),\n });\n\n // Save the auth token\n saveCredentials({\n accessToken: result.accessToken,\n expiresAt: result.expiresAt,\n userId: result.userId,\n email: result.email,\n });\n\n return { result, deviceAuth };\n }),\n\n fetchStagingCredentials: fromPromise(async () => {\n const activeEnv = getActiveEnvironment();\n if (activeEnv?.clientId && activeEnv?.apiKey) {\n return { clientId: activeEnv.clientId, apiKey: activeEnv.apiKey };\n }\n\n const cached = getStagingCredentials();\n if (cached) return cached;\n\n const token = getAccessToken();\n if (!token) throw new Error('No access token available');\n\n const staging = await fetchStagingCredentialsApi(token);\n saveStagingCredentials(staging);\n\n try {\n const config = getConfig() ?? { environments: {} };\n if (!config.environments['default']) {\n config.environments['default'] = {\n name: 'default',\n type: staging.apiKey.startsWith('sk_test_') ? 'sandbox' : 'production',\n apiKey: staging.apiKey,\n clientId: staging.clientId,\n };\n if (!config.activeEnvironment) {\n config.activeEnvironment = 'default';\n }\n saveConfig(config);\n }\n } catch {\n // Don't block install if config-store write fails\n }\n\n return staging;\n }),\n\n // Branch check actors\n checkBranch: fromPromise<BranchCheckOutput, void>(async () => {\n const branch = getCurrentBranch();\n if (!branch) {\n return { branch: null, isProtected: false };\n }\n return {\n branch,\n isProtected: isProtectedBranch(branch),\n };\n }),\n\n createBranch: fromPromise<{ branch: string }, { name: string; fallbackName: string }>(async ({ input }) => {\n const { name, fallbackName } = input;\n const targetBranch = branchExists(name) ? fallbackName : name;\n createGitBranch(targetBranch);\n return { branch: targetBranch };\n }),\n\n // Post-install actors\n detectChanges: fromPromise<{ hasChanges: boolean; files: string[] }, void>(async () => {\n return detectChanges();\n }),\n\n generateCommitMessage: fromPromise<string, { integration: string; files: string[]; direct?: boolean }>(\n async ({ input }) => {\n return generateCommitMessageAi(input.integration, input.files, { direct: input.direct });\n },\n ),\n\n commitChanges: fromPromise<void, { message: string; cwd: string }>(async ({ input }) => {\n stageAndCommit(input.message, input.cwd);\n }),\n\n generatePrDescription: fromPromise<\n string,\n { integration: string; files: string[]; commitMessage: string; direct?: boolean }\n >(async ({ input }) => {\n return generatePrDescriptionAi(input.integration, input.files, input.commitMessage, { direct: input.direct });\n }),\n\n pushBranch: fromPromise<void, { cwd: string }>(async ({ input }) => {\n pushGitBranch(input.cwd);\n }),\n\n createPr: fromPromise<string, { title: string; body: string; cwd: string }>(async ({ input }) => {\n return createPullRequest(input.title, input.body, input.cwd);\n }),\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let inspector: { inspect: any } | undefined;\n if (augmentedOptions.inspect) {\n const originalLog = console.log;\n let inspectUrl: string | undefined;\n\n console.log = (...args: unknown[]) => {\n const msg = args.join(' ');\n if (typeof msg === 'string' && msg.startsWith('https://stately.ai/inspect/')) {\n inspectUrl = msg;\n console.log = originalLog;\n console.log(`Opening XState inspector: ${inspectUrl}`);\n void open(inspectUrl);\n } else {\n originalLog.apply(console, args);\n }\n };\n\n // Dynamic import - @statelyai/inspect is a devDependency\n const { createSkyInspector } = await import('@statelyai/inspect');\n inspector = createSkyInspector();\n setTimeout(() => {\n console.log = originalLog;\n }, 5000).unref();\n }\n\n actor = createActor(machineWithActors, {\n input: { emitter, options: augmentedOptions },\n inspect: inspector?.inspect,\n });\n\n await adapter.start();\n\n // Start telemetry session\n const mode = isNonInteractiveEnvironment() ? 'headless' : augmentedOptions.dashboard ? 'tui' : 'cli';\n analytics.sessionStart(mode, getVersion());\n\n let installerStatus: 'success' | 'error' | 'cancelled' = 'success';\n\n // Handle ctrl+c by sending CANCEL to state machine for graceful shutdown\n const handleSigint = () => {\n installerStatus = 'cancelled';\n actor?.send({ type: 'CANCEL' });\n };\n process.on('SIGINT', handleSigint);\n\n try {\n await new Promise<void>((resolve, reject) => {\n actor!.subscribe({\n complete: () => {\n const snapshot = actor!.getSnapshot();\n if (snapshot.value === 'error') {\n const err = snapshot.context.error;\n installerStatus = 'error';\n reject(err ?? new Error('Wizard failed'));\n } else if (snapshot.value === 'cancelled') {\n installerStatus = 'cancelled';\n resolve();\n } else {\n resolve();\n }\n },\n error: (err) => {\n installerStatus = 'error';\n reject(err);\n },\n });\n\n actor!.start();\n actor!.send({ type: 'START' });\n });\n } catch (error) {\n installerStatus = 'error';\n logError('Wizard failed with error:', error instanceof Error ? error.stack || error.message : String(error));\n throw error;\n } finally {\n process.off('SIGINT', handleSigint);\n await analytics.shutdown(installerStatus);\n await adapter.stop();\n }\n}\n"]}
1
+ {"version":3,"file":"run-with-core.js","sourceRoot":"","sources":["../../src/lib/run-with-core.ts"],"names":[],"mappings":"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","sourcesContent":["import { createActor, fromPromise } from 'xstate';\nimport open from 'opn';\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { installerMachine } from './installer-core.js';\nimport { createInstallerEventEmitter } from './events.js';\nimport { CLIAdapter } from './adapters/cli-adapter.js';\nimport { DashboardAdapter } from './adapters/dashboard-adapter.js';\nimport type { InstallerAdapter } from './adapters/types.js';\nimport type { InstallerOptions } from '../utils/types.js';\nimport { isNonInteractiveEnvironment } from '../utils/environment.js';\nimport type {\n InstallerMachineContext,\n DetectionOutput,\n GitCheckOutput,\n AgentOutput,\n BranchCheckOutput,\n} from './installer-core.types.js';\nimport type { Integration } from './constants.js';\nimport { parseEnvFile } from '../utils/env-parser.js';\nimport { enableDebugLogs, initLogFile, logInfo, logError } from '../utils/debug.js';\n\nimport {\n getAccessToken,\n getCredentials,\n saveCredentials,\n getStagingCredentials,\n saveStagingCredentials,\n} from './credentials.js';\nimport { getConfig, saveConfig, getActiveEnvironment } from './config-store.js';\nimport { checkForEnvFiles, discoverCredentials } from './credential-discovery.js';\nimport { requestDeviceCode, pollForToken } from './device-auth.js';\nimport { fetchStagingCredentials as fetchStagingCredentialsApi } from './staging-api.js';\nimport { getCliAuthClientId, getAuthkitDomain } from './settings.js';\nimport { analytics } from '../utils/analytics.js';\nimport { getVersion } from './settings.js';\nimport { getLlmGatewayUrlFromHost } from '../utils/urls.js';\nimport { isInGitRepo, getUncommittedOrUntrackedFiles } from '../utils/clack-utils.js';\nimport {\n getCurrentBranch,\n isProtectedBranch,\n createBranch as createGitBranch,\n branchExists,\n} from '../utils/git-utils.js';\nimport { detectChanges, stageAndCommit, pushBranch as pushGitBranch, createPullRequest } from './post-install.js';\nimport {\n generateCommitMessage as generateCommitMessageAi,\n generatePrDescription as generatePrDescriptionAi,\n} from './ai-content.js';\nimport { autoConfigureWorkOSEnvironment } from './workos-management.js';\nimport { detectPort, getCallbackPath } from './port-detection.js';\nimport { writeEnvLocal } from './env-writer.js';\nimport { getRegistry } from './registry.js';\n\nasync function runIntegrationInstallerFn(integration: Integration, options: InstallerOptions): Promise<string> {\n const registry = await getRegistry();\n const mod = registry.get(integration);\n if (!mod) {\n throw new Error(`Unknown integration: ${integration}`);\n }\n return mod.run(options);\n}\n\nfunction readExistingCredentials(installDir: string): { apiKey?: string; clientId?: string } {\n const envPath = join(installDir, '.env.local');\n if (!existsSync(envPath)) {\n return {};\n }\n\n try {\n const content = readFileSync(envPath, 'utf-8');\n const envVars = parseEnvFile(content);\n return {\n apiKey: envVars.WORKOS_API_KEY || undefined,\n clientId: envVars.WORKOS_CLIENT_ID || undefined,\n };\n } catch {\n return {};\n }\n}\n\nasync function detectIntegrationFn(options: Pick<InstallerOptions, 'installDir'>): Promise<Integration | undefined> {\n const registry = await getRegistry();\n const configs = registry.detectionOrder();\n\n for (const config of configs) {\n // Use the detect function from INTEGRATION_CONFIG in config.ts for JS integrations,\n // or fall back to checking if the framework package is installed\n const detected = await detectSingleIntegration(config.metadata.integration, options);\n if (detected) {\n return config.metadata.integration;\n }\n }\n return undefined;\n}\n\n/**\n * Detect if a single integration matches the project.\n * Uses package.json detection for JS integrations, manifest files for others.\n */\nasync function detectSingleIntegration(\n integration: string,\n options: Pick<InstallerOptions, 'installDir'>,\n): Promise<boolean> {\n const { getPackageDotJson } = await import('../utils/clack-utils.js');\n const { hasPackageInstalled } = await import('../utils/package-json.js');\n const { existsSync } = await import('node:fs');\n const { join } = await import('node:path');\n\n const registry = await getRegistry();\n const mod = registry.get(integration);\n if (!mod) return false;\n\n const config = mod.config;\n\n // For JS integrations, check package.json\n if (config.metadata.language === 'javascript') {\n const packageJson = await getPackageDotJson(options);\n\n switch (integration) {\n case 'nextjs':\n return hasPackageInstalled('next', packageJson);\n case 'tanstack-start':\n return hasPackageInstalled('@tanstack/react-start', packageJson);\n case 'react-router':\n return hasPackageInstalled('react-router', packageJson);\n case 'react': {\n const hasReact = hasPackageInstalled('react', packageJson);\n const hasNext = hasPackageInstalled('next', packageJson);\n const hasReactRouter = hasPackageInstalled('react-router', packageJson);\n const hasTanstack = hasPackageInstalled('@tanstack/react-start', packageJson);\n const hasSvelteKit = hasPackageInstalled('@sveltejs/kit', packageJson);\n return hasReact && !hasNext && !hasReactRouter && !hasTanstack && !hasSvelteKit;\n }\n case 'sveltekit':\n return hasPackageInstalled('@sveltejs/kit', packageJson);\n case 'node': {\n const hasExpress = hasPackageInstalled('express', packageJson);\n const hasFrontend =\n hasPackageInstalled('next', packageJson) ||\n hasPackageInstalled('@sveltejs/kit', packageJson) ||\n hasPackageInstalled('react', packageJson) ||\n hasPackageInstalled('@tanstack/react-start', packageJson);\n return hasExpress && !hasFrontend;\n }\n case 'vanilla-js':\n return true; // Fallback\n default:\n // Unknown JS integration — try package name detection\n return hasPackageInstalled(config.detection.packageName, packageJson);\n }\n }\n\n // For non-JS integrations, check manifest files\n if (config.metadata.manifestFile) {\n return existsSync(join(options.installDir, config.metadata.manifestFile));\n }\n\n return false;\n}\n\nexport async function runWithCore(options: InstallerOptions): Promise<void> {\n // Initialize debug/logging early so we capture all failures\n initLogFile();\n if (options.debug) {\n enableDebugLogs();\n }\n logInfo('Wizard starting with options:', {\n debug: options.debug,\n dashboard: options.dashboard,\n local: options.local,\n ci: options.ci,\n skipAuth: options.skipAuth,\n installDir: options.installDir,\n });\n\n // Configure telemetry endpoint (same URL as LLM gateway)\n const gatewayUrl = getLlmGatewayUrlFromHost();\n analytics.setGatewayUrl(gatewayUrl);\n\n const existingCreds = readExistingCredentials(options.installDir);\n const augmentedOptions: InstallerOptions = {\n ...options,\n apiKey: options.apiKey || existingCreds.apiKey,\n clientId: options.clientId || existingCreds.clientId,\n };\n\n const emitter = createInstallerEventEmitter();\n let actor: ReturnType<typeof createActor<typeof installerMachine>> | null = null;\n\n const sendEvent = (event: { type: string; [key: string]: unknown }) => {\n if (actor) {\n actor.send(event as Parameters<typeof actor.send>[0]);\n }\n };\n\n let adapter: InstallerAdapter;\n if (isNonInteractiveEnvironment()) {\n const { HeadlessAdapter } = await import('./adapters/headless-adapter.js');\n adapter = new HeadlessAdapter({\n emitter,\n sendEvent,\n debug: augmentedOptions.debug,\n options: {\n apiKey: augmentedOptions.apiKey,\n clientId: augmentedOptions.clientId,\n noBranch: augmentedOptions.noBranch,\n noCommit: augmentedOptions.noCommit,\n createPr: augmentedOptions.createPr,\n noGitCheck: augmentedOptions.noGitCheck,\n },\n });\n } else if (options.dashboard) {\n adapter = new DashboardAdapter({ emitter, sendEvent, debug: augmentedOptions.debug });\n } else {\n adapter = new CLIAdapter({ emitter, sendEvent, debug: augmentedOptions.debug });\n }\n\n const machineWithActors = installerMachine.provide({\n actors: {\n checkAuthentication: fromPromise(async () => {\n const token = getAccessToken();\n if (!token) {\n // This should rarely happen since bin.ts handles auth first\n // But keep as safety net for programmatic usage\n throw new Error('Not authenticated. Run `workos auth login` first.');\n }\n\n // Set telemetry from existing credentials\n const creds = getCredentials();\n if (creds) {\n analytics.setAccessToken(creds.accessToken);\n analytics.setDistinctId(creds.userId);\n }\n return true;\n }),\n\n detectIntegration: fromPromise<DetectionOutput, { options: InstallerOptions }>(async ({ input }) => {\n const integration = await detectIntegrationFn({ installDir: input.options.installDir });\n return { integration };\n }),\n\n checkGitStatus: fromPromise<GitCheckOutput, { installDir: string }>(async () => {\n if (!isInGitRepo()) {\n return { isClean: true, files: [] };\n }\n const files = getUncommittedOrUntrackedFiles();\n return { isClean: files.length === 0, files };\n }),\n\n configureEnvironment: fromPromise<void, { context: InstallerMachineContext }>(async ({ input }) => {\n const { context } = input;\n const { options: installerOptions, integration, credentials } = context;\n\n if (!integration || !credentials) {\n throw new Error('Missing integration or credentials');\n }\n\n const port = detectPort(integration, installerOptions.installDir);\n const callbackPath = getCallbackPath(integration);\n const redirectUri = installerOptions.redirectUri || `http://localhost:${port}${callbackPath}`;\n\n const requiresApiKey = ['nextjs', 'tanstack-start', 'react-router'].includes(integration);\n if (credentials.apiKey && requiresApiKey) {\n await autoConfigureWorkOSEnvironment(credentials.apiKey, integration, port, {\n homepageUrl: installerOptions.homepageUrl,\n redirectUri: installerOptions.redirectUri,\n });\n }\n\n const redirectUriKey = integration === 'nextjs' ? 'NEXT_PUBLIC_WORKOS_REDIRECT_URI' : 'WORKOS_REDIRECT_URI';\n\n writeEnvLocal(installerOptions.installDir, {\n ...(credentials.apiKey ? { WORKOS_API_KEY: credentials.apiKey } : {}),\n WORKOS_CLIENT_ID: credentials.clientId,\n [redirectUriKey]: redirectUri,\n });\n }),\n\n runAgent: fromPromise<AgentOutput, { context: InstallerMachineContext }>(async ({ input }) => {\n const { context } = input;\n const { options: installerOptions, integration, credentials } = context;\n\n if (!integration) {\n return { success: false, error: new Error('No integration specified') };\n }\n\n try {\n const agentOptions: InstallerOptions = {\n ...installerOptions,\n apiKey: credentials?.apiKey,\n clientId: credentials?.clientId,\n emitter: context.emitter,\n };\n const summary = await runIntegrationInstallerFn(integration, agentOptions);\n return {\n success: true,\n summary: summary || `Successfully installed WorkOS AuthKit for ${integration}!`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }),\n\n // Credential discovery actors\n detectEnvFiles: fromPromise(async ({ input }) => {\n return checkForEnvFiles(input.installDir);\n }),\n\n scanEnvFiles: fromPromise(async ({ input }) => {\n return discoverCredentials(input.installDir);\n }),\n\n checkStoredAuth: fromPromise(async () => {\n const token = getAccessToken();\n return token !== null;\n }),\n\n runDeviceAuth: fromPromise(async ({ input }) => {\n const clientId = getCliAuthClientId();\n const authkitDomain = getAuthkitDomain();\n\n if (!clientId) {\n throw new Error('CLI auth not configured. Set WORKOS_CLI_CLIENT_ID environment variable.');\n }\n\n const deviceAuth = await requestDeviceCode({\n clientId,\n authkitDomain,\n });\n\n // Emit device started event with verification info\n input.emitter.emit('device:started', {\n verificationUri: deviceAuth.verification_uri,\n verificationUriComplete: deviceAuth.verification_uri_complete,\n userCode: deviceAuth.user_code,\n });\n\n // Open browser\n try {\n const { default: openFn } = await import('opn');\n await openFn(deviceAuth.verification_uri_complete);\n } catch {\n // User can open manually\n }\n\n const result = await pollForToken(deviceAuth.device_code, {\n clientId,\n authkitDomain,\n interval: deviceAuth.interval,\n onPoll: () => input.emitter.emit('device:polling', {}),\n });\n\n // Save the auth token\n saveCredentials({\n accessToken: result.accessToken,\n expiresAt: result.expiresAt,\n userId: result.userId,\n email: result.email,\n });\n\n return { result, deviceAuth };\n }),\n\n fetchStagingCredentials: fromPromise(async () => {\n const activeEnv = getActiveEnvironment();\n if (activeEnv?.clientId && activeEnv?.apiKey) {\n return { clientId: activeEnv.clientId, apiKey: activeEnv.apiKey };\n }\n\n const cached = getStagingCredentials();\n if (cached) return cached;\n\n const token = getAccessToken();\n if (!token) throw new Error('No access token available');\n\n const staging = await fetchStagingCredentialsApi(token);\n saveStagingCredentials(staging);\n\n try {\n const config = getConfig() ?? { environments: {} };\n if (!config.environments['default']) {\n config.environments['default'] = {\n name: 'default',\n type: staging.apiKey.startsWith('sk_test_') ? 'sandbox' : 'production',\n apiKey: staging.apiKey,\n clientId: staging.clientId,\n };\n if (!config.activeEnvironment) {\n config.activeEnvironment = 'default';\n }\n saveConfig(config);\n }\n } catch {\n // Don't block install if config-store write fails\n }\n\n return staging;\n }),\n\n // Branch check actors\n checkBranch: fromPromise<BranchCheckOutput, void>(async () => {\n const branch = getCurrentBranch();\n if (!branch) {\n return { branch: null, isProtected: false };\n }\n return {\n branch,\n isProtected: isProtectedBranch(branch),\n };\n }),\n\n createBranch: fromPromise<{ branch: string }, { name: string; fallbackName: string }>(async ({ input }) => {\n const { name, fallbackName } = input;\n const targetBranch = branchExists(name) ? fallbackName : name;\n createGitBranch(targetBranch);\n return { branch: targetBranch };\n }),\n\n // Post-install actors\n detectChanges: fromPromise<{ hasChanges: boolean; files: string[] }, void>(async () => {\n return detectChanges();\n }),\n\n generateCommitMessage: fromPromise<string, { integration: string; files: string[]; direct?: boolean }>(\n async ({ input }) => {\n return generateCommitMessageAi(input.integration, input.files, { direct: input.direct });\n },\n ),\n\n commitChanges: fromPromise<void, { message: string; cwd: string }>(async ({ input }) => {\n stageAndCommit(input.message, input.cwd);\n }),\n\n generatePrDescription: fromPromise<\n string,\n { integration: string; files: string[]; commitMessage: string; direct?: boolean }\n >(async ({ input }) => {\n return generatePrDescriptionAi(input.integration, input.files, input.commitMessage, { direct: input.direct });\n }),\n\n pushBranch: fromPromise<void, { cwd: string }>(async ({ input }) => {\n pushGitBranch(input.cwd);\n }),\n\n createPr: fromPromise<string, { title: string; body: string; cwd: string }>(async ({ input }) => {\n return createPullRequest(input.title, input.body, input.cwd);\n }),\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let inspector: { inspect: any } | undefined;\n if (augmentedOptions.inspect) {\n const originalLog = console.log;\n let inspectUrl: string | undefined;\n\n console.log = (...args: unknown[]) => {\n const msg = args.join(' ');\n if (typeof msg === 'string' && msg.startsWith('https://stately.ai/inspect/')) {\n inspectUrl = msg;\n console.log = originalLog;\n console.log(`Opening XState inspector: ${inspectUrl}`);\n void open(inspectUrl);\n } else {\n originalLog.apply(console, args);\n }\n };\n\n // Dynamic import - @statelyai/inspect is a devDependency\n const { createSkyInspector } = await import('@statelyai/inspect');\n inspector = createSkyInspector();\n setTimeout(() => {\n console.log = originalLog;\n }, 5000).unref();\n }\n\n actor = createActor(machineWithActors, {\n input: { emitter, options: augmentedOptions },\n inspect: inspector?.inspect,\n });\n\n await adapter.start();\n\n // Start telemetry session\n const mode = isNonInteractiveEnvironment() ? 'headless' : augmentedOptions.dashboard ? 'tui' : 'cli';\n analytics.sessionStart(mode, getVersion());\n\n let installerStatus: 'success' | 'error' | 'cancelled' = 'success';\n\n // Handle ctrl+c by sending CANCEL to state machine for graceful shutdown\n const handleSigint = () => {\n installerStatus = 'cancelled';\n actor?.send({ type: 'CANCEL' });\n };\n process.on('SIGINT', handleSigint);\n\n try {\n await new Promise<void>((resolve, reject) => {\n actor!.subscribe({\n complete: () => {\n const snapshot = actor!.getSnapshot();\n if (snapshot.value === 'error') {\n const err = snapshot.context.error;\n installerStatus = 'error';\n reject(err ?? new Error('Wizard failed'));\n } else if (snapshot.value === 'cancelled') {\n installerStatus = 'cancelled';\n resolve();\n } else {\n resolve();\n }\n },\n error: (err) => {\n installerStatus = 'error';\n reject(err);\n },\n });\n\n actor!.start();\n actor!.send({ type: 'START' });\n });\n } catch (error) {\n installerStatus = 'error';\n logError('Wizard failed with error:', error instanceof Error ? error.stack || error.message : String(error));\n throw error;\n } finally {\n process.off('SIGINT', handleSigint);\n await analytics.shutdown(installerStatus);\n await adapter.stop();\n }\n}\n"]}
@@ -42,7 +42,7 @@ export async function refreshAccessToken(authkitDomain, clientId) {
42
42
  if (errorData.error === 'invalid_grant') {
43
43
  return {
44
44
  success: false,
45
- error: 'Session expired. Run `workos login` to re-authenticate.',
45
+ error: 'Session expired. Run `workos auth login` to re-authenticate.',
46
46
  errorType: 'invalid_grant',
47
47
  };
48
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"token-refresh-client.js","sourceRoot":"","sources":["../../src/lib/token-refresh-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Token refresh client for WorkOS OAuth\n */\n\nimport { logInfo, logError } from '../utils/debug.js';\nimport { getCredentials } from './credentials.js';\n\nexport interface RefreshResult {\n success: boolean;\n accessToken?: string;\n refreshToken?: string;\n expiresAt?: number;\n error?: string;\n errorType?: 'invalid_grant' | 'network' | 'server' | 'unknown';\n}\n\ninterface TokenRefreshResponse {\n access_token: string;\n refresh_token?: string;\n token_type: string;\n expires_in: number;\n}\n\ninterface TokenErrorResponse {\n error: string;\n error_description?: string;\n}\n\nconst REFRESH_TIMEOUT_MS = 30_000;\n\n/**\n * Refresh access token using stored refresh token.\n *\n * @param authkitDomain - The AuthKit domain (e.g., https://auth.workos.com)\n * @param clientId - OAuth client ID\n * @returns RefreshResult with new tokens or error details\n */\nexport async function refreshAccessToken(authkitDomain: string, clientId: string): Promise<RefreshResult> {\n const creds = getCredentials();\n\n if (!creds?.refreshToken) {\n return {\n success: false,\n error: 'No refresh token available',\n errorType: 'invalid_grant',\n };\n }\n\n const tokenUrl = `${authkitDomain}/oauth2/token`;\n logInfo('[token-refresh] Attempting token refresh');\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), REFRESH_TIMEOUT_MS);\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: creds.refreshToken,\n client_id: clientId,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n const errorData = (await response.json()) as TokenErrorResponse;\n logError('[token-refresh] Refresh failed:', errorData.error);\n\n if (errorData.error === 'invalid_grant') {\n return {\n success: false,\n error: 'Session expired. Run `workos login` to re-authenticate.',\n errorType: 'invalid_grant',\n };\n }\n\n return {\n success: false,\n error: errorData.error_description || errorData.error,\n errorType: 'server',\n };\n }\n\n const data = (await response.json()) as TokenRefreshResponse;\n const expiresAt = Date.now() + data.expires_in * 1000;\n\n logInfo('[token-refresh] Token refreshed successfully, expires:', new Date(expiresAt).toISOString());\n\n return {\n success: true,\n accessToken: data.access_token,\n refreshToken: data.refresh_token, // May be rotated\n expiresAt,\n };\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n logError('[token-refresh] Refresh timed out');\n return {\n success: false,\n error: 'Token refresh timed out',\n errorType: 'network',\n };\n }\n\n logError('[token-refresh] Network error:', error);\n return {\n success: false,\n error: `Network error: ${(error as Error).message}`,\n errorType: 'network',\n };\n }\n}\n\n/**\n * Check if token needs refresh (expires within threshold).\n */\nexport function tokenNeedsRefresh(expiresAt: number, thresholdMs: number = 2 * 60 * 1000): boolean {\n return Date.now() + thresholdMs >= expiresAt;\n}\n"]}
1
+ {"version":3,"file":"token-refresh-client.js","sourceRoot":"","sources":["../../src/lib/token-refresh-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Token refresh client for WorkOS OAuth\n */\n\nimport { logInfo, logError } from '../utils/debug.js';\nimport { getCredentials } from './credentials.js';\n\nexport interface RefreshResult {\n success: boolean;\n accessToken?: string;\n refreshToken?: string;\n expiresAt?: number;\n error?: string;\n errorType?: 'invalid_grant' | 'network' | 'server' | 'unknown';\n}\n\ninterface TokenRefreshResponse {\n access_token: string;\n refresh_token?: string;\n token_type: string;\n expires_in: number;\n}\n\ninterface TokenErrorResponse {\n error: string;\n error_description?: string;\n}\n\nconst REFRESH_TIMEOUT_MS = 30_000;\n\n/**\n * Refresh access token using stored refresh token.\n *\n * @param authkitDomain - The AuthKit domain (e.g., https://auth.workos.com)\n * @param clientId - OAuth client ID\n * @returns RefreshResult with new tokens or error details\n */\nexport async function refreshAccessToken(authkitDomain: string, clientId: string): Promise<RefreshResult> {\n const creds = getCredentials();\n\n if (!creds?.refreshToken) {\n return {\n success: false,\n error: 'No refresh token available',\n errorType: 'invalid_grant',\n };\n }\n\n const tokenUrl = `${authkitDomain}/oauth2/token`;\n logInfo('[token-refresh] Attempting token refresh');\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), REFRESH_TIMEOUT_MS);\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: creds.refreshToken,\n client_id: clientId,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n const errorData = (await response.json()) as TokenErrorResponse;\n logError('[token-refresh] Refresh failed:', errorData.error);\n\n if (errorData.error === 'invalid_grant') {\n return {\n success: false,\n error: 'Session expired. Run `workos auth login` to re-authenticate.',\n errorType: 'invalid_grant',\n };\n }\n\n return {\n success: false,\n error: errorData.error_description || errorData.error,\n errorType: 'server',\n };\n }\n\n const data = (await response.json()) as TokenRefreshResponse;\n const expiresAt = Date.now() + data.expires_in * 1000;\n\n logInfo('[token-refresh] Token refreshed successfully, expires:', new Date(expiresAt).toISOString());\n\n return {\n success: true,\n accessToken: data.access_token,\n refreshToken: data.refresh_token, // May be rotated\n expiresAt,\n };\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n logError('[token-refresh] Refresh timed out');\n return {\n success: false,\n error: 'Token refresh timed out',\n errorType: 'network',\n };\n }\n\n logError('[token-refresh] Network error:', error);\n return {\n success: false,\n error: `Network error: ${(error as Error).message}`,\n errorType: 'network',\n };\n }\n}\n\n/**\n * Check if token needs refresh (expires within threshold).\n */\nexport function tokenNeedsRefresh(expiresAt: number, thresholdMs: number = 2 * 60 * 1000): boolean {\n return Date.now() + thresholdMs >= expiresAt;\n}\n"]}
@@ -17,7 +17,7 @@ export async function ensureValidToken() {
17
17
  logInfo('[ensureValidToken] Token expired, re-authentication required');
18
18
  return {
19
19
  success: false,
20
- error: 'Session expired. Run `workos login` to re-authenticate.',
20
+ error: 'Session expired. Run `workos auth login` to re-authenticate.',
21
21
  };
22
22
  }
23
23
  logInfo('[ensureValidToken] Token valid');
@@ -1 +1 @@
1
- {"version":3,"file":"token-refresh.js","sourceRoot":"","sources":["../../src/lib/token-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAe,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAQ5C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAE/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,yCAAyC,CAAC,CAAC;QACnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,uCAAuC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,CAAC,oCAAoC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAExE,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,8DAA8D,CAAC,CAAC;QACxE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,yDAAyD;SACjE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,gCAAgC,CAAC,CAAC;IAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["import { getCredentials, isTokenExpired, Credentials } from './credentials.js';\nimport { logInfo } from '../utils/debug.js';\n\nexport interface TokenValidationResult {\n success: boolean;\n credentials?: Credentials;\n error?: string;\n}\n\n/**\n * Check if the current token is valid.\n * If expired, returns an error prompting re-authentication.\n * No refresh is attempted - refresh tokens are not stored for security.\n */\nexport async function ensureValidToken(): Promise<TokenValidationResult> {\n const creds = getCredentials();\n\n if (!creds) {\n logInfo('[ensureValidToken] No credentials found');\n return { success: false, error: 'Not authenticated' };\n }\n\n logInfo(`[ensureValidToken] Token expiresAt: ${new Date(creds.expiresAt).toISOString()}`);\n logInfo(`[ensureValidToken] Current time: ${new Date().toISOString()}`);\n\n if (isTokenExpired(creds)) {\n logInfo('[ensureValidToken] Token expired, re-authentication required');\n return {\n success: false,\n error: 'Session expired. Run `workos login` to re-authenticate.',\n };\n }\n\n logInfo('[ensureValidToken] Token valid');\n return { success: true, credentials: creds };\n}\n"]}
1
+ {"version":3,"file":"token-refresh.js","sourceRoot":"","sources":["../../src/lib/token-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAe,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAQ5C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAE/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,yCAAyC,CAAC,CAAC;QACnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,uCAAuC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,CAAC,oCAAoC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAExE,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,8DAA8D,CAAC,CAAC;QACxE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,8DAA8D;SACtE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,gCAAgC,CAAC,CAAC;IAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["import { getCredentials, isTokenExpired, Credentials } from './credentials.js';\nimport { logInfo } from '../utils/debug.js';\n\nexport interface TokenValidationResult {\n success: boolean;\n credentials?: Credentials;\n error?: string;\n}\n\n/**\n * Check if the current token is valid.\n * If expired, returns an error prompting re-authentication.\n * No refresh is attempted - refresh tokens are not stored for security.\n */\nexport async function ensureValidToken(): Promise<TokenValidationResult> {\n const creds = getCredentials();\n\n if (!creds) {\n logInfo('[ensureValidToken] No credentials found');\n return { success: false, error: 'Not authenticated' };\n }\n\n logInfo(`[ensureValidToken] Token expiresAt: ${new Date(creds.expiresAt).toISOString()}`);\n logInfo(`[ensureValidToken] Current time: ${new Date().toISOString()}`);\n\n if (isTokenExpired(creds)) {\n logInfo('[ensureValidToken] Token expired, re-authentication required');\n return {\n success: false,\n error: 'Session expired. Run `workos auth login` to re-authenticate.',\n };\n }\n\n logInfo('[ensureValidToken] Token valid');\n return { success: true, credentials: creds };\n}\n"]}
@@ -28,7 +28,8 @@ export async function checkForUpdates() {
28
28
  if (lt(currentVersion, latestVersion)) {
29
29
  hasWarned = true;
30
30
  yellow(`Update available: ${currentVersion} → ${latestVersion}`);
31
- dim(`Run: npx workos@latest`);
31
+ dim('Run: npx workos@latest');
32
+ console.log();
32
33
  }
33
34
  }
34
35
  catch {