@askalf/dario 4.8.102 → 4.8.104

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.
@@ -118,7 +118,18 @@ export declare class Analytics extends EventEmitter {
118
118
  private computeStats;
119
119
  private perAccountStats;
120
120
  private perModelStats;
121
- private utilizationTrend;
121
+ /**
122
+ * The most recent rate-limit snapshot in the window — current 5h / 7d
123
+ * utilization (0–1) as of the last request. The Analytics tab's rate-limit
124
+ * gauge reads this; an empty window reads 0/0. Mirrors `perAccountStats`'
125
+ * `last.util*` "current" semantics.
126
+ *
127
+ * Replaces the old per-5-min-bucket `utilizationTrend` array: the TUI gauge
128
+ * (the only consumer of `summary.utilization`) reads `.lastUtil5h` /
129
+ * `.lastUtil7d`, which on the array shape were `undefined` → rendered NaN%.
130
+ * See #600.
131
+ */
132
+ private currentUtilization;
122
133
  private predict;
123
134
  }
124
135
  interface PerAccountStat {
@@ -164,12 +175,11 @@ export interface AnalyticsSummary {
164
175
  };
165
176
  perAccount: Record<string, PerAccountStat>;
166
177
  perModel: Record<string, PerModelStat>;
167
- utilization: Array<{
168
- timestamp: number;
169
- avgUtil5h: number;
170
- avgUtil7d: number;
171
- requests: number;
172
- }>;
178
+ /** Current 5h / 7d rate-limit utilization (0–1) as of the last request. */
179
+ utilization: {
180
+ lastUtil5h: number;
181
+ lastUtil7d: number;
182
+ };
173
183
  predictions: {
174
184
  estimatedExhaustionMinutes: number | null;
175
185
  tokenBurnRate: number;
package/dist/analytics.js CHANGED
@@ -175,7 +175,7 @@ export class Analytics extends EventEmitter {
175
175
  },
176
176
  perAccount: this.perAccountStats(recent),
177
177
  perModel: this.perModelStats(recent),
178
- utilization: this.utilizationTrend(recent),
178
+ utilization: this.currentUtilization(recent),
179
179
  predictions: this.predict(recent),
180
180
  };
181
181
  }
@@ -267,29 +267,22 @@ export class Analytics extends EventEmitter {
267
267
  }
268
268
  return result;
269
269
  }
