{ lib , stdenv , fetchurl , nodejs_22 , cacert , makeWrapper , patchelf , gnutar , gzip , openssl , libcap , libz , bubblewrap , runtime ? "native" , nativeBinName ? "codex" , nodeBinName ? "codex-node" }: let version = "0.124.0"; platformMap = { "aarch64-darwin" = "aarch64-apple-darwin"; "x86_64-darwin" = "x86_64-apple-darwin"; "x86_64-linux" = "x86_64-unknown-linux-gnu"; "aarch64-linux" = "aarch64-unknown-linux-gnu"; }; nodePlatformMap = { "aarch64-darwin" = "darwin-arm64"; "x86_64-darwin" = "darwin-x64"; "x86_64-linux" = "linux-x64"; "aarch64-linux" = "linux-arm64"; }; platform = platformMap.${stdenv.hostPlatform.system} or null; nodePlatform = nodePlatformMap.${stdenv.hostPlatform.system} or null; nativeHashes = { "aarch64-apple-darwin" = "1ki9wpmn2f9zwlb9klnwsq2rpbql24gip9dr4azah73r8i4p9s3i"; "x86_64-apple-darwin" = "061ww08dd5vmq5hamwr395fv96lpdrzs86wd98f475rdj7dh08xg"; "x86_64-unknown-linux-gnu" = "02bbzh4mjyix0ifh8xg3pjg9sw56v0hxj8wk2pnwadjfs999sq8d"; "aarch64-unknown-linux-gnu" = "0ydmdjj6q2qnsqmipy7rnl367aij3m8d7db4d2r9gby5m9nlhrcp"; }; nodeOptionalDepHashes = { "darwin-arm64" = "0nivpc52sdx27hm42i79nc2l1amg03ynqxcsy5zh14hmbwxna8c2"; "darwin-x64" = "1nikj6gv8qmfk45rsdmkgq46fmjkr75z00yi5icmian9dzs0r77b"; "linux-x64" = "1p2g4imkpk6abz0lphal2xrlzha54ais2vbx54vpfq0fv5x67qmf"; "linux-arm64" = "1gk5bnx2ypqvrz0mq9linbs2y718zn1g30lrsf2x1vsdnnlf8my0"; }; nativeBinaryUrl = "https://github.com/openai/codex/releases/download/rust-v${version}/codex-${platform}.tar.gz"; nativeBinary = if runtime == "native" && platform != null then fetchurl { url = nativeBinaryUrl; sha256 = nativeHashes.${platform}; } else null; npmTarball = if runtime == "node" then fetchurl { url = "https://registry.npmjs.org/@openai/codex/-/codex-${version}.tgz"; sha256 = "1wj8b1sprq6cx4l2z2plnp5xji7bmmmwi1rmhd3f2vz34x0bwcnm"; } else null; nodeOptionalDep = if runtime == "node" && nodePlatform != null then fetchurl { url = "https://github.com/openai/codex/releases/download/rust-v${version}/codex-npm-${nodePlatform}-${version}.tgz"; sha256 = nodeOptionalDepHashes.${nodePlatform}; } else null; runtimeConfig = { native = { nativeBuildInputs = [ gnutar gzip makeWrapper ] ++ lib.optionals stdenv.isLinux [ patchelf ]; buildInputs = lib.optionals stdenv.isLinux [ openssl libcap libz ]; description = "OpenAI Codex CLI (Native Binary) - AI coding assistant in your terminal"; binName = nativeBinName; }; node = { nativeBuildInputs = [ nodejs_22 cacert makeWrapper ]; buildInputs = []; description = "OpenAI Codex CLI (Node.js) - AI coding assistant in your terminal"; binName = nodeBinName; }; }; selected = runtimeConfig.${runtime}; linuxRuntimePath = lib.makeBinPath (lib.optionals stdenv.isLinux [ bubblewrap ]); in assert runtime == "native" -> platform != null || throw "Native runtime not supported on ${stdenv.hostPlatform.system}. Supported: aarch64-darwin, x86_64-darwin, x86_64-linux, aarch64-linux"; stdenv.mkDerivation rec { pname = if runtime == "native" then "codex" else "codex-${runtime}"; inherit version; dontUnpack = true; dontPatchELF = runtime == "native"; dontStrip = runtime == "native"; nativeBuildInputs = selected.nativeBuildInputs; buildInputs = selected.buildInputs; buildPhase = if runtime == "native" then '' runHook preBuild mkdir -p build tar -xzf ${nativeBinary} -C build mv build/codex-${platform} build/codex chmod u+w,+x build/codex ${lib.optionalString stdenv.isLinux '' patchelf \ --set-interpreter "$(cat ${stdenv.cc}/nix-support/dynamic-linker)" \ --set-rpath "${lib.makeLibraryPath [ openssl libcap libz ]}" \ build/codex ''} runHook postBuild '' else '' runHook preBuild export HOME=$TMPDIR mkdir -p $HOME/.npm export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt export NODE_EXTRA_CA_CERTS=$SSL_CERT_FILE mkdir -p $out/lib/node_modules/@openai tar -xzf ${npmTarball} -C $out/lib/node_modules/@openai mv $out/lib/node_modules/@openai/package $out/lib/node_modules/@openai/codex ${lib.optionalString (nodeOptionalDep != null) '' tar -xzf ${nodeOptionalDep} -C $out/lib/node_modules/@openai mv $out/lib/node_modules/@openai/package $out/lib/node_modules/@openai/codex-${nodePlatform} ''} runHook postBuild ''; installPhase = if runtime == "native" then '' runHook preInstall mkdir -p $out/bin cp build/codex $out/bin/codex-raw chmod +x $out/bin/codex-raw makeWrapper "$out/bin/codex-raw" "$out/bin/${selected.binName}" \ --run 'export CODEX_EXECUTABLE_PATH="$HOME/.local/bin/${selected.binName}"' \ --set DISABLE_AUTOUPDATER 1 \ ${lib.optionalString stdenv.isLinux ''--prefix PATH : "${linuxRuntimePath}"''} runHook postInstall '' else '' runHook preInstall mkdir -p $out/bin makeWrapper ${nodejs_22}/bin/node "$out/bin/${selected.binName}" \ --add-flags --no-warnings \ --add-flags "$out/lib/node_modules/@openai/codex/bin/codex.js" \ --set NODE_PATH "$out/lib/node_modules" \ --run 'export CODEX_EXECUTABLE_PATH="$HOME/.local/bin/${selected.binName}"' \ --set DISABLE_AUTOUPDATER 1 \ ${lib.optionalString stdenv.isLinux ''--prefix PATH : "${linuxRuntimePath}"''} runHook postInstall ''; meta = with lib; { description = selected.description; homepage = "https://github.com/openai/codex"; license = licenses.asl20; platforms = if runtime == "native" then [ "aarch64-darwin" "x86_64-darwin" "x86_64-linux" "aarch64-linux" ] else platforms.all; mainProgram = selected.binName; }; }