@askalf/dario 5.4.13 → 5.4.14

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/README.md CHANGED
@@ -186,7 +186,7 @@ Guarded by a PR-time compat gate that runs the full suite against a live proxy b
186
186
  |---|---|---|
187
187
  | `context-1m` dropped from the default beta set on the OAuth path | Subscription requests default to the 200K window on Sonnet/Opus | v3.38.3–4 |
188
188
  | `thinking: {type:"adaptive"}` gated per-model server-side | Sonnet/Opus 4-5 400 every request through any proxy | [v3.38.5](https://github.com/askalf/dario/pull/273) |
189
- | Per-model `anthropic-beta` sets (opus 9, sonnet 8, haiku 6) | Proxies sending one set diverge for non-opus models | [v4.8.53](https://github.com/askalf/dario/pull/478) |
189
+ | Per-model `anthropic-beta` sets (opus 10, sonnet 9, haiku 6 — they track the baked base, so counts shift when CC's set does) | Proxies sending one set diverge for non-opus models | [v4.8.53](https://github.com/askalf/dario/pull/478) |
190
190
 
191
191
  The full ledger lives in the [CHANGELOG](CHANGELOG.md). Setup + walkthrough: [`docs/drift-monitor.md`](./docs/drift-monitor.md). Residual manual cases — OAuth rotation, runner re-registration — are in the [recovery runbook](./docs/recovery.md).
192
192
 
@@ -218,11 +218,11 @@ The split isn't live, but it was announced once on short notice and could return
218
218
 
219
219
  | Signal | Status |
220
220
  |---|---|
221
- | Source | **~22k** lines of TypeScript across **49** files — auditable in a weekend (v5 removed shim; the pool is the one code path) |
221
+ | Source | **~24k** lines of TypeScript across **52** files — auditable in a weekend (v5 removed shim; the pool is the one code path) |
222
222
  | Dependencies | **0 runtime.** Verify: `npm ls --production` |
223
223
  | Provenance | Every release [SLSA-attested](https://www.npmjs.com/package/@askalf/dario) via GitHub Actions + Sigstore |
224
224
  | Scanning | [CodeQL](https://github.com/askalf/dario/actions/workflows/codeql.yml) on every push and weekly |
225
- | Tests | **113 test files** run in parallel by `test/all.test.mjs` — green on every release |
225
+ | Tests | **132 test files**, 125 run in parallel by `test/all.test.mjs` (e2e / compat / stealth opt out and have their own entry points) — green on every release |
226
226
  | Credentials | Your own subscription tokens, never logged, redacted from errors, `0600` on disk in `0700` dirs |
227
227
  | Network | Binds `127.0.0.1` by default; upstream only to configured backends over HTTPS; hardcoded SSRF allow-list |
228
228
  | Telemetry | **None.** No analytics, no tracking, nothing phones home |
@@ -253,7 +253,7 @@ dario uses your own subscription credentials, authenticates you as you, and impe
253
253
 
254
254
  `dario` (TUI) · `login` · `proxy` · `doctor` · `accounts {list,add,remove}` · `backend {list,add,remove}` · `mcp` · `subagent {install,status,remove}` · `usage` · `config` · `upgrade` · `status` · `refresh` · `resume` · `logout` · `help`
255
255
 
256
- Full flag/env reference: [`docs/commands.md`](./docs/commands.md) · SDK examples + per-tool setup: [`docs/usage.md`](./docs/usage.md)
256
+ Per-flag reference: [`docs/commands.md`](./docs/commands.md) · env vars grouped by task, for Docker / k8s / systemd: [`docs/configuration.md`](./docs/configuration.md) · SDK examples + per-tool setup: [`docs/usage.md`](./docs/usage.md)
257
257
 
258
258
  ---
259
259
 
@@ -299,10 +299,21 @@ PRs welcome. Small TypeScript codebase, zero runtime deps. Architecture + file-b
299
299
  git clone https://github.com/askalf/dario && cd dario
300
300
  npm install
301
301
  npm run dev # tsx, no build step
302
- npm test # 113 test files via test/all.test.mjs
302
+ npm test # 125 suites in parallel via test/all.test.mjs
303
303
  npm run e2e # live proxy + OAuth (needs a working Claude backend)
304
304
  ```
305
305
 
306
+ Drift and audit runners, none of them part of `npm test`:
307
+
308
+ ```bash
309
+ npm run drift:wire # compare a live CC capture against the baked template
310
+ npm run drift:sdk # Agent-SDK / Stainless pin drift
311
+ npm run audit:tui # drives the real TUI through a fake TTY at 12 geometries
312
+ npm run check:overage # overage-classifier check against live headers
313
+ npm run stress # concurrency / queue behaviour under load
314
+ npm run cch:calibrate # re-derive the billing-tag cch seed for a new CC build
315
+ ```
316
+
306
317
  Two easy ways to help beyond code: **star the repo** (the clearest signal this is useful), and **file drift** — open an issue when a rate-limit header flips or a tool that worked yesterday breaks today, and it gets documented in public alongside the fix. Follow [@ask_alf](https://x.com/ask_alf) for drift bulletins as they land.
307
318
 
308
319
  ### Contributors
package/dist/cli.d.ts CHANGED
@@ -69,6 +69,25 @@ export declare function resolveEffortFlag(args: string[], env: string | undefine
69
69
  * dario#80 queue env mirrors.
70
70
  */
71
71
  export declare function parsePositiveIntEnv(value: string | undefined): number | undefined;
72
+ /**
73
+ * Parse a boolean env var that has to be able to say NO.
74
+ *
75
+ * `parseBooleanEnv` returns true|undefined and never false. That is correct
76
+ * for a knob whose default is off and whose env mirror is read with `||` --
77
+ * false and undefined behave identically there, and its truthy-only contract
78
+ * is pinned by test/strict-template-flags.mjs.
79
+ *
80
+ * It is wrong for a knob that defaults ON and is read with
81
+ * `flag ?? env ?? fileCfg ?? true`: undefined falls straight through to the
82
+ * default, so `DARIO_OVERAGE_GUARD=off` left the guard enabled while the
83
+ * comment above claimed it was the equivalent of --no-overage-guard. Silent,
84
+ * and worst for the container users who have no flag to pass instead.
85
+ *
86
+ * Returns false for off/0/false/no, true for on/1/true/yes, undefined for
87
+ * unset or unrecognised — so an unreadable value still defers to the config
88
+ * file and the default rather than guessing.
89
+ */
90
+ export declare function parseTriStateEnv(value: string | undefined): boolean | undefined;
72
91
  /**
73
92
  * Parse a boolean env var. Accepts "1", "true", "yes", "on" (case-insensitive)
74
93
  * as truthy; everything else (including unset) is undefined/false. Exported
package/dist/cli.js CHANGED
@@ -569,13 +569,15 @@ async function proxy() {
569
569
  // --overage-behavior=halt|warn → halt (default) or warn-only (no 503)
570
570
  // --overage-cooldown=<MS> → auto-resume after this delay (default 30 min)
571
571
  // --no-overage-notify → suppress OS-level desktop notification
572
- // DARIO_OVERAGE_GUARD=off → env equivalent of --no-overage-guard
572
+ // DARIO_OVERAGE_GUARD=off|0|false|no → env equivalent of --no-overage-guard
573
573
  // DARIO_OVERAGE_BEHAVIOR=halt|warn → env equivalent of --overage-behavior
574
574
  // DARIO_OVERAGE_COOLDOWN=<MS> → env equivalent of --overage-cooldown
575
- // DARIO_OVERAGE_NOTIFY=off → env equivalent of --no-overage-notify
575
+ // DARIO_OVERAGE_NOTIFY=off|0|false|no → env equivalent of --no-overage-notify
576
576
  const overageGuardEnabledFromFlag = args.includes('--no-overage-guard') ? false
577
577
  : args.includes('--overage-guard') ? true : undefined;
578
- const overageGuardEnabledFromEnv = parseBooleanEnv(process.env['DARIO_OVERAGE_GUARD']);
578
+ // Tri-state: this chain defaults to true, so `=off` must yield false rather
579
+ // than undefined or it is silently ignored.
580
+ const overageGuardEnabledFromEnv = parseTriStateEnv(process.env['DARIO_OVERAGE_GUARD']);
579
581
  const overageGuardEnabled = overageGuardEnabledFromFlag
580
582
  ?? overageGuardEnabledFromEnv
581
583
  ?? fileCfg.overageGuard?.enabled
@@ -591,7 +593,7 @@ async function proxy() {
591
593
  ?? fileCfg.overageGuard?.cooldownMs
592
594
  ?? 30 * 60 * 1000;
593
595
  const overageNotifyFromFlag = args.includes('--no-overage-notify') ? false : undefined;
594
- const overageNotifyFromEnv = parseBooleanEnv(process.env['DARIO_OVERAGE_NOTIFY']);
596
+ const overageNotifyFromEnv = parseTriStateEnv(process.env['DARIO_OVERAGE_NOTIFY']);
595
597
  const overageGuardNotifyOs = overageNotifyFromFlag
596
598
  ?? overageNotifyFromEnv
597
599
  ?? fileCfg.overageGuard?.notifyOs
@@ -795,6 +797,34 @@ export function parsePositiveIntEnv(value) {
795
797
  return undefined;
796
798
  return n;
797
799
  }
800
+ /**
801
+ * Parse a boolean env var that has to be able to say NO.
802
+ *
803
+ * `parseBooleanEnv` returns true|undefined and never false. That is correct
804
+ * for a knob whose default is off and whose env mirror is read with `||` --
805
+ * false and undefined behave identically there, and its truthy-only contract
806
+ * is pinned by test/strict-template-flags.mjs.
807
+ *
808
+ * It is wrong for a knob that defaults ON and is read with
809
+ * `flag ?? env ?? fileCfg ?? true`: undefined falls straight through to the
810
+ * default, so `DARIO_OVERAGE_GUARD=off` left the guard enabled while the
811
+ * comment above claimed it was the equivalent of --no-overage-guard. Silent,
812
+ * and worst for the container users who have no flag to pass instead.
813
+ *
814
+ * Returns false for off/0/false/no, true for on/1/true/yes, undefined for
815
+ * unset or unrecognised — so an unreadable value still defers to the config
816
+ * file and the default rather than guessing.
817
+ */
818
+ export function parseTriStateEnv(value) {
819
+ if (value === undefined)
820
+ return undefined;
821
+ const normalized = value.trim().toLowerCase();
822
+ if (normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on')
823
+ return true;
824
+ if (normalized === '0' || normalized === 'false' || normalized === 'no' || normalized === 'off')
825
+ return false;
826
+ return undefined;
827
+ }
798
828
  /**
799
829
  * Parse a boolean env var. Accepts "1", "true", "yes", "on" (case-insensitive)
800
830
  * as truthy; everything else (including unset) is undefined/false. Exported
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "5.4.13",
3
+ "version": "5.4.14",
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": {