Codexer is a native macOS profile manager for running multiple isolated instances of the OpenAI Codex desktop app at the same time. It is built for the common personal/work-account case: create a profile for each account, launch Codex from that profile, and optionally install a Dock-pinnable shortcut for quick access.
Codexer does not modify /Applications/Codex.app, ~/.codex, or existing Codex
authentication files. Each profile gets its own local state directory.
- Add and remove Codex profiles from a SwiftUI macOS app.
- Launch multiple Codex instances side by side with separate state.
- See whether each profile is running, focus its existing instance, and close only that profile without quitting the stock app or another profile.
- View per-profile session totals, weekly activity, Codex usage-limit windows, job status, log warnings/errors, last activity, and local storage use.
- Install profile-specific
.appshortcuts in~/Applications/Codexer/. - Use native
arm64shortcut launchers, avoiding Rosetta prompts. - Remove shortcuts without deleting profile data.
- Remove a profile from Codexer while preserving its data.
- Delete profile data only through a separate destructive confirmation.
- Restore a previously removed profile from Codexer's managed Profiles folder.
- Reject unsigned, modified, or incorrectly signed Codex app bundles.
Codexer asks macOS to create a new instance of the official signed Codex app with profile-specific environment and arguments equivalent to:
CODEX_HOME=<profile>/CODEX_HOME \
open -n /Applications/Codex.app \
--args --user-data-dir=<profile>/ElectronUserDataThis isolates:
- Codex CLI/app-server config and auth state through
CODEX_HOME. - Electron/browser state through
--user-data-dir. - Local profile data under Codexer-owned folders.
Codexer intentionally does not override HOME, so Codex agents can still use
your normal shell, git config, SSH keys, project files, and developer tools.
Codexer maps each managed ElectronUserData path to the exact main-app PID.
Opening a running profile focuses that PID instead of creating a duplicate.
Closing a profile sends a graceful termination request only to the PID or PIDs
whose command line contains that exact profile path. The stock app, other
profiles, and Electron helper processes do not match. Immediately before focus
or termination, Codexer re-verifies the official bundle, executable, PID, and
profile argument.
Open, Close, shortcut changes, and destructive deletion share a per-profile cross-process lock. This prevents two launchers from opening the same Electron directory at once and prevents launch or shortcut operations from racing deletion. Shortcut configurations are also bound to the profile's ownership marker.
Codexer stores profile metadata here:
~/Library/Application Support/Codexer/profiles.json
Each profile stores isolated state here:
~/Library/Application Support/Codexer/Profiles/<profile-slug>/
CODEX_HOME/
ElectronUserData/
New profile shortcuts use a stable, path-safe profile slug and are installed here:
~/Applications/Codexer/<profile-slug>.app
Duplicate names receive numbered slugs, such as personal.app and
personal-2.app. Renaming a profile does not move its state or shortcut.
Installed shortcuts are real macOS .app bundles. Each shortcut contains:
Contents/MacOS/CodexerShortcutLauncher: a native Swift launcher executable.Contents/Resources/ShortcutConfig.plist: the profile-specific launch paths.Contents/Info.plist: profile-specific bundle name and display name.Contents/Resources/ProfileIcon.icns: a generated profile-color icon.
The shortcut's displayed name uses the profile name. Its stable filename uses
the profile slug. For example, a profile named Work Account installs as:
~/Applications/Codexer/work-account.app
The running OpenAI Codex window and Dock icon still identify themselves as the official app. A shortcut can have a profile-specific Finder, Spotlight, and Launchpad name, but once it launches the official signed app, macOS uses the official app's runtime identity. Giving the running instance a different name would require copying and modifying the official bundle, invalidating its signature and complicating updates. Codexer therefore uses named profiles and PID-scoped Open/Focus/Close controls instead.
Both direct launches and generated shortcuts verify the app's bundle identity and OpenAI signing team before launch.
- macOS 13 or newer.
- Swift 5.9 or newer.
- The official Codex desktop app installed at
/Applications/Codex.app.
If Codex is installed elsewhere, use the app's Select Codex.app action to
point Codexer at the correct bundle.
Build and launch the app bundle:
./script/build_and_run.shBuild, launch, and verify the process exists:
./script/build_and_run.sh --verifyThe generated app bundle is written to:
dist/Codexer.app
The Codex desktop Run action is configured in:
.codex/environments/environment.toml
Run the test suite:
swift testRun the installed-app lifecycle test, which opens and closes a temporary isolated profile:
CODEXER_LIVE_LIFECYCLE=1 swift test \
--filter CodexLauncherTests/testLiveProfileCanOpenAndCloseWithoutTouchingStockInstanceRun a normal SwiftPM build:
swift buildCurrent test coverage includes:
- Profile creation and duplicate slug handling.
- Persisted-path, ownership-marker, and directory-containment validation.
- Rename behavior that keeps profile paths stable.
- Safe profile removal that preserves data by default.
- Transactional destructive deletion and refusal while a profile is in use.
- Read-only profile status scanning from Codex state/log databases.
- Bounded output and timeout handling for external status processes.
- Codex usage-limit parsing for 5-hour and weekly windows from the profile's authenticated Codex app-server.
- Isolated launch generation across 100 simultaneous profile configurations.
- Exact PID discovery, focus-without-duplicate, and profile-scoped close.
- Opt-in live Open/Close verification against the installed official app.
- Validation of the installed official Codex app's code signature.
- Native, atomically replaced shortcut bundle generation.
- Shortcut removal without deleting profile data.
Package.swift
Assets/
AppIcon.png Generated Codexer app icon source
AppIcon.icns macOS app icon used by the app bundle
Sources/
Codexer/ SwiftUI macOS app
CodexerCore/ Profile, launcher, and shortcut logic
CodexerShortcutLauncher/ Native helper copied into generated shortcuts
Tests/
CodexerCoreTests/ Unit tests for core behavior
script/
build_app.sh Build dist/Codexer.app without launching it
build_and_run.sh Build, bundle, launch, and verify helper
package_app.sh Create shareable ZIP and DMG packages
.github/workflows/
release.yml Build/test/package workflow and tagged releases
Create local shareable packages from an existing app bundle:
./script/build_app.sh
./script/package_app.shThe package script writes:
dist/Codexer-<version>.zip
dist/Codexer-<version>.dmg
GitHub Actions builds and tests the app on pushes and pull requests. Pushing a
tag that starts with v creates a GitHub Release and uploads the generated ZIP
and DMG:
git tag v1.0.0
git push origin v1.0.0- Launch Codexer.
- Click
Add Profile. - Enter a profile name such as
PersonalorWork. - Select the profile and click
Open. The action becomesFocuswhile that profile is running. - Sign into the desired Codex account inside that launched instance.
- Click
Install Shortcutto create a Dock-pinnable launcher. - Repeat for additional accounts.
Use Close to quit only the selected profile. Closing a profile quits all
Codex windows belonging to that profile so its Electron state can shut down
cleanly.
To remove a profile safely, use Remove From List. This removes the profile
from Codexer but leaves its data on disk. Use Delete Data only when you want to
remove the profile's login state, Codex state, Electron data, and shortcut. Quit
that profile's Codex instance first; deletion fails closed if any process is
still using its directory.
Restore accepts only an unlisted direct child of Codexer's managed Profiles folder. It does not import arbitrary folders or accept paths that overlap an active profile.
- Codexer relies on Codex continuing to honor
CODEX_HOMEand--user-data-dir. - Isolation covers Codex configuration/authentication state and Electron user data. It is not an operating-system sandbox: instances retain access to the user's files, shell environment, network, keychain, git, and SSH credentials.
- Existing generated shortcuts should be reinstalled after changes to shortcut naming or launcher behavior. Shortcuts created before profile identity was added to their configuration must be reinstalled before they can launch.
- Codexer does not copy OAuth tokens between profiles. Each profile signs in independently.
- Codexer is not an OpenAI product and does not redistribute the Codex app.
Codexer's lifecycle design was checked against several open-source profile and process managers:
- ai-profiles launches isolated Codex profiles and documents the same signed-app Dock identity limitation.
- codex-multi-launcher and
codex-multi-profile-launcher
use separate
CODEX_HOMEand Electron data paths for account isolation. - Signal Desktop Manager tracks profile processes for explicit launch and stop controls.
- PowerSpaces uses PID-targeted macOS activation and graceful termination rather than broad application-name matching.
Codexer combines those patterns with official-bundle signature validation and exact profile-path-to-PID matching.