poe-code 14.0.24 → 14.0.26

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.
Files changed (47) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-bash/dist/browser.js +906 -484
  6. package/packages/safe-bash/dist/browser.js.map +4 -4
  7. package/packages/safe-bash/dist/commands/metadata/stat.d.ts.map +1 -1
  8. package/packages/safe-bash/dist/commands/metadata/stat.js +22 -5
  9. package/packages/safe-bash/dist/commands/metadata/stat.js.map +1 -1
  10. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.d.ts +15 -0
  11. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.d.ts.map +1 -0
  12. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.js +319 -0
  13. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.js.map +1 -0
  14. package/packages/safe-bash/dist/commands/regex-execution/public.d.ts +1 -0
  15. package/packages/safe-bash/dist/commands/regex-execution/public.d.ts.map +1 -1
  16. package/packages/safe-bash/dist/commands/regex-execution/public.js +1 -0
  17. package/packages/safe-bash/dist/commands/regex-execution/public.js.map +1 -1
  18. package/packages/safe-bash/dist/commands/search/grep.d.ts +1 -1
  19. package/packages/safe-bash/dist/commands/search/grep.d.ts.map +1 -1
  20. package/packages/safe-bash/dist/commands/search/grep.js +45 -12
  21. package/packages/safe-bash/dist/commands/search/grep.js.map +1 -1
  22. package/packages/safe-bash/dist/commands/text-programs/awk-runtime.d.ts +1 -0
  23. package/packages/safe-bash/dist/commands/text-programs/awk-runtime.d.ts.map +1 -1
  24. package/packages/safe-bash/dist/commands/text-programs/awk-runtime.js +103 -34
  25. package/packages/safe-bash/dist/commands/text-programs/awk-runtime.js.map +1 -1
  26. package/packages/safe-bash/dist/commands/text-programs/sed.d.ts.map +1 -1
  27. package/packages/safe-bash/dist/commands/text-programs/sed.js +11 -2
  28. package/packages/safe-bash/dist/commands/text-programs/sed.js.map +1 -1
  29. package/packages/safe-bash/dist/commands/text-programs/shared.d.ts +1 -0
  30. package/packages/safe-bash/dist/commands/text-programs/shared.d.ts.map +1 -1
  31. package/packages/safe-bash/dist/commands/text-programs/shared.js +6 -2
  32. package/packages/safe-bash/dist/commands/text-programs/shared.js.map +1 -1
  33. package/packages/safe-bash/dist/commands/text.d.ts.map +1 -1
  34. package/packages/safe-bash/dist/commands/text.js +148 -43
  35. package/packages/safe-bash/dist/commands/text.js.map +1 -1
  36. package/packages/safe-bash/dist/shell/runtime.d.ts +1 -0
  37. package/packages/safe-bash/dist/shell/runtime.d.ts.map +1 -1
  38. package/packages/safe-bash/dist/shell/runtime.js +40 -8
  39. package/packages/safe-bash/dist/shell/runtime.js.map +1 -1
  40. package/packages/safe-bash/dist/shell/shell.js +2 -2
  41. package/packages/safe-bash/dist/shell/shell.js.map +1 -1
  42. package/packages/safe-bash/dist/shell/types.d.ts +3 -0
  43. package/packages/safe-bash/dist/shell/types.d.ts.map +1 -1
  44. package/packages/safe-bash/dist/shell/types.js.map +1 -1
  45. package/packages/safe-bash/dist/shell/worker-limits.d.ts.map +1 -1
  46. package/packages/safe-bash/dist/shell/worker-limits.js +1 -0
  47. package/packages/safe-bash/dist/shell/worker-limits.js.map +1 -1
