@askalf/dario 5.2.9 → 5.2.10
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/accounts.d.ts +12 -1
- package/dist/accounts.js +24 -3
- package/dist/proxy.js +3 -0
- package/package.json +1 -1
package/dist/accounts.d.ts
CHANGED
|
@@ -134,6 +134,9 @@ export declare function ensureLoginCredentialsInPool(alias?: string): Promise<st
|
|
|
134
134
|
* - 'in-sync' : tokens match; no action
|
|
135
135
|
* - 'resynced' : login.json was stale; overwrote with current
|
|
136
136
|
* credentials. Caller should reload pool state
|
|
137
|
+
* - 'creds-stale' : login.json is STRICTLY NEWER than credentials.json
|
|
138
|
+
* (the pool refreshed it; the legacy file is stale) —
|
|
139
|
+
* left login.json untouched. dario#805.
|
|
137
140
|
*
|
|
138
141
|
* Why: the single-account path keeps refreshing `credentials.json` in
|
|
139
142
|
* the background (proxy startup auth check, periodic refresh in oauth.ts).
|
|
@@ -143,9 +146,17 @@ export declare function ensureLoginCredentialsInPool(alias?: string): Promise<st
|
|
|
143
146
|
* says "healthy" so the selector keeps picking it. Detect this at startup
|
|
144
147
|
* and overwrite with the current canonical content. dario#235.
|
|
145
148
|
*
|
|
149
|
+
* BUT the divergence runs BOTH ways. In pool mode the pool's own refresh
|
|
150
|
+
* loop advances `login.json` while `credentials.json` stays frozen (the
|
|
151
|
+
* pool never writes it). Blindly overwriting login.json from credentials.json
|
|
152
|
+
* would then clobber a live token with the stale legacy one whose refresh
|
|
153
|
+
* Anthropic already rotated → invalid_grant on every startup → fleet-wide
|
|
154
|
+
* auth outage. So we reconcile by FRESHNESS, not by assuming credentials.json
|
|
155
|
+
* wins. dario#805 (the second outage of this class within 12h).
|
|
156
|
+
*
|
|
146
157
|
* Runs at any pool size ≥ 1: a lone `login` entry is a live pool member
|
|
147
158
|
* since pool-at-one (dario#618) and can go stale exactly the same way —
|
|
148
159
|
* e.g. after `accounts remove` shrinks a migrated pool back to just the
|
|
149
160
|
* back-filled snapshot.
|
|
150
161
|
*/
|
|
151
|
-
export declare function resyncLoginFromCredentialsIfStale(): Promise<'no-pool' | 'no-login' | 'no-creds' | 'in-sync' | 'resynced'>;
|
|
162
|
+
export declare function resyncLoginFromCredentialsIfStale(): Promise<'no-pool' | 'no-login' | 'no-creds' | 'in-sync' | 'resynced' | 'creds-stale'>;
|
package/dist/accounts.js
CHANGED
|
@@ -553,6 +553,9 @@ export async function ensureLoginCredentialsInPool(alias = MIGRATED_LOGIN_ALIAS)
|
|
|
553
553
|
* - 'in-sync' : tokens match; no action
|
|
554
554
|
* - 'resynced' : login.json was stale; overwrote with current
|
|
555
555
|
* credentials. Caller should reload pool state
|
|
556
|
+
* - 'creds-stale' : login.json is STRICTLY NEWER than credentials.json
|
|
557
|
+
* (the pool refreshed it; the legacy file is stale) —
|
|
558
|
+
* left login.json untouched. dario#805.
|
|
556
559
|
*
|
|
557
560
|
* Why: the single-account path keeps refreshing `credentials.json` in
|
|
558
561
|
* the background (proxy startup auth check, periodic refresh in oauth.ts).
|
|
@@ -562,6 +565,14 @@ export async function ensureLoginCredentialsInPool(alias = MIGRATED_LOGIN_ALIAS)
|
|
|
562
565
|
* says "healthy" so the selector keeps picking it. Detect this at startup
|
|
563
566
|
* and overwrite with the current canonical content. dario#235.
|
|
564
567
|
*
|
|
568
|
+
* BUT the divergence runs BOTH ways. In pool mode the pool's own refresh
|
|
569
|
+
* loop advances `login.json` while `credentials.json` stays frozen (the
|
|
570
|
+
* pool never writes it). Blindly overwriting login.json from credentials.json
|
|
571
|
+
* would then clobber a live token with the stale legacy one whose refresh
|
|
572
|
+
* Anthropic already rotated → invalid_grant on every startup → fleet-wide
|
|
573
|
+
* auth outage. So we reconcile by FRESHNESS, not by assuming credentials.json
|
|
574
|
+
* wins. dario#805 (the second outage of this class within 12h).
|
|
575
|
+
*
|
|
565
576
|
* Runs at any pool size ≥ 1: a lone `login` entry is a live pool member
|
|
566
577
|
* since pool-at-one (dario#618) and can go stale exactly the same way —
|
|
567
578
|
* e.g. after `accounts remove` shrinks a migrated pool back to just the
|
|
@@ -584,9 +595,19 @@ export async function resyncLoginFromCredentialsIfStale() {
|
|
|
584
595
|
loginAcc.refreshToken === tok.refreshToken) {
|
|
585
596
|
return 'in-sync';
|
|
586
597
|
}
|
|
587
|
-
// Tokens diverged
|
|
588
|
-
//
|
|
589
|
-
//
|
|
598
|
+
// Tokens diverged. Reconcile by FRESHNESS — a strictly-newer login.json is
|
|
599
|
+
// the pool having refreshed it (credentials.json is the stale legacy copy),
|
|
600
|
+
// and overwriting it from credentials.json would swap a live token for one
|
|
601
|
+
// whose refresh Anthropic already rotated → invalid_grant → outage (#805).
|
|
602
|
+
// Only the strict case is skipped; equal expiresAt keeps the #235 behaviour
|
|
603
|
+
// (overwrite), since a real refresh always advances expiresAt.
|
|
604
|
+
if (loginAcc.expiresAt > tok.expiresAt) {
|
|
605
|
+
return 'creds-stale';
|
|
606
|
+
}
|
|
607
|
+
// credentials.json is the newer (or equal-age) token — the #235 case: the
|
|
608
|
+
// single-account path refreshed it and the pool snapshot is stale. Overwrite,
|
|
609
|
+
// preserving deviceId/accountUuid (they don't rotate with token refresh;
|
|
610
|
+
// they're pool-internal identity).
|
|
590
611
|
await saveAccount({
|
|
591
612
|
alias: MIGRATED_LOGIN_ALIAS,
|
|
592
613
|
accessToken: tok.accessToken,
|
package/dist/proxy.js
CHANGED
|
@@ -1139,6 +1139,9 @@ export async function startProxy(opts = {}) {
|
|
|
1139
1139
|
if (resyncResult === 'resynced') {
|
|
1140
1140
|
console.log('[dario] re-synced pool `login` account from current credentials.json (was stale; dario#235)');
|
|
1141
1141
|
}
|
|
1142
|
+
else if (resyncResult === 'creds-stale') {
|
|
1143
|
+
console.log('[dario] kept the newer pool `login` token; credentials.json is stale — NOT overwriting (dario#805)');
|
|
1144
|
+
}
|
|
1142
1145
|
// Admin mode (#599) manages the pool over HTTP: it may legitimately start
|
|
1143
1146
|
// with zero accounts and returns a clean 503 until one is added via
|
|
1144
1147
|
// POST /admin/login/*, taking effect with no restart (see onAccountsChanged).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.10",
|
|
4
4
|
"description": "Use your Claude Pro/Max subscription in any tool — Cursor, Cline, Aider, the Agent SDK, your scripts — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|