@xiaoso/dsh-tool-plus 0.1.16 → 0.1.17-beta.0

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 (109) hide show
  1. package/lib/{abort-DZ54CaKU.mjs → abort-BTblp0Rt.mjs} +2 -2
  2. package/lib/{alibaba-coding-plan-DODpkcqi.mjs → alibaba-coding-plan-t3R4YKCB.mjs} +3 -3
  3. package/lib/{alibaba-token-plan-C6lpKCda.mjs → alibaba-token-plan-CO4djG1y.mjs} +4 -4
  4. package/lib/{alibaba-token-plan-CHGyWOfX.mjs → alibaba-token-plan-CUjYJX0-.mjs} +1 -1
  5. package/lib/{anthropic-Dv_GGX6g.mjs → anthropic-nf7w6so1.mjs} +48 -21
  6. package/lib/{api-key-validation-MnMf_ihX.mjs → api-key-validation-C_tZ7Y9a.mjs} +2 -2
  7. package/lib/behavior-BwvTUtag.mjs +111 -0
  8. package/lib/{browser-render-BZXt548F.mjs → browser-render-BQaEVK_n.mjs} +4 -4
  9. package/lib/{reference-CtvM4zLU.mjs → bundled-references-CrQ4dQcT.mjs} +57 -4
  10. package/lib/cascade-BWjRTD1q.mjs +30265 -0
  11. package/lib/{cline-pass-BT9CBEOj.mjs → cline-pass-Bjm-O8GG.mjs} +2 -2
  12. package/lib/cloudflare-CKXRJ0l9.mjs +37 -0
  13. package/lib/{cloudflare-ai-gateway-DReN6ohJ.mjs → cloudflare-ai-gateway-BpnBSjwV.mjs} +8 -4
  14. package/lib/cloudflare-workers-ai-odj9XswL.mjs +32 -0
  15. package/lib/collapse-_nkb2dn7.mjs +1945 -0
  16. package/lib/{coreweave-C82HrLpb.mjs → coreweave-CGDZOD8-.mjs} +1 -1
  17. package/lib/{coreweave-C68UgRQO.mjs → coreweave-DwffcgW5.mjs} +4 -4
  18. package/lib/cursor-BgOuV7Qf.mjs +794 -0
  19. package/lib/{cursor-_gHHq-Dq.mjs → cursor-CF1iHHbv.mjs} +68 -19
  20. package/lib/{cursor-proto-Cr_WEMuv.mjs → cursor-proto-BuNTjX3L.mjs} +823 -23
  21. package/lib/{devin-QpfTSl9H.mjs → devin-7OEeEb80.mjs} +112 -31
  22. package/lib/{devin-proto-DYhp4Ty6.mjs → devin-proto-C-QreeAv.mjs} +71 -5
  23. package/lib/{dom-DG3sPESc.mjs → dom-BmbZv4v9.mjs} +598 -182
  24. package/lib/{error-O63pC8zg.mjs → error-8LVo7tug.mjs} +725 -104
  25. package/lib/factory-droid-ChhmsGWb.mjs +71 -0
  26. package/lib/{fs-promises-shim-B2YFWkcd.mjs → fs-promises-shim-CANAxFWh.mjs} +10 -1
  27. package/lib/{github-copilot-BMEcw8N1.mjs → github-copilot-QwevdT30.mjs} +4 -4
  28. package/lib/{github-copilot-headers-DnjGEbko.mjs → github-copilot-headers-CAUZ0rUD.mjs} +138 -26
  29. package/lib/{gitlab-duo-DnHqJjFY.mjs → gitlab-duo-DigV7k_o.mjs} +2 -2
  30. package/lib/{google-antigravity-B1mSckrK.mjs → google-antigravity-D-oe0r8A.mjs} +6 -7
  31. package/lib/{google-gemini-cli-DJwThCCn.mjs → google-gemini-cli-CQBHgGJT.mjs} +5 -6
  32. package/lib/{google-oauth-shared-BctLpVUN.mjs → google-oauth-shared-CvgVIUwJ.mjs} +2 -2
  33. package/lib/google-validation-CdvRj4ec.mjs +126 -0
  34. package/lib/id-EJwVLDHE.mjs +2548 -0
  35. package/lib/index.mjs +248 -258
  36. package/lib/{kilo-BEgEwMJQ.mjs → kilo-5r6OffCa.mjs} +2 -2
  37. package/lib/{kimi-T9NldEIJ.mjs → kimi-DOOtbXmm.mjs} +9 -10
  38. package/lib/{launch-BIWNyrBB.mjs → launch-DkAjib7h.mjs} +1 -1
  39. package/lib/{markit-Dvp2JPdT.mjs → markit-CCcyeAds.mjs} +359 -140
  40. package/lib/{models-DnXMYGcJ.mjs → models-DCpDT_im.mjs} +199203 -112275
  41. package/lib/{muse-code-CNvqqAp6.mjs → muse-code-CYf8zj_B.mjs} +5 -5
  42. package/lib/{openai-codex-D5-CyTxa.mjs → openai-codex-Cj-TvSFh.mjs} +13 -10
  43. package/lib/{perplexity-A2PEoGaC.mjs → perplexity-Dh_Qgsmx.mjs} +68 -25
  44. package/lib/{pkce-BYjmugmw.mjs → pkce-DO-jBJLV.mjs} +1 -1
  45. package/lib/pricing-DusBEhwm.mjs +593 -0
  46. package/lib/{readability-uGhqb4GC.mjs → readability-XHK0o3bv.mjs} +287 -27
  47. package/lib/{scrapers-C1ujjV8k.mjs → scrapers-B6PADOVm.mjs} +13 -13
  48. package/lib/slugify-ynYWBIA5.mjs +11 -0
  49. package/lib/snowflake-B_jap6lz.mjs +666 -0
  50. package/lib/snowflake-Cu1ZyOp6.mjs +151 -0
  51. package/lib/{src-AELUUb5U.mjs → src-BhinCSpi.mjs} +1172 -458
  52. package/lib/{stream-AVOoe5Hj.mjs → stream-D2ivg3GH.mjs} +3740 -5311
  53. package/lib/{turndown-D6fof1OX.mjs → turndown-Vya8SavL.mjs} +82 -30
  54. package/lib/types/tools/hashline/native/index.d.ts +2 -2
  55. package/lib/types/tools/hashline/native/policy.d.ts +19 -21
  56. package/lib/types/tools/omp/session/agent-storage.d.ts +3 -3
  57. package/lib/types/tools/shared/bun-named-shim.d.ts +5 -0
  58. package/lib/{types-BLrLohwK.mjs → types-tH1v9uRm.mjs} +2 -2
  59. package/lib/{utils-cZX3f_Ls.mjs → utils-C_Ncya1r.mjs} +1737 -509
  60. package/lib/utils-D2tK38xq.mjs +34006 -0
  61. package/lib/{utils-I4I8azHN.mjs → utils-DrDwmNtu.mjs} +8 -3
  62. package/lib/{xai-oauth-CbeldUSV.mjs → xai-oauth-DLLzX6my.mjs} +4 -4
  63. package/lib/{xiaomi-Dl3VSs04.mjs → xiaomi-CqK-KivK.mjs} +2 -2
  64. package/lib/{zai-FyjGSypr.mjs → zai-DoJ2xPIH.mjs} +2 -2
  65. package/lib/{zip-DRrycScC.mjs → zip-DG1mUV6X.mjs} +1 -1
  66. package/package.json +8 -8
  67. package/lib/amazon-bedrock-Dx0rr9dY.mjs +0 -996
  68. package/lib/anthropic-ClCw0PV_.mjs +0 -3624
  69. package/lib/anthropic-wire-lbGAFzYb.mjs +0 -927
  70. package/lib/azure-openai-responses-WE_bgFWp.mjs +0 -285
  71. package/lib/bundled-references-DY3EJxZV.mjs +0 -56
  72. package/lib/cloudflare-ai-gateway-CrMa97Ap.mjs +0 -44
  73. package/lib/collapse-CkMNRNr7.mjs +0 -2304
  74. package/lib/cursor-C6jaIJDg.mjs +0 -283
  75. package/lib/cursor-D-XZYDf_.mjs +0 -4544
  76. package/lib/deterministic-id-CUEIMSqR.mjs +0 -17
  77. package/lib/devin-ExGIghmx.mjs +0 -69
  78. package/lib/devin-u0ljw5P6.mjs +0 -628
  79. package/lib/effort-BdtQMN-_.mjs +0 -23
  80. package/lib/event-stream-BKEtb45Y.mjs +0 -167
  81. package/lib/gemini-headers-Co9cVvex.mjs +0 -54
  82. package/lib/google-auth-qAN-6DMW.mjs +0 -232
  83. package/lib/google-gemini-cli-B2Aw1S5w.mjs +0 -844
  84. package/lib/google-lTxuq28n.mjs +0 -38
  85. package/lib/google-shared-Y01j9xOr.mjs +0 -856
  86. package/lib/google-validation-BEkNs-Bx.mjs +0 -18
  87. package/lib/google-vertex-DcM-FRC5.mjs +0 -99
  88. package/lib/hosts-00rjRzUD.mjs +0 -203
  89. package/lib/id-AL5obQzR.mjs +0 -71
  90. package/lib/idle-iterator-D0ZXEcUq.mjs +0 -366
  91. package/lib/ollama-6R0oXZks.mjs +0 -574
  92. package/lib/openai-codex-responses-C8bnBWOe.mjs +0 -3232
  93. package/lib/openai-completions-DNr3mUsn.mjs +0 -1430
  94. package/lib/openai-configuration-update-xMYUjaK_.mjs +0 -150
  95. package/lib/openai-reasoning-fallback-Ju-5pSR8.mjs +0 -380
  96. package/lib/openai-responses-CjpafAEr.mjs +0 -861
  97. package/lib/protobuf-BMgDYu_U.mjs +0 -717
  98. package/lib/provider-response-SqKSkkUc.mjs +0 -22
  99. package/lib/proxy-DxvCQOCA.mjs +0 -230
  100. package/lib/request-debug-BwPOqN_j.mjs +0 -183
  101. package/lib/sanitize-text-BCf5KmCf.mjs +0 -33
  102. package/lib/sse-debug-B-tkLCPW.mjs +0 -11
  103. package/lib/stream-markup-healing-CN3RsqG9.mjs +0 -267
  104. package/lib/strict-tool-validation-CBTz1dAA.mjs +0 -105
  105. package/lib/taxonomy-DSIM99rS.mjs +0 -15392
  106. package/lib/thinking-ngMwf_1Y.mjs +0 -336
  107. package/lib/type-guards-CttAANEx.mjs +0 -11
  108. package/lib/utils-CE3DSebh.mjs +0 -11763
  109. package/lib/vision-guard-BCpXWUj3.mjs +0 -77
