@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 CHANGED
@@ -526,7 +526,7 @@ export async function addAccountViaOAuth(alias) {
526
526
  grantedAt: Date.now(),
527
527
  ...profileFields(profile),
528
528
  };
529
- await saveAccount(creds);
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 saveAccount(creds);
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
+ }
@@ -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.25",
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.2",
90
+ "@types/node": "^26.6.4",
91
91
  "tsx": "^4.23.15",
92
92
  "typescript": "^5.7.0"
93
93
  }