poe-code 17.0.32 → 17.0.34

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 (92) hide show
  1. package/dist/{chunk-UC3KWJDL.js → chunk-EQAAKXQV.js} +8 -8
  2. package/dist/{chunk-54JM3XZC.js → chunk-LYH24BKM.js} +358 -46
  3. package/dist/chunk-LYH24BKM.js.map +7 -0
  4. package/dist/{chunk-GK6Z56OL.js → chunk-S2NLSD2J.js} +2 -2
  5. package/dist/{core-BR637SCW.js → core-CRWO3R4F.js} +2 -2
  6. package/dist/index.js +2 -2
  7. package/dist/metafile.json +1 -1
  8. package/dist/{program-3DNB5ZIC.js → program-3H7FXQW5.js} +3 -3
  9. package/dist/safe-bash.js +2 -2
  10. package/dist/{src-R4LATOF3.js → src-IES5F6JJ.js} +3 -3
  11. package/package.json +1 -1
  12. package/packages/package-lint/dist/bundle-policy.d.ts +3 -0
  13. package/packages/package-lint/dist/bundle-policy.js +4 -1
  14. package/packages/safe-bash/dist/chunks/{chunk-RVYQDJCC.js → chunk-AOT4SUBQ.js} +2 -2
  15. package/packages/safe-bash/dist/chunks/{chunk-MCBWPJRQ.js → chunk-FOMU56TU.js} +18 -2
  16. package/packages/safe-bash/dist/chunks/chunk-FOMU56TU.js.map +7 -0
  17. package/packages/safe-bash/dist/chunks/{chunk-JESM4RK2.js → chunk-KLEL3WAN.js} +41 -5
  18. package/packages/safe-bash/dist/chunks/chunk-KLEL3WAN.js.map +7 -0
  19. package/packages/safe-bash/dist/chunks/{chunk-LUQYNLH7.js → chunk-L4HKTYVE.js} +2 -2
  20. package/packages/safe-bash/dist/chunks/{chunk-WSCXISXW.js → chunk-RYXT5BJJ.js} +2 -2
  21. package/packages/safe-bash/dist/chunks/{chunk-HC4S4QZD.js → chunk-WSX5CLK2.js} +2 -2
  22. package/packages/safe-bash/dist/chunks/{chunk-BM3BGSH7.js → chunk-YJPA2BVP.js} +63 -20
  23. package/packages/safe-bash/dist/chunks/chunk-YJPA2BVP.js.map +7 -0
  24. package/packages/safe-bash/dist/commands/archive/index.d.ts.map +1 -1
  25. package/packages/safe-bash/dist/commands/archive/index.js +27 -0
  26. package/packages/safe-bash/dist/commands/archive/index.js.map +1 -1
  27. package/packages/safe-bash/dist/commands/archive/options.d.ts +1 -1
  28. package/packages/safe-bash/dist/commands/archive/options.d.ts.map +1 -1
  29. package/packages/safe-bash/dist/commands/archive/options.js +2 -0
  30. package/packages/safe-bash/dist/commands/archive/options.js.map +1 -1
  31. package/packages/safe-bash/dist/commands/basic.d.ts.map +1 -1
  32. package/packages/safe-bash/dist/commands/basic.js +9 -2
  33. package/packages/safe-bash/dist/commands/basic.js.map +1 -1
  34. package/packages/safe-bash/dist/commands/csplit/index.browser.js +1 -1
  35. package/packages/safe-bash/dist/commands/internal.d.ts +5 -2
  36. package/packages/safe-bash/dist/commands/internal.d.ts.map +1 -1
  37. package/packages/safe-bash/dist/commands/internal.js +48 -4
  38. package/packages/safe-bash/dist/commands/internal.js.map +1 -1
  39. package/packages/safe-bash/dist/commands/llm/index.browser.js +2 -2
  40. package/packages/safe-bash/dist/commands/network/index.browser.js +2 -2
  41. package/packages/safe-bash/dist/commands/node/index.browser.js +2 -2
  42. package/packages/safe-bash/dist/commands/regex-execution/ascii.d.ts +2 -0
  43. package/packages/safe-bash/dist/commands/regex-execution/ascii.d.ts.map +1 -1
  44. package/packages/safe-bash/dist/commands/regex-execution/ascii.js +4 -0
  45. package/packages/safe-bash/dist/commands/regex-execution/ascii.js.map +1 -1
  46. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.d.ts.map +1 -1
  47. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.js +51 -21
  48. package/packages/safe-bash/dist/commands/regex-execution/bounded-provider.js.map +1 -1
  49. package/packages/safe-bash/dist/commands/regex-execution/ere/matcher.d.ts +2 -2
  50. package/packages/safe-bash/dist/commands/regex-execution/ere/matcher.d.ts.map +1 -1
  51. package/packages/safe-bash/dist/commands/regex-execution/ere/matcher.js +23 -9
  52. package/packages/safe-bash/dist/commands/regex-execution/ere/matcher.js.map +1 -1
  53. package/packages/safe-bash/dist/commands/search/grep.d.ts.map +1 -1
  54. package/packages/safe-bash/dist/commands/search/grep.js +99 -4
  55. package/packages/safe-bash/dist/commands/search/grep.js.map +1 -1
  56. package/packages/safe-bash/dist/commands/search/options.d.ts +1 -0
  57. package/packages/safe-bash/dist/commands/search/options.d.ts.map +1 -1
  58. package/packages/safe-bash/dist/commands/search/options.js +4 -1
  59. package/packages/safe-bash/dist/commands/search/options.js.map +1 -1
  60. package/packages/safe-bash/dist/commands/search/rg-command.d.ts.map +1 -1
  61. package/packages/safe-bash/dist/commands/search/rg-command.js +59 -0
  62. package/packages/safe-bash/dist/commands/search/rg-command.js.map +1 -1
  63. package/packages/safe-bash/dist/commands/streams.d.ts.map +1 -1
  64. package/packages/safe-bash/dist/commands/streams.js +32 -12
  65. package/packages/safe-bash/dist/commands/streams.js.map +1 -1
  66. package/packages/safe-bash/dist/commands/structured/jq.d.ts.map +1 -1
  67. package/packages/safe-bash/dist/commands/structured/jq.js +8 -4
  68. package/packages/safe-bash/dist/commands/structured/jq.js.map +1 -1
  69. package/packages/safe-bash/dist/commands/structured/values.d.ts +1 -0
  70. package/packages/safe-bash/dist/commands/structured/values.d.ts.map +1 -1
  71. package/packages/safe-bash/dist/commands/structured/values.js +18 -1
  72. package/packages/safe-bash/dist/commands/structured/values.js.map +1 -1
  73. package/packages/safe-bash/dist/commands/text-programs/sed.d.ts.map +1 -1
  74. package/packages/safe-bash/dist/commands/text-programs/sed.js +10 -1
  75. package/packages/safe-bash/dist/commands/text-programs/sed.js.map +1 -1
  76. package/packages/safe-bash/dist/commands/xml/index.browser.js +2 -2
  77. package/packages/safe-bash/dist/commands/yq/index.browser.js +2 -2
  78. package/packages/safe-bash/dist/core.browser.js +248 -29
  79. package/packages/safe-bash/dist/core.browser.js.map +3 -3
  80. package/dist/chunk-54JM3XZC.js.map +0 -7
  81. package/packages/safe-bash/dist/chunks/chunk-BM3BGSH7.js.map +0 -7
  82. package/packages/safe-bash/dist/chunks/chunk-JESM4RK2.js.map +0 -7
  83. package/packages/safe-bash/dist/chunks/chunk-MCBWPJRQ.js.map +0 -7
  84. /package/dist/{chunk-UC3KWJDL.js.map → chunk-EQAAKXQV.js.map} +0 -0
  85. /package/dist/{chunk-GK6Z56OL.js.map → chunk-S2NLSD2J.js.map} +0 -0
  86. /package/dist/{core-BR637SCW.js.map → core-CRWO3R4F.js.map} +0 -0
  87. /package/dist/{program-3DNB5ZIC.js.map → program-3H7FXQW5.js.map} +0 -0
  88. /package/dist/{src-R4LATOF3.js.map → src-IES5F6JJ.js.map} +0 -0
  89. /package/packages/safe-bash/dist/chunks/{chunk-RVYQDJCC.js.map → chunk-AOT4SUBQ.js.map} +0 -0
  90. /package/packages/safe-bash/dist/chunks/{chunk-LUQYNLH7.js.map → chunk-L4HKTYVE.js.map} +0 -0
  91. /package/packages/safe-bash/dist/chunks/{chunk-WSCXISXW.js.map → chunk-RYXT5BJJ.js.map} +0 -0
  92. /package/packages/safe-bash/dist/chunks/{chunk-HC4S4QZD.js.map → chunk-WSX5CLK2.js.map} +0 -0
