{"id":49885583,"url":"https://github.com/marcel2215/codex-switcher-app","last_synced_at":"2026-05-15T18:12:41.975Z","repository":{"id":353219673,"uuid":"1202954242","full_name":"marcel2215/codex-switcher-app","owner":"marcel2215","description":"A macOS SwiftUI app for quickly switching between OpenAI Codex accounts.","archived":false,"fork":false,"pushed_at":"2026-05-15T14:37:16.000Z","size":3574,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-15T16:33:11.680Z","etag":null,"topics":["account","accounts","agnet","app","chatgpt","codex","ios","macos","manager","multiple","openai","profile","profiles","swift","swiftui","switch","switcher","tool","utility","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcel2215.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-06T15:16:20.000Z","updated_at":"2026-05-15T14:37:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marcel2215/codex-switcher-app","commit_stats":null,"previous_names":["marcel2215/codex-switcher-app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marcel2215/codex-switcher-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcel2215%2Fcodex-switcher-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcel2215%2Fcodex-switcher-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcel2215%2Fcodex-switcher-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcel2215%2Fcodex-switcher-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcel2215","download_url":"https://codeload.github.com/marcel2215/codex-switcher-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcel2215%2Fcodex-switcher-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33074524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["account","accounts","agnet","app","chatgpt","codex","ios","macos","manager","multiple","openai","profile","profiles","swift","swiftui","switch","switcher","tool","utility","watchos"],"created_at":"2026-05-15T18:12:41.057Z","updated_at":"2026-05-15T18:12:41.965Z","avatar_url":"https://github.com/marcel2215.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Codex Switcher\n\nCodex Switcher is a native SwiftUI account manager for Codex on **macOS**, with synced companion apps for **iPhone** and **Apple Watch**.\n\nThe app turns Codex's single live `auth.json` login into a managed library of saved accounts. On the Mac it can capture a file-backed Codex auth snapshot, store it safely, restore another saved snapshot, track 5-hour and 7-day rate-limit headroom, and expose account switching through the main window, menu bar, Dock, widgets, controls, and App Intents.\n\n\u003e [!IMPORTANT]\n\u003e Codex Switcher switches accounts by rewriting a file-backed Codex `auth.json`. It intentionally refuses to switch a linked Codex folder that is configured for `keyring` or `auto` credential storage because those modes do not give the app an authoritative `auth.json` file to restore safely.\n\n\u003e [!IMPORTANT]\n\u003e Actual Codex account switching is a **macOS responsibility**. The iPhone and Apple Watch apps are companions for synced account management, rate-limit viewing/refresh, widgets, complications, and archive import/export. They do not directly rewrite a desktop Codex installation.\n\n---\n\n## Quick start\n\n1. Open the **macOS** app.\n2. In **Settings → Codex Folder**, select the `.codex` folder that Codex uses for `auth.json` and `config.toml`.\n3. Make sure the linked Codex folder is file-backed. In `config.toml`, this means either no `cli_auth_credentials_store` setting or:\n\n   ```toml\n   cli_auth_credentials_store = \"file\"\n   ```\n\n4. Press **Add Account**.\n   - If the linked folder currently contains a new or recoverable `auth.json`, Codex Switcher captures it.\n   - Otherwise the app starts a browser sign-in flow and imports the resulting ChatGPT/Codex auth snapshot as a saved account.\n5. Repeat for the accounts you want to keep.\n6. Rename accounts, choose icons, pin favorites, and choose a sort order.\n7. Use **Log In** from the main window, menu bar, Dock menu, widget, control, or Shortcuts/App Intents to restore a saved account.\n\nWhen Codex is already running as a desktop app, Codex Switcher may show **“Account change pending. Restart Codex.”** after a switch. Restart Codex so it reloads the replaced `auth.json`.\n\n---\n\n## Platform roles\n\n| Platform | Role | What it can do |\n| --- | --- | --- |\n| macOS | Authoritative switcher | Link a Codex folder, read/write `auth.json`, capture accounts, switch accounts, run Autopilot, expose menu bar/Dock/widgets/controls/App Intents. |\n| iPhone | Synced companion | Browse and manage synced accounts, import/export `.cxa` archives, refresh rate limits, show Home/Lock Screen widgets, use Home Screen quick actions. |\n| Apple Watch | Lightweight companion | Browse, search, rename, choose icons, remove accounts, refresh rate limits, and show complications. |\n\nThe shared data model is designed so the companion apps stay useful even when a full secret snapshot has not arrived on that device yet. In that case, the UI can still show account metadata while export, live-refresh, or Mac extension-switching surfaces report that a local snapshot is missing.\n\n---\n\n## What the app does\n\n### Account library\n\n- Saves Codex accounts as named records with icons.\n- Supports ChatGPT-backed auth, ChatGPT token payloads, and API-key auth payloads.\n- Searches by account name, email hint, or account identifier.\n- Sorts by **Name**, **Date Added**, **Last Login**, **Rate Limit**, or **Custom** order.\n- Keeps pinned accounts above unpinned accounts while preserving each lane's custom order.\n- Supports up to **1000** saved accounts.\n- Marks invalidated accounts as **Unavailable** instead of silently using a stale refresh token.\n\n### Adding accounts\n\nThe macOS **Add Account** action has two paths:\n\n1. **Capture current `auth.json`** — if the linked Codex folder contains a valid, new, or recoverable file-backed account, the app saves that snapshot.\n2. **Browser sign-in import** — if there is no usable current snapshot, or the current snapshot is already saved, the app opens an OpenAI/Codex browser sign-in flow. The OAuth callback is handled on a local loopback server, then the app builds a file-backed `auth.json`-style snapshot and imports it.\n\nThe browser sign-in path is useful when Codex is logged out, when the linked folder is missing `auth.json`, or when you want to add an account without first manually switching Codex to it. After importing through browser sign-in, select the saved account and choose **Log In** to write it to the linked Codex folder.\n\n### Switching accounts\n\nSwitching restores the selected account's saved snapshot into the linked Codex folder as `auth.json`.\n\nThe switch code is defensive:\n\n- It only runs when the linked folder is reachable and file-backed.\n- It loads the saved snapshot from Keychain.\n- It normalizes legacy ChatGPT token payloads into the current Codex runtime shape before restore.\n- It writes through coordinated file operations.\n- It uses an atomic replacement helper and applies restrictive `0600` permissions.\n- It immediately reads the file back and verifies the identity key.\n- It preserves the account you are switching away from when that live snapshot maps to a saved account.\n- Shared extension switching uses an App Group process lock so widgets/controls do not race each other.\n\n### “None” account\n\nWhen **Show “None” Account** is enabled, the Mac list includes a local logout row. Choosing it deletes the linked `auth.json` instead of writing another account. It is useful for intentionally leaving Codex logged out.\n\n### Account details\n\nAccount detail views on macOS, iPhone, and Apple Watch show account metadata, last login, availability, and stored 5-hour/7-day rate-limit information. On Mac and iPhone, detail views can also export or share a `.cxa` account archive when the full snapshot is available locally.\n\n---\n\n## Auth support\n\nCodex Switcher parses these `auth.json` auth modes:\n\n- `apiKey`\n- `chatgpt`\n- `chatgptAuthTokens`\n\nThe linked folder's `config.toml` credential-store hint controls whether switching is allowed:\n\n| `cli_auth_credentials_store` value | Switching support |\n| --- | --- |\n| `file` | Supported. |\n| missing / unknown | Allowed as potentially file-backed. |\n| `keyring` | Unsupported. |\n| `auto` | Unsupported. |\n\nAPI-key accounts can be captured, named, exported, imported, and restored. They cannot fetch live ChatGPT usage/rate-limit data because the live rate-limit request requires ChatGPT access-token credentials.\n\n### Unavailable accounts\n\nA saved account can become unavailable when its refresh token is revoked, expired, reused, mismatched, missing, or when the saved snapshot is corrupted. The app then zeros the cached rate-limit display, marks the account unavailable, and prevents accidental switching.\n\nTo recover, add/sign in to that account again. Avoid using Codex's own **Log out** button for accounts you want Codex Switcher to preserve, because that can invalidate the refresh token backing the saved snapshot.\n\n---\n\n## Rate limits\n\nCodex Switcher tracks the remaining **5-hour** and **7-day** Codex windows.\n\nRate-limit refresh uses multiple sources:\n\n- **Remote live refresh** for ChatGPT-backed accounts with a synced access token.\n- **macOS session-log fallback** for the currently active account when live refresh is unavailable but recent Codex session telemetry exists in the linked folder.\n- **Local reset normalization** so stored values return to `100%` when a known reset time has passed.\n\nStored rate-limit values carry a data status:\n\n| Status | Meaning |\n| --- | --- |\n| `exact` | Fresh live or directly observed value. |\n| `cached` | Previously known value that is being kept until a better one arrives. |\n| `missing` | No useful value is known yet. |\n| `unavailable` | The account cannot currently provide rate-limit data, often because credentials are invalid. |\n\nThe best-account ranking used by rate-limit sort, Autopilot, and “Switch to Best” requires both 5-hour and 7-day values. It prioritizes the account with the strongest worst-window headroom, then the strongest remaining window.\n\n---\n\n## Autopilot and automation\n\nmacOS settings include three automation toggles:\n\n| Setting | Behavior |\n| --- | --- |\n| **Automatically Add Accounts** | Watches the linked `auth.json`; when Codex changes to a new file-backed account, the app captures it automatically. |\n| **Automatically Remove Accounts** | Removes accounts that become authoritatively unavailable. |\n| **Automatically Switch Accounts** | Runs Autopilot in the background and switches to the account with the most remaining 5-hour/7-day headroom. |\n\nAutopilot refreshes accounts before ranking them, prefers accounts with local snapshots, ignores unavailable accounts, and does not switch when the active account is already the best candidate. It also reacts to launch, app focus, system wake, and quiet periods after Codex session activity. Periodic unattended timers are skipped while the Mac is sleeping or screens are sleeping; Low Power Mode or critically low battery pauses only the periodic timer path, not explicit user/system triggers.\n\n---\n\n## Notifications\n\nmacOS, iPhone, and Apple Watch share rate-limit reset notification preferences. The Mac also has account-switch notifications.\n\nAvailable notification preferences:\n\n- **Account Switch** on macOS.\n- **5-Hour Limit Reset**.\n- **7-Day Limit Reset**.\n\nReset notifications are scheduled only for accounts with exact known reset dates, are prioritized for the current account and pinned accounts, and are capped so the app does not flood Notification Center with stale requests.\n\n---\n\n## Widgets, controls, complications, and shortcuts\n\n### macOS widgets and controls\n\n- **Current Account** widget — shows the account currently active in the linked Codex folder and important setup/error states.\n- **Saved Account** widget — shows one configured saved account and can switch to it.\n- **Rate Limits** widget — shows selected or automatically chosen accounts with 5-hour/7-day headroom.\n- **Open Codex Switcher** control — opens the app.\n- **Switch Codex Account** control — shows which configured account is active and switches when turned on.\n\n### iPhone widgets and quick actions\n\n- **Rate Limits** Home Screen widget.\n- **Rate Limit** Lock Screen accessory widget.\n- Home Screen quick actions for the first accounts in the app's current sort order.\n- Background App Refresh for rotating batches of rate-limit refresh work.\n\n### Apple Watch complications\n\n- **Rate Limit** complication.\n- **Open Codex Switcher** complication.\n\n### App Intents and Shortcuts\n\nThe Mac app owns intents that need app-owned mutations, security-scoped folder access, or durable command results. Shared/widget intents use the App Group state snapshot.\n\nImplemented intents include:\n\n- Open Codex Switcher.\n- Add Current Codex Account.\n- Get Selected Codex Account.\n- Get Current Codex Account.\n- Get Current / Account / Best Codex Rate Limits.\n- Get All Codex Accounts.\n- Get Best Codex Account.\n- Find Codex Account / Find Codex Accounts.\n- Switch Codex Account.\n- Switch to Best Codex Account.\n- Remove Codex Account.\n- Quit Codex Switcher.\n- Toggle notifications, menu bar visibility, Launch at Login, and automatic switching settings.\n\nThe app also contains conditional Spotlight indexing support for accounts when built with the `CODEX_ACCOUNT_SPOTLIGHT` flag.\n\n---\n\n## Sync, storage, and security model\n\nCodex Switcher separates metadata from secrets.\n\n### Synced metadata\n\nAccount rows are stored with SwiftData and CloudKit in the private iCloud container:\n\n```text\niCloud.com.marcel2215.codexswitcher\n```\n\nThe synced metadata includes account name, icon, identity key, auth mode, email/account hints, ordering, pinned state, last login, availability, and cached rate-limit display fields. Full `auth.json` snapshots are migrated out of the SwiftData/CloudKit model and kept in Keychain instead.\n\n### Secret snapshots\n\nFull auth snapshots are stored in Keychain under the shared access group configured by the project:\n\n```text\n$(AppIdentifierPrefix)group.com.marcel2215.codexswitcher\n```\n\nThe snapshot store keeps:\n\n- a device-local shared Keychain copy for fast local access, and\n- a synchronizable iCloud Keychain copy when available.\n\nReads prefer the local shared copy, then fall back to the synchronizable copy, and repair missing copies when possible. A separate local availability file records whether this device currently has a usable snapshot for an account.\n\n### Rate-limit credentials\n\nFor live rate-limit refresh, the app stores a narrow synchronizable Keychain payload containing only the identity key, auth mode, optional ChatGPT account ID, access token, and export timestamp. It deliberately does not duplicate the full `auth.json` just to refresh widgets or companion devices.\n\n### App Group shared state\n\nWidgets, controls, and intents read a portable JSON snapshot from the App Group:\n\n```text\ngroup.com.marcel2215.codexswitcher\n```\n\nImportant App Group files include:\n\n| File | Purpose |\n| --- | --- |\n| `SharedCodexState.json` | Current account, auth state, and display-safe account records for extensions. |\n| `LocalSnapshotAvailability.json` | Per-device snapshot availability. |\n| `LinkedCodexFolderShared.bookmark` | Shared bookmark for the linked Codex folder. |\n| `PendingCodexAppCommands.json` | Durable command queue for app-owned work requested by intents/extensions. |\n| `PendingCodexAppCommandResults.json` | Results for intents waiting on app-owned mutations. |\n| `PendingCodexAccountOpenRequest.json` | Requests to open the app to a specific account. |\n| `CodexAccountSwitch.lock` | Cross-process lock used during shared switching. |\n\nShared JSON files are written atomically with sorted keys, and corrupt shared files are quarantined rather than reused.\n\n### Account archives\n\n`.cxa` files are portable account archives. Current archives use a compressed binary property-list container with the exported UTI:\n\n```text\ncom.marcel2215.codexswitcher.account-archive-binary\n```\n\nThe app can still import legacy `.cxa` archives with the older UTI:\n\n```text\ncom.marcel2215.codexswitcher.account-archive\n```\n\nArchives may contain one or many accounts. Each archived account can include metadata, icon, identity information, cached rate limits, a synced rate-limit credential, and the full auth snapshot.\n\n\u003e [!CAUTION]\n\u003e `.cxa` archives contain secret auth material when export succeeds. The archive format is compressed/opaque, not encrypted. Treat exported archives like credentials.\n\n---\n\n## macOS UI and behavior\n\nThe macOS app includes:\n\n- Main account list with search, pinning, custom icons, drag reordering, and sort controls.\n- Account detail windows with metadata, rate limits, export/share, pin/unpin, and removal actions.\n- Menu bar extra with current account, quick switching, account info, add account, open app, and quit.\n- Dock menu with up to five immediately switchable accounts in the current app sort order.\n- Launch at Login support.\n- Single-instance coordination that asks older app instances to quit when a newer instance launches.\n- Settings sections for Codex folder, general preferences, Autopilot, menu bar, notifications, support links, and destructive reset/remove-all actions.\n\nKeyboard/menu highlights:\n\n- `⌘N` — Add Account.\n- `⌘O` — Import `.cxa` archive.\n- `⌘C` / `⌘V` — Copy/paste account archives.\n- `⌘R` — Refresh.\n- `⌘I` — Get Info.\n- `⌘L` — Log In to selected account.\n- `⌘P` — Pin/unpin selected account.\n- `Delete` — Remove selected account.\n- `⌘Q` — hide to menu bar when the menu bar extra/background residency is enabled; otherwise quit.\n- `⌥⌘Q` — quit when the primary quit action hides to menu bar.\n\n---\n\n## iPhone app behavior\n\nThe iPhone app is a companion account browser and rate-limit surface.\n\nIt supports:\n\n- Synced account list and detail views.\n- Search, sort, custom ordering, pinning, rename, icon selection, and removal.\n- `.cxa` import from Files/share flows and export from account detail views when a snapshot exists locally.\n- Cached and live rate-limit display.\n- Background App Refresh with rotating batches of tracked accounts.\n- Home Screen quick actions based on the current app sort order.\n- Reset notification settings and support links.\n\nIf an account exists in CloudKit but its snapshot has not arrived through iCloud Keychain, the iPhone UI can still show the account but export/live refresh may be unavailable until Keychain sync completes.\n\n---\n\n## Apple Watch behavior\n\nThe Apple Watch app focuses on small-screen account management:\n\n- Synced account list.\n- Search and sort.\n- Account detail views with rate limits and last-login metadata.\n- Rename, icon selection, and removal.\n- Pull/foreground refresh of rate limits.\n- Settings with version and remove-all action.\n- Complications for one-account rate-limit display and app launching.\n\nWatch copy explicitly distinguishes between accounts waiting for iCloud Keychain sync and API-key accounts, where live rate-limit refresh is not available.\n\n---\n\n## Build from source\n\n### Requirements\n\nThe checked-in Xcode project currently declares:\n\n| Setting | Value |\n| --- | --- |\n| Swift | 6.0 |\n| macOS deployment target | 26.0 for app/widget targets; one macOS test configuration also declares 26.4. |\n| iOS deployment target | 26.0 |\n| watchOS deployment target | 26.0 |\n| Marketing version | 1.0 |\n| Build number | 1 |\n\nUse an Xcode version that includes the SDKs needed by those deployment targets.\n\n### Schemes and targets\n\nShared schemes are checked in under `CodexSwitcher.xcodeproj/xcshareddata/xcschemes`:\n\n| Scheme / target | Purpose |\n| --- | --- |\n| `CodexSwitcherMacApp` | macOS app, product name “Codex Switcher”. |\n| `CodexSwitcher` | iPhone app. |\n| `CodexSwitcherWatchApp` | Apple Watch app. |\n| `CodexSwitcherMacWidgets` | macOS widgets and controls. |\n| `CodexSwitcherWidgets` | iPhone widgets. |\n| `CodexSwitcherWatchWidgets` | watchOS widgets/complications. |\n| `CodexSwitcherMacTests`, `CodexSwitcherMacUITests` | macOS tests. |\n| `CodexSwitcherTests`, `CodexSwitcherUITests` | iPhone tests. |\n| `CodexSwitcherWatchTests`, `CodexSwitcherWatchUITests` | watchOS tests. |\n\n### Signing and capabilities\n\nThe repository is configured for the original bundle IDs and Team ID. A fork or local build usually needs updated signing across every app, widget, watch, test, App Group, Keychain, and iCloud entitlement.\n\nCurrent identifiers in the project include:\n\n| Capability / ID | Current value |\n| --- | --- |\n| Main app bundle ID | `com.marcel2215.codexswitcher` |\n| Watch app bundle ID | `com.marcel2215.codexswitcher.watchkitapp` |\n| App Group | `group.com.marcel2215.codexswitcher` |\n| CloudKit container | `iCloud.com.marcel2215.codexswitcher` |\n| Keychain access group | `$(AppIdentifierPrefix)group.com.marcel2215.codexswitcher` |\n| Widget extension bundle IDs | `com.marcel2215.codexswitcher.widgets`, `com.marcel2215.codexswitcher.watchkitapp.widgets` |\n\nmacOS app entitlements include sandboxing, user-selected read/write file access, app-scoped security bookmarks, App Group access, CloudKit/iCloud document support, network client/server access for the local OAuth callback, and shared Keychain access.\n\n### Local build steps\n\n1. Open `CodexSwitcher.xcodeproj` in Xcode.\n2. Select your development team for every app, widget, watch, and test target.\n3. Update bundle IDs, App Group, iCloud container, and Keychain access group if you are not building with the original identifiers.\n4. Build and run `CodexSwitcherMacApp` first.\n5. Link the `.codex` folder in macOS Settings.\n6. Build/run the iPhone and watch apps after the Mac app is working and iCloud/Keychain capabilities are configured.\n\n---\n\n## Repository structure\n\n```text\nCodexSwitcher.xcodeproj/        Xcode project and shared schemes\nCodexSwitcherApp/               iPhone app plus shared cross-platform models, stores, intents, widgets support, and services\nCodexSwitcherMacApp/            macOS app, controllers, views, file access, OAuth sign-in, menu bar/Dock behavior\nCodexSwitcherWatchApp/          Apple Watch app views and bootstrap\nCodexSwitcherWidgets/           iPhone WidgetKit extension\nCodexSwitcherMacWidgets/        macOS widgets and control widgets\nCodexSwitcherWatchWidgets/      watchOS complications/widgets\nCodexSwitcherTests/             iPhone/shared unit tests\nCodexSwitcherMacTests/          macOS unit tests\nCodexSwitcherWatchTests/        watchOS unit tests\nCodexSwitcherUITests/           iPhone UI tests\nCodexSwitcherMacUITests/        macOS UI tests\nCodexSwitcherWatchUITests/      watchOS UI tests\n```\n\n---\n\n## Test coverage highlights\n\nThe test suite covers the main behaviors that make the app safer than a raw file replacer, including:\n\n- `auth.json` parsing for ChatGPT and API-key payloads.\n- Stable identity-key derivation.\n- Account capture, duplicate prevention, recovery of unavailable accounts, and browser-login import behavior.\n- Safe switching, skipped rewrites, legacy OAuth snapshot normalization, and “None” account deletion.\n- Automatic add/remove/switch behavior.\n- Rate-limit refresh, backoff, unauthorized handling, background refresh batches, and notification scheduling.\n- Cloud/Keychain migration and local snapshot availability repair.\n- `.cxa` archive round trips, multi-account archives, compressed container encoding, legacy archive import, filenames, and synced rate-limit credential export.\n- Shared app command queues, pending account-open requests, widget/control switch behavior, Dock menus, menu bar state, and single-instance coordination.\n- Basic UI launch and state tests for macOS, iPhone, and watchOS.\n\nRun the appropriate Xcode test schemes for the platform you are changing.\n\n---\n\n## Troubleshooting\n\n### “Link Codex Folder”\n\nThe Mac app does not have a linked folder yet. Choose the `.codex` folder that contains Codex's `auth.json` and `config.toml`.\n\n### “No auth.json”\n\nCodex may be logged out, using a different `CODEX_HOME`, or using non-file credential storage. Add Account can still open the browser sign-in flow, but switching the linked folder requires a file-backed setup.\n\n### “Unsupported Credential Store”\n\nThe linked folder's `config.toml` advertises `keyring` or `auto`. Change Codex to file-backed credential storage if you want Codex Switcher to restore saved snapshots into that folder.\n\n### “Permission Needed” or “Codex Folder Missing”\n\nThe security-scoped bookmark is stale, the folder moved, or the app lost access. Re-select the Codex folder in Settings.\n\n### “Invalid auth.json”\n\nThe linked file is not valid UTF-8 JSON or does not contain a supported Codex auth payload. Fix Codex's auth file or use Add Account's browser sign-in flow.\n\n### Account is unavailable\n\nThe saved refresh token or snapshot is no longer usable. Remove the account or sign in/add it again to replace the snapshot.\n\n### Widgets show setup or stale states\n\nWidgets read `SharedCodexState.json` from the App Group. Open the Mac app, refresh, and confirm the linked folder and shared App Group/Keychain capabilities are valid.\n\n### iPhone or Watch cannot export an account\n\nThe account metadata may have synced through CloudKit before the full snapshot arrived through iCloud Keychain. Leave iCloud Keychain enabled and allow sync to complete, or export from a Mac that has the local snapshot.\n\n### API-key account has no live rate limits\n\nAPI-key accounts can be switched, but live ChatGPT usage refresh needs a ChatGPT access token. The UI may show cached/missing rate-limit data for API-key accounts.\n\n### Autopilot is not switching\n\nCheck that:\n\n- Automatically Switch Accounts is enabled.\n- The Mac app can access the linked folder.\n- The linked folder is file-backed.\n- Candidate accounts have local snapshots on this Mac.\n- Candidate accounts are not unavailable.\n- Both 5-hour and 7-day rate-limit values are known for ranking.\n- The current account is not already the best candidate.\n\n### Account change pending\n\nIf Codex was running during a switch, restart Codex so it reloads `auth.json`.\n\n---\n\n## Support links\n\nThe app exposes these support links in Settings:\n\n- Website: `https://codexswitcher.marcel2215.com`\n- Source code: `https://github.com/marcel2215/codex-switcher-app`\n- Contact: `marcel2215@icloud.com`\n- Terms of Service: `https://codexswitcher.marcel2215.com/terms-of-service`\n- Privacy Policy: `https://codexswitcher.marcel2215.com/privacy-policy`\n\n---\n\n## Practical summary\n\nCodex Switcher is a multi-platform SwiftUI app that safely manages file-backed Codex `auth.json` identities on macOS, syncs a usable account library across Apple devices, tracks rate-limit headroom, and exposes the system through widgets, controls, watch complications, notifications, and App Intents.\n\nUse it when you want fast, verified switching between saved Codex accounts. Avoid using it as a switcher for Codex setups that rely on `keyring` or `auto` credential stores, because the app is intentionally built around safe control of file-backed `auth.json`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcel2215%2Fcodex-switcher-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcel2215%2Fcodex-switcher-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcel2215%2Fcodex-switcher-app/lists"}