@poe-platform/safe-bash 0.1.545 → 0.1.547

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 (71) hide show
  1. package/dist/safe-bash/chunks/{chunk-FAA2WXKH.js → chunk-4JW32W4B.js} +163 -105
  2. package/dist/safe-bash/chunks/{chunk-FAA2WXKH.js.map → chunk-4JW32W4B.js.map} +3 -3
  3. package/dist/safe-bash/chunks/{chunk-XWCSJDGK.js → chunk-4V3NGZAG.js} +2 -2
  4. package/dist/safe-bash/chunks/{chunk-ASCV3OWE.js → chunk-AWP6Z3RR.js} +3 -3
  5. package/dist/safe-bash/chunks/{chunk-2YHZYNLC.js → chunk-DKT746UJ.js} +2 -2
  6. package/dist/safe-bash/chunks/{chunk-C7Z2SSTY.js → chunk-EUNOVYVT.js} +16 -3
  7. package/dist/safe-bash/chunks/chunk-EUNOVYVT.js.map +7 -0
  8. package/dist/safe-bash/chunks/{chunk-6E3FCEJ5.js → chunk-F5AOPLRZ.js} +2 -2
  9. package/dist/safe-bash/chunks/{chunk-GA43CRT3.js → chunk-FIY2BMTU.js} +2 -2
  10. package/dist/safe-bash/chunks/{chunk-EGLBB57T.js → chunk-IDJQT32M.js} +2 -2
  11. package/dist/safe-bash/chunks/{chunk-25GUOTPE.js → chunk-QX2X5EC5.js} +2 -2
  12. package/dist/safe-bash/chunks/{chunk-CTE3HGYS.js → chunk-VY5N6O6I.js} +3 -3
  13. package/dist/safe-bash/chunks/{chunk-K4RQ7ASH.js → chunk-WJWYJDQE.js} +2 -2
  14. package/dist/safe-bash/chunks/{chunk-R4HP2LEO.js → chunk-WXUZXY35.js} +2 -2
  15. package/dist/safe-bash/chunks/{chunk-IVJ5JGXZ.js → chunk-YFFFBLBC.js} +2 -2
  16. package/dist/safe-bash/commands/archive/unzip/safety.d.ts +3 -2
  17. package/dist/safe-bash/commands/archive/unzip/safety.d.ts.map +1 -1
  18. package/dist/safe-bash/commands/archive/unzip/safety.js +57 -62
  19. package/dist/safe-bash/commands/archive/unzip/safety.js.map +1 -1
  20. package/dist/safe-bash/commands/archive/unzip.d.ts.map +1 -1
  21. package/dist/safe-bash/commands/archive/unzip.js +12 -9
  22. package/dist/safe-bash/commands/archive/unzip.js.map +1 -1
  23. package/dist/safe-bash/commands/archive/zip/safety.d.ts +1 -0
  24. package/dist/safe-bash/commands/archive/zip/safety.d.ts.map +1 -1
  25. package/dist/safe-bash/commands/archive/zip/safety.js +19 -87
  26. package/dist/safe-bash/commands/archive/zip/safety.js.map +1 -1
  27. package/dist/safe-bash/commands/archive/zip.d.ts.map +1 -1
  28. package/dist/safe-bash/commands/archive/zip.js +2 -1
  29. package/dist/safe-bash/commands/archive/zip.js.map +1 -1
  30. package/dist/safe-bash/commands/csplit/command.d.ts.map +1 -1
  31. package/dist/safe-bash/commands/csplit/command.js +3 -1
  32. package/dist/safe-bash/commands/csplit/command.js.map +1 -1
  33. package/dist/safe-bash/commands/csplit/index.browser.js +3 -3
  34. package/dist/safe-bash/commands/csplit/internal.d.ts +2 -0
  35. package/dist/safe-bash/commands/csplit/internal.d.ts.map +1 -1
  36. package/dist/safe-bash/commands/csplit/internal.js +12 -0
  37. package/dist/safe-bash/commands/csplit/internal.js.map +1 -1
  38. package/dist/safe-bash/commands/csplit/io.d.ts +4 -2
  39. package/dist/safe-bash/commands/csplit/io.d.ts.map +1 -1
  40. package/dist/safe-bash/commands/csplit/io.js +98 -58
  41. package/dist/safe-bash/commands/csplit/io.js.map +1 -1
  42. package/dist/safe-bash/commands/factor/index.browser.js +2 -2
  43. package/dist/safe-bash/commands/getopt/index.browser.js +2 -2
  44. package/dist/safe-bash/commands/hexdump/index.browser.js +2 -2
  45. package/dist/safe-bash/commands/iconv/index.browser.js +2 -2
  46. package/dist/safe-bash/commands/line-endings/index.browser.js +3 -3
  47. package/dist/safe-bash/commands/llm/index.browser.js +2 -2
  48. package/dist/safe-bash/commands/network/index.browser.js +3 -3
  49. package/dist/safe-bash/commands/pr/index.browser.js +2 -2
  50. package/dist/safe-bash/commands/tsort/index.browser.js +2 -2
  51. package/dist/safe-bash/commands/yq/index.browser.js +2 -2
  52. package/dist/safe-bash/contracts/filesystem.d.ts +1 -1
  53. package/dist/safe-bash/contracts/filesystem.d.ts.map +1 -1
  54. package/dist/safe-bash/contracts/output.d.ts.map +1 -1
  55. package/dist/safe-bash/contracts/output.js +12 -2
  56. package/dist/safe-bash/contracts/output.js.map +1 -1
  57. package/dist/safe-bash/core.browser.js +255 -141
  58. package/dist/safe-bash/core.browser.js.map +3 -3
  59. package/package.json +2 -2
  60. package/dist/safe-bash/chunks/chunk-C7Z2SSTY.js.map +0 -7
  61. /package/dist/safe-bash/chunks/{chunk-XWCSJDGK.js.map → chunk-4V3NGZAG.js.map} +0 -0
  62. /package/dist/safe-bash/chunks/{chunk-ASCV3OWE.js.map → chunk-AWP6Z3RR.js.map} +0 -0
  63. /package/dist/safe-bash/chunks/{chunk-2YHZYNLC.js.map → chunk-DKT746UJ.js.map} +0 -0
  64. /package/dist/safe-bash/chunks/{chunk-6E3FCEJ5.js.map → chunk-F5AOPLRZ.js.map} +0 -0
  65. /package/dist/safe-bash/chunks/{chunk-GA43CRT3.js.map → chunk-FIY2BMTU.js.map} +0 -0
  66. /package/dist/safe-bash/chunks/{chunk-EGLBB57T.js.map → chunk-IDJQT32M.js.map} +0 -0
  67. /package/dist/safe-bash/chunks/{chunk-25GUOTPE.js.map → chunk-QX2X5EC5.js.map} +0 -0
  68. /package/dist/safe-bash/chunks/{chunk-CTE3HGYS.js.map → chunk-VY5N6O6I.js.map} +0 -0
  69. /package/dist/safe-bash/chunks/{chunk-K4RQ7ASH.js.map → chunk-WJWYJDQE.js.map} +0 -0
  70. /package/dist/safe-bash/chunks/{chunk-R4HP2LEO.js.map → chunk-WXUZXY35.js.map} +0 -0
  71. /package/dist/safe-bash/chunks/{chunk-IVJ5JGXZ.js.map → chunk-YFFFBLBC.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  writeFileOutput
3
- } from "./chunk-R4HP2LEO.js";
3
+ } from "./chunk-WXUZXY35.js";
4
4
  import {
5
5
  PublicDiagnostic,
6
6
  publicDiagnosticMessage
@@ -11291,10 +11291,18 @@ var Budget = class {
11291
11291
  }
11292
11292
  context;
11293
11293
  limits;
11294
+ buffers = /* @__PURE__ */ new Map();
11294
11295
  work = 0;
11295
11296
  checkpoint = 0;
11296
11297
  diagnostics = 0;
11297
11298
  output = 0;
11299
+ reserveBuffered(owner, bytes2) {
11300
+ let total = bytes2;
11301
+ for (const [key, value] of this.buffers) if (key !== owner) total += value;
11302
+ this.check(total, this.limits.maxBufferedBytes, "buffered bytes");
11303
+ if (bytes2) this.buffers.set(owner, bytes2);
11304
+ else this.buffers.delete(owner);
11305
+ }
11298
11306
  quote(value) {
11299
11307
  const locale = this.context.env.LC_ALL || this.context.env.LC_CTYPE || this.context.env.LANG || "C";
11300
11308
  this.charge(value.length);
@@ -11378,6 +11386,9 @@ function fsDetail(error) {
11378
11386
  // packages/safe-bash/src/commands/csplit/io.ts
11379
11387
  init_platform();
11380
11388
  import { retainFileSystemCleanup } from "@poe-platform/safe-fs/core";
11389
+ var retainedLineUnits = 128;
11390
+ var retainedOutputUnits = 256;
11391
+ var outputBufferBytes = 65536;
11381
11392
  function sameIdentity(first, second) {
11382
11393
  return (typeof first.identityScope === "object" && first.identityScope !== null || typeof first.identityScope === "symbol") && first.identityScope === second.identityScope && Number.isSafeInteger(first.dev) && Number.isSafeInteger(first.ino) && first.dev >= 0 && first.ino >= 0 && first.dev === second.dev && first.ino === second.ino;
11383
11394
  }
@@ -11388,11 +11399,19 @@ var Lifecycle = class {
11388
11399
  }
11389
11400
  budget;
11390
11401
  pending = /* @__PURE__ */ new Set();
11391
- cleanups = [];
11402
+ cleanups = /* @__PURE__ */ new Set();
11392
11403
  closing;
11393
11404
  cleanup(action) {
11394
11405
  this.assertOpen();
11395
- this.cleanups.push(action);
11406
+ const owned = async () => {
11407
+ try {
11408
+ await action();
11409
+ } finally {
11410
+ this.cleanups.delete(owned);
11411
+ }
11412
+ };
11413
+ this.cleanups.add(owned);
11414
+ return owned;
11396
11415
  }
11397
11416
  assertOpen() {
11398
11417
  this.budget.context.signal.throwIfAborted();
@@ -11434,10 +11453,18 @@ var Lines = class {
11434
11453
  constructor(lifecycle) {
11435
11454
  this.lifecycle = lifecycle;
11436
11455
  lifecycle.cleanup(async () => {
11437
- if (!this.ended) await this.iterator?.return?.();
11456
+ try {
11457
+ if (!this.ended) await this.iterator?.return?.();
11458
+ } finally {
11459
+ this.lines.length = 0;
11460
+ this.partial = [];
11461
+ lifecycle.budget.reserveBuffered(this, 0);
11462
+ lifecycle.budget.reserveBuffered(this.fallbackAllocation, 0);
11463
+ }
11438
11464
  });
11439
11465
  }
11440
11466
  lifecycle;
11467
+ fallbackAllocation = {};
11441
11468
  lines = [];
11442
11469
  partial = [];
11443
11470
  partialBytes = 0;
@@ -11447,6 +11474,9 @@ var Lines = class {
11447
11474
  ended = false;
11448
11475
  path;
11449
11476
  identity;
11477
+ reserve(extraLines = 0, extraParts = 0) {
11478
+ this.lifecycle.budget.reserveBuffered(this, this.total * 2 + (this.lines.length + extraLines + this.partial.length + extraParts) * retainedLineUnits);
11479
+ }
11450
11480
  async open(name) {
11451
11481
  if (name === "-") {
11452
11482
  this.identity = this.lifecycle.budget.context.stdinInput?.stat;
@@ -11469,7 +11499,11 @@ var Lines = class {
11469
11499
  const capabilities = await this.lifecycle.operation(async () => await fs.capabilitiesFor?.(this.path, { signal }) ?? fs.capabilities);
11470
11500
  if (fs.readStream && capabilities.streamingRead !== false) return fs.readStream(this.path, { signal, chunkSize: 65536 });
11471
11501
  if (this.identity.size > Math.min(limits.maxInputBytes, limits.maxBufferedBytes / 2)) throw new CsplitError("buffered input bytes limit exceeded");
11472
- const value = await this.lifecycle.operation(() => fs.readFile(this.path, { signal, maxBytes: limits.maxInputBytes }));
11502
+ const admittedBytes = this.identity.size;
11503
+ this.lifecycle.budget.reserveBuffered(this.fallbackAllocation, admittedBytes);
11504
+ this.lifecycle.budget.reserveBuffered(this, admittedBytes * 2);
11505
+ const value = await this.lifecycle.operation(() => fs.readFile(this.path, { signal, maxBytes: admittedBytes }));
11506
+ this.lifecycle.budget.check(value.length, admittedBytes, "input bytes");
11473
11507
  return { async *[Symbol.asyncIterator]() {
11474
11508
  yield value;
11475
11509
  } };
@@ -11477,6 +11511,7 @@ var Lines = class {
11477
11511
  appendLine() {
11478
11512
  const { budget } = this.lifecycle;
11479
11513
  budget.check(this.lines.length + 1, budget.limits.maxLines, "line count");
11514
+ this.reserve(1);
11480
11515
  const line = new Uint8Array(this.partialBytes);
11481
11516
  let offset = 0;
11482
11517
  for (const part of this.partial) {
@@ -11486,6 +11521,7 @@ var Lines = class {
11486
11521
  this.lines.push(line);
11487
11522
  this.partial = [];
11488
11523
  this.partialBytes = 0;
11524
+ this.reserve();
11489
11525
  }
11490
11526
  async get(number) {
11491
11527
  const { budget } = this.lifecycle;
@@ -11504,7 +11540,7 @@ var Lines = class {
11504
11540
  if (!(chunk instanceof Uint8Array)) throw new CsplitError("input produced a non-byte chunk");
11505
11541
  this.total += chunk.length;
11506
11542
  budget.check(this.total, budget.limits.maxInputBytes, "input bytes");
11507
- budget.check(this.total * 2, budget.limits.maxBufferedBytes, "buffered bytes");
11543
+ this.reserve();
11508
11544
  if (!chunk.length) budget.check(++this.emptyChunks, budget.limits.maxEmptyChunks, "empty input chunks");
11509
11545
  budget.charge(chunk.length);
11510
11546
  const owned = Uint8Array.from(chunk);
@@ -11513,6 +11549,7 @@ var Lines = class {
11513
11549
  if (owned[offset] === 10) {
11514
11550
  this.partialBytes += offset + 1 - start;
11515
11551
  budget.check(this.partialBytes, budget.limits.maxLineBytes, "line bytes");
11552
+ this.reserve(0, 1);
11516
11553
  this.partial.push(owned.subarray(start, offset + 1));
11517
11554
  this.appendLine();
11518
11555
  start = offset + 1;
@@ -11525,6 +11562,7 @@ var Lines = class {
11525
11562
  if (start < owned.length) {
11526
11563
  this.partialBytes += owned.length - start;
11527
11564
  budget.check(this.partialBytes, budget.limits.maxLineBytes, "line bytes");
11565
+ this.reserve(0, 1);
11528
11566
  this.partial.push(owned.subarray(start));
11529
11567
  }
11530
11568
  await budget.checkpointWork();
@@ -11557,18 +11595,12 @@ var Outputs = class {
11557
11595
  let current = "/";
11558
11596
  for (const component of ["", ...components]) {
11559
11597
  if (component) current = resolvePath(current, component);
11560
- const identity = await this.lifecycle.operation(() => context.fs.lstat(current, { signal: context.signal }));
11598
+ const identity = Object.freeze({ ...await this.lifecycle.operation(() => context.fs.lstat(current, { signal: context.signal })) });
11561
11599
  if (identity.type !== "directory" || !sameIdentity(identity, identity)) throw new CsplitError("unsafe output directory identity");
11562
11600
  parents.push({ path: current, identity });
11563
11601
  }
11564
11602
  return parents;
11565
11603
  }
11566
- async checked(output) {
11567
- await this.checkedParents(output.parents);
11568
- const { context } = this.lifecycle.budget;
11569
- const current = await this.lifecycle.operation(() => context.fs.lstat(output.path, { signal: context.signal }));
11570
- if (!output.identity || current.type !== "file" || !sameIdentity(current, output.identity)) throw new CsplitError("output changed before mutation");
11571
- }
11572
11604
  async checkedParents(parents) {
11573
11605
  const { context } = this.lifecycle.budget;
11574
11606
  for (const parent of parents) {
@@ -11585,53 +11617,48 @@ var Outputs = class {
11585
11617
  budget.check(name.length, limits.maxPathBytes, "output filename bytes");
11586
11618
  const path = resolvePath(context.cwd, pathText(name));
11587
11619
  try {
11620
+ const capabilities = await this.lifecycle.operation(async () => await context.fs.capabilitiesFor?.(path, { signal: context.signal, create: true }) ?? context.fs.capabilities);
11621
+ if (capabilities.atomicFileMutation !== true || !context.fs.writeFileConditional || !context.fs.removeFileConditional) throw new CsplitError("atomic output mutations are not supported");
11588
11622
  const parents = await this.parents(path);
11589
11623
  let existing;
11590
11624
  try {
11591
- existing = await this.lifecycle.operation(() => context.fs.lstat(path, { signal: context.signal }));
11625
+ existing = Object.freeze({ ...await this.lifecycle.operation(() => context.fs.lstat(path, { signal: context.signal })) });
11592
11626
  } catch (error) {
11593
11627
  context.signal.throwIfAborted();
11594
11628
  if (!missing(error)) throw error;
11595
11629
  }
11596
11630
  if (existing && (existing.type !== "file" || !sameIdentity(existing, existing))) throw new CsplitError(`unsafe output file ${budget.quote(name)}`);
11597
11631
  this.input.assertOutput(path, existing);
11598
- const output = { path, name, parents, created: false, removed: false, elided: false, failed: false, size: 0, cleanup: async () => {
11632
+ const metadataBytes = retainedOutputUnits + path.length * 2;
11633
+ const output = { path, parent: parents.at(-1).identity, metadataBytes, created: false, removed: false, elided: false, failed: false, size: 0, buffered: 0, cleanup: async () => {
11599
11634
  } };
11600
- output.cleanup = retainFileSystemCleanup(context.fs, async (view) => {
11635
+ budget.reserveBuffered(output, metadataBytes);
11636
+ output.cleanup = this.lifecycle.cleanup(retainFileSystemCleanup(context.fs, async (view) => {
11637
+ delete output.buffer;
11638
+ output.buffered = 0;
11639
+ budget.reserveBuffered(output, 0);
11601
11640
  if (!output.created || !output.identity || !output.elided && (this.succeeded || this.options.keep || this.preserve)) return;
11602
11641
  try {
11603
- for (const parent of parents) {
11604
- const current2 = await view.lstat(parent.path);
11605
- if (current2.type !== "directory" || !sameIdentity(current2, parent.identity)) return;
11606
- }
11607
- const current = await view.lstat(path);
11608
- if (current.type === "file" && sameIdentity(current, output.identity)) {
11609
- await view.rm(path);
11610
- output.removed = true;
11611
- }
11642
+ if (!view.removeFileConditional) throw new FsError("ENOTSUP");
11643
+ await view.removeFileConditional(path, { expected: output.identity, parent: output.parent });
11644
+ output.removed = true;
11612
11645
  } catch (error) {
11613
- if (!missing(error)) throw error;
11646
+ if (!missing(error) && !(error instanceof FsError && error.code === "EAGAIN")) throw error;
11614
11647
  }
11615
- }, { maxOperations: limits.maxPathDepth + 3 });
11616
- this.lifecycle.cleanup(output.cleanup);
11617
- await this.checkedParents(parents);
11618
- let admitted;
11648
+ }, { maxOperations: 1 }));
11619
11649
  try {
11620
- admitted = await this.lifecycle.operation(() => context.fs.lstat(path, { signal: context.signal }));
11621
- } catch (error) {
11622
- context.signal.throwIfAborted();
11623
- if (!missing(error)) throw error;
11650
+ await this.checkedParents(parents);
11651
+ await this.lifecycle.operation(async () => {
11652
+ output.identity = Object.freeze({ ...await context.fs.writeFileConditional(path, new Uint8Array(), {
11653
+ signal: context.signal,
11654
+ expected: existing ?? null,
11655
+ parent: output.parent
11656
+ }) });
11657
+ output.created = true;
11658
+ });
11659
+ } finally {
11660
+ parents.length = 0;
11624
11661
  }
11625
- if (admitted ? !existing || admitted.type !== "file" || !sameIdentity(admitted, existing) : existing !== void 0) throw new CsplitError("output changed before creation");
11626
- await this.checkedParents(parents);
11627
- await this.lifecycle.operation(async () => {
11628
- await context.fs.writeFile(path, new Uint8Array(), { signal: context.signal, flag: existing ? "w" : "wx" });
11629
- output.created = true;
11630
- if (existing) output.identity = existing;
11631
- const identity = await context.fs.lstat(path, { signal: context.signal });
11632
- if (identity.type !== "file" || !sameIdentity(identity, identity) || existing && !sameIdentity(existing, identity)) throw new CsplitError("output creation identity unavailable");
11633
- output.identity = identity;
11634
- });
11635
11662
  this.index++;
11636
11663
  this.current = output;
11637
11664
  } catch (error) {
@@ -11639,18 +11666,42 @@ var Outputs = class {
11639
11666
  throw error;
11640
11667
  }
11641
11668
  }
11669
+ async flush(output) {
11670
+ if (!output.buffered) return;
11671
+ const { context } = this.lifecycle.budget;
11672
+ try {
11673
+ await this.lifecycle.operation(() => writeFileOutput(context, output.buffer.subarray(0, output.buffered), async (chunk) => {
11674
+ output.identity = Object.freeze({ ...await context.fs.writeFileConditional(output.path, chunk, {
11675
+ signal: context.signal,
11676
+ expected: output.identity,
11677
+ parent: output.parent,
11678
+ append: true
11679
+ }) });
11680
+ output.buffered = 0;
11681
+ }));
11682
+ } catch (error) {
11683
+ output.failed = true;
11684
+ throw error;
11685
+ }
11686
+ }
11642
11687
  async write(value) {
11643
11688
  const output = this.current;
11644
11689
  if (!output) throw new CsplitError("output is not open");
11645
11690
  const { budget } = this.lifecycle;
11646
11691
  budget.fileBytes(value.length);
11647
- try {
11648
- await this.checked(output);
11649
- await this.lifecycle.operation(() => writeFileOutput(budget.context, value, (chunk) => budget.context.fs.appendFile(output.path, chunk, { signal: budget.context.signal })));
11650
- output.size += value.length;
11651
- } catch (error) {
11652
- output.failed = true;
11653
- throw error;
11692
+ if (!output.buffer) {
11693
+ const capacity = Math.min(outputBufferBytes, budget.limits.maxBufferedBytes);
11694
+ budget.reserveBuffered(output, output.metadataBytes + capacity);
11695
+ output.buffer = new Uint8Array(capacity);
11696
+ }
11697
+ for (let offset = 0; offset < value.length; ) {
11698
+ this.lifecycle.assertOpen();
11699
+ const count = Math.min(value.length - offset, output.buffer.length - output.buffered);
11700
+ output.buffer.set(value.subarray(offset, offset + count), output.buffered);
11701
+ output.buffered += count;
11702
+ output.size += count;
11703
+ offset += count;
11704
+ if (output.buffered === output.buffer.length) await this.flush(output);
11654
11705
  }
11655
11706
  }
11656
11707
  async finish() {
@@ -11658,8 +11709,10 @@ var Outputs = class {
11658
11709
  if (!output) return;
11659
11710
  this.current = void 0;
11660
11711
  if (output.failed) return;
11712
+ await this.flush(output);
11713
+ delete output.buffer;
11714
+ this.lifecycle.budget.reserveBuffered(output, output.metadataBytes);
11661
11715
  if (!output.size && this.options.elide) {
11662
- await this.checked(output);
11663
11716
  output.elided = true;
11664
11717
  await output.cleanup();
11665
11718
  if (!output.removed) throw new CsplitError("output changed before empty-file removal");
@@ -12002,62 +12055,67 @@ var Splitter = class {
12002
12055
  // packages/safe-bash/src/commands/csplit/command.ts
12003
12056
  function createCsplitCommandWithExecutor(executor, options2 = {}) {
12004
12057
  const limits = settings(options2);
12005
- return { name: "csplit", description: "Split files at bounded line and BRE boundaries", async execute(context) {
12006
- return withRegexSession(context, executor, async (session) => {
12007
- const budget = new Budget(context, limits);
12008
- const lifecycle = new Lifecycle(budget);
12009
- let output;
12010
- let failure;
12011
- let primary;
12012
- let exitCode = 0;
12013
- try {
12014
- const parsed = parseOptions(budget.arguments(), budget);
12015
- if (parsed.information) {
12016
- await budget.print(parsed.information === "version" ? "csplit (virtual-bash)\n" : "Usage: csplit [OPTION]... FILE PATTERN...\nOptions: -f PREFIX, -b SUFFIX, -k, -z, -n DIGITS, -s, --suppress-matched\nPatterns: INTEGER, /REGEXP/[OFFSET], %REGEXP%[OFFSET], {INTEGER}, {*}\n");
12017
- } else {
12018
- const format = suffixFormatter(parsed, budget);
12019
- const input = new Lines(lifecycle);
12020
- try {
12021
- await input.open(parsed.operands[0]);
12022
- } catch (error) {
12023
- if (error instanceof FsError) throw new CsplitError(`cannot open ${budget.quote(parsed.operands[0])} for reading: ${fsDetail(error)}`);
12024
- throw error;
12058
+ return {
12059
+ name: "csplit",
12060
+ description: "Split files at bounded line and BRE boundaries",
12061
+ filesystemRequirements: [{ id: "split", description: "Atomically mutate owned VFS outputs", capabilities: ["atomicFileMutation"], mutates: true }],
12062
+ async execute(context) {
12063
+ return withRegexSession(context, executor, async (session) => {
12064
+ const budget = new Budget(context, limits);
12065
+ const lifecycle = new Lifecycle(budget);
12066
+ let output;
12067
+ let failure;
12068
+ let primary;
12069
+ let exitCode = 0;
12070
+ try {
12071
+ const parsed = parseOptions(budget.arguments(), budget);
12072
+ if (parsed.information) {
12073
+ await budget.print(parsed.information === "version" ? "csplit (virtual-bash)\n" : "Usage: csplit [OPTION]... FILE PATTERN...\nOptions: -f PREFIX, -b SUFFIX, -k, -z, -n DIGITS, -s, --suppress-matched\nPatterns: INTEGER, /REGEXP/[OFFSET], %REGEXP%[OFFSET], {INTEGER}, {*}\n");
12074
+ } else {
12075
+ const format = suffixFormatter(parsed, budget);
12076
+ const input = new Lines(lifecycle);
12077
+ try {
12078
+ await input.open(parsed.operands[0]);
12079
+ } catch (error) {
12080
+ if (error instanceof FsError) throw new CsplitError(`cannot open ${budget.quote(parsed.operands[0])} for reading: ${fsDetail(error)}`);
12081
+ throw error;
12082
+ }
12083
+ const matcher = new Matcher(session, budget);
12084
+ const patterns = await preparePatterns(parsed.operands.slice(1), matcher);
12085
+ output = new Outputs(lifecycle, parsed, format, input);
12086
+ await new Splitter(input, output, matcher).run(patterns);
12087
+ output.succeeded = true;
12025
12088
  }
12026
- const matcher = new Matcher(session, budget);
12027
- const patterns = await preparePatterns(parsed.operands.slice(1), matcher);
12028
- output = new Outputs(lifecycle, parsed, format, input);
12029
- await new Splitter(input, output, matcher).run(patterns);
12030
- output.succeeded = true;
12031
- }
12032
- } catch (error) {
12033
- primary = { reason: error };
12034
- failure = { reason: error };
12035
- if (output && error instanceof CsplitError && error.preserve) output.preserve = true;
12036
- if (!context.signal.aborted) {
12037
- exitCode = 1;
12038
- try {
12039
- const message = error instanceof ExprMatchError ? error.message : error instanceof FsError ? fsDetail(error) : publicDiagnosticMessage(error, context.onInternalError);
12040
- await budget.print(`csplit: ${message}
12089
+ } catch (error) {
12090
+ primary = { reason: error };
12091
+ failure = { reason: error };
12092
+ if (output && error instanceof CsplitError && error.preserve) output.preserve = true;
12093
+ if (!context.signal.aborted) {
12094
+ exitCode = 1;
12095
+ try {
12096
+ const message = error instanceof ExprMatchError ? error.message : error instanceof FsError ? fsDetail(error) : publicDiagnosticMessage(error, context.onInternalError);
12097
+ await budget.print(`csplit: ${message}
12041
12098
  `, true);
12042
- if (error instanceof CsplitError && error.usage) await budget.print("Try 'csplit --help' for more information.\n", true);
12043
- if (!(error instanceof CsplitError && error.preserve)) await output?.finish();
12044
- failure = void 0;
12045
- } catch (reporting) {
12046
- failure = { reason: new AggregateError([error, reporting], "csplit failure reporting failed") };
12099
+ if (error instanceof CsplitError && error.usage) await budget.print("Try 'csplit --help' for more information.\n", true);
12100
+ if (!(error instanceof CsplitError && error.preserve)) await output?.finish();
12101
+ failure = void 0;
12102
+ } catch (reporting) {
12103
+ failure = { reason: new AggregateError([error, reporting], "csplit failure reporting failed") };
12104
+ }
12047
12105
  }
12048
12106
  }
12049
- }
12050
- try {
12051
- await lifecycle.close();
12052
- } catch (cleanup) {
12053
- const previous = failure ?? primary;
12054
- failure = { reason: previous ? new AggregateError([previous.reason, cleanup], "csplit execution and cleanup failed") : cleanup };
12055
- }
12056
- context.signal.throwIfAborted();
12057
- if (failure) throw failure.reason;
12058
- return { exitCode };
12059
- });
12060
- } };
12107
+ try {
12108
+ await lifecycle.close();
12109
+ } catch (cleanup) {
12110
+ const previous = failure ?? primary;
12111
+ failure = { reason: previous ? new AggregateError([previous.reason, cleanup], "csplit execution and cleanup failed") : cleanup };
12112
+ }
12113
+ context.signal.throwIfAborted();
12114
+ if (failure) throw failure.reason;
12115
+ return { exitCode };
12116
+ });
12117
+ }
12118
+ };
12061
12119
  }
12062
12120
 
12063
12121
  // packages/safe-bash/src/commands/csplit/index.ts
@@ -12100,4 +12158,4 @@ export {
12100
12158
  createCsplitCommands,
12101
12159
  csplitCommands
12102
12160
  };
12103
- //# sourceMappingURL=chunk-FAA2WXKH.js.map
12161
+ //# sourceMappingURL=chunk-4JW32W4B.js.map