@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 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
+ }
@@ -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.289";
513
+ readonly maxTested: "2.1.290";
514
514
  };
515
515
  /**
516
516
  * Compare two dotted-numeric version strings. Returns negative if `a<b`,
@@ -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.289',
1214
+ maxTested: '2.1.290',
1215
1215
  };
1216
1216
  /**
1217
1217
  * Compare two dotted-numeric version strings. Returns negative if `a<b`,
@@ -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 — why the split, and why only one auto-merges
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
- Auto-merge is safe for exit 3 but **not** for exit 2: an empty `computeDrift`
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 a human reviews compat-test + the diff before merging.
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.25",
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.2",
90
+ "@types/node": "^26.6.4",
91
91
  "tsx": "^4.23.15",
92
92
  "typescript": "^5.7.0"
93
93
  }