This repository adapts the upstream macOS ChatGPT Desktop DMG into Linux app and package artifacts.
install.shextractsCodex.dmgwith7z/7zz.- It detects the Electron version from upstream metadata, with a pinned fallback.
- It extracts and patches
app.asarwith fail-soft Linux compatibility patches. - It rebuilds native Node modules such as
better-sqlite3andnode-ptyfor Linux through@electron/rebuild. - It downloads a matching Linux Electron runtime.
- It stages bundled plugins and any enabled optional
linux-features/. - It writes the Linux launcher to
codex-app/start.shfromlauncher/start.sh.template. - Package builders repackage
codex-app/into.deb,.rpm,.pkg.tar.zst, or AppImage artifacts. - Default native packages install
codex-update-managerand asystemd --userservice.
The installer replaces the macOS Electron binary with a Linux build, recompiles native modules, and removes macOS-only pieces such as Sparkle.
Core Linux compatibility patches live under scripts/patches/core/.
Descriptors declare phase, order, target filters, and CI policy.
scripts/patch-linux-window-ui.js is the build-facing CLI only. It parses
arguments, creates/writes the optional report, calls
scripts/patches/runner.js, and applies the critical gate after the report is
written. Internal code imports runner APIs, not the CLI file.
scripts/patches/runner.js collects core descriptors plus enabled
linux-features/ descriptors and executes the fresh-DMG pipeline:
main-bundleextracted-app:pre-webviewwebview-assetextracted-app:post-webview
scripts/patches/engine.js owns descriptor normalization, target/enabled
checks, phase execution, warning capture, and status recording. Shared
implementation code lives under scripts/patches/impl/ by domain; generic
helpers live under scripts/patches/lib/. The deleted compatibility barrels
are intentionally not part of the architecture.
ciPolicy is the single criticality axis, enforced by the patch engine —
patches themselves never abort the build:
required-upstream(critical): the app does not launch or is core-unusable without it. If one fails (no match or a throw), the patcher exits non-zero with an aggregatedCritical patch failuressummary and the build aborts.CODEX_ENFORCE_CRITICAL_PATCHES=0bypasses this for emergency builds.optional: best-effort. Failures and throws are caught by the engine, logged as warnings, and listed in the end-of-buildoptional patches not fully appliedsummary so they can be fixed later.opt-in: disabled unless explicitly enabled; recorded asskipped-disabled.
Every build writes a patch report (<app>/.codex-linux/patch-report.json,
next to build-info.json). scripts/lib/patch-report.js owns report statuses
and failure predicates. CI validates the same report with
scripts/ci/validate-patch-report.js, which shares the failure predicate with
the local gate and prints non-failing optional-drift warnings.
Optional additions belong under linux-features/. Feature patching uses only
entrypoints.patchDescriptors; feature descriptor ids are namespaced in patch
reports and are optional by default.
The launcher serves extracted webview assets from content/webview/ on
127.0.0.1 (5175 by default, 5176 for the dev app), validates the origin,
then starts Electron.
Warm-start launches hand off actions such as --new-chat over a Unix-domain
socket instead of spawning a second app process.
Native-package-only launcher behavior, such as desktop-entry hints and default update-manager startup, lives in:
packaging/linux/codex-packaged-runtime.sh
The current evaluation for a future Rust replacement of the local webview server lives in webview-server-evaluation.md.
The build preserves portable upstream Sites, Deep Research, and Visualize plugins when they are listed in the official DMG marketplace. Their payloads must match the expected local path and contain no symlinks, privileged entries, native executables, or platform-specific bundles. Availability in the app can still depend on upstream account entitlements or rollout gates.
Plugins with native macOS payloads are not copied through this portable path. Linux Computer Use and opt-in Record and Replay use repository-owned Linux replacements instead. The bundled LaTeX plugin remains excluded until its Tectonic runtime has a verified Linux staging path.
The build stages the upstream Chrome plugin, patches its Linux compatibility paths, builds the native messaging host from Rust, and installs browser manifests for Chrome, Brave, and Chromium.
Run the subset that matches your change. For installer, packaging, patcher, or updater changes:
bash -n install.sh scripts/lib/*.sh launcher/start.sh.template scripts/build-deb.sh scripts/build-rpm.sh scripts/build-pacman.sh scripts/build-appimage.sh scripts/install-deps.sh
node --check scripts/patch-linux-window-ui.js
node --test scripts/patch-linux-window-ui.test.js
node --test linux-features/*/test.js
bash tests/scripts_smoke.sh
cargo check -p codex-update-manager
cargo test -p codex-update-manager
cargo check -p codex-computer-use-linux
cargo test -p codex-computer-use-linux
cargo check -p codex-read-aloud-linux
cargo test -p codex-read-aloud-linux
cargo check -p codex-record-replay-linux
cargo test -p codex-record-replay-linux
make packageFor contribution policy and review expectations, see CONTRIBUTING.md.