@allixsenos/asu 0.8.0 → 0.9.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 CHANGED
@@ -7,7 +7,7 @@ ASU is a local TypeScript CLI for humans and agents. It finds supported installa
7
7
  ## What it looks like
8
8
 
9
9
  ```bash
10
- npx --yes @allixsenos/asu
10
+ npx --yes @allixsenos/asu@latest
11
11
  ```
12
12
 
13
13
  ```text
@@ -42,26 +42,26 @@ This is a real run against the maintainer's accounts on 2026-09-10. In a termina
42
42
  ASU needs **Node.js 22.13 or newer** and npm. Sign in through the provider's own CLI first.
43
43
 
44
44
  ```bash
45
- npx --yes @allixsenos/asu
45
+ npx --yes @allixsenos/asu@latest
46
46
  ```
47
47
 
48
48
  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.
49
49
 
50
50
  ```bash
51
51
  # Plain text for terminals, logs, and pipes
52
- npx --yes @allixsenos/asu --plain
52
+ npx --yes @allixsenos/asu@latest --plain
53
53
 
54
54
  # Structured output for agents and scripts
55
- npx --yes @allixsenos/asu --json
55
+ npx --yes @allixsenos/asu@latest --json
56
56
 
57
57
  # One provider, by its bare name
58
- npx --yes @allixsenos/asu claude
58
+ npx --yes @allixsenos/asu@latest claude
59
59
 
60
60
  # Select accounts and bypass the five-minute usage cache
61
- npx --yes @allixsenos/asu claude codex copilot --fresh --table
61
+ npx --yes @allixsenos/asu@latest claude codex copilot --fresh --table
62
62
 
63
63
  # Include every built-in provider, even if no credentials are found
64
- npx --yes @allixsenos/asu --all --table
64
+ npx --yes @allixsenos/asu@latest --all --table
65
65
  ```
66
66
 
67
67
  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.
@@ -395,7 +395,7 @@ A zero exit code does not mean that every provider succeeded. When you automate
395
395
  ### Use JSON in scripts
396
396
 
397
397
  ```bash
398
- npx --yes @allixsenos/asu --json > usage.json
398
+ npx --yes @allixsenos/asu@latest --json > usage.json
399
399
  jq '.providers[] | {providerId, availability, planLabel, windows}' usage.json
400
400
 
401
401
  # Find available providers with a window at or above 80% used
@@ -483,6 +483,8 @@ An HTTP request has an eight-second deadline, a one-MiB response limit, and no r
483
483
 
484
484
  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.
485
485
 
486
+ Once a day, after the report, ASU asks the npm registry for its own newest version and prints one line on stderr when a newer one exists. The request carries only the package name, and the answer is kept in the cache directory. `--no-cache`, `ASU_NO_UPDATE_CHECK=1`, `NO_UPDATE_NOTIFIER=1`, or `CI=true` turns the check off. This is the only request ASU makes to anything other than a provider.
487
+
486
488
  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.
487
489
 
488
490
  ## Troubleshooting
