@poe-platform/safe-bash 0.1.762 → 0.1.763

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 (28) hide show
  1. package/dist/image-ast/index.browser.js +186 -55
  2. package/dist/image-ast/index.js +186 -55
  3. package/dist/pdf-ast/ast.d.ts +23 -0
  4. package/dist/pdf-ast/index.js +273 -91
  5. package/dist/safe-bash/command-chunks/{chunk-D4GXXV65.js → chunk-4XHONGIU.js} +2 -2
  6. package/dist/safe-bash/command-chunks/{chunk-P3Q2QSCA.js → chunk-S3G2B4OX.js} +186 -55
  7. package/dist/safe-bash/command-chunks/{chunk-F7MJRXQ2.js → chunk-S5EX6UP5.js} +1 -1
  8. package/dist/safe-bash/core.browser.js +1 -1
  9. package/dist/safe-bash/shell/runtime.js +1 -1
  10. package/dist/safe-bash-checksum-engine/index.d.ts +1 -1
  11. package/dist/safe-bash-checksum-engine/index.js +5 -1
  12. package/dist/safe-bash-command-ffmpeg/index.js +7486 -7432
  13. package/dist/safe-bash-command-gh/index.js +174 -105
  14. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  15. package/dist/safe-bash-command-pandoc/command.js +3 -3
  16. package/dist/safe-bash-command-pandoc/index.js +3 -3
  17. package/dist/safe-bash-command-pdfimages/index.js +186 -55
  18. package/dist/safe-bash-command-pdfinfo/index.js +273 -91
  19. package/dist/safe-bash-command-pdftk/index.js +186 -55
  20. package/dist/safe-bash-command-pdftoppm/index.js +273 -91
  21. package/dist/safe-bash-command-pdftotext/index.js +186 -55
  22. package/dist/safe-bash-command-qpdf/index.js +186 -55
  23. package/dist/safe-bash-command-sips/index.js +2 -2
  24. package/dist/safe-bash-command-soffice/index.js +1 -1
  25. package/dist/safe-bash-command-ssconvert/index.js +249 -58
  26. package/dist/safe-bash-command-wkhtmltopdf/index.js +186 -55
  27. package/package.json +2 -2
  28. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +13 -0
