@poe-platform/safe-bash 0.1.801 → 0.1.803

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 (198) hide show
  1. package/README.md +4 -2
  2. package/dist/image-ast/index.browser.js +16 -5
  3. package/dist/image-ast/index.js +16 -5
  4. package/dist/safe-bash/chunks/chunk-2LSAMQER.js +84 -0
  5. package/dist/safe-bash/chunks/chunk-3HQU4OJO.js +13 -0
  6. package/dist/safe-bash/chunks/chunk-4BSJLKNM.js +14 -0
  7. package/dist/safe-bash/chunks/chunk-4D4N7IU2.js +47 -0
  8. package/dist/safe-bash/chunks/chunk-55YJASTN.js +14 -0
  9. package/dist/safe-bash/chunks/{chunk-NZQXYWA3.js → chunk-5OHX7C2V.js} +0 -1
  10. package/dist/safe-bash/chunks/chunk-7ZBU7KYV.js +14 -0
  11. package/dist/safe-bash/chunks/{chunk-7VNF5BFF.js → chunk-B7PIL77G.js} +101 -415
  12. package/dist/safe-bash/chunks/chunk-DQP3VHSB.js +15 -0
  13. package/dist/safe-bash/chunks/{chunk-VQDD3G76.js → chunk-EEEWOYEG.js} +18 -18
  14. package/dist/safe-bash/chunks/chunk-FZE4HW6G.js +11 -0
  15. package/dist/safe-bash/chunks/{chunk-45PK3NWI.js → chunk-GDYNCWRV.js} +1 -1
  16. package/dist/safe-bash/chunks/chunk-GEG3BWGE.js +14 -0
  17. package/dist/safe-bash/chunks/chunk-HBCN24ZA.js +50 -0
  18. package/dist/safe-bash/chunks/chunk-HZ7BWKQ3.js +13 -0
  19. package/dist/safe-bash/chunks/{chunk-ICFDYV64.js → chunk-HZAMGT5I.js} +2 -2
  20. package/dist/safe-bash/chunks/{chunk-FNDNHAGE.js → chunk-JMMEIDPF.js} +2 -2
  21. package/dist/safe-bash/chunks/{chunk-IVRQ4BXL.js → chunk-PH63PLPZ.js} +7 -7
  22. package/dist/safe-bash/chunks/{chunk-SZH7EJLD.js → chunk-PNBBUWSM.js} +5529 -6547
  23. package/dist/safe-bash/chunks/chunk-QGUV42T5.js +44 -0
  24. package/dist/safe-bash/chunks/chunk-R3NAKOED.js +51 -0
  25. package/dist/safe-bash/chunks/chunk-RRR7AQ24.js +38 -0
  26. package/dist/safe-bash/chunks/{chunk-PQRAK7HU.js → chunk-RYFQ3LZG.js} +281 -476
  27. package/dist/safe-bash/chunks/chunk-VBTDHOWC.js +55 -0
  28. package/dist/safe-bash/chunks/{chunk-NR3EM4LS.js → chunk-VKNVHEX3.js} +1 -6
  29. package/dist/safe-bash/chunks/chunk-XAQMU6OY.js +14 -0
  30. package/dist/safe-bash/chunks/chunk-ZVD5IS4V.js +49 -0
  31. package/dist/safe-bash/command-chunks/{chunk-ORYGZYKW.js → chunk-4FEVBOL5.js} +1 -1
  32. package/dist/safe-bash/command-chunks/{chunk-VXSLJH7G.js → chunk-6JSIFWYT.js} +26 -6
  33. package/dist/safe-bash/command-chunks/chunk-A7MU7762.js +200 -0
  34. package/dist/safe-bash/command-chunks/{chunk-KJIMDLBB.js → chunk-BXCXRYVU.js} +1 -1
  35. package/dist/safe-bash/command-chunks/{chunk-F4TEEZTL.js → chunk-CQHP3I66.js} +1 -1
  36. package/dist/safe-bash/command-chunks/{chunk-PEF7K3UQ.js → chunk-EARHPPPJ.js} +1 -1
  37. package/dist/safe-bash/command-chunks/{chunk-QKFSRZGQ.js → chunk-GFC2NTDG.js} +2 -2
  38. package/dist/safe-bash/command-chunks/chunk-GIRNFXP3.js +466 -0
  39. package/dist/safe-bash/command-chunks/{chunk-EFANWIHL.js → chunk-GY3BWK7K.js} +1 -0
  40. package/dist/safe-bash/command-chunks/{chunk-FPVUD6TH.js → chunk-HDCNKOIX.js} +9 -7
  41. package/dist/safe-bash/command-chunks/{chunk-MQFIPHIQ.js → chunk-ILX2NOLF.js} +18 -15
  42. package/dist/safe-bash/command-chunks/{chunk-5E4WAO4O.js → chunk-JD5QNRNO.js} +3 -3
  43. package/dist/safe-bash/command-chunks/{chunk-I237SNW5.js → chunk-LFJJQQND.js} +1 -1
  44. package/dist/safe-bash/command-chunks/{chunk-W5DNF4JH.js → chunk-LOICUCHG.js} +1 -1
  45. package/dist/safe-bash/command-chunks/{chunk-7U7EXOXX.js → chunk-NASVPT6F.js} +2 -1
  46. package/dist/safe-bash/command-chunks/{chunk-WBNZ4PRE.js → chunk-NGG2XL56.js} +7 -4
  47. package/dist/safe-bash/command-chunks/{chunk-GLOZX57Y.js → chunk-NKIELG7Y.js} +45 -115
  48. package/dist/safe-bash/command-chunks/{chunk-WPYIOKE3.js → chunk-PICVQ6B5.js} +2 -2
  49. package/dist/safe-bash/command-chunks/{chunk-YOFC45RK.js → chunk-QVOS4YXL.js} +1 -1
  50. package/dist/safe-bash/command-chunks/{chunk-VGG2DL5Q.js → chunk-TRR4MYWF.js} +4 -0
  51. package/dist/safe-bash/command-chunks/{chunk-2JRBIDAD.js → chunk-V4K2JDYU.js} +2 -2
  52. package/dist/safe-bash/command-chunks/{chunk-CZ7EN3JG.js → chunk-VT6MJBEI.js} +1 -1
  53. package/dist/safe-bash/command-chunks/{chunk-PCEFOYA3.js → chunk-WWIBP2ET.js} +41 -114
  54. package/dist/safe-bash/command-chunks/{chunk-F6OYH562.js → chunk-X54L3DBL.js} +4 -9
  55. package/dist/safe-bash/command-chunks/{chunk-TNOA7FCQ.js → chunk-YVNGTIJO.js} +1 -1
  56. package/dist/safe-bash/command-chunks/chunk-ZDN7MJE6.js +168 -0
  57. package/dist/safe-bash/commands/apply-patch/index.browser.js +14 -0
  58. package/dist/safe-bash/commands/archive/index.browser.js +36 -0
  59. package/dist/safe-bash/commands/bytes/compression/index.js +54 -51
  60. package/dist/safe-bash/commands/chmod/index.browser.js +14 -0
  61. package/dist/safe-bash/commands/chmod/index.d.ts +2 -0
  62. package/dist/safe-bash/commands/chmod/index.js +2 -0
  63. package/dist/safe-bash/commands/column/index.browser.js +12 -0
  64. package/dist/safe-bash/commands/du/index.browser.js +14 -0
  65. package/dist/safe-bash/commands/expr/index.browser.js +12 -0
  66. package/dist/safe-bash/commands/file/index.browser.js +14 -0
  67. package/dist/safe-bash/commands/filesystem.js +9 -2
  68. package/dist/safe-bash/commands/grep-aliases/index.browser.js +14 -0
  69. package/dist/safe-bash/commands/html-to-markdown/index.browser.js +16 -0
  70. package/dist/safe-bash/commands/metadata/chmod.d.ts +1 -7
  71. package/dist/safe-bash/commands/metadata/chmod.js +1 -204
  72. package/dist/safe-bash/commands/metadata/index.browser.js +17 -0
  73. package/dist/safe-bash/commands/metadata/internal.d.ts +1 -30
  74. package/dist/safe-bash/commands/metadata/internal.js +1 -76
  75. package/dist/safe-bash/commands/metadata/mktemp.d.ts +1 -3
  76. package/dist/safe-bash/commands/metadata/mktemp.js +1 -202
  77. package/dist/safe-bash/commands/metadata/stat.d.ts +1 -7
  78. package/dist/safe-bash/commands/metadata/stat.js +1 -530
  79. package/dist/safe-bash/commands/mktemp/index.browser.js +13 -0
  80. package/dist/safe-bash/commands/mktemp/index.d.ts +2 -0
  81. package/dist/safe-bash/commands/mktemp/index.js +2 -0
  82. package/dist/safe-bash/commands/network/index.browser.js +1 -1
  83. package/dist/safe-bash/commands/node/index.browser.js +4 -4
  84. package/dist/safe-bash/commands/portable-random.d.ts +1 -1
  85. package/dist/safe-bash/commands/portable-random.js +1 -12
  86. package/dist/safe-bash/commands/python/index.browser.js +8 -8
  87. package/dist/safe-bash/commands/regex-execution/public.browser.js +5 -3
  88. package/dist/safe-bash/commands/split/index.browser.js +14 -0
  89. package/dist/safe-bash/commands/stat/index.browser.js +13 -0
  90. package/dist/safe-bash/commands/stat/index.d.ts +2 -0
  91. package/dist/safe-bash/commands/stat/index.js +2 -0
  92. package/dist/safe-bash/commands/stream-format/index.browser.js +11 -0
  93. package/dist/safe-bash/commands/stream-inspection/index.browser.js +11 -0
  94. package/dist/safe-bash/commands/streams.js +5 -5
  95. package/dist/safe-bash/commands/table-text/index.browser.js +11 -0
  96. package/dist/safe-bash/commands/text.js +48 -143
  97. package/dist/safe-bash/commands/time-env/index.browser.js +15 -0
  98. package/dist/safe-bash/commands/tree/index.browser.js +14 -0
  99. package/dist/safe-bash/full-core.browser.js +256 -247
  100. package/dist/safe-bash/opt-in/commands/yq/native-work.js +1 -0
  101. package/dist/safe-bash/optional-host.browser.js +12 -12
  102. package/dist/safe-bash/plugins/index.browser.js +25 -11
  103. package/dist/safe-bash/registry-entry.browser.js +28 -14
  104. package/dist/safe-bash/search.browser.js +48 -0
  105. package/dist/safe-bash/shell/runtime.d.ts +3 -9
  106. package/dist/safe-bash/shell/runtime.js +63 -311
  107. package/dist/safe-bash/shell/shell.js +0 -23
  108. package/dist/safe-bash/shell/types.d.ts +2 -0
  109. package/dist/safe-bash/shell/worker-limits.js +1 -0
  110. package/dist/safe-bash/shell-entry.browser.js +19 -10
  111. package/dist/safe-bash/worker/host.js +1 -1
  112. package/dist/safe-bash-command-bc/index.js +12 -5
  113. package/dist/safe-bash-command-bzip2/index.js +4 -3
  114. package/dist/safe-bash-command-chmod/LICENSE +21 -0
  115. package/dist/safe-bash-command-chmod/command.d.ts +7 -0
  116. package/dist/safe-bash-command-chmod/command.js +11 -0
  117. package/dist/safe-bash-command-chmod/index.d.ts +6 -0
  118. package/dist/safe-bash-command-chmod/index.js +27 -0
  119. package/dist/safe-bash-command-exiftool/index.js +5 -5
  120. package/dist/safe-bash-command-find/find.js +1 -1
  121. package/dist/safe-bash-command-find/index.js +1 -1
  122. package/dist/safe-bash-command-fmt/index.js +9 -2
  123. package/dist/safe-bash-command-gzip/index.js +45 -42
  124. package/dist/safe-bash-command-imagemagick/index.js +3 -1
  125. package/dist/safe-bash-command-jq/index.js +1 -1
  126. package/dist/safe-bash-command-jq/jq.js +1 -1
  127. package/dist/safe-bash-command-less/index.js +12 -3
  128. package/dist/safe-bash-command-mktemp/LICENSE +21 -0
  129. package/dist/safe-bash-command-mktemp/command.d.ts +3 -0
  130. package/dist/safe-bash-command-mktemp/command.js +9 -0
  131. package/dist/safe-bash-command-mktemp/index.d.ts +6 -0
  132. package/dist/safe-bash-command-mktemp/index.js +25 -0
  133. package/dist/safe-bash-command-nl/index.js +1 -1
  134. package/dist/safe-bash-command-nl/nl.js +1 -1
  135. package/dist/safe-bash-command-od/index.js +6 -2
  136. package/dist/safe-bash-command-op/index.js +25 -6
  137. package/dist/safe-bash-command-rg/index.js +1 -1
  138. package/dist/safe-bash-command-rg/rg-command.d.ts +0 -1
  139. package/dist/safe-bash-command-rg/rg-command.js +3 -5
  140. package/dist/safe-bash-command-sed/index.js +1 -1
  141. package/dist/safe-bash-command-sed/sed.js +1 -1
  142. package/dist/safe-bash-command-sips/index.js +13 -5
  143. package/dist/safe-bash-command-sponge/index.js +10 -3
  144. package/dist/safe-bash-command-stat/LICENSE +21 -0
  145. package/dist/safe-bash-command-stat/command.d.ts +7 -0
  146. package/dist/safe-bash-command-stat/command.js +9 -0
  147. package/dist/safe-bash-command-stat/index.d.ts +6 -0
  148. package/dist/safe-bash-command-stat/index.js +25 -0
  149. package/dist/safe-bash-command-unexpand/index.js +1 -1
  150. package/dist/safe-bash-command-unexpand/unexpand.js +1 -1
  151. package/dist/safe-bash-command-unrtf/index.js +11 -1
  152. package/dist/safe-bash-command-xxd/index.js +6 -2
  153. package/dist/safe-bash-command-xz/command.d.ts +1 -1
  154. package/dist/safe-bash-command-xz/index.js +3 -2
  155. package/dist/safe-bash-command-yq/index.js +1 -0
  156. package/dist/safe-bash-command-yq/native-work.js +1 -0
  157. package/dist/safe-bash-command-yq/query.js +3 -0
  158. package/dist/safe-bash-compression-engine/bounded-codec.js +3 -3
  159. package/dist/safe-bash-compression-engine/codec-loader.js +2 -2
  160. package/dist/safe-bash-compression-engine/files.js +6 -6
  161. package/dist/safe-bash-compression-engine/index.js +5 -5
  162. package/dist/safe-bash-compression-engine/operand.js +6 -6
  163. package/dist/safe-bash-compression-engine/options.js +1 -1
  164. package/dist/safe-bash-compression-engine/stream.js +5 -5
  165. package/dist/safe-bash-compression-engine/zstd-decode.js +4 -4
  166. package/dist/safe-bash-contracts/escaping.js +2 -2
  167. package/dist/safe-bash-contracts/filesystem-output.js +2 -2
  168. package/dist/safe-bash-contracts/index.js +2 -2
  169. package/dist/safe-bash-contracts/io.d.ts +2 -0
  170. package/dist/safe-bash-contracts/io.js +1 -1
  171. package/dist/safe-bash-contracts/output.js +2 -2
  172. package/dist/safe-bash-io-engine/commands/search/requirements.js +1 -1
  173. package/dist/safe-bash-io-engine/commands/text-programs/shared.js +1 -1
  174. package/dist/safe-bash-mcp/index.browser.js +11 -1
  175. package/dist/safe-bash-mcp/index.js +38 -17
  176. package/dist/safe-bash-metadata-engine/LICENSE +21 -0
  177. package/dist/safe-bash-metadata-engine/index.d.ts +30 -0
  178. package/dist/safe-bash-metadata-engine/index.js +82 -0
  179. package/dist/safe-bash-metadata-engine/random.d.ts +1 -0
  180. package/dist/safe-bash-metadata-engine/random.js +21 -0
  181. package/dist/safe-bash-regex-engine/index.js +4 -4
  182. package/dist/safe-bash-regex-engine/text/budget.d.ts +0 -1
  183. package/dist/safe-bash-regex-engine/text/budget.js +1 -1
  184. package/dist/safe-bash-regex-engine/text/regex.js +4 -4
  185. package/dist/safe-bash-regex-engine/text/replacement-buffer.js +2 -2
  186. package/dist/safe-bash-regex-engine/text/rust-syntax.js +2 -2
  187. package/dist/safe-bash-search-engine/ergonomic-regex.js +2 -2
  188. package/dist/safe-bash-search-engine/glob.js +2 -2
  189. package/dist/safe-bash-search-engine/grep.js +2 -2
  190. package/dist/safe-bash-search-engine/matcher.js +2 -2
  191. package/dist/safe-bash-search-engine/options.d.ts +2 -0
  192. package/dist/safe-bash-search-engine/options.js +1 -1
  193. package/dist/safe-bash-search-engine/output.js +1 -1
  194. package/dist/safe-bash-search-engine/shared.js +2 -2
  195. package/dist/safe-bash-search-engine/walk.js +3 -3
  196. package/dist/safe-playwright-cloudflare/browser-snapshot-json.js +2 -2
  197. package/dist/safe-playwright-cloudflare/browser-snapshot-references.js +1 -1
  198. package/package.json +91 -10
