Skip to content

[codex] Add experimental Codex app instances#5

Merged
Ducksss merged 8 commits into
mainfrom
pinzheng/experimental-app-instance
Jun 2, 2026
Merged

[codex] Add experimental Codex app instances#5
Ducksss merged 8 commits into
mainfrom
pinzheng/experimental-app-instance

Conversation

@Ducksss
Copy link
Copy Markdown
Owner

@Ducksss Ducksss commented May 28, 2026

Summary

  • Add experimental app-instance command for launching profile-specific Codex Desktop app clones without quitting existing Codex windows.
  • Isolate each instance with profile-local CODEX_HOME, Electron --user-data-dir, app-instance logs, and patched/re-signed app bundle metadata when macOS tooling is available.
  • Preserve Codex's CFBundleName for Electron helper lookup and launch clones through open -n -a <clone> <workspace> --args ... so workspace folders are opened as documents instead of being treated as Electron app paths.
  • Harden clone identity handling with collision-free profile encoding and automatic rebuilds for stale, missing, or malformed bundle metadata.
  • Refresh README branding with a scoped side-by-side Desktop screenshot, launch-mode guidance, isolation-boundary tables, a real multi-account origin story, and SECURITY.md alignment.
  • Add logs <profile> --instance, completions/help/docs, changelog notes, npm media packaging, and Bash test coverage.

Launch Flow

The normal Desktop command stays conservative:

codex-profile app dev ~/Dev/project-a

That flow treats Codex Desktop as one active profile at a time. It switches Desktop to the selected profile by quitting the currently running Codex app/app-server, then relaunching the canonical /Applications/Codex.app with CODEX_HOME pointed at the selected profile home.

The experimental multi-instance path is explicit:

codex-profile app-instance dev ~/Dev/project-a
codex-profile app-instance default ~/Dev/project-b

For each profile, app-instance creates or reuses a cloned app bundle under ~/Library/Application Support/codex-profile/app-instances/<profile>/, patches only the clone identity needed by macOS, keeps CFBundleName=Codex so Electron can still find Codex Helper.app, launches the workspace through open -n -a <clone> <workspace>, and passes profile-local Electron state with --user-data-dir=<profile-home>/electron-user-data.

README / Branding

  • Adds a README hero asset: "Two Codex Desktop Profiles, Same Mac".
  • Shows profile-scoped settings/account panels side by side with sensitive text blurred or redacted.
  • Adds a human motivation section: a school account with higher limits but no connectors, and a personal account with the connector access needed for email/outreach workflows.
  • Adds a codex-profile app versus codex-profile app-instance table so the expected launch flow is obvious from the Quick Start.
  • Adds an isolation-boundary table that separates profile-local Codex state from OS-level credentials that remain shared.
  • Tightens copy around the core promise: isolated Codex state, no token swapping, and explicit experimental parallel Desktop support.
  • Includes media/ in package.json so README-relative images ship with the npm package.

Review Hardening

  • Bundle identifiers now encode the raw profile name as hex, so valid profiles like client.a, client_a, client-a, and Client-A do not collapse to the same macOS identity.
  • Existing clones are rebuilt when critical metadata is missing, unreadable, stale, or no longer matches the selected profile's expected identifier/display name.
  • The test harness now models open -a <app> <workspace> --args ... more accurately by treating workspace folders as document files, not argv passed to the executable.
  • SECURITY.md now states that app-instance provides profile-level Desktop process isolation, not OS-level isolation.

Why a Separate Command

app and app-instance are intentionally different promises:

  • app is the predictable account-switching path: one Desktop process, one selected CODEX_HOME, no app bundle cloning.
  • app-instance is the experimental power-user path: profile-specific cloned bundles, separate Electron user data, and multiple Desktop processes at once.

Making codex-profile app dev or codex-profile app default implicitly spawn multiple Desktop instances would surprise existing users who expect app to switch the active Desktop profile. It would also mix the stable account-switching flow with the experimental clone flow, where app-server behavior, Electron helper lookup, macOS bundle metadata, and workspace launch semantics all matter.

Validation

  • bash test/codex-profile-test.sh
  • shellcheck bin/codex-profile test/codex-profile-test.sh
  • make test
  • make lint
  • npm pack --dry-run --json
  • git diff --check
  • Local visual review of media/codex-profile-parallel-instances.png
  • Local smoke: launched personal and work app instances simultaneously; both stayed running with distinct profile-local --user-data-dir paths.

Ducksss and others added 6 commits May 28, 2026 18:10
Summary:
- Encode app-instance bundle identifiers from the raw profile name so
  valid names with dots, underscores, hyphens, or case differences do
  not collapse to the same macOS bundle identifier.
- Rebuild existing app clones when required bundle metadata is missing,
  malformed, stale, or still using the previous non-unique identifier.
- Update the fake macOS launch harness so workspace document files stay
  separate from argv, matching the real open command more closely.

