@bman654/clodex 2.18.0 → 2.18.2

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
@@ -346,7 +346,7 @@ import { join } from "path";
346
346
  // package.json
347
347
  var package_default = {
348
348
  name: "@bman654/clodex",
349
- version: "2.18.0",
349
+ version: "2.18.2",
350
350
  publishConfig: {
351
351
  access: "public"
352
352
  },
@@ -401,10 +401,9 @@ var package_default = {
401
401
  "https-proxy-agent": "9.1.0",
402
402
  "ipaddr.js": "2.4.0",
403
403
  "node-forge": "1.4.0",
404
- "node-gyp-build": "4.8.4",
405
404
  open: "11.0.0",
406
405
  picocolors: "1.1.1",
407
- tweakcc: "4.3.0",
406
+ tweakcc: "4.3.3",
408
407
  undici: "7.29.0",
409
408
  ws: "8.21.0"
410
409
  },
@@ -3439,7 +3438,7 @@ function savedStopsAfter(current, assignments) {
3439
3438
  }
3440
3439
 
3441
3440
  // src/patch-transforms.ts
3442
- var PATCH_TRANSFORMS_VERSION = 13;
3441
+ var PATCH_TRANSFORMS_VERSION = 14;
3443
3442
  var NATIVE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
3444
3443
  var BASE_EFFORT_LEVELS = ["low", "medium", "high"];
3445
3444
  function projectNativeEffort(effort) {
@@ -3617,15 +3616,10 @@ function applyClodexPatches(source, config) {
3617
3616
  );
3618
3617
  }
3619
3618
  }
3619
+ const pickerRow = (a) => "{value:" + q(a) + ",label:" + q(a.charAt(0).toUpperCase() + a.slice(1)) + ",description:" + q(displayFor(a, ALIAS_TO_ID[a])) + "}";
3620
3620
  {
3621
3621
  const missing = ALIASES.filter((a) => !new RegExp("value:" + reEsc(q(a))).test(js));
3622
- const entries = missing.map(
3623
- // value = the alias (the name the user types and the binary sends);
3624
- // description = the real model label, e.g. "GPT-5.6 Sol (OpenAI (ChatGPT))".
3625
- // (tweakcc's writeContent round-trips utf8 faithfully — verified — so the
3626
- // old adhoc-patch ASCII-only constraint no longer applies.)
3627
- (a) => "{value:" + q(a) + ",label:" + q(a.charAt(0).toUpperCase() + a.slice(1)) + ",description:" + q(displayFor(a, ALIAS_TO_ID[a])) + "}"
3628
- ).join(",");
3622
+ const entries = missing.map(pickerRow).join(",");
3629
3623
  const injectInto = (options) => missing.length ? "[" + entries + "].forEach(function(_o){if(!" + options + ".some(function(_i){return _i.value===_o.value}))" + options + ".push(_o)});" : "";
3630
3624
  const pickerSite = "PATCH 5: model picker options";
3631
3625
  const modelSelections = [...js.matchAll(/\(([\w$]+)==="opus"\|\|\1==="sonnet"\)/g)];
@@ -3642,6 +3636,25 @@ function applyClodexPatches(source, config) {
3642
3636
  );
3643
3637
  }
3644
3638
  }
