codexuse-cli 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../lib/auto-roll-settings.ts","../../../lib/sqlite-db.ts","../../../lib/profile-manager.ts","../../../lib/codex-settings.ts","../../../lib/logger.ts","../../../lib/codex-cli-channel.ts","../../../lib/license-service.ts","../../../lib/license-secret.ts","../../../lib/license-guard.ts","../src/codex-cli.ts","../src/index.ts"],"sourcesContent":["export interface AutoRollSettings {\n enabled: boolean;\n warningThreshold: number;\n switchThreshold: number;\n}\n\nexport const DEFAULT_AUTO_ROLL_ENABLED = false;\nexport const DEFAULT_AUTO_ROLL_WARNING_THRESHOLD = 85;\nexport const DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD = 95;\nexport const AUTO_ROLL_WARNING_MIN = 50;\n\nfunction clampNumber(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/**\n * Normalize partial auto-roll settings into a safe shape with bounds.\n * Ensures switch threshold is always above warning and both live within [50, 100].\n */\nexport function normalizeAutoRollSettings(\n raw?: Partial<AutoRollSettings> | null,\n): AutoRollSettings {\n const enabled = typeof raw?.enabled === 'boolean' ? raw.enabled : DEFAULT_AUTO_ROLL_ENABLED;\n const rawWarning =\n typeof raw?.warningThreshold === 'number' && Number.isFinite(raw.warningThreshold)\n ? raw.warningThreshold\n : DEFAULT_AUTO_ROLL_WARNING_THRESHOLD;\n const rawSwitch =\n typeof raw?.switchThreshold === 'number' && Number.isFinite(raw.switchThreshold)\n ? raw.switchThreshold\n : DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD;\n\n // First clamp warning to valid range, then ensure switch is above it\n const normalizedWarning = clampNumber(rawWarning, AUTO_ROLL_WARNING_MIN, 99);\n const normalizedSwitch = clampNumber(rawSwitch, normalizedWarning + 1, 100);\n\n return {\n enabled,\n warningThreshold: normalizedWarning,\n switchThreshold: normalizedSwitch,\n };\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync, promises as fsPromises, statSync } from 'node:fs';\n\nimport path from 'node:path';\nimport { createRequire } from 'node:module';\nimport initSqlJs, {\n type Database as SqlJsDatabase,\n type Statement as SqlJsStatement,\n type SqlJsStatic,\n} from 'sql.js';\nimport {\n DEFAULT_AUTO_ROLL_ENABLED,\n DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD,\n DEFAULT_AUTO_ROLL_WARNING_THRESHOLD,\n} from './auto-roll-settings';\n\ninterface SqliteRunResult {\n changes: number;\n}\n\nexport interface SqliteStatement {\n get(...params: unknown[]): Record<string, unknown> | undefined;\n all(...params: unknown[]): Array<Record<string, unknown>>;\n run(...params: unknown[]): SqliteRunResult;\n}\n\nexport interface SqliteDatabase {\n readonly open: boolean;\n prepare(sql: string): SqliteStatement;\n close(): void;\n}\n\nconst require = createRequire(__filename);\nconst wasmDir = path.dirname(require.resolve('sql.js/dist/sql-wasm.wasm'));\nconst sqlModulePromise: Promise<SqlJsStatic> = initSqlJs({\n locateFile: (file: string) => path.join(wasmDir, file),\n});\n\nclass SqliteWasmDatabase implements SqliteDatabase {\n private closed = false;\n\n constructor(private readonly driver: SqlJsDatabase, private readonly dbPath: string) { }\n\n get open(): boolean {\n return !this.closed;\n }\n\n prepare(sql: string): SqliteStatement {\n this.assertOpen();\n return new SqliteWasmStatement(this, sql);\n }\n\n createStatement(sql: string): SqlJsStatement {\n this.assertOpen();\n return this.driver.prepare(sql);\n }\n\n exec(sql: string): void {\n this.assertOpen();\n this.driver.exec(sql);\n }\n\n getRowsModified(): number {\n this.assertOpen();\n return this.driver.getRowsModified();\n }\n\n private persistTimeout: NodeJS.Timeout | null = null;\n\n async persist(): Promise<void> {\n this.assertOpen();\n ensureStorageDirExists(this.dbPath);\n\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n }\n\n this.persistTimeout = setTimeout(async () => {\n try {\n const contents = Buffer.from(this.driver.export());\n await fsPromises.writeFile(this.dbPath, contents);\n this.persistTimeout = null;\n } catch (error) {\n console.error('Failed to persist database:', error);\n }\n }, 500);\n }\n\n close(): void {\n if (!this.closed) {\n // Synchronously flush any pending writes before closing\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n try {\n const contents = Buffer.from(this.driver.export());\n writeFileSync(this.dbPath, contents);\n } catch (error) {\n // Silently ignore ENOENT errors (directory already cleaned up, e.g., in tests)\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error('Failed to flush database on close:', error);\n }\n }\n }\n this.driver.close();\n this.closed = true;\n }\n }\n\n async flushPersistence(): Promise<void> {\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n try {\n const contents = Buffer.from(this.driver.export());\n await fsPromises.writeFile(this.dbPath, contents);\n } catch (error) {\n console.error('Failed to flush database persistence:', error);\n }\n }\n }\n\n private assertOpen(): void {\n if (!this.open) {\n throw new Error('SQLite database connection is closed.');\n }\n }\n}\n\nexport async function flushDatabase(): Promise<void> {\n if (globalCache.cachedDbPromise) {\n const db = await globalCache.cachedDbPromise;\n // We know it's SqliteWasmDatabase in this implementation\n if (db instanceof SqliteWasmDatabase) {\n await db.flushPersistence();\n }\n }\n}\n\nclass SqliteWasmStatement implements SqliteStatement {\n constructor(private readonly database: SqliteWasmDatabase, private readonly sql: string) { }\n\n get(...params: unknown[]): Record<string, unknown> | undefined {\n const statement = this.database.createStatement(this.sql);\n try {\n bindParameters(statement, params);\n if (!statement.step()) {\n return undefined;\n }\n return statement.getAsObject();\n } finally {\n statement.free();\n }\n }\n\n all(...params: unknown[]): Array<Record<string, unknown>> {\n const rows: Array<Record<string, unknown>> = [];\n const statement = this.database.createStatement(this.sql);\n try {\n bindParameters(statement, params);\n while (statement.step()) {\n rows.push(statement.getAsObject());\n }\n } finally {\n statement.free();\n }\n return rows;\n }\n\n run(...params: unknown[]): SqliteRunResult {\n const statement = this.database.createStatement(this.sql);\n try {\n bindParameters(statement, params);\n // Execute statement once; INSERT/UPDATE statements don't produce rows.\n statement.step();\n } finally {\n statement.free();\n }\n const changes = this.database.getRowsModified();\n void this.database.persist();\n return { changes };\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeNamedParameters(params: Record<string, unknown>): Record<string, unknown> {\n const normalized: Record<string, unknown> = {};\n for (const [key, rawValue] of Object.entries(params)) {\n if (key.startsWith('@') || key.startsWith(':') || key.startsWith('$')) {\n normalized[key] = rawValue;\n } else {\n normalized[`@${key}`] = rawValue;\n }\n }\n return normalized;\n}\n\nfunction bindParameters(statement: SqlJsStatement, args: unknown[]): void {\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && isPlainObject(args[0])) {\n statement.bind(normalizeNamedParameters(args[0]));\n return;\n }\n\n statement.bind(args as unknown[]);\n}\n\ntype SqliteCache = {\n cachedDbPath: string | null;\n cachedDbPromise: Promise<SqliteWasmDatabase> | null;\n};\n\nconst STORAGE_DIRECTORY_NAME = '.f86eb5e712267207';\nconst STORAGE_FILENAME = 'state-d64ce728d7a20214.sqlite';\n\nconst GLOBAL_CACHE_KEY = Symbol.for('codex.sqliteCache');\nconst globalCache: SqliteCache =\n (globalThis as Record<symbol, SqliteCache>)[GLOBAL_CACHE_KEY] ??\n ((globalThis as Record<symbol, SqliteCache>)[GLOBAL_CACHE_KEY] = {\n cachedDbPath: null,\n cachedDbPromise: null,\n });\n\nfunction resolveHomeDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE;\n if (!homeDir) {\n throw new Error('HOME directory is not set. Unable to initialize CodexUse storage.');\n }\n return homeDir;\n}\n\nfunction resolveStorageDirectory(): string {\n return path.join(resolveHomeDir(), STORAGE_DIRECTORY_NAME);\n}\n\nfunction resolveDbPath(): string {\n return path.join(resolveStorageDirectory(), STORAGE_FILENAME);\n}\n\nfunction ensureStorageDirExists(targetPath: string): void {\n mkdirSync(path.dirname(targetPath), { recursive: true });\n}\n\nasync function instantiateDatabase(dbPath: string): Promise<SqliteWasmDatabase> {\n try {\n const bakPath = `${dbPath}.bak`;\n if (existsSync(dbPath)) {\n const size = statSync(dbPath).size;\n if (size < 1024 && existsSync(bakPath)) {\n const bakSize = statSync(bakPath).size;\n if (bakSize > size) {\n const backup = readFileSync(bakPath);\n writeFileSync(dbPath, backup);\n console.warn(\"Detected near-empty SQLite file; restored from backup.\");\n }\n }\n }\n } catch (error) {\n console.warn(\"Failed to check/restore SQLite backup:\", error);\n }\n\n const SQL = await sqlModulePromise;\n let fileBuffer: Uint8Array | undefined;\n if (existsSync(dbPath)) {\n fileBuffer = new Uint8Array(readFileSync(dbPath));\n }\n const driver = fileBuffer ? new SQL.Database(fileBuffer) : new SQL.Database();\n const database = new SqliteWasmDatabase(driver, dbPath);\n database.exec('PRAGMA journal_mode = WAL;');\n database.exec('PRAGMA foreign_keys = ON;');\n runMigrations(database);\n database.persist();\n return database;\n}\n\nfunction readUserVersion(database: SqliteWasmDatabase): number {\n const result = database.prepare('PRAGMA user_version').get();\n const version = result?.user_version;\n return typeof version === 'number' ? version : 0;\n}\n\nfunction ensureChatTables(database: SqliteWasmDatabase): void {\n database.exec(`\n PRAGMA foreign_keys = ON;\n\n CREATE TABLE IF NOT EXISTS chat_threads (\n thread_key TEXT PRIMARY KEY,\n title TEXT,\n account_id TEXT,\n profile_name TEXT,\n project_label TEXT,\n project_path TEXT,\n source_path TEXT,\n started_at TEXT,\n ended_at TEXT,\n last_message_at TEXT,\n message_count INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS chat_messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n thread_key TEXT NOT NULL,\n role TEXT,\n content TEXT NOT NULL,\n account_id TEXT,\n profile_name TEXT,\n created_at TEXT,\n FOREIGN KEY(thread_key) REFERENCES chat_threads(thread_key) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_chat_messages_thread ON chat_messages(thread_key);\n CREATE INDEX IF NOT EXISTS idx_chat_messages_created ON chat_messages(created_at);\n\n CREATE TABLE IF NOT EXISTS chat_ingest_offsets (\n file_path TEXT PRIMARY KEY,\n offset INTEGER NOT NULL,\n mtime_ms INTEGER NOT NULL,\n size INTEGER NOT NULL\n );\n `);\n}\n\nfunction ensureSessionTables(database: SqliteWasmDatabase): void {\n database.exec(`\n PRAGMA foreign_keys = ON;\n\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n title TEXT,\n status TEXT,\n model TEXT,\n project_label TEXT,\n project_path TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n last_message_at TEXT\n );\n\n CREATE TABLE IF NOT EXISTS tool_panels (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n type TEXT NOT NULL,\n title TEXT,\n state TEXT,\n metadata TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY(session_id) REFERENCES sessions(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_tool_panels_session ON tool_panels(session_id);\n CREATE INDEX IF NOT EXISTS idx_tool_panels_type ON tool_panels(type);\n\n CREATE TABLE IF NOT EXISTS panel_outputs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n panel_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n type TEXT NOT NULL,\n data TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY(panel_id) REFERENCES tool_panels(id) ON DELETE CASCADE,\n FOREIGN KEY(session_id) REFERENCES sessions(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_panel_outputs_panel ON panel_outputs(panel_id);\n CREATE INDEX IF NOT EXISTS idx_panel_outputs_session ON panel_outputs(session_id);\n CREATE INDEX IF NOT EXISTS idx_panel_outputs_created ON panel_outputs(created_at);\n\n CREATE TABLE IF NOT EXISTS notes (\n id TEXT PRIMARY KEY,\n user_id TEXT,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n tags TEXT,\n is_favorited INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n synced_at TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_notes_user ON notes(user_id);\n CREATE INDEX IF NOT EXISTS idx_notes_updated ON notes(updated_at);\n `);\n}\n\nfunction ensureUsageTables(database: SqliteWasmDatabase): void {\n database.exec(`\n CREATE TABLE IF NOT EXISTS usage (\n session_id TEXT PRIMARY KEY,\n rollout_path TEXT NOT NULL,\n project_path TEXT,\n model TEXT,\n input_tokens INTEGER NOT NULL,\n cached_input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n reasoning_output_tokens INTEGER NOT NULL,\n total_tokens INTEGER NOT NULL,\n timestamp TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_usage_timestamp ON usage(timestamp);\n `);\n}\n\nfunction runMigrations(database: SqliteWasmDatabase): void {\n let userVersion = readUserVersion(database);\n\n if (userVersion < 1) {\n database.exec(`\n CREATE TABLE IF NOT EXISTS profiles (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n data TEXT NOT NULL,\n account_id TEXT,\n workspace_id TEXT,\n workspace_name TEXT,\n email TEXT,\n auth_method TEXT,\n created_at TEXT,\n updated_at TEXT\n );\n\n CREATE UNIQUE INDEX IF NOT EXISTS idx_profiles_account_workspace\n ON profiles(account_id, workspace_id)\n WHERE account_id IS NOT NULL;\n\n PRAGMA user_version = 1;\n `);\n userVersion = 1;\n }\n\n if (userVersion < 2) {\n database.exec(`PRAGMA user_version = 2;`);\n userVersion = 2;\n }\n\n if (userVersion < 3) {\n database.exec(`PRAGMA user_version = 3;`);\n userVersion = 3;\n }\n\n if (userVersion < 4) {\n let legacySettings: Record<string, unknown> | null = null;\n\n try {\n const hasKvStore = Boolean(\n database.prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'kv_store'\",\n ).get() as { name?: string } | undefined,\n );\n if (hasKvStore) {\n const row = database\n .prepare(\"SELECT value FROM kv_store WHERE key = 'settings'\")\n .get() as { value?: string } | undefined;\n if (row?.value) {\n const parsed = JSON.parse(row.value) as Record<string, unknown>;\n if (parsed && typeof parsed === 'object') {\n legacySettings = parsed;\n }\n }\n }\n } catch (error) {\n console.warn(\"Failed to read legacy Codex settings:\", error);\n }\n\n database.exec(`\n PRAGMA foreign_keys = OFF;\n\n DROP TABLE IF EXISTS rate_limit_snapshots;\n DROP TABLE IF EXISTS chat_messages;\n DROP TABLE IF EXISTS chat_threads;\n DROP TABLE IF EXISTS kv_store;\n\n CREATE TABLE IF NOT EXISTS app_settings (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n last_profile_name TEXT,\n license_key TEXT,\n purchase_email TEXT,\n last_verified_at TEXT,\n next_check_at TEXT,\n last_verification_error TEXT,\n status TEXT\n );\n\n INSERT OR IGNORE INTO app_settings (id) VALUES (1);\n\n PRAGMA foreign_keys = ON;\n `);\n\n if (legacySettings) {\n const license = legacySettings.license as Record<string, unknown> | undefined;\n database.prepare(\n `UPDATE app_settings\n SET last_profile_name = @lastProfileName,\n license_key = @licenseKey,\n purchase_email = @purchaseEmail,\n last_verified_at = @lastVerifiedAt,\n next_check_at = @nextCheckAt,\n last_verification_error = @lastVerificationError,\n status = @status\n WHERE id = 1`,\n ).run({\n lastProfileName: typeof legacySettings.lastProfileName === 'string'\n ? legacySettings.lastProfileName\n : null,\n licenseKey: license && typeof license.licenseKey === 'string' ? license.licenseKey : null,\n purchaseEmail: license && typeof license.purchaseEmail === 'string' ? license.purchaseEmail : null,\n lastVerifiedAt: license && typeof license.lastVerifiedAt === 'string' ? license.lastVerifiedAt : null,\n nextCheckAt: license && typeof license.nextCheckAt === 'string' ? license.nextCheckAt : null,\n lastVerificationError:\n license && typeof license.lastVerificationError === 'string'\n ? license.lastVerificationError\n : null,\n status: license && typeof license.status === 'string' ? license.status : null,\n });\n }\n\n database.exec(`PRAGMA user_version = 4;`);\n userVersion = 4;\n }\n\n if (userVersion < 5) {\n database.exec(`\n ALTER TABLE app_settings ADD COLUMN auto_roll_enabled INTEGER;\n ALTER TABLE app_settings ADD COLUMN auto_roll_warning_threshold INTEGER;\n ALTER TABLE app_settings ADD COLUMN auto_roll_switch_threshold INTEGER;\n\n PRAGMA user_version = 5;\n `);\n userVersion = 5;\n }\n\n if (userVersion < 6) {\n database.exec(`\n CREATE TABLE IF NOT EXISTS app_kv (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n\n let appSettingsRow: Record<string, unknown> | null = null;\n try {\n const hasAppSettings = Boolean(\n database.prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'app_settings'\",\n ).get() as { name?: string } | undefined,\n );\n if (hasAppSettings) {\n appSettingsRow = database\n .prepare(\n `SELECT last_profile_name, license_key, purchase_email,\n last_verified_at, next_check_at, last_verification_error, status,\n auto_roll_enabled, auto_roll_warning_threshold, auto_roll_switch_threshold\n FROM app_settings\n WHERE id = 1`,\n )\n .get() as Record<string, unknown> | null;\n }\n } catch (error) {\n console.warn(\"Failed to read legacy app_settings row:\", error);\n }\n\n try {\n const upsertKv = database.prepare(\"INSERT OR REPLACE INTO app_kv (key, value) VALUES (@key, @value)\");\n\n if (appSettingsRow) {\n const lastProfile = typeof appSettingsRow.last_profile_name === 'string'\n ? appSettingsRow.last_profile_name.trim()\n : '';\n if (lastProfile) {\n upsertKv.run({ key: 'last_profile_name', value: JSON.stringify(lastProfile) });\n }\n\n const license = {\n licenseKey: typeof appSettingsRow.license_key === 'string' ? appSettingsRow.license_key : null,\n purchaseEmail: typeof appSettingsRow.purchase_email === 'string' ? appSettingsRow.purchase_email : null,\n lastVerifiedAt: typeof appSettingsRow.last_verified_at === 'string' ? appSettingsRow.last_verified_at : null,\n nextCheckAt: typeof appSettingsRow.next_check_at === 'string' ? appSettingsRow.next_check_at : null,\n lastVerificationError:\n typeof appSettingsRow.last_verification_error === 'string'\n ? appSettingsRow.last_verification_error\n : null,\n status: typeof appSettingsRow.status === 'string' ? appSettingsRow.status : null,\n };\n const hasLicenseData = Boolean(\n license.licenseKey ??\n license.purchaseEmail ??\n license.lastVerifiedAt ??\n license.nextCheckAt ??\n license.lastVerificationError ??\n license.status,\n );\n if (hasLicenseData) {\n upsertKv.run({ key: 'license', value: JSON.stringify(license) });\n }\n\n const hasAutoRollData =\n typeof appSettingsRow.auto_roll_enabled === 'number' ||\n typeof appSettingsRow.auto_roll_warning_threshold === 'number' ||\n typeof appSettingsRow.auto_roll_switch_threshold === 'number';\n if (hasAutoRollData) {\n const warning =\n typeof appSettingsRow.auto_roll_warning_threshold === 'number'\n ? appSettingsRow.auto_roll_warning_threshold\n : DEFAULT_AUTO_ROLL_WARNING_THRESHOLD;\n const switchThreshold =\n typeof appSettingsRow.auto_roll_switch_threshold === 'number'\n ? appSettingsRow.auto_roll_switch_threshold\n : DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD;\n const autoRoll = {\n enabled: Boolean(appSettingsRow.auto_roll_enabled ?? DEFAULT_AUTO_ROLL_ENABLED),\n warningThreshold: warning,\n switchThreshold,\n };\n upsertKv.run({ key: 'auto_roll', value: JSON.stringify(autoRoll) });\n }\n }\n\n try {\n database.exec(\"DROP TABLE IF EXISTS app_settings;\");\n } catch (error) {\n console.warn(\"Failed to drop legacy app_settings table:\", error);\n }\n } catch (error) {\n console.warn(\"Failed to migrate app_settings to app_kv:\", error);\n }\n\n database.exec(`PRAGMA user_version = 6;`);\n userVersion = 6;\n }\n\n if (userVersion < 7) {\n try {\n const columns = database\n .prepare(\"PRAGMA table_info(profiles)\")\n .all() as Array<{ name?: string }> | undefined;\n const hasWorkspaceId = Boolean(columns?.some(column => column.name === 'workspace_id'));\n const hasWorkspaceName = Boolean(columns?.some(column => column.name === 'workspace_name'));\n\n if (!hasWorkspaceId) {\n database.exec(`ALTER TABLE profiles ADD COLUMN workspace_id TEXT;`);\n }\n if (!hasWorkspaceName) {\n database.exec(`ALTER TABLE profiles ADD COLUMN workspace_name TEXT;`);\n }\n } catch (error) {\n console.warn('Failed to add workspace columns during migration:', error);\n }\n\n database.exec(`\n DROP INDEX IF EXISTS idx_profiles_account;\n DROP INDEX IF EXISTS idx_profiles_account_workspace;\n\n CREATE UNIQUE INDEX IF NOT EXISTS idx_profiles_account_workspace\n ON profiles(account_id, workspace_id)\n WHERE account_id IS NOT NULL;\n `);\n\n try {\n const rows = database\n .prepare('SELECT name, workspace_id FROM profiles')\n .all() as Array<{ name?: string; workspace_id?: string }>;\n const update = database.prepare(\n 'UPDATE profiles SET workspace_id = @workspaceId WHERE name = @name AND (workspace_id IS NULL OR workspace_id = \\'\\')',\n );\n for (const row of rows) {\n const name = typeof row.name === 'string' ? row.name : null;\n if (!name) {\n continue;\n }\n const existingWorkspace = typeof row.workspace_id === 'string' ? row.workspace_id.trim() : '';\n if (existingWorkspace) {\n continue;\n }\n update.run({ name, workspaceId: '__default__' });\n }\n } catch (error) {\n console.warn('Failed to backfill workspace_id during migration:', error);\n }\n\n database.exec(`PRAGMA user_version = 7;`);\n userVersion = 7;\n }\n\n if (userVersion < 8) {\n ensureChatTables(database);\n database.exec(`PRAGMA user_version = 8;`);\n userVersion = 8;\n }\n\n if (userVersion < 9) {\n ensureSessionTables(database);\n database.exec(`PRAGMA user_version = 9;`);\n userVersion = 9;\n }\n\n if (userVersion < 10) {\n ensureUsageTables(database);\n database.exec(`PRAGMA user_version = 10;`);\n userVersion = 10;\n }\n\n if (userVersion < 11) {\n try {\n database.exec(`ALTER TABLE usage ADD COLUMN model TEXT;`);\n } catch {\n // ignore if column already exists\n }\n database.exec(`PRAGMA user_version = 11;`);\n userVersion = 11;\n }\n\n // Make sure foreign keys are restored if a migration temporarily disabled them.\n try {\n database.exec('PRAGMA foreign_keys = ON;');\n } catch {\n // best-effort; errors are logged elsewhere\n }\n\n // Idempotent guard: make sure chat tables exist even if user_version was already bumped.\n ensureChatTables(database);\n ensureSessionTables(database);\n ensureUsageTables(database);\n}\n\nexport async function getDatabase(): Promise<SqliteDatabase> {\n const dbPath = resolveDbPath();\n\n if (!globalCache.cachedDbPromise || globalCache.cachedDbPath !== dbPath) {\n if (globalCache.cachedDbPromise) {\n try {\n const previous = await globalCache.cachedDbPromise;\n previous.close();\n } catch {\n // ignore errors closing old database\n }\n }\n globalCache.cachedDbPath = dbPath;\n globalCache.cachedDbPromise = instantiateDatabase(dbPath);\n }\n\n const db = await globalCache.cachedDbPromise;\n try {\n // Ensure migrations run even if the database was opened before this version of the app.\n runMigrations(db as SqliteWasmDatabase);\n } catch (error) {\n console.warn(\"Failed to ensure migrations:\", error);\n }\n return db;\n}\n\nexport async function resetDatabaseConnection(): Promise<void> {\n if (globalCache.cachedDbPromise) {\n try {\n const db = await globalCache.cachedDbPromise;\n db.close();\n } catch {\n // ignore failures during reset\n }\n }\n globalCache.cachedDbPromise = null;\n globalCache.cachedDbPath = null;\n}\n\n/**\n * @internal - exposed for tests to assert the resolved database paths.\n */\nexport function __debugResolveDbPath(): string {\n return resolveDbPath();\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { join } from 'path';\nimport { parse, stringify } from '@iarna/toml';\nimport {\n Profile,\n ProfileData,\n ActiveAuth,\n ProfileMetadata,\n OrganizationInfo,\n SubscriptionInfo,\n TokenAlert,\n TokenIssue,\n TokenStatus,\n} from './types';\nimport { getLastProfileName, persistLastProfileName } from './codex-settings';\nimport { logError, logWarn } from './logger';\n\nconst TOKEN_EXPIRING_SOON_WINDOW_MS = 15 * 60 * 1000;\nexport const REFRESH_TOKEN_REDEEMED_SNIPPET = 'refresh token was already used';\nexport const REFRESH_TOKEN_REDEEMED_REASON =\n 'Your access token could not be refreshed because your refresh token was already used. Please log out and sign in again.';\nconst AUTH_BACKUP_MISSING_MARKER = '__codexuse_missing_auth__';\nconst DEFAULT_WORKSPACE_ID = '__default__';\nconst PROFILE_RECORD_FILENAME = 'profile.json';\n\nexport function detectRefreshTokenRedeemedMessage(output: string | Buffer | null | undefined): string | null {\n if (!output) {\n return null;\n }\n\n const text = output.toString();\n if (!text) {\n return null;\n }\n\n const normalized = text\n .toLowerCase()\n .replace(/\\s+/g, ' ');\n if (!normalized.includes(REFRESH_TOKEN_REDEEMED_SNIPPET)) {\n return null;\n }\n\n const trimmed = text.trim();\n return trimmed.length > 0 ? trimmed : REFRESH_TOKEN_REDEEMED_REASON;\n}\n\ntype ProfileRecord = {\n name: string;\n displayName: string | null;\n data: ProfileData;\n metadata?: ProfileMetadata;\n accountId: string | null;\n workspaceId: string | null;\n workspaceName: string | null;\n email: string | null;\n authMethod: string | null;\n createdAt: string | null;\n updatedAt: string | null;\n};\n\ntype DbProfileRow = {\n name?: string | null;\n data?: string | null;\n account_id?: string | null;\n workspace_id?: string | null;\n workspace_name?: string | null;\n email?: string | null;\n auth_method?: string | null;\n created_at?: string | null;\n updated_at?: string | null;\n};\n\nexport class ProfileManager {\n private codexDir: string;\n private profilesDir: string;\n private profileHomesRoot: string;\n private migrationsDir: string;\n private profileMigrationMarker: string;\n private activeAuth: string;\n private activeAuthBackup: string;\n private lastActiveAuthErrorSignature: string | null;\n private authSwapLock: Promise<void>;\n constructor() {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n this.codexDir = join(homeDir, '.codex');\n this.profilesDir = join(this.codexDir, 'profiles');\n this.profileHomesRoot = join(this.codexDir, 'profile-homes');\n this.migrationsDir = join(this.codexDir, 'migrations');\n this.profileMigrationMarker = join(this.migrationsDir, 'profiles-v1');\n this.activeAuth = join(this.codexDir, 'auth.json');\n this.activeAuthBackup = `${this.activeAuth}.swap`;\n this.lastActiveAuthErrorSignature = null;\n this.authSwapLock = Promise.resolve();\n }\n\n private computeExpiryIso(data: ProfileData | null | undefined): string | undefined {\n if (!data) {\n return undefined;\n }\n if (typeof data.expired === 'string' && data.expired.trim()) {\n const parsed = Date.parse(data.expired);\n if (!Number.isNaN(parsed)) {\n return new Date(parsed).toISOString();\n }\n }\n const expiresIn = typeof data.expires_in === 'number' && Number.isFinite(data.expires_in)\n ? data.expires_in\n : undefined;\n const issuedMs =\n typeof data.timestamp === 'number' && Number.isFinite(data.timestamp)\n ? data.timestamp\n : undefined;\n const issuedAt = issuedMs ? issuedMs : undefined;\n const baseMs = issuedAt ?? Date.now();\n if (expiresIn && expiresIn > 0) {\n return new Date(baseMs + expiresIn * 1000).toISOString();\n }\n return undefined;\n }\n\n private normalizeProfileName(name: string): string {\n if (typeof name !== 'string') {\n throw new Error('Profile name is required');\n }\n\n const trimmed = name.trim();\n if (!trimmed) {\n throw new Error('Profile name must not be empty.');\n }\n\n if (trimmed === '.' || trimmed === '..') {\n throw new Error(`Profile name '${name}' is not allowed.`);\n }\n\n if (/[\\\\/]/.test(trimmed)) {\n throw new Error(\"Profile name cannot contain path separators.\");\n }\n\n if (trimmed.includes('\\0')) {\n throw new Error('Profile name contains invalid characters.');\n }\n\n return trimmed;\n }\n\n private isNotFoundError(error: unknown): boolean {\n return Boolean(\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error as NodeJS.ErrnoException).code === 'ENOENT',\n );\n }\n\n private async readPreferredProfileName(): Promise<string | null> {\n try {\n return await getLastProfileName();\n } catch (error) {\n logWarn('Failed to read preferred profile name:', error);\n return null;\n }\n }\n\n private async persistPreferredProfileName(name: string | null): Promise<void> {\n try {\n await persistLastProfileName(name);\n } catch (error) {\n logWarn('Failed to persist preferred profile name:', error);\n }\n }\n\n private getProfileRecordPath(profileName: string): string {\n return join(this.getProfileHomePath(profileName), PROFILE_RECORD_FILENAME);\n }\n\n private parseProfileRecordPayload(profileName: string, parsed: Record<string, unknown>): ProfileRecord | null {\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n\n const dataRaw = parsed['data'];\n let data: ProfileData | null = null;\n if (dataRaw && typeof dataRaw === 'object') {\n data = dataRaw as ProfileData;\n } else if (typeof dataRaw === 'string') {\n try {\n data = JSON.parse(dataRaw) as ProfileData;\n } catch (error) {\n logWarn(`Failed to parse data payload for profile '${profileName}':`, error);\n return null;\n }\n } else {\n return null;\n }\n const createdAt =\n typeof parsed['createdAt'] === 'string'\n ? parsed['createdAt'] as string\n : typeof parsed['created_at'] === 'string'\n ? parsed['created_at'] as string\n : null;\n const updatedAt =\n typeof parsed['updatedAt'] === 'string'\n ? parsed['updatedAt'] as string\n : typeof parsed['updated_at'] === 'string'\n ? parsed['updated_at'] as string\n : null;\n\n const metadata =\n parsed['metadata'] && typeof parsed['metadata'] === 'object'\n ? parsed['metadata'] as ProfileMetadata\n : undefined;\n\n const displayName =\n typeof parsed['displayName'] === 'string'\n ? parsed['displayName'] as string\n : typeof parsed['display_name'] === 'string'\n ? parsed['display_name'] as string\n : null;\n\n return {\n name: profileName,\n displayName,\n data,\n metadata,\n accountId:\n typeof parsed['accountId'] === 'string'\n ? parsed['accountId']\n : typeof parsed['account_id'] === 'string'\n ? parsed['account_id']\n : null,\n workspaceId:\n typeof parsed['workspaceId'] === 'string'\n ? parsed['workspaceId']\n : typeof parsed['workspace_id'] === 'string'\n ? parsed['workspace_id']\n : null,\n workspaceName:\n typeof parsed['workspaceName'] === 'string'\n ? parsed['workspaceName']\n : typeof parsed['workspace_name'] === 'string'\n ? parsed['workspace_name']\n : null,\n email:\n typeof parsed['email'] === 'string'\n ? parsed['email']\n : typeof parsed['email'] === 'boolean'\n ? null\n : null,\n authMethod:\n typeof parsed['authMethod'] === 'string'\n ? parsed['authMethod']\n : typeof parsed['auth_method'] === 'string'\n ? parsed['auth_method']\n : null,\n createdAt,\n updatedAt,\n };\n }\n\n private decodeProfileRecord(profileName: string, raw: string, sourceLabel: string): ProfileRecord | null {\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n return this.parseProfileRecordPayload(profileName, parsed);\n } catch (error) {\n logWarn(`Failed to parse profile record '${profileName}' from '${sourceLabel}':`, error);\n return null;\n }\n }\n\n private async recoverProfileRecord(recordPath: string, profileName: string): Promise<ProfileRecord | null> {\n const candidates = [`${recordPath}.bak`, `${recordPath}.tmp`];\n\n for (const candidate of candidates) {\n let raw: string;\n try {\n raw = await fs.readFile(candidate, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read backup for '${profileName}' from '${candidate}':`, error);\n }\n continue;\n }\n\n const decoded = this.decodeProfileRecord(profileName, raw, candidate);\n if (!decoded) {\n continue;\n }\n\n try {\n await this.writeProfileRecord(decoded);\n } catch (error) {\n logWarn(`Failed to restore profile '${profileName}' from '${candidate}':`, error);\n }\n return decoded;\n }\n\n return null;\n }\n\n private async readProfileRecord(profileName: string): Promise<ProfileRecord | null> {\n const recordPath = this.getProfileRecordPath(profileName);\n try {\n const raw = await fs.readFile(recordPath, 'utf8');\n const decoded = this.decodeProfileRecord(profileName, raw, recordPath);\n if (decoded) {\n return decoded;\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read profile record '${profileName}':`, error);\n }\n }\n\n return this.recoverProfileRecord(recordPath, profileName);\n }\n\n private async listProfileRecords(): Promise<ProfileRecord[]> {\n const records: ProfileRecord[] = [];\n let entries: Array<string> = [];\n try {\n entries = await fs.readdir(this.profileHomesRoot);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to list profile homes:', error);\n }\n return records;\n }\n\n for (const entry of entries) {\n const homePath = join(this.profileHomesRoot, entry);\n try {\n const stat = await fs.stat(homePath);\n if (!stat.isDirectory()) {\n continue;\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to inspect profile home '${entry}':`, error);\n }\n continue;\n }\n\n try {\n const normalizedName = this.normalizeProfileName(entry);\n const record = await this.readProfileRecord(normalizedName);\n if (record) {\n records.push(record);\n continue;\n }\n\n // Best-effort recovery for homes missing profile.json by rehydrating from auth.json.\n const authPath = join(homePath, 'auth.json');\n try {\n const authRaw = await fs.readFile(authPath, 'utf8');\n const authData = JSON.parse(authRaw) as ActiveAuth;\n const normalized = this.normalizeProfileData(authData);\n const metadata = this.extractProfileMetadata(normalized);\n await this.persistProfileRecord(normalizedName, normalized, metadata);\n const restored = await this.readProfileRecord(normalizedName);\n if (restored) {\n records.push(restored);\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to restore profile record for '${normalizedName}' from auth.json:`, error);\n }\n }\n } catch (error) {\n logWarn(`Skipping invalid profile home '${entry}':`, error);\n }\n }\n\n return records;\n }\n\n private async snapshotExistingProfileRecord(recordPath: string): Promise<void> {\n try {\n const existing = await fs.readFile(recordPath, 'utf8');\n if (existing && existing.trim()) {\n await this.writeAtomic(`${recordPath}.bak`, existing);\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to snapshot existing profile record '${recordPath}':`, error);\n }\n }\n }\n\n private async writeProfileRecord(record: ProfileRecord): Promise<void> {\n const recordPath = this.getProfileRecordPath(record.name);\n const payload = {\n name: record.name,\n display_name: record.displayName,\n data: record.data,\n metadata: record.metadata,\n account_id: record.accountId,\n workspace_id: record.workspaceId,\n workspace_name: record.workspaceName,\n email: record.email,\n auth_method: record.authMethod,\n created_at: record.createdAt,\n updated_at: record.updatedAt,\n };\n const serialized = `${JSON.stringify(payload, null, 2)}\\n`;\n await this.snapshotExistingProfileRecord(recordPath);\n await this.writeAtomic(recordPath, serialized);\n try {\n await this.writeAtomic(`${recordPath}.bak`, serialized);\n } catch (error) {\n logWarn(`Failed to persist profile backup for '${record.name}':`, error);\n }\n }\n\n private resolveAuthMethod(data: ProfileData | null | undefined): string {\n const raw = typeof data?.auth_method === 'string' ? data.auth_method.trim().toLowerCase() : '';\n return raw || 'codex-cli';\n }\n\n private async readActiveAuthFile(): Promise<ActiveAuth | null> {\n try {\n const raw = await fs.readFile(this.activeAuth, 'utf8');\n const trimmed = raw.trim();\n if (!trimmed) {\n return null;\n }\n return JSON.parse(trimmed) as ActiveAuth;\n } catch (error) {\n if (this.isNotFoundError(error)) {\n return null;\n }\n const message = error instanceof Error ? error.message : 'unknown error';\n const signature = typeof message === 'string' ? `${message}:${this.activeAuth}` : this.activeAuth;\n if (this.lastActiveAuthErrorSignature !== signature) {\n logWarn('Failed to read active auth file:', error);\n this.lastActiveAuthErrorSignature = signature;\n }\n return null;\n }\n }\n\n private async getActiveAuthAccountId(): Promise<string | undefined> {\n const activeAuth = await this.readActiveAuthFile();\n if (!activeAuth) {\n return undefined;\n }\n return this.getAccountIdFromData(activeAuth);\n }\n\n /**\n * Decode a JWT payload into an object without validating the signature.\n */\n private decodeJwtPayload(token?: string | null): Record<string, unknown> | null {\n if (!token || typeof token !== 'string') {\n return null;\n }\n\n const segments = token.split('.');\n if (segments.length < 2) {\n return null;\n }\n\n try {\n const payload = Buffer.from(segments[1], 'base64url').toString('utf8');\n return JSON.parse(payload);\n } catch {\n return null;\n }\n }\n\n private toIsoStringFromSeconds(seconds?: number): string | undefined {\n if (typeof seconds !== 'number' || Number.isNaN(seconds)) {\n return undefined;\n }\n\n try {\n return new Date(seconds * 1000).toISOString();\n } catch {\n return undefined;\n }\n }\n\n private normalizeEmailCandidate(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (!trimmed || trimmed.includes(' ')) {\n return undefined;\n }\n\n const atIndex = trimmed.indexOf('@');\n if (atIndex <= 0 || atIndex === trimmed.length - 1) {\n return undefined;\n }\n\n const domain = trimmed.slice(atIndex + 1);\n if (!domain || !domain.includes('.')) {\n return undefined;\n }\n\n return trimmed;\n }\n\n private pickFirstEmail(candidates: Array<string | undefined>): string | undefined {\n for (const candidate of candidates) {\n const normalized = this.normalizeEmailCandidate(candidate);\n if (normalized) {\n return normalized;\n }\n }\n return undefined;\n }\n\n private findEmailInObject(value: unknown, seen = new Set<unknown>()): string | undefined {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n\n if (seen.has(value)) {\n return undefined;\n }\n seen.add(value);\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n const nested = this.findEmailInObject(entry, seen);\n if (nested) {\n return nested;\n }\n }\n return undefined;\n }\n\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n if (typeof entry === 'string') {\n const normalized = this.normalizeEmailCandidate(entry);\n const lowerKey = key.toLowerCase();\n const keyHintsAtEmail =\n lowerKey.includes('email') ||\n lowerKey.includes('contact') ||\n lowerKey.includes('username') ||\n lowerKey.includes('login');\n\n if (normalized && (keyHintsAtEmail || entry.includes('@'))) {\n return normalized;\n }\n }\n\n if (entry && typeof entry === 'object') {\n const nested = this.findEmailInObject(entry, seen);\n if (nested) {\n return nested;\n }\n }\n }\n\n return undefined;\n }\n\n private resolveProfileEmail(data: ProfileData, metadata?: ProfileMetadata): string | undefined {\n const direct = this.normalizeEmailCandidate(data.email);\n if (direct) {\n return direct;\n }\n\n if (metadata?.email) {\n return metadata.email;\n }\n\n return this.findEmailInObject(data);\n }\n\n private evaluateTokenStatus(data: ProfileData, metadata?: ProfileMetadata): TokenStatus {\n const expiresAt = metadata?.tokenExpiresAt ?? this.computeExpiryIso(data);\n const parsedExpiry = expiresAt ? Date.parse(expiresAt) : Number.NaN;\n const hasExpiry = !Number.isNaN(parsedExpiry);\n const tokenAlert = data.tokenAlert;\n\n if (!data || typeof data !== 'object' || Object.keys(data).length === 0) {\n return {\n state: 'missing',\n reason: 'No authentication data saved for this profile.',\n expiresAt,\n issue: 'auth-missing',\n requiresUserAction: true,\n };\n }\n\n if (tokenAlert?.issue) {\n const reason = typeof tokenAlert.reason === 'string' && tokenAlert.reason.trim().length > 0\n ? tokenAlert.reason.trim()\n : tokenAlert.issue === 'refresh-redeemed'\n ? REFRESH_TOKEN_REDEEMED_REASON\n : 'Authentication needs attention. Re-login this profile.';\n const issue = (tokenAlert.issue as TokenIssue) ?? 'auth-missing';\n return {\n state: 'invalid',\n reason,\n expiresAt,\n issue,\n requiresUserAction: true,\n };\n }\n\n if (!data.access_token) {\n return {\n state: 'missing',\n reason: 'Access token is missing. Re-authenticate with Codex CLI.',\n expiresAt,\n issue: 'access-missing',\n requiresUserAction: true,\n };\n }\n\n if (!this.decodeJwtPayload(data.access_token)) {\n return {\n state: 'invalid',\n reason: 'Access token is corrupted or not a valid JWT.',\n expiresAt,\n issue: 'access-invalid',\n requiresUserAction: true,\n };\n }\n\n const refreshToken = typeof data.refresh_token === 'string' ? data.refresh_token.trim() : '';\n if (!refreshToken) {\n return {\n state: 'missing',\n reason: 'Refresh token is missing. Run Codex login again.',\n expiresAt,\n issue: 'refresh-missing',\n requiresUserAction: true,\n };\n }\n\n if (hasExpiry) {\n const diff = parsedExpiry - Date.now();\n if (diff <= 0) {\n return {\n state: 'expiring',\n reason: 'Access token expired.',\n expiresAt,\n accessTokenExpired: true,\n issue: 'access-expired',\n requiresUserAction: false,\n };\n }\n\n if (diff <= TOKEN_EXPIRING_SOON_WINDOW_MS) {\n return {\n state: 'expiring',\n reason: 'Access token expires soon.',\n expiresAt,\n issue: 'access-expiring',\n requiresUserAction: false,\n };\n }\n }\n\n return {\n state: 'ok',\n expiresAt,\n requiresUserAction: false,\n };\n }\n\n private extractProfileMetadata(data: ProfileData): ProfileMetadata | undefined {\n const idPayload = this.decodeJwtPayload(data.id_token) as Record<string, unknown> | null;\n const accessPayload = this.decodeJwtPayload(data.access_token) as Record<string, unknown> | null;\n\n if (!idPayload && !accessPayload) {\n return undefined;\n }\n\n const authInfo = (idPayload?.['https://api.openai.com/auth'] ??\n accessPayload?.['https://api.openai.com/auth']) as Record<string, unknown> | undefined;\n\n const profileInfo = accessPayload?.['https://api.openai.com/profile'] as Record<string, unknown> | undefined;\n\n const getNumber = (obj: Record<string, unknown> | null | undefined, key: string): number | undefined =>\n typeof obj?.[key] === 'number' ? (obj[key] as number) : undefined;\n\n const getString = (obj: Record<string, unknown> | undefined | null, key: string): string | undefined =>\n typeof obj?.[key] === 'string' ? (obj[key] as string) : undefined;\n\n const exp = getNumber(idPayload, 'exp') ?? getNumber(accessPayload, 'exp');\n const iat = getNumber(idPayload, 'iat') ?? getNumber(accessPayload, 'iat');\n const authTime = getNumber(idPayload, 'auth_time') ?? getNumber(accessPayload, 'auth_time');\n\n const organizationsRaw = Array.isArray(authInfo?.['organizations'])\n ? (authInfo?.['organizations'] as unknown[])\n : undefined;\n\n const organizations = organizationsRaw\n ? organizationsRaw\n .map((org): OrganizationInfo => {\n const record = org as Record<string, unknown> | undefined;\n return {\n id: getString(record, 'id'),\n title: getString(record, 'title'),\n role: getString(record, 'role'),\n isDefault: typeof record?.['is_default'] === 'boolean' ? (record?.['is_default'] as boolean) : undefined,\n };\n })\n .filter(\n org =>\n org.id ||\n org.title ||\n org.role ||\n typeof org.isDefault === 'boolean'\n )\n : undefined;\n\n const groups = Array.isArray(authInfo?.['groups'])\n ? (authInfo?.['groups'] as unknown[]).filter((group): group is string => typeof group === 'string')\n : undefined;\n\n const emailVerified =\n typeof profileInfo?.['email_verified'] === 'boolean'\n ? (profileInfo?.['email_verified'] as boolean)\n : typeof idPayload?.['email_verified'] === 'boolean'\n ? (idPayload?.['email_verified'] as boolean)\n : typeof accessPayload?.['email_verified'] === 'boolean'\n ? (accessPayload?.['email_verified'] as boolean)\n : undefined;\n\n const email =\n this.pickFirstEmail([\n getString(profileInfo, 'email'),\n getString(profileInfo, 'email_address'),\n getString(profileInfo, 'primary_email'),\n getString(profileInfo, 'default_email'),\n getString(profileInfo, 'contact_email'),\n ]) ??\n this.findEmailInObject(profileInfo) ??\n this.pickFirstEmail([\n getString(authInfo, 'user_email'),\n getString(authInfo, 'email'),\n getString(authInfo, 'userEmail'),\n getString(authInfo, 'chatgpt_user_email'),\n ]) ??\n this.findEmailInObject(authInfo) ??\n this.pickFirstEmail([\n getString(idPayload, 'email'),\n getString(idPayload, 'preferred_username'),\n getString(idPayload, 'username'),\n ]) ??\n this.findEmailInObject(idPayload) ??\n this.pickFirstEmail([\n getString(accessPayload, 'email'),\n ]) ??\n this.findEmailInObject(accessPayload);\n\n const subscription: SubscriptionInfo | undefined = authInfo\n ? {\n activeStart: getString(authInfo, 'chatgpt_subscription_active_start'),\n activeUntil: getString(authInfo, 'chatgpt_subscription_active_until'),\n lastChecked: getString(authInfo, 'chatgpt_subscription_last_checked'),\n }\n : undefined;\n\n const planType = getString(authInfo, 'chatgpt_plan_type');\n const chatgptUserId = getString(authInfo, 'chatgpt_user_id');\n const chatgptAccountUserId = getString(authInfo, 'chatgpt_account_user_id');\n const userId =\n getString(authInfo, 'user_id') ??\n chatgptAccountUserId ??\n getString(idPayload ?? undefined, 'sub') ??\n getString(accessPayload ?? undefined, 'sub');\n\n const metadata: ProfileMetadata = {\n email,\n planType,\n subscription,\n organizations,\n groups,\n userId,\n chatgptUserId,\n emailVerified,\n tokenExpiresAt: this.toIsoStringFromSeconds(exp),\n tokenIssuedAt: this.toIsoStringFromSeconds(iat),\n tokenAuthTime: this.toIsoStringFromSeconds(authTime),\n };\n\n const hasMeaningfulData =\n Boolean(metadata.planType) ||\n Boolean(\n metadata.subscription &&\n (metadata.subscription.activeStart ||\n metadata.subscription.activeUntil ||\n metadata.subscription.lastChecked)\n ) ||\n Boolean(metadata.organizations && metadata.organizations.length > 0) ||\n Boolean(metadata.groups && metadata.groups.length > 0) ||\n Boolean(metadata.userId) ||\n Boolean(metadata.chatgptUserId) ||\n Boolean(metadata.email) ||\n typeof metadata.emailVerified === 'boolean' ||\n Boolean(metadata.tokenExpiresAt) ||\n Boolean(metadata.tokenIssuedAt) ||\n Boolean(metadata.tokenAuthTime);\n\n return hasMeaningfulData ? metadata : undefined;\n }\n\n /**\n * Initialize the profile manager and create necessary directories\n */\n async initialize(): Promise<void> {\n try {\n await fs.mkdir(this.codexDir, { recursive: true });\n } catch (error) {\n logError('Failed to ensure Codex directory exists:', error);\n throw new Error('Failed to initialize profile manager');\n }\n try {\n await fs.mkdir(this.profileHomesRoot, { recursive: true });\n } catch (error) {\n logError('Failed to ensure profile homes directory exists:', error);\n throw new Error('Failed to initialize profile manager');\n }\n\n await this.recoverActiveAuthBackup();\n const migrationsComplete = await this.hasCompletedMigrations();\n if (!migrationsComplete) {\n await this.migrateLegacyProfiles();\n await this.migrateProfilesFromDatabase();\n await this.removeLegacyArtifacts();\n await this.markMigrationsComplete();\n }\n }\n\n /**\n * Remove deprecated files that previously tracked the current profile.\n * These are now redundant since we infer the active profile from auth.json.\n */\n private async removeLegacyArtifacts(): Promise<void> {\n const legacyTargets = [\n join(this.codexDir, 'current-profile.json'),\n join(this.profilesDir, '.current'),\n `${this.activeAuth}.backup`,\n join(this.codexDir, 'cache', 'rate-limits'),\n ];\n\n for (const target of legacyTargets) {\n try {\n await fs.rm(target, { recursive: true, force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove legacy artifact '${target}':`, error);\n }\n }\n }\n\n try {\n await fs.rm(this.profilesDir, { recursive: true, force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove legacy profiles directory '${this.profilesDir}':`, error);\n }\n }\n }\n\n private async hasCompletedMigrations(): Promise<boolean> {\n try {\n await fs.access(this.profileMigrationMarker);\n return true;\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to read profile migration marker:', error);\n }\n return false;\n }\n }\n\n private async markMigrationsComplete(): Promise<void> {\n try {\n await fs.mkdir(this.migrationsDir, { recursive: true });\n await fs.writeFile(this.profileMigrationMarker, 'ok');\n } catch (error) {\n logWarn('Failed to persist profile migration marker:', error);\n }\n }\n\n private async migrateLegacyProfiles(): Promise<void> {\n let files: string[];\n try {\n files = await fs.readdir(this.profilesDir);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to inspect legacy profiles directory:', error);\n }\n return;\n }\n\n if (files.length === 0) {\n return;\n }\n\n type LegacyCandidate = {\n name: string;\n data: ProfileData;\n profile: Profile;\n accountId?: string;\n };\n\n const accountCandidates = new Map<string, LegacyCandidate>();\n const orphanCandidates: LegacyCandidate[] = [];\n const insertedNames = new Set<string>();\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const name = file.replace(/\\.json$/, '');\n const filePath = join(this.profilesDir, file);\n\n try {\n const raw = await fs.readFile(filePath, 'utf8');\n const data = JSON.parse(raw) as ProfileData;\n const normalizedName = this.normalizeProfileName(name);\n const metadata = this.extractProfileMetadata(data);\n const resolvedEmail = this.resolveProfileEmail(data, metadata);\n if (resolvedEmail) {\n data.email = resolvedEmail;\n }\n const accountId = this.getAccountIdFromData(data);\n const candidate: LegacyCandidate = {\n name: normalizedName,\n data,\n profile: this.buildProfileFromData(normalizedName, data),\n accountId,\n };\n\n if (accountId) {\n const existing = accountCandidates.get(accountId);\n if (existing) {\n const preferred = this.selectPreferredProfile([existing.profile, candidate.profile]);\n if (preferred === candidate.profile) {\n logWarn(\n `Replacing legacy profile '${existing.name}' with '${normalizedName}' for account '${accountId}'.`,\n );\n accountCandidates.set(accountId, candidate);\n } else {\n logWarn(\n `Skipping legacy profile '${name}' because account '${accountId}' already exists as '${existing.name}'.`,\n );\n }\n } else {\n accountCandidates.set(accountId, candidate);\n }\n } else {\n orphanCandidates.push(candidate);\n }\n\n await fs.rm(filePath, { force: true });\n } catch (error) {\n logWarn(`Failed to migrate legacy profile '${name}':`, error);\n }\n }\n\n const persistQueue: LegacyCandidate[] = [...accountCandidates.values(), ...orphanCandidates];\n const existingRecords = await this.listProfileRecords();\n for (const record of existingRecords) {\n insertedNames.add(record.name);\n }\n\n for (const candidate of persistQueue) {\n if (insertedNames.has(candidate.name)) {\n logWarn(`Skipping legacy profile '${candidate.name}' because it was already imported.`);\n continue;\n }\n\n try {\n await this.persistProfileRecord(candidate.name, candidate.data, candidate.profile.metadata);\n insertedNames.add(candidate.name);\n } catch (error) {\n logWarn(`Failed to persist migrated profile '${candidate.name}':`, error);\n }\n }\n }\n\n private async migrateProfilesFromDatabase(): Promise<void> {\n let rows: DbProfileRow[] = [];\n try {\n const { getDatabase } = await import('./sqlite-db');\n const db = await getDatabase();\n rows = db\n .prepare(\n 'SELECT name, data, account_id, workspace_id, workspace_name, email, auth_method, created_at, updated_at FROM profiles',\n )\n .all() as DbProfileRow[];\n } catch (error) {\n logWarn('Failed to read existing database profiles for migration:', error);\n return;\n }\n\n if (!rows || rows.length === 0) {\n return;\n }\n\n const existingNames = new Set<string>((await this.listProfileRecords()).map(record => record.name));\n\n for (const row of rows) {\n const name = typeof row?.name === 'string' ? row.name : null;\n const serialized = typeof row?.data === 'string' ? row.data : null;\n if (!name || !serialized) {\n continue;\n }\n\n let data: ProfileData;\n try {\n data = JSON.parse(serialized) as ProfileData;\n } catch (error) {\n logWarn(`Failed to parse database profile '${name}' during migration:`, error);\n continue;\n }\n\n try {\n const normalizedName = this.normalizeProfileName(name);\n if (existingNames.has(normalizedName)) {\n continue;\n }\n\n data.created_at = data.created_at ?? (typeof row?.created_at === 'string' ? row.created_at : undefined);\n data.email = data.email ?? (typeof row?.email === 'string' ? row.email : undefined);\n data.auth_method = data.auth_method ?? (typeof row?.auth_method === 'string' ? row.auth_method : undefined);\n data.workspace_id = data.workspace_id ?? (typeof row?.workspace_id === 'string' ? row.workspace_id : undefined);\n data.workspace_name =\n data.workspace_name ?? (typeof row?.workspace_name === 'string' ? row.workspace_name : undefined);\n data.updated_at = data.updated_at ?? (typeof row?.updated_at === 'string' ? row.updated_at : undefined);\n\n const metadata = this.extractProfileMetadata(data);\n await this.persistProfileRecord(normalizedName, data, metadata);\n existingNames.add(normalizedName);\n } catch (error) {\n logWarn(`Failed to migrate database profile '${name}':`, error);\n }\n }\n }\n\n private enqueueAuthSwap<T>(task: () => Promise<T>): Promise<T> {\n const run = this.authSwapLock.then(task, task);\n this.authSwapLock = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n\n private async recoverActiveAuthBackup(): Promise<void> {\n let backup: string;\n try {\n backup = await fs.readFile(this.activeAuthBackup, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to inspect active auth backup:', error);\n }\n return;\n }\n\n try {\n if (backup === AUTH_BACKUP_MISSING_MARKER) {\n await fs.rm(this.activeAuth, { force: true });\n } else {\n try {\n await this.writeAtomic(this.activeAuth, backup);\n } catch (error) {\n logWarn('Failed to restore active auth from backup, falling back to direct write:', error);\n try {\n await fs.writeFile(this.activeAuth, backup, 'utf8');\n } catch (fallbackError) {\n logWarn('Direct write failed while restoring active auth backup:', fallbackError);\n }\n }\n }\n } catch (error) {\n logWarn('Failed to restore active auth from backup:', error);\n }\n\n try {\n await fs.rm(this.activeAuthBackup, { force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to remove active auth backup:', error);\n }\n }\n }\n\n private async writeAtomic(filePath: string, contents: string): Promise<void> {\n const tempPath = `${filePath}.tmp`;\n const dir = path.dirname(filePath);\n await fs.mkdir(dir, { recursive: true });\n\n await fs.writeFile(tempPath, contents, 'utf8');\n try {\n await fs.rename(tempPath, filePath);\n } catch (error) {\n // Fall back to writing directly if rename fails for any reason.\n try {\n await fs.writeFile(filePath, contents, 'utf8');\n } catch (writeError) {\n // Surface the original error context to aid debugging.\n const original = error instanceof Error ? error.message : String(error);\n const fallback = writeError instanceof Error ? writeError.message : String(writeError);\n throw new Error(`Atomic write failed (rename: ${original}; direct write: ${fallback})`);\n }\n }\n // Best-effort cleanup of temp file if it still exists.\n try {\n await fs.rm(tempPath, { force: true });\n } catch {\n // ignore cleanup failures\n }\n }\n\n /**\n * Extract account_id from auth data (supports both formats)\n */\n private getAccountIdFromData(data: ProfileData | ActiveAuth): string | undefined {\n if ('account_id' in data && typeof data.account_id === 'string' && data.account_id.trim()) {\n return data.account_id.trim();\n }\n\n if ('tokens' in data && data.tokens && typeof data.tokens === 'object') {\n const accountId = (data.tokens as { account_id?: unknown }).account_id;\n if (typeof accountId === 'string' && accountId.trim()) {\n return accountId.trim();\n }\n }\n\n const projectId =\n 'project_id' in data && typeof (data as ProfileData).project_id === 'string'\n ? (data as ProfileData).project_id?.trim()\n : undefined;\n if (projectId) {\n return projectId;\n }\n\n const email =\n 'email' in data && typeof (data as ProfileData).email === 'string'\n ? (data as ProfileData).email?.trim()\n : undefined;\n return email || undefined;\n }\n\n private resolveWorkspaceIdentity(data: ProfileData | ActiveAuth, metadata?: ProfileMetadata): { id: string; name?: string } {\n const directId =\n 'workspace_id' in data && typeof data.workspace_id === 'string'\n ? data.workspace_id.trim()\n : undefined;\n const directName =\n 'workspace_name' in data && typeof data.workspace_name === 'string'\n ? data.workspace_name.trim()\n : undefined;\n\n if (directId) {\n return { id: directId, name: directName };\n }\n\n const organizations = metadata?.organizations;\n if (organizations && organizations.length > 0) {\n const preferred = organizations.find(org => org.isDefault) ?? organizations[0];\n if (preferred?.id) {\n return { id: preferred.id, name: preferred.title ?? directName };\n }\n }\n\n return { id: DEFAULT_WORKSPACE_ID, name: directName };\n }\n\n private async getProfileRowByName(name: string): Promise<ProfileRecord | undefined> {\n const normalized = this.normalizeProfileName(name);\n const record = await this.readProfileRecord(normalized);\n return record ?? undefined;\n }\n\n private async getProfileRowByAccountId(\n accountId: string,\n options?: { authMethod?: string | null; preferAuthMethod?: string | null },\n ): Promise<ProfileRecord | undefined> {\n const records = await this.listProfileRecords();\n const matches = records.filter(record => {\n const storedAccountId = record.accountId ?? this.getAccountIdFromData(record.data);\n return storedAccountId === accountId;\n });\n\n if (matches.length === 0) {\n return undefined;\n }\n\n const mustMatch = typeof options?.authMethod === 'string' ? options.authMethod.trim().toLowerCase() : null;\n if (mustMatch) {\n return matches.find(record => this.resolveAuthMethod(record.data) === mustMatch);\n }\n\n const prefer = typeof options?.preferAuthMethod === 'string' ? options.preferAuthMethod.trim().toLowerCase() : null;\n if (prefer) {\n return matches.find(record => this.resolveAuthMethod(record.data) === prefer) ?? matches[0];\n }\n\n return matches[0];\n }\n\n private async getProfileRowByAccountAndWorkspace(\n accountId: string,\n workspaceId: string,\n options?: { authMethod?: string | null; preferAuthMethod?: string | null },\n ): Promise<ProfileRecord | undefined> {\n const workspaceKey = workspaceId && workspaceId.trim().length > 0 ? workspaceId.trim() : DEFAULT_WORKSPACE_ID;\n const records = await this.listProfileRecords();\n const matches = records.filter(record => {\n const storedAccountId = record.accountId ?? this.getAccountIdFromData(record.data);\n if (storedAccountId !== accountId) {\n return false;\n }\n const storedWorkspace = record.workspaceId ?? record.data.workspace_id ?? DEFAULT_WORKSPACE_ID;\n return (storedWorkspace && storedWorkspace.trim() ? storedWorkspace.trim() : DEFAULT_WORKSPACE_ID) === workspaceKey;\n });\n\n if (matches.length === 0) {\n return undefined;\n }\n\n const mustMatch = typeof options?.authMethod === 'string' ? options.authMethod.trim().toLowerCase() : null;\n if (mustMatch) {\n return matches.find(record => this.resolveAuthMethod(record.data) === mustMatch);\n }\n\n const prefer = typeof options?.preferAuthMethod === 'string' ? options.preferAuthMethod.trim().toLowerCase() : null;\n if (prefer) {\n return matches.find(record => this.resolveAuthMethod(record.data) === prefer) ?? matches[0];\n }\n\n return matches[0];\n }\n\n private async persistProfileRecord(\n name: string,\n data: ProfileData,\n metadata?: ProfileMetadata,\n options?: { displayName?: string | null },\n ): Promise<void> {\n const resolvedName = this.normalizeProfileName(name);\n const existingRecord = await this.readProfileRecord(resolvedName);\n if (typeof data.auth_method === 'string') {\n data.auth_method = data.auth_method.trim().toLowerCase();\n }\n if (!data.auth_method) {\n data.auth_method = 'codex-cli';\n }\n const resolvedMetadata = metadata ?? this.extractProfileMetadata(data) ?? existingRecord?.metadata;\n const workspace = this.resolveWorkspaceIdentity(data, resolvedMetadata);\n const workspaceId = workspace.id || DEFAULT_WORKSPACE_ID;\n const workspaceName = workspace.name ?? null;\n if (!data.workspace_id) {\n data.workspace_id = workspaceId;\n }\n if (!data.workspace_name && workspaceName) {\n data.workspace_name = workspaceName;\n }\n\n const now = new Date().toISOString();\n const accountId = this.getAccountIdFromData(data) ?? null;\n const resolvedEmail = this.resolveProfileEmail(data, resolvedMetadata) ?? data.email ?? null;\n if (resolvedEmail) {\n data.email = resolvedEmail;\n }\n const createdAt = data.created_at ?? existingRecord?.createdAt ?? now;\n data.created_at = createdAt;\n const updatedAt = data.updated_at ?? now;\n data.updated_at = updatedAt;\n\n const displayName =\n typeof options?.displayName === 'string' && options.displayName.trim().length > 0\n ? options.displayName.trim()\n : existingRecord?.displayName ?? resolvedName;\n\n const record: ProfileRecord = {\n name: resolvedName,\n displayName,\n data,\n metadata: resolvedMetadata,\n accountId,\n workspaceId: data.workspace_id ?? workspaceId,\n workspaceName: data.workspace_name ?? workspaceName,\n email: resolvedEmail ?? null,\n authMethod: typeof data.auth_method === 'string' ? data.auth_method : null,\n createdAt,\n updatedAt,\n };\n\n await fs.mkdir(this.getProfileHomePath(resolvedName), { recursive: true });\n await this.writeProfileRecord(record);\n }\n\n private buildProfileFromRow(row: ProfileRecord): Profile {\n const profile = this.buildProfileFromData(row.name, row.data, {\n displayName: row.displayName ?? undefined,\n email: row.email ?? undefined,\n createdAt: row.createdAt ?? undefined,\n authMethod: row.authMethod ?? undefined,\n accountId: row.accountId ?? undefined,\n workspaceId: row.workspaceId ?? undefined,\n workspaceName: row.workspaceName ?? undefined,\n metadata: row.metadata,\n });\n\n return profile;\n }\n\n private buildProfileFromData(\n name: string,\n data: ProfileData,\n fallback?: {\n displayName?: string;\n email?: string;\n createdAt?: string;\n authMethod?: string;\n accountId?: string;\n projectId?: string;\n workspaceId?: string;\n workspaceName?: string;\n metadata?: ProfileMetadata;\n },\n ): Profile {\n const metadata = fallback?.metadata ?? this.extractProfileMetadata(data);\n const workspace = this.resolveWorkspaceIdentity(data, metadata);\n const workspaceId = workspace.id || fallback?.workspaceId || DEFAULT_WORKSPACE_ID;\n const workspaceName = workspace.name ?? fallback?.workspaceName ?? undefined;\n const email = this.resolveProfileEmail(data, metadata) ?? fallback?.email ?? undefined;\n const tokenStatus = this.evaluateTokenStatus(data, metadata);\n const accountId = this.getAccountIdFromData(data) ?? fallback?.accountId;\n const projectId =\n typeof data.project_id === 'string' && data.project_id.trim().length > 0\n ? data.project_id.trim()\n : fallback?.projectId;\n\n return {\n name,\n displayName: fallback?.displayName ?? name,\n isValid: Boolean(data && Object.keys(data).length > 0),\n accountId,\n projectId,\n workspaceId,\n workspaceName,\n email,\n createdAt: data.created_at ?? fallback?.createdAt ?? undefined,\n authMethod: typeof data.auth_method === 'string'\n ? data.auth_method.trim().toLowerCase()\n : fallback?.authMethod ?? undefined,\n metadata,\n tokenStatus,\n };\n }\n\n private parseTimestamp(value?: string | null): number | null {\n if (typeof value !== 'string' || value.trim() === '') {\n return null;\n }\n\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? null : parsed;\n }\n\n private compareProfilesForPreference(a: Profile, b: Profile): number {\n if (Boolean(a.isValid) !== Boolean(b.isValid)) {\n return a.isValid ? -1 : 1;\n }\n\n const aTimestamp = this.parseTimestamp(a.createdAt ?? null);\n const bTimestamp = this.parseTimestamp(b.createdAt ?? null);\n\n if (aTimestamp !== null || bTimestamp !== null) {\n if (aTimestamp !== null && bTimestamp !== null) {\n if (aTimestamp > bTimestamp) {\n return -1;\n }\n if (aTimestamp < bTimestamp) {\n return 1;\n }\n } else if (aTimestamp !== null) {\n return -1;\n } else {\n return 1;\n }\n }\n\n return a.name.localeCompare(b.name);\n }\n\n private selectPreferredProfile(profiles: Profile[]): Profile {\n if (profiles.length <= 1) {\n return profiles[0];\n }\n\n return profiles\n .slice()\n .sort((a, b) => this.compareProfilesForPreference(a, b))[0];\n }\n\n /**\n * Convert profile data to Codex's expected format\n */\n private convertToCodexFormat(data: ProfileData): ActiveAuth {\n // Check if data is already in Codex format\n if ('tokens' in data) {\n return data as ActiveAuth;\n }\n\n // Convert flat structure to nested Codex format\n return {\n OPENAI_API_KEY: null,\n tokens: {\n id_token: data.id_token,\n access_token: data.access_token,\n refresh_token: data.refresh_token,\n account_id: data.account_id,\n },\n last_refresh: new Date().toISOString(),\n };\n }\n\n /**\n * Normalize Codex auth data to flat profile format\n */\n private normalizeProfileData(data: ActiveAuth): ProfileData {\n // If data is already in flat format, return as-is\n if ('id_token' in data) {\n return data as ProfileData;\n }\n\n // Convert nested Codex format to flat\n const tokens = data.tokens || {};\n const profile: ProfileData = {\n id_token: tokens.id_token,\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n account_id: tokens.account_id,\n };\n\n if (data.email) {\n profile.email = data.email;\n }\n\n return profile;\n }\n\n private mergeProfileRecords(existing: ProfileData, incoming: ProfileData): {\n profile: ProfileData;\n metadata?: ProfileMetadata;\n } {\n const merged: ProfileData = {\n ...existing,\n ...incoming,\n created_at: existing.created_at ?? incoming.created_at ?? new Date().toISOString(),\n };\n\n if (typeof merged.auth_method === 'string') {\n merged.auth_method = merged.auth_method.trim().toLowerCase();\n }\n if (!merged.auth_method) {\n merged.auth_method = 'codex-cli';\n }\n\n const metadata = this.extractProfileMetadata(merged);\n const resolvedEmail = this.resolveProfileEmail(merged, metadata);\n\n if (resolvedEmail) {\n merged.email = resolvedEmail;\n }\n\n const workspace = this.resolveWorkspaceIdentity(merged, metadata);\n if (!merged.workspace_id) {\n merged.workspace_id = workspace.id || existing.workspace_id || DEFAULT_WORKSPACE_ID;\n }\n if (!merged.workspace_name) {\n merged.workspace_name = workspace.name ?? existing.workspace_name;\n }\n\n if (this.hasTokenChanges(existing, incoming)) {\n delete merged.tokenAlert;\n }\n\n return { profile: merged, metadata };\n }\n\n private hasTokenChanges(existing: ProfileData, incoming: ProfileData): boolean {\n const tokenKeys: Array<keyof ProfileData> = ['id_token', 'access_token', 'refresh_token', 'account_id', 'workspace_id'];\n\n return tokenKeys.some(key => {\n const nextValue = incoming[key];\n if (typeof nextValue !== 'string' || nextValue.length === 0) {\n return false;\n }\n return nextValue !== existing[key];\n });\n }\n\n async flagRefreshTokenRedeemed(name: string, reason?: string, options?: { observedAt?: string }): Promise<void> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n logWarn(`Cannot flag refresh token issue for missing profile '${profileName}'.`);\n return;\n }\n\n const observedAt = options?.observedAt ? Date.parse(options.observedAt) : null;\n const updatedAt = record.updatedAt ? Date.parse(record.updatedAt) : null;\n if (observedAt !== null && updatedAt !== null && observedAt <= updatedAt) {\n return;\n }\n\n const data: ProfileData = record.data;\n\n const trimmedReason = typeof reason === 'string' && reason.trim().length > 0 ? reason.trim() : undefined;\n const normalized = trimmedReason?.toLowerCase() ?? '';\n const storedReason = normalized.includes(REFRESH_TOKEN_REDEEMED_SNIPPET)\n ? REFRESH_TOKEN_REDEEMED_REASON\n : trimmedReason ?? REFRESH_TOKEN_REDEEMED_REASON;\n const alert: TokenAlert = {\n issue: 'refresh-redeemed',\n reason: storedReason,\n recordedAt: new Date().toISOString(),\n };\n\n data.tokenAlert = alert;\n\n try {\n const metadata = this.extractProfileMetadata(data);\n await this.persistProfileRecord(profileName, data, metadata);\n } catch (error) {\n logError(`Failed to persist token alert for profile '${profileName}':`, error);\n }\n }\n\n private async syncProfileTokensFromActiveAuth(\n profileName: string,\n baselineProfile: ProfileData,\n authPath?: string,\n ): Promise<void> {\n const targetPath = authPath ?? this.activeAuth;\n try {\n const authRaw = await fs.readFile(targetPath, 'utf8');\n await this.syncProfileTokensFromAuthContent(profileName, baselineProfile, authRaw);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read Codex auth for '${profileName}' while syncing tokens:`, error);\n }\n }\n }\n\n private async syncProfileTokensFromAuthContent(\n profileName: string,\n baselineProfile: ProfileData,\n authContent: string,\n ): Promise<void> {\n let activeAuth: ActiveAuth;\n try {\n activeAuth = JSON.parse(authContent) as ActiveAuth;\n } catch (error) {\n logWarn(`Failed to parse Codex auth while syncing tokens for '${profileName}':`, error);\n return;\n }\n\n const normalized = this.normalizeProfileData(activeAuth);\n const metadata = this.extractProfileMetadata(normalized);\n const workspace = this.resolveWorkspaceIdentity(normalized, metadata);\n normalized.workspace_id = normalized.workspace_id ?? workspace.id ?? DEFAULT_WORKSPACE_ID;\n if (workspace.name) {\n normalized.workspace_name = normalized.workspace_name ?? workspace.name;\n }\n const hasTokens =\n typeof normalized.id_token === 'string' ||\n typeof normalized.access_token === 'string' ||\n typeof normalized.refresh_token === 'string';\n\n if (!hasTokens) {\n return;\n }\n\n let existing = baselineProfile;\n const latestRow = await this.getProfileRowByName(profileName);\n if (latestRow) {\n existing = latestRow.data;\n }\n\n const existingAccountId = this.getAccountIdFromData(existing);\n const newAccountId = this.getAccountIdFromData(normalized);\n\n if (existingAccountId && newAccountId && existingAccountId !== newAccountId) {\n logWarn(\n `Skipped syncing tokens for profile '${profileName}' because Codex auth switched to account '${newAccountId}'.`,\n );\n return;\n }\n\n if (!this.hasTokenChanges(existing, normalized)) {\n return;\n }\n\n const { profile: merged, metadata: mergedMetadata } = this.mergeProfileRecords(existing, normalized);\n\n try {\n await this.persistProfileRecord(profileName, merged, mergedMetadata);\n } catch (error) {\n logError(`Failed to persist refreshed tokens for profile '${profileName}':`, error);\n }\n }\n\n private async copyCodexConfig(targetCodexHome: string): Promise<void> {\n const candidates = ['config.toml', 'config.json', 'config.yaml', 'config.yml'];\n for (const file of candidates) {\n const source = join(this.codexDir, file);\n const destination = join(targetCodexHome, file);\n try {\n await fs.copyFile(source, destination);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to copy Codex config '${file}' to profile home:`, error);\n }\n }\n }\n }\n\n private getProfileHomePath(profileName: string): string {\n return join(this.profileHomesRoot, profileName);\n }\n\n private ensureTrailingNewline(content: string): string {\n return content.endsWith('\\n') ? content : `${content}\\n`;\n }\n\n private async sanitizeProfileConfig(profileHome: string): Promise<void> {\n const configPath = join(profileHome, 'config.toml');\n let raw: string;\n try {\n raw = await fs.readFile(configPath, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read config for profile home '${profileHome}':`, error);\n }\n return;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = parse(raw) as Record<string, unknown>;\n } catch (error) {\n logWarn(`Failed to parse config.toml for profile home '${profileHome}':`, error);\n return;\n }\n\n if (!Object.prototype.hasOwnProperty.call(parsed, 'model_reasoning_effort')) {\n return;\n }\n\n delete parsed['model_reasoning_effort'];\n const sanitized = this.ensureTrailingNewline(stringify(parsed as Record<string, unknown>));\n try {\n await fs.writeFile(configPath, sanitized, 'utf8');\n } catch (error) {\n logWarn(`Failed to write sanitized config.toml for profile home '${profileHome}':`, error);\n }\n }\n\n private async prepareProfileHome(profileName: string, authData: ActiveAuth): Promise<string> {\n const profileHome = this.getProfileHomePath(profileName);\n await fs.mkdir(profileHome, { recursive: true });\n const authPath = join(profileHome, 'auth.json');\n await this.writeAtomic(authPath, JSON.stringify(authData, null, 2));\n await this.copyCodexConfig(profileHome);\n await this.sanitizeProfileConfig(profileHome);\n return profileHome;\n }\n\n /**\n * List all available profiles\n */\n async profileExists(name: string): Promise<boolean> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n return Boolean(await this.getProfileRowByName(profileName));\n }\n\n async listProfiles(): Promise<Profile[]> {\n await this.initialize();\n try {\n const records = await this.listProfileRecords();\n return records\n .map(record => this.buildProfileFromRow(record))\n .filter(profile => !profile.authMethod || profile.authMethod === 'codex-cli')\n .sort((a, b) => {\n const aLabel = a.displayName ?? a.name;\n const bLabel = b.displayName ?? b.name;\n const base = aLabel.localeCompare(bLabel);\n return base !== 0 ? base : a.name.localeCompare(b.name);\n });\n } catch (error) {\n logError('Error reading profiles from disk:', error);\n return [];\n }\n }\n\n /**\n * Create a new profile by running codex login\n */\n async createProfile(name: string): Promise<Profile | null> {\n await this.initialize();\n\n const profileName = this.normalizeProfileName(name);\n if (await this.getProfileRowByName(profileName)) {\n throw new Error(`Profile '${profileName}' already exists!`);\n }\n\n let authData: ActiveAuth;\n try {\n const authRaw = await fs.readFile(this.activeAuth, 'utf8');\n authData = JSON.parse(authRaw) as ActiveAuth;\n } catch (error) {\n logError('Error creating profile:', error);\n throw new Error('Failed to create profile. Make sure Codex CLI is installed and you are logged in.');\n }\n\n const normalizedProfile = this.normalizeProfileData(authData);\n normalizedProfile.created_at = normalizedProfile.created_at ?? new Date().toISOString();\n if (typeof normalizedProfile.auth_method === 'string') {\n normalizedProfile.auth_method = normalizedProfile.auth_method.trim().toLowerCase();\n }\n normalizedProfile.auth_method = normalizedProfile.auth_method ?? 'codex-cli';\n\n const metadata = this.extractProfileMetadata(normalizedProfile);\n const workspace = this.resolveWorkspaceIdentity(normalizedProfile, metadata);\n normalizedProfile.workspace_id = normalizedProfile.workspace_id ?? workspace.id ?? DEFAULT_WORKSPACE_ID;\n if (workspace.name) {\n normalizedProfile.workspace_name = normalizedProfile.workspace_name ?? workspace.name;\n }\n\n const accountId = this.getAccountIdFromData(normalizedProfile);\n if (accountId) {\n const requestedWorkspace = normalizedProfile.workspace_id ?? DEFAULT_WORKSPACE_ID;\n const duplicate = await this.getProfileRowByAccountAndWorkspace(accountId, requestedWorkspace, { authMethod: 'codex-cli' });\n if (duplicate) {\n normalizedProfile.workspace_id = `${requestedWorkspace}:${profileName}`;\n normalizedProfile.workspace_name = normalizedProfile.workspace_name ?? profileName;\n }\n }\n\n const resolvedEmail = this.resolveProfileEmail(normalizedProfile, metadata);\n if (resolvedEmail) {\n normalizedProfile.email = resolvedEmail;\n }\n\n try {\n await this.persistProfileRecord(profileName, normalizedProfile, metadata);\n const stored = await this.getProfileRowByName(profileName);\n return stored ? this.buildProfileFromRow(stored) : null;\n } catch (error) {\n logError('Error creating profile:', error);\n throw new Error('Failed to create profile. Make sure Codex CLI is installed and you are logged in.');\n }\n }\n\n /**\n * Switch to a different profile\n */\n async switchToProfile(name: string): Promise<boolean> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n try {\n const profileData = record.data;\n const codexFormat = this.convertToCodexFormat(profileData);\n await this.writeAtomic(this.activeAuth, JSON.stringify(codexFormat, null, 2));\n await this.persistPreferredProfileName(profileName);\n return true;\n } catch (error) {\n logError('Error switching profile:', error);\n throw new Error('Failed to switch profile');\n }\n }\n\n async refreshProfileAuth(name: string): Promise<Profile> {\n await this.initialize();\n\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n const existing: ProfileData = record.data;\n let activeAuth: ActiveAuth;\n try {\n const authContent = await fs.readFile(this.activeAuth, 'utf8');\n activeAuth = JSON.parse(authContent) as ActiveAuth;\n } catch (error) {\n if (this.isNotFoundError(error)) {\n throw new Error('Codex CLI did not produce an auth file. Complete the login before refreshing this profile.');\n }\n logError('Failed to read Codex auth file during refresh:', error);\n throw new Error('Failed to read Codex auth file. Complete the login and try again.');\n }\n\n const normalized = this.normalizeProfileData(activeAuth);\n const existingAccountId = this.getAccountIdFromData(existing);\n const newAccountId = this.getAccountIdFromData(normalized);\n const normalizedMetadata = this.extractProfileMetadata(normalized);\n const normalizedWorkspace = this.resolveWorkspaceIdentity(normalized, normalizedMetadata);\n normalized.workspace_id = normalized.workspace_id ?? normalizedWorkspace.id ?? DEFAULT_WORKSPACE_ID;\n if (normalizedWorkspace.name) {\n normalized.workspace_name = normalized.workspace_name ?? normalizedWorkspace.name;\n }\n\n if (existingAccountId && newAccountId && existingAccountId !== newAccountId) {\n throw new Error(\n `Active Codex login is for account '${newAccountId}', but profile '${profileName}' is tied to '${existingAccountId}'. Create a new profile for the new account instead.`,\n );\n }\n\n if (existingAccountId && normalized.workspace_id) {\n const currentWorkspace = this.resolveWorkspaceIdentity(existing, this.extractProfileMetadata(existing));\n const targetWorkspaceId = normalized.workspace_id;\n const currentWorkspaceId = currentWorkspace.id ?? DEFAULT_WORKSPACE_ID;\n if (targetWorkspaceId !== currentWorkspaceId) {\n const duplicate = await this.getProfileRowByAccountAndWorkspace(existingAccountId, targetWorkspaceId, {\n authMethod: this.resolveAuthMethod(existing),\n });\n if (duplicate && duplicate.name !== profileName) {\n throw new Error(\n `Account is already saved as profile '${duplicate.name}'. Switch to or delete that profile before creating another.`,\n );\n }\n }\n }\n\n const { profile: merged, metadata } = this.mergeProfileRecords(existing, normalized);\n delete merged.tokenAlert;\n\n await this.persistProfileRecord(profileName, merged, metadata);\n const updated = await this.getProfileRowByName(profileName);\n if (!updated) {\n throw new Error('Failed to persist refreshed profile data.');\n }\n\n const profile = this.buildProfileFromRow(updated);\n if (metadata) {\n profile.metadata = metadata;\n profile.tokenStatus = this.evaluateTokenStatus(merged, metadata);\n }\n return profile;\n }\n\n /**\n * Execute an action with a profile's auth injected.\n * Creates an isolated CODEX_HOME with the profile's auth/config, invokes the action\n * with env overrides, then syncs any refreshed tokens back to the profile.\n */\n async runWithProfileAuth<T>(\n name: string,\n action: (env: NodeJS.ProcessEnv) => Promise<T>,\n ): Promise<T> {\n return this.enqueueAuthSwap(async () => {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n const profileData: ProfileData = record.data;\n const profileHome = this.getProfileHomePath(profileName);\n await fs.mkdir(profileHome, { recursive: true });\n\n if (profileData.auth_method && profileData.auth_method !== 'codex-cli') {\n throw new Error('Unsupported auth method. Codex CLI profiles only.');\n }\n const codexFormat = this.convertToCodexFormat(profileData);\n await this.prepareProfileHome(profileName, codexFormat);\n const authPath = path.join(profileHome, 'auth.json');\n\n const envOverrides: NodeJS.ProcessEnv = {\n ...process.env,\n HOME: profileHome,\n USERPROFILE: profileHome,\n CODEX_HOME: profileHome,\n };\n\n try {\n return await action(envOverrides);\n } finally {\n let finalAuthContent: string | null = null;\n try {\n finalAuthContent = await fs.readFile(authPath, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read isolated auth for '${profileName}' after action:`, error);\n }\n }\n\n try {\n if (finalAuthContent) {\n await this.syncProfileTokensFromAuthContent(profileName, profileData, finalAuthContent);\n } else {\n await this.syncProfileTokensFromActiveAuth(profileName, profileData, authPath);\n }\n } catch (error) {\n logWarn(`Failed to sync refreshed tokens for profile '${profileName}':`, error);\n }\n }\n });\n }\n\n /**\n * Rename a profile\n */\n async renameProfile(oldName: string, newName: string): Promise<boolean> {\n await this.initialize();\n const sourceName = this.normalizeProfileName(oldName);\n const targetName = this.normalizeProfileName(newName);\n\n const existing = await this.getProfileRowByName(sourceName);\n if (!existing) {\n throw new Error(`Profile '${sourceName}' not found!`);\n }\n\n if (await this.getProfileRowByName(targetName)) {\n throw new Error(`Profile '${targetName}' already exists!`);\n }\n\n const preferred = await this.readPreferredProfileName();\n if (preferred && preferred === sourceName) {\n await this.persistPreferredProfileName(targetName);\n }\n\n const oldHome = this.getProfileHomePath(sourceName);\n const newHome = this.getProfileHomePath(targetName);\n try {\n await fs.mkdir(this.profileHomesRoot, { recursive: true });\n await fs.rename(oldHome, newHome);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to move profile home from '${sourceName}' to '${targetName}':`, error);\n }\n }\n\n try {\n const updatedRecord: ProfileRecord = {\n ...existing,\n name: targetName,\n };\n await this.writeProfileRecord(updatedRecord);\n } catch (error) {\n logWarn(`Failed to rewrite profile record after renaming '${sourceName}' to '${targetName}':`, error);\n }\n\n return true;\n }\n\n async updateProfileDisplayName(name: string, displayName: string): Promise<boolean> {\n await this.initialize();\n\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n const trimmed = typeof displayName === 'string' ? displayName.trim() : '';\n if (!trimmed) {\n throw new Error('Profile name must not be empty.');\n }\n\n const now = new Date().toISOString();\n record.displayName = trimmed;\n record.updatedAt = now;\n (record.data as ProfileData & { updated_at?: string }).updated_at = now;\n\n await this.writeProfileRecord(record);\n return true;\n }\n\n /**\n * Delete a profile\n */\n async deleteProfile(name: string): Promise<boolean> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n const preferred = await this.readPreferredProfileName();\n if (preferred && preferred === profileName) {\n await this.persistPreferredProfileName(null);\n }\n try {\n await fs.rm(this.getProfileHomePath(profileName), { recursive: true, force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove profile home for '${profileName}':`, error);\n }\n }\n return true;\n }\n\n /**\n * Delete every profile that does not appear in the allow-list.\n * Used to enforce plan limits when local storage was tampered with.\n */\n async deleteProfilesNotIn(allowedNames: Iterable<string>): Promise<string[]> {\n await this.initialize();\n const normalized = new Set<string>();\n for (const name of allowedNames) {\n try {\n normalized.add(this.normalizeProfileName(name));\n } catch {\n // Skip invalid names so we only retain well-formed entries.\n }\n }\n\n const records = await this.listProfileRecords();\n const deleteCandidates = records\n .map(record => {\n try {\n return this.normalizeProfileName(record.name);\n } catch {\n return null;\n }\n })\n .filter((name): name is string => Boolean(name) && !normalized.has(name));\n\n if (deleteCandidates.length === 0) {\n return [];\n }\n\n const removed: string[] = [];\n for (const name of deleteCandidates) {\n try {\n await fs.rm(this.getProfileHomePath(name), { recursive: true, force: true });\n removed.push(name);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove profile '${name}' during plan enforcement:`, error);\n }\n }\n }\n const preferred = await this.readPreferredProfileName();\n if (preferred && removed.includes(preferred)) {\n await this.persistPreferredProfileName(null);\n }\n return removed;\n }\n\n /**\n * Check if the current auth matches a profile (for smart detection)\n */\n async getCurrentProfile(): Promise<{ name: string | null; trusted: boolean }> {\n await this.initialize();\n const preferredName = await this.readPreferredProfileName();\n if (preferredName) {\n try {\n const normalizedPreferred = this.normalizeProfileName(preferredName);\n const preferredRecord = await this.getProfileRowByName(normalizedPreferred);\n if (preferredRecord) {\n return { name: normalizedPreferred, trusted: true };\n }\n } catch {\n // fall through to active auth detection\n }\n }\n const activeAuth = await this.readActiveAuthFile();\n\n if (activeAuth) {\n const normalizedAuth = this.normalizeProfileData(activeAuth);\n const authMetadata = this.extractProfileMetadata(normalizedAuth);\n const workspace = this.resolveWorkspaceIdentity(normalizedAuth, authMetadata);\n const activeAccountId = this.getAccountIdFromData(normalizedAuth);\n\n if (activeAccountId) {\n const scoped = await this.getProfileRowByAccountAndWorkspace(activeAccountId, workspace.id ?? DEFAULT_WORKSPACE_ID, {\n preferAuthMethod: 'codex-cli',\n });\n if (scoped) {\n const normalized = this.normalizeProfileName(scoped.name);\n await this.persistPreferredProfileName(normalized);\n return { name: normalized, trusted: true };\n }\n\n const matching = await this.getProfileRowByAccountId(activeAccountId, { preferAuthMethod: 'codex-cli' });\n if (matching) {\n const normalized = this.normalizeProfileName(matching.name);\n await this.persistPreferredProfileName(normalized);\n return { name: normalized, trusted: true };\n }\n }\n }\n\n const preferred = await this.readPreferredProfileName();\n if (preferred) {\n try {\n const normalized = this.normalizeProfileName(preferred);\n const exists = await this.getProfileRowByName(normalized);\n if (exists) {\n return { name: normalized, trusted: true };\n }\n } catch {\n await this.persistPreferredProfileName(null);\n return { name: null, trusted: false };\n }\n await this.persistPreferredProfileName(null);\n }\n\n return { name: null, trusted: false };\n }\n\n /**\n * Export a profile to a portable format.\n * Sensitive tokens are included but should be handled securely.\n */\n async exportProfile(name: string): Promise<{\n name: string;\n displayName: string | null;\n email: string | null;\n accountId: string | null;\n workspaceId: string | null;\n workspaceName: string | null;\n authMethod: string | null;\n createdAt: string | null;\n metadata: ProfileMetadata | undefined;\n exportedAt: string;\n }> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n return {\n name: record.name,\n displayName: record.displayName,\n email: record.email,\n accountId: record.accountId,\n workspaceId: record.workspaceId,\n workspaceName: record.workspaceName,\n authMethod: record.authMethod,\n createdAt: record.createdAt,\n metadata: record.metadata,\n exportedAt: new Date().toISOString(),\n };\n }\n\n /**\n * Export all profiles to a portable format.\n */\n async exportAllProfiles(): Promise<Array<{\n name: string;\n displayName: string | null;\n email: string | null;\n accountId: string | null;\n workspaceId: string | null;\n workspaceName: string | null;\n authMethod: string | null;\n createdAt: string | null;\n metadata: ProfileMetadata | undefined;\n exportedAt: string;\n }>> {\n await this.initialize();\n const records = await this.listProfileRecords();\n const exportedAt = new Date().toISOString();\n \n return records.map(record => ({\n name: record.name,\n displayName: record.displayName,\n email: record.email,\n accountId: record.accountId,\n workspaceId: record.workspaceId,\n workspaceName: record.workspaceName,\n authMethod: record.authMethod,\n createdAt: record.createdAt,\n metadata: record.metadata,\n exportedAt,\n }));\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { logWarn } from './logger';\nimport { normalizeAutoRollSettings, type AutoRollSettings } from './auto-roll-settings';\nimport { normalizeCodexCliChannel, parseCodexCliChannel, type CodexCliChannel } from './codex-cli-channel';\n\ntype LicenseStatusCode = 'inactive' | 'active' | 'grace' | 'error';\n\ninterface StoredLicense {\n licenseKey?: string | null;\n purchaseEmail?: string | null;\n lastVerifiedAt?: string | null;\n nextCheckAt?: string | null;\n lastVerificationError?: string | null;\n status?: LicenseStatusCode;\n signature?: string | null;\n}\n\ninterface CodexSettings {\n license?: StoredLicense | null;\n lastProfileName?: string | null;\n autoRoll?: AutoRollSettings | null;\n lastAppVersion?: string | null;\n pendingUpdateVersion?: string | null;\n cliChannel?: CodexCliChannel | null;\n}\n\nconst KEY_LAST_PROFILE_NAME = 'last_profile_name';\nconst KEY_LICENSE = 'license';\nconst KEY_AUTO_ROLL = 'auto_roll';\nconst KEY_LAST_APP_VERSION = 'last_app_version';\nconst KEY_PENDING_UPDATE_VERSION = 'pending_update_version';\nconst KEY_CLI_CHANNEL = 'cli_channel';\nconst SETTINGS_FILE = 'settings.json';\nconst SETTINGS_BACKUP_FILE = 'settings.json.bak';\n\nfunction resolveCodexDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n return homeDir ? path.join(homeDir, '.codex') : '.codex';\n}\n\nfunction resolveSettingsPath(): string {\n return path.join(resolveCodexDir(), SETTINGS_FILE);\n}\n\nfunction resolveBackupSettingsPath(): string {\n return path.join(resolveCodexDir(), SETTINGS_BACKUP_FILE);\n}\n\nasync function ensureCodexDir(): Promise<void> {\n try {\n await fs.mkdir(resolveCodexDir(), { recursive: true });\n } catch (error) {\n logWarn('Failed to ensure Codex directory exists:', error);\n }\n}\n\nasync function writeAtomic(filePath: string, contents: string): Promise<void> {\n const tempPath = `${filePath}.tmp`;\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(tempPath, contents, 'utf8');\n try {\n await fs.rename(tempPath, filePath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n await fs.writeFile(filePath, contents, 'utf8');\n } else {\n throw error;\n }\n }\n try {\n await fs.rm(tempPath, { force: true });\n } catch {\n // ignore cleanup\n }\n}\n\nfunction normalizeStoredLicense(raw?: unknown): StoredLicense | null {\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n\n const source = raw as Record<string, unknown>;\n const licenseKey =\n typeof source.licenseKey === 'string'\n ? source.licenseKey\n : typeof source.license_key === 'string'\n ? source.license_key\n : null;\n const purchaseEmail =\n typeof source.purchaseEmail === 'string'\n ? source.purchaseEmail\n : typeof source.purchase_email === 'string'\n ? source.purchase_email\n : null;\n const lastVerifiedAt =\n typeof source.lastVerifiedAt === 'string'\n ? source.lastVerifiedAt\n : typeof source.last_verified_at === 'string'\n ? source.last_verified_at\n : null;\n const nextCheckAt =\n typeof source.nextCheckAt === 'string'\n ? source.nextCheckAt\n : typeof source.next_check_at === 'string'\n ? source.next_check_at\n : null;\n const lastVerificationError =\n typeof source.lastVerificationError === 'string'\n ? source.lastVerificationError\n : typeof source.last_verification_error === 'string'\n ? source.last_verification_error\n : null;\n const signature =\n typeof source.signature === 'string'\n ? source.signature\n : null;\n const statusCandidate =\n typeof source.status === 'string'\n ? (source.status as LicenseStatusCode)\n : undefined;\n\n const license: StoredLicense = {\n licenseKey,\n purchaseEmail,\n lastVerifiedAt,\n nextCheckAt,\n lastVerificationError,\n signature,\n status: statusCandidate,\n };\n\n const hasLicenseData = Boolean(\n license.licenseKey ??\n license.purchaseEmail ??\n license.lastVerifiedAt ??\n license.nextCheckAt ??\n license.lastVerificationError ??\n license.status,\n );\n\n return hasLicenseData ? license : null;\n}\n\nfunction normalizeStoredAutoRoll(raw?: unknown): AutoRollSettings | null {\n if (!raw) {\n return null;\n }\n\n const parsed = typeof raw === 'string' ? parseJsonValue(raw) : raw;\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n\n try {\n return normalizeAutoRollSettings(parsed as Partial<AutoRollSettings>);\n } catch {\n return null;\n }\n}\n\nfunction parseStoredProfileName(raw?: unknown): string | null {\n if (raw === null || raw === undefined) {\n return null;\n }\n\n if (typeof raw === 'string' || typeof raw === 'number') {\n const normalized = String(raw).trim();\n return normalized.length > 0 ? normalized : null;\n }\n\n const candidate = typeof raw === 'string' ? parseJsonValue(raw) : parseJsonValue(raw);\n if (typeof candidate === 'string' || typeof candidate === 'number') {\n const normalized = String(candidate).trim();\n return normalized.length > 0 ? normalized : null;\n }\n\n return null;\n}\n\nasync function markSettingsCorrupt(settingsPath: string, raw: string): Promise<void> {\n try {\n const suffix = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupPath = `${settingsPath}.corrupt-${suffix}`;\n await fs.writeFile(backupPath, raw, \"utf8\");\n } catch {\n // best effort backup\n }\n}\n\nasync function tryRestoreSettings(fromPath: string, _targetPath: string): Promise<CodexSettings | null> {\n try {\n const raw = await fs.readFile(fromPath, \"utf8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n const normalized = normalizeParsedSettings(parsed);\n await writeSettingsFile(normalized);\n return normalized;\n } catch {\n return null;\n }\n}\n\nfunction normalizeParsedSettings(parsed: Record<string, unknown>): CodexSettings {\n const license = normalizeStoredLicense((parsed as CodexSettings).license ?? (parsed as Record<string, unknown>)[KEY_LICENSE]);\n const autoRoll = normalizeStoredAutoRoll((parsed as CodexSettings).autoRoll ?? (parsed as Record<string, unknown>)[KEY_AUTO_ROLL]);\n const lastProfileName = parseStoredProfileName(\n (parsed as CodexSettings).lastProfileName ?? (parsed as Record<string, unknown>)[KEY_LAST_PROFILE_NAME],\n );\n const lastAppVersion =\n typeof (parsed as CodexSettings).lastAppVersion === 'string'\n ? (parsed as CodexSettings).lastAppVersion\n : typeof (parsed as Record<string, unknown>)[KEY_LAST_APP_VERSION] === 'string'\n ? (parsed as Record<string, unknown>)[KEY_LAST_APP_VERSION] as string\n : null;\n const pendingUpdateVersion =\n typeof (parsed as CodexSettings).pendingUpdateVersion === 'string'\n ? (parsed as CodexSettings).pendingUpdateVersion\n : typeof (parsed as Record<string, unknown>)[KEY_PENDING_UPDATE_VERSION] === 'string'\n ? (parsed as Record<string, unknown>)[KEY_PENDING_UPDATE_VERSION] as string\n : null;\n const cliChannel = parseCodexCliChannel(\n (parsed as CodexSettings).cliChannel ?? (parsed as Record<string, unknown>)[KEY_CLI_CHANNEL],\n );\n\n return {\n ...(license ? { license } : {}),\n ...(autoRoll ? { autoRoll } : {}),\n ...(lastProfileName ? { lastProfileName } : {}),\n ...(lastAppVersion ? { lastAppVersion } : {}),\n ...(pendingUpdateVersion ? { pendingUpdateVersion } : {}),\n ...(cliChannel ? { cliChannel } : {}),\n };\n}\n\nasync function readSettingsFromDisk(): Promise<CodexSettings | null> {\n const settingsPath = resolveSettingsPath();\n try {\n const raw = await fs.readFile(settingsPath, 'utf8');\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n return normalizeParsedSettings(parsed);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n if (error instanceof SyntaxError) {\n try {\n const raw = await fs.readFile(settingsPath, 'utf8');\n await markSettingsCorrupt(settingsPath, raw);\n\n const restoredFromTemp = await tryRestoreSettings(`${settingsPath}.tmp`, settingsPath);\n if (restoredFromTemp) {\n return restoredFromTemp;\n }\n\n const restoredFromBackup = await tryRestoreSettings(resolveBackupSettingsPath(), settingsPath);\n if (restoredFromBackup) {\n return restoredFromBackup;\n }\n\n await fs.writeFile(settingsPath, '{}\\n', 'utf8');\n } catch {\n // ignore backup/cleanup failures\n }\n }\n logWarn('Failed to parse Codex settings file, using defaults:', error);\n return null;\n }\n}\n\nasync function migrateSettingsFromDatabase(): Promise<CodexSettings | null> {\n try {\n const { __debugResolveDbPath, getDatabase } = await import('./sqlite-db');\n const dbPath = __debugResolveDbPath();\n try {\n await fs.access(dbPath);\n } catch {\n return null;\n }\n const db = await getDatabase();\n const rows = db\n .prepare(\n `SELECT key, value\n FROM app_kv\n WHERE key IN ('${KEY_LAST_PROFILE_NAME}', '${KEY_LICENSE}', '${KEY_AUTO_ROLL}', '${KEY_LAST_APP_VERSION}', '${KEY_PENDING_UPDATE_VERSION}', '${KEY_CLI_CHANNEL}')`,\n )\n .all() as Array<{ key?: string; value?: unknown }>;\n\n if (!rows || rows.length === 0) {\n return null;\n }\n\n const kv = new Map<string, unknown>();\n for (const row of rows) {\n if (!row.key) continue;\n if (typeof row.value === 'string') {\n kv.set(row.key, parseJsonValue(row.value));\n } else {\n kv.set(row.key, row.value);\n }\n }\n\n const license = normalizeStoredLicense(kv.get(KEY_LICENSE));\n const autoRoll = normalizeStoredAutoRoll(kv.get(KEY_AUTO_ROLL));\n const lastProfileName = parseStoredProfileName(kv.get(KEY_LAST_PROFILE_NAME));\n const lastAppVersion = typeof kv.get(KEY_LAST_APP_VERSION) === 'string' ? (kv.get(KEY_LAST_APP_VERSION) as string) : null;\n const pendingUpdateVersion =\n typeof kv.get(KEY_PENDING_UPDATE_VERSION) === 'string' ? (kv.get(KEY_PENDING_UPDATE_VERSION) as string) : null;\n const cliChannel = parseCodexCliChannel(kv.get(KEY_CLI_CHANNEL));\n\n const settings: CodexSettings = {\n ...(license ? { license } : {}),\n ...(autoRoll ? { autoRoll } : {}),\n ...(lastProfileName ? { lastProfileName } : {}),\n ...(lastAppVersion ? { lastAppVersion } : {}),\n ...(pendingUpdateVersion ? { pendingUpdateVersion } : {}),\n ...(cliChannel ? { cliChannel } : {}),\n };\n\n if (Object.keys(settings).length === 0) {\n return null;\n }\n\n await writeSettingsFile(settings);\n return settings;\n } catch (error) {\n logWarn('Failed to migrate Codex settings from database:', error);\n return null;\n }\n}\n\nasync function readSettingsFile(): Promise<CodexSettings> {\n await ensureCodexDir();\n\n const diskSettings = await readSettingsFromDisk();\n if (diskSettings) {\n return diskSettings;\n }\n\n const migrated = await migrateSettingsFromDatabase();\n if (migrated) {\n return migrated;\n }\n\n return {};\n}\n\nasync function writeSettingsFile(settings: CodexSettings): Promise<void> {\n await ensureCodexDir();\n const normalizedAutoRoll = settings.autoRoll ? normalizeAutoRollSettings(settings.autoRoll) : null;\n const normalizedLicense = settings.license\n ? {\n licenseKey: settings.license.licenseKey ?? null,\n purchaseEmail: settings.license.purchaseEmail ?? null,\n lastVerifiedAt: settings.license.lastVerifiedAt ?? null,\n nextCheckAt: settings.license.nextCheckAt ?? null,\n lastVerificationError: settings.license.lastVerificationError ?? null,\n status: settings.license.status ?? undefined,\n signature: settings.license.signature ?? null,\n }\n : null;\n\n const payload: CodexSettings = {\n ...(settings.lastProfileName ? { lastProfileName: settings.lastProfileName } : {}),\n ...(normalizedLicense ? { license: normalizedLicense } : {}),\n ...(normalizedAutoRoll ? { autoRoll: normalizedAutoRoll } : {}),\n ...(settings.lastAppVersion ? { lastAppVersion: settings.lastAppVersion } : {}),\n ...(settings.pendingUpdateVersion ? { pendingUpdateVersion: settings.pendingUpdateVersion } : {}),\n ...(settings.cliChannel ? { cliChannel: settings.cliChannel } : {}),\n };\n\n const serialized = JSON.stringify(payload, null, 2);\n const settingsPath = resolveSettingsPath();\n const backupPath = resolveBackupSettingsPath();\n const contents = `${serialized}\\n`;\n await writeAtomic(settingsPath, contents);\n try {\n await writeAtomic(backupPath, contents);\n } catch (error) {\n logWarn('Failed to write Codex settings backup:', error);\n }\n}\n\nfunction parseJsonValue(value?: unknown): unknown | null {\n if (typeof value !== 'string') {\n return null;\n }\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nexport async function getCodexSettings(): Promise<CodexSettings> {\n return readSettingsFile();\n}\n\nexport async function setCodexSettings(settings: CodexSettings): Promise<void> {\n await writeSettingsFile(settings);\n}\n\nexport async function getLastProfileName(): Promise<string | null> {\n const settings = await getCodexSettings();\n const candidate = settings.lastProfileName;\n if (typeof candidate !== 'string') {\n return null;\n }\n const trimmed = candidate.trim();\n return trimmed.length === 0 ? null : trimmed;\n}\n\nexport async function persistLastProfileName(profileName: string | null): Promise<void> {\n const settings = await getCodexSettings();\n if (profileName && profileName.trim().length > 0) {\n settings.lastProfileName = profileName.trim();\n } else if (settings.lastProfileName) {\n delete settings.lastProfileName;\n }\n await setCodexSettings(settings);\n}\n\nexport async function getStoredLicense(): Promise<StoredLicense | null> {\n const settings = await getCodexSettings();\n if (!settings.license) {\n return null;\n }\n return settings.license;\n}\n\nexport async function persistLicense(license: StoredLicense | null): Promise<void> {\n const settings = await getCodexSettings();\n if (license) {\n settings.license = {\n licenseKey: license.licenseKey ?? null,\n purchaseEmail: license.purchaseEmail ?? null,\n lastVerifiedAt: license.lastVerifiedAt ?? null,\n nextCheckAt: license.nextCheckAt ?? null,\n lastVerificationError: license.lastVerificationError ?? null,\n status: license.status ?? 'inactive',\n signature: license.signature ?? null,\n };\n } else if (settings.license) {\n delete settings.license;\n }\n\n await setCodexSettings(settings);\n}\n\nexport async function getStoredAutoRollSettings(): Promise<AutoRollSettings | null> {\n const settings = await getCodexSettings();\n if (!settings.autoRoll) {\n return null;\n }\n\n return normalizeAutoRollSettings(settings.autoRoll);\n}\n\nexport async function persistAutoRollSettings(settings: AutoRollSettings | null): Promise<void> {\n const current = await getCodexSettings();\n if (settings) {\n current.autoRoll = normalizeAutoRollSettings(settings);\n } else if (current.autoRoll) {\n delete current.autoRoll;\n }\n\n await setCodexSettings(current);\n}\n\nexport async function getStoredAppVersion(): Promise<string | null> {\n const settings = await getCodexSettings();\n const candidate = settings.lastAppVersion;\n if (typeof candidate !== 'string') {\n return null;\n }\n const trimmed = candidate.trim();\n return trimmed.length === 0 ? null : trimmed;\n}\n\nexport async function persistAppVersion(version: string | null): Promise<void> {\n const settings = await getCodexSettings();\n if (version && version.trim().length > 0) {\n settings.lastAppVersion = version.trim();\n } else if (settings.lastAppVersion) {\n delete settings.lastAppVersion;\n }\n\n await setCodexSettings(settings);\n}\n\nexport async function getPendingUpdateVersion(): Promise<string | null> {\n const settings = await getCodexSettings();\n const candidate = settings.pendingUpdateVersion;\n if (typeof candidate !== 'string') {\n return null;\n }\n const trimmed = candidate.trim();\n return trimmed.length === 0 ? null : trimmed;\n}\n\nexport async function persistPendingUpdateVersion(version: string | null): Promise<void> {\n const settings = await getCodexSettings();\n if (version && version.trim().length > 0) {\n settings.pendingUpdateVersion = version.trim();\n } else if (settings.pendingUpdateVersion) {\n delete settings.pendingUpdateVersion;\n }\n\n await setCodexSettings(settings);\n}\n\nexport async function getCodexCliChannel(): Promise<CodexCliChannel> {\n const settings = await getCodexSettings();\n return normalizeCodexCliChannel(settings.cliChannel);\n}\n\nexport async function persistCodexCliChannel(channel: CodexCliChannel | null): Promise<void> {\n const settings = await getCodexSettings();\n const normalized = channel ? normalizeCodexCliChannel(channel) : null;\n if (!normalized || normalized === 'stable') {\n if (settings.cliChannel) {\n delete settings.cliChannel;\n }\n } else {\n settings.cliChannel = normalized;\n }\n await setCodexSettings(settings);\n}\n\nexport type { StoredLicense, LicenseStatusCode };\nexport type { AutoRollSettings } from './auto-roll-settings';\nexport type { CodexCliChannel } from './codex-cli-channel';\n","const isTestEnv =\n process.env.NODE_ENV === 'test' ||\n process.env.VITEST === 'true' ||\n process.env.VITEST === '1';\n\nfunction isMocked(fn: unknown): boolean {\n return Boolean(fn && typeof fn === 'function' && 'mock' in (fn as Record<string, unknown>));\n}\n\nexport function logWarn(...args: Parameters<typeof console.warn>): void {\n if (isTestEnv && !isMocked(console.warn)) {\n return;\n }\n console.warn(...args);\n}\n\nexport function logError(...args: Parameters<typeof console.error>): void {\n if (isTestEnv && !isMocked(console.error)) {\n return;\n }\n console.error(...args);\n}\n\nexport function logInfo(...args: Parameters<typeof console.warn>): void {\n if (isTestEnv && !isMocked(console.warn)) {\n return;\n }\n console.warn(...args);\n}\n","export type CodexCliChannel = \"stable\" | \"alpha\";\n\nconst KNOWN_CHANNELS = new Set<CodexCliChannel>([\"stable\", \"alpha\"]);\n\nexport function parseCodexCliChannel(value?: unknown): CodexCliChannel | null {\n if (typeof value !== \"string\") {\n return null;\n }\n\n const normalized = value.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n return KNOWN_CHANNELS.has(normalized as CodexCliChannel)\n ? (normalized as CodexCliChannel)\n : null;\n}\n\nexport function normalizeCodexCliChannel(\n value?: unknown,\n fallback: CodexCliChannel = \"stable\",\n): CodexCliChannel {\n return parseCodexCliChannel(value) ?? fallback;\n}\n","import crypto from 'node:crypto';\nimport { persistLicense, getStoredLicense, type StoredLicense } from './codex-settings';\nimport { getLicenseSecret } from './license-secret';\n\nconst PRODUCT_PERMALINK = 'codex-use';\nconst PRODUCT_ID = '3_CcyVEXt2FOMiEpPx8xzw==';\nconst BASE_PRICE = 19;\nconst BASE_PRICE_DISPLAY = '$19';\nconst PROMO_CODE = 'NOELNEWYEAR50';\nconst PROMO_PERCENT = 50;\nconst PROMO_ACTIVE = true;\nconst PROMO_PRICE_DISPLAY = `$${(BASE_PRICE * (100 - PROMO_PERCENT) / 100).toFixed(2)}`;\nconst PRODUCT_URL = PROMO_ACTIVE\n ? `https://hweihwang.gumroad.com/l/${PRODUCT_PERMALINK}/${PROMO_CODE}`\n : 'https://hweihwang.gumroad.com/l/codex-use';\nconst LICENSE_PRICE_DISPLAY = PROMO_ACTIVE ? PROMO_PRICE_DISPLAY : BASE_PRICE_DISPLAY;\nconst LICENSE_MAX_USES = 5;\nconst FREE_PROFILE_LIMIT = 2;\nconst LICENSE_REFRESH_INTERVAL_MS = 5 * 60 * 1000;\nconst MAX_NEXT_CHECK_MS = 60 * 60 * 1000;\nconst GRACE_MAX_AGE_MS = 3 * 60 * 60 * 1000;\n\ntype LicenseTier = 'free' | 'pro';\ntype LicenseState = 'inactive' | 'active' | 'grace' | 'verifying' | 'error';\n\ninterface LicenseStatus {\n tier: LicenseTier;\n state: LicenseState;\n isPro: boolean;\n profileLimit: number | null;\n profilesRemaining: number | null;\n purchaseEmail: string | null;\n maskedLicenseKey: string | null;\n lastVerifiedAt: string | null;\n nextCheckAt: string | null;\n message: string | null;\n error: string | null;\n productPermalink: string;\n productUrl: string;\n productId: string;\n priceDisplay: string;\n basePriceDisplay: string;\n promoCode: string | null;\n promoPercent: number | null;\n}\n\ninterface GumroadLicenseResponse {\n success: boolean;\n message?: string;\n uses?: number;\n purchase?: {\n id: string;\n email: string;\n product_id?: string;\n product_permalink?: string;\n refunded?: boolean;\n chargebacked?: boolean;\n subscription_cancelled?: boolean;\n subscription_failed?: boolean;\n license_disabled?: boolean;\n variants?: string;\n };\n license_disabled?: boolean;\n}\n\ntype VerificationMode = 'activation' | 'refresh';\n\nclass LicenseError extends Error {\n readonly code: 'network' | 'invalid' | 'revoked';\n\n constructor(message: string, code: 'network' | 'invalid' | 'revoked') {\n super(message);\n this.name = 'LicenseError';\n this.code = code;\n }\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction maskLicenseKey(key: string | null | undefined): string | null {\n if (!key || typeof key !== 'string') {\n return null;\n }\n\n const trimmed = key.trim();\n if (trimmed.length <= 4) {\n return '••••';\n }\n\n const visible = trimmed.slice(-4);\n return `••••${visible}`;\n}\n\nfunction resolveProfilesRemaining(limit: number | null, currentProfiles: number): number | null {\n if (typeof limit !== 'number') {\n return null;\n }\n return Math.max(0, limit - currentProfiles);\n}\n\nfunction determineTierFromStored(stored: StoredLicense | null): LicenseTier {\n if (!stored || !stored.licenseKey) {\n return 'free';\n }\n\n if (stored.status === 'inactive') {\n return 'free';\n }\n\n return 'pro';\n}\n\nfunction licenseSignaturePayload(license: StoredLicense): string {\n const payload = {\n licenseKey: license.licenseKey ?? null,\n purchaseEmail: license.purchaseEmail ?? null,\n lastVerifiedAt: license.lastVerifiedAt ?? null,\n nextCheckAt: license.nextCheckAt ?? null,\n lastVerificationError: license.lastVerificationError ?? null,\n status: license.status ?? null,\n };\n return JSON.stringify(payload);\n}\n\nfunction signLicense(license: StoredLicense, secret: string): string {\n return crypto.createHmac('sha256', secret).update(licenseSignaturePayload(license)).digest('hex');\n}\n\nfunction withSignature(license: StoredLicense, secret: string): StoredLicense {\n return {\n ...license,\n signature: signLicense(license, secret),\n };\n}\n\nfunction isSignatureValid(license: StoredLicense, secret: string): boolean {\n if (!license.signature) {\n return false;\n }\n const expected = signLicense(license, secret);\n return expected === license.signature;\n}\n\nasync function requestGumroadVerify(licenseKey: string, mode: VerificationMode): Promise<GumroadLicenseResponse> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 10_000);\n\n try {\n const body = new URLSearchParams({\n product_permalink: PRODUCT_PERMALINK,\n product_id: PRODUCT_ID,\n license_key: licenseKey,\n increment_uses_count: mode === 'activation' ? 'true' : 'false',\n });\n\n const response = await fetch('https://api.gumroad.com/v2/licenses/verify', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => null);\n const message = errorText\n ? `License verification failed (${response.status}): ${errorText}`\n : `License verification failed (${response.status}).`;\n throw new LicenseError(message, 'network');\n }\n\n const json = (await response.json()) as GumroadLicenseResponse;\n return json;\n } catch (error) {\n if (error instanceof LicenseError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new LicenseError('License verification timed out.', 'network');\n }\n\n throw new LicenseError(\n error instanceof Error ? error.message : 'Unable to reach Gumroad for license verification.',\n 'network',\n );\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction normalizeVerificationResult(response: GumroadLicenseResponse): { email: string | null } {\n if (!response.success) {\n const message = response.message ?? 'License key is invalid.';\n throw new LicenseError(message, 'invalid');\n }\n\n if (!response.purchase) {\n throw new LicenseError('License verification response was incomplete.', 'network');\n }\n\n if (response.purchase.chargebacked || response.purchase.refunded || response.license_disabled) {\n throw new LicenseError('This license has been revoked or refunded.', 'revoked');\n }\n\n if (response.purchase.subscription_cancelled || response.purchase.subscription_failed) {\n throw new LicenseError('This license subscription is no longer active.', 'revoked');\n }\n\n const email = response.purchase.email ?? null;\n return { email };\n}\n\nfunction ensureWithinUseLimit(response: GumroadLicenseResponse): void {\n if (!response.success) {\n return;\n }\n\n if (typeof response.uses !== 'number') {\n return;\n }\n\n if (response.uses > LICENSE_MAX_USES) {\n throw new LicenseError(\n `This license has reached the activation limit (${LICENSE_MAX_USES}). Contact support to move it to another device.`,\n 'invalid',\n );\n }\n}\n\nfunction toLicenseStatus(stored: StoredLicense | null, overrides: Partial<LicenseStatus> = {}): LicenseStatus {\n const tier = determineTierFromStored(stored);\n const isPro = tier === 'pro';\n\n const state: LicenseState =\n stored && stored.status\n ? stored.status\n : isPro\n ? 'active'\n : 'inactive';\n\n const base: LicenseStatus = {\n tier,\n state,\n isPro,\n profileLimit: isPro ? null : FREE_PROFILE_LIMIT,\n profilesRemaining: null,\n purchaseEmail: stored?.purchaseEmail ?? null,\n maskedLicenseKey: maskLicenseKey(stored?.licenseKey),\n lastVerifiedAt: stored?.lastVerifiedAt ?? null,\n nextCheckAt: stored?.nextCheckAt ?? null,\n message: null,\n error: stored?.lastVerificationError ?? null,\n productUrl: PRODUCT_URL,\n productId: PRODUCT_ID,\n productPermalink: PRODUCT_PERMALINK,\n priceDisplay: LICENSE_PRICE_DISPLAY,\n basePriceDisplay: BASE_PRICE_DISPLAY,\n promoCode: PROMO_ACTIVE ? PROMO_CODE : null,\n promoPercent: PROMO_ACTIVE ? PROMO_PERCENT : null,\n };\n\n return { ...base, ...overrides };\n}\n\nfunction parseTimestamp(value: string | null | undefined): number | null {\n if (typeof value !== 'string' || value.trim() === '') {\n return null;\n }\n\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? null : parsed;\n}\n\nclass LicenseService {\n private cache: LicenseStatus | null = null;\n private refreshPromise: Promise<void> | null = null;\n private verificationPromise: Promise<LicenseStatus> | null = null;\n\n async getCachedStatus(): Promise<LicenseStatus> {\n return this.getStatus();\n }\n\n async getStatus(options: { forceRefresh?: boolean } = {}): Promise<LicenseStatus> {\n const forceRefresh = Boolean(options.forceRefresh);\n const secret = await getLicenseSecret();\n const stored = await getStoredLicense();\n\n if (!stored?.licenseKey) {\n const status = toLicenseStatus(null);\n this.cache = status;\n return status;\n }\n\n const now = Date.now();\n const nextCheckTs = parseTimestamp(stored.nextCheckAt);\n const lastVerifiedTs = parseTimestamp(stored.lastVerifiedAt);\n const graceStale =\n (stored.status === 'grace' || stored.status === 'error') &&\n (lastVerifiedTs === null || lastVerifiedTs + GRACE_MAX_AGE_MS < now);\n\n let workingStored: StoredLicense = { ...stored };\n const signatureValid = isSignatureValid(workingStored, secret);\n\n let cappedNextCheckTs = nextCheckTs;\n\n if (nextCheckTs !== null && nextCheckTs > now + MAX_NEXT_CHECK_MS) {\n cappedNextCheckTs = now;\n const updated = {\n ...workingStored,\n nextCheckAt: new Date(cappedNextCheckTs).toISOString(),\n };\n const signed = withSignature(updated, secret);\n workingStored = signed;\n await persistLicense(signed);\n }\n\n const tampered = Boolean(workingStored.licenseKey) && !signatureValid;\n\n const cached = tampered\n ? toLicenseStatus(null, {\n state: 'verifying',\n message: 'License data changed, rechecking.',\n error: 'Untrusted license data.',\n })\n : toLicenseStatus(workingStored);\n this.cache = cached;\n\n const shouldRefresh =\n forceRefresh || graceStale || tampered || cappedNextCheckTs === null || cappedNextCheckTs <= now;\n\n if (!shouldRefresh) {\n return cached;\n }\n\n if (this.verificationPromise && !forceRefresh) {\n return this.verificationPromise;\n }\n\n const verify = async (): Promise<LicenseStatus> => {\n try {\n const result = await requestGumroadVerify(workingStored.licenseKey!, 'refresh');\n ensureWithinUseLimit(result);\n const normalized = normalizeVerificationResult(result);\n const updated: StoredLicense = {\n licenseKey: workingStored.licenseKey,\n purchaseEmail: normalized.email,\n lastVerifiedAt: nowIso(),\n nextCheckAt: new Date(Date.now() + LICENSE_REFRESH_INTERVAL_MS).toISOString(),\n status: 'active',\n lastVerificationError: null,\n };\n\n const signed = withSignature(updated, secret);\n\n await persistLicense(signed);\n const status = toLicenseStatus(signed);\n this.cache = status;\n return status;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'License verification failed.';\n\n if (error instanceof LicenseError && error.code === 'network') {\n const fallbackStored: StoredLicense = withSignature(\n {\n ...workingStored,\n status: tampered ? 'inactive' : workingStored.status === 'inactive' ? 'inactive' : 'grace',\n lastVerificationError: message,\n nextCheckAt: new Date(Date.now() + LICENSE_REFRESH_INTERVAL_MS).toISOString(),\n },\n secret,\n );\n await persistLicense(fallbackStored);\n const fallback = toLicenseStatus(fallbackStored, {\n state: fallbackStored.status ?? 'grace',\n error: message,\n });\n this.cache = fallback;\n return fallback;\n }\n\n const fallbackStored: StoredLicense = withSignature({\n licenseKey: workingStored.licenseKey,\n purchaseEmail: workingStored.purchaseEmail ?? null,\n lastVerifiedAt: workingStored.lastVerifiedAt ?? null,\n nextCheckAt: null,\n status: 'inactive',\n lastVerificationError: message,\n }, secret);\n await persistLicense(fallbackStored);\n const fallback = toLicenseStatus(fallbackStored, { error: message });\n this.cache = fallback;\n return fallback;\n }\n };\n\n this.verificationPromise = verify();\n try {\n return await this.verificationPromise;\n } finally {\n this.verificationPromise = null;\n }\n }\n\n async activate(licenseKey: string): Promise<LicenseStatus> {\n const trimmed = licenseKey.trim();\n if (!trimmed) {\n throw new Error('License key is required.');\n }\n\n const secret = await getLicenseSecret();\n const digest = crypto.createHash('sha256').update(trimmed).digest('hex');\n\n const result = await requestGumroadVerify(trimmed, 'activation');\n ensureWithinUseLimit(result);\n const normalized = normalizeVerificationResult(result);\n const stored: StoredLicense = {\n licenseKey: trimmed,\n purchaseEmail: normalized.email,\n lastVerifiedAt: nowIso(),\n nextCheckAt: new Date(Date.now() + LICENSE_REFRESH_INTERVAL_MS).toISOString(),\n status: 'active',\n lastVerificationError: null,\n };\n\n const signed = withSignature(stored, secret);\n\n await persistLicense(signed);\n const status = toLicenseStatus(signed, {\n message: `License verified (${digest.slice(0, 8)}).`,\n });\n this.cache = status;\n return status;\n }\n\n applyProfileCount(status: LicenseStatus, profileCount: number): LicenseStatus {\n const profilesRemaining = resolveProfilesRemaining(status.profileLimit, profileCount);\n return {\n ...status,\n profilesRemaining,\n };\n }\n\n refreshStatusInBackground(options: { force?: boolean } = {}): void {\n if (this.refreshPromise) {\n return;\n }\n\n const forceRefresh = Boolean(options.force);\n this.refreshPromise = (async () => {\n try {\n await this.getStatus({ forceRefresh });\n } catch (error) {\n console.warn('Background license refresh failed:', error);\n } finally {\n this.refreshPromise = null;\n }\n })();\n }\n}\n\nexport const licenseService = new LicenseService();\nexport type { LicenseStatus, LicenseTier, LicenseState };\nexport { FREE_PROFILE_LIMIT, LICENSE_PRICE_DISPLAY, PRODUCT_PERMALINK, PRODUCT_URL, PRODUCT_ID };\n\nfunction isExplicitInvalidation(message: string | null | undefined): boolean {\n if (!message) {\n return false;\n }\n const normalized = message.toLowerCase();\n return (\n normalized.includes('revoked') ||\n normalized.includes('refunded') ||\n normalized.includes('invalid') ||\n normalized.includes('no longer active')\n );\n}\n\n/**\n * Determines when it is safe to enforce profile limits (e.g., pruning).\n * We skip enforcement when the license state is uncertain (grace/error/verifying)\n * and only enforce limits for true free/unlicensed states or explicit revocations.\n */\nexport function shouldEnforceProfileLimit(status: LicenseStatus): boolean {\n if (status.isPro) {\n return false;\n }\n\n if (status.state === 'grace' || status.state === 'verifying' || status.state === 'error') {\n return false;\n }\n\n if (isExplicitInvalidation(status.error)) {\n return true;\n }\n\n return status.state === 'inactive';\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\n\nconst SECRET_FILE = 'license.secret';\n\nfunction resolveCodexDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n return homeDir ? path.join(homeDir, '.codex') : '.codex';\n}\n\nfunction resolveSecretPath(): string {\n return path.join(resolveCodexDir(), SECRET_FILE);\n}\n\nasync function generateSecret(): Promise<string> {\n return crypto.randomBytes(32).toString('hex');\n}\n\nexport async function getLicenseSecret(): Promise<string> {\n const secretPath = resolveSecretPath();\n try {\n const existing = await fs.readFile(secretPath, 'utf8');\n const trimmed = existing.trim();\n if (trimmed.length > 0) {\n return trimmed;\n }\n } catch {\n // fall through and create a new secret\n }\n\n const secret = await generateSecret();\n try {\n await fs.mkdir(path.dirname(secretPath), { recursive: true });\n } catch {\n // best effort\n }\n\n await fs.writeFile(secretPath, `${secret}\\n`, { mode: 0o600 });\n return secret;\n}\n","import { licenseService } from \"./license-service\";\nimport { ProfileManager } from \"./profile-manager\";\n\nexport async function assertProfileCreationAllowed(\n profileManager?: ProfileManager,\n): Promise<void> {\n const manager = profileManager ?? new ProfileManager();\n await manager.initialize();\n\n const license = await licenseService.getStatus();\n const profiles = await manager.listProfiles();\n const licenseWithCounts = licenseService.applyProfileCount(license, profiles.length);\n\n if (\n typeof licenseWithCounts.profileLimit === \"number\" &&\n licenseWithCounts.profilesRemaining !== null &&\n licenseWithCounts.profilesRemaining <= 0\n ) {\n throw new Error(\"CodexUse Free supports up to 2 profiles. Upgrade to CodexUse Pro for unlimited profiles.\");\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst ENV_HINTS = [\"CODEX_BINARY\", \"CODEX_CLI_PATH\", \"CODEX_PATH\"] as const;\nconst NODE_MODULE_CANDIDATES = [\n [\"@openai\", \"codex\"],\n [\"@openai\", \"codex-alpha\"],\n];\n\nfunction fileExists(candidate: string | null | undefined): string | null {\n if (!candidate) return null;\n const resolved = path.resolve(candidate);\n try {\n const stat = statSync(resolved);\n if (stat.isFile()) return resolved;\n } catch {\n return null;\n }\n return null;\n}\n\nfunction resolveFromEnv(): string | null {\n for (const key of ENV_HINTS) {\n const value = process.env[key];\n if (!value) continue;\n const resolved = fileExists(value);\n if (resolved) return resolved;\n }\n return null;\n}\n\nfunction resolveFromAppResources(): string | null {\n const roots = [\n path.resolve(__dirname, \"..\"),\n path.resolve(__dirname, \"..\", \"..\"),\n ];\n\n for (const root of roots) {\n const base = path.join(root, \"app.asar.unpacked\", \"node_modules\");\n for (const segments of NODE_MODULE_CANDIDATES) {\n const candidate = fileExists(path.join(base, ...segments, \"bin\", \"codex\"));\n if (candidate) return candidate;\n const jsCandidate = fileExists(path.join(base, ...segments, \"bin\", \"codex.js\"));\n if (jsCandidate) return jsCandidate;\n }\n }\n\n return null;\n}\n\nfunction resolveFromNodeModules(): string | null {\n let current = path.resolve(__dirname, \"..\");\n let last = \"\";\n\n while (current !== last) {\n for (const segments of NODE_MODULE_CANDIDATES) {\n const candidate = fileExists(path.join(current, \"node_modules\", ...segments, \"bin\", \"codex\"));\n if (candidate) return candidate;\n const jsCandidate = fileExists(path.join(current, \"node_modules\", ...segments, \"bin\", \"codex.js\"));\n if (jsCandidate) return jsCandidate;\n }\n last = current;\n current = path.dirname(current);\n }\n\n return null;\n}\n\nfunction resolveFromPath(): string | null {\n const pathValue = process.env.PATH ?? \"\";\n const entries = pathValue.split(path.delimiter).filter(Boolean);\n const names = process.platform === \"win32\"\n ? [\"codex.exe\", \"codex.cmd\", \"codex.bat\", \"codex\"]\n : [\"codex\"];\n\n for (const entry of entries) {\n for (const name of names) {\n const candidate = fileExists(path.join(entry, name));\n if (candidate) return candidate;\n }\n }\n\n return null;\n}\n\nexport function resolveCodexBinary(): string | null {\n return (\n resolveFromEnv() ||\n resolveFromAppResources() ||\n resolveFromNodeModules() ||\n resolveFromPath()\n );\n}\n\nexport function requireCodexBinary(context?: string): string {\n const resolved = resolveCodexBinary();\n if (resolved) return resolved;\n const hint = \"Install Codex CLI (npm i -g @openai/codex) or set CODEX_BINARY.\";\n const message = context ? `${context} ${hint}` : hint;\n throw new Error(message);\n}\n\nfunction buildCodexCommand(codexPath: string, args: string[]): { command: string; args: string[]; shell: boolean } {\n const normalized = codexPath.toLowerCase();\n const isJs = normalized.endsWith(\".js\");\n if (isJs) {\n return { command: process.execPath, args: [codexPath, ...args], shell: false };\n }\n\n const useShell = process.platform === \"win32\";\n return { command: codexPath, args, shell: useShell };\n}\n\nexport async function runCodexLogin(): Promise<void> {\n const codexPath = requireCodexBinary(\"Codex CLI is required to login.\");\n const { command, args, shell } = buildCodexCommand(codexPath, [\"login\"]);\n\n const child = spawn(command, args, {\n stdio: \"inherit\",\n env: process.env,\n shell,\n });\n\n const exitCode = await new Promise<number>((resolve) => {\n child.on(\"close\", (code) => resolve(code ?? 0));\n });\n\n if (exitCode !== 0) {\n throw new Error(`Codex CLI login failed (exit code ${exitCode}).`);\n }\n}\n","import { ProfileManager } from \"../../../lib/profile-manager\";\nimport { licenseService } from \"../../../lib/license-service\";\nimport { assertProfileCreationAllowed } from \"../../../lib/license-guard\";\nimport { runCodexLogin } from \"./codex-cli\";\n\ndeclare const __CODEXUSE_CLI_VERSION__: string;\n\nconst VERSION = typeof __CODEXUSE_CLI_VERSION__ === \"string\"\n ? __CODEXUSE_CLI_VERSION__\n : \"0.0.0\";\n\nfunction printHelp(): void {\n console.log(`CodexUse CLI v${VERSION}\n\nUsage:\n codexuse profile list\n codexuse profile current\n codexuse profile add <name> [--skip-login]\n codexuse profile refresh <name> [--skip-login]\n codexuse profile switch <name>\n codexuse profile delete <name>\n codexuse profile rename <old> <new>\n\n codexuse license status [--refresh]\n codexuse license activate <license-key>\n\nFlags:\n -h, --help Show help\n -v, --version Show version\n`);\n}\n\nfunction hasFlag(args: string[], flag: string): boolean {\n return args.includes(flag);\n}\n\nfunction stripFlags(args: string[]): string[] {\n return args.filter(arg => !arg.startsWith(\"-\"));\n}\n\nfunction formatProfileLabel(name: string, displayName?: string | null): string {\n if (displayName && displayName.trim() && displayName !== name) {\n return `${displayName} (${name})`;\n }\n return name;\n}\n\nasync function handleProfile(args: string[]): Promise<void> {\n const flags = args.filter(arg => arg.startsWith(\"-\"));\n const params = stripFlags(args);\n const sub = params[0];\n\n if (!sub || hasFlag(flags, \"--help\") || hasFlag(flags, \"-h\")) {\n printHelp();\n return;\n }\n\n const manager = new ProfileManager();\n\n switch (sub) {\n case \"list\": {\n const profiles = await manager.listProfiles();\n const current = await manager.getCurrentProfile();\n if (!profiles.length) {\n console.log(\"No profiles found.\");\n return;\n }\n for (const profile of profiles) {\n const marker = current.name === profile.name ? \"*\" : \" \";\n const label = formatProfileLabel(profile.name, profile.displayName);\n console.log(`${marker} ${label}`);\n }\n return;\n }\n case \"current\": {\n const current = await manager.getCurrentProfile();\n if (!current.name) {\n console.log(\"No active profile.\");\n return;\n }\n console.log(current.name);\n return;\n }\n case \"add\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n await assertProfileCreationAllowed(manager);\n if (!hasFlag(flags, \"--skip-login\")) {\n await runCodexLogin();\n }\n const profile = await manager.createProfile(name);\n const label = profile ? formatProfileLabel(profile.name, profile.displayName) : name;\n console.log(`Profile created: ${label}`);\n return;\n }\n case \"refresh\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n if (!hasFlag(flags, \"--skip-login\")) {\n await runCodexLogin();\n }\n const profile = await manager.refreshProfileAuth(name);\n const label = formatProfileLabel(profile.name, profile.displayName);\n console.log(`Profile refreshed: ${label}`);\n return;\n }\n case \"switch\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n await manager.switchToProfile(name);\n console.log(`Switched to profile: ${name}`);\n return;\n }\n case \"delete\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n await manager.deleteProfile(name);\n console.log(`Profile deleted: ${name}`);\n return;\n }\n case \"rename\": {\n const from = params[1];\n const to = params[2];\n if (!from || !to) {\n throw new Error(\"Old and new profile names are required.\");\n }\n await manager.renameProfile(from, to);\n console.log(`Profile renamed: ${from} -> ${to}`);\n return;\n }\n default:\n printHelp();\n return;\n }\n}\n\nasync function handleLicense(args: string[]): Promise<void> {\n const flags = args.filter(arg => arg.startsWith(\"-\"));\n const params = stripFlags(args);\n const sub = params[0];\n\n if (!sub || hasFlag(flags, \"--help\") || hasFlag(flags, \"-h\")) {\n printHelp();\n return;\n }\n\n switch (sub) {\n case \"status\": {\n const forceRefresh = hasFlag(flags, \"--refresh\");\n const status = await licenseService.getStatus({ forceRefresh });\n console.log(`Tier: ${status.tier}`);\n console.log(`State: ${status.state}`);\n if (status.profileLimit !== null) {\n console.log(`Profile limit: ${status.profileLimit}`);\n }\n if (status.profilesRemaining !== null) {\n console.log(`Profiles remaining: ${status.profilesRemaining}`);\n }\n if (status.purchaseEmail) {\n console.log(`Email: ${status.purchaseEmail}`);\n }\n if (status.maskedLicenseKey) {\n console.log(`License: ${status.maskedLicenseKey}`);\n }\n if (status.message) {\n console.log(`Message: ${status.message}`);\n }\n if (status.error) {\n console.log(`Error: ${status.error}`);\n }\n return;\n }\n case \"activate\": {\n const key = params[1];\n if (!key) {\n throw new Error(\"License key is required.\");\n }\n const status = await licenseService.activate(key);\n console.log(status.message ?? \"License activated.\");\n return;\n }\n default:\n printHelp();\n return;\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || hasFlag(args, \"--help\") || hasFlag(args, \"-h\")) {\n printHelp();\n return;\n }\n\n if (hasFlag(args, \"--version\") || hasFlag(args, \"-v\")) {\n console.log(VERSION);\n return;\n }\n\n const command = args[0];\n const rest = args.slice(1);\n\n switch (command) {\n case \"profile\":\n await handleProfile(rest);\n return;\n case \"license\":\n await handleLicense(rest);\n return;\n default:\n printHelp();\n return;\n }\n}\n\nmain().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["path","require","initSqlJs","fsPromises","import_path","import_node_fs","import_node_path","path","fs","__debugResolveDbPath","getDatabase","fs","getDatabase","path","import_node_crypto","import_node_fs","import_node_path","resolveCodexDir","path","crypto","fs","crypto","fallbackStored","fallback","import_node_fs","import_node_path","path"]}
1
+ {"version":3,"sources":["../../../lib/auto-roll-settings.ts","../../../lib/sqlite-db.ts","../../../lib/profile-manager.ts","../../../lib/codex-settings.ts","../../../lib/logger.ts","../../../lib/codex-cli-channel.ts","../../../lib/license-service.ts","../../../lib/license-secret.ts","../../../lib/license-guard.ts","../src/codex-cli.ts","../../../lib/codex-rpc.ts","../../../lib/codex-cli.ts","../../../lib/rate-limit-notifier.ts","../src/index.ts"],"sourcesContent":["export interface AutoRollSettings {\n enabled: boolean;\n warningThreshold: number;\n switchThreshold: number;\n}\n\nexport const DEFAULT_AUTO_ROLL_ENABLED = false;\nexport const DEFAULT_AUTO_ROLL_WARNING_THRESHOLD = 85;\nexport const DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD = 95;\nexport const AUTO_ROLL_WARNING_MIN = 50;\n\nfunction clampNumber(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/**\n * Normalize partial auto-roll settings into a safe shape with bounds.\n * Ensures switch threshold is always above warning and both live within [50, 100].\n */\nexport function normalizeAutoRollSettings(\n raw?: Partial<AutoRollSettings> | null,\n): AutoRollSettings {\n const enabled = typeof raw?.enabled === 'boolean' ? raw.enabled : DEFAULT_AUTO_ROLL_ENABLED;\n const rawWarning =\n typeof raw?.warningThreshold === 'number' && Number.isFinite(raw.warningThreshold)\n ? raw.warningThreshold\n : DEFAULT_AUTO_ROLL_WARNING_THRESHOLD;\n const rawSwitch =\n typeof raw?.switchThreshold === 'number' && Number.isFinite(raw.switchThreshold)\n ? raw.switchThreshold\n : DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD;\n\n // First clamp warning to valid range, then ensure switch is above it\n const normalizedWarning = clampNumber(rawWarning, AUTO_ROLL_WARNING_MIN, 99);\n const normalizedSwitch = clampNumber(rawSwitch, normalizedWarning + 1, 100);\n\n return {\n enabled,\n warningThreshold: normalizedWarning,\n switchThreshold: normalizedSwitch,\n };\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync, promises as fsPromises, statSync } from 'node:fs';\n\nimport path from 'node:path';\nimport { createRequire } from 'node:module';\nimport initSqlJs, {\n type Database as SqlJsDatabase,\n type Statement as SqlJsStatement,\n type SqlJsStatic,\n} from 'sql.js';\nimport {\n DEFAULT_AUTO_ROLL_ENABLED,\n DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD,\n DEFAULT_AUTO_ROLL_WARNING_THRESHOLD,\n} from './auto-roll-settings';\n\ninterface SqliteRunResult {\n changes: number;\n}\n\nexport interface SqliteStatement {\n get(...params: unknown[]): Record<string, unknown> | undefined;\n all(...params: unknown[]): Array<Record<string, unknown>>;\n run(...params: unknown[]): SqliteRunResult;\n}\n\nexport interface SqliteDatabase {\n readonly open: boolean;\n prepare(sql: string): SqliteStatement;\n close(): void;\n}\n\nconst require = createRequire(__filename);\nconst wasmDir = path.dirname(require.resolve('sql.js/dist/sql-wasm.wasm'));\nconst sqlModulePromise: Promise<SqlJsStatic> = initSqlJs({\n locateFile: (file: string) => path.join(wasmDir, file),\n});\n\nclass SqliteWasmDatabase implements SqliteDatabase {\n private closed = false;\n\n constructor(private readonly driver: SqlJsDatabase, private readonly dbPath: string) { }\n\n get open(): boolean {\n return !this.closed;\n }\n\n prepare(sql: string): SqliteStatement {\n this.assertOpen();\n return new SqliteWasmStatement(this, sql);\n }\n\n createStatement(sql: string): SqlJsStatement {\n this.assertOpen();\n return this.driver.prepare(sql);\n }\n\n exec(sql: string): void {\n this.assertOpen();\n this.driver.exec(sql);\n }\n\n getRowsModified(): number {\n this.assertOpen();\n return this.driver.getRowsModified();\n }\n\n private persistTimeout: NodeJS.Timeout | null = null;\n\n async persist(): Promise<void> {\n this.assertOpen();\n ensureStorageDirExists(this.dbPath);\n\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n }\n\n this.persistTimeout = setTimeout(async () => {\n try {\n const contents = Buffer.from(this.driver.export());\n await fsPromises.writeFile(this.dbPath, contents);\n this.persistTimeout = null;\n } catch (error) {\n console.error('Failed to persist database:', error);\n }\n }, 500);\n }\n\n close(): void {\n if (!this.closed) {\n // Synchronously flush any pending writes before closing\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n try {\n const contents = Buffer.from(this.driver.export());\n writeFileSync(this.dbPath, contents);\n } catch (error) {\n // Silently ignore ENOENT errors (directory already cleaned up, e.g., in tests)\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error('Failed to flush database on close:', error);\n }\n }\n }\n this.driver.close();\n this.closed = true;\n }\n }\n\n async flushPersistence(): Promise<void> {\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n try {\n const contents = Buffer.from(this.driver.export());\n await fsPromises.writeFile(this.dbPath, contents);\n } catch (error) {\n console.error('Failed to flush database persistence:', error);\n }\n }\n }\n\n private assertOpen(): void {\n if (!this.open) {\n throw new Error('SQLite database connection is closed.');\n }\n }\n}\n\nexport async function flushDatabase(): Promise<void> {\n if (globalCache.cachedDbPromise) {\n const db = await globalCache.cachedDbPromise;\n // We know it's SqliteWasmDatabase in this implementation\n if (db instanceof SqliteWasmDatabase) {\n await db.flushPersistence();\n }\n }\n}\n\nclass SqliteWasmStatement implements SqliteStatement {\n constructor(private readonly database: SqliteWasmDatabase, private readonly sql: string) { }\n\n get(...params: unknown[]): Record<string, unknown> | undefined {\n const statement = this.database.createStatement(this.sql);\n try {\n bindParameters(statement, params);\n if (!statement.step()) {\n return undefined;\n }\n return statement.getAsObject();\n } finally {\n statement.free();\n }\n }\n\n all(...params: unknown[]): Array<Record<string, unknown>> {\n const rows: Array<Record<string, unknown>> = [];\n const statement = this.database.createStatement(this.sql);\n try {\n bindParameters(statement, params);\n while (statement.step()) {\n rows.push(statement.getAsObject());\n }\n } finally {\n statement.free();\n }\n return rows;\n }\n\n run(...params: unknown[]): SqliteRunResult {\n const statement = this.database.createStatement(this.sql);\n try {\n bindParameters(statement, params);\n // Execute statement once; INSERT/UPDATE statements don't produce rows.\n statement.step();\n } finally {\n statement.free();\n }\n const changes = this.database.getRowsModified();\n void this.database.persist();\n return { changes };\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeNamedParameters(params: Record<string, unknown>): Record<string, unknown> {\n const normalized: Record<string, unknown> = {};\n for (const [key, rawValue] of Object.entries(params)) {\n if (key.startsWith('@') || key.startsWith(':') || key.startsWith('$')) {\n normalized[key] = rawValue;\n } else {\n normalized[`@${key}`] = rawValue;\n }\n }\n return normalized;\n}\n\nfunction bindParameters(statement: SqlJsStatement, args: unknown[]): void {\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && isPlainObject(args[0])) {\n statement.bind(normalizeNamedParameters(args[0]));\n return;\n }\n\n statement.bind(args as unknown[]);\n}\n\ntype SqliteCache = {\n cachedDbPath: string | null;\n cachedDbPromise: Promise<SqliteWasmDatabase> | null;\n};\n\nconst STORAGE_DIRECTORY_NAME = '.f86eb5e712267207';\nconst STORAGE_FILENAME = 'state-d64ce728d7a20214.sqlite';\n\nconst GLOBAL_CACHE_KEY = Symbol.for('codex.sqliteCache');\nconst globalCache: SqliteCache =\n (globalThis as Record<symbol, SqliteCache>)[GLOBAL_CACHE_KEY] ??\n ((globalThis as Record<symbol, SqliteCache>)[GLOBAL_CACHE_KEY] = {\n cachedDbPath: null,\n cachedDbPromise: null,\n });\n\nfunction resolveHomeDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE;\n if (!homeDir) {\n throw new Error('HOME directory is not set. Unable to initialize CodexUse storage.');\n }\n return homeDir;\n}\n\nfunction resolveStorageDirectory(): string {\n return path.join(resolveHomeDir(), STORAGE_DIRECTORY_NAME);\n}\n\nfunction resolveDbPath(): string {\n return path.join(resolveStorageDirectory(), STORAGE_FILENAME);\n}\n\nfunction ensureStorageDirExists(targetPath: string): void {\n mkdirSync(path.dirname(targetPath), { recursive: true });\n}\n\nasync function instantiateDatabase(dbPath: string): Promise<SqliteWasmDatabase> {\n try {\n const bakPath = `${dbPath}.bak`;\n if (existsSync(dbPath)) {\n const size = statSync(dbPath).size;\n if (size < 1024 && existsSync(bakPath)) {\n const bakSize = statSync(bakPath).size;\n if (bakSize > size) {\n const backup = readFileSync(bakPath);\n writeFileSync(dbPath, backup);\n console.warn(\"Detected near-empty SQLite file; restored from backup.\");\n }\n }\n }\n } catch (error) {\n console.warn(\"Failed to check/restore SQLite backup:\", error);\n }\n\n const SQL = await sqlModulePromise;\n let fileBuffer: Uint8Array | undefined;\n if (existsSync(dbPath)) {\n fileBuffer = new Uint8Array(readFileSync(dbPath));\n }\n const driver = fileBuffer ? new SQL.Database(fileBuffer) : new SQL.Database();\n const database = new SqliteWasmDatabase(driver, dbPath);\n database.exec('PRAGMA journal_mode = WAL;');\n database.exec('PRAGMA foreign_keys = ON;');\n runMigrations(database);\n database.persist();\n return database;\n}\n\nfunction readUserVersion(database: SqliteWasmDatabase): number {\n const result = database.prepare('PRAGMA user_version').get();\n const version = result?.user_version;\n return typeof version === 'number' ? version : 0;\n}\n\nfunction ensureChatTables(database: SqliteWasmDatabase): void {\n database.exec(`\n PRAGMA foreign_keys = ON;\n\n CREATE TABLE IF NOT EXISTS chat_threads (\n thread_key TEXT PRIMARY KEY,\n title TEXT,\n account_id TEXT,\n profile_name TEXT,\n project_label TEXT,\n project_path TEXT,\n source_path TEXT,\n started_at TEXT,\n ended_at TEXT,\n last_message_at TEXT,\n message_count INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS chat_messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n thread_key TEXT NOT NULL,\n role TEXT,\n content TEXT NOT NULL,\n account_id TEXT,\n profile_name TEXT,\n created_at TEXT,\n FOREIGN KEY(thread_key) REFERENCES chat_threads(thread_key) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_chat_messages_thread ON chat_messages(thread_key);\n CREATE INDEX IF NOT EXISTS idx_chat_messages_created ON chat_messages(created_at);\n\n CREATE TABLE IF NOT EXISTS chat_ingest_offsets (\n file_path TEXT PRIMARY KEY,\n offset INTEGER NOT NULL,\n mtime_ms INTEGER NOT NULL,\n size INTEGER NOT NULL\n );\n `);\n}\n\nfunction ensureSessionTables(database: SqliteWasmDatabase): void {\n database.exec(`\n PRAGMA foreign_keys = ON;\n\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n title TEXT,\n status TEXT,\n model TEXT,\n project_label TEXT,\n project_path TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n last_message_at TEXT\n );\n\n CREATE TABLE IF NOT EXISTS tool_panels (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n type TEXT NOT NULL,\n title TEXT,\n state TEXT,\n metadata TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY(session_id) REFERENCES sessions(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_tool_panels_session ON tool_panels(session_id);\n CREATE INDEX IF NOT EXISTS idx_tool_panels_type ON tool_panels(type);\n\n CREATE TABLE IF NOT EXISTS panel_outputs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n panel_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n type TEXT NOT NULL,\n data TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY(panel_id) REFERENCES tool_panels(id) ON DELETE CASCADE,\n FOREIGN KEY(session_id) REFERENCES sessions(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_panel_outputs_panel ON panel_outputs(panel_id);\n CREATE INDEX IF NOT EXISTS idx_panel_outputs_session ON panel_outputs(session_id);\n CREATE INDEX IF NOT EXISTS idx_panel_outputs_created ON panel_outputs(created_at);\n\n CREATE TABLE IF NOT EXISTS notes (\n id TEXT PRIMARY KEY,\n user_id TEXT,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n tags TEXT,\n is_favorited INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n synced_at TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_notes_user ON notes(user_id);\n CREATE INDEX IF NOT EXISTS idx_notes_updated ON notes(updated_at);\n `);\n}\n\nfunction ensureUsageTables(database: SqliteWasmDatabase): void {\n database.exec(`\n CREATE TABLE IF NOT EXISTS usage (\n session_id TEXT PRIMARY KEY,\n rollout_path TEXT NOT NULL,\n project_path TEXT,\n model TEXT,\n input_tokens INTEGER NOT NULL,\n cached_input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n reasoning_output_tokens INTEGER NOT NULL,\n total_tokens INTEGER NOT NULL,\n timestamp TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_usage_timestamp ON usage(timestamp);\n `);\n}\n\nfunction runMigrations(database: SqliteWasmDatabase): void {\n let userVersion = readUserVersion(database);\n\n if (userVersion < 1) {\n database.exec(`\n CREATE TABLE IF NOT EXISTS profiles (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n data TEXT NOT NULL,\n account_id TEXT,\n workspace_id TEXT,\n workspace_name TEXT,\n email TEXT,\n auth_method TEXT,\n created_at TEXT,\n updated_at TEXT\n );\n\n CREATE UNIQUE INDEX IF NOT EXISTS idx_profiles_account_workspace\n ON profiles(account_id, workspace_id)\n WHERE account_id IS NOT NULL;\n\n PRAGMA user_version = 1;\n `);\n userVersion = 1;\n }\n\n if (userVersion < 2) {\n database.exec(`PRAGMA user_version = 2;`);\n userVersion = 2;\n }\n\n if (userVersion < 3) {\n database.exec(`PRAGMA user_version = 3;`);\n userVersion = 3;\n }\n\n if (userVersion < 4) {\n let legacySettings: Record<string, unknown> | null = null;\n\n try {\n const hasKvStore = Boolean(\n database.prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'kv_store'\",\n ).get() as { name?: string } | undefined,\n );\n if (hasKvStore) {\n const row = database\n .prepare(\"SELECT value FROM kv_store WHERE key = 'settings'\")\n .get() as { value?: string } | undefined;\n if (row?.value) {\n const parsed = JSON.parse(row.value) as Record<string, unknown>;\n if (parsed && typeof parsed === 'object') {\n legacySettings = parsed;\n }\n }\n }\n } catch (error) {\n console.warn(\"Failed to read legacy Codex settings:\", error);\n }\n\n database.exec(`\n PRAGMA foreign_keys = OFF;\n\n DROP TABLE IF EXISTS rate_limit_snapshots;\n DROP TABLE IF EXISTS chat_messages;\n DROP TABLE IF EXISTS chat_threads;\n DROP TABLE IF EXISTS kv_store;\n\n CREATE TABLE IF NOT EXISTS app_settings (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n last_profile_name TEXT,\n license_key TEXT,\n purchase_email TEXT,\n last_verified_at TEXT,\n next_check_at TEXT,\n last_verification_error TEXT,\n status TEXT\n );\n\n INSERT OR IGNORE INTO app_settings (id) VALUES (1);\n\n PRAGMA foreign_keys = ON;\n `);\n\n if (legacySettings) {\n const license = legacySettings.license as Record<string, unknown> | undefined;\n database.prepare(\n `UPDATE app_settings\n SET last_profile_name = @lastProfileName,\n license_key = @licenseKey,\n purchase_email = @purchaseEmail,\n last_verified_at = @lastVerifiedAt,\n next_check_at = @nextCheckAt,\n last_verification_error = @lastVerificationError,\n status = @status\n WHERE id = 1`,\n ).run({\n lastProfileName: typeof legacySettings.lastProfileName === 'string'\n ? legacySettings.lastProfileName\n : null,\n licenseKey: license && typeof license.licenseKey === 'string' ? license.licenseKey : null,\n purchaseEmail: license && typeof license.purchaseEmail === 'string' ? license.purchaseEmail : null,\n lastVerifiedAt: license && typeof license.lastVerifiedAt === 'string' ? license.lastVerifiedAt : null,\n nextCheckAt: license && typeof license.nextCheckAt === 'string' ? license.nextCheckAt : null,\n lastVerificationError:\n license && typeof license.lastVerificationError === 'string'\n ? license.lastVerificationError\n : null,\n status: license && typeof license.status === 'string' ? license.status : null,\n });\n }\n\n database.exec(`PRAGMA user_version = 4;`);\n userVersion = 4;\n }\n\n if (userVersion < 5) {\n database.exec(`\n ALTER TABLE app_settings ADD COLUMN auto_roll_enabled INTEGER;\n ALTER TABLE app_settings ADD COLUMN auto_roll_warning_threshold INTEGER;\n ALTER TABLE app_settings ADD COLUMN auto_roll_switch_threshold INTEGER;\n\n PRAGMA user_version = 5;\n `);\n userVersion = 5;\n }\n\n if (userVersion < 6) {\n database.exec(`\n CREATE TABLE IF NOT EXISTS app_kv (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n\n let appSettingsRow: Record<string, unknown> | null = null;\n try {\n const hasAppSettings = Boolean(\n database.prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'app_settings'\",\n ).get() as { name?: string } | undefined,\n );\n if (hasAppSettings) {\n appSettingsRow = database\n .prepare(\n `SELECT last_profile_name, license_key, purchase_email,\n last_verified_at, next_check_at, last_verification_error, status,\n auto_roll_enabled, auto_roll_warning_threshold, auto_roll_switch_threshold\n FROM app_settings\n WHERE id = 1`,\n )\n .get() as Record<string, unknown> | null;\n }\n } catch (error) {\n console.warn(\"Failed to read legacy app_settings row:\", error);\n }\n\n try {\n const upsertKv = database.prepare(\"INSERT OR REPLACE INTO app_kv (key, value) VALUES (@key, @value)\");\n\n if (appSettingsRow) {\n const lastProfile = typeof appSettingsRow.last_profile_name === 'string'\n ? appSettingsRow.last_profile_name.trim()\n : '';\n if (lastProfile) {\n upsertKv.run({ key: 'last_profile_name', value: JSON.stringify(lastProfile) });\n }\n\n const license = {\n licenseKey: typeof appSettingsRow.license_key === 'string' ? appSettingsRow.license_key : null,\n purchaseEmail: typeof appSettingsRow.purchase_email === 'string' ? appSettingsRow.purchase_email : null,\n lastVerifiedAt: typeof appSettingsRow.last_verified_at === 'string' ? appSettingsRow.last_verified_at : null,\n nextCheckAt: typeof appSettingsRow.next_check_at === 'string' ? appSettingsRow.next_check_at : null,\n lastVerificationError:\n typeof appSettingsRow.last_verification_error === 'string'\n ? appSettingsRow.last_verification_error\n : null,\n status: typeof appSettingsRow.status === 'string' ? appSettingsRow.status : null,\n };\n const hasLicenseData = Boolean(\n license.licenseKey ??\n license.purchaseEmail ??\n license.lastVerifiedAt ??\n license.nextCheckAt ??\n license.lastVerificationError ??\n license.status,\n );\n if (hasLicenseData) {\n upsertKv.run({ key: 'license', value: JSON.stringify(license) });\n }\n\n const hasAutoRollData =\n typeof appSettingsRow.auto_roll_enabled === 'number' ||\n typeof appSettingsRow.auto_roll_warning_threshold === 'number' ||\n typeof appSettingsRow.auto_roll_switch_threshold === 'number';\n if (hasAutoRollData) {\n const warning =\n typeof appSettingsRow.auto_roll_warning_threshold === 'number'\n ? appSettingsRow.auto_roll_warning_threshold\n : DEFAULT_AUTO_ROLL_WARNING_THRESHOLD;\n const switchThreshold =\n typeof appSettingsRow.auto_roll_switch_threshold === 'number'\n ? appSettingsRow.auto_roll_switch_threshold\n : DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD;\n const autoRoll = {\n enabled: Boolean(appSettingsRow.auto_roll_enabled ?? DEFAULT_AUTO_ROLL_ENABLED),\n warningThreshold: warning,\n switchThreshold,\n };\n upsertKv.run({ key: 'auto_roll', value: JSON.stringify(autoRoll) });\n }\n }\n\n try {\n database.exec(\"DROP TABLE IF EXISTS app_settings;\");\n } catch (error) {\n console.warn(\"Failed to drop legacy app_settings table:\", error);\n }\n } catch (error) {\n console.warn(\"Failed to migrate app_settings to app_kv:\", error);\n }\n\n database.exec(`PRAGMA user_version = 6;`);\n userVersion = 6;\n }\n\n if (userVersion < 7) {\n try {\n const columns = database\n .prepare(\"PRAGMA table_info(profiles)\")\n .all() as Array<{ name?: string }> | undefined;\n const hasWorkspaceId = Boolean(columns?.some(column => column.name === 'workspace_id'));\n const hasWorkspaceName = Boolean(columns?.some(column => column.name === 'workspace_name'));\n\n if (!hasWorkspaceId) {\n database.exec(`ALTER TABLE profiles ADD COLUMN workspace_id TEXT;`);\n }\n if (!hasWorkspaceName) {\n database.exec(`ALTER TABLE profiles ADD COLUMN workspace_name TEXT;`);\n }\n } catch (error) {\n console.warn('Failed to add workspace columns during migration:', error);\n }\n\n database.exec(`\n DROP INDEX IF EXISTS idx_profiles_account;\n DROP INDEX IF EXISTS idx_profiles_account_workspace;\n\n CREATE UNIQUE INDEX IF NOT EXISTS idx_profiles_account_workspace\n ON profiles(account_id, workspace_id)\n WHERE account_id IS NOT NULL;\n `);\n\n try {\n const rows = database\n .prepare('SELECT name, workspace_id FROM profiles')\n .all() as Array<{ name?: string; workspace_id?: string }>;\n const update = database.prepare(\n 'UPDATE profiles SET workspace_id = @workspaceId WHERE name = @name AND (workspace_id IS NULL OR workspace_id = \\'\\')',\n );\n for (const row of rows) {\n const name = typeof row.name === 'string' ? row.name : null;\n if (!name) {\n continue;\n }\n const existingWorkspace = typeof row.workspace_id === 'string' ? row.workspace_id.trim() : '';\n if (existingWorkspace) {\n continue;\n }\n update.run({ name, workspaceId: '__default__' });\n }\n } catch (error) {\n console.warn('Failed to backfill workspace_id during migration:', error);\n }\n\n database.exec(`PRAGMA user_version = 7;`);\n userVersion = 7;\n }\n\n if (userVersion < 8) {\n ensureChatTables(database);\n database.exec(`PRAGMA user_version = 8;`);\n userVersion = 8;\n }\n\n if (userVersion < 9) {\n ensureSessionTables(database);\n database.exec(`PRAGMA user_version = 9;`);\n userVersion = 9;\n }\n\n if (userVersion < 10) {\n ensureUsageTables(database);\n database.exec(`PRAGMA user_version = 10;`);\n userVersion = 10;\n }\n\n if (userVersion < 11) {\n try {\n database.exec(`ALTER TABLE usage ADD COLUMN model TEXT;`);\n } catch {\n // ignore if column already exists\n }\n database.exec(`PRAGMA user_version = 11;`);\n userVersion = 11;\n }\n\n // Make sure foreign keys are restored if a migration temporarily disabled them.\n try {\n database.exec('PRAGMA foreign_keys = ON;');\n } catch {\n // best-effort; errors are logged elsewhere\n }\n\n // Idempotent guard: make sure chat tables exist even if user_version was already bumped.\n ensureChatTables(database);\n ensureSessionTables(database);\n ensureUsageTables(database);\n}\n\nexport async function getDatabase(): Promise<SqliteDatabase> {\n const dbPath = resolveDbPath();\n\n if (!globalCache.cachedDbPromise || globalCache.cachedDbPath !== dbPath) {\n if (globalCache.cachedDbPromise) {\n try {\n const previous = await globalCache.cachedDbPromise;\n previous.close();\n } catch {\n // ignore errors closing old database\n }\n }\n globalCache.cachedDbPath = dbPath;\n globalCache.cachedDbPromise = instantiateDatabase(dbPath);\n }\n\n const db = await globalCache.cachedDbPromise;\n try {\n // Ensure migrations run even if the database was opened before this version of the app.\n runMigrations(db as SqliteWasmDatabase);\n } catch (error) {\n console.warn(\"Failed to ensure migrations:\", error);\n }\n return db;\n}\n\nexport async function resetDatabaseConnection(): Promise<void> {\n if (globalCache.cachedDbPromise) {\n try {\n const db = await globalCache.cachedDbPromise;\n db.close();\n } catch {\n // ignore failures during reset\n }\n }\n globalCache.cachedDbPromise = null;\n globalCache.cachedDbPath = null;\n}\n\n/**\n * @internal - exposed for tests to assert the resolved database paths.\n */\nexport function __debugResolveDbPath(): string {\n return resolveDbPath();\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { join } from 'path';\nimport { parse, stringify } from '@iarna/toml';\nimport {\n Profile,\n ProfileData,\n ActiveAuth,\n ProfileMetadata,\n OrganizationInfo,\n SubscriptionInfo,\n TokenAlert,\n TokenIssue,\n TokenStatus,\n} from './types';\nimport { getLastProfileName, persistLastProfileName } from './codex-settings';\nimport { logError, logWarn } from './logger';\n\nconst TOKEN_EXPIRING_SOON_WINDOW_MS = 15 * 60 * 1000;\nexport const REFRESH_TOKEN_REDEEMED_SNIPPET = 'refresh token was already used';\nexport const REFRESH_TOKEN_REDEEMED_REASON =\n 'Your access token could not be refreshed because your refresh token was already used. Please log out and sign in again.';\nconst AUTH_BACKUP_MISSING_MARKER = '__codexuse_missing_auth__';\nconst DEFAULT_WORKSPACE_ID = '__default__';\nconst PROFILE_RECORD_FILENAME = 'profile.json';\n\nexport function detectRefreshTokenRedeemedMessage(output: string | Buffer | null | undefined): string | null {\n if (!output) {\n return null;\n }\n\n const text = output.toString();\n if (!text) {\n return null;\n }\n\n const normalized = text\n .toLowerCase()\n .replace(/\\s+/g, ' ');\n if (!normalized.includes(REFRESH_TOKEN_REDEEMED_SNIPPET)) {\n return null;\n }\n\n const trimmed = text.trim();\n return trimmed.length > 0 ? trimmed : REFRESH_TOKEN_REDEEMED_REASON;\n}\n\ntype ProfileRecord = {\n name: string;\n displayName: string | null;\n data: ProfileData;\n metadata?: ProfileMetadata;\n accountId: string | null;\n workspaceId: string | null;\n workspaceName: string | null;\n email: string | null;\n authMethod: string | null;\n createdAt: string | null;\n updatedAt: string | null;\n};\n\ntype DbProfileRow = {\n name?: string | null;\n data?: string | null;\n account_id?: string | null;\n workspace_id?: string | null;\n workspace_name?: string | null;\n email?: string | null;\n auth_method?: string | null;\n created_at?: string | null;\n updated_at?: string | null;\n};\n\nexport class ProfileManager {\n private codexDir: string;\n private profilesDir: string;\n private profileHomesRoot: string;\n private migrationsDir: string;\n private profileMigrationMarker: string;\n private activeAuth: string;\n private activeAuthBackup: string;\n private lastActiveAuthErrorSignature: string | null;\n private authSwapLock: Promise<void>;\n constructor() {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n this.codexDir = join(homeDir, '.codex');\n this.profilesDir = join(this.codexDir, 'profiles');\n this.profileHomesRoot = join(this.codexDir, 'profile-homes');\n this.migrationsDir = join(this.codexDir, 'migrations');\n this.profileMigrationMarker = join(this.migrationsDir, 'profiles-v1');\n this.activeAuth = join(this.codexDir, 'auth.json');\n this.activeAuthBackup = `${this.activeAuth}.swap`;\n this.lastActiveAuthErrorSignature = null;\n this.authSwapLock = Promise.resolve();\n }\n\n private computeExpiryIso(data: ProfileData | null | undefined): string | undefined {\n if (!data) {\n return undefined;\n }\n if (typeof data.expired === 'string' && data.expired.trim()) {\n const parsed = Date.parse(data.expired);\n if (!Number.isNaN(parsed)) {\n return new Date(parsed).toISOString();\n }\n }\n const expiresIn = typeof data.expires_in === 'number' && Number.isFinite(data.expires_in)\n ? data.expires_in\n : undefined;\n const issuedMs =\n typeof data.timestamp === 'number' && Number.isFinite(data.timestamp)\n ? data.timestamp\n : undefined;\n const issuedAt = issuedMs ? issuedMs : undefined;\n const baseMs = issuedAt ?? Date.now();\n if (expiresIn && expiresIn > 0) {\n return new Date(baseMs + expiresIn * 1000).toISOString();\n }\n return undefined;\n }\n\n private normalizeProfileName(name: string): string {\n if (typeof name !== 'string') {\n throw new Error('Profile name is required');\n }\n\n const trimmed = name.trim();\n if (!trimmed) {\n throw new Error('Profile name must not be empty.');\n }\n\n if (trimmed === '.' || trimmed === '..') {\n throw new Error(`Profile name '${name}' is not allowed.`);\n }\n\n if (/[\\\\/]/.test(trimmed)) {\n throw new Error(\"Profile name cannot contain path separators.\");\n }\n\n if (trimmed.includes('\\0')) {\n throw new Error('Profile name contains invalid characters.');\n }\n\n return trimmed;\n }\n\n private isNotFoundError(error: unknown): boolean {\n return Boolean(\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error as NodeJS.ErrnoException).code === 'ENOENT',\n );\n }\n\n private async readPreferredProfileName(): Promise<string | null> {\n try {\n return await getLastProfileName();\n } catch (error) {\n logWarn('Failed to read preferred profile name:', error);\n return null;\n }\n }\n\n private async persistPreferredProfileName(name: string | null): Promise<void> {\n try {\n await persistLastProfileName(name);\n } catch (error) {\n logWarn('Failed to persist preferred profile name:', error);\n }\n }\n\n private getProfileRecordPath(profileName: string): string {\n return join(this.getProfileHomePath(profileName), PROFILE_RECORD_FILENAME);\n }\n\n private parseProfileRecordPayload(profileName: string, parsed: Record<string, unknown>): ProfileRecord | null {\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n\n const dataRaw = parsed['data'];\n let data: ProfileData | null = null;\n if (dataRaw && typeof dataRaw === 'object') {\n data = dataRaw as ProfileData;\n } else if (typeof dataRaw === 'string') {\n try {\n data = JSON.parse(dataRaw) as ProfileData;\n } catch (error) {\n logWarn(`Failed to parse data payload for profile '${profileName}':`, error);\n return null;\n }\n } else {\n return null;\n }\n const createdAt =\n typeof parsed['createdAt'] === 'string'\n ? parsed['createdAt'] as string\n : typeof parsed['created_at'] === 'string'\n ? parsed['created_at'] as string\n : null;\n const updatedAt =\n typeof parsed['updatedAt'] === 'string'\n ? parsed['updatedAt'] as string\n : typeof parsed['updated_at'] === 'string'\n ? parsed['updated_at'] as string\n : null;\n\n const metadata =\n parsed['metadata'] && typeof parsed['metadata'] === 'object'\n ? parsed['metadata'] as ProfileMetadata\n : undefined;\n\n const displayName =\n typeof parsed['displayName'] === 'string'\n ? parsed['displayName'] as string\n : typeof parsed['display_name'] === 'string'\n ? parsed['display_name'] as string\n : null;\n\n return {\n name: profileName,\n displayName,\n data,\n metadata,\n accountId:\n typeof parsed['accountId'] === 'string'\n ? parsed['accountId']\n : typeof parsed['account_id'] === 'string'\n ? parsed['account_id']\n : null,\n workspaceId:\n typeof parsed['workspaceId'] === 'string'\n ? parsed['workspaceId']\n : typeof parsed['workspace_id'] === 'string'\n ? parsed['workspace_id']\n : null,\n workspaceName:\n typeof parsed['workspaceName'] === 'string'\n ? parsed['workspaceName']\n : typeof parsed['workspace_name'] === 'string'\n ? parsed['workspace_name']\n : null,\n email:\n typeof parsed['email'] === 'string'\n ? parsed['email']\n : typeof parsed['email'] === 'boolean'\n ? null\n : null,\n authMethod:\n typeof parsed['authMethod'] === 'string'\n ? parsed['authMethod']\n : typeof parsed['auth_method'] === 'string'\n ? parsed['auth_method']\n : null,\n createdAt,\n updatedAt,\n };\n }\n\n private decodeProfileRecord(profileName: string, raw: string, sourceLabel: string): ProfileRecord | null {\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n return this.parseProfileRecordPayload(profileName, parsed);\n } catch (error) {\n logWarn(`Failed to parse profile record '${profileName}' from '${sourceLabel}':`, error);\n return null;\n }\n }\n\n private async recoverProfileRecord(recordPath: string, profileName: string): Promise<ProfileRecord | null> {\n const candidates = [`${recordPath}.bak`, `${recordPath}.tmp`];\n\n for (const candidate of candidates) {\n let raw: string;\n try {\n raw = await fs.readFile(candidate, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read backup for '${profileName}' from '${candidate}':`, error);\n }\n continue;\n }\n\n const decoded = this.decodeProfileRecord(profileName, raw, candidate);\n if (!decoded) {\n continue;\n }\n\n try {\n await this.writeProfileRecord(decoded);\n } catch (error) {\n logWarn(`Failed to restore profile '${profileName}' from '${candidate}':`, error);\n }\n return decoded;\n }\n\n return null;\n }\n\n private async readProfileRecord(profileName: string): Promise<ProfileRecord | null> {\n const recordPath = this.getProfileRecordPath(profileName);\n try {\n const raw = await fs.readFile(recordPath, 'utf8');\n const decoded = this.decodeProfileRecord(profileName, raw, recordPath);\n if (decoded) {\n return decoded;\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read profile record '${profileName}':`, error);\n }\n }\n\n return this.recoverProfileRecord(recordPath, profileName);\n }\n\n private async listProfileRecords(): Promise<ProfileRecord[]> {\n const records: ProfileRecord[] = [];\n let entries: Array<string> = [];\n try {\n entries = await fs.readdir(this.profileHomesRoot);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to list profile homes:', error);\n }\n return records;\n }\n\n for (const entry of entries) {\n const homePath = join(this.profileHomesRoot, entry);\n try {\n const stat = await fs.stat(homePath);\n if (!stat.isDirectory()) {\n continue;\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to inspect profile home '${entry}':`, error);\n }\n continue;\n }\n\n try {\n const normalizedName = this.normalizeProfileName(entry);\n const record = await this.readProfileRecord(normalizedName);\n if (record) {\n records.push(record);\n continue;\n }\n\n // Best-effort recovery for homes missing profile.json by rehydrating from auth.json.\n const authPath = join(homePath, 'auth.json');\n try {\n const authRaw = await fs.readFile(authPath, 'utf8');\n const authData = JSON.parse(authRaw) as ActiveAuth;\n const normalized = this.normalizeProfileData(authData);\n const metadata = this.extractProfileMetadata(normalized);\n await this.persistProfileRecord(normalizedName, normalized, metadata);\n const restored = await this.readProfileRecord(normalizedName);\n if (restored) {\n records.push(restored);\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to restore profile record for '${normalizedName}' from auth.json:`, error);\n }\n }\n } catch (error) {\n logWarn(`Skipping invalid profile home '${entry}':`, error);\n }\n }\n\n return records;\n }\n\n private async snapshotExistingProfileRecord(recordPath: string): Promise<void> {\n try {\n const existing = await fs.readFile(recordPath, 'utf8');\n if (existing && existing.trim()) {\n await this.writeAtomic(`${recordPath}.bak`, existing);\n }\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to snapshot existing profile record '${recordPath}':`, error);\n }\n }\n }\n\n private async writeProfileRecord(record: ProfileRecord): Promise<void> {\n const recordPath = this.getProfileRecordPath(record.name);\n const payload = {\n name: record.name,\n display_name: record.displayName,\n data: record.data,\n metadata: record.metadata,\n account_id: record.accountId,\n workspace_id: record.workspaceId,\n workspace_name: record.workspaceName,\n email: record.email,\n auth_method: record.authMethod,\n created_at: record.createdAt,\n updated_at: record.updatedAt,\n };\n const serialized = `${JSON.stringify(payload, null, 2)}\\n`;\n await this.snapshotExistingProfileRecord(recordPath);\n await this.writeAtomic(recordPath, serialized);\n try {\n await this.writeAtomic(`${recordPath}.bak`, serialized);\n } catch (error) {\n logWarn(`Failed to persist profile backup for '${record.name}':`, error);\n }\n }\n\n private resolveAuthMethod(data: ProfileData | null | undefined): string {\n const raw = typeof data?.auth_method === 'string' ? data.auth_method.trim().toLowerCase() : '';\n return raw || 'codex-cli';\n }\n\n private async readActiveAuthFile(): Promise<ActiveAuth | null> {\n try {\n const raw = await fs.readFile(this.activeAuth, 'utf8');\n const trimmed = raw.trim();\n if (!trimmed) {\n return null;\n }\n return JSON.parse(trimmed) as ActiveAuth;\n } catch (error) {\n if (this.isNotFoundError(error)) {\n return null;\n }\n const message = error instanceof Error ? error.message : 'unknown error';\n const signature = typeof message === 'string' ? `${message}:${this.activeAuth}` : this.activeAuth;\n if (this.lastActiveAuthErrorSignature !== signature) {\n logWarn('Failed to read active auth file:', error);\n this.lastActiveAuthErrorSignature = signature;\n }\n return null;\n }\n }\n\n private async getActiveAuthAccountId(): Promise<string | undefined> {\n const activeAuth = await this.readActiveAuthFile();\n if (!activeAuth) {\n return undefined;\n }\n return this.getAccountIdFromData(activeAuth);\n }\n\n /**\n * Decode a JWT payload into an object without validating the signature.\n */\n private decodeJwtPayload(token?: string | null): Record<string, unknown> | null {\n if (!token || typeof token !== 'string') {\n return null;\n }\n\n const segments = token.split('.');\n if (segments.length < 2) {\n return null;\n }\n\n try {\n const payload = Buffer.from(segments[1], 'base64url').toString('utf8');\n return JSON.parse(payload);\n } catch {\n return null;\n }\n }\n\n private toIsoStringFromSeconds(seconds?: number): string | undefined {\n if (typeof seconds !== 'number' || Number.isNaN(seconds)) {\n return undefined;\n }\n\n try {\n return new Date(seconds * 1000).toISOString();\n } catch {\n return undefined;\n }\n }\n\n private normalizeEmailCandidate(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (!trimmed || trimmed.includes(' ')) {\n return undefined;\n }\n\n const atIndex = trimmed.indexOf('@');\n if (atIndex <= 0 || atIndex === trimmed.length - 1) {\n return undefined;\n }\n\n const domain = trimmed.slice(atIndex + 1);\n if (!domain || !domain.includes('.')) {\n return undefined;\n }\n\n return trimmed;\n }\n\n private pickFirstEmail(candidates: Array<string | undefined>): string | undefined {\n for (const candidate of candidates) {\n const normalized = this.normalizeEmailCandidate(candidate);\n if (normalized) {\n return normalized;\n }\n }\n return undefined;\n }\n\n private findEmailInObject(value: unknown, seen = new Set<unknown>()): string | undefined {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n\n if (seen.has(value)) {\n return undefined;\n }\n seen.add(value);\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n const nested = this.findEmailInObject(entry, seen);\n if (nested) {\n return nested;\n }\n }\n return undefined;\n }\n\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n if (typeof entry === 'string') {\n const normalized = this.normalizeEmailCandidate(entry);\n const lowerKey = key.toLowerCase();\n const keyHintsAtEmail =\n lowerKey.includes('email') ||\n lowerKey.includes('contact') ||\n lowerKey.includes('username') ||\n lowerKey.includes('login');\n\n if (normalized && (keyHintsAtEmail || entry.includes('@'))) {\n return normalized;\n }\n }\n\n if (entry && typeof entry === 'object') {\n const nested = this.findEmailInObject(entry, seen);\n if (nested) {\n return nested;\n }\n }\n }\n\n return undefined;\n }\n\n private resolveProfileEmail(data: ProfileData, metadata?: ProfileMetadata): string | undefined {\n const direct = this.normalizeEmailCandidate(data.email);\n if (direct) {\n return direct;\n }\n\n if (metadata?.email) {\n return metadata.email;\n }\n\n return this.findEmailInObject(data);\n }\n\n private evaluateTokenStatus(data: ProfileData, metadata?: ProfileMetadata): TokenStatus {\n const expiresAt = metadata?.tokenExpiresAt ?? this.computeExpiryIso(data);\n const parsedExpiry = expiresAt ? Date.parse(expiresAt) : Number.NaN;\n const hasExpiry = !Number.isNaN(parsedExpiry);\n const tokenAlert = data.tokenAlert;\n\n if (!data || typeof data !== 'object' || Object.keys(data).length === 0) {\n return {\n state: 'missing',\n reason: 'No authentication data saved for this profile.',\n expiresAt,\n issue: 'auth-missing',\n requiresUserAction: true,\n };\n }\n\n if (tokenAlert?.issue) {\n const reason = typeof tokenAlert.reason === 'string' && tokenAlert.reason.trim().length > 0\n ? tokenAlert.reason.trim()\n : tokenAlert.issue === 'refresh-redeemed'\n ? REFRESH_TOKEN_REDEEMED_REASON\n : 'Authentication needs attention. Re-login this profile.';\n const issue = (tokenAlert.issue as TokenIssue) ?? 'auth-missing';\n return {\n state: 'invalid',\n reason,\n expiresAt,\n issue,\n requiresUserAction: true,\n };\n }\n\n if (!data.access_token) {\n return {\n state: 'missing',\n reason: 'Access token is missing. Re-authenticate with Codex CLI.',\n expiresAt,\n issue: 'access-missing',\n requiresUserAction: true,\n };\n }\n\n if (!this.decodeJwtPayload(data.access_token)) {\n return {\n state: 'invalid',\n reason: 'Access token is corrupted or not a valid JWT.',\n expiresAt,\n issue: 'access-invalid',\n requiresUserAction: true,\n };\n }\n\n const refreshToken = typeof data.refresh_token === 'string' ? data.refresh_token.trim() : '';\n if (!refreshToken) {\n return {\n state: 'missing',\n reason: 'Refresh token is missing. Run Codex login again.',\n expiresAt,\n issue: 'refresh-missing',\n requiresUserAction: true,\n };\n }\n\n if (hasExpiry) {\n const diff = parsedExpiry - Date.now();\n if (diff <= 0) {\n return {\n state: 'expiring',\n reason: 'Access token expired.',\n expiresAt,\n accessTokenExpired: true,\n issue: 'access-expired',\n requiresUserAction: false,\n };\n }\n\n if (diff <= TOKEN_EXPIRING_SOON_WINDOW_MS) {\n return {\n state: 'expiring',\n reason: 'Access token expires soon.',\n expiresAt,\n issue: 'access-expiring',\n requiresUserAction: false,\n };\n }\n }\n\n return {\n state: 'ok',\n expiresAt,\n requiresUserAction: false,\n };\n }\n\n private extractProfileMetadata(data: ProfileData): ProfileMetadata | undefined {\n const idPayload = this.decodeJwtPayload(data.id_token) as Record<string, unknown> | null;\n const accessPayload = this.decodeJwtPayload(data.access_token) as Record<string, unknown> | null;\n\n if (!idPayload && !accessPayload) {\n return undefined;\n }\n\n const authInfo = (idPayload?.['https://api.openai.com/auth'] ??\n accessPayload?.['https://api.openai.com/auth']) as Record<string, unknown> | undefined;\n\n const profileInfo = accessPayload?.['https://api.openai.com/profile'] as Record<string, unknown> | undefined;\n\n const getNumber = (obj: Record<string, unknown> | null | undefined, key: string): number | undefined =>\n typeof obj?.[key] === 'number' ? (obj[key] as number) : undefined;\n\n const getString = (obj: Record<string, unknown> | undefined | null, key: string): string | undefined =>\n typeof obj?.[key] === 'string' ? (obj[key] as string) : undefined;\n\n const exp = getNumber(idPayload, 'exp') ?? getNumber(accessPayload, 'exp');\n const iat = getNumber(idPayload, 'iat') ?? getNumber(accessPayload, 'iat');\n const authTime = getNumber(idPayload, 'auth_time') ?? getNumber(accessPayload, 'auth_time');\n\n const organizationsRaw = Array.isArray(authInfo?.['organizations'])\n ? (authInfo?.['organizations'] as unknown[])\n : undefined;\n\n const organizations = organizationsRaw\n ? organizationsRaw\n .map((org): OrganizationInfo => {\n const record = org as Record<string, unknown> | undefined;\n return {\n id: getString(record, 'id'),\n title: getString(record, 'title'),\n role: getString(record, 'role'),\n isDefault: typeof record?.['is_default'] === 'boolean' ? (record?.['is_default'] as boolean) : undefined,\n };\n })\n .filter(\n org =>\n org.id ||\n org.title ||\n org.role ||\n typeof org.isDefault === 'boolean'\n )\n : undefined;\n\n const groups = Array.isArray(authInfo?.['groups'])\n ? (authInfo?.['groups'] as unknown[]).filter((group): group is string => typeof group === 'string')\n : undefined;\n\n const emailVerified =\n typeof profileInfo?.['email_verified'] === 'boolean'\n ? (profileInfo?.['email_verified'] as boolean)\n : typeof idPayload?.['email_verified'] === 'boolean'\n ? (idPayload?.['email_verified'] as boolean)\n : typeof accessPayload?.['email_verified'] === 'boolean'\n ? (accessPayload?.['email_verified'] as boolean)\n : undefined;\n\n const email =\n this.pickFirstEmail([\n getString(profileInfo, 'email'),\n getString(profileInfo, 'email_address'),\n getString(profileInfo, 'primary_email'),\n getString(profileInfo, 'default_email'),\n getString(profileInfo, 'contact_email'),\n ]) ??\n this.findEmailInObject(profileInfo) ??\n this.pickFirstEmail([\n getString(authInfo, 'user_email'),\n getString(authInfo, 'email'),\n getString(authInfo, 'userEmail'),\n getString(authInfo, 'chatgpt_user_email'),\n ]) ??\n this.findEmailInObject(authInfo) ??\n this.pickFirstEmail([\n getString(idPayload, 'email'),\n getString(idPayload, 'preferred_username'),\n getString(idPayload, 'username'),\n ]) ??\n this.findEmailInObject(idPayload) ??\n this.pickFirstEmail([\n getString(accessPayload, 'email'),\n ]) ??\n this.findEmailInObject(accessPayload);\n\n const subscription: SubscriptionInfo | undefined = authInfo\n ? {\n activeStart: getString(authInfo, 'chatgpt_subscription_active_start'),\n activeUntil: getString(authInfo, 'chatgpt_subscription_active_until'),\n lastChecked: getString(authInfo, 'chatgpt_subscription_last_checked'),\n }\n : undefined;\n\n const planType = getString(authInfo, 'chatgpt_plan_type');\n const chatgptUserId = getString(authInfo, 'chatgpt_user_id');\n const chatgptAccountUserId = getString(authInfo, 'chatgpt_account_user_id');\n const userId =\n getString(authInfo, 'user_id') ??\n chatgptAccountUserId ??\n getString(idPayload ?? undefined, 'sub') ??\n getString(accessPayload ?? undefined, 'sub');\n\n const metadata: ProfileMetadata = {\n email,\n planType,\n subscription,\n organizations,\n groups,\n userId,\n chatgptUserId,\n emailVerified,\n tokenExpiresAt: this.toIsoStringFromSeconds(exp),\n tokenIssuedAt: this.toIsoStringFromSeconds(iat),\n tokenAuthTime: this.toIsoStringFromSeconds(authTime),\n };\n\n const hasMeaningfulData =\n Boolean(metadata.planType) ||\n Boolean(\n metadata.subscription &&\n (metadata.subscription.activeStart ||\n metadata.subscription.activeUntil ||\n metadata.subscription.lastChecked)\n ) ||\n Boolean(metadata.organizations && metadata.organizations.length > 0) ||\n Boolean(metadata.groups && metadata.groups.length > 0) ||\n Boolean(metadata.userId) ||\n Boolean(metadata.chatgptUserId) ||\n Boolean(metadata.email) ||\n typeof metadata.emailVerified === 'boolean' ||\n Boolean(metadata.tokenExpiresAt) ||\n Boolean(metadata.tokenIssuedAt) ||\n Boolean(metadata.tokenAuthTime);\n\n return hasMeaningfulData ? metadata : undefined;\n }\n\n /**\n * Initialize the profile manager and create necessary directories\n */\n async initialize(): Promise<void> {\n try {\n await fs.mkdir(this.codexDir, { recursive: true });\n } catch (error) {\n logError('Failed to ensure Codex directory exists:', error);\n throw new Error('Failed to initialize profile manager');\n }\n try {\n await fs.mkdir(this.profileHomesRoot, { recursive: true });\n } catch (error) {\n logError('Failed to ensure profile homes directory exists:', error);\n throw new Error('Failed to initialize profile manager');\n }\n\n await this.recoverActiveAuthBackup();\n const migrationsComplete = await this.hasCompletedMigrations();\n if (!migrationsComplete) {\n await this.migrateLegacyProfiles();\n await this.migrateProfilesFromDatabase();\n await this.removeLegacyArtifacts();\n await this.markMigrationsComplete();\n }\n }\n\n /**\n * Remove deprecated files that previously tracked the current profile.\n * These are now redundant since we infer the active profile from auth.json.\n */\n private async removeLegacyArtifacts(): Promise<void> {\n const legacyTargets = [\n join(this.codexDir, 'current-profile.json'),\n join(this.profilesDir, '.current'),\n `${this.activeAuth}.backup`,\n join(this.codexDir, 'cache', 'rate-limits'),\n ];\n\n for (const target of legacyTargets) {\n try {\n await fs.rm(target, { recursive: true, force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove legacy artifact '${target}':`, error);\n }\n }\n }\n\n try {\n await fs.rm(this.profilesDir, { recursive: true, force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove legacy profiles directory '${this.profilesDir}':`, error);\n }\n }\n }\n\n private async hasCompletedMigrations(): Promise<boolean> {\n try {\n await fs.access(this.profileMigrationMarker);\n return true;\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to read profile migration marker:', error);\n }\n return false;\n }\n }\n\n private async markMigrationsComplete(): Promise<void> {\n try {\n await fs.mkdir(this.migrationsDir, { recursive: true });\n await fs.writeFile(this.profileMigrationMarker, 'ok');\n } catch (error) {\n logWarn('Failed to persist profile migration marker:', error);\n }\n }\n\n private async migrateLegacyProfiles(): Promise<void> {\n let files: string[];\n try {\n files = await fs.readdir(this.profilesDir);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to inspect legacy profiles directory:', error);\n }\n return;\n }\n\n if (files.length === 0) {\n return;\n }\n\n type LegacyCandidate = {\n name: string;\n data: ProfileData;\n profile: Profile;\n accountId?: string;\n };\n\n const accountCandidates = new Map<string, LegacyCandidate>();\n const orphanCandidates: LegacyCandidate[] = [];\n const insertedNames = new Set<string>();\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const name = file.replace(/\\.json$/, '');\n const filePath = join(this.profilesDir, file);\n\n try {\n const raw = await fs.readFile(filePath, 'utf8');\n const data = JSON.parse(raw) as ProfileData;\n const normalizedName = this.normalizeProfileName(name);\n const metadata = this.extractProfileMetadata(data);\n const resolvedEmail = this.resolveProfileEmail(data, metadata);\n if (resolvedEmail) {\n data.email = resolvedEmail;\n }\n const accountId = this.getAccountIdFromData(data);\n const candidate: LegacyCandidate = {\n name: normalizedName,\n data,\n profile: this.buildProfileFromData(normalizedName, data),\n accountId,\n };\n\n if (accountId) {\n const existing = accountCandidates.get(accountId);\n if (existing) {\n const preferred = this.selectPreferredProfile([existing.profile, candidate.profile]);\n if (preferred === candidate.profile) {\n logWarn(\n `Replacing legacy profile '${existing.name}' with '${normalizedName}' for account '${accountId}'.`,\n );\n accountCandidates.set(accountId, candidate);\n } else {\n logWarn(\n `Skipping legacy profile '${name}' because account '${accountId}' already exists as '${existing.name}'.`,\n );\n }\n } else {\n accountCandidates.set(accountId, candidate);\n }\n } else {\n orphanCandidates.push(candidate);\n }\n\n await fs.rm(filePath, { force: true });\n } catch (error) {\n logWarn(`Failed to migrate legacy profile '${name}':`, error);\n }\n }\n\n const persistQueue: LegacyCandidate[] = [...accountCandidates.values(), ...orphanCandidates];\n const existingRecords = await this.listProfileRecords();\n for (const record of existingRecords) {\n insertedNames.add(record.name);\n }\n\n for (const candidate of persistQueue) {\n if (insertedNames.has(candidate.name)) {\n logWarn(`Skipping legacy profile '${candidate.name}' because it was already imported.`);\n continue;\n }\n\n try {\n await this.persistProfileRecord(candidate.name, candidate.data, candidate.profile.metadata);\n insertedNames.add(candidate.name);\n } catch (error) {\n logWarn(`Failed to persist migrated profile '${candidate.name}':`, error);\n }\n }\n }\n\n private async migrateProfilesFromDatabase(): Promise<void> {\n let rows: DbProfileRow[] = [];\n try {\n const { getDatabase } = await import('./sqlite-db');\n const db = await getDatabase();\n rows = db\n .prepare(\n 'SELECT name, data, account_id, workspace_id, workspace_name, email, auth_method, created_at, updated_at FROM profiles',\n )\n .all() as DbProfileRow[];\n } catch (error) {\n logWarn('Failed to read existing database profiles for migration:', error);\n return;\n }\n\n if (!rows || rows.length === 0) {\n return;\n }\n\n const existingNames = new Set<string>((await this.listProfileRecords()).map(record => record.name));\n\n for (const row of rows) {\n const name = typeof row?.name === 'string' ? row.name : null;\n const serialized = typeof row?.data === 'string' ? row.data : null;\n if (!name || !serialized) {\n continue;\n }\n\n let data: ProfileData;\n try {\n data = JSON.parse(serialized) as ProfileData;\n } catch (error) {\n logWarn(`Failed to parse database profile '${name}' during migration:`, error);\n continue;\n }\n\n try {\n const normalizedName = this.normalizeProfileName(name);\n if (existingNames.has(normalizedName)) {\n continue;\n }\n\n data.created_at = data.created_at ?? (typeof row?.created_at === 'string' ? row.created_at : undefined);\n data.email = data.email ?? (typeof row?.email === 'string' ? row.email : undefined);\n data.auth_method = data.auth_method ?? (typeof row?.auth_method === 'string' ? row.auth_method : undefined);\n data.workspace_id = data.workspace_id ?? (typeof row?.workspace_id === 'string' ? row.workspace_id : undefined);\n data.workspace_name =\n data.workspace_name ?? (typeof row?.workspace_name === 'string' ? row.workspace_name : undefined);\n data.updated_at = data.updated_at ?? (typeof row?.updated_at === 'string' ? row.updated_at : undefined);\n\n const metadata = this.extractProfileMetadata(data);\n await this.persistProfileRecord(normalizedName, data, metadata);\n existingNames.add(normalizedName);\n } catch (error) {\n logWarn(`Failed to migrate database profile '${name}':`, error);\n }\n }\n }\n\n private enqueueAuthSwap<T>(task: () => Promise<T>): Promise<T> {\n const run = this.authSwapLock.then(task, task);\n this.authSwapLock = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n\n private async recoverActiveAuthBackup(): Promise<void> {\n let backup: string;\n try {\n backup = await fs.readFile(this.activeAuthBackup, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to inspect active auth backup:', error);\n }\n return;\n }\n\n try {\n if (backup === AUTH_BACKUP_MISSING_MARKER) {\n await fs.rm(this.activeAuth, { force: true });\n } else {\n try {\n await this.writeAtomic(this.activeAuth, backup);\n } catch (error) {\n logWarn('Failed to restore active auth from backup, falling back to direct write:', error);\n try {\n await fs.writeFile(this.activeAuth, backup, 'utf8');\n } catch (fallbackError) {\n logWarn('Direct write failed while restoring active auth backup:', fallbackError);\n }\n }\n }\n } catch (error) {\n logWarn('Failed to restore active auth from backup:', error);\n }\n\n try {\n await fs.rm(this.activeAuthBackup, { force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn('Failed to remove active auth backup:', error);\n }\n }\n }\n\n private async writeAtomic(filePath: string, contents: string): Promise<void> {\n const tempPath = `${filePath}.tmp`;\n const dir = path.dirname(filePath);\n await fs.mkdir(dir, { recursive: true });\n\n await fs.writeFile(tempPath, contents, 'utf8');\n try {\n await fs.rename(tempPath, filePath);\n } catch (error) {\n // Fall back to writing directly if rename fails for any reason.\n try {\n await fs.writeFile(filePath, contents, 'utf8');\n } catch (writeError) {\n // Surface the original error context to aid debugging.\n const original = error instanceof Error ? error.message : String(error);\n const fallback = writeError instanceof Error ? writeError.message : String(writeError);\n throw new Error(`Atomic write failed (rename: ${original}; direct write: ${fallback})`);\n }\n }\n // Best-effort cleanup of temp file if it still exists.\n try {\n await fs.rm(tempPath, { force: true });\n } catch {\n // ignore cleanup failures\n }\n }\n\n /**\n * Extract account_id from auth data (supports both formats)\n */\n private getAccountIdFromData(data: ProfileData | ActiveAuth): string | undefined {\n if ('account_id' in data && typeof data.account_id === 'string' && data.account_id.trim()) {\n return data.account_id.trim();\n }\n\n if ('tokens' in data && data.tokens && typeof data.tokens === 'object') {\n const accountId = (data.tokens as { account_id?: unknown }).account_id;\n if (typeof accountId === 'string' && accountId.trim()) {\n return accountId.trim();\n }\n }\n\n const projectId =\n 'project_id' in data && typeof (data as ProfileData).project_id === 'string'\n ? (data as ProfileData).project_id?.trim()\n : undefined;\n if (projectId) {\n return projectId;\n }\n\n const email =\n 'email' in data && typeof (data as ProfileData).email === 'string'\n ? (data as ProfileData).email?.trim()\n : undefined;\n return email || undefined;\n }\n\n private resolveWorkspaceIdentity(data: ProfileData | ActiveAuth, metadata?: ProfileMetadata): { id: string; name?: string } {\n const directId =\n 'workspace_id' in data && typeof data.workspace_id === 'string'\n ? data.workspace_id.trim()\n : undefined;\n const directName =\n 'workspace_name' in data && typeof data.workspace_name === 'string'\n ? data.workspace_name.trim()\n : undefined;\n\n if (directId) {\n return { id: directId, name: directName };\n }\n\n const organizations = metadata?.organizations;\n if (organizations && organizations.length > 0) {\n const preferred = organizations.find(org => org.isDefault) ?? organizations[0];\n if (preferred?.id) {\n return { id: preferred.id, name: preferred.title ?? directName };\n }\n }\n\n return { id: DEFAULT_WORKSPACE_ID, name: directName };\n }\n\n private async getProfileRowByName(name: string): Promise<ProfileRecord | undefined> {\n const normalized = this.normalizeProfileName(name);\n const record = await this.readProfileRecord(normalized);\n return record ?? undefined;\n }\n\n private async getProfileRowByAccountId(\n accountId: string,\n options?: { authMethod?: string | null; preferAuthMethod?: string | null },\n ): Promise<ProfileRecord | undefined> {\n const records = await this.listProfileRecords();\n const matches = records.filter(record => {\n const storedAccountId = record.accountId ?? this.getAccountIdFromData(record.data);\n return storedAccountId === accountId;\n });\n\n if (matches.length === 0) {\n return undefined;\n }\n\n const mustMatch = typeof options?.authMethod === 'string' ? options.authMethod.trim().toLowerCase() : null;\n if (mustMatch) {\n return matches.find(record => this.resolveAuthMethod(record.data) === mustMatch);\n }\n\n const prefer = typeof options?.preferAuthMethod === 'string' ? options.preferAuthMethod.trim().toLowerCase() : null;\n if (prefer) {\n return matches.find(record => this.resolveAuthMethod(record.data) === prefer) ?? matches[0];\n }\n\n return matches[0];\n }\n\n private async getProfileRowByAccountAndWorkspace(\n accountId: string,\n workspaceId: string,\n options?: { authMethod?: string | null; preferAuthMethod?: string | null },\n ): Promise<ProfileRecord | undefined> {\n const workspaceKey = workspaceId && workspaceId.trim().length > 0 ? workspaceId.trim() : DEFAULT_WORKSPACE_ID;\n const records = await this.listProfileRecords();\n const matches = records.filter(record => {\n const storedAccountId = record.accountId ?? this.getAccountIdFromData(record.data);\n if (storedAccountId !== accountId) {\n return false;\n }\n const storedWorkspace = record.workspaceId ?? record.data.workspace_id ?? DEFAULT_WORKSPACE_ID;\n return (storedWorkspace && storedWorkspace.trim() ? storedWorkspace.trim() : DEFAULT_WORKSPACE_ID) === workspaceKey;\n });\n\n if (matches.length === 0) {\n return undefined;\n }\n\n const mustMatch = typeof options?.authMethod === 'string' ? options.authMethod.trim().toLowerCase() : null;\n if (mustMatch) {\n return matches.find(record => this.resolveAuthMethod(record.data) === mustMatch);\n }\n\n const prefer = typeof options?.preferAuthMethod === 'string' ? options.preferAuthMethod.trim().toLowerCase() : null;\n if (prefer) {\n return matches.find(record => this.resolveAuthMethod(record.data) === prefer) ?? matches[0];\n }\n\n return matches[0];\n }\n\n private async persistProfileRecord(\n name: string,\n data: ProfileData,\n metadata?: ProfileMetadata,\n options?: { displayName?: string | null },\n ): Promise<void> {\n const resolvedName = this.normalizeProfileName(name);\n const existingRecord = await this.readProfileRecord(resolvedName);\n if (typeof data.auth_method === 'string') {\n data.auth_method = data.auth_method.trim().toLowerCase();\n }\n if (!data.auth_method) {\n data.auth_method = 'codex-cli';\n }\n const resolvedMetadata = metadata ?? this.extractProfileMetadata(data) ?? existingRecord?.metadata;\n const workspace = this.resolveWorkspaceIdentity(data, resolvedMetadata);\n const workspaceId = workspace.id || DEFAULT_WORKSPACE_ID;\n const workspaceName = workspace.name ?? null;\n if (!data.workspace_id) {\n data.workspace_id = workspaceId;\n }\n if (!data.workspace_name && workspaceName) {\n data.workspace_name = workspaceName;\n }\n\n const now = new Date().toISOString();\n const accountId = this.getAccountIdFromData(data) ?? null;\n const resolvedEmail = this.resolveProfileEmail(data, resolvedMetadata) ?? data.email ?? null;\n if (resolvedEmail) {\n data.email = resolvedEmail;\n }\n const createdAt = data.created_at ?? existingRecord?.createdAt ?? now;\n data.created_at = createdAt;\n const updatedAt = data.updated_at ?? now;\n data.updated_at = updatedAt;\n\n const displayName =\n typeof options?.displayName === 'string' && options.displayName.trim().length > 0\n ? options.displayName.trim()\n : existingRecord?.displayName ?? resolvedName;\n\n const record: ProfileRecord = {\n name: resolvedName,\n displayName,\n data,\n metadata: resolvedMetadata,\n accountId,\n workspaceId: data.workspace_id ?? workspaceId,\n workspaceName: data.workspace_name ?? workspaceName,\n email: resolvedEmail ?? null,\n authMethod: typeof data.auth_method === 'string' ? data.auth_method : null,\n createdAt,\n updatedAt,\n };\n\n await fs.mkdir(this.getProfileHomePath(resolvedName), { recursive: true });\n await this.writeProfileRecord(record);\n }\n\n private buildProfileFromRow(row: ProfileRecord): Profile {\n const profile = this.buildProfileFromData(row.name, row.data, {\n displayName: row.displayName ?? undefined,\n email: row.email ?? undefined,\n createdAt: row.createdAt ?? undefined,\n authMethod: row.authMethod ?? undefined,\n accountId: row.accountId ?? undefined,\n workspaceId: row.workspaceId ?? undefined,\n workspaceName: row.workspaceName ?? undefined,\n metadata: row.metadata,\n });\n\n return profile;\n }\n\n private buildProfileFromData(\n name: string,\n data: ProfileData,\n fallback?: {\n displayName?: string;\n email?: string;\n createdAt?: string;\n authMethod?: string;\n accountId?: string;\n projectId?: string;\n workspaceId?: string;\n workspaceName?: string;\n metadata?: ProfileMetadata;\n },\n ): Profile {\n const metadata = fallback?.metadata ?? this.extractProfileMetadata(data);\n const workspace = this.resolveWorkspaceIdentity(data, metadata);\n const workspaceId = workspace.id || fallback?.workspaceId || DEFAULT_WORKSPACE_ID;\n const workspaceName = workspace.name ?? fallback?.workspaceName ?? undefined;\n const email = this.resolveProfileEmail(data, metadata) ?? fallback?.email ?? undefined;\n const tokenStatus = this.evaluateTokenStatus(data, metadata);\n const accountId = this.getAccountIdFromData(data) ?? fallback?.accountId;\n const projectId =\n typeof data.project_id === 'string' && data.project_id.trim().length > 0\n ? data.project_id.trim()\n : fallback?.projectId;\n\n return {\n name,\n displayName: fallback?.displayName ?? name,\n isValid: Boolean(data && Object.keys(data).length > 0),\n accountId,\n projectId,\n workspaceId,\n workspaceName,\n email,\n createdAt: data.created_at ?? fallback?.createdAt ?? undefined,\n authMethod: typeof data.auth_method === 'string'\n ? data.auth_method.trim().toLowerCase()\n : fallback?.authMethod ?? undefined,\n metadata,\n tokenStatus,\n };\n }\n\n private parseTimestamp(value?: string | null): number | null {\n if (typeof value !== 'string' || value.trim() === '') {\n return null;\n }\n\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? null : parsed;\n }\n\n private compareProfilesForPreference(a: Profile, b: Profile): number {\n if (Boolean(a.isValid) !== Boolean(b.isValid)) {\n return a.isValid ? -1 : 1;\n }\n\n const aTimestamp = this.parseTimestamp(a.createdAt ?? null);\n const bTimestamp = this.parseTimestamp(b.createdAt ?? null);\n\n if (aTimestamp !== null || bTimestamp !== null) {\n if (aTimestamp !== null && bTimestamp !== null) {\n if (aTimestamp > bTimestamp) {\n return -1;\n }\n if (aTimestamp < bTimestamp) {\n return 1;\n }\n } else if (aTimestamp !== null) {\n return -1;\n } else {\n return 1;\n }\n }\n\n return a.name.localeCompare(b.name);\n }\n\n private selectPreferredProfile(profiles: Profile[]): Profile {\n if (profiles.length <= 1) {\n return profiles[0];\n }\n\n return profiles\n .slice()\n .sort((a, b) => this.compareProfilesForPreference(a, b))[0];\n }\n\n /**\n * Convert profile data to Codex's expected format\n */\n private convertToCodexFormat(data: ProfileData): ActiveAuth {\n // Check if data is already in Codex format\n if ('tokens' in data) {\n return data as ActiveAuth;\n }\n\n // Convert flat structure to nested Codex format\n return {\n OPENAI_API_KEY: null,\n tokens: {\n id_token: data.id_token,\n access_token: data.access_token,\n refresh_token: data.refresh_token,\n account_id: data.account_id,\n },\n last_refresh: new Date().toISOString(),\n };\n }\n\n /**\n * Normalize Codex auth data to flat profile format\n */\n private normalizeProfileData(data: ActiveAuth): ProfileData {\n // If data is already in flat format, return as-is\n if ('id_token' in data) {\n return data as ProfileData;\n }\n\n // Convert nested Codex format to flat\n const tokens = data.tokens || {};\n const profile: ProfileData = {\n id_token: tokens.id_token,\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n account_id: tokens.account_id,\n };\n\n if (data.email) {\n profile.email = data.email;\n }\n\n return profile;\n }\n\n private mergeProfileRecords(existing: ProfileData, incoming: ProfileData): {\n profile: ProfileData;\n metadata?: ProfileMetadata;\n } {\n const merged: ProfileData = {\n ...existing,\n ...incoming,\n created_at: existing.created_at ?? incoming.created_at ?? new Date().toISOString(),\n };\n\n if (typeof merged.auth_method === 'string') {\n merged.auth_method = merged.auth_method.trim().toLowerCase();\n }\n if (!merged.auth_method) {\n merged.auth_method = 'codex-cli';\n }\n\n const metadata = this.extractProfileMetadata(merged);\n const resolvedEmail = this.resolveProfileEmail(merged, metadata);\n\n if (resolvedEmail) {\n merged.email = resolvedEmail;\n }\n\n const workspace = this.resolveWorkspaceIdentity(merged, metadata);\n if (!merged.workspace_id) {\n merged.workspace_id = workspace.id || existing.workspace_id || DEFAULT_WORKSPACE_ID;\n }\n if (!merged.workspace_name) {\n merged.workspace_name = workspace.name ?? existing.workspace_name;\n }\n\n if (this.hasTokenChanges(existing, incoming)) {\n delete merged.tokenAlert;\n }\n\n return { profile: merged, metadata };\n }\n\n private hasTokenChanges(existing: ProfileData, incoming: ProfileData): boolean {\n const tokenKeys: Array<keyof ProfileData> = ['id_token', 'access_token', 'refresh_token', 'account_id', 'workspace_id'];\n\n return tokenKeys.some(key => {\n const nextValue = incoming[key];\n if (typeof nextValue !== 'string' || nextValue.length === 0) {\n return false;\n }\n return nextValue !== existing[key];\n });\n }\n\n async flagRefreshTokenRedeemed(name: string, reason?: string, options?: { observedAt?: string }): Promise<void> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n logWarn(`Cannot flag refresh token issue for missing profile '${profileName}'.`);\n return;\n }\n\n const observedAt = options?.observedAt ? Date.parse(options.observedAt) : null;\n const updatedAt = record.updatedAt ? Date.parse(record.updatedAt) : null;\n if (observedAt !== null && updatedAt !== null && observedAt <= updatedAt) {\n return;\n }\n\n const data: ProfileData = record.data;\n\n const trimmedReason = typeof reason === 'string' && reason.trim().length > 0 ? reason.trim() : undefined;\n const normalized = trimmedReason?.toLowerCase() ?? '';\n const storedReason = normalized.includes(REFRESH_TOKEN_REDEEMED_SNIPPET)\n ? REFRESH_TOKEN_REDEEMED_REASON\n : trimmedReason ?? REFRESH_TOKEN_REDEEMED_REASON;\n const alert: TokenAlert = {\n issue: 'refresh-redeemed',\n reason: storedReason,\n recordedAt: new Date().toISOString(),\n };\n\n data.tokenAlert = alert;\n\n try {\n const metadata = this.extractProfileMetadata(data);\n await this.persistProfileRecord(profileName, data, metadata);\n } catch (error) {\n logError(`Failed to persist token alert for profile '${profileName}':`, error);\n }\n }\n\n private async syncProfileTokensFromActiveAuth(\n profileName: string,\n baselineProfile: ProfileData,\n authPath?: string,\n ): Promise<void> {\n const targetPath = authPath ?? this.activeAuth;\n try {\n const authRaw = await fs.readFile(targetPath, 'utf8');\n await this.syncProfileTokensFromAuthContent(profileName, baselineProfile, authRaw);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read Codex auth for '${profileName}' while syncing tokens:`, error);\n }\n }\n }\n\n private async syncProfileTokensFromAuthContent(\n profileName: string,\n baselineProfile: ProfileData,\n authContent: string,\n ): Promise<void> {\n let activeAuth: ActiveAuth;\n try {\n activeAuth = JSON.parse(authContent) as ActiveAuth;\n } catch (error) {\n logWarn(`Failed to parse Codex auth while syncing tokens for '${profileName}':`, error);\n return;\n }\n\n const normalized = this.normalizeProfileData(activeAuth);\n const metadata = this.extractProfileMetadata(normalized);\n const workspace = this.resolveWorkspaceIdentity(normalized, metadata);\n normalized.workspace_id = normalized.workspace_id ?? workspace.id ?? DEFAULT_WORKSPACE_ID;\n if (workspace.name) {\n normalized.workspace_name = normalized.workspace_name ?? workspace.name;\n }\n const hasTokens =\n typeof normalized.id_token === 'string' ||\n typeof normalized.access_token === 'string' ||\n typeof normalized.refresh_token === 'string';\n\n if (!hasTokens) {\n return;\n }\n\n let existing = baselineProfile;\n const latestRow = await this.getProfileRowByName(profileName);\n if (latestRow) {\n existing = latestRow.data;\n }\n\n const existingAccountId = this.getAccountIdFromData(existing);\n const newAccountId = this.getAccountIdFromData(normalized);\n\n if (existingAccountId && newAccountId && existingAccountId !== newAccountId) {\n logWarn(\n `Skipped syncing tokens for profile '${profileName}' because Codex auth switched to account '${newAccountId}'.`,\n );\n return;\n }\n\n if (!this.hasTokenChanges(existing, normalized)) {\n return;\n }\n\n const { profile: merged, metadata: mergedMetadata } = this.mergeProfileRecords(existing, normalized);\n\n try {\n await this.persistProfileRecord(profileName, merged, mergedMetadata);\n } catch (error) {\n logError(`Failed to persist refreshed tokens for profile '${profileName}':`, error);\n }\n }\n\n private async copyCodexConfig(targetCodexHome: string): Promise<void> {\n const candidates = ['config.toml', 'config.json', 'config.yaml', 'config.yml'];\n for (const file of candidates) {\n const source = join(this.codexDir, file);\n const destination = join(targetCodexHome, file);\n try {\n await fs.copyFile(source, destination);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to copy Codex config '${file}' to profile home:`, error);\n }\n }\n }\n }\n\n private getProfileHomePath(profileName: string): string {\n return join(this.profileHomesRoot, profileName);\n }\n\n private ensureTrailingNewline(content: string): string {\n return content.endsWith('\\n') ? content : `${content}\\n`;\n }\n\n private async sanitizeProfileConfig(profileHome: string): Promise<void> {\n const configPath = join(profileHome, 'config.toml');\n let raw: string;\n try {\n raw = await fs.readFile(configPath, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read config for profile home '${profileHome}':`, error);\n }\n return;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = parse(raw) as Record<string, unknown>;\n } catch (error) {\n logWarn(`Failed to parse config.toml for profile home '${profileHome}':`, error);\n return;\n }\n\n if (!Object.prototype.hasOwnProperty.call(parsed, 'model_reasoning_effort')) {\n return;\n }\n\n delete parsed['model_reasoning_effort'];\n const sanitized = this.ensureTrailingNewline(stringify(parsed as Record<string, unknown>));\n try {\n await fs.writeFile(configPath, sanitized, 'utf8');\n } catch (error) {\n logWarn(`Failed to write sanitized config.toml for profile home '${profileHome}':`, error);\n }\n }\n\n private async prepareProfileHome(profileName: string, authData: ActiveAuth): Promise<string> {\n const profileHome = this.getProfileHomePath(profileName);\n await fs.mkdir(profileHome, { recursive: true });\n const authPath = join(profileHome, 'auth.json');\n await this.writeAtomic(authPath, JSON.stringify(authData, null, 2));\n await this.copyCodexConfig(profileHome);\n await this.sanitizeProfileConfig(profileHome);\n return profileHome;\n }\n\n /**\n * List all available profiles\n */\n async profileExists(name: string): Promise<boolean> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n return Boolean(await this.getProfileRowByName(profileName));\n }\n\n async listProfiles(): Promise<Profile[]> {\n await this.initialize();\n try {\n const records = await this.listProfileRecords();\n return records\n .map(record => this.buildProfileFromRow(record))\n .filter(profile => !profile.authMethod || profile.authMethod === 'codex-cli')\n .sort((a, b) => {\n const aLabel = a.displayName ?? a.name;\n const bLabel = b.displayName ?? b.name;\n const base = aLabel.localeCompare(bLabel);\n return base !== 0 ? base : a.name.localeCompare(b.name);\n });\n } catch (error) {\n logError('Error reading profiles from disk:', error);\n return [];\n }\n }\n\n /**\n * Create a new profile by running codex login\n */\n async createProfile(name: string): Promise<Profile | null> {\n await this.initialize();\n\n const profileName = this.normalizeProfileName(name);\n if (await this.getProfileRowByName(profileName)) {\n throw new Error(`Profile '${profileName}' already exists!`);\n }\n\n let authData: ActiveAuth;\n try {\n const authRaw = await fs.readFile(this.activeAuth, 'utf8');\n authData = JSON.parse(authRaw) as ActiveAuth;\n } catch (error) {\n logError('Error creating profile:', error);\n throw new Error('Failed to create profile. Make sure Codex CLI is installed and you are logged in.');\n }\n\n const normalizedProfile = this.normalizeProfileData(authData);\n normalizedProfile.created_at = normalizedProfile.created_at ?? new Date().toISOString();\n if (typeof normalizedProfile.auth_method === 'string') {\n normalizedProfile.auth_method = normalizedProfile.auth_method.trim().toLowerCase();\n }\n normalizedProfile.auth_method = normalizedProfile.auth_method ?? 'codex-cli';\n\n const metadata = this.extractProfileMetadata(normalizedProfile);\n const workspace = this.resolveWorkspaceIdentity(normalizedProfile, metadata);\n normalizedProfile.workspace_id = normalizedProfile.workspace_id ?? workspace.id ?? DEFAULT_WORKSPACE_ID;\n if (workspace.name) {\n normalizedProfile.workspace_name = normalizedProfile.workspace_name ?? workspace.name;\n }\n\n const accountId = this.getAccountIdFromData(normalizedProfile);\n if (accountId) {\n const requestedWorkspace = normalizedProfile.workspace_id ?? DEFAULT_WORKSPACE_ID;\n const duplicate = await this.getProfileRowByAccountAndWorkspace(accountId, requestedWorkspace, { authMethod: 'codex-cli' });\n if (duplicate) {\n normalizedProfile.workspace_id = `${requestedWorkspace}:${profileName}`;\n normalizedProfile.workspace_name = normalizedProfile.workspace_name ?? profileName;\n }\n }\n\n const resolvedEmail = this.resolveProfileEmail(normalizedProfile, metadata);\n if (resolvedEmail) {\n normalizedProfile.email = resolvedEmail;\n }\n\n try {\n await this.persistProfileRecord(profileName, normalizedProfile, metadata);\n const stored = await this.getProfileRowByName(profileName);\n return stored ? this.buildProfileFromRow(stored) : null;\n } catch (error) {\n logError('Error creating profile:', error);\n throw new Error('Failed to create profile. Make sure Codex CLI is installed and you are logged in.');\n }\n }\n\n /**\n * Switch to a different profile\n */\n async switchToProfile(name: string): Promise<boolean> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n try {\n const profileData = record.data;\n const codexFormat = this.convertToCodexFormat(profileData);\n await this.writeAtomic(this.activeAuth, JSON.stringify(codexFormat, null, 2));\n await this.persistPreferredProfileName(profileName);\n return true;\n } catch (error) {\n logError('Error switching profile:', error);\n throw new Error('Failed to switch profile');\n }\n }\n\n async refreshProfileAuth(name: string): Promise<Profile> {\n await this.initialize();\n\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n const existing: ProfileData = record.data;\n let activeAuth: ActiveAuth;\n try {\n const authContent = await fs.readFile(this.activeAuth, 'utf8');\n activeAuth = JSON.parse(authContent) as ActiveAuth;\n } catch (error) {\n if (this.isNotFoundError(error)) {\n throw new Error('Codex CLI did not produce an auth file. Complete the login before refreshing this profile.');\n }\n logError('Failed to read Codex auth file during refresh:', error);\n throw new Error('Failed to read Codex auth file. Complete the login and try again.');\n }\n\n const normalized = this.normalizeProfileData(activeAuth);\n const existingAccountId = this.getAccountIdFromData(existing);\n const newAccountId = this.getAccountIdFromData(normalized);\n const normalizedMetadata = this.extractProfileMetadata(normalized);\n const normalizedWorkspace = this.resolveWorkspaceIdentity(normalized, normalizedMetadata);\n normalized.workspace_id = normalized.workspace_id ?? normalizedWorkspace.id ?? DEFAULT_WORKSPACE_ID;\n if (normalizedWorkspace.name) {\n normalized.workspace_name = normalized.workspace_name ?? normalizedWorkspace.name;\n }\n\n if (existingAccountId && newAccountId && existingAccountId !== newAccountId) {\n throw new Error(\n `Active Codex login is for account '${newAccountId}', but profile '${profileName}' is tied to '${existingAccountId}'. Create a new profile for the new account instead.`,\n );\n }\n\n if (existingAccountId && normalized.workspace_id) {\n const currentWorkspace = this.resolveWorkspaceIdentity(existing, this.extractProfileMetadata(existing));\n const targetWorkspaceId = normalized.workspace_id;\n const currentWorkspaceId = currentWorkspace.id ?? DEFAULT_WORKSPACE_ID;\n if (targetWorkspaceId !== currentWorkspaceId) {\n const duplicate = await this.getProfileRowByAccountAndWorkspace(existingAccountId, targetWorkspaceId, {\n authMethod: this.resolveAuthMethod(existing),\n });\n if (duplicate && duplicate.name !== profileName) {\n throw new Error(\n `Account is already saved as profile '${duplicate.name}'. Switch to or delete that profile before creating another.`,\n );\n }\n }\n }\n\n const { profile: merged, metadata } = this.mergeProfileRecords(existing, normalized);\n delete merged.tokenAlert;\n\n await this.persistProfileRecord(profileName, merged, metadata);\n const updated = await this.getProfileRowByName(profileName);\n if (!updated) {\n throw new Error('Failed to persist refreshed profile data.');\n }\n\n const profile = this.buildProfileFromRow(updated);\n if (metadata) {\n profile.metadata = metadata;\n profile.tokenStatus = this.evaluateTokenStatus(merged, metadata);\n }\n return profile;\n }\n\n /**\n * Execute an action with a profile's auth injected.\n * Creates an isolated CODEX_HOME with the profile's auth/config, invokes the action\n * with env overrides, then syncs any refreshed tokens back to the profile.\n */\n async runWithProfileAuth<T>(\n name: string,\n action: (env: NodeJS.ProcessEnv) => Promise<T>,\n ): Promise<T> {\n return this.enqueueAuthSwap(async () => {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n const profileData: ProfileData = record.data;\n const profileHome = this.getProfileHomePath(profileName);\n await fs.mkdir(profileHome, { recursive: true });\n\n if (profileData.auth_method && profileData.auth_method !== 'codex-cli') {\n throw new Error('Unsupported auth method. Codex CLI profiles only.');\n }\n const codexFormat = this.convertToCodexFormat(profileData);\n await this.prepareProfileHome(profileName, codexFormat);\n const authPath = path.join(profileHome, 'auth.json');\n\n const envOverrides: NodeJS.ProcessEnv = {\n ...process.env,\n HOME: profileHome,\n USERPROFILE: profileHome,\n CODEX_HOME: profileHome,\n };\n\n try {\n return await action(envOverrides);\n } finally {\n let finalAuthContent: string | null = null;\n try {\n finalAuthContent = await fs.readFile(authPath, 'utf8');\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to read isolated auth for '${profileName}' after action:`, error);\n }\n }\n\n try {\n if (finalAuthContent) {\n await this.syncProfileTokensFromAuthContent(profileName, profileData, finalAuthContent);\n } else {\n await this.syncProfileTokensFromActiveAuth(profileName, profileData, authPath);\n }\n } catch (error) {\n logWarn(`Failed to sync refreshed tokens for profile '${profileName}':`, error);\n }\n }\n });\n }\n\n /**\n * Rename a profile\n */\n async renameProfile(oldName: string, newName: string): Promise<boolean> {\n await this.initialize();\n const sourceName = this.normalizeProfileName(oldName);\n const targetName = this.normalizeProfileName(newName);\n\n const existing = await this.getProfileRowByName(sourceName);\n if (!existing) {\n throw new Error(`Profile '${sourceName}' not found!`);\n }\n\n if (await this.getProfileRowByName(targetName)) {\n throw new Error(`Profile '${targetName}' already exists!`);\n }\n\n const preferred = await this.readPreferredProfileName();\n if (preferred && preferred === sourceName) {\n await this.persistPreferredProfileName(targetName);\n }\n\n const oldHome = this.getProfileHomePath(sourceName);\n const newHome = this.getProfileHomePath(targetName);\n try {\n await fs.mkdir(this.profileHomesRoot, { recursive: true });\n await fs.rename(oldHome, newHome);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to move profile home from '${sourceName}' to '${targetName}':`, error);\n }\n }\n\n try {\n const updatedRecord: ProfileRecord = {\n ...existing,\n name: targetName,\n };\n await this.writeProfileRecord(updatedRecord);\n } catch (error) {\n logWarn(`Failed to rewrite profile record after renaming '${sourceName}' to '${targetName}':`, error);\n }\n\n return true;\n }\n\n async updateProfileDisplayName(name: string, displayName: string): Promise<boolean> {\n await this.initialize();\n\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n const trimmed = typeof displayName === 'string' ? displayName.trim() : '';\n if (!trimmed) {\n throw new Error('Profile name must not be empty.');\n }\n\n const now = new Date().toISOString();\n record.displayName = trimmed;\n record.updatedAt = now;\n (record.data as ProfileData & { updated_at?: string }).updated_at = now;\n\n await this.writeProfileRecord(record);\n return true;\n }\n\n /**\n * Delete a profile\n */\n async deleteProfile(name: string): Promise<boolean> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n const preferred = await this.readPreferredProfileName();\n if (preferred && preferred === profileName) {\n await this.persistPreferredProfileName(null);\n }\n try {\n await fs.rm(this.getProfileHomePath(profileName), { recursive: true, force: true });\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove profile home for '${profileName}':`, error);\n }\n }\n return true;\n }\n\n /**\n * Delete every profile that does not appear in the allow-list.\n * Used to enforce plan limits when local storage was tampered with.\n */\n async deleteProfilesNotIn(allowedNames: Iterable<string>): Promise<string[]> {\n await this.initialize();\n const normalized = new Set<string>();\n for (const name of allowedNames) {\n try {\n normalized.add(this.normalizeProfileName(name));\n } catch {\n // Skip invalid names so we only retain well-formed entries.\n }\n }\n\n const records = await this.listProfileRecords();\n const deleteCandidates = records\n .map(record => {\n try {\n return this.normalizeProfileName(record.name);\n } catch {\n return null;\n }\n })\n .filter((name): name is string => Boolean(name) && !normalized.has(name));\n\n if (deleteCandidates.length === 0) {\n return [];\n }\n\n const removed: string[] = [];\n for (const name of deleteCandidates) {\n try {\n await fs.rm(this.getProfileHomePath(name), { recursive: true, force: true });\n removed.push(name);\n } catch (error) {\n if (!this.isNotFoundError(error)) {\n logWarn(`Failed to remove profile '${name}' during plan enforcement:`, error);\n }\n }\n }\n const preferred = await this.readPreferredProfileName();\n if (preferred && removed.includes(preferred)) {\n await this.persistPreferredProfileName(null);\n }\n return removed;\n }\n\n /**\n * Check if the current auth matches a profile (for smart detection)\n */\n async getCurrentProfile(): Promise<{ name: string | null; trusted: boolean }> {\n await this.initialize();\n const preferredName = await this.readPreferredProfileName();\n if (preferredName) {\n try {\n const normalizedPreferred = this.normalizeProfileName(preferredName);\n const preferredRecord = await this.getProfileRowByName(normalizedPreferred);\n if (preferredRecord) {\n return { name: normalizedPreferred, trusted: true };\n }\n } catch {\n // fall through to active auth detection\n }\n }\n const activeAuth = await this.readActiveAuthFile();\n\n if (activeAuth) {\n const normalizedAuth = this.normalizeProfileData(activeAuth);\n const authMetadata = this.extractProfileMetadata(normalizedAuth);\n const workspace = this.resolveWorkspaceIdentity(normalizedAuth, authMetadata);\n const activeAccountId = this.getAccountIdFromData(normalizedAuth);\n\n if (activeAccountId) {\n const scoped = await this.getProfileRowByAccountAndWorkspace(activeAccountId, workspace.id ?? DEFAULT_WORKSPACE_ID, {\n preferAuthMethod: 'codex-cli',\n });\n if (scoped) {\n const normalized = this.normalizeProfileName(scoped.name);\n await this.persistPreferredProfileName(normalized);\n return { name: normalized, trusted: true };\n }\n\n const matching = await this.getProfileRowByAccountId(activeAccountId, { preferAuthMethod: 'codex-cli' });\n if (matching) {\n const normalized = this.normalizeProfileName(matching.name);\n await this.persistPreferredProfileName(normalized);\n return { name: normalized, trusted: true };\n }\n }\n }\n\n const preferred = await this.readPreferredProfileName();\n if (preferred) {\n try {\n const normalized = this.normalizeProfileName(preferred);\n const exists = await this.getProfileRowByName(normalized);\n if (exists) {\n return { name: normalized, trusted: true };\n }\n } catch {\n await this.persistPreferredProfileName(null);\n return { name: null, trusted: false };\n }\n await this.persistPreferredProfileName(null);\n }\n\n return { name: null, trusted: false };\n }\n\n /**\n * Export a profile to a portable format.\n * Sensitive tokens are included but should be handled securely.\n */\n async exportProfile(name: string): Promise<{\n name: string;\n displayName: string | null;\n email: string | null;\n accountId: string | null;\n workspaceId: string | null;\n workspaceName: string | null;\n authMethod: string | null;\n createdAt: string | null;\n metadata: ProfileMetadata | undefined;\n exportedAt: string;\n }> {\n await this.initialize();\n const profileName = this.normalizeProfileName(name);\n const record = await this.getProfileRowByName(profileName);\n if (!record) {\n throw new Error(`Profile '${profileName}' not found!`);\n }\n\n return {\n name: record.name,\n displayName: record.displayName,\n email: record.email,\n accountId: record.accountId,\n workspaceId: record.workspaceId,\n workspaceName: record.workspaceName,\n authMethod: record.authMethod,\n createdAt: record.createdAt,\n metadata: record.metadata,\n exportedAt: new Date().toISOString(),\n };\n }\n\n /**\n * Export all profiles to a portable format.\n */\n async exportAllProfiles(): Promise<Array<{\n name: string;\n displayName: string | null;\n email: string | null;\n accountId: string | null;\n workspaceId: string | null;\n workspaceName: string | null;\n authMethod: string | null;\n createdAt: string | null;\n metadata: ProfileMetadata | undefined;\n exportedAt: string;\n }>> {\n await this.initialize();\n const records = await this.listProfileRecords();\n const exportedAt = new Date().toISOString();\n \n return records.map(record => ({\n name: record.name,\n displayName: record.displayName,\n email: record.email,\n accountId: record.accountId,\n workspaceId: record.workspaceId,\n workspaceName: record.workspaceName,\n authMethod: record.authMethod,\n createdAt: record.createdAt,\n metadata: record.metadata,\n exportedAt,\n }));\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { logWarn } from './logger';\nimport { normalizeAutoRollSettings, type AutoRollSettings } from './auto-roll-settings';\nimport { normalizeCodexCliChannel, parseCodexCliChannel, type CodexCliChannel } from './codex-cli-channel';\n\ntype LicenseStatusCode = 'inactive' | 'active' | 'grace' | 'error';\n\ninterface StoredLicense {\n licenseKey?: string | null;\n purchaseEmail?: string | null;\n lastVerifiedAt?: string | null;\n nextCheckAt?: string | null;\n lastVerificationError?: string | null;\n status?: LicenseStatusCode;\n signature?: string | null;\n}\n\ninterface CodexSettings {\n license?: StoredLicense | null;\n lastProfileName?: string | null;\n autoRoll?: AutoRollSettings | null;\n lastAppVersion?: string | null;\n pendingUpdateVersion?: string | null;\n cliChannel?: CodexCliChannel | null;\n}\n\nconst KEY_LAST_PROFILE_NAME = 'last_profile_name';\nconst KEY_LICENSE = 'license';\nconst KEY_AUTO_ROLL = 'auto_roll';\nconst KEY_LAST_APP_VERSION = 'last_app_version';\nconst KEY_PENDING_UPDATE_VERSION = 'pending_update_version';\nconst KEY_CLI_CHANNEL = 'cli_channel';\nconst SETTINGS_FILE = 'settings.json';\nconst SETTINGS_BACKUP_FILE = 'settings.json.bak';\n\nfunction resolveCodexDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n return homeDir ? path.join(homeDir, '.codex') : '.codex';\n}\n\nfunction resolveSettingsPath(): string {\n return path.join(resolveCodexDir(), SETTINGS_FILE);\n}\n\nfunction resolveBackupSettingsPath(): string {\n return path.join(resolveCodexDir(), SETTINGS_BACKUP_FILE);\n}\n\nasync function ensureCodexDir(): Promise<void> {\n try {\n await fs.mkdir(resolveCodexDir(), { recursive: true });\n } catch (error) {\n logWarn('Failed to ensure Codex directory exists:', error);\n }\n}\n\nasync function writeAtomic(filePath: string, contents: string): Promise<void> {\n const tempPath = `${filePath}.tmp`;\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(tempPath, contents, 'utf8');\n try {\n await fs.rename(tempPath, filePath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n await fs.writeFile(filePath, contents, 'utf8');\n } else {\n throw error;\n }\n }\n try {\n await fs.rm(tempPath, { force: true });\n } catch {\n // ignore cleanup\n }\n}\n\nfunction normalizeStoredLicense(raw?: unknown): StoredLicense | null {\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n\n const source = raw as Record<string, unknown>;\n const licenseKey =\n typeof source.licenseKey === 'string'\n ? source.licenseKey\n : typeof source.license_key === 'string'\n ? source.license_key\n : null;\n const purchaseEmail =\n typeof source.purchaseEmail === 'string'\n ? source.purchaseEmail\n : typeof source.purchase_email === 'string'\n ? source.purchase_email\n : null;\n const lastVerifiedAt =\n typeof source.lastVerifiedAt === 'string'\n ? source.lastVerifiedAt\n : typeof source.last_verified_at === 'string'\n ? source.last_verified_at\n : null;\n const nextCheckAt =\n typeof source.nextCheckAt === 'string'\n ? source.nextCheckAt\n : typeof source.next_check_at === 'string'\n ? source.next_check_at\n : null;\n const lastVerificationError =\n typeof source.lastVerificationError === 'string'\n ? source.lastVerificationError\n : typeof source.last_verification_error === 'string'\n ? source.last_verification_error\n : null;\n const signature =\n typeof source.signature === 'string'\n ? source.signature\n : null;\n const statusCandidate =\n typeof source.status === 'string'\n ? (source.status as LicenseStatusCode)\n : undefined;\n\n const license: StoredLicense = {\n licenseKey,\n purchaseEmail,\n lastVerifiedAt,\n nextCheckAt,\n lastVerificationError,\n signature,\n status: statusCandidate,\n };\n\n const hasLicenseData = Boolean(\n license.licenseKey ??\n license.purchaseEmail ??\n license.lastVerifiedAt ??\n license.nextCheckAt ??\n license.lastVerificationError ??\n license.status,\n );\n\n return hasLicenseData ? license : null;\n}\n\nfunction normalizeStoredAutoRoll(raw?: unknown): AutoRollSettings | null {\n if (!raw) {\n return null;\n }\n\n const parsed = typeof raw === 'string' ? parseJsonValue(raw) : raw;\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n\n try {\n return normalizeAutoRollSettings(parsed as Partial<AutoRollSettings>);\n } catch {\n return null;\n }\n}\n\nfunction parseStoredProfileName(raw?: unknown): string | null {\n if (raw === null || raw === undefined) {\n return null;\n }\n\n if (typeof raw === 'string' || typeof raw === 'number') {\n const normalized = String(raw).trim();\n return normalized.length > 0 ? normalized : null;\n }\n\n const candidate = typeof raw === 'string' ? parseJsonValue(raw) : parseJsonValue(raw);\n if (typeof candidate === 'string' || typeof candidate === 'number') {\n const normalized = String(candidate).trim();\n return normalized.length > 0 ? normalized : null;\n }\n\n return null;\n}\n\nasync function markSettingsCorrupt(settingsPath: string, raw: string): Promise<void> {\n try {\n const suffix = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupPath = `${settingsPath}.corrupt-${suffix}`;\n await fs.writeFile(backupPath, raw, \"utf8\");\n } catch {\n // best effort backup\n }\n}\n\nasync function tryRestoreSettings(fromPath: string, _targetPath: string): Promise<CodexSettings | null> {\n try {\n const raw = await fs.readFile(fromPath, \"utf8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n const normalized = normalizeParsedSettings(parsed);\n await writeSettingsFile(normalized);\n return normalized;\n } catch {\n return null;\n }\n}\n\nfunction normalizeParsedSettings(parsed: Record<string, unknown>): CodexSettings {\n const license = normalizeStoredLicense((parsed as CodexSettings).license ?? (parsed as Record<string, unknown>)[KEY_LICENSE]);\n const autoRoll = normalizeStoredAutoRoll((parsed as CodexSettings).autoRoll ?? (parsed as Record<string, unknown>)[KEY_AUTO_ROLL]);\n const lastProfileName = parseStoredProfileName(\n (parsed as CodexSettings).lastProfileName ?? (parsed as Record<string, unknown>)[KEY_LAST_PROFILE_NAME],\n );\n const lastAppVersion =\n typeof (parsed as CodexSettings).lastAppVersion === 'string'\n ? (parsed as CodexSettings).lastAppVersion\n : typeof (parsed as Record<string, unknown>)[KEY_LAST_APP_VERSION] === 'string'\n ? (parsed as Record<string, unknown>)[KEY_LAST_APP_VERSION] as string\n : null;\n const pendingUpdateVersion =\n typeof (parsed as CodexSettings).pendingUpdateVersion === 'string'\n ? (parsed as CodexSettings).pendingUpdateVersion\n : typeof (parsed as Record<string, unknown>)[KEY_PENDING_UPDATE_VERSION] === 'string'\n ? (parsed as Record<string, unknown>)[KEY_PENDING_UPDATE_VERSION] as string\n : null;\n const cliChannel = parseCodexCliChannel(\n (parsed as CodexSettings).cliChannel ?? (parsed as Record<string, unknown>)[KEY_CLI_CHANNEL],\n );\n\n return {\n ...(license ? { license } : {}),\n ...(autoRoll ? { autoRoll } : {}),\n ...(lastProfileName ? { lastProfileName } : {}),\n ...(lastAppVersion ? { lastAppVersion } : {}),\n ...(pendingUpdateVersion ? { pendingUpdateVersion } : {}),\n ...(cliChannel ? { cliChannel } : {}),\n };\n}\n\nasync function readSettingsFromDisk(): Promise<CodexSettings | null> {\n const settingsPath = resolveSettingsPath();\n try {\n const raw = await fs.readFile(settingsPath, 'utf8');\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n return normalizeParsedSettings(parsed);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n if (error instanceof SyntaxError) {\n try {\n const raw = await fs.readFile(settingsPath, 'utf8');\n await markSettingsCorrupt(settingsPath, raw);\n\n const restoredFromTemp = await tryRestoreSettings(`${settingsPath}.tmp`, settingsPath);\n if (restoredFromTemp) {\n return restoredFromTemp;\n }\n\n const restoredFromBackup = await tryRestoreSettings(resolveBackupSettingsPath(), settingsPath);\n if (restoredFromBackup) {\n return restoredFromBackup;\n }\n\n await fs.writeFile(settingsPath, '{}\\n', 'utf8');\n } catch {\n // ignore backup/cleanup failures\n }\n }\n logWarn('Failed to parse Codex settings file, using defaults:', error);\n return null;\n }\n}\n\nasync function migrateSettingsFromDatabase(): Promise<CodexSettings | null> {\n try {\n const { __debugResolveDbPath, getDatabase } = await import('./sqlite-db');\n const dbPath = __debugResolveDbPath();\n try {\n await fs.access(dbPath);\n } catch {\n return null;\n }\n const db = await getDatabase();\n const rows = db\n .prepare(\n `SELECT key, value\n FROM app_kv\n WHERE key IN ('${KEY_LAST_PROFILE_NAME}', '${KEY_LICENSE}', '${KEY_AUTO_ROLL}', '${KEY_LAST_APP_VERSION}', '${KEY_PENDING_UPDATE_VERSION}', '${KEY_CLI_CHANNEL}')`,\n )\n .all() as Array<{ key?: string; value?: unknown }>;\n\n if (!rows || rows.length === 0) {\n return null;\n }\n\n const kv = new Map<string, unknown>();\n for (const row of rows) {\n if (!row.key) continue;\n if (typeof row.value === 'string') {\n kv.set(row.key, parseJsonValue(row.value));\n } else {\n kv.set(row.key, row.value);\n }\n }\n\n const license = normalizeStoredLicense(kv.get(KEY_LICENSE));\n const autoRoll = normalizeStoredAutoRoll(kv.get(KEY_AUTO_ROLL));\n const lastProfileName = parseStoredProfileName(kv.get(KEY_LAST_PROFILE_NAME));\n const lastAppVersion = typeof kv.get(KEY_LAST_APP_VERSION) === 'string' ? (kv.get(KEY_LAST_APP_VERSION) as string) : null;\n const pendingUpdateVersion =\n typeof kv.get(KEY_PENDING_UPDATE_VERSION) === 'string' ? (kv.get(KEY_PENDING_UPDATE_VERSION) as string) : null;\n const cliChannel = parseCodexCliChannel(kv.get(KEY_CLI_CHANNEL));\n\n const settings: CodexSettings = {\n ...(license ? { license } : {}),\n ...(autoRoll ? { autoRoll } : {}),\n ...(lastProfileName ? { lastProfileName } : {}),\n ...(lastAppVersion ? { lastAppVersion } : {}),\n ...(pendingUpdateVersion ? { pendingUpdateVersion } : {}),\n ...(cliChannel ? { cliChannel } : {}),\n };\n\n if (Object.keys(settings).length === 0) {\n return null;\n }\n\n await writeSettingsFile(settings);\n return settings;\n } catch (error) {\n logWarn('Failed to migrate Codex settings from database:', error);\n return null;\n }\n}\n\nasync function readSettingsFile(): Promise<CodexSettings> {\n await ensureCodexDir();\n\n const diskSettings = await readSettingsFromDisk();\n if (diskSettings) {\n return diskSettings;\n }\n\n const migrated = await migrateSettingsFromDatabase();\n if (migrated) {\n return migrated;\n }\n\n return {};\n}\n\nasync function writeSettingsFile(settings: CodexSettings): Promise<void> {\n await ensureCodexDir();\n const normalizedAutoRoll = settings.autoRoll ? normalizeAutoRollSettings(settings.autoRoll) : null;\n const normalizedLicense = settings.license\n ? {\n licenseKey: settings.license.licenseKey ?? null,\n purchaseEmail: settings.license.purchaseEmail ?? null,\n lastVerifiedAt: settings.license.lastVerifiedAt ?? null,\n nextCheckAt: settings.license.nextCheckAt ?? null,\n lastVerificationError: settings.license.lastVerificationError ?? null,\n status: settings.license.status ?? undefined,\n signature: settings.license.signature ?? null,\n }\n : null;\n\n const payload: CodexSettings = {\n ...(settings.lastProfileName ? { lastProfileName: settings.lastProfileName } : {}),\n ...(normalizedLicense ? { license: normalizedLicense } : {}),\n ...(normalizedAutoRoll ? { autoRoll: normalizedAutoRoll } : {}),\n ...(settings.lastAppVersion ? { lastAppVersion: settings.lastAppVersion } : {}),\n ...(settings.pendingUpdateVersion ? { pendingUpdateVersion: settings.pendingUpdateVersion } : {}),\n ...(settings.cliChannel ? { cliChannel: settings.cliChannel } : {}),\n };\n\n const serialized = JSON.stringify(payload, null, 2);\n const settingsPath = resolveSettingsPath();\n const backupPath = resolveBackupSettingsPath();\n const contents = `${serialized}\\n`;\n await writeAtomic(settingsPath, contents);\n try {\n await writeAtomic(backupPath, contents);\n } catch (error) {\n logWarn('Failed to write Codex settings backup:', error);\n }\n}\n\nfunction parseJsonValue(value?: unknown): unknown | null {\n if (typeof value !== 'string') {\n return null;\n }\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nexport async function getCodexSettings(): Promise<CodexSettings> {\n return readSettingsFile();\n}\n\nexport async function setCodexSettings(settings: CodexSettings): Promise<void> {\n await writeSettingsFile(settings);\n}\n\nexport async function getLastProfileName(): Promise<string | null> {\n const settings = await getCodexSettings();\n const candidate = settings.lastProfileName;\n if (typeof candidate !== 'string') {\n return null;\n }\n const trimmed = candidate.trim();\n return trimmed.length === 0 ? null : trimmed;\n}\n\nexport async function persistLastProfileName(profileName: string | null): Promise<void> {\n const settings = await getCodexSettings();\n if (profileName && profileName.trim().length > 0) {\n settings.lastProfileName = profileName.trim();\n } else if (settings.lastProfileName) {\n delete settings.lastProfileName;\n }\n await setCodexSettings(settings);\n}\n\nexport async function getStoredLicense(): Promise<StoredLicense | null> {\n const settings = await getCodexSettings();\n if (!settings.license) {\n return null;\n }\n return settings.license;\n}\n\nexport async function persistLicense(license: StoredLicense | null): Promise<void> {\n const settings = await getCodexSettings();\n if (license) {\n settings.license = {\n licenseKey: license.licenseKey ?? null,\n purchaseEmail: license.purchaseEmail ?? null,\n lastVerifiedAt: license.lastVerifiedAt ?? null,\n nextCheckAt: license.nextCheckAt ?? null,\n lastVerificationError: license.lastVerificationError ?? null,\n status: license.status ?? 'inactive',\n signature: license.signature ?? null,\n };\n } else if (settings.license) {\n delete settings.license;\n }\n\n await setCodexSettings(settings);\n}\n\nexport async function getStoredAutoRollSettings(): Promise<AutoRollSettings | null> {\n const settings = await getCodexSettings();\n if (!settings.autoRoll) {\n return null;\n }\n\n return normalizeAutoRollSettings(settings.autoRoll);\n}\n\nexport async function persistAutoRollSettings(settings: AutoRollSettings | null): Promise<void> {\n const current = await getCodexSettings();\n if (settings) {\n current.autoRoll = normalizeAutoRollSettings(settings);\n } else if (current.autoRoll) {\n delete current.autoRoll;\n }\n\n await setCodexSettings(current);\n}\n\nexport async function getStoredAppVersion(): Promise<string | null> {\n const settings = await getCodexSettings();\n const candidate = settings.lastAppVersion;\n if (typeof candidate !== 'string') {\n return null;\n }\n const trimmed = candidate.trim();\n return trimmed.length === 0 ? null : trimmed;\n}\n\nexport async function persistAppVersion(version: string | null): Promise<void> {\n const settings = await getCodexSettings();\n if (version && version.trim().length > 0) {\n settings.lastAppVersion = version.trim();\n } else if (settings.lastAppVersion) {\n delete settings.lastAppVersion;\n }\n\n await setCodexSettings(settings);\n}\n\nexport async function getPendingUpdateVersion(): Promise<string | null> {\n const settings = await getCodexSettings();\n const candidate = settings.pendingUpdateVersion;\n if (typeof candidate !== 'string') {\n return null;\n }\n const trimmed = candidate.trim();\n return trimmed.length === 0 ? null : trimmed;\n}\n\nexport async function persistPendingUpdateVersion(version: string | null): Promise<void> {\n const settings = await getCodexSettings();\n if (version && version.trim().length > 0) {\n settings.pendingUpdateVersion = version.trim();\n } else if (settings.pendingUpdateVersion) {\n delete settings.pendingUpdateVersion;\n }\n\n await setCodexSettings(settings);\n}\n\nexport async function getCodexCliChannel(): Promise<CodexCliChannel> {\n const settings = await getCodexSettings();\n return normalizeCodexCliChannel(settings.cliChannel);\n}\n\nexport async function persistCodexCliChannel(channel: CodexCliChannel | null): Promise<void> {\n const settings = await getCodexSettings();\n const normalized = channel ? normalizeCodexCliChannel(channel) : null;\n if (!normalized || normalized === 'stable') {\n if (settings.cliChannel) {\n delete settings.cliChannel;\n }\n } else {\n settings.cliChannel = normalized;\n }\n await setCodexSettings(settings);\n}\n\nexport type { StoredLicense, LicenseStatusCode };\nexport type { AutoRollSettings } from './auto-roll-settings';\nexport type { CodexCliChannel } from './codex-cli-channel';\n","const isTestEnv =\n process.env.NODE_ENV === 'test' ||\n process.env.VITEST === 'true' ||\n process.env.VITEST === '1';\n\nfunction isMocked(fn: unknown): boolean {\n return Boolean(fn && typeof fn === 'function' && 'mock' in (fn as Record<string, unknown>));\n}\n\nexport function logWarn(...args: Parameters<typeof console.warn>): void {\n if (isTestEnv && !isMocked(console.warn)) {\n return;\n }\n console.warn(...args);\n}\n\nexport function logError(...args: Parameters<typeof console.error>): void {\n if (isTestEnv && !isMocked(console.error)) {\n return;\n }\n console.error(...args);\n}\n\nexport function logInfo(...args: Parameters<typeof console.warn>): void {\n if (isTestEnv && !isMocked(console.warn)) {\n return;\n }\n console.warn(...args);\n}\n","export type CodexCliChannel = \"stable\" | \"alpha\";\n\nconst KNOWN_CHANNELS = new Set<CodexCliChannel>([\"stable\", \"alpha\"]);\n\nexport function parseCodexCliChannel(value?: unknown): CodexCliChannel | null {\n if (typeof value !== \"string\") {\n return null;\n }\n\n const normalized = value.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n return KNOWN_CHANNELS.has(normalized as CodexCliChannel)\n ? (normalized as CodexCliChannel)\n : null;\n}\n\nexport function normalizeCodexCliChannel(\n value?: unknown,\n fallback: CodexCliChannel = \"stable\",\n): CodexCliChannel {\n return parseCodexCliChannel(value) ?? fallback;\n}\n","import crypto from 'node:crypto';\nimport { persistLicense, getStoredLicense, type StoredLicense } from './codex-settings';\nimport { getLicenseSecret } from './license-secret';\n\nconst PRODUCT_PERMALINK = 'codex-use';\nconst PRODUCT_ID = '3_CcyVEXt2FOMiEpPx8xzw==';\nconst BASE_PRICE = 19;\nconst BASE_PRICE_DISPLAY = '$19';\nconst PROMO_CODE = 'NOELNEWYEAR50';\nconst PROMO_PERCENT = 50;\nconst PROMO_ACTIVE = true;\nconst PROMO_PRICE_DISPLAY = `$${(BASE_PRICE * (100 - PROMO_PERCENT) / 100).toFixed(2)}`;\nconst PRODUCT_URL = PROMO_ACTIVE\n ? `https://hweihwang.gumroad.com/l/${PRODUCT_PERMALINK}/${PROMO_CODE}`\n : 'https://hweihwang.gumroad.com/l/codex-use';\nconst LICENSE_PRICE_DISPLAY = PROMO_ACTIVE ? PROMO_PRICE_DISPLAY : BASE_PRICE_DISPLAY;\nconst LICENSE_MAX_USES = 5;\nconst FREE_PROFILE_LIMIT = 2;\nconst LICENSE_REFRESH_INTERVAL_MS = 5 * 60 * 1000;\nconst MAX_NEXT_CHECK_MS = 60 * 60 * 1000;\nconst GRACE_MAX_AGE_MS = 3 * 60 * 60 * 1000;\n\ntype LicenseTier = 'free' | 'pro';\ntype LicenseState = 'inactive' | 'active' | 'grace' | 'verifying' | 'error';\n\ninterface LicenseStatus {\n tier: LicenseTier;\n state: LicenseState;\n isPro: boolean;\n profileLimit: number | null;\n profilesRemaining: number | null;\n purchaseEmail: string | null;\n maskedLicenseKey: string | null;\n lastVerifiedAt: string | null;\n nextCheckAt: string | null;\n message: string | null;\n error: string | null;\n productPermalink: string;\n productUrl: string;\n productId: string;\n priceDisplay: string;\n basePriceDisplay: string;\n promoCode: string | null;\n promoPercent: number | null;\n}\n\ninterface GumroadLicenseResponse {\n success: boolean;\n message?: string;\n uses?: number;\n purchase?: {\n id: string;\n email: string;\n product_id?: string;\n product_permalink?: string;\n refunded?: boolean;\n chargebacked?: boolean;\n subscription_cancelled?: boolean;\n subscription_failed?: boolean;\n license_disabled?: boolean;\n variants?: string;\n };\n license_disabled?: boolean;\n}\n\ntype VerificationMode = 'activation' | 'refresh';\n\nclass LicenseError extends Error {\n readonly code: 'network' | 'invalid' | 'revoked';\n\n constructor(message: string, code: 'network' | 'invalid' | 'revoked') {\n super(message);\n this.name = 'LicenseError';\n this.code = code;\n }\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction maskLicenseKey(key: string | null | undefined): string | null {\n if (!key || typeof key !== 'string') {\n return null;\n }\n\n const trimmed = key.trim();\n if (trimmed.length <= 4) {\n return '••••';\n }\n\n const visible = trimmed.slice(-4);\n return `••••${visible}`;\n}\n\nfunction resolveProfilesRemaining(limit: number | null, currentProfiles: number): number | null {\n if (typeof limit !== 'number') {\n return null;\n }\n return Math.max(0, limit - currentProfiles);\n}\n\nfunction determineTierFromStored(stored: StoredLicense | null): LicenseTier {\n if (!stored || !stored.licenseKey) {\n return 'free';\n }\n\n if (stored.status === 'inactive') {\n return 'free';\n }\n\n return 'pro';\n}\n\nfunction licenseSignaturePayload(license: StoredLicense): string {\n const payload = {\n licenseKey: license.licenseKey ?? null,\n purchaseEmail: license.purchaseEmail ?? null,\n lastVerifiedAt: license.lastVerifiedAt ?? null,\n nextCheckAt: license.nextCheckAt ?? null,\n lastVerificationError: license.lastVerificationError ?? null,\n status: license.status ?? null,\n };\n return JSON.stringify(payload);\n}\n\nfunction signLicense(license: StoredLicense, secret: string): string {\n return crypto.createHmac('sha256', secret).update(licenseSignaturePayload(license)).digest('hex');\n}\n\nfunction withSignature(license: StoredLicense, secret: string): StoredLicense {\n return {\n ...license,\n signature: signLicense(license, secret),\n };\n}\n\nfunction isSignatureValid(license: StoredLicense, secret: string): boolean {\n if (!license.signature) {\n return false;\n }\n const expected = signLicense(license, secret);\n return expected === license.signature;\n}\n\nasync function requestGumroadVerify(licenseKey: string, mode: VerificationMode): Promise<GumroadLicenseResponse> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 10_000);\n\n try {\n const body = new URLSearchParams({\n product_permalink: PRODUCT_PERMALINK,\n product_id: PRODUCT_ID,\n license_key: licenseKey,\n increment_uses_count: mode === 'activation' ? 'true' : 'false',\n });\n\n const response = await fetch('https://api.gumroad.com/v2/licenses/verify', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => null);\n const message = errorText\n ? `License verification failed (${response.status}): ${errorText}`\n : `License verification failed (${response.status}).`;\n throw new LicenseError(message, 'network');\n }\n\n const json = (await response.json()) as GumroadLicenseResponse;\n return json;\n } catch (error) {\n if (error instanceof LicenseError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new LicenseError('License verification timed out.', 'network');\n }\n\n throw new LicenseError(\n error instanceof Error ? error.message : 'Unable to reach Gumroad for license verification.',\n 'network',\n );\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction normalizeVerificationResult(response: GumroadLicenseResponse): { email: string | null } {\n if (!response.success) {\n const message = response.message ?? 'License key is invalid.';\n throw new LicenseError(message, 'invalid');\n }\n\n if (!response.purchase) {\n throw new LicenseError('License verification response was incomplete.', 'network');\n }\n\n if (response.purchase.chargebacked || response.purchase.refunded || response.license_disabled) {\n throw new LicenseError('This license has been revoked or refunded.', 'revoked');\n }\n\n if (response.purchase.subscription_cancelled || response.purchase.subscription_failed) {\n throw new LicenseError('This license subscription is no longer active.', 'revoked');\n }\n\n const email = response.purchase.email ?? null;\n return { email };\n}\n\nfunction ensureWithinUseLimit(response: GumroadLicenseResponse): void {\n if (!response.success) {\n return;\n }\n\n if (typeof response.uses !== 'number') {\n return;\n }\n\n if (response.uses > LICENSE_MAX_USES) {\n throw new LicenseError(\n `This license has reached the activation limit (${LICENSE_MAX_USES}). Contact support to move it to another device.`,\n 'invalid',\n );\n }\n}\n\nfunction toLicenseStatus(stored: StoredLicense | null, overrides: Partial<LicenseStatus> = {}): LicenseStatus {\n const tier = determineTierFromStored(stored);\n const isPro = tier === 'pro';\n\n const state: LicenseState =\n stored && stored.status\n ? stored.status\n : isPro\n ? 'active'\n : 'inactive';\n\n const base: LicenseStatus = {\n tier,\n state,\n isPro,\n profileLimit: isPro ? null : FREE_PROFILE_LIMIT,\n profilesRemaining: null,\n purchaseEmail: stored?.purchaseEmail ?? null,\n maskedLicenseKey: maskLicenseKey(stored?.licenseKey),\n lastVerifiedAt: stored?.lastVerifiedAt ?? null,\n nextCheckAt: stored?.nextCheckAt ?? null,\n message: null,\n error: stored?.lastVerificationError ?? null,\n productUrl: PRODUCT_URL,\n productId: PRODUCT_ID,\n productPermalink: PRODUCT_PERMALINK,\n priceDisplay: LICENSE_PRICE_DISPLAY,\n basePriceDisplay: BASE_PRICE_DISPLAY,\n promoCode: PROMO_ACTIVE ? PROMO_CODE : null,\n promoPercent: PROMO_ACTIVE ? PROMO_PERCENT : null,\n };\n\n return { ...base, ...overrides };\n}\n\nfunction parseTimestamp(value: string | null | undefined): number | null {\n if (typeof value !== 'string' || value.trim() === '') {\n return null;\n }\n\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? null : parsed;\n}\n\nclass LicenseService {\n private cache: LicenseStatus | null = null;\n private refreshPromise: Promise<void> | null = null;\n private verificationPromise: Promise<LicenseStatus> | null = null;\n\n async getCachedStatus(): Promise<LicenseStatus> {\n return this.getStatus();\n }\n\n async getStatus(options: { forceRefresh?: boolean } = {}): Promise<LicenseStatus> {\n const forceRefresh = Boolean(options.forceRefresh);\n const secret = await getLicenseSecret();\n const stored = await getStoredLicense();\n\n if (!stored?.licenseKey) {\n const status = toLicenseStatus(null);\n this.cache = status;\n return status;\n }\n\n const now = Date.now();\n const nextCheckTs = parseTimestamp(stored.nextCheckAt);\n const lastVerifiedTs = parseTimestamp(stored.lastVerifiedAt);\n const graceStale =\n (stored.status === 'grace' || stored.status === 'error') &&\n (lastVerifiedTs === null || lastVerifiedTs + GRACE_MAX_AGE_MS < now);\n\n let workingStored: StoredLicense = { ...stored };\n const signatureValid = isSignatureValid(workingStored, secret);\n\n let cappedNextCheckTs = nextCheckTs;\n\n if (nextCheckTs !== null && nextCheckTs > now + MAX_NEXT_CHECK_MS) {\n cappedNextCheckTs = now;\n const updated = {\n ...workingStored,\n nextCheckAt: new Date(cappedNextCheckTs).toISOString(),\n };\n const signed = withSignature(updated, secret);\n workingStored = signed;\n await persistLicense(signed);\n }\n\n const tampered = Boolean(workingStored.licenseKey) && !signatureValid;\n\n const cached = tampered\n ? toLicenseStatus(null, {\n state: 'verifying',\n message: 'License data changed, rechecking.',\n error: 'Untrusted license data.',\n })\n : toLicenseStatus(workingStored);\n this.cache = cached;\n\n const shouldRefresh =\n forceRefresh || graceStale || tampered || cappedNextCheckTs === null || cappedNextCheckTs <= now;\n\n if (!shouldRefresh) {\n return cached;\n }\n\n if (this.verificationPromise && !forceRefresh) {\n return this.verificationPromise;\n }\n\n const verify = async (): Promise<LicenseStatus> => {\n try {\n const result = await requestGumroadVerify(workingStored.licenseKey!, 'refresh');\n ensureWithinUseLimit(result);\n const normalized = normalizeVerificationResult(result);\n const updated: StoredLicense = {\n licenseKey: workingStored.licenseKey,\n purchaseEmail: normalized.email,\n lastVerifiedAt: nowIso(),\n nextCheckAt: new Date(Date.now() + LICENSE_REFRESH_INTERVAL_MS).toISOString(),\n status: 'active',\n lastVerificationError: null,\n };\n\n const signed = withSignature(updated, secret);\n\n await persistLicense(signed);\n const status = toLicenseStatus(signed);\n this.cache = status;\n return status;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'License verification failed.';\n\n if (error instanceof LicenseError && error.code === 'network') {\n const fallbackStored: StoredLicense = withSignature(\n {\n ...workingStored,\n status: tampered ? 'inactive' : workingStored.status === 'inactive' ? 'inactive' : 'grace',\n lastVerificationError: message,\n nextCheckAt: new Date(Date.now() + LICENSE_REFRESH_INTERVAL_MS).toISOString(),\n },\n secret,\n );\n await persistLicense(fallbackStored);\n const fallback = toLicenseStatus(fallbackStored, {\n state: fallbackStored.status ?? 'grace',\n error: message,\n });\n this.cache = fallback;\n return fallback;\n }\n\n const fallbackStored: StoredLicense = withSignature({\n licenseKey: workingStored.licenseKey,\n purchaseEmail: workingStored.purchaseEmail ?? null,\n lastVerifiedAt: workingStored.lastVerifiedAt ?? null,\n nextCheckAt: null,\n status: 'inactive',\n lastVerificationError: message,\n }, secret);\n await persistLicense(fallbackStored);\n const fallback = toLicenseStatus(fallbackStored, { error: message });\n this.cache = fallback;\n return fallback;\n }\n };\n\n this.verificationPromise = verify();\n try {\n return await this.verificationPromise;\n } finally {\n this.verificationPromise = null;\n }\n }\n\n async activate(licenseKey: string): Promise<LicenseStatus> {\n const trimmed = licenseKey.trim();\n if (!trimmed) {\n throw new Error('License key is required.');\n }\n\n const secret = await getLicenseSecret();\n const digest = crypto.createHash('sha256').update(trimmed).digest('hex');\n\n const result = await requestGumroadVerify(trimmed, 'activation');\n ensureWithinUseLimit(result);\n const normalized = normalizeVerificationResult(result);\n const stored: StoredLicense = {\n licenseKey: trimmed,\n purchaseEmail: normalized.email,\n lastVerifiedAt: nowIso(),\n nextCheckAt: new Date(Date.now() + LICENSE_REFRESH_INTERVAL_MS).toISOString(),\n status: 'active',\n lastVerificationError: null,\n };\n\n const signed = withSignature(stored, secret);\n\n await persistLicense(signed);\n const status = toLicenseStatus(signed, {\n message: `License verified (${digest.slice(0, 8)}).`,\n });\n this.cache = status;\n return status;\n }\n\n applyProfileCount(status: LicenseStatus, profileCount: number): LicenseStatus {\n const profilesRemaining = resolveProfilesRemaining(status.profileLimit, profileCount);\n return {\n ...status,\n profilesRemaining,\n };\n }\n\n refreshStatusInBackground(options: { force?: boolean } = {}): void {\n if (this.refreshPromise) {\n return;\n }\n\n const forceRefresh = Boolean(options.force);\n this.refreshPromise = (async () => {\n try {\n await this.getStatus({ forceRefresh });\n } catch (error) {\n console.warn('Background license refresh failed:', error);\n } finally {\n this.refreshPromise = null;\n }\n })();\n }\n}\n\nexport const licenseService = new LicenseService();\nexport type { LicenseStatus, LicenseTier, LicenseState };\nexport { FREE_PROFILE_LIMIT, LICENSE_PRICE_DISPLAY, PRODUCT_PERMALINK, PRODUCT_URL, PRODUCT_ID };\n\nfunction isExplicitInvalidation(message: string | null | undefined): boolean {\n if (!message) {\n return false;\n }\n const normalized = message.toLowerCase();\n return (\n normalized.includes('revoked') ||\n normalized.includes('refunded') ||\n normalized.includes('invalid') ||\n normalized.includes('no longer active')\n );\n}\n\n/**\n * Determines when it is safe to enforce profile limits (e.g., pruning).\n * We skip enforcement when the license state is uncertain (grace/error/verifying)\n * and only enforce limits for true free/unlicensed states or explicit revocations.\n */\nexport function shouldEnforceProfileLimit(status: LicenseStatus): boolean {\n if (status.isPro) {\n return false;\n }\n\n if (status.state === 'grace' || status.state === 'verifying' || status.state === 'error') {\n return false;\n }\n\n if (isExplicitInvalidation(status.error)) {\n return true;\n }\n\n return status.state === 'inactive';\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\n\nconst SECRET_FILE = 'license.secret';\n\nfunction resolveCodexDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n return homeDir ? path.join(homeDir, '.codex') : '.codex';\n}\n\nfunction resolveSecretPath(): string {\n return path.join(resolveCodexDir(), SECRET_FILE);\n}\n\nasync function generateSecret(): Promise<string> {\n return crypto.randomBytes(32).toString('hex');\n}\n\nexport async function getLicenseSecret(): Promise<string> {\n const secretPath = resolveSecretPath();\n try {\n const existing = await fs.readFile(secretPath, 'utf8');\n const trimmed = existing.trim();\n if (trimmed.length > 0) {\n return trimmed;\n }\n } catch {\n // fall through and create a new secret\n }\n\n const secret = await generateSecret();\n try {\n await fs.mkdir(path.dirname(secretPath), { recursive: true });\n } catch {\n // best effort\n }\n\n await fs.writeFile(secretPath, `${secret}\\n`, { mode: 0o600 });\n return secret;\n}\n","import { licenseService } from \"./license-service\";\nimport { ProfileManager } from \"./profile-manager\";\n\nexport async function assertProfileCreationAllowed(\n profileManager?: ProfileManager,\n): Promise<void> {\n const manager = profileManager ?? new ProfileManager();\n await manager.initialize();\n\n const license = await licenseService.getStatus();\n const profiles = await manager.listProfiles();\n const licenseWithCounts = licenseService.applyProfileCount(license, profiles.length);\n\n if (\n typeof licenseWithCounts.profileLimit === \"number\" &&\n licenseWithCounts.profilesRemaining !== null &&\n licenseWithCounts.profilesRemaining <= 0\n ) {\n throw new Error(\"CodexUse Free supports up to 2 profiles. Upgrade to CodexUse Pro for unlimited profiles.\");\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst ENV_HINTS = [\"CODEX_BINARY\", \"CODEX_CLI_PATH\", \"CODEX_PATH\"] as const;\nconst NODE_MODULE_CANDIDATES = [\n [\"@openai\", \"codex\"],\n [\"@openai\", \"codex-alpha\"],\n];\n\nexport type CodexLoginMode = \"browser\" | \"device\";\n\nfunction fileExists(candidate: string | null | undefined): string | null {\n if (!candidate) return null;\n const resolved = path.resolve(candidate);\n try {\n const stat = statSync(resolved);\n if (stat.isFile()) return resolved;\n } catch {\n return null;\n }\n return null;\n}\n\nfunction resolveFromEnv(): string | null {\n for (const key of ENV_HINTS) {\n const value = process.env[key];\n if (!value) continue;\n const resolved = fileExists(value);\n if (resolved) return resolved;\n }\n return null;\n}\n\nfunction resolveFromAppResources(): string | null {\n const roots = [\n path.resolve(__dirname, \"..\"),\n path.resolve(__dirname, \"..\", \"..\"),\n ];\n\n for (const root of roots) {\n const base = path.join(root, \"app.asar.unpacked\", \"node_modules\");\n for (const segments of NODE_MODULE_CANDIDATES) {\n const candidate = fileExists(path.join(base, ...segments, \"bin\", \"codex\"));\n if (candidate) return candidate;\n const jsCandidate = fileExists(path.join(base, ...segments, \"bin\", \"codex.js\"));\n if (jsCandidate) return jsCandidate;\n }\n }\n\n return null;\n}\n\nfunction resolveFromNodeModules(): string | null {\n let current = path.resolve(__dirname, \"..\");\n let last = \"\";\n\n while (current !== last) {\n for (const segments of NODE_MODULE_CANDIDATES) {\n const candidate = fileExists(path.join(current, \"node_modules\", ...segments, \"bin\", \"codex\"));\n if (candidate) return candidate;\n const jsCandidate = fileExists(path.join(current, \"node_modules\", ...segments, \"bin\", \"codex.js\"));\n if (jsCandidate) return jsCandidate;\n }\n last = current;\n current = path.dirname(current);\n }\n\n return null;\n}\n\nfunction resolveFromPath(): string | null {\n const pathValue = process.env.PATH ?? \"\";\n const entries = pathValue.split(path.delimiter).filter(Boolean);\n const names = process.platform === \"win32\"\n ? [\"codex.exe\", \"codex.cmd\", \"codex.bat\", \"codex\"]\n : [\"codex\"];\n\n for (const entry of entries) {\n for (const name of names) {\n const candidate = fileExists(path.join(entry, name));\n if (candidate) return candidate;\n }\n }\n\n return null;\n}\n\nexport function resolveCodexBinary(): string | null {\n return (\n resolveFromEnv() ||\n resolveFromAppResources() ||\n resolveFromNodeModules() ||\n resolveFromPath()\n );\n}\n\nexport function requireCodexBinary(context?: string): string {\n const resolved = resolveCodexBinary();\n if (resolved) return resolved;\n const hint = \"Install Codex CLI (npm i -g @openai/codex) or set CODEX_BINARY.\";\n const message = context ? `${context} ${hint}` : hint;\n throw new Error(message);\n}\n\nfunction buildCodexCommand(codexPath: string, args: string[]): { command: string; args: string[]; shell: boolean } {\n const normalized = codexPath.toLowerCase();\n const isJs = normalized.endsWith(\".js\");\n if (isJs) {\n return { command: process.execPath, args: [codexPath, ...args], shell: false };\n }\n\n const useShell = process.platform === \"win32\";\n return { command: codexPath, args, shell: useShell };\n}\n\nfunction isHeadless(): boolean {\n if (process.env.CODEXUSE_HEADLESS === \"1\") return true;\n if (process.env.CI) return true;\n if (process.env.SSH_CONNECTION || process.env.SSH_TTY) return true;\n if (process.platform === \"linux\") {\n if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) return true;\n }\n return false;\n}\n\nexport function resolveLoginMode(preferred?: CodexLoginMode | null): CodexLoginMode {\n if (preferred === \"browser\" || preferred === \"device\") {\n return preferred;\n }\n const envMode = process.env.CODEXUSE_LOGIN_MODE;\n if (envMode === \"browser\" || envMode === \"device\") {\n return envMode;\n }\n return isHeadless() ? \"device\" : \"browser\";\n}\n\nexport async function runCodexLogin(mode?: CodexLoginMode | null): Promise<void> {\n const codexPath = requireCodexBinary(\"Codex CLI is required to login.\");\n const resolvedMode = resolveLoginMode(mode ?? null);\n const loginArgs = resolvedMode === \"device\"\n ? [\"login\", \"--device-auth\"]\n : [\"login\"];\n const { command, args, shell } = buildCodexCommand(codexPath, loginArgs);\n\n const child = spawn(command, args, {\n stdio: \"inherit\",\n env: process.env,\n shell,\n });\n\n const exitCode = await new Promise<number>((resolve) => {\n child.on(\"close\", (code) => resolve(code ?? 0));\n });\n\n if (exitCode !== 0) {\n throw new Error(`Codex CLI login failed (exit code ${exitCode}).`);\n }\n}\n","import { spawn } from \"node:child_process\";\nimport readline from \"node:readline\";\nimport { once } from \"node:events\";\nimport { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { requireCodexCli } from \"./codex-cli\";\nimport type { RateLimitSnapshot, RateLimitWindow } from \"./types\";\n\ntype RpcMessage = { id?: number; result?: unknown; error?: unknown };\n\ntype RpcRateLimitWindow = {\n usedPercent?: number;\n windowDurationMins?: number;\n resetsAt?: number;\n};\n\ntype RpcRateLimitSnapshot = {\n primary?: RpcRateLimitWindow | null;\n secondary?: RpcRateLimitWindow | null;\n};\n\nconst RPC_TIMEOUT_MS = 10_000;\n\nasync function sendPayload(\n child: ReturnType<typeof spawn>,\n payload: Record<string, unknown>,\n): Promise<void> {\n child.stdin?.write(JSON.stringify(payload));\n child.stdin?.write(\"\\n\");\n}\n\nasync function readMessage(\n rl: readline.Interface,\n timeoutMs: number,\n): Promise<RpcMessage> {\n const timeout = new Promise<never>((_, reject) => {\n const timer = setTimeout(() => {\n clearTimeout(timer);\n reject(new Error(\"codex RPC timed out\"));\n }, timeoutMs);\n });\n\n const linePromise = once(rl, \"line\").then(args => args[0] as string);\n\n const line = (await Promise.race([linePromise, timeout])) as string;\n try {\n return JSON.parse(line) as RpcMessage;\n } catch {\n throw new Error(\"codex RPC returned malformed JSON\");\n }\n}\n\nfunction toWindow(rpc?: RpcRateLimitWindow | null): RateLimitWindow | undefined {\n if (!rpc) return undefined;\n const usedPercent =\n typeof rpc.usedPercent === \"number\" && Number.isFinite(rpc.usedPercent)\n ? rpc.usedPercent\n : undefined;\n const windowMinutes =\n typeof rpc.windowDurationMins === \"number\" && Number.isFinite(rpc.windowDurationMins)\n ? rpc.windowDurationMins\n : undefined;\n\n let resetsAt: string | undefined;\n let resetsInSeconds: number | undefined;\n if (typeof rpc.resetsAt === \"number\" && Number.isFinite(rpc.resetsAt)) {\n const ms = rpc.resetsAt > 10_000_000_000 ? rpc.resetsAt : rpc.resetsAt * 1000;\n resetsAt = new Date(ms).toISOString();\n resetsInSeconds = Math.max(0, Math.round((ms - Date.now()) / 1000));\n }\n\n if (\n typeof usedPercent === \"undefined\" &&\n typeof windowMinutes === \"undefined\" &&\n typeof resetsAt === \"undefined\"\n ) {\n return undefined;\n }\n\n const window: RateLimitWindow = {};\n if (typeof usedPercent === \"number\") {\n window.usedPercent = usedPercent;\n }\n if (typeof windowMinutes === \"number\") {\n window.windowMinutes = windowMinutes;\n }\n if (typeof resetsAt === \"string\") {\n window.resetsAt = resetsAt;\n }\n if (typeof resetsInSeconds === \"number\") {\n window.resetsInSeconds = resetsInSeconds;\n }\n return window;\n}\n\nexport async function fetchRateLimitsViaRpc(\n envOverride?: NodeJS.ProcessEnv,\n options: { authPath?: string; codexPath?: string } = {},\n): Promise<RateLimitSnapshot | null> {\n const binaryPath = options.codexPath ?? await requireCodexCli();\n const tempHome = await fs.mkdtemp(path.join(os.tmpdir(), \"codex-rpc-\"));\n\n const sourceAuthPath =\n options.authPath ??\n (envOverride?.CODEX_HOME\n ? path.join(envOverride.CODEX_HOME, \"auth.json\")\n : path.join(\n envOverride?.HOME ?? process.env.HOME ?? process.env.USERPROFILE ?? os.homedir(),\n \".codex\",\n \"auth.json\",\n ));\n\n try {\n const authContent = await fs.readFile(sourceAuthPath, \"utf8\").catch(() => null);\n if (!authContent) {\n return null;\n }\n await fs.writeFile(path.join(tempHome, \"auth.json\"), authContent, \"utf8\");\n } catch {\n await fs.rm(tempHome, { recursive: true, force: true }).catch(() => {});\n return null;\n }\n\n const child = spawn(process.execPath, [binaryPath, \"-s\", \"read-only\", \"-a\", \"untrusted\", \"app-server\"], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n ...(envOverride ?? {}),\n HOME: tempHome,\n USERPROFILE: tempHome,\n CODEX_HOME: tempHome,\n CODEX_TELEMETRY_LABEL: \"codex-rpc\",\n ELECTRON_RUN_AS_NODE: \"1\",\n },\n });\n\n const rl = readline.createInterface({\n input: child.stdout!,\n crlfDelay: Infinity,\n });\n\n try {\n await sendPayload(child, {\n id: 1,\n method: \"initialize\",\n params: { clientInfo: { name: \"codexuse\", version: \"0.0.0\" } },\n });\n await readMessage(rl, RPC_TIMEOUT_MS);\n\n await sendPayload(child, { method: \"initialized\", params: {} });\n\n await sendPayload(child, { id: 2, method: \"account/rateLimits/read\", params: {} });\n const message = await readMessage(rl, RPC_TIMEOUT_MS);\n const result = message.result as { rateLimits?: RpcRateLimitSnapshot } | undefined;\n const limits = result?.rateLimits;\n const primary = toWindow(limits?.primary ?? null);\n const secondary = toWindow(limits?.secondary ?? null);\n\n if (!primary && !secondary) {\n return null;\n }\n\n const snapshot: RateLimitSnapshot = {\n lastUpdated: new Date().toISOString(),\n source: \"codex-rpc\",\n };\n if (primary) {\n snapshot.primary = primary;\n }\n if (secondary) {\n snapshot.secondary = secondary;\n }\n return snapshot;\n } finally {\n child.kill();\n rl.close();\n await fs.rm(tempHome, { recursive: true, force: true }).catch(() => {});\n }\n}\n","import { readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { CodexCliInfoPayload, CodexCliStatusPayload } from \"./ipc-types\";\nimport { getCodexCliChannel } from \"./codex-settings\";\nimport type { CodexCliChannel } from \"./codex-cli-channel\";\n\ntype MutableStatus = CodexCliStatusPayload;\n\nlet cachedStatus: MutableStatus | null = null;\nlet cachedChannel: CodexCliChannel | null = null;\n\nfunction fileExists(candidate: string | undefined | null): string | null {\n if (!candidate) {\n return null;\n }\n\n const normalized = path.resolve(candidate);\n\n try {\n const stats = statSync(normalized);\n if (stats.isFile()) {\n return normalized;\n }\n } catch {\n // ignore missing paths\n }\n\n return null;\n}\n\nfunction resolveBundledCodexBinary(channel: CodexCliChannel): string | null {\n const candidates: string[] = [];\n const processWithResources = process as NodeJS.Process & { resourcesPath?: string };\n const resourcesPath = processWithResources.resourcesPath;\n const packageSegments = channel === \"alpha\" ? [\"@openai\", \"codex-alpha\"] : [\"@openai\", \"codex\"];\n\n if (resourcesPath) {\n candidates.push(\n path.join(resourcesPath, \"app.asar.unpacked\", \"node_modules\", ...packageSegments, \"bin\", \"codex.js\"),\n );\n candidates.push(\n path.join(resourcesPath, \"app.asar.unpacked\", \"node_modules\", ...packageSegments, \"bin\", \"codex\"),\n );\n }\n\n const projectRoot = process.cwd();\n candidates.push(path.join(projectRoot, \"node_modules\", ...packageSegments, \"bin\", \"codex.js\"));\n candidates.push(path.join(projectRoot, \"node_modules\", ...packageSegments, \"bin\", \"codex\"));\n\n for (const candidate of candidates) {\n const resolved = fileExists(candidate);\n if (resolved) {\n return resolved;\n }\n }\n\n return null;\n}\n\nfunction resolvePackageJsonPath(cliPath: string): string | null {\n const normalized = path.resolve(cliPath);\n const binDir = path.dirname(normalized);\n const packageDir = path.basename(binDir) === \"bin\" ? path.dirname(binDir) : path.dirname(normalized);\n const pkgPath = path.join(packageDir, \"package.json\");\n return fileExists(pkgPath);\n}\n\nfunction readCodexCliVersion(cliPath: string): string | null {\n const packageJsonPath = resolvePackageJsonPath(cliPath);\n if (!packageJsonPath) {\n return null;\n }\n try {\n const raw = readFileSync(packageJsonPath, \"utf8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n if (typeof parsed?.version !== \"string\") {\n return null;\n }\n const normalized = parsed.version.trim();\n return normalized.length > 0 ? normalized : null;\n } catch {\n return null;\n }\n}\n\nfunction resolveBundledCodexBinaryWithFallback(requestedChannel: CodexCliChannel): {\n path: string | null;\n resolvedChannel: CodexCliChannel | null;\n fallbackUsed: boolean;\n} {\n const direct = resolveBundledCodexBinary(requestedChannel);\n if (direct) {\n return { path: direct, resolvedChannel: requestedChannel, fallbackUsed: false };\n }\n\n if (requestedChannel === \"alpha\") {\n const stable = resolveBundledCodexBinary(\"stable\");\n if (stable) {\n return { path: stable, resolvedChannel: \"stable\", fallbackUsed: true };\n }\n }\n\n return { path: null, resolvedChannel: null, fallbackUsed: false };\n}\n\nfunction buildUnavailableStatus(channel: CodexCliChannel): MutableStatus {\n const channelLabel = channel === \"alpha\" ? \"alpha \" : \"\";\n const channelSuffix =\n channel === \"alpha\"\n ? \" Switch to Stable in Settings or reinstall CodexUse to restore the CLI.\"\n : \" Reinstall CodexUse to restore the CLI.\";\n return {\n available: false,\n path: null,\n reason: `Bundled ${channelLabel}Codex CLI is missing.${channelSuffix}`,\n source: null,\n channel,\n requestedChannel: channel,\n fallbackUsed: false,\n };\n}\n\nfunction evaluateCodexCliStatus(requestedChannel: CodexCliChannel): MutableStatus {\n const resolved = resolveBundledCodexBinaryWithFallback(requestedChannel);\n if (resolved.path && resolved.resolvedChannel) {\n return {\n available: true,\n path: resolved.path,\n reason: null,\n source: \"bundled\",\n channel: resolved.resolvedChannel,\n requestedChannel,\n fallbackUsed: resolved.fallbackUsed,\n };\n }\n\n return buildUnavailableStatus(requestedChannel);\n}\n\nexport async function refreshCodexStatus(): Promise<CodexCliStatusPayload> {\n const channel = await getCodexCliChannel();\n cachedChannel = channel;\n cachedStatus = evaluateCodexCliStatus(channel);\n return { ...cachedStatus };\n}\n\nexport async function getCodexCliStatus(): Promise<CodexCliStatusPayload> {\n const channel = await getCodexCliChannel();\n if (!cachedStatus || cachedChannel !== channel) {\n return refreshCodexStatus();\n }\n return { ...cachedStatus };\n}\n\nexport async function getCodexCliInfo(): Promise<CodexCliInfoPayload> {\n const status = await getCodexCliStatus();\n const version =\n status.available && status.path\n ? readCodexCliVersion(status.path)\n : null;\n return { ...status, version };\n}\n\nexport class CodexCliMissingError extends Error {\n readonly status: CodexCliStatusPayload;\n\n constructor(status: CodexCliStatusPayload, message?: string) {\n super(message ?? status.reason ?? \"Codex CLI is not available\");\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"CodexCliMissingError\";\n this.status = { ...status };\n }\n}\n\nexport async function requireCodexCli(): Promise<string> {\n const status = await refreshCodexStatus();\n if (!status.available || !status.path) {\n throw new CodexCliMissingError(status);\n }\n return status.path;\n}\n","import type { RateLimitSnapshot } from \"@/lib/types\";\n\ntype Notify = (payload: { title: string; body: string }) => void;\n\ninterface RateLimitNotifierOptions {\n notify: Notify;\n now?: () => number;\n approachThresholdPercent?: number;\n approachCooldownMs?: number;\n resetCooldownMs?: number;\n exhaustedThresholdPercent?: number;\n recoveryThresholdPercent?: number;\n}\n\nconst DEFAULT_APPROACH_THRESHOLD = 95;\nconst DEFAULT_APPROACH_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes\nconst DEFAULT_RESET_COOLDOWN_MS = 5 * 60 * 1000; // 5 minutes\nconst DEFAULT_EXHAUSTED_THRESHOLD = 98;\nconst DEFAULT_RECOVERY_THRESHOLD = 50;\nconst APPROACH_RENOTIFY_FLOOR_MS = 2 * 60 * 1000; // Prevents back-to-back alerts when windows jitter\nconst RESET_WINDOW_BUCKET_MS = 5 * 60 * 1000;\n\ninterface RateLimitState {\n lastSnapshot: RateLimitSnapshot | null;\n lastApproachWindow: string | null;\n lastApproachAt: number | null;\n lastResetAt: number | null;\n exhaustedWindow: string | null;\n}\n\nfunction pickResetsAt(snapshot: RateLimitSnapshot | null | undefined): string | null {\n if (!snapshot) {\n return null;\n }\n\n return snapshot.primary?.resetsAt ?? snapshot.secondary?.resetsAt ?? null;\n}\n\nexport function maxUsedPercent(snapshot: RateLimitSnapshot | null | undefined): number | null {\n if (!snapshot) {\n return null;\n }\n\n const candidates = [\n snapshot.primary?.usedPercent,\n snapshot.secondary?.usedPercent,\n ].filter((value): value is number => typeof value === \"number\" && Number.isFinite(value));\n\n if (candidates.length === 0) {\n return null;\n }\n\n return Math.max(...candidates);\n}\n\nfunction normalizeResetWindowKey(resetsAt: string | null | undefined): string | null {\n if (!resetsAt) {\n return null;\n }\n\n const parsed = Date.parse(resetsAt);\n if (Number.isNaN(parsed)) {\n return resetsAt;\n }\n\n const bucket = Math.floor(parsed / RESET_WINDOW_BUCKET_MS);\n return `reset-${bucket}`;\n}\n\nfunction formatResetWindow(snapshot: RateLimitSnapshot | null | undefined): string | null {\n const resetsInSeconds = snapshot?.primary?.resetsInSeconds ?? snapshot?.secondary?.resetsInSeconds ?? null;\n if (typeof resetsInSeconds !== \"number\" || Number.isNaN(resetsInSeconds)) {\n return null;\n }\n\n const minutes = Math.max(0, Math.round(resetsInSeconds / 60));\n if (minutes >= 120) {\n const hours = Math.round(minutes / 60);\n return `${hours}h`;\n }\n\n return `${minutes}m`;\n}\n\nexport class RateLimitNotifier {\n private readonly notify: Notify;\n private readonly now: () => number;\n private readonly approachThreshold: number;\n private readonly approachCooldownMs: number;\n private readonly resetCooldownMs: number;\n private readonly exhaustedThreshold: number;\n private readonly recoveryThreshold: number;\n\n private readonly states = new Map<string, RateLimitState>();\n\n constructor(options: RateLimitNotifierOptions) {\n this.notify = options.notify;\n this.now = options.now ?? (() => Date.now());\n this.approachThreshold = options.approachThresholdPercent ?? DEFAULT_APPROACH_THRESHOLD;\n this.approachCooldownMs = options.approachCooldownMs ?? DEFAULT_APPROACH_COOLDOWN_MS;\n this.resetCooldownMs = options.resetCooldownMs ?? DEFAULT_RESET_COOLDOWN_MS;\n this.exhaustedThreshold = options.exhaustedThresholdPercent ?? DEFAULT_EXHAUSTED_THRESHOLD;\n this.recoveryThreshold = options.recoveryThresholdPercent ?? DEFAULT_RECOVERY_THRESHOLD;\n }\n\n handleSnapshot(accountId: string, profileName: string, snapshot: RateLimitSnapshot | null | undefined): void {\n if (!accountId || !profileName) {\n return;\n }\n\n const state = this.states.get(accountId) ?? {\n lastSnapshot: null,\n lastApproachAt: null,\n lastApproachWindow: null,\n lastResetAt: null,\n exhaustedWindow: null,\n };\n\n const previousUsage = maxUsedPercent(state.lastSnapshot);\n const currentUsage = maxUsedPercent(snapshot);\n const previousWindow = pickResetsAt(state.lastSnapshot);\n const currentWindow = pickResetsAt(snapshot);\n const normalizedPreviousWindow = normalizeResetWindowKey(previousWindow);\n const normalizedCurrentWindow = normalizeResetWindowKey(currentWindow);\n const now = this.now();\n\n const wasExhausted =\n typeof previousUsage === \"number\" && previousUsage >= this.exhaustedThreshold;\n const currentWindowKey =\n normalizedCurrentWindow ??\n normalizedPreviousWindow ??\n currentWindow ??\n previousWindow ??\n \"unknown\";\n\n if (wasExhausted) {\n state.exhaustedWindow = normalizedPreviousWindow ?? state.exhaustedWindow ?? currentWindowKey;\n }\n\n // Reset notifications disabled - they're just noise. Nobody waits around for limits to reset.\n // Clear exhausted state silently so we can re-notify on next approach.\n if (this.shouldNotifyReset(state, currentUsage, currentWindowKey, previousWindow, now)) {\n state.lastResetAt = now;\n state.exhaustedWindow = null;\n state.lastApproachWindow = null;\n state.lastApproachAt = null;\n }\n\n if (\n typeof currentUsage === \"number\" &&\n currentUsage >= this.approachThreshold &&\n this.canNotifyApproach(state, currentWindowKey, now)\n ) {\n const windowText = formatResetWindow(snapshot);\n const body = windowText\n ? `${currentUsage}% used. Resets in ${windowText}.`\n : `${currentUsage}% used.`;\n this.notify({\n title: `${profileName} is nearing its limit`,\n body,\n });\n state.lastApproachWindow = currentWindowKey;\n state.lastApproachAt = now;\n }\n\n if (typeof currentUsage === \"number\" && currentUsage >= this.exhaustedThreshold) {\n state.exhaustedWindow = currentWindowKey;\n }\n\n state.lastSnapshot = snapshot ?? null;\n this.states.set(accountId, state);\n }\n\n private canNotifyApproach(state: RateLimitState, windowKey: string, now: number): boolean {\n if (!windowKey) {\n return false;\n }\n\n if (typeof state.lastApproachAt === \"number\" && now - state.lastApproachAt < APPROACH_RENOTIFY_FLOOR_MS) {\n return false;\n }\n\n if (state.lastApproachWindow !== windowKey) {\n return true;\n }\n\n if (typeof state.lastApproachAt !== \"number\") {\n return true;\n }\n\n return now - state.lastApproachAt >= this.approachCooldownMs;\n }\n\n private shouldNotifyReset(\n state: RateLimitState,\n currentUsage: number | null,\n currentWindowKey: string,\n previousWindow: string | null,\n now: number,\n ): boolean {\n if (!state.exhaustedWindow) {\n return false;\n }\n\n const windowChanged =\n Boolean(currentWindowKey) && currentWindowKey !== state.exhaustedWindow;\n const usageRecovered =\n typeof currentUsage === \"number\" && currentUsage <= this.recoveryThreshold && Boolean(previousWindow);\n\n if (!windowChanged && !usageRecovered) {\n return false;\n }\n\n if (typeof state.lastResetAt === \"number\" && now - state.lastResetAt < this.resetCooldownMs) {\n return false;\n }\n\n return true;\n }\n}\n","import { ProfileManager } from \"../../../lib/profile-manager\";\nimport { licenseService } from \"../../../lib/license-service\";\nimport { assertProfileCreationAllowed } from \"../../../lib/license-guard\";\nimport { runCodexLogin, resolveCodexBinary, resolveLoginMode, type CodexLoginMode } from \"./codex-cli\";\nimport { fetchRateLimitsViaRpc } from \"../../../lib/codex-rpc\";\nimport { maxUsedPercent } from \"../../../lib/rate-limit-notifier\";\nimport type { OrganizationInfo, Profile, RateLimitSnapshot, RateLimitWindow } from \"../../../lib/types\";\n\ndeclare const __CODEXUSE_CLI_VERSION__: string;\n\nconst VERSION = typeof __CODEXUSE_CLI_VERSION__ === \"string\"\n ? __CODEXUSE_CLI_VERSION__\n : \"0.0.0\";\n\nfunction printHelp(): void {\n console.log(`CodexUse CLI v${VERSION}\n\nUsage:\n codexuse profile list [--no-usage] [--compact]\n codexuse profile current\n codexuse profile add <name> [--skip-login] [--device-auth] [--login=browser|device]\n codexuse profile refresh <name> [--skip-login] [--device-auth] [--login=browser|device]\n codexuse profile switch <name>\n codexuse profile delete <name>\n codexuse profile rename <old> <new>\n\n codexuse license status [--refresh]\n codexuse license activate <license-key>\n\nFlags:\n -h, --help Show help\n -v, --version Show version\n --no-usage Skip rate-limit usage fetch\n --compact Names only\n --device-auth Use device auth for Codex login\n --login=MODE Login mode: browser | device\n`);\n}\n\nfunction hasFlag(args: string[], flag: string): boolean {\n return args.includes(flag);\n}\n\nfunction stripFlags(args: string[]): string[] {\n return args.filter(arg => !arg.startsWith(\"-\"));\n}\n\nfunction parseLoginMode(flags: string[]): CodexLoginMode | null {\n if (flags.includes(\"--device-auth\")) return \"device\";\n const explicit = flags.find(flag => flag.startsWith(\"--login=\"));\n if (!explicit) return null;\n const value = explicit.split(\"=\")[1];\n if (value === \"browser\" || value === \"device\") {\n return value;\n }\n return null;\n}\n\nfunction formatProfileLabel(name: string, displayName?: string | null): string {\n if (displayName && displayName.trim() && displayName !== name) {\n return `${displayName} (${name})`;\n }\n return name;\n}\n\nfunction toTitleCase(value: string): string {\n return value.replace(/\\w\\S*/g, word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());\n}\n\nfunction formatShortDate(value?: string | null): string | null {\n if (!value) return null;\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return null;\n if (typeof Intl !== \"undefined\" && Intl.DateTimeFormat) {\n return new Intl.DateTimeFormat(undefined, { month: \"short\", day: \"numeric\" }).format(date);\n }\n return date.toLocaleDateString();\n}\n\nfunction formatRelativeTime(value?: string | null): string | null {\n if (!value) return null;\n const parsed = Date.parse(value);\n if (Number.isNaN(parsed)) return null;\n const diffMs = parsed - Date.now();\n const absMs = Math.abs(diffMs);\n if (absMs < 60_000) {\n return null;\n }\n const minutes = Math.round(absMs / 60_000);\n if (minutes < 60) {\n return diffMs >= 0 ? `in ${minutes}m` : `${minutes}m ago`;\n }\n const hours = Math.round(minutes / 60);\n if (hours < 24) {\n return diffMs >= 0 ? `in ${hours}h` : `${hours}h ago`;\n }\n const days = Math.round(hours / 24);\n return diffMs >= 0 ? `in ${days}d` : `${days}d ago`;\n}\n\nfunction formatOrganizations(organizations?: OrganizationInfo[]): string | null {\n if (!organizations || !Array.isArray(organizations) || organizations.length === 0) {\n return null;\n }\n const parts = organizations\n .map(org => {\n if (!org) return null;\n const name = org.title || org.id;\n if (!name) return null;\n return org.role ? `${name} (${org.role})` : name;\n })\n .filter((value): value is string => Boolean(value));\n return parts.length > 0 ? parts.join(\", \") : null;\n}\n\nfunction formatWindowLabel(windowMinutes?: number): string | null {\n if (typeof windowMinutes !== \"number\" || Number.isNaN(windowMinutes)) {\n return null;\n }\n if (windowMinutes >= 2880) {\n const days = windowMinutes / 1440;\n const rounded = Math.round(days * 10) / 10;\n const display = Number.isInteger(rounded) ? rounded.toFixed(0) : rounded.toFixed(1);\n return `${display.replace(/\\.0$/, \"\")}d window`;\n }\n if (windowMinutes >= 60) {\n const hours = windowMinutes / 60;\n const rounded = Math.round(hours * 10) / 10;\n const display = Number.isInteger(rounded) ? rounded.toFixed(0) : rounded.toFixed(1);\n return `${display.replace(/\\.0$/, \"\")}h window`;\n }\n const minutes = Math.round(windowMinutes);\n return `${minutes}m window`;\n}\n\nfunction formatDurationFromSeconds(seconds?: number | null): string | null {\n if (typeof seconds !== \"number\" || Number.isNaN(seconds)) {\n return null;\n }\n if (seconds <= 0) {\n return \"now\";\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes === 0) {\n return `${Math.max(1, Math.round(seconds))}s`;\n }\n if (minutes < 60) {\n return `${minutes}m`;\n }\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n if (hours < 24) {\n return remainingMinutes ? `${hours}h ${remainingMinutes}m` : `${hours}h`;\n }\n const days = Math.floor(hours / 24);\n const remainingHours = hours % 24;\n return remainingHours ? `${days}d ${remainingHours}h` : `${days}d`;\n}\n\nfunction formatResetText(window: RateLimitWindow): string | null {\n if (window.resetsAt) {\n return formatRelativeTime(window.resetsAt) ?? window.resetsAt;\n }\n const durationText = formatDurationFromSeconds(window.resetsInSeconds);\n if (!durationText) return null;\n if (durationText === \"now\") return \"now\";\n return `in ${durationText}`;\n}\n\ntype RateLimitRow = {\n label: string;\n used: string;\n reset: string | null;\n};\n\nfunction formatWindowUsage(window: RateLimitWindow): RateLimitRow | null {\n const label = formatWindowLabel(window.windowMinutes) ?? \"window\";\n const usedPercent =\n typeof window.usedPercent === \"number\" && Number.isFinite(window.usedPercent)\n ? `${Math.round(Math.max(0, Math.min(100, window.usedPercent)))}%`\n : \"n/a\";\n const resetText = formatResetText(window);\n return {\n label,\n used: usedPercent,\n reset: resetText ? `reset ${resetText}` : null,\n };\n}\n\ntype UsageInfo = {\n summary: string;\n rows: RateLimitRow[] | null;\n};\n\nfunction fallbackUsage(profile: Profile): UsageInfo {\n if (!profile.isValid) {\n return { summary: \"invalid\", rows: null };\n }\n if (profile.tokenStatus?.requiresUserAction) {\n return { summary: \"auth required\", rows: null };\n }\n return { summary: \"n/a\", rows: null };\n}\n\nasync function resolveProfileUsage(\n manager: ProfileManager,\n profile: Profile,\n codexPath: string,\n): Promise<UsageInfo> {\n if (!profile.isValid || profile.tokenStatus?.requiresUserAction) {\n return fallbackUsage(profile);\n }\n\n try {\n const snapshot = await manager.runWithProfileAuth(profile.name, (env) =>\n fetchRateLimitsViaRpc(env, { codexPath }),\n );\n if (!snapshot) {\n return { summary: \"n/a\", rows: null };\n }\n const rows: RateLimitRow[] = [];\n if (snapshot.primary) {\n const row = formatWindowUsage(snapshot.primary);\n if (row) rows.push(row);\n }\n if (snapshot.secondary) {\n const row = formatWindowUsage(snapshot.secondary);\n if (row) rows.push(row);\n }\n const maxPercent = maxUsedPercent(snapshot);\n const summary = typeof maxPercent === \"number\"\n ? `${Math.round(maxPercent)}%`\n : \"n/a\";\n return { summary, rows: rows.length > 0 ? rows : null };\n } catch {\n return { summary: \"n/a\", rows: null };\n }\n}\n\nfunction formatPlan(profile: Profile): string {\n const metadata = profile.metadata;\n if (!metadata) {\n return \"No plan details\";\n }\n const parts: string[] = [];\n if (metadata.planType) {\n parts.push(toTitleCase(metadata.planType));\n }\n const until = metadata.subscription?.activeUntil;\n if (until) {\n const formatted = formatShortDate(until);\n if (formatted) {\n parts.push(`Until ${formatted}`);\n }\n }\n return parts.join(\" · \") || \"No plan details\";\n}\n\nfunction formatAuth(profile: Profile): string {\n const metadata = profile.metadata;\n const relative = formatRelativeTime(metadata?.tokenAuthTime);\n if (relative) return relative;\n if (metadata?.tokenAuthTime) return metadata.tokenAuthTime;\n return \"Not authenticated yet\";\n}\n\nfunction printProfileDetails(profile: Profile, usage?: UsageInfo | null): void {\n const email = profile.email ?? \"Unknown\";\n const plan = formatPlan(profile);\n const orgs = formatOrganizations(profile.metadata?.organizations) ?? \"No organizations\";\n const auth = formatAuth(profile);\n const workspace = profile.workspaceName ?? profile.workspaceId ?? null;\n\n const entries: Array<{ label: string; value: string }> = [\n { label: \"email\", value: email },\n { label: \"plan\", value: plan },\n { label: \"orgs\", value: orgs },\n { label: \"auth\", value: auth },\n ];\n if (workspace) {\n entries.push({ label: \"workspace\", value: workspace });\n }\n const pad = Math.max(...entries.map(entry => entry.label.length));\n for (const entry of entries) {\n console.log(` ${entry.label.padEnd(pad)} : ${entry.value}`);\n }\n\n if (usage) {\n if (usage.rows && usage.rows.length > 0) {\n const labelPad = Math.max(...usage.rows.map(row => row.label.length));\n const usedPad = Math.max(...usage.rows.map(row => row.used.length));\n console.log(` rate limits:`);\n for (const row of usage.rows) {\n const resetText = row.reset ? ` ${row.reset}` : \"\";\n console.log(` ${row.label.padEnd(labelPad)} ${row.used.padStart(usedPad)}${resetText}`);\n }\n return;\n }\n console.log(` rate limits: ${usage.summary}`);\n }\n}\n\nasync function mapWithConcurrency<T, R>(\n items: T[],\n limit: number,\n fn: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = new Array(items.length);\n const workerCount = Math.max(1, Math.min(limit, items.length));\n let nextIndex = 0;\n\n const workers = Array.from({ length: workerCount }, async () => {\n while (true) {\n const current = nextIndex++;\n if (current >= items.length) {\n return;\n }\n results[current] = await fn(items[current], current);\n }\n });\n\n await Promise.all(workers);\n return results;\n}\n\nasync function handleProfile(args: string[]): Promise<void> {\n const flags = args.filter(arg => arg.startsWith(\"-\"));\n const params = stripFlags(args);\n const sub = params[0];\n\n if (!sub || hasFlag(flags, \"--help\") || hasFlag(flags, \"-h\")) {\n printHelp();\n return;\n }\n\n const manager = new ProfileManager();\n\n switch (sub) {\n case \"list\": {\n const profiles = await manager.listProfiles();\n const current = await manager.getCurrentProfile();\n if (!profiles.length) {\n console.log(\"No profiles found.\");\n return;\n }\n const compact = hasFlag(flags, \"--compact\");\n const withUsage = !hasFlag(flags, \"--no-usage\");\n let usageMap: Map<string, UsageInfo> | null = null;\n if (withUsage) {\n usageMap = new Map();\n const codexPath = resolveCodexBinary();\n const codexAvailable = Boolean(codexPath);\n if (!codexAvailable || !codexPath) {\n for (const profile of profiles) {\n usageMap.set(profile.name, { summary: \"codex cli missing\", rows: null });\n }\n } else {\n const limitEnv = Number.parseInt(process.env.CODEXUSE_CLI_USAGE_CONCURRENCY ?? \"3\", 10);\n const limit = Number.isFinite(limitEnv) && limitEnv > 0 ? limitEnv : 3;\n const results = await mapWithConcurrency(profiles, limit, (profile) =>\n resolveProfileUsage(manager, profile, codexPath),\n );\n for (const [index, profile] of profiles.entries()) {\n usageMap.set(profile.name, results[index]);\n }\n }\n }\n for (const [index, profile] of profiles.entries()) {\n const marker = current.name === profile.name ? \"*\" : \" \";\n const label = formatProfileLabel(profile.name, profile.displayName);\n if (index > 0) {\n console.log(\"\");\n }\n const activeLabel = current.name === profile.name ? \" (active)\" : \"\";\n console.log(`${marker} ${label}${activeLabel}`);\n if (compact) continue;\n const usage = usageMap?.get(profile.name) ?? null;\n printProfileDetails(profile, usage);\n }\n return;\n }\n case \"current\": {\n const current = await manager.getCurrentProfile();\n if (!current.name) {\n console.log(\"No active profile.\");\n return;\n }\n console.log(current.name);\n return;\n }\n case \"add\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n await assertProfileCreationAllowed(manager);\n if (!hasFlag(flags, \"--skip-login\")) {\n const loginMode = resolveLoginMode(parseLoginMode(flags));\n await runCodexLogin(loginMode);\n }\n const profile = await manager.createProfile(name);\n const label = profile ? formatProfileLabel(profile.name, profile.displayName) : name;\n console.log(`Profile created: ${label}`);\n return;\n }\n case \"refresh\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n if (!hasFlag(flags, \"--skip-login\")) {\n const loginMode = resolveLoginMode(parseLoginMode(flags));\n await runCodexLogin(loginMode);\n }\n const profile = await manager.refreshProfileAuth(name);\n const label = formatProfileLabel(profile.name, profile.displayName);\n console.log(`Profile refreshed: ${label}`);\n return;\n }\n case \"switch\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n await manager.switchToProfile(name);\n console.log(`Switched to profile: ${name}`);\n return;\n }\n case \"delete\": {\n const name = params[1];\n if (!name) {\n throw new Error(\"Profile name is required.\");\n }\n await manager.deleteProfile(name);\n console.log(`Profile deleted: ${name}`);\n return;\n }\n case \"rename\": {\n const from = params[1];\n const to = params[2];\n if (!from || !to) {\n throw new Error(\"Old and new profile names are required.\");\n }\n await manager.renameProfile(from, to);\n console.log(`Profile renamed: ${from} -> ${to}`);\n return;\n }\n default:\n printHelp();\n return;\n }\n}\n\nasync function handleLicense(args: string[]): Promise<void> {\n const flags = args.filter(arg => arg.startsWith(\"-\"));\n const params = stripFlags(args);\n const sub = params[0];\n\n if (!sub || hasFlag(flags, \"--help\") || hasFlag(flags, \"-h\")) {\n printHelp();\n return;\n }\n\n switch (sub) {\n case \"status\": {\n const forceRefresh = hasFlag(flags, \"--refresh\");\n const status = await licenseService.getStatus({ forceRefresh });\n console.log(`Tier: ${status.tier}`);\n console.log(`State: ${status.state}`);\n if (status.profileLimit !== null) {\n console.log(`Profile limit: ${status.profileLimit}`);\n }\n if (status.profilesRemaining !== null) {\n console.log(`Profiles remaining: ${status.profilesRemaining}`);\n }\n if (status.purchaseEmail) {\n console.log(`Email: ${status.purchaseEmail}`);\n }\n if (status.maskedLicenseKey) {\n console.log(`License: ${status.maskedLicenseKey}`);\n }\n if (status.message) {\n console.log(`Message: ${status.message}`);\n }\n if (status.error) {\n console.log(`Error: ${status.error}`);\n }\n return;\n }\n case \"activate\": {\n const key = params[1];\n if (!key) {\n throw new Error(\"License key is required.\");\n }\n const status = await licenseService.activate(key);\n console.log(status.message ?? \"License activated.\");\n return;\n }\n default:\n printHelp();\n return;\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || hasFlag(args, \"--help\") || hasFlag(args, \"-h\")) {\n printHelp();\n return;\n }\n\n if (hasFlag(args, \"--version\") || hasFlag(args, \"-v\")) {\n console.log(VERSION);\n return;\n }\n\n const command = args[0];\n const rest = args.slice(1);\n\n switch (command) {\n case \"profile\":\n await handleProfile(rest);\n return;\n case \"license\":\n await handleLicense(rest);\n return;\n default:\n printHelp();\n return;\n }\n}\n\nmain().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["path","require","initSqlJs","fsPromises","import_path","import_node_fs","import_node_path","path","fs","__debugResolveDbPath","getDatabase","fs","getDatabase","path","import_node_crypto","import_node_fs","import_node_path","resolveCodexDir","path","crypto","fs","crypto","fallbackStored","fallback","import_node_fs","import_node_path","path","import_node_child_process","import_node_fs","import_node_path","import_node_fs","import_node_path","fileExists","path","fs","path","os","readline"]}