aiuse 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. aiuse-2.1.0/LICENSE +21 -0
  2. aiuse-2.1.0/PKG-INFO +331 -0
  3. aiuse-2.1.0/README.md +295 -0
  4. aiuse-2.1.0/pyproject.toml +75 -0
  5. aiuse-2.1.0/setup.cfg +4 -0
  6. aiuse-2.1.0/src/aiuse/__init__.py +3 -0
  7. aiuse-2.1.0/src/aiuse/__main__.py +3 -0
  8. aiuse-2.1.0/src/aiuse/ai_stub.py +13 -0
  9. aiuse-2.1.0/src/aiuse/analysis/__init__.py +5 -0
  10. aiuse-2.1.0/src/aiuse/analysis/history.py +355 -0
  11. aiuse-2.1.0/src/aiuse/analysis/pace.py +117 -0
  12. aiuse-2.1.0/src/aiuse/analysis/use_or_lose.py +793 -0
  13. aiuse-2.1.0/src/aiuse/cli.py +615 -0
  14. aiuse-2.1.0/src/aiuse/collectors/__init__.py +13 -0
  15. aiuse-2.1.0/src/aiuse/collectors/base.py +82 -0
  16. aiuse-2.1.0/src/aiuse/collectors/codexbar.py +461 -0
  17. aiuse-2.1.0/src/aiuse/collectors/cswap.py +431 -0
  18. aiuse-2.1.0/src/aiuse/collectors/runner.py +492 -0
  19. aiuse-2.1.0/src/aiuse/collectors/tokscale.py +118 -0
  20. aiuse-2.1.0/src/aiuse/config.py +457 -0
  21. aiuse-2.1.0/src/aiuse/models.py +363 -0
  22. aiuse-2.1.0/src/aiuse/report.py +1206 -0
  23. aiuse-2.1.0/src/aiuse/tui/__init__.py +58 -0
  24. aiuse-2.1.0/src/aiuse/tui/app.py +117 -0
  25. aiuse-2.1.0/src/aiuse/tui/builders.py +201 -0
  26. aiuse-2.1.0/src/aiuse.egg-info/PKG-INFO +331 -0
  27. aiuse-2.1.0/src/aiuse.egg-info/SOURCES.txt +42 -0
  28. aiuse-2.1.0/src/aiuse.egg-info/dependency_links.txt +1 -0
  29. aiuse-2.1.0/src/aiuse.egg-info/entry_points.txt +3 -0
  30. aiuse-2.1.0/src/aiuse.egg-info/requires.txt +10 -0
  31. aiuse-2.1.0/src/aiuse.egg-info/top_level.txt +1 -0
  32. aiuse-2.1.0/tests/test_base_run_json.py +79 -0
  33. aiuse-2.1.0/tests/test_cli.py +416 -0
  34. aiuse-2.1.0/tests/test_codexbar_parse.py +543 -0
  35. aiuse-2.1.0/tests/test_config.py +141 -0
  36. aiuse-2.1.0/tests/test_cswap_parse.py +307 -0
  37. aiuse-2.1.0/tests/test_history.py +371 -0
  38. aiuse-2.1.0/tests/test_models_pace.py +68 -0
  39. aiuse-2.1.0/tests/test_pace.py +206 -0
  40. aiuse-2.1.0/tests/test_report.py +662 -0
  41. aiuse-2.1.0/tests/test_runner_consolidation.py +244 -0
  42. aiuse-2.1.0/tests/test_tokscale_parse.py +44 -0
  43. aiuse-2.1.0/tests/test_tui.py +146 -0
  44. aiuse-2.1.0/tests/test_use_or_lose.py +993 -0
