Metadata-Version: 2.5
Name: tokenmaxxr
Version: 1.1.0
Summary: Aggregate AI subscription quota usage (Claude, Kiro, ClinePass, Ollama Cloud, OpenCode Go) into one view.
Project-URL: Homepage, https://github.com/Izzur/tokenmaxxr
Project-URL: Bug Tracker, https://github.com/Izzur/tokenmaxxr/issues
Author-email: Izzur <13365626+Izzur@users.noreply.github.com>
Maintainer-email: Izzur <13365626+Izzur@users.noreply.github.com>
License: MIT
License-File: LICENSE
Keywords: ai,claude,cline,dankmaterialshell,fastfetch,kiro,ollama,opencode,quota,usage,waybar
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: browser-cookie3>=0.20
Requires-Dist: requests>=2.31
Requires-Dist: tomli>=2; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: serve
Requires-Dist: fastapi>=0.110; extra == 'serve'
Requires-Dist: uvicorn>=0.27; extra == 'serve'
Description-Content-Type: text/markdown

# tokenmaxxr

Aggregate AI subscription quota usage (Claude, AWS Kiro, ClinePass, Ollama Cloud, OpenCode Go) into one view.

Five providers, one engine, one versioned JSON contract. CLI for bars/dashboards, a DankMaterialShell bar plugin, optional WebUI, optional HTTP API.

## Install

```bash
# from PyPI (recommended)
uvx tokenmaxxr --json

# from source
git clone https://github.com/Izzur/tokenmaxxr
cd tokenmaxxr
uv pip install -e ".[serve]"  # add [serve] for `tokenmaxxr serve`
```

## Quickstart

```bash
tokenmaxxr              # human table
tokenmaxxr --json       # machine-readable schema:1
tokenmaxxr --refresh    # bypass the 300s cache
tokenmaxxr doctor       # diagnose cookie discovery
tokenmaxxr serve        # WebUI + HTTP API
```

## Web UI

`tokenmaxxr serve` (requires `pip install 'tokenmaxxr[serve]'`) starts a small FastAPI app on `127.0.0.1:8765`:

- `GET  /api/usage`   — schema:1 document (same as `tokenmaxxr --json`)
- `POST /api/refresh` — force a live re-fetch
- `GET  /api/history?provider=&window=` — appended history rows
- `GET  /`           — vanilla-JS dashboard (cards + history chart, opt-in 60s auto-refresh)

The dashboard degrades gracefully: with no cookies, every card shows `no-auth` and a hint.

## Output contract

`tokenmaxxr --json` returns a stable, versioned document:

```json
{
  "schema": 1,
  "fetched_at": "2026-07-22T12:00:00Z",
  "providers": [
    {
      "id": "ollama-cloud",
      "name": "Ollama Cloud",
      "status": "ok",
      "windows": [
        {"label": "5h", "pct_used": 47, "reset_at": "2026-07-22T20:00:00Z"}
      ]
    }
  ]
}
```

`status` is one of `ok` | `stale` | `no-auth` | `error`.

## Config

`$XDG_CONFIG_HOME/tokenmaxxr/config.toml` (default `~/.config/tokenmaxxr/config.toml`), optional:

```toml
include = ["claude", "kiro"]   # whitelist: only these providers
exclude = ["opencode-go"]      # blacklist: everything except these
```

`include` is applied first, then `exclude`. `--provider` on the CLI overrides both.

## Auth sources

Two kinds of provider:

| Provider | Slug | Auth |
|---|---|---|
| Claude | `claude` | Claude Code OAuth token, `$CLAUDE_CONFIG_DIR/.credentials.json` (default `~/.claude/`). Log in once with `claude`. |
| AWS Kiro | `kiro` | kiro-cli token in `~/.local/share/kiro-cli/data.sqlite3`, else Kiro IDE `~/.aws/sso/cache/kiro-auth-token.json`. Log in with `kiro-cli login`. |
| ClinePass | `clinepass` | browser cookies for `app.cline.bot` + `api.cline.bot` |
| Ollama Cloud | `ollama-cloud` | browser cookies for `ollama.com` |
| OpenCode Go | `opencode-go` | browser cookies for `opencode.ai` |

Token providers never refresh tokens themselves (that could invalidate the
CLI's own session). Kiro tokens expire hourly, so an expired one makes
tokenmaxxr run `kiro-cli whoami`, which refreshes in place. An expired Claude
token shows as `no-auth`; run `claude` once and the next poll succeeds.

## Cookie sources

1. `--cookie-file SLUG=/path/to/cookies.sqlite` or `TOKENMAXXR_COOKIE_<DOMAIN>` env
2. Firefox-family stores (globbed: `~/.mozilla/firefox/*`, `~/.zen/*`, Zen/Firefox Flatpak paths, Floorp/LibreWolf/Waterfox)
3. Chromium-family via `browser_cookie3` (best-effort, locked keyring → skip)
4. No match → `no-auth` status + remediation in `doctor`

Cookies are copied to a temp file before reading (WAL lock-safe). Cache and history live under `~/.local/state/tokenmaxxr/`.

## DankMaterialShell (Dankbar)

```bash
uv tool install tokenmaxxr                       # puts `tokenmaxxr` on ~/.local/bin
git clone https://github.com/Izzur/tokenmaxxr
ln -s "$PWD/tokenmaxxr/dms/TokenMaxxr" ~/.config/DankMaterialShell/plugins/TokenMaxxr
```

Then DMS Settings → Plugins → enable **tokenmaxxr**, and add it to a bar
section. Pill shows `C 3d 4h`: for each provider take its longest window
(30d, 7d, …), then show the provider whose longest window resets soonest and
the countdown to it. Left click opens a popout with every window, progress
bar and reset countdown. Right click forces `--refresh`.

Optional settings in `~/.config/DankMaterialShell/plugin_settings.json`:

```json
"tokenMaxxr": { "enabled": true, "command": "tokenmaxxr --json", "interval": 300 }
```

## Waybar

```json
"custom/tokenmaxxr": {
  "exec": "tokenmaxxr --json --provider ollama-cloud",
  "return-type": "json",
  "format": "Ollama 5h: {}%",
  "exec-on-event": true,
  "interval": 600
}
```

`--json` is the stable schema:1 contract — `jq '.providers[0].windows[0].pct_used'` always returns an integer.

## fastfetch

```text
"tokenmaxxr": {
  "type": "command",
  "key": "TKN",
  "command": "tokenmaxxr --json | jq -r '.providers[] | select(.status==\"ok\") | \"\\(.id): \\(.windows[0].pct_used)%\"' | paste -sd, -"
}
```

## Headless / `--cookie-file`

```bash
tokenmaxxr --cookie-file ollama-cloud=/srv/cookies/ollama.sqlite --json
# or
TOKENMAXXR_COOKIE_OLLAMA_COM=/srv/cookies/ollama.sqlite tokenmaxxr --json

## Development

```bash
uv sync --extra dev           # set up dev deps (pytest, fastapi, etc.)
uv run python3 -m pytest      # 32 tests, <1s
uv run python3 -m pytest tests/test_providers.py -v   # one file
```

Provider parser tests live in `tests/test_providers.py` against HTML/JSON
fixtures under `tests/fixtures/`. To add a fixture, drop a real captured
payload into `tests/fixtures/<slug>.<ext>` and write a `test_<slug>` that
feeds it through `RawHtml` and asserts on the parsed `UsageWindow`s.

## License

MIT
