diff --git a/plugins/codex/scripts/lib/codex.mjs b/plugins/codex/scripts/lib/codex.mjs index bf7e8c8..9c925f5 100644 --- a/plugins/codex/scripts/lib/codex.mjs +++ b/plugins/codex/scripts/lib/codex.mjs @@ -34,10 +34,11 @@ * onProgress: ProgressReporter | null * }} TurnCaptureState */ -import { readJsonFile } from "./fs.mjs"; +import { readJsonFile, safeReadFile } from "./fs.mjs"; import { BROKER_BUSY_RPC_CODE, BROKER_ENDPOINT_ENV, CodexAppServerClient } from "./app-server.mjs"; import { loadBrokerSession } from "./broker-lifecycle.mjs"; import { binaryAvailable, runCommand } from "./process.mjs"; +import { resolveWorkspaceRoot } from "./workspace.mjs"; const SERVICE_NAME = "claude_code_codex_plugin"; const TASK_THREAD_PREFIX = "Codex Companion Task"; @@ -691,6 +692,12 @@ export function getSessionRuntimeStatus(env = process.env, cwd = process.cwd()) }; } +function isProjectTrusted(globalConfig, workspaceRoot) { + const escaped = workspaceRoot.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + const re = new RegExp(`\\[projects\\."${escaped}"\\][\\s\\S]*?trust_level\\s*=\\s*["']?trusted`); + return re.test(globalConfig); +} + export function getCodexLoginStatus(cwd) { const availability = getCodexAvailability(cwd); if (!availability.available) { @@ -701,6 +708,30 @@ export function getCodexLoginStatus(cwd) { }; } + if (process.env.OPENAI_API_KEY) { + return { + available: true, + loggedIn: true, + detail: "authenticated via OPENAI_API_KEY" + }; + } + + const providerRe = /^\s*model_provider\s*=\s*["']?([^"'\s\r\n]+)["']?/m; + const globalConfigPath = `${process.env.HOME || process.env.USERPROFILE}/.codex/config.toml`; + const globalConfig = safeReadFile(globalConfigPath); + const workspaceRoot = resolveWorkspaceRoot(cwd); + const projectConfig = isProjectTrusted(globalConfig, workspaceRoot) + ? safeReadFile(`${workspaceRoot}/.codex/config.toml`) + : ""; + const providerMatch = projectConfig.match(providerRe) || globalConfig.match(providerRe); + if (providerMatch && providerMatch[1] !== "openai") { + return { + available: true, + loggedIn: true, + detail: "authenticated via custom model provider" + }; + } + const result = runCommand("codex", ["login", "status"], { cwd }); if (result.error) { return {