ai-limits
See how much of your AI subscriptions is left — Claude and Codex, any number of accounts — right in the GNOME top bar.
✳ 42% ◎ 19% Oct 27 15:49
Claude Max
Session (5h) ████░░░░░░ 42% ↻ 18:30 (in 2h10m)
Week ██░░░░░░░░ 18% ↻ Sun 19:00 (in 5d3h)
Codex · personal ★ most headroom
Week ██░░░░░░░░ 19% ↻ Thu 12:00 (in 2d21h)
Codex · work updated 8h ago
Week █████████░ 91% ↻ 18:00 (in 2h)
Offline by default. ai-limits reads only what Claude Code and Codex already saved on your machine. It sends no requests and does not read your tokens unless you turn on network mode, and network mode refuses to send anything unless the route goes through the VPN interface you name.
Unofficial. Not affiliated with Anthropic or OpenAI. The local formats and the usage endpoint it reads are undocumented and may change.
Install
uv tool install ai-limits # or: pipx install ai-limits
ai-limits # check it sees your accounts
For the optional GNOME Shell 45–49 extension, install from a checkout (it is not in the wheel):
git clone https://github.com/jointsome0-lgtm/ai-limits.git
cd ai-limits
./gnome-extension/install.sh
Platforms
Python 3.11–3.14, with no runtime dependencies. On distributions with an older system Python
(e.g. Ubuntu 22.04 ships 3.10), use uv tool install ai-limits: uv fetches a suitable Python itself.
Linux supports the offline CLI,
Claude tap, and VPN-guarded network mode (ip from iproute2 is required for network mode).
macOS and Windows support the offline CLI and Claude tap; network mode refuses to run
there, before reading credentials or looking up the host. The GNOME extension is Linux-only.
Config and cache use ~/.config/ai-limits and ~/.cache/ai-limits on all platforms, unless
XDG_CONFIG_HOME / XDG_CACHE_HOME override them. On Windows, ~ is the user profile directory
and cache privacy relies on Windows ACLs; on POSIX, directories/files use 0700/0600.
Files and CLI streams use UTF-8. Reset times display in the local timezone; timestamps without
an explicit timezone are interpreted as UTC.
Where the numbers come from
| Provider | Offline source | Network source (opt-in) |
|---|---|---|
| Codex | rate-limit snapshots in ~/.codex/sessions/**/rollout-*.jsonl, updated whenever you use Codex |
— |
| Claude | rate_limits Claude Code passes to its status line; saved by ai-limits tap claude |
api.anthropic.com/api/oauth/usage (adds per-model weekly limits) |
When a window's reset time has passed, the limit is shown as ~0% until fresh data arrives.
Claude: add the tap to your status line
In ~/.claude/settings.json:
"statusLine": { "type": "command", "command": "ai-limits tap claude --print" }
// already have a status line? pass stdin through to it:
"statusLine": { "type": "command", "command": "ai-limits tap claude | bash ~/.claude/statusline.sh" }
Several accounts
Both CLIs keep each login in its own directory (CLAUDE_CONFIG_DIR=…, CODEX_HOME=…). List them in
~/.config/ai-limits/config.toml:
[[account]]
provider = "claude"
label = "Claude Max"
home = "~/.claude"
[[account]]
provider = "codex"
label = "Codex · personal"
home = "~/.codex"
[[account]]
provider = "codex"
label = "Codex · work"
home = "~/.codex-work"
Without a config file, ~/.claude and ~/.codex are picked up automatically. With two or more
accounts of one provider, the one with the most headroom gets a ★ and is the one shown in the panel.
Network mode (Linux only, behind a VPN)
[network]
enabled = true
require_interface = "tun0" # mandatory: no interface, no network
min_interval_seconds = 300
Before every request ai-limits:
- checks the interface exists — if not, it stops before even a DNS lookup;
- resolves the host and asks the kernel which interface the packet would leave by
(
ip route get, which honours policy routing as used by sing-box / xray / WireGuard); - sends an anonymous probe (no token, no cookies) to the same host and IP, e.g.
api.anthropic.com/v1/models. Being the same domain, it takes the same routing rule in your VPN client, so adirectrule or a dead tunnel shows up here. Only the exact answer an allowed region gets for a missing token (401 authentication_error) passes; a region block (403), a timeout or anything unexpected stops here; - only then sends the real request, to exactly that IP, ignoring proxy environment variables.
Every socket is also bound to the interface (SO_BINDTODEVICE), so if the VPN drops between the
checks and the request, the kernel refuses to send it another way. Any failure means no request
with your token, and the panel shows ⏸ next to the last known numbers. Tokens are only read,
never refreshed, never put on a command line, and never written anywhere.
What this cannot see: what your VPN client does inside the tunnel. If its rules send
anthropic.com to a direct outbound (or fall back to direct when the proxy is down), traffic
enters tun0 and still leaves from your real IP. The probe catches a region block, but the only
real guarantee is in your VPN config: route these domains to the proxy with no direct fallback,
or block them when the proxy is down (a kill switch).
CLI
ai-limits summary
ai-limits --version installed version
ai-limits json state for UIs (docs/state-schema.md), also written to ~/.cache/ai-limits/state.json
ai-limits accounts configured / detected accounts
ai-limits tap claude status line helper (see above)
Development
python3 -m unittest discover tests
python3 -m ai_limits json
Releases go to PyPI through Trusted Publishing: run the Build or publish to PyPI workflow
(publish.yml) on main with mode publish; build-only just builds and checks the packages.
The PyPI publisher is owner jointsome0-lgtm, repository ai-limits, workflow publish.yml,
environment pypi. No API token is needed.
The GNOME extension only runs ai-limits json and draws the result; adding a provider means one
module in ai_limits/providers/.
License
MIT
Metadata
Release files for ai-limits 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ai_limits-0.1.0.tar.gz | 41.1 kB | With provenance | Details for ai_limits-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ai_limits-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for ai_limits-0.1.0-py3-none-any.whl |
Total release size: 62.9 kB
Release files / ai_limits-0.1.0.tar.gz
| Download URL | ai_limits-0.1.0.tar.gz |
|---|---|
| Size | 41.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3708ee221fe6663d5e4868e97648546efb5600c9a5fd5d779af70601e1834fbb
|
|
BLAKE2b-256 checksum How to use checksums |
b723e791d946c725b9d3997a65be66e3655d1e8674461e70703c71f5892684ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.
Transparency logRelease files / ai_limits-0.1.0-py3-none-any.whl
| Download URL | ai_limits-0.1.0-py3-none-any.whl |
|---|---|
| Size | 21.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9aced086535813f2babbbd020fbdb40684d8218916ca19dc17e43e01b7628859
|
|
BLAKE2b-256 checksum How to use checksums |
95bd1449b7d234fc589a107037f72e6888b027c7b5f8bf0d06d4346244d45d07
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.
Transparency logSecurity for ai-limits 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for ai_limits-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.