@@ -1,14 +1,15 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- import { n as fs_promises_shim_exports } from "./fs-promises-shim-B2YFWkcd.mjs";
4
- import { k as formatBytes } from "./src-AELUUb5U.mjs";
5
- import { l as unzip, u as unzipText } from "./zip-DRrycScC.mjs";
6
- import { n as normalizeTablesHtml, t as createTurndown } from "./turndown-D6fof1OX.mjs";
3
+ import { n as fs_promises_shim_exports } from "./fs-promises-shim-CANAxFWh.mjs";
4
+ import { R as formatBytes } from "./src-BhinCSpi.mjs";
5
+ import { l as unzip, u as unzipText } from "./zip-DG1mUV6X.mjs";
6
+ import { n as normalizeTablesHtml, t as createTurndown } from "./turndown-Vya8SavL.mjs";
7
7
  import { pdfToMarkdown } from "@oh-my-pi/pi-natives";
8
8
  import * as path$1 from "node:path";
9
- import * as zlib from "node:zlib";
10
9
  import { promisify } from "node:util";
11
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/error.ts
10
+ import * as zlib from "node:zlib";
11
+ import { Readable } from "node:stream";
12
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/error.ts
12
13
  /**
13
14
  * Error raised for invalid, unsupported, or unsafe archive input. The message
14
15
  * is safe to surface directly to users/models; callers that need a different
@@ -21,7 +22,7 @@ var ArchiveError = class extends Error {
21
22
  }
22
23
  };
23
24
  //#endregion
24
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/bytes.ts
25
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/bytes.ts
25
26
  /** Shared UTF-8 decoder for archive member names and text payloads. */
26
27
  const UTF8_DECODER$2 = new TextDecoder();
