@askalf/dario 6.12.25 → 6.12.26
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/docs/drift-monitor.md +53 -0
- 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
|
+
}
|
package/docs/drift-monitor.md
CHANGED
|
@@ -128,6 +128,59 @@ alongside but is not required. A red required check leaves the PR open
|
|
|
128
128
|
with the bot branch preserved. A shape rebake (exit 2) changes the wire-shape
|
|
129
129
|
contract, so a human reviews compat-test + the diff before merging.
|
|
130
130
|
|
|
131
|
+
## The rebake PR
|
|
132
|
+
|
|
133
|
+
On exit 2 the watcher bakes, checks the new bundle against upstream, and opens a
|
|
134
|
+
`bot/template-rebake-*` PR. Three things about that PR come from the bake itself
|
|
135
|
+
and not from the `--check` log:
|
|
136
|
+
|
|
137
|
+
- **What changes.** `scripts/rebake-release-prep.mjs` diffs the bundle on the
|
|
138
|
+
base branch against the baked one (`describeBundleChange` in
|
|
139
|
+
`scripts/drift-report.mjs`) and writes both the CHANGELOG entry and the PR's
|
|
140
|
+
list from it. `--check` compares tool names and header order; the bake writes
|
|
141
|
+
the whole capture, so tool text and header values move with it. Those texts
|
|
142
|
+
say what the bundle holds. What a request carries also depends on the proxy,
|
|
143
|
+
which prefers a fresh live capture, sets some headers itself and manages some
|
|
144
|
+
beta flags per request.
|
|
145
|
+
- **Validation.** `scripts/rebake-upstream-check.mjs` starts the checkout's
|
|
146
|
+
proxy in code (`scripts/_rebake-probe-proxy.mjs`), with the bundle as its
|
|
147
|
+
only template and the proxy's own defaults for building a request: the
|
|
148
|
+
caller's `DARIO_*` and `ANTHROPIC_*` variables and `~/.dario/config.json`
|
|
149
|
+
take no part. It sends one request for the base model and for each
|
|
150
|
+
prompt-variant family. Each request declares, by name, the bundled tools
|
|
151
|
+
whose definitions the request builder uses, so the rebuilt request carries
|
|
152
|
+
those definitions and the bundled prompt for its model. The proxy records
|
|
153
|
+
the `/v1/messages` requests it sends upstream, and the
|
|
154
|
+
script reads that record: a request that lacks the bundled prompt or a
|
|
155
|
+
declared tool's bundled definition makes the run an error, not a verdict. A
|
|
156
|
+
request passes when upstream answers 200 and bills it to the subscription,
|
|
157
|
+
and fails when upstream rejects it or bills it elsewhere. The proxy can send
|
|
158
|
+
a request again, on another seat or changed after upstream refused part of
|
|
159
|
+
it, and the last answer is the one judged. A probe the proxy did not answer
|
|
160
|
+
is an error too, and so is one the proxy answered itself for a reason that
|
|
161
|
+
is not about a seat.
|
|
162
|
+
The script borrows the subscription credential read-only
|
|
163
|
+
(`DARIO_NO_TOKEN_REFRESH=1`). A PR is opened only with a verdict, pass or
|
|
164
|
+
fail: the result is in the PR body and on the bundle's commit as the
|
|
165
|
+
`rebake/upstream` status, and a failed check adds the `upstream-check-failed`
|
|
166
|
+
label. When upstream did not judge a request (it refused the borrowed
|
|
167
|
+
token, rate-limited, failed or did not answer), or the proxy had no seat to
|
|
168
|
+
send one with (a borrowed token inside its expiry margin, or a seat inside a
|
|
169
|
+
rate-limit window), no PR is opened and the next run bakes and checks again.
|
|
170
|
+
On an error the watcher's job fails.
|
|
171
|
+
- **Freshness.** A bake is a snapshot, and Claude Code's remote configuration
|
|
172
|
+
moves under a fixed version. An open rebake PR older than two hours is checked
|
|
173
|
+
against live on every watcher run, with its own bundle as the baseline. It is
|
|
174
|
+
closed, with what the check reported, when two captures in a row report drift
|
|
175
|
+
and neither is the #881 residue. A fresh bake follows when live also differs
|
|
176
|
+
from master; when live has returned to master's shape there is nothing to
|
|
177
|
+
bake. While such a PR is open each run makes one more capture pass, and a
|
|
178
|
+
second when the first reports drift.
|
|
179
|
+
|
|
180
|
+
The bundle is captured from Claude Code and scrubbed by the bake. The prompts
|
|
181
|
+
and tool descriptions in it are Claude Code's wording and are not edited for
|
|
182
|
+
style in review: a change to them comes from a bake.
|
|
183
|
+
|
|
131
184
|
## Setting up the self-hosted runner
|
|
132
185
|
|
|
133
186
|
Any dedicated Linux host works. Hetzner / DO / EC2 / etc. The runner needs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "6.12.
|
|
3
|
+
"version": "6.12.26",
|
|
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
|
}
|