🚀 Socket Launch Week Day 4:Socket MCP Adds Org Alerts, Threat Feed Review, and Package Inspection.Learn more
Sign In

@askalf/dario

Package Overview
Dependencies
Maintainers
1
Versions
293
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@askalf/dario - npm Package Compare versions

Comparing version
4.8.75
to
4.8.76
+28
-0
dist/analytics.d.ts

@@ -58,2 +58,30 @@ /**

export declare function billingBucketFromClaim(claim: string | null | undefined): BillingBucket;
/**
* The `representative-claim` values that mean "billed against the subscription
* pool" — the place dario exists to keep traffic. `five_hour`/`seven_day` and
* their server-side `_fallback` variants are all subscription billing (see
* `billingBucketFromClaim` + discussion #1). Anything else is either a
* non-subscription billing classification or the `unknown` sentinel below.
*/
export declare const SUBSCRIPTION_CLAIMS: ReadonlySet<string>;
/**
* The sentinel `claim` dario assigns when a response carried no rate-limit
* header at all (non-200s, stream aborts, early rejects — see `pool.ts`
* `parseRateLimits` / `EMPTY_SNAPSHOT`). It is NOT a billing classification,
* so the overage-guard must never halt on it.
*/
export declare const NO_BILLING_CLAIM = "unknown";
/**
* True when a claim represents real *non-subscription* billing — the
* condition the overage-guard halts on (see `overage-guard.ts`, #288).
*
* Deliberately an allow-list, not `claim === 'overage'`: it halts on anything
* that is NOT a known subscription claim AND NOT the `unknown` sentinel. That
* catches `overage` and `api` as before, but ALSO any new credit/SDK bucket
* string Anthropic introduces — e.g. the 2026-06-15 Agent-SDK/headless split,
* whose credit-bucket claim dario has never observed (it keeps traffic in the
* pool) and so cannot hardcode. `unknown` is exempt: halting on it would halt
* the proxy on every transient non-200/stream-abort.
*/
export declare function isNonSubscriptionBilling(claim: string | null | undefined): boolean;
export declare class Analytics extends EventEmitter {

@@ -60,0 +88,0 @@ private records;

@@ -40,2 +40,39 @@ /**

}
/**
* The `representative-claim` values that mean "billed against the subscription
* pool" — the place dario exists to keep traffic. `five_hour`/`seven_day` and
* their server-side `_fallback` variants are all subscription billing (see
* `billingBucketFromClaim` + discussion #1). Anything else is either a
* non-subscription billing classification or the `unknown` sentinel below.
*/
export const SUBSCRIPTION_CLAIMS = new Set([
'five_hour',
'seven_day',
'five_hour_fallback',
'seven_day_fallback',
]);
/**
* The sentinel `claim` dario assigns when a response carried no rate-limit
* header at all (non-200s, stream aborts, early rejects — see `pool.ts`
* `parseRateLimits` / `EMPTY_SNAPSHOT`). It is NOT a billing classification,
* so the overage-guard must never halt on it.
*/
export const NO_BILLING_CLAIM = 'unknown';
/**
* True when a claim represents real *non-subscription* billing — the
* condition the overage-guard halts on (see `overage-guard.ts`, #288).
*
* Deliberately an allow-list, not `claim === 'overage'`: it halts on anything
* that is NOT a known subscription claim AND NOT the `unknown` sentinel. That
* catches `overage` and `api` as before, but ALSO any new credit/SDK bucket
* string Anthropic introduces — e.g. the 2026-06-15 Agent-SDK/headless split,
* whose credit-bucket claim dario has never observed (it keeps traffic in the
* pool) and so cannot hardcode. `unknown` is exempt: halting on it would halt
* the proxy on every transient non-200/stream-abort.
*/
export function isNonSubscriptionBilling(claim) {
if (!claim || claim === NO_BILLING_CLAIM)
return false;
return !SUBSCRIPTION_CLAIMS.has(claim);
}
// Anthropic pricing (per 1M tokens, USD). Not authoritative — used for

@@ -42,0 +79,0 @@ // rough burn-rate display in the /analytics summary.

+20
-11
/**
* Overage-guard — halt the proxy on the first `representative-claim: overage`
* response to prevent silent API-rate bleed.
* Overage-guard — halt the proxy the first time a response bills to anything
* other than the subscription pool, to prevent silent API-rate bleed.
*
* Subscribers should never see a single overage hit during normal
* Subscribers should never see a single non-subscription hit during normal
* operation. One means something is wrong (wire-shape drift, classifier

@@ -12,7 +12,14 @@ * change, account misconfig, billing-flip after a CC release) and

* request emits a record carrying its `claim` (raw representative-claim
* value). When `claim === 'overage'` lands, the guard transitions to a
* halted state and emits a `'halt'` event. The HTTP request path checks
* `isHalted()` on every incoming request and returns 503 with an
* Anthropic-shaped error body when halted.
* value). When a non-subscription claim lands — `overage`, `api`, or any
* new credit/SDK-bucket string (the 2026-06-15 Agent-SDK split) — the guard
* transitions to a halted state and emits a `'halt'` event. The detection is
* an allow-list (`isNonSubscriptionBilling`): it fires on anything that is
* not a known subscription claim and not the `unknown` sentinel (which means
* "no rate-limit header" — a transient non-200/abort, not a billing flip).
* The HTTP request path checks `isHalted()` on every incoming request and
* returns 503 with an Anthropic-shaped error body when halted.
*
* The name predates the broadening (it caught only `overage` through v4.8.x,
* #288); the issue lineage + `dario_overage_guard` error type are kept stable.
*
* Resume paths:

@@ -30,3 +37,3 @@ * - explicit: `dario resume` CLI → POST /admin/resume → `clear('manual')`

import { EventEmitter } from 'node:events';
import type { Analytics, RequestRecord } from './analytics.js';
import { type Analytics, type RequestRecord } from './analytics.js';
export interface HaltState {

@@ -63,5 +70,7 @@ since: number;

/**
* Subscribe to an Analytics instance. Every record emitted with
* `claim === 'overage'` triggers halt (when behavior === 'halt') or a
* warn-only event (when behavior === 'warn').
* Subscribe to an Analytics instance. Every record whose claim is a
* non-subscription billing classification (`isNonSubscriptionBilling` —
* `overage`, `api`, or a new credit/SDK bucket) triggers halt (when
* behavior === 'halt') or a warn-only event (when behavior === 'warn').
* Subscription claims and the `unknown` sentinel are ignored.
*

@@ -68,0 +77,0 @@ * Idempotent — calling attach() a second time replaces the listener

/**
* Overage-guard — halt the proxy on the first `representative-claim: overage`
* response to prevent silent API-rate bleed.
* Overage-guard — halt the proxy the first time a response bills to anything
* other than the subscription pool, to prevent silent API-rate bleed.
*
* Subscribers should never see a single overage hit during normal
* Subscribers should never see a single non-subscription hit during normal
* operation. One means something is wrong (wire-shape drift, classifier

@@ -12,7 +12,14 @@ * change, account misconfig, billing-flip after a CC release) and

* request emits a record carrying its `claim` (raw representative-claim
* value). When `claim === 'overage'` lands, the guard transitions to a
* halted state and emits a `'halt'` event. The HTTP request path checks
* `isHalted()` on every incoming request and returns 503 with an
* Anthropic-shaped error body when halted.
* value). When a non-subscription claim lands — `overage`, `api`, or any
* new credit/SDK-bucket string (the 2026-06-15 Agent-SDK split) — the guard
* transitions to a halted state and emits a `'halt'` event. The detection is
* an allow-list (`isNonSubscriptionBilling`): it fires on anything that is
* not a known subscription claim and not the `unknown` sentinel (which means
* "no rate-limit header" — a transient non-200/abort, not a billing flip).
* The HTTP request path checks `isHalted()` on every incoming request and
* returns 503 with an Anthropic-shaped error body when halted.
*
* The name predates the broadening (it caught only `overage` through v4.8.x,
* #288); the issue lineage + `dario_overage_guard` error type are kept stable.
*
* Resume paths:

@@ -30,2 +37,3 @@ * - explicit: `dario resume` CLI → POST /admin/resume → `clear('manual')`

import { EventEmitter } from 'node:events';
import { isNonSubscriptionBilling } from './analytics.js';
export class OverageGuard extends EventEmitter {

@@ -44,5 +52,7 @@ opts;

/**
* Subscribe to an Analytics instance. Every record emitted with
* `claim === 'overage'` triggers halt (when behavior === 'halt') or a
* warn-only event (when behavior === 'warn').
* Subscribe to an Analytics instance. Every record whose claim is a
* non-subscription billing classification (`isNonSubscriptionBilling` —
* `overage`, `api`, or a new credit/SDK bucket) triggers halt (when
* behavior === 'halt') or a warn-only event (when behavior === 'warn').
* Subscription claims and the `unknown` sentinel are ignored.
*

@@ -63,3 +73,3 @@ * Idempotent — calling attach() a second time replaces the listener

this.analyticsListener = (r) => {
if (r.claim === 'overage') {
if (isNonSubscriptionBilling(r.claim)) {
this.onOverageDetected(r);

@@ -120,3 +130,3 @@ }

const title = this.opts.behavior === 'halt' ? 'dario halted' : 'dario warning';
const msg = `Request classified as 'overage' (per-token billing)${this.opts.behavior === 'halt' ? '. Proxy halted. Run `dario resume` to continue.' : ''}`;
const msg = `Request classified as '${r.claim}' (non-subscription billing)${this.opts.behavior === 'halt' ? '. Proxy halted. Run `dario resume` to continue.' : ''}`;
this.opts.notifier(title, msg);

@@ -188,8 +198,8 @@ }

message: `dario halted to prevent API-rate bleed. A request was classified ` +
`as 'overage' (per-token billing) instead of your subscription pool. ` +
`To resume: run \`dario resume\` in another terminal, or wait until ` +
`${isoCooldown} for the cooldown to auto-clear. ` +
`Details: github.com/askalf/dario/issues/288`,
`as '${state.request.claim}' (non-subscription billing) instead of ` +
`your subscription pool. To resume: run \`dario resume\` in another ` +
`terminal, or wait until ${isoCooldown} for the cooldown to ` +
`auto-clear. Details: github.com/askalf/dario/issues/288`,
},
};
}

@@ -324,7 +324,9 @@ import { type IncomingMessage } from 'node:http';

/**
* Overage-guard — halt the proxy on the first response carrying
* `representative-claim: overage`. Subscribers should never see a
* single overage hit during normal operation; one means something
* is wrong (wire-shape drift, classifier change, account misconfig)
* and continuing to forward bleeds against per-token billing.
* Overage-guard — halt the proxy on the first response that bills to
* anything other than the subscription pool (`overage`, `api`, or a new
* credit/SDK bucket — the 2026-06-15 split). Subscribers should never see
* a single non-subscription hit during normal operation; one means
* something is wrong (wire-shape drift, classifier change, account
* misconfig) and continuing to forward bleeds against per-token billing.
* Auto-disabled in upstream-API-key passthrough mode (see proxy setup).
*

@@ -331,0 +333,0 @@ * Default: enabled, halt behavior, 30-min cooldown, OS-notify on.

@@ -28,3 +28,3 @@ /**

import { renderKvRow } from '../layout.js';
import { billingBucketFromClaim } from '../../analytics.js';
import { billingBucketFromClaim, isNonSubscriptionBilling } from '../../analytics.js';
const MAX_BUFFER = 5000;

@@ -147,3 +147,3 @@ export const HitsTab = {

const cooldown = formatRemaining(state.halt.cooldownUntil - Date.now());
const line1 = ` ${fg('red', '⚠ HALTED')} overage detected at ${since} on ${state.halt.request.model} (account=${state.halt.request.account})`;
const line1 = ` ${fg('red', '⚠ HALTED')} ${state.halt.request.claim} detected at ${since} on ${state.halt.request.model} (account=${state.halt.request.account})`;
const line2 = ` ${dim('→ New /v1/messages requests return 503 until')} ${fg('cyan', 'R')} ${dim('here, or')} ${fg('cyan', 'dario resume')}${dim(' from any shell. Auto-resume in')} ${cooldown}${dim('.')}`;

@@ -163,5 +163,8 @@ lines.push(line1);

const r = newestFirst[i];
const isOverage = r.claim === 'overage';
// Flag any non-subscription billing red — the same condition the
// overage-guard halts on (overage, api, or a credit/SDK bucket), not
// just literal `overage`. See isNonSubscriptionBilling (#288).
const isNonSub = isNonSubscriptionBilling(r.claim);
const marker = i === state.selectedIdx ? fg('cyan', '▎')
: isOverage ? fg('red', '!')
: isNonSub ? fg('red', '!')
: ' ';

@@ -175,8 +178,8 @@ const row = marker + ' ' +

pad(formatStatus(r.status), colStatus);
// Overage rows render in red even when unselected; selection still
// wins via the inverse() wrapper so the user can drill into one.
// Non-subscription rows render in red even when unselected; selection
// still wins via the inverse() wrapper so the user can drill into one.
let styled;
if (i === state.selectedIdx)
styled = inverse(truncate(row, w - 2));
else if (isOverage)
else if (isNonSub)
styled = fg('red', truncate(row, w - 2));

@@ -183,0 +186,0 @@ else

@@ -118,3 +118,3 @@ /**

// Red banner header — this is the loud surface when halted
lines.push(' ' + fg('red', '⚠ HALTED') + ' ' + dim(`overage detected ${formatAgo(s.since)} ago`));
lines.push(' ' + fg('red', '⚠ HALTED') + ' ' + dim(`${s.request.claim} detected ${formatAgo(s.since)} ago`));
lines.push(' ' + renderKvRow('Request', `${s.request.model} ${dim('account=' + s.request.account)}`, w - 4));

@@ -121,0 +121,0 @@ lines.push(' ' + renderKvRow('Cause', `representative-claim = ${fg('red', s.request.claim)}`, w - 4));

{
"name": "@askalf/dario",
"version": "4.8.75",
"version": "4.8.76",
"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,0 +5,0 @@ "type": "module",

+18
-17

@@ -203,5 +203,5 @@ <p align="center">

A subscriber should never see a single `representative-claim: overage` response during normal operation. One means something is wrong — wire-shape drift, a classifier change, an account misconfig — and continuing to forward requests in the same shape bleeds real money (accounts with extra-usage enabled) or returns a wall of rejections (accounts without it). The first hit is the signal; the second through hundredth are damage.
A subscriber should never see a single response billed outside their subscription pool during normal operation. One means something is wrong — wire-shape drift, a classifier change, an account misconfig — and continuing to forward requests in the same shape bleeds real money (accounts with extra-usage enabled) or returns a wall of rejections (accounts without it). The first hit is the signal; the second through hundredth are damage.
So the moment any upstream response carries `representative-claim: overage`, dario **halts the proxy**. Every subsequent request returns `503` with an Anthropic-shaped error body the client surfaces verbatim, until you run `dario resume`, press `R` on the TUI, or the cooldown clears (default 30 min). The halt is visible across the TUI's Status, Hits, and Analytics tabs, fires a best-effort native OS notification, and emits named SSE events.
So the moment any upstream response bills to something other than your subscription pool — `representative-claim: overage`, `api`, or a new credit/SDK bucket like the one the 2026-06-15 Agent-SDK split introduces — dario **halts the proxy**. The check is an allow-list, not a match on `overage`: anything that isn't a known subscription claim (`five_hour`/`seven_day` and their fallbacks) and isn't the `unknown` no-header sentinel trips it, so a credit-bucket claim dario has never seen still halts. Every subsequent request returns `503` with an Anthropic-shaped error body the client surfaces verbatim, until you run `dario resume`, press `R` on the TUI, or the cooldown clears (default 30 min). The halt is visible across the TUI's Status, Hits, and Analytics tabs, fires a best-effort native OS notification, and emits named SSE events. (In `--upstream-api-key` passthrough mode the guard is off — `api` billing is the point there, not a failure.)

@@ -372,24 +372,25 @@ ```

## Also by askalf
## Own Your Stack
| Project | What it does |
dario is the routing layer of **[Own Your Stack](https://github.com/askalf)** — open tools for owning your AI infrastructure instead of renting it by the token. One subscription. Your box. Your terms.
| Tool | |
|---|---|
| [askalf platform](https://askalf.org) | Self-hosted AI workforce — agents that run real business + life work. Uses dario as its LLM substrate. *Early access at [askalf.org](https://askalf.org).* |
| [hands](https://github.com/askalf/hands) | Cross-platform computer-use agent — your LLM on your mouse, keyboard, and screen. Routes through dario or any Anthropic-compat. |
| [deepdive](https://github.com/askalf/deepdive) | Local research agent. One command, cited answer. Plan → search → headless fetch → extract → synthesize. |
| [agent](https://github.com/askalf/agent) | Connect any device to an askalf fleet — runs the shell or Claude Code tasks the fleet dispatches. |
| [browser-bridge](https://github.com/askalf/browser-bridge) | Stealth headless Chromium in a container, CDP on 9222. Playwright / Puppeteer / MCP-compatible. |
| [claude-sync](https://github.com/askalf/claude-sync) | Sync Claude Code sessions across machines via a portable `.ccsync` file. |
| [pgflex](https://github.com/askalf/pgflex) | One Postgres API, two modes — real PostgreSQL for production, PGlite (WASM) for dev. |
| [redisflex](https://github.com/askalf/redisflex) | One Redis API, two modes — ioredis for production, in-process for dev. Includes a BullMQ-shaped in-memory queue. |
| **[dario](https://github.com/askalf/dario)** | own your routing — your subscription, in any tool *(you are here)* |
| **[deepdive](https://github.com/askalf/deepdive)** | own your research — local agent, cited answers |
| **[hands](https://github.com/askalf/hands)** | own your computer-use — your LLM on your own mouse & keyboard |
| **[agent](https://github.com/askalf/agent)** | own your fleet — connect any device, dispatch real work |
| **[browser-bridge](https://github.com/askalf/browser-bridge)** | own your browser — stealth headless Chromium, your CDP endpoint |
| **[claude-sync](https://github.com/askalf/claude-sync)** | own your sessions — sync Claude Code across machines |
| **[askalf platform](https://askalf.org)** | own your operation — the self-hosted AI workforce, running on this stack |
---
## Built by Sprayberry Labs
## Built by Thomas Sprayberry
This is one of the open-source building blocks from **[Sprayberry Labs](https://sprayberrylabs.com)** — an independent studio (Atlanta, GA) that ships bespoke software and **fixed-price code & security audits**, delivered with the AI workforce these tools are part of.
dario is part of **Own Your Stack** — the open toolkit behind **[Sprayberry Labs](https://sprayberrylabs.com)**, an independent studio (Atlanta, GA) that ships bespoke software with the autonomous AI workforce these tools are part of.
Part of the [askalf](https://askalf.org) ecosystem — a self-hosted AI workforce platform, now in early access.
Built in the open, scars included. Follow the build → **[@ask_alf](https://x.com/ask_alf)** · **[sprayberrylabs.com/own-your-stack](https://sprayberrylabs.com/own-your-stack)**
**Got a codebase that needs an expert read?** → **[Scan a repo — free mini-audit](https://sprayberrylabs.com)**, or see the **$1,500 fixed-price Audit** and build Sprints. · [sprayberrylabs.com](https://sprayberrylabs.com) · hello@sprayberrylabs.com
---
Part of **[Own Your Stack](https://github.com/askalf)** — own your AI infrastructure instead of renting it. Built by Thomas Sprayberry.

Sorry, the diff of this file is too big to display