@poe-platform/safe-bash 0.1.435 → 0.1.438

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.
@@ -9317,6 +9317,39 @@ function throwCleanupFailures(failures) {
9317
9317
 
9318
9318
  // packages/safe-bash/src/shell/getopts.ts
9319
9319
  init_platform();
9320
+ var ownedInputs = /* @__PURE__ */ new WeakMap();
9321
+ function getoptsInputAllocationSize(argumentsCount) {
9322
+ return { bytes: 256 + argumentsCount * 8, slots: argumentsCount + 2 };
9323
+ }
9324
+ async function createGetoptsInput(args, allocation, controls2) {
9325
+ const work = new ScanWork(controls2);
9326
+ if (!Array.isArray(args)) throw new GetoptsError("INVALID_INPUT", "Getopts requires an argument array");
9327
+ const length = args.length;
9328
+ if (length > work.maxArguments) throw new GetoptsError("ARGUMENT_LIMIT", "Getopts argument limit exceeded");
9329
+ const size = getoptsInputAllocationSize(length);
9330
+ const reservation = allocation?.reserve(size.bytes, size.slots);
9331
+ try {
9332
+ const snapshot = [];
9333
+ for (let index = 0; index < length; index++) {
9334
+ const waiting = work.step();
9335
+ if (waiting) await waiting;
9336
+ snapshot.push(args[index]);
9337
+ }
9338
+ await work.flush();
9339
+ if (args.length !== length) throw new GetoptsError("INVALID_INPUT", "Getopts argument extent changed during admission");
9340
+ const input3 = Object.freeze({ args: Object.freeze(snapshot) });
9341
+ reservation?.commit(input3);
9342
+ ownedInputs.set(input3, {});
9343
+ return input3;
9344
+ } catch (error) {
9345
+ try {
9346
+ reservation?.release();
9347
+ } catch (cleanup) {
9348
+ throw new AggregateError([error, cleanup], "Getopts input allocation and release failed");
9349
+ }
9350
+ throw error;
9351
+ }
9352
+ }
9320
9353
  var GetoptsError = class extends Error {
9321
9354
  constructor(code, message3) {
9322
9355
  super(message3);
@@ -9381,6 +9414,9 @@ var ScanWork = class {
9381
9414
  check() {
9382
9415
  this.signal?.throwIfAborted();
9383
9416
  }
9417
+ get inputBytes() {
9418
+ return this.bytes;
9419
+ }
9384
9420
  step() {
9385
9421
  this.check();
9386
9422
  if (this.steps === this.maxSteps) throw new GetoptsError("STEP_LIMIT", "Getopts work step limit exceeded");
@@ -9437,19 +9473,25 @@ async function validateString(value2, work, optstring = false) {
9437
9473
  else work.addBytes(3);
9438
9474
  }
9439
9475
  }
9440
- async function scanGetopts(state, optstring, args, options3) {
9476
+ async function scanGetopts(state, optstring, input3, options3) {
9441
9477
  if (!record2(options3) || typeof options3.reportErrors !== "boolean") throw new GetoptsError("INVALID_INPUT", "Getopts requires explicit diagnostic policy and work controls");
9442
9478
  const work = new ScanWork(options3.work);
9443
9479
  const original = cloneGetoptsState(state);
9480
+ const owned = ownedInputs.get(input3);
9481
+ const args = owned ? input3.args : input3;
9444
9482
  if (!Array.isArray(args)) throw new GetoptsError("INVALID_INPUT", "Getopts requires an argument array");
9445
9483
  if (args.length > work.maxArguments) throw new GetoptsError("ARGUMENT_LIMIT", "Getopts argument limit exceeded");
9446
9484
  const starting = work.step();
9447
9485
  if (starting) await starting;
9448
9486
  await validateString(optstring, work, true);
9449
- for (let argument2 = 0; argument2 < args.length; argument2++) {
9450
- const waiting = work.step();
9451
- if (waiting) await waiting;
9452
- await validateString(args[argument2], work);
9487
+ const specificationBytes = work.inputBytes;
9488
+ if (owned?.bytes !== void 0) work.addBytes(owned.bytes);
9489
+ else {
9490
+ for (let argument2 = 0; argument2 < args.length; argument2++) {
9491
+ const waiting = work.step();
9492
+ if (waiting) await waiting;
9493
+ await validateString(args[argument2], work);
9494
+ }
9453
9495
  }
9454
9496
  const silent = optstring.startsWith(":");
9455
9497
  const specification = new Int8Array(128).fill(-1);
@@ -9465,6 +9507,7 @@ async function scanGetopts(state, optstring, args, options3) {
9465
9507
  const waiting = work.step();
9466
9508
  if (waiting) await waiting;
9467
9509
  await work.flush();
9510
+ if (owned) owned.bytes = work.inputBytes - specificationBytes;
9468
9511
  return { state: active === void 0 ? { index } : { index, active: { ...active } }, kind, status: kind === "end" ? 1 : 0, option: option2, optind: index, argument: argument2, diagnostic: diagnostic4 };
9469
9512
  };
9470
9513
  const end = () => {
@@ -10632,20 +10675,45 @@ var StateMonitor = class {
10632
10675
  #restorations;
10633
10676
  #overlays;
10634
10677
  #retireCleanup;
10678
+ #positionalRevision = {};
10679
+ #getoptsInput;
10635
10680
  closeValues() {
10636
10681
  this.values.close();
10637
10682
  this.positionals.close();
10683
+ this.invalidateGetoptsInput();
10638
10684
  this.#retireCleanup?.();
10639
10685
  this.#retireCleanup = void 0;
10640
10686
  }
10687
+ get positionalRevision() {
10688
+ return this.#positionalRevision;
10689
+ }
10690
+ get getoptsInput() {
10691
+ return this.#getoptsInput?.input;
10692
+ }
10693
+ retainGetoptsInput(revision, input3, allocation) {
10694
+ this.session.scope.assertOpen();
10695
+ if (revision !== this.#positionalRevision) return false;
10696
+ this.#getoptsInput?.allocation.close();
10697
+ this.#getoptsInput = { input: input3, allocation };
10698
+ return true;
10699
+ }
10700
+ invalidateGetoptsInput() {
10701
+ this.#getoptsInput?.allocation.close();
10702
+ this.#getoptsInput = void 0;
10703
+ this.#positionalRevision = {};
10704
+ }
10641
10705
  changedValue(target, field, key) {
10642
10706
  if (field === "state") {
10643
10707
  if (key === "variables") this.values.invalidate();
10644
- if (key === "positional") this.positionals.invalidate();
10708
+ if (key === "positional") {
10709
+ this.positionals.invalidate();
10710
+ this.invalidateGetoptsInput();
10711
+ }
10645
10712
  } else if (field === "variables" && (this.raw.variables === target || this.raw.variables === this.#wrapped.get(target))) {
10646
10713
  this.values.invalidate(String(key));
10647
10714
  } else if (field === "positional" && (this.raw.positional === target || this.raw.positional === this.#wrapped.get(target))) {
10648
10715
  this.positionals.invalidate();
10716
+ this.invalidateGetoptsInput();
10649
10717
  }
10650
10718
  }
10651
10719
  internalOwner() {
@@ -15520,26 +15588,49 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
15520
15588
  }
15521
15589
  const optstring = context2.args[offset];
15522
15590
  const name2 = context2.args[offset + 1];
15523
- const args = context2.args.length > offset + 2 ? context2.args.slice(offset + 2) : state.positional;
15524
- if (args.length > fields2) this.budget.fail("maxExpansionFields");
15525
- for (let index = 0; index < args.length; index++) {
15526
- this.signal.throwIfAborted();
15527
- admit2(args[index]);
15528
- if ((index + 1) % 128 === 0) await checkpoint();
15529
- }
15530
- const maxBytes = saturatedProduct(bytes3, saturatedSum(args.length, 1));
15531
- const maxSteps = saturatedSum(saturatedProduct(maxBytes, 2), saturatedSum(args.length, 2));
15532
- state.getopts ??= cloneGetoptsBinding(state);
15591
+ const explicit = context2.args.length > offset + 2;
15592
+ const monitor = explicit ? void 0 : stateMonitor(state);
15593
+ const revision = monitor?.positionalRevision;
15594
+ const supplied = explicit ? context2.args.slice(offset + 2) : state.positional;
15595
+ if (supplied.length > fields2) this.budget.fail("maxExpansionFields");
15596
+ const maxBytes = saturatedProduct(bytes3, saturatedSum(supplied.length, 1));
15597
+ const maxSteps = saturatedSum(saturatedProduct(maxBytes, 2), saturatedSum(supplied.length, 2));
15598
+ const work = { maxArguments: fields2, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint };
15599
+ let input3 = monitor?.getoptsInput;
15600
+ let allocation;
15533
15601
  let result2;
15534
15602
  try {
15535
- result2 = await scanGetopts(state.getopts.cursor, optstring, args, {
15536
- reportErrors: state.variables.OPTERR === void 0 || state.variables.OPTERR === "" || decimalIndex(state.variables.OPTERR) !== 0,
15537
- work: { maxArguments: fields2, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint }
15538
- });
15539
- } catch (error) {
15603
+ if (!input3 && monitor) {
15604
+ const size = getoptsInputAllocationSize(supplied.length);
15605
+ const arena = this.budget.values;
15606
+ const usage2 = arena.usage;
15607
+ if (size.bytes + 64 <= arena.maximumBytes - usage2.bytes && size.slots + 1 <= arena.maximumSlots - usage2.slots) {
15608
+ allocation = arena.scope();
15609
+ input3 = await createGetoptsInput(supplied, allocation, work);
15610
+ }
15611
+ }
15612
+ const args = input3?.args ?? supplied;
15613
+ if (!input3 || allocation) for (let index = 0; index < args.length; index++) {
15614
+ this.signal.throwIfAborted();
15615
+ admit2(args[index]);
15616
+ if ((index + 1) % 128 === 0) await checkpoint();
15617
+ }
15618
+ state.getopts ??= cloneGetoptsBinding(state);
15619
+ try {
15620
+ result2 = await scanGetopts(state.getopts.cursor, optstring, input3 ?? args, {
15621
+ reportErrors: state.variables.OPTERR === void 0 || state.variables.OPTERR === "" || decimalIndex(state.variables.OPTERR) !== 0,
15622
+ work
15623
+ });
15624
+ } catch (error) {
15625
+ this.signal.throwIfAborted();
15626
+ if (error instanceof GetoptsError && (error.code === "NON_ASCII_OPTION" || error.code === "INVALID_INPUT")) throw new CommandFailure(`getopts: ${error.message}`, 2);
15627
+ throw error;
15628
+ }
15540
15629
  this.signal.throwIfAborted();
15541
- if (error instanceof GetoptsError && (error.code === "NON_ASCII_OPTION" || error.code === "INVALID_INPUT")) throw new CommandFailure(`getopts: ${error.message}`, 2);
15542
- throw error;
15630
+ if (monitor && monitor.positionalRevision !== revision) throw new CommandFailure("getopts: positional arguments changed during validation", 2);
15631
+ if (allocation && monitor.retainGetoptsInput(revision, input3, allocation)) allocation = void 0;
15632
+ } finally {
15633
+ allocation?.close();
15543
15634
  }
15544
15635
  this.signal.throwIfAborted();
15545
15636
  state.getopts.cursor = result2.state;