@@ -4,7 +4,75 @@ import {
4
4
 
5
5
  // packages/safe-bash-command-gh/dist/index.js
6
6
  init_buffer();
7
- import { commandRuntimeIdentity, readBytes, writeBytes } from "../safe-bash-contracts/index.js";
7
+
8
+ // packages/safe-bash-command-gh/dist/input.js
9
+ init_buffer();
10
+ import { resolvePath } from "@poe-platform/safe-fs/core";
11
+ import { readBytes } from "../safe-bash-contracts/index.js";
12
+ function createGhInput(context, limits) {
13
+ let inputBytes = 0;
14
+ const files = /* @__PURE__ */ new Set();
15
+ let failure;
16
+ const assertWithinLimits = () => {
17
+ if (failure)
18
+ throw failure;
19
+ };
20
+ const chargeBytes = (count) => {
21
+ assertWithinLimits();
22
+ inputBytes += count;
23
+ if (inputBytes > limits.maxInputBytes) {
24
+ failure = new Error("gh input byte limit exceeded");
25
+ throw failure;
26
+ }
27
+ };
28
+ const readFile = async (path, options) => {
29
+ assertWithinLimits();
30
+ const resolved = resolvePath(context.cwd, path);
31
+ const stat = await context.fs.stat(resolved, options);
32
+ if (!files.has(resolved)) {
33
+ if (files.size >= limits.maxFiles) {
34
+ failure = new Error("gh file limit exceeded");
35
+ throw failure;
36
+ }
37
+ files.add(resolved);
38
+ }
39
+ chargeBytes(stat.size);
40
+ const bytes = await context.fs.readFile(resolved, options);
41
+ if (bytes.length > stat.size)
42
+ chargeBytes(bytes.length - stat.size);
43
+ assertWithinLimits();
44
+ return bytes;
45
+ };
46
+ const fs = new Proxy(context.fs, {
47
+ get(target, property) {
48
+ if (property === "readFile")
49
+ return readFile;
50
+ const value = Reflect.get(target, property, target);
51
+ return typeof value === "function" ? value.bind(target) : value;
52
+ }
53
+ });
54
+ let stdin;
55
+ const readStdinBytes = () => stdin ??= (async () => {
56
+ const chunks = [];
57
+ let size = 0;
58
+ for await (const chunk of readBytes(context.stdin, context.signal)) {
59
+ chargeBytes(chunk.length);
60
+ chunks.push(chunk);
61
+ size += chunk.length;
62
+ }
63
+ const bytes = new Uint8Array(size);
64
+ let offset = 0;
65
+ for (const chunk of chunks) {
66
+ bytes.set(chunk, offset);
67
+ offset += chunk.length;
68
+ }
69
+ return bytes;
70
+ })();
71
+ return { fs, readStdinBytes, assertWithinLimits };
72
+ }
73
+
74
+ // packages/safe-bash-command-gh/dist/index.js
75
+ import { commandRuntimeIdentity, writeBytes } from "../safe-bash-contracts/index.js";
8
76
 
9
77
  // packages/safe-bash-command-gh/dist/args.js
10
78
  init_buffer();
@@ -670,7 +738,7 @@ function encodeUtf8(text) {
670
738
 
671
739
  // packages/safe-bash-command-gh/dist/git-vfs.js
672
740
  init_buffer();
673
- import { resolvePath } from "@poe-platform/safe-fs/core";
741
+ import { resolvePath as resolvePath2 } from "@poe-platform/safe-fs/core";
674
742
  import { createGitCommand } from "../safe-bash-command-git/index.js";
675
743
  var cachedGitCommand;
676
744
  function getDefaultGitCommand() {
@@ -722,7 +790,7 @@ async function pathExists(fs, path, signal) {
722
790
  }
723
791
  }
724
792
  async function findGitRoot(fs, startCwd, signal) {
725
- let current = resolvePath("/", startCwd);
793
+ let current = resolvePath2("/", startCwd);
726
794
  for (let depth = 0; depth < 64; depth++) {
727
795
  const gitPath = current === "/" ? "/.git" : `${current}/.git`;
728
796
  if (await pathExists(fs, gitPath, signal)) {
@@ -2040,7 +2108,7 @@ function createGitHubBackend(options) {
2040
2108
 
2041
2109
  // packages/safe-bash-command-gh/dist/commands/issue.js
2042
2110
  init_buffer();
2043
- import { resolvePath as resolvePath2 } from "@poe-platform/safe-fs/core";
2111
+ import { resolvePath as resolvePath3 } from "@poe-platform/safe-fs/core";
2044
2112
 
2045
2113
  // packages/safe-bash-command-gh/dist/template.js
2046
2114
  init_buffer();
@@ -2533,7 +2601,7 @@ function serializeIssueForJson(issue) {
2533
2601
  };
2534
2602
  }
2535
2603
  async function handleIssueCommand(env, rawArgs) {
2536
- const { context, backend, git, openBrowser, limits, stdinText, writeOut, writeErr } = env;
2604
+ const { context, backend, git, openBrowser, limits, readStdinText, writeOut, writeErr } = env;
2537
2605
  const subcommand = rawArgs[0];
2538
2606
  const restArgs = rawArgs.slice(1);
2539
2607
  if (!subcommand || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
@@ -2584,7 +2652,7 @@ async function handleIssueCommand(env, rawArgs) {
2584
2652
  const repo = backend.getOrCreateRepo(coords.owner, coords.name);
2585
2653
  const title = getStringFlag(parsed, "title") ?? "New issue";
2586
2654
  const bodyFile = getStringFlag(parsed, "body-file");
2587
- const body = bodyFile !== void 0 ? bodyFile === "-" ? stdinText : decodeUtf8(await context.fs.readFile(resolvePath2(context.cwd, bodyFile), { signal: context.signal })) : getStringFlag(parsed, "body") ?? "";
2655
+ const body = bodyFile !== void 0 ? bodyFile === "-" ? await readStdinText() : decodeUtf8(await context.fs.readFile(resolvePath3(context.cwd, bodyFile), { signal: context.signal })) : getStringFlag(parsed, "body") ?? "";
2588
2656
  const issue = backend.createIssue(repo, {
2589
2657
  title,
2590
2658
  body,
@@ -2770,7 +2838,7 @@ ${c.body}
2770
2838
  return 0;
2771
2839
  }
2772
2840
  const bodyFile = getStringFlag(parsed, "body-file");
2773
- const body = bodyFile !== void 0 ? bodyFile === "-" ? stdinText : decodeUtf8(await context.fs.readFile(resolvePath2(context.cwd, bodyFile), { signal: context.signal })) : getStringFlag(parsed, "body") ?? "";
2841
+ const body = bodyFile !== void 0 ? bodyFile === "-" ? await readStdinText() : decodeUtf8(await context.fs.readFile(resolvePath3(context.cwd, bodyFile), { signal: context.signal })) : getStringFlag(parsed, "body") ?? "";
2774
2842
  if (!body) {
2775
2843
  await writeErr("body cannot be blank; provide -b/--body or -F/--body-file\n");
2776
2844
  return 1;
@@ -2828,7 +2896,7 @@ ${c.body}
2828
2896
  if (title !== void 0)
2829
2897
  issue.title = title;
2830
2898
  const bodyFile = getStringFlag(parsed, "body-file");
2831
- const body = bodyFile !== void 0 ? bodyFile === "-" ? stdinText : decodeUtf8(await context.fs.readFile(resolvePath2(context.cwd, bodyFile), { signal: context.signal })) : getStringFlag(parsed, "body");
2899
+ const body = bodyFile !== void 0 ? bodyFile === "-" ? await readStdinText() : decodeUtf8(await context.fs.readFile(resolvePath3(context.cwd, bodyFile), { signal: context.signal })) : getStringFlag(parsed, "body");
2832
2900
  if (body !== void 0)
2833
2901
  issue.body = body;
2834
2902
  for (const lblName of getStringArrayFlag(parsed, "add-label")) {
@@ -2990,7 +3058,7 @@ ${c.body}
2990
3058
 
2991
3059
  // packages/safe-bash-command-gh/dist/commands/pr.js
2992
3060
  init_buffer();
2993
- import { resolvePath as resolvePath3 } from "@poe-platform/safe-fs/core";
3061
+ import { resolvePath as resolvePath4 } from "@poe-platform/safe-fs/core";
2994
3062
  var PR_JSON_FIELDS = [
2995
3063
  "additions",
2996
3064
  "assignees",
@@ -3061,12 +3129,12 @@ function serializePrForJson(pr) {
3061
3129
  reactionGroups: []
3062
3130
  };
3063
3131
  }
3064
- async function readBodyFromFlagOrFile(context, bodyFlag, bodyFileFlag, stdinText) {
3132
+ async function readBodyFromFlagOrFile(context, bodyFlag, bodyFileFlag, readStdinText) {
3065
3133
  if (bodyFileFlag !== void 0) {
3066
3134
  if (bodyFileFlag === "-") {
3067
- return stdinText;
3135
+ return readStdinText();
3068
3136
  }
3069
- const resolved = resolvePath3(context.cwd, bodyFileFlag);
3137
+ const resolved = resolvePath4(context.cwd, bodyFileFlag);
3070
3138
  const bytes = await context.fs.readFile(resolved, { signal: context.signal });
3071
3139
  return decodeUtf8(bytes);
3072
3140
  }
@@ -3083,7 +3151,7 @@ function extractRepoAndSelectorFromPrArg(selector, explicitRepoFlag) {
3083
3151
  return { repoOverride: explicitRepoFlag, selector };
3084
3152
  }
3085
3153
  async function handlePrCommand(env, rawArgs) {
3086
- const { context, backend, git, openBrowser, limits, stdinText, writeOut, writeErr } = env;
3154
+ const { context, backend, git, openBrowser, limits, readStdinText, writeOut, writeErr } = env;
3087
3155
  const subcommand = rawArgs[0];
3088
3156
  const restArgs = rawArgs.slice(1);
3089
3157
  if (!subcommand || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
@@ -3178,10 +3246,10 @@ ${existingOpen.url}
3178
3246
  const localCommits = gitRoot ? await inspectLocalCommitsForPr(context, gitRoot, baseBranch, headBranch, git) : [];
3179
3247
  const localFiles = gitRoot ? await readWorktreeFiles(context.fs, gitRoot, context.signal) : void 0;
3180
3248
  let title = getStringFlag(parsed, "title");
3181
- let body = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), stdinText);
3249
+ let body = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), readStdinText);
3182
3250
  if (parsed.flags.has("recover")) {
3183
3251
  const recoverFile = getStringFlag(parsed, "recover");
3184
- const recoverContent = decodeUtf8(await context.fs.readFile(resolvePath3(context.cwd, recoverFile), { signal: context.signal }));
3252
+ const recoverContent = decodeUtf8(await context.fs.readFile(resolvePath4(context.cwd, recoverFile), { signal: context.signal }));
3185
3253
  const lines = recoverContent.split(/\r?\n/u);
3186
3254
  if (!title && lines[0])
3187
3255
  title = lines[0];
@@ -3200,9 +3268,9 @@ ${existingOpen.url}
3200
3268
  const templateFile = getStringFlag(parsed, "template");
3201
3269
  if (templateFile && gitRoot) {
3202
3270
  const candidatePaths = [
3203
- resolvePath3(gitRoot, templateFile),
3204
- resolvePath3(gitRoot, `.github/PULL_REQUEST_TEMPLATE/${templateFile}`),
3205
- resolvePath3(gitRoot, `.github/${templateFile}`)
3271
+ resolvePath4(gitRoot, templateFile),
3272
+ resolvePath4(gitRoot, `.github/PULL_REQUEST_TEMPLATE/${templateFile}`),
3273
+ resolvePath4(gitRoot, `.github/${templateFile}`)
3206
3274
  ];
3207
3275
  for (const p of candidatePaths) {
3208
3276
  if (await pathExists(context.fs, p, context.signal)) {
@@ -3655,7 +3723,7 @@ ${c.body}
3655
3723
  const mergeOid = bytesToHex(sha1Sync(`merged:${repo.nameWithOwner}:${pr.number}:${method}:${backend.isoNow()}`));
3656
3724
  repo.branches.set(pr.baseRefName, mergeOid);
3657
3725
  const subject = getStringFlag(parsed, "subject") ?? `${pr.title} (#${pr.number})`;
3658
- const mergeBody = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), stdinText) ?? pr.body;
3726
+ const mergeBody = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), readStdinText) ?? pr.body;
3659
3727
  repo.commits.set(mergeOid, {
3660
3728
  oid: mergeOid,
3661
3729
  messageHeadline: subject,
@@ -3715,7 +3783,7 @@ ${c.body}
3715
3783
  await writeErr("one of --approve, --request-changes, or --comment is required\n");
3716
3784
  return 1;
3717
3785
  }
3718
- const body = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), stdinText) ?? "";
3786
+ const body = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), readStdinText) ?? "";
3719
3787
  if ((requestChanges || commentOnly) && !body.trim()) {
3720
3788
  await writeErr("body cannot be blank for --request-changes or --comment review\n");
3721
3789
  return 1;
@@ -3839,7 +3907,7 @@ ${c.body}
3839
3907
  await writeErr("no comments found for current user\n");
3840
3908
  return 1;
3841
3909
  }
3842
- const body = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), stdinText);
3910
+ const body = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), readStdinText);
3843
3911
  if (!body) {
3844
3912
  await writeErr("body cannot be blank; provide -b/--body or -F/--body-file\n");
3845
3913
  return 1;
@@ -3910,7 +3978,7 @@ ${c.body}
3910
3978
  const newTitle = getStringFlag(parsed, "title");
3911
3979
  if (newTitle !== void 0)
3912
3980
  pr.title = newTitle;
3913
- const newBody = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), stdinText);
3981
+ const newBody = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), readStdinText);
3914
3982
  if (newBody !== void 0)
3915
3983
  pr.body = newBody;
3916
3984
  const newBase = getStringFlag(parsed, "base");
@@ -4183,7 +4251,7 @@ ${c.body}
4183
4251
  }
