@modelprofile.com/authswitch 3.0.0 → 3.1.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/accounts.d.ts +13 -5
- package/dist_ts/accounts.js +20 -5
- package/dist_ts/classes.accountlist.js +2 -2
- package/dist_ts/classes.claudestatus.js +94 -18
- package/dist_ts/classes.limits.js +9 -5
- package/dist_ts/classes.tui.js +4 -3
- package/dist_ts/interfaces.harness.d.ts +18 -8
- package/dist_ts/interfaces.list.d.ts +5 -1
- package/package.json +2 -2
- package/readme.md +61 -18
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/accounts.ts +22 -8
- package/ts/classes.accountlist.ts +1 -1
- package/ts/classes.claudestatus.ts +102 -14
- package/ts/classes.limits.ts +12 -5
- package/ts/classes.tui.ts +5 -4
- package/ts/interfaces.harness.ts +20 -8
- package/ts/interfaces.list.ts +5 -1
package/dist_ts/classes.tui.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
-
import { accountDetails, accountPlan, accountQuotaSummary, accountResets, accountState, accountUsageWindows,
|
|
2
|
+
import { accountDetails, accountPlan, accountQuotaSummary, accountResets, accountState, accountUsageWindows, usageWindowName, until, readAccountRows } from './accounts.js';
|
|
3
3
|
import { plainText } from './formatting.js';
|
|
4
4
|
import { AuthSwitchOperations } from './classes.operations.js';
|
|
5
5
|
import { describeHarnessProcesses, describeStopOutcome } from './classes.harnessprocesses.js';
|
|
@@ -212,7 +212,8 @@ export class AuthSwitchTui {
|
|
|
212
212
|
const tabs = ui.tabs([{ title: 'Account details', content: details }, { title: 'Activity log', content: ui.logs }]);
|
|
213
213
|
await ui.run({
|
|
214
214
|
view: () => {
|
|
215
|
-
const
|
|
215
|
+
const shown = accountUsageWindows({ status: table.selected?.status }) ?? [];
|
|
216
|
+
const usage = shown.slice(0, 2).map(window => ui.progress(`${usageWindowName(window, shown)} (${window.usedPercent}% used; reset in ${until(window.resetAt, Date.now())})`, Math.min(100, window.usedPercent), 100));
|
|
216
217
|
const accountView = ui.column([
|
|
217
218
|
ui.panel(`${plainText(harness.label)} accounts`, table),
|
|
218
219
|
ui.panel('Status and diagnostics', ui.column([...usage, tabs])),
|
|
@@ -237,4 +238,4 @@ export class AuthSwitchTui {
|
|
|
237
238
|
return 0;
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50dWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnR1aS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFvQixNQUFNLGVBQWUsQ0FBQztBQUMxTCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLG1CQUFtQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFOUYsa0dBQWtHO0FBQ2xHLE1BQU0sT0FBTyxhQUFhO0lBQ0s7SUFBcUQ7SUFBeUQ7SUFBM0ksWUFBNkIsU0FBa0MsRUFBbUIsR0FBc0MsRUFBbUIsYUFBYSxJQUFJLG9CQUFvQixFQUFFO1FBQXJKLGNBQVMsR0FBVCxTQUFTLENBQXlCO1FBQW1CLFFBQUcsR0FBSCxHQUFHLENBQW1DO1FBQW1CLGVBQVUsR0FBVixVQUFVLENBQTZCO0lBQUcsQ0FBQztJQUUvSyxLQUFLLENBQUMsR0FBRyxDQUFDLFlBQTJCO1FBQzFDLElBQUksT0FBTyxHQUFHLFlBQVksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztZQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUM1RSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztRQUN4QixJQUFJLEtBQWdD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RSxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUFFLE9BQU87Z0JBQ3BMLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFBQyxNQUFNLENBQUMsT0FBTyxDQUFDLDRFQUE0RSxDQUFDLENBQUM7b0JBQUMsT0FBTztnQkFBQyxDQUFDO1lBQ3ROLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLENBQUM7Z0JBQUUsT0FBTztZQUNuSSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQ2xDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUNsSCxPQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENB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
|
|
241
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50dWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnR1aS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFvQixNQUFNLGVBQWUsQ0FBQztBQUM5TCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLG1CQUFtQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFOUYsa0dBQWtHO0FBQ2xHLE1BQU0sT0FBTyxhQUFhO0lBQ0s7SUFBcUQ7SUFBeUQ7SUFBM0ksWUFBNkIsU0FBa0MsRUFBbUIsR0FBc0MsRUFBbUIsYUFBYSxJQUFJLG9CQUFvQixFQUFFO1FBQXJKLGNBQVMsR0FBVCxTQUFTLENBQXlCO1FBQW1CLFFBQUcsR0FBSCxHQUFHLENBQW1DO1FBQW1CLGVBQVUsR0FBVixVQUFVLENBQTZCO0lBQUcsQ0FBQztJQUUvSyxLQUFLLENBQUMsR0FBRyxDQUFDLFlBQTJCO1FBQzFDLElBQUksT0FBTyxHQUFHLFlBQVksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztZQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUM1RSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztRQUN4QixJQUFJLEtBQWdD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RSxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUFFLE9BQU87Z0JBQ3BMLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFBQyxNQUFNLENBQUMsT0FBTyxDQUFDLDRFQUE0RSxDQUFDLENBQUM7b0JBQUMsT0FBTztnQkFBQyxDQUFDO1lBQ3ROLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLENBQUM7Z0JBQUUsT0FBTztZQUNuSSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQ2xDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUNsSCxPQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENB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
|
|
@@ -110,6 +110,23 @@ export interface IHarnessStatusFact {
|
|
|
110
110
|
/** The fact duplicates this structured field; omit it only when that field is displayed. */
|
|
111
111
|
summaryKey?: 'subscription' | 'billing' | 'usageWindows' | 'resets' | 'resetDetails';
|
|
112
112
|
}
|
|
113
|
+
/** The provider's own reading of a usage window. Adapters set it only when the provider reports one of these. */
|
|
114
|
+
export type TUsageSeverity = 'normal' | 'warning' | 'critical';
|
|
115
|
+
export interface IHarnessUsageWindow {
|
|
116
|
+
label: string;
|
|
117
|
+
/**
|
|
118
|
+
* Feature-specific quotas (a model, a surface, a product feature) do not determine the general
|
|
119
|
+
* account summary unless the provider picks one as its headline. Omission means account.
|
|
120
|
+
*/
|
|
121
|
+
scope?: 'account' | 'feature';
|
|
122
|
+
durationSeconds: number;
|
|
123
|
+
usedPercent: number;
|
|
124
|
+
resetAt: string | null;
|
|
125
|
+
/** Omitted when the provider gives no reading; consumers then apply their own thresholds. */
|
|
126
|
+
severity?: TUsageSeverity;
|
|
127
|
+
/** Set when the provider picks this window as the one a single-value summary shows. */
|
|
128
|
+
headline?: true;
|
|
129
|
+
}
|
|
113
130
|
export interface IHarnessStatusSummary {
|
|
114
131
|
/** A plan name does not imply an active billing status. */
|
|
115
132
|
subscription?: {
|
|
@@ -125,14 +142,7 @@ export interface IHarnessStatusSummary {
|
|
|
125
142
|
expiresAt?: string;
|
|
126
143
|
};
|
|
127
144
|
/** Missing windows are unknown, not unused. Times are ISO 8601 UTC. */
|
|
128
|
-
usageWindows?:
|
|
129
|
-
label: string;
|
|
130
|
-
/** Feature-specific quotas do not determine the general account summary. Omission means account. */
|
|
131
|
-
scope?: 'account' | 'feature';
|
|
132
|
-
durationSeconds: number;
|
|
133
|
-
usedPercent: number;
|
|
134
|
-
resetAt: string | null;
|
|
135
|
-
}[];
|
|
145
|
+
usageWindows?: IHarnessUsageWindow[];
|
|
136
146
|
resets?: {
|
|
137
147
|
available: number;
|
|
138
148
|
/** May be a partial list. Omission means the detail lookup was unavailable. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IHarnessAccount, IHarnessAccountStatus, IHarnessCredentialDrift } from './interfaces.harness.js';
|
|
1
|
+
import type { IHarnessAccount, IHarnessAccountStatus, IHarnessCredentialDrift, TUsageSeverity } from './interfaces.harness.js';
|
|
2
2
|
/** Credential-free, versioned output of list --json. Missing status fields stay omitted. */
|
|
3
3
|
export interface IAccountList {
|
|
4
4
|
schemaVersion: 2;
|
|
@@ -46,6 +46,10 @@ export interface IAccountLimitRow {
|
|
|
46
46
|
resetAt: string | null;
|
|
47
47
|
/** Human countdown for the same `resetAt`, relative to `generatedAt`. */
|
|
48
48
|
resetsIn: string;
|
|
49
|
+
/** The provider's reading of this window; null when it gave none or the row has no window. */
|
|
50
|
+
severity: TUsageSeverity | null;
|
|
51
|
+
/** Whether the provider picks this window as the one a single-value summary shows. */
|
|
52
|
+
headline: boolean;
|
|
49
53
|
unavailableReason: string | null;
|
|
50
54
|
}
|
|
51
55
|
/** Credential-free, versioned output of active --json. One entry per active credential slot. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelprofile.com/authswitch",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Manage Codex, OpenCode and Claude Code accounts with guided switching and live usage status",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@git.zone/tsbuild": "^4.4.3",
|
|
27
27
|
"@git.zone/tsrun": "^2.0.6",
|
|
28
28
|
"@git.zone/tstest": "^6.1.1",
|
|
29
|
-
"@types/node": "26.5.
|
|
29
|
+
"@types/node": "26.5.1"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@modelprofile.com/flexharness-models": "^7.0.1",
|
package/readme.md
CHANGED
|
@@ -188,7 +188,21 @@ the local file login, so launch-time flags, managed policies and credentials sup
|
|
|
188
188
|
by embedding applications remain under Claude Code's control.
|
|
189
189
|
|
|
190
190
|
Claude's direct OAuth profile and usage lookups report the plan, weekly and five-hour
|
|
191
|
-
usage, model-
|
|
191
|
+
usage, per-model and per-surface windows, and available extra-usage budget information.
|
|
192
|
+
The usage response's `limits[]` rows are the authoritative window list: which
|
|
193
|
+
meters apply, their scope, the service's `severity` (`normal`, `warning`,
|
|
194
|
+
`critical`) and its headline pick are Claude's, so a new per-model weekly limit
|
|
195
|
+
such as **Fable weekly** appears without an authswitch release. `list --json` keeps
|
|
196
|
+
the rows in the service's order; the tables and `limits --json` order them as
|
|
197
|
+
described under **Condensed views**. Rows are classified on their
|
|
198
|
+
kind and reset group exactly as sent. Labels combine the service's model or surface
|
|
199
|
+
name with the window period, and such a scoped row is treated as a feature limit.
|
|
200
|
+
Rows in a reset group authswitch cannot represent (anything but the five-hour
|
|
201
|
+
session and the weekly window) are not shown; one **Unsupported limits**
|
|
202
|
+
availability fact names them. A malformed row, or a `limits` value that is not a
|
|
203
|
+
list, makes the whole usage lookup unavailable rather than partially guessed.
|
|
204
|
+
Responses without `limits[]` rows fall back to the older keyed weekly, five-hour
|
|
205
|
+
and model windows.
|
|
192
206
|
These endpoints require the `user:profile` scope and may reject expired or restricted
|
|
193
207
|
logins. A null reset timestamp is shown as **Not scheduled**. Billing renewal and
|
|
194
208
|
cancellation dates and earned reset credits are unavailable from these endpoints;
|
|
@@ -240,7 +254,8 @@ an uncertain request. `--json` remains a list-only option.
|
|
|
240
254
|
### Management dashboard
|
|
241
255
|
|
|
242
256
|
`authswitch --tui` opens a resizable account table with subscription, usage and
|
|
243
|
-
reset availability, usage bars
|
|
257
|
+
reset availability, usage bars for the lead window and the next general window,
|
|
258
|
+
scrollable account details and an activity log.
|
|
244
259
|
With multiple registered adapters, a harness selector switches the view; account
|
|
245
260
|
selection and mutations always belong to the displayed harness. Status loads
|
|
246
261
|
incrementally through each account's read-only API, without activating it.
|
|
@@ -322,17 +337,25 @@ output to Codex. Each section includes saved accounts and an identifiable active
|
|
|
322
337
|
login even if it has never been saved. `*` marks the active account, and the saved
|
|
323
338
|
marker checks the credential itself rather than just the existence of metadata.
|
|
324
339
|
|
|
325
|
-
The overview compares login state, plan provenance,
|
|
326
|
-
|
|
340
|
+
The overview compares login state, plan provenance, lead-window usage (the
|
|
341
|
+
provider's headline window, otherwise weekly), earned resets and that window's
|
|
342
|
+
reset countdown. Countdowns use days, hours and minutes, such as
|
|
327
343
|
`7d 5h 6min`;
|
|
328
344
|
`<1min` means less than a minute remains and `due` means the reported deadline has
|
|
329
345
|
passed, without claiming the service has refreshed the quota. All countdowns share
|
|
330
346
|
the same snapshot time.
|
|
331
|
-
Usage and countdown refer to the same
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
347
|
+
Usage and countdown refer to the same window. When the provider picks a headline
|
|
348
|
+
window (Claude does, for example its Fable weekly limit), that window leads.
|
|
349
|
+
Otherwise the
|
|
350
|
+
general account window leads, preferring weekly; if no weekly window is reported,
|
|
351
|
+
the longest general window is shown with its actual duration. Other exhausted
|
|
352
|
+
general windows retain their own reset warning. A general window is named by its
|
|
353
|
+
period (`Weekly`, `5h`) unless another shown general window has the same period; a
|
|
354
|
+
feature limit, or a general window sharing its period, is named by its label
|
|
355
|
+
(`Fable weekly: 100% used`, `Claude weekly (weekly_oauth) exhausted`). Feature
|
|
356
|
+
limits such as Spark and code review have a separate table and determine the
|
|
357
|
+
summary only when the provider picks one as its headline. The TUI uses the same
|
|
358
|
+
selection and names.
|
|
336
359
|
Window durations come from the provider, not from the plan name or
|
|
337
360
|
primary/secondary position; a Pro account with only a general weekly window gets
|
|
338
361
|
no invented 5-hour limit.
|
|
@@ -358,9 +381,9 @@ Account limits
|
|
|
358
381
|
┌──────────────────────┬─────────────────────────┬───────────────────────┬────────┬───────────────┐
|
|
359
382
|
│ Provider │ Account │ Limit type │ Used % │ Resets in │
|
|
360
383
|
├──────────────────────┼─────────────────────────┼───────────────────────┼────────┼───────────────┤
|
|
361
|
-
│ Claude Code │ phil@example.com │ Claude weekly │
|
|
362
|
-
│ Claude Code │ phil@example.com │ Claude five-hour │
|
|
363
|
-
│ Claude Code │ phil@example.com │
|
|
384
|
+
│ Claude Code │ phil@example.com │ Claude weekly │ 75% │ 4d 3h │
|
|
385
|
+
│ Claude Code │ phil@example.com │ Claude five-hour │ 12% │ 1h 2m │
|
|
386
|
+
│ Claude Code │ phil@example.com │ Fable weekly │ 88% │ 2d 5h │
|
|
364
387
|
│ Codex │ alice@example.com │ Codex secondary │ 12% │ 3d 4h │
|
|
365
388
|
│ Codex │ alice@example.com │ Codex primary │ 37% │ 2h 13m │
|
|
366
389
|
│ Codex │ alice@example.com │ Code review secondary │ 100% │ 3h 59m │
|
|
@@ -382,9 +405,18 @@ account never blanks another's numbers. `not scheduled` means the provider repor
|
|
|
382
405
|
usage without a reset deadline; it is not the same as `n/a`.
|
|
383
406
|
|
|
384
407
|
Limit types are the provider's own window names, ordered general-before-feature and
|
|
385
|
-
weekly-first within an account.
|
|
408
|
+
weekly-first within an account. Claude's per-model and per-surface limits carry the
|
|
409
|
+
service's name (`Fable weekly`); an unscoped Claude meter other than the five-hour
|
|
410
|
+
session and the weekly total keeps its kind in parentheses
|
|
411
|
+
(`Claude weekly (weekly_oauth)`). The provider column names the harness, qualified by
|
|
386
412
|
the credential slot when a harness owns several (`OpenCode / openai`).
|
|
387
413
|
|
|
414
|
+
**Used %** is coloured by the provider's own reading when it reports one: orange for
|
|
415
|
+
`warning`, red for `critical`, uncoloured for `normal`. Without a reading, `n/a` is
|
|
416
|
+
orange and an exhausted window (100% or more) is red. Colour is omitted when
|
|
417
|
+
`NO_COLOR` is set, output is not a terminal, or the terminal is narrower than 40
|
|
418
|
+
columns.
|
|
419
|
+
|
|
388
420
|
`authswitch active` answers "what am I logged in as" for every harness at once:
|
|
389
421
|
|
|
390
422
|
```
|
|
@@ -440,7 +472,9 @@ arguments to these commands exit with 2.
|
|
|
440
472
|
`limits --json` emits `IAccountLimits` and `active --json` emits `IActiveAccounts`:
|
|
441
473
|
the same rows as the tables, plus the machine-readable fields the tables condense —
|
|
442
474
|
`accountId`, `slotId`, `scope`, `windowSeconds`, the ISO `resetAt` beside the human
|
|
443
|
-
`resetsIn`, the
|
|
475
|
+
`resetsIn`, the provider's `severity` (`normal`, `warning`, `critical`, or null when
|
|
476
|
+
it gave none) and `headline` (true for the window the provider picks for a
|
|
477
|
+
single-value summary), the ISO `savedAt` beside the human `savedAgo`, the per-row
|
|
444
478
|
`unavailableReason` that the footnotes summarise, and `drift`, which carries the
|
|
445
479
|
expected and current account ids, their labels, whether the current one is saved,
|
|
446
480
|
the ISO `switchedAt` of the switch that was undone, and the same sentence as `reason`. Both carry `schemaVersion: 1`, the
|
|
@@ -456,7 +490,9 @@ The exported `IAccountList` contract contains:
|
|
|
456
490
|
empty list).
|
|
457
491
|
- Each account's opaque `id`, `label`, `isActive`, verified `isStashed`, `savedAt`,
|
|
458
492
|
`details`, and `status` containing all labelled `facts`, `problems`, and optional
|
|
459
|
-
typed `summary` fields. Missing fields remain omitted, not replaced by zero
|
|
493
|
+
typed `summary` fields. Missing fields remain omitted, not replaced by zero;
|
|
494
|
+
`summary.usageWindows[]` carries `severity` and `headline` only when the provider
|
|
495
|
+
reported them.
|
|
460
496
|
|
|
461
497
|
JSON retains full fact strings and absolute ISO reset/expiry timestamps. It exports
|
|
462
498
|
the credential-free adapter contract, never credentials, raw HTTP responses or
|
|
@@ -561,11 +597,18 @@ explicit zeroes remain zero. A successful reset-detail lookup supplies the summa
|
|
|
561
597
|
count; if it fails, the limits response can still supply availability.
|
|
562
598
|
|
|
563
599
|
Each usage window may set `scope: 'account' | 'feature'` (default `account`).
|
|
564
|
-
Adapters mark model-specific or feature-specific quotas as `feature
|
|
565
|
-
|
|
566
|
-
|
|
600
|
+
Adapters mark model-specific or feature-specific quotas as `feature`; those quotas
|
|
601
|
+
appear in the feature tables, JSON and details and lead the account summary only
|
|
602
|
+
when the provider marks one as its headline (see below). Weekly windows are identified by `durationSeconds: 604800`;
|
|
567
603
|
neither window labels nor plan names are parsed to infer limits.
|
|
568
604
|
|
|
605
|
+
A window may also carry the provider's own reading: `severity?: TUsageSeverity`
|
|
606
|
+
(`'normal' | 'warning' | 'critical'`) and `headline?: true` for the window the
|
|
607
|
+
provider picks for a single-value summary. Adapters set them only when the provider
|
|
608
|
+
reports them, never from local thresholds. A headline window leads the account
|
|
609
|
+
summary whatever its scope; the first one in the adapter's order wins if several are
|
|
610
|
+
marked.
|
|
611
|
+
|
|
569
612
|
Optional `summary.billing` contains provider-reported `hasActiveSubscription`,
|
|
570
613
|
`autoRenew`, `renewsAt`, `cancelsAt`, and `expiresAt`, independent of the plan name.
|
|
571
614
|
Dates are ISO UTC and omitted
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/accounts.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IAuthHarness, IHarnessAccount, IHarnessAccountStatus, IHarnessCredentialDrift, IHarnessState,
|
|
1
|
+
import type { IAuthHarness, IHarnessAccount, IHarnessAccountStatus, IHarnessCredentialDrift, IHarnessState, IHarnessUsageWindow } from './interfaces.harness.js';
|
|
2
2
|
import { plainText } from './formatting.js';
|
|
3
3
|
|
|
4
4
|
export interface IAccountRow {
|
|
@@ -72,20 +72,34 @@ export const accountPlan = (rowArg: IAccountRow): string => {
|
|
|
72
72
|
const subscription = rowArg.status?.summary?.subscription;
|
|
73
73
|
return subscription ? `${plainText(subscription.plan)}${subscription.source === 'stored' ? ' (stored; unverified)' : ' (live)'}` : rowArg.status ? 'Unavailable' : 'Loading';
|
|
74
74
|
};
|
|
75
|
-
type TUsageWindow = NonNullable<IHarnessStatusSummary['usageWindows']>[number];
|
|
76
75
|
type TAccountStatusRow = Pick<IAccountRow, 'status'>;
|
|
77
|
-
|
|
76
|
+
/**
|
|
77
|
+
* How a single-value summary names a window among the windows it shows. An account window is named by
|
|
78
|
+
* its period while it is the only shown account window of that period; a feature window, or an account
|
|
79
|
+
* window sharing its period with another, is named by its own label, so no meter reads as another's.
|
|
80
|
+
*/
|
|
81
|
+
export const usageWindowName = (windowArg: IHarnessUsageWindow, shownArg: readonly IHarnessUsageWindow[]): string =>
|
|
82
|
+
windowArg.scope === 'feature' || shownArg.some(other => other !== windowArg && other.scope !== 'feature' && other.durationSeconds === windowArg.durationSeconds)
|
|
83
|
+
? plainText(windowArg.label)
|
|
84
|
+
: windowArg.durationSeconds === 604800 ? 'Weekly' : duration(windowArg.durationSeconds);
|
|
78
85
|
/** Order by scope and actual duration: a provider's primary slot need not be five hours. */
|
|
79
|
-
export const orderedUsageWindows = (windowsArg: readonly
|
|
86
|
+
export const orderedUsageWindows = (windowsArg: readonly IHarnessUsageWindow[] = []): IHarnessUsageWindow[] => [...windowsArg].sort((left, right) =>
|
|
80
87
|
Number(left.scope === 'feature') - Number(right.scope === 'feature') ||
|
|
81
88
|
Number(left.durationSeconds !== 604800) - Number(right.durationSeconds !== 604800) || right.durationSeconds - left.durationSeconds);
|
|
82
|
-
|
|
89
|
+
/**
|
|
90
|
+
* The windows a single-value summary shows, lead window first: the provider's headline pick, whatever
|
|
91
|
+
* its scope, then the account windows in display order. Other feature quotas never lead a summary.
|
|
92
|
+
*/
|
|
93
|
+
export const accountUsageWindows = (rowArg: TAccountStatusRow): IHarnessUsageWindow[] | undefined => {
|
|
83
94
|
const windows = rowArg.status?.summary?.usageWindows;
|
|
84
|
-
|
|
95
|
+
if (windows === undefined) return undefined;
|
|
96
|
+
const headline = windows.find(window => window.headline === true);
|
|
97
|
+
const accountWindows = orderedUsageWindows(windows.filter(window => window !== headline && window.scope !== 'feature'));
|
|
98
|
+
return headline === undefined ? accountWindows : [headline, ...accountWindows];
|
|
85
99
|
};
|
|
86
100
|
export const accountUsage = (rowArg: TAccountStatusRow): string => {
|
|
87
101
|
const windows = accountUsageWindows(rowArg);
|
|
88
|
-
return windows?.length ? `${
|
|
102
|
+
return windows?.length ? `${usageWindowName(windows[0], windows)}: ${windows[0].usedPercent}% used` : windows ? 'None reported' : rowArg.status ? 'Unavailable' : 'Loading';
|
|
89
103
|
};
|
|
90
104
|
export const accountResets = (rowArg: IAccountRow): string => rowArg.status?.summary?.resets === undefined ? rowArg.status ? 'Unavailable' : 'Loading' : String(rowArg.status.summary.resets.available);
|
|
91
105
|
export const accountNextReset = (rowArg: TAccountStatusRow, nowArg = Date.now()): string => {
|
|
@@ -96,7 +110,7 @@ export const accountQuotaSummary = (rowArg: TAccountStatusRow, nowArg: number):
|
|
|
96
110
|
const windows = accountUsageWindows(rowArg);
|
|
97
111
|
return [accountUsage(rowArg), ...(windows?.length ? [
|
|
98
112
|
`Reset in: ${accountNextReset(rowArg, nowArg)}`,
|
|
99
|
-
...windows.slice(1).filter(window => window.usedPercent >= 100).map(window => `${
|
|
113
|
+
...windows.slice(1).filter(window => window.usedPercent >= 100).map(window => `${usageWindowName(window, windows)} exhausted\nResets in: ${until(window.resetAt, nowArg)}`),
|
|
100
114
|
] : [])].join('\n');
|
|
101
115
|
};
|
|
102
116
|
export const accountState = (rowArg: IAccountRow): string => `${rowArg.account.isActive ? '* active, ' : ''}${rowArg.account.isStashed ? 'saved' : 'not saved'}`;
|
|
@@ -16,7 +16,7 @@ const publicStatus = (statusArg: IHarnessAccountStatus): IHarnessAccountStatus =
|
|
|
16
16
|
...(summary === undefined ? {} : { summary: {
|
|
17
17
|
...(summary.subscription === undefined ? {} : { subscription: { plan: summary.subscription.plan, source: summary.subscription.source } }),
|
|
18
18
|
...(summary.billing === undefined ? {} : { billing: { hasActiveSubscription: summary.billing.hasActiveSubscription, autoRenew: summary.billing.autoRenew, renewsAt: summary.billing.renewsAt, cancelsAt: summary.billing.cancelsAt, expiresAt: summary.billing.expiresAt } }),
|
|
19
|
-
...(summary.usageWindows === undefined ? {} : { usageWindows: summary.usageWindows.map(({ label, scope, durationSeconds, usedPercent, resetAt }) => ({ label, scope, durationSeconds, usedPercent, resetAt })) }),
|
|
19
|
+
...(summary.usageWindows === undefined ? {} : { usageWindows: summary.usageWindows.map(({ label, scope, durationSeconds, usedPercent, resetAt, severity, headline }) => ({ label, scope, durationSeconds, usedPercent, resetAt, severity, headline })) }),
|
|
20
20
|
...(summary.resets === undefined ? {} : { resets: {
|
|
21
21
|
available: summary.resets.available,
|
|
22
22
|
...(summary.resets.details === undefined ? {} : { details: summary.resets.details.map(({ status, kind, expiresAt }) => ({ status, kind, expiresAt })) }),
|
|
@@ -1,8 +1,107 @@
|
|
|
1
1
|
import { credentialRecord, credentialText } from './classes.credentialstore.js';
|
|
2
|
-
import
|
|
2
|
+
import { plainText } from './formatting.js';
|
|
3
|
+
import type { IHarnessAccountStatus, IHarnessUsageWindow, TUsageSeverity } from './interfaces.harness.js';
|
|
3
4
|
|
|
4
5
|
class ClaudeStatusError extends Error {}
|
|
5
6
|
|
|
7
|
+
interface IClaudeUsageWindows {
|
|
8
|
+
windows: IHarnessUsageWindow[];
|
|
9
|
+
/** Server rows whose reset group the window model cannot represent, named by kind and group. */
|
|
10
|
+
unsupported: string[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Reset times are normalised to ISO 8601 UTC; an unparsable one rejects the whole usage response. */
|
|
14
|
+
const resetTimestamp = (value: unknown): string | null => value == null ? null : new Date(String(value)).toISOString();
|
|
15
|
+
|
|
16
|
+
const SERVER_NAME_LENGTH = 64;
|
|
17
|
+
|
|
18
|
+
/** A server-supplied name becomes label text: no control characters, bounded by code points, and never blank. */
|
|
19
|
+
const serverName = (value: unknown): string => {
|
|
20
|
+
const name = typeof value === 'string' ? Array.from(plainText(value).trim()).slice(0, SERVER_NAME_LENGTH).join('').trimEnd() : '';
|
|
21
|
+
if (!name) throw new Error('Unsupported Claude usage name.');
|
|
22
|
+
return name;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/** Keyed windows, read only from a usage body that carries no limits[] rows. */
|
|
26
|
+
const KEYED_WINDOWS = [
|
|
27
|
+
['five_hour', 'Claude five-hour', 18000, 'account'], ['seven_day', 'Claude weekly', 604800, 'account'],
|
|
28
|
+
['seven_day_oauth_apps', 'OAuth apps weekly', 604800, 'feature'], ['seven_day_opus', 'Opus weekly', 604800, 'feature'], ['seven_day_sonnet', 'Sonnet weekly', 604800, 'feature'],
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
const keyedWindows = (usage: Record<string, unknown>): IHarnessUsageWindow[] => {
|
|
32
|
+
const windows: IHarnessUsageWindow[] = [];
|
|
33
|
+
for (const [key, label, durationSeconds, scope] of KEYED_WINDOWS) {
|
|
34
|
+
if (usage[key] == null) continue;
|
|
35
|
+
const window = credentialRecord(usage[key]);
|
|
36
|
+
if (window.utilization == null) continue;
|
|
37
|
+
if (typeof window.utilization !== 'number' || !Number.isFinite(window.utilization) || window.utilization < 0) throw new Error('Unsupported Claude usage utilization.');
|
|
38
|
+
windows.push({ label, durationSeconds, scope, usedPercent: window.utilization, resetAt: resetTimestamp(window.resets_at) });
|
|
39
|
+
}
|
|
40
|
+
return windows;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The limits[] row groups the window model represents: each group's duration, the period word its
|
|
45
|
+
* labels use, and the kind of the group's unscoped account meter, which keeps the plain label.
|
|
46
|
+
*/
|
|
47
|
+
const LIMIT_GROUPS: ReadonlyMap<string, { durationSeconds: number; period: string; accountKind: string }> = new Map([
|
|
48
|
+
['session', { durationSeconds: 18000, period: 'five-hour', accountKind: 'session' }],
|
|
49
|
+
['weekly', { durationSeconds: 604800, period: 'weekly', accountKind: 'weekly_all' }],
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
const isUsageSeverity = (value: unknown): value is TUsageSeverity => value === 'normal' || value === 'warning' || value === 'critical';
|
|
53
|
+
|
|
54
|
+
/** A scope part is absent (null or omitted) or names the model or surface a row is for. */
|
|
55
|
+
const scopeSubject = (value: unknown): string | undefined => value == null ? undefined : serverName(credentialRecord(value).display_name);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The server's usage rows, in the server's order. An unscoped row is an account meter; a model- or
|
|
59
|
+
* surface-scoped row is a feature quota named by the server's own label. Rows are classified on the
|
|
60
|
+
* kind and group exactly as sent; only the text shown to users is sanitised. Every row is validated
|
|
61
|
+
* before a row in an unrepresentable group is set aside, so a malformed row can never hide behind one.
|
|
62
|
+
*/
|
|
63
|
+
const limitWindows = (rows: readonly unknown[]): IClaudeUsageWindows => {
|
|
64
|
+
const windows: IHarnessUsageWindow[] = [];
|
|
65
|
+
const unsupported = new Set<string>();
|
|
66
|
+
for (const value of rows) {
|
|
67
|
+
const row = credentialRecord(value);
|
|
68
|
+
const { kind, group } = row;
|
|
69
|
+
if (typeof kind !== 'string' || typeof group !== 'string') throw new Error('Unsupported Claude usage meter.');
|
|
70
|
+
const kindName = serverName(kind);
|
|
71
|
+
const groupName = serverName(group);
|
|
72
|
+
const usedPercent = row.percent;
|
|
73
|
+
if (typeof usedPercent !== 'number' || !Number.isFinite(usedPercent) || usedPercent < 0) throw new Error('Unsupported Claude usage percentage.');
|
|
74
|
+
const resetAt = resetTimestamp(row.resets_at);
|
|
75
|
+
const scope: Record<string, unknown> = row.scope == null ? {} : credentialRecord(row.scope);
|
|
76
|
+
const model = scopeSubject(scope.model);
|
|
77
|
+
const surface = scopeSubject(scope.surface);
|
|
78
|
+
const subject = model ?? surface;
|
|
79
|
+
const meter = LIMIT_GROUPS.get(group);
|
|
80
|
+
if (!meter) {
|
|
81
|
+
unsupported.add(`${kindName} in group ${groupName}`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const severity = row.severity;
|
|
85
|
+
windows.push({
|
|
86
|
+
label: subject === undefined ? `Claude ${meter.period}${kind === meter.accountKind ? '' : ` (${kindName})`}` : `${subject} ${meter.period}`,
|
|
87
|
+
durationSeconds: meter.durationSeconds, scope: subject === undefined ? 'account' : 'feature', usedPercent, resetAt,
|
|
88
|
+
...(isUsageSeverity(severity) ? { severity } : {}),
|
|
89
|
+
...(row.is_active === true ? { headline: true as const } : {}),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return { windows, unsupported: [...unsupported] };
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* A usage body's windows. Its limits[] rows are authoritative whenever the server sends any; the keyed
|
|
97
|
+
* fields describe the same meters and are read only from a body without rows.
|
|
98
|
+
*/
|
|
99
|
+
const claudeUsageWindows = (usage: Record<string, unknown>): IClaudeUsageWindows => {
|
|
100
|
+
const limits = usage.limits;
|
|
101
|
+
if (limits != null && !Array.isArray(limits)) throw new Error('Unsupported Claude usage limits.');
|
|
102
|
+
return Array.isArray(limits) && limits.length ? limitWindows(limits) : { windows: keyedWindows(usage), unsupported: [] };
|
|
103
|
+
};
|
|
104
|
+
|
|
6
105
|
/** Read-only Claude Code OAuth account endpoints. No refresh, inference, or browser session is used. */
|
|
7
106
|
export class ClaudeAccountStatus {
|
|
8
107
|
constructor(private readonly fetcher: typeof fetch = globalThis.fetch) {}
|
|
@@ -64,18 +163,7 @@ export class ClaudeAccountStatus {
|
|
|
64
163
|
} else result.problems.push(`Profile: ${profile.reason instanceof ClaudeStatusError ? profile.reason.message : 'Lookup failed.'}`);
|
|
65
164
|
if (usage.status === 'fulfilled') {
|
|
66
165
|
try {
|
|
67
|
-
const windows
|
|
68
|
-
for (const [key, label, durationSeconds, scope] of [
|
|
69
|
-
['five_hour', 'Claude five-hour', 18000, 'account'], ['seven_day', 'Claude weekly', 604800, 'account'],
|
|
70
|
-
['seven_day_oauth_apps', 'OAuth apps weekly', 604800, 'feature'], ['seven_day_opus', 'Opus weekly', 604800, 'feature'], ['seven_day_sonnet', 'Sonnet weekly', 604800, 'feature'],
|
|
71
|
-
] as const) {
|
|
72
|
-
if (usage.value[key] == null) continue;
|
|
73
|
-
const window = credentialRecord(usage.value[key]);
|
|
74
|
-
if (window.utilization == null) continue;
|
|
75
|
-
if (typeof window.utilization !== 'number' || !Number.isFinite(window.utilization) || window.utilization < 0) throw new Error();
|
|
76
|
-
const resetAt = window.resets_at == null ? null : new Date(String(window.resets_at)).toISOString();
|
|
77
|
-
windows.push({ label, durationSeconds, scope, usedPercent: window.utilization, resetAt });
|
|
78
|
-
}
|
|
166
|
+
const { windows, unsupported } = claudeUsageWindows(usage.value);
|
|
79
167
|
result.summary = { ...result.summary, usageWindows: windows };
|
|
80
168
|
for (const window of windows) result.facts.push({ section: 'Usage', summaryKey: 'usageWindows', label: window.label, value: `${window.usedPercent}% used; ${window.resetAt ? 'resets ' + window.resetAt : 'reset not scheduled'}` });
|
|
81
169
|
if (usage.value.extra_usage != null) {
|
|
@@ -90,7 +178,7 @@ export class ClaudeAccountStatus {
|
|
|
90
178
|
}
|
|
91
179
|
if (limit !== undefined && limit > 0 && used !== undefined) result.facts.push({ section: 'Extra usage', label: 'Monthly budget used', value: `${Math.round(used / limit * 10000) / 100}%` });
|
|
92
180
|
}
|
|
93
|
-
if (
|
|
181
|
+
if (unsupported.length) result.facts.push({ section: 'Availability', label: 'Unsupported limits', value: `The service returned limits without a supported reset window, which are not shown: ${unsupported.join(', ')}.` });
|
|
94
182
|
} catch { result.problems.push('Claude usage response is unsupported; missing values were not inferred.'); }
|
|
95
183
|
} else result.problems.push(`Usage: ${usage.reason instanceof ClaudeStatusError ? usage.reason.message : 'Lookup failed.'}`);
|
|
96
184
|
result.facts.push({ section: 'Availability', label: 'Billing dates and earned resets', value: 'Renewal dates, cancellation dates and earned reset credits are not exposed by these Claude Code endpoints.' });
|
package/ts/classes.limits.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import { compactSince, compactUntil, credentialDriftNote, orderedUsageWindows } from './accounts.js';
|
|
3
3
|
import { consoleHeading, consoleTable } from './classes.accountlist.js';
|
|
4
4
|
import type { IAccountList, IAccountLimitRow, IAccountLimits, IActiveAccountDrift, IActiveAccountRow, IActiveAccounts, IHarnessAccountList } from './interfaces.list.js';
|
|
5
|
-
import type { IHarnessCredentialDrift } from './interfaces.harness.js';
|
|
5
|
+
import type { IHarnessCredentialDrift, TUsageSeverity } from './interfaces.harness.js';
|
|
6
6
|
import { dim, plainText } from './formatting.js';
|
|
7
7
|
|
|
8
8
|
type TListedAccount = IHarnessAccountList['accounts'][number];
|
|
@@ -35,7 +35,7 @@ const missingLimitReason = (accountArg: TListedAccount): string => {
|
|
|
35
35
|
if (accountArg.status.summary?.usageWindows === undefined) {
|
|
36
36
|
return availability[0] ?? 'This login does not expose a usage or quota API.';
|
|
37
37
|
}
|
|
38
|
-
return 'The provider reported no usage window for this account.';
|
|
38
|
+
return 'The provider reported no usage window that authswitch can show for this account.';
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
const accountKeys = (harnessArg: IHarnessAccountList, accountArg: TListedAccount) => ({
|
|
@@ -80,7 +80,7 @@ export const accountLimits = (listArg: IAccountList): IAccountLimits => {
|
|
|
80
80
|
for (const harness of listArg.harnesses) {
|
|
81
81
|
const problem = harnessProblem(harness);
|
|
82
82
|
const empty = {
|
|
83
|
-
limitType: null, scope: null, windowSeconds: null, usedPercent: null, resetAt: null, resetsIn: UNAVAILABLE,
|
|
83
|
+
limitType: null, scope: null, windowSeconds: null, usedPercent: null, resetAt: null, resetsIn: UNAVAILABLE, severity: null, headline: false,
|
|
84
84
|
} as const;
|
|
85
85
|
if (problem !== null) {
|
|
86
86
|
rows.push({ harnessId: harness.id, provider: providerName(harness), account: null, accountId: null, isActive: false, ...empty, unavailableReason: problem });
|
|
@@ -102,7 +102,7 @@ export const accountLimits = (listArg: IAccountList): IAccountLimits => {
|
|
|
102
102
|
...accountKeys(harness, account), isActive: account.isActive,
|
|
103
103
|
limitType: plainText(window.label), scope: window.scope ?? 'account', windowSeconds: window.durationSeconds,
|
|
104
104
|
usedPercent: window.usedPercent, resetAt: window.resetAt, resetsIn: compactUntil(window.resetAt, now, UNAVAILABLE),
|
|
105
|
-
unavailableReason: null,
|
|
105
|
+
severity: window.severity ?? null, headline: window.headline === true, unavailableReason: null,
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -165,6 +165,13 @@ export const activeAccounts = (listArg: IAccountList): IActiveAccounts => {
|
|
|
165
165
|
|
|
166
166
|
const percent = (rowArg: IAccountLimitRow): string => rowArg.usedPercent === null ? UNAVAILABLE : `${rowArg.usedPercent}%`;
|
|
167
167
|
|
|
168
|
+
const SEVERITY_COLORS: Record<TUsageSeverity, plugins.smartconsole.TColorName | undefined> = { normal: undefined, warning: 'orange', critical: 'red' };
|
|
169
|
+
|
|
170
|
+
/** The provider's own reading colours a window; without one, n/a and exhausted windows stand out. */
|
|
171
|
+
const percentColor = (rowArg: IAccountLimitRow): plugins.smartconsole.TColorName | undefined =>
|
|
172
|
+
rowArg.severity !== null ? SEVERITY_COLORS[rowArg.severity]
|
|
173
|
+
: rowArg.usedPercent === null ? 'orange' : rowArg.usedPercent >= 100 ? 'red' : undefined;
|
|
174
|
+
|
|
168
175
|
/** Condensed presentation for `authswitch limits` and `authswitch active`. */
|
|
169
176
|
export class CondensedRenderer {
|
|
170
177
|
constructor(private readonly out: plugins.smartconsole.SmartConsole) {}
|
|
@@ -183,7 +190,7 @@ export class CondensedRenderer {
|
|
|
183
190
|
{ key: 'account', title: 'Account', value: row => row.account ?? UNAVAILABLE, style: row => ({ bold: row.isActive }) },
|
|
184
191
|
{ key: 'limit', title: 'Limit type', value: row => row.limitType ?? UNAVAILABLE },
|
|
185
192
|
{ key: 'used', title: 'Used %', value: percent, align: 'right',
|
|
186
|
-
style: row => ({ foreground: row
|
|
193
|
+
style: row => ({ foreground: percentColor(row) }) },
|
|
187
194
|
{ key: 'reset', title: 'Resets in', value: row => row.resetsIn, align: 'right' },
|
|
188
195
|
]);
|
|
189
196
|
this.notes(limitsArg.notes, 'n/a — ');
|
package/ts/classes.tui.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import type { IAuthHarness, IHarnessOutcome, IHarnessProcess, IHarnessState, IHarnessStopOutcome } from './interfaces.harness.js';
|
|
3
|
-
import { accountDetails, accountPlan, accountQuotaSummary, accountResets, accountState, accountUsageWindows,
|
|
3
|
+
import { accountDetails, accountPlan, accountQuotaSummary, accountResets, accountState, accountUsageWindows, usageWindowName, until, readAccountRows, type IAccountRow } from './accounts.js';
|
|
4
4
|
import { plainText } from './formatting.js';
|
|
5
5
|
import { AuthSwitchOperations } from './classes.operations.js';
|
|
6
6
|
import { describeHarnessProcesses, describeStopOutcome } from './classes.harnessprocesses.js';
|
|
@@ -140,9 +140,10 @@ export class AuthSwitchTui {
|
|
|
140
140
|
const tabs = ui.tabs([{ title: 'Account details', content: details }, { title: 'Activity log', content: ui.logs }]);
|
|
141
141
|
await ui.run({
|
|
142
142
|
view: () => {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
const shown = accountUsageWindows({ status: table.selected?.status }) ?? [];
|
|
144
|
+
const usage = shown.slice(0, 2).map(window => ui.progress(
|
|
145
|
+
`${usageWindowName(window, shown)} (${window.usedPercent}% used; reset in ${until(window.resetAt, Date.now())})`, Math.min(100, window.usedPercent), 100,
|
|
146
|
+
));
|
|
146
147
|
const accountView = ui.column([
|
|
147
148
|
ui.panel(`${plainText(harness.label)} accounts`, table),
|
|
148
149
|
ui.panel('Status and diagnostics', ui.column([...usage, tabs])),
|