codex #
codex-x manages the Codex CLI accounts of a machine: what the codex
command does not do for more than one account.
Each account is a Codex home: ~/.codex is default and ~/.codex-NAME is
NAME, as CODEX_HOME selects them; nothing else records them. For each,
codex-x reads the ChatGPT account it is signed in to and the rate-limit
windows it has left, ranks the accounts by when their week resets, and runs
codex in the one named.
Installation #
opam install codex
Usage #
$ codex-x account list # name, state, plan, identity, directory
$ codex-x account show work --json
$ codex-x usage # each window: share used, next reset
$ codex-x usage --recorded # the newest rate limits Codex recorded
$ codex-x pick # the account whose week ends first
$ codex-x pick --at 2026-10-14T22:00:00Z --json
$ eval "$(codex-x env work)"
$ codex-x run work -- exec "hello"
usage and pick ask the endpoint Codex reads its rate limits from
(GET https://chatgpt.com/backend-api/wham/usage), with a 15 s bound, or
with --recorded read the last record in the newest session file under the
home's sessions/. A signed-out, expired or unreadable account, or one
signed in with an API key, which has no plan windows, is reported by name
with the reason. codex-x never refreshes a token itself, and no output
carries one.
pick ranks the accounts by deadline. What is left of a week at its reset
is lost, so of the accounts with headroom now (the shorter window not spent)
the one whose week ends first comes first, then the one with more left;
usage lists the accounts in the same order. --at TIME ranks as at
another time. The commands and the ranking are llm-eio's accounts
library, which claude-x (in ocaml-claude) shares.
Tests #
The unit tests decode Codex's auth.json and rate-limit documents, and the
cram test runs every command over a home with one account in each state,
recorded fixtures only, never the live service; it asserts that no output
carries a token.
License #
ISC. See LICENSE.md.