Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,39 @@ codex-switch account add work --device-auth

# Inspect and switch. Close Codex before switching, then restart it.
codex-switch account list
codex-switch account usage work
codex-switch use work
codex-switch current
```

Use `codex-switch doctor` before reporting a problem. Machine-readable output is
available on status and list commands with `--json`.
available on commands with `--json`.

## Usage without switching

`codex-switch` can inspect every saved account through the official Codex App
Server without making that account active:

```bash
# Query the active managed account now.
codex-switch account usage

# Query one saved account, or all accounts concurrently.
codex-switch account usage work
codex-switch account usage --all

# Refresh all rows in the compact account table.
codex-switch account list --refresh

# Work offline with the last successful snapshots.
codex-switch account list --cached
codex-switch account usage work --cached
```

Normal `account list` calls refresh only missing snapshots or snapshots older
than 60 seconds. Each query runs in an isolated temporary `CODEX_HOME`; it does
not switch `$CODEX_HOME/auth.json`, sessions, plugins, or UI state. The cache
contains usage numbers and public account metadata only, never tokens.

## Commands

Expand All @@ -75,7 +102,8 @@ codex-switch select

codex-switch account add <alias>
codex-switch account import-current <alias>
codex-switch account list
codex-switch account list [--refresh|--cached]
codex-switch account usage [alias] [--all] [--cached]
codex-switch account show <alias>
codex-switch account rename <old> <new>
codex-switch account reauth <alias>
Expand All @@ -94,6 +122,11 @@ Normal account switches modify only:
- `$CODEX_HOME/auth.json`
- `codex-switch`'s own state and encrypted vault

An account-usage query may persist an officially refreshed credential generation
back to the encrypted vault. If the queried profile is active, the same
generation is safely reconciled into `$CODEX_HOME/auth.json`; no account selection
or Codex-owned state changes.

Initialization may make a one-time, backed-up change to
`$CODEX_HOME/config.toml` to set `cli_auth_credentials_store = "file"`.
`codex-switch` does not rewrite session history or Codex configuration during a
Expand Down
28 changes: 28 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
- `vault` encrypts all saved account profiles with XChaCha20-Poly1305.
- `switcher` reconciles a live Codex refresh generation, prepares a journal,
performs compare-before-replace, and records the selected profile.
- `codexusage` runs the official Codex App Server in an isolated temporary
`CODEX_HOME` and reads the stable account, rate-limit, and token-usage methods.
- `accountusage` queries up to four profiles concurrently, reconciles credential
refresh generations, and coordinates with switching through the same lock.
- `usagecache` stores credential-free successful snapshots separately from the
encrypted vault.
- `atomicfile` publishes complete files and refuses symlink destinations.
- `doctor` reports only redacted, non-secret local facts.

Expand All @@ -43,6 +49,25 @@ The journal contains only profile IDs, hashes, and timestamps. If the process
stops after replacement but before state persistence, recovery compares the live
file with both hashes and completes the state transition.

## Isolated usage query

```text
acquire shared operation lock
-> decrypt and validate selected profile(s)
-> create one temporary CODEX_HOME per profile
-> write only that profile plus file-store config
-> initialize the official Codex App Server
-> read account/rateLimits/read and account/usage/read
-> stop the server and delete the temporary home
-> reconcile any newer credential generation
-> atomically save credential-free usage snapshots
```

The live account selection never changes. If Codex rotates a refresh token while
answering the query, identity and generation checks run before the new document
is saved. For an active profile, compare-before-replace protects the live
projection from a concurrent Codex write.

## Data locations

`CODEX_HOME` resolution:
Expand All @@ -59,3 +84,6 @@ file with both hashes and completes the state transition.

Only tests and advanced portable installations should normally override these
paths.

The usage cache is `usage-cache.v1.json` inside the resolved `codex-switch` data
directory. It contains no authentication documents.
21 changes: 17 additions & 4 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,21 @@ The command creates a timestamped backup before making a surgical top-level

## Codex releases

Development began against Codex CLI `0.148.0-alpha.15`. The project does not use
that version's private OAuth endpoints. Login is delegated to the installed
official CLI, reducing the compatibility surface to its documented cached
authentication shape.
Development began against Codex CLI `0.148.0-alpha.15`; isolated account-usage
queries were validated with `0.148.0-alpha.21`. The project does not use private
OAuth or usage endpoints. Login is delegated to the installed official CLI, and
usage is read through the documented stable Codex App Server protocol.

Usage querying initializes `codex app-server` and calls:

- `account/read`
- `account/rateLimits/read`
- `account/usage/read`

If one usage method is unavailable, the other is still cached and marked
partial. If both are unavailable, update the installed Codex client. These
methods require a ChatGPT/Codex service login; API-key-only and Amazon Bedrock
profiles are not supported by `codex-switch`.

On an unknown or malformed schema, `codex-switch` stops before overwriting the
live file. Add a redacted fixture and a versioned adapter before broadening the
Expand All @@ -39,5 +50,7 @@ accepted shape.
## Upstream references

- OpenAI authentication documentation: https://developers.openai.com/codex/auth
- OpenAI Codex App Server documentation:
https://learn.chatgpt.com/docs/app-server
- CC Switch managed Codex OAuth implementation:
https://github.com/farion1231/cc-switch/tree/v3.20.0
7 changes: 7 additions & 0 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ focuses on:

- Commands never expose a token retrieval operation.
- JSON output is intentionally based on dedicated public view types.
- Usage queries create per-profile temporary homes with mode `0700` and
credential files with mode `0600`, then remove them after the App Server exits.
- The usage cache contains rate limits, aggregate token statistics, timestamps,
and public account metadata only. It never contains authentication documents.
- A token refreshed during an isolated query is accepted only after account,
workspace, and refresh-generation checks. Active-file updates use a
compare-before-replace check under the shared operation lock.
- Real credentials are forbidden in tests and fixtures.
- The Linux desktop implementation fails closed when Secret Service is absent.
- Portable backups require a passphrase of at least 12 characters and use
Expand Down
25 changes: 25 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,31 @@ codex-switch account reauth <alias>

The ambiguity is intentionally not resolved by guessing.

## Account usage is unavailable

Confirm the official Codex executable is installed and current:

```bash
codex --version
codex-switch account usage <alias>
```

Usage queries require network access and a saved ChatGPT login. They do not work
for API-key-only or Amazon Bedrock authentication. A missing method on an older
Codex build is reported as partial when the other method still works; update
Codex if both usage methods are unavailable.

For an offline or temporarily failing service, inspect the last successful
snapshot without making a request:

```bash
codex-switch account list --cached
codex-switch account usage <alias> --cached
```

A stale cached snapshot is labeled `stale`; a failed refresh keeps that snapshot
and displays a warning rather than discarding useful data.

## Interrupted switch journal

Run `codex-switch status`. Recovery compares the current `auth.json` hash with
Expand Down
Loading