codexsyncd is a native Rust CLI that selects the best available Codex login state from CodexBar's managed Codex homes and writes it to ~/.codex/auth.json.
It does not patch Codex, run a proxy, or hot-swap an already running Codex TUI. It only changes the auth file on disk, so the main effect is on the next Codex process that reads that file.
It also does not require the CodexBar app process to stay running. After CodexBar has created the local managed account files, codexsyncd reads those files directly and refreshes usage with the stored OAuth state, so you can rotate accounts without keeping CodexBar open just for background polling.
- Reads CodexBar's managed account list.
- Loads each managed home's
auth.json. - Fetches live Codex usage from ChatGPT's WHAM usage API with that account's OAuth token.
- Refreshes the OAuth token when it is close to expiry or already expired.
- Chooses the best candidate by:
- highest
remaining5h - highest
remaining7d - newest CodexBar account record timestamp
- stable email/account ordering
- highest
- Writes the selected auth state to
~/.codex/auth.json. - Optionally installs a LaunchAgent that periodically runs
sync --apply. - Does not depend on a running CodexBar process; CodexBar is only needed to create and maintain the local managed login states.
- macOS
- CodexBar already installed and logged into one or more Codex accounts
- CodexBar managed accounts file present at:
~/Library/Application Support/CodexBar/managed-codex-accounts.json ~/.local/bininPATHif you want to run the installed binary directly
Users do not need to clone the repository if you publish GitHub Releases.
curl -fsSL https://raw.githubusercontent.com/Zezi-Ray/codexsyncd/main/scripts/install.sh | bashInstall a specific version:
curl -fsSL https://raw.githubusercontent.com/Zezi-Ray/codexsyncd/main/scripts/install.sh | VERSION=v0.1.0 bashCustom install directory:
curl -fsSL https://raw.githubusercontent.com/Zezi-Ray/codexsyncd/main/scripts/install.sh | INSTALL_DIR="$HOME/bin" bashThis installer currently supports Apple Silicon macOS only.
Download the matching macOS asset from the Releases page, then install it into your PATH:
curl -L -o codexsyncd-aarch64-apple-darwin.tar.gz \
https://github.com/Zezi-Ray/codexsyncd/releases/latest/download/codexsyncd-aarch64-apple-darwin.tar.gz
tar -xzf codexsyncd-aarch64-apple-darwin.tar.gz
chmod +x codexsyncd
mv codexsyncd ~/.local/bin/codexsyncdPublished release asset:
codexsyncd-aarch64-apple-darwin.tar.gz
After the repository is public on GitHub:
cargo install --git https://github.com/Zezi-Ray/codexsyncd.gitcargo build --release
install -m 755 ./target/release/codexsyncd ~/.local/bin/codexsyncd| Command | Description |
|---|---|
codexsyncd status |
Show current account, selected account, usage, and next scheduled apply time. |
codexsyncd status --json |
Print status as JSON. |
codexsyncd sync --dry-run |
Preview the account that would be selected. |
codexsyncd sync --apply |
Replace ~/.codex/auth.json with the selected account. |
codexsyncd install |
Install the LaunchAgent. Default interval: 30 minutes. |
codexsyncd install --interval 3600 |
Install the LaunchAgent with a custom interval in seconds. |
codexsyncd uninstall |
Remove the LaunchAgent. |
Common options:
--json output JSON where supported
--accounts <path> override CodexBar accounts file
--target <path> override target auth.json
--min-token-minutes n skip tokens expiring sooncodexsyncd reads live usage from ChatGPT's WHAM usage API.
- Plus-style accounts typically expose both
5hand7dwindows. - Free accounts typically expose only a weekly window, so output only shows
7d.
Example status output:
current: free@example.test
nextApplyAt: 2026-04-23 18:30:00 +08:00
selected: example@plus.test (abc123)
selectedUsage: 5h=92 7d=78
accountUsages:
free@example.test (def456): 7d=100
plus@example.test (abc123): 5h=92 7d=78
If a usage request fails for one account, that account is still considered valid if its token is otherwise valid, but it will not get a usage score for that run.
nextApplyAt is estimated from the installed LaunchAgent's StartInterval plus the last successful sync --apply timestamp in ~/.codex/codexsyncd/state.json. It is unknown when the LaunchAgent is not installed or no previous apply state exists.
- Expired tokens are skipped.
- Tokens expiring within
--min-token-minutesare skipped unless refresh succeeds first. sync --applydoes not check whether acodexprocess is already running.- Replacing
~/.codex/auth.jsondoes not hot-switch the auth state inside an already running Codex session. - If the selected account is already the current target account, the run is skipped with reason
already-selected.
- CodexBar managed accounts:
~/Library/Application Support/CodexBar/managed-codex-accounts.json - Target auth file:
~/.codex/auth.json - State file:
~/.codex/codexsyncd/state.json - LaunchAgent plist:
~/Library/LaunchAgents/com.ray.codexsyncd.plist - LaunchAgent logs:
~/Library/Logs/com.ray.codexsyncd/stdout.log~/Library/Logs/com.ray.codexsyncd/stderr.log
When sync --apply writes a new target auth file, it also creates a backup:
<target>.bak.codexsyncd
Temporary atomic-write files use the .codexsyncd.*.tmp suffix.
This repository includes two GitHub Actions workflows:
ci.ymlRunscargo fmt -- --checkandcargo teston pushes and pull requests.release.ymlOnv*tags, builds the Apple Silicon macOS binary and publishes a GitHub Release withgh.
Release publishing flow:
git tag v0.1.0
git push origin v0.1.0The release workflow will:
- build
codexsyncdonmacos-14foraarch64-apple-darwin - package the binary as
.tar.gz - generate
checksums.txt - create or update the GitHub Release with
gh release create/gh release upload
statusis read-only.--helpand subcommand--helponly print usage; they do not install, uninstall, or switch auth files.
Licensed under the Apache License, Version 2.0. See LICENSE.