@@ -499,13 +501,14 @@ ASU prints and caches only normalized usage. It excludes tokens, refresh tokens,
499
501
  | `invalid_response` | The provider may have a new response schema. See the [known limitations](docs/provider-contracts.md#known-limitations). |
500
502
  | Usage looks stale | Examine `fetchedAt` and `cached`, then use `--fresh`. ASU cannot make the provider update its figures sooner. |
501
503
  | 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. |
504
+ | `npx --yes @allixsenos/asu` runs an old version | npx reuses the first version it cached for a bare name and never looks again. Use `@allixsenos/asu@latest`, which resolves on every run, or remove the cache with `rm -rf ~/.npm/_npx`. ASU prints a one-line notice on stderr once a day when a newer version exists. |
502
505
 
503
506
  ## Plugins
504
507
 
505
508
  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.
506
509
 
507
510
  ```bash
508
- npx --yes @allixsenos/asu --plugin ./my-provider.mjs --provider my-provider --json
511
+ npx --yes @allixsenos/asu@latest --plugin ./my-provider.mjs --provider my-provider --json
509
512
  ```
510
513
 
511
514
  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.js CHANGED
@@ -8,7 +8,9 @@ import { createLocalContext, homePath } from './local.js';
8
8
  import { loadProviders } from './registry.js';
9
9
  import { UsageService } from './service.js';
10
10
  import { barsOverflow, render, tableWraps } from './output.js';
11
- import { version } from './version.js';
11
+ import { name, version } from './version.js';
12
+ import { checkForUpdate } from './update.js';
13
+ import { createTransport } from './transport.js';
12
14
  export const help = `asu — agent subscription usage
13
15
 
14
16
  Usage: asu [usage] [provider...] [options]
@@ -81,6 +83,13 @@ export async function run(args = process.argv.slice(2)) {
81
83
  if (format === 'bars' && !explicit && barsOverflow(report, options))
82
84
  format = 'plain';
83
85
  process.stdout.write(render(report, format, options));
86
+ // Once a day, after the report, ask npm for a newer version. One line on stderr, never on stdout.
87
+ const env = local.env;
88
+ if (!values['no-cache'] && !env.ASU_NO_UPDATE_CHECK && !env.NO_UPDATE_NOTIFIER && !env.CI) {
89
+ const notice = await checkForUpdate({ directory, request: createTransport(fetch, 2_000, 65_536), name, version });
90
+ if (notice)
91
+ process.stderr.write(`${notice}\n`);
92
+ }
84
93
  return report.providers.some(provider => provider.availability === 'available') ? 0 : 1;
85
94
  }
86
95
  catch (error) {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { RequestJson } from './transport.js';
2
+ export declare const UPDATE_CHECK_INTERVAL_MS = 86400000;
3
+ export interface UpdateCheckOptions {
4
+ /** The private cache directory. The daily stamp lives next to the usage cache. */
5
+ directory: string;
6
+ request: RequestJson;
7
+ name: string;
8
+ version: string;
9
+ now?: () => number;
10
+ }
11
+ /**
12
+ * Ask the npm registry for the newest version at most once a day.
13
+ * Returns a one-line notice when a newer version exists, otherwise null. Never throws.
14
+ */
15
+ export declare function checkForUpdate(options: UpdateCheckOptions): Promise<string | null>;
package/dist/update.js ADDED
@@ -0,0 +1,51 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ export const UPDATE_CHECK_INTERVAL_MS = 86_400_000;
4
+ /** Compare two plain x.y.z versions by their numeric parts. A prerelease or anything unparsable compares as older. */
5
+ function newer(candidate, current) {
6
+ const parse = (value) => /^(\d+)\.(\d+)\.(\d+)$/.exec(value)?.slice(1, 4).map(Number);
7
+ const a = parse(candidate), b = parse(current);
8
+ if (!a || !b)
9
+ return false;
10
+ for (let i = 0; i < 3; i++)
11
+ if (a[i] !== b[i])
12
+ return a[i] > b[i];
13
+ return false;
14
+ }
15
+ async function readStamp(path) {
16
+ try {
17
+ const raw = JSON.parse(await readFile(path, 'utf8'));
18
+ if (raw && typeof raw === 'object' && typeof raw.checkedAt === 'string' && typeof raw.latest === 'string')
19
+ return raw;
20
+ }
21
+ catch { /* No stamp yet, or an unreadable one. Check again. */ }
22
+ return null;
23
+ }
24
+ /**
25
+ * Ask the npm registry for the newest version at most once a day.
26
+ * Returns a one-line notice when a newer version exists, otherwise null. Never throws.
27
+ */
28
+ export async function checkForUpdate(options) {
29
+ const now = options.now ?? Date.now;
30
+ const path = join(options.directory, 'update-check.json');
31
+ try {
32
+ let stamp = await readStamp(path);
33
+ if (!stamp || now() - Date.parse(stamp.checkedAt) >= UPDATE_CHECK_INTERVAL_MS || now() < Date.parse(stamp.checkedAt)) {
34
+ const document = await options.request(`https://registry.npmjs.org/${encodeURIComponent(options.name)}/latest`);
35
+ const latest = document && typeof document === 'object' && typeof document.version === 'string'
36
+ ? document.version : null;
37
+ if (!latest)
38
+ return null;
39
+ stamp = { checkedAt: new Date(now()).toISOString(), latest };
40
+ await mkdir(options.directory, { recursive: true, mode: 0o700 });
41
+ await writeFile(path, JSON.stringify(stamp), { mode: 0o600 });
42
+ }
43
+ return newer(stamp.latest, options.version)
44
+ ? `asu: ${stamp.latest} is available, you run ${options.version}. Update: npx --yes ${options.name}@latest`
45
+ : null;
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- /** The package version, read once from package.json so the CLI, User-Agent and package never disagree. */
1
+ export declare const name: string;
2
2
  export declare const version: string;
