Repository navigation
Never run the Codex inside Codex.app or ChatGPT.app - #97
Open
jparker2006 wants to merge 1 commit into
Open
jparker2006 wants to merge 1 commit into
jparker2006 wants to merge 1 commit into
Conversation
Cloudroom fell back to the codex binary inside Codex.app or ChatGPT.app and ran it, including in the background. When macOS flags that build, it moves the whole app to the Bin (davidondrej#96). Codex lookup now skips app bundles, even through a PATH symlink; those users get the existing Install action.
jparker2006
added a commit
to jparker2006/cloudroom-core
that referenced
this pull request
Oct 31, 2026
With davidondrej#97 a null lookup means no usable Codex; a bare "codex" could still reach one inside Codex.app through the OS PATH lookup. Sign-in now fails with the not-installed error, and the expiry check counts it as signed in. Refs davidondrej#96
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem. When there's no standalone Codex CLI,
findCliExecutable("codex")fell back to the binary inside/Applicationsor~/Applications{ChatGPT,Codex}.app/Contents/Resources/{codex-cli/bin/codex,codex}. Every caller then ran it: provider status (--version),codex login,codex app-server,codex mcp list, local threads, model list. When macOS flags that Codex build, running a binary inside the bundle makes macOS move the whole app to the Bin. That's what happened in #96.provider-maintenance.tsalso treated an app-bundled Codex as installed and never offered Install or Update ("only updates with the app"), so users were stuck on whatever binary the app shipped.Repro. I wrote two tests. Both fail on
origin/mainand pass with this PR. Each one stubsprocess.platformtodarwinthe same wayapps/cliandapps/desktoptests do, and uses a temp HOME withApplications/Codex.appandChatGPT.appinside it:process-utils: on a Codex.app-only machine,findCliExecutable("codex")returns…/Applications/ChatGPT.app/Contents/Resources/codex-cli/bin/codexon main (expected '…/Ap…' to be null). A PATH symlink into the bundle is returned too.provider-codex: the fake bundledcodexwrites a marker file when it runs. On main,getCodexProviderInstallationStatus()runs it (expected true to be false).Fix. Cloudroom never runs binaries inside other apps'
.appbundles.cli-locations.ts: removedcodexAppBundlePaths. Codex lookup also skips any candidate whose realpath contains.app/, so a PATH symlink into Codex.app is skipped too. Official standalone, PATH, and Homebrew/npm installs resolve exactly as before.provider-maintenance.ts: removed theappBundledlogic, which is now dead. If no allowed Codex exists,codexExecutable()returns the path OpenAI's installer would use instead of a barecodex. A bare name would let the OS's PATH lookup reach the same Codex.app symlink. Status, health and usage then report "not installed" without running anything, and a thread or model-list spawn fails with the usual "could not find the Codex CLI" guidance. I duplicated the 4-line path becauseofficialCodexPathisn't exported through@get-bb/plugin-sdk.bridge.ts: the missing-CLI message now adds "Cloudroom never runs the copy inside Codex.app or ChatGPT.app."The
.app/rule is Codex-only. Claude's own CLI can live in aclaude.appbundle (seedesktopClaude()), so a blanket rule infindCliExecutablecould break Claude lookups.Tests. I ran these from
gui/afternpx --yes pnpm@9.15.9 install --frozen-lockfile:cd packages/process-utils && npx vitest run --config vitest.config.ts→ 5 files passed, 36 tests passed, 6 skipped (Windows-only)cd plugins/provider-codex && npx vitest run --config vitest.config.ts --maxWorkers=2→ 28 files passed, 286 tests passednpx turbo run typecheck --filter=@cloudroom/process-utils --filter=bb-plugin-provider-codex --concurrency=2 --force→ 6/6 tasks passednpx oxfmt --checkon the touched files passes, exceptbridge.ts, which was already unformatted on main. I left it alone to avoid churn./usr/local/bin/codex, so I renamed it for one run. Without it, both new tests fail on main as shown above and pass with this PR. That includes theinstalled: false+installAction.kind: "install"branch. Both tests compare against "whatever non-bundle codex this machine has", so they're hermetic on dev Macs and CI.Where the UI triggers
codex --version(routes.providerCliStatus). It fires on app launch, before any click, while setup step 1 is showing:routes.providerCliStatus(apps/server/src/routes/hosts.ts:347) →getProviderInstallations→ Codex bridge →getCodexProviderInstallationStatus→codex --version.SidebarUpdatesBadge(AppSidebar.tsx:321) →useUpdateInventory(useUpdateInventory.ts:88) queries it for every connected host.<Onboarding />is a sibling of<Routes>inApp.tsx, soAppLayoutand its sidebar mount under the setup overlay at launch.RootComposeView.tsx:877(home compose view) also queries it. So doProvidersSettingsSection, the Updates settings,MachineSettingsViewandMissingProviderCliRowwhen they're shown.SESSION_STATIC_QUERY_POLICY(staleTime: Infinity), so it runs once per session per host.runProviderAutoUpdates(start-server.ts:319, 60 s after start and then every 10 min) hits the same status, but it's opt-in (providerAutoUpdatedefaults to[]).On v135, a Codex.app-only Mac therefore also ran Codex.app's
codex --versionfrom this path at launch, a third background trigger next tosetup-telemetryandharness-versions. With this PR, that path can only run a CLI the user installed. I didn't redesign the UI.Other code that builds paths into Codex.app or ChatGPT.app (I grepped all of
gui/):packages/scripts/src/commands/archive-codex-tmp-bb-sessions.tsis a manual dev script (pnpm codex:archive-tmp-bb-sessions) and nothing in the app calls it. Its default is$CODEX_BIN, then/Applications/Codex.app/Contents/Resources/codex, thencodexon PATH, so it does default to the bundle when no flag is given. I left it unchanged because it never runs automatically.apps/server/src/services/cloudroom/setup-telemetry.tsappVersion("Codex.app")only readsInfo.plistwithplutiland doesn't run the bundle. ItscliPlace"app_bundle"branch can no longer happen for Codex. (That's builder 2's file; I didn't edit it.)For the other builders (not edited here):
sandboxes.ts:102,142(builder 1) usefindCliExecutable("codex") ?? "codex"forcodex loginandcodex app-server. The bare"codex"fallback can still reach a PATH symlink into Codex.app. It needs the same fix ascodexExecutable().claude-token.tsrunSetupTokenruns the Claude desktop app's private…/Claude/claude-code/<v>/claude.app/Contents/MacOS/claudewhen no Claude CLI exists. It only runs when the user clicks Connect Claude, but it's literally a binary inside another app's bundle.What users will notice. People whose only Codex is inside Codex.app or ChatGPT.app now see Codex as not installed. They'll be asked to Install the Codex CLI once, using the existing Install action:
npm install -g @openai/codex, falling back to OpenAI's official installer. After that, Codex updates normally instead of being stuck on the app's copy. Everyone with a standalone, npm or Homebrew Codex sees no change.Not verified. I couldn't test the real macOS side (XProtect moving a flagged app) in this Linux sandbox. All darwin branches were tested with a stubbed
process.platform.Refs #96