27
28
  function readUInt16LE(bytes, offset) {
@@ -49,7 +50,7 @@ function bytesMatchAscii(bytes, offset, value) {
49
50
  return true;
50
51
  }
51
52
  //#endregion
52
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/paths.ts
53
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/paths.ts
53
54
  const PATH_ERROR_PREVIEW_BYTES = 256;
54
55
  /**
55
56
  * Normalize a user-supplied lookup path inside an archive. Returns `""` for
@@ -107,10 +108,11 @@ function assertArchivePathString(value, field, maxPathBytes) {
107
108
  assertArchivePathBytes(Buffer.byteLength(value, "utf-8"), field, maxPathBytes);
108
109
  }
109
110
  //#endregion
110
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/limits.ts
111
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/limits.ts
111
112
  const DEFAULT_ARCHIVE_LIMITS = {
112
113
  maxEntries: 1e6,
113
114
  maxInMemorySize: 268435456,
115
+ maxStreamSize: 4294967296,
114
116
  maxIndexSize: 67108864,
115
117
  maxMemberSize: 67108864,
116
118
  maxPathBytes: 4096,
@@ -140,7 +142,7 @@ function assertEntryCount(count, limits) {
140
142
  if (count > limits.maxEntries) throw new ArchiveError(`Archive has too many entries (> ${limits.maxEntries} limit)`);
141
143
  }
142
144
  //#endregion
143
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/entries.ts
145
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/entries.ts
144
146
  /**
145
147
  * Insert `entry` into the index map with archive append/update semantics:
146
148
  * files replace directories of the same path, directories never shadow files,
@@ -215,7 +217,7 @@ function resolveArchiveLinkPath(entries, archivePath, maxLinkDepth) {
215
217
  throw new ArchiveError(`Archive path '${archivePath}' crosses a cyclic symlink`);
216
218
  }
217
219
  //#endregion
218
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/reader.ts
220
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/reader.ts
219
221
  /** Raise the canonical error for a symlink whose target cannot be materialized. */
220
222
  function throwUnreadableArchiveLink(targetPath, memberPath) {
221
223
  throw new ArchiveError(`Archive symlink '${formatArchivePathForError(memberPath)}' cannot be materialized from target '${formatArchivePathForError(targetPath)}'`);
@@ -329,7 +331,7 @@ var ArchiveReader = class {
329
331
  }
330
332
  };
331
333
  //#endregion
332
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/checksums.ts
334
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/checksums.ts
333
335
  /** CRC-32 (IEEE 802.3, reflected). Chainable: pass the previous value as `seed`. */
334
336
  function crc32(bytes, seed = 0) {
335
337
  return Bun.hash.crc32(bytes, seed) >>> 0;
@@ -380,7 +382,7 @@ function crc16Arc(bytes, seed = 0) {
380
382
  return value;
381
383
  }
382
384
  //#endregion
383
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/source.ts
385
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/source.ts
384
386
  /** Reject a nonsensical `[start, end)` range before any read. */
385
387
  function assertValidRange(start, end) {
386
388
  if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start) throw new ArchiveError("Invalid archive range");
@@ -419,8 +421,35 @@ function fileByteSource(filePath) {
419
421
  async function readAllBytes(source) {
420
422
  return source.read(0, source.size);
421
423
  }
424
+ /** Chunk size for streamed decompression, on both the compressed and the decompressed side. */
425
+ const STREAM_CHUNK_SIZE = 1048576;
426
+ async function* readChunks(source) {
427
+ for (let start = 0; start < source.size; start += STREAM_CHUNK_SIZE) yield await source.read(start, Math.min(source.size, start + STREAM_CHUNK_SIZE));
428
+ }
429
+ /**
430
+ * Decompress a {@link ByteSource} through `decoder` chunk by chunk, so neither
431
+ * the compressed nor the decompressed stream is ever held whole. Output past
432
+ * `maxOutput` bytes fails, so a decompression bomb cannot run without bound.
433
+ */
434
+ async function* decodeByteSource(source, decoder, maxOutput) {
435
+ const input = Readable.from(readChunks(source));
436
+ input.once("error", (error) => decoder.destroy(error));
437
+ let output = 0;
438
+ try {
439
+ for await (const chunk of input.pipe(decoder)) {
440
+ output += chunk.byteLength;
441
+ if (output > maxOutput) throw new ArchiveError(`Archive decompresses past the ${formatBytes(maxOutput)} stream limit`);
442
+ yield chunk;
443
+ }
444
+ } catch (error) {
445
+ if (error instanceof ArchiveError) throw error;
446
+ throw new ArchiveError(error instanceof Error ? error.message : String(error));
447
+ } finally {
448
+ input.destroy();
449
+ }
450
+ }
422
451
  //#endregion
423
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/lzh.ts
452
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/lzh.ts
424
453
  const LEGACY_DECODER$1 = new TextDecoder("windows-1252");
425
454
  const UTF16LE_DECODER = new TextDecoder("utf-16");
426
455
  const LHA_METHOD_PATTERN = /^-(?:lh[0-7d]|lz[45s])-$/;
@@ -939,7 +968,7 @@ const readLzh = async (source, options) => {
939
968
  return entries;
940
969
  };
941
970
  //#endregion
942
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/arj.ts
971
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/arj.ts
943
972
  const ARJ_SIGNATURE_0 = 96;
944
973
  const ARJ_SIGNATURE_1 = 234;
945
974
  const ARJ_MAX_BASIC_HEADER = 2600;
@@ -1189,7 +1218,7 @@ const readArj = async (source, options) => {
1189
1218
  return entries;
1190
1219
  };
1191
1220
  //#endregion
1192
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/asar.ts
1221
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/asar.ts
1193
1222
  const ASAR_HEADER_DECODER = new TextDecoder("utf-8", { fatal: true });
1194
1223
  new TextEncoder();
1195
1224
  const ASAR_PICKLE_PREFIX_SIZE = 8;
@@ -1417,7 +1446,7 @@ const readAsar = async (source, options) => {
1417
1446
  }
1418
1447
  };
1419
1448
  //#endregion
1420
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/lzx.ts
1449
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/lzx.ts
1421
1450
  const FRAME_SIZE = 32768;
1422
1451
  const MIN_MATCH = 2;
1423
1452
  const NUM_PRIMARY_LENGTHS = 7;
@@ -1731,7 +1760,7 @@ var LzxDecoder = class {
1731
1760
  }
1732
1761
  };
1733
1762
  //#endregion
1734
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/cab.ts
1763
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/cab.ts
1735
1764
  const CAB_SIGNATURE = "MSCF";
1736
1765
  const FIXED_HEADER_SIZE = 36;
1737
1766
  const DATA_BLOCK_SIZE = 8;
@@ -1997,7 +2026,7 @@ const readCab = async (source, options) => {
1997
2026
  }
1998
2027
  };
1999
2028
  //#endregion
2000
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/bzip2.ts
2029
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/bzip2.ts
2001
2030
  const BLOCK_MAGIC = [
2002
2031
  49,
2003
2032
  65,
@@ -2863,8 +2892,12 @@ async function gzipDecompress(bytes, maxOutput) {
2863
2892
  throw new ArchiveError(error instanceof Error ? error.message : String(error));
2864
2893
  }
2865
2894
  }
2895
+ /** Decompress a gzip source as a stream of chunks, bounded to `maxOutput` bytes, for output too large to hold at once. */
2896
+ function gzipDecompressStream(source, maxOutput) {
2897
+ return decodeByteSource(source, zlib.createGunzip({ chunkSize: STREAM_CHUNK_SIZE }), maxOutput);
2898
+ }
2866
2899
  //#endregion
2867
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/lzma.ts
2900
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/lzma.ts
2868
2901
  const TOP_VALUE = 1 << 24;
2869
2902
  const BIT_MODEL_TOTAL = 2048;
2870
2903
  const MOVE_BITS = 5;
@@ -3247,7 +3280,7 @@ async function lzma2Decompress(dictSizeProp, bytes, maxOutput) {
3247
3280
  }
3248
3281
  }
3249
3282
  //#endregion
3250
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/lzw.ts
3283
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/lzw.ts
3251
3284
  const CLEAR_CODE = 256;
3252
3285
  const FIRST_BLOCK_CODE = 257;
3253
3286
  const MIN_BITS = 9;
@@ -3377,7 +3410,7 @@ async function lzwDecompress(bytes, maxOutput) {
3377
3410
  }
3378
3411
  }
3379
3412
  //#endregion
3380
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/xz.ts
3413
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/codecs/xz.ts
3381
3414
  const XZ_MAGIC = Uint8Array.of(253, 55, 122, 88, 90, 0);
3382
3415
  function read32LE$1(bytes, offset) {
3383
3416
  if (offset < 0 || offset + 4 > bytes.byteLength) throw new ArchiveError("Invalid XZ stream: truncated integer");
@@ -3855,8 +3888,12 @@ async function zstdDecompress(bytes, maxOutput) {
3855
3888
  throw new ArchiveError(error instanceof Error ? error.message : String(error));
3856
3889
  }
3857
3890
  }
3891
+ /** Decompress a zstd source as a stream of chunks, bounded to `maxOutput` bytes, for output too large to hold at once. */
3892
+ function zstdDecompressStream(source, maxOutput) {
3893
+ return decodeByteSource(source, zlib.createZstdDecompress({ chunkSize: STREAM_CHUNK_SIZE }), maxOutput);
3894
+ }
3858
3895
  //#endregion
3859
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/cpio.ts
3896
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/cpio.ts
3860
3897
  const NEWC_HEADER_SIZE = 110;
3861
3898
  const ODC_HEADER_SIZE = 76;
3862
3899
  const BINARY_HEADER_SIZE = 26;
@@ -4158,7 +4195,7 @@ function sniffCpio(bytes) {
4158
4195
  }
4159
4196
  }
4160
4197
  //#endregion
4161
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/tar.ts
4198
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/tar.ts
4162
4199
  const BLOCK_SIZE = 512;
4163
4200
  const NAME_OFFSET = 0;
4164
4201
  const NAME_LENGTH = 100;
@@ -4185,21 +4222,120 @@ const MAX_PAX_NUMERIC_BYTES = 32;
4185
4222
  const PAX_SPARSE_MARKER = "GNU.sparse.";
4186
4223
  const TEXT_DECODER = new TextDecoder();
4187
4224
  new TextEncoder();
