Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Use the native Codex update command for supported versions - #4065

Open
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates
Open

Use the native Codex update command for supported versions#4065
Destreyf wants to merge 4 commits into
pingdotgg:mainfrom
Destreyf:t3code/version-aware-codex-updates

Conversation

@Destreyf

@DestreyfDestreyf commented Jul 16, 2026

Copy link
Copy Markdown

What Changed

  • Use the configured Codex executable with structured ["update"] arguments when the installed version is valid semver and >= 0.128.0 and the installation is npm-, Bun-, Homebrew-, or standalone-managed. Default installations continue to execute codex update, while custom names and absolute paths update the same executable that was probed.
  • Retain the existing npm, pnpm, Bun, Vite+, and Homebrew path detection for older, missing, or malformed versions. pnpm and Vite+ retain their legacy commands at every version because upstream native detection currently classifies their JS wrappers as npm-managed.
  • Store the resolved maintenance capability with each provider snapshot so versionAdvisory.updateCommand, canUpdate, and runner execution stay aligned.
  • Preserve package-manager lock grouping for native updates and reserve the Codex-native lock for standalone or otherwise unclassified installations.
  • Preserve the configured provider-instance environment and effective home for native updates. Standalone executables override auth-overlay shadow homes with the shared installation home derived from the already-resolved path.
  • Add strict semver validation and focused coverage for the stable boundary, prereleases, legacy managers, manual-only paths, configured executables, install context, and update concurrency.

Why

Codex added its native codex update command in openai/codex@b985768. It first appeared in 0.126.0-alpha.9, but 0.128.0 was the first stable npm release containing it, so this uses 0.128.0 as the conservative capability boundary.

Supported modern Codex installations can therefore perform their own installation-method detection instead of relying on T3 Code to invoke a package manager. Older or indeterminate installations, plus pnpm and Vite+ installations not currently supported by the native detector, continue using the existing behavior. Other provider drivers are unchanged.

Fixes#4066.

Related: #2765 covers Windows-specific child-process/PATH failures when spawning package-manager update commands. This PR may avoid that path for supported modern Codex installations, but it does not replace the Windows-specific fix.

Testing

  • Focused provider-maintenance suite — 98 passed
  • Provider-instance, adapter-registry, and Codex-home integration suite — 11 passed
  • vp check — passed with 9 existing unrelated web lint warnings
  • vp run typecheck — passed

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI changes)
  • I included a video for animation/interaction changes (no animation or interaction changes)

Note

Use native codex update command for Codex versions >= 0.128.0

  • Introduces version-gated maintenance capability selection in codexMaintenance.ts: versions >= 0.128.0 use the native codex update command; older versions retain legacy package-manager (pnpm/vp) updates.
  • Adds makeCodexMaintenanceEnvironment to set CODEX_HOME based on whether the executable is from a shared standalone install or an instance-specific path.
  • Changes ServerProviderShape.maintenanceCapabilities from a synchronous property to getMaintenanceCapabilities, an Effect, allowing capabilities to update when the probed version changes.
  • Extends ProviderMaintenanceCommandAction with an optional env field; ProviderMaintenanceRunner now passes this env (e.g. CODEX_HOME) to spawned update processes.
  • Fixes parseSemver in both shared/src/semver.ts and providerMaintenance.ts to strip build metadata before parsing numeric segments.
  • Behavioral Change: consumers of ServerProviderShape must now call getMaintenanceCapabilities as an Effect instead of reading a direct property.

Macroscope summarized 90b261b.


Note

Medium Risk
Changes provider self-update execution (spawn env, version-gated commands) and makes maintenance capabilities async per snapshot; mistakes could run wrong update commands or misreport update availability for Codex.

Overview
Codex provider updates now prefer the probed executable’s native codex update flow when the installed version is valid semver and ≥ 0.128.0; older, missing, or malformed versions keep the existing package-manager path detection (with pnpm and vp always on legacy commands).

Maintenance capabilities are tied to the live snapshot:ServerProviderShape exposes getMaintenanceCapabilities as an Effect instead of a fixed field, and makeManagedServerProvider can resolveMaintenanceCapabilities after each probe so version advisories, canUpdate, and the update runner use the same command. Codex wires this through new codexMaintenance helpers (version gate, optional update env including CODEX_HOME for standalone installs) and resolveProviderMaintenanceCapabilitiesWithPathsEffect for resolved binary paths.

The maintenance runner forwards optional env into child-process spawn; shared semver gains isValidSemverVersion and build-metadata stripping in parseSemver.

Reviewed by Cursor Bugbot for commit e0ae1d7. Bugbot is set up for automated code reviews on this repo. Configure here.

@DestreyfDestreyf mentioned this pull request Jul 16, 2026
2 tasks
@github-actionsgithub-actionsBot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 16, 2026
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces version-gated maintenance capabilities that change how Codex updates are executed based on installed version. It adds new selection logic, interface changes (sync to Effect-based), and environment handling - significant runtime behavior changes that warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@DestreyfDestreyf changed the title Use native Codex updates for supported versionsUse the native Codex update command for supported versionsJul 16, 2026
@coderabbitai

