From a70842d9ef1fd3f3f4b4275832695d959d7a51eb Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sat, 20 Dec 2025 13:30:49 +0700 Subject: [PATCH] feat: auto-detect and use system-installed codex binary from PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements automatic detection and usage of system-installed Codex binary with transparent fallback to embedded binary. Changes: - Add detectSystemCodexPath() to check for codex in PATH using `which` - Update CodexAgentClient constructor to auto-detect system binary - Log which binary is being used (system vs embedded) for debugging - Preserve ability to explicitly override via codexPathOverride option Benefits: - No manual configuration required - Uses latest system codex when available - Seamless fallback to embedded binary - Transparent to rest of codebase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../src/server/agent/providers/codex-agent.ts | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/server/src/server/agent/providers/codex-agent.ts b/packages/server/src/server/agent/providers/codex-agent.ts index f82de1dae..a06aeb198 100644 --- a/packages/server/src/server/agent/providers/codex-agent.ts +++ b/packages/server/src/server/agent/providers/codex-agent.ts @@ -3,6 +3,7 @@ import { promises as fs, constants as fsConstants } from "node:fs"; import type { Dirent } from "node:fs"; import os from "node:os"; import path from "node:path"; +import { execSync } from "node:child_process"; import { Codex, @@ -208,13 +209,38 @@ function normalizeExtraOptions(extra?: Record): CodexOptionsOve return normalized; } +function detectSystemCodexPath(): string | undefined { + try { + const codexPath = execSync("which codex", { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim(); + if (codexPath && codexPath.length > 0) { + return codexPath; + } + } catch { + // which command failed - codex not in PATH + } + return undefined; +} + export class CodexAgentClient implements AgentClient { readonly provider = "codex" as const; readonly capabilities = CODEX_CAPABILITIES; private readonly codex: Codex; constructor(options?: CodexOptions) { - this.codex = new Codex(options); + const codexOptions = { ...options }; + + // If no explicit codexPathOverride, try to use system-installed codex from PATH + if (!codexOptions.codexPathOverride) { + const systemCodexPath = detectSystemCodexPath(); + if (systemCodexPath) { + codexOptions.codexPathOverride = systemCodexPath; + console.log(`[Codex] Using system binary: ${systemCodexPath}`); + } else { + console.log("[Codex] Using embedded binary (no system codex found in PATH)"); + } + } + + this.codex = new Codex(codexOptions); } async createSession(config: AgentSessionConfig): Promise {