4184
4252
  const revertBranch = `revert-${pr.number}-${pr.headRefName}`;
4185
4253
  const revertTitle = getStringFlag(parsed, "title") ?? `Revert "${pr.title}"`;
4186
- const revertBody = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), stdinText) ?? `Reverts ${repo.nameWithOwner}#${pr.number}`;
4254
+ const revertBody = await readBodyFromFlagOrFile(context, getStringFlag(parsed, "body"), getStringFlag(parsed, "body-file"), readStdinText) ?? `Reverts ${repo.nameWithOwner}#${pr.number}`;
4187
4255
  const revertPr = backend.createPullRequest(repo, {
4188
4256
  title: revertTitle,
4189
4257
  body: revertBody,
@@ -4202,7 +4270,7 @@ ${c.body}
4202
4270
 
4203
4271
  // packages/safe-bash-command-gh/dist/commands/release-run-workflow.js
4204
4272
  init_buffer();
4205
- import { isFsError, resolvePath as resolvePath4 } from "@poe-platform/safe-fs/core";
4273
+ import { isFsError, resolvePath as resolvePath5 } from "@poe-platform/safe-fs/core";
4206
4274
  var RELEASE_JSON_FIELDS = [
4207
4275
  "apiUrl",
4208
4276
  "assets",
@@ -4254,7 +4322,7 @@ function globMatches(pattern, candidate) {
4254
4322
  return new RegExp(`^${escaped}$`, "iu").test(candidate);
4255
4323
  }
4256
4324
  async function handleReleaseCommand(env, rawArgs) {
4257
- const { context, backend, openssl, openBrowser, stdinText, writeOut, writeErr } = env;
4325
+ const { context, backend, openssl, openBrowser, readStdinText, writeOut, writeErr } = env;
4258
4326
  const subcommand = rawArgs[0];
4259
4327
  const restArgs = rawArgs.slice(1);
4260
4328
  if (!subcommand || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
@@ -4319,7 +4387,7 @@ async function handleReleaseCommand(env, rawArgs) {
4319
4387
  return 1;
4320
4388
  }
4321
4389
  const notesFile = getStringFlag(parsed, "notes-file");
4322
- let body = notesFile !== void 0 ? notesFile === "-" ? stdinText : decodeUtf8(await context.fs.readFile(resolvePath4(context.cwd, notesFile), { signal: context.signal })) : getStringFlag(parsed, "notes") ?? "";
4390
+ let body = notesFile !== void 0 ? notesFile === "-" ? await readStdinText() : decodeUtf8(await context.fs.readFile(resolvePath5(context.cwd, notesFile), { signal: context.signal })) : getStringFlag(parsed, "notes") ?? "";
4323
4391
  if (!body && getBoolFlag(parsed, "generate-notes")) {
4324
4392
  const prs = Array.from(repo.pullRequests.values());
4325
4393
  body = "## What's Changed\n" + (prs.length > 0 ? prs.map((p) => `* ${p.title} by @${p.author.login} in #${p.number}`).join("\n") : `* Release ${tagName}`);
@@ -4337,7 +4405,7 @@ async function handleReleaseCommand(env, rawArgs) {
4337
4405
  const hashIdx = fileSpec.indexOf("#");
4338
4406
  const rawPath = hashIdx === -1 ? fileSpec : fileSpec.slice(0, hashIdx);
4339
4407
  const label = hashIdx === -1 ? "" : fileSpec.slice(hashIdx + 1);
4340
- const resolved = resolvePath4(context.cwd, rawPath);
4408
+ const resolved = resolvePath5(context.cwd, rawPath);
4341
4409
  const data = await context.fs.readFile(resolved, { signal: context.signal });
4342
4410
  const fileName = resolved.split("/").pop() ?? rawPath;
4343
4411
  assets.push({
@@ -4466,7 +4534,7 @@ async function handleReleaseCommand(env, rawArgs) {
4466
4534
  const hashIdx = fileSpec.indexOf("#");
4467
4535
  const rawPath = hashIdx === -1 ? fileSpec : fileSpec.slice(0, hashIdx);
4468
4536
  const label = hashIdx === -1 ? "" : fileSpec.slice(hashIdx + 1);
4469
- const resolved = resolvePath4(context.cwd, rawPath);
4537
+ const resolved = resolvePath5(context.cwd, rawPath);
4470
4538
  const data = await context.fs.readFile(resolved, { signal: context.signal });
4471
4539
  const fileName = resolved.split("/").pop() ?? rawPath;
4472
4540
  const existingIdx = rel.assets.findIndex((a) => a.name === fileName);
@@ -4513,7 +4581,7 @@ async function handleReleaseCommand(env, rawArgs) {
4513
4581
  `);
4514
4582
  return 1;
4515
4583
  }
4516
- const outDir = resolvePath4(context.cwd, getStringFlag(parsed, "dir") ?? ".");
4584
+ const outDir = resolvePath5(context.cwd, getStringFlag(parsed, "dir") ?? ".");
4517
4585
  await context.fs.mkdir(outDir, { recursive: true, signal: context.signal });
4518
4586
  const clobber = getBoolFlag(parsed, "clobber");
4519
4587
  const skipExisting = getBoolFlag(parsed, "skip-existing");
@@ -4537,13 +4605,13 @@ async function handleReleaseCommand(env, rawArgs) {
4537
4605
  const archiveFormat = getStringFlag(parsed, "archive");
4538
4606
  if (archiveFormat) {
4539
4607
  const fileName = `${repo.name}-${rel.tagName}.${archiveFormat}`;
4540
- const dest = getStringFlag(parsed, "output") ? resolvePath4(context.cwd, getStringFlag(parsed, "output")) : `${outDir === "/" ? "" : outDir}/${fileName}`;
4608
+ const dest = getStringFlag(parsed, "output") ? resolvePath5(context.cwd, getStringFlag(parsed, "output")) : `${outDir === "/" ? "" : outDir}/${fileName}`;
4541
4609
  return await download(dest, encodeUtf8(`ARCHIVE:${repo.nameWithOwner}:${rel.tagName}`)) ? 0 : 1;
4542
4610
  }
4543
4611
  const patterns = getStringArrayFlag(parsed, "pattern");
4544
4612
  const matching = rel.assets.filter((a) => patterns.length === 0 || patterns.some((pat) => globMatches(pat, a.name)));
4545
4613
  for (const asset of matching) {
4546
- const dest = getStringFlag(parsed, "output") ? resolvePath4(context.cwd, getStringFlag(parsed, "output")) : `${outDir === "/" ? "" : outDir}/${asset.name}`;
4614
+ const dest = getStringFlag(parsed, "output") ? resolvePath5(context.cwd, getStringFlag(parsed, "output")) : `${outDir === "/" ? "" : outDir}/${asset.name}`;
4547
4615
  if (!await download(dest, asset.data))
4548
4616
  return 1;
4549
4617
  }
@@ -4572,7 +4640,7 @@ async function handleReleaseCommand(env, rawArgs) {
4572
4640
  if (title !== void 0)
4573
4641
  rel.name = title;
4574
4642
  const notesFile = getStringFlag(parsed, "notes-file");
4575
- const notes = notesFile !== void 0 ? notesFile === "-" ? stdinText : decodeUtf8(await context.fs.readFile(resolvePath4(context.cwd, notesFile), { signal: context.signal })) : getStringFlag(parsed, "notes");
4643
+ const notes = notesFile !== void 0 ? notesFile === "-" ? await readStdinText() : decodeUtf8(await context.fs.readFile(resolvePath5(context.cwd, notesFile), { signal: context.signal })) : getStringFlag(parsed, "notes");
4576
4644
  if (notes !== void 0)
4577
4645
  rel.body = notes;
4578
4646
  if (parsed.flags.has("draft"))
@@ -4635,7 +4703,7 @@ async function handleReleaseCommand(env, rawArgs) {
4635
4703
  let bytes = encodeUtf8(targetTagOrFile);
4636
4704
  if (subcommand === "verify-asset") {
4637
4705
  const assetFile = parsed.positionals[1] ?? parsed.positionals[0];
4638
- bytes = await context.fs.readFile(resolvePath4(context.cwd, assetFile), { signal: context.signal });
4706
+ bytes = await context.fs.readFile(resolvePath5(context.cwd, assetFile), { signal: context.signal });
4639
4707
  }
4640
4708
  const verification = await openssl.verifyAttestationSignature({ repository: repo.nameWithOwner }, bytes);
4641
4709
  await writeOut(`\u2713 Verification succeeded! Digest ${verification.subjectDigest} signed by ${verification.issuer} for ${verification.repository}
@@ -4872,7 +4940,7 @@ async function handleRunCommand(env, rawArgs) {
4872
4940
  `);
4873
4941
  return 1;
4874
4942
  }
4875
- const outDir = resolvePath4(context.cwd, getStringFlag(parsed, "dir") ?? ".");
4943
+ const outDir = resolvePath5(context.cwd, getStringFlag(parsed, "dir") ?? ".");
4876
4944
  await context.fs.mkdir(outDir, { recursive: true, signal: context.signal });
4877
4945
  const nameFilters = getStringArrayFlag(parsed, "name");
4878
4946
  for (const art of run.artifacts) {
@@ -5025,7 +5093,7 @@ State: ${wf.state}
5025
5093
 
5026
5094
  // packages/safe-bash-command-gh/dist/commands/repo.js
5027
5095
  init_buffer();
5028
- import { resolvePath as resolvePath5 } from "@poe-platform/safe-fs/core";
5096
+ import { resolvePath as resolvePath6 } from "@poe-platform/safe-fs/core";
5029
5097
  var REPO_JSON_FIELDS = [
5030
5098
  "archivedAt",
5031
5099
  "assignableUsers",
@@ -5268,7 +5336,7 @@ async function handleRepoCommand(env, rawArgs) {
5268
5336
  }, env.http, limits);
5269
5337
  }
5270
5338
  const dirArg = parsed.positionals[1] ?? repo.name;
5271
- const targetDir = resolvePath5(context.cwd, dirArg);
5339
+ const targetDir = resolvePath6(context.cwd, dirArg);
5272
5340
  const branchFlag = extractBranchFromGitFlags(parsed.passthrough);
5273
5341
  const upstreamRemoteName = getStringFlag(parsed, "upstream-remote-name") ?? "upstream";
5274
5342
  const useSsh = repoArg.startsWith("git@") || repoArg.startsWith("ssh://") || backend.config.gitProtocol === "ssh";
@@ -5312,7 +5380,7 @@ async function handleRepoCommand(env, rawArgs) {
5312
5380
  return 0;
5313
5381
  }
5314
5382
  const sourceDirFlag = getStringFlag(parsed, "source");
5315
- const rawName = parsed.positionals[0] ?? (sourceDirFlag ? resolvePath5(context.cwd, sourceDirFlag).split("/").filter(Boolean).pop() : void 0) ?? "new-repo";
5383
+ const rawName = parsed.positionals[0] ?? (sourceDirFlag ? resolvePath6(context.cwd, sourceDirFlag).split("/").filter(Boolean).pop() : void 0) ?? "new-repo";
5316
5384
  const coords = parseRepoSpec(rawName, backend.defaultHost, backend.getActiveUser());
5317
5385
  if (backend.getRepo(coords.owner, coords.name)) {
5318
5386
  await writeErr(`repository ${coords.nameWithOwner} already exists
@@ -5329,7 +5397,7 @@ async function handleRepoCommand(env, rawArgs) {
5329
5397
  Object.assign(initialFiles, tmplFiles);
5330
5398
  }
5331
5399
  if (sourceDirFlag && getBoolFlag(parsed, "push")) {
5332
- const srcPath = resolvePath5(context.cwd, sourceDirFlag);
5400
+ const srcPath = resolvePath6(context.cwd, sourceDirFlag);
5333
5401
  const localFiles = await readWorktreeFiles(context.fs, srcPath, context.signal);
5334
5402
  Object.assign(initialFiles, localFiles);
5335
5403
  }
@@ -5379,7 +5447,7 @@ Copyright (c) ${coords.owner}
5379
5447
  if (getBoolFlag(parsed, "disable-wiki"))
5380
5448
  repo.hasWikiEnabled = false;
5381
5449
  if (sourceDirFlag) {
5382
- const srcPath = resolvePath5(context.cwd, sourceDirFlag);
5450
+ const srcPath = resolvePath6(context.cwd, sourceDirFlag);
5383
5451
  const remoteName = getStringFlag(parsed, "remote") ?? "origin";
5384
5452
  await updateGitRemote(context.fs, srcPath, remoteName, repo.cloneUrl, "base", context.signal);
5385
5453
  if (getBoolFlag(parsed, "push")) {
@@ -5388,7 +5456,7 @@ Copyright (c) ${coords.owner}
5388
5456
  repo.branchFiles.set(currentBranch, worktree);
5389
5457
  }
5390
5458
  } else if (getBoolFlag(parsed, "clone")) {
5391
- const cloneTarget = resolvePath5(context.cwd, repo.name);
5459
+ const cloneTarget = resolvePath6(context.cwd, repo.name);
5392
5460
  await cloneRepositoryIntoVfs({
5393
5461
  context,
5394
5462
  repo,
@@ -5450,7 +5518,7 @@ Copyright (c) ${coords.owner}
5450
5518
  await updateGitRemote(context.fs, gitRoot, "upstream", sourceRepo.cloneUrl, "base", context.signal);
5451
5519
  }
5452
5520
  if (getBoolFlag(parsed, "clone")) {
5453
- const targetDir = resolvePath5(context.cwd, forkRepo.name);
5521
+ const targetDir = resolvePath6(context.cwd, forkRepo.name);
5454
5522
  await cloneRepositoryIntoVfs({
5455
5523
  context,
5456
5524
  repo: forkRepo,
@@ -5826,7 +5894,7 @@ Copyright (c) ${coords.owner}
5826
5894
  await writeErr("deploy key file required\n");
5827
5895
  return 1;
5828
5896
  }
5829
- const keyContent = decodeUtf8(await context.fs.readFile(resolvePath5(context.cwd, keyFile), { signal: context.signal })).trim();
5897
+ const keyContent = decodeUtf8(await context.fs.readFile(resolvePath6(context.cwd, keyFile), { signal: context.signal })).trim();
5830
5898
  if (ssh) {
5831
5899
  await ssh.fingerprint(keyContent);
5832
5900
  }
@@ -5958,7 +6026,7 @@ Alphanumeric: ${item.isAlphanumeric}
5958
6026
 
5959
6027
  // packages/safe-bash-command-gh/dist/commands/api.js
5960
6028
  init_buffer();
5961
- import { resolvePath as resolvePath6 } from "@poe-platform/safe-fs/core";
6029
+ import { resolvePath as resolvePath7 } from "@poe-platform/safe-fs/core";
5962
6030
  function setNestedField(target, keyPath, value) {
5963
6031
  const bracketMatch = /^([^[\]]+)((?:\[[^\]]*\])+)$/u.exec(keyPath);
5964
6032
  if (!bracketMatch) {
@@ -6002,7 +6070,7 @@ function setNestedField(target, keyPath, value) {
6002
6070
  }
6003
6071
  }
6004
6072
  async function handleApiCommand(env, rawArgs) {
6005
- const { context, backend, http, git, limits, stdinBytes, stdinText, writeOut, writeErr } = env;
6073
+ const { context, backend, http, git, limits, readStdinBytes, readStdinText, writeOut, writeErr } = env;
6006
6074
  const schemas = [
6007
6075
  { short: "X", long: "method", type: "string" },
6008
6076
  { short: "f", long: "raw-field", type: "string[]" },
@@ -6068,7 +6136,7 @@ async function handleApiCommand(env, rawArgs) {
6068
6136
  let coerced = rawVal;
6069
6137
  if (rawVal.startsWith("@")) {
6070
6138
  const fileRef = rawVal.slice(1);
6071
- coerced = fileRef === "-" ? stdinText : decodeUtf8(await context.fs.readFile(resolvePath6(context.cwd, fileRef), { signal: context.signal }));
6139
+ coerced = fileRef === "-" ? await readStdinText() : decodeUtf8(await context.fs.readFile(resolvePath7(context.cwd, fileRef), { signal: context.signal }));
6072
6140
  } else if (rawVal === "true")
6073
6141
  coerced = true;
6074
6142
  else if (rawVal === "false")
@@ -6093,7 +6161,7 @@ async function handleApiCommand(env, rawArgs) {
6093
6161
  }
6094
6162
  let requestBodyBytes = new Uint8Array();
6095
6163
  if (inputFlag !== void 0) {
6096
- requestBodyBytes = inputFlag === "-" ? stdinBytes : await context.fs.readFile(resolvePath6(context.cwd, inputFlag), { signal: context.signal });
6164
+ requestBodyBytes = inputFlag === "-" ? await readStdinBytes() : await context.fs.readFile(resolvePath7(context.cwd, inputFlag), { signal: context.signal });
6097
6165
  } else if (isGraphQl) {
6098
6166
  const query = String(payload.query ?? "");
6099
6167
  const variables = {};
@@ -6134,6 +6202,7 @@ async function handleApiCommand(env, rawArgs) {
6134
6202
  const jqFlag = getStringFlag(parsed, "jq");
6135
6203
  const templateFlag = getStringFlag(parsed, "template");
6136
6204
  const collectedPages = [];
6205
+ let hasArrayPage = false;
6137
6206
  let nextUrl = fullUrl;
6138
6207
  let lastStatus = 200;
6139
6208
  let lastHeaders = {};
@@ -6158,6 +6227,7 @@ async function handleApiCommand(env, rawArgs) {
6158
6227
  try {
6159
6228
  const parsedPage = JSON.parse(lastBodyText);
6160
6229
  if (Array.isArray(parsedPage) && paginate && !slurp) {
6230
+ hasArrayPage = true;
6161
6231
  collectedPages.push(...parsedPage);
6162
6232
  } else {
6163
6233
  collectedPages.push(parsedPage);
@@ -6182,7 +6252,7 @@ async function handleApiCommand(env, rawArgs) {
6182
6252
  }
6183
6253
  outputPrefix = headerLines.join("\r\n") + "\r\n\r\n";
6184
6254
  }
6185
- const finalData = paginate ? slurp ? collectedPages : collectedPages.length === 1 && !Array.isArray(collectedPages[0]) ? collectedPages[0] : collectedPages : collectedPages[0];
6255
+ const finalData = paginate ? slurp ? collectedPages : !hasArrayPage && collectedPages.length === 1 && !Array.isArray(collectedPages[0]) ? collectedPages[0] : collectedPages : collectedPages[0];
6186
6256
  if (jqFlag) {
6187
6257
  const jqOut = await evaluateJqExpression(finalData, jqFlag, context.signal, limits.maxOutputBytes);
6188
6258
  await writeOut(outputPrefix + jqOut);
@@ -6210,10 +6280,10 @@ async function handleApiCommand(env, rawArgs) {
6210
6280
 
6211
6281
  // packages/safe-bash-command-gh/dist/commands/auth.js
6212
6282
  init_buffer();
6213
- import { resolvePath as resolvePath7 } from "@poe-platform/safe-fs/core";
6283
+ import { resolvePath as resolvePath8 } from "@poe-platform/safe-fs/core";
6214
6284
  function getGhConfigDir(context) {
6215
6285
  if (context.env.GH_CONFIG_DIR) {
6216
- return resolvePath7(context.cwd, context.env.GH_CONFIG_DIR);
6286
+ return resolvePath8(context.cwd, context.env.GH_CONFIG_DIR);
6217
6287
  }
6218
6288
  const home = context.env.HOME || "/home/user";
6219
6289
  return `${home.replace(/\/+$/u, "")}/.config/gh`;
@@ -6236,7 +6306,7 @@ async function persistHostsConfig(context, backend) {
6236
6306
  });
6237
6307
  }
6238
6308
  async function handleAuthCommand(env, rawArgs) {
6239
- const { context, backend, stdinText, writeOut, writeErr } = env;
6309
+ const { context, backend, readStdinText, writeOut, writeErr } = env;
6240
6310
  const subcommand = rawArgs[0];
6241
6311
  const restArgs = rawArgs.slice(1);
6242
6312
  if (!subcommand || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
@@ -6273,7 +6343,7 @@ async function handleAuthCommand(env, rawArgs) {
6273
6343
  const user = getStringFlag(parsed, "user") ?? backend.currentUser;
6274
6344
  let token = "gho_authenticated_token";
6275
6345
  if (getBoolFlag(parsed, "with-token")) {
6276
- token = stdinText.trim();
6346
+ token = (await readStdinText()).trim();
6277
6347
  if (!token) {
6278
6348
  await writeErr("error: token required on standard input when using --with-token\n");
6279
6349
  return 1;
@@ -6488,9 +6558,9 @@ async function handleAuthCommand(env, rawArgs) {
6488
6558
 
6489
6559
  // packages/safe-bash-command-gh/dist/commands/misc.js
6490
6560
  init_buffer();
6491
- import { resolvePath as resolvePath8 } from "@poe-platform/safe-fs/core";
6561
+ import { resolvePath as resolvePath9 } from "@poe-platform/safe-fs/core";
6492
6562
  async function handleGistCommand(env, rawArgs) {
6493
- const { context, backend, git, stdinText, writeOut, writeErr } = env;
6563
+ const { context, backend, git, readStdinText, writeOut, writeErr } = env;
6494
6564
  const sub = rawArgs[0];
6495
6565
  const rest = rawArgs.slice(1);
6496
6566
  if (!sub || sub === "--help" || sub === "-h" || sub === "help") {
@@ -6507,10 +6577,11 @@ async function handleGistCommand(env, rawArgs) {
6507
6577
  const files = {};
6508
6578
  if (parsed.positionals.length === 0 || parsed.positionals.length === 1 && parsed.positionals[0] === "-") {
6509
6579
  const fn = getStringFlag(parsed, "filename") ?? "gistfile0.txt";
6510
- files[fn] = { filename: fn, content: stdinText, size: stdinText.length };
6580
+ const content = await readStdinText();
6581
+ files[fn] = { filename: fn, content, size: content.length };
6511
6582
  } else {
6512
6583
  for (const fileArg of parsed.positionals) {
6513
- const resolved = resolvePath8(context.cwd, fileArg);
6584
+ const resolved = resolvePath9(context.cwd, fileArg);
6514
6585
  const content = decodeUtf8(await context.fs.readFile(resolved, { signal: context.signal }));
6515
6586
  const fn = resolved.split("/").pop() ?? fileArg;
6516
6587
  files[fn] = { filename: fn, content, size: content.length };
@@ -6612,7 +6683,7 @@ async function handleGistCommand(env, rawArgs) {
6612
6683
  gist.description = desc;
6613
6684
  const addFile = getStringFlag(parsed, "add");
6614
6685
  if (addFile) {
6615
- const resolved = resolvePath8(context.cwd, addFile);
6686
+ const resolved = resolvePath9(context.cwd, addFile);
6616
6687
  const content = decodeUtf8(await context.fs.readFile(resolved, { signal: context.signal }));
6617
6688
  const fn = getStringFlag(parsed, "filename") ?? resolved.split("/").pop() ?? addFile;
6618
6689
  gist.files[fn] = { filename: fn, content, size: content.length };
@@ -6634,7 +6705,7 @@ async function handleGistCommand(env, rawArgs) {
6634
6705
  `);
6635
6706
  return 1;
6636
6707
  }
6637
- const targetDir = resolvePath8(context.cwd, parsed.positionals[1] ?? gist.id);
6708
+ const targetDir = resolvePath9(context.cwd, parsed.positionals[1] ?? gist.id);
6638
6709
  const fileMap = Object.fromEntries(Object.values(gist.files).map((f) => [f.filename, f.content]));
6639
6710
  await context.fs.mkdir(targetDir, { recursive: true, signal: context.signal });
6640
6711
  await runGitInVfs(context, ["init", "-b", "main"], { cwd: targetDir, git });
@@ -6960,7 +7031,7 @@ async function handleLabelCommand(env, rawArgs) {
6960
7031
  return 1;
6961
7032
  }
6962
7033
  async function handleSecretCommand(env, rawArgs) {
6963
- const { context, backend, openssl, stdinText, writeOut, writeErr } = env;
7034
+ const { context, backend, openssl, readStdinText, writeOut, writeErr } = env;
6964
7035
  const sub = rawArgs[0] ?? "list";
6965
7036
  const rest = rawArgs.slice(1);
6966
7037
  const schemas = [
@@ -6996,7 +7067,7 @@ async function handleSecretCommand(env, rawArgs) {
6996
7067
  if (sub === "set") {
6997
7068
  const envFile = getStringFlag(parsed, "env-file");
6998
7069
  if (envFile) {
6999
- const text = decodeUtf8(await context.fs.readFile(resolvePath8(context.cwd, envFile), { signal: context.signal }));
7070
+ const text = decodeUtf8(await context.fs.readFile(resolvePath9(context.cwd, envFile), { signal: context.signal }));
7000
7071
  for (const line of text.split(/\r?\n/u)) {
7001
7072
  const trimmed = line.trim();
7002
7073
  if (!trimmed || trimmed.startsWith("#"))
@@ -7021,7 +7092,7 @@ async function handleSecretCommand(env, rawArgs) {
7021
7092
  await writeErr("secret name required\n");
7022
7093
  return 1;
7023
7094
  }
7024
- const value = getStringFlag(parsed, "body") ?? stdinText.trim();
7095
+ const value = getStringFlag(parsed, "body") ?? (await readStdinText()).trim();
7025
7096
  const encrypted = await openssl.encryptSecretForGitHub(value, "gh_pub_key_b64", "key_1");
7026
7097
  const entry = {
7027
7098
  name,
@@ -7047,7 +7118,7 @@ async function handleSecretCommand(env, rawArgs) {
7047
7118
  return 1;
7048
7119
  }
7049
7120
  async function handleVariableCommand(env, rawArgs) {
7050
- const { context, backend, stdinText, writeOut, writeErr } = env;
7121
+ const { context, backend, readStdinText, writeOut, writeErr } = env;
7051
7122
  const sub = rawArgs[0] ?? "list";
7052
7123
  const rest = rawArgs.slice(1);
7053
7124
  const schemas = [
@@ -7095,7 +7166,7 @@ async function handleVariableCommand(env, rawArgs) {
7095
7166
  await writeErr("variable name required\n");
7096
7167
  return 1;
7097
7168
  }
7098
- const value = getStringFlag(parsed, "body") ?? parsed.positionals[1] ?? stdinText.trim();
7169
+ const value = getStringFlag(parsed, "body") ?? parsed.positionals[1] ?? (await readStdinText()).trim();
7099
7170
  const ts = backend.isoNow();
7100
7171
  const entry = {
7101
7172
  name,
@@ -7180,7 +7251,7 @@ async function handleCacheCommand(env, rawArgs) {
7180
7251
  return 1;
7181
7252
  }
7182
7253
  async function handleSshKeyCommand(env, rawArgs) {
7183
- const { context, backend, ssh, stdinText, writeOut, writeErr } = env;
7254
+ const { context, backend, ssh, readStdinText, writeOut, writeErr } = env;
7184
7255
  const sub = rawArgs[0] ?? "list";
7185
7256
  const rest = rawArgs.slice(1);
7186
7257
  const schemas = [
@@ -7208,9 +7279,11 @@ async function handleSshKeyCommand(env, rawArgs) {
7208
7279
  }
7209
7280
  if (sub === "add") {
7210
7281
  const keyFile = parsed.positionals[0];
7211
- let keyContent = stdinText.trim();
7282
+ let keyContent;
7212
7283
  if (keyFile && keyFile !== "-") {
7213
- keyContent = decodeUtf8(await context.fs.readFile(resolvePath8(context.cwd, keyFile), { signal: context.signal })).trim();
7284
+ keyContent = decodeUtf8(await context.fs.readFile(resolvePath9(context.cwd, keyFile), { signal: context.signal })).trim();
7285
+ } else {
7286
+ keyContent = (await readStdinText()).trim();
7214
7287
  }
7215
7288
  if (!keyContent) {
7216
7289
  const generated = await ssh.keygen({ comment: `${backend.getActiveUser()}@safe-bash` });
@@ -7243,7 +7316,7 @@ async function handleSshKeyCommand(env, rawArgs) {
7243
7316
  return 1;
7244
7317
  }
7245
7318
  async function handleGpgKeyCommand(env, rawArgs) {
7246
- const { context, backend, openssl, stdinText, writeOut, writeErr } = env;
7319
+ const { context, backend, openssl, readStdinText, writeOut, writeErr } = env;
7247
7320
  const sub = rawArgs[0] ?? "list";
7248
7321
  const rest = rawArgs.slice(1);
7249
7322
  const parsed = parseCommandArgs(rest, [{ short: "t", long: "title", type: "string" }]);
@@ -7267,7 +7340,7 @@ async function handleGpgKeyCommand(env, rawArgs) {
7267
7340
  }
7268
7341
  if (sub === "add") {
7269
7342
  const keyFile = parsed.positionals[0];
7270
- const rawKey = keyFile && keyFile !== "-" ? decodeUtf8(await context.fs.readFile(resolvePath8(context.cwd, keyFile), { signal: context.signal })).trim() : stdinText.trim() || "-----BEGIN PGP PUBLIC KEY BLOCK-----\nFAKE\n-----END PGP PUBLIC KEY BLOCK-----";
7343
+ const rawKey = keyFile && keyFile !== "-" ? decodeUtf8(await context.fs.readFile(resolvePath9(context.cwd, keyFile), { signal: context.signal })).trim() : (await readStdinText()).trim() || "-----BEGIN PGP PUBLIC KEY BLOCK-----\nFAKE\n-----END PGP PUBLIC KEY BLOCK-----";
7271
7344
  const digest = await openssl.sha256(rawKey);
7272
7345
  const keyId = bytesToHex(digest).slice(0, 16).toUpperCase();
7273
7346
  const id = backend.nextId();
@@ -7316,7 +7389,7 @@ async function handleAttestationCommand(env, rawArgs) {
7316
7389
  await writeErr("artifact path required for attestation verify\n");
7317
7390
  return 1;
7318
7391
  }
7319
- const bytes = await context.fs.readFile(resolvePath8(context.cwd, fileArg), {
7392
+ const bytes = await context.fs.readFile(resolvePath9(context.cwd, fileArg), {
7320
7393
  signal: context.signal
7321
7394
  });
7322
7395
  let bundleData = {
@@ -7325,7 +7398,7 @@ async function handleAttestationCommand(env, rawArgs) {
7325
7398
  const bundleFile = getStringFlag(parsed, "bundle");
7326
7399
  if (bundleFile) {
7327
7400
  try {
7328
- bundleData = JSON.parse(decodeUtf8(await context.fs.readFile(resolvePath8(context.cwd, bundleFile), { signal: context.signal })));
7401
+ bundleData = JSON.parse(decodeUtf8(await context.fs.readFile(resolvePath9(context.cwd, bundleFile), { signal: context.signal })));
7329
7402
  } catch {
7330
7403
  }
7331
7404
  }
@@ -8154,23 +8227,31 @@ function normalizeTopLevelArgs(rawArgs) {
8154
8227
  }
8155
8228
  function createGhCommand(options = {}) {
8156
8229
  const limits = { ...DEFAULT_GH_LIMITS, ...options.limits };
8157
- const backend = options.backend ?? createGitHubBackend({
8158
- defaultHost: options.defaultHost,
8159
- defaultUser: options.defaultUser,
8160
- defaultToken: options.defaultToken,
8161
- now: options.now
8162
- });
8230
+ const backends = /* @__PURE__ */ new WeakMap();
8163
8231
  const openssl = createDefaultOpenSslProvider(options.openssl);
8164
- const ssh = createDefaultSshProvider(options.ssh, backend.getActiveUser());
8165
8232
  const def = {
8166
8233
  name: "gh",
8167
8234
  runtimeIdentity: commandRuntimeIdentity,
8168
8235
  description: "Work seamlessly with GitHub from the command line",
8169
8236
  async execute(context) {
8170
8237
  context.signal.throwIfAborted();
8238
+ let backend = options.backend ?? backends.get(context.fs);
8239
+ if (!backend) {
8240
+ backend = createGitHubBackend({
8241
+ defaultHost: options.defaultHost,
8242
+ defaultUser: options.defaultUser,
8243
+ defaultToken: options.defaultToken,
8244
+ now: options.now
8245
+ });
8246
+ backends.set(context.fs, backend);
8247
+ }
8171
8248
  backend.resetUsage();
8249
+ const ssh = createDefaultSshProvider(options.ssh, backend.getActiveUser());
8250
+ const input = createGhInput(context, limits);
8251
+ context = { ...context, fs: input.fs };
8172
8252
  let outputBytes = 0;
8173
8253
  const writeOut = async (text) => {
8254
+ input.assertWithinLimits();
8174
8255
  const bytes = encodeUtf8(text);
8175
8256
  outputBytes += bytes.length;
8176
8257
  if (outputBytes > limits.maxOutputBytes) {
@@ -8183,22 +8264,8 @@ function createGhCommand(options = {}) {
8183
8264
  await writeBytes(context.stderr, bytes, context.signal);
8184
8265
  };
8185
8266
  try {
8186
- const stdinChunks = [];
8187
- let totalIn = 0;
8188
- for await (const chunk of readBytes(context.stdin, context.signal)) {
8189
- totalIn += chunk.length;
8190
- if (totalIn > limits.maxInputBytes) {
8191
- throw new Error("gh input byte limit exceeded");
8192
- }
8193
- stdinChunks.push(chunk);
8194
- }
8195
- const stdinBytes = new Uint8Array(totalIn);
8196
- let inOffset = 0;
8197
- for (const chunk of stdinChunks) {
8198
- stdinBytes.set(chunk, inOffset);
8199
- inOffset += chunk.length;
8200
- }
8201
- const stdinText = decodeUtf8(stdinBytes);
8267
+ const readStdinBytes = input.readStdinBytes;
8268
+ const readStdinText = async () => decodeUtf8(await readStdinBytes());
8202
8269
  const dispatch = async (argsToRun, depth = 0) => {
8203
8270
  if (depth > 8) {
8204
8271
  await writeErr("gh: alias expansion loop detected\n");
@@ -8240,7 +8307,7 @@ function createGhCommand(options = {}) {
8240
8307
  git: options.git,
8241
8308
  openBrowser: options.openBrowser,
8242
8309
  limits,
8243
- stdinText,
8310
+ readStdinText,
8244
8311
  writeOut,
8245
8312
  writeErr
8246
8313
  };
@@ -8253,7 +8320,7 @@ function createGhCommand(options = {}) {
8253
8320
  git: options.git,
8254
8321
  openBrowser: options.openBrowser,
8255
8322
  limits,
8256
- stdinText,
8323
+ readStdinText,
8257
8324
  writeOut,
8258
8325
  writeErr
8259
8326
  }, subArgs);
@@ -8276,7 +8343,7 @@ function createGhCommand(options = {}) {
8276
8343
  git: options.git,
8277
8344
  openBrowser: options.openBrowser,
8278
8345
  limits,
8279
- stdinText,
8346
+ readStdinText,
8280
8347
  writeOut,
8281
8348
  writeErr
8282
8349
  }, subArgs);
@@ -8287,8 +8354,8 @@ function createGhCommand(options = {}) {
8287
8354
  http: options.http,
8288
8355
  git: options.git,
8289
8356
  limits,
8290
- stdinBytes,
8291
- stdinText,
8357
+ readStdinBytes,
8358
+ readStdinText,
8292
8359
  writeOut,
8293
8360
  writeErr
8294
8361
  }, subArgs);
@@ -8297,7 +8364,7 @@ function createGhCommand(options = {}) {
8297
8364
  limits,
8298
8365
  context,
8299
8366
  backend,
8300
- stdinText,
8367
+ readStdinText,
8301
8368
  writeOut,
8302
8369
  writeErr
8303
8370
  }, subArgs);
@@ -8360,6 +8427,7 @@ complete -W "pr repo issue api auth release run workflow gist search label secre
8360
8427
  }
8361
8428
  };
8362
8429
  const exitCode = await dispatch(context.args);
8430
+ input.assertWithinLimits();
8363
8431
  return { exitCode };
8364
8432
  } catch (error) {
8365
8433
  context.signal.throwIfAborted();
@@ -8370,12 +8438,13 @@ complete -W "pr repo issue api auth release run workflow gist search label secre
8370
8438
  }
8371
8439
  }
8372
8440
  };
8373
- ghBackendByExecutor.set(def.execute, {
8374
- backend,
8375
- hasCustomHttp: Boolean(options.http),
8376
- hasCustomBrowser: Boolean(options.openBrowser),
8377
- limits
8378
- });
8441
+ if (options.backend)
8442
+ ghBackendByExecutor.set(def.execute, {
8443
+ backend: options.backend,
8444
+ hasCustomHttp: Boolean(options.http),
8445
+ hasCustomBrowser: Boolean(options.openBrowser),
8446
+ limits
8447
+ });
8379
8448
  return def;
8380
8449
  }
8381
8450
  var ghBackendByExecutor = /* @__PURE__ */ new WeakMap();
@@ -8566,7 +8635,7 @@ function serializePrForJsonSync(pr) {
8566
8635
  }
8567
8636
  function evalSyncGh(execFn, rawArgs, env, cwd, readFileSync) {
8568
8637
  const meta = ghBackendByExecutor.get(execFn);
8569
- if (!meta)
8638
+ if (!meta || readFileSync)
8570
8639
  return void 0;
8571
8640
  const { backend, hasCustomHttp, limits } = meta;
8572
8641
  let argsToRun = rawArgs;