From c5254061e13ce66996a7c4d9c7a68a9dff2d6149 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Sun, 28 Sep 2025 10:40:46 -0700 Subject: [PATCH 1/2] chore: remove responses-api-proxy from the multitool --- codex-rs/Cargo.lock | 5 ++--- codex-rs/Cargo.toml | 1 - codex-rs/cli/Cargo.toml | 1 - codex-rs/cli/src/main.rs | 11 ----------- codex-rs/responses-api-proxy/Cargo.toml | 6 +++--- codex-rs/responses-api-proxy/src/main.rs | 18 ++++++++---------- 6 files changed, 13 insertions(+), 29 deletions(-) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 00d95eb4e9..fc0eb20a88 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -695,7 +695,6 @@ dependencies = [ "codex-process-hardening", "codex-protocol", "codex-protocol-ts", - "codex-responses-api-proxy", "codex-tui", "ctor 0.5.0", "owo-colors", @@ -996,13 +995,13 @@ version = "0.0.0" dependencies = [ "anyhow", "clap", - "codex-arg0", + "codex-process-hardening", + "ctor 0.5.0", "libc", "reqwest", "serde", "serde_json", "tiny_http", - "tokio", "zeroize", ] diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index ddd7ed51a3..862f06aa17 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -53,7 +53,6 @@ codex-ollama = { path = "ollama" } codex-process-hardening = { path = "process-hardening" } codex-protocol = { path = "protocol" } codex-protocol-ts = { path = "protocol-ts" } -codex-responses-api-proxy = { path = "responses-api-proxy" } codex-rmcp-client = { path = "rmcp-client" } codex-tui = { path = "tui" } codex-utils-readiness = { path = "utils/readiness" } diff --git a/codex-rs/cli/Cargo.toml b/codex-rs/cli/Cargo.toml index 094a35b42c..618f4b7b03 100644 --- a/codex-rs/cli/Cargo.toml +++ b/codex-rs/cli/Cargo.toml @@ -28,7 +28,6 @@ codex-mcp-server = { workspace = true } codex-process-hardening = { workspace = true } codex-protocol = { workspace = true } codex-protocol-ts = { workspace = true } -codex-responses-api-proxy = { workspace = true } codex-tui = { workspace = true } ctor = { workspace = true } owo-colors = { workspace = true } diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs index 7dcfdae2f3..5c95df0afa 100644 --- a/codex-rs/cli/src/main.rs +++ b/codex-rs/cli/src/main.rs @@ -1,4 +1,3 @@ -use anyhow::Context; use clap::CommandFactory; use clap::Parser; use clap_complete::Shell; @@ -15,7 +14,6 @@ use codex_cli::login::run_logout; use codex_cli::proto; use codex_common::CliConfigOverrides; use codex_exec::Cli as ExecCli; -use codex_responses_api_proxy::Args as ResponsesApiProxyArgs; use codex_tui::AppExitInfo; use codex_tui::Cli as TuiCli; use owo_colors::OwoColorize; @@ -87,10 +85,6 @@ enum Subcommand { /// Internal: generate TypeScript protocol bindings. #[clap(hide = true)] GenerateTs(GenerateTsCommand), - - /// Internal: run the responses API proxy. - #[clap(hide = true)] - ResponsesApiProxy(ResponsesApiProxyArgs), } #[derive(Debug, Parser)] @@ -339,11 +333,6 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() Some(Subcommand::GenerateTs(gen_cli)) => { codex_protocol_ts::generate_ts(&gen_cli.out_dir, gen_cli.prettier.as_deref())?; } - Some(Subcommand::ResponsesApiProxy(args)) => { - tokio::task::spawn_blocking(move || codex_responses_api_proxy::run_main(args)) - .await - .context("responses-api-proxy blocking task panicked")??; - } } Ok(()) diff --git a/codex-rs/responses-api-proxy/Cargo.toml b/codex-rs/responses-api-proxy/Cargo.toml index b66473b195..651019a816 100644 --- a/codex-rs/responses-api-proxy/Cargo.toml +++ b/codex-rs/responses-api-proxy/Cargo.toml @@ -8,7 +8,7 @@ name = "codex_responses_api_proxy" path = "src/lib.rs" [[bin]] -name = "responses-api-proxy" +name = "codex-responses-api-proxy" path = "src/main.rs" [lints] @@ -17,11 +17,11 @@ workspace = true [dependencies] anyhow = { workspace = true } clap = { workspace = true, features = ["derive"] } -codex-arg0 = { workspace = true } +codex-process-hardening = { workspace = true } +ctor = { workspace = true } libc = { workspace = true } reqwest = { workspace = true, features = ["blocking", "json", "rustls-tls"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tiny_http = { workspace = true } -tokio = { workspace = true } zeroize = { workspace = true } diff --git a/codex-rs/responses-api-proxy/src/main.rs b/codex-rs/responses-api-proxy/src/main.rs index eaa534d981..c4568d76aa 100644 --- a/codex-rs/responses-api-proxy/src/main.rs +++ b/codex-rs/responses-api-proxy/src/main.rs @@ -1,14 +1,12 @@ -use anyhow::Context; use clap::Parser; -use codex_arg0::arg0_dispatch_or_else; use codex_responses_api_proxy::Args as ResponsesApiProxyArgs; -pub fn main() -> anyhow::Result<()> { - arg0_dispatch_or_else(|_codex_linux_sandbox_exe| async move { - let args = ResponsesApiProxyArgs::parse(); - tokio::task::spawn_blocking(move || codex_responses_api_proxy::run_main(args)) - .await - .context("responses-api-proxy blocking task panicked")??; - Ok(()) - }) +#[ctor::ctor] +fn pre_main() { + codex_process_hardening::pre_main_hardening(); +} + +pub fn main() -> anyhow::Result<()> { + let args = ResponsesApiProxyArgs::parse(); + codex_responses_api_proxy::run_main(args) } From d75ecbf3abc812671610c6903a5922688e774aee Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Sun, 28 Sep 2025 11:32:25 -0700 Subject: [PATCH 2/2] feat: build codex-responses-api-proxy for all platforms as part of the GitHub Release --- .github/dotslash-config.json | 28 +++++++++++++++++ .github/workflows/rust-release.yml | 4 ++- codex-cli/scripts/build_npm_package.py | 7 ++--- codex-cli/scripts/install_native_deps.py | 38 ++++++++++++++++++++---- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/.github/dotslash-config.json b/.github/dotslash-config.json index 8566e03490..5e28cdf207 100644 --- a/.github/dotslash-config.json +++ b/.github/dotslash-config.json @@ -27,6 +27,34 @@ "path": "codex.exe" } } + }, + "codex-responses-api-proxy": { + "platforms": { + "macos-aarch64": { + "regex": "^codex-responses-api-proxy-aarch64-apple-darwin\\.zst$", + "path": "codex-responses-api-proxy" + }, + "macos-x86_64": { + "regex": "^codex-responses-api-proxy-x86_64-apple-darwin\\.zst$", + "path": "codex-responses-api-proxy" + }, + "linux-x86_64": { + "regex": "^codex-responses-api-proxy-x86_64-unknown-linux-musl\\.zst$", + "path": "codex-responses-api-proxy" + }, + "linux-aarch64": { + "regex": "^codex-responses-api-proxy-aarch64-unknown-linux-musl\\.zst$", + "path": "codex-responses-api-proxy" + }, + "windows-x86_64": { + "regex": "^codex-responses-api-proxy-x86_64-pc-windows-msvc\\.exe\\.zst$", + "path": "codex-responses-api-proxy.exe" + }, + "windows-aarch64": { + "regex": "^codex-responses-api-proxy-aarch64-pc-windows-msvc\\.exe\\.zst$", + "path": "codex-responses-api-proxy.exe" + } + } } } } diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index c808216d96..345fd091a7 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -97,7 +97,7 @@ jobs: sudo apt install -y musl-tools pkg-config - name: Cargo build - run: cargo build --target ${{ matrix.target }} --release --bin codex + run: cargo build --target ${{ matrix.target }} --release --bin codex --bin codex-responses-api-proxy - name: Stage artifacts shell: bash @@ -107,8 +107,10 @@ jobs: if [[ "${{ matrix.runner }}" == windows* ]]; then cp target/${{ matrix.target }}/release/codex.exe "$dest/codex-${{ matrix.target }}.exe" + cp target/${{ matrix.target }}/release/codex-responses-api-proxy.exe "$dest/codex-responses-api-proxy-${{ matrix.target }}.exe" else cp target/${{ matrix.target }}/release/codex "$dest/codex-${{ matrix.target }}" + cp target/${{ matrix.target }}/release/codex-responses-api-proxy "$dest/codex-responses-api-proxy-${{ matrix.target }}" fi - if: ${{ matrix.runner == 'windows-11-arm' }} diff --git a/codex-cli/scripts/build_npm_package.py b/codex-cli/scripts/build_npm_package.py index 0401f10385..bedb1c2438 100755 --- a/codex-cli/scripts/build_npm_package.py +++ b/codex-cli/scripts/build_npm_package.py @@ -158,11 +158,8 @@ def stage_sources(staging_dir: Path, version: str) -> None: out.write("\n") -def install_native_binaries(staging_dir: Path, workflow_url: str | None) -> None: - cmd = ["./scripts/install_native_deps.py"] - if workflow_url: - cmd.extend(["--workflow-url", workflow_url]) - cmd.append(str(staging_dir)) +def install_native_binaries(staging_dir: Path, workflow_url: str) -> None: + cmd = ["./scripts/install_native_deps.py", "--workflow-url", workflow_url, str(staging_dir)] subprocess.check_call(cmd, cwd=CODEX_CLI_ROOT) diff --git a/codex-cli/scripts/install_native_deps.py b/codex-cli/scripts/install_native_deps.py index 7fbb44393a..c9e3ac2def 100755 --- a/codex-cli/scripts/install_native_deps.py +++ b/codex-cli/scripts/install_native_deps.py @@ -145,7 +145,35 @@ def fetch_rg( def _download_artifacts(workflow_id: str, dest_dir: Path) -> None: - cmd = [ + """ + Find all the .zst variants of the Codex CLI artifacts in the given workflow + run and download them into the given directory. + """ + view_cmd = [ + "gh", + "run", + "view", + workflow_id, + "--repo", + "openai/codex", + "--json", + "artifacts", + ] + data = json.loads(subprocess.check_output(view_cmd, text=True)) + all_artifact_names = [ + artifact["name"] + for artifact in data.get("artifacts", []) + if not artifact["name"].startswith("codex-responses-api-proxy") + ] + artifact_names = [ + name + for name in all_artifact_names + if not name.startswith("codex-responses-api-proxy") and name.endswith(".zst") + ] + + if not artifact_names: + raise RuntimeError("No codex artifacts found in workflow run.") + download_cmd = [ "gh", "run", "download", @@ -155,7 +183,9 @@ def _download_artifacts(workflow_id: str, dest_dir: Path) -> None: "openai/codex", workflow_id, ] - subprocess.check_call(cmd) + for name in artifact_names: + download_cmd.extend(["--name", name]) + subprocess.check_call(download_cmd) def install_codex_binaries( @@ -259,9 +289,7 @@ def extract_archive( if archive_format == "zst": output_path = archive_path.parent / dest.name - subprocess.check_call( - ["zstd", "-f", "-d", str(archive_path), "-o", str(output_path)] - ) + subprocess.check_call(["zstd", "-f", "-d", str(archive_path), "-o", str(output_path)]) shutil.move(str(output_path), dest) return