@@ -6,7 +6,8 @@ import {
6
6
  init_buffer();
7
7
  import { PublicDiagnostic, UsageError } from "../safe-bash-contracts/diagnostics.js";
8
8
  import {
9
- commandRuntimeIdentity
9
+ commandRuntimeIdentity,
10
+ withInputByteBudget
10
11
  } from "../safe-bash-contracts/index.js";
11
12
  import { codeOf, diagnostic, output } from "../safe-bash-compression-engine/internal.js";
12
13
  import { runOperand } from "../safe-bash-compression-engine/operand.js";
@@ -35,7 +36,7 @@ function createNamedBzip2Command(name, options = {}) {
35
36
  name,
36
37
  description: `${name} block-sorting file compressor`,
37
38
  runtimeIdentity: commandRuntimeIdentity,
38
- async execute(context) {
39
+ execute: withInputByteBudget(async (context) => {
39
40
  context.signal.throwIfAborted();
40
41
  try {
41
42
  const parsed = parseOptions(name, context.args);
@@ -105,7 +106,7 @@ No FILE or FILE '-' uses stdin; file output uses private VFS staging.
105
106
  await diagnostic(context, error);
106
107
  return { exitCode: error instanceof UsageError ? 2 : 1 };
107
108
  }
108
- }
109
+ })
109
110
  };
110
111
  }
