@askalf/dario 6.0.35 → 6.0.36
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/cli.d.ts +36 -0
- package/dist/cli.js +48 -34
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -105,6 +105,42 @@ export declare function parseBooleanEnv(value: string | undefined): boolean | un
|
|
|
105
105
|
* Set(['thinking','env']) — value "thinking,env" → preserve listed
|
|
106
106
|
*/
|
|
107
107
|
export declare function resolvePreserveOrchestrationTags(args: string[], env: string | undefined): Set<string> | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* The seat shape a running proxy returns from `/accounts`.
|
|
110
|
+
*
|
|
111
|
+
* Everything past `alias` is optional on purpose. A freshly installed CLI
|
|
112
|
+
* routinely queries a proxy still running the PREVIOUS release, whose seats
|
|
113
|
+
* predate whichever field the newest feature added — `sharesWindowWith`,
|
|
114
|
+
* `organizationId` and `grantedAt` all arrived that way (dario#1248 review).
|
|
115
|
+
* The payload is accepted on `mode` + `accounts` alone, so the renderer, not
|
|
116
|
+
* the fetch, is where a missing field would throw. Defaulting each one here
|
|
117
|
+
* keeps `accounts list --live` degrading to a thinner line instead of dying
|
|
118
|
+
* with a TypeError and skipping the on-disk fallback it advertises.
|
|
119
|
+
*/
|
|
120
|
+
export interface LiveSeat {
|
|
121
|
+
alias?: string;
|
|
122
|
+
status?: string;
|
|
123
|
+
action?: 'none' | 'wait' | 'regrant';
|
|
124
|
+
util5h?: number;
|
|
125
|
+
util7d?: number;
|
|
126
|
+
utilAgeMs?: number | null;
|
|
127
|
+
resetInMs?: number | null;
|
|
128
|
+
requestCount?: number;
|
|
129
|
+
rejectedCount?: number;
|
|
130
|
+
organizationId?: string | null;
|
|
131
|
+
sharesWindowWith?: string[];
|
|
132
|
+
grantedAt?: number | null;
|
|
133
|
+
}
|
|
134
|
+
export interface LivePayload {
|
|
135
|
+
mode?: string;
|
|
136
|
+
accounts?: LiveSeat[];
|
|
137
|
+
distinctWindows?: number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Render the live pool listing. Pure — returns the lines rather than printing
|
|
141
|
+
* them, so a legacy payload can be driven straight through it in a test.
|
|
142
|
+
*/
|
|
143
|
+
export declare function formatLiveAccountsListing(payload: LivePayload, port: number, now: number): string[];
|
|
108
144
|
/**
|
|
109
145
|
* Decide whether this module is being invoked as the CLI entry point or
|
|
110
146
|
* imported as a library. Pure, exported for tests; the file-bottom uses
|
package/dist/cli.js
CHANGED
|
@@ -894,6 +894,52 @@ function parsePositiveIntFlag(prefix) {
|
|
|
894
894
|
}
|
|
895
895
|
return n;
|
|
896
896
|
}
|
|
897
|
+
/**
|
|
898
|
+
* Render the live pool listing. Pure — returns the lines rather than printing
|
|
899
|
+
* them, so a legacy payload can be driven straight through it in a test.
|
|
900
|
+
*/
|
|
901
|
+
export function formatLiveAccountsListing(payload, port, now) {
|
|
902
|
+
const seats = Array.isArray(payload.accounts) ? payload.accounts : [];
|
|
903
|
+
const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
|
|
904
|
+
const pct = (n) => `${Math.round(num(n) * 100)}%`;
|
|
905
|
+
const mins = (ms) => {
|
|
906
|
+
const m = Math.max(1, Math.round(ms / 60_000));
|
|
907
|
+
return m >= 60 ? `${Math.floor(m / 60)}h ${m % 60}m` : `${m}m`;
|
|
908
|
+
};
|
|
909
|
+
const age = (ms) => typeof ms !== 'number' || !Number.isFinite(ms)
|
|
910
|
+
? 'never measured'
|
|
911
|
+
: ms < 60_000 ? `read ${Math.round(ms / 1000)}s ago` : `read ${mins(ms)} ago`;
|
|
912
|
+
const lines = [];
|
|
913
|
+
lines.push('');
|
|
914
|
+
lines.push(` dario — Accounts (live, from http://127.0.0.1:${port})`);
|
|
915
|
+
lines.push(' ────────────────');
|
|
916
|
+
lines.push('');
|
|
917
|
+
const windows = typeof payload.distinctWindows === 'number' ? payload.distinctWindows : seats.length;
|
|
918
|
+
lines.push(` Pool of ${seats.length} (${seats.length === 1 ? '1 seat' : seats.length + ' seats'} on ${windows} distinct window${windows === 1 ? '' : 's'})`);
|
|
919
|
+
lines.push('');
|
|
920
|
+
for (const s of seats) {
|
|
921
|
+
const alias = typeof s.alias === 'string' ? s.alias : '(unnamed)';
|
|
922
|
+
const rawStatus = typeof s.status === 'string' ? s.status : 'unknown';
|
|
923
|
+
const status = rawStatus === 'rejected' && typeof s.resetInMs === 'number' ? `rejected, back in ${mins(s.resetInMs)}` : rawStatus;
|
|
924
|
+
lines.push(` ${alias.padEnd(20)} ${status.padEnd(26)} 5h ${pct(s.util5h).padEnd(6)} 7d ${pct(s.util7d).padEnd(6)} ${age(s.utilAgeMs)}`);
|
|
925
|
+
// The one-word next step (dario#1244): a parked seat wants nothing from
|
|
926
|
+
// the operator; an auth-failure streak wants a re-grant.
|
|
927
|
+
const next = s.action === 'regrant' ? 'next: re-grant this seat (dario accounts remove + add)'
|
|
928
|
+
: s.action === 'wait' ? 'next: nothing, it comes back on its own'
|
|
929
|
+
: null;
|
|
930
|
+
const facts = [
|
|
931
|
+
`served ${num(s.requestCount)}`,
|
|
932
|
+
`429s ${num(s.rejectedCount)}`,
|
|
933
|
+
...(next ? [next] : []),
|
|
934
|
+
typeof s.organizationId === 'string' && s.organizationId ? `org ${s.organizationId.slice(0, 8)}…` : 'org not yet observed',
|
|
935
|
+
...(Array.isArray(s.sharesWindowWith) && s.sharesWindowWith.length > 0 ? [`shares its window with ${s.sharesWindowWith.join(', ')}`] : []),
|
|
936
|
+
];
|
|
937
|
+
lines.push(` ${''.padEnd(20)} ${facts.join(' · ')}`);
|
|
938
|
+
lines.push(` ${''.padEnd(20)} ${describeGrantAge(grantAge(typeof s.grantedAt === 'number' ? s.grantedAt : undefined, now))}`);
|
|
939
|
+
}
|
|
940
|
+
lines.push('');
|
|
941
|
+
return lines;
|
|
942
|
+
}
|
|
897
943
|
/**
|
|
898
944
|
* `dario accounts list --live` — the running proxy's view of the pool
|
|
899
945
|
* (dario#1244): status with its countdown, the reading and its age, 429s
|
|
@@ -924,40 +970,8 @@ async function accountsListLive() {
|
|
|
924
970
|
}
|
|
925
971
|
if (!payload || payload.mode !== 'pool' || !Array.isArray(payload.accounts))
|
|
926
972
|
return false;
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
const pct = (n) => `${Math.round(n * 100)}%`;
|
|
930
|
-
const mins = (ms) => {
|
|
931
|
-
const m = Math.max(1, Math.round(ms / 60_000));
|
|
932
|
-
return m >= 60 ? `${Math.floor(m / 60)}h ${m % 60}m` : `${m}m`;
|
|
933
|
-
};
|
|
934
|
-
const age = (ms) => ms === null ? 'never measured' : ms < 60_000 ? `read ${Math.round(ms / 1000)}s ago` : `read ${mins(ms)} ago`;
|
|
935
|
-
console.log('');
|
|
936
|
-
console.log(` dario — Accounts (live, from http://127.0.0.1:${port})`);
|
|
937
|
-
console.log(' ────────────────');
|
|
938
|
-
console.log('');
|
|
939
|
-
const windows = payload.distinctWindows ?? seats.length;
|
|
940
|
-
console.log(` Pool of ${seats.length} (${seats.length === 1 ? '1 seat' : seats.length + ' seats'} on ${windows} distinct window${windows === 1 ? '' : 's'})`);
|
|
941
|
-
console.log('');
|
|
942
|
-
for (const s of seats) {
|
|
943
|
-
const status = s.status === 'rejected' && typeof s.resetInMs === 'number' ? `rejected, back in ${mins(s.resetInMs)}` : s.status;
|
|
944
|
-
console.log(` ${s.alias.padEnd(20)} ${status.padEnd(26)} 5h ${pct(s.util5h).padEnd(6)} 7d ${pct(s.util7d).padEnd(6)} ${age(s.utilAgeMs)}`);
|
|
945
|
-
// The one-word next step (dario#1244): a parked seat wants nothing from
|
|
946
|
-
// the operator; an auth-failure streak wants a re-grant.
|
|
947
|
-
const next = s.action === 'regrant' ? 'next: re-grant this seat (dario accounts remove + add)'
|
|
948
|
-
: s.action === 'wait' ? 'next: nothing, it comes back on its own'
|
|
949
|
-
: null;
|
|
950
|
-
const facts = [
|
|
951
|
-
`served ${s.requestCount}`,
|
|
952
|
-
`429s ${s.rejectedCount}`,
|
|
953
|
-
...(next ? [next] : []),
|
|
954
|
-
s.organizationId ? `org ${s.organizationId.slice(0, 8)}…` : 'org not yet observed',
|
|
955
|
-
...(s.sharesWindowWith.length > 0 ? [`shares its window with ${s.sharesWindowWith.join(', ')}`] : []),
|
|
956
|
-
];
|
|
957
|
-
console.log(` ${''.padEnd(20)} ${facts.join(' · ')}`);
|
|
958
|
-
console.log(` ${''.padEnd(20)} ${describeGrantAge(grantAge(s.grantedAt ?? undefined, now))}`);
|
|
959
|
-
}
|
|
960
|
-
console.log('');
|
|
973
|
+
for (const line of formatLiveAccountsListing(payload, port, Date.now()))
|
|
974
|
+
console.log(line);
|
|
961
975
|
return true;
|
|
962
976
|
}
|
|
963
977
|
async function accounts() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.36",
|
|
4
4
|
"description": "Use your Claude and ChatGPT subscriptions in Cursor, Cline, Aider, Claude Code and the Agent SDK — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint: either plan answers either wire shape, with automatic failover when one hits its limit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|