Standalone Codex plugin for automatically redeeming explicitly authorized, banked usage resets. It supports one-shot, bounded, and continuous authorization and runs as a private macOS LaunchAgent, so Codex does not need to remain open.
Important
This is an unofficial community project. It is not affiliated with, endorsed by, or supported by OpenAI.
The safe default waits until the Codex backend reports an exhausted rate limit. An explicit percentage threshold is also available for users who want an earlier attempt.
- Plain
arm --yesauthorizes one exact currently available reset credit. arm --count N --yesauthorizes up to N successful resets and waits for current or future detailed credits.arm --continuous --yesis standing authorization for current and future credits until explicit disarm.- Every consume request still uses one exact backend-provided credit ID and a durable UUID.
- The exact credit ID and a UUID idempotency key are persisted before redemption.
- Ambiguous failures retry the same UUID. A confirmed
nothingToResetresponse creates a fresh logical attempt. - Redeemed, expired, missing-detail, workspace, and spend-control states fail closed.
check --dry-runnever consumes a credit or changes state.- State transitions use a private file lock plus atomic, fsynced writes.
- Monotonic revisions prevent stale workers from passing compare-and-swap after an authorization cycles back to waiting.
- Non-final successful or unavailable credits enter
settlinguntil an authoritative snapshot prevents stale reselection; final one-shot or bounded outcomes complete directly. - The watcher talks only to the public
codex app-serverprotocol. It does not read Codex credentials or call private backend routes. - Logs and notifications contain fixed messages, never backend payloads, credit IDs, or tokens.
- macOS with per-user LaunchAgents
- Codex CLI with
codex app-serverand reset-credit support uvfor a durable managed service runtime; without it, a working Python 3.10–3.13 whose lifecycle you manage- An authenticated Codex account with a detailed banked reset credit
Git/Codex must be able to access RobertTLange/codex-auto-reset before installing it as a marketplace.
codex plugin marketplace add RobertTLange/codex-auto-reset --ref main
codex plugin add codex-auto-reset@codex-auto-resetOpen a new Codex conversation, then ask:
Use $codex-auto-reset to install the background service and show its status.
When uv is installed, the skill selects a durable uv-managed Python rather than a project .venv or Homebrew Cellar target. Its fallback uses a validated PATH Python whose durability is the user's responsibility.
For repository development:
uv sync --locked --dev
uv run codex-auto-reset --helpFor a repository checkout, the same bundled wrapper is available directly:
MANAGE=./plugins/codex-auto-reset/skills/codex-auto-reset/scripts/manage
"$MANAGE" <command>Installed-plugin users should invoke $codex-auto-reset in a new Codex conversation instead of guessing the plugin cache path. For checkout usage, use this wrapper for service operations; it deliberately avoids a repository .venv, which may be deleted or recreated.
Backend-confirmed exhaustion, 60-second polling:
"$MANAGE" install-serviceExplicit earlier attempt at 95% used:
"$MANAGE" install-service \
--poll-seconds 300 \
--usage-threshold-percent 95Omitted options preserve the existing service settings. To remove a saved percentage threshold:
"$MANAGE" install-service --backend-onlyThe backend remains authoritative. If it answers nothingToReset, the authorization stays armed and the watcher tries a fresh logical attempt on a later poll.
One exact currently available credit:
"$MANAGE" status
"$MANAGE" arm --yesPlain arm reads the current bank and chooses the available Codex reset that expires soonest. arm --count 1 is equivalent. It refuses count-only responses because an exact credit ID is required.
A bounded sequence, including credits issued later:
"$MANAGE" arm --count 5 --yesContinuous redemption until explicitly disabled:
"$MANAGE" arm --continuous --yesBounded and continuous authorization may start while the bank is empty. The watcher waits for a detailed credit, atomically binds its exact ID, and consumes at most one credit per polling iteration. A terminal or unavailable candidate does not reduce the bounded success allowance.
"$MANAGE" check --dry-run
"$MANAGE" runtime"$MANAGE" disarm --yes
"$MANAGE" uninstall-service --yesdisarm and uninstall refuse an in-flight redeeming state, leaving the service running. Waiting, armed, settling, bounded, and continuous authorization can otherwise be disabled. If redemption races with uninstall after launchd stops, uninstall restarts the watcher before refusing so its idempotent attempt can finish.
To remove the Codex plugin after removing its service:
codex plugin remove codex-auto-reset@codex-auto-resetdisabled -> waiting -> armed -> redeeming -> settling -> waiting -> ...
| | |
| | +-- authoritative retirement proof
| +-- nothingToReset -> armed (fresh UUID)
+-- no detailed credit -> waiting
one-shot/final bounded success -> completed
disabled: no authorization; no account request from the watcher.waiting: bounded or continuous authorization is active, but no exact credit is currently bound.armed: one exact credit is bound; the watcher evaluates policy.redeeming: the request identity is durable; ambiguous failures retry it.settling: the previous identity is retained until a complete snapshot proves it cannot be selected again.completed: one-shot authorization or a bounded success allowance is finished.
status reports lifecycle, authorization mode, successful resets, and remaining allowance without starting Codex or exposing credit IDs.
| Path | Purpose | Mode |
|---|---|---|
~/Library/Application Support/codex-auto-reset/state.json |
Authorization and idempotency state | 0600 |
~/Library/Application Support/codex-auto-reset/config.json |
Polling and threshold settings | 0600 |
~/Library/Application Support/codex-auto-reset/lib/ |
Private copied watcher runtime | 0700 tree |
~/Library/LaunchAgents/com.roberttlange.codex-auto-reset.plist |
LaunchAgent definition | 0600 |
~/Library/Logs/codex-auto-reset/ |
Sanitized stdout/stderr | private directory |
State/config parents must be owned by the current user and private. Symlinked managed paths are rejected.
codex plugin marketplace upgrade codex-auto-reset
codex plugin remove codex-auto-reset@codex-auto-reset
codex plugin add codex-auto-reset@codex-auto-resetOpen a new Codex conversation and run the skill's install workflow again. Service settings are preserved unless explicitly changed.
Status: disabled: install may be running, but no reset is authorized. Run an explicit arm command.waiting: authorization is active, but no detailed credit exists yet, or the exact credit is not eligible.settling: the watcher is retaining the previous identity until the backend authoritatively retires it.retry_pending: app-server, state, or protocol failure. The watcher backs off to at most 15 minutes and notifies only on status transitions.unavailable: the current exact credit was redeemed, expired, or reported unavailable. Bounded or continuous authorization may remain active; runstatusanddisarm --yesif no future reset should be redeemed.- Service diagnostics: inspect
~/Library/Logs/codex-auto-reset/stdout.logandstderr.log. - LaunchAgent diagnostics:
launchctl print gui/$(id -u)/com.roberttlange.codex-auto-reset.
- macOS only; launchd is the supported background runner.
- The app-server reset-credit protocol is still evolving. This implementation follows the current
openai/codexapp-server contract. - When
availableCountis present butcreditsdetail is absent or capped, only a returned detailed credit can be armed. This intentional fail-closed behavior can leave otherwise available count-only credits unused. - Missing, malformed, count-only, or capped detail never proves that a settling credit retired.
- Percentage mode is opt-in. It evaluates reported
usedPercent; the backend can still decline an early reset. - Paid credits are not reset credits and are never spent by this plugin.
Version 1 state is migrated fail-closed: disabled remains disabled, and armed, redeeming, or completed state remains an exact one-shot authorization. Upgrading never creates bounded or continuous authority.
uv sync --locked --dev
uv run ruff check .
uv run ruff format --check .
uv run pytest --cov=codex_auto_reset --cov-fail-under=80
uv buildSee SECURITY.md for the threat model and reporting guidance.
