workos 0.8.2 → 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 (46) 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 +5 -4
  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/lib/adapters/cli-adapter.js +1 -1
  12. package/dist/lib/adapters/cli-adapter.js.map +1 -1
  13. package/dist/lib/agent-interface.js +5 -5
  14. package/dist/lib/agent-interface.js.map +1 -1
  15. package/dist/lib/credential-proxy.js +1 -1
  16. package/dist/lib/credential-proxy.js.map +1 -1
  17. package/dist/lib/ensure-auth.js +3 -3
  18. package/dist/lib/ensure-auth.js.map +1 -1
  19. package/dist/lib/run-with-core.js +1 -1
  20. package/dist/lib/run-with-core.js.map +1 -1
  21. package/dist/lib/token-refresh-client.js +1 -1
  22. package/dist/lib/token-refresh-client.js.map +1 -1
  23. package/dist/lib/token-refresh.js +1 -1
  24. package/dist/lib/token-refresh.js.map +1 -1
  25. package/dist/lib/version-check.js +2 -1
  26. package/dist/lib/version-check.js.map +1 -1
  27. package/dist/utils/exit-codes.js +1 -1
  28. package/dist/utils/exit-codes.js.map +1 -1
  29. package/dist/utils/help-json.js +7 -2
  30. package/dist/utils/help-json.js.map +1 -1
  31. package/package.json +1 -1
  32. package/skills/workos-authkit-nextjs/SKILL.md +1 -1
  33. package/skills/workos-authkit-react/SKILL.md +19 -10
  34. package/skills/workos-authkit-react-router/SKILL.md +18 -8
  35. package/skills/workos-authkit-sveltekit/SKILL.md +55 -7
  36. package/skills/workos-authkit-tanstack-start/SKILL.md +22 -8
  37. package/skills/workos-authkit-vanilla-js/SKILL.md +19 -10
  38. package/skills/workos-elixir/SKILL.md +37 -0
  39. package/skills/workos-go/SKILL.md +36 -1
  40. package/skills/workos-kotlin/SKILL.md +34 -0
  41. package/skills/workos-management/SKILL.md +1 -1
  42. package/skills/workos-node/SKILL.md +33 -0
  43. package/skills/workos-php/SKILL.md +34 -1
  44. package/skills/workos-php-laravel/SKILL.md +36 -1
  45. package/skills/workos-python/SKILL.md +34 -0
  46. package/skills/workos-ruby/SKILL.md +35 -0