111
112
  function createBzip2Command(options = {}) {
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Poe Platform
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ export { modeChange } from "../safe-bash-io-engine/commands/mode-change.js";
2
+ import { type MetadataCommandsOptions } from "../safe-bash-metadata-engine/index.js";
3
+ export declare function createChmodCommand(configuration?: MetadataCommandsOptions): import("../safe-bash-contracts/index.js").CommandDefinition;
4
+ export declare function evalSyncChmod(opArgs: readonly string[], umask: number, chmodNodeSync?: (filePath: string, change: (stat: {
5
+ type: "file" | "directory" | "symlink";
6
+ mode: number;
7
+ }) => number) => boolean): string | undefined;
@@ -0,0 +1,11 @@
1
+ import {
2
+ createChmodCommand,
3
+ evalSyncChmod,
4
+ modeChange
5
+ } from "../safe-bash/command-chunks/chunk-A7MU7762.js";
6
+ import "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
7
+ export {
8
+ createChmodCommand,
9
+ evalSyncChmod,
10
+ modeChange
11
+ };
@@ -0,0 +1,6 @@
1
+ import type { VirtualShellPlugin } from "../safe-bash-contracts/index.js";
2
+ import type { MetadataCommandsOptions } from "../safe-bash-metadata-engine/index.js";
3
+ export * from "./command.js";
4
+ export type { MetadataCommandsOptions as ChmodCommandsOptions, MetadataLimits as ChmodLimits } from "../safe-bash-metadata-engine/index.js";
5
+ export declare function createChmodCommands(options?: MetadataCommandsOptions): import("../safe-bash-contracts/index.js").CommandDefinition[];
6
+ export declare function chmodCommands(options?: MetadataCommandsOptions): VirtualShellPlugin;
@@ -0,0 +1,27 @@
1
+ import {
2
+ createChmodCommand,
3
+ evalSyncChmod,
4
+ modeChange
5
+ } from "../safe-bash/command-chunks/chunk-A7MU7762.js";
6
+ import {
7
+ init_buffer
8
+ } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
9
+
10
+ // packages/safe-bash-command-chmod/src/index.ts
11
+ init_buffer();
12
+ function createChmodCommands(options = {}) {
13
+ return [createChmodCommand(options)];
14
+ }
15
+ function chmodCommands(options = {}) {
16
+ const commands = createChmodCommands(options);
17
+ return { name: "chmod-commands", setup(host) {
18
+ for (const command of commands) host.commands.register(command, { replace: options.replace ?? false });
19
+ } };
20
+ }
21
+ export {
22
+ chmodCommands,
23
+ createChmodCommand,
24
+ createChmodCommands,
25
+ evalSyncChmod,
26
+ modeChange
27
+ };
@@ -10,7 +10,7 @@ init_buffer();
10
10
  import { yieldTurn } from "../safe-bash-contracts/yield.js";
11
11
  import { commandRuntimeIdentity, getCommandArguments } from "../safe-bash-contracts/command.js";
12
12
  import { FsError as FsError2 } from "../safe-bash-contracts/errors.js";
13
- import { readBytes as readBytes2, writeBytes } from "../safe-bash-contracts/io.js";
13
+ import { readBytes as readBytes2, writeBytes, withInputByteBudget } from "../safe-bash-contracts/io.js";
14
14
  import { createOutputOperation } from "../safe-bash-contracts/output.js";
15
15
  import { shellValueByteLength } from "../safe-bash-contracts/value.js";
16
16
 
@@ -1779,7 +1779,7 @@ function createExiftoolCommand(options = {}) {
1779
1779
  name: "exiftool",
1780
1780
  runtimeIdentity: commandRuntimeIdentity,
1781
1781
  description: "Inspect and edit admitted PNG, JPEG and PDF metadata through virtual files",
1782
- async execute(context) {
1782
+ execute: withInputByteBudget(async (context) => {
1783
1783
  const publication = new Publication(context, limits.maxStagingAttempts);
1784
1784
  let stdout, stderr;
1785
1785
  let failed = false, failure;
@@ -1824,7 +1824,7 @@ function createExiftoolCommand(options = {}) {
1824
1824
  invocation = parseArguments(await expandArgfiles(context.args, context, publication, resources), resources.limits);
1825
1825
  } catch (error) {
1826
1826
  context.signal.throwIfAborted();
1827
- if (error instanceof ResourceLimitError) throw error;
1827
+ if (error instanceof ResourceLimitError || error instanceof Error && error.name === "BudgetExceededError" || error instanceof FsError2 && error.code === "EFBIG") throw error;
1828
1828
  await output("Error: " + (error instanceof Error ? error.message : String(error)) + "\n", true);
1829
1829
  return { exitCode: 1 };
1830
1830
  }
@@ -1948,7 +1948,7 @@ function createExiftoolCommand(options = {}) {
1948
1948
  tags = jpeg ? inspectJpeg(bytes, resources).tags : png ? inspectPng(bytes, resources).tags : isPdf ? inspectPdf(bytes, resources).tags : [];
1949
1949
  } catch (error) {
1950
1950
  context.signal.throwIfAborted();
1951
- if (error instanceof ResourceLimitError) throw error;
1951
+ if (error instanceof ResourceLimitError || error instanceof Error && error.name === "BudgetExceededError" || error instanceof FsError2 && error.code === "EFBIG") throw error;
1952
1952
  errors++;
1953
1953
  const message = error instanceof FsError2 && error.code === "ENOENT" ? "File not found" : error instanceof Error ? error.message : String(error);
1954
1954
  await output("Error: " + message + " - " + file + "\n", true);
@@ -2053,7 +2053,7 @@ function createExiftoolCommand(options = {}) {
2053
2053
  } finally {
2054
2054
  await cleanup();
2055
2055
  }
2056
- }
2056
+ })
2057
2057
  });
2058
2058
  }