@@ -41,7 +41,7 @@ var require_base64_js = __commonJS({
41
41
  "node_modules/base64-js/index.js"(exports) {
42
42
  "use strict";
43
43
  init_platform();
44
- exports.byteLength = byteLength;
44
+ exports.byteLength = byteLength2;
45
45
  exports.toByteArray = toByteArray;
46
46
  exports.fromByteArray = fromByteArray;
47
47
  var lookup = [];
@@ -66,7 +66,7 @@ var require_base64_js = __commonJS({
66
66
  var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
67
67
  return [validLen, placeHoldersLen];
68
68
  }
69
- function byteLength(b64) {
69
+ function byteLength2(b64) {
70
70
  var lens = getLens(b64);
71
71
  var validLen = lens[0];
72
72
  var placeHoldersLen = lens[1];
@@ -366,7 +366,7 @@ var require_buffer = __commonJS({
366
366
  if (!Buffer3.isEncoding(encoding)) {
367
367
  throw new TypeError("Unknown encoding: " + encoding);
368
368
  }
369
- const length = byteLength(string, encoding) | 0;
369
+ const length = byteLength2(string, encoding) | 0;
370
370
  let buf = createBuffer(length);
371
371
  const actual = buf.write(string, encoding);
372
372
  if (actual !== length) {
@@ -374,11 +374,11 @@ var require_buffer = __commonJS({
374
374
  }
375
375
  return buf;
376
376
  }
377
- function fromArrayLike(array) {
378
- const length = array.length < 0 ? 0 : checked(array.length) | 0;
377
+ function fromArrayLike(array2) {
378
+ const length = array2.length < 0 ? 0 : checked(array2.length) | 0;
379
379
  const buf = createBuffer(length);
380
380
  for (let i = 0; i < length; i += 1) {
381
- buf[i] = array[i] & 255;
381
+ buf[i] = array2[i] & 255;
382
382
  }
383
383
  return buf;
384
384
  }
@@ -389,20 +389,20 @@ var require_buffer = __commonJS({
389
389
  }
390
390
  return fromArrayLike(arrayView);
391
391
  }
392
- function fromArrayBuffer(array, byteOffset, length) {
393
- if (byteOffset < 0 || array.byteLength < byteOffset) {
392
+ function fromArrayBuffer(array2, byteOffset2, length) {
393
+ if (byteOffset2 < 0 || array2.byteLength < byteOffset2) {
394
394
  throw new RangeError('"offset" is outside of buffer bounds');
395
395
  }
396
- if (array.byteLength < byteOffset + (length || 0)) {
396
+ if (array2.byteLength < byteOffset2 + (length || 0)) {
397
397
  throw new RangeError('"length" is outside of buffer bounds');
398
398
  }
399
399
  let buf;
400
- if (byteOffset === void 0 && length === void 0) {
401
- buf = new Uint8Array(array);
400
+ if (byteOffset2 === void 0 && length === void 0) {
401
+ buf = new Uint8Array(array2);
402
402
  } else if (length === void 0) {
403
- buf = new Uint8Array(array, byteOffset);
403
+ buf = new Uint8Array(array2, byteOffset2);
404
404
  } else {
405
- buf = new Uint8Array(array, byteOffset, length);
405
+ buf = new Uint8Array(array2, byteOffset2, length);
406
406
  }
407
407
  Object.setPrototypeOf(buf, Buffer3.prototype);
408
408
  return buf;
@@ -520,7 +520,7 @@ var require_buffer = __commonJS({
520
520
  }
521
521
  return buffer;
522
522
  };
523
- function byteLength(string, encoding) {
523
+ function byteLength2(string, encoding) {
524
524
  if (Buffer3.isBuffer(string)) {
525
525
  return string.length;
526
526
  }
@@ -563,7 +563,7 @@ var require_buffer = __commonJS({
563
563
  }
564
564
  }
565
565
  }
566
- Buffer3.byteLength = byteLength;
566
+ Buffer3.byteLength = byteLength2;
567
567
  function slowToString(encoding, start, end) {
568
568
  let loweredCase = false;
569
569
  if (start === void 0 || start < 0) {
@@ -726,26 +726,26 @@ var require_buffer = __commonJS({
726
726
  if (y < x) return 1;
727
727
  return 0;
728
728
  };
729
- function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
729
+ function bidirectionalIndexOf(buffer, val, byteOffset2, encoding, dir) {
730
730
  if (buffer.length === 0) return -1;
731
- if (typeof byteOffset === "string") {
732
- encoding = byteOffset;
733
- byteOffset = 0;
734
- } else if (byteOffset > 2147483647) {
735
- byteOffset = 2147483647;
736
- } else if (byteOffset < -2147483648) {
737
- byteOffset = -2147483648;
738
- }
739
- byteOffset = +byteOffset;
740
- if (numberIsNaN(byteOffset)) {
741
- byteOffset = dir ? 0 : buffer.length - 1;
742
- }
743
- if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
744
- if (byteOffset >= buffer.length) {
731
+ if (typeof byteOffset2 === "string") {
732
+ encoding = byteOffset2;
733
+ byteOffset2 = 0;
734
+ } else if (byteOffset2 > 2147483647) {
735
+ byteOffset2 = 2147483647;
736
+ } else if (byteOffset2 < -2147483648) {
737
+ byteOffset2 = -2147483648;
738
+ }
739
+ byteOffset2 = +byteOffset2;
740
+ if (numberIsNaN(byteOffset2)) {
741
+ byteOffset2 = dir ? 0 : buffer.length - 1;
742
+ }
743
+ if (byteOffset2 < 0) byteOffset2 = buffer.length + byteOffset2;
744
+ if (byteOffset2 >= buffer.length) {
745
745
  if (dir) return -1;
746
- else byteOffset = buffer.length - 1;
747
- } else if (byteOffset < 0) {
748
- if (dir) byteOffset = 0;
746
+ else byteOffset2 = buffer.length - 1;
747
+ } else if (byteOffset2 < 0) {
748
+ if (dir) byteOffset2 = 0;
749
749
  else return -1;
750
750
  }
751
751
  if (typeof val === "string") {
@@ -755,21 +755,21 @@ var require_buffer = __commonJS({
755
755
  if (val.length === 0) {
756
756
  return -1;
757
757
  }
758
- return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
758
+ return arrayIndexOf(buffer, val, byteOffset2, encoding, dir);
759
759
  } else if (typeof val === "number") {
760
760
  val = val & 255;
761
761
  if (typeof Uint8Array.prototype.indexOf === "function") {
762
762
  if (dir) {
763
- return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
763
+ return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset2);
764
764
  } else {
765
- return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
765
+ return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset2);
766
766
  }
767
767
  }
768
- return arrayIndexOf(buffer, [val], byteOffset, encoding, dir);
768
+ return arrayIndexOf(buffer, [val], byteOffset2, encoding, dir);
769
769
  }
770
770
  throw new TypeError("val must be string, number or Buffer");
771
771
  }
772
- function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
772
+ function arrayIndexOf(arr, val, byteOffset2, encoding, dir) {
773
773
  let indexSize = 1;
774
774
  let arrLength = arr.length;
775
775
  let valLength = val.length;
@@ -782,7 +782,7 @@ var require_buffer = __commonJS({
782
782
  indexSize = 2;
783
783
  arrLength /= 2;
784
784
  valLength /= 2;
785
- byteOffset /= 2;
785
+ byteOffset2 /= 2;
786
786
  }
787
787
  }
788
788
  function read(buf, i2) {
@@ -795,7 +795,7 @@ var require_buffer = __commonJS({
795
795
  let i;
796
796
  if (dir) {
797
797
  let foundIndex = -1;
798
- for (i = byteOffset; i < arrLength; i++) {
798
+ for (i = byteOffset2; i < arrLength; i++) {
799
799
  if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
800
800
  if (foundIndex === -1) foundIndex = i;
801
801
  if (i - foundIndex + 1 === valLength) return foundIndex * indexSize;
@@ -805,8 +805,8 @@ var require_buffer = __commonJS({
805
805
  }
806
806
  }
807
807
  } else {
808
- if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
809
- for (i = byteOffset; i >= 0; i--) {
808
+ if (byteOffset2 + valLength > arrLength) byteOffset2 = arrLength - valLength;
809
+ for (i = byteOffset2; i >= 0; i--) {
810
810
  let found = true;
811
811
  for (let j = 0; j < valLength; j++) {
812
812
  if (read(arr, i + j) !== read(val, j)) {
@@ -819,14 +819,14 @@ var require_buffer = __commonJS({
819
819
  }
820
820
  return -1;
821
821
  }
822
- Buffer3.prototype.includes = function includes(val, byteOffset, encoding) {
823
- return this.indexOf(val, byteOffset, encoding) !== -1;
822
+ Buffer3.prototype.includes = function includes(val, byteOffset2, encoding) {
823
+ return this.indexOf(val, byteOffset2, encoding) !== -1;
824
824
  };
825
- Buffer3.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
826
- return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
825
+ Buffer3.prototype.indexOf = function indexOf(val, byteOffset2, encoding) {
826
+ return bidirectionalIndexOf(this, val, byteOffset2, encoding, true);
827
827
  };
828
- Buffer3.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
829
- return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
828
+ Buffer3.prototype.lastIndexOf = function lastIndexOf(val, byteOffset2, encoding) {
829
+ return bidirectionalIndexOf(this, val, byteOffset2, encoding, false);
830
830
  };
831
831
  function hexWrite(buf, string, offset, length) {
832
832
  offset = Number(offset) || 0;
@@ -1066,28 +1066,28 @@ var require_buffer = __commonJS({
1066
1066
  if (offset % 1 !== 0 || offset < 0) throw new RangeError("offset is not uint");
1067
1067
  if (offset + ext > length) throw new RangeError("Trying to access beyond buffer length");
1068
1068
  }
1069
- Buffer3.prototype.readUintLE = Buffer3.prototype.readUIntLE = function readUIntLE(offset, byteLength2, noAssert) {
1069
+ Buffer3.prototype.readUintLE = Buffer3.prototype.readUIntLE = function readUIntLE(offset, byteLength3, noAssert) {
1070
1070
  offset = offset >>> 0;
1071
- byteLength2 = byteLength2 >>> 0;
1072
- if (!noAssert) checkOffset(offset, byteLength2, this.length);
1071
+ byteLength3 = byteLength3 >>> 0;
1072
+ if (!noAssert) checkOffset(offset, byteLength3, this.length);
1073
1073
  let val = this[offset];
1074
1074
  let mul = 1;
1075
1075
  let i = 0;
1076
- while (++i < byteLength2 && (mul *= 256)) {
1076
+ while (++i < byteLength3 && (mul *= 256)) {
1077
1077
  val += this[offset + i] * mul;
1078
1078
  }
1079
1079
  return val;
1080
1080
  };
1081
- Buffer3.prototype.readUintBE = Buffer3.prototype.readUIntBE = function readUIntBE(offset, byteLength2, noAssert) {
1081
+ Buffer3.prototype.readUintBE = Buffer3.prototype.readUIntBE = function readUIntBE(offset, byteLength3, noAssert) {
1082
1082
  offset = offset >>> 0;
1083
- byteLength2 = byteLength2 >>> 0;
1083
+ byteLength3 = byteLength3 >>> 0;
1084
1084
  if (!noAssert) {
1085
- checkOffset(offset, byteLength2, this.length);
1085
+ checkOffset(offset, byteLength3, this.length);
1086
1086
  }
1087
- let val = this[offset + --byteLength2];
1087
+ let val = this[offset + --byteLength3];
1088
1088
  let mul = 1;
1089
- while (byteLength2 > 0 && (mul *= 256)) {
1090
- val += this[offset + --byteLength2] * mul;
1089
+ while (byteLength3 > 0 && (mul *= 256)) {
1090
+ val += this[offset + --byteLength3] * mul;
1091
1091
  }
1092
1092
  return val;
1093
1093
  };
@@ -1140,32 +1140,32 @@ var require_buffer = __commonJS({
1140
1140
  const lo = this[++offset] * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + last;
1141
1141
  return (BigInt(hi) << BigInt(32)) + BigInt(lo);
1142
1142
  });
1143
- Buffer3.prototype.readIntLE = function readIntLE(offset, byteLength2, noAssert) {
1143
+ Buffer3.prototype.readIntLE = function readIntLE(offset, byteLength3, noAssert) {
1144
1144
  offset = offset >>> 0;
1145
- byteLength2 = byteLength2 >>> 0;
1146
- if (!noAssert) checkOffset(offset, byteLength2, this.length);
1145
+ byteLength3 = byteLength3 >>> 0;
1146
+ if (!noAssert) checkOffset(offset, byteLength3, this.length);
1147
1147
  let val = this[offset];
1148
1148
  let mul = 1;
1149
1149
  let i = 0;
1150
- while (++i < byteLength2 && (mul *= 256)) {
1150
+ while (++i < byteLength3 && (mul *= 256)) {
1151
1151
  val += this[offset + i] * mul;
1152
1152
  }
1153
1153
  mul *= 128;
1154
- if (val >= mul) val -= Math.pow(2, 8 * byteLength2);
1154
+ if (val >= mul) val -= Math.pow(2, 8 * byteLength3);
1155
1155
  return val;
1156
1156
  };
1157
- Buffer3.prototype.readIntBE = function readIntBE(offset, byteLength2, noAssert) {
1157
+ Buffer3.prototype.readIntBE = function readIntBE(offset, byteLength3, noAssert) {
1158
1158
  offset = offset >>> 0;
1159
- byteLength2 = byteLength2 >>> 0;
1160
- if (!noAssert) checkOffset(offset, byteLength2, this.length);
1161
- let i = byteLength2;
1159
+ byteLength3 = byteLength3 >>> 0;
1160
+ if (!noAssert) checkOffset(offset, byteLength3, this.length);
1161
+ let i = byteLength3;
1162
1162
  let mul = 1;
1163
1163
  let val = this[offset + --i];
1164
1164
  while (i > 0 && (mul *= 256)) {
1165
1165
  val += this[offset + --i] * mul;
1166
1166
  }
1167
1167
  mul *= 128;
1168
- if (val >= mul) val -= Math.pow(2, 8 * byteLength2);
1168
+ if (val >= mul) val -= Math.pow(2, 8 * byteLength3);
1169
1169
  return val;
1170
1170
  };
1171
1171
  Buffer3.prototype.readInt8 = function readInt8(offset, noAssert) {
@@ -1244,37 +1244,37 @@ var require_buffer = __commonJS({
1244
1244
  if (value2 > max || value2 < min) throw new RangeError('"value" argument is out of bounds');
1245
1245
  if (offset + ext > buf.length) throw new RangeError("Index out of range");
1246
1246
  }
1247
- Buffer3.prototype.writeUintLE = Buffer3.prototype.writeUIntLE = function writeUIntLE(value2, offset, byteLength2, noAssert) {
1247
+ Buffer3.prototype.writeUintLE = Buffer3.prototype.writeUIntLE = function writeUIntLE(value2, offset, byteLength3, noAssert) {
1248
1248
  value2 = +value2;
1249
1249
  offset = offset >>> 0;
1250
- byteLength2 = byteLength2 >>> 0;
1250
+ byteLength3 = byteLength3 >>> 0;
1251
1251
  if (!noAssert) {
1252
- const maxBytes = Math.pow(2, 8 * byteLength2) - 1;
1253
- checkInt(this, value2, offset, byteLength2, maxBytes, 0);
1252
+ const maxBytes = Math.pow(2, 8 * byteLength3) - 1;
1253
+ checkInt(this, value2, offset, byteLength3, maxBytes, 0);
1254
1254
  }
1255
1255
  let mul = 1;
1256
1256
  let i = 0;
1257
1257
  this[offset] = value2 & 255;
1258
- while (++i < byteLength2 && (mul *= 256)) {
1258
+ while (++i < byteLength3 && (mul *= 256)) {
1259
1259
  this[offset + i] = value2 / mul & 255;
1260
1260
  }
1261
- return offset + byteLength2;
1261
+ return offset + byteLength3;
1262
1262
  };
1263
- Buffer3.prototype.writeUintBE = Buffer3.prototype.writeUIntBE = function writeUIntBE(value2, offset, byteLength2, noAssert) {
1263
+ Buffer3.prototype.writeUintBE = Buffer3.prototype.writeUIntBE = function writeUIntBE(value2, offset, byteLength3, noAssert) {
1264
1264
  value2 = +value2;
1265
1265
  offset = offset >>> 0;
1266
- byteLength2 = byteLength2 >>> 0;
1266
+ byteLength3 = byteLength3 >>> 0;
1267
1267
  if (!noAssert) {
1268
- const maxBytes = Math.pow(2, 8 * byteLength2) - 1;
1269
- checkInt(this, value2, offset, byteLength2, maxBytes, 0);
1268
+ const maxBytes = Math.pow(2, 8 * byteLength3) - 1;
1269
+ checkInt(this, value2, offset, byteLength3, maxBytes, 0);
1270
1270
  }
1271
- let i = byteLength2 - 1;
1271
+ let i = byteLength3 - 1;
1272
1272
  let mul = 1;
1273
1273
  this[offset + i] = value2 & 255;
1274
1274
  while (--i >= 0 && (mul *= 256)) {
1275
1275
  this[offset + i] = value2 / mul & 255;
1276
1276
  }
1277
- return offset + byteLength2;
1277
+ return offset + byteLength3;
1278
1278
  };
1279
1279
  Buffer3.prototype.writeUint8 = Buffer3.prototype.writeUInt8 = function writeUInt8(value2, offset, noAssert) {
1280
1280
  value2 = +value2;
@@ -1365,33 +1365,33 @@ var require_buffer = __commonJS({
1365
1365
  Buffer3.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE(value2, offset = 0) {
1366
1366
  return wrtBigUInt64BE(this, value2, offset, BigInt(0), BigInt("0xffffffffffffffff"));
1367
1367
  });
1368
- Buffer3.prototype.writeIntLE = function writeIntLE(value2, offset, byteLength2, noAssert) {
1368
+ Buffer3.prototype.writeIntLE = function writeIntLE(value2, offset, byteLength3, noAssert) {
1369
1369
  value2 = +value2;
1370
1370
  offset = offset >>> 0;
1371
1371
  if (!noAssert) {
1372
- const limit = Math.pow(2, 8 * byteLength2 - 1);
1373
- checkInt(this, value2, offset, byteLength2, limit - 1, -limit);
1372
+ const limit = Math.pow(2, 8 * byteLength3 - 1);
1373
+ checkInt(this, value2, offset, byteLength3, limit - 1, -limit);
1374
1374
  }
1375
1375
  let i = 0;
1376
1376
  let mul = 1;
1377
1377
  let sub = 0;
1378
1378
  this[offset] = value2 & 255;
1379
- while (++i < byteLength2 && (mul *= 256)) {
1379
+ while (++i < byteLength3 && (mul *= 256)) {
1380
1380
  if (value2 < 0 && sub === 0 && this[offset + i - 1] !== 0) {
1381
1381
  sub = 1;
1382
1382
  }
1383
1383
  this[offset + i] = (value2 / mul >> 0) - sub & 255;
1384
1384
  }
1385
- return offset + byteLength2;
1385
+ return offset + byteLength3;
1386
1386
  };
1387
- Buffer3.prototype.writeIntBE = function writeIntBE(value2, offset, byteLength2, noAssert) {
1387
+ Buffer3.prototype.writeIntBE = function writeIntBE(value2, offset, byteLength3, noAssert) {
1388
1388
  value2 = +value2;
1389
1389
  offset = offset >>> 0;
1390
1390
  if (!noAssert) {
1391
- const limit = Math.pow(2, 8 * byteLength2 - 1);
1392
- checkInt(this, value2, offset, byteLength2, limit - 1, -limit);
1391
+ const limit = Math.pow(2, 8 * byteLength3 - 1);
1392
+ checkInt(this, value2, offset, byteLength3, limit - 1, -limit);
1393
1393
  }
1394
- let i = byteLength2 - 1;
1394
+ let i = byteLength3 - 1;
1395
1395
  let mul = 1;
1396
1396
  let sub = 0;
1397
1397
  this[offset + i] = value2 & 255;
@@ -1401,7 +1401,7 @@ var require_buffer = __commonJS({
1401
1401
  }
1402
1402
  this[offset + i] = (value2 / mul >> 0) - sub & 255;
1403
1403
  }
1404
- return offset + byteLength2;
1404
+ return offset + byteLength3;
1405
1405
  };
1406
1406
  Buffer3.prototype.writeInt8 = function writeInt8(value2, offset, noAssert) {
1407
1407
  value2 = +value2;
@@ -1646,28 +1646,28 @@ var require_buffer = __commonJS({
1646
1646
  }
1647
1647
  return `${val.slice(0, i)}${res}`;
1648
1648
  }
1649
- function checkBounds(buf, offset, byteLength2) {
1649
+ function checkBounds(buf, offset, byteLength3) {
1650
1650
  validateNumber(offset, "offset");
1651
- if (buf[offset] === void 0 || buf[offset + byteLength2] === void 0) {
1652
- boundsError(offset, buf.length - (byteLength2 + 1));
1651
+ if (buf[offset] === void 0 || buf[offset + byteLength3] === void 0) {
1652
+ boundsError(offset, buf.length - (byteLength3 + 1));
1653
1653
  }
1654
1654
  }
1655
- function checkIntBI(value2, min, max, buf, offset, byteLength2) {
1655
+ function checkIntBI(value2, min, max, buf, offset, byteLength3) {
1656
1656
  if (value2 > max || value2 < min) {
1657
1657
  const n = typeof min === "bigint" ? "n" : "";
1658
1658
  let range;
1659
- if (byteLength2 > 3) {
1659
+ if (byteLength3 > 3) {
1660
1660
  if (min === 0 || min === BigInt(0)) {
1661
- range = `>= 0${n} and < 2${n} ** ${(byteLength2 + 1) * 8}${n}`;
1661
+ range = `>= 0${n} and < 2${n} ** ${(byteLength3 + 1) * 8}${n}`;
1662
1662
  } else {
1663
- range = `>= -(2${n} ** ${(byteLength2 + 1) * 8 - 1}${n}) and < 2 ** ${(byteLength2 + 1) * 8 - 1}${n}`;
1663
+ range = `>= -(2${n} ** ${(byteLength3 + 1) * 8 - 1}${n}) and < 2 ** ${(byteLength3 + 1) * 8 - 1}${n}`;
1664
1664
  }
1665
1665
  } else {
1666
1666
  range = `>= ${min}${n} and <= ${max}${n}`;
1667
1667
  }
1668
1668
  throw new errors.ERR_OUT_OF_RANGE("value", range, value2);
1669
1669
  }
1670
- checkBounds(buf, offset, byteLength2);
1670
+ checkBounds(buf, offset, byteLength3);
1671
1671
  }
1672
1672
  function validateNumber(value2, name2) {
1673
1673
  if (typeof value2 !== "number") {
@@ -2179,18 +2179,18 @@ var CommandRegistry = class {
2179
2179
  constructor(commands = []) {
2180
2180
  for (const command2 of commands) this.register(command2);
2181
2181
  }
2182
- register(command2, options2 = {}) {
2183
- const { name: name2, execute: execute2 } = command2;
2182
+ register(command2, options3 = {}) {
2183
+ const { name: name2, execute: execute3 } = command2;
2184
2184
  if (typeof name2 !== "string" || !name2 || /[\s/\0]/u.test(name2)) {
2185
2185
  throw new TypeError("Command names must be nonempty and contain no whitespace, slash, or NUL");
2186
2186
  }
2187
- if (typeof execute2 !== "function") {
2187
+ if (typeof execute3 !== "function") {
2188
2188
  throw new TypeError("Command execute must be a function");
2189
2189
  }
2190
- if (this.#commands.has(name2) && !options2.replace) {
2190
+ if (this.#commands.has(name2) && !options3.replace) {
2191
2191
  throw new Error(`Command already registered: ${name2}`);
2192
2192
  }
2193
- this.#commands.set(name2, Object.freeze({ ...command2, name: name2, execute: execute2 }));
2193
+ this.#commands.set(name2, Object.freeze({ ...command2, name: name2, execute: execute3 }));
2194
2194
  return this;
2195
2195
  }
2196
2196
  get(name2) {
@@ -2273,9 +2273,9 @@ init_platform();
2273
2273
  import { collectBytes, readBytes } from "poe-code/safe-fs/core";
2274
2274
  import { collectBytes as collectBytes2, readBytes as readBytes2, toByteSource } from "poe-code/safe-fs/core";
2275
2275
  var outputFailure = /* @__PURE__ */ Symbol("output failure");
2276
- function createBytePipe(options2 = {}) {
2277
- const highWaterMark = options2.highWaterMark ?? 64 * 1024;
2278
- const signal = options2.signal;
2276
+ function createBytePipe(options3 = {}) {
2277
+ const highWaterMark = options3.highWaterMark ?? 64 * 1024;
2278
+ const signal = options3.signal;
2279
2279
  if (!Number.isSafeInteger(highWaterMark) || highWaterMark < 1) {
2280
2280
  throw new RangeError("highWaterMark must be a positive safe integer");
2281
2281
  }
@@ -2390,8 +2390,8 @@ async function pipeBytes(source, sink, signal) {
2390
2390
  }
2391
2391
  signal?.throwIfAborted();
2392
2392
  }
2393
- async function collectText(source, options2) {
2394
- return new TextDecoder().decode(await collectBytes(source, options2));
2393
+ async function collectText(source, options3) {
2394
+ return new TextDecoder().decode(await collectBytes(source, options3));
2395
2395
  }
2396
2396
  async function abortable(operation, signal) {
2397
2397
  signal?.throwIfAborted();
@@ -2796,17 +2796,6 @@ function concatenate(chunks, size = chunks.reduce((sum, chunk) => sum + chunk.le
2796
2796
  }
2797
2797
  return result;
2798
2798
  }
2799
- async function collect(source, signal, limit = bufferLimit) {
2800
- const chunks = [];
2801
- let size = 0;
2802
- for await (const chunk of source) {
2803
- signal.throwIfAborted();
2804
- size += chunk.length;
2805
- if (size > limit) throw new FsError("EFBIG", { message: `buffer limit exceeded (${limit} bytes)` });
2806
- chunks.push(new Uint8Array(chunk));
2807
- }
2808
- return concatenate(chunks, size);
2809
- }
2810
2799
  async function* lines(source, separator = 10) {
2811
2800
  let pending = [];
2812
2801
  let size = 0;
@@ -3128,23 +3117,23 @@ function compareCopyIdentity(left, right) {
3128
3117
  if (!left || !right || !complete(left) || !complete(right)) return "unknown";
3129
3118
  return left.identityScope === right.identityScope && left.dev === right.dev && left.ino === right.ino ? "same" : "distinct";
3130
3119
  }
3131
- async function compareObservedEntries(fs, path, stat, peer, peerPath, peerStat, options2 = {}) {
3132
- options2.signal?.throwIfAborted();
3120
+ async function compareObservedEntries(fs, path, stat, peer, peerPath, peerStat, options3 = {}) {
3121
+ options3.signal?.throwIfAborted();
3133
3122
  const identity = compareCopyIdentity(stat, peerStat);
3134
3123
  if (identity !== "unknown") return identity;
3135
3124
  let result = "unknown";
3136
3125
  const operands = fs === peer ? [[fs, path, peer, peerPath]] : [[fs, path, peer, peerPath], [peer, peerPath, fs, path]];
3137
3126
  for (const [owner, ownPath, other, otherPath] of operands) {
3138
- options2.signal?.throwIfAborted();
3127
+ options3.signal?.throwIfAborted();
3139
3128
  if (!owner.compareEntry) continue;
3140
3129
  let answer;
3141
3130
  try {
3142
- answer = await owner.compareEntry(ownPath, other, otherPath, options2);
3131
+ answer = await owner.compareEntry(ownPath, other, otherPath, options3);
3143
3132
  } catch (error) {
3144
- options2.signal?.throwIfAborted();
3133
+ options3.signal?.throwIfAborted();
3145
3134
  throw error;
3146
3135
  }
3147
- options2.signal?.throwIfAborted();
3136
+ options3.signal?.throwIfAborted();
3148
3137
  if (answer !== "same" && answer !== "distinct" && answer !== "unknown") {
3149
3138
  throw new FsError("EIO", { path, dest: peerPath, message: "invalid entry comparison answer" });
3150
3139
  }
@@ -4597,6 +4586,68 @@ function streamCommands() {
4597
4586
 
4598
4587
  // packages/safe-bash/src/commands/text.ts
4599
4588
  init_platform();
4589
+ var SortWork = class {
4590
+ constructor(signal) {
4591
+ this.signal = signal;
4592
+ }
4593
+ signal;
4594
+ #pending = 0;
4595
+ charge(units = 1) {
4596
+ this.signal.throwIfAborted();
4597
+ this.#pending += units;
4598
+ if (this.#pending >= 4096) return this.#checkpoint();
4599
+ }
4600
+ async #checkpoint() {
4601
+ while (this.#pending >= 4096) {
4602
+ this.#pending -= 4096;
4603
+ await yieldTurn(this.signal);
4604
+ this.signal.throwIfAborted();
4605
+ }
4606
+ }
4607
+ };
4608
+ async function sortRecords(records, compare, work) {
4609
+ if (records.length < 2) return records;
4610
+ let source = records;
4611
+ let target = new Array(records.length);
4612
+ for (let width = 1; width < records.length; width *= 2) {
4613
+ for (let begin = 0; begin < records.length; begin += width * 2) {
4614
+ const middle = Math.min(begin + width, records.length);
4615
+ const end = Math.min(begin + width * 2, records.length);
4616
+ let left = begin;
4617
+ let right = middle;
4618
+ for (let index = begin; index < end; index++) {
4619
+ const checkpoint = work.charge();
4620
+ if (checkpoint) await checkpoint;
4621
+ if (left < middle && (right === end || await compare(source[left], source[right]) <= 0)) target[index] = source[left++];
4622
+ else target[index] = source[right++];
4623
+ }
4624
+ }
4625
+ [source, target] = [target, source];
4626
+ }
4627
+ return source;
4628
+ }
4629
+ async function compareSortBytes(left, right, work) {
4630
+ const length = Math.min(left.length, right.length);
4631
+ for (let offset = 0; offset < length; offset += 1024) {
4632
+ const end = Math.min(offset + 1024, length);
4633
+ await work.charge(2 * (end - offset));
4634
+ const compared = import_buffer.Buffer.compare(left.subarray(offset, end), right.subarray(offset, end));
4635
+ if (compared) return compared;
4636
+ }
4637
+ return left.length - right.length;
4638
+ }
4639
+ async function foldSortBytes(bytes2, work) {
4640
+ const folded = new Uint8Array(bytes2.length);
4641
+ for (let offset = 0; offset < bytes2.length; offset += 1024) {
4642
+ const end = Math.min(offset + 1024, bytes2.length);
4643
+ await work.charge(end - offset);
4644
+ for (let index = offset; index < end; index++) {
4645
+ const byte = bytes2[index];
4646
+ folded[index] = byte >= 97 && byte <= 122 ? byte - 32 : byte;
4647
+ }
4648
+ }
4649
+ return folded;
4650
+ }
4600
4651
  async function admitTextOutput(context, destination) {
4601
4652
  if (destination === void 0) return;
4602
4653
  assertCommandRequirements(context, textOutputRequirements, ["output"]);
@@ -4613,27 +4664,37 @@ function compareBytes(left, right) {
4613
4664
  function fold(bytes2) {
4614
4665
  return bytes2.map((byte) => byte >= 97 && byte <= 122 ? byte - 32 : byte);
4615
4666
  }
4616
- function parseNumeric(bytes2) {
4667
+ async function parseNumeric(bytes2, work) {
4668
+ await work.charge(bytes2.length);
4617
4669
  const match = /^[ \t]*(-?)([0-9]*)(?:\.([0-9]*))?/u.exec(import_buffer.Buffer.from(bytes2).toString("latin1"));
4618
4670
  const whole = (match[2] ?? "").replace(/^0+/u, "") || "0";
4619
4671
  const fraction = (match[3] ?? "").replace(/0+$/u, "");
4620
4672
  return { whole, fraction, negative: match[1] === "-" && (whole !== "0" || fraction !== "") };
4621
4673
  }
4622
- function compareNumericValues(first, second) {
4674
+ async function compareNumericValues(first, second, work) {
4623
4675
  if (first.negative !== second.negative) return first.negative ? -1 : 1;
4624
4676
  let compared = first.whole.length - second.whole.length;
4625
- if (!compared) compared = first.whole < second.whole ? -1 : first.whole > second.whole ? 1 : 0;
4677
+ if (!compared) {
4678
+ for (let offset = 0; offset < first.whole.length && !compared; offset += 1024) {
4679
+ const end = Math.min(offset + 1024, first.whole.length);
4680
+ await work.charge(2 * (end - offset));
4681
+ const firstWhole = first.whole.slice(offset, end);
4682
+ const secondWhole = second.whole.slice(offset, end);
4683
+ compared = firstWhole < secondWhole ? -1 : firstWhole > secondWhole ? 1 : 0;
4684
+ }
4685
+ }
4626
4686
  if (!compared) {
4627
4687
  const width = Math.max(first.fraction.length, second.fraction.length);
4628
- const firstFraction = first.fraction.padEnd(width, "0");
4629
- const secondFraction = second.fraction.padEnd(width, "0");
4630
- compared = firstFraction < secondFraction ? -1 : firstFraction > secondFraction ? 1 : 0;
4688
+ for (let offset = 0; offset < width && !compared; offset += 1024) {
4689
+ const end = Math.min(offset + 1024, width);
4690
+ await work.charge(2 * (end - offset));
4691
+ const firstFraction = first.fraction.slice(offset, end).padEnd(end - offset, "0");
4692
+ const secondFraction = second.fraction.slice(offset, end).padEnd(end - offset, "0");
4693
+ compared = firstFraction < secondFraction ? -1 : firstFraction > secondFraction ? 1 : 0;
4694
+ }
4631
4695
  }
4632
4696
  return first.negative ? -compared : compared;
4633
4697
  }
4634
- function numericCompare(left, right) {
4635
- return compareNumericValues(parseNumeric(left), parseNumeric(right));
4636
- }
4637
4698
  function sortKey(specification) {
4638
4699
  const match = /^([0-9]+)(?:\.([0-9]+))?([bfnr]*)(?:,([0-9]+)(?:\.([0-9]+))?([bfnr]*))?$/u.exec(specification);
4639
4700
  if (!match) throw new UsageError(`invalid key '${specification}'`);
@@ -4645,25 +4706,33 @@ function sortKey(specification) {
4645
4706
  flags: new Set((match[3] ?? "") + (match[6] ?? ""))
4646
4707
  };
4647
4708
  }
4648
- function keyBytes(line, key, separator, blanks) {
4709
+ async function keyBytes(line, key, separator, blanks, work) {
4649
4710
  const fields = [];
4650
4711
  if (separator !== void 0) {
4651
4712
  let start2 = 0;
4652
- for (let offset = 0; offset <= line.length; offset++) if (offset === line.length || line[offset] === separator) {
4653
- fields.push({ start: start2, end: offset });
4654
- start2 = offset + 1;
4713
+ for (let offset = 0; offset <= line.length; offset++) {
4714
+ if (offset > 0 && offset % 1024 === 0) await work.charge(1024);
4715
+ if (offset === line.length || line[offset] === separator) {
4716
+ fields.push({ start: start2, end: offset });
4717
+ start2 = offset + 1;
4718
+ }
4655
4719
  }
4656
4720
  } else {
4657
4721
  let offset = 0;
4658
4722
  while (offset < line.length) {
4659
4723
  const leading = offset;
4660
- while (offset < line.length && (line[offset] === 32 || line[offset] === 9)) offset++;
4724
+ while (offset < line.length && (line[offset] === 32 || line[offset] === 9)) {
4725
+ if (++offset % 1024 === 0) await work.charge(1024);
4726
+ }
4661
4727
  const start2 = blanks ? offset : leading;
4662
4728
  if (offset === line.length) break;
4663
- while (offset < line.length && line[offset] !== 32 && line[offset] !== 9) offset++;
4729
+ while (offset < line.length && line[offset] !== 32 && line[offset] !== 9) {
4730
+ if (++offset % 1024 === 0) await work.charge(1024);
4731
+ }
4664
4732
  fields.push({ start: start2, end: offset });
4665
4733
  }
4666
4734
  }
4735
+ await work.charge(line.length % 1024);
4667
4736
  const start = (fields[key.start - 1]?.start ?? line.length) + key.startCharacter - 1;
4668
4737
  const last = key.end === void 0 ? void 0 : fields[key.end - 1];
4669
4738
  const end = key.end === void 0 ? line.length : last === void 0 ? line.length : key.endCharacter === void 0 ? last.end : Math.min(last.end, last.start + key.endCharacter);
@@ -4726,42 +4795,50 @@ function textCommands() {
4726
4795
  const keys = (parsed.values.get("k") ?? []).map(sortKey);
4727
4796
  const simple = !keys.length && !["b", "f", "n"].some((flag) => parsed.flags.has(flag));
4728
4797
  const direction = parsed.flags.has("r") ? -1 : 1;
4729
- let compareNumeric = numericCompare;
4798
+ const work = new SortWork(context.signal);
4799
+ let compareNumeric = async (left, right) => compareNumericValues(await parseNumeric(left, work), await parseNumeric(right, work), work);
4730
4800
  if (!keys.length && parsed.flags.has("n") && !["b", "f", "c"].some((flag) => parsed.flags.has(flag))) {
4731
4801
  const numericValues = /* @__PURE__ */ new Map();
4732
4802
  let retainedBytes = 0;
4733
- const numericValue = (bytes2) => {
4803
+ const numericValue = async (bytes2) => {
4734
4804
  const cached = numericValues.get(bytes2);
4735
4805
  if (cached !== void 0) return cached;
4736
4806
  context.signal.throwIfAborted();
4737
4807
  const charge2 = 6 * bytes2.length + 2;
4738
- if (numericValues.size >= 16384 || charge2 > 1048576 - retainedBytes) return parseNumeric(bytes2);
4739
- const parsedValue = parseNumeric(bytes2);
4808
+ if (numericValues.size >= 16384 || charge2 > 1048576 - retainedBytes) return parseNumeric(bytes2, work);
4809
+ const parsedValue = await parseNumeric(bytes2, work);
4740
4810
  numericValues.set(bytes2, parsedValue);
4741
4811
  retainedBytes += charge2;
4742
4812
  return parsedValue;
4743
4813
  };
4744
- compareNumeric = (left, right) => compareNumericValues(numericValue(left), numericValue(right));
4814
+ compareNumeric = async (left, right) => compareNumericValues(await numericValue(left), await numericValue(right), work);
4745
4815
  }
4746
- let keyCompare = simple ? (left, right) => compareBytes(left, right) * direction : (left, right) => {
4816
+ let keyCompare = async (left, right) => {
4817
+ const checkpoint = work.charge();
4818
+ if (checkpoint) await checkpoint;
4819
+ if (simple) return await compareSortBytes(left, right, work) * direction;
4747
4820
  for (const key of keys.length ? keys : [void 0]) {
4821
+ await work.charge();
4748
4822
  const flags = key?.flags.size ? key.flags : parsed.flags;
4749
- let first = key ? keyBytes(left, key, separator, flags.has("b")) : left;
4750
- let second = key ? keyBytes(right, key, separator, flags.has("b")) : right;
4823
+ let first = key ? await keyBytes(left, key, separator, flags.has("b"), work) : left;
4824
+ let second = key ? await keyBytes(right, key, separator, flags.has("b"), work) : right;
4751
4825
  if (!key && flags.has("b")) {
4752
- const trim = (bytes2) => {
4826
+ const trim = async (bytes2) => {
4753
4827
  let offset = 0;
4754
- while (bytes2[offset] === 9 || bytes2[offset] === 32) offset++;
4828
+ while (bytes2[offset] === 9 || bytes2[offset] === 32) {
4829
+ if (++offset % 1024 === 0) await work.charge(1024);
4830
+ }
4831
+ await work.charge(offset % 1024);
4755
4832
  return bytes2.subarray(offset);
4756
4833
  };
4757
- first = trim(first);
4758
- second = trim(second);
4834
+ first = await trim(first);
4835
+ second = await trim(second);
4759
4836
  }
4760
4837
  if (flags.has("f")) {
4761
- first = fold(first);
4762
- second = fold(second);
4838
+ first = await foldSortBytes(first, work);
4839
+ second = await foldSortBytes(second, work);
4763
4840
  }
4764
- let result = flags.has("n") ? compareNumeric(first, second) : compareBytes(first, second);
4841
+ let result = flags.has("n") ? await compareNumeric(first, second) : await compareSortBytes(first, second, work);
4765
4842
  if (flags.has("r")) result = -result;
4766
4843
  if (result) return result;
4767
4844
  }
@@ -4772,24 +4849,29 @@ function textCommands() {
4772
4849
  if (numericKey && numericKeyFlags.has("n") && !["b", "f"].some((flag) => numericKeyFlags.has(flag)) && !parsed.flags.has("c")) {
4773
4850
  const keyedNumericValues = /* @__PURE__ */ new Map();
4774
4851
  let retainedKeyBytes = 0;
4775
- const keyedNumericValue = (record3) => {
4776
- const cached = keyedNumericValues.get(record3);
4852
+ const keyedNumericValue = async (record4) => {
4853
+ const cached = keyedNumericValues.get(record4);
4777
4854
  if (cached !== void 0) return cached;
4778
4855
  context.signal.throwIfAborted();
4779
- const bytes2 = keyBytes(record3, numericKey, separator, false);
4856
+ const bytes2 = await keyBytes(record4, numericKey, separator, false, work);
4780
4857
  const charge2 = 6 * bytes2.length + 2;
4781
- if (keyedNumericValues.size >= 16384 || charge2 > 1048576 - retainedKeyBytes) return parseNumeric(bytes2);
4782
- const parsedValue = parseNumeric(bytes2);
4783
- keyedNumericValues.set(record3, parsedValue);
4858
+ if (keyedNumericValues.size >= 16384 || charge2 > 1048576 - retainedKeyBytes) return parseNumeric(bytes2, work);
4859
+ const parsedValue = await parseNumeric(bytes2, work);
4860
+ keyedNumericValues.set(record4, parsedValue);
4784
4861
  retainedKeyBytes += charge2;
4785
4862
  return parsedValue;
4786
4863
  };
4787
- keyCompare = (left, right) => {
4788
- const result = compareNumericValues(keyedNumericValue(left), keyedNumericValue(right));
4864
+ keyCompare = async (left, right) => {
4865
+ const checkpoint = work.charge();
4866
+ if (checkpoint) await checkpoint;
4867
+ const result = await compareNumericValues(await keyedNumericValue(left), await keyedNumericValue(right), work);
4789
4868
  return numericKeyFlags.has("r") ? -result : result;
4790
4869
  };
4791
4870
  }
4792
- const compare = simple ? keyCompare : (left, right) => keyCompare(left, right) || (parsed.flags.has("s") || parsed.flags.has("u") ? 0 : compareBytes(left, right) * (parsed.flags.has("r") ? -1 : 1));
4871
+ const compare = async (left, right) => {
4872
+ const result = await keyCompare(left, right);
4873
+ return result || (simple || parsed.flags.has("s") || parsed.flags.has("u") ? 0 : await compareSortBytes(left, right, work) * direction);
4874
+ };
4793
4875
  const records = [];
4794
4876
  let size = 0;
4795
4877
  const exitCode = 0;
@@ -4809,7 +4891,7 @@ function textCommands() {
4809
4891
  context.signal.throwIfAborted();
4810
4892
  size += line.bytes.length + 1;
4811
4893
  if (size > bufferLimit) throw new FsError("EFBIG", { message: "sort buffer limit exceeded" });
4812
- if (parsed.flags.has("c") && records.length && (compare(records.at(-1), line.bytes) > 0 || parsed.flags.has("u") && keyCompare(records.at(-1), line.bytes) === 0)) {
4894
+ if (parsed.flags.has("c") && records.length && (await compare(records.at(-1), line.bytes) > 0 || parsed.flags.has("u") && await keyCompare(records.at(-1), line.bytes) === 0)) {
4813
4895
  await diagnostic(context, new Error(`disorder at record ${records.length + 1}`));
4814
4896
  return { exitCode: 1 };
4815
4897
  }
@@ -4821,18 +4903,18 @@ function textCommands() {
4821
4903
  }
4822
4904
  }
4823
4905
  if (parsed.flags.has("c")) return { exitCode };
4824
- records.sort(compare);
4906
+ const ordered = await sortRecords(records, compare, work);
4825
4907
  const sorted = (async function* () {
4826
4908
  let previous;
4827
4909
  let buffer = new Uint8Array(64 * 1024);
4828
4910
  let used = 0;
4829
- for (const record3 of records) {
4911
+ for (const record4 of ordered) {
4830
4912
  context.signal.throwIfAborted();
4831
- if (parsed.flags.has("u") && previous !== void 0 && keyCompare(previous, record3) === 0) continue;
4913
+ if (parsed.flags.has("u") && previous !== void 0 && await keyCompare(previous, record4) === 0) continue;
4832
4914
  let offset = 0;
4833
- while (offset < record3.length) {
4834
- const length = Math.min(record3.length - offset, buffer.length - used);
4835
- buffer.set(record3.subarray(offset, offset + length), used);
4915
+ while (offset < record4.length) {
4916
+ const length = Math.min(record4.length - offset, buffer.length - used);
4917
+ buffer.set(record4.subarray(offset, offset + length), used);
4836
4918
  offset += length;
4837
4919
  used += length;
4838
4920
  if (used === buffer.length) {
@@ -4847,7 +4929,7 @@ function textCommands() {
4847
4929
  buffer = new Uint8Array(64 * 1024);
4848
4930
  used = 0;
4849
4931
  }
4850
- previous = record3;
4932
+ previous = record4;
4851
4933
  }
4852
4934
  if (used) yield buffer.subarray(0, used);
4853
4935
  })();
@@ -4878,19 +4960,19 @@ function textCommands() {
4878
4960
  let previousKey;
4879
4961
  let count2 = 0;
4880
4962
  const selected = () => (!parsed.flags.has("d") || count2 > 1) && (!parsed.flags.has("u") || count2 === 1);
4881
- const record3 = () => concatenate([...parsed.flags.has("c") ? [encoder2.encode(`${String(count2).padStart(7)} `)] : [], previous, Uint8Array.of(delimiter)]);
4963
+ const record4 = () => concatenate([...parsed.flags.has("c") ? [encoder2.encode(`${String(count2).padStart(7)} `)] : [], previous, Uint8Array.of(delimiter)]);
4882
4964
  for await (const line of lines(input(context, parsed.operands[0]), delimiter)) {
4883
4965
  context.signal.throwIfAborted();
4884
4966
  const currentKey = key(line.bytes);
4885
4967
  if (previousKey && compareBytes(previousKey, currentKey) === 0) count2++;
4886
4968
  else {
4887
- if (previous !== void 0 && selected()) yield record3();
4969
+ if (previous !== void 0 && selected()) yield record4();
4888
4970
  previous = line.bytes;
4889
4971
  previousKey = currentKey;
4890
4972
  count2 = 1;
4891
4973
  }
4892
4974
  }
4893
- if (previous !== void 0 && selected()) yield record3();
4975
+ if (previous !== void 0 && selected()) yield record4();
4894
4976
  })();
4895
4977
  if (parsed.operands[1] !== void 0 && parsed.operands[0] !== "-" && pathOf(context, parsed.operands[0]) === pathOf(context, parsed.operands[1])) throw new UsageError("input and output must be different files");
4896
4978
  await emitRecords(context, records, parsed.operands[1]);
@@ -4923,9 +5005,9 @@ function textCommands() {
4923
5005
  context.signal.throwIfAborted();
4924
5006
  let bytes2;
4925
5007
  if (mode === "f") {
4926
- const record3 = import_buffer.Buffer.from(line.bytes.buffer, line.bytes.byteOffset, line.bytes.byteLength);
5008
+ const record4 = import_buffer.Buffer.from(line.bytes.buffer, line.bytes.byteOffset, line.bytes.byteLength);
4927
5009
  const separator = import_buffer.Buffer.from(delimiter);
4928
- let boundary = record3.indexOf(separator);
5010
+ let boundary = record4.indexOf(separator);
4929
5011
  if (boundary < 0) {
4930
5012
  if (parsed.flags.has("s")) continue;
4931
5013
  bytes2 = line.bytes;
@@ -4938,12 +5020,12 @@ function textCommands() {
4938
5020
  while (true) {
4939
5021
  if (selected(field++)) {
4940
5022
  if (emitted) pieces.push(joiner);
4941
- pieces.push(record3.subarray(start, boundary < 0 ? record3.length : boundary));
5023
+ pieces.push(record4.subarray(start, boundary < 0 ? record4.length : boundary));
4942
5024
  emitted = true;
4943
5025
  }
4944
5026
  if (boundary < 0) break;
4945
5027
  start = boundary + separator.length;
4946
- boundary = record3.indexOf(separator, start);
5028
+ boundary = record4.indexOf(separator, start);
4947
5029
  }
4948
5030
  bytes2 = concatenate(pieces);
4949
5031
  }
@@ -6327,7 +6409,7 @@ var Parser = class {
6327
6409
  this.advance();
6328
6410
  let nodes = 0;
6329
6411
  const grouped = /* @__PURE__ */ new WeakSet();
6330
- const admit = () => {
6412
+ const admit2 = () => {
6331
6413
  if (nodes >= 4096) this.error("Conditional syntax exceeds 4096 nodes");
6332
6414
  nodes++;
6333
6415
  };
@@ -6338,7 +6420,7 @@ var Parser = class {
6338
6420
  const primary = (depth) => {
6339
6421
  if (depth > 64) this.error("Conditional syntax nesting exceeds 64");
6340
6422
  if (this.is("!")) {
6341
- admit();
6423
+ admit2();
6342
6424
  this.advance();
6343
6425
  const expression2 = primary(depth + 1);
6344
6426
  return expression2.kind === "not" && !grouped.has(expression2) ? expression2.operand : { kind: "not", operand: expression2 };
@@ -6350,7 +6432,7 @@ var Parser = class {
6350
6432
  grouped.add(expression2);
6351
6433
  return expression2;
6352
6434
  }
6353
- admit();
6435
+ admit2();
6354
6436
  const first = operand();
6355
6437
  if (conditionalBinary.has(this.current.value)) {
6356
6438
  const operator = this.current.value;
@@ -6365,7 +6447,7 @@ var Parser = class {
6365
6447
  const conjunction = (depth) => {
6366
6448
  let expression2 = primary(depth);
6367
6449
  while (this.is("&&")) {
6368
- admit();
6450
+ admit2();
6369
6451
  this.advance();
6370
6452
  expression2 = { kind: "and", left: expression2, right: primary(depth) };
6371
6453
  }
@@ -6374,7 +6456,7 @@ var Parser = class {
6374
6456
  const disjunction = (depth) => {
6375
6457
  let expression2 = conjunction(depth);
6376
6458
  while (this.is("||")) {
6377
- admit();
6459
+ admit2();
6378
6460
  this.advance();
6379
6461
  expression2 = { kind: "or", left: expression2, right: conjunction(depth) };
6380
6462
  }
@@ -6539,18 +6621,18 @@ var Parser = class {
6539
6621
  return script;
6540
6622
  }
6541
6623
  redirect() {
6542
- let descriptor;
6624
+ let descriptor2;
6543
6625
  if (this.current.kind === "word" && /^\d+$/u.test(this.current.value)) {
6544
6626
  const next = this.peek();
6545
- if (/^(?:>|>>|<|<<|<<-|<<<|>&|<&|>\|)$/u.test(next.value) && this.current.end === next.offset) descriptor = Number(this.advance().value);
6627
+ if (/^(?:>|>>|<|<<|<<-|<<<|>&|<&|>\|)$/u.test(next.value) && this.current.end === next.offset) descriptor2 = Number(this.advance().value);
6546
6628
  }
6547
6629
  if (!/^(?:>|>>|<|<<|<<-|<<<|>&|<&|>\||&>)$/u.test(this.current.value) || this.current.kind !== "operator") return void 0;
6548
6630
  const operator = this.advance().value;
6549
- descriptor ??= operator.startsWith("<") ? 0 : 1;
6550
- if (!Number.isSafeInteger(descriptor) || descriptor > 255) this.error("File descriptor must be between 0 and 255");
6631
+ descriptor2 ??= operator.startsWith("<") ? 0 : 1;
6632
+ if (!Number.isSafeInteger(descriptor2) || descriptor2 > 255) this.error("File descriptor must be between 0 and 255");
6551
6633
  if (!this.current.word) this.error("Expected redirect target");
6552
6634
  const target = this.advance();
6553
- return { descriptor, operator, target: target.word, line: this.lexer.lineAt(Math.max(target.offset, target.end - 1)), ...(operator === "<&" || operator === ">&") && this.lexer.source[target.end - 1] === "-" ? { move: true } : {}, ...target.document ? { document: target.document } : {} };
6635
+ return { descriptor: descriptor2, operator, target: target.word, line: this.lexer.lineAt(Math.max(target.offset, target.end - 1)), ...(operator === "<&" || operator === ">&") && this.lexer.source[target.end - 1] === "-" ? { move: true } : {}, ...target.document ? { document: target.document } : {} };
6554
6636
  }
6555
6637
  };
6556
6638
  function parseShell(source, depth = 0) {
@@ -6599,13 +6681,13 @@ init_platform();
6599
6681
  // packages/safe-bash/src/shell/value-state.ts
6600
6682
  init_platform();
6601
6683
  var ValueArena = class {
6602
- constructor(maximumBytes, maximumSlots, checkpoint, fail = (limit) => {
6684
+ constructor(maximumBytes, maximumSlots, checkpoint, fail2 = (limit) => {
6603
6685
  throw new ShellLimitError(limit);
6604
6686
  }) {
6605
6687
  this.maximumBytes = maximumBytes;
6606
6688
  this.maximumSlots = maximumSlots;
6607
6689
  this.checkpoint = checkpoint;
6608
- this.fail = fail;
6690
+ this.fail = fail2;
6609
6691
  }
6610
6692
  maximumBytes;
6611
6693
  maximumSlots;
@@ -6635,25 +6717,25 @@ var ValueArena = class {
6635
6717
  if (!Number.isSafeInteger(bytes2) || bytes2 < 0 || !Number.isSafeInteger(slots) || slots < 0) throw new RangeError("Invalid shell value allocation");
6636
6718
  if (bytes2 > this.maximumBytes - this.#bytes) this.fail("maxExpansionBytes");
6637
6719
  if (slots > this.maximumSlots - this.#slots) this.fail("maxExpansionFields");
6638
- const record3 = { bytes: bytes2, slots, references: 1 };
6720
+ const record4 = { bytes: bytes2, slots, references: 1 };
6639
6721
  this.#bytes += bytes2;
6640
6722
  this.#slots += slots;
6641
- this.#records.add(record3);
6642
- return record3;
6723
+ this.#records.add(record4);
6724
+ return record4;
6643
6725
  }
6644
- commit(record3, object) {
6726
+ commit(record4, object) {
6645
6727
  this.assertOpen();
6646
- if (!this.#records.has(record3) || record3.object || this.#objects.has(object)) throw new Error("Shell value reservation is not fresh");
6647
- record3.object = object;
6648
- this.#objects.set(object, record3);
6649
- }
6650
- release(record3) {
6651
- if (!this.#records.has(record3)) return;
6652
- if (--record3.references) return;
6653
- this.#records.delete(record3);
6654
- if (record3.object) this.#objects.delete(record3.object);
6655
- this.#bytes -= record3.bytes;
6656
- this.#slots -= record3.slots;
6728
+ if (!this.#records.has(record4) || record4.object || this.#objects.has(object)) throw new Error("Shell value reservation is not fresh");
6729
+ record4.object = object;
6730
+ this.#objects.set(object, record4);
6731
+ }
6732
+ release(record4) {
6733
+ if (!this.#records.has(record4)) return;
6734
+ if (--record4.references) return;
6735
+ this.#records.delete(record4);
6736
+ if (record4.object) this.#objects.delete(record4.object);
6737
+ this.#bytes -= record4.bytes;
6738
+ this.#slots -= record4.slots;
6657
6739
  }
6658
6740
  hold(value2) {
6659
6741
  this.assertOpen();
@@ -6696,7 +6778,7 @@ var ValueArena = class {
6696
6778
  }
6697
6779
  close() {
6698
6780
  this.#closed = true;
6699
- for (const record3 of this.#records) if (record3.object) this.#objects.delete(record3.object);
6781
+ for (const record4 of this.#records) if (record4.object) this.#objects.delete(record4.object);
6700
6782
  this.#records.clear();
6701
6783
  this.#bytes = 0;
6702
6784
  this.#slots = 0;
@@ -6718,19 +6800,19 @@ var ValueScope = class {
6718
6800
  reserve(bytes2, slots) {
6719
6801
  this.assertOpen();
6720
6802
  this.#enrollment ??= this.arena.allocate(64, 1);
6721
- const record3 = this.arena.allocate(bytes2, slots);
6803
+ const record4 = this.arena.allocate(bytes2, slots);
6722
6804
  let released = false;
6723
6805
  const release = () => {
6724
6806
  if (released) return;
6725
6807
  released = true;
6726
6808
  this.#releases.delete(release);
6727
- this.arena.release(record3);
6809
+ this.arena.release(record4);
6728
6810
  };
6729
6811
  this.#releases.add(release);
6730
6812
  return { commit: (value2) => {
6731
6813
  this.assertOpen();
6732
6814
  if (released) throw new Error("Shell value reservation is released");
6733
- this.arena.commit(record3, value2);
6815
+ this.arena.commit(record4, value2);
6734
6816
  }, release };
6735
6817
  }
6736
6818
  hold(value2) {
@@ -6898,28 +6980,28 @@ function positionalTemplate(source, checkpoint) {
6898
6980
  }
6899
6981
  return found;
6900
6982
  }
6901
- function positionalValue(name2, options2) {
6983
+ function positionalValue(name2, options3) {
6902
6984
  let index = 0;
6903
6985
  let outside = false;
6904
6986
  for (let position = 0; position < name2.length; position++) {
6905
- if (position % 128 === 0) options2.checkpoint();
6987
+ if (position % 128 === 0) options3.checkpoint();
6906
6988
  const next = name2.charCodeAt(position) - 48;
6907
- if (index > Math.floor((options2.positional.length - next) / 10)) outside = true;
6989
+ if (index > Math.floor((options3.positional.length - next) / 10)) outside = true;
6908
6990
  if (!outside) index = index * 10 + next;
6909
6991
  }
6910
- return outside ? void 0 : index === 0 ? options2.arg0 : options2.positional[index - 1];
6992
+ return outside ? void 0 : index === 0 ? options3.arg0 : options3.positional[index - 1];
6911
6993
  }
6912
- function evaluatePositionalArithmetic(program, options2, evaluate) {
6994
+ function evaluatePositionalArithmetic(program, options3, evaluate) {
6913
6995
  const source = program.source;
6914
6996
  if (!source.includes("$")) return evaluate(program);
6915
- options2.checkpoint();
6916
- if (!positionalTemplate(source, options2.checkpoint)) return evaluate(program);
6917
- const header = options2.owner?.reserve({ metadata: 128, allocatedSlots: 2, work: source.length * 2 + 8 });
6997
+ options3.checkpoint();
6998
+ if (!positionalTemplate(source, options3.checkpoint)) return evaluate(program);
6999
+ const header = options3.owner?.reserve({ metadata: 128, allocatedSlots: 2, work: source.length * 2 + 8 });
6918
7000
  const admissions = [];
6919
7001
  const chunks = [];
6920
7002
  let bytes2 = 0;
6921
7003
  const reserve = (payload) => {
6922
- const admission = options2.owner?.reserve({ payload, metadata: 64, allocatedSlots: 2, work: 4 });
7004
+ const admission = options3.owner?.reserve({ payload, metadata: 64, allocatedSlots: 2, work: 4 });
6923
7005
  if (admission) admissions.push(admission);
6924
7006
  };
6925
7007
  const length = (text, start, end, maximum) => {
@@ -6927,7 +7009,7 @@ function evaluatePositionalArithmetic(program, options2, evaluate) {
6927
7009
  let nextCheckpoint = start;
6928
7010
  for (let position = start; position < end; ) {
6929
7011
  if (position >= nextCheckpoint) {
6930
- options2.checkpoint();
7012
+ options3.checkpoint();
6931
7013
  nextCheckpoint = position + 128;
6932
7014
  }
6933
7015
  const code = text.charCodeAt(position++);
@@ -6937,14 +7019,14 @@ function evaluatePositionalArithmetic(program, options2, evaluate) {
6937
7019
  size += 4;
6938
7020
  position++;
6939
7021
  } else size += 3;
6940
- if (size > maximum) options2.limit();
7022
+ if (size > maximum) options3.limit();
6941
7023
  }
6942
- options2.owner?.reserve({ work: end - start }).release();
7024
+ options3.owner?.reserve({ work: end - start }).release();
6943
7025
  return size;
6944
7026
  };
6945
7027
  const literal = (start, end) => {
6946
7028
  if (start === end) return;
6947
- const size = length(source, start, end, options2.maximumBytes - bytes2);
7029
+ const size = length(source, start, end, options3.maximumBytes - bytes2);
6948
7030
  reserve(size);
6949
7031
  chunks.push(source.slice(start, end));
6950
7032
  bytes2 += size;
@@ -6954,7 +7036,7 @@ function evaluatePositionalArithmetic(program, options2, evaluate) {
6954
7036
  let nextCheckpoint = 0;
6955
7037
  for (let position = 0; position < source.length; ) {
6956
7038
  if (position >= nextCheckpoint) {
6957
- options2.checkpoint();
7039
+ options3.checkpoint();
6958
7040
  nextCheckpoint = position + 128;
6959
7041
  }
6960
7042
  if (source[position] !== "$") {
@@ -6967,17 +7049,17 @@ function evaluatePositionalArithmetic(program, options2, evaluate) {
6967
7049
  let nameEnd = nameStart + 1;
6968
7050
  if (braced) while (digit(source, nameEnd)) {
6969
7051
  if (nameEnd >= nextCheckpoint) {
6970
- options2.checkpoint();
7052
+ options3.checkpoint();
6971
7053
  nextCheckpoint = nameEnd + 128;
6972
7054
  }
6973
7055
  nameEnd++;
6974
7056
  }
6975
7057
  reserve(nameEnd - nameStart);
6976
7058
  const name2 = source.slice(nameStart, nameEnd);
6977
- const value2 = positionalValue(name2, options2);
6978
- options2.requireParameter(name2, value2);
7059
+ const value2 = positionalValue(name2, options3);
7060
+ options3.requireParameter(name2, value2);
6979
7061
  const text = value2 ?? "";
6980
- const size = length(text, 0, text.length, options2.maximumBytes - bytes2);
7062
+ const size = length(text, 0, text.length, options3.maximumBytes - bytes2);
6981
7063
  reserve(size);
6982
7064
  chunks.push(text);
6983
7065
  bytes2 += size;
@@ -6985,10 +7067,10 @@ function evaluatePositionalArithmetic(program, options2, evaluate) {
6985
7067
  start = position;
6986
7068
  }
6987
7069
  literal(start, source.length);
6988
- options2.checkpoint();
7070
+ options3.checkpoint();
6989
7071
  reserve(bytes2);
6990
7072
  const expanded = chunks.join("");
6991
- options2.checkpoint();
7073
+ options3.checkpoint();
6992
7074
  return evaluate(prepareArithmetic(expanded));
6993
7075
  } finally {
6994
7076
  for (let position = admissions.length - 1; position >= 0; position--) admissions[position].release();
@@ -7522,7 +7604,7 @@ async function* argumentsFrom(source, signal, delimiter, replacement = false) {
7522
7604
  if (quote || escaped) throw new UsageError(quote ? "unmatched quote in input" : "trailing backslash in input");
7523
7605
  if (active) yield current;
7524
7606
  }
7525
- function executionCommands(execute2) {
7607
+ function executionCommands(execute3) {
7526
7608
  return [
7527
7609
  define("env", async (context) => {
7528
7610
  const argumentValues = getCommandArguments(context);
@@ -7573,7 +7655,7 @@ function executionCommands(execute2) {
7573
7655
  stderr: context.stderr,
7574
7656
  ...context.stdinIsDefault === void 0 ? {} : { stdinIsDefault: context.stdinIsDefault }
7575
7657
  });
7576
- return execute2({ ...context, command: parsed.operands[offset], args: childArguments.args, argumentValues: childArguments, env: childEnv, cwd });
7658
+ return execute3({ ...context, command: parsed.operands[offset], args: childArguments.args, argumentValues: childArguments, env: childEnv, cwd });
7577
7659
  }
7578
7660
  for (const name2 of names) await output(context, `${name2}=${env[name2]}${parsed.flags.has("0") ? "\0" : "\n"}`);
7579
7661
  return { exitCode: 0 };
@@ -7613,7 +7695,7 @@ function executionCommands(execute2) {
7613
7695
  const size = encoder2.encode(command2).length + 1 + childArguments.values.reduce((sum, argument) => sum + shellValueByteLength(argument) + 1, 0);
7614
7696
  if (size > maxBytes) throw new UsageError("expanded arguments exceed command size limit");
7615
7697
  if (parsed.flags.has("t")) await writeBytes(context.stderr, encoder2.encode([command2, ...args].map((argument) => /^[A-Za-z0-9_./-]+$/u.test(argument) ? argument : `'${argument.replaceAll("'", "'\\''")}'`).join(" ") + "\n"), context.signal);
7616
- const result = await execute2({ ...context, command: command2, args, argumentValues: childArguments, stdin: emptyInput(), stdinIsDefault: true, env: { ...context.env } });
7698
+ const result = await execute3({ ...context, command: command2, args, argumentValues: childArguments, stdin: emptyInput(), stdinIsDefault: true, env: { ...context.env } });
7617
7699
  executed = true;
7618
7700
  if (result.exitCode === 255) {
7619
7701
  status = 124;
@@ -7770,9 +7852,9 @@ async function validateString(value2, work, optstring = false) {
7770
7852
  else work.addBytes(3);
7771
7853
  }
7772
7854
  }
7773
- async function scanGetopts(state, optstring, args, options2) {
7774
- if (!record2(options2) || typeof options2.reportErrors !== "boolean") throw new GetoptsError("INVALID_INPUT", "Getopts requires explicit diagnostic policy and work controls");
7775
- const work = new ScanWork(options2.work);
7855
+ async function scanGetopts(state, optstring, args, options3) {
7856
+ if (!record2(options3) || typeof options3.reportErrors !== "boolean") throw new GetoptsError("INVALID_INPUT", "Getopts requires explicit diagnostic policy and work controls");
7857
+ const work = new ScanWork(options3.work);
7776
7858
  const original = cloneGetoptsState(state);
7777
7859
  if (!Array.isArray(args)) throw new GetoptsError("INVALID_INPUT", "Getopts requires an argument array");
7778
7860
  if (args.length > work.maxArguments) throw new GetoptsError("ARGUMENT_LIMIT", "Getopts argument limit exceeded");
@@ -7827,7 +7909,7 @@ async function scanGetopts(state, optstring, args, options2) {
7827
7909
  active = attached ? { argument: active.argument, offset } : void 0;
7828
7910
  if (!attached) index++;
7829
7911
  if (specification[code] === -1) {
7830
- return finish("unknown-option", "?", silent ? { kind: "set", value: option } : { kind: "unset" }, !silent && options2.reportErrors ? { kind: "unknown-option", option } : null);
7912
+ return finish("unknown-option", "?", silent ? { kind: "set", value: option } : { kind: "unset" }, !silent && options3.reportErrors ? { kind: "unknown-option", option } : null);
7831
7913
  }
7832
7914
  if (specification[code] === 1) {
7833
7915
  if (attached) {
@@ -7840,7 +7922,7 @@ async function scanGetopts(state, optstring, args, options2) {
7840
7922
  index++;
7841
7923
  return finish("option", option, { kind: "set", value: value2 }, null);
7842
7924
  }
7843
- return finish("missing-argument", silent ? ":" : "?", silent ? { kind: "set", value: option } : { kind: "unset" }, !silent && options2.reportErrors ? { kind: "missing-argument", option } : null);
7925
+ return finish("missing-argument", silent ? ":" : "?", silent ? { kind: "set", value: option } : { kind: "unset" }, !silent && options3.reportErrors ? { kind: "missing-argument", option } : null);
7844
7926
  }
7845
7927
  return finish("option", option, { kind: "unset" }, null);
7846
7928
  }
@@ -8179,17 +8261,17 @@ function throwLocalActivationFailure(state) {
8179
8261
  const failure = localActivationFailure(state);
8180
8262
  if (failure.failed) throw failure.reason;
8181
8263
  }
8182
- function prepareChildCancellation(parent, options2, snapshot, controls) {
8264
+ function prepareChildCancellation(parent, options3, snapshot, controls) {
8183
8265
  const parentState = requireLink(parent);
8184
8266
  throwAdmissionFailure(parentState);
8185
8267
  let localSignal;
8186
- if (options2 !== void 0) {
8187
- if (options2 === null || typeof options2 !== "object" && typeof options2 !== "function") {
8268
+ if (options3 !== void 0) {
8269
+ if (options3 === null || typeof options3 !== "object" && typeof options3 !== "function") {
8188
8270
  return stagedFailure(parentState, new TypeError("Cancellation options must be an object or function"));
8189
8271
  }
8190
8272
  let candidate;
8191
8273
  try {
8192
- candidate = options2.signal;
8274
+ candidate = options3.signal;
8193
8275
  } catch (error) {
8194
8276
  return stagedFailure(parentState, error);
8195
8277
  }
@@ -9154,10 +9236,10 @@ var StateMonitor = class {
9154
9236
  monitor.finish(tickets, name2);
9155
9237
  return result;
9156
9238
  },
9157
- defineProperty(target, key, descriptor) {
9239
+ defineProperty(target, key, descriptor2) {
9158
9240
  const name2 = named ? String(key) : void 0;
9159
9241
  const tickets = monitor.mutation(name2);
9160
- const result = Reflect.defineProperty(target, key, descriptor);
9242
+ const result = Reflect.defineProperty(target, key, descriptor2);
9161
9243
  if (result) monitor.changedValue(target, field, key);
9162
9244
  monitor.finish(tickets, name2);
9163
9245
  return result;
@@ -9954,6 +10036,7 @@ var defaultLimits = {
9954
10036
  maxInputBytes: 32 * 1024 * 1024,
9955
10037
  maxOutputBytes: 16 * 1024 * 1024,
9956
10038
  maxCommands: 1e4,
10039
+ maxRedirects: 64,
9957
10040
  maxPipelineStages: 64,
9958
10041
  maxLoopIterations: 1e4,
9959
10042
  maxSubstitutionDepth: 64,
@@ -10178,12 +10261,21 @@ var Capture = class {
10178
10261
  }
10179
10262
  return bytes2;
10180
10263
  }
10264
+ takeBytes() {
10265
+ const chunk = this.chunks.length === 1 ? this.chunks[0] : void 0;
10266
+ const bytes2 = chunk && chunk.byteLength === chunk.buffer.byteLength ? chunk : this.bytes();
10267
+ this.chunks.length = 0;
10268
+ this.length = 0;
10269
+ this.#tail = void 0;
10270
+ this.#tailLength = 0;
10271
+ return bytes2;
10272
+ }
10181
10273
  };
10182
10274
  var typedSavedVariables = /* @__PURE__ */ new WeakMap();
10183
10275
  var valueScope = /* @__PURE__ */ Symbol("shell value allocation scope");
10184
10276
  var invokedValues = /* @__PURE__ */ new WeakMap();
10185
10277
  function isolateIO(io) {
10186
- return { ...io, ...io.descriptors ? { descriptors: new Map([...io.descriptors].map(([number, descriptor]) => [number, { ...descriptor }])) } : {} };
10278
+ return { ...io, ...io.descriptors ? { descriptors: new Map([...io.descriptors].map(([number, descriptor2]) => [number, { ...descriptor2 }])) } : {} };
10187
10279
  }
10188
10280
  function activeIO(io) {
10189
10281
  const input3 = io.descriptors?.get(0);
@@ -10197,6 +10289,13 @@ function activeIO(io) {
10197
10289
  ...error?.closed && error.output === io.stderr ? { stderr: closedSink } : {}
10198
10290
  };
10199
10291
  }
10292
+ function appendOutputBytes(current, chunk) {
10293
+ const length = current.length + chunk.length;
10294
+ const bytes2 = current.buffer.byteLength - current.byteOffset >= length ? new Uint8Array(current.buffer, current.byteOffset, length) : new Uint8Array(Math.max(length, current.length * 2, 64));
10295
+ if (bytes2.buffer !== current.buffer) bytes2.set(current);
10296
+ bytes2.set(chunk, current.length);
10297
+ return bytes2.subarray(0, length);
10298
+ }
10200
10299
  var Flow = class extends Error {
10201
10300
  constructor(kind, status, levels = 1) {
10202
10301
  super(kind);
@@ -10654,11 +10753,11 @@ var DirectoryStackWork = class {
10654
10753
  await writeText(this.stdout, text);
10655
10754
  this.signal.throwIfAborted();
10656
10755
  }
10657
- async display(cwd, entries, options2, home) {
10756
+ async display(cwd, entries, options3, home) {
10658
10757
  await this.scan(cwd, "path");
10659
- const homeBytes = !options2.long && home !== void 0 ? await this.scan(home, "HOME") : 0;
10660
- const start = options2.index ?? 0;
10661
- const end = options2.index ?? entries.length;
10758
+ const homeBytes = !options3.long && home !== void 0 ? await this.scan(home, "HOME") : 0;
10759
+ const start = options3.index ?? 0;
10760
+ const end = options3.index ?? entries.length;
10662
10761
  for (let index = start; index <= end; index++) {
10663
10762
  await this.charge(1);
10664
10763
  let entry = index === 0 ? cwd : entries[index - 1];
@@ -10676,12 +10775,12 @@ var DirectoryStackWork = class {
10676
10775
  if (entry.length === home.length || entry[home.length] === "/") entry = `~${entry.slice(home.length)}`;
10677
10776
  }
10678
10777
  }
10679
- if (index !== start && !options2.lines && !options2.verbose) await this.emit(" ");
10680
- if (options2.verbose) await this.emit(`${String(index).padStart(2, " ")} `);
10778
+ if (index !== start && !options3.lines && !options3.verbose) await this.emit(" ");
10779
+ if (options3.verbose) await this.emit(`${String(index).padStart(2, " ")} `);
10681
10780
  await this.emit(entry);
10682
- if (options2.lines || options2.verbose) await this.emit("\n");
10781
+ if (options3.lines || options3.verbose) await this.emit("\n");
10683
10782
  }
10684
- if (!options2.lines && !options2.verbose) await this.emit("\n");
10783
+ if (!options3.lines && !options3.verbose) await this.emit("\n");
10685
10784
  await this.flushOutput();
10686
10785
  }
10687
10786
  };
@@ -10739,34 +10838,34 @@ var RuntimeCancellationState = class {
10739
10838
  }
10740
10839
  bind(promise, boundary) {
10741
10840
  if (this.#closed) throw new Error("Cancellation outcome admission is closed");
10742
- const record3 = { promise, boundary, finalized: false, consumed: false };
10743
- this.#records.add(record3);
10744
- return record3;
10841
+ const record4 = { promise, boundary, finalized: false, consumed: false };
10842
+ this.#records.add(record4);
10843
+ return record4;
10745
10844
  }
10746
- finalize(record3, selection) {
10747
- if (record3.consumed || !this.#records.has(record3)) return;
10748
- record3.selection = selection;
10749
- record3.finalized = true;
10845
+ finalize(record4, selection) {
10846
+ if (record4.consumed || !this.#records.has(record4)) return;
10847
+ record4.selection = selection;
10848
+ record4.finalized = true;
10750
10849
  }
10751
10850
  consume(rawReturn, capturedReason) {
10752
- for (const record3 of this.#records) {
10753
- if (record3.promise !== rawReturn) continue;
10754
- record3.consumed = true;
10755
- this.#records.delete(record3);
10756
- const selection = record3.selection;
10757
- if (!record3.finalized || selection?.outcome.kind !== "throw" || !Object.is(selection.outcome.reason, capturedReason)) return void 0;
10851
+ for (const record4 of this.#records) {
10852
+ if (record4.promise !== rawReturn) continue;
10853
+ record4.consumed = true;
10854
+ this.#records.delete(record4);
10855
+ const selection = record4.selection;
10856
+ if (!record4.finalized || selection?.outcome.kind !== "throw" || !Object.is(selection.outcome.reason, capturedReason)) return void 0;
10758
10857
  return selection.report;
10759
10858
  }
10760
10859
  return void 0;
10761
10860
  }
10762
- discard(record3) {
10763
- if (!record3) return;
10764
- record3.consumed = true;
10765
- this.#records.delete(record3);
10861
+ discard(record4) {
10862
+ if (!record4) return;
10863
+ record4.consumed = true;
10864
+ this.#records.delete(record4);
10766
10865
  }
10767
10866
  close() {
10768
10867
  this.#closed = true;
10769
- for (const record3 of this.#records) record3.consumed = true;
10868
+ for (const record4 of this.#records) record4.consumed = true;
10770
10869
  this.#records.clear();
10771
10870
  this.#diagnostics = /* @__PURE__ */ new WeakMap();
10772
10871
  }
@@ -10820,7 +10919,7 @@ var InvocationCancellationOwner = class {
10820
10919
  throw error;
10821
10920
  }
10822
10921
  }
10823
- capture(execute2, frame) {
10922
+ capture(execute3, frame) {
10824
10923
  return new Promise((resolve) => {
10825
10924
  let settled = false;
10826
10925
  let raw;
@@ -10842,7 +10941,7 @@ var InvocationCancellationOwner = class {
10842
10941
  });
10843
10942
  };
10844
10943
  try {
10845
- raw = Promise.resolve(execute2());
10944
+ raw = Promise.resolve(execute3());
10846
10945
  } catch (reason) {
10847
10946
  settle({ kind: "throw", reason });
10848
10947
  return;
@@ -11080,13 +11179,13 @@ var Runtime = class _Runtime {
11080
11179
  }
11081
11180
  );
11082
11181
  }
11083
- invokeChild(options2, state, parent, validate, execute2) {
11182
+ invokeChild(options3, state, parent, validate, execute3) {
11084
11183
  const publicPromise = Promise.resolve().then(async () => {
11085
11184
  if (!this.cancellation.deliverySignal.aborted) parent.assertOpen();
11086
11185
  const childDepth = this.cancellationDepth + 1;
11087
11186
  const prepared = prepareChildCancellation(
11088
11187
  this.cancellation,
11089
- options2,
11188
+ options3,
11090
11189
  this.cancellationAdmission(childDepth)
11091
11190
  );
11092
11191
  this.cancellationOwner?.assertAdmissionOpen();
@@ -11126,7 +11225,7 @@ var Runtime = class _Runtime {
11126
11225
  frame
11127
11226
  );
11128
11227
  let captured;
11129
- const executeChild = () => execute2(runtime, scope);
11228
+ const executeChild = () => execute3(runtime, scope);
11130
11229
  if (owner) captured = await owner.capture(executeChild, frame);
11131
11230
  else {
11132
11231
  try {
@@ -11275,8 +11374,8 @@ var Runtime = class _Runtime {
11275
11374
  if (!typedSavedVariables.has(saved)) await this.prepareVariable(state, name2, saved);
11276
11375
  await owner.ledger.checkpoint(this.signal);
11277
11376
  }
11278
- for (const frame of stateMonitor(state).overlayFrames()) for (const [name2, record3] of frame) {
11279
- const saved = record3;
11377
+ for (const frame of stateMonitor(state).overlayFrames()) for (const [name2, record4] of frame) {
11378
+ const saved = record4;
11280
11379
  if (!saved.superseded && !typedSavedVariables.has(saved)) await this.prepareVariable(state, name2, saved, true);
11281
11380
  await owner.ledger.checkpoint(this.signal);
11282
11381
  }
@@ -11805,7 +11904,7 @@ var Runtime = class _Runtime {
11805
11904
  let io = originalIO;
11806
11905
  let diagnosticFailure;
11807
11906
  try {
11808
- const execute2 = async () => {
11907
+ const execute3 = async () => {
11809
11908
  if (command2.kind === "function") {
11810
11909
  if (state.profile === "sh" && specialBuiltinNames.has(command2.name)) {
11811
11910
  await this.diagnostic(io, `\`${command2.name}': is a special builtin`);
@@ -11958,7 +12057,7 @@ var Runtime = class _Runtime {
11958
12057
  }
11959
12058
  return status2;
11960
12059
  };
11961
- const status = await execute2();
12060
+ const status = await execute3();
11962
12061
  await finishOutputs(status);
11963
12062
  return status;
11964
12063
  } catch (caught) {
@@ -12052,6 +12151,8 @@ var Runtime = class _Runtime {
12052
12151
  return value2;
12053
12152
  }
12054
12153
  async redirect(redirects, state, io, inputs, outputs, isolatedInlineInput = false, persistMoves = false, fileShortcut = false, line) {
12154
+ this.signal.throwIfAborted();
12155
+ if (redirects.length > this.budget.limits.maxRedirects) this.budget.fail("maxRedirects");
12055
12156
  io.descriptors ??= /* @__PURE__ */ new Map([
12056
12157
  [0, { input: io.stdin, ...io.stdinIsDefault === void 0 ? {} : { stdinIsDefault: io.stdinIsDefault } }],
12057
12158
  [1, { output: io.stdout }],
@@ -12072,8 +12173,8 @@ var Runtime = class _Runtime {
12072
12173
  if (io.stdout === closedSink) descriptors.delete(1);
12073
12174
  if (io.stderr === closedSink) descriptors.delete(2);
12074
12175
  const currentIO = () => {
12075
- const descriptor = descriptors.get(0)?.closed ? void 0 : descriptors.get(0);
12076
- const stdinIsDefault = descriptor?.input ? descriptor.stdinIsDefault : false;
12176
+ const descriptor2 = descriptors.get(0)?.closed ? void 0 : descriptors.get(0);
12177
+ const stdinIsDefault = descriptor2?.input ? descriptor2.stdinIsDefault : false;
12077
12178
  return {
12078
12179
  [invocationScope]: io[invocationScope],
12079
12180
  ...io.execution === void 0 ? {} : { execution: io.execution },
@@ -12082,7 +12183,7 @@ var Runtime = class _Runtime {
12082
12183
  ...io.scriptName === void 0 ? {} : { scriptName: io.scriptName },
12083
12184
  ...io.substitutionDiagnosticLine === void 0 ? {} : { substitutionDiagnosticLine: io.substitutionDiagnosticLine },
12084
12185
  ...io.substitutionDiagnosticLines === void 0 ? {} : { substitutionDiagnosticLines: io.substitutionDiagnosticLines },
12085
- stdin: descriptor?.input ?? closedSource,
12186
+ stdin: descriptor2?.input ?? closedSource,
12086
12187
  ...stdinIsDefault === void 0 ? {} : { stdinIsDefault },
12087
12188
  stdout: descriptors.get(1)?.closed ? closedSink : descriptors.get(1)?.output ?? closedSink,
12088
12189
  stderr: descriptors.get(2)?.closed ? closedSink : descriptors.get(2)?.output ?? closedSink,
@@ -12124,20 +12225,20 @@ var Runtime = class _Runtime {
12124
12225
  const move = target.endsWith("-");
12125
12226
  if (move && !redirect.move) throw new Error(`${target}: ambiguous redirect`);
12126
12227
  const sourceDescriptor = Number(move ? target.slice(0, -1) : target);
12127
- const descriptor = descriptors.get(sourceDescriptor);
12128
- if (!descriptor || descriptor.closed || !move && (redirect.operator === "<&" ? !descriptor.input : !descriptor.output)) throw new Error(`${move ? sourceDescriptor : target}: Bad file descriptor`);
12129
- descriptors.set(redirect.descriptor, { ...descriptor });
12228
+ const descriptor2 = descriptors.get(sourceDescriptor);
12229
+ if (!descriptor2 || descriptor2.closed || !move && (redirect.operator === "<&" ? !descriptor2.input : !descriptor2.output)) throw new Error(`${move ? sourceDescriptor : target}: Bad file descriptor`);
12230
+ descriptors.set(redirect.descriptor, { ...descriptor2 });
12130
12231
  if (move && sourceDescriptor !== redirect.descriptor) {
12131
12232
  descriptors.delete(sourceDescriptor);
12132
- if (persistMoves && !replaced.has(sourceDescriptor)) descriptor.closed = true;
12233
+ if (persistMoves && !replaced.has(sourceDescriptor)) descriptor2.closed = true;
12133
12234
  }
12134
12235
  }
12135
12236
  } else {
12136
12237
  const path = resolvePath(state.cwd, target);
12137
- const options2 = { signal: this.signal };
12238
+ const options3 = { signal: this.signal };
12138
12239
  if (redirect.operator === "<") {
12139
- await interruptible(this.fs.access(path, 4, options2), this.signal);
12140
- const stat = await interruptible(this.fs.stat(path, options2), this.signal);
12240
+ await interruptible(this.fs.access(path, 4, options3), this.signal);
12241
+ const stat = await interruptible(this.fs.stat(path, options3), this.signal);
12141
12242
  if (stat.type === "directory" && !fileShortcut) throw new Error(`${target}: Is a directory`);
12142
12243
  const source = stat.type === "directory" ? toByteSource("") : await fileInput(this.fs, path, this.budget.limits.maxInputBytes, this.signal);
12143
12244
  const input3 = new ShellInput(source, this.budget, this.signal);
@@ -12145,7 +12246,7 @@ var Runtime = class _Runtime {
12145
12246
  descriptors.set(redirect.descriptor, { input: input3, stdinIsDefault: false });
12146
12247
  } else {
12147
12248
  const append = redirect.operator === ">>";
12148
- const capabilities = await this.fs.capabilitiesFor?.(path, options2) ?? this.fs.capabilities;
12249
+ const capabilities = await this.fs.capabilitiesFor?.(path, options3) ?? this.fs.capabilities;
12149
12250
  const random = capabilities.randomAccessWrite === true;
12150
12251
  let file;
12151
12252
  await this.fileOperation(path, async () => {
@@ -12158,8 +12259,8 @@ var Runtime = class _Runtime {
12158
12259
  let offset = 0;
12159
12260
  const incremental = async () => {
12160
12261
  await this.fileOperation(path, async () => {
12161
- if (append) await this.fs.appendFile(path, new Uint8Array(), options2);
12162
- else await this.fs.writeFile(path, new Uint8Array(), { ...options2, flag: "w" });
12262
+ if (append) await this.fs.appendFile(path, new Uint8Array(), options3);
12263
+ else await this.fs.writeFile(path, new Uint8Array(), { ...options3, flag: "w" });
12163
12264
  if (!append) file.data = new Uint8Array();
12164
12265
  });
12165
12266
  return { write: (chunk) => {
@@ -12167,22 +12268,27 @@ var Runtime = class _Runtime {
12167
12268
  return this.fileOperation(path, async () => {
12168
12269
  if (closed) throw new Error("Output descriptor is closed");
12169
12270
  const current = file.data;
12170
- if (append) {
12171
- await this.fs.appendFile(path, copy2, options2);
12172
- if (current) {
12173
- const bytes2 = new Uint8Array(current.length + copy2.length);
12174
- bytes2.set(current);
12175
- bytes2.set(copy2, current.length);
12176
- file.data = bytes2;
12271
+ let atEOF = false;
12272
+ if (!append && current && offset === current.length && capabilities.append === true && capabilities.stat !== false) {
12273
+ try {
12274
+ atEOF = (await interruptible(this.fs.stat(path, options3), this.signal)).size === offset;
12275
+ } catch {
12276
+ this.signal.throwIfAborted();
12177
12277
  }
12278
+ this.signal.throwIfAborted();
12279
+ }
12280
+ if (append || atEOF) {
12281
+ const bytes2 = current ? appendOutputBytes(current, copy2) : void 0;
12282
+ await this.fs.appendFile(path, copy2, options3);
12283
+ file.data = bytes2;
12178
12284
  } else {
12179
12285
  const bytes2 = new Uint8Array(Math.max(current?.length ?? 0, offset + copy2.length));
12180
12286
  if (current) bytes2.set(current);
12181
12287
  bytes2.set(copy2, offset);
12182
- await this.fs.writeFile(path, bytes2, options2);
12288
+ await this.fs.writeFile(path, bytes2, options3);
12183
12289
  file.data = bytes2;
12184
- offset += copy2.length;
12185
12290
  }
12291
+ if (!append) offset += copy2.length;
12186
12292
  });
12187
12293
  } };
12188
12294
  };
@@ -12448,8 +12554,8 @@ var Runtime = class _Runtime {
12448
12554
  fs: this.fs,
12449
12555
  signal: this.commandSignal,
12450
12556
  registerCleanup: (cleanup) => scope.register(cleanup),
12451
- invoke: (name3, args, options2) => {
12452
- const invocation = this.invoke(name3, args, options2, context, state, scope);
12557
+ invoke: (name3, args, options3) => {
12558
+ const invocation = this.invoke(name3, args, options3, context, state, scope);
12453
12559
  void invocation.catch(() => void 0);
12454
12560
  return invocation;
12455
12561
  }
@@ -12465,7 +12571,7 @@ var Runtime = class _Runtime {
12465
12571
  });
12466
12572
  return this.observeRuntimeReturn(raw, runtimeFrame, () => downstream);
12467
12573
  });
12468
- const execute2 = composeMiddleware(middleware, (forwarded) => scope.run(async () => {
12574
+ const execute3 = composeMiddleware(middleware, (forwarded) => scope.run(async () => {
12469
12575
  scope.assertOpen();
12470
12576
  const forwardedValues = getCommandArguments(forwarded);
12471
12577
  const admitted = forwardedValues === argumentValues ? argumentValues : this.admitArguments(forwardedValues.values, allocation);
@@ -12678,7 +12784,7 @@ var Runtime = class _Runtime {
12678
12784
  }
12679
12785
  }));
12680
12786
  try {
12681
- return validateExitCode((await interruptible(execute2(context), this.signal)).exitCode);
12787
+ return validateExitCode((await interruptible(execute3(context), this.signal)).exitCode);
12682
12788
  } catch (error) {
12683
12789
  if (builtinFailure && error === builtinFailure.error) throw new ExecutionFailure(error, io, builtinFailure.diagnostic);
12684
12790
  if (runtimeFrame.report && Object.is(runtimeFrame.report.origin.signal.reason, error) && this.outcomeFrame) {
@@ -12812,10 +12918,10 @@ ${functionDisplay(name2, state.functions.get(name2))}`;
12812
12918
  const target = component === void 0 ? name2 : `${component || "."}${component?.endsWith("/") ? "" : "/"}${name2}`;
12813
12919
  const resolved = resolvePath(state.cwd, target);
12814
12920
  try {
12815
- const options2 = { signal: this.signal };
12816
- if ((await interruptible(this.fs.stat(resolved, options2), this.signal)).type !== "file") continue;
12921
+ const options3 = { signal: this.signal };
12922
+ if ((await interruptible(this.fs.stat(resolved, options3), this.signal)).type !== "file") continue;
12817
12923
  if (this.fs.capabilities.permissions !== true) throw new CommandFailure(`${target}: execution permissions are not supported by this filesystem`, 126);
12818
- await interruptible(this.fs.access(resolved, ACCESS_MODES.X_OK, options2), this.signal);
12924
+ await interruptible(this.fs.access(resolved, ACCESS_MODES.X_OK, options3), this.signal);
12819
12925
  matches.push(target);
12820
12926
  if (!all) return matches;
12821
12927
  } catch (error) {
@@ -13039,8 +13145,8 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13039
13145
  stderr: this.budget.sink(incoming.stderr, runtime.signal),
13040
13146
  signal: this.commandSignal,
13041
13147
  registerCleanup: (cleanup) => scope.register(cleanup),
13042
- invoke: (name2, args, options2) => {
13043
- const invocation = invocationOverride.current ? invocationOverride.current(name2, args, options2) : runtime.invoke(name2, args, options2, context, child, scope);
13148
+ invoke: (name2, args, options3) => {
13149
+ const invocation = invocationOverride.current ? invocationOverride.current(name2, args, options3) : runtime.invoke(name2, args, options3, context, child, scope);
13044
13150
  void invocation.catch(() => void 0);
13045
13151
  return invocation;
13046
13152
  }
@@ -13060,7 +13166,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13060
13166
  });
13061
13167
  return runtime.observeRuntimeReturn(raw, runtimeFrame, () => downstream);
13062
13168
  });
13063
- const execute2 = composeMiddleware(middleware, async () => {
13169
+ const execute3 = composeMiddleware(middleware, async () => {
13064
13170
  scope.assertOpen();
13065
13171
  const forwardedValues = getCommandArguments(context);
13066
13172
  const admitted = forwardedValues === argumentValues ? argumentValues : runtime.admitArguments(forwardedValues.values, allocation);
@@ -13071,7 +13177,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13071
13177
  return await runtime.observeRuntimeReturn(raw, runtimeFrame);
13072
13178
  });
13073
13179
  try {
13074
- const result = await interruptible(execute2(context), runtime.signal);
13180
+ const result = await interruptible(execute3(context), runtime.signal);
13075
13181
  runtime.signal.throwIfAborted();
13076
13182
  return validateExitCode(result.exitCode);
13077
13183
  } catch (error) {
@@ -13084,8 +13190,8 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13084
13190
  if (ownsScope) await scope.close();
13085
13191
  }
13086
13192
  }
13087
- shebangTarget(context, state, io, command2, args, options2, target, loadedSource) {
13088
- return this.invokeChild(options2, state, io[invocationScope], () => {
13193
+ shebangTarget(context, state, io, command2, args, options3, target, loadedSource) {
13194
+ return this.invokeChild(options3, state, io[invocationScope], () => {
13089
13195
  this.signal.throwIfAborted();
13090
13196
  io[invocationScope].assertOpen();
13091
13197
  if (typeof command2 !== "string" || command2.includes("\0") || !Array.isArray(args) || args.some((argument) => typeof argument !== "string" || argument.includes("\0"))) {
@@ -13096,14 +13202,14 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13096
13202
  for (const argument of [command2, ...args]) {
13097
13203
  if (import_buffer.Buffer.byteLength(argument) > this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
13098
13204
  }
13099
- }, (runtime, scope) => runtime.shebangTargetScoped(context, state, io, command2, args, options2, target, loadedSource, scope));
13205
+ }, (runtime, scope) => runtime.shebangTargetScoped(context, state, io, command2, args, options3, target, loadedSource, scope));
13100
13206
  }
13101
- async shebangTargetScoped(context, state, io, command2, args, options2, target, loadedSource, scope) {
13207
+ async shebangTargetScoped(context, state, io, command2, args, options3, target, loadedSource, scope) {
13102
13208
  const reserved = command2 === "bash" || command2 === "sh";
13103
13209
  const direct = command2.includes("/");
13104
13210
  const definition = this.commands.get(command2);
13105
13211
  const child = await this.shebangState(context, state);
13106
- child.cwd = resolvePath(context.cwd, options2.cwd ?? ".");
13212
+ child.cwd = resolvePath(context.cwd, options3.cwd ?? ".");
13107
13213
  if (!reserved) {
13108
13214
  if (child.depth >= this.budget.limits.maxSubstitutionDepth) this.budget.fail("maxSubstitutionDepth");
13109
13215
  child.depth++;
@@ -13112,18 +13218,18 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13112
13218
  child.sourceDepth = 0;
13113
13219
  child.locals = [];
13114
13220
  }
13115
- const stdinIsDefault = options2.stdin === void 0 ? context.stdinIsDefault : options2.stdinIsDefault ?? false;
13116
- const argumentValues = getCommandArguments({ args, ...options2.argumentValues ? { argumentValues: options2.argumentValues } : {} });
13221
+ const stdinIsDefault = options3.stdin === void 0 ? context.stdinIsDefault : options3.stdinIsDefault ?? false;
13222
+ const argumentValues = getCommandArguments({ args, ...options3.argumentValues ? { argumentValues: options3.argumentValues } : {} });
13117
13223
  const selected = {
13118
13224
  ...context,
13119
13225
  command: command2,
13120
13226
  args: argumentValues.args,
13121
13227
  argumentValues,
13122
13228
  cwd: child.cwd,
13123
- env: options2.replaceEnv ? { ...options2.env } : { ...context.env, ...options2.env, PWD: child.cwd },
13124
- stdin: options2.stdin ?? context.stdin,
13125
- stdout: options2.stdout ?? context.stdout,
13126
- stderr: options2.stderr ?? context.stderr,
13229
+ env: options3.replaceEnv ? { ...options3.env } : { ...context.env, ...options3.env, PWD: child.cwd },
13230
+ stdin: options3.stdin ?? context.stdin,
13231
+ stdout: options3.stdout ?? context.stdout,
13232
+ stderr: options3.stderr ?? context.stderr,
13127
13233
  ...stdinIsDefault === void 0 ? {} : { stdinIsDefault }
13128
13234
  };
13129
13235
  const exitCode = await this.shebangStage(selected, child, io, async (runtime, forwarded, state2, childIO) => {
@@ -13139,7 +13245,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13139
13245
  await writeText(forwarded.stderr, `env: ${command2}: command not found
13140
13246
  `);
13141
13247
  return { exitCode: 127 };
13142
- }, void 0, options2.stdin !== context.stdin ? options2.stdin : void 0, scope);
13248
+ }, void 0, options3.stdin !== context.stdin ? options3.stdin : void 0, scope);
13143
13249
  return { exitCode };
13144
13250
  }
13145
13251
  async envShebang(context, state, io, optionalArgument, target, args, loadedSource) {
@@ -13160,8 +13266,8 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13160
13266
  let failureReport;
13161
13267
  const result = await interruptible(Promise.resolve(definition.execute({
13162
13268
  ...forwarded,
13163
- invoke: (command2, arguments_, options2) => {
13164
- const raw = forwarded.invoke(command2, arguments_, options2);
13269
+ invoke: (command2, arguments_, options3) => {
13270
+ const raw = forwarded.invoke(command2, arguments_, options3);
13165
13271
  return raw.catch((error) => {
13166
13272
  failed = true;
13167
13273
  failure = error;
@@ -13176,7 +13282,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13176
13282
  throw failure;
13177
13283
  }
13178
13284
  return { exitCode: validateExitCode(result.exitCode) };
13179
- }, (runtime, forwarded, child, childIO) => (command2, arguments_, options2 = {}) => runtime.shebangTarget(forwarded, child, childIO, command2, arguments_, options2, target, loadedSource));
13285
+ }, (runtime, forwarded, child, childIO) => (command2, arguments_, options3 = {}) => runtime.shebangTarget(forwarded, child, childIO, command2, arguments_, options3, target, loadedSource));
13180
13286
  }
13181
13287
  async scriptFile(context, state, io, target, args, direct, errexit = false, loadedSource) {
13182
13288
  if (target === "") throw new CommandFailure(`${context.command}: : No such file or directory`, 127);
@@ -13188,14 +13294,14 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13188
13294
  try {
13189
13295
  if (loadedSource?.path === path) source = loadedSource.source;
13190
13296
  else {
13191
- const options2 = { signal: this.signal };
13192
- const stat = await interruptible(this.fs.stat(path, options2), this.signal);
13297
+ const options3 = { signal: this.signal };
13298
+ const stat = await interruptible(this.fs.stat(path, options3), this.signal);
13193
13299
  if (stat.type !== "file") throw new CommandFailure(`${target}: ${stat.type === "directory" ? "Is a directory" : "not a regular file"}`, 126);
13194
13300
  if (direct && this.fs.capabilities.permissions !== true) throw new CommandFailure(`${target}: execution permissions are not supported by this filesystem`, 126);
13195
- await interruptible(this.fs.access(path, ACCESS_MODES.R_OK | (direct ? ACCESS_MODES.X_OK : 0), options2), this.signal);
13301
+ await interruptible(this.fs.access(path, ACCESS_MODES.R_OK | (direct ? ACCESS_MODES.X_OK : 0), options3), this.signal);
13196
13302
  const maxBytes = this.budget.limits.maxSourceBytes - this.budget.sourceBytes;
13197
13303
  if (stat.size > maxBytes) this.budget.fail("maxSourceBytes");
13198
- const bytes2 = await interruptible(this.fs.readFile(path, { ...options2, maxBytes }), this.signal);
13304
+ const bytes2 = await interruptible(this.fs.readFile(path, { ...options3, maxBytes }), this.signal);
13199
13305
  this.budget.source(bytes2.byteLength);
13200
13306
  source = this.sourceText(bytes2, target);
13201
13307
  }
@@ -13322,7 +13428,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13322
13428
  let target = filename;
13323
13429
  let source;
13324
13430
  try {
13325
- const options2 = { signal: this.signal };
13431
+ const options3 = { signal: this.signal };
13326
13432
  if (filename && !filename.includes("/") && state.variables.PATH) {
13327
13433
  if (import_buffer.Buffer.byteLength(state.variables.PATH) > this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
13328
13434
  const components = state.variables.PATH.split(":");
@@ -13333,8 +13439,8 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13333
13439
  const candidate = `${component || "."}${component.endsWith("/") ? "" : "/"}${filename}`;
13334
13440
  const path2 = resolvePath(state.cwd, candidate);
13335
13441
  try {
13336
- if ((await interruptible(this.fs.stat(path2, options2), this.signal)).type !== "file") continue;
13337
- await interruptible(this.fs.access(path2, ACCESS_MODES.R_OK, options2), this.signal);
13442
+ if ((await interruptible(this.fs.stat(path2, options3), this.signal)).type !== "file") continue;
13443
+ await interruptible(this.fs.access(path2, ACCESS_MODES.R_OK, options3), this.signal);
13338
13444
  target = candidate;
13339
13445
  found = true;
13340
13446
  break;
@@ -13347,13 +13453,13 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13347
13453
  }
13348
13454
  if (!filename) throw new CommandFailure(": No such file or directory", 1);
13349
13455
  const path = resolvePath(state.cwd, target);
13350
- const stat = await interruptible(this.fs.stat(path, options2), this.signal);
13456
+ const stat = await interruptible(this.fs.stat(path, options3), this.signal);
13351
13457
  if (stat.type === "directory") throw new CommandFailure(`${context.command}: ${target}: is a directory`, 1);
13352
13458
  if (stat.type !== "file") throw new CommandFailure(`${target}: not a regular file`, 1);
13353
- await interruptible(this.fs.access(path, ACCESS_MODES.R_OK, options2), this.signal);
13459
+ await interruptible(this.fs.access(path, ACCESS_MODES.R_OK, options3), this.signal);
13354
13460
  const maxBytes = this.budget.limits.maxSourceBytes - this.budget.sourceBytes;
13355
13461
  if (stat.size > maxBytes) this.budget.fail("maxSourceBytes");
13356
- const bytes2 = await interruptible(this.fs.readFile(path, { ...options2, maxBytes }), this.signal);
13462
+ const bytes2 = await interruptible(this.fs.readFile(path, { ...options3, maxBytes }), this.signal);
13357
13463
  this.budget.source(bytes2.byteLength);
13358
13464
  source = this.sourceText(bytes2, target);
13359
13465
  } catch (error) {
@@ -13418,22 +13524,22 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13418
13524
  }
13419
13525
  }
13420
13526
  }
13421
- invoke(name2, args, options2 = {}, context, state, parent) {
13422
- return this.invokeChild(options2, state, parent, () => {
13527
+ invoke(name2, args, options3 = {}, context, state, parent) {
13528
+ return this.invokeChild(options3, state, parent, () => {
13423
13529
  if (typeof name2 !== "string" || name2.includes("\0") || !Array.isArray(args) || args.some((arg) => typeof arg !== "string" || arg.includes("\0"))) {
13424
13530
  throw new TypeError("invoke requires a command and literal string arguments without NUL");
13425
13531
  }
13426
13532
  if (state.depth >= this.budget.limits.maxSubstitutionDepth) this.budget.fail("maxSubstitutionDepth");
13427
- }, (runtime, scope) => runtime.invokeScoped(name2, args, options2, context, state, scope));
13533
+ }, (runtime, scope) => runtime.invokeScoped(name2, args, options3, context, state, scope));
13428
13534
  }
13429
- async invokeScoped(name2, args, options2, context, state, scope) {
13535
+ async invokeScoped(name2, args, options3, context, state, scope) {
13430
13536
  this.signal.throwIfAborted();
13431
13537
  const allocation = this.budget.values.scope();
13432
13538
  scope.register(() => allocation.close());
13433
- const carrier = this.admitArguments(getCommandArguments({ args, ...options2.argumentValues ? { argumentValues: options2.argumentValues } : {} }).values, allocation);
13539
+ const carrier = this.admitArguments(getCommandArguments({ args, ...options3.argumentValues ? { argumentValues: options3.argumentValues } : {} }).values, allocation);
13434
13540
  const child = await cloneState(state, this.signal);
13435
- child.cwd = resolvePath(context.cwd, options2.cwd ?? ".");
13436
- const env = options2.replaceEnv ? { ...options2.env } : { ...context.env, ...options2.env, PWD: child.cwd };
13541
+ child.cwd = resolvePath(context.cwd, options3.cwd ?? ".");
13542
+ const env = options3.replaceEnv ? { ...options3.env } : { ...context.env, ...options3.env, PWD: child.cwd };
13437
13543
  if (guestArrays(child) || Object.keys(env).some((key) => arrayStore(child)?.get(key))) await this.indexedEnvironment(child, env);
13438
13544
  else {
13439
13545
  for (const key of child.exported) delete child.variables[key];
@@ -13449,15 +13555,15 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13449
13555
  child.functionDepth = 0;
13450
13556
  child.sourceDepth = 0;
13451
13557
  child.locals = [];
13452
- const input3 = options2.stdin === void 0 ? void 0 : new ShellInput(options2.stdin, this.budget, this.signal);
13453
- const stdinIsDefault = options2.stdin === void 0 ? context.stdinIsDefault : options2.stdinIsDefault ?? false;
13558
+ const input3 = options3.stdin === void 0 ? void 0 : new ShellInput(options3.stdin, this.budget, this.signal);
13559
+ const stdinIsDefault = options3.stdin === void 0 ? context.stdinIsDefault : options3.stdinIsDefault ?? false;
13454
13560
  const io = {
13455
13561
  ...context,
13456
13562
  [invocationScope]: scope,
13457
13563
  stdin: input3 ?? context.stdin,
13458
13564
  ...stdinIsDefault === void 0 ? {} : { stdinIsDefault },
13459
- stdout: options2.stdout ? this.budget.sink(options2.stdout, this.signal) : context.stdout,
13460
- stderr: options2.stderr ? this.budget.sink(options2.stderr, this.signal) : context.stderr
13565
+ stdout: options3.stdout ? this.budget.sink(options3.stdout, this.signal) : context.stdout,
13566
+ stderr: options3.stderr ? this.budget.sink(options3.stderr, this.signal) : context.stderr
13461
13567
  };
13462
13568
  const command2 = {
13463
13569
  kind: "simple",
@@ -13505,8 +13611,8 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13505
13611
  else if (flag === "o" && position === option.length - 1) {
13506
13612
  const name2 = args[index + 1];
13507
13613
  if (name2 === void 0) {
13508
- const options2 = [["errexit", !!state.errexit], ["nounset", !!state.nounset], ["pipefail", state.pipefail]];
13509
- for (const [name3, active] of options2) await writeText(stdout, enabled ? `${name3} ${active ? "on" : "off"}
13614
+ const options3 = [["errexit", !!state.errexit], ["nounset", !!state.nounset], ["pipefail", state.pipefail]];
13615
+ for (const [name3, active] of options3) await writeText(stdout, enabled ? `${name3} ${active ? "on" : "off"}
13510
13616
  ` : `set ${active ? "-" : "+"}o ${name3}
13511
13617
  `);
13512
13618
  } else {
@@ -13537,7 +13643,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13537
13643
  async letBuiltin(context, state) {
13538
13644
  this.signal.throwIfAborted();
13539
13645
  const { maxExpansionBytes: bytes2, maxExpansionFields: fields } = this.budget.limits;
13540
- const admit = (value3) => {
13646
+ const admit2 = (value3) => {
13541
13647
  if (typeof value3 !== "string" || value3.includes("\0")) throw new CommandFailure("let: arguments must be strings without NUL", 2);
13542
13648
  if (value3.length > bytes2 || import_buffer.Buffer.byteLength(value3) > bytes2) this.budget.fail("maxExpansionBytes");
13543
13649
  };
@@ -13549,10 +13655,10 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13549
13655
  const { args } = context;
13550
13656
  if (!Array.isArray(args)) throw new CommandFailure("let: argument array required", 2);
13551
13657
  if (args.length + 1 > fields) this.budget.fail("maxExpansionFields");
13552
- admit(context.command);
13658
+ admit2(context.command);
13553
13659
  for (let index = 0; index < args.length; index++) {
13554
13660
  this.signal.throwIfAborted();
13555
- admit(args[index]);
13661
+ admit2(args[index]);
13556
13662
  if ((index + 1) % 128 === 0) await checkpoint();
13557
13663
  }
13558
13664
  if (args[0] === "--help") throw new CommandFailure("let: --help: unsupported option", 2);
@@ -13581,7 +13687,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13581
13687
  async getoptsBuiltin(context, state) {
13582
13688
  this.signal.throwIfAborted();
13583
13689
  const { maxExpansionBytes: bytes2, maxExpansionFields: fields } = this.budget.limits;
13584
- const admit = (value2) => {
13690
+ const admit2 = (value2) => {
13585
13691
  if (typeof value2 !== "string") throw new CommandFailure("getopts: arguments must be strings without NUL", 2);
13586
13692
  if (value2.length > bytes2 || import_buffer.Buffer.byteLength(value2) > bytes2) this.budget.fail("maxExpansionBytes");
13587
13693
  if (value2.includes("\0")) throw new CommandFailure("getopts: arguments must be strings without NUL", 2);
@@ -13593,10 +13699,10 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13593
13699
  };
13594
13700
  if (!Array.isArray(context.args)) throw new CommandFailure("getopts: argument array required", 2);
13595
13701
  if (context.args.length + 1 > fields) this.budget.fail("maxExpansionFields");
13596
- admit(context.command);
13702
+ admit2(context.command);
13597
13703
  for (let index = 0; index < context.args.length; index++) {
13598
13704
  this.signal.throwIfAborted();
13599
- admit(context.args[index]);
13705
+ admit2(context.args[index]);
13600
13706
  if ((index + 1) % 128 === 0) await checkpoint();
13601
13707
  }
13602
13708
  const offset = context.args[0] === "--" ? 1 : 0;
@@ -13615,7 +13721,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13615
13721
  if (args.length > fields) this.budget.fail("maxExpansionFields");
13616
13722
  for (let index = 0; index < args.length; index++) {
13617
13723
  this.signal.throwIfAborted();
13618
- admit(args[index]);
13724
+ admit2(args[index]);
13619
13725
  if ((index + 1) % 128 === 0) await checkpoint();
13620
13726
  }
13621
13727
  const maxBytes = saturatedProduct(bytes2, saturatedSum(args.length, 1));
@@ -13976,14 +14082,14 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
13976
14082
  const declarationArgs = [...args];
13977
14083
  let indexedLocal = false;
13978
14084
  if (command2 === "local") {
13979
- const options2 = localDeclarationOptions(declarationArgs, this.signal);
13980
- if (options2.error !== void 0) {
13981
- await writeText(stderr, `local: ${options2.error}: unsupported option
14085
+ const options3 = localDeclarationOptions(declarationArgs, this.signal);
14086
+ if (options3.error !== void 0) {
14087
+ await writeText(stderr, `local: ${options3.error}: unsupported option
13982
14088
  `);
13983
14089
  return 2;
13984
14090
  }
13985
- indexedLocal = options2.indexed;
13986
- declarationArgs.splice(0, options2.offset);
14091
+ indexedLocal = options3.indexed;
14092
+ declarationArgs.splice(0, options3.offset);
13987
14093
  if (indexedLocal && declarationArgs.length === 0) {
13988
14094
  await writeText(stderr, "local: -a requires a variable name\n");
13989
14095
  return 2;
@@ -15178,15 +15284,15 @@ var ShellInput = class _ShellInput {
15178
15284
  return bytes2;
15179
15285
  });
15180
15286
  }
15181
- line(raw, options2) {
15182
- return this.#cursor.consume(this.signal, () => options2 ? this.readBounded(raw, options2) : this.readLine(raw));
15287
+ line(raw, options3) {
15288
+ return this.#cursor.consume(this.signal, () => options3 ? this.readBounded(raw, options3) : this.readLine(raw));
15183
15289
  }
15184
- async readBounded(raw, options2) {
15290
+ async readBounded(raw, options3) {
15185
15291
  const text = new ReadText();
15186
15292
  let characters = 0;
15187
15293
  const escaped = /* @__PURE__ */ new Set();
15188
15294
  const decoder3 = new TextDecoder("utf-8", { fatal: true });
15189
- const delimiter = options2.delimiter ?? 10;
15295
+ const delimiter = options3.delimiter ?? 10;
15190
15296
  let chunk = new Uint8Array();
15191
15297
  let offset = 0;
15192
15298
  let length = 0;
@@ -15194,7 +15300,7 @@ var ShellInput = class _ShellInput {
15194
15300
  let escapedCharacter = false;
15195
15301
  let units = 0;
15196
15302
  let pulls = 0;
15197
- let terminated = options2.count === 0;
15303
+ let terminated = options3.count === 0;
15198
15304
  try {
15199
15305
  while (!terminated) {
15200
15306
  if (offset === chunk.length) {
@@ -15208,7 +15314,7 @@ var ShellInput = class _ShellInput {
15208
15314
  if (!chunk.length) continue;
15209
15315
  }
15210
15316
  const byte = chunk[offset++];
15211
- if (!options2.exact && !escaping && byte === delimiter) {
15317
+ if (!options3.exact && !escaping && byte === delimiter) {
15212
15318
  terminated = true;
15213
15319
  break;
15214
15320
  }
@@ -15238,8 +15344,8 @@ var ShellInput = class _ShellInput {
15238
15344
  characters++;
15239
15345
  decodedCharacters++;
15240
15346
  }
15241
- units += options2.byteCount ? 1 : decodedCharacters;
15242
- if (units === options2.count) terminated = true;
15347
+ units += options3.byteCount ? 1 : decodedCharacters;
15348
+ if (units === options3.count) terminated = true;
15243
15349
  }
15244
15350
  decoder3.decode();
15245
15351
  return { value: text.finish(), escaped, terminated };
@@ -15349,7 +15455,7 @@ var RootInvocationCancellationOwner = class {
15349
15455
  assertAdmissionOpen() {
15350
15456
  if (!this.#admissionOpen) throw new Error("Root cancellation admission is closed");
15351
15457
  }
15352
- capture(execute2) {
15458
+ capture(execute3) {
15353
15459
  return new Promise((resolve) => {
15354
15460
  let settled = false;
15355
15461
  let raw;
@@ -15371,7 +15477,7 @@ var RootInvocationCancellationOwner = class {
15371
15477
  });
15372
15478
  };
15373
15479
  try {
15374
- raw = Promise.resolve(execute2());
15480
+ raw = Promise.resolve(execute3());
15375
15481
  } catch (reason) {
15376
15482
  settle({ kind: "throw", reason });
15377
15483
  return;
@@ -15412,12 +15518,12 @@ var Shell = class {
15412
15518
  #disposed = false;
15413
15519
  #disposal;
15414
15520
  #active = /* @__PURE__ */ new Set();
15415
- constructor(options2) {
15416
- if (!options2?.fs) throw new TypeError("Shell requires an explicit filesystem");
15417
- warnIfHostProcessEnv(options2.env);
15418
- resolveLimits(options2.limits);
15419
- this.#options = { ...options2, cwd: resolvePath("/", options2.cwd ?? "/"), env: { ...options2.env }, limits: { ...options2.limits } };
15420
- this.commands = options2.commands ?? new CommandRegistry();
15521
+ constructor(options3) {
15522
+ if (!options3?.fs) throw new TypeError("Shell requires an explicit filesystem");
15523
+ warnIfHostProcessEnv(options3.env);
15524
+ resolveLimits(options3.limits);
15525
+ this.#options = { ...options3, cwd: resolvePath("/", options3.cwd ?? "/"), env: { ...options3.env }, limits: { ...options3.limits } };
15526
+ this.commands = options3.commands ?? new CommandRegistry();
15421
15527
  }
15422
15528
  use(middleware) {
15423
15529
  if (this.#disposed) throw new Error("Shell is disposed");
@@ -15430,17 +15536,17 @@ var Shell = class {
15430
15536
  if (!middleware || typeof middleware.setup !== "function") throw new TypeError("Expected middleware or shell plugin");
15431
15537
  this.#ready = this.#ready.then(async () => {
15432
15538
  let active = true;
15433
- const admit = () => {
15539
+ const admit2 = () => {
15434
15540
  if (this.#disposed && !active) throw new Error("Shell is disposed");
15435
15541
  };
15436
15542
  const host = {
15437
15543
  commands: this.commands,
15438
15544
  use: (middleware2) => {
15439
- admit();
15545
+ admit2();
15440
15546
  this.#install(middleware2);
15441
15547
  },
15442
15548
  registerFileSystem: (scheme, factory) => {
15443
- admit();
15549
+ admit2();
15444
15550
  this.#registerFileSystem(scheme, factory);
15445
15551
  }
15446
15552
  };
@@ -15454,9 +15560,9 @@ var Shell = class {
15454
15560
  void this.#ready.catch(() => void 0);
15455
15561
  }
15456
15562
  }
15457
- register(command2, options2) {
15563
+ register(command2, options3) {
15458
15564
  if (this.#disposed) throw new Error("Shell is disposed");
15459
- this.commands.register(command2, options2);
15565
+ this.commands.register(command2, options3);
15460
15566
  return this;
15461
15567
  }
15462
15568
  registerFileSystem(scheme, factory) {
@@ -15468,23 +15574,23 @@ var Shell = class {
15468
15574
  if (this.#filesystems.has(scheme)) throw new Error(`Filesystem already registered: ${scheme}`);
15469
15575
  this.#filesystems.set(scheme, factory);
15470
15576
  }
15471
- async createFileSystem(scheme, options2 = {}) {
15577
+ async createFileSystem(scheme, options3 = {}) {
15472
15578
  if (this.#disposed) throw new Error("Shell is disposed");
15473
15579
  await this.#ready;
15474
15580
  const factory = this.#filesystems.get(scheme);
15475
15581
  if (!factory) throw new Error(`Unknown filesystem scheme: ${scheme}`);
15476
- return factory(options2);
15582
+ return factory(options3);
15477
15583
  }
15478
- async exec(source, options2 = {}) {
15584
+ async exec(source, options3 = {}) {
15479
15585
  if (this.#disposed) throw new Error("Shell is disposed");
15480
- warnIfHostProcessEnv(options2.env);
15481
- const budget = new Budget(resolveLimits(this.#options.limits, options2.limits), options2.signal);
15482
- const scope = new InvocationScope(options2.signal);
15586
+ warnIfHostProcessEnv(options3.env);
15587
+ const budget = new Budget(resolveLimits(this.#options.limits, options3.limits), options3.signal);
15588
+ const scope = new InvocationScope(options3.signal);
15483
15589
  const cancellationState = new RuntimeCancellationState();
15484
15590
  const owner = new RootInvocationCancellationOwner(scope);
15485
15591
  const boundary = createRootCancellationLink({
15486
15592
  admission: Runtime.rootCancellationAdmission(budget),
15487
- callerSignal: options2.signal,
15593
+ callerSignal: options3.signal,
15488
15594
  controls: [{ role: "budget-control", signal: budget.controller.signal }]
15489
15595
  });
15490
15596
  try {
@@ -15499,7 +15605,7 @@ var Shell = class {
15499
15605
  this.#active.add(active);
15500
15606
  let captured;
15501
15607
  try {
15502
- captured = await owner.capture(() => this.#execute(source, options2, scope, budget, boundary, cancellationState, owner));
15608
+ captured = await owner.capture(() => this.#execute(source, options3, scope, budget, boundary, cancellationState, owner));
15503
15609
  } finally {
15504
15610
  budget.close();
15505
15611
  await scope.close();
@@ -15511,7 +15617,7 @@ var Shell = class {
15511
15617
  throwCleanupFailures(scope.failures);
15512
15618
  return selection.outcome.value;
15513
15619
  }
15514
- async #execute(source, options2, scope, budget, cancellation, cancellationState, owner) {
15620
+ async #execute(source, options3, scope, budget, cancellation, cancellationState, owner) {
15515
15621
  if (typeof source !== "string") throw new TypeError("Shell source must be a string");
15516
15622
  if (import_buffer.Buffer.byteLength(source) > budget.limits.maxSourceBytes) throw new ShellLimitError("maxSourceBytes");
15517
15623
  budget.source(import_buffer.Buffer.byteLength(source));
@@ -15535,20 +15641,20 @@ var Shell = class {
15535
15641
  const io = {
15536
15642
  [invocationScope]: scope,
15537
15643
  stdin: toByteSource(""),
15538
- stdinIsDefault: options2.stdin === void 0,
15539
- stdout: sink(stdout, options2.stdout),
15540
- stderr: sink(stderr, options2.stderr)
15644
+ stdinIsDefault: options3.stdin === void 0,
15645
+ stdout: sink(stdout, options3.stdout),
15646
+ stderr: sink(stderr, options3.stderr)
15541
15647
  };
15542
15648
  let exitCode;
15543
15649
  let failed = false;
15544
15650
  try {
15545
15651
  try {
15546
- let unit = parseShellUnit(source, 0, byteLocale({ ...this.#options.env, ...options2.env }));
15547
- stdin = new ShellInput(typeof options2.stdin === "string" || options2.stdin instanceof Uint8Array ? toByteSource(options2.stdin) : options2.stdin ?? toByteSource(""), budget);
15652
+ let unit = parseShellUnit(source, 0, byteLocale({ ...this.#options.env, ...options3.env }));
15653
+ stdin = new ShellInput(typeof options3.stdin === "string" || options3.stdin instanceof Uint8Array ? toByteSource(options3.stdin) : options3.stdin ?? toByteSource(""), budget);
15548
15654
  io.stdin = stdin;
15549
15655
  await interruptible(this.#ready, budget.signal);
15550
- const cwd = resolvePath("/", options2.cwd ?? this.#options.cwd ?? "/");
15551
- const variables = Object.assign(/* @__PURE__ */ Object.create(null), this.#options.env, options2.env, { PWD: cwd });
15656
+ const cwd = resolvePath("/", options3.cwd ?? this.#options.cwd ?? "/");
15657
+ const variables = Object.assign(/* @__PURE__ */ Object.create(null), this.#options.env, options3.env, { PWD: cwd });
15552
15658
  for (const [name2, value2] of Object.entries(variables)) {
15553
15659
  if (name2.includes("\0") || name2.includes("=") || typeof value2 !== "string" || value2.includes("\0")) throw new TypeError("Invalid environment entry");
15554
15660
  }
@@ -15575,7 +15681,7 @@ var Shell = class {
15575
15681
  };
15576
15682
  const admission = Runtime.rootCancellationAdmission(budget);
15577
15683
  const runtime = new Runtime(
15578
- options2.fs ?? this.#options.fs,
15684
+ options3.fs ?? this.#options.fs,
15579
15685
  this.commands,
15580
15686
  [...this.#middleware],
15581
15687
  budget,
@@ -15629,8 +15735,8 @@ shell: -c: line ${line}: \`${source.split("\n")[line - 1] ?? ""}'
15629
15735
  });
15630
15736
  else await stdin?.close();
15631
15737
  }
15632
- const stdoutBytes = stdout.bytes();
15633
- const stderrBytes = stderr.bytes();
15738
+ const stdoutBytes = stdout.takeBytes();
15739
+ const stderrBytes = stderr.takeBytes();
15634
15740
  return {
15635
15741
  stdout: new TextDecoder("utf-8", { ignoreBOM: true }).decode(stdoutBytes),
15636
15742
  stderr: new TextDecoder("utf-8", { ignoreBOM: true }).decode(stderrBytes),
@@ -15680,6 +15786,7 @@ var cloudflareWorkerLimits = Object.freeze({
15680
15786
  maxInputBytes: 4 * 1024 * 1024,
15681
15787
  maxOutputBytes: 4 * 1024 * 1024,
15682
15788
  maxCommands: 1e3,
15789
+ maxRedirects: 64,
15683
15790
  maxPipelineStages: 64,
15684
15791
  maxLoopIterations: 1e3,
15685
15792
  maxSubstitutionDepth: 16,
@@ -15761,8 +15868,8 @@ function requestBody(source, signal) {
15761
15868
  }
15762
15869
  });
15763
15870
  }
15764
- function createFetchTransport(options2 = {}) {
15765
- const fetchRequest = options2.fetch ?? globalThis.fetch;
15871
+ function createFetchTransport(options3 = {}) {
15872
+ const fetchRequest = options3.fetch ?? globalThis.fetch;
15766
15873
  if (typeof fetchRequest !== "function") throw new TypeError("Fetch is unavailable");
15767
15874
  return async (input3) => {
15768
15875
  input3.signal.throwIfAborted();
@@ -15829,7 +15936,7 @@ function privateHostname(input3) {
15829
15936
  const [first, second] = octets;
15830
15937
  return first === 10 || first === 127 || first === 0 || first === 169 && second === 254 || first === 192 && second === 168 || first === 172 && second >= 16 && second <= 31;
15831
15938
  }
15832
- function createOriginAuthorizer(allowlist = "*", options2 = {}) {
15939
+ function createOriginAuthorizer(allowlist = "*", options3 = {}) {
15833
15940
  const origins = /* @__PURE__ */ new Set();
15834
15941
  const hosts = /* @__PURE__ */ new Set();
15835
15942
  for (const entry of allowlist === "*" ? [] : allowlist) {
@@ -15849,7 +15956,7 @@ function createOriginAuthorizer(allowlist = "*", options2 = {}) {
15849
15956
  return (request) => {
15850
15957
  const url = new URL(request.url);
15851
15958
  const hostname = url.hostname.toLowerCase().replace(/\.$/u, "");
15852
- if (options2.denyPrivateNetworks && privateHostname(hostname)) return false;
15959
+ if (options3.denyPrivateNetworks && privateHostname(hostname)) return false;
15853
15960
  return allowlist === "*" || origins.has(url.origin) || hosts.has(hostname);
15854
15961
  };
15855
15962
  }
@@ -15899,25 +16006,25 @@ var ExprMatchError = class extends Error {
15899
16006
  function exactObject(value2, keys) {
15900
16007
  return value2 !== null && typeof value2 === "object" && !Array.isArray(value2) && Object.keys(value2).length === keys.length && keys.every((key) => Object.hasOwn(value2, key));
15901
16008
  }
15902
- function validateExprInput(descriptor, rows, signal) {
16009
+ function validateExprInput(descriptor2, rows, signal) {
15903
16010
  signal.throwIfAborted();
15904
16011
  const invalid = () => {
15905
16012
  throw new RegexExecutionError("PROTOCOL", "invalid expr request");
15906
16013
  };
15907
- if (!exactObject(descriptor, ["kind", "pattern", "profile", "limits"]) || descriptor.kind !== "expr-match" || !(descriptor.pattern instanceof Uint8Array) || !["byte", "utf8-scalar"].includes(descriptor.profile)) invalid();
16014
+ if (!exactObject(descriptor2, ["kind", "pattern", "profile", "limits"]) || descriptor2.kind !== "expr-match" || !(descriptor2.pattern instanceof Uint8Array) || !["byte", "utf8-scalar"].includes(descriptor2.profile)) invalid();
15908
16015
  const keys = Object.keys(exprMatchCeilings);
15909
- if (!exactObject(descriptor.limits, keys)) invalid();
16016
+ if (!exactObject(descriptor2.limits, keys)) invalid();
15910
16017
  for (const key of keys) {
15911
- if (!Number.isSafeInteger(descriptor.limits[key]) || descriptor.limits[key] < 1 || descriptor.limits[key] > exprMatchCeilings[key]) invalid();
16018
+ if (!Number.isSafeInteger(descriptor2.limits[key]) || descriptor2.limits[key] < 1 || descriptor2.limits[key] > exprMatchCeilings[key]) invalid();
15912
16019
  }
15913
16020
  if (!Array.isArray(rows) || rows.length !== 1) invalid();
15914
16021
  const row = rows[0];
15915
16022
  if (!exactObject(row, ["bytes", "all", "terminated"]) || !(row.bytes instanceof Uint8Array) || row.all !== false || row.terminated !== false) invalid();
15916
- if (descriptor.pattern.length > descriptor.limits.maxPatternBytes || row.bytes.length > descriptor.limits.maxSubjectBytes) {
16023
+ if (descriptor2.pattern.length > descriptor2.limits.maxPatternBytes || row.bytes.length > descriptor2.limits.maxSubjectBytes) {
15917
16024
  throw new ExprMatchError("limit", "regex input bytes limit exceeded");
15918
16025
  }
15919
16026
  }
15920
- function validateExprReply(value2, id, descriptor, subject, signal) {
16027
+ function validateExprReply(value2, id, descriptor2, subject, signal) {
15921
16028
  signal.throwIfAborted();
15922
16029
  const invalid = () => {
15923
16030
  throw new RegexExecutionError("PROTOCOL", "invalid expr reply");
@@ -15931,13 +16038,13 @@ function validateExprReply(value2, id, descriptor, subject, signal) {
15931
16038
  }
15932
16039
  if (!exactObject(reply, ["id", "operation", "result"])) return invalid();
15933
16040
  const result = reply.result;
15934
- if (!exactObject(result, ["offsetUnit", "matched", "hasCapture", "overall", "capture", "steps"]) || result.offsetUnit !== "byte" || typeof result.matched !== "boolean" || typeof result.hasCapture !== "boolean" || !Number.isSafeInteger(result.steps) || result.steps < 1 || result.steps > descriptor.limits.maxSteps) return invalid();
16041
+ if (!exactObject(result, ["offsetUnit", "matched", "hasCapture", "overall", "capture", "steps"]) || result.offsetUnit !== "byte" || typeof result.matched !== "boolean" || typeof result.hasCapture !== "boolean" || !Number.isSafeInteger(result.steps) || result.steps < 1 || result.steps > descriptor2.limits.maxSteps) return invalid();
15935
16042
  const span = (value3) => {
15936
16043
  if (value3 === null) return null;
15937
16044
  if (!exactObject(value3, ["start", "end"]) || !Number.isSafeInteger(value3.start) || !Number.isSafeInteger(value3.end)) return invalid();
15938
16045
  const start = value3.start, end = value3.end;
15939
16046
  if (start < 0 || end < start || end > subject.length) return invalid();
15940
- if (descriptor.profile === "utf8-scalar") {
16047
+ if (descriptor2.profile === "utf8-scalar") {
15941
16048
  for (const offset of [start, end]) if (offset < subject.length && subject[offset] >= 128 && subject[offset] <= 191) return invalid();
15942
16049
  }
15943
16050
  return { start, end };
@@ -15946,8 +16053,8 @@ function validateExprReply(value2, id, descriptor, subject, signal) {
15946
16053
  if (result.matched !== (overall !== null) || overall && overall.start !== 0 || capture && (!result.hasCapture || !overall || capture.start < overall.start || capture.end > overall.end)) return invalid();
15947
16054
  return { offsetUnit: "byte", matched: result.matched, hasCapture: result.hasCapture, overall, capture, steps: result.steps };
15948
16055
  }
15949
- function policy(options2) {
15950
- const result = { ...defaults, ...options2 };
16056
+ function policy(options3) {
16057
+ const result = { ...defaults, ...options3 };
15951
16058
  for (const key of Object.keys(defaults)) {
15952
16059
  const minimum = key === "maxQueuedRequests" || key === "maxQueuedBytes" ? 0 : 1;
15953
16060
  if (!Number.isSafeInteger(result[key]) || result[key] < minimum) throw new RangeError(`regex ${key} must be a safe integer >= ${minimum}`);
@@ -15957,9 +16064,9 @@ function policy(options2) {
15957
16064
  }
15958
16065
  return Object.freeze(result);
15959
16066
  }
15960
- function inputBytes(descriptor, rows, signal) {
15961
- let total = 128 + (descriptor.kind === "glob" ? descriptor.globOptions.length * 32 : 0);
15962
- for (const pattern of descriptor.patterns) {
16067
+ function inputBytes(descriptor2, rows, signal) {
16068
+ let total = 128 + (descriptor2.kind === "glob" ? descriptor2.globOptions.length * 32 : 0);
16069
+ for (const pattern of descriptor2.patterns) {
15963
16070
  signal.throwIfAborted();
15964
16071
  total += 16 + pattern.length * 2;
15965
16072
  if (!Number.isSafeInteger(total)) throw new RegexExecutionError("QUEUE_EXHAUSTED", "input accounting overflow");
@@ -16004,7 +16111,7 @@ async function awaitRetirements(retirements) {
16004
16111
  if (failures.length === 1) throw failures[0];
16005
16112
  if (failures.length > 1) throw new AggregateError(failures, "regex retirement failed");
16006
16113
  }
16007
- async function withRegexSession(context, executor, execute2) {
16114
+ async function withRegexSession(context, executor, execute3) {
16008
16115
  context.signal.throwIfAborted();
16009
16116
  let session;
16010
16117
  let closing;
@@ -16022,7 +16129,7 @@ async function withRegexSession(context, executor, execute2) {
16022
16129
  context.signal.throwIfAborted();
16023
16130
  if (closing) throw new RegexExecutionError("CLOSED", "invocation is closed");
16024
16131
  session = executor.open(context.signal);
16025
- outcome = { result: await execute2(session) };
16132
+ outcome = { result: await execute3(session) };
16026
16133
  } catch (error) {
16027
16134
  outcome = { error };
16028
16135
  }
@@ -16114,10 +16221,10 @@ var Slot = class {
16114
16221
  }
16115
16222
  };
16116
16223
  var RegexExecutor = class {
16117
- constructor(provider, options2 = defaults) {
16224
+ constructor(provider, options3 = defaults) {
16118
16225
  this.provider = provider;
16119
16226
  if (!provider || typeof provider.createWorker !== "function") throw new TypeError("a bounded regex provider is required");
16120
- this.options = policy(options2);
16227
+ this.options = policy(options3);
16121
16228
  }
16122
16229
  provider;
16123
16230
  options;
@@ -16152,21 +16259,21 @@ var RegexExecutor = class {
16152
16259
  this.slots.delete(slot);
16153
16260
  this.pump();
16154
16261
  }
16155
- request(descriptor, rows, signal, retirements = /* @__PURE__ */ new Set()) {
16262
+ request(descriptor2, rows, signal, retirements = /* @__PURE__ */ new Set()) {
16156
16263
  signal.throwIfAborted();
16157
16264
  if (this.disposed) return Promise.reject(new RegexExecutionError("CLOSED", "executor is disposed"));
16158
- if (descriptor.kind === "expr-match") validateExprInput(descriptor, rows, signal);
16159
- const bytes2 = descriptor.kind === "expr-match" ? 256 + descriptor.pattern.length + rows[0].bytes.length : inputBytes(descriptor, rows, signal);
16265
+ if (descriptor2.kind === "expr-match") validateExprInput(descriptor2, rows, signal);
16266
+ const bytes2 = descriptor2.kind === "expr-match" ? 256 + descriptor2.pattern.length + rows[0].bytes.length : inputBytes(descriptor2, rows, signal);
16160
16267
  const available = this.queue.length === 0 && ([...this.slots].some((slot) => !slot.busy && !slot.retired) || this.slots.size < this.options.maxWorkers);
16161
16268
  if (!available && (this.queue.length >= this.options.maxQueuedRequests || bytes2 > this.options.maxQueuedBytes - this.queuedBytes)) return Promise.reject(new RegexExecutionError("QUEUE_EXHAUSTED", "queued request count or input byte limit exceeded"));
16162
- const ownedDescriptor = descriptor.kind === "expr-match" ? { ...descriptor, pattern: Uint8Array.from(descriptor.pattern), limits: { ...descriptor.limits } } : { ...descriptor, patterns: descriptor.patterns.map((pattern) => {
16269
+ const ownedDescriptor = descriptor2.kind === "expr-match" ? { ...descriptor2, pattern: Uint8Array.from(descriptor2.pattern), limits: { ...descriptor2.limits } } : { ...descriptor2, patterns: descriptor2.patterns.map((pattern) => {
16163
16270
  signal.throwIfAborted();
16164
16271
  return pattern;
16165
16272
  }) };
16166
16273
  if (ownedDescriptor.kind === "glob") {
16167
- const globOptions = ownedDescriptor.globOptions.map((options2) => {
16274
+ const globOptions = ownedDescriptor.globOptions.map((options3) => {
16168
16275
  signal.throwIfAborted();
16169
- return { ...options2 };
16276
+ return { ...options3 };
16170
16277
  });
16171
16278
  Object.assign(ownedDescriptor, { globOptions });
16172
16279
  }
@@ -16284,18 +16391,18 @@ var RegexSession = class {
16284
16391
  retirements = /* @__PURE__ */ new Set();
16285
16392
  controller = new AbortController();
16286
16393
  requestSignal;
16287
- run(descriptor, rows) {
16394
+ run(descriptor2, rows) {
16288
16395
  this.signal.throwIfAborted();
16289
16396
  if (this.closed) throw new RegexExecutionError("CLOSED", "invocation is closed");
16290
- const result = this.executor.request(descriptor, rows, this.requestSignal, this.retirements);
16397
+ const result = this.executor.request(descriptor2, rows, this.requestSignal, this.retirements);
16291
16398
  this.pending.add(result);
16292
16399
  void result.then(() => this.pending.delete(result), () => this.pending.delete(result));
16293
16400
  return result;
16294
16401
  }
16295
- matchExpr(descriptor, subject) {
16402
+ matchExpr(descriptor2, subject) {
16296
16403
  this.signal.throwIfAborted();
16297
16404
  if (this.closed) throw new RegexExecutionError("CLOSED", "invocation is closed");
16298
- const result = this.executor.request(descriptor, [{ bytes: subject, all: false, terminated: false }], this.requestSignal, this.retirements);
16405
+ const result = this.executor.request(descriptor2, [{ bytes: subject, all: false, terminated: false }], this.requestSignal, this.retirements);
16299
16406
  this.pending.add(result);
16300
16407
  void result.then(() => this.pending.delete(result), () => this.pending.delete(result));
16301
16408
  return result;
@@ -16428,10 +16535,10 @@ async function* requiredFileInput(context, requirements, mode, file, maxBytes) {
16428
16535
  var ProgramError = class extends Error {
16429
16536
  };
16430
16537
  var Budget3 = class {
16431
- constructor(context, options2) {
16538
+ constructor(context, options3) {
16432
16539
  this.context = context;
16433
- this.remaining = options2.maxSteps ?? 5e6;
16434
- this.maxBufferBytes = options2.maxBufferBytes ?? 32 * 1024 * 1024;
16540
+ this.remaining = options3.maxSteps ?? 5e6;
16541
+ this.maxBufferBytes = options3.maxBufferBytes ?? 32 * 1024 * 1024;
16435
16542
  for (const value2 of [this.remaining, this.maxBufferBytes]) {
16436
16543
  if (!Number.isSafeInteger(value2) || value2 < 1) throw new ProgramError("limits must be positive safe integers");
16437
16544
  }
@@ -16440,6 +16547,7 @@ var Budget3 = class {
16440
16547
  maxBufferBytes;
16441
16548
  remaining;
16442
16549
  checkpoints = 0;
16550
+ lastYield = monotonicNow();
16443
16551
  step(count2 = 1) {
16444
16552
  this.context.signal.throwIfAborted();
16445
16553
  this.remaining -= count2;
@@ -16450,7 +16558,11 @@ var Budget3 = class {
16450
16558
  return text;
16451
16559
  }
16452
16560
  async checkpoint() {
16453
- if (++this.checkpoints % 256 === 0) await yieldTurn(this.context.signal);
16561
+ this.context.signal.throwIfAborted();
16562
+ if (++this.checkpoints % 256 === 0 || monotonicNow() - this.lastYield >= 25) {
16563
+ await yieldTurn(this.context.signal);
16564
+ this.lastYield = monotonicNow();
16565
+ }
16454
16566
  this.context.signal.throwIfAborted();
16455
16567
  }
16456
16568
  };
@@ -17048,10 +17160,10 @@ async function execute(program, context, files, quiet, budget) {
17048
17160
  following = void 0;
17049
17161
  return next;
17050
17162
  };
17051
- const prepareRecord = async (record3) => {
17052
- if (record3.terminated || files.length < 2) return record3;
17163
+ const prepareRecord = async (record4) => {
17164
+ if (record4.terminated || files.length < 2) return record4;
17053
17165
  const next = await peekNext();
17054
- return !next.done && next.value.fileIndex !== record3.fileIndex ? { ...record3, terminated: true } : record3;
17166
+ return !next.done && next.value.fileIndex !== record4.fileIndex ? { ...record4, terminated: true } : record4;
17055
17167
  };
17056
17168
  let number = 0;
17057
17169
  let hold = "";
@@ -17066,8 +17178,8 @@ async function execute(program, context, files, quiet, budget) {
17066
17178
  while (!current.done) {
17067
17179
  budget.step();
17068
17180
  number++;
17069
- let record3 = await prepareRecord(current.value);
17070
- let pattern = record3.text;
17181
+ let record4 = await prepareRecord(current.value);
17182
+ let pattern = record4.text;
17071
17183
  const appended = [];
17072
17184
  let appendedSize = 0;
17073
17185
  const append = (item) => {
@@ -17079,7 +17191,7 @@ async function execute(program, context, files, quiet, budget) {
17079
17191
  let deleted = false;
17080
17192
  let quit = false;
17081
17193
  let status = 0;
17082
- const print = () => write(context, pattern + (record3.terminated ? "\n" : ""));
17194
+ const print = () => write(context, pattern + (record4.terminated ? "\n" : ""));
17083
17195
  const flush = async () => {
17084
17196
  await assertPathRequirements(context, sedRequirements, ["script-read"], appended.flatMap((item) => item.file === void 0 ? [] : [item.file]));
17085
17197
  if (!quiet && !deleted) await print();
@@ -17140,7 +17252,7 @@ async function execute(program, context, files, quiet, budget) {
17140
17252
  break;
17141
17253
  case "P": {
17142
17254
  const end = pattern.indexOf("\n");
17143
- await write(context, end < 0 ? pattern + (record3.terminated ? "\n" : "") : pattern.slice(0, end + 1));
17255
+ await write(context, end < 0 ? pattern + (record4.terminated ? "\n" : "") : pattern.slice(0, end + 1));
17144
17256
  break;
17145
17257
  }
17146
17258
  case "=":
@@ -17230,9 +17342,16 @@ async function execute(program, context, files, quiet, budget) {
17230
17342
  }
17231
17343
  break;
17232
17344
  }
17233
- case "y":
17234
- pattern = [...pattern].map((character) => instruction.translation.get(character) ?? character).join("");
17345
+ case "y": {
17346
+ budget.step(pattern.length);
17347
+ const translated = import_buffer.Buffer.allocUnsafe(pattern.length);
17348
+ for (let index = 0; index < pattern.length; index++) {
17349
+ if (index % 256 === 0) await budget.checkpoint();
17350
+ translated[index] = (instruction.translation.get(pattern[index]) ?? pattern[index]).charCodeAt(0);
17351
+ }
17352
+ pattern = translated.toString("latin1");
17235
17353
  break;
17354
+ }
17236
17355
  case "b":
17237
17356
  pc = instruction.jump;
17238
17357
  continue;
@@ -17254,9 +17373,9 @@ async function execute(program, context, files, quiet, budget) {
17254
17373
  if (instruction.kind === "N") await flush();
17255
17374
  return { status: 0, quit: false };
17256
17375
  }
17257
- record3 = await prepareRecord(next.value);
17376
+ record4 = await prepareRecord(next.value);
17258
17377
  number++;
17259
- pattern = instruction.kind === "N" ? budget.check(pattern + "\n" + record3.text) : record3.text;
17378
+ pattern = instruction.kind === "N" ? budget.check(pattern + "\n" + record4.text) : record4.text;
17260
17379
  substituted = false;
17261
17380
  break;
17262
17381
  }
@@ -17272,9 +17391,9 @@ async function execute(program, context, files, quiet, budget) {
17272
17391
  await source.return(void 0);
17273
17392
  }
17274
17393
  }
17275
- function sedCommand(options2 = {}) {
17394
+ function sedCommand(options3 = {}) {
17276
17395
  const definition = command("sed", async (context) => {
17277
- const budget = new Budget3(context, options2);
17396
+ const budget = new Budget3(context, options3);
17278
17397
  const sources = [];
17279
17398
  const files = [];
17280
17399
  let quiet = false;
@@ -17370,6 +17489,7 @@ function sedCommand(options2 = {}) {
17370
17489
 
17371
17490
  // packages/safe-bash/src/commands/search/grep.ts
17372
17491
  init_platform();
17492
+ var maxPatternCount = 1024;
17373
17493
  function createGrepCommands(executor) {
17374
17494
  return [{ name: "grep", filesystemRequirements: grepRequirements, execute: (context) => withRegexSession(context, executor, async (session) => {
17375
17495
  try {
@@ -17382,20 +17502,46 @@ function createGrepCommands(executor) {
17382
17502
  const names = parsed.operands.length ? parsed.operands : ["-"];
17383
17503
  const patternFiles = parsed.values.get("f") ?? [];
17384
17504
  const patterns2 = [];
17385
- const addPatterns = (text, file) => {
17386
- if (file && text === "") return;
17387
- const parts = text.split("\n");
17388
- if (parts.length > 1 && parts.at(-1) === "") parts.pop();
17389
- patterns2.push(...parts);
17505
+ let patternCount = 0;
17506
+ let patternBytes = 0;
17507
+ const admit2 = (chunk, atStart) => {
17508
+ context.signal.throwIfAborted();
17509
+ const size = typeof chunk === "string" ? import_buffer.Buffer.byteLength(chunk) : chunk.length;
17510
+ if (size > bufferLimit - patternBytes) throw new UsageError(`pattern byte limit exceeded (${bufferLimit} bytes)`);
17511
+ patternBytes += size;
17512
+ for (let offset = 0; offset < chunk.length; ) {
17513
+ if (atStart && ++patternCount > maxPatternCount) throw new UsageError(`pattern count limit exceeded (${maxPatternCount})`);
17514
+ const newline = typeof chunk === "string" ? chunk.indexOf("\n", offset) : chunk.indexOf(10, offset);
17515
+ if (newline < 0) return false;
17516
+ offset = newline + 1;
17517
+ atStart = true;
17518
+ }
17519
+ return atStart;
17390
17520
  };
17391
- for (const pattern of parsed.values.get("e") ?? []) addPatterns(import_buffer.Buffer.from(pattern).toString("latin1"), false);
17521
+ const addArgument = async (pattern) => {
17522
+ admit2(pattern, true);
17523
+ if (pattern === "") {
17524
+ if (++patternCount > maxPatternCount) throw new UsageError(`pattern count limit exceeded (${maxPatternCount})`);
17525
+ patterns2.push("");
17526
+ } else {
17527
+ for await (const line of lines(toByteSource(pattern))) patterns2.push(import_buffer.Buffer.from(line.bytes).toString("latin1"));
17528
+ }
17529
+ };
17530
+ async function* admitted(source) {
17531
+ let atStart = true;
17532
+ for await (const chunk of source) {
17533
+ atStart = admit2(chunk, atStart);
17534
+ yield chunk;
17535
+ }
17536
+ }
17537
+ for (const pattern of parsed.values.get("e") ?? []) await addArgument(pattern);
17392
17538
  for (const name2 of patternFiles) {
17393
- const source = name2 === "-" ? input(context) : requiredFileInput(context, grepRequirements, "pattern-file", name2, bufferLimit);
17394
- addPatterns(import_buffer.Buffer.from(await collect(source, context.signal)).toString("latin1"), true);
17539
+ const source = name2 === "-" ? input(context) : requiredFileInput(context, grepRequirements, "pattern-file", name2, bufferLimit - patternBytes);
17540
+ for await (const line of lines(admitted(source))) patterns2.push(import_buffer.Buffer.from(line.bytes).toString("latin1"));
17395
17541
  }
17396
- if (positionalPattern !== void 0) addPatterns(import_buffer.Buffer.from(positionalPattern).toString("latin1"), false);
17542
+ if (positionalPattern !== void 0) await addArgument(positionalPattern);
17397
17543
  if (parsed.flags.has("E") && parsed.flags.has("F")) throw new UsageError("conflicting matchers specified");
17398
- const descriptor = {
17544
+ const descriptor2 = {
17399
17545
  kind: "grep",
17400
17546
  patterns: patterns2,
17401
17547
  fixed: parsed.flags.has("F"),
@@ -17404,7 +17550,7 @@ function createGrepCommands(executor) {
17404
17550
  whole: parsed.flags.has("x"),
17405
17551
  word: parsed.flags.has("w")
17406
17552
  };
17407
- await session.run(descriptor, []);
17553
+ await session.run(descriptor2, []);
17408
17554
  const maxCount = value(parsed, "m") === void 0 ? Infinity : integer(value(parsed, "m"));
17409
17555
  const batchSize = Number.isFinite(maxCount) || parsed.flags.has("q") || parsed.flags.has("l") || parsed.flags.has("L") ? 1 : 128;
17410
17556
  const delimiter = parsed.flags.has("z") ? "\0" : "\n";
@@ -17419,7 +17565,7 @@ function createGrepCommands(executor) {
17419
17565
  const available = new AvailableRecords(parsed.flags.has("z") ? 0 : 10, bufferLimit);
17420
17566
  const source = name2 === "-" ? input(context) : requiredFileInput(context, grepRequirements, "file", name2, bufferLimit);
17421
17567
  records: if (maxCount > 0) for await (const batch of available.batches(lines(available.source(source), parsed.flags.has("z") ? 0 : 10), (line) => line.bytes.length, () => batchSize)) {
17422
- const results = await session.run(descriptor, batch.map((line) => ({ bytes: line.bytes, all: parsed.flags.has("o"), terminated: line.terminated })));
17568
+ const results = await session.run(descriptor2, batch.map((line) => ({ bytes: line.bytes, all: parsed.flags.has("o"), terminated: line.terminated })));
17423
17569
  for (let index = 0; index < batch.length; index++) {
17424
17570
  const line = batch[index];
17425
17571
  context.signal.throwIfAborted();
@@ -17839,13 +17985,13 @@ function pathFor(context, path) {
17839
17985
  var OutputClosed = class extends SearchError {
17840
17986
  };
17841
17987
  var Limits = class {
17842
- constructor(context, options2) {
17988
+ constructor(context, options3) {
17843
17989
  this.context = context;
17844
17990
  this.signal = AbortSignal.any([context.signal, this.stopped.signal]);
17845
- this.maxOutputBytes = options2.maxOutputBytes ?? 16 * 1024 * 1024;
17846
- this.maxLineBytes = options2.maxLineBytes ?? 1024 * 1024;
17847
- this.maxFileBytes = options2.maxFileBytes ?? 64 * 1024 * 1024;
17848
- this.maxFiles = options2.maxFiles ?? 1e5;
17991
+ this.maxOutputBytes = options3.maxOutputBytes ?? 16 * 1024 * 1024;
17992
+ this.maxLineBytes = options3.maxLineBytes ?? 1024 * 1024;
17993
+ this.maxFileBytes = options3.maxFileBytes ?? 64 * 1024 * 1024;
17994
+ this.maxFiles = options3.maxFiles ?? 1e5;
17849
17995
  for (const limit of [this.maxOutputBytes, this.maxLineBytes, this.maxFileBytes, this.maxFiles]) {
17850
17996
  if (!Number.isSafeInteger(limit) || limit < 1) throw new SearchError("search limits must be positive safe integers");
17851
17997
  }
@@ -18030,13 +18176,13 @@ async function matchGlobs(globs, candidates, session) {
18030
18176
  bytes2 += size;
18031
18177
  offset++;
18032
18178
  }
18033
- const descriptor = {
18179
+ const descriptor2 = {
18034
18180
  kind: "glob",
18035
18181
  patterns: batch.map((glob) => glob.source),
18036
18182
  globOptions: batch.map((glob) => ({ insensitive: glob.insensitive, literalUnclosedClass: glob.literalUnclosedClass }))
18037
18183
  };
18038
18184
  try {
18039
- results.push(...(await session.run(descriptor, rows)).map((result) => result.length > 0));
18185
+ results.push(...(await session.run(descriptor2, rows)).map((result) => result.length > 0));
18040
18186
  } catch (error) {
18041
18187
  if (error instanceof RegexExecutionError && error.code === "MATCH") throw new SearchError(error.message);
18042
18188
  throw error;
@@ -18235,10 +18381,10 @@ var Walker = class {
18235
18381
  };
18236
18382
 
18237
18383
  // packages/safe-bash/src/commands/search/rg-command.ts
18238
- function selectInput(context, args, options2) {
18384
+ function selectInput(context, args, options3) {
18239
18385
  if (args.paths.length) return { paths: args.paths, implicit: false };
18240
- if (args.mode === "files" || options2.defaultInput === "cwd" || args.patternFiles.includes("-")) return { paths: ["."], implicit: true };
18241
- const stdin = options2.defaultInput === "stdin" || context.stdinIsDefault === false;
18386
+ if (args.mode === "files" || options3.defaultInput === "cwd" || args.patternFiles.includes("-")) return { paths: ["."], implicit: true };
18387
+ const stdin = options3.defaultInput === "stdin" || context.stdinIsDefault === false;
18242
18388
  return { paths: stdin ? ["-"] : ["."], implicit: !stdin };
18243
18389
  }
18244
18390
  async function patterns(context, args) {
@@ -18360,7 +18506,7 @@ async function searchFile(context, args, limits, matcher, printer, target, stdin
18360
18506
  }
18361
18507
  return { found, stats: totals };
18362
18508
  }
18363
- function createRgCommand(executor, options2 = {}) {
18509
+ function createRgCommand(executor, options3 = {}) {
18364
18510
  return {
18365
18511
  name: "rg",
18366
18512
  filesystemRequirements: searchRequirements,
@@ -18371,12 +18517,12 @@ function createRgCommand(executor, options2 = {}) {
18371
18517
  let failed = false;
18372
18518
  let found = false;
18373
18519
  try {
18374
- const limits = new Limits(context, options2);
18520
+ const limits = new Limits(context, options3);
18375
18521
  args = parse2(context.args);
18376
18522
  if (args.mode !== "files" && args.patternFiles.includes("-") && args.paths.includes("-")) {
18377
18523
  throw new SearchError("cannot search stdin while also reading patterns from stdin");
18378
18524
  }
18379
- const selection = selectInput(context, args, options2);
18525
+ const selection = selectInput(context, args, options3);
18380
18526
  const report = async (error) => {
18381
18527
  context.signal.throwIfAborted();
18382
18528
  failed = true;
@@ -18426,16 +18572,16 @@ function createRgCommand(executor, options2 = {}) {
18426
18572
  }
18427
18573
 
18428
18574
  // packages/safe-bash/src/commands/search/portable.ts
18429
- function portableSearchCommands(options2) {
18430
- const executor = new RegexExecutor(options2.provider, options2.regex);
18431
- const commands = [...createGrepCommands(executor), createRgCommand(executor, options2.search), sedCommand(options2.sed)];
18575
+ function portableSearchCommands(options3) {
18576
+ const executor = new RegexExecutor(options3.provider, options3.regex);
18577
+ const commands = [...createGrepCommands(executor), createRgCommand(executor, options3.search), sedCommand(options3.sed)];
18432
18578
  return {
18433
18579
  name: "portable-search-commands",
18434
18580
  setup(host) {
18435
- if (!options2.replace) for (const command2 of commands) {
18581
+ if (!options3.replace) for (const command2 of commands) {
18436
18582
  if (host.commands.has(command2.name)) throw new Error(`Command already registered: ${command2.name}`);
18437
18583
  }
18438
- for (const command2 of commands) host.commands.register(command2, { replace: options2.replace ?? false });
18584
+ for (const command2 of commands) host.commands.register(command2, { replace: options3.replace ?? false });
18439
18585
  },
18440
18586
  dispose: () => executor.dispose()
18441
18587
  };
@@ -18444,6 +18590,281 @@ function portableSearchCommands(options2) {
18444
18590
  // packages/safe-bash/src/commands/regex-execution/public.ts
18445
18591
  init_platform();
18446
18592
 
18593
+ // packages/safe-bash/src/commands/regex-execution/bounded-provider.ts
18594
+ init_platform();
18595
+ var defaults2 = Object.freeze({
18596
+ maxWorkers: 2,
18597
+ maxPatterns: 32,
18598
+ maxPatternBytes: 8192,
18599
+ maxRows: 128,
18600
+ maxInputBytes: 65536,
18601
+ maxResultBytes: 2048,
18602
+ maxWork: 2e6,
18603
+ maxAllocationUnits: 1e6,
18604
+ maxStates: 65536
18605
+ });
18606
+ var ceilings = Object.freeze({
18607
+ maxWorkers: 32,
18608
+ maxPatterns: 128,
18609
+ maxPatternBytes: 65532,
18610
+ maxRows: 4096,
18611
+ maxInputBytes: 1048576,
18612
+ maxResultBytes: 65536,
18613
+ maxWork: 33554432,
18614
+ maxAllocationUnits: 4e6,
18615
+ maxStates: 65536
18616
+ });
18617
+ var typedArrayPrototype2 = Object.getPrototypeOf(Uint8Array.prototype);
18618
+ var byteLength = Object.getOwnPropertyDescriptor(typedArrayPrototype2, "byteLength").get;
18619
+ var byteOffset = Object.getOwnPropertyDescriptor(typedArrayPrototype2, "byteOffset").get;
18620
+ var byteBuffer = Object.getOwnPropertyDescriptor(typedArrayPrototype2, "buffer").get;
18621
+ function fail(kind, message2) {
18622
+ throw new Error(`bounded regex ${kind}: ${message2}`);
18623
+ }
18624
+ function record3(value2, keys, optional = []) {
18625
+ if (value2 === null || typeof value2 !== "object" || Array.isArray(value2)) fail("protocol", "expected a data record");
18626
+ const ownKeys = Reflect.ownKeys(value2);
18627
+ if (ownKeys.length < keys.length || ownKeys.length > keys.length + optional.length || ownKeys.some((key) => typeof key !== "string" || !keys.includes(key) && !optional.includes(key))) fail("protocol", "unexpected data-record fields");
18628
+ for (const key of [...keys, ...optional]) {
18629
+ const property = Object.getOwnPropertyDescriptor(value2, key);
18630
+ if (property === void 0 ? keys.includes(key) : !("value" in property)) fail("protocol", "missing field or accessor");
18631
+ }
18632
+ }
18633
+ function array(value2, limit, label) {
18634
+ if (!Array.isArray(value2)) fail("protocol", `${label} must be an array`);
18635
+ if (value2.length > limit) fail("limit", `${label} count limit exceeded`);
18636
+ const keys = Reflect.ownKeys(value2);
18637
+ if (keys.length !== value2.length + 1) fail("protocol", `${label} must be a dense data array`);
18638
+ for (let index = 0; index < value2.length; index++) {
18639
+ const property = Object.getOwnPropertyDescriptor(value2, index);
18640
+ if (!property || !("value" in property)) fail("protocol", `${label} must be a dense data array`);
18641
+ }
18642
+ }
18643
+ function options2(input3) {
18644
+ const keys = Object.keys(defaults2);
18645
+ try {
18646
+ record3(input3, [], keys);
18647
+ } catch {
18648
+ throw new TypeError("bounded regex options require supported own data fields");
18649
+ }
18650
+ const result = { ...defaults2 };
18651
+ for (const key of keys) {
18652
+ if (!Object.hasOwn(input3, key)) continue;
18653
+ const value2 = input3[key];
18654
+ if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 1 || value2 > ceilings[key]) throw new RangeError(`bounded regex option ${key} is outside its limit`);
18655
+ result[key] = value2;
18656
+ }
18657
+ return Object.freeze(result);
18658
+ }
18659
+ function descriptor(value2, limits) {
18660
+ if (value2 === null || typeof value2 !== "object") fail("protocol", "invalid descriptor");
18661
+ const kind = Object.getOwnPropertyDescriptor(value2, "kind");
18662
+ if (!kind || !("value" in kind)) fail("protocol", "invalid descriptor kind");
18663
+ if (kind.value !== "grep" && kind.value !== "rg") fail("unsupported", "only grep and fixed rg selection descriptors are supported");
18664
+ const flags = kind.value === "grep" ? ["fixed", "extended", "insensitive", "whole", "word"] : ["fixed", "whole", "word", "nullData"];
18665
+ record3(value2, ["kind", "patterns", ...flags, ...kind.value === "rg" ? ["case"] : []]);
18666
+ for (const flag of flags) if (typeof value2[flag] !== "boolean") fail("protocol", `invalid ${flag} flag`);
18667
+ if (kind.value === "rg" && !["sensitive", "insensitive", "smart"].includes(value2.case)) fail("protocol", "invalid case flag");
18668
+ if (value2.word || kind.value === "grep" && value2.insensitive || kind.value === "rg" && value2.case !== "sensitive") fail("unsupported", "only case-sensitive, non-word selection is supported");
18669
+ if (kind.value === "rg" && !value2.fixed) fail("unsupported", "rg regex and Unicode modes are unsupported; use fixed ASCII patterns");
18670
+ array(value2.patterns, limits.maxPatterns, "pattern");
18671
+ let bytes2 = 0;
18672
+ for (let index = 0; index < value2.patterns.length; index++) {
18673
+ const pattern = value2.patterns[index];
18674
+ if (typeof pattern !== "string") fail("protocol", "patterns must be strings");
18675
+ if (pattern.length > limits.maxPatternBytes - bytes2) fail("limit", "aggregate pattern byte limit exceeded");
18676
+ bytes2 += pattern.length;
18677
+ }
18678
+ return value2;
18679
+ }
18680
+ function admit(input3, limits, signal) {
18681
+ record3(input3, ["id", "descriptor", "rows"]);
18682
+ const selected = descriptor(input3.descriptor, limits);
18683
+ array(input3.rows, limits.maxRows, "row");
18684
+ if (input3.rows.length > Math.floor(limits.maxResultBytes / 16)) fail("limit", "result byte limit exceeded");
18685
+ let bytes2 = 0;
18686
+ for (let index = 0; index < input3.rows.length; index++) {
18687
+ const row = input3.rows[index];
18688
+ record3(row, ["bytes", "all", "terminated"], ["directory", "ancestors"]);
18689
+ if (!(row.bytes instanceof Uint8Array) || typeof row.all !== "boolean" || typeof row.terminated !== "boolean" || Object.hasOwn(row, "directory") && typeof row.directory !== "boolean" || Object.hasOwn(row, "ancestors") && typeof row.ancestors !== "boolean") fail("protocol", "invalid row");
18690
+ if (Object.hasOwn(row, "directory") || Object.hasOwn(row, "ancestors")) fail("unsupported", "glob row flags are unsupported");
18691
+ if (row.all) fail("unsupported", "all-match enumeration is unsupported");
18692
+ const length = byteLength.call(row.bytes);
18693
+ if (length > limits.maxInputBytes - bytes2) fail("limit", "aggregate input byte limit exceeded");
18694
+ bytes2 += length;
18695
+ }
18696
+ const ledger = new EreLedger({ maxExpansionBytes: 1048576, maxExpansionFields: 8192 }, {
18697
+ patternBytes: limits.maxPatternBytes + 4,
18698
+ subjectBytes: limits.maxInputBytes,
18699
+ work: limits.maxWork,
18700
+ allocationUnits: limits.maxAllocationUnits,
18701
+ states: limits.maxStates
18702
+ });
18703
+ ledger.charge("allocationUnits", bytes2 + input3.rows.length * 12 + selected.patterns.length * 2 + 16, signal);
18704
+ const patterns2 = [];
18705
+ for (let index = 0; index < selected.patterns.length; index++) patterns2.push(selected.patterns[index]);
18706
+ const ownedDescriptor = selected.kind === "grep" ? { kind: "grep", patterns: patterns2, fixed: selected.fixed, extended: selected.extended, insensitive: selected.insensitive, whole: selected.whole, word: selected.word } : { kind: "rg", patterns: patterns2, fixed: selected.fixed, case: selected.case, whole: selected.whole, word: selected.word, nullData: selected.nullData };
18707
+ const rows = [];
18708
+ for (let index = 0; index < input3.rows.length; index++) {
18709
+ const row = input3.rows[index];
18710
+ const source = new Uint8Array(byteBuffer.call(row.bytes), byteOffset.call(row.bytes), byteLength.call(row.bytes));
18711
+ const copy2 = new Uint8Array(source.length);
18712
+ copy2.set(source);
18713
+ rows.push({ bytes: copy2, all: false, terminated: row.terminated });
18714
+ }
18715
+ return { id: input3.id, descriptor: ownedDescriptor, rows, ledger };
18716
+ }
18717
+ async function admitBre(pattern, ledger, signal) {
18718
+ let bracket = -1;
18719
+ let member = false;
18720
+ let namedClass = false;
18721
+ for (let index = 0; index < pattern.length; index++) {
18722
+ ledger.charge("work", 1, signal);
18723
+ await ledger.checkpoint(signal);
18724
+ const character = pattern[index];
18725
+ if ("\\()+?{}|".includes(character)) fail("unsupported", "BRE escapes, groups and interval/operator extensions are unsupported; use grep -E");
18726
+ if (bracket >= 0) {
18727
+ if (index === bracket + 1 && character === "^") continue;
18728
+ if (namedClass) {
18729
+ if (character === "]" && pattern[index - 1] === ":") namedClass = false;
18730
+ } else if (character === "]" && member) bracket = -1;
18731
+ else if (character === "[" && pattern[index + 1] === ":") namedClass = true;
18732
+ member = true;
18733
+ } else if (character === "[") {
18734
+ bracket = index;
18735
+ member = false;
18736
+ } else if (character === "^" && index !== 0 || character === "$" && index !== pattern.length - 1) {
18737
+ fail("unsupported", "BRE anchors are supported only at record boundaries");
18738
+ } else if (character === "*" && (index === 0 || index === 1 && pattern[0] === "^")) {
18739
+ fail("unsupported", "BRE leading literal star is unsupported; use fixed matching");
18740
+ }
18741
+ }
18742
+ }
18743
+ async function execute2(input3, signal) {
18744
+ const { descriptor: selected, rows, ledger } = input3;
18745
+ const programs2 = [];
18746
+ for (const pattern of selected.patterns) {
18747
+ if (selected.kind === "grep" && !selected.fixed && !selected.extended) await admitBre(pattern, ledger, signal);
18748
+ if (selected.kind === "rg" && !selected.nullData && pattern.includes("\n")) fail("unsupported", "rg multiline matching is unsupported");
18749
+ ledger.charge("allocationUnits", (selected.whole ? 3 : 1) * 3 + 2, signal);
18750
+ const fragments = selected.whole ? [{ text: "^(", literal: false }, { text: pattern, literal: selected.fixed }, { text: ")$", literal: false }] : [{ text: pattern, literal: selected.fixed }];
18751
+ programs2.push(await compileEre(fragments, ledger, signal));
18752
+ }
18753
+ const results = [];
18754
+ for (const row of rows) {
18755
+ ledger.charge("allocationUnits", row.bytes.length * 2 + 2, signal);
18756
+ const characters = [];
18757
+ for (const byte of row.bytes) {
18758
+ ledger.charge("work", 1, signal);
18759
+ if (byte === 0 || byte > 127) fail("unsupported", "subjects require non-NUL ASCII; Unicode and invalid UTF-8 are unsupported");
18760
+ characters.push(String.fromCharCode(byte));
18761
+ await ledger.checkpoint(signal);
18762
+ }
18763
+ const subject = characters.join("");
18764
+ let span;
18765
+ for (const program of programs2) {
18766
+ const match = await matchEre(program, subject, ledger, signal);
18767
+ if (!match.matched) continue;
18768
+ const candidate = match.captures[0];
18769
+ if (selected.kind === "grep") {
18770
+ span = candidate;
18771
+ break;
18772
+ }
18773
+ if (!span || candidate.start < span.start) span = candidate;
18774
+ }
18775
+ signal.throwIfAborted();
18776
+ results.push(span ? new Float64Array([span.start, span.end]) : new Float64Array());
18777
+ }
18778
+ return { id: input3.id, results };
18779
+ }
18780
+ var CooperativeWorker = class {
18781
+ constructor(limits, release) {
18782
+ this.limits = limits;
18783
+ this.release = release;
18784
+ queueMicrotask(() => {
18785
+ if (!this.#closing) this.emit({ ready: true });
18786
+ });
18787
+ }
18788
+ limits;
18789
+ release;
18790
+ #controller = new AbortController();
18791
+ #listeners = /* @__PURE__ */ new Map();
18792
+ #tasks = /* @__PURE__ */ new Set();
18793
+ #busy = false;
18794
+ #closing;
18795
+ on(event, listener) {
18796
+ if (this.#closing) return;
18797
+ let listeners = this.#listeners.get(event);
18798
+ if (!listeners) {
18799
+ listeners = /* @__PURE__ */ new Set();
18800
+ this.#listeners.set(event, listeners);
18801
+ }
18802
+ listeners.add(listener);
18803
+ }
18804
+ off(event, listener) {
18805
+ this.#listeners.get(event)?.delete(listener);
18806
+ }
18807
+ emit(value2) {
18808
+ for (const listener of this.#listeners.get("message") ?? []) listener(value2);
18809
+ }
18810
+ postMessage(input3) {
18811
+ if (this.#closing) throw new Error("bounded regex worker is closed");
18812
+ if (this.#busy) throw new Error("bounded regex worker is busy");
18813
+ const identity = input3 !== null && typeof input3 === "object" ? Object.getOwnPropertyDescriptor(input3, "id") : void 0;
18814
+ if (!identity || !("value" in identity) || !Number.isSafeInteger(identity.value) || identity.value < 1) fail("protocol", "invalid request identity");
18815
+ const id = identity.value;
18816
+ const submitted = Object.getOwnPropertyDescriptor(input3, "descriptor")?.value;
18817
+ const expression = submitted !== null && typeof submitted === "object" && Object.getOwnPropertyDescriptor(submitted, "kind")?.value === "expr-match";
18818
+ let owned;
18819
+ let failure;
18820
+ try {
18821
+ owned = admit(input3, this.limits, this.#controller.signal);
18822
+ } catch (error) {
18823
+ failure = error instanceof Error ? error.message.slice(0, 512) : "bounded regex protocol: request admission failed";
18824
+ }
18825
+ this.#busy = true;
18826
+ const task = Promise.resolve().then(async () => {
18827
+ let reply;
18828
+ try {
18829
+ this.#controller.signal.throwIfAborted();
18830
+ reply = owned ? await execute2(owned, this.#controller.signal) : { id, error: failure };
18831
+ } catch (error) {
18832
+ reply = { id, error: error instanceof Error ? error.message.slice(0, 512) : "bounded regex request failed" };
18833
+ }
18834
+ if (expression && "error" in reply) reply = { id, operation: "expr-match", category: "unsupported", error: reply.error };
18835
+ owned = void 0;
18836
+ this.#busy = false;
18837
+ if (!this.#closing) this.emit(reply);
18838
+ });
18839
+ this.#tasks.add(task);
18840
+ void task.then(() => this.#tasks.delete(task), () => this.#tasks.delete(task));
18841
+ }
18842
+ terminate() {
18843
+ if (!this.#closing) {
18844
+ this.#closing = Promise.allSettled([...this.#tasks]).then(() => {
18845
+ this.#listeners.clear();
18846
+ this.#tasks.clear();
18847
+ this.release();
18848
+ });
18849
+ this.#controller.abort(new Error("bounded regex worker terminated"));
18850
+ }
18851
+ return this.#closing;
18852
+ }
18853
+ };
18854
+ function createBoundedRegexProvider(input3 = {}) {
18855
+ const limits = options2(input3);
18856
+ let active = 0;
18857
+ return Object.freeze({
18858
+ createWorker() {
18859
+ if (active >= limits.maxWorkers) fail("limit", "worker count limit exceeded");
18860
+ active++;
18861
+ return new CooperativeWorker(limits, () => {
18862
+ active--;
18863
+ });
18864
+ }
18865
+ });
18866
+ }
18867
+
18447
18868
  // packages/safe-bash/src/browser.ts
18448
18869
  function createBrowserCommands() {
18449
18870
  return [
@@ -18454,17 +18875,17 @@ function createBrowserCommands() {
18454
18875
  ...textCommands()
18455
18876
  ];
18456
18877
  }
18457
- function browserCommands(options2 = {}) {
18878
+ function browserCommands(options3 = {}) {
18458
18879
  return {
18459
18880
  name: "browser-commands",
18460
18881
  setup(host) {
18461
18882
  const commands = createBrowserCommands();
18462
- if (!options2.replace) {
18883
+ if (!options3.replace) {
18463
18884
  for (const command2 of commands) {
18464
18885
  if (host.commands.has(command2.name)) throw new Error(`Command already registered: ${command2.name}`);
18465
18886
  }
18466
18887
  }
18467
- for (const command2 of commands) host.commands.register(command2, { replace: options2.replace ?? false });
18888
+ for (const command2 of commands) host.commands.register(command2, { replace: options3.replace ?? false });
18468
18889
  }
18469
18890
  };
18470
18891
  }
@@ -18495,6 +18916,7 @@ export {
18495
18916
  collectText,
18496
18917
  compileEre,
18497
18918
  composeMiddleware,
18919
+ createBoundedRegexProvider,
18498
18920
  createBrowserCommands,
18499
18921
  createBytePipe,
18500
18922
  createCommandArguments,