@@ -1 +1 @@
1
- {"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for WorkOS wizards\n * Uses Claude Agent SDK directly with WorkOS MCP server\n */\n\nimport { getPackageRoot } from '../utils/paths.js';\nimport { debug, logInfo, logWarn, logError, initLogFile, getLogFilePath } from '../utils/debug.js';\nimport type { InstallerOptions } from '../utils/types.js';\nimport { analytics } from '../utils/analytics.js';\nimport { INSTALLER_INTERACTION_EVENT_NAME } from './constants.js';\nimport { LINTING_TOOLS } from './safe-tools.js';\nimport { getLlmGatewayUrlFromHost } from '../utils/urls.js';\nimport { getConfig } from './settings.js';\nimport { getCredentials, hasCredentials } from './credentials.js';\nimport { ensureValidToken } from './token-refresh.js';\nimport type { InstallerEventEmitter } from './events.js';\nimport { startCredentialProxy, type CredentialProxyHandle } from './credential-proxy.js';\nimport { getAuthkitDomain, getCliAuthClientId } from './settings.js';\nimport type {\n SDKMessage,\n SDKUserMessage,\n Options as AgentSDKOptions,\n PermissionResult,\n query as queryFn,\n} from '@anthropic-ai/claude-agent-sdk';\n\n// File content cache for computing edit diffs\nconst fileContentCache = new Map<string, string>();\n// Track pending Read operations by tool_use_id\nconst pendingReads = new Map<string, string>();\n// Track tool start times by tool_use_id for telemetry\nconst pendingToolCalls = new Map<string, { toolName: string; startTime: number }>();\n\n// Module-level variable to track proxy handle for cleanup\nlet activeProxyHandle: CredentialProxyHandle | null = null;\n\n// Dynamic import cache for ESM module\nlet _sdkModule: { query: typeof queryFn } | null = null;\nasync function getSDKModule(): Promise<{ query: typeof queryFn }> {\n if (!_sdkModule) {\n _sdkModule = await import('@anthropic-ai/claude-agent-sdk');\n }\n return _sdkModule;\n}\n\nexport const AgentSignals = {\n /** Signal emitted when the agent reports progress to the user */\n STATUS: '[STATUS]',\n /** Signal emitted when the agent cannot access the WorkOS MCP server */\n ERROR_MCP_MISSING: '[ERROR-MCP-MISSING]',\n /** Signal emitted when the agent cannot access the setup resource */\n ERROR_RESOURCE_MISSING: '[ERROR-RESOURCE-MISSING]',\n} as const;\n\nexport type AgentSignal = (typeof AgentSignals)[keyof typeof AgentSignals];\n\n/**\n * Error types that can be returned from agent execution.\n * These correspond to the error signals that the agent emits.\n */\nexport enum AgentErrorType {\n /** Agent could not access the WorkOS MCP server */\n MCP_MISSING = 'INSTALLER_MCP_MISSING',\n /** Agent could not access the setup resource */\n RESOURCE_MISSING = 'INSTALLER_RESOURCE_MISSING',\n /** Agent execution failed (API error, auth error, etc.) */\n EXECUTION_ERROR = 'INSTALLER_EXECUTION_ERROR',\n}\n\nexport type AgentConfig = {\n workingDirectory: string;\n workOSApiKey: string;\n workOSApiHost: string;\n};\n\nexport interface RetryConfig {\n /** Max correction attempts after initial run. Default: 2 */\n maxRetries: number;\n /** Run between agent turns. Return null if passed, or error prompt if failed. */\n validateAndFormat: (workingDirectory: string) => Promise<string | null>;\n}\n\n/**\n * Configuration object for running the agent.\n * Built by initializeAgent (production) or constructed directly (evals).\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n mcpServers: AgentSDKOptions['mcpServers'];\n model: string;\n allowedTools: string[];\n sdkEnv: Record<string, string | undefined>;\n};\n\n/**\n * Package managers that can be used to run commands.\n * Includes JS and non-JS ecosystem package managers for multi-SDK support.\n */\nconst PACKAGE_MANAGERS = [\n // JavaScript\n 'npm',\n 'pnpm',\n 'yarn',\n 'bun',\n 'npx',\n 'pnpx',\n 'bunx',\n // Python\n 'pip',\n 'pip3',\n 'poetry',\n 'uv',\n 'pipx',\n 'python',\n 'python3',\n // Ruby\n 'gem',\n 'bundle',\n 'bundler',\n 'ruby',\n // PHP\n 'composer',\n 'php',\n // Go\n 'go',\n // .NET\n 'dotnet',\n 'nuget',\n // Elixir\n 'mix',\n 'hex',\n 'elixir',\n // Kotlin/Java\n 'gradle',\n 'gradlew',\n './gradlew',\n 'mvn',\n];\n\n/**\n * Safe scripts/commands that can be run with any package manager.\n * Uses startsWith matching, so 'build' matches 'build', 'build:prod', etc.\n * Note: Linting tools are in LINTING_TOOLS and checked separately.\n */\nconst SAFE_SCRIPTS = [\n // Package installation\n 'install',\n 'add',\n 'ci',\n // Build\n 'build',\n // Type checking (various naming conventions)\n 'tsc',\n 'typecheck',\n 'type-check',\n 'check-types',\n 'types',\n // Linting/formatting script names (actual tools are in LINTING_TOOLS)\n 'lint',\n 'format',\n // Common cross-language commands\n 'check',\n 'test',\n 'run',\n 'serve',\n 'dev',\n 'start',\n 'compile',\n 'vet',\n // Python-specific\n 'manage.py',\n 'pytest',\n // Ruby-specific\n 'rspec',\n 'rake',\n 'routes',\n // PHP-specific\n 'artisan',\n 'phpunit',\n // Elixir-specific\n 'deps.get',\n 'credo',\n 'dialyzer',\n // .NET-specific\n 'restore',\n];\n\n/**\n * Dangerous shell operators that could allow command injection.\n * Note: We handle `2>&1` and `| tail/head` separately as safe patterns.\n */\nconst DANGEROUS_OPERATORS = /[;`$()]/;\n\n/**\n * Check if command is an allowed package manager command.\n * Matches: <pkg-manager> [run|exec] <safe-script> [args...]\n */\nfunction matchesAllowedPrefix(command: string): boolean {\n const parts = command.split(/\\s+/);\n if (parts.length === 0 || !PACKAGE_MANAGERS.includes(parts[0])) {\n return false;\n }\n\n // Skip 'run' or 'exec' if present\n let scriptIndex = 1;\n if (parts[scriptIndex] === 'run' || parts[scriptIndex] === 'exec') {\n scriptIndex++;\n }\n\n // Get the script/command portion (may include args)\n const scriptPart = parts.slice(scriptIndex).join(' ');\n\n // Check if script starts with any safe script name or linting tool\n return (\n SAFE_SCRIPTS.some((safe) => scriptPart.startsWith(safe)) ||\n LINTING_TOOLS.some((tool) => scriptPart.startsWith(tool))\n );\n}\n\n/**\n * Permission hook that allows only safe commands.\n * - Package manager install commands\n * - Build/typecheck/lint commands for verification\n * - Piping to tail/head for output limiting is allowed\n * - Stderr redirection (2>&1) is allowed\n */\nexport function installerCanUseTool(toolName: string, input: Record<string, unknown>): PermissionResult {\n // Allow all non-Bash tools\n if (toolName !== 'Bash') {\n return { behavior: 'allow', updatedInput: input };\n }\n\n const command = (typeof input.command === 'string' ? input.command : '').trim();\n\n // Block definitely dangerous operators: ; ` $ ( )\n if (DANGEROUS_OPERATORS.test(command)) {\n logWarn(`Denying bash command with dangerous operators: ${command}`);\n debug(`Denying bash command with dangerous operators: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'dangerous operators',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Shell operators like ; \\` $ ( ) are not permitted.`,\n };\n }\n\n // Normalize: remove safe stderr redirection (2>&1, 2>&2, etc.)\n const normalized = command.replace(/\\s*\\d*>&\\d+\\s*/g, ' ').trim();\n\n // Check for pipe to tail/head (safe output limiting)\n const pipeMatch = normalized.match(/^(.+?)\\s*\\|\\s*(tail|head)(\\s+\\S+)*\\s*$/);\n if (pipeMatch) {\n const baseCommand = pipeMatch[1].trim();\n\n // Block if base command has pipes or & (multiple chaining)\n if (/[|&]/.test(baseCommand)) {\n logWarn(`Denying bash command with multiple pipes: ${command}`);\n debug(`Denying bash command with multiple pipes: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'multiple pipes',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Only single pipe to tail/head is permitted.`,\n };\n }\n\n if (matchesAllowedPrefix(baseCommand)) {\n logInfo(`Allowing bash command with output limiter: ${command}`);\n debug(`Allowing bash command with output limiter: ${command}`);\n return { behavior: 'allow', updatedInput: input };\n }\n }\n\n // Block remaining pipes and & (not covered by tail/head case above)\n if (/[|&]/.test(normalized)) {\n logWarn(`Denying bash command with pipe/&: ${command}`);\n debug(`Denying bash command with pipe/&: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'disallowed pipe',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Pipes are only permitted with tail/head for output limiting.`,\n };\n }\n\n // Check if command starts with any allowed prefix\n if (matchesAllowedPrefix(normalized)) {\n logInfo(`Allowing bash command: ${command}`);\n debug(`Allowing bash command: ${command}`);\n return { behavior: 'allow', updatedInput: input };\n }\n\n logWarn(`Denying bash command: ${command}`);\n debug(`Denying bash command: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'not in allowlist',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Only install, build, typecheck, lint, and formatting commands are permitted.`,\n };\n}\n\n/**\n * Initialize agent configuration for the LLM gateway\n */\nexport async function initializeAgent(config: AgentConfig, options: InstallerOptions): Promise<AgentRunConfig> {\n // Initialize log file for this run\n initLogFile();\n logInfo('Agent initialization starting');\n logInfo('Install directory:', options.installDir);\n\n // Emit status event for adapters to render\n options.emitter?.emit('status', { message: 'Initializing Claude agent...' });\n\n try {\n let authMode: string;\n // Build SDK env without mutating process.env\n const sdkEnv: Record<string, string | undefined> = {\n ...process.env,\n // Disable experimental betas (like input_examples) that the LLM gateway doesn't support\n CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: 'true',\n // Disable SDK telemetry - our gateway doesn't proxy /api/event_logging/batch\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 'true',\n };\n\n if (options.direct) {\n // Direct mode: use user's Anthropic API key, skip gateway\n if (!process.env.ANTHROPIC_API_KEY) {\n throw new Error(\n 'Direct mode requires ANTHROPIC_API_KEY environment variable.\\n' +\n 'Set it with: export ANTHROPIC_API_KEY=sk-ant-...\\n' +\n 'Get your key at: https://console.anthropic.com/settings/keys',\n );\n }\n\n // SDK defaults to api.anthropic.com when no base URL set\n delete sdkEnv.ANTHROPIC_BASE_URL;\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = 'direct:api.anthropic.com';\n logInfo('Direct mode: using ANTHROPIC_API_KEY, bypassing llm-gateway');\n\n // Set analytics tag for direct mode\n analytics.setTag('api_mode', 'direct');\n } else {\n // Gateway mode (existing behavior)\n const gatewayUrl = getLlmGatewayUrlFromHost();\n\n // Check/refresh authentication for production (unless skipping auth)\n if (!options.skipAuth && !options.local) {\n if (!hasCredentials()) {\n throw new Error('Not authenticated. Run `workos login` to authenticate.');\n }\n\n const creds = getCredentials();\n if (!creds) {\n throw new Error('Not authenticated. Run `workos login` to authenticate.');\n }\n\n // Check if we have refresh token capability and proxy is not disabled\n if (creds.refreshToken && process.env.INSTALLER_DISABLE_PROXY !== '1') {\n // Start credential proxy with lazy refresh\n logInfo('[agent-interface] Starting credential proxy with lazy refresh...');\n const appConfig = getConfig();\n\n activeProxyHandle = await startCredentialProxy({\n upstreamUrl: gatewayUrl,\n refresh: {\n authkitDomain: getAuthkitDomain(),\n clientId: getCliAuthClientId(),\n refreshThresholdMs: appConfig.proxy.refreshThresholdMs,\n onRefreshSuccess: () => {\n options.emitter?.emit('status', { message: 'Session extended' });\n },\n onRefreshExpired: () => {\n logError('[agent-interface] Session expired, refresh token invalid');\n options.emitter?.emit('error', {\n message: 'Session expired. Run `workos login` to re-authenticate.',\n });\n },\n },\n });\n\n // Point SDK at proxy instead of direct gateway\n sdkEnv.ANTHROPIC_BASE_URL = activeProxyHandle.url;\n logInfo(`[agent-interface] Using credential proxy at ${activeProxyHandle.url}`);\n\n // Proxy handles auth, so we don't set ANTHROPIC_AUTH_TOKEN\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = `proxy:${activeProxyHandle.url}→${gatewayUrl}`;\n } else {\n // No refresh token OR proxy disabled - fall back to old behavior (5 min limit)\n if (!creds.refreshToken) {\n logWarn('[agent-interface] No refresh token available, session limited to 5 minutes');\n logWarn('[agent-interface] Run `workos login` to enable extended sessions');\n options.emitter?.emit('status', {\n message: 'Note: Run `workos login` to enable extended sessions',\n });\n } else {\n logWarn('[agent-interface] Proxy disabled via INSTALLER_DISABLE_PROXY');\n }\n\n const refreshResult = await ensureValidToken();\n if (!refreshResult.success) {\n throw new Error(refreshResult.error || 'Authentication failed');\n }\n\n sdkEnv.ANTHROPIC_BASE_URL = gatewayUrl;\n sdkEnv.ANTHROPIC_AUTH_TOKEN = creds.accessToken;\n authMode = options.local ? `local-gateway:${gatewayUrl}` : `workos-gateway:${gatewayUrl}`;\n logInfo('Sending access token to gateway (legacy mode)');\n }\n } else if (options.skipAuth) {\n // Skip auth mode - direct to gateway without auth\n sdkEnv.ANTHROPIC_BASE_URL = gatewayUrl;\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = `skip-auth:${gatewayUrl}`;\n logInfo('Skipping auth - no token sent to gateway');\n } else {\n // Local mode without auth\n sdkEnv.ANTHROPIC_BASE_URL = gatewayUrl;\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = `local-gateway:${gatewayUrl}`;\n logInfo('Local mode - no token sent to gateway');\n }\n\n logInfo('Configured LLM gateway:', sdkEnv.ANTHROPIC_BASE_URL);\n\n // Set analytics tag for gateway mode\n analytics.setTag('api_mode', activeProxyHandle ? 'gateway-proxy' : 'gateway');\n }\n\n // Configure WorkOS MCP docs server for accessing WorkOS documentation\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n mcpServers: {\n workos: {\n command: 'npx',\n args: ['-y', '@workos/mcp-docs-server'],\n },\n },\n model: getConfig().model,\n allowedTools: ['Skill', 'Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch'],\n sdkEnv,\n };\n\n const configInfo = { workingDirectory: agentRunConfig.workingDirectory, authMode, useMcp: false };\n logInfo('Agent config:', configInfo);\n debug('Agent config:', configInfo);\n\n // Emit status events for adapters to render\n const currentLogPath = getLogFilePath();\n if (currentLogPath) {\n options.emitter?.emit('status', { message: `Verbose logs: ${currentLogPath}` });\n }\n options.emitter?.emit('status', { message: \"Agent initialized. Let's get cooking!\" });\n\n return agentRunConfig;\n } catch (error) {\n // Clean up proxy if initialization fails\n if (activeProxyHandle) {\n logInfo('[agent-interface] Cleaning up proxy after init error');\n await activeProxyHandle.stop();\n activeProxyHandle = null;\n }\n logError('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Execute an agent with the provided prompt and options\n * Handles the full lifecycle via event emissions - adapters handle UI rendering.\n *\n * @returns An object containing any error detected in the agent's output\n */\nexport async function runAgent(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: InstallerOptions,\n config?: {\n spinnerMessage?: string;\n successMessage?: string;\n errorMessage?: string;\n },\n emitter?: InstallerEventEmitter,\n retryConfig?: RetryConfig,\n onMessage?: (message: SDKMessage) => void,\n): Promise<{ error?: AgentErrorType; errorMessage?: string; retryCount?: number }> {\n const { spinnerMessage = 'Setting up WorkOS AuthKit...' } = config ?? {};\n\n const { query } = await getSDKModule();\n\n // Emit progress for adapters to handle (e.g., CLI adapter starts spinner)\n emitter?.emit('agent:progress', { step: 'Starting', detail: 'This may take a few minutes. Grab some coffee!' });\n emitter?.emit('agent:progress', { step: spinnerMessage });\n\n logInfo('Starting agent run');\n logInfo('Prompt:', prompt);\n\n const startTime = Date.now();\n const collectedText: string[] = [];\n\n try {\n let retryCount = 0;\n const maxRetries = retryConfig?.maxRetries ?? 0;\n\n // Turn completion signals — resolveCurrentTurn is called when a 'result'\n // message arrives; the prompt generator awaits currentTurnDone between turns.\n let resolveCurrentTurn!: () => void;\n let currentTurnDone!: Promise<void>;\n\n function resetTurnSignal() {\n currentTurnDone = new Promise<void>((resolve) => {\n resolveCurrentTurn = resolve;\n });\n }\n resetTurnSignal();\n\n const createPromptStream = async function* (): AsyncGenerator<SDKUserMessage> {\n yield {\n type: 'user' as const,\n session_id: '',\n message: { role: 'user' as const, content: prompt },\n parent_tool_use_id: null,\n };\n\n if (retryConfig && maxRetries > 0) {\n while (retryCount < maxRetries) {\n await currentTurnDone;\n\n emitter?.emit('validation:retry:start', { attempt: retryCount + 1 });\n\n let validationPrompt: string | null;\n try {\n validationPrompt = await retryConfig.validateAndFormat(agentConfig.workingDirectory);\n } catch (err) {\n // Don't block on validation bugs — treat as passed\n logError('validateAndFormat threw:', err);\n validationPrompt = null;\n }\n\n emitter?.emit('validation:retry:complete', {\n attempt: retryCount + 1,\n passed: validationPrompt === null,\n });\n\n if (validationPrompt === null) break;\n\n retryCount++;\n emitter?.emit('agent:retry', { attempt: retryCount, maxRetries });\n\n resetTurnSignal();\n\n yield {\n type: 'user',\n session_id: '',\n message: { role: 'user', content: validationPrompt },\n parent_tool_use_id: null,\n };\n }\n }\n\n await currentTurnDone;\n };\n\n // Load plugin with bundled skills\n const pluginPath = getPackageRoot(import.meta.url);\n logInfo('Loading plugin from:', pluginPath);\n\n const response = query({\n prompt: createPromptStream(),\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'acceptEdits',\n mcpServers: agentConfig.mcpServers,\n env: agentConfig.sdkEnv,\n canUseTool: (toolName, input) => {\n logInfo('canUseTool called:', { toolName, input });\n const result = installerCanUseTool(toolName, input);\n logInfo('canUseTool result:', result);\n return Promise.resolve(result);\n },\n tools: { type: 'preset', preset: 'claude_code' },\n allowedTools: agentConfig.allowedTools,\n plugins: [{ type: 'local', path: pluginPath }],\n // Capture stderr from CLI subprocess for debugging\n stderr: (data: string) => {\n logInfo('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n });\n\n // Process the async generator\n let sdkError: string | undefined;\n for await (const message of response) {\n const messageError = handleSDKMessage(message, options, collectedText, emitter);\n if (messageError) {\n sdkError = messageError;\n }\n if (message.type === 'result') {\n resolveCurrentTurn();\n }\n try {\n onMessage?.(message);\n } catch {\n /* non-critical */\n }\n }\n\n const durationMs = Date.now() - startTime;\n const outputText = collectedText.join('\\n');\n\n // Check for SDK errors first (e.g., API errors, auth failures)\n // Return error type + message - caller decides whether to throw or emit events\n if (sdkError) {\n logError('Agent SDK error:', sdkError);\n return { error: AgentErrorType.EXECUTION_ERROR, errorMessage: sdkError };\n }\n\n // Check for error markers in the agent's output\n if (outputText.includes(AgentSignals.ERROR_MCP_MISSING)) {\n logError('Agent error: MCP_MISSING');\n return { error: AgentErrorType.MCP_MISSING, errorMessage: 'Could not access WorkOS MCP server' };\n }\n\n if (outputText.includes(AgentSignals.ERROR_RESOURCE_MISSING)) {\n logError('Agent error: RESOURCE_MISSING');\n return { error: AgentErrorType.RESOURCE_MISSING, errorMessage: 'Could not access setup resource' };\n }\n\n logInfo(`Agent run completed in ${Math.round(durationMs / 1000)}s (${retryCount} retries)`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'agent integration completed',\n duration_ms: durationMs,\n duration_seconds: Math.round(durationMs / 1000),\n retry_count: retryCount,\n max_retries: maxRetries,\n passed_after_retry: retryCount > 0,\n });\n\n // Don't emit agent:success here - let the state machine handle lifecycle events\n return { retryCount };\n } catch (error) {\n // Don't emit events here - just log and re-throw for state machine to handle\n logError('Agent run failed:', error);\n debug('Full error:', error);\n throw error;\n } finally {\n // Always clean up proxy when agent run completes\n if (activeProxyHandle) {\n logInfo('[agent-interface] Stopping credential proxy');\n\n analytics.capture('installer.proxy', {\n action: 'stop',\n port: activeProxyHandle.port,\n });\n\n await activeProxyHandle.stop();\n activeProxyHandle = null;\n }\n }\n}\n\n/**\n * Handle SDK messages and emit events for adapters to render.\n * @returns Error message if this was an error result, undefined otherwise\n */\nfunction handleSDKMessage(\n message: SDKMessage,\n options: InstallerOptions,\n collectedText: string[],\n emitter?: InstallerEventEmitter,\n): string | undefined {\n logInfo(`SDK Message: ${message.type}`, JSON.stringify(message, null, 2));\n\n switch (message.type) {\n case 'assistant': {\n // Extract usage data from Anthropic API response for telemetry\n const usage = message.message?.usage;\n if (usage) {\n const inputTokens = usage.input_tokens ?? 0;\n const outputTokens = usage.output_tokens ?? 0;\n const model = message.message?.model ?? 'unknown';\n analytics.llmRequest(model, inputTokens, outputTokens);\n analytics.incrementAgentIterations();\n }\n\n // Extract text content from assistant messages\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'text' && typeof block.text === 'string') {\n collectedText.push(block.text);\n\n // Emit output event for dashboard\n emitter?.emit('output', { text: block.text });\n\n // Check for [STATUS] markers and emit progress events\n const statusRegex = new RegExp(\n `^.*${AgentSignals.STATUS.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\\\s*(.+?)$`,\n 'm',\n );\n const statusMatch = block.text.match(statusRegex);\n if (statusMatch) {\n const statusText = statusMatch[1].trim();\n // Emit progress event - adapters handle spinner updates\n emitter?.emit('agent:progress', { step: statusText });\n emitter?.emit('status', { message: statusText });\n }\n }\n\n // Check for tool_use blocks (Write/Edit operations)\n if (block.type === 'tool_use') {\n const toolName = block.name as string;\n const toolUseId = block.id as string;\n const input = block.input as Record<string, unknown>;\n\n // Log tool usage for debugging\n logInfo(`Tool use: ${toolName}`);\n\n // Track tool start time for telemetry\n if (toolUseId) {\n pendingToolCalls.set(toolUseId, { toolName, startTime: Date.now() });\n }\n\n // Emit file:write event for Write tool\n if (toolName === 'Write' && input) {\n const filePath = input.file_path as string;\n const fileContent = input.content as string;\n if (filePath && fileContent) {\n emitter?.emit('file:write', { path: filePath, content: fileContent });\n }\n }\n\n // Emit file:edit event for Edit tool\n if (toolName === 'Edit' && input) {\n const filePath = input.file_path as string;\n const oldString = input.old_string as string;\n const newString = input.new_string as string;\n if (filePath && oldString !== undefined && newString !== undefined) {\n // Emit the actual strings being replaced, not reconstructed full file\n emitter?.emit('file:edit', {\n path: filePath,\n oldContent: oldString,\n newContent: newString,\n });\n }\n }\n\n // Track Read operations for caching file content later\n if (toolName === 'Read' && input && block.id) {\n const filePath = input.file_path as string;\n if (filePath) {\n pendingReads.set(block.id as string, filePath);\n }\n }\n }\n }\n }\n break;\n }\n\n case 'user': {\n // User messages contain tool results\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n // Tool results contain file content from Read operations\n if (block.type === 'tool_result' && block.tool_use_id) {\n const toolUseId = block.tool_use_id as string;\n\n // Emit telemetry for completed tool call\n const pendingTool = pendingToolCalls.get(toolUseId);\n if (pendingTool) {\n const durationMs = Date.now() - pendingTool.startTime;\n // Check if tool result indicates error (is_error field or error in content)\n const isError = block.is_error === true;\n analytics.toolCalled(pendingTool.toolName, durationMs, !isError);\n pendingToolCalls.delete(toolUseId);\n }\n\n const filePath = pendingReads.get(toolUseId);\n if (filePath) {\n // Extract content from the tool result\n let resultContent = '';\n if (typeof block.content === 'string') {\n resultContent = block.content;\n } else if (Array.isArray(block.content)) {\n // Content might be array of text blocks\n for (const item of block.content) {\n if (item.type === 'text' && item.text) {\n resultContent += item.text;\n }\n }\n }\n if (resultContent) {\n fileContentCache.set(filePath, resultContent);\n }\n pendingReads.delete(toolUseId);\n }\n }\n }\n }\n break;\n }\n\n case 'result': {\n if (message.subtype === 'success') {\n logInfo('Agent completed successfully');\n if (typeof message.result === 'string') {\n collectedText.push(message.result);\n }\n } else {\n // Error result\n logError('Agent error result:', message.subtype);\n if (message.errors && message.errors.length > 0) {\n for (const err of message.errors) {\n logError('ERROR:', err);\n // Emit error event - adapters handle rendering\n emitter?.emit('error', { message: err });\n }\n // Return the first error message\n return message.errors[0];\n }\n // Return generic error if subtype indicates failure but no errors array\n return `Agent execution failed: ${message.subtype}`;\n }\n break;\n }\n\n case 'system': {\n if (message.subtype === 'init') {\n logInfo('Agent session initialized', {\n model: message.model,\n tools: message.tools?.length,\n mcpServers: message.mcp_servers,\n });\n }\n break;\n }\n\n default:\n // Log other message types for debugging\n if (options.debug) {\n debug(`Unhandled message type: ${message.type}`);\n }\n break;\n }\n return undefined;\n}\n\n/**\n * Get the active proxy handle (for testing/debugging).\n */\nexport function getActiveProxyHandle(): CredentialProxyHandle | null {\n return activeProxyHandle;\n}\n"]}
1
+ {"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for WorkOS wizards\n * Uses Claude Agent SDK directly with WorkOS MCP server\n */\n\nimport { getPackageRoot } from '../utils/paths.js';\nimport { debug, logInfo, logWarn, logError, initLogFile, getLogFilePath } from '../utils/debug.js';\nimport type { InstallerOptions } from '../utils/types.js';\nimport { analytics } from '../utils/analytics.js';\nimport { INSTALLER_INTERACTION_EVENT_NAME } from './constants.js';\nimport { LINTING_TOOLS } from './safe-tools.js';\nimport { getLlmGatewayUrlFromHost } from '../utils/urls.js';\nimport { getConfig } from './settings.js';\nimport { getCredentials, hasCredentials } from './credentials.js';\nimport { ensureValidToken } from './token-refresh.js';\nimport type { InstallerEventEmitter } from './events.js';\nimport { startCredentialProxy, type CredentialProxyHandle } from './credential-proxy.js';\nimport { getAuthkitDomain, getCliAuthClientId } from './settings.js';\nimport type {\n SDKMessage,\n SDKUserMessage,\n Options as AgentSDKOptions,\n PermissionResult,\n query as queryFn,\n} from '@anthropic-ai/claude-agent-sdk';\n\n// File content cache for computing edit diffs\nconst fileContentCache = new Map<string, string>();\n// Track pending Read operations by tool_use_id\nconst pendingReads = new Map<string, string>();\n// Track tool start times by tool_use_id for telemetry\nconst pendingToolCalls = new Map<string, { toolName: string; startTime: number }>();\n\n// Module-level variable to track proxy handle for cleanup\nlet activeProxyHandle: CredentialProxyHandle | null = null;\n\n// Dynamic import cache for ESM module\nlet _sdkModule: { query: typeof queryFn } | null = null;\nasync function getSDKModule(): Promise<{ query: typeof queryFn }> {\n if (!_sdkModule) {\n _sdkModule = await import('@anthropic-ai/claude-agent-sdk');\n }\n return _sdkModule;\n}\n\nexport const AgentSignals = {\n /** Signal emitted when the agent reports progress to the user */\n STATUS: '[STATUS]',\n /** Signal emitted when the agent cannot access the WorkOS MCP server */\n ERROR_MCP_MISSING: '[ERROR-MCP-MISSING]',\n /** Signal emitted when the agent cannot access the setup resource */\n ERROR_RESOURCE_MISSING: '[ERROR-RESOURCE-MISSING]',\n} as const;\n\nexport type AgentSignal = (typeof AgentSignals)[keyof typeof AgentSignals];\n\n/**\n * Error types that can be returned from agent execution.\n * These correspond to the error signals that the agent emits.\n */\nexport enum AgentErrorType {\n /** Agent could not access the WorkOS MCP server */\n MCP_MISSING = 'INSTALLER_MCP_MISSING',\n /** Agent could not access the setup resource */\n RESOURCE_MISSING = 'INSTALLER_RESOURCE_MISSING',\n /** Agent execution failed (API error, auth error, etc.) */\n EXECUTION_ERROR = 'INSTALLER_EXECUTION_ERROR',\n}\n\nexport type AgentConfig = {\n workingDirectory: string;\n workOSApiKey: string;\n workOSApiHost: string;\n};\n\nexport interface RetryConfig {\n /** Max correction attempts after initial run. Default: 2 */\n maxRetries: number;\n /** Run between agent turns. Return null if passed, or error prompt if failed. */\n validateAndFormat: (workingDirectory: string) => Promise<string | null>;\n}\n\n/**\n * Configuration object for running the agent.\n * Built by initializeAgent (production) or constructed directly (evals).\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n mcpServers: AgentSDKOptions['mcpServers'];\n model: string;\n allowedTools: string[];\n sdkEnv: Record<string, string | undefined>;\n};\n\n/**\n * Package managers that can be used to run commands.\n * Includes JS and non-JS ecosystem package managers for multi-SDK support.\n */\nconst PACKAGE_MANAGERS = [\n // JavaScript\n 'npm',\n 'pnpm',\n 'yarn',\n 'bun',\n 'npx',\n 'pnpx',\n 'bunx',\n // Python\n 'pip',\n 'pip3',\n 'poetry',\n 'uv',\n 'pipx',\n 'python',\n 'python3',\n // Ruby\n 'gem',\n 'bundle',\n 'bundler',\n 'ruby',\n // PHP\n 'composer',\n 'php',\n // Go\n 'go',\n // .NET\n 'dotnet',\n 'nuget',\n // Elixir\n 'mix',\n 'hex',\n 'elixir',\n // Kotlin/Java\n 'gradle',\n 'gradlew',\n './gradlew',\n 'mvn',\n];\n\n/**\n * Safe scripts/commands that can be run with any package manager.\n * Uses startsWith matching, so 'build' matches 'build', 'build:prod', etc.\n * Note: Linting tools are in LINTING_TOOLS and checked separately.\n */\nconst SAFE_SCRIPTS = [\n // Package installation\n 'install',\n 'add',\n 'ci',\n // Build\n 'build',\n // Type checking (various naming conventions)\n 'tsc',\n 'typecheck',\n 'type-check',\n 'check-types',\n 'types',\n // Linting/formatting script names (actual tools are in LINTING_TOOLS)\n 'lint',\n 'format',\n // Common cross-language commands\n 'check',\n 'test',\n 'run',\n 'serve',\n 'dev',\n 'start',\n 'compile',\n 'vet',\n // Python-specific\n 'manage.py',\n 'pytest',\n // Ruby-specific\n 'rspec',\n 'rake',\n 'routes',\n // PHP-specific\n 'artisan',\n 'phpunit',\n // Elixir-specific\n 'deps.get',\n 'credo',\n 'dialyzer',\n // .NET-specific\n 'restore',\n];\n\n/**\n * Dangerous shell operators that could allow command injection.\n * Note: We handle `2>&1` and `| tail/head` separately as safe patterns.\n */\nconst DANGEROUS_OPERATORS = /[;`$()]/;\n\n/**\n * Check if command is an allowed package manager command.\n * Matches: <pkg-manager> [run|exec] <safe-script> [args...]\n */\nfunction matchesAllowedPrefix(command: string): boolean {\n const parts = command.split(/\\s+/);\n if (parts.length === 0 || !PACKAGE_MANAGERS.includes(parts[0])) {\n return false;\n }\n\n // Skip 'run' or 'exec' if present\n let scriptIndex = 1;\n if (parts[scriptIndex] === 'run' || parts[scriptIndex] === 'exec') {\n scriptIndex++;\n }\n\n // Get the script/command portion (may include args)\n const scriptPart = parts.slice(scriptIndex).join(' ');\n\n // Check if script starts with any safe script name or linting tool\n return (\n SAFE_SCRIPTS.some((safe) => scriptPart.startsWith(safe)) ||\n LINTING_TOOLS.some((tool) => scriptPart.startsWith(tool))\n );\n}\n\n/**\n * Permission hook that allows only safe commands.\n * - Package manager install commands\n * - Build/typecheck/lint commands for verification\n * - Piping to tail/head for output limiting is allowed\n * - Stderr redirection (2>&1) is allowed\n */\nexport function installerCanUseTool(toolName: string, input: Record<string, unknown>): PermissionResult {\n // Allow all non-Bash tools\n if (toolName !== 'Bash') {\n return { behavior: 'allow', updatedInput: input };\n }\n\n const command = (typeof input.command === 'string' ? input.command : '').trim();\n\n // Block definitely dangerous operators: ; ` $ ( )\n if (DANGEROUS_OPERATORS.test(command)) {\n logWarn(`Denying bash command with dangerous operators: ${command}`);\n debug(`Denying bash command with dangerous operators: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'dangerous operators',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Shell operators like ; \\` $ ( ) are not permitted.`,\n };\n }\n\n // Normalize: remove safe stderr redirection (2>&1, 2>&2, etc.)\n const normalized = command.replace(/\\s*\\d*>&\\d+\\s*/g, ' ').trim();\n\n // Check for pipe to tail/head (safe output limiting)\n const pipeMatch = normalized.match(/^(.+?)\\s*\\|\\s*(tail|head)(\\s+\\S+)*\\s*$/);\n if (pipeMatch) {\n const baseCommand = pipeMatch[1].trim();\n\n // Block if base command has pipes or & (multiple chaining)\n if (/[|&]/.test(baseCommand)) {\n logWarn(`Denying bash command with multiple pipes: ${command}`);\n debug(`Denying bash command with multiple pipes: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'multiple pipes',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Only single pipe to tail/head is permitted.`,\n };\n }\n\n if (matchesAllowedPrefix(baseCommand)) {\n logInfo(`Allowing bash command with output limiter: ${command}`);\n debug(`Allowing bash command with output limiter: ${command}`);\n return { behavior: 'allow', updatedInput: input };\n }\n }\n\n // Block remaining pipes and & (not covered by tail/head case above)\n if (/[|&]/.test(normalized)) {\n logWarn(`Denying bash command with pipe/&: ${command}`);\n debug(`Denying bash command with pipe/&: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'disallowed pipe',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Pipes are only permitted with tail/head for output limiting.`,\n };\n }\n\n // Check if command starts with any allowed prefix\n if (matchesAllowedPrefix(normalized)) {\n logInfo(`Allowing bash command: ${command}`);\n debug(`Allowing bash command: ${command}`);\n return { behavior: 'allow', updatedInput: input };\n }\n\n logWarn(`Denying bash command: ${command}`);\n debug(`Denying bash command: ${command}`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'bash command denied',\n reason: 'not in allowlist',\n command,\n });\n return {\n behavior: 'deny',\n message: `Bash command not allowed. Only install, build, typecheck, lint, and formatting commands are permitted.`,\n };\n}\n\n/**\n * Initialize agent configuration for the LLM gateway\n */\nexport async function initializeAgent(config: AgentConfig, options: InstallerOptions): Promise<AgentRunConfig> {\n // Initialize log file for this run\n initLogFile();\n logInfo('Agent initialization starting');\n logInfo('Install directory:', options.installDir);\n\n // Emit status event for adapters to render\n options.emitter?.emit('status', { message: 'Initializing Claude agent...' });\n\n try {\n let authMode: string;\n // Build SDK env without mutating process.env\n const sdkEnv: Record<string, string | undefined> = {\n ...process.env,\n // Disable experimental betas (like input_examples) that the LLM gateway doesn't support\n CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: 'true',\n // Disable SDK telemetry - our gateway doesn't proxy /api/event_logging/batch\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 'true',\n };\n\n if (options.direct) {\n // Direct mode: use user's Anthropic API key, skip gateway\n if (!process.env.ANTHROPIC_API_KEY) {\n throw new Error(\n 'Direct mode requires ANTHROPIC_API_KEY environment variable.\\n' +\n 'Set it with: export ANTHROPIC_API_KEY=sk-ant-...\\n' +\n 'Get your key at: https://console.anthropic.com/settings/keys',\n );\n }\n\n // SDK defaults to api.anthropic.com when no base URL set\n delete sdkEnv.ANTHROPIC_BASE_URL;\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = 'direct:api.anthropic.com';\n logInfo('Direct mode: using ANTHROPIC_API_KEY, bypassing llm-gateway');\n\n // Set analytics tag for direct mode\n analytics.setTag('api_mode', 'direct');\n } else {\n // Gateway mode (existing behavior)\n const gatewayUrl = getLlmGatewayUrlFromHost();\n\n // Check/refresh authentication for production (unless skipping auth)\n if (!options.skipAuth && !options.local) {\n if (!hasCredentials()) {\n throw new Error('Not authenticated. Run `workos auth login` to authenticate.');\n }\n\n const creds = getCredentials();\n if (!creds) {\n throw new Error('Not authenticated. Run `workos auth login` to authenticate.');\n }\n\n // Check if we have refresh token capability and proxy is not disabled\n if (creds.refreshToken && process.env.INSTALLER_DISABLE_PROXY !== '1') {\n // Start credential proxy with lazy refresh\n logInfo('[agent-interface] Starting credential proxy with lazy refresh...');\n const appConfig = getConfig();\n\n activeProxyHandle = await startCredentialProxy({\n upstreamUrl: gatewayUrl,\n refresh: {\n authkitDomain: getAuthkitDomain(),\n clientId: getCliAuthClientId(),\n refreshThresholdMs: appConfig.proxy.refreshThresholdMs,\n onRefreshSuccess: () => {\n options.emitter?.emit('status', { message: 'Session extended' });\n },\n onRefreshExpired: () => {\n logError('[agent-interface] Session expired, refresh token invalid');\n options.emitter?.emit('error', {\n message: 'Session expired. Run `workos auth login` to re-authenticate.',\n });\n },\n },\n });\n\n // Point SDK at proxy instead of direct gateway\n sdkEnv.ANTHROPIC_BASE_URL = activeProxyHandle.url;\n logInfo(`[agent-interface] Using credential proxy at ${activeProxyHandle.url}`);\n\n // Proxy handles auth, so we don't set ANTHROPIC_AUTH_TOKEN\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = `proxy:${activeProxyHandle.url}→${gatewayUrl}`;\n } else {\n // No refresh token OR proxy disabled - fall back to old behavior (5 min limit)\n if (!creds.refreshToken) {\n logWarn('[agent-interface] No refresh token available, session limited to 5 minutes');\n logWarn('[agent-interface] Run `workos auth login` to enable extended sessions');\n options.emitter?.emit('status', {\n message: 'Note: Run `workos auth login` to enable extended sessions',\n });\n } else {\n logWarn('[agent-interface] Proxy disabled via INSTALLER_DISABLE_PROXY');\n }\n\n const refreshResult = await ensureValidToken();\n if (!refreshResult.success) {\n throw new Error(refreshResult.error || 'Authentication failed');\n }\n\n sdkEnv.ANTHROPIC_BASE_URL = gatewayUrl;\n sdkEnv.ANTHROPIC_AUTH_TOKEN = creds.accessToken;\n authMode = options.local ? `local-gateway:${gatewayUrl}` : `workos-gateway:${gatewayUrl}`;\n logInfo('Sending access token to gateway (legacy mode)');\n }\n } else if (options.skipAuth) {\n // Skip auth mode - direct to gateway without auth\n sdkEnv.ANTHROPIC_BASE_URL = gatewayUrl;\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = `skip-auth:${gatewayUrl}`;\n logInfo('Skipping auth - no token sent to gateway');\n } else {\n // Local mode without auth\n sdkEnv.ANTHROPIC_BASE_URL = gatewayUrl;\n delete sdkEnv.ANTHROPIC_AUTH_TOKEN;\n authMode = `local-gateway:${gatewayUrl}`;\n logInfo('Local mode - no token sent to gateway');\n }\n\n logInfo('Configured LLM gateway:', sdkEnv.ANTHROPIC_BASE_URL);\n\n // Set analytics tag for gateway mode\n analytics.setTag('api_mode', activeProxyHandle ? 'gateway-proxy' : 'gateway');\n }\n\n // Configure WorkOS MCP docs server for accessing WorkOS documentation\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n mcpServers: {\n workos: {\n command: 'npx',\n args: ['-y', '@workos/mcp-docs-server'],\n },\n },\n model: getConfig().model,\n allowedTools: ['Skill', 'Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch'],\n sdkEnv,\n };\n\n const configInfo = { workingDirectory: agentRunConfig.workingDirectory, authMode, useMcp: false };\n logInfo('Agent config:', configInfo);\n debug('Agent config:', configInfo);\n\n // Emit status events for adapters to render\n const currentLogPath = getLogFilePath();\n if (currentLogPath) {\n options.emitter?.emit('status', { message: `Verbose logs: ${currentLogPath}` });\n }\n options.emitter?.emit('status', { message: \"Agent initialized. Let's get cooking!\" });\n\n return agentRunConfig;\n } catch (error) {\n // Clean up proxy if initialization fails\n if (activeProxyHandle) {\n logInfo('[agent-interface] Cleaning up proxy after init error');\n await activeProxyHandle.stop();\n activeProxyHandle = null;\n }\n logError('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Execute an agent with the provided prompt and options\n * Handles the full lifecycle via event emissions - adapters handle UI rendering.\n *\n * @returns An object containing any error detected in the agent's output\n */\nexport async function runAgent(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: InstallerOptions,\n config?: {\n spinnerMessage?: string;\n successMessage?: string;\n errorMessage?: string;\n },\n emitter?: InstallerEventEmitter,\n retryConfig?: RetryConfig,\n onMessage?: (message: SDKMessage) => void,\n): Promise<{ error?: AgentErrorType; errorMessage?: string; retryCount?: number }> {\n const { spinnerMessage = 'Setting up WorkOS AuthKit...' } = config ?? {};\n\n const { query } = await getSDKModule();\n\n // Emit progress for adapters to handle (e.g., CLI adapter starts spinner)\n emitter?.emit('agent:progress', { step: 'Starting', detail: 'This may take a few minutes. Grab some coffee!' });\n emitter?.emit('agent:progress', { step: spinnerMessage });\n\n logInfo('Starting agent run');\n logInfo('Prompt:', prompt);\n\n const startTime = Date.now();\n const collectedText: string[] = [];\n\n try {\n let retryCount = 0;\n const maxRetries = retryConfig?.maxRetries ?? 0;\n\n // Turn completion signals — resolveCurrentTurn is called when a 'result'\n // message arrives; the prompt generator awaits currentTurnDone between turns.\n let resolveCurrentTurn!: () => void;\n let currentTurnDone!: Promise<void>;\n\n function resetTurnSignal() {\n currentTurnDone = new Promise<void>((resolve) => {\n resolveCurrentTurn = resolve;\n });\n }\n resetTurnSignal();\n\n const createPromptStream = async function* (): AsyncGenerator<SDKUserMessage> {\n yield {\n type: 'user' as const,\n session_id: '',\n message: { role: 'user' as const, content: prompt },\n parent_tool_use_id: null,\n };\n\n if (retryConfig && maxRetries > 0) {\n while (retryCount < maxRetries) {\n await currentTurnDone;\n\n emitter?.emit('validation:retry:start', { attempt: retryCount + 1 });\n\n let validationPrompt: string | null;\n try {\n validationPrompt = await retryConfig.validateAndFormat(agentConfig.workingDirectory);\n } catch (err) {\n // Don't block on validation bugs — treat as passed\n logError('validateAndFormat threw:', err);\n validationPrompt = null;\n }\n\n emitter?.emit('validation:retry:complete', {\n attempt: retryCount + 1,\n passed: validationPrompt === null,\n });\n\n if (validationPrompt === null) break;\n\n retryCount++;\n emitter?.emit('agent:retry', { attempt: retryCount, maxRetries });\n\n resetTurnSignal();\n\n yield {\n type: 'user',\n session_id: '',\n message: { role: 'user', content: validationPrompt },\n parent_tool_use_id: null,\n };\n }\n }\n\n await currentTurnDone;\n };\n\n // Load plugin with bundled skills\n const pluginPath = getPackageRoot(import.meta.url);\n logInfo('Loading plugin from:', pluginPath);\n\n const response = query({\n prompt: createPromptStream(),\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'acceptEdits',\n mcpServers: agentConfig.mcpServers,\n env: agentConfig.sdkEnv,\n canUseTool: (toolName, input) => {\n logInfo('canUseTool called:', { toolName, input });\n const result = installerCanUseTool(toolName, input);\n logInfo('canUseTool result:', result);\n return Promise.resolve(result);\n },\n tools: { type: 'preset', preset: 'claude_code' },\n allowedTools: agentConfig.allowedTools,\n plugins: [{ type: 'local', path: pluginPath }],\n // Capture stderr from CLI subprocess for debugging\n stderr: (data: string) => {\n logInfo('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n });\n\n // Process the async generator\n let sdkError: string | undefined;\n for await (const message of response) {\n const messageError = handleSDKMessage(message, options, collectedText, emitter);\n if (messageError) {\n sdkError = messageError;\n }\n if (message.type === 'result') {\n resolveCurrentTurn();\n }\n try {\n onMessage?.(message);\n } catch {\n /* non-critical */\n }\n }\n\n const durationMs = Date.now() - startTime;\n const outputText = collectedText.join('\\n');\n\n // Check for SDK errors first (e.g., API errors, auth failures)\n // Return error type + message - caller decides whether to throw or emit events\n if (sdkError) {\n logError('Agent SDK error:', sdkError);\n return { error: AgentErrorType.EXECUTION_ERROR, errorMessage: sdkError };\n }\n\n // Check for error markers in the agent's output\n if (outputText.includes(AgentSignals.ERROR_MCP_MISSING)) {\n logError('Agent error: MCP_MISSING');\n return { error: AgentErrorType.MCP_MISSING, errorMessage: 'Could not access WorkOS MCP server' };\n }\n\n if (outputText.includes(AgentSignals.ERROR_RESOURCE_MISSING)) {\n logError('Agent error: RESOURCE_MISSING');\n return { error: AgentErrorType.RESOURCE_MISSING, errorMessage: 'Could not access setup resource' };\n }\n\n logInfo(`Agent run completed in ${Math.round(durationMs / 1000)}s (${retryCount} retries)`);\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'agent integration completed',\n duration_ms: durationMs,\n duration_seconds: Math.round(durationMs / 1000),\n retry_count: retryCount,\n max_retries: maxRetries,\n passed_after_retry: retryCount > 0,\n });\n\n // Don't emit agent:success here - let the state machine handle lifecycle events\n return { retryCount };\n } catch (error) {\n // Don't emit events here - just log and re-throw for state machine to handle\n logError('Agent run failed:', error);\n debug('Full error:', error);\n throw error;\n } finally {\n // Always clean up proxy when agent run completes\n if (activeProxyHandle) {\n logInfo('[agent-interface] Stopping credential proxy');\n\n analytics.capture('installer.proxy', {\n action: 'stop',\n port: activeProxyHandle.port,\n });\n\n await activeProxyHandle.stop();\n activeProxyHandle = null;\n }\n }\n}\n\n/**\n * Handle SDK messages and emit events for adapters to render.\n * @returns Error message if this was an error result, undefined otherwise\n */\nfunction handleSDKMessage(\n message: SDKMessage,\n options: InstallerOptions,\n collectedText: string[],\n emitter?: InstallerEventEmitter,\n): string | undefined {\n logInfo(`SDK Message: ${message.type}`, JSON.stringify(message, null, 2));\n\n switch (message.type) {\n case 'assistant': {\n // Extract usage data from Anthropic API response for telemetry\n const usage = message.message?.usage;\n if (usage) {\n const inputTokens = usage.input_tokens ?? 0;\n const outputTokens = usage.output_tokens ?? 0;\n const model = message.message?.model ?? 'unknown';\n analytics.llmRequest(model, inputTokens, outputTokens);\n analytics.incrementAgentIterations();\n }\n\n // Extract text content from assistant messages\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'text' && typeof block.text === 'string') {\n collectedText.push(block.text);\n\n // Emit output event for dashboard\n emitter?.emit('output', { text: block.text });\n\n // Check for [STATUS] markers and emit progress events\n const statusRegex = new RegExp(\n `^.*${AgentSignals.STATUS.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\\\s*(.+?)$`,\n 'm',\n );\n const statusMatch = block.text.match(statusRegex);\n if (statusMatch) {\n const statusText = statusMatch[1].trim();\n // Emit progress event - adapters handle spinner updates\n emitter?.emit('agent:progress', { step: statusText });\n emitter?.emit('status', { message: statusText });\n }\n }\n\n // Check for tool_use blocks (Write/Edit operations)\n if (block.type === 'tool_use') {\n const toolName = block.name as string;\n const toolUseId = block.id as string;\n const input = block.input as Record<string, unknown>;\n\n // Log tool usage for debugging\n logInfo(`Tool use: ${toolName}`);\n\n // Track tool start time for telemetry\n if (toolUseId) {\n pendingToolCalls.set(toolUseId, { toolName, startTime: Date.now() });\n }\n\n // Emit file:write event for Write tool\n if (toolName === 'Write' && input) {\n const filePath = input.file_path as string;\n const fileContent = input.content as string;\n if (filePath && fileContent) {\n emitter?.emit('file:write', { path: filePath, content: fileContent });\n }\n }\n\n // Emit file:edit event for Edit tool\n if (toolName === 'Edit' && input) {\n const filePath = input.file_path as string;\n const oldString = input.old_string as string;\n const newString = input.new_string as string;\n if (filePath && oldString !== undefined && newString !== undefined) {\n // Emit the actual strings being replaced, not reconstructed full file\n emitter?.emit('file:edit', {\n path: filePath,\n oldContent: oldString,\n newContent: newString,\n });\n }\n }\n\n // Track Read operations for caching file content later\n if (toolName === 'Read' && input && block.id) {\n const filePath = input.file_path as string;\n if (filePath) {\n pendingReads.set(block.id as string, filePath);\n }\n }\n }\n }\n }\n break;\n }\n\n case 'user': {\n // User messages contain tool results\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n // Tool results contain file content from Read operations\n if (block.type === 'tool_result' && block.tool_use_id) {\n const toolUseId = block.tool_use_id as string;\n\n // Emit telemetry for completed tool call\n const pendingTool = pendingToolCalls.get(toolUseId);\n if (pendingTool) {\n const durationMs = Date.now() - pendingTool.startTime;\n // Check if tool result indicates error (is_error field or error in content)\n const isError = block.is_error === true;\n analytics.toolCalled(pendingTool.toolName, durationMs, !isError);\n pendingToolCalls.delete(toolUseId);\n }\n\n const filePath = pendingReads.get(toolUseId);\n if (filePath) {\n // Extract content from the tool result\n let resultContent = '';\n if (typeof block.content === 'string') {\n resultContent = block.content;\n } else if (Array.isArray(block.content)) {\n // Content might be array of text blocks\n for (const item of block.content) {\n if (item.type === 'text' && item.text) {\n resultContent += item.text;\n }\n }\n }\n if (resultContent) {\n fileContentCache.set(filePath, resultContent);\n }\n pendingReads.delete(toolUseId);\n }\n }\n }\n }\n break;\n }\n\n case 'result': {\n if (message.subtype === 'success') {\n logInfo('Agent completed successfully');\n if (typeof message.result === 'string') {\n collectedText.push(message.result);\n }\n } else {\n // Error result\n logError('Agent error result:', message.subtype);\n if (message.errors && message.errors.length > 0) {\n for (const err of message.errors) {\n logError('ERROR:', err);\n // Emit error event - adapters handle rendering\n emitter?.emit('error', { message: err });\n }\n // Return the first error message\n return message.errors[0];\n }\n // Return generic error if subtype indicates failure but no errors array\n return `Agent execution failed: ${message.subtype}`;\n }\n break;\n }\n\n case 'system': {\n if (message.subtype === 'init') {\n logInfo('Agent session initialized', {\n model: message.model,\n tools: message.tools?.length,\n mcpServers: message.mcp_servers,\n });\n }\n break;\n }\n\n default:\n // Log other message types for debugging\n if (options.debug) {\n debug(`Unhandled message type: ${message.type}`);\n }\n break;\n }\n return undefined;\n}\n\n/**\n * Get the active proxy handle (for testing/debugging).\n */\nexport function getActiveProxyHandle(): CredentialProxyHandle | null {\n return activeProxyHandle;\n}\n"]}
@@ -174,7 +174,7 @@ async function handleRequest(req, res, upstream, useHttps, thresholdMs) {
174
174
  res.writeHead(401, { 'Content-Type': 'application/json' });
175
175
  res.end(JSON.stringify({
176
176
  error: 'credentials_unavailable',
177
- message: 'Not authenticated. Run `workos login` first.',
177
+ message: 'Not authenticated. Run `workos auth login` first.',
178
178
  }));
179
179
  return;
180
180
  }
@@ -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"]}
@@ -59,7 +59,7 @@ export async function ensureAuthenticated() {
59
59
  if (refreshResult.errorType === 'invalid_grant') {
60
60
  clearCredentials();
61
61
  if (isNonInteractiveEnvironment()) {
62
- 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.');
63
63
  }
64
64
  logInfo('[ensure-auth] Refresh token expired, triggering login');
65
65
  await runLogin();
@@ -69,7 +69,7 @@ export async function ensureAuthenticated() {
69
69
  }
70
70
  // Network or server error - keep credentials intact for retry
71
71
  if (isNonInteractiveEnvironment()) {
72
- 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.`);
73
73
  }
74
74
  logInfo(`[ensure-auth] Refresh failed (${refreshResult.errorType}), triggering login`);
75
75
  await runLogin();
@@ -81,7 +81,7 @@ export async function ensureAuthenticated() {
81
81
  // Case 4: No refresh token available — clear stale creds, must login
82
82
  clearCredentials();
83
83
  if (isNonInteractiveEnvironment()) {
84
- 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.');
85
85
  }
86
86
  logInfo('[ensure-auth] No refresh token, triggering login');
87
87
  await runLogin();
@@ -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, 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('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 = 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 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 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"]}
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();