Skip to main content

Cross-platform Codex workspace switcher with a preserved macOS shell workflow.

Project description

codex-workspaces

English | 简体中文 | Changelog

codex-workspaces switches between multiple Codex workspace directories under ~/.codex-workspaces/workspaces/ and points the active ~/.codex path at the selected workspace.

The project now has two entry points:

  • A cross-platform Python 3 CLI for Linux, macOS, and Windows.
  • The original macOS Bash script, still kept at macos/codex-workspaces, for users who installed the shell workflow directly.

On macOS, the Python CLI preserves the original app workflow: stop Codex App, switch the workspace link, and start Codex App again. On Linux and Windows, the CLI checks the process list first; if Codex is running, it records the process command, stops it, switches the workspace link, and starts it again. If no process is found, it only switches the workspace link.

Features

  • Manage workspace directories such as ~/.codex-workspaces/workspaces/work.
  • Manage account snapshots under ~/.codex-workspaces/accounts/.
  • Switch the active ~/.codex symlink or directory link.
  • Initialize workspace directories with metadata.
  • Add a new account through an isolated temporary login workspace with accounts add --login.
  • Temporarily switch the current workspace account with accounts use, then restore the workspace default account.
  • Best-effort parse local auth.json metadata such as email/account identifiers without network calls.
  • Export and import account snapshot backups with explicit warnings for credential-bearing archives.
  • Inspect workspace/account metadata and run account-focused doctor diagnostics.
  • Migrate older ~/.codex-<name> workspaces and import legacy ~/.codex-accounts auth snapshots.
  • Keep macOS Codex App stop/start/restart support, with best-effort process-based stop/start on Linux and Windows when a running Codex process is found.
  • Show local token usage stats from Codex state_*.sqlite in read-only mode, including daily, model, workspace, account, JSON, and Markdown views.
  • Block unsafe operations from a detected Codex built-in terminal when they cannot be delegated safely.
  • Support English and Chinese output through CODEX_WORKSPACES_LANG.
  • Package as a Python project with tests, CI, and PyPI publishing workflow.

Requirements

  • Python 3.9 or newer for the Python CLI.
  • macOS has native Codex App control; Linux and Windows use best-effort process detection for start, stop, and restart.
  • Linux and macOS use directory symlinks.
  • Windows uses directory symlinks when available and falls back to directory junctions.

Install

Install the Python CLI from PyPI:

python3 -m pip install codex-workspaces

For isolated CLI installs, pipx is recommended:

pipx install codex-workspaces

Install from a local checkout for development:

python3 -m pip install -e ".[dev]"

The legacy macOS shell installer is still available from the macos/ directory:

tmp="$(mktemp -t codex-workspaces.XXXXXX)" && curl -fsSL https://raw.githubusercontent.com/blockchain-project-lives/codex-workspaces/main/macos/codex-workspaces -o "$tmp" && bash "$tmp" install && rm -f "$tmp"

Workspace Layout

Default layout:

~/.codex           -> active workspace link
~/.codex-workspaces/
  config.json
  state.json
  lock
  workspaces/
    work/
      auth.json
      .codex-workspace.json
    personal/
      auth.json
      .codex-workspace.json
  accounts/
    acct_work/
      auth.json
      meta.json

Customize paths with CODEX_WORKSPACES_LINK and CODEX_WORKSPACES_ROOT.

Repository Structure

The repo is organized around a small Python core plus platform-specific helpers:

  • src/codex_workspaces/cli.py: command-line parsing and command dispatch.
  • src/codex_workspaces/core.py: main workflows for workspace switching, accounts, migration, doctor, stats, and config.
  • src/codex_workspaces/store.py: metadata persistence, workspace/account layout, and secure file writes.
  • src/codex_workspaces/platforms.py: macOS app control plus Linux/Windows process discovery and restart behavior.
  • src/codex_workspaces/private_api/: experimental realtime quota and reset-credits provider, auth extraction, models, and error types.
  • src/codex_workspaces/stats.py: local SQLite usage stats parsing and aggregation.
  • src/codex_workspaces/auth_inspector.py: best-effort local auth.json parsing without network requests.
  • macos/: the legacy Bash implementation and its own readme.
  • docs/: design, testing, and release notes.
  • tests/: unit and CLI coverage for the Python package.

If you want to understand the tool quickly, reading order is usually cli.py -> core.py -> store.py -> private_api/.

Usage

Initialize workspaces:

codex-workspaces init personal
codex-workspaces init work

Migrate older ~/.codex-<name> directories without deleting the originals:

codex-workspaces migrate --dry-run
codex-workspaces migrate