coderabbitaiBot commented Jul 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 262ea88d-b6e4-40de-bf67-2246c27dca6a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NicL9923NicL9923 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.

Three install-context and update-coordination issues below. The capability/snapshot state plumbing and validation otherwise look solid.

Comment threadapps/server/src/provider/codexMaintenance.ts
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts Outdated
Comment threadapps/server/src/provider/codexMaintenance.ts Outdated
@github-actionsgithub-actionsBot added the size:L 100-499 changed lines (additions + deletions). label Jul 18, 2026
Comment threadapps/server/src/provider/Drivers/CodexDriver.ts
@Dropje97

Copy link
Copy Markdown

Just added a second, independent reproduction of the underlying bug in #5629 — same standalone-installer layout, but with npm's global prefix set to ~/.local, the npm install -g fallback collides with the installer's own symlink and exits 1 (EEXIST) instead of silently installing a shadow copy. So on that configuration the in-app update isn't just cosmetically stuck, it fails outright with no path forward from the UI.

Mentioning it here mostly as a data point that the nativeUpdate path this PR adds fixes more than the "still needs an update" loop.

@Destreyf — this is currently conflicting against main and has been idle since late July. Any appetite to rebase it? Happy to test a rebased branch against a standalone install on Linux if that helps.

@Destreyf
Destreyfforce-pushed the t3code/version-aware-codex-updates branch from 90b261b to e0ae1d7CompareSeptember 1, 2026 15:56
@Destreyf

Copy link
Copy Markdown
Author

@Dropje97 should be rebased appropriately now.

@Dropje97

Dropje97 commented Sep 1, 2026

Copy link
Copy Markdown

Tested e0ae1d7 on Linux against a standalone install.

~/.local/bin/codex -> ~/.codex/packages/standalone/releases/0.151.0-x86_64-unknown-linux-musl/bin/codex
codex-cli 0.151.0, binaryPath left at the default "codex", CODEX_HOME unset

Before this PR the advisory resolves to the npm command, which exits 1 on this machine — my npm global prefix is ~/.local, the same bin dir the standalone installer owns, so npm's bin-link step hits EEXIST (this is #5629). Straight out of the provider cache on my running instance:

"status": "behind_latest", "currentVersion": "0.151.0", "latestVersion": "0.152.0",
"updateCommand": "npm install -g --allow-scripts=@openai/codex @openai/codex@latest"

With this PR, driving the real resolution code against my actual filesystem and the running server's PATH:

resolvedCommandPath = ~/.local/bin/codex
realCommandPath = ~/.codex/packages/standalone/releases/0.151.0-.../bin/codex
legacy = npm install -g --allow-scripts=@openai/codex @openai/codex@latest
selected = codex ["update"], lockKey "npm-global", CODEX_HOME=~/.codex
advisory = updateCommand "codex update", canUpdate true

The version gate lets 0.151.0 through, the standalone CODEX_HOME override fires, and the UI would show the native command instead of the broken npm one.

Test runs on the rebased branch: apps/server/src/provider 740 passed / 8 skipped / 0 failed, packages/shared/src/semver.test.ts 12 passed. Rebase looks clean from here — merge-base is exactly current main, no drift.

Two minor observations, neither a blocker:

  1. This standalone install inherits lockKey: "npm-global" rather than codex-native, because the legacy layer classifies a bare binaryPath as npm. It over-serializes, so it is safe, and it looks deliberate and test-covered — just noting it reads differently from the literal wording of the earlier review point about lock grouping.
  2. A standalone install located outside the configured home would not get the CODEX_HOME override, and would presumably be classified as "Other" by upstream's own detection. Not a regression, but uncovered. I am less confident about this one — I could not exercise that layout here.

Update — the native command was run end to end, and it works.

I ran it exactly as the runner would spawn it:

$ CODEX_HOME=~/.codex codex update
Updating Codex via `sh -c 'curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh'`...
==> Updating Codex CLI from 0.151.0 to 0.152.0
==> Detected platform: Linux (x64)
==> Installing standalone package to ~/.codex/packages/standalone/releases/0.152.0-x86_64-unknown-linux-musl
==> ~/.local/bin is already on PATH
Codex CLI 0.152.0 installed successfully.
exit 0

Post-conditions checked:

  • codex --versioncodex-cli 0.152.0 (was 0.151.0)
  • ~/.codex/packages/standalone/current correctly repointed to releases/0.152.0-..., symlink chain via ~/.local/bin/codex intact
  • no npm copy created~/.local/lib/node_modules/ still contains no @openai/codex

That last point is the whole difference. Upstream's own install-context detection correctly identified the standalone layout and updated in place, where the legacy npm path either aborts with EEXIST (my prefix) or silently creates a second, unused install (the #5629 reporter's prefix).

So on this configuration the PR takes the provider from "update is impossible from the UI" to "update succeeds", verified end to end.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use native Codex updates for supported CLI versions

3 participants

@Destreyf@Dropje97@NicL9923