2059
2059
  var exiftoolCommand = createExiftoolCommand();
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createFindDefinitions,
3
3
  evalSyncFind
4
- } from "../safe-bash/command-chunks/chunk-QKFSRZGQ.js";
4
+ } from "../safe-bash/command-chunks/chunk-GFC2NTDG.js";
5
5
  import "../safe-bash/command-chunks/chunk-5ZMZ573Q.js";
6
6
  import "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
7
7
  export {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createFindDefinitions,
3
3
  evalSyncFind
4
- } from "../safe-bash/command-chunks/chunk-QKFSRZGQ.js";
4
+ } from "../safe-bash/command-chunks/chunk-GFC2NTDG.js";
5
5
  import "../safe-bash/command-chunks/chunk-5ZMZ573Q.js";
6
6
  import {
7
7
  init_buffer
@@ -2217,12 +2217,14 @@ function pathOf(context, path) {
2217
2217
  return isAbsolutePath(path) ? path : `${context.cwd.endsWith("/") ? context.cwd.slice(0, -1) : context.cwd}/${path}`;
2218
2218
  }
2219
2219
  var InputBudget = class {
2220
- constructor(maximum, sourceBufferBytes) {
2220
+ constructor(maximum, sourceBufferBytes, inputBudget) {
2221
2221
  this.maximum = maximum;
2222
2222
  this.sourceBufferBytes = sourceBufferBytes;
2223
+ this.inputBudget = inputBudget;
2223
2224
  }
2224
2225
  maximum;
2225
2226
  sourceBufferBytes;
2227
+ inputBudget;
2226
2228
  used = 0;
2227
2229
  get maxReadBytes() {
2228
2230
  return Math.max(0, Math.min(this.sourceBufferBytes, this.maximum - this.used));
@@ -2234,6 +2236,7 @@ var InputBudget = class {
2234
2236
  if (size > this.maximum - this.used) throw new FsError("EFBIG", { message: "byte command input limit exceeded" });
2235
2237
  if (size > this.maxReadBytes) throw new FmtError("LIMIT", "source chunk retention limit exceeded");
2236
2238
  this.used += size;
2239
+ this.inputBudget?.check(this.used);
2237
2240
  if (!size) yield byteSpan(chunk, 0, 0);
2238
2241
  for (let offset = 0; offset < size; offset += 4096) yield byteSpan(chunk, offset, Math.min(4096, size - offset));
2239
2242
  }
@@ -2390,7 +2393,7 @@ async function fmt(context, configuration = {}) {
2390
2393
  const engineBytes = 10120 + settings.prefix.length;
2391
2394
  const batchBytes = limits.retainedBytes >= Math.max(32768, engineBytes + 16384 + 4096) ? 16384 : 0;
2392
2395
  const engineLimit = limits.retainedBytes - batchBytes;
2393
- const budget = new InputBudget(limits.inputBytes, engineLimit - engineBytes);
2396
+ const budget = new InputBudget(limits.inputBytes, engineLimit - engineBytes, context.inputBudget);
2394
2397
  let work = 0, outputBytes = 0;
2395
2398
  stdout = createOutputOperation({ signal: local.signal }, context.stdout);
2396
2399
  const outputContext = { ...context, stdout: stdout.output };
@@ -2406,6 +2409,7 @@ async function fmt(context, configuration = {}) {
2406
2409
  try {
2407
2410
  await current.open(name, nameBytes);
2408
2411
  } catch (error) {
2412
+ if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
2409
2413
  local.signal.throwIfAborted();
2410
2414
  await diagnostic(context, fileError(error, name, nameBytes, true, context));
2411
2415
  await current.close();
@@ -2439,6 +2443,7 @@ async function fmt(context, configuration = {}) {
2439
2443
  bytes2 = await current.next();
2440
2444
  if (bytes2?.length) received = true;
2441
2445
  } catch (error) {
2446
+ if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
2442
2447
  local.signal.throwIfAborted();
2443
2448
  if (isFsError(error, "EFBIG")) throw new FmtError("LIMIT", "byte command input limit exceeded");
2444
2449
  readFailed = true;
@@ -2467,6 +2472,7 @@ async function fmt(context, configuration = {}) {
2467
2472
  }
2468
2473
  if (outBatchUsed) await flushOutBatch();
2469
2474
  } catch (error) {
2475
+ if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
2470
2476
  local.signal.throwIfAborted();
2471
2477
  try {
2472
2478
  await flushOutBatch();
@@ -2496,6 +2502,7 @@ async function fmt(context, configuration = {}) {
2496
2502
  } catch (error) {
2497
2503
  failed = true;
2498
2504
  context.signal.throwIfAborted();
2505
+ if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
2499
2506
  if (error instanceof FmtError && error.usage) await writeBytes(context.stderr, Uint8Array.from(`fmt: ${error.message}
2500
2507
  Try 'fmt --help' for more information.
2501
2508
  `, (character) => character.charCodeAt(0)), context.signal);
@@ -16,10 +16,11 @@ function createGzipCommands(config = {}) {
16
16
  if (maxDecodedBytes !== void 0 && maxDecodedBytes !== Infinity && (!Number.isSafeInteger(maxDecodedBytes) || maxDecodedBytes < 0)) {
17
17
  throw new RangeError("maxDecodedBytes must be a nonnegative safe integer or Infinity");
18
18
  }
19
- const commands = profiles.filter((profile) => profile.format === "gzip").flatMap((profile) => profile.names.map((name) => define(name, withInputByteBudget(async (context) => {
20
- const options = parseOptions(name, context.args);
21
- if (options.help) {
22
- await output(context, `Usage: ${name} [OPTION]... [FILE]...
19
+ const commands = profiles.filter((profile) => profile.format === "gzip").flatMap((profile) => profile.names.map((name) => {
20
+ const command = define(name, async (context) => {
21
+ const options = parseOptions(name, context.args);
22
+ if (options.help) {
23
+ await output(context, `Usage: ${name} [OPTION]... [FILE]...
23
24
  -c, --stdout, --to-stdout
24
25
  -d, --decompress, --uncompress
25
26
  -k, --keep
@@ -29,48 +30,50 @@ ${options.format === "zstd" ? "-1..-9, --best\nHigher levels and --fast[=NUM] ar
29
30
  `}-h, --help
30
31
  No FILE or FILE '-' uses stdin; file output uses private VFS staging.
31
32
  `);
32
- return { exitCode: 0 };
33
- }
34
- let plans;
35
- let planningFailed = false;
36
- try {
37
- if (options.operands.length > 1) {
38
- plans = [];
39
- for (const name2 of options.operands) {
40
- try {
41
- plans.push(...await planOperands(context, { ...options, operands: [name2] }));
42
- } catch (error) {
43
- context.signal.throwIfAborted();
44
- if (codeOf(error) === "EROFS") throw error;
45
- planningFailed = true;
46
- if (options.quiet < 2) await diagnostic(context, error);
47
- }
48
- }
49
- if (plans.length > 1) await verifyOperandDestinations(context, plans);
50
- } else plans = await planOperands(context, options);
51
- } catch (error) {
52
- context.signal.throwIfAborted();
53
- if (options.quiet < 2) throw error;
54
- return { exitCode: 1 };
55
- }
56
- const decodedBudget = new DecodedBudget(maxDecodedBytes);
57
- let exitCode = planningFailed ? 1 : 0;
58
- for (const plan of plans) {
33
+ return { exitCode: 0 };
34
+ }
35
+ let plans;
36
+ let planningFailed = false;
59
37
  try {
60
- const warned = await runOperand(context, plan, options, decodedBudget);
61
- if (warned) {
62
- if (!options.quiet) await diagnostic(context, new PublicDiagnostic(`${plan.source}: decompression OK, trailing garbage ignored`));
63
- if (exitCode === 0) exitCode = 2;
64
- }
38
+ if (options.operands.length > 1) {
39
+ plans = [];
40
+ for (const name2 of options.operands) {
41
+ try {
42
+ plans.push(...await planOperands(context, { ...options, operands: [name2] }));
43
+ } catch (error) {
44
+ context.signal.throwIfAborted();
45
+ if (codeOf(error) === "EROFS") throw error;
46
+ planningFailed = true;
47
+ if (options.quiet < 2) await diagnostic(context, error);
48
+ }
49
+ }
50
+ if (plans.length > 1) await verifyOperandDestinations(context, plans);
51
+ } else plans = await planOperands(context, options);
65
52
  } catch (error) {
66
53
  context.signal.throwIfAborted();
67
- if (options.quiet < 2) await diagnostic(context, error);
68
- exitCode = 1;
69
- if (decodedBudget.exceeded) break;
54
+ if (options.quiet < 2) throw error;
55
+ return { exitCode: 1 };
70
56
  }
71
- }
72
- return { exitCode };
73
- }))));
57
+ const decodedBudget = new DecodedBudget(maxDecodedBytes);
58
+ let exitCode = planningFailed ? 1 : 0;
59
+ for (const plan of plans) {
60
+ try {
61
+ const warned = await runOperand(context, plan, options, decodedBudget);
62
+ if (warned) {
63
+ if (!options.quiet) await diagnostic(context, new PublicDiagnostic(`${plan.source}: decompression OK, trailing garbage ignored`));
64
+ if (exitCode === 0) exitCode = 2;
65
+ }
66
+ } catch (error) {
67
+ context.signal.throwIfAborted();
68
+ if (options.quiet < 2) await diagnostic(context, error);
69
+ exitCode = 1;
70
+ if (decodedBudget.exceeded) break;
71
+ }
72
+ }
73
+ return { exitCode };
74
+ });
75
+ return { ...command, execute: withInputByteBudget(async (context) => command.execute(context)) };
76
+ }));
74
77
  if (maxDecodedBytes === void 0 || maxDecodedBytes === Infinity) {
75
78
  for (const c of commands) builtInDirectContextExecutors.add(c.execute);
76
79
  }
@@ -35,6 +35,7 @@ import {
35
35
 
36
36
  // packages/safe-bash-command-imagemagick/src/index.ts
37
37
  init_buffer();
38
+ import { FsError } from "../safe-bash-contracts/errors.js";
38
39
  import { resolvePath } from "../safe-bash-contracts/path.js";
39
40
  import { yieldTurn, drainCooperativeSteps as drainSteps } from "../safe-bash-contracts/yield.js";
40
41
  import { InputByteBudget } from "../safe-bash-contracts/io.js";
@@ -5089,7 +5090,8 @@ async function executeVfsMagickTool(context, runner, maxInputBytes) {
5089
5090
  bytes = await context.fs.readFile(resolvePath(context.cwd, candidate), {
5090
5091
  signal: invocation.signal
5091
5092
  });
5092
- } catch {
5093
+ } catch (error) {
5094
+ if (!(error instanceof FsError) || !["ENOENT", "ENOTDIR", "EISDIR", "EACCES", "EPERM"].includes(error.code)) throw error;
5093
5095
  continue;
5094
5096
  }
5095
5097
  chargeInput(bytes.byteLength);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createJqCommand
3
- } from "../safe-bash/command-chunks/chunk-MQFIPHIQ.js";
3
+ } from "../safe-bash/command-chunks/chunk-ILX2NOLF.js";
4
4
  import {
5
5
  init_buffer
6
6
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createJqCommand,
3
3
  executeJq
4
- } from "../safe-bash/command-chunks/chunk-MQFIPHIQ.js";
4
+ } from "../safe-bash/command-chunks/chunk-ILX2NOLF.js";
5
5
  import "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
6
6
  export {
7
7
  createJqCommand,
@@ -52,13 +52,14 @@ function settings(options = {}) {
52
52
  }
53
53
  return Object.freeze(limits);
54
54
  }
55
- async function readSourceText(source, maxBytes, signal) {
55
+ async function readSourceText(source, maxBytes, signal, admit) {
56
56
  const chunks = [];
57
57
  let total = 0;
58
58
  let quantum = 0;
59
59
  let chunksRead = 0;
60
60
  for await (const chunk of readBytes(source, signal)) {
61
61
  total += chunk.byteLength;
62
+ admit(chunk.byteLength);
62
63
  signal.throwIfAborted();
63
64
  quantum += Math.max(1, chunk.byteLength);
64
65
  if (quantum >= 16384 || ++chunksRead >= 128) {
@@ -86,6 +87,11 @@ function createPagerCommand(name, options = {}) {
86
87
  description: `Non-interactive ${name} pager pass-through`,
87
88
  runtimeIdentity: commandRuntimeIdentity,
88
89
  async execute(context) {
90
+ let inputBytes = 0;
91
+ const admit = (bytes) => {
92
+ context.signal.throwIfAborted();
93
+ context.inputBudget?.check(inputBytes += bytes);
94
+ };
89
95
  const maxBytes = Math.min(limits.maxInputBytes, context.limits?.maxInputBytes ?? limits.maxInputBytes);
90
96
  context.signal.throwIfAborted();
91
97
  const args = getCommandArguments(context).args;
@@ -165,6 +171,7 @@ function createPagerCommand(name, options = {}) {
165
171
  await yieldTurn(context.signal);
166
172
  }
167
173
  total += chunk.byteLength;
174
+ admit(chunk.byteLength);
168
175
  if (total > maxBytes) {
169
176
  await writeText(context.stderr, `${name}: input exceeds maximum size of ${maxBytes} bytes
170
177
  `);
@@ -179,7 +186,7 @@ function createPagerCommand(name, options = {}) {
179
186
  const texts = [];
180
187
  let exitCode = 0;
181
188
  if (files.length === 0) {
182
- texts.push(await readSourceText(context.stdin, maxBytes, context.signal));
189
+ texts.push(await readSourceText(context.stdin, maxBytes, context.signal, admit));
183
190
  } else {
184
191
  for (const file of files) {
185
192
  if (file === "-") {
@@ -187,16 +194,18 @@ function createPagerCommand(name, options = {}) {
187
194
  let total = 0;
188
195
  for await (const chunk of readBytes(context.stdin, context.signal)) {
189
196
  total += chunk.byteLength;
197
+ admit(chunk.byteLength);
190
198
  if (total > maxBytes) throw new PublicDiagnostic(`input exceeds maximum size of ${maxBytes} bytes`);
191
199
  await writeBytes(context.stdout, chunk, context.signal);
192
200
  await yieldTurn(context.signal);
193
201
  }
194
- } else texts.push(await readSourceText(context.stdin, maxBytes, context.signal));
202
+ } else texts.push(await readSourceText(context.stdin, maxBytes, context.signal, admit));
195
203
  } else {
196
204
  try {
197
205
  const targetPath = pathPosix.resolve(context.cwd, file);
198
206
  const raw = await context.fs.readFile(targetPath, { signal: context.signal });
199
207
  context.signal.throwIfAborted();
208
+ admit(raw.byteLength);
200
209
  if (raw.byteLength > maxBytes) {
201
210
  await writeText(context.stderr, `${name}: ${file}: input exceeds maximum size
202
211
  `);
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Poe Platform
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ import { type MetadataCommandsOptions } from "../safe-bash-metadata-engine/index.js";
2
+ export declare function evalSyncMktemp(opArgs: readonly string[], env: Readonly<Record<string, string>>, statTypeSync?: (filePath: string) => string | undefined, writeFileSync?: (filePath: string, bytes: Uint8Array) => boolean, mkdirSync?: (filePath: string) => boolean): string | undefined;
3
+ export declare function createMktempCommand(configuration?: MetadataCommandsOptions): import("../safe-bash-contracts/index.js").CommandDefinition;
@@ -0,0 +1,9 @@
1
+ import {
2
+ createMktempCommand,
3
+ evalSyncMktemp
4
+ } from "../safe-bash/command-chunks/chunk-ZDN7MJE6.js";
5
+ import "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
6
+ export {
7
+ createMktempCommand,
8
+ evalSyncMktemp
9
+ };
@@ -0,0 +1,6 @@
1
+ import type { VirtualShellPlugin } from "../safe-bash-contracts/index.js";
2
+ import type { MetadataCommandsOptions } from "../safe-bash-metadata-engine/index.js";
3
+ export * from "./command.js";
4
+ export type { MetadataCommandsOptions as MktempCommandsOptions, MetadataLimits as MktempLimits } from "../safe-bash-metadata-engine/index.js";
5
+ export declare function createMktempCommands(options?: MetadataCommandsOptions): import("../safe-bash-contracts/index.js").CommandDefinition[];
6
+ export declare function mktempCommands(options?: MetadataCommandsOptions): VirtualShellPlugin;
@@ -0,0 +1,25 @@
1
+ import {
2
+ createMktempCommand,
3
+ evalSyncMktemp
4
+ } from "../safe-bash/command-chunks/chunk-ZDN7MJE6.js";
5
+ import {
6
+ init_buffer
7
+ } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
8
+
9
+ // packages/safe-bash-command-mktemp/src/index.ts
10
+ init_buffer();
11
+ function createMktempCommands(options = {}) {
12
+ return [createMktempCommand(options)];
13
+ }
14
+ function mktempCommands(options = {}) {
15
+ const commands = createMktempCommands(options);
16
+ return { name: "mktemp-commands", setup(host) {
17
+ for (const command of commands) host.commands.register(command, { replace: options.replace ?? false });
18
+ } };
19
+ }
20
+ export {
21
+ createMktempCommand,
22
+ createMktempCommands,
23
+ evalSyncMktemp,
24
+ mktempCommands
25
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createNlWithSettings
3
- } from "../safe-bash/command-chunks/chunk-EFANWIHL.js";
3
+ } from "../safe-bash/command-chunks/chunk-GY3BWK7K.js";
4
4
  import {
5
5
  init_buffer
6
6
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createNlWithSettings
3
- } from "../safe-bash/command-chunks/chunk-EFANWIHL.js";
3
+ } from "../safe-bash/command-chunks/chunk-GY3BWK7K.js";
4
4
  import "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
5
5
  export {
6
6
  createNlWithSettings
@@ -139,10 +139,12 @@ function output(context, text) {
139
139
  return writeBytes(context.stdout, bytes, context.signal);
140
140
  }
141
141
  var ByteInputBudget = class {
142
- constructor(maxInputBytes) {
142
+ constructor(maxInputBytes, inputBudget) {
143
143
  this.maxInputBytes = maxInputBytes;
144
+ this.inputBudget = inputBudget;
144
145
  }
145
146
  maxInputBytes;
147
+ inputBudget;
146
148
  #bytes = 0;
147
149
  #failure;
148
150
  assertOpen(signal) {
@@ -158,13 +160,14 @@ var ByteInputBudget = class {
158
160
  throw this.#failure;
159
161
  }
160
162
  this.#bytes += chunk.byteLength;
163
+ this.inputBudget?.check(this.#bytes);
161
164
  yield chunk;
162
165
  this.assertOpen(signal);
163
166
  }
164
167
  }
165
168
  };
166
169
  async function* sources(context, operands, maxInputBytes, onFileError) {
167
- const budget = new ByteInputBudget(maxInputBytes);
170
+ const budget = new ByteInputBudget(maxInputBytes, context.inputBudget);
168
171
  let usedStdin = false;
169
172
  let emptyChunks = 0;
170
173
  for (const operand of operands.length ? operands : ["-"]) {
@@ -510,6 +513,7 @@ function defineOdCommand(handler) {
510
513
  return await handler(context);
511
514
  } catch (error) {
512
515
  context.signal.throwIfAborted();
516
+ if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
513
517
  await writeDiagnostic(
514
518
  context.stderr,
515
519
  `${context.command}: ${publicDiagnosticMessage(error, context.onInternalError)}
@@ -7,6 +7,7 @@ init_buffer();
7
7
 
8
8
  // packages/safe-bash-command-op/src/cli.ts
9
9
  init_buffer();
10
+ import { isFsError } from "@poe-platform/safe-fs/core";
10
11
  import { InputByteBudget } from "../safe-bash-contracts/io.js";
11
12
 
12
13
  // packages/safe-bash-command-op/src/encoding.ts
@@ -3687,6 +3688,7 @@ function createOpCommand(options = {}) {
3687
3688
  }
3688
3689
  return { exitCode: 0 };
3689
3690
  } catch (error) {
3691
+ if (error instanceof Error && error.name === "BudgetExceededError" || isFsError(error, "EPIPE")) throw error;
3690
3692
  let message = error instanceof Error ? error.message : "operation failed";
3691
3693
  try {
3692
3694
  budget.assertOpen();
@@ -4666,7 +4668,7 @@ function createItemHandlers(backend) {
4666
4668
 
4667
4669
  // packages/safe-bash-command-op/src/index.ts
4668
4670
  import { readBytes } from "../safe-bash-contracts/index.js";
4669
- import { resolvePath } from "@poe-platform/safe-fs/core";
4671
+ import { isFsError as isFsError2, resolvePath } from "@poe-platform/safe-fs/core";
4670
4672
 
4671
4673
  // packages/safe-bash-command-op/src/types.ts
4672
4674
  init_buffer();
@@ -4730,27 +4732,44 @@ function createOpCommand2(options = {}) {
4730
4732
  if (!("fs" in context)) return command.execute(context);
4731
4733
  const host = context;
4732
4734
  const { fs, signal, cwd } = context;
4735
+ let inputBytes = 0;
4736
+ const account = (bytes) => {
4737
+ context.inputBudget?.check(inputBytes += bytes.byteLength);
4738
+ return bytes;
4739
+ };
4733
4740
  const invocation = {
4734
4741
  ...host,
4735
4742
  args: context.args,
4736
4743
  env: { ...context.env },
4737
4744
  signal,
4738
- stdin: readBytes(context.stdin, signal),
4745
+ stdin: (async function* () {
4746
+ for await (const bytes of readBytes(context.stdin, signal)) yield account(bytes);
4747
+ })(),
4739
4748
  stdout: context.stdout,
4740
4749
  stderr: context.stderr,
4741
4750
  ...authentication === void 0 ? {} : { authentication },
4742
4751
  ...pluginScope === void 0 ? {} : { pluginScope },
4743
4752
  ...confirmPluginClear === void 0 ? {} : { confirmPluginClear },
4744
4753
  ...selectPlugin === void 0 ? {} : { selectPlugin },
4745
- readFile: host.readFile ?? (async (path) => {
4754
+ readFile: async (path) => {
4755
+ if (host.readFile) return account(await host.readFile(path));
4746
4756
  signal.throwIfAborted();
4747
4757
  const resolved = resolvePath(cwd, path);
4748
4758
  const capabilities = fs.capabilitiesFor ? await fs.capabilitiesFor(resolved, { signal }) : fs.capabilities;
4749
4759
  if (capabilities.read !== true) throw new Error("op requires VFS read capability");
4750
- const bytes = await fs.readFile(resolved, { signal });
4760
+ let bytes;
4761
+ try {
4762
+ bytes = await fs.readFile(resolved, {
4763
+ signal,
4764
+ ...context.inputBudget ? { maxBytes: Math.max(0, context.inputBudget.maxBytes - inputBytes) } : {}
4765
+ });
4766
+ } catch (error) {
4767
+ if (isFsError2(error, "EFBIG") && context.inputBudget) context.inputBudget.check(context.inputBudget.maxBytes + 1);
4768
+ throw error;
4769
+ }
4751
4770
  signal.throwIfAborted();
4752
- return Uint8Array.from(bytes);
4753
- }),
4771
+ return Uint8Array.from(account(bytes));
4772
+ },
4754
4773
  writeFile: host.writeFile ?? (async (path, bytes, settings = {}) => {
4755
4774
  signal.throwIfAborted();
4756
4775
  const resolved = resolvePath(cwd, path);