If your current ~/.codex is a real directory instead of a link, migrate it into a named workspace explicitly:

codex-workspaces init personal --migrate-current

Set up account snapshots after Codex has created an auth.json in the active workspace:

codex-workspaces use work --no-stop --no-start
codex-workspaces accounts save work
codex-workspaces accounts set-default work acct_work --activate
codex-workspaces accounts list

Standalone accounts can be initialized and later populated from the current workspace auth.json:

codex-workspaces accounts init research
codex-workspaces accounts save research

To add a new account without logging out of the current workspace account, use a temporary login workspace:

codex-workspaces accounts add research --login

This switches ~/.codex to a temporary login-<account> workspace, lets you log in, saves the generated auth.json as acct_<account>, and restores the previous workspace. If login is interrupted, clean stale temporary workspaces with codex-workspaces accounts cleanup-login-temp.

Account metadata such as email, account_id, user_id, organization_id, and plan is parsed from local auth.json on a best-effort basis. Parsing failures are ignored, sensitive token-like fields are never printed, and no private API or network request is used.

Export or import account backups:

codex-workspaces accounts export accounts.tar.gz --all
codex-workspaces accounts export accounts-with-auth.tar.gz --all --include-auth --yes
codex-workspaces accounts import accounts-with-auth.tar.gz --dry-run
codex-workspaces accounts import accounts-with-auth.tar.gz --rename-conflicts

Backups created with --include-auth contain Codex credentials from auth.json. Store them securely and never commit them to git. Without --include-auth, export writes metadata only.

Import legacy codex-accounts AUTH-mode snapshots:

codex-workspaces accounts import-legacy ~/.codex-accounts

Switch workspaces:

codex-workspaces work
codex-workspaces use personal
codex-workspaces switch work

On macOS, switching stops and restarts Codex App by default. On Linux and Windows, switching does the same only when a running Codex process can be found and recorded. Skip those steps when needed:

codex-workspaces work --no-stop --no-start

Inspect workspaces:

codex-workspaces list
codex-workspaces current
codex-workspaces info work
codex-workspaces doctor
codex-workspaces stats
codex-workspaces stats summary --days 30
codex-workspaces stats daily --format markdown
codex-workspaces stats models --format json
codex-workspaces stats workspaces
codex-workspaces stats accounts
codex-workspaces stats work --days 14

stats only reads local SQLite state. Missing or unrecognized workspace/account/model data is shown as unknown; results are best-effort and depend on the local Codex files available in each workspace.

Experimental Realtime Account Data

codex-workspaces can optionally query experimental realtime account data for managed accounts through a private API provider.

These features are disabled by default. They may break when upstream Codex/OpenAI internals change, may return 401/403/429, and are not required for workspace or account switching.

Enable explicitly:

codex-workspaces config set experimental_private_api.enabled true
codex-workspaces config set experimental_private_api.quota_enabled true
codex-workspaces config set experimental_private_api.reset_credits_enabled true

Switches and endpoint fields:

  • experimental_private_api.enabled: master switch. When off, no experimental account lookups run.
  • experimental_private_api.quota_enabled: enables realtime WHAM quota lookup.
  • experimental_private_api.reset_credits_enabled: enables reset credits lookup and includes that block in accounts info.
  • experimental_private_api.refresh_enabled: reserved for explicit remote refresh flows; still off by default.
  • experimental_private_api.base_url defaults to https://chatgpt.com
  • experimental_private_api.quota_endpoint defaults to /backend-api/wham/usage
  • experimental_private_api.reset_credits_endpoint defaults to /backend-api/wham/rate-limit-reset-credits
  • experimental_private_api.account_endpoint defaults to an empty string

When the master switch is on, accounts info <account> shows a dedicated Experimental section. Enabled features render their live data as nested blocks, so local metadata and experimental metadata stay clearly separated.

Query current account quota:

codex-workspaces quota
codex-workspaces quota --json

Query a specific managed account:

codex-workspaces accounts quota acct_work
codex-workspaces accounts info acct_work

Query all accounts with quota:

codex-workspaces accounts list -a
codex-workspaces accounts list --all-with-quota --json

Refresh remote account metadata and quota cache:

codex-workspaces accounts refresh
codex-workspaces accounts refresh acct_work
codex-workspaces accounts refresh --all --json

Refresh remains disabled by default. The current account_endpoint is not the Codex responses API; do not point it at the responses endpoint unless the provider logic is updated to support that POST-based flow.

Realtime quota uses explicit experimental configuration, timeout, serial account iteration, and a local TTL cache under ~/.codex-workspaces/cache/quota/. The cache stores quota summaries and auth hashes only; it does not store tokens, cookies, authorization headers, or raw auth.json.

