@allixsenos/asu 0.3.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 +497 -0
- package/dist/cache.d.ts +15 -0
- package/dist/cache.js +112 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +95 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.js +24 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +14 -0
- package/dist/local.js +121 -0
- package/dist/local.js.map +1 -0
- package/dist/models.d.ts +184 -0
- package/dist/models.js +57 -0
- package/dist/models.js.map +1 -0
- package/dist/output.d.ts +13 -0
- package/dist/output.js +187 -0
- package/dist/output.js.map +1 -0
- package/dist/providers/base.d.ts +25 -0
- package/dist/providers/base.js +2 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/claude.d.ts +4 -0
- package/dist/providers/claude.js +167 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +4 -0
- package/dist/providers/codex.js +66 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/copilot.d.ts +4 -0
- package/dist/providers/copilot.js +64 -0
- package/dist/providers/copilot.js.map +1 -0
- package/dist/providers/cursor.d.ts +6 -0
- package/dist/providers/cursor.js +69 -0
- package/dist/providers/cursor.js.map +1 -0
- package/dist/providers/grok.d.ts +4 -0
- package/dist/providers/grok.js +59 -0
- package/dist/providers/grok.js.map +1 -0
- package/dist/providers/kimi.d.ts +4 -0
- package/dist/providers/kimi.js +49 -0
- package/dist/providers/kimi.js.map +1 -0
- package/dist/providers/minimax.d.ts +4 -0
- package/dist/providers/minimax.js +73 -0
- package/dist/providers/minimax.js.map +1 -0
- package/dist/providers/parse.d.ts +16 -0
- package/dist/providers/parse.js +78 -0
- package/dist/providers/parse.js.map +1 -0
- package/dist/providers/zai.d.ts +5 -0
- package/dist/providers/zai.js +67 -0
- package/dist/providers/zai.js.map +1 -0
- package/dist/registry.d.ts +4 -0
- package/dist/registry.js +45 -0
- package/dist/registry.js.map +1 -0
- package/dist/service.d.ts +28 -0
- package/dist/service.js +117 -0
- package/dist/service.js.map +1 -0
- package/dist/transport.d.ts +8 -0
- package/dist/transport.js +63 -0
- package/dist/transport.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/docs/architecture.md +83 -0
- package/docs/provider-contracts.md +32 -0
- package/docs/releasing.md +51 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luka Kladarić
|
|
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,497 @@
|
|
|
1
|
+
# ASU: agent subscription usage
|
|
2
|
+
|
|
3
|
+
See how much of your coding-agent subscription you used, straight from the provider's account API.
|
|
4
|
+
|
|
5
|
+
ASU is a local TypeScript CLI for humans and agents. It finds supported installations and credentials, fetches usage from each provider concurrently, and prints a table, plain text, or versioned JSON. Each provider has its own adapter. A failed provider does not hide the results of the other providers.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
ASU needs **Node.js 22.13 or newer**, npm, and Git. Sign in through the provider's own CLI first.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx --yes github:allixsenos/asu --table
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This runs the current `main` branch. The repository commits the built `dist/` directory, so the install needs no build step and no token. To run a released version instead, use the tarball of the newest [GitHub release](https://github.com/allixsenos/asu/releases):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx --yes https://github.com/allixsenos/asu/releases/latest/download/asu.tgz --table
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Released versions are also on npm as [`@allixsenos/asu`](https://www.npmjs.com/package/@allixsenos/asu):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx --yes @allixsenos/asu --table
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Your provider credentials, which are separate, let ASU read usage.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Plain text for terminals, logs, and pipes
|
|
31
|
+
npx --yes github:allixsenos/asu --plain
|
|
32
|
+
|
|
33
|
+
# Structured output for agents and scripts
|
|
34
|
+
npx --yes github:allixsenos/asu --json
|
|
35
|
+
|
|
36
|
+
# Select accounts and bypass the five-minute usage cache
|
|
37
|
+
npx --yes github:allixsenos/asu --provider claude,codex,copilot --fresh --table
|
|
38
|
+
|
|
39
|
+
# Include every built-in provider, even if no credentials are found
|
|
40
|
+
npx --yes github:allixsenos/asu --all --table
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
For SSH, use `git+ssh://git@github.com/allixsenos/asu.git#main` in place of `github:allixsenos/asu`. For reproducible automation, pin a reviewed commit SHA or tag, for example `github:allixsenos/asu#v0.1.0`. The `--fresh` flag refreshes provider usage. It does not select a newer package revision.
|
|
44
|
+
|
|
45
|
+
## Real account output
|
|
46
|
+
|
|
47
|
+
We fetched the snapshot below on **2026-09-07 at 12:18 UTC** from the maintainer's authenticated Claude, Codex, and GitHub Copilot accounts on Linux. These are real provider-reported figures, not fixtures or estimates. They become stale as usage changes.
|
|
48
|
+
|
|
49
|
+
The capture used the local checkout:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
node dist/cli.js --provider claude,codex,copilot --fresh --no-cache --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
ASU's own renderers made the table and the plain text below from that same JSON snapshot with `--utc`, so all three examples show identical data. The examples include no credentials and no account identifiers. All reset times are UTC.
|
|
56
|
+
|
|
57
|
+
Without `--utc`, the table and the plain text show reset, fetch, and expiry times relative to now, for example `2h30m` or `45m`. A time a day or more away also names the local calendar day, for example `7d (Tue 15 Sep)`. A reset time that already passed shows as `now`. JSON always contains the full UTC timestamps.
|
|
58
|
+
|
|
59
|
+
### Pretty table
|
|
60
|
+
|
|
61
|
+
Use `--table` for this view. It is also the default in an interactive terminal that is wide enough. When a cell would wrap, the default falls back to plain text. Pass `--table` to force the table.
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
ASU · 2026-09-07T12:18:06.253Z
|
|
65
|
+
┌──────────────────┬────────────────────┬───────────────────────┬───────────────────────┬────────────────────┐
|
|
66
|
+
│ Provider │ Plan / status │ Window / balance │ Usage │ Resets (UTC) │
|
|
67
|
+
├──────────────────┼────────────────────┼───────────────────────┼───────────────────────┼────────────────────┤
|
|
68
|
+
│ Claude │ Max 20x │ 5 hours │ 45% used │ 2026-09-07 14:29 │
|
|
69
|
+
│ │ available │ │ │ │
|
|
70
|
+
│ │ fresh │ │ │ │
|
|
71
|
+
│ │ │ Weekly │ 78% used │ 2026-09-08 04:59 │
|
|
72
|
+
│ │ │ Weekly · Fable │ 45% used │ 2026-09-08 04:59 │
|
|
73
|
+
├──────────────────┼────────────────────┼───────────────────────┼───────────────────────┼────────────────────┤
|
|
74
|
+
│ Codex │ Plus │ 5 hours │ 41% used │ 2026-09-07 16:48 │
|
|
75
|
+
│ │ available │ │ │ │
|
|
76
|
+
│ │ fresh │ │ │ │
|
|
77
|
+
│ │ │ Weekly │ 6% used │ 2026-09-14 11:48 │
|
|
78
|
+
│ │ │ Gpt Reserve · Weekly │ 0% used │ 2026-09-14 12:18 │
|
|
79
|
+
│ │ │ Credits │ 0 credits left │ — │
|
|
80
|
+
├──────────────────┼────────────────────┼───────────────────────┼───────────────────────┼────────────────────┤
|
|
81
|
+
│ GitHub Copilot │ Individual │ Chat │ 0% used │ 2026-10-01 00:00 │
|
|
82
|
+
│ │ available │ │ 0 / 200 requests │ │
|
|
83
|
+
│ │ fresh │ │ │ │
|
|
84
|
+
│ │ │ Completions │ 0% used │ 2026-10-01 00:00 │
|
|
85
|
+
│ │ │ │ 0 / 2,000 requests │ │
|
|
86
|
+
│ │ │ Premium Interactions │ 100% used │ 2026-10-01 00:00 │
|
|
87
|
+
│ │ │ │ 0 / 0 requests │ │
|
|
88
|
+
└──────────────────┴────────────────────┴───────────────────────┴───────────────────────┴────────────────────┘
|
|
89
|
+
Claude: installed: yes, authenticated: yes. Fetched 2026-09-07T12:18:06.042Z; cache expires 2026-09-07T12:23:06.042Z.
|
|
90
|
+
Extra usage: Disabled
|
|
91
|
+
Codex: installed: yes, authenticated: yes. Fetched 2026-09-07T12:18:06.217Z; cache expires 2026-09-07T12:23:06.217Z.
|
|
92
|
+
Credits available: No
|
|
93
|
+
GitHub Copilot: installed: yes, authenticated: yes. Fetched 2026-09-07T12:18:06.252Z; cache expires 2026-09-07T12:23:06.252Z.
|
|
94
|
+
Quota reset: 2026-10-01T00:00:00.000Z
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Read Copilot's premium row with care. The endpoint returned zero entitlement, zero remaining requests, and zero percent remaining. ASU therefore shows `100% used` next to `0 / 0 requests`. This does **not** show that anyone consumed a premium request. The internal endpoint can return legacy quota information. Treat its quantities as the provider's reported snapshot, not as a complete billing statement.
|
|
98
|
+
|
|
99
|
+
### Plain text
|
|
100
|
+
|
|
101
|
+
Use `--plain` for readable output in logs and pipes. It is the default when stdout is not a terminal.
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary>Show the complete plain-text output</summary>
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
ASU · 2026-09-07T12:18:06.253Z
|
|
108
|
+
|
|
109
|
+
Claude (claude)
|
|
110
|
+
available; installed: yes, authenticated: yes
|
|
111
|
+
Plan: Max 20x
|
|
112
|
+
5 hours: 45% used; resets 2026-09-07T14:29:59.895Z
|
|
113
|
+
Weekly: 78% used; resets 2026-09-08T04:59:59.895Z
|
|
114
|
+
Weekly · Fable: 45% used; resets 2026-09-08T04:59:59.895Z
|
|
115
|
+
Extra usage: Disabled
|
|
116
|
+
Fetched 2026-09-07T12:18:06.042Z; fresh; expires 2026-09-07T12:23:06.042Z
|
|
117
|
+
|
|
118
|
+
Codex (codex)
|
|
119
|
+
available; installed: yes, authenticated: yes
|
|
120
|
+
Plan: Plus
|
|
121
|
+
5 hours: 41% used; resets 2026-09-07T16:48:37.000Z
|
|
122
|
+
Weekly: 6% used; resets 2026-09-14T11:48:37.000Z
|
|
123
|
+
Gpt Reserve · Weekly: 0% used; resets 2026-09-14T12:18:06.000Z
|
|
124
|
+
Credits: 0 credits left
|
|
125
|
+
Credits available: No
|
|
126
|
+
Fetched 2026-09-07T12:18:06.217Z; fresh; expires 2026-09-07T12:23:06.217Z
|
|
127
|
+
|
|
128
|
+
GitHub Copilot (copilot)
|
|
129
|
+
available; installed: yes, authenticated: yes
|
|
130
|
+
Plan: Individual
|
|
131
|
+
Chat: 0% used; 0 / 200 requests; resets 2026-10-01T00:00:00.000Z
|
|
132
|
+
Completions: 0% used; 0 / 2,000 requests; resets 2026-10-01T00:00:00.000Z
|
|
133
|
+
Premium Interactions: 100% used; 0 / 0 requests; resets 2026-10-01T00:00:00.000Z
|
|
134
|
+
Quota reset: 2026-10-01T00:00:00.000Z
|
|
135
|
+
Fetched 2026-09-07T12:18:06.252Z; fresh; expires 2026-09-07T12:23:06.252Z
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
</details>
|
|
139
|
+
|
|
140
|
+
### JSON
|
|
141
|
+
|
|
142
|
+
Use `--json` for agents and scripts. Stdout contains the report. An ASU invocation error goes to stderr. The human output rounds quantities to two decimal places and shows relative times. JSON keeps the normalized numeric precision and the full UTC timestamps.
|
|
143
|
+
|
|
144
|
+
<details>
|
|
145
|
+
<summary>Show the complete version 1 JSON report</summary>
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"schemaVersion": 1,
|
|
150
|
+
"generatedAt": "2026-09-07T12:18:06.253Z",
|
|
151
|
+
"warnings": [],
|
|
152
|
+
"providers": [
|
|
153
|
+
{
|
|
154
|
+
"planLabel": "Max 20x",
|
|
155
|
+
"windows": [
|
|
156
|
+
{
|
|
157
|
+
"id": "five_hour",
|
|
158
|
+
"label": "5 hours",
|
|
159
|
+
"percentUsed": 45,
|
|
160
|
+
"resetsAt": "2026-09-07T14:29:59.895Z"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": "seven_day",
|
|
164
|
+
"label": "Weekly",
|
|
165
|
+
"percentUsed": 78,
|
|
166
|
+
"resetsAt": "2026-09-08T04:59:59.895Z"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"id": "weekly-model-fable",
|
|
170
|
+
"label": "Weekly · Fable",
|
|
171
|
+
"percentUsed": 45,
|
|
172
|
+
"resetsAt": "2026-09-08T04:59:59.895Z",
|
|
173
|
+
"scope": {
|
|
174
|
+
"model": "Fable"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"balances": [],
|
|
179
|
+
"details": [
|
|
180
|
+
{
|
|
181
|
+
"label": "Extra usage",
|
|
182
|
+
"value": "Disabled"
|
|
183
|
+
}
|
|
184
|
+
],
|
|
185
|
+
"providerId": "claude",
|
|
186
|
+
"displayName": "Claude",
|
|
187
|
+
"experimental": false,
|
|
188
|
+
"installed": true,
|
|
189
|
+
"credentialsPresent": true,
|
|
190
|
+
"authenticated": true,
|
|
191
|
+
"availability": "available",
|
|
192
|
+
"reason": null,
|
|
193
|
+
"fetchedAt": "2026-09-07T12:18:06.042Z",
|
|
194
|
+
"expiresAt": "2026-09-07T12:23:06.042Z",
|
|
195
|
+
"cached": false
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"planLabel": "Plus",
|
|
199
|
+
"windows": [
|
|
200
|
+
{
|
|
201
|
+
"id": "usage-primary_window",
|
|
202
|
+
"label": "5 hours",
|
|
203
|
+
"percentUsed": 41,
|
|
204
|
+
"resetsAt": "2026-09-07T16:48:37.000Z"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"id": "usage-secondary_window",
|
|
208
|
+
"label": "Weekly",
|
|
209
|
+
"percentUsed": 6,
|
|
210
|
+
"resetsAt": "2026-09-14T11:48:37.000Z"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"id": "additional-0-gpt-reserve-primary_window",
|
|
214
|
+
"label": "Gpt Reserve · Weekly",
|
|
215
|
+
"percentUsed": 0,
|
|
216
|
+
"resetsAt": "2026-09-14T12:18:06.000Z"
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"balances": [
|
|
220
|
+
{
|
|
221
|
+
"id": "credits",
|
|
222
|
+
"label": "Credits",
|
|
223
|
+
"unit": "credits",
|
|
224
|
+
"remaining": 0,
|
|
225
|
+
"unlimited": false
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
"details": [
|
|
229
|
+
{
|
|
230
|
+
"label": "Credits available",
|
|
231
|
+
"value": "No"
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
"providerId": "codex",
|
|
235
|
+
"displayName": "Codex",
|
|
236
|
+
"experimental": false,
|
|
237
|
+
"installed": true,
|
|
238
|
+
"credentialsPresent": true,
|
|
239
|
+
"authenticated": true,
|
|
240
|
+
"availability": "available",
|
|
241
|
+
"reason": null,
|
|
242
|
+
"fetchedAt": "2026-09-07T12:18:06.217Z",
|
|
243
|
+
"expiresAt": "2026-09-07T12:23:06.217Z",
|
|
244
|
+
"cached": false
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"planLabel": "Individual",
|
|
248
|
+
"windows": [
|
|
249
|
+
{
|
|
250
|
+
"id": "chat",
|
|
251
|
+
"label": "Chat",
|
|
252
|
+
"percentUsed": 0,
|
|
253
|
+
"resetsAt": "2026-10-01T00:00:00.000Z",
|
|
254
|
+
"used": 0,
|
|
255
|
+
"limit": 200,
|
|
256
|
+
"unit": "requests",
|
|
257
|
+
"unlimited": false
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"id": "completions",
|
|
261
|
+
"label": "Completions",
|
|
262
|
+
"percentUsed": 0,
|
|
263
|
+
"resetsAt": "2026-10-01T00:00:00.000Z",
|
|
264
|
+
"used": 0,
|
|
265
|
+
"limit": 2000,
|
|
266
|
+
"unit": "requests",
|
|
267
|
+
"unlimited": false
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"id": "premium-interactions",
|
|
271
|
+
"label": "Premium Interactions",
|
|
272
|
+
"percentUsed": 100,
|
|
273
|
+
"resetsAt": "2026-10-01T00:00:00.000Z",
|
|
274
|
+
"used": 0,
|
|
275
|
+
"limit": 0,
|
|
276
|
+
"unit": "requests",
|
|
277
|
+
"unlimited": false
|
|
278
|
+
}
|
|
279
|
+
],
|
|
280
|
+
"balances": [],
|
|
281
|
+
"details": [
|
|
282
|
+
{
|
|
283
|
+
"label": "Quota reset",
|
|
284
|
+
"value": "2026-10-01T00:00:00.000Z"
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
"providerId": "copilot",
|
|
288
|
+
"displayName": "GitHub Copilot",
|
|
289
|
+
"experimental": false,
|
|
290
|
+
"installed": true,
|
|
291
|
+
"credentialsPresent": true,
|
|
292
|
+
"authenticated": true,
|
|
293
|
+
"availability": "available",
|
|
294
|
+
"reason": null,
|
|
295
|
+
"fetchedAt": "2026-09-07T12:18:06.252Z",
|
|
296
|
+
"expiresAt": "2026-09-07T12:23:06.252Z",
|
|
297
|
+
"cached": false
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
</details>
|
|
304
|
+
|
|
305
|
+
## CLI reference
|
|
306
|
+
|
|
307
|
+
```text
|
|
308
|
+
asu [usage] [options]
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
When you run ASU through `npx`, put the ASU options after the package URL.
|
|
312
|
+
|
|
313
|
+
| Option | Behavior |
|
|
314
|
+
| --- | --- |
|
|
315
|
+
| `--format plain\|table\|json` | Select one output format. Without it, a terminal gets the table, or plain text when the table would wrap. A pipe gets plain text. |
|
|
316
|
+
| `--plain`, `--table`, `--json` | Shortcuts for `--format`. Use only one. |
|
|
317
|
+
| `--utc` | Print full UTC timestamps in table and plain output instead of times relative to now, such as `2h30m` or `7d (Tue 15 Sep)` |
|
|
318
|
+
| `--provider claude,codex` | Select provider IDs. Repeat the flag or separate the IDs with commas. |
|
|
319
|
+
| `--all` | Include providers with no detected installation or credentials |
|
|
320
|
+
| `--fresh` | Bypass cached usage. Concurrent fresh requests still share one fetch. |
|
|
321
|
+
| `--no-cache` | Do not read or write the persistent cache |
|
|
322
|
+
| `--cache-dir PATH` | Set the usage cache directory |
|
|
323
|
+
| `--plugin PATH_OR_PACKAGE` | Load a trusted provider plugin that you name explicitly. Repeatable. |
|
|
324
|
+
| `--help`, `-h` | Show help |
|
|
325
|
+
| `--version`, `-v` | Print the package version |
|
|
326
|
+
|
|
327
|
+
Without `--all` or `--provider`, ASU omits a provider that has no detected installation, no credentials, and no discovery error. Credentials can work even when the provider's executable is not on `PATH`. Installation and authentication are separate fields. `null` means unknown.
|
|
328
|
+
|
|
329
|
+
### Exit codes
|
|
330
|
+
|
|
331
|
+
| Code | Meaning |
|
|
332
|
+
| --- | --- |
|
|
333
|
+
| `0` | At least one selected provider returned available usage |
|
|
334
|
+
| `1` | No selected provider returned available usage. ASU still prints a report. |
|
|
335
|
+
| `2` | Invalid invocation or plugin configuration. ASU prints an error to stderr. |
|
|
336
|
+
|
|
337
|
+
A zero exit code does not mean that every provider succeeded. When you automate ASU, examine the `availability` of each provider. Missing credentials, a timeout, or a malformed response from one provider does not discard the data of the other providers.
|
|
338
|
+
|
|
339
|
+
### Use JSON in scripts
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
npx --yes github:allixsenos/asu --json > usage.json
|
|
343
|
+
jq '.providers[] | {providerId, availability, planLabel, windows}' usage.json
|
|
344
|
+
|
|
345
|
+
# Find available providers with a window at or above 80% used
|
|
346
|
+
jq '[.providers[]
|
|
347
|
+
| select(.availability == "available")
|
|
348
|
+
| select(any(.windows[]; .percentUsed != null and .percentUsed >= 80))
|
|
349
|
+
| .providerId]' usage.json
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
A consumer must examine `schemaVersion` before it processes a report. Version 1 includes:
|
|
353
|
+
|
|
354
|
+
| Field | Meaning |
|
|
355
|
+
| --- | --- |
|
|
356
|
+
| `generatedAt`, `warnings`, `providers` | Report timestamp, shared warnings, and independent provider results |
|
|
357
|
+
| `providerId`, `displayName`, `experimental` | Provider identity and live-validation status |
|
|
358
|
+
| `installed`, `credentialsPresent`, `authenticated` | Separate discovery and authentication observations |
|
|
359
|
+
| `availability`, `reason` | `available`, `unavailable`, or `error`, with a reason code and a safe message when needed |
|
|
360
|
+
| `planLabel` | Subscription label, or `null` if unknown |
|
|
361
|
+
| `windows` | Variable-length usage windows with IDs, percentages, UTC resets, optional quantities, and model or surface scope |
|
|
362
|
+
| `balances` | Reported credits or monetary balances with explicit units |
|
|
363
|
+
| `details` | Additional normalized label and value pairs |
|
|
364
|
+
| `fetchedAt`, `expiresAt`, `cached` | Timestamp and freshness of each provider snapshot |
|
|
365
|
+
|
|
366
|
+
An unknown percentage or reset time is `null`. A missing quantity or balance does not mean zero. An unlimited allowance is explicit. A percentage can exceed 100 if a provider reports overage. Do not assume a fixed number or order of windows. See the [report contract](docs/architecture.md#report-contract) and the [schemas](src/models.ts) for the full model.
|
|
367
|
+
|
|
368
|
+
## Supported providers
|
|
369
|
+
|
|
370
|
+
| ID | Provider | Credential sources, in precedence order | Validation |
|
|
371
|
+
| --- | --- | --- | --- |
|
|
372
|
+
| `claude` | Claude | `.credentials.json` under `$CLAUDE_CONFIG_DIR`, `$CLAUDE_HOME`, or `~/.claude`. macOS Keychain fallback. | Live account, Linux |
|
|
373
|
+
| `codex` | Codex | `$CODEX_HOME/auth.json`, `~/.config/codex/auth.json`, `~/.codex/auth.json` | Live account, Linux |
|
|
374
|
+
| `copilot` | GitHub Copilot | `COPILOT_TOKEN`, `GITHUB_TOKEN`, `GITHUB_PAT`, GitHub CLI `hosts.yml` | Live account, Linux |
|
|
375
|
+
| `cursor` | Cursor | `CURSOR_ACCESS_TOKEN`, `CURSOR_TOKEN`, desktop SQLite, `~/.config/cursor/auth.json` | Experimental. Fixture tests only. |
|
|
376
|
+
| `zai` | Z.ai | `ZAI_API_KEY`, `GLM_API_KEY` | Experimental. Fixture tests only. |
|
|
377
|
+
| `grok` | Grok | `GROK_API_KEY`, `GROK_TOKEN`, `~/.grok/auth.json` | Experimental. Fixture tests only. |
|
|
378
|
+
| `kimi` | Kimi | `KIMI_TOKEN`, `KIMI_API_KEY`, credentials under `$KIMI_CODE_HOME` or `~/.kimi-code`, legacy `~/.kimi` | Experimental. Fixture tests only. |
|
|
379
|
+
| `minimax` | MiniMax | `MINIMAX_API_KEY`, `~/.mmx/credentials.json`, `~/.mmx/config.json` | Experimental. Fixture tests only. |
|
|
380
|
+
|
|
381
|
+
Only Claude Max 20x, Codex Plus, and GitHub Copilot Individual passed a check against the maintainer's live accounts. The other five adapters always return `experimental: true`, and the human output marks them. A passed fixture test does not prove a live subscription or every credential-store variant. The macOS and Windows paths have no live test.
|
|
382
|
+
|
|
383
|
+
Credential lookup details:
|
|
384
|
+
|
|
385
|
+
- Claude reads `claudeAiOauth.accessToken`. On macOS it falls back to the Keychain service `Claude Code-credentials`. It tries the current user's account before the legacy service-only lookup.
|
|
386
|
+
- Codex needs the OAuth `tokens.access_token`, with an optional `tokens.account_id`. This adapter does not support API-key authentication or credentials that live only in the OS keyring.
|
|
387
|
+
- Copilot obeys `GH_CONFIG_DIR` and `XDG_CONFIG_HOME` when it reads the GitHub CLI credentials. It does not read credentials that live only in the Copilot CLI's own store. An installed `gh` alone does not count as an installed Copilot CLI.
|
|
388
|
+
- Cursor reads its desktop `state.vscdb` in read-only mode. It uses the platform locations, including macOS Application Support and Windows `APPDATA`. The Linux lookup obeys `XDG_CONFIG_HOME`.
|
|
389
|
+
- Kimi's credential file is `credentials/kimi-code.json` under its configured or default home.
|
|
390
|
+
- MiniMax supports `MINIMAX_REGION=cn` or a recognized `MINIMAX_BASE_URL`. ASU rejects an arbitrary API destination.
|
|
391
|
+
|
|
392
|
+
The APIs include undocumented internal endpoints and can change. The request methods, schemas, primary sources, and limitations of each adapter are in [provider contracts](docs/provider-contracts.md).
|
|
393
|
+
|
|
394
|
+
## How it works
|
|
395
|
+
|
|
396
|
+
```text
|
|
397
|
+
CLI options → provider registry → concurrent provider operations
|
|
398
|
+
│
|
|
399
|
+
read local credentials (read-only)
|
|
400
|
+
│
|
|
401
|
+
five-minute cache or provider usage API
|
|
402
|
+
│
|
|
403
|
+
normalize, validate, and redact
|
|
404
|
+
│
|
|
405
|
+
table / plain text / JSON
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Each provider lives in its own file under [`src/providers/`](src/providers). The shared service handles deadlines, failure isolation, caching, and report validation. The renderers accept any number of windows or balances. All work happens in the local Node process. There is no dashboard, HTTP server, hosted backend, or telemetry.
|
|
409
|
+
|
|
410
|
+
### Cache and timeouts
|
|
411
|
+
|
|
412
|
+
ASU caches a result for **five minutes**, separately for each provider and credential identity. It selects the cache directory in this order:
|
|
413
|
+
|
|
414
|
+
1. `--cache-dir PATH`
|
|
415
|
+
2. `$ASU_CACHE_DIR`
|
|
416
|
+
3. `$XDG_CACHE_HOME/asu`
|
|
417
|
+
4. `~/.cache/asu`
|
|
418
|
+
|
|
419
|
+
ASU reads the credentials on each invocation. A changed credential changes the cache key. Concurrent calls in one process share one fetch. Concurrent CLI invocations use file locks. ASU also caches an API failure. It examines missing, malformed, and locally expired credentials again on each invocation, without an API request.
|
|
420
|
+
|
|
421
|
+
Use `--fresh` to bypass an existing result after you solve a problem. Use `--no-cache` when ASU must not read or write the persistent cache. The report still includes the five-minute `expiresAt` of the snapshot when disk caching is off. ASU replaces an expired entry at the next lookup. It does not remove the old entries of unused accounts.
|
|
422
|
+
|
|
423
|
+
An HTTP request has an eight-second deadline, a one-MiB response limit, and no redirects. Each provider operation has a twelve-second deadline. A wait for the cache lock stops after about 32 seconds. When the cache fails, ASU fetches without persistence and adds a warning.
|
|
424
|
+
|
|
425
|
+
### Credential handling
|
|
426
|
+
|
|
427
|
+
ASU reads existing credentials and sends them only to the provider endpoint of the adapter. It never refreshes a token, signs in, rewrites a provider file, runs the provider CLI to get usage, or estimates subscription consumption from conversation history. Missing or rejected credentials give an unavailable result. Sign in or refresh through the provider's own CLI.
|
|
428
|
+
|
|
429
|
+
ASU prints and caches only normalized usage. It excludes tokens, refresh tokens, account IDs, and raw API errors. The cache uses private directory and file permissions on Unix, and SHA-256 filenames derived from the credential identity. A usage report still contains plan and account-usage information. The maintainer shared the examples above on purpose.
|
|
430
|
+
|
|
431
|
+
## Troubleshooting
|
|
432
|
+
|
|
433
|
+
| Symptom | What to examine |
|
|
434
|
+
| --- | --- |
|
|
435
|
+
| GitHub says the repository is missing or access is denied | Examine your Git access with `git ls-remote https://github.com/allixsenos/asu.git HEAD`. The SSH URL needs a GitHub SSH key. |
|
|
436
|
+
| The Git install fails during `prepare` | Examine the Node version, the dependency-registry access, and whether npm permits build scripts. See the local checkout instructions below. |
|
|
437
|
+
| `npx` exits with code 1 and prints nothing, or npm 9 reports `could not determine executable to run` | npm 9 cannot run the nested install that a Git dependency with a `build` or `prepare` script needs through `npx`. ASU commits `dist/` and has neither script, so a current checkout does not hit this. Clear the npx cache with `rm -rf ~/.npm/_npx` and retry, or use the release tarball URL. |
|
|
438
|
+
| No supported agents or credentials detected | Use `--all`, examine the credential sources above, and examine the home-directory overrides and `PATH`. |
|
|
439
|
+
| `missing_credentials`, `invalid_credentials`, or `unauthorized` | Sign in or refresh through the provider's CLI, then run ASU again with `--fresh`. A successful CLI login helps only if ASU supports its credential store. |
|
|
440
|
+
| `credential_read_error` | Make sure that your current user can read the credential file or store. |
|
|
441
|
+
| `timeout`, `rate_limited`, or `http_error` | Examine the connectivity and the provider status. Wait before you retry after a rate limit. Use `--fresh` to bypass a cached failure. |
|
|
442
|
+
| `invalid_response` | The provider may have a new response schema. See the [known limitations](docs/provider-contracts.md#known-limitations). |
|
|
443
|
+
| Usage looks stale | Examine `fetchedAt` and `cached`, then use `--fresh`. ASU cannot make the provider update its figures sooner. |
|
|
444
|
+
| One provider fails but the command exits with zero | Exit code `0` means that at least one provider succeeded. Examine the `availability` of each provider. |
|
|
445
|
+
|
|
446
|
+
## Plugins
|
|
447
|
+
|
|
448
|
+
A provider is an ESM module with a unique ID, a version, and three operations: detect the installation, resolve the credentials, and fetch normalized usage. An adapter owns its credential format and its API contract. The shared service and the renderers stay provider-independent.
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
npx --yes github:allixsenos/asu --plugin ./my-provider.mjs --provider my-provider --json
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
A plugin can export `default` or `provider`. ASU resolves an installed package name from the current working directory. A plugin is local code that you load explicitly, and it has full access to the process. Load only modules that you trust. ASU does not download plugins and does not search for them. See the [plugin contract and example](docs/architecture.md#external-plugin-example) for the details. The package also exports its service, schemas, and TypeScript types as a library.
|
|
455
|
+
|
|
456
|
+
## Local development and testing
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
gh repo clone allixsenos/asu
|
|
460
|
+
cd asu
|
|
461
|
+
npm ci
|
|
462
|
+
|
|
463
|
+
# dist/ is committed. Rebuild after you edit TypeScript and commit the result.
|
|
464
|
+
npm run compile
|
|
465
|
+
node dist/cli.js --table
|
|
466
|
+
node dist/cli.js --provider claude,codex,copilot --fresh --json
|
|
467
|
+
|
|
468
|
+
# Required checks for behavior changes
|
|
469
|
+
npm run check
|
|
470
|
+
npm test
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
The tests use synthetic API responses and temporary credential stores. They cover normalization, credential precedence and expiration, malformed responses, failure isolation, timeouts, cache expiry, concurrent requests, account changes, redaction, and real CLI subprocess output. They do not use your accounts and do not call provider APIs. Live verification is a separate step, as the snapshot above documents.
|
|
474
|
+
|
|
475
|
+
GitHub Actions runs the type checks, the tests, and a packed-package smoke test on Node 22 and 24. It also fails when the committed `dist/` differs from a fresh build. To try the packed artifact locally without a publication:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
npx --yes --package "./$(npm pack --silent)" asu --help
|
|
479
|
+
npx --yes --package "./$(npm pack --silent)" asu --table
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Enable the commit-message hook of the repository and prefer rebase on pull:
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
git config core.hooksPath .githooks
|
|
486
|
+
git config pull.rebase true
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Conventional Commits are mandatory. Prefer small, scoped commits and squash merges. Rebase merges are permitted, and merge commits are off. [`CLAUDE.md`](CLAUDE.md) is a symlink to [`AGENTS.md`](AGENTS.md), so Claude and other agents share the project instructions.
|
|
490
|
+
|
|
491
|
+
## Releases
|
|
492
|
+
|
|
493
|
+
release-please writes [`CHANGELOG.md`](CHANGELOG.md) and creates each release from the commit history. [Releasing](docs/releasing.md) describes the release pull request, the GitHub release with the packed tarball, and the npm publication.
|
|
494
|
+
|
|
495
|
+
## Project status
|
|
496
|
+
|
|
497
|
+
Public repository under the [MIT license](LICENSE). The release workflow publishes the package to the public npm registry.
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ProviderUsage } from './models.js';
|
|
2
|
+
export declare const CACHE_TTL_MS = 300000;
|
|
3
|
+
export declare function cacheKey(parts: unknown[]): string;
|
|
4
|
+
export declare class UsageCache {
|
|
5
|
+
private readonly directory?;
|
|
6
|
+
private readonly now;
|
|
7
|
+
private readonly memory;
|
|
8
|
+
private readonly pending;
|
|
9
|
+
readonly warnings: Set<string>;
|
|
10
|
+
constructor(directory?: string | undefined, now?: () => number);
|
|
11
|
+
getOrFetch(key: string, load: () => Promise<ProviderUsage>, fresh?: boolean): Promise<ProviderUsage>;
|
|
12
|
+
private valid;
|
|
13
|
+
private read;
|
|
14
|
+
private load;
|
|
15
|
+
}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { chmod, lstat, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import lockfile from 'proper-lockfile';
|
|
5
|
+
import { providerUsageSchema } from './models.js';
|
|
6
|
+
export const CACHE_TTL_MS = 300_000;
|
|
7
|
+
export function cacheKey(parts) {
|
|
8
|
+
return createHash('sha256').update(JSON.stringify(parts)).digest('hex');
|
|
9
|
+
}
|
|
10
|
+
export class UsageCache {
|
|
11
|
+
directory;
|
|
12
|
+
now;
|
|
13
|
+
memory = new Map();
|
|
14
|
+
pending = new Map();
|
|
15
|
+
warnings = new Set();
|
|
16
|
+
constructor(directory, now = Date.now) {
|
|
17
|
+
this.directory = directory;
|
|
18
|
+
this.now = now;
|
|
19
|
+
}
|
|
20
|
+
async getOrFetch(key, load, fresh = false) {
|
|
21
|
+
if (!/^[a-f0-9]{64}$/.test(key))
|
|
22
|
+
throw new Error('Invalid cache key');
|
|
23
|
+
const pending = this.pending.get(key);
|
|
24
|
+
if (pending)
|
|
25
|
+
return structuredClone(await pending);
|
|
26
|
+
const startedAt = this.now();
|
|
27
|
+
const current = this.memory.get(key);
|
|
28
|
+
if (!fresh && current && this.valid(current))
|
|
29
|
+
return { ...structuredClone(current), cached: true };
|
|
30
|
+
const work = this.load(key, load, fresh, startedAt);
|
|
31
|
+
this.pending.set(key, work);
|
|
32
|
+
try {
|
|
33
|
+
const result = await work;
|
|
34
|
+
this.memory.set(key, structuredClone(result));
|
|
35
|
+
return structuredClone(result);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
this.pending.delete(key);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
valid(data) {
|
|
42
|
+
return Date.parse(data.fetchedAt) <= this.now() && Date.parse(data.expiresAt) > this.now()
|
|
43
|
+
&& Date.parse(data.expiresAt) - Date.parse(data.fetchedAt) <= CACHE_TTL_MS;
|
|
44
|
+
}
|
|
45
|
+
async read(path, fresh, startedAt) {
|
|
46
|
+
try {
|
|
47
|
+
const stat = await lstat(path);
|
|
48
|
+
if (!stat.isFile() || stat.size > 1_048_576)
|
|
49
|
+
return null;
|
|
50
|
+
const result = providerUsageSchema.safeParse(JSON.parse(await readFile(path, 'utf8')));
|
|
51
|
+
if (!result.success || !this.valid(result.data))
|
|
52
|
+
return null;
|
|
53
|
+
if (fresh && Date.parse(result.data.fetchedAt) < startedAt)
|
|
54
|
+
return null;
|
|
55
|
+
return { ...result.data, cached: true };
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async load(key, load, fresh, startedAt) {
|
|
62
|
+
if (!this.directory)
|
|
63
|
+
return load();
|
|
64
|
+
const path = join(this.directory, `${key}.json`);
|
|
65
|
+
let release;
|
|
66
|
+
let compromised = false;
|
|
67
|
+
try {
|
|
68
|
+
await mkdir(this.directory, { recursive: true, mode: 0o700 });
|
|
69
|
+
const stat = await lstat(this.directory);
|
|
70
|
+
if (!stat.isDirectory() || (process.getuid && stat.uid !== process.getuid()))
|
|
71
|
+
throw new Error();
|
|
72
|
+
if (process.platform !== 'win32')
|
|
73
|
+
await chmod(this.directory, 0o700);
|
|
74
|
+
const cached = await this.read(path, fresh, startedAt);
|
|
75
|
+
if (cached)
|
|
76
|
+
return cached;
|
|
77
|
+
release = await lockfile.lock(path, { realpath: false, stale: 30_000, update: 5_000,
|
|
78
|
+
retries: { retries: 160, factor: 1, minTimeout: 200, maxTimeout: 200 },
|
|
79
|
+
onCompromised: () => { compromised = true; this.warnings.add('Cache lock was lost; this result was not saved.'); },
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
this.warnings.add('Persistent cache unavailable; results may require fresh provider requests.');
|
|
84
|
+
return load();
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
// A different invocation may have filled the cache while we waited for its lock.
|
|
88
|
+
const cached = await this.read(path, fresh, startedAt);
|
|
89
|
+
if (cached)
|
|
90
|
+
return cached;
|
|
91
|
+
const result = await load();
|
|
92
|
+
if (!compromised) {
|
|
93
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
94
|
+
try {
|
|
95
|
+
await writeFile(temporary, JSON.stringify(providerUsageSchema.parse(result)), { mode: 0o600, flag: 'wx' });
|
|
96
|
+
await rename(temporary, path);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
this.warnings.add('Could not save the usage cache.');
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await unlink(temporary).catch(() => { });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
await release?.().catch(() => { });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export declare const help = "asu \u2014 agent subscription usage\n\nUsage: asu [usage] [options]\n\n --format plain|table|json Output format (table in a terminal, plain when piped or when the table would wrap)\n --json Shortcut for --format json\n --plain Shortcut for --format plain\n --table Shortcut for --format table\n --utc Print full UTC timestamps instead of times relative to now\n --provider <id> Select provider; repeat or use comma-separated IDs\n --all Include providers with no detected install or credentials\n --fresh Fetch again, bypassing the five-minute cache\n --no-cache Do not read or write the persistent cache\n --cache-dir <path> Override the private usage cache directory\n --plugin <path-or-package> Load a trusted provider plugin; repeatable\n --help, -h Show this help\n --version, -v Show version\n\nProviders: claude, codex, copilot, cursor, zai, grok, kimi, minimax\nCredentials are read-only. Sign in and refresh tokens through the provider CLI.\nJSON has schemaVersion: 1. Diagnostics go to stderr; stdout contains only the report.\nExit codes: 0 at least one available provider; 1 none available; 2 invocation error.\n";
|
|
3
|
+
export declare function run(args?: string[]): Promise<number>;
|