@rynfar/meridian 1.41.1 → 1.42.1

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.
@@ -5,7 +5,7 @@ import {
5
5
  resolveProfile,
6
6
  restoreActiveProfile,
7
7
  setActiveProfile
8
- } from "./cli-vdp9s10c.js";
8
+ } from "./cli-cx463q74.js";
9
9
  import {
10
10
  isTrackedPlugin,
11
11
  recordError,
@@ -20,15 +20,30 @@ import {
20
20
  profileBarJs,
21
21
  themeCss
22
22
  } from "./cli-4rqtm83g.js";
23
+ import {
24
+ getAuthCacheInfo,
25
+ getClaudeAuthStatusAsync,
26
+ getResolvedClaudeExecutableInfo,
27
+ hasExtendedContext,
28
+ isClosedControllerError,
29
+ mapModelToClaudeModel,
30
+ recordExtendedContextUnavailable,
31
+ resolveClaudeExecutableAsync,
32
+ resolveSdkModelDefaults,
33
+ stripExtendedContext
34
+ } from "./cli-3jqvrake.js";
23
35
  import {
24
36
  checkPluginConfigured
25
37
  } from "./cli-rtab0qa6.js";
26
38
  import {
27
39
  claudeLog,
28
40
  createPlatformCredentialStore,
41
+ ensureFreshToken,
29
42
  refreshOAuthToken,
43
+ startBackgroundRefresh,
44
+ stopBackgroundRefresh,
30
45
  withClaudeLogContext
31
- } from "./cli-e289rj3k.js";
46
+ } from "./cli-7k1fcprd.js";
32
47
  import {
33
48
  __commonJS,
34
49
  __esm,
@@ -1179,13 +1194,13 @@ __export(exports_sdkFeatures, {
1179
1194
  getAllFeatureConfigs: () => getAllFeatureConfigs
1180
1195
  });
1181
1196
  import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync as renameSync2 } from "node:fs";
1182
- import { join as join5 } from "node:path";
1197
+ import { join as join4 } from "node:path";
1183
1198
  import { homedir as homedir3 } from "node:os";
1184
1199
  function getConfigPath() {
1185
- const dir = join5(homedir3(), ".config", "meridian");
1200
+ const dir = join4(homedir3(), ".config", "meridian");
1186
1201
  if (!existsSync5(dir))
1187
1202
  mkdirSync2(dir, { recursive: true });
1188
- return join5(dir, "sdk-features.json");
1203
+ return join4(dir, "sdk-features.json");
1189
1204
  }