3639
+ {
3640
+ const catalogSite = "PATCH 11: catalog picker options";
3641
+ const catalogMarker = "/*ccpatch:picker*/";
3642
+ const catalogAnchor = /function [\w$]+\(([\w$]+),([\w$]+)\)\{let ([\w$]+)=[\w$]+\(\1,\2\),([\w$]+)=\3\?\?[\w$]+\(\1\)(?=[,;])(?=[\s\S]{0,400}ANTHROPIC_CUSTOM_MODEL_OPTION)/;
3643
+ const entryPoints = source.match(new RegExp(catalogAnchor.source, "g"))?.length ?? 0;
3644
+ const rows = ALIASES.map(pickerRow).join(",");
3645
+ if (ALIASES.length === 0) {
3646
+ log13("SKIP", catalogSite, "no aliases configured");
3647
+ } else if (entryPoints !== 1 && !js.includes(catalogMarker)) {
3648
+ log13("FAIL", catalogSite, entryPoints === 0 ? "anchor not found" : "anchor matched " + entryPoints + " times (expected 1)");
3649
+ } else {
3650
+ applyOnce(
3651
+ catalogSite,
3652
+ catalogAnchor,
3653
+ (m, _first, _second, _catalog, options) => m + ",_ccpick=" + catalogMarker + "[" + rows + "].forEach(function(_o){if(!" + options + ".some(function(_i){return _i.value===_o.value}))" + options + ".push(_o)})",
3654
+ { marker: catalogMarker, required: false }
3655
+ );
3656
+ }
3657
+ }
3645
3658
  {
3646
3659
  const safe = (s) => String(s).replace(/`/g, "'").replace(/\$\{/g, "(");
3647
3660
  const listing = IDENTITIES.map(function(i) {
@@ -3873,8 +3886,8 @@ import {
3873
3886
  statSync as statSync7,
3874
3887
  unlinkSync as unlinkSync3,
3875
3888
  writeFileSync as writeFileSync5,
3876
- openSync as openSync8,
3877
- closeSync as closeSync8,
3889
+ openSync as openSync9,
3890
+ closeSync as closeSync9,
3878
3891
  realpathSync as realpathSync3
3879
3892
  } from "fs";
3880
3893
  import { homedir as homedir3 } from "os";
@@ -4148,14 +4161,14 @@ function uniqueMatch(source, name, pattern) {
4148
4161
  }
4149
4162
  return match[0];
4150
4163
  }
4151
- function captureNeedle(source, name, needle) {
4152
- if (countExactOccurrences(source, needle) !== 1) {
4164
+ function captureNeedle(source, name, needle, expected = 1) {
4165
+ if (countExactOccurrences(source, needle) !== expected) {
4153
4166
  throw new Error(`clodex patch: could not capture built-in postcondition: ${name}`);
4154
4167
  }
4155
4168
  return {
4156
4169
  name,
4157
4170
  protectedText: needle,
4158
- occurrences: 1
4171
+ occurrences: expected
4159
4172
  };
4160
4173
  }
4161
4174
  function capturePattern(source, name, pattern) {
@@ -4215,16 +4228,25 @@ function captureBuiltInPatchProofs(source, config, results) {
4215
4228
  ));
4216
4229
  }
4217
4230
  }
4218
- if (protectsResult(results, "PATCH 5: model picker options")) {
4231
+ const pickerSites = [
4232
+ "PATCH 5: model picker options",
4233
+ "PATCH 11: catalog picker options"
4234
+ ].filter((name) => protectsResult(results, name));
4235
+ if (pickerSites.length > 0) {
4219
4236
  for (const { alias, id, display } of aliases) {
4220
4237
  const entry = "{value:" + JSON.stringify(alias) + ",label:" + JSON.stringify(alias.charAt(0).toUpperCase() + alias.slice(1)) + ",description:" + JSON.stringify(display ?? `Custom model (${id})`) + "}";
4221
4238
  proofs.push(captureNeedle(
4222
4239
  source,
4223
- `PATCH 5: model picker options (${alias})`,
4224
- entry
4240
+ `model picker options (${alias})`,
4241
+ entry,
4242
+ pickerSites.length
4225
4243
  ));
4226
4244
  }
4227
4245
  }
4246
+ addPattern(
4247
+ "PATCH 11: catalog picker options",
4248
+ /,_ccpick=\/\*ccpatch:picker\*\/\[[\s\S]*?\]\.forEach\(function\(_o\)\{if\(![\w$]+\.some\(function\(_i\)\{return _i\.value===_o\.value\}\)\)[\w$]+\.push\(_o\)\}\)/
4249
+ );
4228
4250
  addPattern(
4229
4251
  "PATCH 7: per-model context window",
4230
4252
  /\/\*ccpatch:ctx\*\/var _ccw=\(\{[^{}]*\}\)\[[^\]]*\];if\(_ccw!==void 0\)return _ccw;/
@@ -6064,11 +6086,11 @@ var OPENAI_OAUTH_MODEL_SEEDS = [
6064
6086
  // program, so most installs will never see this id in their catalog.
6065
6087
  { id: "gpt-daybreak-blue-latest", name: "GPT Daybreak Blue", contextWindow: 272e3, maxContextWindow: 872e3, maxOutputTokens: 128e3, reasoning: true, useResponsesLite: true, preferWebSockets: true, minimalClientVersion: "0.144.0" },
6066
6088
  // GPT-5.6 family (Sol / Terra / Luna)
6067
- { id: "gpt-5.6-sol", name: "GPT-5.6 Sol", contextWindow: 272e3, maxContextWindow: 872e3, maxOutputTokens: 128e3, reasoning: true, minimalClientVersion: "0.144.0" },
6068
- { id: "gpt-5.6-terra", name: "GPT-5.6 Terra", contextWindow: 272e3, maxContextWindow: 872e3, maxOutputTokens: 128e3, reasoning: true, minimalClientVersion: "0.144.0" },
6089
+ { id: "gpt-5.6-sol", name: "GPT-5.6 Sol", contextWindow: 272e3, maxContextWindow: 872e3, maxOutputTokens: 128e3, reasoning: true, useResponsesLite: true, preferWebSockets: true, minimalClientVersion: "0.144.0" },
6090
+ { id: "gpt-5.6-terra", name: "GPT-5.6 Terra", contextWindow: 272e3, maxContextWindow: 872e3, maxOutputTokens: 128e3, reasoning: true, useResponsesLite: true, preferWebSockets: true, minimalClientVersion: "0.144.0" },
6069
6091
  { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", contextWindow: 272e3, maxContextWindow: 872e3, maxOutputTokens: 128e3, reasoning: true, useResponsesLite: true, preferWebSockets: true, minimalClientVersion: "0.144.0" },
6070
6092
  // GPT-5.5 family (Pro)
6071
- { id: "gpt-5.5", name: "GPT-5.5", contextWindow: 272e3, maxOutputTokens: 128e3, reasoning: true },
6093
+ { id: "gpt-5.5", name: "GPT-5.5", contextWindow: 272e3, maxContextWindow: 272e3, maxOutputTokens: 128e3, reasoning: true, useResponsesLite: false, preferWebSockets: true, minimalClientVersion: "0.124.0" },
6072
6094
  // GPT-5.4 family
6073
6095
  { id: "gpt-5.4", name: "GPT-5.4", contextWindow: 272e3, maxContextWindow: 1e6 },
6074
6096
  { id: "gpt-5.4-mini", name: "GPT-5.4 Mini", contextWindow: 272e3 },
@@ -7380,270 +7402,44 @@ function inspectClaudeNativeBinaryPlaceholder(path) {
7380
7402
  }
7381
7403
  }
7382
7404
 
7383
- // src/bun-entry-module.ts
7384
- import { closeSync as closeSync3, openSync as openSync3, readSync as readSync2, statSync as statSync6, writeSync } from "fs";
7405
+ // src/patch-signature.ts
7385
7406
  import { execFileSync as execFileSync2 } from "child_process";
7386
- var BUN_TRAILER = Buffer.from("\n---- Bun! ----\n");
7387
- var BUN_OFFSETS_BYTES = 32;
7388
- var TAIL_SCAN_BYTES = 16 * 1024 * 1024;
7389
- var MODULE_STRUCT_BYTES_CURRENT = 52;
7390
- var MODULE_STRUCT_BYTES_LEGACY = 36;
7391
- var CONTENTS_FIELD_AT = 8;
7392
- var SOURCEMAP_FIELD_AT = 16;
7393
- var BYTECODE_FIELD_AT = 24;
7394
- var MODULE_INFO_FIELD_AT = 32;
7395
- var BYTECODE_ORIGIN_PATH_FIELD_AT = 40;
7396
- var BUN_BLOB_FLAGS = {
7397
- /** Every module's source text lies in one run no other region falls inside. */
7398
- SOURCE_TEXT_CONTIGUOUS: 1 << 4,
7399
- /** A `[u32; modules]` of each module's source hash follows the module table. */
7400
- HAS_SOURCE_HASHES: 1 << 5,
7401
- /** After the source hashes: `u32 count`, then `count` x `{ u32 id, offset, length }`. */
7402
- HAS_BUILTIN_BYTECODE: 1 << 6,
7403
- /** After the builtin-bytecode table: one `{ offset, length }` for the shared string table. */
7404
- HAS_BYTECODE_STRING_TABLE: 1 << 7
7405
- };
7406
- var LOADER_FROM_END = 3;
7407
- var BUN_JAVASCRIPT_LOADER = 1;
7408
- var MAX_MODULE_NAME_BYTES = 4096;
7409
- var MIN_SHIMMABLE_NAME_BYTES = 7;
7410
- function tweakccRecognizesModuleName(name) {
7411
- return name.endsWith("/claude") || name === "claude" || name.endsWith("/claude.exe") || name === "claude.exe" || name.endsWith("/src/entrypoints/cli.js") || name === "src/entrypoints/cli.js";
7412
- }
7413
- function entryModuleShimName(byteLength) {
7414
- if (byteLength < MIN_SHIMMABLE_NAME_BYTES) return null;
7415
- const padding = byteLength - MIN_SHIMMABLE_NAME_BYTES;
7416
- return "/clodex".padEnd(padding, "-").slice(0, padding) + "/claude";
7417
- }
7418
- function readAt(fd, length, position) {
7419
- if (length <= 0 || position < 0) return null;
7420
- const buffer = Buffer.alloc(length);
7421
- const read = readSync2(fd, buffer, 0, length, position);
7422
- return read === length ? buffer : null;
7423
- }
7424
- function readBunModuleNames(fd, fileSize) {
7425
- const tailLength = Math.min(fileSize, TAIL_SCAN_BYTES);
7426
- const tail = readAt(fd, tailLength, fileSize - tailLength);
7427
- if (!tail) return null;
7428
- const tailAt = fileSize - tailLength;
7429
- for (let searchFrom = tail.length - 1; searchFrom >= 0; ) {
7430
- const trailerInTail = tail.lastIndexOf(BUN_TRAILER, searchFrom);
7431
- if (trailerInTail < 0) return null;
7432
- const parsed = parseBunModuleNamesAt(fd, tailAt + trailerInTail - BUN_OFFSETS_BYTES);
7433
- if (parsed) return parsed;
7434
- searchFrom = trailerInTail - 1;
7435
- }
7436
- return null;
7437
- }
7438
- function parseBunModuleNamesAt(fd, offsetsAt) {
7439
- try {
7440
- return parseBunModuleNamesAtUnchecked(fd, offsetsAt);
7441
- } catch {
7442
- return null;
7443
- }
7444
- }
7445
- function parseBunModuleNamesAtUnchecked(fd, offsetsAt) {
7446
- const offsets = readAt(fd, BUN_OFFSETS_BYTES, offsetsAt);
7447
- if (!offsets) return null;
7448
- const byteCount = offsets.readBigUInt64LE(0);
7449
- const modulesOffset = offsets.readUInt32LE(8);
7450
- const modulesLength = offsets.readUInt32LE(12);
7451
- const entryPointId = offsets.readUInt32LE(16);
7452
- const compileExecArgvOffset = offsets.readUInt32LE(20);
7453
- const compileExecArgvLength = offsets.readUInt32LE(24);
7454
- const flags = offsets.readUInt32LE(28);
7455
- if (byteCount <= 0n || byteCount > BigInt(offsetsAt)) return null;
7456
- const blobAt = offsetsAt - Number(byteCount);
7457
- if (modulesLength <= 0 || BigInt(modulesOffset) + BigInt(modulesLength) > byteCount) return null;
7458
- const structBytes = modulesLength % MODULE_STRUCT_BYTES_LEGACY === 0 && modulesLength % MODULE_STRUCT_BYTES_CURRENT !== 0 ? MODULE_STRUCT_BYTES_LEGACY : MODULE_STRUCT_BYTES_CURRENT;
7459
- const moduleCount = Math.floor(modulesLength / structBytes);
7460
- if (moduleCount <= 0 || entryPointId >= moduleCount) return null;
7461
- const modules = readAt(fd, moduleCount * structBytes, blobAt + modulesOffset);
7462
- if (!modules) return null;
7463
- const names = [];
7464
- const nameOffsets = [];
7465
- const contents = [];
7466
- const sourcemap = [];
7467
- const bytecode = [];
7468
- const moduleInfo = [];
7469
- const bytecodeOriginPath = [];
7470
- const loaders = [];
7471
- for (let index = 0; index < moduleCount; index++) {
7472
- const nameOffset = modules.readUInt32LE(index * structBytes);
7473
- const nameLength = modules.readUInt32LE(index * structBytes + 4);
7474
- if (nameLength <= 0 || nameLength > MAX_MODULE_NAME_BYTES) return null;
7475
- if (BigInt(nameOffset) + BigInt(nameLength) > byteCount) return null;
7476
- const bytes = readAt(fd, nameLength + 1, blobAt + nameOffset);
7477
- if (!bytes || bytes[nameLength] !== 0) return null;
7478
- const name = bytes.subarray(0, nameLength).toString("utf8");
7479
- if (!/^[\x20-\x7e]+$/.test(name)) return null;
7480
- names.push(name);
7481
- nameOffsets.push(blobAt + nameOffset);
7482
- const pairAt = (field) => ({
7483
- offset: modules.readUInt32LE(index * structBytes + field),
7484
- length: modules.readUInt32LE(index * structBytes + field + 4)
7485
- });
7486
- contents.push(pairAt(CONTENTS_FIELD_AT));
7487
- sourcemap.push(pairAt(SOURCEMAP_FIELD_AT));
7488
- bytecode.push(pairAt(BYTECODE_FIELD_AT));
7489
- const current = structBytes === MODULE_STRUCT_BYTES_CURRENT;
7490
- moduleInfo.push(current ? pairAt(MODULE_INFO_FIELD_AT) : { offset: 0, length: 0 });
7491
- bytecodeOriginPath.push(
7492
- current ? pairAt(BYTECODE_ORIGIN_PATH_FIELD_AT) : { offset: 0, length: 0 }
7493
- );
7494
- loaders.push(modules.readUInt8(index * structBytes + structBytes - LOADER_FROM_END));
7495
- }
7496
- return {
7497
- names,
7498
- entryPointId,
7499
- offsets: nameOffsets,
7500
- contents,
7501
- sourcemap,
7502
- bytecode,
7503
- moduleInfo,
7504
- bytecodeOriginPath,
7505
- loaders,
7506
- blobAt,
7507
- modulesAt: blobAt + modulesOffset,
7508
- modulesOffset,
7509
- modulesLength,
7510
- structBytes,
7511
- byteCount: Number(byteCount),
7512
- compileExecArgv: { offset: compileExecArgvOffset, length: compileExecArgvLength },
7513
- flags
7514
- };
7515
- }
7516
- function findStandIn(fd, fileSize, marker) {
7517
- const needle = Buffer.from(marker);
7518
- const chunkBytes = 8 * 1024 * 1024;
7519
- const offsets = [];
7520
- let carry = Buffer.alloc(0);
7521
- for (let position = 0; position < fileSize; ) {
7522
- const length = Math.min(chunkBytes, fileSize - position);
7523
- const chunk = readAt(fd, length, position);
7524
- if (!chunk) throw new Error("could not re-read the candidate to verify the entry-module name");
7525
- const window = carry.length > 0 ? Buffer.concat([carry, chunk]) : chunk;
7526
- const windowAt = position - carry.length;
7527
- for (let at = window.indexOf(needle); at >= 0; at = window.indexOf(needle, at + 1)) {
7528
- offsets.push(windowAt + at);
7529
- }
7530
- carry = Buffer.from(window.subarray(Math.max(0, window.length - (needle.length - 1))));
7531
- position += length;
7532
- }
7533
- return offsets;
7534
- }
7535
- function restoreEveryStandIn(fd, fileSize, shim) {
7536
- const moduleNameCopies = () => findStandIn(fd, fileSize, shim.marker).filter((offset) => isModuleNameAt(fd, offset, shim.marker));
7537
- const found = moduleNameCopies();
7538
- for (const offset of found) writeNameBytes(fd, shim.original, offset);
7539
- if (found.length > 0 && moduleNameCopies().length > 0) {
7540
- throw new Error(`the entry-module stand-in ${shim.marker} survived restoration`);
7541
- }
7542
- }
7543
- function isModuleNameAt(fd, offset, marker) {
7544
- const after = readAt(fd, 1, offset + Buffer.byteLength(marker));
7545
- return after !== null && after[0] === 0;
7546
- }
7547
- function writeNameBytes(fd, name, offset) {
7548
- const bytes = Buffer.from(name);
7549
- const written = writeSync(fd, bytes, 0, bytes.length, offset);
7550
- if (written !== bytes.length) {
7551
- throw new Error(`wrote ${written} of ${bytes.length} entry-module name bytes at ${offset}`);
7552
- }
7553
- }
7554
- function isMachO(fd) {
7555
- const magic = readAt(fd, 4, 0);
7556
- if (!magic) return false;
7557
- const value = magic.readUInt32BE(0);
7558
- return value === 4277009102 || value === 4277009103 || value === 3472551422 || value === 3489328638 || value === 3405691582 || value === 3405691583;
7559
- }
7560
- function readBunModuleTable(path) {
7407
+ import { closeSync as closeSync3, openSync as openSync3, readSync as readSync2 } from "fs";
7408
+ function signAndVerifyMachOCandidate(path, installPath = path) {
7409
+ if (process.platform !== "darwin") return;
7561
7410
  const fd = openSync3(path, "r");
7411
+ let machO = false;
7562
7412
  try {
7563
- return readBunModuleNames(fd, statSync6(path).size);
7564
- } finally {
7565
- closeSync3(fd);
7566
- }
7567
- }
7568
- function readBunJavaScriptModules(path) {
7569
- const fd = openSync3(path, "r");
7570
- try {
7571
- const parsed = readBunModuleNames(fd, statSync6(path).size);
7572
- if (!parsed) return null;
7573
- const modules = [];
7574
- for (let index = 0; index < parsed.names.length; index++) {
7575
- if (parsed.loaders[index] !== BUN_JAVASCRIPT_LOADER) continue;
7576
- const range = parsed.contents[index];
7577
- if (range.offset < 0 || range.length < 0 || range.offset + range.length > parsed.byteCount) {
7578
- return null;
7579
- }
7580
- const bytes = range.length === 0 ? Buffer.alloc(0) : readAt(fd, range.length, parsed.blobAt + range.offset);
7581
- if (!bytes) return null;
7582
- modules.push({
7583
- index,
7584
- name: parsed.names[index],
7585
- source: bytes.toString("utf8"),
7586
- byteLength: bytes.length
7587
- });
7588
- }
7589
- return modules;
7590
- } finally {
7591
- closeSync3(fd);
7592
- }
7593
- }
7594
- function shimEntryModuleName(path) {
7595
- const fd = openSync3(path, "r+");
7596
- try {
7597
- const parsed = readBunModuleNames(fd, statSync6(path).size);
7598
- if (!parsed) return null;
7599
- if (parsed.names.some(tweakccRecognizesModuleName)) return null;
7600
- const original = parsed.names[parsed.entryPointId];
7601
- const offset = parsed.offsets[parsed.entryPointId];
7602
- const marker = entryModuleShimName(Buffer.byteLength(original));
7603
- if (marker === null) return null;
7604
- if (findStandIn(fd, statSync6(path).size, marker).some((offset2) => isModuleNameAt(fd, offset2, marker))) {
7605
- return null;
7413
+ const magic = Buffer.alloc(4);
7414
+ if (readSync2(fd, magic, 0, 4, 0) === 4) {
7415
+ machO = [
7416
+ 4277009102,
7417
+ 4277009103,
7418
+ 3472551422,
7419
+ 3489328638,
7420
+ 3405691582,
7421
+ 3405691583,
7422
+ 3199925962
7423
+ ].includes(magic.readUInt32BE(0));
7606
7424
  }
7607
- writeNameBytes(fd, marker, offset);
7608
- return { offset, original, marker };
7609
7425
  } finally {
7610
7426
  closeSync3(fd);
7611
7427
  }
7612
- }
7613
- function restoreEntryModuleName(path, shim, { resign }) {
7614
- const fd = openSync3(path, "r+");
7615
- let machO;
7428
+ if (!machO) return;
7616
7429
  try {
7617
- const parsed = readBunModuleNames(fd, statSync6(path).size);
7618
- const offset = parsed?.offsets[parsed.entryPointId];
7619
- if (!parsed || offset === void 0 || parsed.names[parsed.entryPointId] !== shim.marker) {
7620
- throw new Error(
7621
- `expected the entry module of ${path} to be named ${shim.marker}, found ${parsed ? JSON.stringify(parsed.names[parsed.entryPointId]) : "no readable Bun module list"}`
7622
- );
7623
- }
7624
- writeNameBytes(fd, shim.original, offset);
7625
- restoreEveryStandIn(fd, statSync6(path).size, shim);
7626
- machO = resign;
7627
- } finally {
7628
- closeSync3(fd);
7629
- }
7630
- if (machO) resignMachOBinary(path);
7631
- }
7632
- function resignMachOBinary(path) {
7633
- const fd = openSync3(path, "r");
7634
- let machO;
7635
- try {
7636
- machO = isMachO(fd);
7637
- } finally {
7638
- closeSync3(fd);
7639
- }
7640
- if (machO && process.platform === "darwin") {
7641
- execFileSync2("codesign", ["-s", "-", "-f", path], { stdio: "ignore" });
7430
+ execFileSync2("codesign", ["-s", "-", "-f", path], { stdio: "pipe" });
7431
+ execFileSync2("codesign", ["--verify", "--strict", path], { stdio: "pipe" });
7432
+ } catch (error) {
7433
+ const stderr = error?.stderr;
7434
+ const detail = String(stderr ?? "").trim().split(`${path}: `).join("").split(/\r?\n/).filter((line) => line !== "replacing existing signature").join("\n").trim() || (error instanceof Error ? error.message.trimEnd() : String(error).trimEnd());
7435
+ throw new Error(
7436
+ `Mach-O signing or verification failed for ${installPath}: ${detail}. Claude Code was left unchanged.`
7437
+ );
7642
7438
  }
7643
7439
  }
7644
7440
 
7645
7441
  // src/bun-compiled-pointer.ts
7646
- import { closeSync as closeSync4, fstatSync as fstatSync2, openSync as openSync4, readSync as readSync3, writeSync as writeSync2 } from "fs";
7442
+ import { closeSync as closeSync4, fstatSync as fstatSync2, openSync as openSync4, readSync as readSync3, writeSync } from "fs";
7647
7443
  var TWEAKCC_SCAN_STRIDE = 16384n;
7648
7444
  var SCAN_CHUNK = 1 << 20;
7649
7445
  var ELF_MAGIC = 1179403647;
@@ -7651,7 +7447,7 @@ var ELFCLASS64 = 2;
7651
7447
  var ELFDATA2LSB = 1;
7652
7448
  var PT_LOAD = 1;
7653
7449
  var PF_W = 2;
7654
- function readAt2(fd, length, position) {
7450
+ function readAt(fd, length, position) {
7655
7451
  const buf = Buffer.alloc(length);
7656
7452
  let read = 0;
7657
7453
  while (read < length) {
@@ -7662,7 +7458,7 @@ function readAt2(fd, length, position) {
7662
7458
  return read === length ? buf : buf.subarray(0, read);
7663
7459
  }
7664
7460
  function readElfLayout(fd) {
7665
- const ident = readAt2(fd, 64, 0);
7461
+ const ident = readAt(fd, 64, 0);
7666
7462
  if (ident.length < 64) return null;
7667
7463
  if (ident.readUInt32LE(0) !== ELF_MAGIC) return null;
7668
7464
  if (ident[4] !== ELFCLASS64 || ident[5] !== ELFDATA2LSB) return null;
@@ -7678,7 +7474,7 @@ function readElfLayout(fd) {
7678
7474
  const fileSize = fstatSync2(fd).size;
7679
7475
  const fits = (offset, length) => Number.isSafeInteger(offset) && offset >= 0 && length >= 0 && offset + length <= fileSize;
7680
7476
  if (!fits(Number(shoff), shnum * shentsize)) return null;
7681
- const shTable = readAt2(fd, shnum * shentsize, Number(shoff));
7477
+ const shTable = readAt(fd, shnum * shentsize, Number(shoff));
7682
7478
  if (shTable.length !== shnum * shentsize) return null;
7683
7479
  const raw = [];
7684
7480
  for (let i = 0; i < shnum; i++) {
@@ -7692,7 +7488,7 @@ function readElfLayout(fd) {
7692
7488
  }
7693
7489
  const strtab = raw[shstrndx];
7694
7490
  if (!fits(Number(strtab.offset), Number(strtab.size))) return null;
7695
- const names = readAt2(fd, Number(strtab.size), Number(strtab.offset));
7491
+ const names = readAt(fd, Number(strtab.size), Number(strtab.offset));
7696
7492
  const sections = raw.map((section) => {
7697
7493
  const start = section.nameOffset;
7698
7494
  let end = start;
@@ -7705,7 +7501,7 @@ function readElfLayout(fd) {
7705
7501
  };
7706
7502
  });
7707
7503
  if (!fits(Number(phoff), phnum * phentsize)) return null;
7708
- const phTable = readAt2(fd, phnum * phentsize, Number(phoff));
7504
+ const phTable = readAt(fd, phnum * phentsize, Number(phoff));
7709
7505
  if (phTable.length !== phnum * phentsize) return null;
7710
7506
  const segments = [];
7711
7507
  for (let i = 0; i < phnum; i++) {
@@ -7742,7 +7538,7 @@ function tweakccWouldFind(fd, segment, needle) {
7742
7538
  const last = segment.vaddr + segment.filesz - 8n;
7743
7539
  for (let vaddr = first; vaddr <= last; vaddr += TWEAKCC_SCAN_STRIDE) {
7744
7540
  const at = Number(segment.offset + (vaddr - segment.vaddr));
7745
- if (readAt2(fd, 8, at).equals(needle)) return vaddr;
7541
+ if (readAt(fd, 8, at).equals(needle)) return vaddr;
7746
7542
  }
7747
7543
  return null;
7748
7544
  }
@@ -7751,7 +7547,7 @@ function scanForNeedle(fd, from, to, needle, skipFrom, skipTo) {
7751
7547
  for (let start = from; start < to; start += SCAN_CHUNK - 7) {
7752
7548
  const length = Math.min(SCAN_CHUNK, to - start);
7753
7549
  if (length < 8) break;
7754
- const chunk = readAt2(fd, length, start);
7550
+ const chunk = readAt(fd, length, start);
7755
7551
  let at = 0;
7756
7552
  for (; ; ) {
7757
7553
  const found = chunk.indexOf(needle, at);
@@ -7809,9 +7605,9 @@ function shimBunCompiledPointer(path) {
7809
7605
  throw new Error("no address tweakcc's ELF repack scans is usable for Bun's blob pointer");
7810
7606
  }
7811
7607
  const standInOffset = Number(segment.offset + (standInVaddr - segment.vaddr));
7812
- const displaced = readAt2(fd, 8, standInOffset);
7608
+ const displaced = readAt(fd, 8, standInOffset);
7813
7609
  if (displaced.length !== 8) throw new Error("could not read the bytes Bun's blob pointer displaces");
7814
- writeSync2(fd, needle, 0, 8, standInOffset);
7610
+ writeSync(fd, needle, 0, 8, standInOffset);
7815
7611
  return { pointerVaddr, standInVaddr, displaced, bunVaddr: bun.addr };
7816
7612
  } finally {
7817
7613
  closeSync4(fd);
@@ -7831,7 +7627,7 @@ function restoreBunCompiledPointer(path, shim) {
7831
7627
  "the repack left Bun's blob pointer outside the loaded image, or in more than one segment of it"
7832
7628
  );
7833
7629
  }
7834
- const standIn = readAt2(fd, 8, standInOffset);
7630
+ const standIn = readAt(fd, 8, standInOffset);
7835
7631
  if (standIn.length !== 8) {
7836
7632
  throw new Error("the repacked binary ends before the stand-in for Bun's blob pointer");
7837
7633
  }
@@ -7846,12 +7642,12 @@ function restoreBunCompiledPointer(path, shim) {
7846
7642
  }
7847
7643
  const value = Buffer.alloc(8);
7848
7644
  value.writeBigUInt64LE(written);
7849
- writeSync2(fd, value, 0, 8, pointerOffset);
7850
- writeSync2(fd, shim.displaced, 0, 8, standInOffset);
7851
- if (!readAt2(fd, 8, pointerOffset).equals(value)) {
7645
+ writeSync(fd, value, 0, 8, pointerOffset);
7646
+ writeSync(fd, shim.displaced, 0, 8, standInOffset);
7647
+ if (!readAt(fd, 8, pointerOffset).equals(value)) {
7852
7648
  throw new Error("Bun's blob pointer did not take the repacked address");
7853
7649
  }
7854
- if (!readAt2(fd, 8, standInOffset).equals(shim.displaced)) {
7650
+ if (!readAt(fd, 8, standInOffset).equals(shim.displaced)) {
7855
7651
  throw new Error("the bytes the stand-in displaced were not restored");
7856
7652
  }
7857
7653
  } finally {
@@ -7860,13 +7656,185 @@ function restoreBunCompiledPointer(path, shim) {
7860
7656
  }
7861
7657
 
7862
7658
  // src/bun-bundle.ts
7863
- import { closeSync as closeSync5, openSync as openSync5, readSync as readSync4, writeSync as writeSync3 } from "fs";
7659
+ import { closeSync as closeSync6, openSync as openSync6, readSync as readSync5, writeSync as writeSync2 } from "fs";
7660
+
7661
+ // src/bun-module-table.ts
7662
+ import { closeSync as closeSync5, openSync as openSync5, readSync as readSync4, statSync as statSync6 } from "fs";
7663
+ var BUN_TRAILER = Buffer.from("\n---- Bun! ----\n");
7664
+ var BUN_OFFSETS_BYTES = 32;
7665
+ var TAIL_SCAN_BYTES = 16 * 1024 * 1024;
7666
+ var MODULE_STRUCT_BYTES_CURRENT = 52;
7667
+ var MODULE_STRUCT_BYTES_LEGACY = 36;
7668
+ var CONTENTS_FIELD_AT = 8;
7669
+ var SOURCEMAP_FIELD_AT = 16;
7670
+ var BYTECODE_FIELD_AT = 24;
7671
+ var MODULE_INFO_FIELD_AT = 32;
7672
+ var BYTECODE_ORIGIN_PATH_FIELD_AT = 40;
7673
+ var BUN_BLOB_FLAGS = {
7674
+ /** Every module's source text lies in one run no other region falls inside. */
7675
+ SOURCE_TEXT_CONTIGUOUS: 1 << 4,
7676
+ /** A `[u32; modules]` of each module's source hash follows the module table. */
7677
+ HAS_SOURCE_HASHES: 1 << 5,
7678
+ /** After the source hashes: `u32 count`, then `count` x `{ u32 id, offset, length }`. */
7679
+ HAS_BUILTIN_BYTECODE: 1 << 6,
7680
+ /** After the builtin-bytecode table: one `{ offset, length }` for the shared string table. */
7681
+ HAS_BYTECODE_STRING_TABLE: 1 << 7
7682
+ };
7683
+ var LOADER_FROM_END = 3;
7684
+ var BUN_JAVASCRIPT_LOADER = 1;
7685
+ var MAX_MODULE_NAME_BYTES = 4096;
7686
+ function tweakccRecognizesModuleName(name) {
7687
+ return name.endsWith("/claude") || name === "claude" || name.endsWith("/claude.exe") || name === "claude.exe" || name.endsWith("/src/entrypoints/cli.js") || name === "src/entrypoints/cli.js" || name.endsWith("/cli") || name === "cli";
7688
+ }
7689
+ function readAt2(fd, length, position) {
7690
+ if (length <= 0 || position < 0) return null;
7691
+ const buffer = Buffer.alloc(length);
7692
+ const read = readSync4(fd, buffer, 0, length, position);
7693
+ return read === length ? buffer : null;
7694
+ }
7695
+ function readBunModuleNames(fd, fileSize) {
7696
+ const tailLength = Math.min(fileSize, TAIL_SCAN_BYTES);
7697
+ const tail = readAt2(fd, tailLength, fileSize - tailLength);
7698
+ if (!tail) return null;
7699
+ const tailAt = fileSize - tailLength;
7700
+ for (let searchFrom = tail.length - 1; searchFrom >= 0; ) {
7701
+ const trailerInTail = tail.lastIndexOf(BUN_TRAILER, searchFrom);
7702
+ if (trailerInTail < 0) return null;
7703
+ const parsed = parseBunModuleNamesAt(fd, tailAt + trailerInTail - BUN_OFFSETS_BYTES);
7704
+ if (parsed) return parsed;
7705
+ searchFrom = trailerInTail - 1;
7706
+ }
7707
+ return null;
7708
+ }
7709
+ function parseBunModuleNamesAt(fd, offsetsAt) {
7710
+ try {
7711
+ return parseBunModuleNamesAtUnchecked(fd, offsetsAt);
7712
+ } catch {
7713
+ return null;
7714
+ }
7715
+ }
7716
+ function parseBunModuleNamesAtUnchecked(fd, offsetsAt) {
7717
+ const offsets = readAt2(fd, BUN_OFFSETS_BYTES, offsetsAt);
7718
+ if (!offsets) return null;
7719
+ const byteCount = offsets.readBigUInt64LE(0);
7720
+ const modulesOffset = offsets.readUInt32LE(8);
7721
+ const modulesLength = offsets.readUInt32LE(12);
7722
+ const entryPointId = offsets.readUInt32LE(16);
7723
+ const compileExecArgvOffset = offsets.readUInt32LE(20);
7724
+ const compileExecArgvLength = offsets.readUInt32LE(24);
7725
+ const flags = offsets.readUInt32LE(28);
7726
+ if (byteCount <= 0n || byteCount > BigInt(offsetsAt)) return null;
7727
+ const blobAt = offsetsAt - Number(byteCount);
7728
+ if (modulesLength <= 0 || BigInt(modulesOffset) + BigInt(modulesLength) > byteCount) return null;
7729
+ const structBytes = modulesLength % MODULE_STRUCT_BYTES_LEGACY === 0 && modulesLength % MODULE_STRUCT_BYTES_CURRENT !== 0 ? MODULE_STRUCT_BYTES_LEGACY : MODULE_STRUCT_BYTES_CURRENT;
7730
+ const moduleCount = Math.floor(modulesLength / structBytes);
7731
+ if (moduleCount <= 0 || entryPointId >= moduleCount) return null;
7732
+ const modules = readAt2(fd, moduleCount * structBytes, blobAt + modulesOffset);
7733
+ if (!modules) return null;
7734
+ const names = [];
7735
+ const nameOffsets = [];
7736
+ const contents = [];
7737
+ const sourcemap = [];
7738
+ const bytecode = [];
7739
+ const moduleInfo = [];
7740
+ const bytecodeOriginPath = [];
7741
+ const loaders = [];
7742
+ for (let index = 0; index < moduleCount; index++) {
7743
+ const nameOffset = modules.readUInt32LE(index * structBytes);
7744
+ const nameLength = modules.readUInt32LE(index * structBytes + 4);
7745
+ if (nameLength <= 0 || nameLength > MAX_MODULE_NAME_BYTES) return null;
7746
+ if (BigInt(nameOffset) + BigInt(nameLength) > byteCount) return null;
7747
+ const bytes = readAt2(fd, nameLength + 1, blobAt + nameOffset);
7748
+ if (!bytes || bytes[nameLength] !== 0) return null;
7749
+ const name = bytes.subarray(0, nameLength).toString("utf8");
7750
+ if (!/^[\x20-\x7e]+$/.test(name)) return null;
7751
+ names.push(name);
7752
+ nameOffsets.push(blobAt + nameOffset);
7753
+ const pairAt = (field) => ({
7754
+ offset: modules.readUInt32LE(index * structBytes + field),
7755
+ length: modules.readUInt32LE(index * structBytes + field + 4)
7756
+ });
7757
+ contents.push(pairAt(CONTENTS_FIELD_AT));
7758
+ sourcemap.push(pairAt(SOURCEMAP_FIELD_AT));
7759
+ bytecode.push(pairAt(BYTECODE_FIELD_AT));
7760
+ const current = structBytes === MODULE_STRUCT_BYTES_CURRENT;
7761
+ moduleInfo.push(current ? pairAt(MODULE_INFO_FIELD_AT) : { offset: 0, length: 0 });
7762
+ bytecodeOriginPath.push(
7763
+ current ? pairAt(BYTECODE_ORIGIN_PATH_FIELD_AT) : { offset: 0, length: 0 }
7764
+ );
7765
+ loaders.push(modules.readUInt8(index * structBytes + structBytes - LOADER_FROM_END));
7766
+ }
7767
+ return {
7768
+ names,
7769
+ entryPointId,
7770
+ offsets: nameOffsets,
7771
+ contents,
7772
+ sourcemap,
7773
+ bytecode,
7774
+ moduleInfo,
7775
+ bytecodeOriginPath,
7776
+ loaders,
7777
+ blobAt,
7778
+ modulesAt: blobAt + modulesOffset,
7779
+ modulesOffset,
7780
+ modulesLength,
7781
+ structBytes,
7782
+ byteCount: Number(byteCount),
7783
+ compileExecArgv: { offset: compileExecArgvOffset, length: compileExecArgvLength },
7784
+ flags
7785
+ };
7786
+ }
7787
+ function readBunModuleTable(path) {
7788
+ const fd = openSync5(path, "r");
7789
+ try {
7790
+ return readBunModuleNames(fd, statSync6(path).size);
7791
+ } finally {
7792
+ closeSync5(fd);
7793
+ }
7794
+ }
7795
+ function readBunJavaScriptModules(path) {
7796
+ const fd = openSync5(path, "r");
7797
+ try {
7798
+ const parsed = readBunModuleNames(fd, statSync6(path).size);
7799
+ if (!parsed) return null;
7800
+ const modules = [];
7801
+ for (let index = 0; index < parsed.names.length; index++) {
7802
+ if (parsed.loaders[index] !== BUN_JAVASCRIPT_LOADER) continue;
7803
+ const range = parsed.contents[index];
7804
+ if (range.offset < 0 || range.length < 0 || range.offset + range.length > parsed.byteCount) {
7805
+ return null;
7806
+ }
7807
+ const bytes = range.length === 0 ? Buffer.alloc(0) : readAt2(fd, range.length, parsed.blobAt + range.offset);
7808
+ if (!bytes) return null;
7809
+ modules.push({
7810
+ index,
7811
+ name: parsed.names[index],
7812
+ source: bytes.toString("utf8"),
7813
+ byteLength: bytes.length
7814
+ });
7815
+ }
7816
+ return modules;
7817
+ } finally {
7818
+ closeSync5(fd);
7819
+ }
7820
+ }
7821
+
7822
+ // src/bun-bundle.ts
7864
7823
  function writableModuleIndex(path) {
7865
7824
  const table = readBunModuleTable(path);
7866
7825
  if (!table) return null;
7867
7826
  const index = table.names.findIndex(tweakccRecognizesModuleName);
7868
7827
  return index < 0 ? null : index;
7869
7828
  }
7829
+ function assertRecognizedEntryModule(path) {
7830
+ const table = readBunModuleTable(path);
7831
+ if (table && !table.names.some(tweakccRecognizesModuleName)) {
7832
+ const entry = table.names[table.entryPointId];
7833
+ throw new Error(
7834
+ `Claude Code entry module ${JSON.stringify(entry)} is not recognized by tweakcc. Update clodex and try again. Claude Code was left unchanged.`
7835
+ );
7836
+ }
7837
+ }
7870
7838
  var BUNDLE_MODULE_SEPARATOR = '\n/*clodex:module-boundary`;{}"]*/\n';
7871
7839
  function readClaudeBundle(path) {
7872
7840
  const modules = readBunJavaScriptModules(path);
@@ -7976,18 +7944,18 @@ function placeholderOf(byteLength) {
7976
7944
  return PLACEHOLDER_TEXT.repeat(Math.ceil(byteLength / PLACEHOLDER_TEXT.length)).slice(0, byteLength);
7977
7945
  }
7978
7946
  function readBlobData(path, table, into) {
7979
- const fd = openSync5(path, "r");
7947
+ const fd = openSync6(path, "r");
7980
7948
  try {
7981
7949
  let read = 0;
7982
7950
  while (read < table.byteCount) {
7983
- const got = readSync4(fd, into, read, table.byteCount - read, table.blobAt + read);
7951
+ const got = readSync5(fd, into, read, table.byteCount - read, table.blobAt + read);
7984
7952
  if (got <= 0) {
7985
7953
  throw new Error(`read ${read} of the ${table.byteCount} blob bytes of ${path}`);
7986
7954
  }
7987
7955
  read += got;
7988
7956
  }
7989
7957
  } finally {
7990
- closeSync5(fd);
7958
+ closeSync6(fd);
7991
7959
  }
7992
7960
  }
7993
7961
  function repointModule(data, table, append) {
@@ -8039,7 +8007,7 @@ function applyBundleWritePlan(path, plan) {
8039
8007
  }
8040
8008
  const offsets = Buffer.from(plan.offsets);
8041
8009
  offsets.writeBigUInt64LE(BigInt(byteCount), 0);
8042
- const fd = openSync5(path, "r+");
8010
+ const fd = openSync6(path, "r+");
8043
8011
  try {
8044
8012
  writeAll(fd, plan.data, repacked.blobAt, path);
8045
8013
  const padding = byteCount - plan.data.length;
@@ -8047,7 +8015,7 @@ function applyBundleWritePlan(path, plan) {
8047
8015
  writeAll(fd, offsets, repacked.blobAt + byteCount, path);
8048
8016
  writeAll(fd, BUN_TRAILER2, repacked.blobAt + byteCount + BUN_OFFSETS_BYTES2, path);
8049
8017
  } finally {
8050
- closeSync5(fd);
8018
+ closeSync6(fd);
8051
8019
  }
8052
8020
  const published = readBunModuleTable(path);
8053
8021
  if (!published) throw new Error(`cannot re-read the Bun module table of ${path} after publishing its blob`);
@@ -8075,7 +8043,7 @@ function applyBundleWritePlan(path, plan) {
8075
8043
  function writeAll(fd, bytes, position, path) {
8076
8044
  let written = 0;
8077
8045
  while (written < bytes.length) {
8078
- const wrote = writeSync3(fd, bytes, written, bytes.length - written, position + written);
8046
+ const wrote = writeSync2(fd, bytes, written, bytes.length - written, position + written);
8079
8047
  if (wrote <= 0) throw new Error(`wrote ${written} of ${bytes.length} blob bytes to ${path}`);
8080
8048
  written += wrote;
8081
8049
  }
@@ -8086,13 +8054,20 @@ import { wrapLanguageModel, extractReasoningMiddleware } from "ai";
8086
8054
 
8087
8055
  // src/oauth/responses-websocket.ts
8088
8056
  import { createHash as createHash5 } from "crypto";
8089
- import { closeSync as closeSync6, openSync as openSync6 } from "fs";
8057
+ import { closeSync as closeSync7, openSync as openSync7 } from "fs";
8090
8058
  import { devNull } from "os";
8091
8059
  import { AsyncLocalStorage } from "async_hooks";
8092
8060
 
8093
8061
  // src/outbound-proxy.ts
8062
+ import { randomUUID as randomUUID3 } from "crypto";
8094
8063
  import { networkInterfaces } from "os";
8095
8064
  import { HttpsProxyAgent } from "https-proxy-agent";
8065
+ var OUTBOUND_PROXY_HOP_HEADER = "x-clodex-proxy-hop";
8066
+ var outboundProxyHopNonce = randomUUID3();
8067
+ function isOwnOutboundProxyHop(value) {
8068
+ return (Array.isArray(value) ? value : [value]).some((entry) => entry?.split(",").some((part) => part.trim() === outboundProxyHopNonce));
8069
+ }
8070
+ var proxyHopHeaders = { [OUTBOUND_PROXY_HOP_HEADER]: outboundProxyHopNonce };
8096
8071
  function hasOutboundProxyEnv(env = process.env) {
8097
8072
  return Boolean(
8098
8073
  env["HTTPS_PROXY"]?.trim() || env["https_proxy"]?.trim() || env["HTTP_PROXY"]?.trim() || env["http_proxy"]?.trim()
@@ -8139,7 +8114,16 @@ function proxyUrlTargetsListener(proxyUrl, listenerHost, listenerPort, localAddr
8139
8114
  }
8140
8115
  const proxyPort = parsed.port ? Number(parsed.port) : parsed.protocol === "https:" ? 443 : parsed.protocol === "http:" ? 80 : void 0;
8141
8116
  if (proxyPort !== listenerPort) return false;
8142
- const normalizeHost = (host) => host.toLowerCase().replace(/^\[|\]$/g, "");
8117
+ const normalizeHost = (host) => {
8118
+ const plain = host.toLowerCase().replace(/^\[|\]$/g, "");
8119
+ const mapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(plain);
8120
+ if (mapped) {
8121
+ const high = parseInt(mapped[1], 16);
8122
+ const low = parseInt(mapped[2], 16);
8123
+ return `${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`;
8124
+ }
8125
+ return plain.replace(/^::ffff:(?=\d+\.)/, "").replace(/^localhost\.$/, "localhost");
8126
+ };
8143
8127
  const proxyHost = normalizeHost(parsed.hostname);
8144
8128
  const boundHost = normalizeHost(listenerHost);
8145
8129
  if (proxyHost === boundHost) return true;
@@ -8172,7 +8156,7 @@ function outboundHttpProxyAgent(targetUrl, env = process.env) {
8172
8156
  if (!parsedProxy.hostname || !["http:", "https:"].includes(parsedProxy.protocol)) {
8173
8157
  throw new TypeError("Invalid proxy URL");
8174
8158
  }
8175
- return new HttpsProxyAgent(parsedProxy, { keepAlive: true });
8159
+ return new HttpsProxyAgent(parsedProxy, { keepAlive: true, headers: { ...proxyHopHeaders } });
8176
8160
  } catch (err) {
8177
8161
  emitParentNotice(
8178
8162
  `clodex: HTTP(S)_PROXY cannot be used for a CONNECT tunnel; using a direct connection (${err instanceof Error ? err.message : String(err)})`
@@ -9888,7 +9872,7 @@ function descriptorExhaustionCode(error) {
9888
9872
  const code = error.code;
9889
9873
  if (isDescriptorExhaustion(code)) return code;
9890
9874
  try {
9891
- closeSync6(openSync6(devNull, "r"));
9875
+ closeSync7(openSync7(devNull, "r"));
9892
9876
  return void 0;
9893
9877
  } catch (probe) {
9894
9878
  const probeCode = probe.code;
@@ -10784,7 +10768,7 @@ function createResponsesWebSocketFetch(wsUrl, log13, options = {}) {
10784
10768
  }
10785
10769
 
10786
10770
  // src/oauth/claude-identity.ts
10787
- import { createHash as createHash6, randomUUID as randomUUID3 } from "crypto";
10771
+ import { createHash as createHash6, randomUUID as randomUUID4 } from "crypto";
10788
10772
  var CLAUDE_CODE_CLI_VERSION = "2.1.195";
10789
10773
  var CLAUDE_CODE_USER_AGENT = `claude-cli/${CLAUDE_CODE_CLI_VERSION} (external, cli)`;
10790
10774
  var CLAUDE_CODE_ENTRYPOINT = process.env.CLAUDE_CODE_ENTRYPOINT ?? "cli";
@@ -10793,7 +10777,7 @@ var sessionCache = /* @__PURE__ */ new Map();
10793
10777
  function getOrCreateSessionId(seed) {
10794
10778
  let id = sessionCache.get(seed);
10795
10779
  if (!id) {
10796
- id = randomUUID3();
10780
+ id = randomUUID4();
10797
10781
  sessionCache.set(seed, id);
10798
10782
  }
10799
10783
  return id;
@@ -11717,7 +11701,7 @@ function thinkingProviderOptions(npm) {
11717
11701
 
11718
11702
  // src/proxy.ts
11719
11703
  import { createServer } from "http";
11720
- import { appendFileSync as appendFileSync2, openSync as openSync7, writeSync as writeSync4, closeSync as closeSync7 } from "fs";
11704
+ import { appendFileSync as appendFileSync2, openSync as openSync8, writeSync as writeSync3, closeSync as closeSync8 } from "fs";
11721
11705
 
11722
11706
  // src/http-utils.ts
11723
11707
  import * as zlib from "zlib";
@@ -11949,7 +11933,7 @@ function routeUnavailableMessage(modelId, reason) {
11949
11933
  }
11950
11934
 
11951
11935
  // src/upstream-forward.ts
11952
- import { randomUUID as randomUUID4 } from "crypto";
11936
+ import { randomUUID as randomUUID5 } from "crypto";
11953
11937
  import { Readable, Transform } from "stream";
11954
11938
  import { StringDecoder } from "string_decoder";
11955
11939
 
@@ -12046,7 +12030,7 @@ function upstreamHoldsThreads(url) {
12046
12030
  }
12047
12031
  }
12048
12032
  function anchorSafeMessageId(id) {
12049
- return typeof id === "string" && id.startsWith("msg_") ? "clodex_" + randomUUID4().replace(/-/g, "") : id;
12033
+ return typeof id === "string" && id.startsWith("msg_") ? "clodex_" + randomUUID5().replace(/-/g, "") : id;
12050
12034
  }
12051
12035
  function isThreadContinuation(body) {
12052
12036
  const thread = body.thread;
@@ -12195,10 +12179,10 @@ async function relayAnthropicMessages(res, messagesUrl, body, apiKey, clientWant
12195
12179
  }
12196
12180
 
12197
12181
  // src/proxy.ts
12198
- import { randomUUID as randomUUID6 } from "crypto";
12182
+ import { randomUUID as randomUUID7 } from "crypto";
12199
12183
 
12200
12184
  // src/sdk-adapter.ts
12201
- import { createHash as createHash7, randomUUID as randomUUID5 } from "crypto";
12185
+ import { createHash as createHash7, randomUUID as randomUUID6 } from "crypto";
12202
12186
  import { streamText, generateText, tool, jsonSchema } from "ai";
12203
12187
 
12204
12188
  // src/proxy-shared.ts
@@ -13042,7 +13026,7 @@ function forwardAbortSignal(source, target) {
13042
13026
  return () => source.removeEventListener("abort", forward);
13043
13027
  }
13044
13028
  function translatedMessageId() {
13045
- return "clodex_" + randomUUID5().replace(/-/g, "");
13029
+ return "clodex_" + randomUUID6().replace(/-/g, "");
13046
13030
  }
13047
13031
  async function writeAnthropicStream(stream, modelId, write, log13, observer, tools) {
13048
13032
  const messageId = translatedMessageId();
@@ -13567,12 +13551,12 @@ function createTranslationLifecycle(logPath, requestId, claudeSessionId, modelId
13567
13551
  function appendSecureLog(logPath, line) {
13568
13552
  const redacted = redactTraceLine(line);
13569
13553
  try {
13570
- const fd = openSync7(logPath, "a", 384);
13554
+ const fd = openSync8(logPath, "a", 384);
13571
13555
  try {
13572
- writeSync4(fd, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
13556
+ writeSync3(fd, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
13573
13557
  `);
13574
13558
  } finally {
13575
- closeSync7(fd);
13559
+ closeSync8(fd);
13576
13560
  }
13577
13561
  } catch {
13578
13562
  try {
@@ -13619,7 +13603,7 @@ function configuredAliasLookupNames(alias) {
13619
13603
  }))].map(normalizeRouteLookupId);
13620
13604
  }
13621
13605
  async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenceLogPath, debugLogPath, webSocketDiagnosticsLogPath, modelAliases) {
13622
- const proxyToken = randomUUID6();
13606
+ const proxyToken = randomUUID7();
13623
13607
  silenceSdkWarnings();
13624
13608
  if (routes.length === 0) {
13625
13609
  throw new Error("Proxy catalog requires at least one route");
@@ -14042,7 +14026,7 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
14042
14026
  res,
14043
14027
  upstreamStatus === 500 ? 502 : upstreamStatus,
14044
14028
  clientMessage,
14045
- contextLengthExceeded ? relayRequestId ?? randomUUID6() : void 0
14029
+ contextLengthExceeded ? relayRequestId ?? randomUUID7() : void 0
14046
14030
  );
14047
14031
  } else {
14048
14032
  const errorType = anthropicErrorType(upstreamStatus, details?.transportCode);
@@ -14050,7 +14034,7 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
14050
14034
  data: ${JSON.stringify({
14051
14035
  type: "error",
14052
14036
  error: { type: errorType, message: clientMessage },
14053
- ...contextLengthExceeded ? { request_id: relayRequestId ?? randomUUID6() } : {}
14037
+ ...contextLengthExceeded ? { request_id: relayRequestId ?? randomUUID7() } : {}
14054
14038
  })}
14055
14039
 
14056
14040
  `);
@@ -14440,10 +14424,10 @@ function tryAcquirePatchLock(lockPath = getPatchLockPath(), opts = {}) {
14440
14424
  mkdirSync5(join8(lockPath, ".."), { recursive: true, mode: 448 });
14441
14425
  for (let attempt = 0; attempt < 2; attempt++) {
14442
14426
  try {
14443
- const fd = openSync8(lockPath, "wx");
14427
+ const fd = openSync9(lockPath, "wx");
14444
14428
  const content = { pid: process.pid, startedAt: now };
14445
14429
  writeFileSync5(fd, JSON.stringify(content));
14446
- closeSync8(fd);
14430
+ closeSync9(fd);
14447
14431
  return () => {
14448
14432
  try {
14449
14433
  unlinkSync3(lockPath);
@@ -14647,7 +14631,7 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
14647
14631
  const candidatePath = join8(candidateDir, basename(binaryPath));
14648
14632
  const seedCandidate = async (from) => {
14649
14633
  copyFileSync(from, candidatePath);
14650
- const shim = shimEntryModuleName(candidatePath);
14634
+ assertRecognizedEntryModule(candidatePath);
14651
14635
  const installation = await tryDetectInstallation({ path: candidatePath });
14652
14636
  const bundle = readClaudeBundle(candidatePath);
14653
14637
  if (!bundle && installation.kind === "native") {
@@ -14656,7 +14640,6 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
14656
14640
  );
14657
14641
  }
14658
14642
  const source = bundle ? bundle.source : await readContent(installation);
14659
- if (shim) restoreEntryModuleName(candidatePath, shim, { resign: false });
14660
14643
  return { installation, source, bundle };
14661
14644
  };
14662
14645
  const facts = collectPristineFacts({
@@ -14766,8 +14749,6 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
14766
14749
  local = discardLocalPatchOutcome(builtIn.content, local.results);
14767
14750
  }
14768
14751
  results = [...results, ...local.results];
14769
- const writeShim = shimEntryModuleName(candidatePath);
14770
- let publishedBlob = false;
14771
14752
  if (loaded.bundle) {
14772
14753
  const writable = writableModuleIndex(candidatePath);
14773
14754
  if (writable === null) {
@@ -14783,14 +14764,12 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
14783
14764
  await writeContent(loaded.installation, plan2.content);
14784
14765
  if (bunPointerShim) restoreBunCompiledPointer(candidatePath, bunPointerShim);
14785
14766
  applyBundleWritePlan(candidatePath, plan2);
14786
- publishedBlob = true;
14787
14767
  } else {
14788
14768
  const bunPointerShim = shimBunCompiledPointer(candidatePath);
14789
14769
  await writeContent(loaded.installation, local.content);
14790
14770
  if (bunPointerShim) restoreBunCompiledPointer(candidatePath, bunPointerShim);
14791
14771
  }
14792
- if (writeShim) restoreEntryModuleName(candidatePath, writeShim, { resign: true });
14793
- else if (publishedBlob) resignMachOBinary(candidatePath);
14772
+ signAndVerifyMachOCandidate(candidatePath, binaryPath);
14794
14773
  patchedSize = statSync7(candidatePath).size;
14795
14774
  patchedSha256 = sha256File(candidatePath);
14796
14775
  renameSync2(candidatePath, binaryPath);
@@ -15380,15 +15359,15 @@ function localProvidersToServerModels(localProviders) {
15380
15359
  }
15381
15360
 
15382
15361
  // src/registry/credential-cleanup-journal.ts
15383
- import { randomUUID as randomUUID7 } from "crypto";
15362
+ import { randomUUID as randomUUID8 } from "crypto";
15384
15363
  import {
15385
- closeSync as closeSync9,
15364
+ closeSync as closeSync10,
15386
15365
  existsSync as existsSync5,
15387
15366
  fstatSync as fstatSync3,
15388
15367
  fsyncSync as fsyncSync2,
15389
15368
  lstatSync,
15390
15369
  mkdirSync as mkdirSync6,
15391
- openSync as openSync9,
15370
+ openSync as openSync10,
15392
15371
  readFileSync as readFileSync11,
15393
15372
  renameSync as renameSync3,
15394
15373
  unlinkSync as unlinkSync4,
@@ -15480,7 +15459,7 @@ function readJournalUnlocked(path) {
15480
15459
  if (before.isSymbolicLink() || !before.isFile()) {
15481
15460
  throw new Error("Credential cleanup journal must be a regular file.");
15482
15461
  }
15483
- fd = openSync9(path, "r");
15462
+ fd = openSync10(path, "r");
15484
15463
  const opened = fstatSync3(fd);
15485
15464
  if (before.dev !== opened.dev || before.ino !== opened.ino) {
15486
15465
  throw new Error("Credential cleanup journal changed while opening.");
@@ -15501,39 +15480,39 @@ function readJournalUnlocked(path) {
15501
15480
  const message = error instanceof Error ? error.message : String(error);
15502
15481
  throw new Error(`Could not read credential cleanup journal: ${message}`);
15503
15482
  } finally {
15504
- if (fd !== void 0) closeSync9(fd);
15483
+ if (fd !== void 0) closeSync10(fd);
15505
15484
  }
15506
15485
  }
15507
15486
  function syncParentDirectory(path) {
15508
15487
  let fd;
15509
15488
  try {
15510
- fd = openSync9(dirname6(path), "r");
15489
+ fd = openSync10(dirname6(path), "r");
15511
15490
  fsyncSync2(fd);
15512
15491
  } catch (error) {
15513
15492
  const code = error.code;
15514
15493
  if (code !== "EINVAL" && code !== "ENOTSUP" && code !== "EPERM") throw error;
15515
15494
  } finally {
15516
- if (fd !== void 0) closeSync9(fd);
15495
+ if (fd !== void 0) closeSync10(fd);
15517
15496
  }
15518
15497
  }
15519
15498
  function writeJournalUnlocked(journal, path) {
15520
15499
  assertRegistryWriteOwnership(path);
15521
15500
  ensureSecureAppHome();
15522
15501
  mkdirSync6(dirname6(path), { recursive: true, mode: DIR_MODE2 });
15523
- const tmp = `${path}.${process.pid}.${randomUUID7()}.tmp`;
15502
+ const tmp = `${path}.${process.pid}.${randomUUID8()}.tmp`;
15524
15503
  let fd;
15525
15504
  try {
15526
- fd = openSync9(tmp, "wx", FILE_MODE4);
15505
+ fd = openSync10(tmp, "wx", FILE_MODE4);
15527
15506
  writeFileSync6(fd, `${JSON.stringify(journal, null, 2)}
15528
15507
  `);
15529
15508
  fsyncSync2(fd);
15530
- closeSync9(fd);
15509
+ closeSync10(fd);
15531
15510
  fd = void 0;
15532
15511
  assertRegistryWriteOwnership(path);
15533
15512
  renameSync3(tmp, path);
15534
15513
  syncParentDirectory(path);
15535
15514
  } finally {
15536
- if (fd !== void 0) closeSync9(fd);
15515
+ if (fd !== void 0) closeSync10(fd);
15537
15516
  try {
15538
15517
  unlinkSync4(tmp);
15539
15518
  } catch (error) {
@@ -18637,7 +18616,7 @@ async function askSaveServerPassword() {
18637
18616
 
18638
18617
  // src/server/router.ts
18639
18618
  import { createServer as createServer2 } from "http";
18640
- import { randomUUID as randomUUID8 } from "crypto";
18619
+ import { randomUUID as randomUUID9 } from "crypto";
18641
18620
 
18642
18621
  // src/openai-adapter.ts
18643
18622
  import { tool as tool2, jsonSchema as jsonSchema2, streamText as streamText2, generateText as generateText2 } from "ai";
@@ -19053,7 +19032,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
19053
19032
  plog(`model not found: ${body.model}`);
19054
19033
  return;
19055
19034
  }
19056
- const requestId = randomUUID8();
19035
+ const requestId = randomUUID9();
19057
19036
  const claudeSessionIdHeader = Array.isArray(req.headers["x-claude-code-session-id"]) ? req.headers["x-claude-code-session-id"][0] : req.headers["x-claude-code-session-id"];
19058
19037
  const claudeSessionId = extractClaudeSessionId(body, claudeSessionIdHeader);
19059
19038
  const claudeAgentIds = extractClaudeAgentIds(req.headers);
@@ -19727,7 +19706,7 @@ import * as http2 from "http";
19727
19706
  import * as https from "https";
19728
19707
  import * as net from "net";
19729
19708
  import { PassThrough } from "stream";
19730
- import { randomUUID as randomUUID9 } from "crypto";
19709
+ import { randomUUID as randomUUID10 } from "crypto";
19731
19710
  import { URL as URL2 } from "url";
19732
19711
  import { createBrotliDecompress, createGunzip, createInflate } from "zlib";
19733
19712
 
@@ -20019,7 +19998,7 @@ function requestHeadersWithoutProxyHeaders(req) {
20019
19998
  const headers = [];
20020
19999
  for (let i = 0; i < req.rawHeaders.length; i += 2) {
20021
20000
  const name = req.rawHeaders[i];
20022
- if (/^proxy-(authorization|connection)$/i.test(name)) continue;
20001
+ if (/^proxy-(authorization|connection)$/i.test(name) || name.toLowerCase() === OUTBOUND_PROXY_HOP_HEADER) continue;
20023
20002
  headers.push(name, req.rawHeaders[i + 1] ?? "");
20024
20003
  }
20025
20004
  return headers;
@@ -20556,6 +20535,7 @@ async function startHttpProxy(options) {
20556
20535
  const anthropicOrigin = new URL2(options.anthropicOrigin ?? "https://api.anthropic.com");
20557
20536
  const anthropicProxyUrl = outboundProxyUrlForTarget(anthropicOrigin.href);
20558
20537
  let anthropicAgent;
20538
+ let anthropicViaProxy = false;
20559
20539
  let adapter = options.adapterHandle ?? null;
20560
20540
  if (options.routes.length > 0) {
20561
20541
  adapter ??= await startProxyCatalog(
@@ -20570,11 +20550,27 @@ async function startHttpProxy(options) {
20570
20550
  }
20571
20551
  const adapterAgent = adapter ? new http2.Agent({ keepAlive: true }) : void 0;
20572
20552
  let shuttingDown = false;
20553
+ let warnedProxyLoop = false;
20554
+ const rejectProxyLoop = (target) => {
20555
+ if (warnedProxyLoop) return;
20556
+ warnedProxyLoop = true;
20557
+ const secure = target.startsWith("https:");
20558
+ const candidates = secure ? ["HTTPS_PROXY", "https_proxy"] : ["HTTP_PROXY", "http_proxy"];
20559
+ const name = candidates.find((key) => process.env[key]?.trim()) ?? candidates[0];
20560
+ emitParentNotice(`clodex: outbound proxy loop detected; check ${name} (request returned to this proxy)`);
20561
+ };
20573
20562
  const mitmServer = https.createServer({
20574
20563
  key: certificates.serverKey,
20575
20564
  cert: certificates.serverCert,
20576
20565
  minVersion: "TLSv1.2"
20577
20566
  }, async (req, res) => {
20567
+ if (isOwnOutboundProxyHop(req.headers[OUTBOUND_PROXY_HOP_HEADER])) {
20568
+ rejectProxyLoop("https://api.anthropic.com");
20569
+ res.writeHead(508, { "Content-Type": "text/plain" });
20570
+ res.end("Outbound proxy loop detected");
20571
+ return;
20572
+ }
20573
+ delete req.headers[OUTBOUND_PROXY_HOP_HEADER];
20578
20574
  let rawBody;
20579
20575
  try {
20580
20576
  rawBody = await readRawBody(req);
@@ -20585,7 +20581,7 @@ async function startHttpProxy(options) {
20585
20581
  }
20586
20582
  const messagesEndpoint = anthropicMessagesEndpoint(req.url);
20587
20583
  if (req.method === "POST" && messagesEndpoint) {
20588
- const requestId = randomUUID9();
20584
+ const requestId = randomUUID10();
20589
20585
  let parsed = null;
20590
20586
  let route;
20591
20587
  let adapterBody = rawBody;
@@ -20733,6 +20729,12 @@ async function startHttpProxy(options) {
20733
20729
  return connectTunnelAgents.get(proxyUrl);
20734
20730
  };
20735
20731
  mitmServer.on("upgrade", (req, socket, head) => {
20732
+ if (isOwnOutboundProxyHop(req.headers[OUTBOUND_PROXY_HOP_HEADER])) {
20733
+ rejectProxyLoop("https://api.anthropic.com");
20734
+ socket.once("error", () => socket.destroy());
20735
+ socket.end("HTTP/1.1 508 Loop Detected\r\nConnection: close\r\n\r\n", () => socket.destroy());
20736
+ return;
20737
+ }
20736
20738
  forwardAnthropicUpgrade(
20737
20739
  req,
20738
20740
  socket,
@@ -20743,13 +20745,40 @@ async function startHttpProxy(options) {
20743
20745
  sockets
20744
20746
  );
20745
20747
  });
20746
- const proxyServer = http2.createServer(forwardPlainHttp);
20748
+ const proxyServer = http2.createServer((req, res) => {
20749
+ if (isOwnOutboundProxyHop(req.headers[OUTBOUND_PROXY_HOP_HEADER])) {
20750
+ rejectProxyLoop(req.url ?? "");
20751
+ res.writeHead(508, { "Content-Type": "text/plain" });
20752
+ res.end("Outbound proxy loop detected");
20753
+ return;
20754
+ }
20755
+ forwardPlainHttp(req, res);
20756
+ });
20747
20757
  proxyServer.on("connection", (socket) => {
20748
20758
  sockets.add(socket);
20749
20759
  socket.once("close", () => sockets.delete(socket));
20750
20760
  });
20751
20761
  proxyServer.on("connect", (req, clientSocket, head) => {
20762
+ const ownHop = isOwnOutboundProxyHop(req.headers[OUTBOUND_PROXY_HOP_HEADER]);
20763
+ const rejectOwnHop = () => {
20764
+ rejectProxyLoop(`https://${req.url ?? ""}`);
20765
+ clientSocket.once("error", () => clientSocket.destroy());
20766
+ const body = "Outbound proxy loop detected";
20767
+ clientSocket.end(
20768
+ `HTTP/1.1 508 Loop Detected\r
20769
+ Content-Type: text/plain\r
20770
+ Content-Length: ${Buffer.byteLength(body)}\r
20771
+ Connection: close\r
20772
+ \r
20773
+ ${body}`,
20774
+ () => clientSocket.destroy()
20775
+ );
20776
+ };
20752
20777
  if (shouldInterceptConnect(req.url ?? "")) {
20778
+ if (ownHop && anthropicViaProxy) {
20779
+ rejectOwnHop();
20780
+ return;
20781
+ }
20753
20782
  clientSocket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
20754
20783
  if (head.length > 0) clientSocket.unshift(head);
20755
20784
  mitmServer.emit("connection", clientSocket);
@@ -20772,6 +20801,10 @@ async function startHttpProxy(options) {
20772
20801
  );
20773
20802
  }
20774
20803
  const outboundAgent = outboundProxyUrl !== void 0 && !selfTargeting ? connectTunnelAgent(outboundProxyUrl, targetUrl) : void 0;
20804
+ if (ownHop && outboundAgent) {
20805
+ rejectOwnHop();
20806
+ return;
20807
+ }
20775
20808
  if (outboundAgent) {
20776
20809
  let upstream2;
20777
20810
  let proxyConnectStatus;
@@ -20790,7 +20823,7 @@ async function startHttpProxy(options) {
20790
20823
  if (proxyConnectStatus !== 200 || clientSocket.destroyed) {
20791
20824
  connected.destroy();
20792
20825
  if (!clientSocket.destroyed) {
20793
- clientSocket.end("HTTP/1.1 502 Bad Gateway\r\n\r\n", () => clientSocket.destroy());
20826
+ clientSocket.end(proxyConnectStatus === 508 ? "HTTP/1.1 508 Loop Detected\r\n\r\n" : "HTTP/1.1 502 Bad Gateway\r\n\r\n", () => clientSocket.destroy());
20794
20827
  }
20795
20828
  return;
20796
20829
  }
@@ -20868,6 +20901,7 @@ async function startHttpProxy(options) {
20868
20901
  );
20869
20902
  } else {
20870
20903
  anthropicAgent = outboundHttpProxyAgent(anthropicOrigin.href);
20904
+ anthropicViaProxy = anthropicAgent !== void 0;
20871
20905
  }
20872
20906
  anthropicAgent ??= createPassthroughAgent();
20873
20907
  return {