@askalf/dario 3.2.1 → 3.2.3

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
@@ -33,7 +33,7 @@ export ANTHROPIC_BASE_URL=http://localhost:3456 # or OPENAI_BASE_URL=http://lo
33
33
  export ANTHROPIC_API_KEY=dario # or OPENAI_API_KEY=dario
34
34
  ```
35
35
 
36
- Opus, Sonnet, Haiku — all models, streaming, tool use. **Zero dependencies.** ~1,900 lines of TypeScript. Works with Cursor, Continue, Aider, LiteLLM, Hermes, OpenClaw, or any tool that speaks the Anthropic or OpenAI API. When rate limited, `--cli` routes through Claude Code for uninterrupted Opus access.
36
+ Opus, Sonnet, Haiku — all models, streaming, tool use. **Zero dependencies.** ~2,100 lines of TypeScript. Works with Cursor, Continue, Aider, LiteLLM, Hermes, OpenClaw, or any tool that speaks the Anthropic or OpenAI API. When rate limited, `--cli` routes through Claude Code for uninterrupted Opus access. Auto-launches under [Bun](https://bun.sh) when available for TLS fingerprint fidelity.
37
37
 
38
38
  <table>
39
39
  <tr>
@@ -80,7 +80,7 @@ Opus, Sonnet, Haiku — all models, streaming, tool use. **Zero dependencies.**
80
80
 
81
81
  Most Claude subscription proxies have a critical billing problem: **Anthropic classifies their requests as third-party and routes all usage to Extra Usage billing** — even when you have Max plan limits available. You're paying for your subscription twice.
82
82
 
83
- dario is the only proxy that solves this. Instead of transforming your requests signal by signal, dario v3.0 uses **template replay** — it replaces the entire request with Claude Code's exact template. CC's tool definitions, CC's field structure, CC's parameters. Only your conversation content is preserved. Anthropic's classifier sees a genuine Claude Code request because it IS one.
83
+ dario is the only proxy that solves this. Instead of transforming your requests signal by signal, dario uses **template replay** — it replaces the entire request with Claude Code's exact template, extracted via MITM capture from CC v2.1.104. 25 tool definitions, 25KB system prompt, exact field order, exact beta headers, exact metadata structure. Only your conversation content is preserved. When Bun is installed, dario auto-relaunches under Bun for TLS fingerprint fidelity matching CC's runtime. Anthropic's classifier sees a genuine Claude Code request because it IS one.
84
84
 
85
85
  | | dario | Other proxies |
86
86
  |---|---|---|
@@ -101,7 +101,7 @@ dario is the only proxy that solves this. Instead of transforming your requests
101
101
  | OpenAI API compat | **Yes** | Yes | Yes |
102
102
  | Orchestration sanitization | **Yes** | Yes | No |
103
103
  | Token anomaly detection | **Yes** | Yes | No |
104
- | Codebase size | ~1,900 lines | ~9,000 lines | Platform |
104
+ | Codebase size | ~2,100 lines | ~9,000 lines | Platform |
105
105
  | Dependencies | 0 | Many | Many |
106
106
  | Setup | 2 commands | Config + build | Config + dashboard |
107
107
 
@@ -450,12 +450,17 @@ Your app sends whatever it wants — any tools, any parameters. dario replaces t
450
450
  | `--port=PORT` | Port to listen on | `3456` |
451
451
  | `--verbose` / `-v` | Log every request | off |
452
452
  | `DARIO_API_KEY` | If set, all endpoints (except `/health`) require matching `x-api-key` header or `Authorization: Bearer` header | unset (open) |
453
+ | `DARIO_NO_BUN` | Disable automatic Bun relaunch (stay on Node.js) | unset |
454
+ | `DARIO_MIN_INTERVAL_MS` | Minimum ms between requests (rate governor) | `500` |
453
455
 
454
456
  ## Supported Features
455
457
 
456
458
  ### Direct API Mode
457
459
  - All Claude models (Opus 4.6, Sonnet 4.6, Haiku 4.5) + 1M extended context aliases (`opus1m`, `sonnet1m`)
458
- - **Template replay** (v3.0) — replaces the entire request with Claude Code's exact template. CC's tool definitions, field structure, and parameters are sent upstream. Only your conversation content is preserved. Your client's tools are mapped to CC equivalents and reverse-mapped in responses. Tested with 40 third-party tools all route to `five_hour`. See [Discussion 13](https://github.com/askalf/dario/discussions/13) and [Discussion 14](https://github.com/askalf/dario/discussions/14).
460
+ - **Template replay** (v3.0+) — replaces the entire request with Claude Code's exact template, extracted via MITM capture from CC v2.1.104. 25 tool definitions, 25KB system prompt, exact body key order, exact beta headers (model-conditional), exact metadata structure. Client tools are mapped to CC equivalents and reverse-mapped in responses. Template data stored as JSON for easy updates. See [Discussion 13](https://github.com/askalf/dario/discussions/13) and [Discussion 14](https://github.com/askalf/dario/discussions/14).
461
+ - **Bun auto-relaunch** (v3.2) — auto-detects Bun and relaunches under it for TLS fingerprint fidelity. CC runs on Bun; Node.js has a different TLS fingerprint visible at the network level.
462
+ - **Session ID rotation** (v3.2) — each request gets a fresh session ID, matching CC `--print` behavior.
463
+ - **Rate governor** (v3.2) — 500ms minimum interval between requests prevents inhuman cadence. Configurable via `DARIO_MIN_INTERVAL_MS`.
459
464
  - **Enriched 429 errors** — rate limit errors include utilization %, limiting window, and reset time instead of Anthropic's default `"Error"` message
460
465
  - **Auto CLI fallback** — if the API returns 429 and Claude Code is installed, transparently retries through `claude --print` with SSE conversion
461
466
  - **OpenAI-compatible** (`/v1/chat/completions`) — works with any OpenAI SDK or tool
@@ -535,6 +540,18 @@ Should work if your plan includes Claude Code access. Not tested yet — please
535
540
  **Do I need Claude Code installed?**
536
541
  Recommended but not required. If Claude Code is installed and logged in, `dario login` picks up your credentials automatically. Without Claude Code, dario runs its own OAuth flow to authenticate directly. Note: `--cli` mode requires Claude Code (`npm install -g @anthropic-ai/claude-code`).
537
542
 
543
+ **First time setup — account priming**
544
+ If dario is the first thing you use with a new Claude account, run a few real Claude Code commands first to establish a session baseline:
545
+ ```bash
546
+ claude --print "hello"
547
+ claude --print "hello"
548
+ claude --print "hello"
549
+ ```
550
+ This primes the account with legitimate Claude Code sessions. Then start dario normally. Without priming, new accounts may see billing classification issues on first use.
551
+
552
+ **Do I need Bun installed?**
553
+ Optional but recommended. If [Bun](https://bun.sh) is installed, dario auto-relaunches under it for TLS fingerprint fidelity with Claude Code's runtime. Without Bun, dario runs on Node.js and works fine — the TLS fingerprint is the only difference. Install Bun: `curl -fsSL https://bun.sh/install | bash`
554
+
538
555
  **What happens when my token expires?**
