@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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +497 -0
  3. package/dist/cache.d.ts +15 -0
  4. package/dist/cache.js +112 -0
  5. package/dist/cache.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.js +95 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/errors.d.ts +10 -0
  10. package/dist/errors.js +24 -0
  11. package/dist/errors.js.map +1 -0
  12. package/dist/index.d.ts +11 -0
  13. package/dist/index.js +8 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/local.d.ts +14 -0
  16. package/dist/local.js +121 -0
  17. package/dist/local.js.map +1 -0
  18. package/dist/models.d.ts +184 -0
  19. package/dist/models.js +57 -0
  20. package/dist/models.js.map +1 -0
  21. package/dist/output.d.ts +13 -0
  22. package/dist/output.js +187 -0
  23. package/dist/output.js.map +1 -0
  24. package/dist/providers/base.d.ts +25 -0
  25. package/dist/providers/base.js +2 -0
  26. package/dist/providers/base.js.map +1 -0
  27. package/dist/providers/claude.d.ts +4 -0
  28. package/dist/providers/claude.js +167 -0
  29. package/dist/providers/claude.js.map +1 -0
  30. package/dist/providers/codex.d.ts +4 -0
  31. package/dist/providers/codex.js +66 -0
  32. package/dist/providers/codex.js.map +1 -0
  33. package/dist/providers/copilot.d.ts +4 -0
  34. package/dist/providers/copilot.js +64 -0
  35. package/dist/providers/copilot.js.map +1 -0
  36. package/dist/providers/cursor.d.ts +6 -0
  37. package/dist/providers/cursor.js +69 -0
  38. package/dist/providers/cursor.js.map +1 -0
  39. package/dist/providers/grok.d.ts +4 -0
  40. package/dist/providers/grok.js +59 -0
  41. package/dist/providers/grok.js.map +1 -0
  42. package/dist/providers/kimi.d.ts +4 -0
  43. package/dist/providers/kimi.js +49 -0
  44. package/dist/providers/kimi.js.map +1 -0
  45. package/dist/providers/minimax.d.ts +4 -0
  46. package/dist/providers/minimax.js +73 -0
  47. package/dist/providers/minimax.js.map +1 -0
  48. package/dist/providers/parse.d.ts +16 -0
  49. package/dist/providers/parse.js +78 -0
  50. package/dist/providers/parse.js.map +1 -0
  51. package/dist/providers/zai.d.ts +5 -0
  52. package/dist/providers/zai.js +67 -0
  53. package/dist/providers/zai.js.map +1 -0
  54. package/dist/registry.d.ts +4 -0
  55. package/dist/registry.js +45 -0
  56. package/dist/registry.js.map +1 -0
  57. package/dist/service.d.ts +28 -0
  58. package/dist/service.js +117 -0
  59. package/dist/service.js.map +1 -0
  60. package/dist/transport.d.ts +8 -0
  61. package/dist/transport.js +63 -0
  62. package/dist/transport.js.map +1 -0
  63. package/dist/version.d.ts +2 -0
  64. package/dist/version.js +4 -0
  65. package/dist/version.js.map +1 -0
  66. package/docs/architecture.md +83 -0
  67. package/docs/provider-contracts.md +32 -0
  68. package/docs/releasing.md +51 -0
  69. package/package.json +48 -0
