@askalf/dario 6.6.3 → 6.6.5
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/doctor-core.d.ts
CHANGED
|
@@ -52,6 +52,33 @@ export declare function continuationReadiness(input: {
|
|
|
52
52
|
status: CheckStatus;
|
|
53
53
|
detail: string;
|
|
54
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Ledger readiness (v6.6.4). The ledger is a file the proxy writes a few
|
|
57
|
+
* seconds after each request; the number it feeds (`dario usage`, the TUI's
|
|
58
|
+
* API-equivalent row) only ever moves if that write lands. A bind mount that
|
|
59
|
+
* came up read-only, a home directory the proxy cannot create, a file a
|
|
60
|
+
* root-owned rig left behind — each of these looks exactly like "no traffic"
|
|
61
|
+
* from the outside. This row says whether the file can be written, when it
|
|
62
|
+
* last was, and what it holds. File and configuration only: the proxy's own
|
|
63
|
+
* unflushed records are not visible here.
|
|
64
|
+
*/
|
|
65
|
+
export declare function ledgerReadiness(input: {
|
|
66
|
+
enabled: boolean;
|
|
67
|
+
path: string;
|
|
68
|
+
exists: boolean;
|
|
69
|
+
writable: boolean;
|
|
70
|
+
/** Why the file could not be parsed, when it exists and could not be. */
|
|
71
|
+
parseError?: string;
|
|
72
|
+
/** Epoch ms of the file's `updated` stamp, when it parsed. */
|
|
73
|
+
updatedAtMs?: number;
|
|
74
|
+
requests?: number;
|
|
75
|
+
apiEquivalentCost?: number;
|
|
76
|
+
since?: string;
|
|
77
|
+
nowMs?: number;
|
|
78
|
+
}): {
|
|
79
|
+
status: CheckStatus;
|
|
80
|
+
detail: string;
|
|
81
|
+
};
|
|
55
82
|
export declare function failoverReadiness(input: {
|
|
56
83
|
chain: readonly string[];
|
|
57
84
|
codexAccounts: number;
|
package/dist/doctor-core.js
CHANGED
|
@@ -64,6 +64,50 @@ export function continuationReadiness(input) {
|
|
|
64
64
|
: 'the chain has nowhere to go for a second hop (see Failover)'),
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Ledger readiness (v6.6.4). The ledger is a file the proxy writes a few
|
|
69
|
+
* seconds after each request; the number it feeds (`dario usage`, the TUI's
|
|
70
|
+
* API-equivalent row) only ever moves if that write lands. A bind mount that
|
|
71
|
+
* came up read-only, a home directory the proxy cannot create, a file a
|
|
72
|
+
* root-owned rig left behind — each of these looks exactly like "no traffic"
|
|
73
|
+
* from the outside. This row says whether the file can be written, when it
|
|
74
|
+
* last was, and what it holds. File and configuration only: the proxy's own
|
|
75
|
+
* unflushed records are not visible here.
|
|
76
|
+
*/
|
|
77
|
+
export function ledgerReadiness(input) {
|
|
78
|
+
if (!input.enabled) {
|
|
79
|
+
return { status: 'info', detail: 'off — no lifetime API-equivalent numbers (unset DARIO_LEDGER / drop --no-ledger)' };
|
|
80
|
+
}
|
|
81
|
+
if (!input.exists) {
|
|
82
|
+
return input.writable
|
|
83
|
+
? { status: 'ok', detail: `no file yet at ${input.path} — it appears after the first request through the proxy` }
|
|
84
|
+
: { status: 'warn', detail: `cannot write ${input.path} — the ledger will never record anything (check the directory's owner and mount)` };
|
|
85
|
+
}
|
|
86
|
+
if (input.parseError) {
|
|
87
|
+
return { status: 'warn', detail: `${input.path} is unreadable (${input.parseError}) — the proxy moves it aside and starts fresh on its next start; the history in it is lost` };
|
|
88
|
+
}
|
|
89
|
+
const now = input.nowMs ?? Date.now();
|
|
90
|
+
const age = typeof input.updatedAtMs === 'number' ? Math.max(0, now - input.updatedAtMs) : null;
|
|
91
|
+
const ageText = age === null ? 'last write unknown' : `last write ${describeAge(age)} ago`;
|
|
92
|
+
const usd = typeof input.apiEquivalentCost === 'number' ? `$${input.apiEquivalentCost >= 100 ? Math.round(input.apiEquivalentCost).toLocaleString('en-US') : input.apiEquivalentCost.toFixed(2)}` : '$?';
|
|
93
|
+
const body = `${(input.requests ?? 0).toLocaleString('en-US')} requests since ${(input.since ?? '').slice(0, 10) || '?'}, ${usd} API-equivalent; ${ageText}`;
|
|
94
|
+
if (!input.writable) {
|
|
95
|
+
return { status: 'warn', detail: `${body} — file is read-only now, so nothing since then is being saved (${input.path})` };
|
|
96
|
+
}
|
|
97
|
+
return { status: 'ok', detail: `${body} (${input.path})` };
|
|
98
|
+
}
|
|
99
|
+
function describeAge(ms) {
|
|
100
|
+
const s = Math.round(ms / 1000);
|
|
101
|
+
if (s < 60)
|
|
102
|
+
return `${s}s`;
|
|
103
|
+
const m = Math.round(s / 60);
|
|
104
|
+
if (m < 60)
|
|
105
|
+
return `${m}m`;
|
|
106
|
+
const h = Math.round(m / 60);
|
|
107
|
+
if (h < 48)
|
|
108
|
+
return `${h}h`;
|
|
109
|
+
return `${Math.round(h / 24)}d`;
|
|
110
|
+
}
|
|
67
111
|
export function failoverReadiness(input) {
|
|
68
112
|
const { chain, codexAccounts, backends } = input;
|
|
69
113
|
const hasCodex = codexAccounts > 0;
|
|
@@ -1200,6 +1244,54 @@ export async function runChecks(opts = {}) {
|
|
|
1200
1244
|
catch (err) {
|
|
1201
1245
|
checks.push({ status: 'warn', label: 'Failover', detail: `check failed: ${err.message}` });
|
|
1202
1246
|
}
|
|
1247
|
+
// ---- Ledger (v6.6.4) — see ledgerReadiness() for the why. The default
|
|
1248
|
+
// port's file; DARIO_LEDGER_PATH is honoured like the proxy honours it.
|
|
1249
|
+
try {
|
|
1250
|
+
const { resolveLedgerPath, ledgerDisabledByEnv, readLedgerFile, summarizeLedger } = await import('./ledger.js');
|
|
1251
|
+
const { access, constants } = await import('node:fs/promises');
|
|
1252
|
+
const path = resolveLedgerPath(3456);
|
|
1253
|
+
const enabled = !ledgerDisabledByEnv();
|
|
1254
|
+
let exists = false;
|
|
1255
|
+
let writable = false;
|
|
1256
|
+
try {
|
|
1257
|
+
await access(path, constants.F_OK);
|
|
1258
|
+
exists = true;
|
|
1259
|
+
}
|
|
1260
|
+
catch { /* no file yet */ }
|
|
1261
|
+
// The proxy creates missing directories on its first flush, so test the
|
|
1262
|
+
// nearest ancestor that exists — a fresh install has no ~/.dario yet.
|
|
1263
|
+
let probe = exists ? path : dirname(path);
|
|
1264
|
+
while (!exists) {
|
|
1265
|
+
try {
|
|
1266
|
+
await access(probe, constants.F_OK);
|
|
1267
|
+
break;
|
|
1268
|
+
}
|
|
1269
|
+
catch { /* climb */ }
|
|
1270
|
+
const up = dirname(probe);
|
|
1271
|
+
if (up === probe)
|
|
1272
|
+
break;
|
|
1273
|
+
probe = up;
|
|
1274
|
+
}
|
|
1275
|
+
try {
|
|
1276
|
+
await access(probe, constants.W_OK);
|
|
1277
|
+
writable = true;
|
|
1278
|
+
}
|
|
1279
|
+
catch { /* not writable */ }
|
|
1280
|
+
const { file, error } = exists ? await readLedgerFile(path) : { file: null, error: undefined };
|
|
1281
|
+
const summary = file ? summarizeLedger(file, path) : null;
|
|
1282
|
+
const verdict = ledgerReadiness({
|
|
1283
|
+
enabled, path, exists, writable,
|
|
1284
|
+
parseError: error,
|
|
1285
|
+
updatedAtMs: file ? Date.parse(file.updated) : undefined,
|
|
1286
|
+
requests: summary?.requests,
|
|
1287
|
+
apiEquivalentCost: summary?.apiEquivalentCost,
|
|
1288
|
+
since: summary?.since,
|
|
1289
|
+
});
|
|
1290
|
+
checks.push({ status: verdict.status, label: 'Ledger', detail: verdict.detail });
|
|
1291
|
+
}
|
|
1292
|
+
catch (err) {
|
|
1293
|
+
checks.push({ status: 'warn', label: 'Ledger', detail: `check failed: ${err.message}` });
|
|
1294
|
+
}
|
|
1203
1295
|
// ---- CC sub-agent (v3.26, direction #2)
|
|
1204
1296
|
try {
|
|
1205
1297
|
const { loadSubagentStatus } = await import('./subagent.js');
|
|
@@ -496,7 +496,7 @@ export declare function detectDrift(t: TemplateData, installedOverride?: string
|
|
|
496
496
|
*/
|
|
497
497
|
export declare const SUPPORTED_CC_RANGE: {
|
|
498
498
|
readonly min: "1.0.0";
|
|
499
|
-
readonly maxTested: "2.1.
|
|
499
|
+
readonly maxTested: "2.1.270";
|
|
500
500
|
};
|
|
501
501
|
/**
|
|
502
502
|
* Compare two dotted-numeric version strings. Returns negative if `a<b`,
|
package/dist/live-fingerprint.js
CHANGED
|
@@ -1194,7 +1194,7 @@ export function detectDrift(t, installedOverride) {
|
|
|
1194
1194
|
*/
|
|
1195
1195
|
export const SUPPORTED_CC_RANGE = {
|
|
1196
1196
|
min: '1.0.0',
|
|
1197
|
-
maxTested: '2.1.
|
|
1197
|
+
maxTested: '2.1.270',
|
|
1198
1198
|
};
|
|
1199
1199
|
/**
|
|
1200
1200
|
* Compare two dotted-numeric version strings. Returns negative if `a<b`,
|
|
@@ -60,6 +60,18 @@ is never overwritten in place. Days past 730 roll off the front.
|
|
|
60
60
|
The test suite pins `DARIO_LEDGER_PATH` to a temp directory, so a suite run
|
|
61
61
|
does not add stub traffic to the operator's file.
|
|
62
62
|
|
|
63
|
+
`dario doctor` has a **Ledger** row (6.6.4): whether the default port's file
|
|
64
|
+
(or `DARIO_LEDGER_PATH`) can be written, when it was last written, and what
|
|
65
|
+
it holds. A bind mount that came up read-only, a home the proxy cannot
|
|
66
|
+
create, a file a root-owned rig left behind — from the outside each looks
|
|
67
|
+
exactly like "no traffic", and the number stops moving without a word. The
|
|
68
|
+
row reads the file only; records the proxy has not flushed yet are not in it.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
[ OK ] Ledger 160 requests since 2026-09-12, $1.74 API-equivalent; last write 3s ago (/home/dario/.dario/ledger.json)
|
|
72
|
+
[WARN] Ledger cannot write /home/dario/.dario/ledger.json — the ledger will never record anything (check the directory's owner and mount)
|
|
73
|
+
```
|
|
74
|
+
|
|
63
75
|
## Reading it
|
|
64
76
|
|
|
65
77
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "6.6.
|
|
3
|
+
"version": "6.6.5",
|
|
4
4
|
"description": "Use your Claude and ChatGPT subscriptions in Cursor, Cline, Aider, Claude Code and the Agent SDK — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint: either plan answers either wire shape, with automatic failover when one hits its limit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|