539
556
  Dario auto-refreshes tokens 30 minutes before expiry. You should never see an auth error in normal use. If something goes wrong, `dario refresh` forces an immediate refresh.
540
557
 
@@ -580,7 +597,7 @@ Dario handles your OAuth tokens. Here's why you can trust it:
580
597
 
581
598
  | Signal | Status |
582
599
  |--------|--------|
583
- | **Source code** | ~1,900 lines of TypeScript — small enough to audit in one sitting |
600
+ | **Source code** | ~2,100 lines of TypeScript — small enough to audit in one sitting |
584
601
  | **Dependencies** | 0 runtime dependencies. Verify: `npm ls --production` |
585
602
  | **npm provenance** | Every release is [SLSA attested](https://www.npmjs.com/package/@askalf/dario) via GitHub Actions |
586
603
  | **Security scanning** | [CodeQL](https://github.com/askalf/dario/actions/workflows/codeql.yml) runs on every push and weekly |
@@ -612,14 +629,15 @@ cd $(npm root -g)/@askalf/dario && npm ls --production
612
629
 
613
630
  ## Contributing
614
631
 
615
- PRs welcome. The codebase is ~1,900 lines of TypeScript across 5 files:
632
+ PRs welcome. The codebase is ~2,100 lines of TypeScript across 5 files:
616
633
 
617
634
  | File | Purpose |
618
635
  |------|---------|
619
- | `src/proxy.ts` | HTTP proxy server + CLI backend |
620
- | `src/cc-template.ts` | Claude Code request template + tool mapping |
636
+ | `src/proxy.ts` | HTTP proxy server, CLI backend, rate governor |
637
+ | `src/cc-template.ts` | CC template engine + tool mapping |
638
+ | `src/cc-template-data.json` | MITM-extracted CC data (25 tools, 25KB system prompt) |
621
639
  | `src/oauth.ts` | Token storage, refresh, credential detection |
622
- | `src/cli.ts` | CLI entry point |
640
+ | `src/cli.ts` | CLI entry point + Bun auto-relaunch |
623
641
  | `src/index.ts` | Library exports |
624
642
 
625
643
  ```bash
package/dist/proxy.js CHANGED
@@ -731,12 +731,9 @@ export async function startProxy(opts = {}) {
731
731
  beta += ',' + clientBeta;
732
732
  }
733
733
  else {
734
- // CC v2.1.104 beta set — context-1m only for Sonnet 4.6 (CC gates it via feature flag)
735
- const baseBetas = 'claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,advisor-tool-2026-03-01,effort-2025-11-24';
736
- const isSonnet46 = requestModel.includes('sonnet-4-6') || requestModel.includes('sonnet46');
737
- beta = isSonnet46
738
- ? 'claude-code-20250219,oauth-2025-04-20,context-1m-2025-08-07,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,advisor-tool-2026-03-01,effort-2025-11-24'
739
- : baseBetas;
734
+ // CC v2.1.104 beta set — context-1m excluded (requires Extra Usage enabled,
735
+ // CC only adds it via coral_reef_sonnet feature flag which most accounts don't have)
736
+ beta = 'claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,advisor-tool-2026-03-01,effort-2025-11-24';
740
737
  if (clientBeta) {
741
738
  const baseSet = new Set(beta.split(','));
742
739
  const filtered = filterBillableBetas(clientBeta)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "3.2.1",
3
+ "version": "3.2.3",
4
4
  "description": "Use your Claude subscription as an API. No API key needed. Local proxy for Claude Max/Pro subscriptions.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -61,4 +61,4 @@
61
61
  "tsx": "^4.19.0",
62
62
  "typescript": "^5.7.0"
63
63
  }
64
- }
64
+ }