From d6c5df9a0a8228b2b9a94cdae5e5747e8d98108a Mon Sep 17 00:00:00 2001 From: Jeremy Rose <172423086+nornagon-openai@users.noreply.github.com> Date: Tue, 14 Oct 2025 10:49:44 -0700 Subject: [PATCH] detect Bun installs in CLI update banner (#5074) ## Summary - detect Bun-managed installs in the JavaScript launcher and set a dedicated environment flag - show a Bun-specific upgrade command in the update banner when that flag is present Fixes #5012 ------ https://chatgpt.com/codex/tasks/task_i_68e95c439494832c835bdf34b3b1774e --------- Co-authored-by: Michael Bolin --- codex-cli/bin/codex.js | 35 ++++++++++++++++++++++++++++++++++- codex-rs/tui/src/lib.rs | 10 +++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) mode change 100755 => 100644 codex-cli/bin/codex.js diff --git a/codex-cli/bin/codex.js b/codex-cli/bin/codex.js old mode 100755 new mode 100644 index 17dd98a8..805be85a --- a/codex-cli/bin/codex.js +++ b/codex-cli/bin/codex.js @@ -80,6 +80,32 @@ function getUpdatedPath(newDirs) { return updatedPath; } +/** + * Use heuristics to detect the package manager that was used to install Codex + * in order to give the user a hint about how to update it. + */ +function detectPackageManager() { + const userAgent = process.env.npm_config_user_agent || ""; + if (/\bbun\//.test(userAgent)) { + return "bun"; + } + + const execPath = process.env.npm_execpath || ""; + if (execPath.includes("bun")) { + return "bun"; + } + + if ( + process.env.BUN_INSTALL || + process.env.BUN_INSTALL_GLOBAL_DIR || + process.env.BUN_INSTALL_BIN_DIR + ) { + return "bun"; + } + + return userAgent ? "npm" : null; +} + const additionalDirs = []; const pathDir = path.join(archRoot, "path"); if (existsSync(pathDir)) { @@ -87,9 +113,16 @@ if (existsSync(pathDir)) { } const updatedPath = getUpdatedPath(additionalDirs); +const env = { ...process.env, PATH: updatedPath }; +const packageManagerEnvVar = + detectPackageManager() === "bun" + ? "CODEX_MANAGED_BY_BUN" + : "CODEX_MANAGED_BY_NPM"; +env[packageManagerEnvVar] = "1"; + const child = spawn(binaryPath, process.argv.slice(2), { stdio: "inherit", - env: { ...process.env, PATH: updatedPath, CODEX_MANAGED_BY_NPM: "1" }, + env, }); child.on("error", (err) => { diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index 5d7188c0..7d7412e0 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -310,6 +310,7 @@ async fn run_ratatui_app( let current_version = env!("CARGO_PKG_VERSION"); let exe = std::env::current_exe()?; + let managed_by_bun = std::env::var_os("CODEX_MANAGED_BY_BUN").is_some(); let managed_by_npm = std::env::var_os("CODEX_MANAGED_BY_NPM").is_some(); let mut content_lines: Vec> = vec![ @@ -330,7 +331,14 @@ async fn run_ratatui_app( Line::from(""), ]; - if managed_by_npm { + if managed_by_bun { + let bun_cmd = "bun install -g @openai/codex@latest"; + content_lines.push(Line::from(vec![ + "Run ".into(), + bun_cmd.cyan(), + " to update.".into(), + ])); + } else if managed_by_npm { let npm_cmd = "npm install -g @openai/codex@latest"; content_lines.push(Line::from(vec![ "Run ".into(),