270
- utilizationTrend(records) {
270
+ /**
271
+ * The most recent rate-limit snapshot in the window — current 5h / 7d
272
+ * utilization (0–1) as of the last request. The Analytics tab's rate-limit
273
+ * gauge reads this; an empty window reads 0/0. Mirrors `perAccountStats`'
274
+ * `last.util*` "current" semantics.
275
+ *
276
+ * Replaces the old per-5-min-bucket `utilizationTrend` array: the TUI gauge
277
+ * (the only consumer of `summary.utilization`) reads `.lastUtil5h` /
278
+ * `.lastUtil7d`, which on the array shape were `undefined` → rendered NaN%.
279
+ * See #600.
280
+ */
281
+ currentUtilization(records) {
271
282
  if (records.length === 0)
272
- return [];
273
- const bucketMs = 5 * 60_000;
274
- const buckets = new Map();
275
- for (const r of records) {
276
- const key = Math.floor(r.timestamp / bucketMs) * bucketMs;
277
- const existing = buckets.get(key);
278
- if (existing) {
279
- existing.push(r);
280
- }
281
- else {
282
- buckets.set(key, [r]);
283
- }
284
- }
285
- return [...buckets.entries()]
286
- .sort(([a], [b]) => a - b)
287
- .map(([ts, recs]) => ({
288
- timestamp: ts,
289
- avgUtil5h: Math.round(recs.reduce((s, r) => s + r.util5h, 0) / recs.length * 100) / 100,
290
- avgUtil7d: Math.round(recs.reduce((s, r) => s + r.util7d, 0) / recs.length * 100) / 100,
291
- requests: recs.length,
292
- }));
283
+ return { lastUtil5h: 0, lastUtil7d: 0 };
284
+ const last = records[records.length - 1];
285
+ return { lastUtil5h: last.util5h, lastUtil7d: last.util7d };
293
286
  }
294
287
  predict(records) {
295
288
  if (records.length < 3) {
@@ -1,6 +1,6 @@
1
1
  {
2
- "_version": "2.1.195",
3
- "_captured": "2026-06-24T06:27:30.671Z",
2
+ "_version": "2.1.196",
3
+ "_captured": "2026-06-30T06:36:26.548Z",
4
4
  "_source": "bundled",
5
5
  "_schemaVersion": 3,
6
6
  "agent_identity": "You are a Claude agent, built on Anthropic's Claude Agent SDK.",
@@ -711,7 +711,7 @@
711
711
  },
712
712
  {
713
713
  "name": "Monitor",
714
- "description": "Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** (\"tell me when the server is ready / the build finishes\") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q \"Ready in\" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.\n- **One per occurrence, indefinitely** (\"tell me every time an ERROR line appears\") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).\n- **One per occurrence, until a known end** (\"emit each CI step result, stop when the run completes\") → Monitor with a command that emits lines and then exits.\n\nYour script's stdout is the event stream. Each line becomes a notification. Exit ends the watch.\n\n # Each matching log line is an event\n tail -f /var/log/app.log | grep --line-buffered \"ERROR\"\n\n # Each file change is an event\n inotifywait -m --format '%e %f' /watched/dir\n\n # Poll GitHub for new PR comments and emit one line per new comment\n last=$(date -u +%Y-%m-%dT%H:%M:%SZ)\n while true; do\n now=$(date -u +%Y-%m-%dT%H:%M:%SZ)\n gh api \"repos/owner/repo/issues/123/comments?since=$last\" --jq '.[] | \"\\(.user.login): \\(.body)\"'\n last=$now; sleep 30\n done\n\n # Node script that emits events as they arrive (e.g. WebSocket listener)\n node watch-for-events.js\n\n # Per-occurrence with a natural end: emit each CI check as it lands, exit when the run completes\n prev=\"\"\n while true; do\n s=$(gh pr checks 123 --json name,bucket)\n cur=$(jq -r '.[] | select(.bucket!=\"pending\") | \"\\(.name): \\(.bucket)\"' <<<\"$s\" | sort)\n comm -13 <(echo \"$prev\") <(echo \"$cur\")\n prev=$cur\n jq -e 'all(.bucket!=\"pending\")' <<<\"$s\" >/dev/null && break\n sleep 30\n done\n\n**Don't use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For \"tell me when X is ready,\" use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.\n\n**Script quality:**\n- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.\n- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn't kill the monitor.\n- Poll intervals: 30s+ for remote APIs (rate limits), 0.5-1s for local checks.\n- Write a specific `description` — it appears in every notification (\"errors in deploy.log\" not \"watching logs\").\n- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)\n\n**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to \"still running.\" Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.\n\n # Wrong — silent on crash, hang, or any non-success exit\n tail -f run.log | grep --line-buffered \"elapsed_steps=\"\n\n # Right — one alternation covering progress + the failure signatures you'd act on\n tail -f run.log | grep -E --line-buffered \"elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM\"\n\nFor poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.\n\n**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means \"the lines you'd act on,\" not \"only good news.\" Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.\n\nStdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.\n\nThe script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout → killed. Set `persistent: true` for session-length watches (PR monitoring, log tails) — the monitor runs until you call TaskStop or the session ends. Use TaskStop to cancel early.",
714
+ "description": "Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** (\"tell me when the server is ready / the build finishes\") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q \"Ready in\" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.\n- **One per occurrence, indefinitely** (\"tell me every time an ERROR line appears\") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).\n- **One per occurrence, until a known end** (\"emit each CI step result, stop when the run completes\") → Monitor with a command that emits lines and then exits.\n\nYour script's stdout is the event stream. Each line becomes a notification. Exit ends the watch.\n\n # Each matching log line is an event\n tail -f /var/log/app.log | grep --line-buffered \"ERROR\"\n\n # Each file change is an event\n inotifywait -m --format '%e %f' /watched/dir\n\n # Poll GitHub for new PR comments and emit one line per new comment\n last=$(date -u +%Y-%m-%dT%H:%M:%SZ)\n while true; do\n now=$(date -u +%Y-%m-%dT%H:%M:%SZ)\n gh api \"repos/owner/repo/issues/123/comments?since=$last\" --jq '.[] | \"\\(.user.login): \\(.body)\"'\n last=$now; sleep 30\n done\n\n # Node script that emits events as they arrive (e.g. WebSocket listener)\n node watch-for-events.js\n\n # Per-occurrence with a natural end: emit each CI check as it lands, exit when the run completes\n prev=\"\"\n while true; do\n s=$(gh pr checks 123 --json name,bucket)\n cur=$(jq -r '.[] | select(.bucket!=\"pending\") | \"\\(.name): \\(.bucket)\"' <<<\"$s\" | sort)\n comm -13 <(echo \"$prev\") <(echo \"$cur\")\n prev=$cur\n jq -e 'all(.bucket!=\"pending\")' <<<\"$s\" >/dev/null && break\n sleep 30\n done\n\n**Don't use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For \"tell me when X is ready,\" use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.\n\n**Script quality:**\n- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.\n- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn't kill the monitor.\n- Poll intervals: 30s+ for remote APIs (rate limits), 0.5-1s for local checks.\n- Write a specific `description` — it appears in every notification (\"errors in deploy.log\" not \"watching logs\").\n- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)\n\n**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to \"still running.\" Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.\n\n # Wrong — silent on crash, hang, or any non-success exit\n tail -f run.log | grep --line-buffered \"elapsed_steps=\"\n\n # Right — one alternation covering progress + the failure signatures you'd act on\n tail -f run.log | grep -E --line-buffered \"elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM\"\n\nFor poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.\n\n**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means \"the lines you'd act on,\" not \"only good news.\" Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.\n\nStdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.\n\nThe script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout → killed. Set `persistent: true` for session-length watches (PR monitoring, log tails) — the monitor runs until you call TaskStop or the session ends. Use TaskStop to cancel early.\n**ws source** — open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.\n\n Monitor({\n ws: {url: 'wss://events.example.com/stream', protocols: ['v1']},\n description: 'deploy events',\n })\n\nEach text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as `[binary frame, N bytes]` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash — a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.\n\nPrefer this over `command: 'websocat wss://…'` — it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.",
715
715
  "input_schema": {
716
716
  "$schema": "https://json-schema.org/draft/2020-12/schema",
717
717
  "type": "object",
@@ -734,13 +734,32 @@
734
734
  "command": {
735
735
  "description": "Shell command or script. Each stdout line is an event; exit ends the watch.",
736
736
  "type": "string"
737
+ },
738
+ "ws": {
739
+ "description": "WebSocket to open. Each text frame is an event; binary frames are reported as a placeholder line. Socket close ends the watch. Cannot be combined with command.",
740
+ "type": "object",
741
+ "properties": {
742
+ "url": {
743
+ "type": "string"
744
+ },
745
+ "protocols": {
746
+ "type": "array",
747
+ "items": {
748
+ "type": "string",
749
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$"
750
+ }
751
+ }
752
+ },
753
+ "required": [
754
+ "url"
755
+ ],
756
+ "additionalProperties": false
737
757
  }
738
758
  },
739
759
  "required": [
740
760
  "description",
741
761
  "timeout_ms",
742
- "persistent",
743
- "command"
762
+ "persistent"
744
763
  ],
745
764
  "additionalProperties": false
746
765
  }
@@ -881,6 +900,82 @@
881
900
  "additionalProperties": false
882
901
  }
883
902
  },
903
+ {
904
+ "name": "ReportFindings",
905
+ "description": "Report code-review findings as a typed list so the host UI can render them. Use this only when the active code-review instructions tell you to report findings with this tool; otherwise follow whatever output format those instructions specify. When reporting a review's results, call it once with the verified findings ranked most-severe first (empty array if nothing survived verification) and do not also print the findings as text. When re-reporting after applying fixes (only if the apply instructions ask for it), set `outcome` on each finding to what actually happened.",
906
+ "input_schema": {
907
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
908
+ "type": "object",
909
+ "properties": {
910
+ "level": {
911
+ "description": "Effort level the review ran at",
912
+ "type": "string",
913
+ "enum": [
914
+ "low",
915
+ "medium",
916
+ "high",
917
+ "xhigh",
918
+ "max"
919
+ ]
920
+ },
921
+ "findings": {
922
+ "description": "Verified findings, most-severe first; empty if none survived",
923
+ "maxItems": 32,
924
+ "type": "array",
925
+ "items": {
926
+ "type": "object",
927
+ "properties": {
928
+ "file": {
929
+ "description": "Repo-relative path of the file the finding is in",
930
+ "type": "string"
931
+ },
932
+ "line": {
933
+ "description": "1-indexed line the finding anchors to",
934
+ "type": "integer",
935
+ "minimum": -9007199254740991,
936
+ "maximum": 9007199254740991
937
+ },
938
+ "summary": {
939
+ "description": "One-sentence statement of the defect",
940
+ "type": "string"
941
+ },
942
+ "failure_scenario": {
943
+ "description": "Concrete inputs/state → wrong output/crash",
944
+ "type": "string"
945
+ },
946
+ "verdict": {
947
+ "description": "Set when a verify pass ran; absent on inline-only reviews",
948
+ "type": "string",
949
+ "enum": [
950
+ "CONFIRMED",
951
+ "PLAUSIBLE"
952
+ ]
953
+ },
954
+ "outcome": {
955
+ "description": "Set ONLY when re-reporting after applying fixes: what happened to this finding",
956
+ "type": "string",
957
+ "enum": [
958
+ "fixed",
959
+ "skipped",
960
+ "no_change_needed"
961
+ ]
962
+ }
963
+ },
964
+ "required": [
965
+ "file",
966
+ "summary",
967
+ "failure_scenario"
968
+ ],
969
+ "additionalProperties": false
970
+ }
971
+ }
972
+ },
973
+ "required": [
974
+ "findings"
975
+ ],
976
+ "additionalProperties": false
977
+ }
978
+ },
884
979
  {
885
980
  "name": "ScheduleWakeup",
886
981
  "description": "Schedule when to resume work in /loop dynamic mode — the user invoked /loop without an interval, asking you to self-pace iterations of a specific task.\n\nDo NOT schedule a short-interval wakeup to poll for background work you started — when harness-tracked work finishes, you are re-invoked automatically, so polling is wasted. Instead schedule a long fallback (1200s+) so the loop survives if the work hangs or never notifies. The exception is external work the harness cannot track (a CI run, a deploy, a remote queue) — there, pick a delay matched to how fast that state actually changes.\n\nPass the same /loop prompt back via `prompt` each turn so the next firing repeats the task. For an autonomous /loop (no user prompt), pass the literal sentinel `<<autonomous-loop-dynamic>>` as `prompt` instead — the runtime resolves it back to the autonomous-loop instructions at fire time. (There is a similar `<<autonomous-loop>>` sentinel for CronCreate-based autonomous loops; do not confuse the two — ScheduleWakeup always uses the `-dynamic` variant.) Omit the call to end the loop.\n\n## Picking delaySeconds\n\nThe Anthropic prompt cache has a 5-minute TTL. Sleeping past 300 seconds means the next wake-up reads your full conversation context uncached — slower and more expensive. So the natural breakpoints:\n\n- **Under 5 minutes (60s–270s)**: cache stays warm. Right for actively polling external state the harness can't notify you about — a CI run, a deploy, a remote queue.\n- **5 minutes to 1 hour (300s–3600s)**: pay the cache miss. Right when there's no point checking sooner — waiting on something that takes minutes to change, genuinely idle, or as the long fallback heartbeat when something else is the primary wake signal.\n\n**Don't pick 300s.** It's the worst-of-both: you pay the cache miss without amortizing it. If you're tempted to \"wait 5 minutes,\" either drop to 270s (stay in cache) or commit to 1200s+ (one cache miss buys a much longer wait). Don't think in round-number minutes — think in cache windows.\n\nFor idle ticks with no specific signal to watch, default to **1200s–1800s** (20–30 min). The loop checks back, you don't burn cache 12× per hour for nothing, and the user can always interrupt if they need you sooner.\n\nThink about what you're actually waiting for, not just \"how long should I sleep.\" If you're polling a CI run that takes ~8 minutes, sleeping 60s burns the cache 8 times before it finishes — sleep ~270s twice instead.\n\nThe runtime clamps to [60, 3600], so you don't need to clamp yourself.\n\n## The reason field\n\nOne short sentence on what you chose and why. Goes to telemetry and is shown back to the user. \"watching CI run\" beats \"waiting.\" The user reads this to understand what you're doing without having to predict your cadence in advance — make it specific.\n",
@@ -1281,6 +1376,7 @@
1281
1376
  "NotebookEdit",
1282
1377
  "PushNotification",
1283
1378
  "Read",
1379
+ "ReportFindings",
1284
1380
  "ScheduleWakeup",
1285
1381
  "SendMessage",
1286
1382
  "Skill",
@@ -1321,14 +1417,14 @@
1321
1417
  "anthropic_beta": "claude-code-20250219,interleaved-thinking-2025-05-14,thinking-token-count-2026-05-13,context-management-2025-06-27,prompt-caching-scope-2026-01-05,mid-conversation-system-2026-04-07,advisor-tool-2026-03-01,effort-2025-11-24",
1322
1418
  "header_values": {
1323
1419
  "accept": "application/json",
1324
- "user-agent": "claude-cli/2.1.195 (external, sdk-cli)",
1420
+ "user-agent": "claude-cli/2.1.196 (external, sdk-cli)",
1325
1421
  "x-stainless-arch": "x64",
1326
1422
  "x-stainless-lang": "js",
1327
1423
  "x-stainless-os": "Linux",
1328
1424
  "x-stainless-package-version": "0.94.0",
1329
1425
  "x-stainless-retry-count": "0",
1330
1426
  "x-stainless-runtime": "node",
1331
- "x-stainless-runtime-version": "v24.3.0",
1427
+ "x-stainless-runtime-version": "v26.3.0",
1332
1428
  "x-stainless-timeout": "600",
1333
1429
  "anthropic-dangerous-direct-browser-access": "true",
1334
1430
  "anthropic-version": "2023-06-01",
@@ -1346,5 +1442,5 @@
1346
1442
  "output_config",
1347
1443
  "stream"
1348
1444
  ],
1349
- "_supportedMaxTested": "2.1.195"
1445
+ "_supportedMaxTested": "2.1.196"
1350
1446
  }
@@ -78,7 +78,7 @@ export const AnalyticsTab = {
78
78
  lines.push(' ' + renderKvRow('Tokens out', formatNumber(s.window.totalOutputTokens), w - 4));
79
79
  lines.push(' ' + renderKvRow('Thinking tokens', formatNumber(s.window.totalThinkingTokens), w - 4));
80
80
  lines.push(' ' + renderKvRow('Avg latency', `${Math.round(s.window.avgLatencyMs)}ms`, w - 4));
81
- lines.push(' ' + renderKvRow('Subscription %', `${(s.window.subscriptionPercent * 100).toFixed(0)}%`, w - 4));
81
+ lines.push(' ' + renderKvRow('Subscription %', `${s.window.subscriptionPercent.toFixed(0)}%`, w - 4));
82
82
  // ── Per-model bars ─────────────────────────────────────────
83
83
  const models = Object.entries(s.perModel).sort((a, b) => b[1].requests - a[1].requests);
84
84
  if (models.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "4.8.102",
3
+ "version": "4.8.104",
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": {