package/dist/output.js ADDED
@@ -0,0 +1,187 @@
1
+ function duration(ms) {
2
+ const minutes = Math.round(ms / 60_000);
3
+ if (minutes < 1)
4
+ return '<1m';
5
+ const days = Math.floor(minutes / 1440), hours = Math.floor(minutes % 1440 / 60), rest = minutes % 60;
6
+ if (days)
7
+ return hours ? `${days}d${hours}h` : `${days}d`;
8
+ if (hours)
9
+ return rest ? `${hours}h${rest}m` : `${hours}h`;
10
+ return `${rest}m`;
11
+ }
12
+ // A duration of a day or more also names the local calendar day, because "7d" alone does not say which date that is.
13
+ const dayParts = new Intl.DateTimeFormat('en-US', { weekday: 'short', day: 'numeric', month: 'short' });
14
+ const dayLabel = { format: (at) => {
15
+ const part = (type) => dayParts.formatToParts(at).find(item => item.type === type)?.value ?? '';
16
+ return `${part('weekday')} ${part('day')} ${part('month')}`;
17
+ } };
18
+ /** A future time: the ISO timestamp with --utc, otherwise "in 2h30m" or "in 7d (Tue 15 Sep)", or "now" once it has passed. */
19
+ function ahead(iso, options) {
20
+ if (iso === null)
21
+ return 'unknown';
22
+ if (options.utc)
23
+ return iso;
24
+ const at = Date.parse(iso), diff = at - (options.now ?? Date.now());
25
+ if (diff <= 0)
26
+ return 'now';
27
+ return diff < 86_400_000 ? `in ${duration(diff)}` : `in ${duration(diff)} (${dayLabel.format(at)})`;
28
+ }
29
+ /** A past time: the ISO timestamp with --utc, otherwise "3m ago". */
30
+ function ago(iso, options) {
31
+ return options.utc ? iso : `${duration(Math.max(0, (options.now ?? Date.now()) - Date.parse(iso)))} ago`;
32
+ }
33
+ const isoTimestamp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
34
+ /** A detail value that is an ISO timestamp reads like any other time. Anything else prints as is. */
35
+ function detailValue(value, options) {
36
+ if (!isoTimestamp.test(value))
37
+ return value;
38
+ return Date.parse(value) > (options.now ?? Date.now()) ? ahead(value, options) : ago(value, options);
39
+ }
40
+ const amount = (value) => new Intl.NumberFormat('en-US', { maximumFractionDigits: 2 }).format(value);
41
+ const yesNo = (value) => value === null ? 'unknown' : value ? 'yes' : 'no';
42
+ function windowValue(window) {
43
+ if (window.unlimited)
44
+ return 'Unlimited';
45
+ const parts = [window.percentUsed === null ? 'Usage unknown' : `${amount(window.percentUsed)}% used`];
46
+ if (window.used !== undefined)
47
+ parts.push(`${amount(window.used)}${window.limit === undefined ? '' : ` / ${amount(window.limit)}`}${window.unit ? ` ${window.unit}` : ''}`);
48
+ else if (window.limit !== undefined)
49
+ parts.push(`limit ${amount(window.limit)}${window.unit ? ` ${window.unit}` : ''}`);
50
+ return parts.join('; ');
51
+ }
52
+ function balanceValue(balance) {
53
+ if (balance.unlimited)
54
+ return 'Unlimited';
55
+ const parts = [];
56
+ if (balance.remaining !== undefined)
57
+ parts.push(`${amount(balance.remaining)} ${balance.unit} left`);
58
+ if (balance.used !== undefined)
59
+ parts.push(`${amount(balance.used)} ${balance.unit} used`);
60
+ if (balance.limit !== undefined)
61
+ parts.push(`limit ${amount(balance.limit)} ${balance.unit}`);
62
+ return parts.join('; ') || 'Balance unknown';
63
+ }
64
+ function providerSummary(provider) {
65
+ return `installed: ${yesNo(provider.installed)}, authenticated: ${yesNo(provider.authenticated)}`;
66
+ }
67
+ export function renderPlain(report, options = {}) {
68
+ const lines = [`ASU · ${report.generatedAt}`];
69
+ for (const provider of report.providers) {
70
+ lines.push('', `${provider.displayName} (${provider.providerId})${provider.experimental ? ' [experimental]' : ''}`, ` ${provider.availability}; ${providerSummary(provider)}`);
71
+ if (provider.planLabel)
72
+ lines.push(` Plan: ${provider.planLabel}`);
73
+ for (const window of provider.windows)
74
+ lines.push(` ${window.label}: ${windowValue(window)}; resets ${ahead(window.resetsAt, options)}`);
75
+ for (const balance of provider.balances)
76
+ lines.push(` ${balance.label}: ${balanceValue(balance)}`);
77
+ for (const detail of provider.details)
78
+ lines.push(` ${detail.label}: ${detailValue(detail.value, options)}`);
79
+ if (provider.reason)
80
+ lines.push(` ${provider.reason.code}: ${provider.reason.message}`);
81
+ lines.push(` Fetched ${ago(provider.fetchedAt, options)}; ${provider.cached ? 'cached' : 'fresh'}; expires ${ahead(provider.expiresAt, options)}`);
82
+ }
83
+ if (!report.providers.length)
84
+ lines.push('', 'No supported agents or credentials detected. Use --all to list every provider.');
85
+ for (const warning of report.warnings)
86
+ lines.push('', `Warning: ${warning}`);
87
+ return lines.join('\n') + '\n';
88
+ }
89
+ // Cell wrapping preserves long labels, including CJK characters, without terminal escape sequences.
90
+ const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
91
+ function width(character) {
92
+ const cp = character.codePointAt(0) ?? 0;
93
+ return /\p{Extended_Pictographic}/u.test(character) || cp >= 0x1100 && (cp <= 0x115f || cp >= 0x2329 && cp <= 0x232a || cp >= 0x2e80 && cp <= 0xa4cf
94
+ || cp >= 0xac00 && cp <= 0xd7a3 || cp >= 0xf900 && cp <= 0xfaff
95
+ || cp >= 0xfe10 && cp <= 0xfe6f || cp >= 0xff00 && cp <= 0xff60
96
+ || cp >= 0xffe0 && cp <= 0xffe6 || cp >= 0x20000 && cp <= 0x3fffd) ? 2 : 1;
97
+ }
98
+ function textWidth(text) { return [...segmenter.segment(text)].reduce((sum, item) => sum + width(item.segment), 0); }
99
+ function wrap(text, columns) {
100
+ const lines = [];
101
+ for (const paragraph of text.split('\n')) {
102
+ let line = '', length = 0;
103
+ for (const { segment } of segmenter.segment(paragraph)) {
104
+ const size = width(segment);
105
+ if (length + size > columns) {
106
+ lines.push(line);
107
+ line = '';
108
+ length = 0;
109
+ }
110
+ line += segment;
111
+ length += size;
112
+ }
113
+ lines.push(line);
114
+ }
115
+ return lines;
116
+ }
117
+ function buildTable(report, options) {
118
+ let wrapped = false;
119
+ const widths = [16, 18, 25, 24, 18];
120
+ const target = Math.max(60, Math.min(180, options.columns ?? 110));
121
+ const minima = [8, 9, 10, 10, 7];
122
+ while (widths.reduce((sum, value) => sum + value, 16) > target) {
123
+ let index = -1;
124
+ for (let i = 0; i < widths.length; i++)
125
+ if (widths[i] > minima[i] && (index < 0 || widths[i] > widths[index]))
126
+ index = i;
127
+ if (index < 0)
128
+ break;
129
+ widths[index] = widths[index] - 1;
130
+ }
131
+ const border = (left, middle, right) => left + widths.map(w => '─'.repeat(w + 2)).join(middle) + right;
132
+ const lines = [`ASU · ${report.generatedAt}`, border('┌', '┬', '┐')];
133
+ function row(cells) {
134
+ const wrappedCells = cells.map((cell, i) => wrap(cell, widths[i]));
135
+ // Intentional line breaks inside a cell are not wrapping. Extra lines beyond them are.
136
+ if (wrappedCells.some((cell, i) => cell.length > cells[i].split('\n').length))
137
+ wrapped = true;
138
+ const height = Math.max(...wrappedCells.map(cell => cell.length));
139
+ for (let line = 0; line < height; line++)
140
+ lines.push('│ ' + wrappedCells.map((cell, i) => {
141
+ const value = cell[line] ?? '';
142
+ return value + ' '.repeat(widths[i] - textWidth(value));
143
+ }).join(' │ ') + ' │');
144
+ }
145
+ row(['Provider', 'Plan / status', 'Window / balance', 'Usage', options.utc ? 'Resets (UTC)' : 'Resets in']);
146
+ for (const provider of report.providers) {
147
+ lines.push(border('├', '┼', '┤'));
148
+ const timeCell = (text) => text.replace(/^in /, '').replace(/^\w/, char => char.toUpperCase());
149
+ const rows = provider.windows.map(window => [window.label, windowValue(window).replaceAll('; ', '\n'),
150
+ options.utc && window.resetsAt ? window.resetsAt.replace('T', ' ').slice(0, 16) : timeCell(ahead(window.resetsAt, options))]);
151
+ rows.push(...provider.balances.map(balance => [balance.label, balanceValue(balance).replaceAll('; ', '\n'), '—']));
152
+ // Details are rows too. A timestamp detail lines up with the other dates in the last column.
153
+ rows.push(...provider.details.map(detail => isoTimestamp.test(detail.value)
154
+ ? [detail.label, '—', options.utc ? detail.value.replace('T', ' ').slice(0, 16) : timeCell(detailValue(detail.value, options))]
155
+ : [detail.label, detail.value, '—']));
156
+ if (provider.reason)
157
+ rows.push(['Reason', provider.reason.code, '—']);
158
+ if (!rows.length)
159
+ rows.push(['—', '—', '—']);
160
+ rows.forEach((cells, index) => row([index ? '' : provider.displayName + (provider.experimental ? ' *' : ''),
161
+ index ? '' : [provider.planLabel, provider.availability, provider.cached ? 'cached' : 'fresh'].filter(Boolean).join('\n'), ...cells]));
162
+ }
163
+ lines.push(border('└', '┴', '┘'));
164
+ if (!report.providers.length)
165
+ lines.push('No supported agents or credentials detected. Use --all to list every provider.');
166
+ // The footer is bookkeeping only. Usage, details, and the reason code are rows in the table.
167
+ for (const provider of report.providers) {
168
+ lines.push(`${provider.displayName}: fetched ${ago(provider.fetchedAt, options)}; cache expires ${ahead(provider.expiresAt, options)}.`
169
+ + (provider.reason ? ` ${provider.reason.message}` : ''));
170
+ }
171
+ if (report.providers.some(p => p.experimental))
172
+ lines.push('* Experimental adapter: fixture-tested, not verified against a live subscription.');
173
+ for (const warning of report.warnings)
174
+ lines.push(`Warning: ${warning}`);
175
+ return { text: lines.join('\n') + '\n', wrapped };
176
+ }
177
+ export function renderTable(report, options = {}) {
178
+ return buildTable(report, options).text;
179
+ }
180
+ /** True when a cell would wrap at this width. The CLI then prefers plain output unless the table was requested. */
181
+ export function tableWraps(report, options = {}) {
182
+ return buildTable(report, options).wrapped;
183
+ }
184
+ export function render(report, format, options = {}) {
185
+ return format === 'json' ? JSON.stringify(report, null, 2) + '\n' : format === 'table' ? renderTable(report, options) : renderPlain(report, options);
186
+ }
187
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { LocalContext } from '../local.js';
2
+ import type { RequestJson } from '../transport.js';
3
+ import type { UsageData } from '../models.js';
4
+ /** Private to the backend: never serialize this object. */
5
+ export interface Credentials {
6
+ token: string;
7
+ accountId?: string;
8
+ expiresAt?: number;
9
+ metadata?: Record<string, string>;
10
+ }
11
+ export interface ProviderContext extends LocalContext {
12
+ request: RequestJson;
13
+ signal: AbortSignal;
14
+ now: () => number;
15
+ }
16
+ export interface Provider {
17
+ id: string;
18
+ displayName: string;
19
+ /** Bump when request/normalization semantics change, to invalidate cached data. */
20
+ version: number;
21
+ experimental?: boolean;
22
+ detect(context: LocalContext): Promise<boolean | null>;
23
+ resolveCredentials(context: LocalContext): Promise<Credentials | null>;
24
+ fetchUsage(context: ProviderContext, credentials: Credentials): Promise<UsageData>;
25
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeClaude(payload: unknown, metadata?: Record<string, string>): UsageData;
4
+ export declare const claude: Provider;
@@ -0,0 +1,167 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { join } from 'node:path';
3
+ import { UsageError } from '../errors.js';
4
+ import { detectCommands, homePath } from '../local.js';
5
+ import { emptyUsage } from '../models.js';
6
+ import { credentialObject, nonnegative, object, optionalObject, percent, requireUsage, slug, string, timestamp, title } from './parse.js';
7
+ function sameScope(a, b) {
8
+ return ['model', 'surface'].every(dimension => {
9
+ const x = a[dimension], y = b[dimension];
10
+ if (!x || !y)
11
+ return x === y;
12
+ return x.id && y.id ? x.id === y.id : slug(x.name) === slug(y.name);
13
+ });
14
+ }
15
+ function scopeId(scope) {
16
+ return ['model', 'surface'].flatMap(dimension => {
17
+ const entry = scope[dimension];
18
+ if (!entry)
19
+ return [];
20
+ // Hash API identities without folding punctuation or case together.
21
+ const identity = entry.id ? createHash('sha256').update(entry.id).digest('hex').slice(0, 12) : slug(entry.name).slice(0, 35);
22
+ return [`${dimension}-${identity}`];
23
+ }).join('-');
24
+ }
25
+ export function normalizeClaude(payload, metadata = {}) {
26
+ const raw = object(payload), data = emptyUsage();
27
+ for (const [key, label] of [['five_hour', '5 hours'], ['seven_day', 'Weekly']]) {
28
+ if (raw[key] == null)
29
+ continue;
30
+ const window = object(raw[key]);
31
+ data.windows.push({ id: key, label, percentUsed: percent(window.utilization), resetsAt: timestamp(window.resets_at) });
32
+ }
33
+ const scoped = [];
34
+ let skipped = 0;
35
+ for (const [key, value] of Object.entries(raw)) {
36
+ if (!key.startsWith('seven_day_') || value == null)
37
+ continue;
38
+ try {
39
+ const window = object(value), name = title(key.slice(10));
40
+ const scope = key === 'seven_day_oauth_apps' ? { surface: { name } } : { model: { name } };
41
+ scoped.push({ scope, percent: percent(window.utilization), reset: timestamp(window.resets_at) });
42
+ }
43
+ catch {
44
+ skipped++;
45
+ }
46
+ }
47
+ for (const section of [raw.limits, raw.model_scoped]) {
48
+ if (section == null)
49
+ continue;
50
+ if (!Array.isArray(section)) {
51
+ skipped++;
52
+ continue;
53
+ }
54
+ for (const value of section) {
55
+ try {
56
+ const entry = object(value);
57
+ if (entry.kind !== 'weekly_scoped')
58
+ continue;
59
+ const rawScope = object(entry.scope), scope = {};
60
+ for (const dimension of ['model', 'surface']) {
61
+ const part = optionalObject(rawScope[dimension]);
62
+ const id = string(part.id), name = string(part.display_name) ?? id;
63
+ if (name)
64
+ scope[dimension] = { id, name };
65
+ }
66
+ if (!scope.model && !scope.surface) {
67
+ skipped++;
68
+ continue;
69
+ }
70
+ const next = { scope, percent: entry.percent == null ? null : percent(entry.percent), reset: timestamp(entry.resets_at) };
71
+ const index = scoped.findIndex(item => sameScope(item.scope, scope));
72
+ if (index < 0)
73
+ scoped.push(next);
74
+ else
75
+ scoped[index] = { ...next, percent: next.percent ?? scoped[index].percent, reset: next.reset ?? scoped[index].reset };
76
+ }
77
+ catch {
78
+ skipped++;
79
+ }
80
+ }
81
+ }
82
+ const ids = new Set();
83
+ for (const item of scoped) {
84
+ const baseId = `weekly-${scopeId(item.scope)}`;
85
+ let id = baseId, suffix = 2;
86
+ while (ids.has(id))
87
+ id = `${baseId}-${suffix++}`;
88
+ ids.add(id);
89
+ data.windows.push({ id, label: `Weekly · ${[item.scope.model?.name, item.scope.surface?.name].filter(Boolean).join(' / ')}`,
90
+ percentUsed: item.percent, resetsAt: item.reset,
91
+ scope: { model: item.scope.model?.name, surface: item.scope.surface?.name } });
92
+ }
93
+ const extra = optionalObject(raw.extra_usage);
94
+ if (typeof extra.is_enabled === 'boolean')
95
+ data.details.push({ label: 'Extra usage', value: extra.is_enabled ? 'Enabled' : 'Disabled' });
96
+ requireUsage(data); // A locally known plan must not make an empty API response appear valid.
97
+ if (skipped)
98
+ data.details.push({ label: 'Response warning', value: `${skipped} unrecognized scoped limits omitted` });
99
+ const plan = metadata.subscriptionType;
100
+ if (plan) {
101
+ const multiplier = metadata.rateLimitTier?.match(/(?:^|_)(\d+x)(?:_|$)/)?.[1];
102
+ data.planLabel = `${title(plan)}${multiplier ? ` ${multiplier}` : ''}`;
103
+ }
104
+ return data;
105
+ }
106
+ function parseCredentials(raw) {
107
+ const root = credentialObject(raw);
108
+ if (root.claudeAiOauth == null)
109
+ return null;
110
+ const oauth = credentialObject(root.claudeAiOauth), token = string(oauth.accessToken);
111
+ if (!token)
112
+ return null;
113
+ const metadata = {};
114
+ for (const field of ['subscriptionType', 'rateLimitTier']) {
115
+ const value = string(oauth[field]);
116
+ if (value)
117
+ metadata[field] = value;
118
+ }
119
+ return { token, metadata, expiresAt: nonnegative(oauth.expiresAt) };
120
+ }
121
+ export const claude = {
122
+ id: 'claude', displayName: 'Claude', version: 1,
123
+ detect: context => detectCommands(context, ['claude']),
124
+ async resolveCredentials(context) {
125
+ let failure;
126
+ try {
127
+ const home = homePath(context, context.env.CLAUDE_CONFIG_DIR || context.env.CLAUDE_HOME, '.claude');
128
+ const raw = await context.readJson(join(home, '.credentials.json'));
129
+ const credentials = raw == null ? null : parseCredentials(raw);
130
+ if (credentials)
131
+ return credentials;
132
+ }
133
+ catch (error) {
134
+ failure = error;
135
+ }
136
+ if (context.platform === 'darwin') {
137
+ const raw = await context.keychain('Claude Code-credentials', value => {
138
+ try {
139
+ return parseCredentials(JSON.parse(value)) !== null;
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ });
145
+ if (raw) {
146
+ try {
147
+ const credentials = parseCredentials(JSON.parse(raw));
148
+ if (credentials)
149
+ return credentials;
150
+ }
151
+ catch {
152
+ failure = new UsageError('invalid_credentials');
153
+ }
154
+ }
155
+ }
156
+ if (failure)
157
+ throw failure;
158
+ return null;
159
+ },
160
+ async fetchUsage(context, credentials) {
161
+ const raw = await context.request('https://api.anthropic.com/api/oauth/usage', {
162
+ signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}`, 'anthropic-beta': 'oauth-2025-04-20' },
163
+ });
164
+ return normalizeClaude(raw, credentials.metadata);
165
+ },
166
+ };
167
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeCodex(payload: unknown, now?: number): UsageData;
4
+ export declare const codex: Provider;
@@ -0,0 +1,66 @@
1
+ import { join } from 'node:path';
2
+ import { detectCommands, homePath } from '../local.js';
3
+ import { emptyUsage } from '../models.js';
4
+ import { credentialObject, list, nonnegative, number, object, optionalObject, percent, requireUsage, slug, string, timestamp, title } from './parse.js';
5
+ export function normalizeCodex(payload, now = Date.now()) {
6
+ const raw = object(payload), data = emptyUsage();
7
+ const plan = string(raw.plan_type);
8
+ data.planLabel = plan ? title(plan) : null;
9
+ function windows(value, prefix, label) {
10
+ const limits = optionalObject(value);
11
+ for (const [key, fallback] of [['primary_window', 'Primary'], ['secondary_window', 'Secondary']]) {
12
+ if (limits[key] == null)
13
+ continue;
14
+ const window = object(limits[key]);
15
+ const seconds = nonnegative(window.limit_window_seconds);
16
+ const period = seconds === 18_000 ? '5 hours' : seconds === 604_800 ? 'Weekly'
17
+ : seconds ? `${seconds / 3600} hours` : fallback;
18
+ const resetAfter = nonnegative(window.reset_after_seconds);
19
+ data.windows.push({ id: `${prefix}-${key}`, label: `${label}${period}`,
20
+ percentUsed: percent(window.used_percent),
21
+ resetsAt: timestamp(window.reset_at ?? (resetAfter === undefined ? undefined : now + resetAfter * 1000)) });
22
+ }
23
+ }
24
+ windows(raw.rate_limit, 'usage', '');
25
+ windows(raw.code_review_rate_limit, 'code-review', 'Code review · ');
26
+ for (const [index, value] of list(raw.additional_rate_limits).entries()) {
27
+ const entry = object(value), name = string(entry.limit_name) ?? string(entry.metered_feature) ?? `Additional ${index + 1}`;
28
+ windows(entry.rate_limit, `additional-${index}-${slug(name).slice(0, 45)}`, `${title(name)} · `);
29
+ }
30
+ const credits = optionalObject(raw.credits), balance = number(credits.balance);
31
+ if (balance !== undefined || typeof credits.unlimited === 'boolean')
32
+ data.balances.push({ id: 'credits', label: 'Credits', unit: 'credits', remaining: balance, unlimited: credits.unlimited === true });
33
+ if (typeof credits.has_credits === 'boolean')
34
+ data.details.push({ label: 'Credits available', value: credits.has_credits ? 'Yes' : 'No' });
35
+ return requireUsage(data);
36
+ }
37
+ export const codex = {
38
+ id: 'codex', displayName: 'Codex', version: 1,
39
+ detect: context => detectCommands(context, ['codex']),
40
+ async resolveCredentials(context) {
41
+ const paths = [
42
+ ...(context.env.CODEX_HOME ? [join(homePath(context, context.env.CODEX_HOME, '.codex'), 'auth.json')] : []),
43
+ join(context.home, '.config', 'codex', 'auth.json'), join(context.home, '.codex', 'auth.json'),
44
+ ];
45
+ for (const path of new Set(paths)) {
46
+ const raw = await context.readJson(path);
47
+ if (raw == null)
48
+ continue;
49
+ const root = credentialObject(raw);
50
+ if (root.tokens == null)
51
+ continue;
52
+ const tokens = credentialObject(root.tokens), token = string(tokens.access_token);
53
+ if (token)
54
+ return { token, accountId: string(tokens.account_id) };
55
+ }
56
+ return null;
57
+ },
58
+ async fetchUsage(context, credentials) {
59
+ const headers = { Authorization: `Bearer ${credentials.token}` };
60
+ if (credentials.accountId)
61
+ headers['ChatGPT-Account-Id'] = credentials.accountId;
62
+ const raw = await context.request('https://chatgpt.com/backend-api/wham/usage', { signal: context.signal, headers });
63
+ return normalizeCodex(raw, context.now());
64
+ },
65
+ };
66
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/providers/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeCopilot(payload: unknown): UsageData;
4
+ export declare const copilot: Provider;
@@ -0,0 +1,64 @@
1
+ import { join } from 'node:path';
2
+ import { parse } from 'yaml';
3
+ import { UsageError } from '../errors.js';
4
+ import { detectCommands, homePath } from '../local.js';
5
+ import { emptyUsage } from '../models.js';
6
+ import { credentialObject, nonnegative, object, optionalObject, percent, ratio, requireUsage, slug, string, timestamp, title } from './parse.js';
7
+ export function normalizeCopilot(payload) {
8
+ const raw = object(payload), data = emptyUsage();
9
+ const plan = string(raw.copilot_plan);
10
+ data.planLabel = plan ? title(plan) : null;
11
+ const resetsAt = timestamp(raw.quota_reset_date);
12
+ for (const [name, value] of Object.entries(optionalObject(raw.quota_snapshots))) {
13
+ const quota = object(value), unlimited = quota.unlimited === true || quota.entitlement === -1 || quota.entitlement === '-1';
14
+ const remainingPercent = nonnegative(quota.percent_remaining);
15
+ if (remainingPercent !== undefined && remainingPercent > 100)
16
+ throw new UsageError('invalid_response');
17
+ const limit = nonnegative(quota.entitlement), remaining = nonnegative(quota.remaining);
18
+ const used = limit !== undefined && remaining !== undefined ? Math.max(0, limit - remaining) : nonnegative(quota.used);
19
+ const percentUsed = unlimited ? null : remainingPercent === undefined ? ratio(used, limit) : percent(100 - remainingPercent);
20
+ if (percentUsed === null && used === undefined && limit === undefined && !unlimited)
21
+ continue;
22
+ data.windows.push({ id: slug(name), label: title(name), percentUsed, used, limit, unlimited,
23
+ resetsAt: timestamp(quota.reset_date) ?? resetsAt, unit: 'requests' });
24
+ }
25
+ // Each window carries the reset date. The detail only matters for a plan-only response.
26
+ if (resetsAt && !data.windows.length)
27
+ data.details.push({ label: 'Quota reset', value: resetsAt });
28
+ return requireUsage(data);
29
+ }
30
+ export const copilot = {
31
+ id: 'copilot', displayName: 'GitHub Copilot', version: 2,
32
+ // gh alone is not proof that Copilot is installed.
33
+ detect: context => detectCommands(context, ['copilot', 'github-copilot']),
34
+ async resolveCredentials(context) {
35
+ const envToken = string(context.env.COPILOT_TOKEN) ?? string(context.env.GITHUB_TOKEN) ?? string(context.env.GITHUB_PAT);
36
+ if (envToken)
37
+ return { token: envToken };
38
+ const config = homePath(context, context.env.GH_CONFIG_DIR, context.env.XDG_CONFIG_HOME ? join(context.env.XDG_CONFIG_HOME, 'gh') : '.config/gh');
39
+ const text = await context.readText(join(config, 'hosts.yml'));
40
+ if (text === null)
41
+ return null;
42
+ try {
43
+ const root = credentialObject(parse(text, { maxAliasCount: 0 }));
44
+ if (!root['github.com'])
45
+ return null;
46
+ const github = credentialObject(root['github.com']);
47
+ const user = string(github.user);
48
+ const users = github.users == null ? {} : credentialObject(github.users);
49
+ const current = user && users[user] ? credentialObject(users[user]) : {};
50
+ const token = string(github.oauth_token) ?? string(current.oauth_token);
51
+ return token ? { token } : null;
52
+ }
53
+ catch {
54
+ throw new UsageError('invalid_credentials');
55
+ }
56
+ },
57
+ async fetchUsage(context, credentials) {
58
+ return normalizeCopilot(await context.request('https://api.github.com/copilot_internal/user', {
59
+ signal: context.signal, headers: { Authorization: `token ${credentials.token}`,
60
+ 'Editor-Version': 'vscode/1.96.2', 'Editor-Plugin-Version': 'copilot-chat/0.26.7' },
61
+ }));
62
+ },
63
+ };
64
+ //# sourceMappingURL=copilot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../src/providers/copilot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { LocalContext } from '../local.js';
2
+ import type { UsageData } from '../models.js';
3
+ import type { Provider } from './base.js';
4
+ export declare function cursorDatabasePaths(context: LocalContext): string[];
5
+ export declare function normalizeCursor(payload: unknown): UsageData;
6
+ export declare const cursor: Provider;