Skip to content

Conversation

@bolinfest
Copy link
Collaborator

@bolinfest bolinfest commented Aug 24, 2025

Historically, Codex CLI has treated apply_patch (and its sometimes misspelling, applypatch) as a "virtual CLI," intercepting it when it appears as the first arg to command for the "container.exec", "shell", or "local_shell"` tools.

This approach has a known limitation where if, say, the model created a Python script that runs apply_patch and then tried to run the Python script, we have no insight as to what the model is trying to do and the Python Script would fail because apply_patch was never really on the PATH.

One way to solve this problem is to require users to install an apply_patch executable alongside the codex executable (or at least put it someplace where Codex can discover it). Though to keep Codex CLI as a standalone executable, we exploit "the arg0 trick" where we create a temporary directory with an entry named apply_patch and prepend that directory to the PATH for the duration of the invocation of Codex.

  • On UNIX, apply_patch is a symlink to codex, which now changes its behavior to behave like apply_patch if arg0 is apply_patch (or applypatch)
  • On Windows, apply_patch.bat is a batch script that runs codex --codex-run-as-apply-patch %*, as Codex also changes its behavior if the first argument is --codex-run-as-apply-patch.

Copy link
Collaborator

@dylan-hurd-oai dylan-hurd-oai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 discussions about edge cases, but LGTM!


// Retain the TempDir so it exists for the lifetime of the invocation of
// this executable. Admittedly, we could invoke `keep()` on it, but it
// would be nice to avoid leaving temporary directories behind, if possible.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, i think this is a reasonable approach

};

unsafe {
std::env::set_var("PATH", updated_path_env_var);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking out loud: set_var can technically panic if updated_path_env_var contains a null char, but I think we're reasonably safe here since std::env::var would return VarError in that case, and temp_dir.path() should not return a null char, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On both Windows and UNIX, a file path can never contain NUL, so correct, we don't have to worry about that here.

// While it is possible that Codex could likely proceed successfully
// even if updating the PATH fails, let's be strict.
eprintln!("could not update PATH: {err}");
std::process::exit(1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think we may want to proceed here? It feels like this should be rare, but we could still proceed optimistically. Or log a more helpful error here for the user to know what happened and why we're exiting.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we can eprintln! since there is no logging library set up at this point...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, removed the exit() call here and updated comment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome, thanks!

@bolinfest bolinfest merged commit 517ffd0 into main Aug 24, 2025
28 of 30 checks passed
@bolinfest bolinfest deleted the pr2646 branch August 24, 2025 21:35
@github-actions github-actions bot locked and limited conversation to collaborators Aug 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants