@bman654/clodex 2.8.1 → 2.8.3

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
@@ -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.1",
385
+ version: "2.8.3",
386
386
  publishConfig: {
387
387
  access: "public"
388
388
  },
@@ -924,6 +924,7 @@ async function startCallbackServer(options) {
924
924
  let codeResolve;
925
925
  let codeReject;
926
926
  let buffered;
927
+ let ignoredStateMismatchCount = 0;
927
928
  const { path, redirectHost } = options;
928
929
  const server = http.createServer((req, res) => {
929
930
  const u = new URL(req.url ?? "/", "http://localhost");
@@ -936,6 +937,7 @@ async function startCallbackServer(options) {
936
937
  const state = u.searchParams.get("state") ?? "";
937
938
  const error = u.searchParams.get("error") ?? "";
938
939
  if (options.expectedState !== void 0 && state !== options.expectedState) {
940
+ ignoredStateMismatchCount++;
939
941
  res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
940
942
  res.end("Invalid OAuth state");
941
943
  return;
@@ -976,7 +978,9 @@ async function startCallbackServer(options) {
976
978
  return;
977
979
  }
978
980
  const timer = setTimeout(
979
- () => reject(new Error("OAuth timeout \u2014 browser closed without completing sign-in")),
981
+ () => reject(new Error(
982
+ ignoredStateMismatchCount > 0 ? `OAuth timeout \u2014 ignored ${ignoredStateMismatchCount} callback(s) carrying a different sign-in state; you probably completed an older browser tab. Run the command again and use the newest tab.` : "OAuth timeout \u2014 browser closed without completing sign-in"
983
+ )),
980
984
  timeoutMs
981
985
  );
982
986
  codeResolve = (params) => {
@@ -1136,7 +1140,7 @@ async function runOpenAiBrowserFlow(onAuthorizeUrl, opts) {
1136
1140
  } catch (error) {
1137
1141
  if (error.code === "EADDRINUSE") {
1138
1142
  throw new Error(
1139
- `Ports ${ports.join(" and ")} are in use \u2014 close any other OpenAI sign-in (e.g. codex login) and try again.`
1143
+ `Ports ${ports.join(" and ")} are in use \u2014 browser sign-in needs one free. Check for another OpenAI sign-in (e.g. \`codex login\`), or any other process holding them, then try again.`
1140
1144
  );
1141
1145
  }
1142
1146
  throw new Error(
@@ -3419,7 +3423,7 @@ function savedStopsAfter(current, assignments) {
3419
3423
  }
3420
3424
 
3421
3425
  // src/patch-transforms.ts
3422
- var PATCH_TRANSFORMS_VERSION = 9;
3426
+ var PATCH_TRANSFORMS_VERSION = 10;
3423
3427
  var NATIVE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
3424
3428
  var BASE_EFFORT_LEVELS = ["low", "medium", "high"];
3425
3429
  function projectNativeEffort(effort) {
@@ -3840,8 +3844,8 @@ import {
3840
3844
  statSync as statSync6,
3841
3845
  unlinkSync as unlinkSync3,
3842
3846
  writeFileSync as writeFileSync5,
3843
- openSync as openSync4,
3844
- closeSync as closeSync4,
3847
+ openSync as openSync5,
3848
+ closeSync as closeSync5,
3845
3849
  realpathSync
3846
3850
  } from "fs";
3847
3851
  import { homedir as homedir3 } from "os";
@@ -6801,6 +6805,20 @@ var TAIL_SCAN_BYTES = 16 * 1024 * 1024;
6801
6805
  var MODULE_STRUCT_BYTES_CURRENT = 52;
6802
6806
  var MODULE_STRUCT_BYTES_LEGACY = 36;
6803
6807
  var CONTENTS_FIELD_AT = 8;
6808
+ var SOURCEMAP_FIELD_AT = 16;
6809
+ var BYTECODE_FIELD_AT = 24;
6810
+ var MODULE_INFO_FIELD_AT = 32;
6811
+ var BYTECODE_ORIGIN_PATH_FIELD_AT = 40;
6812
+ var BUN_BLOB_FLAGS = {
6813
+ /** Every module's source text lies in one run no other region falls inside. */
6814
+ SOURCE_TEXT_CONTIGUOUS: 1 << 4,
6815
+ /** A `[u32; modules]` of each module's source hash follows the module table. */
6816
+ HAS_SOURCE_HASHES: 1 << 5,
6817
+ /** After the source hashes: `u32 count`, then `count` x `{ u32 id, offset, length }`. */
6818
+ HAS_BUILTIN_BYTECODE: 1 << 6,
6819
+ /** After the builtin-bytecode table: one `{ offset, length }` for the shared string table. */
6820
+ HAS_BYTECODE_STRING_TABLE: 1 << 7
6821
+ };
6804
6822
  var LOADER_FROM_END = 3;
6805
6823
  var BUN_JAVASCRIPT_LOADER = 1;
6806
6824
  var MAX_MODULE_NAME_BYTES = 4096;
@@ -6847,6 +6865,9 @@ function parseBunModuleNamesAtUnchecked(fd, offsetsAt) {
6847
6865
  const modulesOffset = offsets.readUInt32LE(8);
6848
6866
  const modulesLength = offsets.readUInt32LE(12);
6849
6867
  const entryPointId = offsets.readUInt32LE(16);
6868
+ const compileExecArgvOffset = offsets.readUInt32LE(20);
6869
+ const compileExecArgvLength = offsets.readUInt32LE(24);
6870
+ const flags = offsets.readUInt32LE(28);
6850
6871
  if (byteCount <= 0n || byteCount > BigInt(offsetsAt)) return null;
6851
6872
  const blobAt = offsetsAt - Number(byteCount);
6852
6873
  if (modulesLength <= 0 || BigInt(modulesOffset) + BigInt(modulesLength) > byteCount) return null;
@@ -6858,6 +6879,10 @@ function parseBunModuleNamesAtUnchecked(fd, offsetsAt) {
6858
6879
  const names = [];
6859
6880
  const nameOffsets = [];
6860
6881
  const contents = [];
6882
+ const sourcemap = [];
6883
+ const bytecode = [];
6884
+ const moduleInfo = [];
6885
+ const bytecodeOriginPath = [];
6861
6886
  const loaders = [];
6862
6887
  for (let index = 0; index < moduleCount; index++) {
6863
6888
  const nameOffset = modules.readUInt32LE(index * structBytes);
@@ -6870,10 +6895,18 @@ function parseBunModuleNamesAtUnchecked(fd, offsetsAt) {
6870
6895
  if (!/^[\x20-\x7e]+$/.test(name)) return null;
6871
6896
  names.push(name);
6872
6897
  nameOffsets.push(blobAt + nameOffset);
6873
- contents.push({
6874
- offset: modules.readUInt32LE(index * structBytes + CONTENTS_FIELD_AT),
6875
- length: modules.readUInt32LE(index * structBytes + CONTENTS_FIELD_AT + 4)
6898
+ const pairAt = (field) => ({
6899
+ offset: modules.readUInt32LE(index * structBytes + field),
6900
+ length: modules.readUInt32LE(index * structBytes + field + 4)
6876
6901
  });
6902
+ contents.push(pairAt(CONTENTS_FIELD_AT));
6903
+ sourcemap.push(pairAt(SOURCEMAP_FIELD_AT));
6904
+ bytecode.push(pairAt(BYTECODE_FIELD_AT));
6905
+ const current = structBytes === MODULE_STRUCT_BYTES_CURRENT;
6906
+ moduleInfo.push(current ? pairAt(MODULE_INFO_FIELD_AT) : { offset: 0, length: 0 });
6907
+ bytecodeOriginPath.push(
6908
+ current ? pairAt(BYTECODE_ORIGIN_PATH_FIELD_AT) : { offset: 0, length: 0 }
6909
+ );
6877
6910
  loaders.push(modules.readUInt8(index * structBytes + structBytes - LOADER_FROM_END));
6878
6911
  }
6879
6912
  return {
@@ -6881,11 +6914,19 @@ function parseBunModuleNamesAtUnchecked(fd, offsetsAt) {
6881
6914
  entryPointId,
6882
6915
  offsets: nameOffsets,
6883
6916
  contents,
6917
+ sourcemap,
6918
+ bytecode,
6919
+ moduleInfo,
6920
+ bytecodeOriginPath,
6884
6921
  loaders,
6885
6922
  blobAt,
6886
6923
  modulesAt: blobAt + modulesOffset,
6924
+ modulesOffset,
6925
+ modulesLength,
6887
6926
  structBytes,
6888
- byteCount: Number(byteCount)
6927
+ byteCount: Number(byteCount),
6928
+ compileExecArgv: { offset: compileExecArgvOffset, length: compileExecArgvLength },
6929
+ flags
6889
6930
  };
6890
6931
  }
6891
6932
  function findStandIn(fd, fileSize, marker) {
@@ -6935,10 +6976,7 @@ function isMachO(fd) {
6935
6976
  function readBunModuleTable(path) {
6936
6977
  const fd = openSync2(path, "r");
6937
6978
  try {
6938
- const parsed = readBunModuleNames(fd, statSync4(path).size);
6939
- if (!parsed) return null;
6940
- const { names, loaders, contents, entryPointId, blobAt, modulesAt, structBytes, byteCount } = parsed;
6941
- return { names, loaders, contents, entryPointId, blobAt, modulesAt, structBytes, byteCount };
6979
+ return readBunModuleNames(fd, statSync4(path).size);
6942
6980
  } finally {
6943
6981
  closeSync2(fd);
6944
6982
  }
@@ -6969,33 +7007,6 @@ function readBunJavaScriptModules(path) {
6969
7007
  closeSync2(fd);
6970
7008
  }
6971
7009
  }
6972
- function repointBunModuleContents(path, edits) {
6973
- if (edits.length === 0) return;
6974
- const fd = openSync2(path, "r+");
6975
- try {
6976
- const parsed = readBunModuleNames(fd, statSync4(path).size);
6977
- if (!parsed) throw new Error(`cannot read the Bun module table of ${path}`);
6978
- for (const { index, range } of edits) {
6979
- if (index < 0 || index >= parsed.names.length) {
6980
- throw new Error(`module ${index} is outside the ${parsed.names.length}-module table of ${path}`);
6981
- }
6982
- if (range.offset < 0 || range.length < 0 || range.offset + range.length > parsed.byteCount) {
6983
- throw new Error(
6984
- `module ${index} would point at ${range.offset}+${range.length}, outside the ${parsed.byteCount}-byte blob of ${path}`
6985
- );
6986
- }
6987
- const at = parsed.modulesAt + index * parsed.structBytes + CONTENTS_FIELD_AT;
6988
- const pair = Buffer.alloc(8);
6989
- pair.writeUInt32LE(range.offset, 0);
6990
- pair.writeUInt32LE(range.length, 4);
6991
- if (writeSync2(fd, pair, 0, pair.length, at) !== pair.length) {
6992
- throw new Error(`short write repointing module ${index} of ${path}`);
6993
- }
6994
- }
6995
- } finally {
6996
- closeSync2(fd);
6997
- }
6998
- }
6999
7010
  function shimEntryModuleName(path) {
7000
7011
  const fd = openSync2(path, "r+");
7001
7012
  try {
@@ -7048,6 +7059,7 @@ function resignMachOBinary(path) {
7048
7059
  }
7049
7060
 
7050
7061
  // src/bun-bundle.ts
7062
+ import { closeSync as closeSync3, openSync as openSync3, readSync as readSync2, writeSync as writeSync3 } from "fs";
7051
7063
  function writableModuleIndex(path) {
7052
7064
  const table = readBunModuleTable(path);
7053
7065
  if (!table) return null;
@@ -7074,69 +7086,197 @@ function splitBundleSource(bundle, patched) {
7074
7086
  }
7075
7087
  return parts;
7076
7088
  }
7077
- function planBundleWrite(bundle, patchedSources, writableIndex) {
7089
+ var BUN_TRAILER2 = Buffer.from("\n---- Bun! ----\n");
7090
+ var BUN_OFFSETS_BYTES2 = 32;
7091
+ var PLACEHOLDER_SLACK_BYTES = 64 * 1024;
7092
+ var BYTECODE_ALIGNMENT = 128;
7093
+ var APPEND_ALIGNMENT = 8;
7094
+ function repackedBlobBytes(table, writableIndex, contentBytes) {
7095
+ let total = 0;
7096
+ for (let index = 0; index < table.names.length; index++) {
7097
+ const fields = [
7098
+ Buffer.byteLength(table.names[index], "utf8"),
7099
+ index === writableIndex ? contentBytes : table.contents[index].length,
7100
+ table.sourcemap[index].length,
7101
+ table.bytecode[index].length
7102
+ ];
7103
+ if (table.structBytes === 52) {
7104
+ fields.push(table.moduleInfo[index].length, table.bytecodeOriginPath[index].length);
7105
+ }
7106
+ for (const length of fields) total += length + 1;
7107
+ }
7108
+ return total + table.modulesLength + table.compileExecArgv.length + 1 + BUN_OFFSETS_BYTES2 + BUN_TRAILER2.length;
7109
+ }
7110
+ function planBundleWrite(path, bundle, patchedSources, writableIndex) {
7078
7111
  if (patchedSources.length !== bundle.modules.length) {
7079
7112
  throw new Error(
7080
7113
  `expected ${bundle.modules.length} patched module sources, got ${patchedSources.length}`
7081
7114
  );
7082
7115
  }
7083
- const writable = bundle.modules.findIndex((module) => module.index === writableIndex);
7084
- if (writable < 0) {
7085
- throw new Error(`module ${writableIndex} is not one of this binary's JavaScript modules`);
7086
- }
7087
- const changed = bundle.modules.map((module, at) => at).filter((at) => at !== writable && patchedSources[at] !== bundle.modules[at].source);
7088
- if (changed.length === 0) return { content: patchedSources[writable], repoints: [] };
7089
- const order = [writable, ...changed];
7090
- const repoints = [];
7091
- let content = "";
7092
- let start = 0;
7093
- for (const at of order) {
7116
+ const table = readBunModuleTable(path);
7117
+ if (!table) throw new Error(`cannot read the Bun module table of ${path}`);
7118
+ const recognized = table.names.filter(tweakccRecognizesModuleName);
7119
+ if (recognized.length !== 1) {
7120
+ throw new Error(
7121
+ `${path} has ${recognized.length} modules tweakcc would write to; the patch was planned around exactly one`
7122
+ );
7123
+ }
7124
+ if (!table.names[writableIndex] || !tweakccRecognizesModuleName(table.names[writableIndex])) {
7125
+ throw new Error(`module ${writableIndex} of ${path} is not the one tweakcc writes to`);
7126
+ }
7127
+ const appends = [];
7128
+ const sources = [];
7129
+ let cursor = table.byteCount;
7130
+ for (let at = 0; at < bundle.modules.length; at++) {
7131
+ const module = bundle.modules[at];
7094
7132
  const source = patchedSources[at];
7095
- const length = Buffer.byteLength(source, "utf8");
7096
- repoints.push({ index: bundle.modules[at].index, start, length, expected: source });
7097
- content += source + "\0";
7098
- start += length + 1;
7133
+ if (source === module.source) continue;
7134
+ cursor += (APPEND_ALIGNMENT - cursor % APPEND_ALIGNMENT) % APPEND_ALIGNMENT;
7135
+ const bytes = Buffer.from(source, "utf8");
7136
+ appends.push({ index: module.index, range: { offset: cursor, length: bytes.length }, expected: source });
7137
+ sources.push(bytes);
7138
+ cursor += bytes.length + 1;
7139
+ }
7140
+ if (cursor > 4294967295) {
7141
+ throw new Error(`the patched blob of ${path} would be ${cursor} bytes, past the 4 GiB a Bun offset can address`);
7142
+ }
7143
+ const data = Buffer.alloc(cursor);
7144
+ readBlobData(path, table, data);
7145
+ appends.forEach((append, at) => sources[at].copy(data, append.range.offset));
7146
+ for (const append of appends) repointModule(data, table, append);
7147
+ const offsets = Buffer.alloc(BUN_OFFSETS_BYTES2);
7148
+ offsets.writeUInt32LE(table.modulesOffset, 8);
7149
+ offsets.writeUInt32LE(table.modulesLength, 12);
7150
+ offsets.writeUInt32LE(table.entryPointId, 16);
7151
+ offsets.writeUInt32LE(table.compileExecArgv.offset, 20);
7152
+ offsets.writeUInt32LE(table.compileExecArgv.length, 24);
7153
+ offsets.writeUInt32LE(table.flags & ~BUN_BLOB_FLAGS.SOURCE_TEXT_CONTIGUOUS, 28);
7154
+ const wanted = data.length + BUN_OFFSETS_BYTES2 + BUN_TRAILER2.length + PLACEHOLDER_SLACK_BYTES;
7155
+ const empty = repackedBlobBytes(table, writableIndex, 0);
7156
+ if (wanted < empty) {
7157
+ throw new Error(
7158
+ `repacking ${path} is predicted to make a blob of at least ${empty} bytes, more than the ${wanted} the placeholder is sized against; clodex is reading overlapping payload ranges out of this binary's module table`
7159
+ );
7160
+ }
7161
+ return {
7162
+ content: placeholderOf(wanted - empty),
7163
+ data,
7164
+ offsets,
7165
+ writableIndex,
7166
+ names: table.names,
7167
+ entryPointId: table.entryPointId,
7168
+ flags: table.flags & ~BUN_BLOB_FLAGS.SOURCE_TEXT_CONTIGUOUS,
7169
+ blobAt: table.blobAt,
7170
+ appends
7171
+ };
7172
+ }
7173
+ var PLACEHOLDER_TEXT = "/*clodex:placeholder*/\n";
7174
+ function placeholderOf(byteLength) {
7175
+ return PLACEHOLDER_TEXT.repeat(Math.ceil(byteLength / PLACEHOLDER_TEXT.length)).slice(0, byteLength);
7176
+ }
7177
+ function readBlobData(path, table, into) {
7178
+ const fd = openSync3(path, "r");
7179
+ try {
7180
+ let read = 0;
7181
+ while (read < table.byteCount) {
7182
+ const got = readSync2(fd, into, read, table.byteCount - read, table.blobAt + read);
7183
+ if (got <= 0) {
7184
+ throw new Error(`read ${read} of the ${table.byteCount} blob bytes of ${path}`);
7185
+ }
7186
+ read += got;
7187
+ }
7188
+ } finally {
7189
+ closeSync3(fd);
7190
+ }
7191
+ }
7192
+ function repointModule(data, table, append) {
7193
+ const structAt = table.modulesOffset + append.index * table.structBytes;
7194
+ data.writeUInt32LE(append.range.offset, structAt + 8);
7195
+ data.writeUInt32LE(append.range.length, structAt + 12);
7196
+ data.writeUInt32LE(0, structAt + 24);
7197
+ data.writeUInt32LE(0, structAt + 28);
7198
+ if (table.structBytes === 52) {
7199
+ data.writeUInt32LE(0, structAt + 32);
7200
+ data.writeUInt32LE(0, structAt + 36);
7201
+ data.writeUInt32LE(0, structAt + 40);
7202
+ data.writeUInt32LE(0, structAt + 44);
7203
+ }
7204
+ if ((table.flags & BUN_BLOB_FLAGS.HAS_SOURCE_HASHES) === 0) return;
7205
+ const hashAt = table.modulesOffset + table.modulesLength + append.index * 4;
7206
+ if (hashAt + 4 > table.byteCount) {
7207
+ throw new Error(
7208
+ `the blob claims a source hash per module but the table is followed by only ${table.byteCount - table.modulesOffset - table.modulesLength} bytes`
7209
+ );
7099
7210
  }
7100
- return { content, repoints };
7211
+ data.writeUInt32LE(0, hashAt);
7101
7212
  }
7102
7213
  function applyBundleWritePlan(path, plan) {
7103
- const table = readBunModuleTable(path);
7104
- if (!table) {
7105
- if (plan.repoints.length === 0) return;
7106
- throw new Error(`cannot read the Bun module table of ${path} after repacking`);
7214
+ const repacked = readBunModuleTable(path);
7215
+ if (!repacked) throw new Error(`cannot read the Bun module table of ${path} after repacking`);
7216
+ const placeholderBytes = Buffer.byteLength(plan.content, "utf8");
7217
+ const written = repacked.contents[plan.writableIndex];
7218
+ if (!written || written.length !== placeholderBytes) {
7219
+ throw new Error(
7220
+ `${path} holds ${written ? written.length : "no"} bytes where the ${placeholderBytes} bytes clodex wrote should be; refusing to publish a blob addressed against it`
7221
+ );
7107
7222
  }
7108
- const recognized = table.names.filter(tweakccRecognizesModuleName);
7109
- if (recognized.length !== 1) {
7223
+ if (repacked.names.length !== plan.names.length || repacked.names.some((name, index) => name !== plan.names[index])) {
7110
7224
  throw new Error(
7111
- `${path} has ${recognized.length} modules tweakcc would write to; the patch was planned around exactly one`
7225
+ `${path} exposes a different module table after repacking than the patch was planned around`
7112
7226
  );
7113
7227
  }
7114
- if (plan.repoints.length === 0) return;
7115
- const writable = table.names.findIndex(tweakccRecognizesModuleName);
7116
- if (writable !== plan.repoints[0].index) {
7228
+ if (repacked.blobAt % BYTECODE_ALIGNMENT !== plan.blobAt % BYTECODE_ALIGNMENT) {
7117
7229
  throw new Error(
7118
- `${path} exposes module ${writable} to tweakcc, but the patch was planned around module ${plan.repoints[0].index}`
7230
+ `repacking ${path} moved its Bun blob from ${plan.blobAt} to ${repacked.blobAt}, which is a different offset modulo ${BYTECODE_ALIGNMENT}; every unpatched module's cached bytecode would be misaligned`
7119
7231
  );
7120
7232
  }
7121
- const written = table.contents[writable];
7122
- const expectedBytes = Buffer.byteLength(plan.content, "utf8");
7123
- if (written.length !== expectedBytes) {
7233
+ const byteCount = repacked.byteCount;
7234
+ if (byteCount < plan.data.length) {
7124
7235
  throw new Error(
7125
- `${path} holds ${written.length} bytes where the ${expectedBytes} bytes clodex wrote should be; refusing to repoint its modules`
7236
+ `repacking ${path} left ${byteCount} bytes for a blob that needs ${plan.data.length}; refusing to publish a truncated one`
7126
7237
  );
7127
7238
  }
7128
- const edits = plan.repoints.map((repoint) => ({
7129
- index: repoint.index,
7130
- range: { offset: written.offset + repoint.start, length: repoint.length }
7131
- }));
7132
- repointBunModuleContents(path, edits);
7239
+ const offsets = Buffer.from(plan.offsets);
7240
+ offsets.writeBigUInt64LE(BigInt(byteCount), 0);
7241
+ const fd = openSync3(path, "r+");
7242
+ try {
7243
+ writeAll(fd, plan.data, repacked.blobAt, path);
7244
+ const padding = byteCount - plan.data.length;
7245
+ if (padding > 0) writeAll(fd, Buffer.alloc(padding), repacked.blobAt + plan.data.length, path);
7246
+ writeAll(fd, offsets, repacked.blobAt + byteCount, path);
7247
+ writeAll(fd, BUN_TRAILER2, repacked.blobAt + byteCount + BUN_OFFSETS_BYTES2, path);
7248
+ } finally {
7249
+ closeSync3(fd);
7250
+ }
7251
+ const published = readBunModuleTable(path);
7252
+ if (!published) throw new Error(`cannot re-read the Bun module table of ${path} after publishing its blob`);
7253
+ if (published.byteCount !== byteCount || published.entryPointId !== plan.entryPointId || published.flags !== plan.flags || published.names.length !== plan.names.length || published.names.some((name, index) => name !== plan.names[index])) {
7254
+ throw new Error(`the blob published into ${path} does not read back as the one that was planned`);
7255
+ }
7133
7256
  const after = readBunJavaScriptModules(path);
7134
- if (!after) throw new Error(`cannot re-read the modules of ${path} after repointing them`);
7135
- const byIndex = new Map(after.map((module) => [module.index, module.source]));
7136
- for (const repoint of plan.repoints) {
7137
- if (byIndex.get(repoint.index) !== repoint.expected) {
7138
- throw new Error(`module ${repoint.index} of ${path} did not read back as the patched source`);
7139
- }
7257
+ if (!after) throw new Error(`cannot re-read the modules of ${path} after publishing its blob`);
7258
+ const expected = new Map(plan.appends.map((append) => [append.index, append.expected]));
7259
+ let matched = 0;
7260
+ for (const module of after) {
7261
+ const want = expected.get(module.index);
7262
+ if (want === void 0) continue;
7263
+ if (module.source !== want) {
7264
+ throw new Error(`module ${module.index} of ${path} did not read back as the patched source`);
7265
+ }
7266
+ matched++;
7267
+ }
7268
+ if (matched !== expected.size) {
7269
+ throw new Error(
7270
+ `${matched} of the ${expected.size} patched modules of ${path} came back as JavaScript Bun will execute`
7271
+ );
7272
+ }
7273
+ }
7274
+ function writeAll(fd, bytes, position, path) {
7275
+ let written = 0;
7276
+ while (written < bytes.length) {
7277
+ const wrote = writeSync3(fd, bytes, written, bytes.length - written, position + written);
7278
+ if (wrote <= 0) throw new Error(`wrote ${written} of ${bytes.length} blob bytes to ${path}`);
7279
+ written += wrote;
7140
7280
  }
7141
7281
  }
7142
7282
 
@@ -7635,6 +7775,7 @@ function sanitizeMessage(message) {
7635
7775
 
7636
7776
  // src/tool-input-sanitize.ts
7637
7777
  function sanitizeToolInput(input, requiredProps) {
7778
+ if (!input || typeof input !== "object" || Array.isArray(input)) return input;
7638
7779
  const out = /* @__PURE__ */ Object.create(null);
7639
7780
  for (const [k, v] of Object.entries(input)) {
7640
7781
  if (v === null) continue;
@@ -10019,7 +10160,7 @@ function thinkingProviderOptions(npm) {
10019
10160
 
10020
10161
  // src/proxy.ts
10021
10162
  import { createServer } from "http";
10022
- import { appendFileSync as appendFileSync2, openSync as openSync3, writeSync as writeSync3, closeSync as closeSync3 } from "fs";
10163
+ import { appendFileSync as appendFileSync2, openSync as openSync4, writeSync as writeSync4, closeSync as closeSync4 } from "fs";
10023
10164
 
10024
10165
  // src/http-utils.ts
10025
10166
  import * as zlib from "zlib";
@@ -10819,6 +10960,22 @@ function translateMessages(messages, npm, openAiPromptCacheBreakpoints = false)
10819
10960
  }
10820
10961
  return out;
10821
10962
  }
10963
+ function isPlainObject(value) {
10964
+ return value !== null && typeof value === "object" && !Array.isArray(value);
10965
+ }
10966
+ function parsesAsJson(text5) {
10967
+ if (text5.trim() === "") return true;
10968
+ try {
10969
+ JSON.parse(text5);
10970
+ return true;
10971
+ } catch {
10972
+ return false;
10973
+ }
10974
+ }
10975
+ function representableToolInput(input) {
10976
+ if (typeof input === "string") return input;
10977
+ return isPlainObject(input) || Array.isArray(input) ? input : {};
10978
+ }
10822
10979
  function toolRequiredProps(tools) {
10823
10980
  const map = /* @__PURE__ */ new Map();
10824
10981
  for (const [name, t] of Object.entries(tools ?? {})) {
@@ -10828,12 +10985,16 @@ function toolRequiredProps(tools) {
10828
10985
  }
10829
10986
  return map;
10830
10987
  }
10831
- function translateTools(anthropicTools) {
10988
+ function translateTools(anthropicTools, npm) {
10832
10989
  if (!anthropicTools?.length) return void 0;
10833
10990
  const tools = {};
10834
10991
  for (const t of anthropicTools) {
10835
10992
  if (!t.name || !t.input_schema) continue;
10836
- tools[t.name] = tool({ description: t.description ?? "", inputSchema: jsonSchema(t.input_schema) });
10993
+ tools[t.name] = tool({
10994
+ description: t.description ?? "",
10995
+ inputSchema: jsonSchema(t.input_schema),
10996
+ strict: npm === "@ai-sdk/openai" ? false : void 0
10997
+ });
10837
10998
  }
10838
10999
  return Object.keys(tools).length ? tools : void 0;
10839
11000
  }
@@ -10897,7 +11058,7 @@ function translateRequest(body, npm, options) {
10897
11058
  ...translateMessages(messages, npm, supportsExplicitOpenAiCaching)
10898
11059
  ],
10899
11060
  allowSystemInMessages: true,
10900
- tools: translateTools(upstreamTools.length ? upstreamTools : void 0),
11061
+ tools: translateTools(upstreamTools.length ? upstreamTools : void 0, npm),
10901
11062
  toolChoice: compactRequest ? "none" : translateToolChoice(body.tool_choice),
10902
11063
  maxOutputTokens: options?.openAiOAuth ? void 0 : body.max_tokens,
10903
11064
  temperature: body.temperature,
@@ -11114,7 +11275,8 @@ async function writeAnthropicStream(stream, modelId, write, log12, observer, too
11114
11275
  const id = part.toolCallId ?? "";
11115
11276
  if (idToBlock.has(id)) {
11116
11277
  if (!flushedTools.has(id)) {
11117
- const json = part.input !== void 0 && part.input !== null ? JSON.stringify(sanitizeToolInput(part.input, requiredProps.get(part.toolName ?? ""))) : toolJsonBuffer.get(id) ?? "";
11278
+ const buffered = toolJsonBuffer.get(id);
11279
+ const json = buffered !== void 0 && !isPlainObject(part.input) && !parsesAsJson(buffered) ? buffered : part.input !== void 0 && part.input !== null ? JSON.stringify(sanitizeToolInput(part.input, requiredProps.get(part.toolName ?? ""))) : buffered ?? "";
11118
11280
  if (json) {
11119
11281
  emit("content_block_delta", {
11120
11282
  type: "content_block_delta",
@@ -11319,7 +11481,7 @@ async function generateAnthropicResponse(model, params, modelId, options) {
11319
11481
  type: "tool_use",
11320
11482
  id: encodeToolUseId(tc.toolCallId, grabRoundTripSignature(tc)),
11321
11483
  name: tc.toolName,
11322
- input: sanitizeToolInput(tc.input ?? {}, requiredProps.get(tc.toolName))
11484
+ input: representableToolInput(sanitizeToolInput(tc.input ?? {}, requiredProps.get(tc.toolName)))
11323
11485
  }))
11324
11486
  ],
11325
11487
  stop_reason: finishReason === "tool-calls" ? "tool_use" : "end_turn",
@@ -11473,12 +11635,12 @@ function createTranslationLifecycle(logPath, requestId, claudeSessionId, modelId
11473
11635
  function appendSecureLog(logPath, line) {
11474
11636
  const redacted = redactTraceLine(line);
11475
11637
  try {
11476
- const fd = openSync3(logPath, "a", 384);
11638
+ const fd = openSync4(logPath, "a", 384);
11477
11639
  try {
11478
- writeSync3(fd, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
11640
+ writeSync4(fd, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
11479
11641
  `);
11480
11642
  } finally {
11481
- closeSync3(fd);
11643
+ closeSync4(fd);
11482
11644
  }
11483
11645
  } catch {
11484
11646
  try {
@@ -12341,10 +12503,10 @@ function tryAcquirePatchLock(lockPath = getPatchLockPath(), opts = {}) {
12341
12503
  mkdirSync5(join7(lockPath, ".."), { recursive: true, mode: 448 });
12342
12504
  for (let attempt = 0; attempt < 2; attempt++) {
12343
12505
  try {
12344
- const fd = openSync4(lockPath, "wx");
12506
+ const fd = openSync5(lockPath, "wx");
12345
12507
  const content = { pid: process.pid, startedAt: now };
12346
12508
  writeFileSync5(fd, JSON.stringify(content));
12347
- closeSync4(fd);
12509
+ closeSync5(fd);
12348
12510
  return () => {
12349
12511
  try {
12350
12512
  unlinkSync3(lockPath);
@@ -12592,25 +12754,26 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
12592
12754
  }
12593
12755
  results = [...results, ...local.results];
12594
12756
  const writeShim = shimEntryModuleName(candidatePath);
12595
- let repointed = false;
12757
+ let publishedBlob = false;
12596
12758
  if (loaded.bundle) {
12597
12759
  const writable = writableModuleIndex(candidatePath);
12598
12760
  if (writable === null) {
12599
12761
  throw new Error("no module of the patch candidate carries a name tweakcc can write to");
12600
12762
  }
12601
12763
  const plan2 = planBundleWrite(
12764
+ candidatePath,
12602
12765
  loaded.bundle,
12603
12766
  splitBundleSource(loaded.bundle, local.content),
12604
12767
  writable
12605
12768
  );
12606
12769
  await writeContent(loaded.installation, plan2.content);
12607
12770
  applyBundleWritePlan(candidatePath, plan2);
12608
- repointed = plan2.repoints.length > 0;
12771
+ publishedBlob = true;
12609
12772
  } else {
12610
12773
  await writeContent(loaded.installation, local.content);
12611
12774
  }
12612
12775
  if (writeShim) restoreEntryModuleName(candidatePath, writeShim, { resign: true });
12613
- else if (repointed) resignMachOBinary(candidatePath);
12776
+ else if (publishedBlob) resignMachOBinary(candidatePath);
12614
12777
  patchedSize = statSync6(candidatePath).size;
12615
12778
  patchedSha256 = sha256File(candidatePath);
12616
12779
  renameSync2(candidatePath, binaryPath);
@@ -13128,13 +13291,13 @@ function localProvidersToServerModels(localProviders) {
13128
13291
  // src/registry/credential-cleanup-journal.ts
13129
13292
  import { randomUUID as randomUUID4 } from "crypto";
13130
13293
  import {
13131
- closeSync as closeSync5,
13294
+ closeSync as closeSync6,
13132
13295
  existsSync as existsSync6,
13133
13296
  fstatSync,
13134
13297
  fsyncSync as fsyncSync2,
13135
13298
  lstatSync,
13136
13299
  mkdirSync as mkdirSync6,
13137
- openSync as openSync5,
13300
+ openSync as openSync6,
13138
13301
  readFileSync as readFileSync9,
13139
13302
  renameSync as renameSync3,
13140
13303
  unlinkSync as unlinkSync4,
@@ -13226,7 +13389,7 @@ function readJournalUnlocked(path) {
13226
13389
  if (before.isSymbolicLink() || !before.isFile()) {
13227
13390
  throw new Error("Credential cleanup journal must be a regular file.");
13228
13391
  }
13229
- fd = openSync5(path, "r");
13392
+ fd = openSync6(path, "r");
13230
13393
  const opened = fstatSync(fd);
13231
13394
  if (before.dev !== opened.dev || before.ino !== opened.ino) {
13232
13395
  throw new Error("Credential cleanup journal changed while opening.");
@@ -13247,19 +13410,19 @@ function readJournalUnlocked(path) {
13247
13410
  const message = error instanceof Error ? error.message : String(error);
13248
13411
  throw new Error(`Could not read credential cleanup journal: ${message}`);
13249
13412
  } finally {
13250
- if (fd !== void 0) closeSync5(fd);
13413
+ if (fd !== void 0) closeSync6(fd);
13251
13414
  }
13252
13415
  }
13253
13416
  function syncParentDirectory(path) {
13254
13417
  let fd;
13255
13418
  try {
13256
- fd = openSync5(dirname4(path), "r");
13419
+ fd = openSync6(dirname4(path), "r");
13257
13420
  fsyncSync2(fd);
13258
13421
  } catch (error) {
13259
13422
  const code = error.code;
13260
13423
  if (code !== "EINVAL" && code !== "ENOTSUP" && code !== "EPERM") throw error;
13261
13424
  } finally {
13262
- if (fd !== void 0) closeSync5(fd);
13425
+ if (fd !== void 0) closeSync6(fd);
13263
13426
  }
13264
13427
  }
13265
13428
  function writeJournalUnlocked(journal, path) {
@@ -13269,17 +13432,17 @@ function writeJournalUnlocked(journal, path) {
13269
13432
  const tmp = `${path}.${process.pid}.${randomUUID4()}.tmp`;
13270
13433
  let fd;
13271
13434
  try {
13272
- fd = openSync5(tmp, "wx", FILE_MODE4);
13435
+ fd = openSync6(tmp, "wx", FILE_MODE4);
13273
13436
  writeFileSync6(fd, `${JSON.stringify(journal, null, 2)}
13274
13437
  `);
13275
13438
  fsyncSync2(fd);
13276
- closeSync5(fd);
13439
+ closeSync6(fd);
13277
13440
  fd = void 0;
13278
13441
  assertRegistryWriteOwnership(path);
13279
13442
  renameSync3(tmp, path);
13280
13443
  syncParentDirectory(path);
13281
13444
  } finally {
13282
- if (fd !== void 0) closeSync5(fd);
13445
+ if (fd !== void 0) closeSync6(fd);
13283
13446
  try {
13284
13447
  unlinkSync4(tmp);
13285
13448
  } catch (error) {