1190
1205
  function readConfig() {
1191
1206
  const now = Date.now();
@@ -3708,7 +3723,7 @@ var serve = (options, listeningListener) => {
3708
3723
 
3709
3724
  // src/proxy/server.ts
3710
3725
  import { homedir as homedir4 } from "node:os";
3711
- import { join as join6 } from "node:path";
3726
+ import { join as join5 } from "node:path";
3712
3727
  import { query } from "@anthropic-ai/claude-agent-sdk";
3713
3728
 
3714
3729
  // src/proxy/rateLimitStore.ts
@@ -3788,8 +3803,8 @@ async function readAccessToken(store) {
3788
3803
  const creds = await store.read();
3789
3804
  return creds?.claudeAiOauth?.accessToken ?? null;
3790
3805
  }
3791
- async function callAnthropic(token, signal) {
3792
- const res = await fetch(OAUTH_USAGE_URL, {
3806
+ async function callAnthropic(token, fetchImpl, signal) {
3807
+ const res = await fetchImpl(OAUTH_USAGE_URL, {
3793
3808
  headers: {
3794
3809
  Authorization: `Bearer ${token}`,
3795
3810
  "anthropic-beta": OAUTH_BETA_HEADER,
@@ -3801,9 +3816,17 @@ async function callAnthropic(token, signal) {
3801
3816
  return { __status: res.status };
3802
3817
  return await res.json();
3803
3818
  }
3819
+ var _testOverride = null;
3804
3820
  async function fetchOAuthUsage(opts) {
3821
+ if (_testOverride && !opts?.fetchImpl && !opts?.store) {
3822
+ return _testOverride(opts);
3823
+ }
3824
+ return fetchOAuthUsageImpl(opts);
3825
+ }
3826
+ async function fetchOAuthUsageImpl(opts) {
3805
3827
  const ttl = opts?.ttlMs ?? CACHE_TTL_MS_DEFAULT;
3806
3828
  const cacheKey2 = opts?.profileId ?? DEFAULT_KEY;
3829
+ const fetchImpl = opts?.fetchImpl ?? globalThis.fetch;
3807
3830
  if (!opts?.force) {
3808
3831
  const cached = cacheByProfile.get(cacheKey2);
3809
3832
  if (cached && Date.now() - cached.fetchedAt < ttl)
@@ -3818,7 +3841,7 @@ async function fetchOAuthUsage(opts) {
3818
3841
  const token = await readAccessToken(store);
3819
3842
  if (!token)
3820
3843
  return null;
3821
- let result = await callAnthropic(token);
3844
+ let result = await callAnthropic(token, fetchImpl);
3822
3845
  if ("__status" in result && result.__status === 401) {
3823
3846
  claudeLog("oauth_usage.token_refresh_attempt", { profile: cacheKey2 });
3824
3847
  const refreshed = await refreshOAuthToken(store);
@@ -3829,7 +3852,7 @@ async function fetchOAuthUsage(opts) {
3829
3852
  const newToken = await readAccessToken(store);
3830
3853
  if (!newToken)
3831
3854
  return null;
3832
- result = await callAnthropic(newToken);
3855
+ result = await callAnthropic(newToken, fetchImpl);
3833
3856
  }
3834
3857
  if ("__status" in result) {
3835
3858
  claudeLog("oauth_usage.upstream_error", { profile: cacheKey2, status: result.__status });
@@ -3849,6 +3872,17 @@ async function fetchOAuthUsage(opts) {
3849
3872
  return promise;
3850
3873
  }
3851
3874
 
3875
+ // src/proxy/cwd.ts
3876
+ import { existsSync } from "node:fs";
3877
+ function resolveSdkWorkingDirectory(opts) {
3878
+ const exists = opts.exists ?? existsSync;
3879
+ const claimed = opts.envOverride || opts.adapterCwd || opts.fallback;
3880
+ if (exists(claimed)) {
3881
+ return { workingDirectory: claimed, claimedWorkingDirectory: claimed, fellBack: false };
3882
+ }
3883
+ return { workingDirectory: opts.fallback, claimedWorkingDirectory: claimed, fellBack: true };
3884
+ }
3885
+
3852
3886
  // src/proxy/types.ts
3853
3887
  var DEFAULT_PROXY_CONFIG = {
3854
3888
  port: 3456,
@@ -3945,8 +3979,8 @@ function createRequestContext(params) {
3945
3979
  };
3946
3980
  }
3947
3981
  // src/proxy/server.ts
3948
- import { exec as execCallback2 } from "child_process";
3949
- import { promisify as promisify3 } from "util";
3982
+ import { exec as execCallback } from "child_process";
3983
+ import { promisify as promisify2 } from "util";
3950
3984
  import { randomUUID } from "crypto";
3951
3985
 
3952
3986
  // src/proxy/passthroughTools.ts
@@ -8447,7 +8481,7 @@ class MemoryDiagnosticLogStore {
8447
8481
  }
8448
8482
  var diagnosticLog = new MemoryDiagnosticLogStore;
8449
8483
  // src/telemetry/routes.ts
8450
- import { existsSync, readFileSync } from "node:fs";
8484
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
8451
8485
  import { resolve, dirname } from "node:path";
8452
8486
  import { fileURLToPath } from "node:url";
8453
8487
 
@@ -8801,7 +8835,7 @@ timer = setInterval(refresh, 5000);
8801
8835
 
8802
8836
  // src/telemetry/routes.ts
8803
8837
  var _iconPath = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "assets", "icon.svg");
8804
- var _iconSvg = existsSync(_iconPath) ? readFileSync(_iconPath, "utf-8") : null;
8838
+ var _iconSvg = existsSync2(_iconPath) ? readFileSync(_iconPath, "utf-8") : null;
8805
8839
  function createTelemetryRoutes() {
8806
8840
  const routes = new Hono2;
8807
8841
  routes.get("/", (c) => {
@@ -9139,7 +9173,13 @@ function classifyError(errMsg) {
9139
9173
  }
9140
9174
  function isExpiredTokenError(errMsg) {
9141
9175
  const lower = errMsg.toLowerCase();
9142
- return lower.includes("oauth token has expired") || lower.includes("not logged in");
9176
+ if (lower.includes("oauth token has expired") || lower.includes("not logged in"))
9177
+ return true;
9178
+ if (lower.includes("invalid_token") || lower.includes("token_expired"))
9179
+ return true;
9180
+ if (lower.includes("401") && (lower.includes("authentication") || lower.includes("unauthorized") || lower.includes("invalid")))
9181
+ return true;
9182
+ return false;
9143
9183
  }
9144
9184
  function isStaleSessionError(error) {
9145
9185
  if (!(error instanceof Error))
@@ -9232,252 +9272,6 @@ function formatSdkTermination(t, ctx) {
9232
9272
  return `sdk_termination ${parts.join(" ")}`;
9233
9273
  }
9234
9274
 
9235
- // src/proxy/models.ts
9236
- import { exec as execCallback } from "child_process";
9237
- import { existsSync as existsSync2, statSync } from "fs";
9238
- import { fileURLToPath as fileURLToPath2 } from "url";
9239
- import { join as join2, dirname as dirname2 } from "path";
9240
- import { promisify } from "util";
9241
- var exec = promisify(execCallback);
9242
- var STUB_SIZE_THRESHOLD = 4096;
9243
- var CANONICAL_OPUS_MODEL = "claude-opus-4-7";
9244
- var CANONICAL_SONNET_MODEL = "claude-sonnet-4-6";
9245
- var CANONICAL_HAIKU_MODEL = "claude-haiku-4-5";
9246
- function resolveSdkModelDefaults() {
9247
- return {
9248
- ANTHROPIC_DEFAULT_OPUS_MODEL: process.env.MERIDIAN_DEFAULT_OPUS_MODEL ?? CANONICAL_OPUS_MODEL,
9249
- ANTHROPIC_DEFAULT_SONNET_MODEL: process.env.MERIDIAN_DEFAULT_SONNET_MODEL ?? CANONICAL_SONNET_MODEL,
9250
- ANTHROPIC_DEFAULT_HAIKU_MODEL: process.env.MERIDIAN_DEFAULT_HAIKU_MODEL ?? CANONICAL_HAIKU_MODEL
9251
- };
9252
- }
9253
- var AUTH_STATUS_CACHE_TTL_MS = 60000;
9254
- var AUTH_STATUS_FAILURE_TTL_MS = 5000;
9255
- var cachedAuthStatus = null;
9256
- var lastKnownGoodAuthStatus = null;
9257
- var cachedAuthStatusAt = 0;
9258
- var cachedAuthStatusIsFailure = false;
9259
- var cachedAuthStatusPromise = null;
9260
- function supports1mContext(model) {
9261
- if (model.includes("4-5") || model.includes("4.5"))
9262
- return false;
9263
- return true;
9264
- }
9265
- function mapModelToClaudeModel(model, subscriptionType, agentMode) {
9266
- if (model.includes("haiku"))
9267
- return "haiku";
9268
- const use1m = supports1mContext(model);
9269
- const isSubagent = agentMode === "subagent";
9270
- if (model.includes("opus")) {
9271
- if (use1m && !isSubagent && !isExtendedContextKnownUnavailable())
9272
- return "opus[1m]";
9273
- return "opus";
9274
- }
9275
- const sonnetOverride = process.env.MERIDIAN_SONNET_MODEL ?? process.env.CLAUDE_PROXY_SONNET_MODEL;
9276
- if (sonnetOverride === "sonnet[1m]") {
9277
- if (!use1m || isSubagent || isExtendedContextKnownUnavailable())
9278
- return "sonnet";
9279
- return "sonnet[1m]";
9280
- }
9281
- return "sonnet";
9282
- }
9283
- var EXTRA_USAGE_RETRY_MS = 60 * 60 * 1000;
9284
- var extraUsageUnavailableAt = 0;
9285
- function recordExtendedContextUnavailable() {
9286
- extraUsageUnavailableAt = Date.now();
9287
- }
9288
- function isExtendedContextKnownUnavailable() {
9289
- return extraUsageUnavailableAt > 0 && Date.now() - extraUsageUnavailableAt < EXTRA_USAGE_RETRY_MS;
9290
- }
9291
- function stripExtendedContext(model) {
9292
- if (model === "opus[1m]")
9293
- return "opus";
9294
- if (model === "sonnet[1m]")
9295
- return "sonnet";
9296
- return model;
9297
- }
9298
- function hasExtendedContext(model) {
9299
- return model.endsWith("[1m]");
9300
- }
9301
- var profileAuthCaches = new Map;
9302
- function getAuthCacheInfo(profileId) {
9303
- if (!profileId) {
9304
- return { lastCheckedAt: cachedAuthStatusAt, lastSuccessAt: cachedAuthStatusIsFailure ? 0 : cachedAuthStatusAt, isFailure: cachedAuthStatusIsFailure };
9305
- }
9306
- const cache = profileAuthCaches.get(profileId);
9307
- if (!cache)
9308
- return { lastCheckedAt: 0, lastSuccessAt: 0, isFailure: false };
9309
- return { lastCheckedAt: cache.at, lastSuccessAt: cache.lastSuccessAt, isFailure: cache.isFailure };
9310
- }
9311
- function getAuthCache(key) {
9312
- let cache = profileAuthCaches.get(key);
9313
- if (!cache) {
9314
- cache = { status: null, lastKnownGood: null, at: 0, isFailure: false, promise: null, lastSuccessAt: 0 };
9315
- profileAuthCaches.set(key, cache);
9316
- }
9317
- return cache;
9318
- }
9319
- async function getClaudeAuthStatusAsync(profileId, envOverrides) {
9320
- const isDefault = !profileId;
9321
- const cache = isDefault ? null : getAuthCache(profileId);
9322
- const c_status = cache ? cache.status : cachedAuthStatus;
9323
- const c_lastKnownGood = cache ? cache.lastKnownGood : lastKnownGoodAuthStatus;
9324
- const c_at = cache ? cache.at : cachedAuthStatusAt;
9325
- const c_isFailure = cache ? cache.isFailure : cachedAuthStatusIsFailure;
9326
- let c_promise = cache ? cache.promise : cachedAuthStatusPromise;
9327
- const ttl = c_isFailure ? AUTH_STATUS_FAILURE_TTL_MS : AUTH_STATUS_CACHE_TTL_MS;
9328
- if (c_at > 0 && Date.now() - c_at < ttl) {
9329
- return c_status ?? c_lastKnownGood;
9330
- }
9331
- if (c_promise)
9332
- return c_promise;
9333
- c_promise = (async () => {
9334
- try {
9335
- const { stdout } = await exec("claude auth status", {
9336
- timeout: 5000,
9337
- ...envOverrides ? { env: { ...process.env, ...envOverrides } } : {}
9338
- });
9339
- const parsed = JSON.parse(stdout);
9340
- if (cache) {
9341
- cache.status = parsed;
9342
- cache.lastKnownGood = parsed;
9343
- cache.at = Date.now();
9344
- cache.isFailure = false;
9345
- cache.lastSuccessAt = Date.now();
9346
- } else {
9347
- cachedAuthStatus = parsed;
9348
- lastKnownGoodAuthStatus = parsed;
9349
- cachedAuthStatusAt = Date.now();
9350
- cachedAuthStatusIsFailure = false;
9351
- }
9352
- return parsed;
9353
- } catch {
9354
- if (cache) {
9355
- cache.isFailure = true;
9356
- cache.at = Date.now();
9357
- cache.status = null;
9358
- return cache.lastKnownGood;
9359
- } else {
9360
- cachedAuthStatusIsFailure = true;
9361
- cachedAuthStatusAt = Date.now();
9362
- cachedAuthStatus = null;
9363
- return lastKnownGoodAuthStatus;
9364
- }
9365
- }
9366
- })();
9367
- if (cache)
9368
- cache.promise = c_promise;
9369
- else
9370
- cachedAuthStatusPromise = c_promise;
9371
- try {
9372
- return await c_promise;
9373
- } finally {
9374
- if (cache)
9375
- cache.promise = null;
9376
- else
9377
- cachedAuthStatusPromise = null;
9378
- }
9379
- }
9380
- var cachedClaudePath = null;
9381
- var cachedClaudePathPromise = null;
9382
- var DEFAULT_DEPS = {
9383
- existsSync: existsSync2,
9384
- statSync: (p) => statSync(p),
9385
- exec,
9386
- resolvePackage: (specifier) => fileURLToPath2(import.meta.resolve(specifier)),
9387
- envGet: (name) => process.env[name],
9388
- platform: process.platform,
9389
- arch: process.arch,
9390
- isBun: typeof process.versions.bun !== "undefined"
9391
- };
9392
- function tryEnvOverride(deps) {
9393
- const explicit = deps.envGet("MERIDIAN_CLAUDE_PATH");
9394
- if (!explicit)
9395
- return null;
9396
- return deps.existsSync(explicit) ? explicit : null;
9397
- }
9398
- function tryBundledBinary(deps) {
9399
- try {
9400
- const pkgPath = deps.resolvePackage("@anthropic-ai/claude-code/package.json");
9401
- const bundled = join2(dirname2(pkgPath), "bin", "claude.exe");
9402
- if (!deps.existsSync(bundled))
9403
- return null;
9404
- const size = deps.statSync(bundled).size;
9405
- if (size <= STUB_SIZE_THRESHOLD)
9406
- return null;
9407
- return bundled;
9408
- } catch {
9409
- return null;
9410
- }
9411
- }
9412
- function tryPlatformPackage(deps) {
9413
- const binName = deps.platform === "win32" ? "claude.exe" : "claude";
9414
- const candidates = [`@anthropic-ai/claude-code-${deps.platform}-${deps.arch}`];
9415
- if (deps.platform === "linux") {
9416
- candidates.push(`@anthropic-ai/claude-code-${deps.platform}-${deps.arch}-musl`);
9417
- }
9418
- for (const pkg of candidates) {
9419
- try {
9420
- const pkgJson = deps.resolvePackage(`${pkg}/package.json`);
9421
- const candidate = join2(dirname2(pkgJson), binName);
9422
- if (deps.existsSync(candidate))
9423
- return candidate;
9424
- } catch {}
9425
- }
9426
- return null;
9427
- }
9428
- async function tryPathLookup(deps) {
9429
- const cmd = deps.platform === "win32" ? "where claude" : "which claude";
9430
- try {
9431
- const { stdout } = await deps.exec(cmd);
9432
- const candidates = stdout.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
9433
- for (const candidate of candidates) {
9434
- if (deps.platform === "win32" && candidate.startsWith("/"))
9435
- continue;
9436
- if (deps.existsSync(candidate))
9437
- return candidate;
9438
- }
9439
- } catch {}
9440
- return null;
9441
- }
9442
- function tryLegacySdkCliJs(deps) {
9443
- if (!deps.isBun)
9444
- return null;
9445
- try {
9446
- const sdkPath = deps.resolvePackage("@anthropic-ai/claude-agent-sdk");
9447
- const cliJs = join2(dirname2(sdkPath), "cli.js");
9448
- return deps.existsSync(cliJs) ? cliJs : null;
9449
- } catch {
9450
- return null;
9451
- }
9452
- }
9453
- async function resolveClaudeExecutable(deps = DEFAULT_DEPS) {
9454
- return tryEnvOverride(deps) ?? tryBundledBinary(deps) ?? tryPlatformPackage(deps) ?? await tryPathLookup(deps) ?? tryLegacySdkCliJs(deps);
9455
- }
9456
- async function resolveClaudeExecutableAsync() {
9457
- if (cachedClaudePath)
9458
- return cachedClaudePath;
9459
- if (cachedClaudePathPromise)
9460
- return cachedClaudePathPromise;
9461
- cachedClaudePathPromise = (async () => {
9462
- const resolved = await resolveClaudeExecutable();
9463
- if (resolved) {
9464
- cachedClaudePath = resolved;
9465
- return resolved;
9466
- }
9467
- throw new Error("Could not find Claude Code executable. Install via: npm install -g @anthropic-ai/claude-code, " + "or set MERIDIAN_CLAUDE_PATH=/path/to/claude to point at an existing binary.");
9468
- })();
9469
- try {
9470
- return await cachedClaudePathPromise;
9471
- } finally {
9472
- cachedClaudePathPromise = null;
9473
- }
9474
- }
9475
- function isClosedControllerError(error) {
9476
- if (!(error instanceof Error))
9477
- return false;
9478
- return error.message.includes("Controller is already closed");
9479
- }
9480
-
9481
9275
  // src/proxy/openai.ts
9482
9276
  function extractOpenAiContent(content) {
9483
9277
  if (typeof content === "string")
@@ -10995,8 +10789,8 @@ function detectAdapter(c) {
10995
10789
  import { createSdkMcpServer as createSdkMcpServer2, tool } from "@anthropic-ai/claude-agent-sdk";
10996
10790
  import * as fs from "node:fs/promises";
10997
10791
  import * as path2 from "node:path";
10998
- import { exec as exec2 } from "node:child_process";
10999
- import { promisify as promisify2 } from "node:util";
10792
+ import { exec } from "node:child_process";
10793
+ import { promisify } from "node:util";
11000
10794
 
11001
10795
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
11002
10796
  var balanced = (a, b, str) => {
@@ -12433,7 +12227,7 @@ minimatch.escape = escape;
12433
12227
  minimatch.unescape = unescape;
12434
12228
 
12435
12229
  // node_modules/glob/dist/esm/glob.js
12436
- import { fileURLToPath as fileURLToPath4 } from "node:url";
12230
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
12437
12231
 
12438
12232
  // node_modules/lru-cache/dist/esm/index.js
12439
12233
  var defaultPerf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
@@ -13596,7 +13390,7 @@ class LRUCache {
13596
13390
 
13597
13391
  // node_modules/path-scurry/dist/esm/index.js
13598
13392
  import { posix, win32 } from "node:path";
13599
- import { fileURLToPath as fileURLToPath3 } from "node:url";
13393
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
13600
13394
  import { lstatSync, readdir as readdirCB, readdirSync, readlinkSync, realpathSync as rps } from "fs";
13601
13395
  import * as actualFS from "node:fs";
13602
13396
  import { lstat, readdir, readlink, realpath } from "node:fs/promises";
@@ -15051,7 +14845,7 @@ class PathScurryBase {
15051
14845
  constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS } = {}) {
15052
14846
  this.#fs = fsFromOption(fs);
15053
14847
  if (cwd instanceof URL || cwd.startsWith("file://")) {
15054
- cwd = fileURLToPath3(cwd);
14848
+ cwd = fileURLToPath2(cwd);
15055
14849
  }
15056
14850
  const cwdPath = pathImpl.resolve(cwd);
15057
14851
  this.roots = Object.create(null);
@@ -16355,7 +16149,7 @@ class Glob {
16355
16149
  if (!opts.cwd) {
16356
16150
  this.cwd = "";
16357
16151
  } else if (opts.cwd instanceof URL || opts.cwd.startsWith("file://")) {
16358
- opts.cwd = fileURLToPath4(opts.cwd);
16152
+ opts.cwd = fileURLToPath3(opts.cwd);
16359
16153
  }
16360
16154
  this.cwd = opts.cwd || "";
16361
16155
  this.root = opts.root;
@@ -16546,7 +16340,7 @@ var glob = Object.assign(glob_, {
16546
16340
  glob.glob = glob;
16547
16341
 
16548
16342
  // src/mcpTools.ts
16549
- var execAsync = promisify2(exec2);
16343
+ var execAsync = promisify(exec);
16550
16344
  var getCwd = () => process.env.MERIDIAN_WORKDIR ?? process.env.CLAUDE_PROXY_WORKDIR ?? process.cwd();
16551
16345
  function createOpencodeMcpServer() {
16552
16346
  return createSdkMcpServer2({
@@ -16686,6 +16480,8 @@ function createOpencodeMcpServer() {
16686
16480
  function stripConfigDir(env2) {
16687
16481
  if (!("CLAUDE_CONFIG_DIR" in env2))
16688
16482
  return env2;
16483
+ if (env2.CLAUDE_CODE_OAUTH_TOKEN)
16484
+ return env2;
16689
16485
  const out = { ...env2 };
16690
16486
  delete out.CLAUDE_CONFIG_DIR;
16691
16487
  return out;
@@ -16719,6 +16515,8 @@ function resolveSystemPrompt(systemContext, passthrough, settingSources, codeSys
16719
16515
  }
16720
16516
  if (append)
16721
16517
  return { systemPrompt: append };
16518
+ if (codeSystemPrompt === false)
16519
+ return { systemPrompt: "" };
16722
16520
  return {};
16723
16521
  }
16724
16522
  function buildQueryOptions(ctx) {
@@ -16774,6 +16572,8 @@ function buildQueryOptions(ctx) {
16774
16572
  allowDangerouslySkipPermissions: true,
16775
16573
  ...resolveSystemPrompt(systemContext, passthrough, settingSources, codeSystemPrompt, clientSystemPrompt, cwdNote),
16776
16574
  ...passthrough ? {
16575
+ tools: [],
16576
+ settingSources: [],
16777
16577
  disallowedTools: [...allBlockedTools],
16778
16578
  ...passthroughMcp ? {
16779
16579
  allowedTools: [...passthroughMcp.toolNames],
@@ -16831,7 +16631,8 @@ function getAdapterTransforms(adapterName) {
16831
16631
 
16832
16632
  // src/proxy/plugins/loader.ts
16833
16633
  import { readdirSync as readdirSync2, readFileSync as readFileSync2, existsSync as existsSync3 } from "fs";
16834
- import { join as join3, isAbsolute as isAbsolute2, extname } from "path";
16634
+ import { join as join2, isAbsolute as isAbsolute2, extname } from "path";
16635
+ import { pathToFileURL } from "url";
16835
16636
 
16836
16637
  // src/proxy/plugins/validation.ts
16837
16638
  var KNOWN_ADAPTERS = ["opencode", "crush", "droid", "pi", "forgecode", "passthrough"];
@@ -16915,7 +16716,7 @@ async function loadPlugins(pluginDir, configPath) {
16915
16716
  const loaded = [];
16916
16717
  const seenNames = new Set;
16917
16718
  for (const { filename, entry } of ordered) {
16918
- const filePath = isAbsolute2(filename) ? filename : join3(pluginDir, filename);
16719
+ const filePath = isAbsolute2(filename) ? filename : join2(pluginDir, filename);
16919
16720
  if (entry && !entry.enabled) {
16920
16721
  loaded.push({
16921
16722
  name: filename,
@@ -16928,7 +16729,8 @@ async function loadPlugins(pluginDir, configPath) {
16928
16729
  }
16929
16730
  try {
16930
16731
  const cacheBuster = `?t=${Date.now()}-${++loadCounter}`;
16931
- const mod = await import(filePath + cacheBuster);
16732
+ const specifier = process.platform === "win32" ? pathToFileURL(filePath).href + cacheBuster : filePath + cacheBuster;
16733
+ const mod = await import(specifier);
16932
16734
  const exported = mod.default ?? mod;
16933
16735
  const transforms = Array.isArray(exported) ? exported : [exported];
16934
16736
  for (const item of transforms) {
@@ -17291,12 +17093,12 @@ import {
17291
17093
  openSync,
17292
17094
  readFileSync as readFileSync3,
17293
17095
  renameSync,
17294
- statSync as statSync2,
17096
+ statSync,
17295
17097
  unlinkSync,
17296
17098
  writeFileSync
17297
17099
  } from "node:fs";
17298
17100
  import { homedir as homedir2 } from "node:os";
17299
- import { join as join4 } from "node:path";
17101
+ import { join as join3 } from "node:path";
17300
17102
  var DEFAULT_MAX_STORED_SESSIONS = 1e4;
17301
17103
  var STALE_LOCK_THRESHOLD_MS = 30000;
17302
17104
  function getMaxStoredSessions() {
@@ -17320,7 +17122,7 @@ function acquireLock(lockPath) {
17320
17122
  return false;
17321
17123
  }
17322
17124
  try {
17323
- const stat = statSync2(lockPath);
17125
+ const stat = statSync(lockPath);
17324
17126
  if (Date.now() - stat.mtimeMs > STALE_LOCK_THRESHOLD_MS) {
17325
17127
  unlinkSync(lockPath);
17326
17128
  const fd = openSync(lockPath, "wx");
@@ -17347,11 +17149,11 @@ function getStorePath() {
17347
17149
  if (!existsSync4(dir)) {
17348
17150
  mkdirSync(dir, { recursive: true });
17349
17151
  }
17350
- return join4(dir, "sessions.json");
17152
+ return join3(dir, "sessions.json");
17351
17153
  }
17352
17154
  function getDefaultCacheDir() {
17353
- const newDir = join4(homedir2(), ".cache", "meridian");
17354
- const oldDir = join4(homedir2(), ".cache", "opencode-claude-max-proxy");
17155
+ const newDir = join3(homedir2(), ".cache", "meridian");
17156
+ const oldDir = join3(homedir2(), ".cache", "opencode-claude-max-proxy");
17355
17157
  if (existsSync4(newDir))
17356
17158
  return newDir;
17357
17159
  if (existsSync4(oldDir)) {
@@ -17691,7 +17493,7 @@ function storeSession(sessionId, messages, claudeSessionId, workingDirectory, sd
17691
17493
  }
17692
17494
 
17693
17495
  // src/proxy/server.ts
17694
- var exec3 = promisify3(execCallback2);
17496
+ var exec2 = promisify2(execCallback);
17695
17497
  var claudeExecutable = "";
17696
17498
  var MULTIMODAL_TYPES = new Set(["image", "document", "file"]);
17697
17499
  function hasMultimodalContent(content) {
@@ -17869,8 +17671,8 @@ function createProxyServer(config = {}) {
17869
17671
  const sessionDiscoveredTools = new Map;
17870
17672
  const sessionToolCache = new Map;
17871
17673
  const sessionMcpCache = new LRUMap(getMaxSessionsLimit());
17872
- const pluginDir = finalConfig.pluginDir ?? join6(homedir4(), ".config", "meridian", "plugins");
17873
- const pluginConfigPath = finalConfig.pluginConfigPath ?? join6(homedir4(), ".config", "meridian", "plugins.json");
17674
+ const pluginDir = finalConfig.pluginDir ?? join5(homedir4(), ".config", "meridian", "plugins");
17675
+ const pluginConfigPath = finalConfig.pluginConfigPath ?? join5(homedir4(), ".config", "meridian", "plugins.json");
17874
17676
  let loadedPlugins = [];
17875
17677
  let pluginTransforms = [];
17876
17678
  const app = new Hono2;
@@ -17884,6 +17686,8 @@ function createProxyServer(config = {}) {
17884
17686
  app.use("/profiles", requireAuth);
17885
17687
  app.use("/plugins/*", requireAuth);
17886
17688
  app.use("/plugins", requireAuth);
17689
+ app.use("/settings/*", requireAuth);
17690
+ app.use("/settings", requireAuth);
17887
17691
  app.use("/auth/*", requireAuth);
17888
17692
  app.get("/", (c) => {
17889
17693
  const accept = c.req.header("accept") || "";
@@ -17944,8 +17748,19 @@ function createProxyServer(config = {}) {
17944
17748
  const agentMode = c.req.header("x-opencode-agent-mode") ?? null;
17945
17749
  const requestSource = c.req.header("x-meridian-source")?.slice(0, 64) || undefined;
17946
17750
  let model = mapModelToClaudeModel(body.model || "sonnet", authStatus?.subscriptionType, agentMode);
17947
- const workingDirectory = (process.env.MERIDIAN_WORKDIR ?? process.env.CLAUDE_PROXY_WORKDIR) || adapter.extractWorkingDirectory(body) || process.cwd();
17948
- const clientWorkingDirectory = adapter.extractClientWorkingDirectory?.(body) || workingDirectory;
17751
+ const cwdResolution = resolveSdkWorkingDirectory({
17752
+ envOverride: process.env.MERIDIAN_WORKDIR ?? process.env.CLAUDE_PROXY_WORKDIR,
17753
+ adapterCwd: adapter.extractWorkingDirectory(body),
17754
+ fallback: process.cwd()
17755
+ });
17756
+ const workingDirectory = cwdResolution.workingDirectory;
17757
+ if (cwdResolution.fellBack) {
17758
+ claudeLog("cwd_fallback", {
17759
+ claimed: cwdResolution.claimedWorkingDirectory,
17760
+ usedInstead: workingDirectory
17761
+ });
17762
+ }
17763
+ const clientWorkingDirectory = adapter.extractClientWorkingDirectory?.(body) || cwdResolution.claimedWorkingDirectory;
17949
17764
  const {
17950
17765
  ANTHROPIC_API_KEY: _dropApiKey,
17951
17766
  ANTHROPIC_BASE_URL: _dropBaseUrl,
@@ -18224,6 +18039,7 @@ function createProxyServer(config = {}) {
18224
18039
  const RATE_LIMIT_BASE_DELAY_MS = 1000;
18225
18040
  const response = async function* () {
18226
18041
  let rateLimitRetries = 0;
18042
+ await ensureFreshToken().catch(() => {});
18227
18043
  let tokenRefreshed = false;
18228
18044
  while (true) {
18229
18045
  let didYieldContent = false;
@@ -18625,6 +18441,7 @@ Subprocess stderr: ${stderrOutput}`;
18625
18441
  const RATE_LIMIT_BASE_DELAY_MS = 1000;
18626
18442
  const response = async function* () {
18627
18443
  let rateLimitRetries = 0;
18444
+ await ensureFreshToken().catch(() => {});
18628
18445
  let tokenRefreshed = false;
18629
18446
  while (true) {
18630
18447
  let didYieldClientEvent = false;
@@ -19442,6 +19259,7 @@ data: ${JSON.stringify({
19442
19259
  auth: { loggedIn: false }
19443
19260
  }, 503);
19444
19261
  }
19262
+ const claudeExecutableInfo = getResolvedClaudeExecutableInfo();
19445
19263
  return c.json({
19446
19264
  status: "healthy",
19447
19265
  version: serverVersion,
@@ -19451,6 +19269,7 @@ data: ${JSON.stringify({
19451
19269
  subscriptionType: auth.subscriptionType
19452
19270
  },
19453
19271
  mode: envBool("PASSTHROUGH") ? "passthrough" : "internal",
19272
+ ...claudeExecutableInfo ? { claudeExecutable: claudeExecutableInfo } : {},
19454
19273
  plugin: { opencode: checkPluginConfigured() ? "configured" : "not-configured" }
19455
19274
  });
19456
19275
  } catch {
@@ -19563,9 +19382,16 @@ data: ${JSON.stringify({
19563
19382
  if (!anthropicBody) {
19564
19383
  return c.json({ type: "error", error: { type: "invalid_request_error", message: "messages: Field required" } }, 400);
19565
19384
  }
19385
+ const internalHeaders = { "Content-Type": "application/json" };
19386
+ const xApiKey = c.req.header("x-api-key");
19387
+ if (xApiKey)
19388
+ internalHeaders["x-api-key"] = xApiKey;
19389
+ const authz = c.req.header("authorization");
19390
+ if (authz)
19391
+ internalHeaders["authorization"] = authz;
19566
19392
  const internalReq = new Request("http://internal/v1/messages", {
19567
19393
  method: "POST",
19568
- headers: { "Content-Type": "application/json" },
19394
+ headers: internalHeaders,
19569
19395
  body: JSON.stringify(anthropicBody)
19570
19396
  });
19571
19397
  const internalRes = await app.fetch(internalReq);
@@ -19844,6 +19670,10 @@ async function startProxyServer(config = {}) {
19844
19670
  console.log(`Telemetry dashboard: http://${finalConfig.host}:${info.port}/telemetry`);
19845
19671
  const pins = resolveSdkModelDefaults();
19846
19672
  console.log(`Model pins: opus=${pins.ANTHROPIC_DEFAULT_OPUS_MODEL} sonnet=${pins.ANTHROPIC_DEFAULT_SONNET_MODEL} haiku=${pins.ANTHROPIC_DEFAULT_HAIKU_MODEL}`);
19673
+ const claudeInfo = getResolvedClaudeExecutableInfo();
19674
+ if (claudeInfo) {
19675
+ console.log(`Claude executable: ${claudeInfo.path} (resolved via ${claudeInfo.source})`);
19676
+ }
19847
19677
  console.log(`
19848
19678
  Point any Anthropic-compatible tool at this endpoint:`);
19849
19679
  console.log(` ANTHROPIC_API_KEY=x ANTHROPIC_BASE_URL=http://${finalConfig.host}:${info.port}`);
@@ -19865,6 +19695,7 @@ Or use a different port:`);
19865
19695
  console.error(` MERIDIAN_PORT=4567 meridian`);
19866
19696
  }
19867
19697
  });
19698
+ startBackgroundRefresh();
19868
19699
  let authKeepaliveInterval;
19869
19700
  const effectiveProfiles = getEffectiveProfiles(finalConfig.profiles);
19870
19701
  if (effectiveProfiles.length > 0) {
@@ -19888,6 +19719,7 @@ Or use a different port:`);
19888
19719
  async close() {
19889
19720
  if (authKeepaliveInterval)
19890
19721
  clearInterval(authKeepaliveInterval);
19722
+ stopBackgroundRefresh();
19891
19723
  await new Promise((resolve3, reject) => {
19892
19724
  server.close((err) => err ? reject(err) : resolve3());
19893
19725
  });