Skip to content

Detect Codex installs managed by pnpm - #31503

Merged
charliemarsh-oai merged 11 commits into
mainfrom
charlie/fix-pnpm-install-detection
Jul 8, 2026
Merged

Detect Codex installs managed by pnpm#31503
charliemarsh-oai merged 11 commits into
mainfrom
charlie/fix-pnpm-install-detection

Conversation

@charliemarsh-oai

@charliemarsh-oai charliemarsh-oai commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Why

The Codex JavaScript shim currently distinguishes npm and Bun installs, but a global pnpm install falls back to npm. That causes the native CLI, codex doctor, and update flows to report or run npm commands even though pnpm owns the installation. pnpm also allows its global package and bin directories to differ, so PNPM_HOME does not reliably identify the package owner.

What changed

  • detect pnpm-managed installs by finding pnpm's node_modules/.modules.yaml metadata from the launched JavaScript entrypoint
  • pass a mutually exclusive CODEX_MANAGED_BY_PNPM marker into the native CLI
  • represent pnpm in install context, doctor output, version checks, and TUI update actions without changing the existing public InstallContext::from_exe signature
  • recommend pnpm add -g @openai/codex for pnpm-managed installs and snapshot the rendered TUI update notice

Validated with the 9-test install-context suite, the focused pnpm TUI snapshot test, and Node's syntax check for the launcher.

Closes #10294.

Comment thread codex-cli/bin/codex.js Outdated
{
"bun": "CODEX_MANAGED_BY_BUN",
"pnpm": "CODEX_MANAGED_BY_PNPM",
}[detectPackageManager()] ?? "CODEX_MANAGED_BY_NPM";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@codex is there a better way to do this that's less ugly?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hahaha. We can do a nested ternary?

Comment thread codex-cli/bin/codex.js Outdated
Comment on lines +123 to +124
// pnpm records installation metadata in node_modules/.modules.yaml. Search
// the canonical package root and lexical entrypoint because either can be

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@codex i'm a bit worried about this while(true) and traversal through a potentially deepish directory, is there no better way to distinguish pnpm from npm?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Summary

  • Replaced the unbounded while (true) parent-directory walk in pnpm detection with a bounded scan of node_modules roots derived from the resolved Codex package paths. codex-cli/bin/codex.jsL123-L140
  • Kept the pnpm ownership guard intact by requiring .modules.yaml and verifying that node_modules/@openai/codex resolves to the current Codex package root before returning pnpm. codex-cli/bin/codex.jsL142-L156
  • Committed the follow-up change as 68aa389a314224d0697958b8150ec689b456ea83 and created the follow-up PR titled “Bound pnpm owner detection in CLI shim.”

Testing

  • node --check codex-cli/bin/codex.js && prettier --check codex-cli/bin/codex.js && git diff --check
  • ⚠️ cd codex-rs && just fmt (failed due environment/tooling limits: missing dotslash, plus Python formatter dependencies could not be downloaded through the proxy)

View task →

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the traversal was already bounded by the filesystem root, but I rewrote it to make that clearer.

We still need to inspect the parent directories since pnpm’s global isolated layout places the owning node_modules several levels above the package root.

Comment thread codex-rs/install-context/src/lib.rs Outdated
Comment thread codex-cli/bin/codex.js
CODEX_MANAGED_PACKAGE_ROOT: realpathSync(path.join(__dirname, "..")),
CODEX_MANAGED_PACKAGE_ROOT: codexPackageRoot,
};
delete env.CODEX_MANAGED_BY_NPM;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need to delete the env variables newly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is an existing bug on main (npm-managed Codex starts a shell, that shell invokes a Bun-managed Codex but inherits CODEX_MANAGED_BY_NPM=1). This PR makes it a bit worse since we now have even more combinations here. But it isn't strictly necessary, I can remove or carve into a separate PR if preferred.

Comment thread codex-rs/install-context/src/lib.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 419307d38f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/update_action.rs
Comment on lines 71 to 75
pub fn from_exe(
is_macos: bool,
current_exe: Option<&Path>,
managed_by_npm: bool,
managed_by_bun: bool,
method_override: Option<InstallMethod>,
) -> Self {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Restore InstallContext::from_exe's public signature

This changes the public codex_install_context::InstallContext::from_exe API from the existing npm/bun boolean parameters to Option<InstallMethod>, so any out-of-tree caller of this crate will fail to compile even though the change only needs a pnpm override internally. The commit notes that the existing public signature should be preserved; keep this method compatible and route the new override through an added/private helper instead.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

(Is it important to follow semver here and avoid breakages on a function like this? Do we care about that?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We don't care about this as long as the whole thing compiles

@charliemarsh-oai
charliemarsh-oai force-pushed the charlie/fix-pnpm-install-detection branch from 419307d to 23aa44d Compare July 8, 2026 11:42
@charliemarsh-oai
charliemarsh-oai merged commit e212cc9 into main Jul 8, 2026
35 checks passed
@charliemarsh-oai
charliemarsh-oai deleted the charlie/fix-pnpm-install-detection branch July 8, 2026 16:18
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update codex using pnpm

3 participants