package/dist/version.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { createRequire } from 'node:module';
2
- /** The package version, read once from package.json so the CLI, User-Agent and package never disagree. */
3
- export const version = createRequire(import.meta.url)('../package.json').version;
2
+ /** The package name and version, read once from package.json so the CLI, User-Agent and package never disagree. */
3
+ const pkg = createRequire(import.meta.url)('../package.json');
4
+ export const name = pkg.name;
5
+ export const version = pkg.version;
4
6
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,0GAA0G;AAC1G,MAAM,CAAC,MAAM,OAAO,GAAY,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAyB,CAAC,OAAO,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,mHAAmH;AACnH,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAsC,CAAC;AACnG,MAAM,CAAC,MAAM,IAAI,GAAW,GAAG,CAAC,IAAI,CAAC;AACrC,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC"}
@@ -5,12 +5,12 @@ ASU reports how much of a coding-agent subscription you used, straight from the
5
5
  ## The call
6
6
 
7
7
  ```bash
8
- npx --yes @allixsenos/asu <provider> --json
8
+ npx --yes @allixsenos/asu@latest <provider> --json
9
9
  ```
10
10
 
11
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
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.
13
+ Use `--json`. Stdout holds only the report. Diagnostics go to stderr, including a once-a-day notice when a newer ASU exists, which you can ignore. The `@latest` tag matters: `npx` freezes a bare package name at the first version it cached. 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
14
 
15
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
16
 
@@ -32,14 +32,14 @@ For each entry in `providers`:
32
32
  Highest usage across all windows of one provider:
33
33
 
34
34
  ```bash
35
- npx --yes @allixsenos/asu claude --json \
35
+ npx --yes @allixsenos/asu@latest claude --json \
36
36
  | jq '[.providers[0].windows[].percentUsed | select(. != null)] | max'
37
37
  ```
38
38
 
39
39
  Minutes until the most constrained window resets:
40
40
 
41
41
  ```bash
42
- npx --yes @allixsenos/asu claude --json \
42
+ npx --yes @allixsenos/asu@latest claude --json \
43
43
  | jq -r '.providers[0].windows | max_by(.percentUsed // 0) | .resetsAt' \
44
44
  | xargs -I{} node -e 'console.log(Math.round((Date.parse("{}") - Date.now()) / 60000))'
45
45
  ```
@@ -47,7 +47,7 @@ npx --yes @allixsenos/asu claude --json \
47
47
  Every available provider with a window at or above 80 percent:
48
48
 
49
49
  ```bash
50
- npx --yes @allixsenos/asu --json | jq '[.providers[]
50
+ npx --yes @allixsenos/asu@latest --json | jq '[.providers[]
51
51
  | select(.availability == "available")
52
52
  | select(any(.windows[]; .percentUsed != null and .percentUsed >= 80))
53
53
  | .providerId]'
@@ -63,7 +63,7 @@ npx --yes @allixsenos/asu --json | jq '[.providers[]
63
63
  ## Paste into your project's agent instructions
64
64
 
65
65
  ```markdown
66
- Before a long task, run `npx --yes @allixsenos/asu claude --json` and read the highest
66
+ Before a long task, run `npx --yes @allixsenos/asu@latest claude --json` and read the highest
67
67
  `percentUsed` in `providers[0].windows`. Continue below 70. Between 70 and 90 use smaller
68
68
  steps. At 90 or above, stop, and tell the user the figure and the `resetsAt` time.
69
69
  Do not run it more than once per five minutes.
package/docs/releasing.md CHANGED
@@ -43,7 +43,7 @@ After that, every release publishes on its own.
43
43
  ## Install a released version
44
44
 
45
45
  ```bash
46
- npx --yes @allixsenos/asu --table
46
+ npx --yes @allixsenos/asu@latest --table
47
47
  ```
48
48
 
49
49
  No token is needed. The package is public on the npm registry.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allixsenos/asu",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Agent subscription usage for humans and agents",
5
5
  "type": "module",
6
6
  "bin": {