aiuse-2.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 djbclark
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
aiuse-2.1.0/PKG-INFO ADDED
@@ -0,0 +1,331 @@
1
+ Metadata-Version: 2.4
2
+ Name: aiuse
3
+ Version: 2.1.0
4
+ Summary: Aggregate AI subscription/API usage and flag use-it-or-lose-it allotments
5
+ Author: djbclark
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/djbclark/aiuse
8
+ Project-URL: Repository, https://github.com/djbclark/aiuse
9
+ Project-URL: Issues, https://github.com/djbclark/aiuse/issues
10
+ Project-URL: Changelog, https://github.com/djbclark/aiuse/releases
11
+ Keywords: ai,quota,claude,codex,copilot,cli
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: POSIX
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Utilities
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: pyyaml>=6.0
27
+ Requires-Dist: rich>=13.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: bandit>=1.7.9; extra == "dev"
30
+ Requires-Dist: mypy>=1.19; extra == "dev"
31
+ Requires-Dist: pre-commit>=4.0; extra == "dev"
32
+ Requires-Dist: pytest>=8.0; extra == "dev"
33
+ Requires-Dist: ruff>=0.15.21; extra == "dev"
34
+ Requires-Dist: yamllint>=1.35.1; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # aiuse
38
+
39
+ Aggregate live **subscription quota** and **prepaid balance** information across
40
+ your local AI tooling, then highlight allotments you should use **before they
41
+ reset** (use-it-or-lose-it).
42
+
43
+ CLI command: **`aiuse`** (stub **`ai`** → same entrypoint)
44
+
45
+ > **AI agents:** start at [`AGENTS.md`](AGENTS.md) for a map of this repo,
46
+ > active priorities, Claude/cswap reliability notes
47
+ > ([`docs/cswap-reliability.md`](docs/cswap-reliability.md)), and
48
+ > review-derived fixes in [`docs/fix-implementation-plan.md`](docs/fix-implementation-plan.md).
49
+
50
+ ## Data sources
51
+
52
+ | Tool | Purpose | Authority |
53
+ | ------------------------------------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
54
+ | [**cswap**](https://github.com/realiti4/claude-swap) `cswap list --json` | Live Claude Code quota for every configured email/account | Canonical multi-account Claude source; may hydrate from cswap’s local usage cache when JSON is decision-stale |
55
+ | [**CodexBar**](https://github.com/) `codexbar usage --format json` | Live quotas and balances for enabled providers | Preferred for non-Claude providers; Claude fallback if cswap has no live rows |
56
+ | [**tokscale**](https://www.npmjs.com/) `tokscale usage --json` | Independent live subscription quota measurement | Cross-checked against CodexBar (and Claude/cswap); selected when preferred source has no live row |
57
+
58
+ This project shells out to tools already on your `PATH`; it does not scrape billing dashboards itself. For Claude multi-account reliability (stale JSON vs cache), see [`docs/cswap-reliability.md`](docs/cswap-reliability.md).
59
+
60
+ ## Install
61
+
62
+ **End users (pipx):**
63
+
64
+ ```bash
65
+ pipx install aiuse
66
+ # until PyPI is live, or always from git tip:
67
+ # pipx install 'git+https://github.com/djbclark/aiuse.git'
68
+ aiuse doctor
69
+ ```
70
+
71
+ (`ai` is installed as a stub that runs the same CLI.)
72
+
73
+ **Homebrew (personal tap):**
74
+
75
+ ```bash
76
+ brew tap djbclark/aiuse
77
+ brew trust djbclark/aiuse
78
+ brew install aiuse
79
+ ```
80
+
81
+ **Developers (editable):**
82
+
83
+ ```bash
84
+ cd /path/to/aiuse
85
+ python3 -m venv .venv
86
+ source .venv/bin/activate
87
+ pip install -e ".[dev]"
88
+ ```
89
+
90
+ More channels: [`docs/packaging.md`](docs/packaging.md).
91
+
92
+ Optional config (standard location: **`~/.config/aiuse/`**, or `$XDG_CONFIG_HOME/aiuse/`):
93
+
94
+ ```bash
95
+ # Create directories + default files (never overwrites existing files)
96
+ aiuse --generate-config
97
+
98
+ # Or copy examples by hand:
99
+ mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse"
100
+ cp config/services.example.yaml "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse/services.yaml"
101
+ cp config/config.example.toml "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse/config.toml"
102
+ ```
103
+
104
+ | File | Purpose |
105
+ | ------------------------------- | ----------------------------------------------------------------------------- |
106
+ | `~/.config/aiuse/services.yaml` | Plans, analysis thresholds, which collectors are enabled |
107
+ | `~/.config/aiuse/config.toml` | Tool settings: subprocess **timeouts** (default **45s**), room for more later |
108
+
109
+ Run `aiuse --show-config-path` to print both paths. `aiuse --generate-config` creates
110
+ missing parent dirs (`~/.config`, `~/.config/aiuse`) and writes defaults; if a file
111
+ already exists it is left alone and reported on stderr. Provider credentials stay
112
+ with cswap, CodexBar, and tokscale — these files do not hold tokens or emails.
113
+
114
+ ## Daily workflow
115
+
116
+ ```bash
117
+ # Once: create defaults under ~/.config/aiuse/ (never overwrites)
118
+ aiuse --generate-config
119
+ aiuse doctor # PATH tools + config presence + timeouts
120
+
121
+ # Morning / before a long coding block
122
+ aiuse # priority ladder on stdout (use-soon at bottom); meta on stderr
123
+ aiuse --full # long report: per-provider, tips, detailed plan
124
+ aiuse --brief # same as default (compat alias)
125
+ aiuse --no-tui # classic plain-text report (also used when piping)
126
+ aiuse -q # ladder only (no stderr meta / Collecting…)
127
+
128
+ # Scripting / cron (JSON on stdout; use exit codes)
129
+ aiuse -q --json
130
+ # exit 0 = ok, no burn/conserve alerts
131
+ # exit 1 = hard failure (collectors failed, no accounts)
132
+ # exit 2 = success with at least one burn/conserve alert
133
+ # field contract: docs/json-contract.md
134
+
135
+ # Shell completion (bash or zsh)
136
+ eval "$(aiuse --print-completion bash)"
137
+ # or: source completions/ai.bash
138
+
139
+ # Tighter thresholds for “only what resets soon”
140
+ aiuse --min-remaining 50 --max-days 7
141
+ ```
142
+
143
+ ## Usage
144
+
145
+ ```bash
146
+ # Pretty human-readable report (default)
147
+ aiuse
148
+ aiuse --format pretty
149
+ aiuse --no-color # plain text, no ANSI
150
+ aiuse -q / --quiet # suppress progress on stderr
151
+
152
+ # or without install:
153
+ PYTHONPATH=src python -m ai
154
+
155
+ # Machine-readable JSON on stdout (progress on stderr unless -q)
156
+ aiuse --json
157
+ aiuse --format json
158
+ aiuse --json --alerts-only
159
+ aiuse --save ~/tmp/ai-snapshot.json # also write JSON file
160
+
161
+ # Faster / partial
162
+ aiuse --providers copilot,grok,codex # query these separately
163
+ aiuse --no-tokscale
164
+ aiuse --min-remaining 50 --max-days 10
165
+
166
+ # Subprocess timeout for external tools (default 45s; also in config.toml)
167
+ aiuse --timeout 45
168
+ aiuse -t45
169
+
170
+ # Environment check (tools on PATH, config files, timeouts) — no usage collection
171
+ aiuse doctor
172
+ aiuse --doctor
173
+ ```
174
+
175
+ | Flag | Effect |
176
+ | ------------------------------------------------ | -------------------------------------------------------------------------------- |
177
+ | _(none)_ / `--format pretty` | Priority ladder on stdout (empty→slow→mid→use); meta on stderr; plain when piped |
178
+ | `--full` | Long pretty report: per-provider, cross-checks, tips, detailed plan |
179
+ | `--json` / `--format json` | Full snapshot + alerts as JSON |
180
+ | `--brief` | Alias of default priority-ladder pretty report |
181
+ | `--no-tui` | Force classic plain-text pretty report |
182
+ | `--no-color` | Disable ANSI colors in plain-text pretty mode |
183
+ | `-q` / `--quiet` | Suppress progress messages on stderr |
184
+ | `--alerts-only` | Recommendations only (respects pretty vs json) |
185
+ | `--traditional-summary` | Legacy flat summary format instead of unified action plan |
186
+ | `--print-completion bash\|zsh` | Print shell completion script to stdout |
187
+ | `--no-tokscale` / `--no-cswap` / `--no-codexbar` | Skip specific collectors |
188
+ | `--providers copilot,grok` | Query specific CodexBar providers (CSV, one per subprocess) |
189
+ | `-t` / `--timeout SECONDS` | Force subprocess timeout for all external tools (default **45**) |
190
+ | `--generate-config` | Write default `~/.config/aiuse/*` files; never overwrites existing |
191
+ | `--show-config-path` | Print services.yaml and config.toml paths |
192
+ | `doctor` / `--doctor` | Check tools on PATH, config presence, effective timeouts; no collect |
193
+ | `--min-remaining 50 --max-days 10` | Override alert thresholds |
194
+ | `--save PATH` | Also write full JSON snapshot to PATH |
195
+
196
+ ### Exit codes
197
+
198
+ | Code | When |
199
+ | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
200
+ | **0** | Collect succeeded (or nothing to report) and there are **no** burn/conserve alerts. INFO-only notes still count as 0. |
201
+ | **1** | Hard failure: collectors reported errors and **no** accounts were collected. Also used by `aiuse doctor` when an **enabled** tool is missing from `PATH`, and by `--generate-config` when nothing was written / overwrite refused. |
202
+ | **2** | Collect succeeded and at least one **burn** or **conserve** alert is present. Cross-check disagreements alone do **not** set 2. Bad `--timeout` values also use 2. |
203
+
204
+ `aiuse doctor` checks config file presence, **config validation** (unknown keys, bad
205
+ timeouts, dead plan aliases), tools on `PATH`, and a light **version probe**
206
+ (`cswap --version`, `codexbar -V`, `tokscale --version`). It does **not** call
207
+ usage APIs or verify login sessions.
208
+
209
+ ## What “use it or lose it” means
210
+
211
+ Most **subscription** coding plans (Claude Pro/Max, ChatGPT Plus/Codex, Cursor, Copilot, SuperGrok, Google AI Pro, …) grant **windows** of usage (5-hour, weekly, monthly). When the window resets, **unused capacity disappears** — you still paid for the month.
212
+
213
+ This tool:
214
+
215
+ 1. Pulls **remaining %** and **reset times** from cswap for each distinct Claude Code account and from CodexBar/tokscale for other providers.
216
+ 2. Scores windows with **pace-based** logic (default): compare how far through the cycle you are vs how much you've used, then project waste or early lockout.
217
+ 3. Classifies each window as **Burn** (will leave capacity unused), **Conserve** (on track to exhaust before reset — slow down), or **On pace** (no alert).
218
+ 4. For **shared-allotment** providers (Claude, Gemini by default), scores the longest governing window only so a fresh 5-hour bar does not outrank the weekly budget it draws from.
219
+ 5. Default pretty output is a **priority ladder** on stdout (depleted → conserve → mid → use-soon at bottom; read bottom→top). Meta goes to stderr. Use `aiuse --full` for per-provider detail.
220
+ 6. On `--full`, keeps the trailing plan within ~**23 lines × console width** when possible; if the detailed plan is taller, both detailed and **at a glance** are printed (glance last).
221
+ 7. Cross-checks overlapping sources; Claude multi-account stays canonical in cswap (with cache hydrate + fallbacks).
222
+
223
+ This command intentionally does not report historical local-token usage or
224
+ API-equivalent cost estimates.
225
+
226
+ ## Example output
227
+
228
+ ```
229
+ ================================================================================
230
+ AI USAGE — USE IT OR LOSE IT
231
+ Collected at … · 3 accounts · 2 alerts
232
+ ================================================================================
233
+
234
+ ## Per-provider usage
235
+ --------------------------------------------------------------------------------
236
+ Codex · account=you@example.com · plan=plus · selected live source: CodexBar
237
+ quota: Codex weekly quota
238
+ [============] 100% left 0% used resets in 6.4d (Jul 28 21:59 UTC)
239
+ $6.90 · flex:▒ semi
240
+
241
+ ## Cross-checks (informational)
242
+ --------------------------------------------------------------------------------
243
+ Tools poll at different times; multi-account Claude is cswap-only. …
244
+
245
+ ## Tips
246
+ --------------------------------------------------------------------------------
247
+ • …
248
+
249
+ ## Action plan — use these before they reset
250
+ --------------------------------------------------------------------------------
251
+ Available capacity this cycle: $35.65 across 6 windows (5 providers).
252
+
253
+ THIS WEEK (start now — capacity will reset or needs lead time)
254
+ ─────────────────────────────────────────────────────────────
255
+ . Codex · you@example.com · Codex weekly quota: 88% left · use within 6.4 days · $6.07 at risk
256
+ Semi-throttled — steady usage will exhaust it.
257
+ . OpenCode Go · default · OpenCode Go weekly quota: 98% left · use within 4.5 days · $3.37 at risk
258
+ Burstable — one heavy session will cover it.
259
+ ```
260
+
261
+ ## Project layout
262
+
263
+ ```
264
+ src/aiuse/
265
+ cli.py # entrypoint
266
+ collectors/ # cswap, codexbar, tokscale
267
+ analysis/use_or_lose.py
268
+ report.py
269
+ config/services.example.yaml
270
+ tests/
271
+ ```
272
+
273
+ ## Tests
274
+
275
+ ```bash
276
+ just test
277
+ just check # tests plus deterministic lint, type, spelling, and format checks
278
+ just lint # full check plus Bandit, Semgrep, and Gitleaks
279
+ just format
280
+ ```
281
+
282
+ The quality suite mirrors the applicable tools from `stayturgid`: pytest, Ruff,
283
+ mypy, yamllint, markdownlint, Prettier (including TOML support), typos, Bandit,
284
+ Semgrep, Gitleaks, pre-commit, and `just`. Ansible, shell, JavaScript/CSS, dotenv,
285
+ Caddy, and browser-page checks are omitted because this repository contains none
286
+ of those corresponding inputs.
287
+
288
+ ## Scoring modes (`analysis.scoring_mode`)
289
+
290
+ | Mode | Meaning |
291
+ | -------------------- | ------------------------------------------------------------------------------- |
292
+ | **`pace`** (default) | Burn / conserve / on-pace from projected waste and lockout |
293
+ | **`multi_dim`** | Previous value + flexibility + deadline blend (escape hatch) |
294
+ | **`legacy`** | Original deadline-heavy scorer (`use_multi_dim_scoring: false` still maps here) |
295
+
296
+ Pace knobs (also in `services.yaml` under `analysis.pace`):
297
+
298
+ - `waste_alert_fraction` (default 0.30) — project this much unused → **Burn**
299
+ - `min_elapsed_fraction` (default 0.15) — too early in the window → **On pace** unless history says otherwise
300
+ - `conserve_min_lead_hours` (default 4) — exhaust this far before reset → **Conserve**
301
+
302
+ Shared allotment: `analysis.provider_overrides.<provider>.shared_allotment: true` (Claude/Gemini default) scores only the longest window per account.
303
+
304
+ ## Notes / limitations
305
+
306
+ - Live quota accuracy depends on each tool's auth (browser cookies, OAuth, keychain). Errors are reported per account rather than aborting the whole run.
307
+ - cswap, CodexBar, and tokscale run concurrently; each CodexBar provider is its own subprocess. Default tool timeout is **45s** (`-t` / `config.toml [timeouts]`).
308
+ - Per-window detail still shows $ value, flexibility class, and a **pace** ratio when computable.
309
+ - Duplicate live measurements are retained for cross-checking but only one copy drives recommendations.
310
+ - Dollar values use plan `monthly_price` with waking-hours correction (default 16h/day).
311
+
312
+ ## Related reading
313
+
314
+ - [`docs/consumption-flexibility-plan.md`](docs/consumption-flexibility-plan.md) — historical multi-dimensional scoring design (**superseded** by pace-based scoring in Phase 2 of the fix plan).
315
+ - [`docs/code-review-2026-07-23.html`](docs/code-review-2026-07-23.html) — a 79-agent adversarial code review (45 findings) plus design proposals for containing tokscale's collector timeouts and fixing the rating algorithm. Open it directly in a browser for the styled version; GitHub's file viewer only shows the source.
316
+ - [`docs/fix-implementation-plan.md`](docs/fix-implementation-plan.md) — review-derived fix plan (Steps **1–32** and **34** done; Phase 7 optional 33/35 remain). Start at [`AGENTS.md`](AGENTS.md) for current priorities, not Step 1.
317
+ - [Issue #1](https://github.com/djbclark/aiuse/issues/1) — track consuming upstream cswap display-grade last-good JSON ([claude-swap#170](https://github.com/realiti4/claude-swap/issues/170)).
318
+ - [`docs/cswap-reliability.md`](docs/cswap-reliability.md) — Claude multi-account reliability: why `cswap list --json` can drop usable quota, and how cache hydration + fallbacks work.
319
+ - [`docs/opencode-go-quota.md`](docs/opencode-go-quota.md) — OpenCode Go: why CodexBar `auto`/local can show remaining % when the TUI says limit reached, and how `aiuse` prefers web.
320
+ - [`docs/cursor-quota.md`](docs/cursor-quota.md) — Cursor Included/Auto/API + on-demand vs CodexBar slots.
321
+ - [`docs/pretty-display.md`](docs/pretty-display.md) — why pretty output uses Rich (not Textual / not Rich `Layout`) so the full report stays in scrollback.
322
+ - [`docs/packaging.md`](docs/packaging.md) — pipx / PyPI / Homebrew notes.
323
+ - [`docs/claude-local-usage.md`](docs/claude-local-usage.md) — Local Claude Code files / ccusage (token burn) vs subscription 5h/7d % from the OAuth usage API.
324
+ - [`docs/tokscale-per-provider-investigation.md`](docs/tokscale-per-provider-investigation.md) — why tokscale cannot yet fan out per provider like CodexBar.
325
+ - [`docs/json-contract.md`](docs/json-contract.md) — stable JSON fields and exit codes for scripts.
326
+ - [`docs/collector-concurrency.md`](docs/collector-concurrency.md) — parallel collect + 45s timeout audit.
327
+ - [`docs/handoff.md`](docs/handoff.md) — latest session wrap-up and loose ends (for agents and future you).
328
+ - [`completions/`](completions/) — bash/zsh completion (`aiuse --print-completion bash`).
329
+ - [`docs/review-workflow.js`](docs/review-workflow.js) — the Claude Code Workflow script that generated the review, checked in for reproducibility.
330
+ - [`docs/memory/`](docs/memory/) — thin Claude symlink target for this project; see `AGENTS.md` for persistence policy and links to `~/ops/site-private` generic memory.
331
+ - Local quota dashboards in the same category as OpenUsage / CodexBar menu bar tools
aiuse-2.1.0/README.md ADDED
@@ -0,0 +1,295 @@
1
+ # aiuse
2
+
3
+ Aggregate live **subscription quota** and **prepaid balance** information across
4
+ your local AI tooling, then highlight allotments you should use **before they
5
+ reset** (use-it-or-lose-it).
6
+
7
+ CLI command: **`aiuse`** (stub **`ai`** → same entrypoint)
8
+
9
+ > **AI agents:** start at [`AGENTS.md`](AGENTS.md) for a map of this repo,
10
+ > active priorities, Claude/cswap reliability notes
11
+ > ([`docs/cswap-reliability.md`](docs/cswap-reliability.md)), and
12
+ > review-derived fixes in [`docs/fix-implementation-plan.md`](docs/fix-implementation-plan.md).
13
+
14
+ ## Data sources
15
+
16
+ | Tool | Purpose | Authority |
17
+ | ------------------------------------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
18
+ | [**cswap**](https://github.com/realiti4/claude-swap) `cswap list --json` | Live Claude Code quota for every configured email/account | Canonical multi-account Claude source; may hydrate from cswap’s local usage cache when JSON is decision-stale |
19
+ | [**CodexBar**](https://github.com/) `codexbar usage --format json` | Live quotas and balances for enabled providers | Preferred for non-Claude providers; Claude fallback if cswap has no live rows |
20
+ | [**tokscale**](https://www.npmjs.com/) `tokscale usage --json` | Independent live subscription quota measurement | Cross-checked against CodexBar (and Claude/cswap); selected when preferred source has no live row |
21
+
22
+ This project shells out to tools already on your `PATH`; it does not scrape billing dashboards itself. For Claude multi-account reliability (stale JSON vs cache), see [`docs/cswap-reliability.md`](docs/cswap-reliability.md).
23
+
24
+ ## Install
25
+
26
+ **End users (pipx):**
27
+
28
+ ```bash
29
+ pipx install aiuse
30
+ # until PyPI is live, or always from git tip:
31
+ # pipx install 'git+https://github.com/djbclark/aiuse.git'
32
+ aiuse doctor
33
+ ```
34
+
35
+ (`ai` is installed as a stub that runs the same CLI.)
36
+
37
+ **Homebrew (personal tap):**
38
+
39
+ ```bash
40
+ brew tap djbclark/aiuse
41
+ brew trust djbclark/aiuse
42
+ brew install aiuse
43
+ ```
44
+
45
+ **Developers (editable):**
46
+
47
+ ```bash
48
+ cd /path/to/aiuse
49
+ python3 -m venv .venv
50
+ source .venv/bin/activate
51
+ pip install -e ".[dev]"
52
+ ```
53
+
54
+ More channels: [`docs/packaging.md`](docs/packaging.md).
55
+
56
+ Optional config (standard location: **`~/.config/aiuse/`**, or `$XDG_CONFIG_HOME/aiuse/`):
57
+
58
+ ```bash
59
+ # Create directories + default files (never overwrites existing files)
60
+ aiuse --generate-config
61
+
62
+ # Or copy examples by hand:
63
+ mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse"
64
+ cp config/services.example.yaml "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse/services.yaml"
65
+ cp config/config.example.toml "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse/config.toml"
66
+ ```
67
+
68
+ | File | Purpose |
69
+ | ------------------------------- | ----------------------------------------------------------------------------- |
70
+ | `~/.config/aiuse/services.yaml` | Plans, analysis thresholds, which collectors are enabled |
71
+ | `~/.config/aiuse/config.toml` | Tool settings: subprocess **timeouts** (default **45s**), room for more later |
72
+
73
+ Run `aiuse --show-config-path` to print both paths. `aiuse --generate-config` creates
74
+ missing parent dirs (`~/.config`, `~/.config/aiuse`) and writes defaults; if a file
75
+ already exists it is left alone and reported on stderr. Provider credentials stay
76
+ with cswap, CodexBar, and tokscale — these files do not hold tokens or emails.
77
+
78
+ ## Daily workflow
79
+
80
+ ```bash
81
+ # Once: create defaults under ~/.config/aiuse/ (never overwrites)
82
+ aiuse --generate-config
83
+ aiuse doctor # PATH tools + config presence + timeouts
84
+
85
+ # Morning / before a long coding block
86
+ aiuse # priority ladder on stdout (use-soon at bottom); meta on stderr
87
+ aiuse --full # long report: per-provider, tips, detailed plan
88
+ aiuse --brief # same as default (compat alias)
89
+ aiuse --no-tui # classic plain-text report (also used when piping)
90
+ aiuse -q # ladder only (no stderr meta / Collecting…)
91
+
92
+ # Scripting / cron (JSON on stdout; use exit codes)
93
+ aiuse -q --json
94
+ # exit 0 = ok, no burn/conserve alerts
95
+ # exit 1 = hard failure (collectors failed, no accounts)
96
+ # exit 2 = success with at least one burn/conserve alert
97
+ # field contract: docs/json-contract.md
98
+
99
+ # Shell completion (bash or zsh)
100
+ eval "$(aiuse --print-completion bash)"
101
+ # or: source completions/ai.bash
102
+
103
+ # Tighter thresholds for “only what resets soon”
104
+ aiuse --min-remaining 50 --max-days 7
105
+ ```
106
+
107
+ ## Usage
108
+
109
+ ```bash
110
+ # Pretty human-readable report (default)
111
+ aiuse
112
+ aiuse --format pretty
113
+ aiuse --no-color # plain text, no ANSI
114
+ aiuse -q / --quiet # suppress progress on stderr
115
+
116
+ # or without install:
117
+ PYTHONPATH=src python -m ai
118
+
119
+ # Machine-readable JSON on stdout (progress on stderr unless -q)
120
+ aiuse --json
121
+ aiuse --format json
122
+ aiuse --json --alerts-only
123
+ aiuse --save ~/tmp/ai-snapshot.json # also write JSON file
124
+
125
+ # Faster / partial
126
+ aiuse --providers copilot,grok,codex # query these separately
127
+ aiuse --no-tokscale
128
+ aiuse --min-remaining 50 --max-days 10
129
+
130
+ # Subprocess timeout for external tools (default 45s; also in config.toml)
131
+ aiuse --timeout 45
132
+ aiuse -t45
133
+
134
+ # Environment check (tools on PATH, config files, timeouts) — no usage collection
135
+ aiuse doctor
136
+ aiuse --doctor
137
+ ```
138
+
139
+ | Flag | Effect |
140
+ | ------------------------------------------------ | -------------------------------------------------------------------------------- |
141
+ | _(none)_ / `--format pretty` | Priority ladder on stdout (empty→slow→mid→use); meta on stderr; plain when piped |
142
+ | `--full` | Long pretty report: per-provider, cross-checks, tips, detailed plan |
143
+ | `--json` / `--format json` | Full snapshot + alerts as JSON |
144
+ | `--brief` | Alias of default priority-ladder pretty report |
145
+ | `--no-tui` | Force classic plain-text pretty report |
146
+ | `--no-color` | Disable ANSI colors in plain-text pretty mode |
147
+ | `-q` / `--quiet` | Suppress progress messages on stderr |
148
+ | `--alerts-only` | Recommendations only (respects pretty vs json) |
149
+ | `--traditional-summary` | Legacy flat summary format instead of unified action plan |
150
+ | `--print-completion bash\|zsh` | Print shell completion script to stdout |
151
+ | `--no-tokscale` / `--no-cswap` / `--no-codexbar` | Skip specific collectors |
152
+ | `--providers copilot,grok` | Query specific CodexBar providers (CSV, one per subprocess) |
153
+ | `-t` / `--timeout SECONDS` | Force subprocess timeout for all external tools (default **45**) |
154
+ | `--generate-config` | Write default `~/.config/aiuse/*` files; never overwrites existing |
155
+ | `--show-config-path` | Print services.yaml and config.toml paths |
156
+ | `doctor` / `--doctor` | Check tools on PATH, config presence, effective timeouts; no collect |
157
+ | `--min-remaining 50 --max-days 10` | Override alert thresholds |
158
+ | `--save PATH` | Also write full JSON snapshot to PATH |
159
+
160
+ ### Exit codes
161
+
162
+ | Code | When |
163
+ | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
164
+ | **0** | Collect succeeded (or nothing to report) and there are **no** burn/conserve alerts. INFO-only notes still count as 0. |
165
+ | **1** | Hard failure: collectors reported errors and **no** accounts were collected. Also used by `aiuse doctor` when an **enabled** tool is missing from `PATH`, and by `--generate-config` when nothing was written / overwrite refused. |
166
+ | **2** | Collect succeeded and at least one **burn** or **conserve** alert is present. Cross-check disagreements alone do **not** set 2. Bad `--timeout` values also use 2. |
167
+
168
+ `aiuse doctor` checks config file presence, **config validation** (unknown keys, bad
169
+ timeouts, dead plan aliases), tools on `PATH`, and a light **version probe**
170
+ (`cswap --version`, `codexbar -V`, `tokscale --version`). It does **not** call
171
+ usage APIs or verify login sessions.
172
+
173
+ ## What “use it or lose it” means
174
+
175
+ Most **subscription** coding plans (Claude Pro/Max, ChatGPT Plus/Codex, Cursor, Copilot, SuperGrok, Google AI Pro, …) grant **windows** of usage (5-hour, weekly, monthly). When the window resets, **unused capacity disappears** — you still paid for the month.
176
+
177
+ This tool:
178
+
179
+ 1. Pulls **remaining %** and **reset times** from cswap for each distinct Claude Code account and from CodexBar/tokscale for other providers.
180
+ 2. Scores windows with **pace-based** logic (default): compare how far through the cycle you are vs how much you've used, then project waste or early lockout.
181
+ 3. Classifies each window as **Burn** (will leave capacity unused), **Conserve** (on track to exhaust before reset — slow down), or **On pace** (no alert).
182
+ 4. For **shared-allotment** providers (Claude, Gemini by default), scores the longest governing window only so a fresh 5-hour bar does not outrank the weekly budget it draws from.
183
+ 5. Default pretty output is a **priority ladder** on stdout (depleted → conserve → mid → use-soon at bottom; read bottom→top). Meta goes to stderr. Use `aiuse --full` for per-provider detail.
184
+ 6. On `--full`, keeps the trailing plan within ~**23 lines × console width** when possible; if the detailed plan is taller, both detailed and **at a glance** are printed (glance last).
185
+ 7. Cross-checks overlapping sources; Claude multi-account stays canonical in cswap (with cache hydrate + fallbacks).
186
+
187
+ This command intentionally does not report historical local-token usage or
188
+ API-equivalent cost estimates.
189
+
190
+ ## Example output
191
+
192
+ ```
193
+ ================================================================================
194
+ AI USAGE — USE IT OR LOSE IT
195
+ Collected at … · 3 accounts · 2 alerts
196
+ ================================================================================
197
+
198
+ ## Per-provider usage
199
+ --------------------------------------------------------------------------------
200
+ Codex · account=you@example.com · plan=plus · selected live source: CodexBar
201
+ quota: Codex weekly quota
202
+ [============] 100% left 0% used resets in 6.4d (Jul 28 21:59 UTC)
203
+ $6.90 · flex:▒ semi
204
+
205
+ ## Cross-checks (informational)
206
+ --------------------------------------------------------------------------------
207
+ Tools poll at different times; multi-account Claude is cswap-only. …
208
+
209
+ ## Tips
210
+ --------------------------------------------------------------------------------
211
+ • …
212
+
213
+ ## Action plan — use these before they reset
214
+ --------------------------------------------------------------------------------
215
+ Available capacity this cycle: $35.65 across 6 windows (5 providers).
216
+
217
+ THIS WEEK (start now — capacity will reset or needs lead time)
218
+ ─────────────────────────────────────────────────────────────
219
+ . Codex · you@example.com · Codex weekly quota: 88% left · use within 6.4 days · $6.07 at risk
220
+ Semi-throttled — steady usage will exhaust it.
221
+ . OpenCode Go · default · OpenCode Go weekly quota: 98% left · use within 4.5 days · $3.37 at risk
222
+ Burstable — one heavy session will cover it.
223
+ ```
224
+
225
+ ## Project layout
226
+
227
+ ```
228
+ src/aiuse/
229
+ cli.py # entrypoint
230
+ collectors/ # cswap, codexbar, tokscale
231
+ analysis/use_or_lose.py
232
+ report.py
233
+ config/services.example.yaml
234
+ tests/
235
+ ```
236
+
237
+ ## Tests
238
+
239
+ ```bash
240
+ just test
241
+ just check # tests plus deterministic lint, type, spelling, and format checks
242
+ just lint # full check plus Bandit, Semgrep, and Gitleaks
243
+ just format
244
+ ```
245
+
246
+ The quality suite mirrors the applicable tools from `stayturgid`: pytest, Ruff,
247
+ mypy, yamllint, markdownlint, Prettier (including TOML support), typos, Bandit,
248
+ Semgrep, Gitleaks, pre-commit, and `just`. Ansible, shell, JavaScript/CSS, dotenv,
249
+ Caddy, and browser-page checks are omitted because this repository contains none
250
+ of those corresponding inputs.
251
+
252
+ ## Scoring modes (`analysis.scoring_mode`)
253
+
254
+ | Mode | Meaning |
255
+ | -------------------- | ------------------------------------------------------------------------------- |
256
+ | **`pace`** (default) | Burn / conserve / on-pace from projected waste and lockout |
257
+ | **`multi_dim`** | Previous value + flexibility + deadline blend (escape hatch) |
258
+ | **`legacy`** | Original deadline-heavy scorer (`use_multi_dim_scoring: false` still maps here) |
259
+
260
+ Pace knobs (also in `services.yaml` under `analysis.pace`):
261
+
262
+ - `waste_alert_fraction` (default 0.30) — project this much unused → **Burn**
263
+ - `min_elapsed_fraction` (default 0.15) — too early in the window → **On pace** unless history says otherwise
264
+ - `conserve_min_lead_hours` (default 4) — exhaust this far before reset → **Conserve**
265
+
266
+ Shared allotment: `analysis.provider_overrides.<provider>.shared_allotment: true` (Claude/Gemini default) scores only the longest window per account.
267
+
268
+ ## Notes / limitations
269
+
270
+ - Live quota accuracy depends on each tool's auth (browser cookies, OAuth, keychain). Errors are reported per account rather than aborting the whole run.
271
+ - cswap, CodexBar, and tokscale run concurrently; each CodexBar provider is its own subprocess. Default tool timeout is **45s** (`-t` / `config.toml [timeouts]`).
272
+ - Per-window detail still shows $ value, flexibility class, and a **pace** ratio when computable.
273
+ - Duplicate live measurements are retained for cross-checking but only one copy drives recommendations.
274
+ - Dollar values use plan `monthly_price` with waking-hours correction (default 16h/day).
275
+
276
+ ## Related reading
277
+
278
+ - [`docs/consumption-flexibility-plan.md`](docs/consumption-flexibility-plan.md) — historical multi-dimensional scoring design (**superseded** by pace-based scoring in Phase 2 of the fix plan).
279
+ - [`docs/code-review-2026-07-23.html`](docs/code-review-2026-07-23.html) — a 79-agent adversarial code review (45 findings) plus design proposals for containing tokscale's collector timeouts and fixing the rating algorithm. Open it directly in a browser for the styled version; GitHub's file viewer only shows the source.
280
+ - [`docs/fix-implementation-plan.md`](docs/fix-implementation-plan.md) — review-derived fix plan (Steps **1–32** and **34** done; Phase 7 optional 33/35 remain). Start at [`AGENTS.md`](AGENTS.md) for current priorities, not Step 1.
281
+ - [Issue #1](https://github.com/djbclark/aiuse/issues/1) — track consuming upstream cswap display-grade last-good JSON ([claude-swap#170](https://github.com/realiti4/claude-swap/issues/170)).
282
+ - [`docs/cswap-reliability.md`](docs/cswap-reliability.md) — Claude multi-account reliability: why `cswap list --json` can drop usable quota, and how cache hydration + fallbacks work.
283
+ - [`docs/opencode-go-quota.md`](docs/opencode-go-quota.md) — OpenCode Go: why CodexBar `auto`/local can show remaining % when the TUI says limit reached, and how `aiuse` prefers web.
284
+ - [`docs/cursor-quota.md`](docs/cursor-quota.md) — Cursor Included/Auto/API + on-demand vs CodexBar slots.
285
+ - [`docs/pretty-display.md`](docs/pretty-display.md) — why pretty output uses Rich (not Textual / not Rich `Layout`) so the full report stays in scrollback.
286
+ - [`docs/packaging.md`](docs/packaging.md) — pipx / PyPI / Homebrew notes.
287
+ - [`docs/claude-local-usage.md`](docs/claude-local-usage.md) — Local Claude Code files / ccusage (token burn) vs subscription 5h/7d % from the OAuth usage API.
288
+ - [`docs/tokscale-per-provider-investigation.md`](docs/tokscale-per-provider-investigation.md) — why tokscale cannot yet fan out per provider like CodexBar.
289
+ - [`docs/json-contract.md`](docs/json-contract.md) — stable JSON fields and exit codes for scripts.
290
+ - [`docs/collector-concurrency.md`](docs/collector-concurrency.md) — parallel collect + 45s timeout audit.
291
+ - [`docs/handoff.md`](docs/handoff.md) — latest session wrap-up and loose ends (for agents and future you).
292
+ - [`completions/`](completions/) — bash/zsh completion (`aiuse --print-completion bash`).
293
+ - [`docs/review-workflow.js`](docs/review-workflow.js) — the Claude Code Workflow script that generated the review, checked in for reproducibility.
294
+ - [`docs/memory/`](docs/memory/) — thin Claude symlink target for this project; see `AGENTS.md` for persistence policy and links to `~/ops/site-private` generic memory.
295
+ - Local quota dashboards in the same category as OpenUsage / CodexBar menu bar tools