AGENTS.md
July 10, 2026 ยท View on GitHub
Purpose
This repository adapts the official macOS ChatGPT Desktop DMG into a runnable
Linux app, packages it as .deb, .rpm, pacman, and AppImage artifacts, and
ships a local Rust update manager that can rebuild future Linux packages from
newer upstream DMGs.
The build flow: install.sh downloads/extracts Codex.dmg, patches the
extracted app through core and enabled Linux feature descriptors, rebuilds
native modules, downloads Linux Electron, stages bundled resources, writes
codex-app/start.sh, and lets package builders produce native artifacts or
AppImage. Native packages also include codex-update-manager and an
update-builder bundle.
Maintainer Rules
- This project supports only the latest upstream
CODEX.DMG. When fixing upstream drift, remove old drift workarounds in the same change. Do not keep legacy DMG shapes, fallback patch paths, or version-specific compatibility branches around. - Keep core behavior focused on the app launching and working for most Linux
users. Experimental, workflow-specific, editor-specific, browser-specific,
distro-specific, or minority-use integrations belong in
linux-features/and must be disabled by default. - If an optional feature needs a new core touchpoint, add the smallest generic extension point to core, then keep feature-specific logic inside that feature directory.
- Do not enable optional features in committed config.
linux-features/features.jsonis local and gitignored;features.example.jsonstays empty. - Each repository feature under
linux-features/<id>/and each local feature underlinux-features/local/<id>/must include aREADME.mdnext tofeature.json. - Do not manually patch generated output such as
codex-app/start.shfor a durable fix. Change the source template, build helper, feature, or patch descriptor and regenerate. - Treat updater, package builder, launcher, and feature framework changes as cross-format changes unless the code explicitly scopes them to one package format or desktop target.
Source Routing
Use source files, not generated artifacts. Main routing:
- Launcher/webview:
launcher/start.sh.template,launcher/webview-server.py. - Packaged runtimes:
packaging/linux/codex-packaged-runtime.sh,packaging/appimage/codex-appimage-runtime.sh. - Build pipeline:
scripts/lib/*.sh. - Core patches: descriptors in
scripts/patches/core/**/patch.js, implementations inscripts/patches/impl/, helpers inscripts/patches/lib/. - Linux features:
linux-features/<id>/. - Package builders:
scripts/build-*.shandscripts/lib/package-common.sh. - Updater:
updater/src/. - Computer Use:
computer-use-linux/; compositor backends undercomputer-use-linux/src/windowing/backends/. - Nix:
flake.nix,flake.lock, andnix/.
Detailed agent docs: repository map, generated/runtime notes, and validation playbook.
Primary human docs: architecture, build and packaging, Linux features, updater, Linux Computer Use, Nix, and troubleshooting.
Patch And Feature Rules
scripts/patch-linux-window-ui.jsis the build-facing ASAR patcher CLI only. Do not import internals from it; use runner/helper APIs.- Core patch descriptors are the source of truth for shipped Linux
compatibility patches. Read
scripts/patches/core/README.mdbefore adding or moving descriptors. - ASAR patches are fail-soft unless intentionally marked
required-upstream. Each patch should be idempotent and report warnings when current upstream drift prevents a needle from matching. - Patch reports are written for installs/rebuilds. Upstream-build CI fails only for required upstream patches that are missing or skipped.
- Do not recreate deleted compatibility barrels such as
scripts/patches/main-process.js,webview-assets.js, orshared.js. - Feature patching uses only
entrypoints.patchDescriptors. Removed feature patch entrypoints such asmainBundlePatchandentrypoints.patchesare not supported. - Declarative feature
resources,runtimeHooks, andpackageHooksare preferred over ad hoc staging whenever possible. - Feature resource targets must stay inside the app directory and cannot target
the app root. Mode values must be quoted octal strings such as
"0644"or"0755".
Important Runtime Behavior
- DMG extraction can warn when
7zcannot materialize the/Applicationssymlink. This is acceptable if a.appbundle was extracted successfully. - The managed Node.js runtime is installed under
codex-app/resources/node-runtime/. IfCODEX_MANAGED_NODE_VERSIONorCODEX_MANAGED_NODE_URLis overridden,CODEX_MANAGED_NODE_SHA256must be set too. - GUI launchers often do not inherit shell
PATH. The generated launcher searches common Codex CLI andnvmlocations and respectsCODEX_CLI_PATH. - CLI preflight is launcher-scoped and best-effort. It can prompt to install or update the Codex CLI, but failures should warn rather than block app launch.
- The generated launcher starts the local webview server before Electron and verifies the expected startup markers. See webview server evaluation before changing the server model.
- Warm-start handoff uses a Unix-domain socket under
$XDG_RUNTIME_DIRso second launches can send actions to the running app. - Linux Computer Use plugin registration is default-on platform port glue, but Computer Use UI enablement remains opt-in and must not bypass upstream server-side rollouts unrelated to local Linux support.
- The Linux Chrome integration patches staged bundled resources. Do not fix only the user cache.
- Native package install/removal hooks start, stop, disable, and reload the
systemd --userupdater service on a best-effort basis. - Failed privileged updater installs stay failed until a newer rebuild or an explicit retry path; avoid auto-retrying every reconcile cycle.
- Manual rollback uses the last-known-good package recorded in updater state and the same format-specific command layer as normal installs.
Generated Artifacts
Treat these as generated or local runtime state, not primary source:
codex-app/, codex-app-next/, codex-*-app/, dist/,
dist/appimage.AppDir/, dist-next/rebuild/, target/, Codex.dmg,
linux-features/features.json, linux-features/local/,
codex-app/.codex-linux/linux-features-staged.json, updater config/state/log
files under ~/.config, ~/.local/state, and ~/.cache, launcher state under
~/.cache/codex-desktop and ~/.local/state/codex-desktop, and
$XDG_RUNTIME_DIR/codex-desktop/launch-action.sock.
See generated and runtime notes for details.
Common Commands
Regenerate the Linux app: ./install.sh ./Codex.dmg or ./install.sh.
Guided native setup/install/update: make setup-native,
make bootstrap-native, make install-native, make update-native.
Build native packages:
./scripts/build-deb.sh
./scripts/build-rpm.sh
./scripts/build-pacman.sh
./scripts/build-appimage.sh
Side-by-side rebuild candidate: ./scripts/rebuild-candidate.sh or
./scripts/rebuild-candidate.sh --install.
Runtime Expectations
python3,7z,curl,unzip,tar,make, andg++are required forinstall.sh.- Native package builders require their format-specific tools:
dpkg-deb,rpmbuild,makepkg/pacman tooling, orappimagetool. scripts/install-deps.shbootstraps common host dependencies. On apt-based systems,NODEJS_MAJOR=24 bash scripts/install-deps.shselects Node.js 24.- The packaged app still needs the Codex CLI at runtime, but launcher preflight attempts a best-effort install/update when possible.
Validation Matrix
Run the subset that matches the change; see the validation playbook for expanded checks.
bash -n install.sh
bash -n scripts/lib/*.sh
bash -n launcher/start.sh.template
bash -n scripts/build-deb.sh scripts/build-rpm.sh scripts/build-pacman.sh scripts/build-appimage.sh
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
Build the affected package formats when package payloads or shared package
logic changes. Run ./scripts/ci-local.sh pr or ./scripts/ci-local.sh all
for broad cross-format confidence.
Editing Guidance
- Keep native-package-only behavior in
packaging/linux/helpers and AppImage-only behavior inpackaging/appimage/helpers. - Keep all package builders aligned through
scripts/lib/package-common.shwhen adding or removing shared payload files. - Keep new core patch descriptors fail-soft and idempotent unless there is a
deliberate
required-upstreamCI policy. - Keep optional feature patches optional in CI and disabled by default.
- Add tests near the behavior being changed: patcher tests for ASAR needles, feature tests for Linux features, Rust tests for updater/MCP backends, and package smoke checks for payload/layout changes.
- When refreshing Nix hashes, use
scripts/ci/update-nix-hashes.sh; do not hand-edit SRI hashes inflake.nix.