quota-axi 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/dist/bin/quota-axi.d.ts +2 -0
- package/dist/bin/quota-axi.js +4 -0
- package/dist/bin/quota-axi.js.map +1 -0
- package/dist/src/cache.d.ts +3 -0
- package/dist/src/cache.js +198 -0
- package/dist/src/cache.js.map +1 -0
- package/dist/src/cli.d.ts +18 -0
- package/dist/src/cli.js +152 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/lib/fs.d.ts +14 -0
- package/dist/src/lib/fs.js +72 -0
- package/dist/src/lib/fs.js.map +1 -0
- package/dist/src/lib/process.d.ts +4 -0
- package/dist/src/lib/process.js +77 -0
- package/dist/src/lib/process.js.map +1 -0
- package/dist/src/lib/time.d.ts +5 -0
- package/dist/src/lib/time.js +38 -0
- package/dist/src/lib/time.js.map +1 -0
- package/dist/src/providers/claude.d.ts +9 -0
- package/dist/src/providers/claude.js +425 -0
- package/dist/src/providers/claude.js.map +1 -0
- package/dist/src/providers/codex.d.ts +12 -0
- package/dist/src/providers/codex.js +501 -0
- package/dist/src/providers/codex.js.map +1 -0
- package/dist/src/providers/common.d.ts +19 -0
- package/dist/src/providers/common.js +61 -0
- package/dist/src/providers/common.js.map +1 -0
- package/dist/src/providers/index.d.ts +3 -0
- package/dist/src/providers/index.js +20 -0
- package/dist/src/providers/index.js.map +1 -0
- package/dist/src/render.d.ts +6 -0
- package/dist/src/render.js +94 -0
- package/dist/src/render.js.map +1 -0
- package/dist/src/types.d.ts +70 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kun Chen
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<h1 align="center">quota-axi</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/quota-axi"><img alt="npm" src="https://img.shields.io/npm/v/quota-axi?style=flat-square" /></a>
|
|
5
|
+
<a href="https://github.com/kunchenguid/quota-axi/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/kunchenguid/quota-axi/ci.yml?style=flat-square&label=ci" /></a>
|
|
6
|
+
<a href="https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-blue?style=flat-square"><img alt="Platform" src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-blue?style=flat-square" /></a>
|
|
7
|
+
<a href="https://x.com/kunchenguid"><img alt="X" src="https://img.shields.io/badge/X-@kunchenguid-black?style=flat-square" /></a>
|
|
8
|
+
<a href="https://discord.gg/Wsy2NpnZDu"><img alt="Discord" src="https://img.shields.io/discord/1439901831038763092?style=flat-square&label=discord" /></a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<h3 align="center">Know your local agent quota headroom without turning it into routing advice.</h3>
|
|
12
|
+
|
|
13
|
+
Agents need quota state before they choose where work can safely run.
|
|
14
|
+
Vendor dashboards are not shaped for shell automation, and local CLIs expose different windows, resets, and auth files.
|
|
15
|
+
|
|
16
|
+
quota-axi reports local Claude and Codex quota windows in one AXI-shaped call.
|
|
17
|
+
It is data only: it never routes, recommends, proxies, intercepts, logs in, imports browser cookies, or mutates provider state.
|
|
18
|
+
|
|
19
|
+
- **Honest comparison ceiling** - quota-axi reports normalized quota windows, reset times, and provider credit balances when available.
|
|
20
|
+
- **Local first** - it reads local Claude and Codex auth sources, calls first-party provider endpoints, and can fall back to a read-only Codex app-server probe.
|
|
21
|
+
- **Agent shaped** - default stdout is compact TOON, with JSON available for callers that need the normalized model.
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
$ npx -y quota-axi
|
|
27
|
+
bin: ~/.npm/_npx/.../quota-axi
|
|
28
|
+
description: Report local agent-provider quota windows for routing-aware agents
|
|
29
|
+
generatedAt: "2026-07-06T18:10:00.000Z"
|
|
30
|
+
providers[2]{provider,plan,source,status,refreshedAt}:
|
|
31
|
+
claude,pro,oauth,fresh,"2026-07-06T18:09:55.000Z"
|
|
32
|
+
codex,plus,cli-rpc,fresh,"2026-07-06T18:09:58.000Z"
|
|
33
|
+
windows[6]{provider,id,label,percentRemaining,resetsAt,state}:
|
|
34
|
+
claude,five_hour,session,82,"2026-07-06T22:15:00.000Z",fresh
|
|
35
|
+
claude,seven_day,week,64,"2026-07-10T16:00:00.000Z",fresh
|
|
36
|
+
claude,seven_day_opus,opus week,93,"2026-07-11T09:30:00.000Z",fresh
|
|
37
|
+
claude,extra_usage,extra usage,75,unknown,fresh
|
|
38
|
+
codex,five_hour,session,71,"2026-07-06T21:45:00.000Z",fresh
|
|
39
|
+
codex,weekly,week,43,"2026-07-11T09:00:00.000Z",fresh
|
|
40
|
+
help[3]:
|
|
41
|
+
Run `quota-axi --provider claude --json` for JSON output
|
|
42
|
+
Run `quota-axi --full` to include account and source-attempt details
|
|
43
|
+
Run `quota-axi auth` to inspect local auth source availability without printing secrets
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
$ quota-axi auth
|
|
48
|
+
bin: ~/.npm/_npx/.../quota-axi
|
|
49
|
+
description: Inspect local quota auth sources without printing secret values
|
|
50
|
+
auth[4]{provider,source,path,status,error}:
|
|
51
|
+
claude,oauth-file,~/.claude/.credentials.json,available,none
|
|
52
|
+
claude,keychain,none,skipped,keychain_prompt_required
|
|
53
|
+
codex,auth-json,~/.codex/auth.json,available,none
|
|
54
|
+
codex,cli-rpc,none,available,none
|
|
55
|
+
help[1]:
|
|
56
|
+
Run `quota-axi --allow-keychain-prompt auth` to permit macOS Keychain access
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
quota-axi requires Node.js 20 or newer.
|
|
62
|
+
|
|
63
|
+
**npm**
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
npm install -g quota-axi
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Direct use**
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
npx -y quota-axi
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**From source**
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
git clone https://github.com/kunchenguid/quota-axi.git
|
|
79
|
+
cd quota-axi
|
|
80
|
+
pnpm install
|
|
81
|
+
pnpm run build
|
|
82
|
+
pnpm run dev
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## How It Works
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
┌────────────┐
|
|
89
|
+
│ quota-axi │
|
|
90
|
+
└─────┬──────┘
|
|
91
|
+
▼
|
|
92
|
+
┌───────────────┐
|
|
93
|
+
│ claude,codex │
|
|
94
|
+
└─────┬─────────┘
|
|
95
|
+
▼
|
|
96
|
+
┌───────────────┐ ┌──────────────┐
|
|
97
|
+
│ local auth │ ───▶ │ first-party │
|
|
98
|
+
│ sources │ │ usage APIs │
|
|
99
|
+
└─────┬─────────┘ └──────┬───────┘
|
|
100
|
+
▼ ▼
|
|
101
|
+
┌───────────────┐ ┌──────────────┐
|
|
102
|
+
│ codex-only │ ───▶ │ normalized │
|
|
103
|
+
│ CLI fallback │ │ quota model │
|
|
104
|
+
└─────┬─────────┘ └──────┬───────┘
|
|
105
|
+
▼ ▼
|
|
106
|
+
┌───────────────┐ ┌──────────────┐
|
|
107
|
+
│ stale cache │ ◀─── │ TOON or JSON │
|
|
108
|
+
└───────────────┘ └──────────────┘
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- **Live first** - direct provider usage calls use 15 second request timeouts, Codex JSON-RPC reads use short per-call timeouts, and stale cache fallback is per provider.
|
|
112
|
+
- **No default Keychain prompt** - macOS Claude Keychain reads are skipped unless `--allow-keychain-prompt` is passed.
|
|
113
|
+
- **Partial success is success** - one provider can fail while another returns fresh or stale data, and the process still exits 0. Exit code 1 means every provider failed, and 2 means a usage error.
|
|
114
|
+
- **No token equivalence** - quota-axi does not claim that one provider percentage equals another provider percentage.
|
|
115
|
+
|
|
116
|
+
## CLI Reference
|
|
117
|
+
|
|
118
|
+
| Command | Description |
|
|
119
|
+
| ----------- | ------------------------------------------------ |
|
|
120
|
+
| `quota-axi` | Report Claude and Codex quota windows |
|
|
121
|
+
| `auth` | Report local auth-source availability, no values |
|
|
122
|
+
|
|
123
|
+
### Flags
|
|
124
|
+
|
|
125
|
+
| Flag | Description |
|
|
126
|
+
| ------------------------- | ------------------------------------------------------ |
|
|
127
|
+
| `--provider claude,codex` | Scope providers |
|
|
128
|
+
| `--json` | Emit normalized JSON instead of TOON for quota or auth |
|
|
129
|
+
| `--full` | Include quota account identity and source attempts |
|
|
130
|
+
| `--allow-keychain-prompt` | Permit macOS Claude Keychain access that could prompt |
|
|
131
|
+
| `-h`, `--help` | Print terse AXI help |
|
|
132
|
+
| `-v`, `-V`, `--version` | Print version |
|
|
133
|
+
|
|
134
|
+
## Output Model
|
|
135
|
+
|
|
136
|
+
`--json` emits `schemaVersion: 1`.
|
|
137
|
+
Quota reports contain `providers`, each with `provider`, `label`, `source`, `windows`, `state`, optional `plan`, and optional `credits`.
|
|
138
|
+
With `--full`, providers can also include `account` identity and per-source `attempts`.
|
|
139
|
+
Provider `state` includes `status`, `stale`, `sourcesTried`, optional `refreshedAt`, optional `error`, and optional `retryAfter`.
|
|
140
|
+
Quota windows include `id`, `label`, `kind`, optional percentages, optional reset fields, optional `windowSeconds`, and optional credit-spend fields.
|
|
141
|
+
Account identity and per-source `attempts` are omitted unless `--full` is passed.
|
|
142
|
+
Provider statuses are `fresh`, `stale`, `unavailable`, `auth_required`, `rate_limited`, or `error`.
|
|
143
|
+
Provider sources are `oauth`, `cli-rpc`, `api`, `web`, `cache`, or `unavailable`; v1 emits `oauth`, `cli-rpc`, `cache`, and `unavailable`.
|
|
144
|
+
Window kinds are `session`, `weekly`, `monthly`, `model`, `credits`, or `unknown`.
|
|
145
|
+
Source attempts use `success`, `failed`, or `skipped`.
|
|
146
|
+
Claude can report `five_hour`, `seven_day`, optional `seven_day_opus`, and optional `extra_usage` windows.
|
|
147
|
+
When the account's usage response includes a scoped `limits` list, quota-axi surfaces every active window it describes instead, including model-scoped ones (e.g. Fable) as a `model:<slug>` window.
|
|
148
|
+
Codex can report `five_hour` and `weekly` windows plus optional credit balance data, plus any additional model- or feature-scoped rate limits the account has as `model:<id>:5h` / `model:<id>:7d` windows, and an optional code-review rate limit as `code_review_five_hour` / `code_review_weekly`.
|
|
149
|
+
`auth --json` emits `generatedAt`, `schemaVersion: 1`, and `auth`, where each provider report has `provider` and `sources`.
|
|
150
|
+
Auth source entries include `source`, optional `path`, `status`, and optional `error`.
|
|
151
|
+
Auth source statuses are `available`, `missing`, `invalid`, `expired`, or `skipped`.
|
|
152
|
+
Auth source names are `oauth-file`, `keychain`, `auth-json`, and `cli-rpc`.
|
|
153
|
+
|
|
154
|
+
## Security Posture
|
|
155
|
+
|
|
156
|
+
quota-axi reads `~/.claude/.credentials.json` for Claude.
|
|
157
|
+
On macOS, it reads `Claude Code-credentials` from Keychain only with `--allow-keychain-prompt`; when enabled, the Keychain credential is tried before file credentials.
|
|
158
|
+
For Codex, it reads `$CODEX_HOME/auth.json` or `~/.codex/auth.json` before the read-only CLI fallback.
|
|
159
|
+
Codex `auth.json` support is OAuth-token only; API key values such as `OPENAI_API_KEY` are treated as invalid for quota usage calls and are not sent to ChatGPT usage endpoints.
|
|
160
|
+
It may run `codex -s read-only -a untrusted app-server` for Codex JSON-RPC fallback.
|
|
161
|
+
It never launches the Claude CLI, so it cannot accidentally spend the quota it measures.
|
|
162
|
+
|
|
163
|
+
Direct HTTP requests go only to Anthropic and OpenAI first-party usage endpoints with the user's local credentials.
|
|
164
|
+
It sends credential values only to the first-party provider request they authenticate.
|
|
165
|
+
It never prints, logs, or caches credential values.
|
|
166
|
+
The cache lives at `~/.cache/quota-axi/quotas.json` (or under `$XDG_CACHE_HOME/quota-axi/` when `XDG_CACHE_HOME` is set), uses `0600` file permissions, and stores normalized non-secret snapshots only.
|
|
167
|
+
Only fresh provider snapshots with windows are cached.
|
|
168
|
+
Failed providers, stale providers, account identity, and source attempts are not cached.
|
|
169
|
+
|
|
170
|
+
## Development
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
pnpm install # Install dependencies
|
|
174
|
+
pnpm run build # Compile TypeScript to dist/
|
|
175
|
+
pnpm test # Run fixture parser and CLI tests
|
|
176
|
+
pnpm run dev # Run the CLI with tsx
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Attribution
|
|
180
|
+
|
|
181
|
+
quota-axi is independently implemented from local Baby Menu quota code and public provider behavior references.
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-axi.js","sourceRoot":"","sources":["../../bin/quota-axi.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { chmodSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { cacheFilePath, ensurePrivateParent, readJsonFile } from "./lib/fs.js";
|
|
3
|
+
const PROVIDER_IDS = [
|
|
4
|
+
"claude",
|
|
5
|
+
"codex",
|
|
6
|
+
];
|
|
7
|
+
const PROVIDER_SOURCES = [
|
|
8
|
+
"oauth",
|
|
9
|
+
"cli-rpc",
|
|
10
|
+
"api",
|
|
11
|
+
"web",
|
|
12
|
+
"cache",
|
|
13
|
+
"unavailable",
|
|
14
|
+
];
|
|
15
|
+
const PROVIDER_STATUSES = [
|
|
16
|
+
"fresh",
|
|
17
|
+
"stale",
|
|
18
|
+
"unavailable",
|
|
19
|
+
"auth_required",
|
|
20
|
+
"rate_limited",
|
|
21
|
+
"error",
|
|
22
|
+
];
|
|
23
|
+
const WINDOW_KINDS = [
|
|
24
|
+
"session",
|
|
25
|
+
"weekly",
|
|
26
|
+
"monthly",
|
|
27
|
+
"model",
|
|
28
|
+
"credits",
|
|
29
|
+
"unknown",
|
|
30
|
+
];
|
|
31
|
+
export function readCachedProvider(provider) {
|
|
32
|
+
return readCacheProviders().find((item) => item.provider === provider);
|
|
33
|
+
}
|
|
34
|
+
export function writeCachedProviders(providers) {
|
|
35
|
+
const cacheable = providers
|
|
36
|
+
.map(toCacheProvider)
|
|
37
|
+
.filter((provider) => Boolean(provider));
|
|
38
|
+
if (cacheable.length === 0)
|
|
39
|
+
return;
|
|
40
|
+
const file = cacheFilePath();
|
|
41
|
+
const byProvider = new Map();
|
|
42
|
+
for (const provider of readCacheProviders())
|
|
43
|
+
byProvider.set(provider.provider, provider);
|
|
44
|
+
for (const provider of cacheable)
|
|
45
|
+
byProvider.set(provider.provider, provider);
|
|
46
|
+
const merged = PROVIDER_IDS.map((provider) => byProvider.get(provider)).filter((provider) => Boolean(provider));
|
|
47
|
+
ensurePrivateParent(file);
|
|
48
|
+
const temp = `${file}.${process.pid}.tmp`;
|
|
49
|
+
writeFileSync(temp, `${JSON.stringify({ generatedAt: new Date().toISOString(), schemaVersion: 1, providers: merged }, null, 2)}\n`, { mode: 0o600 });
|
|
50
|
+
chmodSync(temp, 0o600);
|
|
51
|
+
renameSync(temp, file);
|
|
52
|
+
chmodSync(file, 0o600);
|
|
53
|
+
}
|
|
54
|
+
function readCacheProviders() {
|
|
55
|
+
const raw = readJsonFile(cacheFilePath());
|
|
56
|
+
const payload = objectValue(raw);
|
|
57
|
+
if (!payload ||
|
|
58
|
+
payload.schemaVersion !== 1 ||
|
|
59
|
+
!Array.isArray(payload.providers))
|
|
60
|
+
return [];
|
|
61
|
+
return payload.providers
|
|
62
|
+
.map(normalizeCachedProvider)
|
|
63
|
+
.filter((provider) => Boolean(provider));
|
|
64
|
+
}
|
|
65
|
+
function toCacheProvider(provider) {
|
|
66
|
+
if (provider.state.status !== "fresh" || provider.windows.length === 0)
|
|
67
|
+
return undefined;
|
|
68
|
+
return normalizeCachedProvider({
|
|
69
|
+
provider: provider.provider,
|
|
70
|
+
label: provider.label,
|
|
71
|
+
source: provider.source,
|
|
72
|
+
plan: provider.plan,
|
|
73
|
+
windows: provider.windows,
|
|
74
|
+
credits: provider.credits,
|
|
75
|
+
state: {
|
|
76
|
+
status: provider.state.status,
|
|
77
|
+
stale: false,
|
|
78
|
+
refreshedAt: provider.state.refreshedAt,
|
|
79
|
+
sourcesTried: provider.state.sourcesTried,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function normalizeCachedProvider(raw) {
|
|
84
|
+
const data = objectValue(raw);
|
|
85
|
+
if (!data)
|
|
86
|
+
return undefined;
|
|
87
|
+
const provider = literalValue(data.provider, PROVIDER_IDS);
|
|
88
|
+
const label = stringValue(data.label);
|
|
89
|
+
const source = literalValue(data.source, PROVIDER_SOURCES);
|
|
90
|
+
const state = objectValue(data.state);
|
|
91
|
+
const status = literalValue(state?.status, PROVIDER_STATUSES);
|
|
92
|
+
const sourcesTried = stringArrayValue(state?.sourcesTried);
|
|
93
|
+
const windows = Array.isArray(data.windows)
|
|
94
|
+
? data.windows
|
|
95
|
+
.map(normalizeCachedWindow)
|
|
96
|
+
.filter((window) => Boolean(window))
|
|
97
|
+
: [];
|
|
98
|
+
if (!provider ||
|
|
99
|
+
!label ||
|
|
100
|
+
!source ||
|
|
101
|
+
!state ||
|
|
102
|
+
!status ||
|
|
103
|
+
!sourcesTried ||
|
|
104
|
+
windows.length === 0)
|
|
105
|
+
return undefined;
|
|
106
|
+
const result = {
|
|
107
|
+
provider,
|
|
108
|
+
label,
|
|
109
|
+
source,
|
|
110
|
+
windows,
|
|
111
|
+
state: {
|
|
112
|
+
status,
|
|
113
|
+
stale: booleanValue(state.stale) ?? false,
|
|
114
|
+
sourcesTried,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
const plan = stringValue(data.plan);
|
|
118
|
+
const refreshedAt = stringValue(state.refreshedAt);
|
|
119
|
+
const credits = normalizeCachedCredits(data.credits);
|
|
120
|
+
if (plan)
|
|
121
|
+
result.plan = plan;
|
|
122
|
+
if (refreshedAt)
|
|
123
|
+
result.state.refreshedAt = refreshedAt;
|
|
124
|
+
if (credits)
|
|
125
|
+
result.credits = credits;
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
function normalizeCachedWindow(raw) {
|
|
129
|
+
const data = objectValue(raw);
|
|
130
|
+
if (!data)
|
|
131
|
+
return undefined;
|
|
132
|
+
const id = stringValue(data.id);
|
|
133
|
+
const label = stringValue(data.label);
|
|
134
|
+
const kind = literalValue(data.kind, WINDOW_KINDS);
|
|
135
|
+
if (!id || !label || !kind)
|
|
136
|
+
return undefined;
|
|
137
|
+
const result = { id, label, kind };
|
|
138
|
+
assignNumber(result, "percentUsed", data.percentUsed);
|
|
139
|
+
assignNumber(result, "percentRemaining", data.percentRemaining);
|
|
140
|
+
assignString(result, "resetsAt", data.resetsAt);
|
|
141
|
+
assignString(result, "resetText", data.resetText);
|
|
142
|
+
assignNumber(result, "windowSeconds", data.windowSeconds);
|
|
143
|
+
assignNumber(result, "spentUsd", data.spentUsd);
|
|
144
|
+
assignNumber(result, "limitUsd", data.limitUsd);
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
function normalizeCachedCredits(raw) {
|
|
148
|
+
const data = objectValue(raw);
|
|
149
|
+
if (!data)
|
|
150
|
+
return undefined;
|
|
151
|
+
const remaining = numberValue(data.remaining);
|
|
152
|
+
const unlimited = booleanValue(data.unlimited);
|
|
153
|
+
const unit = literalValue(data.unit, ["usd", "credits"]);
|
|
154
|
+
if (remaining === undefined && unlimited === undefined && unit === undefined)
|
|
155
|
+
return undefined;
|
|
156
|
+
return {
|
|
157
|
+
remaining,
|
|
158
|
+
unlimited,
|
|
159
|
+
unit,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function assignNumber(target, key, value) {
|
|
163
|
+
const number = numberValue(value);
|
|
164
|
+
if (number !== undefined)
|
|
165
|
+
target[key] = number;
|
|
166
|
+
}
|
|
167
|
+
function assignString(target, key, value) {
|
|
168
|
+
const string = stringValue(value);
|
|
169
|
+
if (string !== undefined)
|
|
170
|
+
target[key] = string;
|
|
171
|
+
}
|
|
172
|
+
function objectValue(value) {
|
|
173
|
+
return value && typeof value === "object"
|
|
174
|
+
? value
|
|
175
|
+
: undefined;
|
|
176
|
+
}
|
|
177
|
+
function stringValue(value) {
|
|
178
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
179
|
+
}
|
|
180
|
+
function numberValue(value) {
|
|
181
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
182
|
+
? value
|
|
183
|
+
: undefined;
|
|
184
|
+
}
|
|
185
|
+
function booleanValue(value) {
|
|
186
|
+
return typeof value === "boolean" ? value : undefined;
|
|
187
|
+
}
|
|
188
|
+
function stringArrayValue(value) {
|
|
189
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string")
|
|
190
|
+
? value
|
|
191
|
+
: undefined;
|
|
192
|
+
}
|
|
193
|
+
function literalValue(value, values) {
|
|
194
|
+
return typeof value === "string" && values.includes(value)
|
|
195
|
+
? value
|
|
196
|
+
: undefined;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProviderId } from "./types.js";
|
|
2
|
+
export declare const DESCRIPTION = "Report local agent-provider quota windows for routing-aware agents.";
|
|
3
|
+
export declare const TOP_HELP = "usage: quota-axi [auth] [flags]\ncommands[2]:\n (none)=quota, auth\nflags[6]:\n --provider <claude,codex>, --json, --full, --allow-keychain-prompt, --help, -v/--version\nexamples:\n quota-axi\n quota-axi --provider claude\n quota-axi --json\n quota-axi --full\n quota-axi auth\n";
|
|
4
|
+
type MainOptions = {
|
|
5
|
+
argv?: string[];
|
|
6
|
+
stdout?: Pick<NodeJS.WriteStream, "write">;
|
|
7
|
+
binPath?: string;
|
|
8
|
+
};
|
|
9
|
+
type ParsedArgs = {
|
|
10
|
+
command: "quota" | "auth" | "help" | "version";
|
|
11
|
+
providers: ProviderId[];
|
|
12
|
+
json: boolean;
|
|
13
|
+
full: boolean;
|
|
14
|
+
allowKeychainPrompt: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare function main(options?: MainOptions): Promise<void>;
|
|
17
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
18
|
+
export {};
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { writeCachedProviders } from "./cache.js";
|
|
5
|
+
import { nowIso } from "./lib/time.js";
|
|
6
|
+
import { PROVIDERS, parseProviders } from "./providers/index.js";
|
|
7
|
+
import { redactedResponse, renderAuthToon, renderError, renderQuotaToon, } from "./render.js";
|
|
8
|
+
export const DESCRIPTION = "Report local agent-provider quota windows for routing-aware agents.";
|
|
9
|
+
export const TOP_HELP = `usage: quota-axi [auth] [flags]
|
|
10
|
+
commands[2]:
|
|
11
|
+
(none)=quota, auth
|
|
12
|
+
flags[6]:
|
|
13
|
+
--provider <claude,codex>, --json, --full, --allow-keychain-prompt, --help, -v/--version
|
|
14
|
+
examples:
|
|
15
|
+
quota-axi
|
|
16
|
+
quota-axi --provider claude
|
|
17
|
+
quota-axi --json
|
|
18
|
+
quota-axi --full
|
|
19
|
+
quota-axi auth
|
|
20
|
+
`;
|
|
21
|
+
export async function main(options = {}) {
|
|
22
|
+
const stdout = options.stdout ?? process.stdout;
|
|
23
|
+
const binPath = options.binPath ?? process.argv[1] ?? "quota-axi";
|
|
24
|
+
try {
|
|
25
|
+
const parsed = parseArgs(options.argv ?? process.argv.slice(2));
|
|
26
|
+
if (parsed.command === "help") {
|
|
27
|
+
stdout.write(TOP_HELP);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (parsed.command === "version") {
|
|
31
|
+
stdout.write(`quota-axi ${readPackageVersion()}\n`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const providerOptions = {
|
|
35
|
+
allowKeychainPrompt: parsed.allowKeychainPrompt,
|
|
36
|
+
};
|
|
37
|
+
if (parsed.command === "auth") {
|
|
38
|
+
const reports = await inspectAuth(parsed.providers, providerOptions);
|
|
39
|
+
if (parsed.json) {
|
|
40
|
+
stdout.write(`${JSON.stringify({ generatedAt: nowIso(), schemaVersion: 1, auth: reports }, null, 2)}\n`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
stdout.write(`${renderAuthToon(reports, binPath)}\n`);
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const response = await fetchQuota(parsed.providers, providerOptions);
|
|
48
|
+
const rendered = parsed.json
|
|
49
|
+
? JSON.stringify(redactedResponse(response, parsed.full), null, 2)
|
|
50
|
+
: renderQuotaToon(redactedResponse(response, parsed.full), binPath, parsed.full);
|
|
51
|
+
stdout.write(`${rendered}\n`);
|
|
52
|
+
if (response.providers.every((provider) => isFailed(provider))) {
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
}
|
|
55
|
+
writeCachedProvidersBestEffort(response.providers);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
stdout.write(`${renderError(error instanceof Error ? error.message : "quota-axi failed", "usage", ["Run `quota-axi --help` for supported commands and flags"])}\n`);
|
|
59
|
+
process.exitCode = 2;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function parseArgs(argv) {
|
|
63
|
+
let command = "quota";
|
|
64
|
+
let providerValue;
|
|
65
|
+
let json = false;
|
|
66
|
+
let full = false;
|
|
67
|
+
let allowKeychainPrompt = false;
|
|
68
|
+
for (let index = 0; index < argv.length; index++) {
|
|
69
|
+
const arg = argv[index];
|
|
70
|
+
if (arg === "auth") {
|
|
71
|
+
command = "auth";
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (arg === "--help" || arg === "-h") {
|
|
75
|
+
command = "help";
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (arg === "--version" || arg === "-v" || arg === "-V") {
|
|
79
|
+
command = "version";
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (arg === "--json") {
|
|
83
|
+
json = true;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (arg === "--full") {
|
|
87
|
+
full = true;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (arg === "--allow-keychain-prompt") {
|
|
91
|
+
allowKeychainPrompt = true;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (arg === "--provider") {
|
|
95
|
+
const value = argv[index + 1];
|
|
96
|
+
if (!value)
|
|
97
|
+
throw new Error("--provider requires a comma-separated provider list");
|
|
98
|
+
providerValue = value;
|
|
99
|
+
index++;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (arg.startsWith("--provider=")) {
|
|
103
|
+
providerValue = arg.slice("--provider=".length);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`unknown argument: ${arg}`);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
command,
|
|
110
|
+
providers: parseProviders(providerValue),
|
|
111
|
+
json,
|
|
112
|
+
full,
|
|
113
|
+
allowKeychainPrompt,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async function fetchQuota(providers, options) {
|
|
117
|
+
const results = await Promise.all(providers.map((provider) => PROVIDERS[provider].fetchQuota(options)));
|
|
118
|
+
return {
|
|
119
|
+
generatedAt: nowIso(),
|
|
120
|
+
schemaVersion: 1,
|
|
121
|
+
providers: results,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async function inspectAuth(providers, options) {
|
|
125
|
+
return Promise.all(providers.map((provider) => PROVIDERS[provider].inspectAuth(options)));
|
|
126
|
+
}
|
|
127
|
+
function isFailed(provider) {
|
|
128
|
+
return !["fresh", "stale"].includes(provider.state.status);
|
|
129
|
+
}
|
|
130
|
+
function writeCachedProvidersBestEffort(providers) {
|
|
131
|
+
try {
|
|
132
|
+
writeCachedProviders(providers);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function readPackageVersion() {
|
|
139
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
140
|
+
for (const candidate of [
|
|
141
|
+
join(here, "..", "package.json"),
|
|
142
|
+
join(here, "..", "..", "package.json"),
|
|
143
|
+
]) {
|
|
144
|
+
if (!existsSync(candidate))
|
|
145
|
+
continue;
|
|
146
|
+
const parsed = JSON.parse(readFileSync(candidate, "utf-8"));
|
|
147
|
+
if (typeof parsed.version === "string" && parsed.version.length > 0)
|
|
148
|
+
return parsed.version;
|
|
149
|
+
}
|
|
150
|
+
return "0.0.0";
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type JsonFileReadResult = {
|
|
2
|
+
status: "success";
|
|
3
|
+
value: unknown;
|
|
4
|
+
} | {
|
|
5
|
+
status: "missing";
|
|
6
|
+
} | {
|
|
7
|
+
status: "invalid";
|
|
8
|
+
error: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function collapseHome(path: string): string;
|
|
11
|
+
export declare function cacheFilePath(): string;
|
|
12
|
+
export declare function ensurePrivateParent(file: string): void;
|
|
13
|
+
export declare function readJsonFile(file: string): unknown | undefined;
|
|
14
|
+
export declare function readJsonFileResult(file: string): JsonFileReadResult;
|