4188
- var TarMemberSource = class {
4225
+ /** Forward-only reader over tar bytes that arrive in chunks: one buffer, or a decompressing stream. */
4226
+ var TarByteStream = class {
4227
+ #chunks;
4228
+ #chunk = /* @__PURE__ */ new Uint8Array(0);
4229
+ #position = 0;
4230
+ constructor(chunks) {
4231
+ this.#chunks = Symbol.asyncIterator in chunks ? chunks[Symbol.asyncIterator]() : chunks[Symbol.iterator]();
4232
+ }
4233
+ /** Bytes consumed so far. */
4234
+ get position() {
4235
+ return this.#position;
4236
+ }
4237
+ /** The next `length` bytes; shorter only when the stream ends first. */
4238
+ async read(length) {
4239
+ if (this.#chunk.byteLength >= length) {
4240
+ const bytes = this.#chunk.subarray(0, length);
4241
+ this.#chunk = this.#chunk.subarray(length);
4242
+ this.#position += length;
4243
+ return bytes;
4244
+ }
4245
+ const bytes = new Uint8Array(length);
4246
+ let filled = 0;
4247
+ while (filled < length && (this.#chunk.byteLength > 0 || await this.#next())) {
4248
+ const take = Math.min(length - filled, this.#chunk.byteLength);
4249
+ bytes.set(this.#chunk.subarray(0, take), filled);
4250
+ this.#chunk = this.#chunk.subarray(take);
4251
+ filled += take;
4252
+ }
4253
+ this.#position += filled;
4254
+ return filled === length ? bytes : bytes.subarray(0, filled);
4255
+ }
4256
+ /** Step over `length` bytes; false when the stream ends first. */
4257
+ async skip(length) {
4258
+ let remaining = length;
4259
+ while (remaining > 0) {
4260
+ if (this.#chunk.byteLength === 0 && !await this.#next()) return false;
4261
+ const take = Math.min(remaining, this.#chunk.byteLength);
4262
+ this.#chunk = this.#chunk.subarray(take);
4263
+ this.#position += take;
4264
+ remaining -= take;
4265
+ }
4266
+ return true;
4267
+ }
4268
+ /** Stop the underlying stream without draining it. */
4269
+ async close() {
4270
+ await this.#chunks.return?.();
4271
+ }
4272
+ async #next() {
4273
+ const result = await this.#chunks.next();
4274
+ if (result.done) return false;
4275
+ this.#chunk = result.value;
4276
+ return true;
4277
+ }
4278
+ };
4279
+ var TarBufferPayload = class {
4189
4280
  #buffer;
4281
+ constructor(buffer) {
4282
+ this.#buffer = buffer;
4283
+ }
4284
+ async read(offset, size, memberPath) {
4285
+ if (size > this.#buffer.byteLength - offset) throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' is truncated`);
4286
+ const bytes = this.#buffer.subarray(offset, offset + size);
4287
+ if (bytes.byteLength !== size) throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' has an invalid size`);
4288
+ return bytes;
4289
+ }
4290
+ };
4291
+ /**
4292
+ * Member bytes of a tar too large to hold decompressed: each read decompresses
4293
+ * the stream again up to the member. Reads are serialized, and a read ahead of
4294
+ * the previous one continues that pass, so reading every member in archive
4295
+ * order decompresses the stream once.
4296
+ */
4297
+ var TarStreamPayload = class {
4298
+ #open;
4299
+ #stream;
4300
+ #pending = Promise.resolve();
4301
+ constructor(open) {
4302
+ this.#open = open;
4303
+ }
4304
+ read(offset, size, memberPath) {
4305
+ const bytes = this.#pending.then(() => this.#readAt(offset, size, memberPath));
4306
+ this.#pending = bytes.catch(() => void 0);
4307
+ return bytes;
4308
+ }
4309
+ async #readAt(offset, size, memberPath) {
4310
+ let stream = this.#stream;
4311
+ this.#stream = void 0;
4312
+ if (!stream || stream.position > offset) {
4313
+ await stream?.close();
4314
+ stream = new TarByteStream(this.#open());
4315
+ }
4316
+ try {
4317
+ const bytes = await stream.skip(offset - stream.position) ? await stream.read(size) : void 0;
4318
+ if (bytes?.byteLength !== size) throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' is truncated`);
4319
+ this.#stream = stream;
4320
+ return bytes.byteLength === bytes.buffer.byteLength ? bytes : new Uint8Array(bytes);
4321
+ } catch (error) {
4322
+ await stream.close();
4323
+ throw error;
4324
+ }
4325
+ }
4326
+ };
4327
+ var TarMemberSource = class {
4328
+ #payload;
4190
4329
  #dataOffset;
4191
4330
  #sparse;
4192
- constructor(buffer, dataOffset, sparse) {
4193
- this.#buffer = buffer;
4331
+ constructor(payload, dataOffset, sparse) {
4332
+ this.#payload = payload;
4194
4333
  this.#dataOffset = dataOffset;
4195
4334
  this.#sparse = sparse;
4196
4335
  }
4197
4336
  async read(size, memberPath) {
4198
4337
  if (this.#sparse) throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' is a sparse file and cannot be read`);
4199
- if (size > this.#buffer.byteLength - this.#dataOffset) throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' is truncated`);
4200
- const bytes = this.#buffer.subarray(this.#dataOffset, this.#dataOffset + size);
4201
- if (bytes.byteLength !== size) throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' has an invalid size`);
4202
- return bytes;
4338
+ return this.#payload.read(this.#dataOffset, size, memberPath);
4203
4339
  }
4204
4340
  };
4205
4341
  function readTarString(buffer, offset, length) {
@@ -4271,7 +4407,6 @@ function checksumMatches(buffer, offset) {
4271
4407
  return stored === unsigned || stored === signed;
4272
4408
  }
4273
4409
  function parsePaxRecords(data, limits) {
4274
- assertIndexSize(data.byteLength, limits, "tar PAX metadata");
4275
4410
  const attrs = /* @__PURE__ */ new Map();
4276
4411
  let pos = 0;
4277
4412
  while (pos < data.byteLength) {
@@ -4348,7 +4483,6 @@ function renameOldGnuEntries(entries, pendingLinks, fromPath, toPath, limits) {
4348
4483
  for (const pending of pendingLinks.values()) if (pending.kind === "hard link" && (pending.targetPath === fromPath || pending.targetPath.startsWith(`${fromPath}/`))) pending.targetPath = `${toPath}${pending.targetPath.slice(fromPath.length)}`;
4349
4484
  }
4350
4485
  function applyOldGnuNameRecords(data, entries, pendingLinks, limits) {
4351
- assertIndexSize(data.byteLength, limits, "old-GNU name metadata");
4352
4486
  const terminator = data.indexOf(0);
4353
4487
  const end = terminator === -1 ? data.byteLength : terminator;
4354
4488
  let start = 0;
@@ -4448,10 +4582,19 @@ function resolvePendingLinks(entries, pendingLinks, limits) {
4448
4582
  }
4449
4583
  if (unresolved.size > 0) throw new ArchiveError("Archive contains cyclic or unsupported links");
4450
4584
  }
4451
- /** Index an already-decompressed tar buffer with bounded GNU, ustar, and PAX handling. */
4452
- function readTarEntriesFromBuffer(buffer, options) {
4585
+ /** Read one metadata record's payload, bounded by `maxIndexSize`, and step over its padding. */
4586
+ async function readTarMetadata(stream, size, limits, what) {
4587
+ assertIndexSize(size, limits, what);
4588
+ const data = await stream.read(size);
4589
+ if (data.byteLength !== size || !await stream.skip(paddedSize(size) - size)) throw new ArchiveError("Archive member data is truncated");
4590
+ return data;
4591
+ }
4592
+ /**
4593
+ * Walk tar headers with bounded GNU, ustar, and PAX handling. Member data is
4594
+ * stepped over, never held: entries point into `payload` by stream offset.
4595
+ */
4596
+ async function readTarEntries(stream, payload, options) {
4453
4597
  const { limits } = options;
4454
- assertInMemorySize(buffer.byteLength, limits);
4455
4598
  const entries = /* @__PURE__ */ new Map();
4456
4599
  const pendingLinks = /* @__PURE__ */ new Map();
4457
4600
  const addEntry = (entry, pendingLink) => {
@@ -4462,59 +4605,46 @@ function readTarEntriesFromBuffer(buffer, options) {
4462
4605
  if (pendingLink) pendingLinks.set(indexed, pendingLink);
4463
4606
  assertEntryCount(entries.size, limits);
4464
4607
  };
4465
- let offset = 0;
4466
4608
  let longName;
4467
4609
  let longLink;
4468
4610
  let localPax;
4469
4611
  const globalPax = /* @__PURE__ */ new Map();
4470
4612
  let sawTerminator = false;
4471
- while (offset + BLOCK_SIZE <= buffer.byteLength) {
4472
- if (isZeroBlock(buffer, offset)) {
4613
+ for (let header = await stream.read(BLOCK_SIZE); header.byteLength === BLOCK_SIZE; header = await stream.read(BLOCK_SIZE)) {
4614
+ if (isZeroBlock(header, 0)) {
4473
4615
  sawTerminator = true;
4474
4616
  break;
4475
4617
  }
4476
- if (!checksumMatches(buffer, offset)) throw new ArchiveError("Invalid or corrupt tar archive header");
4477
- const headerOffset = offset;
4478
- const typeFlag = String.fromCharCode(buffer[headerOffset + TYPEFLAG_OFFSET] || 48);
4479
- let size = readTarSize(buffer, headerOffset + SIZE_OFFSET);
4480
- let name = readTarString(buffer, headerOffset + NAME_OFFSET, NAME_LENGTH);
4481
- if (isUstarHeader(buffer, headerOffset)) {
4482
- const prefix = readTarString(buffer, headerOffset + PREFIX_OFFSET, PREFIX_LENGTH);
4618
+ if (!checksumMatches(header, 0)) throw new ArchiveError("Invalid or corrupt tar archive header");
4619
+ const typeFlag = String.fromCharCode(header[TYPEFLAG_OFFSET] || 48);
4620
+ let size = readTarSize(header, SIZE_OFFSET);
4621
+ let name = readTarString(header, NAME_OFFSET, NAME_LENGTH);
4622
+ if (isUstarHeader(header, 0)) {
4623
+ const prefix = readTarString(header, PREFIX_OFFSET, PREFIX_LENGTH);
4483
4624
  if (prefix) name = `${prefix}/${name}`;
4484
4625
  }
4485
- let linkName = readTarString(buffer, headerOffset + LINKNAME_OFFSET, LINKNAME_LENGTH);
4486
- const mtime = readTarNumeric(buffer, headerOffset + MTIME_OFFSET, MTIME_LENGTH);
4487
- const rawMode = readTarNumeric(buffer, headerOffset + MODE_OFFSET, MODE_LENGTH);
4626
+ let linkName = readTarString(header, LINKNAME_OFFSET, LINKNAME_LENGTH);
4627
+ const mtime = readTarNumeric(header, MTIME_OFFSET, MTIME_LENGTH);
4628
+ const rawMode = readTarNumeric(header, MODE_OFFSET, MODE_LENGTH);
4488
4629
  const mode = Number.isSafeInteger(rawMode) && rawMode >= 0 ? rawMode : void 0;
4489
- offset += BLOCK_SIZE;
4490
- const dataBlocks = paddedSize(size);
4491
- if (dataBlocks > buffer.byteLength - offset) throw new ArchiveError("Archive member data is truncated");
4492
- const data = buffer.subarray(offset, offset + size);
4493
4630
  if (typeFlag === "L") {
4494
- assertIndexSize(data.byteLength, limits, "GNU long-name metadata");
4495
- longName = readMetadataPath(data, "GNU long path", limits);
4496
- offset += dataBlocks;
4631
+ longName = readMetadataPath(await readTarMetadata(stream, size, limits, "GNU long-name metadata"), "GNU long path", limits);
4497
4632
  continue;
4498
4633
  }
4499
4634
  if (typeFlag === "K") {
4500
- assertIndexSize(data.byteLength, limits, "GNU long-link metadata");
4501
- longLink = readMetadataPath(data, "GNU long link target", limits);
4502
- offset += dataBlocks;
4635
+ longLink = readMetadataPath(await readTarMetadata(stream, size, limits, "GNU long-link metadata"), "GNU long link target", limits);
4503
4636
  continue;
4504
4637
  }
4505
4638
  if (typeFlag === "N") {
4506
- applyOldGnuNameRecords(data, entries, pendingLinks, limits);
4507
- offset += dataBlocks;
4639
+ applyOldGnuNameRecords(await readTarMetadata(stream, size, limits, "old-GNU name metadata"), entries, pendingLinks, limits);
4508
4640
  continue;
4509
4641
  }
4510
4642
  if (typeFlag === "x" || typeFlag === "X") {
4511
- localPax = parsePaxRecords(data, limits);
4512
- offset += dataBlocks;
4643
+ localPax = parsePaxRecords(await readTarMetadata(stream, size, limits, "tar PAX metadata"), limits);
4513
4644
  continue;
4514
4645
  }
4515
4646
  if (typeFlag === "g") {
4516
- applyGlobalPax(globalPax, parsePaxRecords(data, limits));
4517
- offset += dataBlocks;
4647
+ applyGlobalPax(globalPax, parsePaxRecords(await readTarMetadata(stream, size, limits, "tar PAX metadata"), limits));
4518
4648
  continue;
4519
4649
  }
4520
4650
  if (typeFlag === "M") throw new ArchiveError("GNU multi-volume tar members are not supported");
@@ -4532,18 +4662,16 @@ function readTarEntriesFromBuffer(buffer, options) {
4532
4662
  const paxSparseRealSize = paxAttribute(globalPax, localPax, "GNU.sparse.realsize");
4533
4663
  if (paxSparseRealSize !== void 0) displaySize = parsePaxSize(paxSparseRealSize, "sparse real size");
4534
4664
  const sparse = typeFlag === "S" || paxDeclaresSparse(globalPax, localPax);
4535
- if (typeFlag === "S" && buffer[headerOffset + GNU_SPARSE_ISEXTENDED_OFFSET] === 1) {
4665
+ if (typeFlag === "S" && header[GNU_SPARSE_ISEXTENDED_OFFSET] === 1) {
4536
4666
  let extended = true;
4537
4667
  while (extended) {
4538
- if (offset + BLOCK_SIZE > buffer.byteLength) throw new ArchiveError("Archive sparse metadata is truncated");
4539
- extended = buffer[offset + GNU_SPARSE_CONT_ISEXTENDED_OFFSET] === 1;
4540
- offset += BLOCK_SIZE;
4668
+ const block = await stream.read(BLOCK_SIZE);
4669
+ if (block.byteLength < BLOCK_SIZE) throw new ArchiveError("Archive sparse metadata is truncated");
4670
+ extended = block[GNU_SPARSE_CONT_ISEXTENDED_OFFSET] === 1;
4541
4671
  }
4542
4672
  }
4543
- const dataOffset = offset;
4544
- const memberDataBlocks = paddedSize(size);
4545
- if (memberDataBlocks > buffer.byteLength - dataOffset) throw new ArchiveError(`Archive member '${formatArchivePathForError(name)}' is truncated`);
4546
- offset += memberDataBlocks;
4673
+ const dataOffset = stream.position;
4674
+ if (!await stream.skip(paddedSize(size))) throw new ArchiveError(`Archive member '${formatArchivePathForError(name)}' is truncated`);
4547
4675
  longName = void 0;
4548
4676
  longLink = void 0;
4549
4677
  localPax = void 0;
@@ -4601,7 +4729,7 @@ function readTarEntriesFromBuffer(buffer, options) {
4601
4729
  mode,
4602
4730
  storage: {
4603
4731
  type: "member",
4604
- source: new TarMemberSource(buffer, dataOffset, sparse)
4732
+ source: new TarMemberSource(payload, dataOffset, sparse)
4605
4733
  }
4606
4734
  });
4607
4735
  }
@@ -4609,6 +4737,25 @@ function readTarEntriesFromBuffer(buffer, options) {
4609
4737
  resolvePendingLinks(entries, pendingLinks, limits);
4610
4738
  return [...entries.values()];
4611
4739
  }
4740
+ /** Index an already-decompressed tar buffer; members are views into it. */
4741
+ async function readTarEntriesFromBuffer(buffer, options) {
4742
+ assertInMemorySize(buffer.byteLength, options.limits);
4743
+ return readTarEntries(new TarByteStream([buffer]), new TarBufferPayload(buffer), options);
4744
+ }
4745
+ /**
4746
+ * Index a decompressed tar stream that is too large to hold in memory: one
4747
+ * pass over `open()` walks the headers, and member reads open it again.
4748
+ */
4749
+ async function readTarEntriesFromStream(open, options) {
4750
+ const stream = new TarByteStream(open());
4751
+ try {
4752
+ const entries = await readTarEntries(stream, new TarStreamPayload(open), options);
4753
+ await stream.skip(Number.POSITIVE_INFINITY);
4754
+ return entries;
4755
+ } finally {
4756
+ await stream.close();
4757
+ }
4758
+ }
4612
4759
  /** Read and index a tar source after one bounded whole-stream read. */
4613
4760
  const readTar = async (source, options) => {
4614
4761
  assertInMemorySize(source.size, options.limits);
@@ -4635,7 +4782,7 @@ function sniffTar(bytes) {
4635
4782
  }
4636
4783
  }
4637
4784
  //#endregion
4638
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/unix-ar.ts
4785
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/unix-ar.ts
4639
4786
  const SIGNATURE$1 = "!<arch>\n";
4640
4787
  const HEADER_SIZE = 60;
4641
4788
  const NAME_SIZE = 16;
@@ -4848,7 +4995,7 @@ function sniffUnixAr(bytes) {
4848
4995
  return bytesMatchAscii(bytes, 0, SIGNATURE$1);
4849
4996
  }
4850
4997
  //#endregion
4851
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/deb.ts
4998
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/deb.ts
4852
4999
  const AR_SIGNATURE = "!<arch>\n";
4853
5000
  const DEBIAN_BINARY = "debian-binary";
4854
5001
  function firstArMemberName(bytes) {
@@ -4950,7 +5097,7 @@ async function readDebImpl(source, options) {
4950
5097
  upsertArchiveEntry(result, outerEntry);
4951
5098
  continue;
4952
5099
  }
4953
- const innerEntries = readTarEntriesFromBuffer(await decompressDebTar(await readOuterMember(outerEntry), tar.compression, options), options);
5100
+ const innerEntries = await readTarEntriesFromBuffer(await decompressDebTar(await readOuterMember(outerEntry), tar.compression, options), options);
4954
5101
  for (const innerEntry of innerEntries) upsertArchiveEntry(result, tar.kind === "control" ? prefixControlEntry(innerEntry) : innerEntry);
4955
5102
  }
4956
5103
  ensureParentDirectories(result, options.limits);
@@ -4970,7 +5117,7 @@ function sniffDeb(bytes) {
4970
5117
  return firstArMemberName(bytes) === DEBIAN_BINARY;
4971
5118
  }
4972
5119
  //#endregion
4973
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/iso.ts
5120
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/iso.ts
4974
5121
  const ISO_SECTOR_SIZE = 2048;
4975
5122
  const VOLUME_DESCRIPTOR_START = 16 * ISO_SECTOR_SIZE;
4976
5123
  const MAX_DIRECTORY_DEPTH = 256;
@@ -5479,7 +5626,7 @@ const readIso = async (source, options) => {
5479
5626
  }
5480
5627
  };
5481
5628
  //#endregion
5482
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/rar/rar4-decoder.ts
5629
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/rar/rar4-decoder.ts
5483
5630
  const MAIN_SIZE$1 = 299;
5484
5631
  const DIST_SIZE$1 = 60;
5485
5632
  const LOW_DIST_SIZE = 17;
@@ -5987,7 +6134,7 @@ function corrupt$1(reason) {
5987
6134
  throw new ArchiveError(`Invalid RAR4 archive: ${reason}`);
5988
6135
  }
5989
6136
  //#endregion
5990
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/rar/rar5-decoder.ts
6137
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/rar/rar5-decoder.ts
5991
6138
  const MAIN_SIZE = 306;
5992
6139
  const DIST_SIZE = 80;
5993
6140
  const ALIGN_SIZE = 16;
@@ -6387,7 +6534,7 @@ function fail(reason) {
6387
6534
  throw new ArchiveError(`Invalid RAR5 archive: ${reason}`);
6388
6535
  }
6389
6536
  //#endregion
6390
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/rar.ts
6537
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/rar.ts
6391
6538
  const RAR4_MARKER = Uint8Array.of(82, 97, 114, 33, 26, 7, 0);
6392
6539
  const RAR5_MARKER = Uint8Array.of(82, 97, 114, 33, 26, 7, 1, 0);
6393
6540
  const UTF8$1 = new TextDecoder("utf-8", { fatal: true });
@@ -7019,7 +7166,7 @@ function corrupt(reason) {
7019
7166
  throw new ArchiveError(`Invalid RAR archive: ${reason}`);
7020
7167
  }
7021
7168
  //#endregion
7022
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/rpm.ts
7169
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/rpm.ts
7023
7170
  const RPM_LEAD_SIZE = 96;
7024
7171
  const RPM_HEADER_INTRO_SIZE = 16;
7025
7172
  const RPM_INDEX_ENTRY_SIZE = 16;
@@ -7236,7 +7383,7 @@ function sniffRpm(bytes) {
7236
7383
  return bytes.byteLength >= 4 && bytes[0] === 237 && bytes[1] === 171 && bytes[2] === 238 && bytes[3] === 219;
7237
7384
  }
7238
7385
  //#endregion
7239
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/sevenzip/decode.ts
7386
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/sevenzip/decode.ts
7240
7387
  function methodName(id) {
7241
7388
  switch (id) {
7242
7389
  case 0n: return "Copy";
@@ -7400,7 +7547,7 @@ var SevenZipFolderSource = class {
7400
7547
  }
7401
7548
  };
7402
7549
  //#endregion
7403
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/sevenzip.ts
7550
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/sevenzip.ts
7404
7551
  const SIGNATURE = Uint8Array.of(55, 122, 188, 175, 39, 28);
7405
7552
  const UTF16_LE = new TextDecoder("utf-16", { fatal: true });
7406
7553
  const UTF8 = new TextDecoder("utf-8", { fatal: true });
@@ -7962,7 +8109,7 @@ const readSevenZip = async (source, options) => {
7962
8109
  }
7963
8110
  };
7964
8111
  //#endregion
7965
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/zip.ts
8112
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/zip.ts
7966
8113
  const LOCAL_HEADER_SIGNATURE = 67324752;
7967
8114
  const CENTRAL_HEADER_SIGNATURE = 33639248;
7968
8115
  const ZIP64_EOCD_SIGNATURE = 101075792;
@@ -8340,7 +8487,7 @@ const readZip = async (source, options) => {
8340
8487
  }
8341
8488
  };
8342
8489
  //#endregion
8343
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/ar/registry.ts
8490
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/registry.ts
8344
8491
  /** Every recognized extension paired with its format, longest first. */
8345
8492
  const EXTENSION_TABLE = Object.entries({
8346
8493
  zip: [
@@ -8412,6 +8559,20 @@ var BufferMember = class {
8412
8559
  return this.#bytes;
8413
8560
  }
8414
8561
  };
8562
+ /** Index decompressed bytes as tar when they are one, else as a single stem-named member. */
8563
+ async function readDecompressed(inner, options) {
8564
+ assertInMemorySize(inner.byteLength, options.limits);
8565
+ if (sniffTar(inner)) return readTarEntriesFromBuffer(inner, options);
8566
+ return [{
8567
+ path: stemMemberName(options.archivePath),
8568
+ isDirectory: false,
8569
+ size: inner.byteLength,
8570
+ storage: {
8571
+ type: "member",
8572
+ source: new BufferMember(inner)
8573
+ }
8574
+ }];
8575
+ }
8415
8576
  /**
8416
8577
  * Reader for one compressed stream: decompress bounded, then index the inner
8417
8578
  * bytes as tar when they are one, else surface a single stem-named member.
@@ -8421,27 +8582,40 @@ var BufferMember = class {
8421
8582
  function compressedReader(decompress) {
8422
8583
  return async (source, options) => {
8423
8584
  assertInMemorySize(source.size, options.limits);
8424
- const inner = await decompress(await readAllBytes(source), options.limits.maxInMemorySize);
8425
- assertInMemorySize(inner.byteLength, options.limits);
8426
- if (sniffTar(inner)) return readTarEntriesFromBuffer(inner, options);
8427
- return [{
8428
- path: stemMemberName(options.archivePath),
8429
- isDirectory: false,
8430
- size: inner.byteLength,
8431
- storage: {
8432
- type: "member",
8433
- source: new BufferMember(inner)
8434
- }
8435
- }];
8585
+ return readDecompressed(await decompress(await readAllBytes(source), options.limits.maxInMemorySize), options);
8586
+ };
8587
+ }
8588
+ /**
8589
+ * {@link compressedReader} for codecs that decompress as a stream. Output that
8590
+ * fits `maxInMemorySize` is indexed the same way; a tar that inflates past it
8591
+ * is indexed by a streaming header walk instead, its members decompressed
8592
+ * again when read, so memory stays bounded by the limits either way. Each pass
8593
+ * stops at `maxStreamSize`.
8594
+ */
8595
+ function streamedReader(decompress) {
8596
+ return async (source, options) => {
8597
+ const { maxInMemorySize, maxStreamSize } = options.limits;
8598
+ const chunks = [];
8599
+ let size = 0;
8600
+ for await (const chunk of decompress(source, maxStreamSize)) {
8601
+ chunks.push(chunk);
8602
+ size += chunk.byteLength;
8603
+ if (size > maxInMemorySize) break;
8604
+ }
8605
+ const kept = Buffer.concat(chunks, size <= maxInMemorySize ? size : Math.min(size, 512));
8606
+ chunks.length = 0;
8607
+ if (size <= maxInMemorySize) return readDecompressed(kept, options);
8608
+ if (!sniffTar(kept)) throw new ArchiveError(`Archive is too large to read in memory (decompressed > ${formatBytes(maxInMemorySize)} limit)`);
8609
+ return readTarEntriesFromStream(() => decompress(source, maxStreamSize), options);
8436
8610
  };
8437
8611
  }
8438
8612
  const READERS = {
8439
8613
  zip: readZip,
8440
8614
  tar: readTar,
8441
- "tar.gz": compressedReader(gzipDecompress),
8615
+ "tar.gz": streamedReader(gzipDecompressStream),
8442
8616
  "tar.bz2": compressedReader(bzip2Decompress),
8443
8617
  "tar.xz": compressedReader(xzDecompress),
8444
- "tar.zst": compressedReader(zstdDecompress),
8618
+ "tar.zst": streamedReader(zstdDecompressStream),
8445
8619
  "tar.Z": compressedReader(lzwDecompress),
8446
8620
  asar: readAsar,
8447
8621
  rar: readRar,
@@ -8454,10 +8628,10 @@ const READERS = {
8454
8628
  deb: readDeb,
8455
8629
  lzh: readLzh,
8456
8630
  arj: readArj,
8457
- gz: compressedReader(gzipDecompress),
8631
+ gz: streamedReader(gzipDecompressStream),
8458
8632
  bz2: compressedReader(bzip2Decompress),
8459
8633
  xz: compressedReader(xzDecompress),
8460
- zst: compressedReader(zstdDecompress),
8634
+ zst: streamedReader(zstdDecompressStream),
8461
8635
  Z: compressedReader(lzwDecompress),
8462
8636
  lzma: compressedReader(lzmaAloneDecompress)
8463
8637
  };
@@ -8509,32 +8683,61 @@ async function openArchive(input, options = {}) {
8509
8683
  };
8510
8684
  return new ArchiveReader(format, await formatReaderFor(format)(source, readOptions), limits);
8511
8685
  }
8686
+ //#endregion
8687
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/ar/zip-package.ts
8512
8688
  /**
8513
- * Fully materialize every file member into a `path → bytes` map. Use this
8514
- * for whole-archive rewrite; browsing and single-member reads should use
8515
- * {@link openArchive} so payloads remain lazy. Total extracted bytes are
8516
- * bounded by `limits.maxInMemorySize`.
8689
+ * A ZIP-based document package (OOXML, EPUB) whose members are inflated only
8690
+ * when read. Lookups use exact member paths, so a converter sees the same
8691
+ * members a fully materialized `path → bytes` map would expose. Each member's
8692
+ * size counts once toward a cap on total inflated bytes, like a fully
8693
+ * materialized archive, so a crafted package cannot amplify past the in-memory
8694
+ * limit one member at a time.
8517
8695
  */
8518
- async function readArchiveEntries(input, options = {}) {
8519
- const archive = await openArchive(input, options);
8520
- const entries = /* @__PURE__ */ new Map();
8521
- let total = 0;
8522
- for (const entry of archive.indexEntries()) {
8523
- if (entry.isDirectory) continue;
8524
- const file = await archive.readFile(entry.path);
8525
- entries.set(entry.path, file.bytes);
8526
- total += file.bytes.byteLength;
8527
- assertInMemorySize(total, archive.limits);
8696
+ var ZipPackage = class ZipPackage {
8697
+ #archive;
8698
+ #members = /* @__PURE__ */ new Set();
8699
+ #limits;
8700
+ /** Members already counted toward {@link #inflated}; re-reading one is free against the cap. */
8701
+ #counted = /* @__PURE__ */ new Set();
8702
+ #inflated = 0;
8703
+ constructor(archive, maxTotalBytes = DEFAULT_ARCHIVE_LIMITS.maxInMemorySize) {
8704
+ this.#archive = archive;
8705
+ this.#limits = {
8706
+ ...DEFAULT_ARCHIVE_LIMITS,
8707
+ maxInMemorySize: maxTotalBytes
8708
+ };
8709
+ for (const entry of archive.indexEntries()) if (!entry.isDirectory) this.#members.add(entry.path);
8710
+ }
8711
+ /** Index a ZIP buffer without inflating any member. */
8712
+ static async open(bytes, maxTotalBytes) {
8713
+ return new ZipPackage(await openArchive({
8714
+ bytes,
8715
+ format: "zip"
8716
+ }), maxTotalBytes);
8717
+ }
8718
+ /** Exact paths of every file member. */
8719
+ get members() {
8720
+ return this.#members;
8721
+ }
8722
+ /** Inflate one member, or `undefined` when absent. Throws once distinct inflated bytes exceed the cap. */
8723
+ async readBytes(memberPath) {
8724
+ if (!this.#members.has(memberPath)) return void 0;
8725
+ const { bytes } = await this.#archive.readFile(memberPath);
8726
+ if (!this.#counted.has(memberPath)) {
8727
+ this.#counted.add(memberPath);
8728
+ this.#inflated += bytes.length;
8729
+ assertInMemorySize(this.#inflated, this.#limits);
8730
+ }
8731
+ return bytes;
8528
8732
  }
8529
- return entries;
8530
- }
8531
- /** Read one materialized member as UTF-8 text, or `undefined` when absent. */
8532
- function archiveEntryText(entries, entryPath) {
8533
- const bytes = entries.get(entryPath);
8534
- return bytes ? UTF8_DECODER$2.decode(bytes) : void 0;
8535
- }
8733
+ /** Inflate one member as UTF-8 text, or `undefined` when absent. */
8734
+ async readText(memberPath) {
8735
+ const bytes = await this.readBytes(memberPath);
8736
+ return bytes ? UTF8_DECODER$2.decode(bytes) : void 0;
8737
+ }
8738
+ };
8536
8739
  //#endregion
8537
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/docx/xml.ts
8740
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/docx/xml.ts
8538
8741
  const ENTITY_PATTERN = /&(?:#x[\da-fA-F]+|#\d+|amp|apos|gt|lt|quot);/g;
8539
8742
  const ATTRIBUTE_PATTERN = /([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
8540
8743
  function decodeEntities(value) {
@@ -8679,7 +8882,7 @@ function descendants(element, name) {
8679
8882
  return matches;
8680
8883
  }
8681
8884
  //#endregion
8682
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/docx/converter.ts
8885
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/docx/converter.ts
8683
8886
  /** Mammoth-shaped helpers for configuring embedded image conversion. */
8684
8887
  const images = {
8685
8888
  /** Wrap an image-to-attributes callback for `convertToHtml`. */
@@ -8885,8 +9088,8 @@ async function renderImage(element, context) {
8885
9088
  const relationship = relationshipId ? context.relationships.get(relationshipId) : void 0;
8886
9089
  if (!relationship || relationship.external) return "";
8887
9090
  const memberPath = relationshipPath(relationship.target);
8888
- const bytes = context.entries.get(memberPath);
8889
- if (!bytes) {
9091
+ const docx = context.package;
9092
+ if (!docx.members.has(memberPath)) {
8890
9093
  context.messages.push({
8891
9094
  type: "warning",
8892
9095
  message: `Could not find image ${memberPath}`
@@ -8901,13 +9104,23 @@ async function renderImage(element, context) {
8901
9104
  altText,
8902
9105
  async read(encoding) {
8903
9106
  if (encoding !== "base64") throw new Error(`Unsupported image encoding: ${encoding}`);
9107
+ const bytes = await readImageMember(docx, memberPath);
8904
9108
  return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
9109
+ },
9110
+ readBytes() {
9111
+ return readImageMember(docx, memberPath);
8905
9112
  }
8906
9113
  };
8907
9114
  const converted = await context.convertImage.convert(image);
8908
9115
  const attributes = Object.entries(converted).filter((entry) => typeof entry[1] === "string").sort(([left], [right]) => left.localeCompare(right)).map(([name, value]) => `${name}="${escapeAttribute(value)}"`).join(" ");
8909
9116
  return attributes ? `<img ${attributes} />` : "<img />";
8910
9117
  }
9118
+ /** Bytes of an image member already known to exist. */
9119
+ async function readImageMember(docx, memberPath) {
9120
+ const bytes = await docx.readBytes(memberPath);
9121
+ if (!bytes) throw new Error(`Could not find image ${memberPath}`);
9122
+ return bytes;
9123
+ }
8911
9124
  function renderFootnoteReference(element, context) {
8912
9125
  const id = attribute(element, "w:id");
8913
9126
  if (!id || !context.footnotes.has(id)) return "";
@@ -9137,24 +9350,22 @@ function defaultImageConverter() {
9137
9350
  }
9138
9351
  /** Convert a DOCX buffer or path to mammoth-compatible HTML. */
9139
9352
  async function convertToHtml(input, options = {}) {
9140
- const entries = await readArchiveEntries({
9141
- bytes: "buffer" in input && input.buffer ? input.buffer : await fs_promises_shim_exports.readFile(input.path),
9142
- format: "zip"
9143
- });
9144
- const documentXml = archiveEntryText(entries, "word/document.xml");
9353
+ const bytes = "buffer" in input && input.buffer ? input.buffer : await fs_promises_shim_exports.readFile(input.path);
9354
+ const docx = await ZipPackage.open(bytes);
9355
+ const documentXml = await docx.readText("word/document.xml");
9145
9356
  if (!documentXml) throw new Error("Invalid DOCX: missing word/document.xml");
9146
9357
  const context = {
9147
- entries,
9148
- relationships: parseRelationships(archiveEntryText(entries, "word/_rels/document.xml.rels")),
9149
- contentTypes: parseContentTypes(archiveEntryText(entries, "[Content_Types].xml")),
9150
- styles: parseStyles(archiveEntryText(entries, "word/styles.xml")),
9151
- numbering: parseNumbering(archiveEntryText(entries, "word/numbering.xml")),
9358
+ package: docx,
9359
+ relationships: parseRelationships(await docx.readText("word/_rels/document.xml.rels")),
9360
+ contentTypes: parseContentTypes(await docx.readText("[Content_Types].xml")),
9361
+ styles: parseStyles(await docx.readText("word/styles.xml")),
9362
+ numbering: parseNumbering(await docx.readText("word/numbering.xml")),
9152
9363
  messages: [],
9153
9364
  warnedStyles: /* @__PURE__ */ new Set(),
9154
9365
  customStyles: parseCustomStyles(options.styleMap),
9155
9366
  includeDefaultStyleMap: options.includeDefaultStyleMap !== false,
9156
9367
  convertImage: options.convertImage ?? defaultImageConverter(),
9157
- footnotes: parseFootnotes(archiveEntryText(entries, "word/footnotes.xml")),
9368
+ footnotes: parseFootnotes(await docx.readText("word/footnotes.xml")),
9158
9369
  usedFootnotes: [],
9159
9370
  footnoteOrdinals: /* @__PURE__ */ new Map()
9160
9371
  };
@@ -9166,7 +9377,7 @@ async function convertToHtml(input, options = {}) {
9166
9377
  };
9167
9378
  }
9168
9379
  //#endregion
9169
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/docx.ts
9380
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/docx.ts
9170
9381
  /** Mammoth-shaped default export for drop-in consumer imports. */
9171
9382
  const docx = {
9172
9383
  convertToHtml,
@@ -9215,7 +9426,7 @@ var DocxConverter = class {
9215
9426
  }
9216
9427
  };
9217
9428
  //#endregion
9218
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/xml.ts
9429
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/xml.ts
9219
9430
  const STANDARD_ENTITIES = {
9220
9431
  amp: "&",
9221
9432
  apos: "'",
@@ -9269,6 +9480,10 @@ var XmlReader = class {
9269
9480
  this.#readProcessingInstruction(document);
9270
9481
  continue;
9271
9482
  }
9483
+ if (this.#xml.startsWith("</", this.#position)) {
9484
+ this.#skipThrough(">");
9485
+ continue;
9486
+ }
9272
9487
  if (this.#xml[this.#position] === "<") {
9273
9488
  const element = this.#readElement("");
9274
9489
  this.#addValue(document, element.name, element.name, element.value, element.leaf, null);
@@ -9302,6 +9517,9 @@ var XmlReader = class {
9302
9517
  this.#position++;
9303
9518
  this.#skipWhitespace();
9304
9519
  value = this.#readAttributeValue();
9520
+ } else if (attributeName === "") {
9521
+ this.#position++;
9522
+ continue;
9305
9523
  }
9306
9524
  attributes.push([attributeName, value]);
9307
9525
  }
@@ -9315,6 +9533,7 @@ var XmlReader = class {
9315
9533
  this.#position = close < 0 ? this.#xml.length : close + 1;
9316
9534
  break;
9317
9535
  }
9536
+ if (this.#xml.startsWith("</", this.#position)) break;
9318
9537
  if (this.#xml.startsWith("<![CDATA[", this.#position)) {
9319
9538
  const end = this.#xml.indexOf("]]>", this.#position + 9);
9320
9539
  const normalized = this.#xml.slice(this.#position + 9, end < 0 ? this.#xml.length : end);