When experimental_private_api.reset_credits_enabled is true, accounts info <account> shows reset credits with local-time grant and expiry timestamps. The output intentionally omits credit IDs and other unique identifiers. When experimental_private_api.quota_enabled is also true, the same command includes a nested quota block as well.

stats and quota are different: stats is local historical usage from SQLite, while quota is a realtime remote lookup. Quota failures do not affect local workspace/account switching.

Switch accounts within the current workspace:

codex-workspaces accounts use acct_personal
codex-workspaces accounts restore-default

accounts use only changes the current workspace active_account_id; it does not change default_account_id. Entering a workspace uses CODEX_WORKSPACES_RESTORE_POLICY: workspace-default restores the workspace default account, last-active restores that workspace's last active account, and keep-current keeps the account you were just using when possible.

auth.json contains credentials. Do not commit workspace directories, account snapshots, SQLite state, sessions, or shell snapshots to git; the project .gitignore excludes these patterns for local checkouts.

Manage account metadata and snapshots:

codex-workspaces accounts note acct_research "lab account"
codex-workspaces accounts info acct_research
codex-workspaces accounts info "$(codex-workspaces accounts current --id)"
codex-workspaces accounts rename acct_research acct_lab
codex-workspaces accounts delete acct_lab --force

Account deletion always requires --force and refuses to delete an account that is still configured as any workspace's default account.

Manage workspace metadata and lifecycle:

codex-workspaces note work "main paid workspace"
codex-workspaces rename work main
codex-workspaces delete old-workspace --force

Control Codex App:

codex-workspaces stop
codex-workspaces start
codex-workspaces restart

stats only reads local SQLite files such as state_*.sqlite or sqlite/state_*.sqlite. It does not call quota or refresh private APIs.

Environment Variables

Variable Default Description
CODEX_APP_NAME Codex macOS app name and Linux/Windows process name to control.
CODEX_QUIT_TIMEOUT 20 Seconds to wait for app exit.
CODEX_WORKSPACES_LINK $HOME/.codex Active workspace link path.
CODEX_WORKSPACES_ROOT $HOME/.codex-workspaces Managed root for workspaces, accounts, backups, and lock file.
CODEX_WORKSPACES_RESTORE_POLICY workspace-default Account restore policy when entering a workspace: workspace-default, last-active, or keep-current.
CODEX_WORKSPACES_LANG auto Force output language with en or zh.

Only the CODEX_WORKSPACES_* variables are used for workspace-specific configuration.

Development

python3 -m pip install -e ".[dev]"
python3 -m pytest
python3 -m build
python3 -m twine check dist/*

Design, test, and release notes live in docs/.

Publishing

CI runs tests on Linux, macOS, and Windows across Python 3.9, 3.11, and 3.13. The Publish to TestPyPI workflow runs for v* tags, and the Publish to PyPI workflow publishes from release/v* branches or manual runs.

Configure TestPyPI and PyPI Trusted Publishing for this repository before using the release workflows. See docs/RELEASE.zh-CN.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codex_workspaces-0.3.6.tar.gz (88.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_workspaces-0.3.6-py3-none-any.whl (62.4 kB view details)

Uploaded Python 3

File details

Details for the file codex_workspaces-0.3.6.tar.gz.

File metadata

  • Download URL: codex_workspaces-0.3.6.tar.gz
  • Upload date:
  • Size: 88.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codex_workspaces-0.3.6.tar.gz
Algorithm Hash digest
SHA256 bb912b2c1775f475d9428d52d17aee0c568cfc2b98c6d912dae3d0dbe838cf8b
MD5 a0f7e06bdc5505c3456982429741e926
BLAKE2b-256 a63abaa01252a7abb90f59a8db63d567fa29f1bda2191ef6e848738c8198a56f

See more details on using hashes here.

Provenance

The following attestation bundles were made for codex_workspaces-0.3.6.tar.gz:

Publisher: publish.yml on blockchain-project-lives/codex-workspaces

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codex_workspaces-0.3.6-py3-none-any.whl.

File metadata

File hashes

Hashes for codex_workspaces-0.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 b3b634ecd269567e4cdb4100422f870f1d2f188e3d8f8c4d859b22c95fc474bb
MD5 4f2d41789051bdd100a67bbd2d2c82a4
BLAKE2b-256 ba83d63069ea51175eeac101b983b727b25df6219a6623fac8131fa44f2de7f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for codex_workspaces-0.3.6-py3-none-any.whl:

Publisher: publish.yml on blockchain-project-lives/codex-workspaces

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page