@allixsenos/asu 0.3.0 → 0.5.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/README.md +62 -21
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +11 -6
- package/dist/cli.js.map +1 -1
- package/dist/providers/parse.js +2 -1
- package/dist/providers/parse.js.map +1 -1
- package/docs/agent-usage.md +76 -0
- package/docs/architecture.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,43 +4,83 @@ See how much of your coding-agent subscription you used, straight from the provi
|
|
|
4
4
|
|
|
5
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
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
ASU needs **Node.js 22.13 or newer**, npm, and Git. Sign in through the provider's own CLI first.
|
|
7
|
+
## What it looks like
|
|
10
8
|
|
|
11
9
|
```bash
|
|
12
|
-
npx --yes
|
|
10
|
+
npx --yes @allixsenos/asu --table
|
|
13
11
|
```
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
```text
|
|
14
|
+
ASU · 2026-09-08T09:22:58.225Z
|
|
15
|
+
┌──────────────────┬────────────────────┬───────────────────────┬───────────────────────┬────────────────────┐
|
|
16
|
+
│ Provider │ Plan / status │ Window / balance │ Usage │ Resets in │
|
|
17
|
+
├──────────────────┼────────────────────┼───────────────────────┼───────────────────────┼────────────────────┤
|
|
18
|
+
│ Claude │ Max 20x │ 5 hours │ 22% used │ 7m │
|
|
19
|
+
│ │ available │ │ │ │
|
|
20
|
+
│ │ fresh │ │ │ │
|
|
21
|
+
│ │ │ Weekly │ 5% used │ 6d19h (Tue 15 Sep) │
|
|
22
|
+
│ │ │ Weekly · Fable │ 7% used │ 6d19h (Tue 15 Sep) │
|
|
23
|
+
│ │ │ Extra usage │ Disabled │ — │
|
|
24
|
+
├──────────────────┼────────────────────┼───────────────────────┼───────────────────────┼────────────────────┤
|
|
25
|
+
│ Codex │ Plus │ 5 hours │ 0% used │ 5h │
|
|
26
|
+
│ │ available │ │ │ │
|
|
27
|
+
│ │ fresh │ │ │ │
|
|
28
|
+
│ │ │ Weekly │ 0% used │ 7d (Tue 15 Sep) │
|
|
29
|
+
│ │ │ Gpt Reserve · Weekly │ 0% used │ 7d (Tue 15 Sep) │
|
|
30
|
+
│ │ │ Credits │ 0 credits left │ — │
|
|
31
|
+
│ │ │ Credits available │ No │ — │
|
|
32
|
+
├──────────────────┼────────────────────┼───────────────────────┼───────────────────────┼────────────────────┤
|
|
33
|
+
│ GitHub Copilot │ Individual │ Chat │ 0% used │ 22d14h (Thu 1 Oct) │
|
|
34
|
+
│ │ available │ │ 0 / 200 requests │ │
|
|
35
|
+
│ │ fresh │ │ │ │
|
|
36
|
+
│ │ │ Completions │ 0% used │ 22d14h (Thu 1 Oct) │
|
|
37
|
+
│ │ │ │ 0 / 2,000 requests │ │
|
|
38
|
+
│ │ │ Premium Interactions │ 100% used │ 22d14h (Thu 1 Oct) │
|
|
39
|
+
│ │ │ │ 0 / 0 requests │ │
|
|
40
|
+
└──────────────────┴────────────────────┴───────────────────────┴───────────────────────┴────────────────────┘
|
|
41
|
+
Claude: fetched <1m ago; cache expires in 5m.
|
|
42
|
+
Codex: fetched <1m ago; cache expires in 5m.
|
|
43
|
+
GitHub Copilot: fetched <1m ago; cache expires in 5m.
|
|
19
44
|
```
|
|
20
45
|
|
|
21
|
-
|
|
46
|
+
This is a real run against the maintainer's accounts on 2026-09-08. Reset times are relative to the moment of the run. Pass `--utc` for full timestamps, `--plain` for log-friendly text, or `--json` for agents and scripts.
|
|
47
|
+
|
|
48
|
+
## Quick start
|
|
49
|
+
|
|
50
|
+
ASU needs **Node.js 22.13 or newer** and npm. Sign in through the provider's own CLI first.
|
|
22
51
|
|
|
23
52
|
```bash
|
|
24
53
|
npx --yes @allixsenos/asu --table
|
|
25
54
|
```
|
|
26
55
|
|
|
27
|
-
Your provider credentials, which are separate, let ASU read usage.
|
|
56
|
+
This runs the newest release of [`@allixsenos/asu`](https://www.npmjs.com/package/@allixsenos/asu) from npm. No token is needed. Your provider credentials, which are separate, let ASU read usage.
|
|
28
57
|
|
|
29
58
|
```bash
|
|
30
59
|
# Plain text for terminals, logs, and pipes
|
|
31
|
-
npx --yes
|
|
60
|
+
npx --yes @allixsenos/asu --plain
|
|
32
61
|
|
|
33
62
|
# Structured output for agents and scripts
|
|
34
|
-
npx --yes
|
|
63
|
+
npx --yes @allixsenos/asu --json
|
|
64
|
+
|
|
65
|
+
# One provider, by its bare name
|
|
66
|
+
npx --yes @allixsenos/asu claude
|
|
35
67
|
|
|
36
68
|
# Select accounts and bypass the five-minute usage cache
|
|
37
|
-
npx --yes
|
|
69
|
+
npx --yes @allixsenos/asu claude codex copilot --fresh --table
|
|
38
70
|
|
|
39
71
|
# Include every built-in provider, even if no credentials are found
|
|
40
|
-
npx --yes
|
|
72
|
+
npx --yes @allixsenos/asu --all --table
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
To pin a version, name it, for example `@allixsenos/asu@0.3.0`. The `--fresh` flag refreshes provider usage. It does not select a newer package revision.
|
|
76
|
+
|
|
77
|
+
### Run the unreleased main branch
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx --yes github:allixsenos/asu --table
|
|
41
81
|
```
|
|
42
82
|
|
|
43
|
-
For SSH, use `git+ssh://git@github.com/allixsenos/asu.git#main
|
|
83
|
+
This needs Git. The repository commits the built `dist/` directory, so the install needs no build step. For SSH, use `git+ssh://git@github.com/allixsenos/asu.git#main`. To pin a commit or a tag, append it, for example `github:allixsenos/asu#v0.3.0`. Each GitHub release also carries the packed tarball, and `npx --yes https://github.com/allixsenos/asu/releases/latest/download/asu.tgz --table` runs the newest one.
|
|
44
84
|
|
|
45
85
|
## Real account output
|
|
46
86
|
|
|
@@ -305,17 +345,18 @@ Use `--json` for agents and scripts. Stdout contains the report. An ASU invocati
|
|
|
305
345
|
## CLI reference
|
|
306
346
|
|
|
307
347
|
```text
|
|
308
|
-
asu [usage] [options]
|
|
348
|
+
asu [usage] [provider...] [options]
|
|
309
349
|
```
|
|
310
350
|
|
|
311
|
-
When you run ASU through `npx`, put the ASU options after the package
|
|
351
|
+
When you run ASU through `npx`, put the ASU options after the package name.
|
|
312
352
|
|
|
313
353
|
| Option | Behavior |
|
|
314
354
|
| --- | --- |
|
|
315
355
|
| `--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
356
|
| `--plain`, `--table`, `--json` | Shortcuts for `--format`. Use only one. |
|
|
317
357
|
| `--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
|
-
|
|
|
358
|
+
| `claude codex` | Select providers by their bare names, in any position. `asu claude --plain` and `asu --plain claude` are the same. |
|
|
359
|
+
| `--provider claude,codex` | The same selection as a flag. Repeat the flag or separate the IDs with commas. |
|
|
319
360
|
| `--all` | Include providers with no detected installation or credentials |
|
|
320
361
|
| `--fresh` | Bypass cached usage. Concurrent fresh requests still share one fetch. |
|
|
321
362
|
| `--no-cache` | Do not read or write the persistent cache |
|
|
@@ -339,7 +380,7 @@ A zero exit code does not mean that every provider succeeded. When you automate
|
|
|
339
380
|
### Use JSON in scripts
|
|
340
381
|
|
|
341
382
|
```bash
|
|
342
|
-
npx --yes
|
|
383
|
+
npx --yes @allixsenos/asu --json > usage.json
|
|
343
384
|
jq '.providers[] | {providerId, availability, planLabel, windows}' usage.json
|
|
344
385
|
|
|
345
386
|
# Find available providers with a window at or above 80% used
|
|
@@ -363,7 +404,7 @@ A consumer must examine `schemaVersion` before it processes a report. Version 1
|
|
|
363
404
|
| `details` | Additional normalized label and value pairs |
|
|
364
405
|
| `fetchedAt`, `expiresAt`, `cached` | Timestamp and freshness of each provider snapshot |
|
|
365
406
|
|
|
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.
|
|
407
|
+
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. An agent that wants to watch its own budget can follow [Use ASU from an agent](docs/agent-usage.md). The [asu-usage skill](skills/asu-usage/SKILL.md) measures what one command costs, and `npx skills add allixsenos/asu` installs it.
|
|
367
408
|
|
|
368
409
|
## Supported providers
|
|
369
410
|
|
|
@@ -448,7 +489,7 @@ ASU prints and caches only normalized usage. It excludes tokens, refresh tokens,
|
|
|
448
489
|
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
490
|
|
|
450
491
|
```bash
|
|
451
|
-
npx --yes
|
|
492
|
+
npx --yes @allixsenos/asu --plugin ./my-provider.mjs --provider my-provider --json
|
|
452
493
|
```
|
|
453
494
|
|
|
454
495
|
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.
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
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";
|
|
2
|
+
export declare const help = "asu \u2014 agent subscription usage\n\nUsage: asu [usage] [provider...] [options]\n\n asu Every detected provider\n asu claude One provider, by its bare name\n asu claude codex --plain Several providers, with options anywhere\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; same as a bare name, 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
3
|
export declare function run(args?: string[]): Promise<number>;
|
package/dist/cli.js
CHANGED
|
@@ -11,14 +11,18 @@ import { render, tableWraps } from './output.js';
|
|
|
11
11
|
import { version } from './version.js';
|
|
12
12
|
export const help = `asu — agent subscription usage
|
|
13
13
|
|
|
14
|
-
Usage: asu [usage] [options]
|
|
14
|
+
Usage: asu [usage] [provider...] [options]
|
|
15
|
+
|
|
16
|
+
asu Every detected provider
|
|
17
|
+
asu claude One provider, by its bare name
|
|
18
|
+
asu claude codex --plain Several providers, with options anywhere
|
|
15
19
|
|
|
16
20
|
--format plain|table|json Output format (table in a terminal, plain when piped or when the table would wrap)
|
|
17
21
|
--json Shortcut for --format json
|
|
18
22
|
--plain Shortcut for --format plain
|
|
19
23
|
--table Shortcut for --format table
|
|
20
24
|
--utc Print full UTC timestamps instead of times relative to now
|
|
21
|
-
--provider <id> Select provider; repeat or use comma-separated IDs
|
|
25
|
+
--provider <id> Select provider; same as a bare name, repeat or use comma-separated IDs
|
|
22
26
|
--all Include providers with no detected install or credentials
|
|
23
27
|
--fresh Fetch again, bypassing the five-minute cache
|
|
24
28
|
--no-cache Do not read or write the persistent cache
|
|
@@ -49,15 +53,16 @@ export async function run(args = process.argv.slice(2)) {
|
|
|
49
53
|
process.stdout.write(`${version}\n`);
|
|
50
54
|
return 0;
|
|
51
55
|
}
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
// Bare words are provider names. A leading "usage" stays accepted for compatibility.
|
|
57
|
+
const names = positionals[0] === 'usage' ? positionals.slice(1) : positionals;
|
|
54
58
|
const formats = [values.format, values.json ? 'json' : undefined, values.plain ? 'plain' : undefined, values.table ? 'table' : undefined].filter(Boolean);
|
|
55
59
|
if (formats.length > 1 || formats.some(value => !['plain', 'table', 'json'].includes(value)))
|
|
56
60
|
throw new Error('Choose one output format: plain, table, or json.');
|
|
57
61
|
const explicit = formats.length > 0;
|
|
58
62
|
format = formats[0] ?? format;
|
|
59
63
|
const providers = await loadProviders(values.plugin);
|
|
60
|
-
const
|
|
64
|
+
const selected = [...(values.provider ?? []), ...names].flatMap(value => value.split(',')).map(value => value.trim()).filter(Boolean);
|
|
65
|
+
const providerIds = selected.length ? selected : undefined;
|
|
61
66
|
if (providerIds?.some(id => !providers.some(provider => provider.id === id)))
|
|
62
67
|
throw new Error('Unknown provider ID. See --help for built-ins.');
|
|
63
68
|
const local = createLocalContext();
|
|
@@ -76,7 +81,7 @@ export async function run(args = process.argv.slice(2)) {
|
|
|
76
81
|
}
|
|
77
82
|
catch (error) {
|
|
78
83
|
// All errors exposed here are ours; do not print plugin/import/runtime exception messages.
|
|
79
|
-
const messages = ['
|
|
84
|
+
const messages = ['Choose one output format: plain, table, or json.',
|
|
80
85
|
'Unknown provider ID. See --help for built-ins.', 'Could not load a provider plugin. Check its path, exports, and unique provider ID.'];
|
|
81
86
|
const message = error instanceof Error && messages.includes(error.message) ? error.message : 'Could not run ASU. Check arguments and plugin configuration; see --help.';
|
|
82
87
|
process.stderr.write(`asu: ${message}\n`);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/providers/parse.js
CHANGED
|
@@ -39,8 +39,9 @@ export function timestamp(value) {
|
|
|
39
39
|
: numeric < 100_000_000_000 ? numeric * 1000 : numeric;
|
|
40
40
|
if (!Number.isFinite(ms))
|
|
41
41
|
throw new UsageError('invalid_response');
|
|
42
|
+
// Providers compute reset times relative to the request, so the milliseconds jitter between calls. Whole seconds are stable enough.
|
|
42
43
|
try {
|
|
43
|
-
return new Date(ms).toISOString();
|
|
44
|
+
return new Date(Math.round(ms / 1000) * 1000).toISOString();
|
|
44
45
|
}
|
|
45
46
|
catch {
|
|
46
47
|
throw new UsageError('invalid_response');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/providers/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC1G,OAAO,KAAY,CAAC;AACtB,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAc,IAAS,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClG,MAAM,UAAU,IAAI,CAAC,KAAc;IACjC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACjH,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC;AACD,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC9D,OAAO,CAAC,CAAC,CAAC,2DAA2D;AACvE,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACtF,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACnE,IAAI,CAAC;QAAC,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/providers/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Use ASU from an agent
|
|
2
|
+
|
|
3
|
+
ASU reports how much of a coding-agent subscription you used, straight from the provider's account API. An agent can call it to check its own budget before a long task. The figures tell it when to slow down or stop.
|
|
4
|
+
|
|
5
|
+
## The call
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx --yes @allixsenos/asu <provider> --json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Provider names: `claude` for Claude Code, `codex` for Codex, `copilot` for GitHub Copilot, `cursor`, `zai`, `grok`, `kimi`, `minimax`. Without a name, ASU reports every provider it detects.
|
|
12
|
+
|
|
13
|
+
Use `--json`. Stdout holds only the report. Diagnostics go to stderr. Exit code 0 means at least one selected provider returned usage. Exit code 1 means none did, and the report still explains why. Exit code 2 means the invocation was wrong.
|
|
14
|
+
|
|
15
|
+
ASU only reads credentials that the provider's own CLI already stored. It never signs in, refreshes a token, or writes to a provider file.
|
|
16
|
+
|
|
17
|
+
## What to read
|
|
18
|
+
|
|
19
|
+
Check `schemaVersion` first. This document describes version 1.
|
|
20
|
+
|
|
21
|
+
For each entry in `providers`:
|
|
22
|
+
|
|
23
|
+
- `availability` is `available`, `unavailable`, or `error`. Only `available` carries usage.
|
|
24
|
+
- `windows` is the list of rate-limit windows. Each has `label`, `percentUsed`, and `resetsAt`. A provider can have any number of windows, in any order. Do not assume a fixed set.
|
|
25
|
+
- `percentUsed` is `null` when the provider did not report it. It can exceed 100 when the provider reports overage.
|
|
26
|
+
- `resetsAt` is a UTC timestamp or `null`. Time until reset is `resetsAt` minus now. Providers compute it relative to each request, so the value can jitter by a second or more between calls, and an idle Codex window moves with the clock. Treat a change of less than a few minutes as the same reset. A real reset moves it forward by a whole window.
|
|
27
|
+
- `reason.code` explains an unavailable or failed provider: `missing_credentials`, `invalid_credentials`, `unauthorized`, `timeout`, `rate_limited`, `http_error`, `invalid_response`, or `provider_error`.
|
|
28
|
+
- `cached` is true when the figures come from ASU's five-minute cache. `fetchedAt` is the time of that fetch.
|
|
29
|
+
|
|
30
|
+
## Recipes
|
|
31
|
+
|
|
32
|
+
Highest usage across all windows of one provider:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx --yes @allixsenos/asu claude --json \
|
|
36
|
+
| jq '[.providers[0].windows[].percentUsed | select(. != null)] | max'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Minutes until the most constrained window resets:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx --yes @allixsenos/asu claude --json \
|
|
43
|
+
| jq -r '.providers[0].windows | max_by(.percentUsed // 0) | .resetsAt' \
|
|
44
|
+
| xargs -I{} node -e 'console.log(Math.round((Date.parse("{}") - Date.now()) / 60000))'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Every available provider with a window at or above 80 percent:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx --yes @allixsenos/asu --json | jq '[.providers[]
|
|
51
|
+
| select(.availability == "available")
|
|
52
|
+
| select(any(.windows[]; .percentUsed != null and .percentUsed >= 80))
|
|
53
|
+
| .providerId]'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## A policy that works
|
|
57
|
+
|
|
58
|
+
1. Run the call once at the start of a task, then again before each expensive step.
|
|
59
|
+
2. Read the highest `percentUsed` among the windows that reset within the next few hours. For Claude and Codex that is the five-hour window. The weekly window matters when it is above 90.
|
|
60
|
+
3. Below 70, continue. Between 70 and 90, prefer smaller steps and fewer retries. At or above 90, finish the current step, report the figure and the reset time to the user, and stop.
|
|
61
|
+
4. Do not poll more often than every five minutes. ASU caches for five minutes, and `--fresh` sends a new request to the provider. Frequent fresh requests can hit the provider's rate limit, which ASU reports as `rate_limited`.
|
|
62
|
+
|
|
63
|
+
## Paste into your project's agent instructions
|
|
64
|
+
|
|
65
|
+
```markdown
|
|
66
|
+
Before a long task, run `npx --yes @allixsenos/asu claude --json` and read the highest
|
|
67
|
+
`percentUsed` in `providers[0].windows`. Continue below 70. Between 70 and 90 use smaller
|
|
68
|
+
steps. At 90 or above, stop, and tell the user the figure and the `resetsAt` time.
|
|
69
|
+
Do not run it more than once per five minutes.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Replace `claude` with the provider you run on.
|
|
73
|
+
|
|
74
|
+
## Measure one command
|
|
75
|
+
|
|
76
|
+
The [asu-usage skill](../skills/asu-usage/SKILL.md) in this repository takes a snapshot before and after a command, prints the percentage points each window consumed, and appends the result to a ledger. Install it with `npx skills add allixsenos/asu`, or copy the directory into your agent's skills folder.
|
package/docs/architecture.md
CHANGED
|
@@ -74,7 +74,7 @@ ASU resolves an installed package name from the current working directory. It ne
|
|
|
74
74
|
|
|
75
75
|
`schemaVersion: 1` is the machine interface. `generatedAt` describes the report. `fetchedAt` and `expiresAt` describe each provider snapshot. A result includes `providerId`, `displayName`, `experimental`, `installed`, `credentialsPresent`, `authenticated`, `availability`, an optional `reason`, `planLabel`, `windows`, `balances`, `details`, and `cached`.
|
|
76
76
|
|
|
77
|
-
A window has a stable ID, a label, `percentUsed`, and a UTC `resetsAt`. It can also have quantities, a unit, an unlimited flag, and a model or surface scope. An unknown percentage or reset is `null`. An absent balance or quantity is not zero. A percentage can exceed 100 when the provider reports overage. The human renderers round to two decimals. JSON keeps the normalized precision. An unlimited window shows no percentage.
|
|
77
|
+
A window has a stable ID, a label, `percentUsed`, and a UTC `resetsAt`. It can also have quantities, a unit, an unlimited flag, and a model or surface scope. An unknown percentage or reset is `null`. `resetsAt` has whole-second precision. Providers compute it relative to the request, so two calls can still differ by a second or more for the same window, and an idle Codex window moves with the clock. Compare reset times with a tolerance of a few minutes. An absent balance or quantity is not zero. A percentage can exceed 100 when the provider reports overage. The human renderers round to two decimals. JSON keeps the normalized precision. An unlimited window shows no percentage.
|
|
78
78
|
|
|
79
79
|
Availability is one of three values. `available` means the provider returned usage. `unavailable` means the credentials are missing, rejected, or unreadable. `error` means the fetch or the normalization failed. `authenticated` is `true` only after a recognized successful usage response. It is `false` for unavailable credentials. It is `null` after a request failure that cannot establish authentication. These are snapshot values. They do not promise that the token stays valid after `fetchedAt`.
|
|
80
80
|
|