@askalf/dario 6.12.25 → 6.12.27
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/accounts.js +21 -2
- package/dist/live-fingerprint.d.ts +1 -1
- package/dist/live-fingerprint.js +1 -1
- package/docs/drift-monitor.md +69 -4
- package/package.json +2 -2
package/dist/accounts.js
CHANGED
|
@@ -526,7 +526,7 @@ export async function addAccountViaOAuth(alias) {
|
|
|
526
526
|
grantedAt: Date.now(),
|
|
527
527
|
...profileFields(profile),
|
|
528
528
|
};
|
|
529
|
-
await
|
|
529
|
+
await saveGrantedAccount(creds);
|
|
530
530
|
resolve(creds);
|
|
531
531
|
}
|
|
532
532
|
catch (err) {
|
|
@@ -663,7 +663,7 @@ export async function completeAddAccount(alias, code, codeVerifier, state) {
|
|
|
663
663
|
grantedAt: Date.now(),
|
|
664
664
|
...profileFields(profile),
|
|
665
665
|
};
|
|
666
|
-
await
|
|
666
|
+
await saveGrantedAccount(creds);
|
|
667
667
|
return creds;
|
|
668
668
|
}
|
|
669
669
|
export function getAccountsDir() {
|
|
@@ -935,3 +935,22 @@ export async function mirrorLoginToCredentials(refreshed) {
|
|
|
935
935
|
});
|
|
936
936
|
return 'mirrored';
|
|
937
937
|
}
|
|
938
|
+
/**
|
|
939
|
+
* Save an account that an OAuth grant has just produced.
|
|
940
|
+
*
|
|
941
|
+
* A grant on the `login` alias is mirrored to credentials.json at once.
|
|
942
|
+
* mirrorLoginToCredentials otherwise runs only when the pool next refreshes
|
|
943
|
+
* the seat, which is hours away after a grant, and until then every other
|
|
944
|
+
* reader of credentials.json (a co-resident Claude Code, a runner that borrows
|
|
945
|
+
* the file) holds the token of the grant that was just replaced. After a
|
|
946
|
+
* re-grant of a dead seat that token is refused upstream.
|
|
947
|
+
*
|
|
948
|
+
* Best-effort, like the mirror after a refresh: the account is already saved,
|
|
949
|
+
* and a mirror that fails must not fail the grant.
|
|
950
|
+
*/
|
|
951
|
+
async function saveGrantedAccount(creds) {
|
|
952
|
+
await saveAccount(creds);
|
|
953
|
+
await mirrorLoginToCredentials(creds).catch((err) => {
|
|
954
|
+
console.error(`[dario] could not mirror the granted ${creds.alias} token to credentials.json: ${err instanceof Error ? err.message : err}`);
|
|
955
|
+
});
|
|
956
|
+
}
|
|
@@ -510,7 +510,7 @@ export declare function detectDrift(t: TemplateData, installedOverride?: string
|
|
|
510
510
|
*/
|
|
511
511
|
export declare const SUPPORTED_CC_RANGE: {
|
|
512
512
|
readonly min: "1.0.0";
|
|
513
|
-
readonly maxTested: "2.1.
|
|
513
|
+
readonly maxTested: "2.1.290";
|
|
514
514
|
};
|
|
515
515
|
/**
|
|
516
516
|
* Compare two dotted-numeric version strings. Returns negative if `a<b`,
|
package/dist/live-fingerprint.js
CHANGED
|
@@ -1211,7 +1211,7 @@ export function detectDrift(t, installedOverride) {
|
|
|
1211
1211
|
*/
|
|
1212
1212
|
export const SUPPORTED_CC_RANGE = {
|
|
1213
1213
|
min: '1.0.0',
|
|
1214
|
-
maxTested: '2.1.
|
|
1214
|
+
maxTested: '2.1.290',
|
|
1215
1215
|
};
|
|
1216
1216
|
/**
|
|
1217
1217
|
* Compare two dotted-numeric version strings. Returns negative if `a<b`,
|
package/docs/drift-monitor.md
CHANGED
|
@@ -67,6 +67,10 @@ fields that always differ between runs (`_captured` timestamp, user-agent
|
|
|
67
67
|
string, `_version` / `_supportedMaxTested` labels). It flags **shape** drift in:
|
|
68
68
|
|
|
69
69
|
- **tools** added or removed (by name set)
|
|
70
|
+
- **tool descriptions, input schemas and order** for tools on both sides
|
|
71
|
+
- **header values** the proxy replays (not `user-agent`, which carries the
|
|
72
|
+
version, and not `x-api-key`, `x-stainless-os` or `x-stainless-arch`, which
|
|
73
|
+
describe the capture)
|
|
70
74
|
- **anthropic_beta** header values added or removed
|
|
71
75
|
- **system_prompt** content (any character delta)
|
|
72
76
|
- **body_field_order** (top-level JSON key order)
|
|
@@ -95,7 +99,7 @@ That exact sequence reached the ship gate on 2026-07-02 (PR #632: runner CC at
|
|
|
95
99
|
older. A *deliberate* downgrade bake (an upstream CC release gets pulled and
|
|
96
100
|
the bundle must go backward) bypasses it with `--allow-older-cc`.
|
|
97
101
|
|
|
98
|
-
### Exit 2 vs exit 3
|
|
102
|
+
### Exit 2 vs exit 3: why the split, and what each needs to merge
|
|
99
103
|
|
|
100
104
|
Because `--check` ignores `_version`, a CC release whose wire shape is
|
|
101
105
|
*unchanged* (the common case for a patch bump) produces a bundle whose shape
|
|
@@ -114,8 +118,8 @@ user-agent header) — never the wire shape — patch-bumps `package.json`,
|
|
|
114
118
|
promotes the CHANGELOG, opens a `bot/template-label-*` PR, and turns on
|
|
115
119
|
**auto-merge**.
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
means the live capture shows no difference in the fields listed under
|
|
121
|
+
An exit 3 PR merges on the review and the required checks alone: an empty
|
|
122
|
+
`computeDrift` means the live capture shows no difference in the fields listed under
|
|
119
123
|
[What --check considers drift](#what---check-considers-drift). It is not a
|
|
120
124
|
byte comparison: tools are compared by name only (descriptions and schemas
|
|
121
125
|
of existing tools are not), the memory path in the system prompt is
|
|
@@ -126,7 +130,68 @@ same deterministic-bump risk class `cc-drift-watch.yml` already auto-merges for
|
|
|
126
130
|
(build ×3, live-test, CodeQL, actionlint, validate-package-json); compat runs
|
|
127
131
|
alongside but is not required. A red required check leaves the PR open
|
|
128
132
|
with the bot branch preserved. A shape rebake (exit 2) changes the wire-shape
|
|
129
|
-
contract, so
|
|
133
|
+
contract, so it needs one thing more before it merges: the upstream check
|
|
134
|
+
described under [The rebake PR](#the-rebake-pr) has to have passed on the
|
|
135
|
+
bundle the PR's head carries. A rebake whose check failed waits for a person.
|
|
136
|
+
|
|
137
|
+
## The rebake PR
|
|
138
|
+
|
|
139
|
+
On exit 2 the watcher bakes, checks the new bundle against upstream, and opens a
|
|
140
|
+
`bot/template-rebake-*` PR. Three things about that PR come from the bake itself
|
|
141
|
+
and not from the `--check` log:
|
|
142
|
+
|
|
143
|
+
- **What changes.** `scripts/rebake-release-prep.mjs` diffs the bundle on the
|
|
144
|
+
base branch against the baked one (`describeBundleChange` in
|
|
145
|
+
`scripts/drift-report.mjs`) and writes both the CHANGELOG entry and the PR's
|
|
146
|
+
list from it. The bake writes the whole capture, and `--check` compares the
|
|
147
|
+
tools and the replayed header values as well as their order. Those texts
|
|
148
|
+
say what the bundle holds. What a request carries also depends on the proxy,
|
|
149
|
+
which prefers a fresh live capture, sets some headers itself and manages some
|
|
150
|
+
beta flags per request.
|
|
151
|
+
- **Validation.** `scripts/rebake-upstream-check.mjs` starts the checkout's
|
|
152
|
+
proxy in code (`scripts/_rebake-probe-proxy.mjs`), with the bundle as its
|
|
153
|
+
only template and the proxy's own defaults for building a request: the
|
|
154
|
+
caller's `DARIO_*` and `ANTHROPIC_*` variables and `~/.dario/config.json`
|
|
155
|
+
take no part. It sends one request for the base model and for each
|
|
156
|
+
prompt-variant family. Each request declares, by name, the bundled tools
|
|
157
|
+
whose definitions the request builder uses, so the rebuilt request carries
|
|
158
|
+
those definitions and the bundled prompt for its model. The proxy records
|
|
159
|
+
the `/v1/messages` requests it sends upstream, and the
|
|
160
|
+
script reads that record: a request that lacks the bundled prompt or a
|
|
161
|
+
declared tool's bundled definition makes the run an error, not a verdict. A
|
|
162
|
+
request passes when upstream answers 200 and bills it to the subscription,
|
|
163
|
+
and fails when upstream rejects it or bills it elsewhere. The proxy can send
|
|
164
|
+
a request again, on another seat or changed after upstream refused part of
|
|
165
|
+
it, and the last answer is the one judged. A probe the proxy did not answer
|
|
166
|
+
is an error too, and so is one the proxy answered itself for a reason that
|
|
167
|
+
is not about a seat.
|
|
168
|
+
The script borrows the subscription credential read-only
|
|
169
|
+
(`DARIO_NO_TOKEN_REFRESH=1`). A PR is opened only with a verdict, pass or
|
|
170
|
+
fail: the result is in the PR body and on the bundle's commit as the
|
|
171
|
+
`rebake/upstream` status, and a failed check adds the `upstream-check-failed`
|
|
172
|
+
label. When upstream did not judge a request (it refused the borrowed
|
|
173
|
+
token, rate-limited, failed or did not answer), or the proxy had no seat to
|
|
174
|
+
send one with (a borrowed token inside its expiry margin, or a seat inside a
|
|
175
|
+
rate-limit window), no PR is opened and the next run bakes and checks again.
|
|
176
|
+
On an error the watcher's job fails.
|
|
177
|
+
- **Freshness.** A bake is a snapshot, and Claude Code's remote configuration
|
|
178
|
+
moves under a fixed version. An open rebake PR older than two hours is checked
|
|
179
|
+
against live on every watcher run, with its own bundle as the baseline. It is
|
|
180
|
+
closed, with what the check reported, when two captures in a row report drift
|
|
181
|
+
and neither is the #881 residue. A fresh bake follows when live also differs
|
|
182
|
+
from master; when live has returned to master's shape there is nothing to
|
|
183
|
+
bake. While such a PR is open each run makes one more capture pass, and a
|
|
184
|
+
second when the first reports drift.
|
|
185
|
+
|
|
186
|
+
The platform review gate merges the PR once the review approves it at its
|
|
187
|
+
head, the required checks pass, and the `rebake/upstream` status is a pass on a
|
|
188
|
+
commit of the PR whose `src/cc-template-data.json` is the one the head carries.
|
|
189
|
+
A failed check, or a bundle changed after the check, leaves the merge to a
|
|
190
|
+
person.
|
|
191
|
+
|
|
192
|
+
The bundle is captured from Claude Code and scrubbed by the bake. The prompts
|
|
193
|
+
and tool descriptions in it are Claude Code's wording and are not edited for
|
|
194
|
+
style in review: a change to them comes from a bake.
|
|
130
195
|
|
|
131
196
|
## Setting up the self-hosted runner
|
|
132
197
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "6.12.
|
|
3
|
+
"version": "6.12.27",
|
|
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": {
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"node": ">=18.0.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@types/node": "^26.6.
|
|
90
|
+
"@types/node": "^26.6.4",
|
|
91
91
|
"tsx": "^4.23.15",
|
|
92
92
|
"typescript": "^5.7.0"
|
|
93
93
|
}
|