@@ -1264,6 +1264,9 @@ var AvailableRecords = class {
1264
1264
  function foldAscii(code) {
1265
1265
  return code >= 65 && code <= 90 ? code + 32 : code;
1266
1266
  }
1267
+ function isAsciiWord(code) {
1268
+ return code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 95;
1269
+ }
1267
1270
 
1268
1271
  // packages/safe-bash/src/contracts/yield.ts
1269
1272
  var checkpoints = /* @__PURE__ */ new WeakMap();
@@ -9846,7 +9849,7 @@ async function matchEre(program, subject, ledger, signal) {
9846
9849
  await admitAscii(subject, ledger, signal);
9847
9850
  return runMatcher(program, subject, ledger, signal, 0, true);
9848
9851
  }
9849
- async function prepareUtf8EreSubject(bytes8, ledger, signal) {
9852
+ async function prepareUtf8EreSubject(bytes8, ledger, signal, leftmostFirst = false, word = false) {
9850
9853
  ledger.check(signal);
9851
9854
  ledger.admitInput("subjectBytes", bytes8.length, signal);
9852
9855
  ledger.charge("allocationUnits", bytes8.length * 11 + 16, signal);
@@ -9857,7 +9860,7 @@ async function prepareUtf8EreSubject(bytes8, ledger, signal) {
9857
9860
  const offsets = [];
9858
9861
  for (let offset = 0; offset < owned.length; ) {
9859
9862
  const first = owned[offset];
9860
- const width = first < 128 ? 1 : first < 224 ? 2 : first < 240 ? 3 : 4;
9863
+ const width = word || first < 128 ? 1 : first < 224 ? 2 : first < 240 ? 3 : 4;
9861
9864
  ledger.charge("work", width, signal);
9862
9865
  await ledger.checkpoint(signal);
9863
9866
  offsets.push(offset);
@@ -9882,14 +9885,14 @@ async function prepareUtf8EreSubject(bytes8, ledger, signal) {
9882
9885
  else upper = middle;
9883
9886
  }
9884
9887
  if (offsets[lower] !== start) throw new RangeError("UTF-8 ERE cursor must be a scalar boundary");
9885
- const span = await runMatcher(program, subject, ledger, signal, lower, false);
9888
+ const span = await runMatcher(program, subject, ledger, signal, lower, false, leftmostFirst, word);
9886
9889
  if (!span) return void 0;
9887
9890
  ledger.charge("allocationUnits", 2, signal);
9888
9891
  return Object.freeze({ start: offsets[span.start], end: offsets[span.end] });
9889
9892
  };
9890
9893
  };
9891
9894
  }
9892
- async function runMatcher(program, subject, ledger, signal, from, materialize) {
9895
+ async function runMatcher(program, subject, ledger, signal, from, materialize, leftmostFirst = false, word = false) {
9893
9896
  const root = resolveEreProgram(program, ledger);
9894
9897
  const width = program.groups + 1;
9895
9898
  ledger.charge("work", width * 2, signal);
@@ -9908,6 +9911,11 @@ async function runMatcher(program, subject, ledger, signal, from, materialize) {
9908
9911
  pending.push({ position, task: next, captures, histories });
9909
9912
  };
9910
9913
  for (let start = from; start <= subject.length; start++) {
9914
+ if (word) {
9915
+ ledger.charge("work", 1, signal);
9916
+ await ledger.checkpoint(signal);
9917
+ if (isAsciiWord(subject.charCodeAt(start - 1))) continue;
9918
+ }
9911
9919
  push(start, task(() => ({ kind: "node", node: root, next: null })), emptyCaptures, emptyHistories);
9912
9920
  let best;
9913
9921
  while (pending.length > 0) {
@@ -9916,6 +9924,11 @@ async function runMatcher(program, subject, ledger, signal, from, materialize) {
9916
9924
  const state = pending.pop();
9917
9925
  const current = state.task;
9918
9926
  if (current === null) {
9927
+ if (word && isAsciiWord(subject.charCodeAt(state.position))) continue;
9928
+ if (leftmostFirst) {
9929
+ best = state;
9930
+ break;
9931
+ }
9919
9932
  if (!best || await preferred(state, best, ledger, signal)) best = state;
9920
9933
  continue;
9921
9934
  }
@@ -9957,7 +9970,7 @@ async function runMatcher(program, subject, ledger, signal, from, materialize) {
9957
9970
  case "literal":
9958
9971
  case "set": {
9959
9972
  const code = subject.charCodeAt(state.position);
9960
- if (state.position < subject.length && (node.kind === "dot" || node.kind === "literal" && (node.insensitive ? foldAscii(node.code) === foldAscii(code) : node.code === code) || node.kind === "set" && (code < 128 ? node.members[code] : node.nonAscii))) {
9973
+ if (state.position < subject.length && (node.kind === "dot" && (!leftmostFirst || code !== 10) || node.kind === "literal" && (node.insensitive ? foldAscii(node.code) === foldAscii(code) : node.code === code) || node.kind === "set" && (code < 128 ? node.members[code] : node.nonAscii))) {
9961
9974
  push(state.position + 1, current.next, state.captures, state.histories);
9962
9975
  }
9963
9976
  break;
@@ -10101,13 +10114,12 @@ function descriptor(value2, limits) {
10101
10114
  if (value2 === null || typeof value2 !== "object") fail("protocol", "invalid descriptor");
10102
10115
  const kind = Object.getOwnPropertyDescriptor(value2, "kind");
10103
10116
  if (!kind || !("value" in kind)) fail("protocol", "invalid descriptor kind");
10104
- if (kind.value !== "grep" && kind.value !== "rg") fail("unsupported", "only grep and fixed rg selection descriptors are supported");
10117
+ if (kind.value !== "grep" && kind.value !== "rg") fail("unsupported", "only grep and rg selection descriptors are supported");
10105
10118
  const flags4 = kind.value === "grep" ? ["fixed", "extended", "insensitive", "whole", "word"] : ["fixed", "whole", "word", "nullData"];
10106
10119
  record(value2, ["kind", "patterns", ...flags4, ...kind.value === "rg" ? ["case"] : []]);
10107
10120
  for (const flag of flags4) if (typeof value2[flag] !== "boolean") fail("protocol", `invalid ${flag} flag`);
10108
10121
  if (kind.value === "rg" && !["sensitive", "insensitive", "smart"].includes(value2.case)) fail("protocol", "invalid case flag");
10109
- if (value2.word || kind.value === "rg" && value2.case !== "sensitive") fail("unsupported", "word matching and rg case-insensitive selection are unsupported");
10110
- if (kind.value === "rg" && !value2.fixed) fail("unsupported", "rg regex modes are unsupported; use fixed UTF-8 patterns");
10122
+ if (kind.value === "rg" && (value2.word || value2.case !== "sensitive")) fail("unsupported", "rg word matching and case-insensitive selection are unsupported");
10111
10123
  array(value2.patterns, limits.maxPatterns, "pattern");
10112
10124
  let bytes8 = 0;
10113
10125
  for (let index = 0; index < value2.patterns.length; index++) {
@@ -10129,7 +10141,6 @@ function admit(input4, limits, signal) {
10129
10141
  record(row, ["bytes", "all", "terminated"], ["directory", "ancestors"]);
10130
10142
  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");
10131
10143
  if (Object.hasOwn(row, "directory") || Object.hasOwn(row, "ancestors")) fail("unsupported", "glob row flags are unsupported");
10132
- if (row.all && selected.kind !== "grep") fail("unsupported", "rg all-match enumeration is unsupported");
10133
10144
  const length2 = byteLength.call(row.bytes);
10134
10145
  if (length2 > limits.maxInputBytes - bytes8) fail("limit", "aggregate input byte limit exceeded");
10135
10146
  bytes8 += length2;
@@ -10313,17 +10324,28 @@ async function compileLiteral(bytes8, ledger, signal, insensitive = false) {
10313
10324
  }
10314
10325
  return { bytes: bytes8, fallback, insensitive };
10315
10326
  }
10316
- async function literalStart(program, subject, whole, ledger, signal, from = 0) {
10327
+ async function literalStart(program, subject, whole, word, ledger, signal, from = 0) {
10317
10328
  const { bytes: bytes8, fallback } = program;
10318
10329
  ledger.charge("work", 1, signal);
10319
10330
  await ledger.checkpoint(signal);
10320
10331
  if (whole && (from !== 0 || bytes8.length !== subject.length) || bytes8.length > subject.length - from) return -1;
10321
- if (bytes8.length === 0) return from;
10332
+ if (bytes8.length === 0) {
10333
+ for (let start = from; start <= subject.length; start++) {
10334
+ ledger.charge("work", 1, signal);
10335
+ await ledger.checkpoint(signal);
10336
+ if (!word || !isAsciiWord(subject[start - 1] ?? -1) && !isAsciiWord(subject[start] ?? -1)) return start;
10337
+ }
10338
+ return -1;
10339
+ }
10322
10340
  for (let index = from, prefix3 = 0; index < subject.length; ) {
10323
10341
  ledger.charge("work", 1, signal);
10324
10342
  if ((program.insensitive ? foldAscii(subject[index]) : subject[index]) === bytes8[prefix3]) {
10325
10343
  index++;
10326
- if (++prefix3 === bytes8.length) return index - prefix3;
10344
+ if (++prefix3 === bytes8.length) {
10345
+ const start = index - prefix3;
10346
+ if (!word || !isAsciiWord(subject[start - 1] ?? -1) && !isAsciiWord(subject[index] ?? -1)) return start;
10347
+ prefix3 = fallback[prefix3 - 1];
10348
+ }
10327
10349
  } else if (prefix3 > 0) prefix3 = fallback[prefix3 - 1];
10328
10350
  else index++;
10329
10351
  await ledger.checkpoint(signal);
@@ -10335,6 +10357,9 @@ async function enumerate(input4, row, finders, usage3, signal) {
10335
10357
  ledger.charge("allocationUnits", finders.length + 2, signal);
10336
10358
  const cached = new Array(finders.length);
10337
10359
  const ranges2 = [];
10360
+ const byteEmpty = input4.descriptor.kind === "rg" && !input4.descriptor.whole && input4.descriptor.patterns.length === 1 && input4.descriptor.patterns[0] === "";
10361
+ const byteCursor = input4.descriptor.kind === "grep" && input4.descriptor.word;
10362
+ let previousEnd = -1;
10338
10363
  for (let from = 0; from <= row.bytes.length; ) {
10339
10364
  let best;
10340
10365
  for (let index = 0; index < finders.length; index++) {
@@ -10345,9 +10370,14 @@ async function enumerate(input4, row, finders, usage3, signal) {
10345
10370
  candidate = await finders[index](from) ?? null;
10346
10371
  cached[index] = candidate;
10347
10372
  }
10348
- if (candidate && (!best || candidate.start < best.start || candidate.start === best.start && candidate.end > best.end)) best = candidate;
10373
+ if (candidate && (!best || candidate.start < best.start || input4.descriptor.kind === "grep" && candidate.start === best.start && candidate.end > best.end)) best = candidate;
10374
+ }
10375
+ if (!best || byteEmpty && !row.terminated && best.start === row.bytes.length) break;
10376
+ if (input4.descriptor.kind === "rg" && !byteEmpty && best.start === best.end && best.start === previousEnd) {
10377
+ const byte = row.bytes[best.end];
10378
+ from = best.end + (byte === void 0 || byte < 128 ? 1 : byte < 224 ? 2 : byte < 240 ? 3 : 4);
10379
+ continue;
10349
10380
  }
10350
- if (!best) break;
10351
10381
  if (ranges2.length / 2 >= limits.maxMatchesPerLine) fail("limit", "matches per line limit exceeded");
10352
10382
  if (usage3.count >= limits.maxTotalMatches) fail("limit", "total match limit exceeded");
10353
10383
  if (usage3.count >= Math.floor(limits.maxResultBytes / 16)) fail("limit", "result byte limit exceeded");
@@ -10355,10 +10385,11 @@ async function enumerate(input4, row, finders, usage3, signal) {
10355
10385
  ledger.charge("allocationUnits", 24, signal);
10356
10386
  usage3.count++;
10357
10387
  ranges2.push(best.start, best.end);
10388
+ previousEnd = best.end;
10358
10389
  if (best.end > best.start) from = best.end;
10359
10390
  else {
10360
10391
  const byte = row.bytes[best.end];
10361
- from = best.end + (byte === void 0 || byte < 128 ? 1 : byte < 224 ? 2 : byte < 240 ? 3 : 4);
10392
+ from = best.end + (byteEmpty || byteCursor || byte === void 0 || byte < 128 ? 1 : byte < 224 ? 2 : byte < 240 ? 3 : 4);
10362
10393
  }
10363
10394
  }
10364
10395
  ledger.charge("work", ranges2.length, signal);
@@ -10379,7 +10410,7 @@ async function executeLiteral(input4, signal) {
10379
10410
  if (row.all) {
10380
10411
  ledger.charge("allocationUnits", programs2.length * 2, signal);
10381
10412
  const finders = programs2.map((program) => async (from) => {
10382
- const start2 = await literalStart(program, row.bytes, selected.whole, ledger, signal, from);
10413
+ const start2 = await literalStart(program, row.bytes, selected.whole, selected.word, ledger, signal, from);
10383
10414
  if (start2 < 0) return void 0;
10384
10415
  ledger.charge("allocationUnits", 2, signal);
10385
10416
  return { start: start2, end: start2 + program.bytes.length };
@@ -10390,7 +10421,7 @@ async function executeLiteral(input4, signal) {
10390
10421
  let start = -1;
10391
10422
  let end = -1;
10392
10423
  for (const program of programs2) {
10393
- const candidate = await literalStart(program, row.bytes, selected.whole, ledger, signal);
10424
+ const candidate = await literalStart(program, row.bytes, selected.whole, selected.word, ledger, signal);
10394
10425
  if (candidate < 0) continue;
10395
10426
  if (start < 0 || candidate < start) {
10396
10427
  start = candidate;
@@ -10409,7 +10440,19 @@ async function executeLiteral(input4, signal) {
10409
10440
  }
10410
10441
  async function execute(input4, signal) {
10411
10442
  const { descriptor: selected, rows: rows2, ledger } = input4;
10412
- if (selected.fixed) return executeLiteral(input4, signal);
10443
+ let literal = selected.fixed;
10444
+ if (!literal && selected.kind === "rg") {
10445
+ literal = true;
10446
+ patterns: for (const pattern of selected.patterns) {
10447
+ ledger.charge("work", pattern.length, signal);
10448
+ await ledger.checkpoint(signal);
10449
+ for (const character of pattern) if ("\\.^$[]()|*+?{}".includes(character)) {
10450
+ literal = false;
10451
+ break patterns;
10452
+ }
10453
+ }
10454
+ }
10455
+ if (literal) return executeLiteral(input4, signal);
10413
10456
  const programs2 = [];
10414
10457
  for (const pattern of selected.patterns) {
10415
10458
  if (selected.kind === "rg" && !selected.nullData && pattern.includes("\n")) fail("unsupported", "rg multiline matching is unsupported");
@@ -10427,7 +10470,7 @@ async function execute(input4, signal) {
10427
10470
  const results = [];
10428
10471
  const usage3 = { count: 0 };
10429
10472
  for (const row of rows2) {
10430
- const subject = await prepareUtf8EreSubject(row.bytes, ledger, signal);
10473
+ const subject = await prepareUtf8EreSubject(row.bytes, ledger, signal, selected.kind === "rg", selected.word);
10431
10474
  if (row.all) {
10432
10475
  ledger.charge("allocationUnits", programs2.length + 1, signal);
10433
10476
  const finders = [];
@@ -10727,8 +10770,9 @@ function options2(args, short, long = {}, stopAtOperand = false, onOperand, onVa
10727
10770
  if (argument2.startsWith("--")) {
10728
10771
  const equals = argument2.indexOf("=");
10729
10772
  const name2 = argument2.slice(2, equals < 0 ? void 0 : equals);
10730
- const key = long[name2];
10731
- if (!key || !specifications.has(key)) throw new UsageError(`unrecognized option '${argument2}'`);
10773
+ const alias2 = long[name2];
10774
+ const key = alias2 === false ? name2 : alias2;
10775
+ if (!key || alias2 !== false && !specifications.has(key)) throw new UsageError(`unrecognized option '${argument2}'`);
10732
10776
  if (specifications.get(key)) {
10733
10777
  const value2 = equals >= 0 ? argument2.slice(equals + 1) : args[++index];
10734
10778
  if (value2 === void 0) throw new UsageError(`option '--${name2}' requires an argument`);
@@ -10908,7 +10952,8 @@ function replaceArgument(source2, pattern, replacement) {
10908
10952
  chunks.push(source2.subarray(start));
10909
10953
  return concatenate(chunks);
10910
10954
  }
10911
- function escapeBytes(text4, zeroOctal = false, bareOctal = false) {
10955
+ function escapeBytes(text4, zeroOctal = false, bareOctal = false, unicode) {
10956
+ if (unicode && typeof text4 === "string") text4 = encoder2.encode(text4);
10912
10957
  if (typeof text4 === "string") {
10913
10958
  const chunks = [];
10914
10959
  const control2 = { a: 7, b: 8, e: 27, E: 27, f: 12, n: 10, r: 13, t: 9, v: 11, "\\": 92 };
@@ -10945,7 +10990,7 @@ function escapeBytes(text4, zeroOctal = false, bareOctal = false) {
10945
10990
  return { bytes: concatenate(chunks), stop: false };
10946
10991
  }
10947
10992
  const source2 = text4;
10948
- const bytes8 = new Uint8Array(source2.length);
10993
+ const bytes8 = new Uint8Array(source2.length * (unicode && !unicode.utf8 ? 3 : 1));
10949
10994
  const control = { 97: 7, 98: 8, 101: 27, 69: 27, 102: 12, 110: 10, 114: 13, 116: 9, 118: 11, 92: 92 };
10950
10995
  let size = 0;
10951
10996
  for (let index = 0; index < source2.length; ) {
@@ -10969,6 +11014,40 @@ function escapeBytes(text4, zeroOctal = false, bareOctal = false) {
10969
11014
  index = offset;
10970
11015
  continue;
10971
11016
  }
11017
+ if (unicode && (next === 117 || next === 85)) {
11018
+ const digits = next === 117 ? 4 : 8;
11019
+ let offset = index + 2;
11020
+ const end = Math.min(source2.length, offset + digits);
11021
+ let value2 = 0;
11022
+ while (offset < end) {
11023
+ const digit4 = source2[offset];
11024
+ const number8 = digit4 >= 48 && digit4 <= 57 ? digit4 - 48 : digit4 >= 65 && digit4 <= 70 ? digit4 - 55 : digit4 >= 97 && digit4 <= 102 ? digit4 - 87 : -1;
11025
+ if (number8 < 0) break;
11026
+ value2 = value2 * 16 + number8;
11027
+ offset++;
11028
+ }
11029
+ if (offset === index + 2) unicode.missingDigit(String.fromCharCode(next));
11030
+ else {
11031
+ if (value2 < 2147483648) {
11032
+ if (!unicode.utf8 && value2 > 127) {
11033
+ const literal = encoder2.encode(`\\${value2 <= 65535 ? "u" : "U"}${value2.toString(16).toUpperCase().padStart(value2 <= 65535 ? 4 : 8, "0")}`);
11034
+ bytes8.set(literal, size);
11035
+ size += literal.length;
11036
+ } else if (value2 < 128) bytes8[size++] = value2;
11037
+ else {
11038
+ const length2 = value2 < 2048 ? 2 : value2 < 65536 ? 3 : value2 < 2097152 ? 4 : value2 < 67108864 ? 5 : 6;
11039
+ for (let position = length2 - 1; position > 0; position--) {
11040
+ bytes8[size + position] = 128 | value2 & 63;
11041
+ value2 = Math.floor(value2 / 64);
11042
+ }
11043
+ bytes8[size] = 255 << 8 - length2 & 255 | value2;
11044
+ size += length2;
11045
+ }
11046
+ }
11047
+ index = offset;
11048
+ continue;
11049
+ }
11050
+ }
10972
11051
  if (next === 120) {
10973
11052
  let offset = index + 2;
10974
11053
  const end = Math.min(source2.length, offset + 2);
@@ -11068,6 +11147,11 @@ async function formatPrintf(context2) {
11068
11147
  let argument2 = 1;
11069
11148
  let exitCode = 0;
11070
11149
  let stopped = false;
11150
+ const locale = context2.env.LC_ALL || context2.env.LC_CTYPE || context2.env.LANG || "C.UTF-8";
11151
+ const unicodeErrors = [];
11152
+ const unicode = { utf8: locale !== "C" && locale !== "POSIX", missingDigit: (escape2) => {
11153
+ unicodeErrors.push(escape2);
11154
+ } };
11071
11155
  do {
11072
11156
  const before = argument2;
11073
11157
  for (let offset = 0; offset < formatLength && !stopped; ) {
@@ -11075,7 +11159,9 @@ async function formatPrintf(context2) {
11075
11159
  const end = rawFormat ? rawFormat.indexOf(37, offset) : format3.indexOf("%", offset);
11076
11160
  const limit2 = end < 0 ? formatLength : end;
11077
11161
  const literal = rawFormat ? rawFormat.subarray(offset, limit2) : format3.slice(offset, limit2);
11078
- const escaped3 = escapeBytes(literal);
11162
+ const escaped3 = escapeBytes(literal, false, false, unicode);
11163
+ for (const escape2 of unicodeErrors.splice(0)) await writeDiagnostic(context2.stderr, `printf: missing unicode digit for \\${escape2}
11164
+ `, context2.signal);
11079
11165
  await output(context2, escaped3.bytes);
11080
11166
  stopped = escaped3.stop;
11081
11167
  offset += literal.length;
@@ -11104,7 +11190,9 @@ async function formatPrintf(context2) {
11104
11190
  if (specifier === "b" || specifier === "s") {
11105
11191
  const suppliedValue = arguments_.values[suppliedIndex] ?? "";
11106
11192
  const raw7 = specifier === "b" && typeof suppliedValue === "string" ? suppliedValue : arguments_.bytes(suppliedIndex) ?? new Uint8Array();
11107
- const escaped3 = specifier === "b" ? escapeBytes(raw7, true, true) : { bytes: raw7, stop: false };
11193
+ const escaped3 = specifier === "b" ? escapeBytes(raw7, true, true, unicode) : { bytes: raw7, stop: false };
11194
+ for (const escape2 of unicodeErrors.splice(0)) await writeDiagnostic(context2.stderr, `printf: missing unicode digit for \\${escape2}
11195
+ `, context2.signal);
11108
11196
  const bytes8 = escaped3.bytes.subarray(0, precision);
11109
11197
  const padding = " ".repeat(Math.max(0, width - bytes8.length));
11110
11198
  if (!flags4.includes("-")) await output(context2, padding);
@@ -15138,7 +15226,7 @@ async function* combinedInput(context2, names, state) {
15138
15226
  }
15139
15227
  }
15140
15228
  }
15141
- async function prefix(context2, source2, count2, bytes8, skip) {
15229
+ async function prefix(context2, source2, count2, bytes8, skip, delimiter) {
15142
15230
  let remaining = count2;
15143
15231
  if (!remaining && !skip) return;
15144
15232
  for await (const chunk of source2) {
@@ -15149,7 +15237,7 @@ async function prefix(context2, source2, count2, bytes8, skip) {
15149
15237
  offset = Math.min(chunk.length, remaining);
15150
15238
  remaining -= offset;
15151
15239
  } else {
15152
- for (; offset < chunk.length && remaining; offset++) if (chunk[offset] === 10) remaining--;
15240
+ for (; offset < chunk.length && remaining; offset++) if (chunk[offset] === delimiter) remaining--;
15153
15241
  }
15154
15242
  }
15155
15243
  if (skip) {
@@ -15160,12 +15248,12 @@ async function prefix(context2, source2, count2, bytes8, skip) {
15160
15248
  }
15161
15249
  }
15162
15250
  }
15163
- async function suffix(context2, source2, count2, bytes8, omit) {
15251
+ async function suffix(context2, source2, count2, bytes8, omit, delimiter) {
15164
15252
  let pending = [];
15165
15253
  let start = 0;
15166
15254
  let size = 0;
15167
15255
  const records5 = bytes8 ? source2 : (async function* () {
15168
- for await (const line of lines(source2)) yield line.terminated ? concatenate([line.bytes, Uint8Array.of(10)]) : line.bytes;
15256
+ for await (const line of lines(source2, delimiter)) yield line.terminated ? concatenate([line.bytes, Uint8Array.of(delimiter)]) : line.bytes;
15169
15257
  })();
15170
15258
  for await (const chunk of records5) {
15171
15259
  context2.signal.throwIfAborted();
@@ -15240,9 +15328,10 @@ function headTail(name2, maxTailFollowHandles = 64) {
15240
15328
  return define(name2, async (context2) => {
15241
15329
  const args = context2.args[0] && /^-[0-9]+$/u.test(context2.args[0]) ? ["-n", context2.args[0].slice(1), ...context2.args.slice(1)] : context2.args;
15242
15330
  const follow = name2 === "tail" ? parseTailFollow(args) : void 0;
15243
- const parsed = options2(follow?.args ?? args, "n:c:qv", { lines: "n", bytes: "c", quiet: "q", silent: "q", verbose: "v" });
15331
+ const parsed = options2(follow?.args ?? args, "n:c:qvz", { lines: "n", bytes: "c", quiet: "q", silent: "q", verbose: "v", "zero-terminated": "z" });
15244
15332
  if (parsed.flags.has("n") && parsed.flags.has("c")) throw new UsageError("cannot combine line and byte counts");
15245
15333
  const bytes8 = parsed.flags.has("c");
15334
+ const delimiter = parsed.flags.has("z") ? 0 : 10;
15246
15335
  const amount = value(parsed, bytes8 ? "c" : "n") ?? "10";
15247
15336
  const positive = amount.startsWith("+");
15248
15337
  const negative = amount.startsWith("-");
@@ -15256,7 +15345,7 @@ function headTail(name2, maxTailFollowHandles = 64) {
15256
15345
  bytes: bytes8,
15257
15346
  positive,
15258
15347
  headers: parsed.flags.has("v") || names.length > 1 && !parsed.flags.has("q")
15259
- }, maxTailFollowHandles, (target, source2) => positive ? prefix(target, source2, Math.max(0, count2 - 1), bytes8, true) : suffix(target, source2, count2, bytes8, false));
15348
+ }, maxTailFollowHandles, (target, source2) => positive ? prefix(target, source2, Math.max(0, count2 - 1), bytes8, true, delimiter) : suffix(target, source2, count2, bytes8, false, delimiter));
15260
15349
  await assertInputRequirements(context2, names);
15261
15350
  assertCommandRequirements(context2, inspectedInputRequirements, [names.some((name3) => name3 !== "-") ? "file" : "stdin"]);
15262
15351
  let exitCode = 0;
@@ -15274,9 +15363,9 @@ function headTail(name2, maxTailFollowHandles = 64) {
15274
15363
  `);
15275
15364
  headerWritten = true;
15276
15365
  }
15277
- if (name2 === "head" && !negative) await prefix(context2, input(context2, file), count2, bytes8, false);
15278
- else if (name2 === "tail" && positive) await prefix(context2, input(context2, file), Math.max(0, count2 - 1), bytes8, true);
15279
- else await suffix(context2, input(context2, file), count2, bytes8, name2 === "head");
15366
+ if (name2 === "head" && !negative) await prefix(context2, input(context2, file), count2, bytes8, false, delimiter);
15367
+ else if (name2 === "tail" && positive) await prefix(context2, input(context2, file), Math.max(0, count2 - 1), bytes8, true, delimiter);
15368
+ else await suffix(context2, input(context2, file), count2, bytes8, name2 === "head", delimiter);
15280
15369
  } catch (error) {
15281
15370
  await diagnostic(context2, error);
15282
15371
  exitCode = 1;
@@ -15345,7 +15434,26 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
15345
15434
  }
15346
15435
  return [
15347
15436
  define("cat", async (context2) => {
15348
- const parsed = options2(context2.args, "nbsvETAute", { number: "n", "number-nonblank": "b", "squeeze-blank": "s", "show-ends": "E", "show-tabs": "T", "show-nonprinting": "v", "show-all": "A" });
15437
+ const parsed = options2(context2.args, "nbsvETAute", { help: false, number: "n", "number-nonblank": "b", "squeeze-blank": "s", "show-ends": "E", "show-tabs": "T", "show-nonprinting": "v", "show-all": "A" });
15438
+ if (parsed.flags.has("help")) {
15439
+ await output(context2, `Usage: cat [OPTION]... [FILE]...
15440
+ Concatenate FILEs to standard output. With no FILE, or FILE -, read standard input.
15441
+
15442
+ -n, --number Number all output lines
15443
+ -b, --number-nonblank Number nonempty output lines (overrides -n)
15444
+ -s, --squeeze-blank Suppress repeated empty output lines
15445
+ -E, --show-ends Display $ at each line end
15446
+ -T, --show-tabs Display TAB characters as ^I
15447
+ -v, --show-nonprinting Display nonprinting characters
15448
+ -A, --show-all Equivalent to -vET
15449
+ -e Equivalent to -vE
15450
+ -t Equivalent to -vT
15451
+ -u Accepted for compatibility; ignored
15452
+ --help Display this help and exit
15453
+ -- End options; remaining arguments are filenames
15454
+ `);
15455
+ return { exitCode: 0 };
15456
+ }
15349
15457
  await assertInputRequirements(context2, parsed.operands);
15350
15458
  if (parsed.flags.has("A")) for (const flag of ["v", "E", "T"]) parsed.flags.add(flag);
15351
15459
  if (parsed.flags.has("e")) {
@@ -25721,7 +25829,7 @@ async function execute2(program, context2, files, quiet, budget, separator, outp
25721
25829
  const character = pattern[offset];
25722
25830
  const lineEnd = character === "\n" && separator === "\n";
25723
25831
  const token = character === void 0 || lineEnd ? "$" : escapes3[character] ?? (character.charCodeAt(0) < 32 || character.charCodeAt(0) >= 127 ? `\\${character.charCodeAt(0).toString(8).padStart(3, "0")}` : character);
25724
- if (line.length + token.length >= 60) {
25832
+ if (character !== void 0 && !lineEnd && line.length + token.length >= 70) {
25725
25833
  await emit2(line + "\\" + separator);
25726
25834
  line = "";
25727
25835
  }
@@ -25882,6 +25990,14 @@ function sedCommand(options3 = {}) {
25882
25990
  separator = "\0";
25883
25991
  continue;
25884
25992
  }
25993
+ if (argument2 === "--quiet") {
25994
+ quiet = true;
25995
+ continue;
25996
+ }
25997
+ if (argument2 === "--regexp-extended") {
25998
+ extended = true;
25999
+ continue;
26000
+ }
25885
26001
  if (argument2.startsWith("--")) throw new ProgramError(`unsupported option '${argument2}'`);
25886
26002
  for (let position = 1; position < argument2.length; position++) {
25887
26003
  const flag = argument2[position];
@@ -28513,6 +28629,21 @@ async function sortedKeys(value2, budget) {
28513
28629
  await stableSort(keys2, budget, (left, right) => stringCompare(left, right, budget));
28514
28630
  return keys2;
28515
28631
  }
28632
+ async function sortObjectKeys(value2, budget) {
28633
+ await budget.tick();
28634
+ if (Array.isArray(value2)) {
28635
+ budget.collection(value2.length);
28636
+ const result2 = [];
28637
+ for (const item of value2) result2.push(await sortObjectKeys(item, budget));
28638
+ return result2;
28639
+ }
28640
+ if (isObject(value2)) {
28641
+ const result2 = object();
28642
+ for (const key of await sortedKeys(value2, budget)) put(result2, key, await sortObjectKeys(value2[key], budget));
28643
+ return result2;
28644
+ }
28645
+ return value2;
28646
+ }
28516
28647
  async function compare4(left, right, budget) {
28517
28648
  await budget.tick();
28518
28649
  const rank2 = (value2) => value2 === null ? 0 : value2 === false ? 1 : value2 === true ? 2 : isNumber(value2) ? 3 : typeof value2 === "string" ? 4 : Array.isArray(value2) ? 5 : 6;
@@ -29757,7 +29888,7 @@ function argumentsFor(args, budget) {
29757
29888
  argumentBytes += Buffer.byteLength(argument2);
29758
29889
  if (argumentBytes > budget.limits.maxInputBytes) throw new JqLimitError("maxInputBytes");
29759
29890
  }
29760
- const options3 = { raw: false, rawInput: false, joinOutput: false, compact: false, slurp: false, nullInput: false, exitStatus: false, source: void 0, programFile: void 0, files: [], variables: /* @__PURE__ */ new Map() };
29891
+ const options3 = { raw: false, rawInput: false, joinOutput: false, compact: false, sortKeys: false, slurp: false, nullInput: false, exitStatus: false, source: void 0, programFile: void 0, files: [], variables: /* @__PURE__ */ new Map() };
29761
29892
  const named2 = object();
29762
29893
  let ended = false;
29763
29894
  let variableBytes = 0;
@@ -29798,10 +29929,10 @@ function argumentsFor(args, budget) {
29798
29929
  options3.programFile = operand();
29799
29930
  continue;
29800
29931
  }
29801
- const long = { "--raw-output": "r", "--raw-input": "R", "--join-output": "j", "--compact-output": "c", "--slurp": "s", "--null-input": "n", "--exit-status": "e" };
29932
+ const long = { "--raw-output": "r", "--raw-input": "R", "--join-output": "j", "--compact-output": "c", "--sort-keys": "S", "--slurp": "s", "--null-input": "n", "--exit-status": "e" };
29802
29933
  if (!ended && argument2.startsWith("-") && argument2 !== "-") {
29803
29934
  const flags4 = Object.hasOwn(long, argument2) ? long[argument2] : argument2.startsWith("--") ? "" : argument2.slice(1);
29804
- if (!flags4 || !/^[rRjcsne]+$/u.test(flags4)) throw new JqError(`unsupported option ${argument2}`, 2);
29935
+ if (!flags4 || [...flags4].some((flag) => !"rRjcSsne".includes(flag))) throw new JqError(`unsupported option ${argument2}`, 2);
29805
29936
  for (const flag of flags4) {
29806
29937
  if (flag === "r") options3.raw = true;
29807
29938
  else if (flag === "R") options3.rawInput = true;
@@ -29809,6 +29940,7 @@ function argumentsFor(args, budget) {
29809
29940
  options3.joinOutput = true;
29810
29941
  options3.raw = true;
29811
29942
  } else if (flag === "c") options3.compact = true;
29943
+ else if (flag === "S") options3.sortKeys = true;
29812
29944
  else if (flag === "s") options3.slurp = true;
29813
29945
  else if (flag === "n") options3.nullInput = true;
29814
29946
  else options3.exitStatus = true;
@@ -29934,7 +30066,8 @@ async function execute3(context2, limits) {
29934
30066
  if (++budget.results > limits.maxResults) throw new JqLimitError("maxResults");
29935
30067
  const remaining = limits.maxOutputBytes - budget.outputBytes;
29936
30068
  const suffix2 = options3.joinOutput ? "" : "\n";
29937
- const text4 = options3.raw && typeof result2 === "string" ? result2 : await stringify(result2, budget, !options3.compact, Math.max(0, remaining - suffix2.length), "maxOutputBytes");
30069
+ const output3 = options3.sortKeys ? await sortObjectKeys(result2, budget) : result2;
30070
+ const text4 = options3.raw && typeof output3 === "string" ? output3 : await stringify(output3, budget, !options3.compact, Math.max(0, remaining - suffix2.length), "maxOutputBytes");
29938
30071
  const bytes8 = Buffer.from(`${text4}${suffix2}`);
29939
30072
  if (bytes8.byteLength > remaining) throw new JqLimitError("maxOutputBytes");
29940
30073
  budget.outputBytes += bytes8.byteLength;
@@ -30315,6 +30448,9 @@ function parse6(args) {
30315
30448
  return output3;
30316
30449
  };
30317
30450
  switch (flag) {
30451
+ case "help":
30452
+ result2.help = true;
30453
+ break;
30318
30454
  case "e":
30319
30455
  case "regexp":
30320
30456
  result2.explicitPatterns = true;
@@ -30560,7 +30696,7 @@ function parse6(args) {
30560
30696
  }
30561
30697
  }
30562
30698
  if (result2.before > 1e5 || result2.after > 1e5) throw new SearchError("context limit exceeded");
30563
- if (result2.mode !== "files" && !result2.explicitPatterns) {
30699
+ if (!result2.help && result2.mode !== "files" && !result2.explicitPatterns) {
30564
30700
  const pattern = operands.shift();
30565
30701
  if (pattern === void 0) throw new SearchError("a search pattern is required");
30566
30702
  result2.patterns.push(pattern);
@@ -31154,6 +31290,65 @@ function createRgCommand(executor, options3 = {}) {
31154
31290
  try {
31155
31291
  const limits = new Limits(context2, options3);
31156
31292
  args = parse6(context2.args);
31293
+ if (args.help) {
31294
+ await limits.output(Buffer.from(`Usage: rg [OPTIONS] PATTERN [PATH ...]
31295
+ Search files for PATTERN. PATH - reads standard input.
31296
+ Default input depends on shell configuration.
31297
+
31298
+ -e, --regexp=PATTERN Add a pattern (repeatable)
31299
+ -f, --file=FILE Read patterns from FILE
31300
+ -F, --fixed-strings Use fixed strings
31301
+ -i, --ignore-case Ignore case distinctions
31302
+ -s, --case-sensitive Match case sensitively
31303
+ -S, --smart-case Infer case sensitivity from the pattern
31304
+ -v, --invert-match Select nonmatching lines
31305
+ -w, --word-regexp Match whole words
31306
+ -x, --line-regexp Match whole lines
31307
+ -n, --line-number Print line numbers
31308
+ -N, --no-line-number Suppress line numbers
31309
+ -H, --with-filename Print filenames
31310
+ -I, --no-filename Suppress filenames
31311
+ -o, --only-matching Print matching parts
31312
+ -l, --files-with-matches Print filenames with matches
31313
+ --files-without-match Print filenames without matches
31314
+ --files List files without searching
31315
+ -c, --count Print matching line counts
31316
+ --count-matches Print match counts
31317
+ --json Emit JSON events
31318
+ -q, --quiet Suppress normal output
31319
+ -g, --glob=GLOB Include or exclude paths (repeatable)
31320
+ --iglob=GLOB Case-insensitive glob
31321
+ -t, --type=TYPE Include a file type
31322
+ -T, --type-not=TYPE Exclude a file type
31323
+ -., --hidden Search hidden files
31324
+ -L, --follow Follow symbolic links
31325
+ --no-ignore Disable ignore-file filtering
31326
+ -u, --unrestricted Relax ignore, hidden and binary filtering (repeatable)
31327
+ -a, --text Search binary files as text
31328
+ -A, --after-context=NUM Print NUM lines after matches
31329
+ -B, --before-context=NUM Print NUM lines before matches
31330
+ -C, --context=NUM Print NUM lines before and after matches
31331
+ -m, --max-count=NUM Limit matching lines per file
31332
+ --max-depth=NUM Limit directory traversal depth (maximum 128)
31333
+ --column Print columns
31334
+ -b, --byte-offset Print byte offsets
31335
+ -0, --null NUL-terminate filenames
31336
+ --null-data Use NUL-delimited records
31337
+ --crlf Handle CRLF line endings
31338
+ --heading Group output by filename
31339
+ --sort=path Sort paths
31340
+ --color=never Disable color
31341
+ --help Display this help and exit
31342
+ -- End options
31343
+
31344
+ Exit status: 0 when a match is found, 1 when none is found, 2 on error.
31345
+ Regular expression support depends on the configured regex executor.
31346
+ The default supports UTF-8 literals and bounded ASCII regular expressions.
31347
+ Regex operators: . ^ $ [...] (...) | * + ? {n,m}; -F treats patterns literally.
31348
+ Word/case flags and extended regex syntax require a configured executor.
31349
+ `));
31350
+ return { exitCode: 0 };
31351
+ }
31157
31352
  if (args.mode !== "files" && args.patternFiles.includes("-") && args.paths.includes("-")) {
31158
31353
  throw new SearchError("cannot search stdin while also reading patterns from stdin");
31159
31354
  }
@@ -31211,7 +31406,51 @@ var maxPatternCount = 1024;
31211
31406
  function createGrepCommands(executor) {
31212
31407
  return [{ name: "grep", filesystemRequirements: grepRequirements, execute: (context2) => withRegexSession(context2, executor, async (session) => {
31213
31408
  try {
31214
- const parsed = options2(context2.args, "EFivnclLqhHowxae:f:m:sz", { "extended-regexp": "E", "fixed-strings": "F", "ignore-case": "i", "invert-match": "v", "line-number": "n", count: "c", "files-with-matches": "l", "files-without-match": "L", quiet: "q", silent: "q", "no-filename": "h", "with-filename": "H", "only-matching": "o", "word-regexp": "w", "line-regexp": "x", regexp: "e", file: "f", "max-count": "m", "no-messages": "s", text: "a", "null-data": "z" });
31409
+ const contextLengths = /* @__PURE__ */ new Map();
31410
+ const parsed = options2(context2.args, "EFivnclLqhHowxae:f:m:szA:B:C:", { help: false, "extended-regexp": "E", "fixed-strings": "F", "ignore-case": "i", "invert-match": "v", "line-number": "n", count: "c", "files-with-matches": "l", "files-without-match": "L", quiet: "q", silent: "q", "no-filename": "h", "with-filename": "H", "only-matching": "o", "word-regexp": "w", "line-regexp": "x", regexp: "e", file: "f", "max-count": "m", "no-messages": "s", text: "a", "null-data": "z", "after-context": "A", "before-context": "B", context: "C" }, false, void 0, (key, index, offset) => {
31411
+ if (!["A", "B", "C"].includes(key)) return;
31412
+ const text4 = context2.args[index].slice(offset);
31413
+ try {
31414
+ contextLengths.set(key, integer2(text4));
31415
+ } catch {
31416
+ throw new UsageError(`${text4}: invalid context length argument`);
31417
+ }
31418
+ });
31419
+ if (parsed.flags.has("help")) {
31420
+ await output(context2, `Usage: grep [OPTION]... PATTERN [FILE]...
31421
+ Print lines matching PATTERN. With no FILE, or FILE -, read standard input.
31422
+
31423
+ -E, --extended-regexp Use extended regular expressions
31424
+ -F, --fixed-strings Use fixed strings
31425
+ -e, --regexp=PATTERN Add a pattern (repeatable)
31426
+ -f, --file=FILE Read patterns from FILE
31427
+ -i, --ignore-case Ignore case distinctions
31428
+ -v, --invert-match Select nonmatching lines
31429
+ -w, --word-regexp Match whole words
31430
+ -x, --line-regexp Match whole lines
31431
+ -n, --line-number Print line numbers
31432
+ -H, --with-filename Print filenames
31433
+ -h, --no-filename Suppress filenames
31434
+ -o, --only-matching Print only matching parts
31435
+ -c, --count Print matching line counts
31436
+ -l, --files-with-matches Print filenames with matches
31437
+ -L, --files-without-match Print filenames without matches
31438
+ -q, --quiet, --silent Suppress normal output
31439
+ -m, --max-count=NUM Stop after NUM selected lines per file
31440
+ -A, --after-context=NUM Print NUM lines after selected lines
31441
+ -B, --before-context=NUM Print NUM lines before selected lines
31442
+ -C, --context=NUM Print NUM lines before and after selected lines
31443
+ -s, --no-messages Suppress file error messages
31444
+ -a, --text Process input as text
31445
+ -z, --null-data Use NUL-delimited records
31446
+ --help Display this help and exit
31447
+ -- End options
31448
+
31449
+ Exit status: 0 when a line is selected, 1 when none is selected, 2 on error.
31450
+ Regular expression support depends on the configured regex executor.
31451
+ `);
31452
+ return { exitCode: 0 };
31453
+ }
31215
31454
  let positionalPattern;
31216
31455
  if (!parsed.flags.has("e") && !parsed.flags.has("f")) {
31217
31456
  if (!parsed.operands.length) throw new UsageError("missing pattern");
@@ -31273,13 +31512,30 @@ function createGrepCommands(executor) {
31273
31512
  const batchSize = Number.isFinite(maxCount) || parsed.flags.has("q") || parsed.flags.has("l") || parsed.flags.has("L") ? 1 : 128;
31274
31513
  const delimiter = parsed.flags.has("z") ? "\0" : "\n";
31275
31514
  const extractMatches = parsed.flags.has("o") && !["c", "q", "l", "L", "v"].some((flag) => parsed.flags.has(flag));
31515
+ const displayLines = !["c", "q", "l", "L"].some((flag) => parsed.flags.has(flag));
31516
+ const withContext = contextLengths.size > 0 && displayLines && !(parsed.flags.has("o") && parsed.flags.has("v"));
31517
+ const before = withContext ? contextLengths.get("B") ?? contextLengths.get("C") ?? 0 : 0;
31518
+ const after = withContext ? contextLengths.get("A") ?? contextLengths.get("C") ?? 0 : 0;
31519
+ let emittedGroup = false;
31276
31520
  let anySelected = false;
31277
31521
  let failed = false;
31278
31522
  for (const name2 of names) {
31279
31523
  let count2 = 0;
31280
31524
  let number8 = 0;
31525
+ let lastCovered = 0;
31526
+ let remainingAfter = 0;
31527
+ let pendingBytes = 0;
31528
+ const pending = /* @__PURE__ */ new Map();
31281
31529
  const named2 = name2 === "-" ? "(standard input)" : name2;
31282
- const prefix3 = (lineNumber = false) => `${!parsed.flags.has("h") && (parsed.flags.has("H") || names.length > 1) ? `${named2}:` : ""}${lineNumber && parsed.flags.has("n") ? `${number8}:` : ""}`;
31530
+ const prefix3 = (lineNumber = false, position = number8, separator = ":") => `${!parsed.flags.has("h") && (parsed.flags.has("H") || names.length > 1) ? `${named2}${separator}` : ""}${lineNumber && parsed.flags.has("n") ? `${position}${separator}` : ""}`;
31531
+ const emitContext = async (line, position) => {
31532
+ if (!parsed.flags.has("o")) {
31533
+ await output(context2, prefix3(true, position, "-"));
31534
+ await output(context2, line.bytes);
31535
+ await output(context2, delimiter);
31536
+ }
31537
+ lastCovered = position;
31538
+ };
31283
31539
  try {
31284
31540
  const available2 = new AvailableRecords(parsed.flags.has("z") ? 0 : 10, bufferLimit);
31285
31541
  const source2 = name2 === "-" ? input(context2) : requiredFileInput(context2, grepRequirements, "file", name2, bufferLimit);
@@ -31290,12 +31546,40 @@ function createGrepCommands(executor) {
31290
31546
  context2.signal.throwIfAborted();
31291
31547
  number8++;
31292
31548
  const found = results[index];
31293
- if (found.length > 0 === parsed.flags.has("v")) continue;
31549
+ const selected = count2 < maxCount && found.length > 0 !== parsed.flags.has("v");
31550
+ if (!selected) {
31551
+ if (remainingAfter > 0) {
31552
+ await emitContext(line, number8);
31553
+ remainingAfter--;
31554
+ if (count2 >= maxCount && remainingAfter === 0) break records;
31555
+ } else if (before > 0) {
31556
+ if (pending.size >= before) {
31557
+ const oldest = pending.keys().next().value;
31558
+ pendingBytes -= pending.get(oldest).bytes.length + 1;
31559
+ pending.delete(oldest);
31560
+ }
31561
+ const size = line.bytes.length + 1;
31562
+ if (size > bufferLimit - pendingBytes) throw new UsageError(`context byte limit exceeded (${bufferLimit} bytes)`);
31563
+ pending.set(number8, { bytes: Uint8Array.from(line.bytes), terminated: line.terminated });
31564
+ pendingBytes += size;
31565
+ }
31566
+ continue;
31567
+ }
31294
31568
  count2++;
31295
31569
  if (!parsed.flags.has("L")) anySelected = true;
31296
31570
  if (parsed.flags.has("q")) return { exitCode: 0 };
31297
31571
  if (parsed.flags.has("l") || parsed.flags.has("L")) break records;
31298
31572
  if (!parsed.flags.has("c")) {
31573
+ if (withContext) {
31574
+ const first = pending.keys().next().value ?? number8;
31575
+ if (emittedGroup && (lastCovered === 0 || first > lastCovered + 1)) await output(context2, "--\n");
31576
+ for (const [position, previous] of pending) await emitContext(previous, position);
31577
+ pending.clear();
31578
+ pendingBytes = 0;
31579
+ remainingAfter = after;
31580
+ lastCovered = number8;
31581
+ emittedGroup = true;
31582
+ }
31299
31583
  if (parsed.flags.has("o")) {
31300
31584
  if (!parsed.flags.has("v")) {
31301
31585
  let end = -1;
@@ -31313,7 +31597,7 @@ function createGrepCommands(executor) {
31313
31597
  await output(context2, delimiter);
31314
31598
  }
31315
31599
  }
31316
- if (count2 >= maxCount) break records;
31600
+ if (count2 >= maxCount && remainingAfter === 0) break records;
31317
31601
  }
31318
31602
  }
31319
31603
  if (parsed.flags.has("l") && count2 > 0 || parsed.flags.has("L") && count2 === 0) {
@@ -37886,6 +38170,7 @@ async function parseOptions2(context2, limits) {
37886
38170
  if (values3.has(flag) && value2 === void 0) value2 = context2.args[++index];
37887
38171
  if (values3.has(flag) && value2 === void 0) fail2(`missing argument for --${name2}`);
37888
38172
  if (!values3.has(flag) && value2 !== void 0) fail2(`option --${name2} does not take an argument`);
38173
+ if (flag === "help") return "help";
37889
38174
  await apply(flag, value2);
37890
38175
  } else if (!end && (argument2.startsWith("-") && argument2 !== "-" || index === 0 && /^[ctxzvfCT]+$/u.test(argument2))) {
37891
38176
  const old = !argument2.startsWith("-");
@@ -43621,6 +43906,33 @@ function createTarCommand(options3 = {}) {
43621
43906
  const context2 = { ...original, signal };
43622
43907
  try {
43623
43908
  const parsed = await parseOptions2(context2, limits);
43909
+ if (parsed === "help") {
43910
+ await writeBytes(context2.stdout, Buffer.from(`Usage: tar [OPTION]... [FILE]...
43911
+ Create, list or extract USTAR/PAX archives in the virtual filesystem.
43912
+
43913
+ -c, --create Create an archive
43914
+ -t, --list List archive members
43915
+ -x, --extract, --get Extract archive members
43916
+ -f, --file=ARCHIVE Use ARCHIVE (default - for standard input/output)
43917
+ -z, --gzip Use gzip compression
43918
+ -v, --verbose List processed members
43919
+ -C, --directory=DIR Change directory for subsequent operands
43920
+ -T, --files-from=FILE Read filenames from FILE (- for standard input)
43921
+ --null Read NUL-delimited filenames; implies verbatim names
43922
+ --no-null Read newline-delimited filenames
43923
+ --verbatim-files-from Treat file-list entries as literal filenames
43924
+ --no-verbatim-files-from Enable supported file-list directory options
43925
+ --exclude=PATTERN Exclude paths (place before source operands)
43926
+ --strip-components=NUM Remove leading components when reading archives
43927
+ --format=FORMAT Create pax (default), posix or ustar archives
43928
+ --help Display this help and exit
43929
+ -- End options; remaining arguments are filenames
43930
+
43931
+ Exactly one of -c, -t or -x is required for archive operations.
43932
+ Examples: tar cf archive.tar file; tar tf archive.tar; tar xf archive.tar -C directory
43933
+ `), signal);
43934
+ return { exitCode: 0 };
43935
+ }
43624
43936
  const budget = new Budget18(context2, limits);
43625
43937
  if (parsed.mode === "c") {
43626
43938
  const prepared = await manifest(context2, parsed, budget);
@@ -87918,4 +88230,4 @@ export {
87918
88230
  isAbsolutePath3 as isAbsolutePath,
87919
88231
  posixPath2 as posixPath
87920
88232
  };
87921
- //# sourceMappingURL=chunk-54JM3XZC.js.map
88233
+ //# sourceMappingURL=chunk-LYH24BKM.js.map