@askalf/dario 4.8.154 → 5.0.1

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.js CHANGED
@@ -53,6 +53,22 @@ const DEFAULT_COMMAND = args.includes('--no-tui') ? 'help' : 'tui';
53
53
  // `dario --version` etc. still dispatch as expected.
54
54
  const positionalArgs = args.filter((a) => a !== '--no-tui');
55
55
  const command = positionalArgs[0] ?? DEFAULT_COMMAND;
56
+ // v5.0 pool-as-primitive: materialize the just-authenticated `dario login`
57
+ // credentials as a pool of one (accounts/login.json under the reserved `login`
58
+ // alias) so every surface — proxy, doctor, config-report, /accounts — reads a
59
+ // single credential model. Idempotent and copy-only: a no-op when an accounts/
60
+ // pool already exists or no credentials are reachable, and it never refreshes
61
+ // the token lineage (see ensureLoginCredentialsInPool). Best-effort — a failure
62
+ // here shouldn't fail an otherwise-successful login; the proxy back-fills again
63
+ // at startup.
64
+ async function materializeLoginPool() {
65
+ try {
66
+ const alias = await ensureLoginCredentialsInPool();
67
+ if (alias)
68
+ console.log(' Pool: materialized as a pool of one (alias `login`).');
69
+ }
70
+ catch { /* non-fatal; proxy startup back-fills again */ }
71
+ }
56
72
  async function login() {
57
73
  console.log('');
58
74
  console.log(' dario — Claude Login');
@@ -74,6 +90,7 @@ async function login() {
74
90
  if (creds?.claudeAiOauth?.accessToken && creds.claudeAiOauth.expiresAt > Date.now()) {
75
91
  if (noProxy) {
76
92
  console.log(' Found valid credentials. (--no-proxy / --manual: not starting proxy.)');
93
+ await materializeLoginPool();
77
94
  console.log('');
78
95
  return;
79
96
  }
@@ -93,6 +110,7 @@ async function login() {
93
110
  const tokens = await refreshTokens();
94
111
  const expiresIn = Math.round((tokens.expiresAt - Date.now()) / 60000);
95
112
  console.log(` Refresh successful! Token expires in ${expiresIn} minutes.`);
113
+ await materializeLoginPool();
96
114
  console.log('');
97
115
  console.log(' Run `dario proxy` to start the API proxy.');
98
116
  console.log('');
@@ -129,6 +147,7 @@ async function login() {
129
147
  const expiresIn = Math.round((tokens.expiresAt - Date.now()) / 60000);
130
148
  console.log(' Login successful!');
131
149
  console.log(` Token expires in ${expiresIn} minutes (auto-refreshes).`);
150
+ await materializeLoginPool();
132
151
  console.log('');
133
152
  if (noProxy) {
134
153
  console.log(' (--no-proxy / --manual: credentials saved, proxy not started.)');
@@ -360,9 +379,10 @@ async function proxy() {
360
379
  // read-to-completion pattern. Costs tokens (the response is fully
361
380
  // generated even if nobody reads it), so it's opt-in.
362
381
  const drainOnClose = args.includes('--drain-on-close') || fileCfg.drainOnClose || undefined;
363
- // --session-* knobs (v3.28, direction #1). Control the single-account
364
- // session-id lifecycle: idle threshold, jitter on that threshold, hard
365
- // max-age, and whether to give each upstream client its own session.
382
+ // --session-* knobs (v3.28, direction #1). Control the session-id lifecycle:
383
+ // idle threshold, jitter on that threshold, hard max-age, and whether to give
384
+ // each upstream client its own session. v5.0: this policy now applies
385
+ // per-account (a pool of one behaves exactly as the pre-v5 single account).
366
386
  // All defaults preserve v3.27 behaviour exactly. Logic lives in
367
387
  // src/session-rotation.ts; these flags just feed resolveSessionRotationConfig.
368
388
  const sessionIdleRotateMs = parsePositiveIntFlag('--session-idle-rotate=');
@@ -777,23 +797,24 @@ async function accounts() {
777
797
  console.log(' ────────────────');
778
798
  console.log('');
779
799
  if (aliases.length === 0) {
780
- console.log(' No multi-account pool configured.');
800
+ console.log(' No accounts in the pool yet.');
781
801
  console.log('');
782
- console.log(' Pool mode activates automatically when ~/.dario/accounts/');
783
- console.log(' has any entry. Add the first with:');
802
+ console.log(' The pool is the one credential model (v5.0): `dario login`');
803
+ console.log(' is a pool of one, materialized as the `login` account. Add');
804
+ console.log(' more to load-balance across subscriptions:');
784
805
  console.log(' dario accounts add <alias>');
785
806
  console.log('');
786
- console.log(' Single-account dario (the default) keeps working as-is');
787
- console.log(' with ~/.dario/credentials.json you do not need to');
788
- console.log(' migrate unless you want pool routing across accounts.');
807
+ console.log(' If you have run `dario login` but see this, its credentials');
808
+ console.log(' materialize into the pool on the next `dario login` or');
809
+ console.log(' `dario proxy`.');
789
810
  console.log('');
790
811
  return;
791
812
  }
792
813
  const loaded = await loadAllAccounts();
793
814
  const now = Date.now();
794
- console.log(` ${aliases.length} account${aliases.length === 1 ? '' : 's'} configured`);
815
+ console.log(` Pool of ${aliases.length} (${aliases.length === 1 ? '1 account' : aliases.length + ' accounts'})`);
795
816
  if (aliases.length === 1) {
796
- console.log(' (Pool routing serves this account — add another to load-balance across subscriptions.)');
817
+ console.log(' (A pool of one — add another with `dario accounts add <alias>` to load-balance.)');
797
818
  }
798
819
  console.log('');
799
820
  for (const a of loaded) {
@@ -1094,13 +1115,6 @@ async function help() {
1094
1115
  dario backend add NAME --key=sk-... [--base-url=...]
1095
1116
  Add an OpenAI-compat backend (OpenAI, OpenRouter, Groq, etc.)
1096
1117
  dario backend remove N Remove an OpenAI-compat backend
1097
- dario shim -- CMD ARGS [DEPRECATED — removal scheduled for v5.x]
1098
- Run CMD with dario's fetch-patch in-process.
1099
- Only replaces 3 of 8 billing-classifier axes
1100
- (system blocks, agent identity, header order).
1101
- Falls back to passthrough on 1-block system
1102
- requests (\`claude -p\`, Agent SDK). Use proxy
1103
- mode for non-CC clients. See CHANGELOG v4.2.0.
1104
1118
  dario subagent install Register ~/.claude/agents/dario.md so Claude Code
1105
1119
  can delegate dario diagnostics / template-refresh
1106
1120
  operations to a named sub-agent (v3.26)
@@ -1208,7 +1222,7 @@ async function help() {
1208
1222
  proxy's JA3/JA4 ClientHello indistinguishable
1209
1223
  from a stock CC request. Install Bun
1210
1224
  (https://bun.sh) so dario auto-relaunches
1211
- under it, or use shim mode. (v3.23)
1225
+ under it. (v3.23)
1212
1226
  --stealth Single-flag behavioral-stealth preset.
1213
1227
  Flips pace-jitter, think-time, and
1214
1228
  session-start defaults from 0 to non-zero
@@ -1268,11 +1282,12 @@ async function help() {
1268
1282
  is fully generated even if nobody reads
1269
1283
  it) for fingerprint fidelity. Bounded by
1270
1284
  the 5-minute upstream timeout. (v3.25)
1271
- --session-idle-rotate=MS Idle ms before the single-account session
1272
- id rotates (default: 900000 = 15 min).
1285
+ --session-idle-rotate=MS Idle ms before an account's session id
1286
+ rotates (default: 900000 = 15 min).
1273
1287
  Real CC rotates once per conversation, not
1274
1288
  per call; the default matches its observed
1275
- cadence. Pool mode is unaffected. (v3.28)
1289
+ cadence. Applies per account a pool of one
1290
+ rotates as the pre-v5 single account did. (v3.28)
1276
1291
  --session-rotate-jitter=MS
1277
1292
  Max additional uniform-random jitter (ms)
1278
1293
  added to the idle threshold, sampled once
@@ -1489,109 +1504,20 @@ async function help() {
1489
1504
  Tokens auto-refresh in the background — set it and forget it.
1490
1505
  `);
1491
1506
  }
1507
+ // `dario shim` was removed in v5.0 (deprecated since v4.2 — it matched only
1508
+ // 3 of the 8 billing-classifier axes and fell back to passthrough on 1-block
1509
+ // system requests). This stub keeps the failure mode a one-line pointer
1510
+ // instead of an "unknown command" for users upgrading across the boundary.
1492
1511
  async function shim() {
1493
- // dario shim -- <command> [args...]
1494
- // The `--` separator is conventional but optional; if the user omits it
1495
- // we just pass everything after `shim` through to the child.
1496
- const rest = args.slice(1);
1497
- const sepIdx = rest.indexOf('--');
1498
- let verbose = false;
1499
- let priority = 'normal';
1500
- let head;
1501
- let childArgs;
1502
- if (sepIdx >= 0) {
1503
- head = rest.slice(0, sepIdx);
1504
- childArgs = rest.slice(sepIdx + 1);
1505
- }
1506
- else {
1507
- head = [];
1508
- childArgs = rest;
1509
- }
1510
- for (const flag of head) {
1511
- if (flag === '-v' || flag === '--verbose')
1512
- verbose = true;
1513
- else if (flag.startsWith('--priority=')) {
1514
- const v = flag.slice('--priority='.length);
1515
- if (v !== 'normal' && v !== 'below-normal' && v !== 'low') {
1516
- console.error(`--priority: invalid value ${JSON.stringify(v)}. Expected one of: normal, below-normal, low.`);
1517
- process.exit(1);
1518
- }
1519
- priority = v;
1520
- }
1521
- else {
1522
- console.error(`Unknown shim flag: ${flag}`);
1523
- process.exit(1);
1524
- }
1525
- }
1526
- if (childArgs.length === 0) {
1527
- console.error('Usage: dario shim [-v] [--priority=normal|below-normal|low] -- <command> [args...]');
1528
- console.error('Example: dario shim -- claude --print -p "hi"');
1529
- console.error(' dario shim --priority=below-normal -- claude (recommended on Windows when RDP\'d into the host)');
1530
- process.exit(1);
1531
- }
1532
- // v4.2.0+: shim mode is DEPRECATED — set for removal in v5.x.
1533
- //
1534
- // The empirical reason (verified by side-by-side fingerprint diff of
1535
- // shim's `_rewriteBody` against the proxy's `buildCCRequest` — see
1536
- // CHANGELOG v4.2.0 entry): shim mode only replaces 3 of the 8 axes
1537
- // Anthropic's billing classifier actually inspects (system blocks,
1538
- // agent identity, header order). It leaves the client's JSON key
1539
- // order, max_tokens value, metadata billing tag, and any non-CC
1540
- // fields (temperature, top_p, service_tier) unchanged on the wire.
1541
- // And on the most-common claude -p / Agent-SDK request shape (which
1542
- // sends a 1-block system, not the 3-block shape shim's shape-check
1543
- // hardcodes), shim silently falls back to total passthrough — sending
1544
- // the client's raw body to api.anthropic.com with zero replay.
1545
- //
1546
- // For interactive CC (`dario shim -- claude`), this is mostly a no-op
1547
- // because CC's own outbound already matches every axis dario would
1548
- // synthesize. But for any non-CC client (`dario shim -- aider`,
1549
- // `dario shim -- cline`, your own scripts), shim mode does not deliver
1550
- // the wire fidelity the README claims.
1551
- //
1552
- // We warn loudly here instead of silently breaking, and point users
1553
- // at proxy mode. Set DARIO_SHIM_NO_DEPRECATION_WARNING=1 to suppress
1554
- // the banner for scripts that need the exit-code semantics but have
1555
- // already migrated their understanding.
1556
- if (process.env['DARIO_SHIM_NO_DEPRECATION_WARNING'] !== '1') {
1557
- console.error('');
1558
- console.error('[dario] ⚠ DEPRECATION: `dario shim` is deprecated in v4.2 and scheduled for removal in v5.x.');
1559
- console.error('[dario]');
1560
- console.error('[dario] Shim mode only matches a subset of the wire-shape axes Anthropic\'s billing classifier');
1561
- console.error('[dario] inspects. Specifically, it does not normalize JSON key order, max_tokens, metadata');
1562
- console.error('[dario] billing-tag, or non-CC body fields. On `claude -p` / Agent-SDK style requests (1-block');
1563
- console.error('[dario] system), shim falls back to total passthrough — the client\'s raw body reaches the');
1564
- console.error('[dario] upstream unchanged.');
1565
- console.error('[dario]');
1566
- console.error('[dario] Use proxy mode instead, which rebuilds every request to CC\'s exact wire shape:');
1567
- console.error('[dario]');
1568
- console.error('[dario] Terminal 1: dario proxy');
1569
- console.error('[dario] Terminal 2: ANTHROPIC_BASE_URL=http://localhost:3456 \\');
1570
- console.error('[dario] ANTHROPIC_API_KEY=dario \\');
1571
- console.error('[dario] ' + childArgs.join(' '));
1572
- console.error('[dario]');
1573
- console.error('[dario] To suppress this banner: DARIO_SHIM_NO_DEPRECATION_WARNING=1');
1574
- console.error('');
1575
- }
1576
- const { runShim } = await import('./shim/host.js');
1577
- try {
1578
- const result = await runShim({
1579
- command: childArgs[0],
1580
- args: childArgs.slice(1),
1581
- verbose,
1582
- priority,
1583
- });
1584
- if (verbose) {
1585
- const summary = result.analytics.summary(60);
1586
- console.error(`[dario shim] ${result.events.length} relay events, ` +
1587
- `subscriptionPercent=${summary.window.subscriptionPercent}%`);
1588
- }
1589
- process.exit(result.exitCode);
1590
- }
1591
- catch (err) {
1592
- console.error('shim failed:', sanitizeError(err));
1593
- process.exit(1);
1594
- }
1512
+ console.error('`dario shim` was removed in v5.0. Use proxy mode instead:');
1513
+ console.error('');
1514
+ console.error(' Terminal 1: dario proxy');
1515
+ console.error(' Terminal 2: ANTHROPIC_BASE_URL=http://localhost:3456 \\');
1516
+ console.error(' ANTHROPIC_API_KEY=dario \\');
1517
+ console.error(' <your command>');
1518
+ console.error('');
1519
+ console.error('See MIGRATION.md (v4 → v5) for details.');
1520
+ process.exit(1);
1595
1521
  }
1596
1522
  async function subagent() {
1597
1523
  const sub = args[1] ?? 'status';
@@ -82,10 +82,25 @@ export async function collectEffectiveConfig() {
82
82
  try {
83
83
  const { listAccountAliases } = await import('./accounts.js');
84
84
  const aliases = await listAccountAliases();
85
+ // Pool-as-primitive (v5.0): the pool is the one credential model. An empty
86
+ // accounts/ dir means either not-logged-in or a `dario login` whose
87
+ // credentials.json hasn't been back-filled into the pool yet (that happens
88
+ // on the next `dario login` / `dario proxy`), so report the pending pool-of-one.
89
+ let mode;
90
+ if (aliases.length > 0) {
91
+ mode = `pool of ${aliases.length}`;
92
+ }
93
+ else {
94
+ const { loadCredentials } = await import('./oauth.js');
95
+ const creds = await loadCredentials();
96
+ mode = creds?.claudeAiOauth?.accessToken
97
+ ? 'pool of 1 (login, not yet materialized)'
98
+ : 'empty (run `dario login`)';
99
+ }
85
100
  sections.push({
86
101
  title: 'Account pool',
87
102
  rows: [
88
- { label: 'mode', value: aliases.length === 0 ? 'single-account (no pool)' : `pool of ${aliases.length}` },
103
+ { label: 'mode', value: mode },
89
104
  ...(aliases.length > 0 ? [{ label: 'aliases', value: aliases.join(', ') }] : []),
90
105
  ],
91
106
  });
package/dist/doctor.d.ts CHANGED
@@ -70,7 +70,7 @@ export interface IdentityDriftInput {
70
70
  deviceId: string;
71
71
  accountUuid: string;
72
72
  } | null;
73
- /** Pool account snapshots — `[]` for single-account mode. */
73
+ /** Pool account snapshots — `[]` when no pool accounts are materialized yet. */
74
74
  poolAccounts: Array<{
75
75
  alias: string;
76
76
  deviceId: string;
package/dist/doctor.js CHANGED
@@ -104,7 +104,7 @@ export function checkIdentityDrift(input) {
104
104
  return [{
105
105
  status: 'info',
106
106
  label: 'Identity',
107
- detail: `~/.claude.json userID=${shortId(live.deviceId)} — single-account mode reads identity live per-request, so drift between the loaded bearer and ~/.claude.json only surfaces as 401 from Anthropic on non-Haiku models. Pool mode (\`dario accounts add\`) snapshots identity for drift detection.`,
107
+ detail: `~/.claude.json userID=${shortId(live.deviceId)} — no pool accounts snapshotted yet, so identity drift can't be checked. It starts once the login pool-of-one is materialized (\`dario login\` / \`dario proxy\`) or you \`dario accounts add\` more; until then a mismatch only surfaces as a 401 from Anthropic on non-Haiku models.`,
108
108
  }];
109
109
  }
110
110
  const aligned = [];
@@ -740,7 +740,17 @@ export async function runChecks(opts = {}) {
740
740
  const { listAccountAliases, loadAllAccounts } = await import('./accounts.js');
741
741
  const aliases = await listAccountAliases();
742
742
  if (aliases.length === 0) {
743
- checks.push({ status: 'info', label: 'Pool', detail: 'single-account mode — `dario accounts add <alias>` enables headroom-routed pool across multiple subscriptions' });
743
+ // Pool-as-primitive (v5.0): no accounts/ entries. Either not logged in,
744
+ // or a pre-v5 `dario login` whose credentials.json hasn't been back-filled
745
+ // into the pool yet — that happens on the next `dario login` / `dario proxy`.
746
+ const { loadCredentials } = await import('./oauth.js');
747
+ const creds = await loadCredentials();
748
+ if (creds?.claudeAiOauth?.accessToken) {
749
+ checks.push({ status: 'info', label: 'Pool', detail: 'pool of 1 (login credentials present, not yet materialized — runs on next `dario login` or `dario proxy`); `dario accounts add <alias>` adds more for headroom routing' });
750
+ }
751
+ else {
752
+ checks.push({ status: 'info', label: 'Pool', detail: 'empty — run `dario login` (a pool of one) or `dario accounts add <alias>`' });
753
+ }
744
754
  }
745
755
  else {
746
756
  const loaded = await loadAllAccounts();
@@ -749,9 +759,9 @@ export async function runChecks(opts = {}) {
749
759
  checks.push({
750
760
  status: expired > 0 ? 'warn' : 'ok',
751
761
  label: 'Pool',
752
- detail: `${aliases.length} account${aliases.length === 1 ? '' : 's'}` +
762
+ detail: `pool of ${aliases.length}` +
753
763
  (expired > 0 ? `, ${expired} expired` : '') +
754
- (aliases.length === 1 ? ' (pool active — add more to load-balance)' : ''),
764
+ (aliases.length === 1 ? ' (a pool of one `dario accounts add <alias>` to load-balance)' : ''),
755
765
  });
756
766
  // Next-account-in-rotation surfacing. The proxy's per-request
757
767
  // selector picks by max headroom (with 7d_<family> per-model
@@ -761,9 +771,9 @@ export async function runChecks(opts = {}) {
761
771
  // operators wondering "if I send a request right now, which
762
772
  // account gets it?" — it matches `pool.select()` with no family
763
773
  // hint, the same call the proxy uses when no model is parsed
764
- // yet (e.g. on misshapen requests). Bypassed when only one
765
- // account is loaded since "rotation" doesn't apply.
766
- if (aliases.length >= 2) {
774
+ // yet (e.g. on misshapen requests). Shown for a pool of one too
775
+ // (v5.0): it confirms the sole account is eligible, not rejected.
776
+ if (aliases.length >= 1) {
767
777
  try {
768
778
  const { AccountPool } = await import('./pool.js');
769
779
  const pool = new AccountPool();
@@ -41,9 +41,9 @@
41
41
  * provided both run on the same Node major. A cross-runtime worry
42
42
  * surfaces when Anthropic ships Bun- or bundled-binary CC: at that
43
43
  * point Node-dario and Bun-CC would JA-differ.
44
- * → Mitigation: detect Bun-compiled CC, fall back to shim mode
45
- * (which patches fetch INSIDE the CC process, inheriting CC's
46
- * own TLS stack for free).
44
+ * → Mitigation: dario auto-relaunches under Bun when it's on PATH so
45
+ * the proxy's ClientHello matches CC's Bun/BoringSSL shape;
46
+ * `--strict-tls` refuses to start otherwise.
47
47
  *
48
48
  * 3. HTTP/2 frame ordering + SETTINGS parameters. Similar to TLS, this
49
49
  * is controlled by the HTTP library. Node and undici produce a
@@ -115,8 +115,8 @@ export interface TemplateData {
115
115
  /**
116
116
  * The `anthropic-beta` flag set CC sent on the captured request, verbatim.
117
117
  * Schema v2 (v3.19). Previously the proxy path hardcoded this — bumping
118
- * CC's beta list required a dario release. Now the shim and proxy both
119
- * replay whatever the live capture recorded. Falls back to
118
+ * CC's beta list required a dario release. Now the proxy replays
119
+ * whatever the live capture recorded. Falls back to
120
120
  * `'claude-code-20250219'` when undefined (bundled snapshots, older caches).
121
121
  */
122
122
  anthropic_beta?: string;
@@ -236,9 +236,9 @@ export declare function probeInstalledCCVersion(): string | null;
236
236
  export declare function formatCaptureAge(capturedIso: string, now?: number): string;
237
237
  /**
238
238
  * One-line human summary of the active template — what source, which CC
239
- * version captured it, and how old that capture is. Proxy and shim
240
- * startup log this so users can tell at a glance whether they're on a
241
- * fresh live capture or a stale bundled fallback.
239
+ * version captured it, and how old that capture is. Proxy startup logs
240
+ * this so users can tell at a glance whether they're on a fresh live
241
+ * capture or a stale bundled fallback.
242
242
  */
243
243
  export declare function describeTemplate(t: TemplateData): string;
244
244
  export interface DriftResult {
@@ -41,9 +41,9 @@
41
41
  * provided both run on the same Node major. A cross-runtime worry
42
42
  * surfaces when Anthropic ships Bun- or bundled-binary CC: at that
43
43
  * point Node-dario and Bun-CC would JA-differ.
44
- * → Mitigation: detect Bun-compiled CC, fall back to shim mode
45
- * (which patches fetch INSIDE the CC process, inheriting CC's
46
- * own TLS stack for free).
44
+ * → Mitigation: dario auto-relaunches under Bun when it's on PATH so
45
+ * the proxy's ClientHello matches CC's Bun/BoringSSL shape;
46
+ * `--strict-tls` refuses to start otherwise.
47
47
  *
48
48
  * 3. HTTP/2 frame ordering + SETTINGS parameters. Similar to TLS, this
49
49
  * is controlled by the HTTP library. Node and undici produce a
@@ -735,9 +735,9 @@ export function formatCaptureAge(capturedIso, now = Date.now()) {
735
735
  }
736
736
  /**
737
737
  * One-line human summary of the active template — what source, which CC
738
- * version captured it, and how old that capture is. Proxy and shim
739
- * startup log this so users can tell at a glance whether they're on a
740
- * fresh live capture or a stale bundled fallback.
738
+ * version captured it, and how old that capture is. Proxy startup logs
739
+ * this so users can tell at a glance whether they're on a fresh live
740
+ * capture or a stale bundled fallback.
741
741
  */
742
742
  export function describeTemplate(t) {
743
743
  const source = t._source ?? 'bundled';
package/dist/proxy.d.ts CHANGED
@@ -463,17 +463,8 @@ export declare function describeAuthReject(headers: IncomingMessage['headers']):
463
463
  */
464
464
  export declare function upstreamAuthHeaders(upstreamApiKey: string, accessToken: string): Record<string, string>;
465
465
  /**
466
- * Whether the proxy routes through the account pool. Any entry in
467
- * `~/.dario/accounts/` activates the pool (#618)so a cold
468
- * `dario accounts add` bootstraps a servable proxy with no `dario login`
469
- * step — and admin mode always does (#599), where the pool may start empty
470
- * and be populated over HTTP. Login-only setups (no accounts/ entries) keep
471
- * the single-account credentials.json path. Pure + exported for unit
472
- * testing.
473
- */
474
- export declare function shouldUsePool(accountCount: number, adminEnabled: boolean): boolean;
475
- /**
476
- * Resolve the single-account startup auth outcome, refreshing an expired-but-
466
+ * Resolve the startup auth outcome when the pool is empty and there's a
467
+ * `dario login` credentials.json to fall back on refreshing an expired-but-
477
468
  * refreshable access token before giving up.
478
469
  *
479
470
  * The classic single-account startup used to read getStatus() once and, on any