@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/dist/cli.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from 'node:util';
|
|
3
|
+
import { realpathSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { resolve } from 'node:path';
|
|
6
|
+
import { UsageCache } from './cache.js';
|
|
7
|
+
import { createLocalContext, homePath } from './local.js';
|
|
8
|
+
import { loadProviders } from './registry.js';
|
|
9
|
+
import { UsageService } from './service.js';
|
|
10
|
+
import { render, tableWraps } from './output.js';
|
|
11
|
+
import { version } from './version.js';
|
|
12
|
+
export const help = `asu — agent subscription usage
|
|
13
|
+
|
|
14
|
+
Usage: asu [usage] [options]
|
|
15
|
+
|
|
16
|
+
--format plain|table|json Output format (table in a terminal, plain when piped or when the table would wrap)
|
|
17
|
+
--json Shortcut for --format json
|
|
18
|
+
--plain Shortcut for --format plain
|
|
19
|
+
--table Shortcut for --format table
|
|
20
|
+
--utc Print full UTC timestamps instead of times relative to now
|
|
21
|
+
--provider <id> Select provider; repeat or use comma-separated IDs
|
|
22
|
+
--all Include providers with no detected install or credentials
|
|
23
|
+
--fresh Fetch again, bypassing the five-minute cache
|
|
24
|
+
--no-cache Do not read or write the persistent cache
|
|
25
|
+
--cache-dir <path> Override the private usage cache directory
|
|
26
|
+
--plugin <path-or-package> Load a trusted provider plugin; repeatable
|
|
27
|
+
--help, -h Show this help
|
|
28
|
+
--version, -v Show version
|
|
29
|
+
|
|
30
|
+
Providers: claude, codex, copilot, cursor, zai, grok, kimi, minimax
|
|
31
|
+
Credentials are read-only. Sign in and refresh tokens through the provider CLI.
|
|
32
|
+
JSON has schemaVersion: 1. Diagnostics go to stderr; stdout contains only the report.
|
|
33
|
+
Exit codes: 0 at least one available provider; 1 none available; 2 invocation error.
|
|
34
|
+
`;
|
|
35
|
+
export async function run(args = process.argv.slice(2)) {
|
|
36
|
+
let format = process.stdout.isTTY ? 'table' : 'plain';
|
|
37
|
+
try {
|
|
38
|
+
const { values, positionals } = parseArgs({ args, allowPositionals: true, strict: true, options: {
|
|
39
|
+
format: { type: 'string' }, json: { type: 'boolean' }, plain: { type: 'boolean' }, table: { type: 'boolean' }, utc: { type: 'boolean' },
|
|
40
|
+
provider: { type: 'string', multiple: true }, all: { type: 'boolean' }, fresh: { type: 'boolean' },
|
|
41
|
+
'no-cache': { type: 'boolean' }, 'cache-dir': { type: 'string' }, plugin: { type: 'string', multiple: true },
|
|
42
|
+
help: { type: 'boolean', short: 'h' }, version: { type: 'boolean', short: 'v' },
|
|
43
|
+
} });
|
|
44
|
+
if (values.help) {
|
|
45
|
+
process.stdout.write(help);
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
if (values.version) {
|
|
49
|
+
process.stdout.write(`${version}\n`);
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
if (positionals.length > 1 || positionals.length === 1 && positionals[0] !== 'usage')
|
|
53
|
+
throw new Error('Expected asu [usage]. See --help.');
|
|
54
|
+
const formats = [values.format, values.json ? 'json' : undefined, values.plain ? 'plain' : undefined, values.table ? 'table' : undefined].filter(Boolean);
|
|
55
|
+
if (formats.length > 1 || formats.some(value => !['plain', 'table', 'json'].includes(value)))
|
|
56
|
+
throw new Error('Choose one output format: plain, table, or json.');
|
|
57
|
+
const explicit = formats.length > 0;
|
|
58
|
+
format = formats[0] ?? format;
|
|
59
|
+
const providers = await loadProviders(values.plugin);
|
|
60
|
+
const providerIds = values.provider?.flatMap(value => value.split(',')).map(value => value.trim());
|
|
61
|
+
if (providerIds?.some(id => !providers.some(provider => provider.id === id)))
|
|
62
|
+
throw new Error('Unknown provider ID. See --help for built-ins.');
|
|
63
|
+
const local = createLocalContext();
|
|
64
|
+
const cacheRoot = homePath(local, local.env.XDG_CACHE_HOME, '.cache');
|
|
65
|
+
const directory = homePath(local, values['cache-dir'] ?? local.env.ASU_CACHE_DIR, `${cacheRoot}/asu`);
|
|
66
|
+
const service = new UsageService(providers, { local, cache: new UsageCache(values['no-cache'] ? undefined : directory) });
|
|
67
|
+
const report = await service.collect({ providerIds, fresh: values.fresh });
|
|
68
|
+
if (!values.all && !providerIds?.length)
|
|
69
|
+
report.providers = report.providers.filter(provider => provider.installed || provider.credentialsPresent || provider.reason?.code !== 'missing_credentials');
|
|
70
|
+
const options = { columns: process.stdout.columns, utc: values.utc };
|
|
71
|
+
// A table that must wrap in a narrow terminal is harder to read than plain text.
|
|
72
|
+
if (format === 'table' && !explicit && tableWraps(report, options))
|
|
73
|
+
format = 'plain';
|
|
74
|
+
process.stdout.write(render(report, format, options));
|
|
75
|
+
return report.providers.some(provider => provider.availability === 'available') ? 0 : 1;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
// All errors exposed here are ours; do not print plugin/import/runtime exception messages.
|
|
79
|
+
const messages = ['Expected asu [usage]. See --help.', 'Choose one output format: plain, table, or json.',
|
|
80
|
+
'Unknown provider ID. See --help for built-ins.', 'Could not load a provider plugin. Check its path, exports, and unique provider ID.'];
|
|
81
|
+
const message = error instanceof Error && messages.includes(error.message) ? error.message : 'Could not run ASU. Check arguments and plugin configuration; see --help.';
|
|
82
|
+
process.stderr.write(`asu: ${message}\n`);
|
|
83
|
+
return 2;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (process.argv[1] && realpathSync(resolve(process.argv[1])) === fileURLToPath(import.meta.url)) {
|
|
87
|
+
process.stdout.on('error', (error) => {
|
|
88
|
+
if (error.code === 'EPIPE')
|
|
89
|
+
process.exit(0);
|
|
90
|
+
process.stderr.write('asu: Could not write output.\n');
|
|
91
|
+
process.exit(2);
|
|
92
|
+
});
|
|
93
|
+
process.exitCode = await run();
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReasonCode } from './models.js';
|
|
2
|
+
/** Only fixed messages reach output; errors may otherwise contain credentials. */
|
|
3
|
+
export declare class UsageError extends Error {
|
|
4
|
+
readonly code: ReasonCode;
|
|
5
|
+
constructor(code: ReasonCode);
|
|
6
|
+
}
|
|
7
|
+
export declare function safeReason(error: unknown): {
|
|
8
|
+
code: ReasonCode;
|
|
9
|
+
message: string;
|
|
10
|
+
};
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const messages = {
|
|
2
|
+
missing_credentials: 'No supported local credentials found. Sign in using the provider CLI.',
|
|
3
|
+
invalid_credentials: 'Local credentials are malformed or expired. Sign in using the provider CLI.',
|
|
4
|
+
credential_read_error: 'Could not read the local credential store. Check its permissions and format.',
|
|
5
|
+
unauthorized: 'The provider rejected these credentials. Sign in using the provider CLI.',
|
|
6
|
+
timeout: 'The provider did not respond before the deadline.',
|
|
7
|
+
rate_limited: 'The provider is rate limiting usage requests. Try again after the cache expires.',
|
|
8
|
+
http_error: 'The provider usage endpoint returned an HTTP error.',
|
|
9
|
+
invalid_response: 'The provider returned an unrecognized or malformed usage response.',
|
|
10
|
+
provider_error: 'The provider could not report usage.',
|
|
11
|
+
};
|
|
12
|
+
/** Only fixed messages reach output; errors may otherwise contain credentials. */
|
|
13
|
+
export class UsageError extends Error {
|
|
14
|
+
code;
|
|
15
|
+
constructor(code) {
|
|
16
|
+
super(messages[code]);
|
|
17
|
+
this.code = code;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function safeReason(error) {
|
|
21
|
+
const code = error instanceof UsageError && Object.hasOwn(messages, error.code) ? error.code : 'provider_error';
|
|
22
|
+
return { code, message: messages[code] };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAA+B;IAC3C,mBAAmB,EAAE,uEAAuE;IAC5F,mBAAmB,EAAE,6EAA6E;IAClG,qBAAqB,EAAE,8EAA8E;IACrG,YAAY,EAAE,0EAA0E;IACxF,OAAO,EAAE,mDAAmD;IAC5D,YAAY,EAAE,kFAAkF;IAChG,UAAU,EAAE,qDAAqD;IACjE,gBAAgB,EAAE,oEAAoE;IACtF,cAAc,EAAE,sCAAsC;CACvD,CAAC;AAEF,kFAAkF;AAClF,MAAM,OAAO,UAAW,SAAQ,KAAK;IACd;IAArB,YAAqB,IAAgB;QAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAA1C,SAAI,GAAJ,IAAI,CAAY;IAA2B,CAAC;CAClE;AACD,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,MAAM,IAAI,GAAG,KAAK,YAAY,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAChH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AAC3C,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { Provider, ProviderContext, Credentials } from './providers/base.js';
|
|
2
|
+
export type { UsageData, ProviderUsage, UsageReport, UsageWindow, Balance } from './models.js';
|
|
3
|
+
export type { LocalContext } from './local.js';
|
|
4
|
+
export type { RequestJson, JsonRequest } from './transport.js';
|
|
5
|
+
export { usageDataSchema, providerUsageSchema, reportSchema, emptyUsage } from './models.js';
|
|
6
|
+
export { UsageError } from './errors.js';
|
|
7
|
+
export { UsageService } from './service.js';
|
|
8
|
+
export { UsageCache } from './cache.js';
|
|
9
|
+
export { createLocalContext } from './local.js';
|
|
10
|
+
export { createTransport } from './transport.js';
|
|
11
|
+
export { builtInProviders, loadProviders } from './registry.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { usageDataSchema, providerUsageSchema, reportSchema, emptyUsage } from './models.js';
|
|
2
|
+
export { UsageError } from './errors.js';
|
|
3
|
+
export { UsageService } from './service.js';
|
|
4
|
+
export { UsageCache } from './cache.js';
|
|
5
|
+
export { createLocalContext } from './local.js';
|
|
6
|
+
export { createTransport } from './transport.js';
|
|
7
|
+
export { builtInProviders, loadProviders } from './registry.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/local.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface LocalContext {
|
|
2
|
+
home: string;
|
|
3
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
4
|
+
platform: NodeJS.Platform;
|
|
5
|
+
readText(path: string): Promise<string | null>;
|
|
6
|
+
readJson(path: string): Promise<unknown | null>;
|
|
7
|
+
keychain(service: string, validate?: (value: string) => boolean): Promise<string | null>;
|
|
8
|
+
sqliteToken(path: string, key: string): Promise<string | null>;
|
|
9
|
+
}
|
|
10
|
+
export declare function readText(path: string): Promise<string | null>;
|
|
11
|
+
export declare function readKeychainEntry(service: string, account: string | undefined, run: (args: string[]) => Promise<string>, validate?: (_value: string) => boolean): Promise<string | null>;
|
|
12
|
+
export declare function createLocalContext(overrides?: Partial<LocalContext>): LocalContext;
|
|
13
|
+
export declare function homePath(context: LocalContext, setting: string | undefined, fallback: string): string;
|
|
14
|
+
export declare function detectCommands(context: LocalContext, names: string[], appPaths?: string[]): Promise<boolean>;
|
package/dist/local.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { access, open } from 'node:fs/promises';
|
|
2
|
+
import { constants } from 'node:fs';
|
|
3
|
+
import { delimiter, join, resolve } from 'node:path';
|
|
4
|
+
import { homedir, userInfo } from 'node:os';
|
|
5
|
+
import { execFile } from 'node:child_process';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { UsageError } from './errors.js';
|
|
8
|
+
const exec = promisify(execFile);
|
|
9
|
+
export async function readText(path) {
|
|
10
|
+
let file;
|
|
11
|
+
try {
|
|
12
|
+
file = await open(path, constants.O_RDONLY | (constants.O_NONBLOCK ?? 0));
|
|
13
|
+
const stat = await file.stat();
|
|
14
|
+
if (!stat.isFile() || stat.size > 1_048_576)
|
|
15
|
+
throw new UsageError('credential_read_error');
|
|
16
|
+
const buffer = Buffer.alloc(1_048_577);
|
|
17
|
+
let size = 0;
|
|
18
|
+
while (size < buffer.length) {
|
|
19
|
+
const { bytesRead } = await file.read(buffer, size, buffer.length - size, null);
|
|
20
|
+
if (!bytesRead)
|
|
21
|
+
break;
|
|
22
|
+
size += bytesRead;
|
|
23
|
+
}
|
|
24
|
+
if (size > 1_048_576)
|
|
25
|
+
throw new UsageError('credential_read_error');
|
|
26
|
+
return buffer.subarray(0, size).toString('utf8');
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error.code === 'ENOENT')
|
|
30
|
+
return null;
|
|
31
|
+
throw new UsageError('credential_read_error');
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
await file?.close();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function readKeychainEntry(service, account, run, validate = (_value) => true) {
|
|
38
|
+
for (const args of [...(account ? [['-a', account]] : []), []]) {
|
|
39
|
+
try {
|
|
40
|
+
const raw = (await run(['find-generic-password', '-s', service, ...args, '-w'])).trim();
|
|
41
|
+
if (raw && validate(raw))
|
|
42
|
+
return raw;
|
|
43
|
+
}
|
|
44
|
+
catch { /* Try the legacy service-only lookup after an unavailable or invalid entry. */ }
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
async function keychain(service, validate) {
|
|
49
|
+
if (process.platform !== 'darwin')
|
|
50
|
+
return null;
|
|
51
|
+
let account;
|
|
52
|
+
try {
|
|
53
|
+
account = userInfo().username;
|
|
54
|
+
}
|
|
55
|
+
catch { /* Try legacy lookup below. */ }
|
|
56
|
+
return readKeychainEntry(service, account, async (args) => {
|
|
57
|
+
const { stdout } = await exec('/usr/bin/security', args, { timeout: 2_000, maxBuffer: 1_048_576 });
|
|
58
|
+
return stdout;
|
|
59
|
+
}, validate);
|
|
60
|
+
}
|
|
61
|
+
async function sqliteToken(path, key) {
|
|
62
|
+
try {
|
|
63
|
+
await access(path);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
// A subprocess contains node:sqlite's experimental warning on Node 22 and bounds a busy database.
|
|
69
|
+
// No token is passed in argv, and child output is never logged.
|
|
70
|
+
const script = `const {DatabaseSync}=require('node:sqlite');
|
|
71
|
+
const db=new DatabaseSync(process.argv[1],{readOnly:true});
|
|
72
|
+
try { const r=db.prepare('SELECT value FROM ItemTable WHERE key = ?').get(process.argv[2]);
|
|
73
|
+
if(typeof r?.value==='string') process.stdout.write(r.value); } finally {db.close();}`;
|
|
74
|
+
try {
|
|
75
|
+
const { stdout } = await exec(process.execPath, ['--no-warnings', '-e', script, path, key], { timeout: 2_000, maxBuffer: 65_536 });
|
|
76
|
+
return stdout.trim() || null;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new UsageError('credential_read_error');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export function createLocalContext(overrides = {}) {
|
|
83
|
+
const local = { home: homedir(), env: process.env, platform: process.platform,
|
|
84
|
+
readText, keychain, sqliteToken, ...overrides };
|
|
85
|
+
return { ...local, readJson: overrides.readJson ?? (async (path) => {
|
|
86
|
+
const text = await local.readText(path);
|
|
87
|
+
if (text === null)
|
|
88
|
+
return null;
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(text);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
throw new UsageError('invalid_credentials');
|
|
94
|
+
}
|
|
95
|
+
}) };
|
|
96
|
+
}
|
|
97
|
+
export function homePath(context, setting, fallback) {
|
|
98
|
+
const path = setting || join(context.home, fallback);
|
|
99
|
+
return path.startsWith('~/') ? join(context.home, path.slice(2)) : resolve(path);
|
|
100
|
+
}
|
|
101
|
+
export async function detectCommands(context, names, appPaths = []) {
|
|
102
|
+
const suffixes = context.platform === 'win32' ? ['', '.exe', '.cmd', '.bat'] : [''];
|
|
103
|
+
const paths = (context.env.PATH ?? '').split(delimiter).filter(Boolean)
|
|
104
|
+
.flatMap(dir => names.flatMap(name => suffixes.map(suffix => join(dir, name + suffix))));
|
|
105
|
+
for (const path of paths) {
|
|
106
|
+
try {
|
|
107
|
+
await access(path, context.platform === 'win32' ? constants.F_OK : constants.X_OK);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
catch { /* next */ }
|
|
111
|
+
}
|
|
112
|
+
for (const path of appPaths) {
|
|
113
|
+
try {
|
|
114
|
+
await access(path);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
catch { /* next */ }
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../src/local.ts"],"names":[],"mappings":"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"}
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const displayText: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
3
|
+
export declare const windowSchema: z.ZodObject<{
|
|
4
|
+
id: z.ZodString;
|
|
5
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
6
|
+
percentUsed: z.ZodNullable<z.ZodNumber>;
|
|
7
|
+
resetsAt: z.ZodNullable<z.ZodISODateTime>;
|
|
8
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
unit: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
11
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
12
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
13
|
+
model: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
14
|
+
surface: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
15
|
+
}, z.core.$strip>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export declare const balanceSchema: z.ZodObject<{
|
|
18
|
+
id: z.ZodString;
|
|
19
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
20
|
+
unit: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
21
|
+
remaining: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export declare const usageDataSchema: z.ZodObject<{
|
|
27
|
+
planLabel: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
28
|
+
windows: z.ZodArray<z.ZodObject<{
|
|
29
|
+
id: z.ZodString;
|
|
30
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
31
|
+
percentUsed: z.ZodNullable<z.ZodNumber>;
|
|
32
|
+
resetsAt: z.ZodNullable<z.ZodISODateTime>;
|
|
33
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
unit: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
36
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
38
|
+
model: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
39
|
+
surface: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
}, z.core.$strip>>;
|
|
42
|
+
balances: z.ZodArray<z.ZodObject<{
|
|
43
|
+
id: z.ZodString;
|
|
44
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
45
|
+
unit: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
46
|
+
remaining: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
50
|
+
}, z.core.$strip>>;
|
|
51
|
+
details: z.ZodArray<z.ZodObject<{
|
|
52
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
53
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
54
|
+
}, z.core.$strip>>;
|
|
55
|
+
}, z.core.$strip>;
|
|
56
|
+
export declare const reasonCodes: readonly ["missing_credentials", "invalid_credentials", "credential_read_error", "unauthorized", "timeout", "rate_limited", "http_error", "invalid_response", "provider_error"];
|
|
57
|
+
export declare const providerUsageSchema: z.ZodObject<{
|
|
58
|
+
planLabel: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
59
|
+
windows: z.ZodArray<z.ZodObject<{
|
|
60
|
+
id: z.ZodString;
|
|
61
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
62
|
+
percentUsed: z.ZodNullable<z.ZodNumber>;
|
|
63
|
+
resetsAt: z.ZodNullable<z.ZodISODateTime>;
|
|
64
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
unit: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
67
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
68
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
model: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
70
|
+
surface: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
72
|
+
}, z.core.$strip>>;
|
|
73
|
+
balances: z.ZodArray<z.ZodObject<{
|
|
74
|
+
id: z.ZodString;
|
|
75
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
76
|
+
unit: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
77
|
+
remaining: z.ZodOptional<z.ZodNumber>;
|
|
78
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
81
|
+
}, z.core.$strip>>;
|
|
82
|
+
details: z.ZodArray<z.ZodObject<{
|
|
83
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
84
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
85
|
+
}, z.core.$strip>>;
|
|
86
|
+
providerId: z.ZodString;
|
|
87
|
+
displayName: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
88
|
+
experimental: z.ZodBoolean;
|
|
89
|
+
installed: z.ZodNullable<z.ZodBoolean>;
|
|
90
|
+
credentialsPresent: z.ZodBoolean;
|
|
91
|
+
authenticated: z.ZodNullable<z.ZodBoolean>;
|
|
92
|
+
availability: z.ZodEnum<{
|
|
93
|
+
error: "error";
|
|
94
|
+
available: "available";
|
|
95
|
+
unavailable: "unavailable";
|
|
96
|
+
}>;
|
|
97
|
+
reason: z.ZodNullable<z.ZodObject<{
|
|
98
|
+
code: z.ZodEnum<{
|
|
99
|
+
missing_credentials: "missing_credentials";
|
|
100
|
+
invalid_credentials: "invalid_credentials";
|
|
101
|
+
credential_read_error: "credential_read_error";
|
|
102
|
+
unauthorized: "unauthorized";
|
|
103
|
+
timeout: "timeout";
|
|
104
|
+
rate_limited: "rate_limited";
|
|
105
|
+
http_error: "http_error";
|
|
106
|
+
invalid_response: "invalid_response";
|
|
107
|
+
provider_error: "provider_error";
|
|
108
|
+
}>;
|
|
109
|
+
message: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
110
|
+
}, z.core.$strip>>;
|
|
111
|
+
fetchedAt: z.ZodISODateTime;
|
|
112
|
+
expiresAt: z.ZodISODateTime;
|
|
113
|
+
cached: z.ZodBoolean;
|
|
114
|
+
}, z.core.$strip>;
|
|
115
|
+
export declare const reportSchema: z.ZodObject<{
|
|
116
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
117
|
+
generatedAt: z.ZodISODateTime;
|
|
118
|
+
warnings: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
119
|
+
providers: z.ZodArray<z.ZodObject<{
|
|
120
|
+
planLabel: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
121
|
+
windows: z.ZodArray<z.ZodObject<{
|
|
122
|
+
id: z.ZodString;
|
|
123
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
124
|
+
percentUsed: z.ZodNullable<z.ZodNumber>;
|
|
125
|
+
resetsAt: z.ZodNullable<z.ZodISODateTime>;
|
|
126
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
127
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
128
|
+
unit: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
129
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
130
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
131
|
+
model: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
132
|
+
surface: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
133
|
+
}, z.core.$strip>>;
|
|
134
|
+
}, z.core.$strip>>;
|
|
135
|
+
balances: z.ZodArray<z.ZodObject<{
|
|
136
|
+
id: z.ZodString;
|
|
137
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
138
|
+
unit: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
139
|
+
remaining: z.ZodOptional<z.ZodNumber>;
|
|
140
|
+
used: z.ZodOptional<z.ZodNumber>;
|
|
141
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
142
|
+
unlimited: z.ZodOptional<z.ZodBoolean>;
|
|
143
|
+
}, z.core.$strip>>;
|
|
144
|
+
details: z.ZodArray<z.ZodObject<{
|
|
145
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
146
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
147
|
+
}, z.core.$strip>>;
|
|
148
|
+
providerId: z.ZodString;
|
|
149
|
+
displayName: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
150
|
+
experimental: z.ZodBoolean;
|
|
151
|
+
installed: z.ZodNullable<z.ZodBoolean>;
|
|
152
|
+
credentialsPresent: z.ZodBoolean;
|
|
153
|
+
authenticated: z.ZodNullable<z.ZodBoolean>;
|
|
154
|
+
availability: z.ZodEnum<{
|
|
155
|
+
error: "error";
|
|
156
|
+
available: "available";
|
|
157
|
+
unavailable: "unavailable";
|
|
158
|
+
}>;
|
|
159
|
+
reason: z.ZodNullable<z.ZodObject<{
|
|
160
|
+
code: z.ZodEnum<{
|
|
161
|
+
missing_credentials: "missing_credentials";
|
|
162
|
+
invalid_credentials: "invalid_credentials";
|
|
163
|
+
credential_read_error: "credential_read_error";
|
|
164
|
+
unauthorized: "unauthorized";
|
|
165
|
+
timeout: "timeout";
|
|
166
|
+
rate_limited: "rate_limited";
|
|
167
|
+
http_error: "http_error";
|
|
168
|
+
invalid_response: "invalid_response";
|
|
169
|
+
provider_error: "provider_error";
|
|
170
|
+
}>;
|
|
171
|
+
message: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
172
|
+
}, z.core.$strip>>;
|
|
173
|
+
fetchedAt: z.ZodISODateTime;
|
|
174
|
+
expiresAt: z.ZodISODateTime;
|
|
175
|
+
cached: z.ZodBoolean;
|
|
176
|
+
}, z.core.$strip>>;
|
|
177
|
+
}, z.core.$strip>;
|
|
178
|
+
export type UsageWindow = z.infer<typeof windowSchema>;
|
|
179
|
+
export type Balance = z.infer<typeof balanceSchema>;
|
|
180
|
+
export type UsageData = z.infer<typeof usageDataSchema>;
|
|
181
|
+
export type ProviderUsage = z.infer<typeof providerUsageSchema>;
|
|
182
|
+
export type UsageReport = z.infer<typeof reportSchema>;
|
|
183
|
+
export type ReasonCode = typeof reasonCodes[number];
|
|
184
|
+
export declare function emptyUsage(): UsageData;
|
package/dist/models.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { stripVTControlCharacters } from 'node:util';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const displayText = z.string().max(1024).transform(value => stripVTControlCharacters(value).replace(/[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/g, ' ').trim());
|
|
4
|
+
const id = z.string().regex(/^[a-z0-9][a-z0-9._:-]{0,127}$/);
|
|
5
|
+
const quantity = z.number().finite().nonnegative();
|
|
6
|
+
const timestamp = z.iso.datetime();
|
|
7
|
+
export const windowSchema = z.object({
|
|
8
|
+
id,
|
|
9
|
+
label: displayText,
|
|
10
|
+
percentUsed: quantity.nullable(),
|
|
11
|
+
resetsAt: timestamp.nullable(),
|
|
12
|
+
used: quantity.optional(),
|
|
13
|
+
limit: quantity.optional(),
|
|
14
|
+
unit: displayText.optional(),
|
|
15
|
+
unlimited: z.boolean().optional(),
|
|
16
|
+
scope: z.object({ model: displayText.optional(), surface: displayText.optional() }).optional(),
|
|
17
|
+
});
|
|
18
|
+
export const balanceSchema = z.object({
|
|
19
|
+
id,
|
|
20
|
+
label: displayText,
|
|
21
|
+
unit: displayText,
|
|
22
|
+
remaining: z.number().finite().optional(),
|
|
23
|
+
used: quantity.optional(),
|
|
24
|
+
limit: quantity.optional(),
|
|
25
|
+
unlimited: z.boolean().optional(),
|
|
26
|
+
});
|
|
27
|
+
export const usageDataSchema = z.object({
|
|
28
|
+
planLabel: displayText.nullable(),
|
|
29
|
+
windows: z.array(windowSchema).max(100),
|
|
30
|
+
balances: z.array(balanceSchema).max(100),
|
|
31
|
+
details: z.array(z.object({ label: displayText, value: displayText })).max(100),
|
|
32
|
+
});
|
|
33
|
+
export const reasonCodes = ['missing_credentials', 'invalid_credentials', 'credential_read_error',
|
|
34
|
+
'unauthorized', 'timeout', 'rate_limited', 'http_error', 'invalid_response', 'provider_error'];
|
|
35
|
+
export const providerUsageSchema = usageDataSchema.extend({
|
|
36
|
+
providerId: id,
|
|
37
|
+
displayName: displayText,
|
|
38
|
+
experimental: z.boolean(),
|
|
39
|
+
installed: z.boolean().nullable(),
|
|
40
|
+
credentialsPresent: z.boolean(),
|
|
41
|
+
authenticated: z.boolean().nullable(),
|
|
42
|
+
availability: z.enum(['available', 'unavailable', 'error']),
|
|
43
|
+
reason: z.object({ code: z.enum(reasonCodes), message: displayText }).nullable(),
|
|
44
|
+
fetchedAt: timestamp,
|
|
45
|
+
expiresAt: timestamp,
|
|
46
|
+
cached: z.boolean(),
|
|
47
|
+
});
|
|
48
|
+
export const reportSchema = z.object({
|
|
49
|
+
schemaVersion: z.literal(1),
|
|
50
|
+
generatedAt: timestamp,
|
|
51
|
+
warnings: z.array(displayText),
|
|
52
|
+
providers: z.array(providerUsageSchema),
|
|
53
|
+
});
|
|
54
|
+
export function emptyUsage() {
|
|
55
|
+
return { planLabel: null, windows: [], balances: [], details: [] };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAChE,wBAAwB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,yDAAyD,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAClH,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;AACnD,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,EAAE;IACF,KAAK,EAAE,WAAW;IAClB,WAAW,EAAE,QAAQ,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE;IACzB,KAAK,EAAE,QAAQ,CAAC,QAAQ,EAAE;IAC1B,IAAI,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC/F,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,EAAE;IACF,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,WAAW;IACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE;IACzB,KAAK,EAAE,QAAQ,CAAC,QAAQ,EAAE;IAC1B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE;IACjC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;CAChF,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,qBAAqB,EAAE,qBAAqB,EAAE,uBAAuB;IAC/F,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,CAAU,CAAC;AAC1G,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,WAAW;IACxB,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE;IACzB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,kBAAkB,EAAE,CAAC,CAAC,OAAO,EAAE;IAC/B,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACrC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE;IAChF,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;CACpB,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3B,WAAW,EAAE,SAAS;IACtB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;IAC9B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC;CACxC,CAAC,CAAC;AAQH,MAAM,UAAU,UAAU;IACxB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AACrE,CAAC"}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { UsageReport } from './models.js';
|
|
2
|
+
export type OutputFormat = 'plain' | 'table' | 'json';
|
|
3
|
+
export interface RenderOptions {
|
|
4
|
+
columns?: number;
|
|
5
|
+
/** Print full UTC timestamps instead of times relative to now. */
|
|
6
|
+
utc?: boolean;
|
|
7
|
+
now?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function renderPlain(report: UsageReport, options?: RenderOptions): string;
|
|
10
|
+
export declare function renderTable(report: UsageReport, options?: RenderOptions): string;
|
|
11
|
+
/** True when a cell would wrap at this width. The CLI then prefers plain output unless the table was requested. */
|
|
12
|
+
export declare function tableWraps(report: UsageReport, options?: RenderOptions): boolean;
|
|
13
|
+
export declare function render(report: UsageReport, format: OutputFormat, options?: RenderOptions): string;
|