@bman654/clodex 2.8.3 → 2.8.4
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/README.md +8 -1
- package/dist/cli.js +408 -111
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -382,7 +382,7 @@ import { join } from "path";
|
|
|
382
382
|
// package.json
|
|
383
383
|
var package_default = {
|
|
384
384
|
name: "@bman654/clodex",
|
|
385
|
-
version: "2.8.
|
|
385
|
+
version: "2.8.4",
|
|
386
386
|
publishConfig: {
|
|
387
387
|
access: "public"
|
|
388
388
|
},
|
|
@@ -3423,7 +3423,7 @@ function savedStopsAfter(current, assignments) {
|
|
|
3423
3423
|
}
|
|
3424
3424
|
|
|
3425
3425
|
// src/patch-transforms.ts
|
|
3426
|
-
var PATCH_TRANSFORMS_VERSION =
|
|
3426
|
+
var PATCH_TRANSFORMS_VERSION = 11;
|
|
3427
3427
|
var NATIVE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
3428
3428
|
var BASE_EFFORT_LEVELS = ["low", "medium", "high"];
|
|
3429
3429
|
function projectNativeEffort(effort) {
|
|
@@ -3633,19 +3633,19 @@ function applyClodexPatches(source, config) {
|
|
|
3633
3633
|
}
|
|
3634
3634
|
if (Object.keys(CONTEXT_BY_KEY).length) {
|
|
3635
3635
|
const MARKER = "/*ccpatch:ctx*/";
|
|
3636
|
-
const
|
|
3636
|
+
const snippetFor = (modelParam) => MARKER + "var _ccw=(" + JSON.stringify(CONTEXT_BY_KEY) + ")[String(" + modelParam + '||"").trim().toLowerCase()];if(_ccw!==void 0)return _ccw;';
|
|
3637
3637
|
if (js.includes(MARKER)) {
|
|
3638
3638
|
applyOnce(
|
|
3639
3639
|
"PATCH 7: per-model context window (refresh)",
|
|
3640
|
-
/\/\*ccpatch:ctx\*\/var _ccw=\(\{[^{}]*\}\)\[[
|
|
3641
|
-
() =>
|
|
3640
|
+
/\/\*ccpatch:ctx\*\/var _ccw=\(\{[^{}]*\}\)\[String\(([\w$]+)\|\|""\)\.trim\(\)\.toLowerCase\(\)\];if\(_ccw!==void 0\)return _ccw;/,
|
|
3641
|
+
(_m, modelParam) => snippetFor(modelParam),
|
|
3642
3642
|
{ required: true, noopIsSkip: true }
|
|
3643
3643
|
);
|
|
3644
3644
|
} else {
|
|
3645
3645
|
applyOnce(
|
|
3646
3646
|
"PATCH 7: per-model context window",
|
|
3647
|
-
/(function [\w$]+\(
|
|
3648
|
-
(_m, head, body) => head +
|
|
3647
|
+
/(function [\w$]+\(([\w$]+),([\w$]+)\)\{)(let [\w$]+=[\w$]+\(\);if\([\w$]+!==void 0\)return [\w$]+;if\([\w$]+\(\2,\3\)\)return [\w$]+;return [\w$]+\(\2,\3\)\})/,
|
|
3648
|
+
(_m, head, modelParam, _windowParam, body) => head + snippetFor(modelParam) + body,
|
|
3649
3649
|
{ required: true }
|
|
3650
3650
|
);
|
|
3651
3651
|
}
|
|
@@ -3727,15 +3727,15 @@ function applyClodexPatches(source, config) {
|
|
|
3727
3727
|
const marker = "/*ccpatch:child-network-env*/";
|
|
3728
3728
|
const contractVar = q(NETWORK_ENV_CONTRACT_VAR);
|
|
3729
3729
|
const networkVars = JSON.stringify(CHILD_NETWORK_ENV_VARS);
|
|
3730
|
-
const requiredBodyLiterals = [
|
|
3731
|
-
|
|
3732
|
-
"CLAUDE_CODE_REMOTE",
|
|
3730
|
+
const requiredBodyLiterals = ["{...process.env"];
|
|
3731
|
+
const scrubbedEnvNames = [
|
|
3733
3732
|
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
3734
3733
|
"CLAUDE_CODE_SUBSCRIPTION_TYPE",
|
|
3735
3734
|
"CLAUDE_BG_PTY_AUTH",
|
|
3736
3735
|
'"OTEL_"',
|
|
3737
3736
|
"CLAUDE_CODE_OTEL_DIAG_STDERR"
|
|
3738
3737
|
];
|
|
3738
|
+
const MIN_SCRUBBED_ENV_NAMES = 1;
|
|
3739
3739
|
const blockEndIndex = (text5, open2) => {
|
|
3740
3740
|
const depths = [0];
|
|
3741
3741
|
const templates = [false];
|
|
@@ -3815,11 +3815,15 @@ function applyClodexPatches(source, config) {
|
|
|
3815
3815
|
/(function [\w$]+\(\)\{)(let (?:[^;{}]|\{[^;{}]*\})*?[\w$]+\(process\.env\.CLAUDE_CODE_REMOTE\)\?(?:(?!\}\s*function )[\s\S])*?\)return process\.env;let ([\w$]+)=\{(?:(?!\}\s*function )[\s\S])*?return \3)(\})/,
|
|
3816
3816
|
(match, head, body, _copyVar, tail) => {
|
|
3817
3817
|
const at = js.indexOf(match);
|
|
3818
|
-
const
|
|
3819
|
-
const
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3818
|
+
const closingBrace = at < 0 ? -1 : blockEndIndex(js, at + head.length - 1);
|
|
3819
|
+
const braceScanFailed = at < 0 || closingBrace < 0;
|
|
3820
|
+
const bound = braceScanFailed ? 0 : closingBrace - at - (match.length - 1);
|
|
3821
|
+
const missingLiteral = requiredBodyLiterals.find((literal) => !body.includes(literal));
|
|
3822
|
+
const scrubbedSeen = scrubbedEnvNames.filter((name) => body.includes(name));
|
|
3823
|
+
const why = missingLiteral !== void 0 ? "body does not contain " + missingLiteral : scrubbedSeen.length < MIN_SCRUBBED_ENV_NAMES ? "body scrubs only " + scrubbedSeen.length + " of the " + scrubbedEnvNames.length + " known child-env names (expected at least " + MIN_SCRUBBED_ENV_NAMES + ")" : /\bfunction\s*[\w$]*\(/.test(body) ? "body declares a nested function" : braceScanFailed ? "the brace walk never reached the function's closing brace" : bound !== 0 ? "match ends " + bound + " characters from the function it started in" : void 0;
|
|
3824
|
+
if (why !== void 0) {
|
|
3825
|
+
log12("FAIL", patchName, "target validation failed: " + why);
|
|
3826
|
+
fail("clodex patch: child network environment target validation failed: " + why);
|
|
3823
3827
|
}
|
|
3824
3828
|
const restoredBody = body.replace(/process\.env/g, "_clodexChildEnv");
|
|
3825
3829
|
const restore = marker + "let _clodexChildEnv=process.env,_clodexNetworkRaw=_clodexChildEnv[" + contractVar + "];if(_clodexNetworkRaw!==void 0){_clodexChildEnv={..._clodexChildEnv};delete _clodexChildEnv[" + contractVar + '];try{let _clodexNetwork=JSON.parse(_clodexNetworkRaw);if(_clodexNetwork&&typeof _clodexNetwork==="object"&&!Array.isArray(_clodexNetwork)&&_clodexNetwork.version===1&&_clodexNetwork.original&&typeof _clodexNetwork.original==="object"&&!Array.isArray(_clodexNetwork.original)&&_clodexNetwork.injected&&typeof _clodexNetwork.injected==="object"&&!Array.isArray(_clodexNetwork.injected)&&Object.keys(_clodexNetwork.original).every(_clodexKey=>' + networkVars + '.includes(_clodexKey)&&(typeof _clodexNetwork.original[_clodexKey]==="string"||_clodexNetwork.original[_clodexKey]===null)&&Object.prototype.hasOwnProperty.call(_clodexNetwork.injected,_clodexKey))&&Object.keys(_clodexNetwork.injected).every(_clodexKey=>' + networkVars + '.includes(_clodexKey)&&(typeof _clodexNetwork.injected[_clodexKey]==="string"||_clodexNetwork.injected[_clodexKey]===null)&&Object.prototype.hasOwnProperty.call(_clodexNetwork.original,_clodexKey)))for(let _clodexKey of ' + networkVars + '){if(Object.prototype.hasOwnProperty.call(_clodexNetwork.original,_clodexKey)&&Object.prototype.hasOwnProperty.call(_clodexNetwork.injected,_clodexKey)){let _clodexOriginal=_clodexNetwork.original[_clodexKey],_clodexInjected=_clodexNetwork.injected[_clodexKey],_clodexCurrent=_clodexChildEnv[_clodexKey]===void 0?null:_clodexChildEnv[_clodexKey];if((typeof _clodexOriginal==="string"||_clodexOriginal===null)&&(typeof _clodexInjected==="string"||_clodexInjected===null)&&_clodexCurrent===_clodexInjected){if(_clodexOriginal===null)delete _clodexChildEnv[_clodexKey];else _clodexChildEnv[_clodexKey]=_clodexOriginal}}}}catch(_clodexError){}}';
|
|
@@ -3844,8 +3848,8 @@ import {
|
|
|
3844
3848
|
statSync as statSync6,
|
|
3845
3849
|
unlinkSync as unlinkSync3,
|
|
3846
3850
|
writeFileSync as writeFileSync5,
|
|
3847
|
-
openSync as
|
|
3848
|
-
closeSync as
|
|
3851
|
+
openSync as openSync6,
|
|
3852
|
+
closeSync as closeSync6,
|
|
3849
3853
|
realpathSync
|
|
3850
3854
|
} from "fs";
|
|
3851
3855
|
import { homedir as homedir3 } from "os";
|
|
@@ -6201,6 +6205,7 @@ function writeInferenceResponseLifecycleLog(path, entry) {
|
|
|
6201
6205
|
const outputTokens = nonNegativeInteger(entry.outputTokens);
|
|
6202
6206
|
const cacheCreationInputTokens = nonNegativeInteger(entry.cacheCreationInputTokens);
|
|
6203
6207
|
const cacheReadInputTokens = nonNegativeInteger(entry.cacheReadInputTokens);
|
|
6208
|
+
const attempt = nonNegativeInteger(entry.attempt);
|
|
6204
6209
|
writeSecureLogLine(path, JSON.stringify({
|
|
6205
6210
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6206
6211
|
event: entry.event,
|
|
@@ -6231,7 +6236,9 @@ function writeInferenceResponseLifecycleLog(path, entry) {
|
|
|
6231
6236
|
...entry.errorCode ? { errorCode: compactLogValue(entry.errorCode, 100) } : {},
|
|
6232
6237
|
...entry.errorSignature ? { errorSignature: compactLogValue(entry.errorSignature, 100) } : {},
|
|
6233
6238
|
...entry.failureSource ? { failureSource: entry.failureSource } : {},
|
|
6234
|
-
...entry.terminationSource ? { terminationSource: entry.terminationSource } : {}
|
|
6239
|
+
...entry.terminationSource ? { terminationSource: entry.terminationSource } : {},
|
|
6240
|
+
...attempt !== void 0 ? { attempt } : {},
|
|
6241
|
+
...entry.reusedSocket !== void 0 ? { reusedSocket: entry.reusedSocket } : {}
|
|
6235
6242
|
}));
|
|
6236
6243
|
}
|
|
6237
6244
|
function writeProxyLifecycleLog(path, entry) {
|
|
@@ -7058,8 +7065,208 @@ function resignMachOBinary(path) {
|
|
|
7058
7065
|
}
|
|
7059
7066
|
}
|
|
7060
7067
|
|
|
7061
|
-
// src/bun-
|
|
7068
|
+
// src/bun-compiled-pointer.ts
|
|
7062
7069
|
import { closeSync as closeSync3, openSync as openSync3, readSync as readSync2, writeSync as writeSync3 } from "fs";
|
|
7070
|
+
var TWEAKCC_SCAN_STRIDE = 16384n;
|
|
7071
|
+
var SCAN_CHUNK = 1 << 20;
|
|
7072
|
+
var ELF_MAGIC = 1179403647;
|
|
7073
|
+
var ELFCLASS64 = 2;
|
|
7074
|
+
var ELFDATA2LSB = 1;
|
|
7075
|
+
var PT_LOAD = 1;
|
|
7076
|
+
var PF_W = 2;
|
|
7077
|
+
function readAt2(fd, length, position) {
|
|
7078
|
+
const buf = Buffer.alloc(length);
|
|
7079
|
+
let read = 0;
|
|
7080
|
+
while (read < length) {
|
|
7081
|
+
const n = readSync2(fd, buf, read, length - read, position + read);
|
|
7082
|
+
if (n <= 0) break;
|
|
7083
|
+
read += n;
|
|
7084
|
+
}
|
|
7085
|
+
return read === length ? buf : buf.subarray(0, read);
|
|
7086
|
+
}
|
|
7087
|
+
function readElfLayout(fd) {
|
|
7088
|
+
const ident = readAt2(fd, 64, 0);
|
|
7089
|
+
if (ident.length < 64) return null;
|
|
7090
|
+
if (ident.readUInt32LE(0) !== ELF_MAGIC) return null;
|
|
7091
|
+
if (ident[4] !== ELFCLASS64 || ident[5] !== ELFDATA2LSB) return null;
|
|
7092
|
+
const phoff = ident.readBigUInt64LE(32);
|
|
7093
|
+
const shoff = ident.readBigUInt64LE(40);
|
|
7094
|
+
const phentsize = ident.readUInt16LE(54);
|
|
7095
|
+
const phnum = ident.readUInt16LE(56);
|
|
7096
|
+
const shentsize = ident.readUInt16LE(58);
|
|
7097
|
+
const shnum = ident.readUInt16LE(60);
|
|
7098
|
+
const shstrndx = ident.readUInt16LE(62);
|
|
7099
|
+
if (shnum === 0 || phnum === 65535) return null;
|
|
7100
|
+
if (shstrndx >= shnum || shentsize < 64 || phentsize < 56) return null;
|
|
7101
|
+
const shTable = readAt2(fd, shnum * shentsize, Number(shoff));
|
|
7102
|
+
if (shTable.length !== shnum * shentsize) return null;
|
|
7103
|
+
const raw = [];
|
|
7104
|
+
for (let i = 0; i < shnum; i++) {
|
|
7105
|
+
const at = i * shentsize;
|
|
7106
|
+
raw.push({
|
|
7107
|
+
nameOffset: shTable.readUInt32LE(at),
|
|
7108
|
+
addr: shTable.readBigUInt64LE(at + 16),
|
|
7109
|
+
offset: shTable.readBigUInt64LE(at + 24),
|
|
7110
|
+
size: shTable.readBigUInt64LE(at + 32)
|
|
7111
|
+
});
|
|
7112
|
+
}
|
|
7113
|
+
const strtab = raw[shstrndx];
|
|
7114
|
+
const names = readAt2(fd, Number(strtab.size), Number(strtab.offset));
|
|
7115
|
+
const sections = raw.map((section) => {
|
|
7116
|
+
const start = section.nameOffset;
|
|
7117
|
+
let end = start;
|
|
7118
|
+
while (end < names.length && names[end] !== 0) end++;
|
|
7119
|
+
return {
|
|
7120
|
+
name: names.toString("utf8", start, end),
|
|
7121
|
+
addr: section.addr,
|
|
7122
|
+
offset: section.offset,
|
|
7123
|
+
size: section.size
|
|
7124
|
+
};
|
|
7125
|
+
});
|
|
7126
|
+
const phTable = readAt2(fd, phnum * phentsize, Number(phoff));
|
|
7127
|
+
if (phTable.length !== phnum * phentsize) return null;
|
|
7128
|
+
const segments = [];
|
|
7129
|
+
for (let i = 0; i < phnum; i++) {
|
|
7130
|
+
const at = i * phentsize;
|
|
7131
|
+
segments.push({
|
|
7132
|
+
type: phTable.readUInt32LE(at),
|
|
7133
|
+
flags: phTable.readUInt32LE(at + 4),
|
|
7134
|
+
offset: phTable.readBigUInt64LE(at + 8),
|
|
7135
|
+
vaddr: phTable.readBigUInt64LE(at + 16),
|
|
7136
|
+
filesz: phTable.readBigUInt64LE(at + 32)
|
|
7137
|
+
});
|
|
7138
|
+
}
|
|
7139
|
+
return { sections, segments };
|
|
7140
|
+
}
|
|
7141
|
+
function alignUp(value, to) {
|
|
7142
|
+
return (value + to - 1n) / to * to;
|
|
7143
|
+
}
|
|
7144
|
+
function writableLoad(layout) {
|
|
7145
|
+
return layout.segments.find((segment) => segment.type === PT_LOAD && (segment.flags & PF_W) !== 0);
|
|
7146
|
+
}
|
|
7147
|
+
function fileOffsetOf(layout, vaddr, length) {
|
|
7148
|
+
let found = null;
|
|
7149
|
+
for (const segment of layout.segments) {
|
|
7150
|
+
if (segment.type !== PT_LOAD) continue;
|
|
7151
|
+
if (vaddr < segment.vaddr) continue;
|
|
7152
|
+
if (vaddr + length > segment.vaddr + segment.filesz) continue;
|
|
7153
|
+
if (found !== null) return null;
|
|
7154
|
+
found = Number(segment.offset + (vaddr - segment.vaddr));
|
|
7155
|
+
}
|
|
7156
|
+
return found;
|
|
7157
|
+
}
|
|
7158
|
+
function tweakccWouldFind(fd, segment, needle) {
|
|
7159
|
+
const first = alignUp(segment.vaddr, TWEAKCC_SCAN_STRIDE);
|
|
7160
|
+
const last = segment.vaddr + segment.filesz - 8n;
|
|
7161
|
+
for (let vaddr = first; vaddr <= last; vaddr += TWEAKCC_SCAN_STRIDE) {
|
|
7162
|
+
const at = Number(segment.offset + (vaddr - segment.vaddr));
|
|
7163
|
+
if (readAt2(fd, 8, at).equals(needle)) return vaddr;
|
|
7164
|
+
}
|
|
7165
|
+
return null;
|
|
7166
|
+
}
|
|
7167
|
+
function scanForNeedle(fd, from, to, needle, skipFrom, skipTo) {
|
|
7168
|
+
const hits = [];
|
|
7169
|
+
for (let start = from; start < to; start += SCAN_CHUNK - 7) {
|
|
7170
|
+
const length = Math.min(SCAN_CHUNK, to - start);
|
|
7171
|
+
if (length < 8) break;
|
|
7172
|
+
const chunk = readAt2(fd, length, start);
|
|
7173
|
+
let at = 0;
|
|
7174
|
+
for (; ; ) {
|
|
7175
|
+
const found = chunk.indexOf(needle, at);
|
|
7176
|
+
if (found < 0) break;
|
|
7177
|
+
const offset = start + found;
|
|
7178
|
+
if (offset < skipFrom || offset >= skipTo) hits.push(offset);
|
|
7179
|
+
at = found + 1;
|
|
7180
|
+
}
|
|
7181
|
+
}
|
|
7182
|
+
return hits;
|
|
7183
|
+
}
|
|
7184
|
+
function shimBunCompiledPointer(path) {
|
|
7185
|
+
const fd = openSync3(path, "r+");
|
|
7186
|
+
try {
|
|
7187
|
+
const layout = readElfLayout(fd);
|
|
7188
|
+
if (!layout) return null;
|
|
7189
|
+
const bun = layout.sections.find((section) => section.name === ".bun");
|
|
7190
|
+
if (!bun || bun.size === 0n) return null;
|
|
7191
|
+
const segment = writableLoad(layout);
|
|
7192
|
+
if (!segment) return null;
|
|
7193
|
+
const needle = Buffer.alloc(8);
|
|
7194
|
+
needle.writeBigUInt64LE(bun.addr);
|
|
7195
|
+
if (tweakccWouldFind(fd, segment, needle) !== null) return null;
|
|
7196
|
+
const segmentStart = Number(segment.offset);
|
|
7197
|
+
const segmentEnd = Number(segment.offset + segment.filesz);
|
|
7198
|
+
const bunStart = Number(bun.offset);
|
|
7199
|
+
const bunEnd = Number(bun.offset + bun.size);
|
|
7200
|
+
const candidates = scanForNeedle(fd, segmentStart, segmentEnd, needle, bunStart, bunEnd);
|
|
7201
|
+
if (candidates.length !== 1) {
|
|
7202
|
+
throw new Error(
|
|
7203
|
+
`cannot locate Bun's blob pointer: ${candidates.length} candidates in the writable segment (expected 1). Refusing to repack a binary whose Bun global would be left stale.`
|
|
7204
|
+
);
|
|
7205
|
+
}
|
|
7206
|
+
const pointerOffset = candidates[0];
|
|
7207
|
+
const pointerVaddr = segment.vaddr + BigInt(pointerOffset) - segment.offset;
|
|
7208
|
+
const first = alignUp(segment.vaddr, TWEAKCC_SCAN_STRIDE);
|
|
7209
|
+
const last = segment.vaddr + segment.filesz - 8n;
|
|
7210
|
+
let standInVaddr = null;
|
|
7211
|
+
for (let vaddr = first; vaddr <= last; vaddr += TWEAKCC_SCAN_STRIDE) {
|
|
7212
|
+
const at = Number(segment.offset + (vaddr - segment.vaddr));
|
|
7213
|
+
if (at + 8 > bunStart && at < bunEnd) continue;
|
|
7214
|
+
if (at + 8 > pointerOffset && at < pointerOffset + 8) continue;
|
|
7215
|
+
standInVaddr = vaddr;
|
|
7216
|
+
break;
|
|
7217
|
+
}
|
|
7218
|
+
if (standInVaddr === null) {
|
|
7219
|
+
throw new Error("no address tweakcc's ELF repack scans is usable for Bun's blob pointer");
|
|
7220
|
+
}
|
|
7221
|
+
const standInOffset = Number(segment.offset + (standInVaddr - segment.vaddr));
|
|
7222
|
+
const displaced = readAt2(fd, 8, standInOffset);
|
|
7223
|
+
if (displaced.length !== 8) throw new Error("could not read the bytes Bun's blob pointer displaces");
|
|
7224
|
+
writeSync3(fd, needle, 0, 8, standInOffset);
|
|
7225
|
+
return { pointerVaddr, standInVaddr, displaced, bunVaddr: bun.addr };
|
|
7226
|
+
} finally {
|
|
7227
|
+
closeSync3(fd);
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
function restoreBunCompiledPointer(path, shim) {
|
|
7231
|
+
const fd = openSync3(path, "r+");
|
|
7232
|
+
try {
|
|
7233
|
+
const layout = readElfLayout(fd);
|
|
7234
|
+
if (!layout) throw new Error("the repacked binary is no longer a 64-bit little-endian ELF");
|
|
7235
|
+
const bun = layout.sections.find((section) => section.name === ".bun");
|
|
7236
|
+
if (!bun) throw new Error("the repacked binary has no .bun section");
|
|
7237
|
+
const standInOffset = fileOffsetOf(layout, shim.standInVaddr, 8n);
|
|
7238
|
+
const pointerOffset = fileOffsetOf(layout, shim.pointerVaddr, 8n);
|
|
7239
|
+
if (standInOffset === null || pointerOffset === null) {
|
|
7240
|
+
throw new Error(
|
|
7241
|
+
"the repack left Bun's blob pointer outside the loaded image, or in more than one segment of it"
|
|
7242
|
+
);
|
|
7243
|
+
}
|
|
7244
|
+
const written = readAt2(fd, 8, standInOffset).readBigUInt64LE(0);
|
|
7245
|
+
if (written === shim.bunVaddr) {
|
|
7246
|
+
throw new Error("the repack did not rewrite Bun's blob pointer \u2014 the stand-in was not used");
|
|
7247
|
+
}
|
|
7248
|
+
if (written !== bun.addr) {
|
|
7249
|
+
throw new Error(
|
|
7250
|
+
`the repack pointed Bun at 0x${written.toString(16)} but put .bun at 0x${bun.addr.toString(16)}`
|
|
7251
|
+
);
|
|
7252
|
+
}
|
|
7253
|
+
const value = Buffer.alloc(8);
|
|
7254
|
+
value.writeBigUInt64LE(written);
|
|
7255
|
+
writeSync3(fd, value, 0, 8, pointerOffset);
|
|
7256
|
+
writeSync3(fd, shim.displaced, 0, 8, standInOffset);
|
|
7257
|
+
if (!readAt2(fd, 8, pointerOffset).equals(value)) {
|
|
7258
|
+
throw new Error("Bun's blob pointer did not take the repacked address");
|
|
7259
|
+
}
|
|
7260
|
+
if (!readAt2(fd, 8, standInOffset).equals(shim.displaced)) {
|
|
7261
|
+
throw new Error("the bytes the stand-in displaced were not restored");
|
|
7262
|
+
}
|
|
7263
|
+
} finally {
|
|
7264
|
+
closeSync3(fd);
|
|
7265
|
+
}
|
|
7266
|
+
}
|
|
7267
|
+
|
|
7268
|
+
// src/bun-bundle.ts
|
|
7269
|
+
import { closeSync as closeSync4, openSync as openSync4, readSync as readSync3, writeSync as writeSync4 } from "fs";
|
|
7063
7270
|
function writableModuleIndex(path) {
|
|
7064
7271
|
const table = readBunModuleTable(path);
|
|
7065
7272
|
if (!table) return null;
|
|
@@ -7175,18 +7382,18 @@ function placeholderOf(byteLength) {
|
|
|
7175
7382
|
return PLACEHOLDER_TEXT.repeat(Math.ceil(byteLength / PLACEHOLDER_TEXT.length)).slice(0, byteLength);
|
|
7176
7383
|
}
|
|
7177
7384
|
function readBlobData(path, table, into) {
|
|
7178
|
-
const fd =
|
|
7385
|
+
const fd = openSync4(path, "r");
|
|
7179
7386
|
try {
|
|
7180
7387
|
let read = 0;
|
|
7181
7388
|
while (read < table.byteCount) {
|
|
7182
|
-
const got =
|
|
7389
|
+
const got = readSync3(fd, into, read, table.byteCount - read, table.blobAt + read);
|
|
7183
7390
|
if (got <= 0) {
|
|
7184
7391
|
throw new Error(`read ${read} of the ${table.byteCount} blob bytes of ${path}`);
|
|
7185
7392
|
}
|
|
7186
7393
|
read += got;
|
|
7187
7394
|
}
|
|
7188
7395
|
} finally {
|
|
7189
|
-
|
|
7396
|
+
closeSync4(fd);
|
|
7190
7397
|
}
|
|
7191
7398
|
}
|
|
7192
7399
|
function repointModule(data, table, append) {
|
|
@@ -7238,7 +7445,7 @@ function applyBundleWritePlan(path, plan) {
|
|
|
7238
7445
|
}
|
|
7239
7446
|
const offsets = Buffer.from(plan.offsets);
|
|
7240
7447
|
offsets.writeBigUInt64LE(BigInt(byteCount), 0);
|
|
7241
|
-
const fd =
|
|
7448
|
+
const fd = openSync4(path, "r+");
|
|
7242
7449
|
try {
|
|
7243
7450
|
writeAll(fd, plan.data, repacked.blobAt, path);
|
|
7244
7451
|
const padding = byteCount - plan.data.length;
|
|
@@ -7246,7 +7453,7 @@ function applyBundleWritePlan(path, plan) {
|
|
|
7246
7453
|
writeAll(fd, offsets, repacked.blobAt + byteCount, path);
|
|
7247
7454
|
writeAll(fd, BUN_TRAILER2, repacked.blobAt + byteCount + BUN_OFFSETS_BYTES2, path);
|
|
7248
7455
|
} finally {
|
|
7249
|
-
|
|
7456
|
+
closeSync4(fd);
|
|
7250
7457
|
}
|
|
7251
7458
|
const published = readBunModuleTable(path);
|
|
7252
7459
|
if (!published) throw new Error(`cannot re-read the Bun module table of ${path} after publishing its blob`);
|
|
@@ -7274,7 +7481,7 @@ function applyBundleWritePlan(path, plan) {
|
|
|
7274
7481
|
function writeAll(fd, bytes, position, path) {
|
|
7275
7482
|
let written = 0;
|
|
7276
7483
|
while (written < bytes.length) {
|
|
7277
|
-
const wrote =
|
|
7484
|
+
const wrote = writeSync4(fd, bytes, written, bytes.length - written, position + written);
|
|
7278
7485
|
if (wrote <= 0) throw new Error(`wrote ${written} of ${bytes.length} blob bytes to ${path}`);
|
|
7279
7486
|
written += wrote;
|
|
7280
7487
|
}
|
|
@@ -10160,7 +10367,7 @@ function thinkingProviderOptions(npm) {
|
|
|
10160
10367
|
|
|
10161
10368
|
// src/proxy.ts
|
|
10162
10369
|
import { createServer } from "http";
|
|
10163
|
-
import { appendFileSync as appendFileSync2, openSync as
|
|
10370
|
+
import { appendFileSync as appendFileSync2, openSync as openSync5, writeSync as writeSync5, closeSync as closeSync5 } from "fs";
|
|
10164
10371
|
|
|
10165
10372
|
// src/http-utils.ts
|
|
10166
10373
|
import * as zlib from "zlib";
|
|
@@ -10736,6 +10943,18 @@ function upstreamMaxRetries(env = process.env, warn = (message) => emitParentNot
|
|
|
10736
10943
|
}
|
|
10737
10944
|
return value;
|
|
10738
10945
|
}
|
|
10946
|
+
var CLIENT_MAX_RETRIES_ENV = "CLAUDE_CODE_MAX_RETRIES";
|
|
10947
|
+
var DEFAULT_PASSTHROUGH_RETRIES = 1;
|
|
10948
|
+
function passthroughUpstreamRetries(env = process.env) {
|
|
10949
|
+
const explicit = upstreamMaxRetries(env);
|
|
10950
|
+
if (explicit !== void 0) return explicit;
|
|
10951
|
+
const raw = env[CLIENT_MAX_RETRIES_ENV]?.trim();
|
|
10952
|
+
if (raw !== void 0 && raw !== "") {
|
|
10953
|
+
const clientRetries = Number(raw);
|
|
10954
|
+
if (Number.isFinite(clientRetries) && clientRetries === 0) return 0;
|
|
10955
|
+
}
|
|
10956
|
+
return DEFAULT_PASSTHROUGH_RETRIES;
|
|
10957
|
+
}
|
|
10739
10958
|
|
|
10740
10959
|
// src/sdk-adapter.ts
|
|
10741
10960
|
function sdkTranslationErrorSignature(error) {
|
|
@@ -11635,12 +11854,12 @@ function createTranslationLifecycle(logPath, requestId, claudeSessionId, modelId
|
|
|
11635
11854
|
function appendSecureLog(logPath, line) {
|
|
11636
11855
|
const redacted = redactTraceLine(line);
|
|
11637
11856
|
try {
|
|
11638
|
-
const fd =
|
|
11857
|
+
const fd = openSync5(logPath, "a", 384);
|
|
11639
11858
|
try {
|
|
11640
|
-
|
|
11859
|
+
writeSync5(fd, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
|
|
11641
11860
|
`);
|
|
11642
11861
|
} finally {
|
|
11643
|
-
|
|
11862
|
+
closeSync5(fd);
|
|
11644
11863
|
}
|
|
11645
11864
|
} catch {
|
|
11646
11865
|
try {
|
|
@@ -12503,10 +12722,10 @@ function tryAcquirePatchLock(lockPath = getPatchLockPath(), opts = {}) {
|
|
|
12503
12722
|
mkdirSync5(join7(lockPath, ".."), { recursive: true, mode: 448 });
|
|
12504
12723
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
12505
12724
|
try {
|
|
12506
|
-
const fd =
|
|
12725
|
+
const fd = openSync6(lockPath, "wx");
|
|
12507
12726
|
const content = { pid: process.pid, startedAt: now };
|
|
12508
12727
|
writeFileSync5(fd, JSON.stringify(content));
|
|
12509
|
-
|
|
12728
|
+
closeSync6(fd);
|
|
12510
12729
|
return () => {
|
|
12511
12730
|
try {
|
|
12512
12731
|
unlinkSync3(lockPath);
|
|
@@ -12766,11 +12985,15 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
|
|
|
12766
12985
|
splitBundleSource(loaded.bundle, local.content),
|
|
12767
12986
|
writable
|
|
12768
12987
|
);
|
|
12988
|
+
const bunPointerShim = shimBunCompiledPointer(candidatePath);
|
|
12769
12989
|
await writeContent(loaded.installation, plan2.content);
|
|
12990
|
+
if (bunPointerShim) restoreBunCompiledPointer(candidatePath, bunPointerShim);
|
|
12770
12991
|
applyBundleWritePlan(candidatePath, plan2);
|
|
12771
12992
|
publishedBlob = true;
|
|
12772
12993
|
} else {
|
|
12994
|
+
const bunPointerShim = shimBunCompiledPointer(candidatePath);
|
|
12773
12995
|
await writeContent(loaded.installation, local.content);
|
|
12996
|
+
if (bunPointerShim) restoreBunCompiledPointer(candidatePath, bunPointerShim);
|
|
12774
12997
|
}
|
|
12775
12998
|
if (writeShim) restoreEntryModuleName(candidatePath, writeShim, { resign: true });
|
|
12776
12999
|
else if (publishedBlob) resignMachOBinary(candidatePath);
|
|
@@ -13291,13 +13514,13 @@ function localProvidersToServerModels(localProviders) {
|
|
|
13291
13514
|
// src/registry/credential-cleanup-journal.ts
|
|
13292
13515
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
13293
13516
|
import {
|
|
13294
|
-
closeSync as
|
|
13517
|
+
closeSync as closeSync7,
|
|
13295
13518
|
existsSync as existsSync6,
|
|
13296
13519
|
fstatSync,
|
|
13297
13520
|
fsyncSync as fsyncSync2,
|
|
13298
13521
|
lstatSync,
|
|
13299
13522
|
mkdirSync as mkdirSync6,
|
|
13300
|
-
openSync as
|
|
13523
|
+
openSync as openSync7,
|
|
13301
13524
|
readFileSync as readFileSync9,
|
|
13302
13525
|
renameSync as renameSync3,
|
|
13303
13526
|
unlinkSync as unlinkSync4,
|
|
@@ -13389,7 +13612,7 @@ function readJournalUnlocked(path) {
|
|
|
13389
13612
|
if (before.isSymbolicLink() || !before.isFile()) {
|
|
13390
13613
|
throw new Error("Credential cleanup journal must be a regular file.");
|
|
13391
13614
|
}
|
|
13392
|
-
fd =
|
|
13615
|
+
fd = openSync7(path, "r");
|
|
13393
13616
|
const opened = fstatSync(fd);
|
|
13394
13617
|
if (before.dev !== opened.dev || before.ino !== opened.ino) {
|
|
13395
13618
|
throw new Error("Credential cleanup journal changed while opening.");
|
|
@@ -13410,19 +13633,19 @@ function readJournalUnlocked(path) {
|
|
|
13410
13633
|
const message = error instanceof Error ? error.message : String(error);
|
|
13411
13634
|
throw new Error(`Could not read credential cleanup journal: ${message}`);
|
|
13412
13635
|
} finally {
|
|
13413
|
-
if (fd !== void 0)
|
|
13636
|
+
if (fd !== void 0) closeSync7(fd);
|
|
13414
13637
|
}
|
|
13415
13638
|
}
|
|
13416
13639
|
function syncParentDirectory(path) {
|
|
13417
13640
|
let fd;
|
|
13418
13641
|
try {
|
|
13419
|
-
fd =
|
|
13642
|
+
fd = openSync7(dirname4(path), "r");
|
|
13420
13643
|
fsyncSync2(fd);
|
|
13421
13644
|
} catch (error) {
|
|
13422
13645
|
const code = error.code;
|
|
13423
13646
|
if (code !== "EINVAL" && code !== "ENOTSUP" && code !== "EPERM") throw error;
|
|
13424
13647
|
} finally {
|
|
13425
|
-
if (fd !== void 0)
|
|
13648
|
+
if (fd !== void 0) closeSync7(fd);
|
|
13426
13649
|
}
|
|
13427
13650
|
}
|
|
13428
13651
|
function writeJournalUnlocked(journal, path) {
|
|
@@ -13432,17 +13655,17 @@ function writeJournalUnlocked(journal, path) {
|
|
|
13432
13655
|
const tmp = `${path}.${process.pid}.${randomUUID4()}.tmp`;
|
|
13433
13656
|
let fd;
|
|
13434
13657
|
try {
|
|
13435
|
-
fd =
|
|
13658
|
+
fd = openSync7(tmp, "wx", FILE_MODE4);
|
|
13436
13659
|
writeFileSync6(fd, `${JSON.stringify(journal, null, 2)}
|
|
13437
13660
|
`);
|
|
13438
13661
|
fsyncSync2(fd);
|
|
13439
|
-
|
|
13662
|
+
closeSync7(fd);
|
|
13440
13663
|
fd = void 0;
|
|
13441
13664
|
assertRegistryWriteOwnership(path);
|
|
13442
13665
|
renameSync3(tmp, path);
|
|
13443
13666
|
syncParentDirectory(path);
|
|
13444
13667
|
} finally {
|
|
13445
|
-
if (fd !== void 0)
|
|
13668
|
+
if (fd !== void 0) closeSync7(fd);
|
|
13446
13669
|
try {
|
|
13447
13670
|
unlinkSync4(tmp);
|
|
13448
13671
|
} catch (error) {
|
|
@@ -17391,20 +17614,37 @@ function ensureHttpProxyCertificates() {
|
|
|
17391
17614
|
serverKey: readFileSync10(paths.serverKey, "utf8")
|
|
17392
17615
|
};
|
|
17393
17616
|
}
|
|
17394
|
-
function ensureHttpProxyCaBundle(relayCaCertPath, additionalCaCertPath) {
|
|
17617
|
+
function ensureHttpProxyCaBundle(relayCaCertPath, additionalCaCertPath, onWarning) {
|
|
17395
17618
|
if (!additionalCaCertPath?.trim()) return relayCaCertPath;
|
|
17619
|
+
const warn = (detail) => {
|
|
17620
|
+
onWarning?.(
|
|
17621
|
+
`${detail} The CA bundle handed to the child is ${relayCaCertPath}; node's built-in roots are unaffected.`
|
|
17622
|
+
);
|
|
17623
|
+
return relayCaCertPath;
|
|
17624
|
+
};
|
|
17625
|
+
let additionalCa;
|
|
17396
17626
|
try {
|
|
17397
17627
|
if (resolve2(additionalCaCertPath) === resolve2(relayCaCertPath)) return relayCaCertPath;
|
|
17628
|
+
additionalCa = readFileSync10(additionalCaCertPath, "utf8").trim();
|
|
17629
|
+
} catch (err) {
|
|
17630
|
+
return warn(
|
|
17631
|
+
`NODE_EXTRA_CA_CERTS=${additionalCaCertPath} cannot be read (${err instanceof Error ? err.message : String(err)}), so it is not part of the proxy CA bundle. Where node reports this itself it says only "Ignoring extra certs ... load failed", without naming the variable. Clear or correct it.`
|
|
17632
|
+
);
|
|
17633
|
+
}
|
|
17634
|
+
if (!additionalCa) {
|
|
17635
|
+
return warn(`NODE_EXTRA_CA_CERTS=${additionalCaCertPath} is empty, so it adds nothing.`);
|
|
17636
|
+
}
|
|
17637
|
+
try {
|
|
17398
17638
|
const relayCa = readFileSync10(relayCaCertPath, "utf8").trimEnd();
|
|
17399
|
-
const additionalCa = readFileSync10(additionalCaCertPath, "utf8").trim();
|
|
17400
|
-
if (!additionalCa) return relayCaCertPath;
|
|
17401
17639
|
const combinedPath = join8(dirname5(relayCaCertPath), "combined-ca.pem");
|
|
17402
17640
|
writePublic(combinedPath, `${relayCa}
|
|
17403
17641
|
${additionalCa}
|
|
17404
17642
|
`);
|
|
17405
17643
|
return combinedPath;
|
|
17406
|
-
} catch {
|
|
17407
|
-
return
|
|
17644
|
+
} catch (err) {
|
|
17645
|
+
return warn(
|
|
17646
|
+
`clodex could not build the combined CA bundle in ${dirname5(relayCaCertPath)} (${err instanceof Error ? err.message : String(err)}), so the readable, non-empty NODE_EXTRA_CA_CERTS=${additionalCaCertPath} was left out of it. Fix the reported error and restart clodex.`
|
|
17647
|
+
);
|
|
17408
17648
|
}
|
|
17409
17649
|
}
|
|
17410
17650
|
|
|
@@ -17413,6 +17653,16 @@ var ANTHROPIC_HOST = "api.anthropic.com";
|
|
|
17413
17653
|
var MAX_BODY_BYTES = 50 * 1024 * 1024;
|
|
17414
17654
|
var MAX_ERROR_BODY_BYTES = 64 * 1024;
|
|
17415
17655
|
var MAX_USAGE_SSE_BLOCK_BYTES = 64 * 1024;
|
|
17656
|
+
var RETRYABLE_PASSTHROUGH_CODE = "ECONNRESET";
|
|
17657
|
+
function upstreamUnreachableDetail(err) {
|
|
17658
|
+
return err.message || err.code || err.name || "connection failed";
|
|
17659
|
+
}
|
|
17660
|
+
function createPassthroughAgent() {
|
|
17661
|
+
return new https.Agent({
|
|
17662
|
+
keepAlive: true,
|
|
17663
|
+
timeout: https.globalAgent.options.timeout ?? 5e3
|
|
17664
|
+
});
|
|
17665
|
+
}
|
|
17416
17666
|
function numericUsage(value) {
|
|
17417
17667
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
17418
17668
|
}
|
|
@@ -17561,6 +17811,7 @@ function requestHeadersWithoutProxyHeaders(req) {
|
|
|
17561
17811
|
function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorized, agent, onErrorResponse, onResponseUsage, lifecycle, isLocalShutdown = () => false) {
|
|
17562
17812
|
return new Promise((resolve3) => {
|
|
17563
17813
|
const startedAt = Date.now();
|
|
17814
|
+
const retryBudget = passthroughUpstreamRetries();
|
|
17564
17815
|
let lastActivityAt = startedAt;
|
|
17565
17816
|
let headersReceived = false;
|
|
17566
17817
|
let firstByteAt;
|
|
@@ -17610,42 +17861,91 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
17610
17861
|
resolve3();
|
|
17611
17862
|
};
|
|
17612
17863
|
const errorType = (err) => err.code ?? err.name;
|
|
17613
|
-
|
|
17614
|
-
|
|
17615
|
-
|
|
17616
|
-
|
|
17617
|
-
|
|
17618
|
-
|
|
17619
|
-
|
|
17620
|
-
|
|
17621
|
-
|
|
17622
|
-
|
|
17623
|
-
|
|
17624
|
-
|
|
17625
|
-
|
|
17626
|
-
|
|
17627
|
-
|
|
17628
|
-
|
|
17629
|
-
|
|
17630
|
-
|
|
17631
|
-
|
|
17864
|
+
let upstream;
|
|
17865
|
+
let attempt = 0;
|
|
17866
|
+
const isRetryableUpstreamFailure = (err, request3) => attempt <= retryBudget && !headersReceived && !failed && !clientDisconnected && !isLocalShutdown() && request3.reusedSocket === true && err.code === RETRYABLE_PASSTHROUGH_CODE;
|
|
17867
|
+
const sendAttempt = () => {
|
|
17868
|
+
attempt += 1;
|
|
17869
|
+
const request3 = https.request({
|
|
17870
|
+
protocol: "https:",
|
|
17871
|
+
hostname: origin.hostname,
|
|
17872
|
+
port: origin.port || 443,
|
|
17873
|
+
method: req.method,
|
|
17874
|
+
path: req.url,
|
|
17875
|
+
headers: requestHeadersWithoutProxyHeaders(req),
|
|
17876
|
+
servername: net.isIP(origin.hostname) ? void 0 : origin.hostname,
|
|
17877
|
+
rejectUnauthorized,
|
|
17878
|
+
agent
|
|
17879
|
+
}, (upstreamRes) => {
|
|
17880
|
+
headersReceived = true;
|
|
17881
|
+
statusCode = upstreamRes.statusCode ?? 502;
|
|
17882
|
+
lastActivityAt = Date.now();
|
|
17883
|
+
upstreamRes.on("data", (chunk) => {
|
|
17884
|
+
const now = Date.now();
|
|
17885
|
+
if (firstByteAt === void 0) {
|
|
17886
|
+
firstByteAt = now;
|
|
17887
|
+
writeLifecycle("response_started", {
|
|
17888
|
+
statusCode,
|
|
17889
|
+
durationMs: now - startedAt,
|
|
17890
|
+
timeToFirstByteMs: now - startedAt,
|
|
17891
|
+
...attempt > 1 ? { attempt } : {}
|
|
17892
|
+
});
|
|
17893
|
+
}
|
|
17894
|
+
lastActivityAt = now;
|
|
17895
|
+
bytes += chunk.length;
|
|
17896
|
+
chunks += 1;
|
|
17897
|
+
});
|
|
17898
|
+
copyResponse(upstreamRes, res, onErrorResponse, onResponseUsage);
|
|
17899
|
+
upstreamRes.once("end", () => {
|
|
17900
|
+
responseEnded = true;
|
|
17901
|
+
lastActivityAt = Date.now();
|
|
17902
|
+
done();
|
|
17903
|
+
});
|
|
17904
|
+
upstreamRes.once("error", (err) => {
|
|
17905
|
+
if (clientDisconnected || failed) {
|
|
17906
|
+
done();
|
|
17907
|
+
return;
|
|
17908
|
+
}
|
|
17909
|
+
failed = true;
|
|
17910
|
+
stopProgress();
|
|
17911
|
+
const now = Date.now();
|
|
17912
|
+
writeLifecycle("response_failed", {
|
|
17632
17913
|
statusCode,
|
|
17914
|
+
phase: responsePhase(),
|
|
17633
17915
|
durationMs: now - startedAt,
|
|
17634
|
-
timeToFirstByteMs:
|
|
17916
|
+
...firstByteAt !== void 0 ? { timeToFirstByteMs: firstByteAt - startedAt } : {},
|
|
17917
|
+
idleMs: now - lastActivityAt,
|
|
17918
|
+
bytes,
|
|
17919
|
+
chunks,
|
|
17920
|
+
errorType: errorType(err),
|
|
17921
|
+
terminationSource: "upstream_failure",
|
|
17922
|
+
attempt
|
|
17635
17923
|
});
|
|
17636
|
-
|
|
17637
|
-
|
|
17638
|
-
bytes += chunk.length;
|
|
17639
|
-
chunks += 1;
|
|
17640
|
-
});
|
|
17641
|
-
copyResponse(upstreamRes, res, onErrorResponse, onResponseUsage);
|
|
17642
|
-
upstreamRes.once("end", () => {
|
|
17643
|
-
responseEnded = true;
|
|
17644
|
-
lastActivityAt = Date.now();
|
|
17645
|
-
done();
|
|
17924
|
+
done();
|
|
17925
|
+
});
|
|
17646
17926
|
});
|
|
17647
|
-
|
|
17648
|
-
|
|
17927
|
+
upstream = request3;
|
|
17928
|
+
request3.once("error", (err) => {
|
|
17929
|
+
if (clientDisconnected) {
|
|
17930
|
+
done();
|
|
17931
|
+
return;
|
|
17932
|
+
}
|
|
17933
|
+
if (isRetryableUpstreamFailure(err, request3)) {
|
|
17934
|
+
const retriedAt = Date.now();
|
|
17935
|
+
writeLifecycle("response_retried", {
|
|
17936
|
+
phase: responsePhase(),
|
|
17937
|
+
durationMs: retriedAt - startedAt,
|
|
17938
|
+
idleMs: retriedAt - lastActivityAt,
|
|
17939
|
+
errorType: errorType(err),
|
|
17940
|
+
terminationSource: "upstream_failure",
|
|
17941
|
+
attempt,
|
|
17942
|
+
reusedSocket: true
|
|
17943
|
+
});
|
|
17944
|
+
lastActivityAt = retriedAt;
|
|
17945
|
+
sendAttempt();
|
|
17946
|
+
return;
|
|
17947
|
+
}
|
|
17948
|
+
if (failed) {
|
|
17649
17949
|
done();
|
|
17650
17950
|
return;
|
|
17651
17951
|
}
|
|
@@ -17653,19 +17953,25 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
17653
17953
|
stopProgress();
|
|
17654
17954
|
const now = Date.now();
|
|
17655
17955
|
writeLifecycle("response_failed", {
|
|
17656
|
-
statusCode,
|
|
17956
|
+
statusCode: 502,
|
|
17657
17957
|
phase: responsePhase(),
|
|
17658
17958
|
durationMs: now - startedAt,
|
|
17659
|
-
...firstByteAt !== void 0 ? { timeToFirstByteMs: firstByteAt - startedAt } : {},
|
|
17660
17959
|
idleMs: now - lastActivityAt,
|
|
17661
17960
|
bytes,
|
|
17662
17961
|
chunks,
|
|
17663
17962
|
errorType: errorType(err),
|
|
17664
|
-
terminationSource: "upstream_failure"
|
|
17963
|
+
terminationSource: isLocalShutdown() ? "local_shutdown" : "upstream_failure",
|
|
17964
|
+
attempt,
|
|
17965
|
+
reusedSocket: request3.reusedSocket === true
|
|
17665
17966
|
});
|
|
17967
|
+
const detail = upstreamUnreachableDetail(err);
|
|
17968
|
+
onErrorResponse?.(502, `Anthropic upstream unreachable: ${detail}`);
|
|
17969
|
+
if (!res.headersSent) res.writeHead(502, { "Content-Type": "text/plain" });
|
|
17970
|
+
res.end(`Anthropic upstream unreachable: ${detail}`);
|
|
17666
17971
|
done();
|
|
17667
17972
|
});
|
|
17668
|
-
|
|
17973
|
+
request3.end(rawBody);
|
|
17974
|
+
};
|
|
17669
17975
|
res.once("finish", () => {
|
|
17670
17976
|
stopProgress();
|
|
17671
17977
|
if (failed || clientDisconnected) return;
|
|
@@ -17675,7 +17981,8 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
17675
17981
|
durationMs: now - startedAt,
|
|
17676
17982
|
...firstByteAt !== void 0 ? { timeToFirstByteMs: firstByteAt - startedAt } : {},
|
|
17677
17983
|
bytes,
|
|
17678
|
-
chunks
|
|
17984
|
+
chunks,
|
|
17985
|
+
...attempt > 1 ? { attempt } : {}
|
|
17679
17986
|
});
|
|
17680
17987
|
});
|
|
17681
17988
|
res.once("close", () => {
|
|
@@ -17693,33 +18000,10 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
17693
18000
|
chunks,
|
|
17694
18001
|
terminationSource: isLocalShutdown() ? "local_shutdown" : "downstream_client"
|
|
17695
18002
|
});
|
|
17696
|
-
upstream
|
|
17697
|
-
done();
|
|
17698
|
-
});
|
|
17699
|
-
upstream.once("error", (err) => {
|
|
17700
|
-
if (clientDisconnected) {
|
|
17701
|
-
done();
|
|
17702
|
-
return;
|
|
17703
|
-
}
|
|
17704
|
-
failed = true;
|
|
17705
|
-
stopProgress();
|
|
17706
|
-
const now = Date.now();
|
|
17707
|
-
writeLifecycle("response_failed", {
|
|
17708
|
-
statusCode: 502,
|
|
17709
|
-
phase: responsePhase(),
|
|
17710
|
-
durationMs: now - startedAt,
|
|
17711
|
-
idleMs: now - lastActivityAt,
|
|
17712
|
-
bytes,
|
|
17713
|
-
chunks,
|
|
17714
|
-
errorType: errorType(err),
|
|
17715
|
-
terminationSource: "upstream_failure"
|
|
17716
|
-
});
|
|
17717
|
-
onErrorResponse?.(502, `Anthropic upstream unreachable: ${err.message}`);
|
|
17718
|
-
if (!res.headersSent) res.writeHead(502, { "Content-Type": "text/plain" });
|
|
17719
|
-
res.end(`Anthropic upstream unreachable: ${err.message}`);
|
|
18003
|
+
upstream?.destroy(new Error("Client disconnected"));
|
|
17720
18004
|
done();
|
|
17721
18005
|
});
|
|
17722
|
-
|
|
18006
|
+
sendAttempt();
|
|
17723
18007
|
});
|
|
17724
18008
|
}
|
|
17725
18009
|
function forwardToAdapter(req, res, rawBody, adapter, adapterRequest = http2.request, adapterAgent, lifecycle, isLocalShutdown = () => false) {
|
|
@@ -18196,6 +18480,7 @@ async function startHttpProxy(options) {
|
|
|
18196
18480
|
} else {
|
|
18197
18481
|
anthropicAgent = outboundHttpProxyAgent(anthropicOrigin.href);
|
|
18198
18482
|
}
|
|
18483
|
+
anthropicAgent ??= createPassthroughAgent();
|
|
18199
18484
|
return {
|
|
18200
18485
|
host: options.host ?? "127.0.0.1",
|
|
18201
18486
|
port: address.port,
|
|
@@ -18329,11 +18614,15 @@ async function startConfiguredHttpProxy(port, debug = false, inferenceLogPath =
|
|
|
18329
18614
|
debugLogPath,
|
|
18330
18615
|
webSocketDiagnosticsLogPath
|
|
18331
18616
|
));
|
|
18617
|
+
let caWarning;
|
|
18332
18618
|
handle.caCertPath = ensureHttpProxyCaBundle(
|
|
18333
18619
|
handle.caCertPath,
|
|
18334
|
-
process.env["NODE_EXTRA_CA_CERTS"]
|
|
18620
|
+
process.env["NODE_EXTRA_CA_CERTS"],
|
|
18621
|
+
(message) => {
|
|
18622
|
+
caWarning = message;
|
|
18623
|
+
}
|
|
18335
18624
|
);
|
|
18336
|
-
return { handle, loaded };
|
|
18625
|
+
return { handle, loaded, ...caWarning ? { caWarning } : {} };
|
|
18337
18626
|
}
|
|
18338
18627
|
function waitForShutdown() {
|
|
18339
18628
|
return new Promise((resolve3) => {
|
|
@@ -18362,7 +18651,7 @@ async function runHttpProxyServerCommand(debug = false, webSocketDiagnostics = f
|
|
|
18362
18651
|
p9.log.error(`Failed to start HTTP proxy: ${err instanceof Error ? err.message : String(err)}`);
|
|
18363
18652
|
return 1;
|
|
18364
18653
|
}
|
|
18365
|
-
const { handle, loaded } = started;
|
|
18654
|
+
const { handle, loaded, caWarning } = started;
|
|
18366
18655
|
writeProxyLifecycleLog(inferenceLogPath, {
|
|
18367
18656
|
event: "proxy_started",
|
|
18368
18657
|
pid: process.pid,
|
|
@@ -18374,6 +18663,10 @@ async function runHttpProxyServerCommand(debug = false, webSocketDiagnostics = f
|
|
|
18374
18663
|
console.log(pc10.bold(pc10.green("clodex proxy-mode server running")));
|
|
18375
18664
|
for (const line of formatHttpProxyEnvironmentLines(handle)) console.log(line);
|
|
18376
18665
|
console.log(` Request log: ${handle.inferenceLogPath}`);
|
|
18666
|
+
if (caWarning) {
|
|
18667
|
+
console.log("");
|
|
18668
|
+
console.log(pc10.yellow(` clodex: ${caWarning}`));
|
|
18669
|
+
}
|
|
18377
18670
|
if (handle.webSocketDiagnosticsLogPath) {
|
|
18378
18671
|
console.log(` WebSocket diagnostics: ${handle.webSocketDiagnosticsLogPath}`);
|
|
18379
18672
|
console.log(pc10.yellow(" Diagnostic mode records request headers and metadata; credential headers are redacted."));
|
|
@@ -19959,7 +20252,11 @@ async function runClaudeHttpProxyCommand(parsed, claudeArgs, agentStdout) {
|
|
|
19959
20252
|
p12.log.error(`Failed to start proxy: ${err instanceof Error ? err.message : String(err)}`);
|
|
19960
20253
|
return 1;
|
|
19961
20254
|
}
|
|
19962
|
-
const { handle, loaded } = started;
|
|
20255
|
+
const { handle, loaded, caWarning } = started;
|
|
20256
|
+
if (caWarning) {
|
|
20257
|
+
if (agentStdout) emitParentNotice(`clodex: ${caWarning}`);
|
|
20258
|
+
else p12.log.warn(caWarning);
|
|
20259
|
+
}
|
|
19963
20260
|
const inheritedProxyPort = (() => {
|
|
19964
20261
|
const value = process.env["HTTPS_PROXY"] ?? process.env["HTTP_PROXY"] ?? process.env["https_proxy"] ?? process.env["http_proxy"];
|
|
19965
20262
|
if (!value) return void 0;
|