@rynfar/meridian 1.41.0 → 1.42.0

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/cli.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-swjr844z.js";
5
- import"./cli-vdp9s10c.js";
4
+ } from "./cli-kvwnarfk.js";
5
+ import"./cli-cx463q74.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-4rqtm83g.js";
8
8
  import"./cli-340h1chz.js";
9
9
  import"./cli-rtab0qa6.js";
10
- import"./cli-0eky480v.js";
10
+ import"./cli-7k1fcprd.js";
11
11
  import {
12
12
  __require
13
13
  } from "./cli-p9swy5t3.js";
@@ -50,12 +50,18 @@ See https://github.com/rynfar/meridian for full documentation.`);
50
50
  process.exit(0);
51
51
  }
52
52
  if (args[0] === "profile") {
53
- const { profileAdd, profileList, profileRemove, profileSwitch, profileLogin, profileHelp } = await import("./profileCli-5f15dx7k.js");
53
+ const { profileAdd, profileAddOauthToken, profileList, profileRemove, profileSwitch, profileLogin, profileHelp } = await import("./profileCli-wpb4qbjn.js");
54
54
  const subcommand = args[1];
55
55
  const profileId = args[2];
56
- if (subcommand === "add" && profileId)
57
- profileAdd(profileId);
58
- else if (subcommand === "list" || subcommand === "ls")
56
+ if (subcommand === "add" && profileId) {
57
+ const oauthFlagIdx = args.indexOf("--oauth-token", 3);
58
+ if (oauthFlagIdx >= 0) {
59
+ const tokenArg = args[oauthFlagIdx + 1];
60
+ await profileAddOauthToken(profileId, tokenArg);
61
+ } else {
62
+ profileAdd(profileId);
63
+ }
64
+ } else if (subcommand === "list" || subcommand === "ls")
59
65
  profileList();
60
66
  else if (subcommand === "remove" && profileId)
61
67
  profileRemove(profileId);
@@ -89,7 +95,7 @@ Restart OpenCode for the plugin to take effect.`);
89
95
  process.exit(0);
90
96
  }
91
97
  if (args[0] === "refresh-token") {
92
- const { refreshOAuthToken } = await import("./tokenRefresh-3kh1e8q8.js");
98
+ const { refreshOAuthToken } = await import("./tokenRefresh-swetnf89.js");
93
99
  const success = await refreshOAuthToken();
94
100
  if (success) {
95
101
  console.log("Token refreshed successfully");
@@ -147,7 +153,7 @@ async function runCli(start = startProxyServer, runExec = exec) {
147
153
  console.error("\x1B[33m⚠ Could not verify Claude auth status. If requests fail, run: claude login\x1B[0m");
148
154
  }
149
155
  if (!profiles) {
150
- const { enableDiskProfileDiscovery } = await import("./profiles-edzz1ffd.js");
156
+ const { enableDiskProfileDiscovery } = await import("./profiles-rdd84b45.js");
151
157
  enableDiskProfileDiscovery();
152
158
  }
153
159
  const proxy = await start({ port, host, idleTimeoutSeconds, profiles, defaultProfile, version });
@@ -116,6 +116,33 @@ function profileAdd(id) {
116
116
  saveProfileConfig(profiles);
117
117
  printEnvHint(profiles);
118
118
  }
119
+ async function profileAddOauthToken(id, tokenArg) {
120
+ if (!id || /[^a-zA-Z0-9_-]/.test(id)) {
121
+ console.error("\x1B[31m✗ Invalid profile ID.\x1B[0m Use only letters, numbers, hyphens, underscores.");
122
+ process.exit(1);
123
+ }
124
+ const profiles = loadProfileConfig();
125
+ if (profiles.find((p) => p.id === id)) {
126
+ console.error(`\x1B[31m✗ Profile "${id}" already exists.\x1B[0m`);
127
+ console.error(` Run: meridian profile list`);
128
+ process.exit(1);
129
+ }
130
+ let token = tokenArg?.trim() ?? "";
131
+ if (!token) {
132
+ console.log(`\x1B[36mAdding profile: ${id} (OAuth token)\x1B[0m`);
133
+ console.log(` Generate a token with: \x1B[1mclaude setup-token\x1B[0m`);
134
+ console.log();
135
+ token = promptToken(`Paste OAuth token for "${id}" (input hidden):`);
136
+ }
137
+ if (!token) {
138
+ console.error("\x1B[31m✗ Empty token. Aborted.\x1B[0m");
139
+ process.exit(1);
140
+ }
141
+ profiles.push({ id, type: "oauth-token", oauthToken: token });
142
+ saveProfileConfig(profiles);
143
+ console.log(`\x1B[32m✓ Profile "${id}" added (OAuth token).\x1B[0m`);
144
+ printEnvHint(profiles);
145
+ }
119
146
  function profileList() {
120
147
  const profiles = loadProfileConfig();
121
148
  if (profiles.length === 0) {
@@ -126,6 +153,10 @@ function profileList() {
126
153
  console.log(`Profiles:
127
154
  `);
128
155
  for (const p of profiles) {
156
+ if (p.oauthToken || p.type === "oauth-token") {
157
+ console.log(` ${p.id.padEnd(20)} \x1B[32m✓ OAuth token\x1B[0m`);
158
+ continue;
159
+ }
129
160
  const auth = getAuthStatus(p.claudeConfigDir ?? "");
130
161
  const status = auth.loggedIn ? `\x1B[32m✓ ${auth.email} (${auth.subscriptionType || "unknown"})\x1B[0m` : "\x1B[31m✗ not logged in\x1B[0m";
131
162
  console.log(` ${p.id.padEnd(20)} ${status}`);
@@ -133,6 +164,18 @@ function profileList() {
133
164
  console.log();
134
165
  printEnvHint(profiles);
135
166
  }
167
+ function dirsToRemoveOnProfileRemove(profile, profilesDir) {
168
+ const dirs = [];
169
+ if (profile.claudeConfigDir && profile.claudeConfigDir.startsWith(profilesDir)) {
170
+ dirs.push(profile.claudeConfigDir);
171
+ }
172
+ if (profile.oauthToken || profile.type === "oauth-token") {
173
+ const isolationDir = join(profilesDir, profile.id);
174
+ if (!dirs.includes(isolationDir))
175
+ dirs.push(isolationDir);
176
+ }
177
+ return dirs;
178
+ }
136
179
  function profileRemove(id) {
137
180
  const profiles = loadProfileConfig();
138
181
  const idx = profiles.findIndex((p) => p.id === id);
@@ -140,11 +183,13 @@ function profileRemove(id) {
140
183
  console.error(`\x1B[31m✗ Profile "${id}" not found.\x1B[0m`);
141
184
  process.exit(1);
142
185
  }
143
- const configDir = profiles[idx].claudeConfigDir ?? "";
186
+ const removed = profiles[idx];
187
+ const dirsToRemove = dirsToRemoveOnProfileRemove(removed, PROFILES_DIR);
144
188
  profiles.splice(idx, 1);
145
189
  saveProfileConfig(profiles);
146
- if (configDir && existsSync(configDir) && configDir.startsWith(PROFILES_DIR)) {
147
- rmSync(configDir, { recursive: true, force: true });
190
+ for (const dir of dirsToRemove) {
191
+ if (existsSync(dir))
192
+ rmSync(dir, { recursive: true, force: true });
148
193
  }
149
194
  console.log(`\x1B[32m✓ Profile "${id}" removed.\x1B[0m`);
150
195
  if (profiles.length > 0) {
@@ -181,6 +226,11 @@ function profileLogin(id) {
181
226
  console.error(`\x1B[31m✗ Profile "${id}" not found.\x1B[0m Run: meridian profile add ${id}`);
182
227
  process.exit(1);
183
228
  }
229
+ if (profile.oauthToken || profile.type === "oauth-token") {
230
+ console.error(`\x1B[31m✗ Profile "${id}" uses an OAuth token; \`claude auth login\` does not apply.\x1B[0m`);
231
+ console.error(` To replace the token: meridian profile remove ${id} && meridian profile add ${id} --oauth-token`);
232
+ process.exit(1);
233
+ }
184
234
  console.log(`\x1B[36mRe-authenticating profile: ${id}\x1B[0m`);
185
235
  console.log();
186
236
  console.log("\x1B[33m⚠ Make sure you're signed into the correct Claude account in your browser.\x1B[0m");
@@ -209,6 +259,41 @@ function promptYesNo(question) {
209
259
  const answer = (result.stdout?.toString().trim() ?? "").toLowerCase();
210
260
  return answer !== "n" && answer !== "no";
211
261
  }
262
+ function promptToken(question) {
263
+ process.stderr.write(`${question}
264
+ > `);
265
+ const script = [
266
+ `const stdin = process.stdin;`,
267
+ `if (!stdin.isTTY) {`,
268
+ ` let buf = "";`,
269
+ ` stdin.setEncoding("utf8");`,
270
+ ` stdin.on("data", (c) => { buf += c; });`,
271
+ ` stdin.on("end", () => { process.stdout.write(buf.split(/\\r?\\n/)[0] || ""); process.exit(0); });`,
272
+ `} else {`,
273
+ ` stdin.setRawMode(true); stdin.resume(); stdin.setEncoding("utf8");`,
274
+ ` let input = "";`,
275
+ ` stdin.on("data", (key) => {`,
276
+ ` if (key === "\\u0003") { process.stderr.write("\\n"); process.exit(1); }`,
277
+ ` else if (key === "\\r" || key === "\\n") {`,
278
+ ` stdin.setRawMode(false); process.stderr.write("\\n");`,
279
+ ` process.stdout.write(input); process.exit(0);`,
280
+ ` }`,
281
+ ` else if (key === "\\u007f" || key === "\\b") {`,
282
+ ` if (input.length > 0) input = input.slice(0, -1);`,
283
+ ` }`,
284
+ ` else { input += key; }`,
285
+ ` });`,
286
+ `}`
287
+ ].join(`
288
+ `);
289
+ const result = spawnSync("node", ["-e", script], { stdio: ["inherit", "pipe", "inherit"] });
290
+ if (result.status !== 0) {
291
+ process.stderr.write(`
292
+ `);
293
+ process.exit(1);
294
+ }
295
+ return (result.stdout?.toString() ?? "").trim();
296
+ }
212
297
  function printEnvHint(_profiles) {
213
298
  console.log(`\x1B[90mConfig: ${CONFIG_FILE}\x1B[0m`);
214
299
  console.log("\x1B[90mProfiles are picked up automatically — no restart needed.\x1B[0m");
@@ -217,17 +302,22 @@ function profileHelp() {
217
302
  console.log(`meridian profile — manage Claude account profiles
218
303
 
219
304
  Commands:
220
- meridian profile add <name> Add a profile and authenticate
221
- meridian profile list List profiles and auth status
222
- meridian profile remove <name> Remove a profile
223
- meridian profile switch <name> Switch the active profile (requires running proxy)
224
- meridian profile login <name> Re-authenticate an existing profile
305
+ meridian profile add <name> Add a profile via browser login
306
+ meridian profile add <name> --oauth-token [TOKEN] Add a profile from a \`claude setup-token\` value
307
+ (if TOKEN is omitted, you will be prompted; input is hidden)
308
+ meridian profile list List profiles and auth status
309
+ meridian profile remove <name> Remove a profile
310
+ meridian profile switch <name> Switch the active profile (requires running proxy)
311
+ meridian profile login <name> Re-authenticate an existing profile (claude-max only)
225
312
 
226
313
  Examples:
227
- meridian profile add personal # Add personal account
228
- meridian profile add work # Add work account
229
- meridian profile switch work # Switch to work account
230
- meridian profile list # Show all profiles`);
314
+ meridian profile add personal # Add personal account (browser login)
315
+ meridian profile add work # Add work account
316
+ meridian profile add ci --oauth-token # Add headless CI profile (prompted, no echo)
317
+ meridian profile add ci --oauth-token sk-ant-oat01-...
318
+ # Add headless CI profile (token from CLI argument)
319
+ meridian profile switch work # Switch to work account
320
+ meridian profile list # Show all profiles`);
231
321
  }
232
322
  export {
233
323
  profileSwitch,
@@ -235,5 +325,7 @@ export {
235
325
  profileLogin,
236
326
  profileList,
237
327
  profileHelp,
238
- profileAdd
328
+ profileAddOauthToken,
329
+ profileAdd,
330
+ dirsToRemoveOnProfileRemove
239
331
  };
@@ -9,7 +9,7 @@ import {
9
9
  resolveProfile,
10
10
  restoreActiveProfile,
11
11
  setActiveProfile
12
- } from "./cli-vdp9s10c.js";
12
+ } from "./cli-cx463q74.js";
13
13
  import"./cli-340h1chz.js";
14
14
  import"./cli-p9swy5t3.js";
15
15
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"droid.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/droid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAwC9C,eAAO,MAAM,YAAY,EAAE,YA8E1B,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"droid.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/droid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAwC9C,eAAO,MAAM,YAAY,EAAE,YAmF1B,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Resolve the SDK subprocess `cwd:` option, falling back to a known-valid
3
+ * path on the proxy host when the resolved working directory doesn't exist.
4
+ *
5
+ * Background — issue #381:
6
+ * When meridian runs on a remote machine (e.g. accessed over Tailscale)
7
+ * and the client (OpenCode/Crush/etc.) runs on a different machine, the
8
+ * adapter extracts the client's reported working directory and passes it
9
+ * to the SDK as `cwd:`. That path doesn't exist on the proxy host, so
10
+ * `child_process.spawn(claude, { cwd })` fails with ENOENT — which the
11
+ * SDK then reports as the misleading "Claude Code native binary not
12
+ * found at ..." error.
13
+ *
14
+ * Falling back to the proxy's own `process.cwd()` lets the SDK spawn
15
+ * succeed; `clientWorkingDirectory` is tracked separately (and emitted
16
+ * into the model's context via buildCwdNote) so the model still hears
17
+ * about the user's real working directory.
18
+ */
19
+ export interface CwdResolution {
20
+ /** Path passed to the SDK as `cwd:`. Always exists on the proxy host. */
21
+ workingDirectory: string;
22
+ /**
23
+ * The originally-resolved path before existence validation. May not
24
+ * exist on the proxy host. Used as `clientWorkingDirectory` for
25
+ * fingerprint bucketing and the system-prompt cwdNote.
26
+ */
27
+ claimedWorkingDirectory: string;
28
+ /** True if `workingDirectory` differs from `claimedWorkingDirectory`. */
29
+ fellBack: boolean;
30
+ }
31
+ export interface ResolveCwdOpts {
32
+ /** MERIDIAN_WORKDIR / CLAUDE_PROXY_WORKDIR (highest precedence). */
33
+ envOverride: string | undefined;
34
+ /** Adapter's extracted client working directory. */
35
+ adapterCwd: string | undefined;
36
+ /** Last-resort fallback. Must exist; typically `process.cwd()`. */
37
+ fallback: string;
38
+ /** Injection point for tests. Defaults to `node:fs`'s existsSync. */
39
+ exists?: (path: string) => boolean;
40
+ }
41
+ export declare function resolveSdkWorkingDirectory(opts: ResolveCwdOpts): CwdResolution;
42
+ //# sourceMappingURL=cwd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cwd.d.ts","sourceRoot":"","sources":["../../src/proxy/cwd.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,uBAAuB,EAAE,MAAM,CAAA;IAC/B,yEAAyE;IACzE,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,oDAAoD;IACpD,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CACnC;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,cAAc,GAAG,aAAa,CAO9E"}
@@ -15,10 +15,20 @@ export declare function classifyError(errMsg: string): ClassifiedError;
15
15
  * Detect errors caused by an expired or missing OAuth access token.
16
16
  * Triggers an inline token refresh + retry in server.ts.
17
17
  *
18
- * Two distinct messages from the Claude Code CLI:
19
- * - "OAuth token has expired" CLI sent the token, Anthropic API rejected it
20
- * - "Not logged in" — CLI checked expiresAt locally and refused to try
21
- * Both are resolved by refreshing the token.
18
+ * Patterns, in order of specificity:
19
+ * - "OAuth token has expired" / "Not logged in" CLI-emitted (subprocess
20
+ * either got 401 with this wording from Anthropic or detected expiry
21
+ * locally before sending).
22
+ * - "invalid_token" / "token_expired" — RFC 6750 resource-server errors that
23
+ * can appear in the API response body.
24
+ * - "401" + ("authentication" | "unauthorized" | "invalid") — generic 401
25
+ * wrapping. Anthropic's API does not always echo the CLI-specific wording,
26
+ * so without this branch a stale access token returns a generic 401 to the
27
+ * proxy and refresh-and-retry never fires (caller sees the 401).
28
+ *
29
+ * False positives only cost one OAuth round-trip — the refresh is single-shot
30
+ * per request (gated by `tokenRefreshed` in server.ts) and surfaces the
31
+ * original error if it doesn't help.
22
32
  */
23
33
  export declare function isExpiredTokenError(errMsg: string): boolean;
24
34
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CA+G7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,SAAS,CAAA;IAC5D,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAuCpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CA+G7D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,SAAS,CAAA;IAC5D,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAuCpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
@@ -25,8 +25,12 @@ export declare const CANONICAL_HAIKU_MODEL = "claude-haiku-4-5";
25
25
  * Build the ANTHROPIC_DEFAULT_{TYPE}_MODEL env record to apply before the
26
26
  * inherited process env, so user-set shell values still win but unset
27
27
  * variables get Meridian's canonical pins.
28
+ *
29
+ * Accepts an optional `env` arg so unit tests can pass a synthetic env
30
+ * map instead of mutating process.env (which leaks between parallel
31
+ * test files).
28
32
  */
29
- export declare function resolveSdkModelDefaults(): Record<string, string>;
33
+ export declare function resolveSdkModelDefaults(env?: NodeJS.ProcessEnv): Record<string, string>;
30
34
  export interface ClaudeAuthStatus {
31
35
  loggedIn?: boolean;
32
36
  subscriptionType?: string;
@@ -71,6 +75,18 @@ export declare function getAuthCacheInfo(profileId?: string): {
71
75
  * @param envOverrides - Optional env vars for per-profile auth (e.g. CLAUDE_CONFIG_DIR).
72
76
  */
73
77
  export declare function getClaudeAuthStatusAsync(profileId?: string, envOverrides?: Record<string, string>): Promise<ClaudeAuthStatus | null>;
78
+ /**
79
+ * Tag identifying which resolver step produced the path. Surfaced at startup
80
+ * and in `/health` so users can self-diagnose "wrong claude got picked"
81
+ * without having to inspect their PATH manually (closes the diagnostic gap
82
+ * from #478, where a Bun-shimmed `claude` on PATH led to silent failures
83
+ * that looked indistinguishable from any other SDK error).
84
+ */
85
+ export type ClaudeExecutableSource = "env" | "bundled" | "platform-package" | "path-lookup" | "legacy-cli-js";
86
+ export interface ClaudeExecutableInfo {
87
+ path: string;
88
+ source: ClaudeExecutableSource;
89
+ }
74
90
  /**
75
91
  * Resolve the Claude executable path asynchronously (non-blocking).
76
92
  *
@@ -82,6 +98,49 @@ export declare function getClaudeAuthStatusAsync(profileId?: string, envOverride
82
98
  * The promise is cleared in `finally` to allow retry on failure while
83
99
  * cachedClaudePath prevents re-resolution on success.
84
100
  */
101
+ /**
102
+ * Resolver step contract — each tries one source, returns a path on success
103
+ * or null on miss. Failures (thrown errors) are caught by the caller and
104
+ * treated as misses so unresolved sources never block subsequent steps.
105
+ */
106
+ type ResolverDeps = {
107
+ existsSync: (p: string) => boolean;
108
+ statSync: (p: string) => {
109
+ size: number;
110
+ };
111
+ exec: (cmd: string) => Promise<{
112
+ stdout: string;
113
+ }>;
114
+ resolvePackage: (specifier: string) => string;
115
+ envGet: (name: string) => string | undefined;
116
+ platform: NodeJS.Platform;
117
+ arch: string;
118
+ isBun: boolean;
119
+ };
120
+ /**
121
+ * Pure resolver, source-aware variant — runs each step and returns the
122
+ * first hit (path + source tag), or null when all steps miss.
123
+ *
124
+ * Order matters: `env` wins unconditionally (operator escape hatch), then
125
+ * `bundled` (the path the SDK expects), then `platform-package` (postinstall
126
+ * fallback), then `path-lookup` (system PATH — most likely to surface
127
+ * unintended shims, see #478), then `legacy-cli-js` (only matters on stale
128
+ * Bun installs of SDK < 0.2.98).
129
+ */
130
+ export declare function resolveClaudeExecutableWithSource(deps?: ResolverDeps): Promise<ClaudeExecutableInfo | null>;
131
+ /**
132
+ * Pure resolver — returns the path string only. Kept for callers that
133
+ * don't need the source tag (existing behavior; preserves the existing
134
+ * test surface in claude-executable-resolver.test.ts).
135
+ */
136
+ export declare function resolveClaudeExecutable(deps?: ResolverDeps): Promise<string | null>;
137
+ /**
138
+ * Returns the cached resolved-executable info — `null` if
139
+ * `resolveClaudeExecutableAsync` hasn't run yet. Used by `/health` and the
140
+ * startup log so the resolver only runs once and both surfaces see the
141
+ * same answer.
142
+ */
143
+ export declare function getResolvedClaudeExecutableInfo(): ClaudeExecutableInfo | null;
85
144
  export declare function resolveClaudeExecutableAsync(): Promise<string>;
86
145
  /** Reset cached path — for testing only */
87
146
  export declare function resetCachedClaudePath(): void;
@@ -96,4 +155,5 @@ export declare function expireAuthStatusCache(): void;
96
155
  * This happens when the client disconnects mid-stream.
97
156
  */
98
157
  export declare function isClosedControllerError(error: unknown): boolean;
158
+ export {};
99
159
  //# sourceMappingURL=models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/proxy/models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAA;AAEjF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAA;AACrD,eAAO,MAAM,sBAAsB,sBAAsB,CAAA;AACzD,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AAEvD;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMhE;AACD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AA0BD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CA8B7H;AAWD;;;;;;GAMG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,IAAI,OAAO,CAG3D;AAED,0EAA0E;AAC1E,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAIpE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE9D;AAaD;gFACgF;AAChF,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAOzH;AAWD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAuD1I;AAOD;;;;;;;;;;GAUG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC,CAyDpE;AAED,2CAA2C;AAC3C,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAED,kDAAkD;AAClD,wBAAgB,2BAA2B,IAAI,IAAI,CAOlD;AAED;;6DAE6D;AAC7D,wBAAgB,qBAAqB,IAAI,IAAI,CAO5C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG/D"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/proxy/models.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,19 @@ export interface OAuthUsageSnapshot {
37
37
  extraUsage: OAuthExtraUsageInfo | null;
38
38
  fetchedAt: number;
39
39
  }
40
+ /** Minimal fetch shape used by callAnthropic. Avoids `typeof fetch`'s
41
+ * `preconnect` property, which makes test casts unwieldy. */
42
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
43
+ export interface FetchOAuthUsageOpts {
44
+ ttlMs?: number;
45
+ force?: boolean;
46
+ store?: CredentialStore;
47
+ profileId?: string | null;
48
+ claudeConfigDir?: string;
49
+ fetchImpl?: FetchLike;
50
+ }
51
+ /** Test-only setter. Pass `null` to clear. */
52
+ export declare function __setFetchOAuthUsageOverride(fn: ((opts?: FetchOAuthUsageOpts) => Promise<OAuthUsageSnapshot | null>) | null): void;
40
53
  /**
41
54
  * Fetch latest OAuth usage for a specific profile (or the default OAuth
42
55
  * account if none specified). Returns null if no OAuth token is available
@@ -54,14 +67,11 @@ export interface OAuthUsageSnapshot {
54
67
  * @param claudeConfigDir When provided, reads credentials from this dir's
55
68
  * keychain entry (macOS) or `.credentials.json`
56
69
  * (Linux) instead of the platform default.
70
+ * @param fetchImpl Override the fetch implementation (for testing).
71
+ * Defaults to globalThis.fetch.
57
72
  */
58
- export declare function fetchOAuthUsage(opts?: {
59
- ttlMs?: number;
60
- force?: boolean;
61
- store?: CredentialStore;
62
- profileId?: string | null;
63
- claudeConfigDir?: string;
64
- }): Promise<OAuthUsageSnapshot | null>;
73
+ export declare function fetchOAuthUsage(opts?: FetchOAuthUsageOpts): Promise<OAuthUsageSnapshot | null>;
65
74
  /** Test-only / shutdown helper — clears all cached snapshots and pending fetches. */
66
75
  export declare function resetOAuthUsageCache(): void;
76
+ export {};
67
77
  //# sourceMappingURL=oauthUsage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauthUsage.d.ts","sourceRoot":"","sources":["../../src/proxy/oauthUsage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAoD,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAgCvG,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;CAClB;AA0ED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,eAAe,CAAC,IAAI,CAAC,EAAE;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAgDrC;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
1
+ {"version":3,"file":"oauthUsage.d.ts","sourceRoot":"","sources":["../../src/proxy/oauthUsage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAoD,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAgCvG,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;CAClB;AA6DD;8DAC8D;AAC9D,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAmBzE,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAcD,8CAA8C;AAC9C,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,GAC9E,IAAI,CAEN;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,eAAe,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAOpG;AAqDD,qFAAqF;AACrF,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/proxy/plugins/loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAgB,YAAY,EAAE,MAAM,SAAS,CAAA;AAStE,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CASnE;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiIzB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,CAIxE"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/proxy/plugins/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAgB,YAAY,EAAE,MAAM,SAAS,CAAA;AAStE,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CASnE;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CA+IzB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,CAIxE"}
@@ -2,8 +2,9 @@
2
2
  * Multi-profile support.
3
3
  *
4
4
  * Allows a single Meridian instance to route requests to different Claude
5
- * accounts. Each profile is a named auth context (a CLAUDE_CONFIG_DIR for
6
- * Max subscriptions, or an API key for direct API access).
5
+ * accounts. Each profile is a named auth context a CLAUDE_CONFIG_DIR for
6
+ * Max subscriptions, an Anthropic API key for direct API access, or a
7
+ * long-lived OAuth token minted by `claude setup-token`.
7
8
  *
8
9
  * Profile selection priority:
9
10
  * 1. x-meridian-profile request header (per-request override)
@@ -18,11 +19,16 @@
18
19
  * while avoiding synchronous disk I/O on every request.
19
20
  */
20
21
  export declare function loadProfilesFromDisk(): ProfileConfig[];
21
- export type ProfileType = "claude-max" | "api";
22
+ export type ProfileType = "claude-max" | "api" | "oauth-token";
22
23
  export interface ProfileConfig {
23
24
  /** Unique profile identifier (e.g. "personal", "work") */
24
25
  id: string;
25
- /** Auth type — "claude-max" uses CLAUDE_CONFIG_DIR, "api" uses ANTHROPIC_API_KEY */
26
+ /**
27
+ * Auth type. Inferred from the populated credential field when omitted:
28
+ * - `oauthToken` → "oauth-token" (CLAUDE_CODE_OAUTH_TOKEN)
29
+ * - `apiKey`/`baseUrl` → must be combined with explicit `type: "api"`
30
+ * - `claudeConfigDir` → "claude-max" (CLAUDE_CONFIG_DIR)
31
+ */
26
32
  type?: ProfileType;
27
33
  /** Path to .claude config directory (claude-max profiles) */
28
34
  claudeConfigDir?: string;
@@ -30,6 +36,8 @@ export interface ProfileConfig {
30
36
  apiKey?: string;
31
37
  /** Anthropic base URL override (api profiles) */
32
38
  baseUrl?: string;
39
+ /** Long-lived OAuth token from `claude setup-token` (oauth-token profiles) */
40
+ oauthToken?: string;
33
41
  }
34
42
  export interface ResolvedProfile {
35
43
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/proxy/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAcH;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,EAAE,CAkBtD;AAED,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,KAAK,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAA;IACV,oFAAoF;IACpF,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,WAAW,CAAA;IACjB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC5B;AAOD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGxD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAY3E;AAUD;;kEAEkE;AAClE,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,SAAS,GAAG,aAAa,EAAE,CAOjG;AAED,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,SAAS,GAAG,OAAO,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,CAAC,EAAE,MAAM,GACnB,eAAe,CAkBjB;AAqBD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAU7D"}
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/proxy/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,EAAE,CAkBtD;AAED,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,KAAK,GAAG,aAAa,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAA;IACV;;;;;OAKG;IACH,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,WAAW,CAAA;IACjB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC5B;AAOD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGxD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAY3E;AAUD;;kEAEkE;AAClE,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,SAAS,GAAG,aAAa,EAAE,CAOjG;AAED,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,SAAS,GAAG,OAAO,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,CAAC,EAAE,MAAM,GACnB,eAAe,CAkBjB;AAkCD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAU7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAW,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAErF,OAAO,EAAE,0BAA0B,EAAwB,MAAM,oBAAoB,CAAA;AAsBrF,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IACnC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAA;IACrB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAA;IACxB,0CAA0C;IAC1C,WAAW,EAAE,OAAO,CAAA;IACpB,0CAA0C;IAC1C,MAAM,EAAE,OAAO,CAAA;IACf,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,mEAAmE;IACnE,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAA;IAC9D,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5C,yDAAyD;IACzD,gBAAgB,EAAE,OAAO,CAAA;IACzB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAA;IACf,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd,iDAAiD;IACjD,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,+CAA+C;IAC/C,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAA;IACrB,wCAAwC;IACxC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,mEAAmE;IACnE,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAA;IAC1C,0EAA0E;IAC1E,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,CAAA;IACnG,8EAA8E;IAC9E,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,yEAAyE;IACzE,cAAc,CAAC,EAAE,aAAa,EAAE,CAAA;IAChC,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,wDAAwD;IACxD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,+CAA+C;IAC/C,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;IAChC,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;CACjB;AA+BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAkBvE;AAyBD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,gBAAgB,CAuFrE"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdkFeatures.d.ts","sourceRoot":"","sources":["../../src/proxy/sdkFeatures.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,gBAAgB,EAAE,OAAO,CAAA;IACzB,kFAAkF;IAClF,kBAAkB,EAAE,OAAO,CAAA;IAC3B,4DAA4D;IAC5D,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAA;IACf,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;IAC7C,4CAA4C;IAC5C,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iFAAiF;IACjF,YAAY,EAAE,OAAO,CAAA;IACrB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAA;IACjB,uEAAuE;IACvE,qBAAqB,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;AA6DpE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAU1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAOtE;AAKD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAgC5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAInG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAI9D"}
1
+ {"version":3,"file":"sdkFeatures.d.ts","sourceRoot":"","sources":["../../src/proxy/sdkFeatures.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,gBAAgB,EAAE,OAAO,CAAA;IACzB,kFAAkF;IAClF,kBAAkB,EAAE,OAAO,CAAA;IAC3B,4DAA4D;IAC5D,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAA;IACf,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;IAC7C,4CAA4C;IAC5C,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iFAAiF;IACjF,YAAY,EAAE,OAAO,CAAA;IACrB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAA;IACjB,uEAAuE;IACvE,qBAAqB,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;AA6EpE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAU1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAOtE;AAKD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAgC5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAInG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAI9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAgCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AA+N7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA+9EhF;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAoEhG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAgCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AA+N7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA6jFhF;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmFhG"}
@@ -41,6 +41,17 @@ export interface CredentialStore {
41
41
  read(): Promise<CredentialsFile | null>;
42
42
  write(credentials: CredentialsFile): Promise<boolean>;
43
43
  }
44
+ /**
45
+ * Serialize a credentials object to the on-disk / Keychain format Claude Code
46
+ * expects.
47
+ *
48
+ * MUST be compact (no whitespace) — Claude Code's credential parser cannot
49
+ * read pretty-printed JSON and treats the user as logged out when it
50
+ * encounters one. See issue #452.
51
+ *
52
+ * Exported so the regression test can pin the output format directly.
53
+ */
54
+ export declare function serializeCredentials(credentials: CredentialsFile): string;
44
55
  /**
45
56
  * Returns the appropriate credential store for the current platform.
46
57
  *
@@ -66,6 +77,47 @@ export declare function credentialsFilePathForProfile(claudeConfigDir?: string):
66
77
  * @param store Override the credential store (for testing).
67
78
  */
68
79
  export declare function refreshOAuthToken(store?: CredentialStore): Promise<boolean>;
80
+ /**
81
+ * Refresh the access token if it is within `bufferMs` of expiry.
82
+ *
83
+ * Cheap to call before every SDK request: when the token isn't due yet this
84
+ * is just one credential-store read. When it is due, the underlying
85
+ * `refreshOAuthToken()` call is in-flight-deduplicated so concurrent callers
86
+ * share one network round-trip.
87
+ *
88
+ * Returns true when the token is fresh after the call (already valid OR
89
+ * successfully refreshed), false on any failure (no credentials, no
90
+ * expiresAt, refresh request failed). False is non-fatal — the caller
91
+ * proceeds with whatever token is on disk and falls back to the reactive
92
+ * refresh-on-401 path if Anthropic rejects it.
93
+ */
94
+ export declare function ensureFreshToken(store?: CredentialStore, bufferMs?: number): Promise<boolean>;
95
+ /**
96
+ * Start a self-rescheduling timer that refreshes the access token shortly
97
+ * before each expiry — regardless of incoming traffic.
98
+ *
99
+ * Idempotent: a second call while one is already running is a no-op. Safe to
100
+ * call from any code path; returns synchronously and schedules in the
101
+ * background.
102
+ *
103
+ * Why traffic-independent matters: without this, an idle proxy never fires
104
+ * either the proactive (`ensureFreshToken`) or reactive (401-retry) refresh
105
+ * path. Anthropic's OAuth refresh tokens appear to be invalidated server-side
106
+ * after sitting unused for an extended period (observed 2026-05-03: two NAS
107
+ * instances idle past expiry both got `400 invalid_grant` on a manual refresh
108
+ * attempt; only fix was OAuth-flow re-login). Running a refresh every ~8h
109
+ * keeps the refresh chain warm.
110
+ *
111
+ * On `refreshOAuthToken()` failure (network, transient API error, refresh
112
+ * token rejected) we retry every `failureRetryMs` — gives operators a window
113
+ * to `claude login` and have the new tokens picked up automatically on the
114
+ * next tick.
115
+ */
116
+ export declare function startBackgroundRefresh(store?: CredentialStore, bufferMs?: number, failureRetryMs?: number): void;
117
+ /** Stop the background scheduler. Idempotent. */
118
+ export declare function stopBackgroundRefresh(): void;
119
+ /** For testing only. */
120
+ export declare function isBackgroundRefreshActive(): boolean;
69
121
  /** Reset in-flight state — for testing only. */
70
122
  export declare function resetInflightRefresh(): void;
71
123
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/proxy/tokenRefresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED,gEAAgE;AAChE,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,eAAe;IACvB,aAAa,EAAE,gBAAgB,CAAA;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAMD,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IACvC,KAAK,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACtD;AAuGD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAQlG;AAED,uGAAuG;AACvG,wBAAgB,6BAA6B,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AASD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAQjF;AAiED,gDAAgD;AAChD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
1
+ {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/proxy/tokenRefresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED,gEAAgE;AAChE,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,eAAe;IACvB,aAAa,EAAE,gBAAgB,CAAA;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAMD,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IACvC,KAAK,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,eAAe,GAAG,MAAM,CAEzE;AAuGD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAQlG;AAED,uGAAuG;AACvG,wBAAgB,6BAA6B,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AASD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAQjF;AAiED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,CAAC,EAAE,eAAe,EACvB,QAAQ,SAAgB,GACvB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,EAAE,eAAe,EACvB,QAAQ,SAAgB,EACxB,cAAc,SAAgB,GAC7B,IAAI,CAKN;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C;AA0DD,wBAAwB;AACxB,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED,gDAAgD;AAChD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}