@ngandu/ulicode 0.0.6

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 (59) hide show
  1. package/CHANGELOG.md +1081 -0
  2. package/README.md +312 -0
  3. package/dist/agents/definitions/ask.agent.md +53 -0
  4. package/dist/agents/definitions/audit-tests.agent.md +138 -0
  5. package/dist/agents/definitions/build.agent.md +111 -0
  6. package/dist/agents/definitions/execute.agent.md +99 -0
  7. package/dist/agents/definitions/explore.agent.md +57 -0
  8. package/dist/agents/definitions/fast.agent.md +48 -0
  9. package/dist/agents/definitions/plan-mode.agent.md +102 -0
  10. package/dist/agents/definitions/planner.agent.md +59 -0
  11. package/dist/chunk-3YYDXNUH.js +854 -0
  12. package/dist/chunk-3YYDXNUH.js.map +1 -0
  13. package/dist/chunk-IEV2IT3O.cjs +873 -0
  14. package/dist/chunk-IEV2IT3O.cjs.map +1 -0
  15. package/dist/chunk-MBWGSXBT.js +11927 -0
  16. package/dist/chunk-MBWGSXBT.js.map +1 -0
  17. package/dist/chunk-MS5RYNRK.js +137 -0
  18. package/dist/chunk-MS5RYNRK.js.map +1 -0
  19. package/dist/chunk-OXFO76JC.js +2633 -0
  20. package/dist/chunk-OXFO76JC.js.map +1 -0
  21. package/dist/chunk-PKRLG6A4.js +1756 -0
  22. package/dist/chunk-PKRLG6A4.js.map +1 -0
  23. package/dist/chunk-PUVEPQQ3.cjs +1805 -0
  24. package/dist/chunk-PUVEPQQ3.cjs.map +1 -0
  25. package/dist/chunk-R6JK3DE3.cjs +148 -0
  26. package/dist/chunk-R6JK3DE3.cjs.map +1 -0
  27. package/dist/chunk-Y3HWP75B.cjs +11974 -0
  28. package/dist/chunk-Y3HWP75B.cjs.map +1 -0
  29. package/dist/chunk-Y5PO67TG.cjs +2659 -0
  30. package/dist/chunk-Y5PO67TG.cjs.map +1 -0
  31. package/dist/cli.cjs +372 -0
  32. package/dist/cli.cjs.map +1 -0
  33. package/dist/cli.d.cts +1 -0
  34. package/dist/cli.d.ts +1 -0
  35. package/dist/cli.js +370 -0
  36. package/dist/cli.js.map +1 -0
  37. package/dist/index.cjs +16 -0
  38. package/dist/index.cjs.map +1 -0
  39. package/dist/index.d.cts +165 -0
  40. package/dist/index.d.ts +165 -0
  41. package/dist/index.js +3 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/permissions-NRD36MYI.cjs +40 -0
  44. package/dist/permissions-NRD36MYI.cjs.map +1 -0
  45. package/dist/permissions-RC7CYR5H.js +3 -0
  46. package/dist/permissions-RC7CYR5H.js.map +1 -0
  47. package/dist/project-q9WpahUs.d.cts +329 -0
  48. package/dist/project-q9WpahUs.d.ts +329 -0
  49. package/dist/storage-6P53PQBL.cjs +24 -0
  50. package/dist/storage-6P53PQBL.cjs.map +1 -0
  51. package/dist/storage-QELMNBZ2.js +3 -0
  52. package/dist/storage-QELMNBZ2.js.map +1 -0
  53. package/dist/tui.cjs +76 -0
  54. package/dist/tui.cjs.map +1 -0
  55. package/dist/tui.d.cts +1013 -0
  56. package/dist/tui.d.ts +1013 -0
  57. package/dist/tui.js +3 -0
  58. package/dist/tui.js.map +1 -0
  59. package/package.json +107 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/project.ts","../src/auth/pkce.ts","../src/auth/providers/anthropic.ts","../src/auth/providers/openai-codex.ts","../src/auth/storage.ts"],"names":["scope","rid","CLIENT_ID","AUTHORIZE_URL","TOKEN_URL","REDIRECT_URI"],"mappings":"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","file":"chunk-3YYDXNUH.js","sourcesContent":["/**\n * Project detection utilities\n *\n * Detects project identity from git repo or filesystem path.\n * Handles git worktrees by finding the main repository.\n */\n\nimport { execSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nexport interface ProjectInfo {\n /** Unique resource ID for this project (used for thread grouping) */\n resourceId: string;\n /** Human-readable project name */\n name: string;\n /** Absolute path to the project root */\n rootPath: string;\n /** Git remote URL if available */\n gitUrl?: string;\n /** Current git branch */\n gitBranch?: string;\n /** Whether this is a git worktree */\n isWorktree: boolean;\n /** Path to main git repo (different from rootPath if worktree) */\n mainRepoPath?: string;\n /** Whether the resourceId was explicitly overridden (env var or config) */\n resourceIdOverride?: boolean;\n}\n\n/**\n * Run a git command and return stdout, or undefined if it fails\n */\nfunction git(args: string, cwd: string): string | undefined {\n try {\n return execSync(`git ${args}`, {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Slugify a string for use in IDs\n */\nfunction slugify(str: string): string {\n return str\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\n/**\n * Create a short hash of a string\n */\nfunction shortHash(str: string): string {\n return createHash('sha256').update(str).digest('hex').slice(0, 12);\n}\n\n/**\n * Normalize a git URL to a canonical form for comparison\n * - Removes .git suffix\n * - Converts SSH to HTTPS format for consistency\n * - Lowercases\n */\nfunction normalizeGitUrl(url: string): string {\n return url\n .replace(/\\.git$/, '')\n .replace(/^git@([^:]+):/, 'https://$1/')\n .replace(/^ssh:\\/\\/git@/, 'https://')\n .toLowerCase();\n}\n\n/**\n * Detect project info from a directory path\n */\nexport function detectProject(projectPath: string): ProjectInfo {\n const absolutePath = path.resolve(projectPath);\n\n // Check if this is a git repo\n const gitDir = git('rev-parse --git-dir', absolutePath);\n const isGitRepo = gitDir !== undefined;\n\n let rootPath = absolutePath;\n let gitUrl: string | undefined;\n let gitBranch: string | undefined;\n let isWorktree = false;\n let mainRepoPath: string | undefined;\n\n if (isGitRepo) {\n // Get the repo root (handles being in a subdirectory)\n rootPath = git('rev-parse --show-toplevel', absolutePath) || absolutePath;\n\n // Check for worktree - git-common-dir differs from git-dir in worktrees\n const commonDir = git('rev-parse --git-common-dir', absolutePath);\n if (commonDir && commonDir !== '.git' && commonDir !== gitDir) {\n isWorktree = true;\n // The common dir is inside the main repo's .git folder\n mainRepoPath = path.dirname(path.resolve(rootPath, commonDir));\n }\n\n // Get remote URL (prefer origin, fall back to first remote)\n gitUrl = git('remote get-url origin', absolutePath);\n if (!gitUrl) {\n const remotes = git('remote', absolutePath);\n if (remotes) {\n const firstRemote = remotes.split('\\n')[0];\n if (firstRemote) {\n gitUrl = git(`remote get-url ${firstRemote}`, absolutePath);\n }\n }\n }\n\n // Get current branch\n gitBranch = git('rev-parse --abbrev-ref HEAD', absolutePath);\n }\n\n // Generate resource ID\n // Priority: normalized git URL > main repo path (for worktrees) > absolute path\n let resourceIdSource: string;\n if (gitUrl) {\n resourceIdSource = normalizeGitUrl(gitUrl);\n } else if (mainRepoPath) {\n resourceIdSource = mainRepoPath;\n } else {\n resourceIdSource = rootPath;\n }\n\n // Create a readable but unique resource ID\n // Format: slugified-name-shorthash\n const baseName = gitUrl\n ? gitUrl\n .split('/')\n .pop()\n ?.replace(/\\.git$/, '') || 'project'\n : path.basename(rootPath);\n\n const resourceId = `${slugify(baseName)}-${shortHash(resourceIdSource)}`;\n\n return {\n resourceId,\n name: baseName,\n rootPath,\n gitUrl,\n gitBranch,\n isWorktree,\n mainRepoPath,\n };\n}\n\n/**\n * Get the current git branch for a given directory.\n * Lightweight alternative to detectProject() for refreshing just the branch.\n */\nexport function getCurrentGitBranch(cwd: string): string | undefined {\n return git('rev-parse --abbrev-ref HEAD', cwd);\n}\n\n/**\n * Get the application data directory for Ulicode.\n * - macOS: ~/Library/Application Support/ulicode\n * - Linux: ~/.local/share/ulicode\n * - Windows: %APPDATA%/ulicode\n *\n * Falls back to temporary uli-cli and legacy pulse/mastracode directories when they already exist.\n */\nexport function getAppDataDir(): string {\n const platform = os.platform();\n let baseDir: string;\n\n if (platform === 'darwin') {\n baseDir = path.join(os.homedir(), 'Library', 'Application Support');\n } else if (platform === 'win32') {\n baseDir = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');\n } else {\n // Linux and others - follow XDG spec\n baseDir = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n }\n\n const appDir = path.join(baseDir, 'ulicode');\n const legacyDirs = [path.join(baseDir, 'uli-cli'), path.join(baseDir, 'pulse'), path.join(baseDir, 'mastracode')];\n\n for (const legacyDir of legacyDirs) {\n if (!fs.existsSync(appDir) && fs.existsSync(legacyDir)) {\n return legacyDir;\n }\n }\n\n // Ensure directory exists\n if (!fs.existsSync(appDir)) {\n fs.mkdirSync(appDir, { recursive: true });\n }\n\n return appDir;\n}\n/**\n * Get the database path for Ulicode.\n * Can be overridden with the ULICODE_DB_PATH, temporary ULI_DB_PATH, legacy PULSE_DB_PATH, or legacy MASTRA_DB_PATH environment variables for debugging.\n */\nexport function getDatabasePath(): string {\n if (process.env.ULICODE_DB_PATH) {\n return process.env.ULICODE_DB_PATH;\n }\n if (process.env.ULI_DB_PATH) {\n return process.env.ULI_DB_PATH;\n }\n if (process.env.PULSE_DB_PATH) {\n return process.env.PULSE_DB_PATH;\n }\n if (process.env.MASTRA_DB_PATH) {\n return process.env.MASTRA_DB_PATH;\n }\n return path.join(getAppDataDir(), 'mastra.db');\n}\n\nimport type { StorageBackend, StorageSettings } from '../onboarding/settings.js';\n\n/**\n * LibSQL storage configuration.\n */\nexport interface LibSQLStorageConfig {\n backend: 'libsql';\n url: string;\n authToken?: string;\n isRemote: boolean;\n}\n\n/**\n * PostgreSQL storage configuration.\n */\nexport interface PgStorageConfig {\n backend: 'pg';\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n schemaName?: string;\n disableInit?: boolean;\n skipDefaultIndexes?: boolean;\n}\n\n/**\n * Resolved storage configuration for either backend.\n */\nexport type StorageConfig = LibSQLStorageConfig | PgStorageConfig;\n\n/**\n * Get the resolved storage configuration.\n *\n * Priority (highest to lowest):\n * 1. Environment variables: MASTRA_STORAGE_BACKEND + backend-specific vars\n * 2. Global settings (from /settings): settings.storage\n * 3. Legacy config files: .mastracode/database.json (LibSQL only)\n * 4. Local file database (LibSQL default)\n *\n * For PG, the env vars are:\n * MASTRA_STORAGE_BACKEND=pg\n * MASTRA_PG_CONNECTION_STRING or MASTRA_PG_HOST/PORT/DATABASE/USER/PASSWORD\n * MASTRA_PG_SCHEMA_NAME (optional)\n *\n * For LibSQL, the legacy env vars still work:\n * MASTRA_DB_URL + MASTRA_DB_AUTH_TOKEN\n */\nexport function getStorageConfig(projectDir?: string, storageSettings?: StorageSettings): StorageConfig {\n // 1. Environment variable — explicit backend selection\n const envBackend = process.env.MASTRA_STORAGE_BACKEND as StorageBackend | undefined;\n\n if (envBackend === 'pg') {\n return resolvePgFromEnv();\n }\n\n // Legacy LibSQL env vars (MASTRA_DB_URL) — treat as explicit libsql\n if (envBackend === 'libsql' || process.env.MASTRA_DB_URL) {\n return resolveLibSQLFromEnv();\n }\n\n // 2. Global settings (from /settings)\n if (storageSettings && storageSettings.backend === 'pg') {\n return resolvePgFromSettings(storageSettings);\n }\n\n if (storageSettings && storageSettings.backend === 'libsql' && storageSettings.libsql.url) {\n return {\n backend: 'libsql',\n url: storageSettings.libsql.url,\n authToken: storageSettings.libsql.authToken,\n isRemote: !storageSettings.libsql.url.startsWith('file:'),\n };\n }\n\n // 3. Legacy project/global config files (.mastracode/database.json)\n if (projectDir) {\n const projectConfig = loadDatabaseConfig(path.join(projectDir, '.mastracode', 'database.json'));\n if (projectConfig) return projectConfig;\n }\n const globalConfig = loadDatabaseConfig(path.join(os.homedir(), '.mastracode', 'database.json'));\n if (globalConfig) return globalConfig;\n\n // 4. Default: local LibSQL file database\n return {\n backend: 'libsql',\n url: `file:${getDatabasePath()}`,\n isRemote: false,\n };\n}\n\nfunction resolveLibSQLFromEnv(): LibSQLStorageConfig {\n const url = process.env.MASTRA_DB_URL!;\n return {\n backend: 'libsql',\n url,\n authToken: process.env.MASTRA_DB_AUTH_TOKEN,\n isRemote: !url.startsWith('file:'),\n };\n}\n\nfunction resolvePgFromEnv(): PgStorageConfig {\n const connectionString = process.env.MASTRA_PG_CONNECTION_STRING;\n if (connectionString) {\n return {\n backend: 'pg',\n connectionString,\n schemaName: process.env.MASTRA_PG_SCHEMA_NAME,\n };\n }\n\n // Host/port style\n return {\n backend: 'pg',\n host: process.env.MASTRA_PG_HOST,\n port: process.env.MASTRA_PG_PORT ? parseInt(process.env.MASTRA_PG_PORT, 10) : undefined,\n database: process.env.MASTRA_PG_DATABASE,\n user: process.env.MASTRA_PG_USER,\n password: process.env.MASTRA_PG_PASSWORD,\n schemaName: process.env.MASTRA_PG_SCHEMA_NAME,\n };\n}\n\nfunction resolvePgFromSettings(settings: StorageSettings): PgStorageConfig {\n const pg = settings.pg;\n return {\n backend: 'pg',\n connectionString: pg.connectionString,\n host: pg.host,\n port: pg.port,\n database: pg.database,\n user: pg.user,\n password: pg.password,\n schemaName: pg.schemaName,\n disableInit: pg.disableInit,\n skipDefaultIndexes: pg.skipDefaultIndexes,\n };\n}\n\n/**\n * Load database config from a legacy JSON file.\n * Expected format: { \"url\": \"libsql://...\", \"authToken\": \"...\" }\n */\nfunction loadDatabaseConfig(filePath: string): LibSQLStorageConfig | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (typeof parsed?.url === 'string' && parsed.url) {\n return {\n backend: 'libsql',\n url: parsed.url,\n authToken: typeof parsed.authToken === 'string' ? parsed.authToken : undefined,\n isRemote: !parsed.url.startsWith('file:'),\n };\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the current user identity.\n *\n * Priority:\n * 1. MASTRA_USER_ID environment variable\n * 2. git config user.email (from project dir or global)\n * 3. OS username as fallback\n */\nexport function getUserId(projectDir?: string): string {\n // 1. Environment variable override\n if (process.env.MASTRA_USER_ID) {\n return process.env.MASTRA_USER_ID;\n }\n\n // 2. git user.email\n const cwd = projectDir || process.cwd();\n const email = git('config user.email', cwd);\n if (email) {\n return email;\n }\n\n // 3. OS username fallback\n return os.userInfo().username || 'unknown';\n}\n\n/**\n * Observational memory scope: \"thread\" (per-conversation) or \"resource\" (shared across threads).\n */\nexport type OmScope = 'thread' | 'resource';\n\n/**\n * Get the configured observational memory scope.\n *\n * Priority:\n * 1. MASTRA_OM_SCOPE environment variable (\"thread\" or \"resource\")\n * 2. Project config: .mastracode/database.json → omScope\n * 3. Global config: ~/.mastracode/database.json → omScope\n * 4. Default: \"thread\"\n */\nexport function getOmScope(projectDir?: string): OmScope {\n // 1. Environment variable\n const envScope = process.env.MASTRA_OM_SCOPE;\n if (envScope === 'thread' || envScope === 'resource') {\n return envScope;\n }\n\n // 2. Project-level config\n if (projectDir) {\n const scope = loadOmScopeFromConfig(path.join(projectDir, '.mastracode', 'database.json'));\n if (scope) return scope;\n }\n\n // 3. Global config\n const scope = loadOmScopeFromConfig(path.join(os.homedir(), '.mastracode', 'database.json'));\n if (scope) return scope;\n\n // 4. Default\n return 'thread';\n}\n\nfunction loadOmScopeFromConfig(filePath: string): OmScope | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed?.omScope === 'thread' || parsed?.omScope === 'resource') {\n return parsed.omScope;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get an explicit resource ID override, if configured.\n *\n * Resource IDs act as shared tags — two users who set the same resourceId\n * will share threads and observations for that resource.\n *\n * Priority:\n * 1. MASTRA_RESOURCE_ID environment variable\n * 2. Project config: .mastracode/database.json → resourceId\n * 3. Global config: ~/.mastracode/database.json → resourceId\n * 4. null (use auto-detected value)\n */\nexport function getResourceIdOverride(projectDir?: string): string | null {\n // 1. Environment variable\n if (process.env.MASTRA_RESOURCE_ID) {\n return process.env.MASTRA_RESOURCE_ID;\n }\n\n // 2. Project-level config\n if (projectDir) {\n const rid = loadStringField(path.join(projectDir, '.mastracode', 'database.json'), 'resourceId');\n if (rid) return rid;\n }\n\n // 3. Global config\n const rid = loadStringField(path.join(os.homedir(), '.mastracode', 'database.json'), 'resourceId');\n if (rid) return rid;\n\n return null;\n}\n\nfunction loadStringField(filePath: string, field: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n const value = parsed?.[field];\n if (typeof value === 'string' && value) {\n return value;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * PKCE utilities using Web Crypto API.\n * Works in both Node.js 20+ and browsers.\n */\n\n/**\n * Encode bytes as base64url string.\n */\nfunction base64urlEncode(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Generate PKCE code verifier and challenge.\n * Uses Web Crypto API for cross-platform compatibility.\n */\nexport async function generatePKCE(): Promise<{\n verifier: string;\n challenge: string;\n}> {\n // Generate random verifier\n const verifierBytes = new Uint8Array(32);\n crypto.getRandomValues(verifierBytes);\n const verifier = base64urlEncode(verifierBytes);\n\n // Compute SHA-256 challenge\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const challenge = base64urlEncode(new Uint8Array(hashBuffer));\n\n return { verifier, challenge };\n}\n","/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts\n */\n\nimport { generatePKCE } from '../pkce.js';\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from '../types.js';\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode('OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl');\nconst AUTHORIZE_URL = 'https://claude.ai/oauth/authorize';\nconst TOKEN_URL = 'https://console.anthropic.com/v1/oauth/token';\nconst REDIRECT_URI = 'https://console.anthropic.com/oauth/code/callback';\nconst SCOPES = 'org:create_api_key user:profile user:inference';\n\n/**\n * Login with Anthropic OAuth (device code flow)\n */\nexport async function loginAnthropic(\n onAuthUrl: (url: string) => void,\n onPromptCode: () => Promise<string>,\n): Promise<OAuthCredentials> {\n const { verifier, challenge } = await generatePKCE();\n\n // Build authorization URL\n const authParams = new URLSearchParams({\n code: 'true',\n client_id: CLIENT_ID,\n response_type: 'code',\n redirect_uri: REDIRECT_URI,\n scope: SCOPES,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n state: verifier,\n });\n\n const authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`;\n\n // Notify caller with URL to open\n onAuthUrl(authUrl);\n\n // Wait for user to paste authorization code (format: code#state)\n const authCode = await onPromptCode();\n const splits = authCode.split('#');\n const code = splits[0];\n const state = splits[1];\n\n // Exchange code for tokens\n const tokenResponse = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code: code,\n state: state,\n redirect_uri: REDIRECT_URI,\n code_verifier: verifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const error = await tokenResponse.text();\n throw new Error(`Token exchange failed: ${error}`);\n }\n\n const tokenData = (await tokenResponse.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n // Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n const expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n return {\n refresh: tokenData.refresh_token,\n access: tokenData.access_token,\n expires: expiresAt,\n };\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'refresh_token',\n client_id: CLIENT_ID,\n refresh_token: refreshToken,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Anthropic token refresh failed: ${error}`);\n }\n\n const data = (await response.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n return {\n refresh: data.refresh_token,\n access: data.access_token,\n expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n };\n}\n\nexport const anthropicOAuthProvider: OAuthProviderInterface = {\n id: 'anthropic',\n name: 'Anthropic (Claude Pro/Max)',\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginAnthropic(\n url => callbacks.onAuth({ url }),\n () => callbacks.onPrompt({ message: 'Paste the authorization code:' }),\n );\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshAnthropicToken(credentials.refresh);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * OpenAI Codex (ChatGPT OAuth) flow\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/openai-codex.ts\n *\n * NOTE: This module uses Node.js crypto and http for the OAuth callback.\n * It is only intended for CLI use, not browser environments.\n */\n\n// NEVER convert to top-level imports - breaks browser/Vite builds (web-ui)\nlet _randomBytes: ((size: number) => Buffer) | null = null;\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet _http: typeof import('node:http') | null = null;\nif (typeof process !== 'undefined' && (process.versions?.node || process.versions?.bun)) {\n import('node:crypto').then(m => {\n _randomBytes = m.randomBytes;\n });\n import('node:http').then(m => {\n _http = m;\n });\n}\n\nimport { generatePKCE } from '../pkce.js';\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthPrompt, OAuthProviderInterface } from '../types.js';\n\nconst CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';\nconst AUTHORIZE_URL = 'https://auth.openai.com/oauth/authorize';\nconst TOKEN_URL = 'https://auth.openai.com/oauth/token';\nconst REDIRECT_URI = 'http://localhost:1455/auth/callback';\nconst SCOPE = 'openid profile email offline_access';\nconst JWT_CLAIM_PATH = 'https://api.openai.com/auth';\n\nconst SUCCESS_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Authentication successful</title>\n</head>\n<body>\n <p>Authentication successful. Return to your terminal to continue.</p>\n</body>\n</html>`;\n\ntype TokenSuccess = {\n type: 'success';\n access: string;\n refresh: string;\n expires: number;\n};\ntype TokenFailure = { type: 'failed' };\ntype TokenResult = TokenSuccess | TokenFailure;\n\ntype JwtPayload = {\n [JWT_CLAIM_PATH]?: {\n chatgpt_account_id?: string;\n };\n [key: string]: unknown;\n};\n\nfunction createState(): string {\n if (!_randomBytes) {\n throw new Error('OpenAI Codex OAuth is only available in Node.js environments');\n }\n return _randomBytes(16).toString('hex');\n}\n\nfunction parseAuthorizationInput(input: string): {\n code?: string;\n state?: string;\n} {\n const value = input.trim();\n if (!value) return {};\n\n try {\n const url = new URL(value);\n return {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n };\n } catch {\n // not a URL\n }\n\n if (value.includes('#')) {\n const [code, state] = value.split('#', 2);\n return { code, state };\n }\n\n if (value.includes('code=')) {\n const params = new URLSearchParams(value);\n return {\n code: params.get('code') ?? undefined,\n state: params.get('state') ?? undefined,\n };\n }\n\n return { code: value };\n}\n\nfunction decodeJwt(token: string): JwtPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n const payload = parts[1] ?? '';\n const decoded = atob(payload);\n return JSON.parse(decoded) as JwtPayload;\n } catch {\n return null;\n }\n}\n\nasync function exchangeAuthorizationCode(\n code: string,\n verifier: string,\n redirectUri: string = REDIRECT_URI,\n): Promise<TokenResult> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code,\n code_verifier: verifier,\n redirect_uri: redirectUri,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error('[openai-codex] code->token failed:', response.status, text);\n return { type: 'failed' };\n }\n\n const json = (await response.json()) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n\n if (!json.access_token || !json.refresh_token || typeof json.expires_in !== 'number') {\n console.error('[openai-codex] token response missing fields:', json);\n return { type: 'failed' };\n }\n\n return {\n type: 'success',\n access: json.access_token,\n refresh: json.refresh_token,\n expires: Date.now() + json.expires_in * 1000,\n };\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<TokenResult> {\n try {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: CLIENT_ID,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error('[openai-codex] Token refresh failed:', response.status, text);\n return { type: 'failed' };\n }\n\n const json = (await response.json()) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n\n if (!json.access_token || !json.refresh_token || typeof json.expires_in !== 'number') {\n console.error('[openai-codex] Token refresh response missing fields:', json);\n return { type: 'failed' };\n }\n\n return {\n type: 'success',\n access: json.access_token,\n refresh: json.refresh_token,\n expires: Date.now() + json.expires_in * 1000,\n };\n } catch (error) {\n console.error('[openai-codex] Token refresh error:', error);\n return { type: 'failed' };\n }\n}\n\nasync function createAuthorizationFlow(\n originator: string = 'pi',\n): Promise<{ verifier: string; state: string; url: string }> {\n const { verifier, challenge } = await generatePKCE();\n const state = createState();\n\n const url = new URL(AUTHORIZE_URL);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('client_id', CLIENT_ID);\n url.searchParams.set('redirect_uri', REDIRECT_URI);\n url.searchParams.set('scope', SCOPE);\n url.searchParams.set('code_challenge', challenge);\n url.searchParams.set('code_challenge_method', 'S256');\n url.searchParams.set('state', state);\n url.searchParams.set('id_token_add_organizations', 'true');\n url.searchParams.set('codex_cli_simplified_flow', 'true');\n url.searchParams.set('originator', originator);\n\n return { verifier, state, url: url.toString() };\n}\n\ntype OAuthServerInfo = {\n close: () => void;\n cancelWait: () => void;\n waitForCode: () => Promise<{ code: string } | null>;\n};\n\nfunction startLocalOAuthServer(state: string): Promise<OAuthServerInfo> {\n if (!_http) {\n throw new Error('OpenAI Codex OAuth is only available in Node.js environments');\n }\n let lastCode: string | null = null;\n let cancelled = false;\n const server = _http.createServer((req, res) => {\n try {\n const url = new URL(req.url || '', 'http://localhost');\n if (url.pathname !== '/auth/callback') {\n res.statusCode = 404;\n res.end('Not found');\n return;\n }\n if (url.searchParams.get('state') !== state) {\n res.statusCode = 400;\n res.end('State mismatch');\n return;\n }\n const code = url.searchParams.get('code');\n if (!code) {\n res.statusCode = 400;\n res.end('Missing authorization code');\n return;\n }\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(SUCCESS_HTML);\n lastCode = code;\n } catch {\n res.statusCode = 500;\n res.end('Internal error');\n }\n });\n\n return new Promise(resolve => {\n server\n .listen(1455, '127.0.0.1', () => {\n resolve({\n close: () => server.close(),\n cancelWait: () => {\n cancelled = true;\n },\n waitForCode: async () => {\n const sleep = () => new Promise(r => setTimeout(r, 100));\n for (let i = 0; i < 600; i += 1) {\n if (lastCode) return { code: lastCode };\n if (cancelled) return null;\n await sleep();\n }\n return null;\n },\n });\n })\n .on('error', (err: NodeJS.ErrnoException) => {\n console.error(\n '[openai-codex] Failed to bind http://127.0.0.1:1455 (',\n err.code,\n ') Falling back to manual paste.',\n );\n resolve({\n close: () => {\n try {\n server.close();\n } catch {\n // ignore\n }\n },\n cancelWait: () => {},\n waitForCode: async () => null,\n });\n });\n });\n}\n\nfunction getAccountId(accessToken: string): string | null {\n const payload = decodeJwt(accessToken);\n const auth = payload?.[JWT_CLAIM_PATH];\n const accountId = auth?.chatgpt_account_id;\n return typeof accountId === 'string' && accountId.length > 0 ? accountId : null;\n}\n\n/**\n * Login with OpenAI Codex OAuth\n *\n * @param options.onAuth - Called with URL and instructions when auth starts\n * @param options.onPrompt - Called to prompt user for manual code paste (fallback if no onManualCodeInput)\n * @param options.onProgress - Optional progress messages\n * @param options.onManualCodeInput - Optional promise that resolves with user-pasted code.\n * Races with browser callback - whichever completes first wins.\n * Useful for showing paste input immediately alongside browser flow.\n * @param options.originator - OAuth originator parameter (defaults to \"pi\")\n */\nexport async function loginOpenAICodex(options: {\n onAuth: (info: { url: string; instructions?: string }) => void;\n onPrompt: (prompt: OAuthPrompt) => Promise<string>;\n onProgress?: (message: string) => void;\n onManualCodeInput?: () => Promise<string>;\n originator?: string;\n}): Promise<OAuthCredentials> {\n const { verifier, state, url } = await createAuthorizationFlow(options.originator);\n const server = await startLocalOAuthServer(state);\n\n options.onAuth({\n url,\n instructions: 'A browser window should open. Complete login to finish.',\n });\n\n let code: string | undefined;\n try {\n if (options.onManualCodeInput) {\n // Race between browser callback and manual input\n let manualCode: string | undefined;\n let manualError: Error | undefined;\n const manualPromise = options\n .onManualCodeInput()\n .then(input => {\n manualCode = input;\n server.cancelWait();\n })\n .catch(err => {\n manualError = err instanceof Error ? err : new Error(String(err));\n server.cancelWait();\n });\n\n const result = await server.waitForCode();\n\n // If manual input was cancelled, throw that error\n if (manualError) {\n throw manualError;\n }\n\n if (result?.code) {\n // Browser callback won\n code = result.code;\n } else if (manualCode) {\n // Manual input won (or callback timed out and user had entered code)\n const parsed = parseAuthorizationInput(manualCode);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n\n // If still no code, wait for manual promise to complete and try that\n if (!code) {\n await manualPromise;\n if (manualError) {\n throw manualError;\n }\n if (manualCode) {\n const parsed = parseAuthorizationInput(manualCode);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n }\n } else {\n // Original flow: wait for callback, then prompt if needed\n const result = await server.waitForCode();\n if (result?.code) {\n code = result.code;\n }\n }\n\n // Fallback to onPrompt if still no code\n if (!code) {\n const input = await options.onPrompt({\n message: 'Paste the authorization code (or full redirect URL):',\n });\n const parsed = parseAuthorizationInput(input);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n\n if (!code) {\n throw new Error('Missing authorization code');\n }\n\n const tokenResult = await exchangeAuthorizationCode(code, verifier);\n if (tokenResult.type !== 'success') {\n throw new Error('Token exchange failed');\n }\n\n const accountId = getAccountId(tokenResult.access);\n if (!accountId) {\n throw new Error('Failed to extract accountId from token');\n }\n\n return {\n access: tokenResult.access,\n refresh: tokenResult.refresh,\n expires: tokenResult.expires,\n accountId,\n };\n } finally {\n server.close();\n }\n}\n\n/**\n * Refresh OpenAI Codex OAuth token\n */\nexport async function refreshOpenAICodexToken(refreshToken: string): Promise<OAuthCredentials> {\n const result = await refreshAccessToken(refreshToken);\n if (result.type !== 'success') {\n throw new Error('Failed to refresh OpenAI Codex token');\n }\n\n const accountId = getAccountId(result.access);\n if (!accountId) {\n throw new Error('Failed to extract accountId from token');\n }\n\n return {\n access: result.access,\n refresh: result.refresh,\n expires: result.expires,\n accountId,\n };\n}\n\nexport const openaiCodexOAuthProvider: OAuthProviderInterface = {\n id: 'openai-codex',\n name: 'ChatGPT Plus/Pro (Codex Subscription)',\n usesCallbackServer: true,\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginOpenAICodex({\n onAuth: callbacks.onAuth,\n onPrompt: callbacks.onPrompt,\n onProgress: callbacks.onProgress,\n onManualCodeInput: callbacks.onManualCodeInput,\n });\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshOpenAICodexToken(credentials.refresh);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { getAppDataDir } from '../utils/project.js';\nimport { anthropicOAuthProvider } from './providers/anthropic.js';\nimport { openaiCodexOAuthProvider } from './providers/openai-codex.js';\nimport type {\n AuthCredential,\n AuthStorageData,\n OAuthLoginCallbacks,\n OAuthProviderId,\n OAuthProviderInterface,\n} from './types.js';\n\n/**\n * Best/default models for each OAuth provider.\n * Used when auto-selecting a model after login.\n */\nexport const PROVIDER_DEFAULT_MODELS: Record<OAuthProviderId, string> = {\n anthropic: 'anthropic/claude-opus-4-6',\n 'openai-codex': 'openai/gpt-5.2-codex',\n google: 'google/gemini-2.5-flash',\n};\n\n// Provider registry\nconst oauthProviderRegistry = new Map<string, OAuthProviderInterface>([\n [anthropicOAuthProvider.id, anthropicOAuthProvider],\n [openaiCodexOAuthProvider.id, openaiCodexOAuthProvider],\n]);\n\n/**\n * Get an OAuth provider by ID\n */\nexport function getOAuthProvider(id: OAuthProviderId): OAuthProviderInterface | undefined {\n return oauthProviderRegistry.get(id);\n}\n\n/**\n * Get all registered OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInterface[] {\n return Array.from(oauthProviderRegistry.values());\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n private data: AuthStorageData = {};\n\n constructor(private authPath: string = join(getAppDataDir(), 'auth.json')) {\n this.reload();\n }\n\n /**\n * Reload credentials from disk.\n */\n reload(): void {\n if (!existsSync(this.authPath)) {\n this.data = {};\n return;\n }\n try {\n this.data = JSON.parse(readFileSync(this.authPath, 'utf-8'));\n } catch {\n this.data = {};\n }\n }\n\n /**\n * Save credentials to disk.\n */\n private save(): void {\n const dir = dirname(this.authPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), 'utf-8');\n chmodSync(this.authPath, 0o600);\n }\n\n /**\n * Get credential for a provider.\n */\n get(provider: string): AuthCredential | undefined {\n return this.data[provider] ?? undefined;\n }\n\n /**\n * Set credential for a provider.\n */\n set(provider: string, credential: AuthCredential): void {\n this.data[provider] = credential;\n this.save();\n }\n\n /**\n * Remove credential for a provider.\n */\n remove(provider: string): void {\n delete this.data[provider];\n this.save();\n }\n\n /**\n * List all providers with credentials.\n */\n list(): string[] {\n return Object.keys(this.data);\n }\n\n /**\n * Check if credentials exist for a provider.\n */\n has(provider: string): boolean {\n return provider in this.data;\n }\n\n /**\n * Check if logged in via OAuth for a provider.\n */\n isLoggedIn(provider: string): boolean {\n const cred = this.data[provider];\n return cred?.type === 'oauth';\n }\n\n /**\n * Login to an OAuth provider.\n */\n async login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n throw new Error(`Unknown OAuth provider: ${providerId}`);\n }\n\n const credentials = await provider.login(callbacks);\n this.set(providerId, { type: 'oauth', ...credentials });\n }\n\n /**\n * Logout from a provider.\n */\n logout(provider: string): void {\n this.remove(provider);\n }\n\n /**\n * Get API key for a provider, auto-refreshing OAuth tokens if needed.\n */\n async getApiKey(providerId: string): Promise<string | undefined> {\n const cred = this.data[providerId];\n\n if (cred?.type === 'api_key') {\n return cred.key;\n }\n\n if (cred?.type === 'oauth') {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n return undefined;\n }\n\n // Check if token needs refresh\n if (Date.now() >= cred.expires) {\n try {\n const newCreds = await provider.refreshToken(cred);\n this.set(providerId, { type: 'oauth', ...newCreds });\n return provider.getApiKey(newCreds);\n } catch {\n // Refresh failed - user needs to re-login\n return undefined;\n }\n }\n\n return provider.getApiKey(cred);\n }\n\n return undefined;\n }\n}\n"]}