Rationale:
- Parallel Desktop instances depend on macOS seeing each cloned bundle
  as a distinct app. Non-unique identifiers can make distinct profiles
  fight over the same LaunchServices identity.
- Users should not need to know when an old or damaged clone needs
  --rebuild; the command can detect bad metadata and repair it.
- Tests should model the production launch boundary instead of passing
  document paths through argv and giving false confidence.

Tests:
- bash test/codex-profile-test.sh
- shellcheck bin/codex-profile test/codex-profile-test.sh
- make test
- git diff --check

Co-authored-by: Codex <codex@openai.com>
Summary:
- Add a polished README demo asset showing two profile-scoped Codex
  Desktop instances side by side.
- Refresh README positioning around isolated CODEX_HOME profiles and the
  experimental parallel Desktop workflow.
- Include media assets in the npm package file list so README images are
  packaged with the published artifact.

Rationale:
- The new app-instance feature needs a clearer visual story than command
  examples alone: two profiles, one Mac, no token swapping.
- The README should sell the feature while staying explicit that this is
  Codex state isolation, not full OS credential isolation.
- Existing README-relative media should not be omitted from npm package
  contents.

Tests:
- make test
- make lint
- npm pack --dry-run --json
- git diff --check

Co-authored-by: Codex <codex@openai.com>
Summary:
- Tighten the README demo section around the parallel Desktop hero image.
- Add launch-mode and isolation-boundary tables for app-instance.
- Mirror the experimental Desktop security boundary in SECURITY.md.

Rationale:
- Make the PR easier to review by explaining why app and app-instance stay
  separate and what each command guarantees.
- Keep the branding polished without overstating OS-level isolation.

Tests:
- git diff --check
- make lint
- npm pack --dry-run --json
- make test

Co-authored-by: Codex <codex@openai.com>
Summary:
- Add a README section explaining the real school/personal account workflow
  that motivated codex-profile.
- Note the changelog entry for the origin-story documentation.

Rationale:
- Make the project motivation concrete without encouraging token copying or
  overselling the isolation boundary.
- Explain why separate Codex homes and parallel Desktop profiles matter for
  accounts with different limits and connector access.

Tests:
- git diff --check
- make lint
- npm pack --dry-run --json
- make test

Co-authored-by: Codex <codex@openai.com>
@Ducksss Ducksss marked this pull request as ready for review June 2, 2026 09:09
Copilot AI review requested due to automatic review settings June 2, 2026 09:09
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an experimental multi-instance launch mode for Codex Desktop (app-instance) to support running multiple profile-isolated Desktop windows in parallel on macOS, alongside documentation, packaging, and test coverage updates.

Changes:

  • Introduces codex-profile app-instance <profile> to create/reuse a per-profile cloned Codex.app, patch bundle metadata, and launch with isolated Electron user data + instance logs.
  • Extends logs with --instance to read the new desktop-instance.log.
  • Updates README/SECURITY/CHANGELOG and npm packaging (ships media/), plus adds Bash test coverage for the new flow and completions/help output.

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
bin/codex-profile Adds app-instance, clone/metadata helpers, logs --instance, and completion updates.
test/codex-profile-test.sh Adds fake macOS tooling + new tests covering parallel instance launches, clone rebuild logic, and logs/completions output.
README.md Documents the new experimental parallel Desktop workflow, isolation boundaries, and includes media assets.
SECURITY.md Clarifies that app-instance is profile-level Desktop isolation, not OS-level isolation.
CHANGELOG.md Notes the new command/features, tests, and related fixes.
package.json Updates description and includes media/ in the published files list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/codex-profile-test.sh
Ducksss and others added 2 commits June 2, 2026 16:15
Summary:
- Merge current main into the app-instance PR branch.
- Resolve the test runner conflict by keeping main\s forced-quit app test
  and the branch app-instance tests.

Rationale:
- Clear the PR merge conflict while preserving regression coverage from both
  branches.
- Keep the branch aligned with main\s updated Desktop app quit behavior.

Tests:
- git diff --check
- make lint
- npm pack --dry-run --json
- make test

Co-authored-by: Codex <codex@openai.com>
Summary:
- Teach the fake plutil helper to extract arbitrary plist keys, not only
  CFBundleName.
- Add coverage proving compatible existing app-instance clones are reused
  instead of being rebuilt.

Rationale:
- Match the macOS plutil behavior used by app-instance metadata validation.
- Prevent tests from masking bundle identifier or display name validation bugs.

Tests:
- git diff --check
- make lint
- npm pack --dry-run --json
- make test

Co-authored-by: Codex <codex@openai.com>
@Ducksss Ducksss merged commit 55e41e5 into main Jun 2, 2026
2 checks passed
@Ducksss Ducksss deleted the pinzheng/experimental-app-instance branch June 2, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants