@wrongstack/tools 0.313.0 → 0.313.1

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 (134) hide show
  1. package/dist/audit.js +10 -4055
  2. package/dist/bash.js +9 -2308
  3. package/dist/batch-tool-use.js +2 -187
  4. package/dist/browser/index.js +25 -1339
  5. package/dist/builtin.js +69 -33949
  6. package/dist/chunk-2CTB3UK5.js +197 -0
  7. package/dist/chunk-2ME7ZWDD.js +1272 -0
  8. package/dist/chunk-2TFQDEPU.js +113 -0
  9. package/dist/chunk-2ZCJNKFE.js +315 -0
  10. package/dist/chunk-3PVYQFRQ.js +472 -0
  11. package/dist/chunk-3QMQBO5Z.js +89 -0
  12. package/dist/chunk-42AKKX7O.js +385 -0
  13. package/dist/chunk-42SKEETB.js +113 -0
  14. package/dist/chunk-4BHUSMNL.js +104 -0
  15. package/dist/chunk-4I4LWFOO.js +431 -0
  16. package/dist/chunk-553IQUMO.js +478 -0
  17. package/dist/chunk-55KF77OK.js +1944 -0
  18. package/dist/chunk-6HLZK37X.js +359 -0
  19. package/dist/chunk-6RNIFLG4.js +305 -0
  20. package/dist/chunk-A6BRWIXN.js +317 -0
  21. package/dist/chunk-AHHDWNXC.js +200 -0
  22. package/dist/chunk-B2CIOKWP.js +899 -0
  23. package/dist/chunk-BTSFTGIL.js +7 -0
  24. package/dist/chunk-D33S4RQG.js +222 -0
  25. package/dist/chunk-DIJKHSUO.js +134 -0
  26. package/dist/chunk-DPL47QGS.js +3515 -0
  27. package/dist/chunk-EMRGN4KM.js +170 -0
  28. package/dist/chunk-FGOABE4Z.js +955 -0
  29. package/dist/chunk-FW65TP4G.js +520 -0
  30. package/dist/chunk-GOIZNNOA.js +221 -0
  31. package/dist/chunk-H5MJUAA6.js +295 -0
  32. package/dist/chunk-H5OHH6F4.js +223 -0
  33. package/dist/chunk-HC5RM4WY.js +199 -0
  34. package/dist/chunk-HEQFMLZ7.js +190 -0
  35. package/dist/chunk-HFXSNKCV.js +196 -0
  36. package/dist/chunk-HXSBQ2SE.js +1723 -0
  37. package/dist/chunk-ILESNGNM.js +163 -0
  38. package/dist/chunk-INF5CGAO.js +137 -0
  39. package/dist/chunk-IWDFZ6XR.js +337 -0
  40. package/dist/chunk-IXMNTNW5.js +238 -0
  41. package/dist/chunk-J4SRJKBW.js +428 -0
  42. package/dist/chunk-J5SKD6LN.js +235 -0
  43. package/dist/chunk-JRJJX3L5.js +424 -0
  44. package/dist/chunk-KXNDHMUB.js +366 -0
  45. package/dist/chunk-LIJQMYYX.js +59 -0
  46. package/dist/chunk-MAN26PZ5.js +260 -0
  47. package/dist/chunk-MKRQMLZA.js +474 -0
  48. package/dist/chunk-NBDZMMG2.js +169 -0
  49. package/dist/chunk-NHA6BEIH.js +101 -0
  50. package/dist/chunk-OA6YJIWL.js +4412 -0
  51. package/dist/chunk-OZC255IC.js +2830 -0
  52. package/dist/chunk-PUR6WU2B.js +154 -0
  53. package/dist/chunk-Q5JPPCZC.js +12 -0
  54. package/dist/chunk-QBV725YG.js +128 -0
  55. package/dist/chunk-QHVW4AAM.js +892 -0
  56. package/dist/chunk-QNJ7AQ4B.js +1000 -0
  57. package/dist/chunk-RGISBZBD.js +231 -0
  58. package/dist/chunk-RJZQWEMS.js +84 -0
  59. package/dist/chunk-RP2ZA47V.js +15 -0
  60. package/dist/chunk-RXISBFR5.js +315 -0
  61. package/dist/chunk-S5CCLZL3.js +99 -0
  62. package/dist/chunk-TVTCSBJF.js +122 -0
  63. package/dist/chunk-U4D5S3VQ.js +21 -0
  64. package/dist/chunk-U4VAATKP.js +193 -0
  65. package/dist/chunk-UKU2ZX4C.js +203 -0
  66. package/dist/chunk-UNSKG6DC.js +159 -0
  67. package/dist/chunk-URFKEIHM.js +1091 -0
  68. package/dist/chunk-UTV7YAW7.js +178 -0
  69. package/dist/chunk-V43EQ6VR.js +68 -0
  70. package/dist/chunk-VB3MJGCV.js +610 -0
  71. package/dist/chunk-WHIIIREL.js +223 -0
  72. package/dist/chunk-XMIFYKUT.js +1371 -0
  73. package/dist/chunk-YF2RSV34.js +54 -0
  74. package/dist/chunk-Z6DAKQ3U.js +1 -0
  75. package/dist/chunk-ZIGAZFWE.js +522 -0
  76. package/dist/circuit-breaker.js +3 -191
  77. package/dist/codebase-index/index.js +84 -13688
  78. package/dist/codebase-index/parser-worker-script.js +8 -3995
  79. package/dist/codebase-index/project-server.js +60 -8548
  80. package/dist/codebase-index/worker.js +20 -8416
  81. package/dist/design.js +2 -299
  82. package/dist/diff.js +4 -256
  83. package/dist/document.js +4 -222
  84. package/dist/e2e.js +5 -476
  85. package/dist/edit.js +14 -10200
  86. package/dist/exec.js +16 -3131
  87. package/dist/fetch.js +8 -398
  88. package/dist/format.js +10 -3750
  89. package/dist/generic-parser-VUXDIAOZ.js +13 -0
  90. package/dist/git.js +4 -380
  91. package/dist/glob.js +6 -280
  92. package/dist/go-parser-6CA77WZ4.js +469 -0
  93. package/dist/grep.js +7 -604
  94. package/dist/index.js +318 -35387
  95. package/dist/install.js +10 -4091
  96. package/dist/json-parser-7YMDJSBJ.js +213 -0
  97. package/dist/json.js +4 -665
  98. package/dist/kanban.js +3 -2096
  99. package/dist/languages/index.js +23 -4664
  100. package/dist/legacy-bridge-7UKZT46G.js +18 -0
  101. package/dist/lint.js +10 -3706
  102. package/dist/logs.js +4 -287
  103. package/dist/memory.js +6 -215
  104. package/dist/mode.js +3 -99
  105. package/dist/outdated.js +4 -5170
  106. package/dist/pack.js +65 -33897
  107. package/dist/parser-dispatch-VPOFDO2U.js +14 -0
  108. package/dist/patch.js +13 -9935
  109. package/dist/plan.js +5 -3286
  110. package/dist/process-registry.js +8 -651
  111. package/dist/ps-slash.js +12 -1439
  112. package/dist/py-parser-GPM5VYRG.js +16 -0
  113. package/dist/read.js +13 -9816
  114. package/dist/replace.js +15 -10014
  115. package/dist/rs-parser-WVQ4KYCX.js +81 -0
  116. package/dist/scaffold.js +4 -253
  117. package/dist/search.js +5 -585
  118. package/dist/session-kanban.js +30 -972
  119. package/dist/skill.js +2 -215
  120. package/dist/task.js +5 -3410
  121. package/dist/test.js +10 -3773
  122. package/dist/todo.js +4 -2891
  123. package/dist/tool-help.js +3 -123
  124. package/dist/tool-search.js +3 -79
  125. package/dist/tool-tier.js +68 -33984
  126. package/dist/tool-use.js +2 -93
  127. package/dist/tree-sitter-parser-YCILHGZD.js +17 -0
  128. package/dist/tree.js +4 -288
  129. package/dist/ts-parser-YH4ZMWMH.js +232 -0
  130. package/dist/typecheck.js +10 -3753
  131. package/dist/win32.js +6 -60
  132. package/dist/write.js +14 -9882
  133. package/dist/yaml-parser-GFAOKV53.js +157 -0
  134. package/package.json +5 -5
@@ -0,0 +1,113 @@
1
+ // src/_output-spool.ts
2
+ import { createWriteStream, mkdirSync } from "node:fs";
3
+ import * as fsp from "node:fs/promises";
4
+ import * as path from "node:path";
5
+ import { wstackGlobalRoot } from "@wrongstack/core/utils";
6
+ var SPOOL_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
7
+ var SPOOL_WRITE_HWM_BYTES = 4 * 1024 * 1024;
8
+ var sweepStarted = false;
9
+ function toolOutputDir() {
10
+ return path.join(wstackGlobalRoot(), "tool-output");
11
+ }
12
+ function sweepOldSpoolFiles(dir) {
13
+ if (sweepStarted) return;
14
+ sweepStarted = true;
15
+ void (async () => {
16
+ try {
17
+ const now = Date.now();
18
+ for (const name of await fsp.readdir(dir)) {
19
+ if (!name.endsWith(".log")) continue;
20
+ const p = path.join(dir, name);
21
+ try {
22
+ const st = await fsp.stat(p);
23
+ if (now - st.mtimeMs > SPOOL_RETENTION_MS) await fsp.unlink(p);
24
+ } catch {
25
+ }
26
+ }
27
+ } catch {
28
+ }
29
+ })();
30
+ }
31
+ function spoolNote(info) {
32
+ const dropped = info.droppedBytes > 0 ? `, ~${info.droppedBytes} bytes dropped under backpressure` : "";
33
+ return `
34
+ [output truncated \u2014 full ${info.bytes} bytes at ${info.path}${dropped}; read/grep that file selectively instead of re-running with more output]`;
35
+ }
36
+ function createOutputSpool(opts) {
37
+ const threshold = opts.thresholdBytes ?? 32768;
38
+ const safeTool = opts.tool.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40) || "tool";
39
+ let head = "";
40
+ let headBytes = 0;
41
+ let totalBytes = 0;
42
+ let droppedBytes = 0;
43
+ let stream = null;
44
+ let filePath = null;
45
+ let failed = false;
46
+ let finalized = false;
47
+ const open = () => {
48
+ if (stream || failed) return;
49
+ try {
50
+ const dir = toolOutputDir();
51
+ mkdirSync(dir, { recursive: true });
52
+ sweepOldSpoolFiles(dir);
53
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
54
+ const rand = Math.random().toString(36).slice(2, 6);
55
+ filePath = path.join(dir, `${stamp}-${safeTool}-${rand}.log`);
56
+ stream = createWriteStream(filePath, { flags: "w", encoding: "utf8" });
57
+ stream.on("error", () => {
58
+ failed = true;
59
+ stream = null;
60
+ filePath = null;
61
+ });
62
+ stream.write(head);
63
+ } catch {
64
+ failed = true;
65
+ stream = null;
66
+ filePath = null;
67
+ }
68
+ };
69
+ return {
70
+ write(text) {
71
+ if (finalized || !text) return;
72
+ const textBytes = Buffer.byteLength(text, "utf8");
73
+ totalBytes += textBytes;
74
+ if (!stream && !failed) {
75
+ if (headBytes + textBytes <= threshold) {
76
+ head += text;
77
+ headBytes += textBytes;
78
+ return;
79
+ }
80
+ head += text;
81
+ open();
82
+ head = "";
83
+ return;
84
+ }
85
+ if (stream) {
86
+ if (stream.writableLength > SPOOL_WRITE_HWM_BYTES) {
87
+ droppedBytes += textBytes;
88
+ return;
89
+ }
90
+ stream.write(text);
91
+ }
92
+ },
93
+ finalize() {
94
+ if (finalized) {
95
+ return filePath ? { path: filePath, bytes: totalBytes, droppedBytes } : null;
96
+ }
97
+ finalized = true;
98
+ head = "";
99
+ if (!stream || !filePath) return null;
100
+ try {
101
+ stream.end();
102
+ } catch {
103
+ }
104
+ return { path: filePath, bytes: totalBytes, droppedBytes };
105
+ }
106
+ };
107
+ }
108
+
109
+ export {
110
+ spoolNote,
111
+ createOutputSpool
112
+ };
113
+ //# sourceMappingURL=chunk-2TFQDEPU.js.map
@@ -0,0 +1,315 @@
1
+ import {
2
+ enqueueReindex
3
+ } from "./chunk-2ME7ZWDD.js";
4
+ import {
5
+ resolveRealInsideRoot,
6
+ safeResolveReal,
7
+ sha256hex
8
+ } from "./chunk-D33S4RQG.js";
9
+
10
+ // src/patch.ts
11
+ import { spawn } from "node:child_process";
12
+ import * as fs from "node:fs/promises";
13
+ import * as os from "node:os";
14
+ import * as path from "node:path";
15
+ import { buildChildEnv, toErrorMessage } from "@wrongstack/core/utils";
16
+ var patchTool = {
17
+ name: "patch",
18
+ category: "Filesystem",
19
+ description: "Apply a unified diff (patch) to the project. This is the correct tool when you have a diff that needs to be applied precisely, including handling of rejects.",
20
+ usageHint: "Best used when you already have a diff (from generation, external source, or previous step).\n- Use `dry_run: true` to see what would happen without modifying files.\n- Applied with `--merge`: a conflicting hunk writes git-style conflict\n markers (<<<<<<< / ======= / >>>>>>>) INTO the file and reports failure.\n It does NOT create .rej/.orig files. `files` lists what changed on disk\n even when the patch failed, so read those back before retrying.\nOften cleaner than many small `edit` operations for larger changes.",
21
+ selection: {
22
+ doNotUseWhen: "you do not already have a unified diff or only need one precise replacement.",
23
+ useInstead: ["edit"]
24
+ },
25
+ permission: "confirm",
26
+ // WS-046: gives permission decisions something to key on.
27
+ // The target directory. The patch body itself is unstable (every diff
28
+ // differs), so it could never re-match its own stored rule.
29
+ subjectKey: "directory",
30
+ mutating: true,
31
+ capabilities: ["fs.write"],
32
+ icon: "edit",
33
+ timeoutMs: 3e4,
34
+ inputSchema: {
35
+ type: "object",
36
+ properties: {
37
+ patch: { type: "string", description: "Unified diff patch content" },
38
+ directory: { type: "string", description: "Root directory for patch (default: cwd)" },
39
+ strip: { type: "integer", description: "Strip leading path components (default: 1)" },
40
+ dry_run: { type: "boolean", description: "Preview without applying" }
41
+ },
42
+ required: ["patch"]
43
+ },
44
+ async execute(input, ctx, opts) {
45
+ if (!input?.patch) throw new Error("patch: patch content is required");
46
+ const strip = Math.max(1, input.strip ?? 1);
47
+ const dryRun = input.dry_run ?? false;
48
+ const refuse = (message) => ({
49
+ applied: 0,
50
+ rejected: 1,
51
+ files: [],
52
+ dry_run: dryRun,
53
+ message
54
+ });
55
+ let dir;
56
+ try {
57
+ dir = input.directory ? await safeResolveReal(input.directory, ctx) : ctx.cwd;
58
+ } catch (err) {
59
+ return refuse(`patch refused: ${toErrorMessage(err)}`);
60
+ }
61
+ const realRoot = await fs.realpath(ctx.projectRoot).catch(() => path.resolve(ctx.projectRoot));
62
+ const targets = extractDiffTargets(input.patch);
63
+ const resolvedTargets = [];
64
+ for (const t of targets) {
65
+ const stripped = stripPathComponents(t.raw, strip);
66
+ if (!stripped) continue;
67
+ if (path.isAbsolute(stripped)) {
68
+ return refuse(`patch refused: target "${t.raw}" strips to absolute path`);
69
+ }
70
+ const candidate = path.resolve(dir, stripped);
71
+ let real;
72
+ try {
73
+ real = await resolveRealInsideRoot(candidate, ctx);
74
+ } catch (err) {
75
+ return refuse(`patch refused: target "${t.raw}" ${toErrorMessage(err)}`);
76
+ }
77
+ const rel = path.relative(realRoot, real);
78
+ if (rel.startsWith("..") || path.isAbsolute(rel)) {
79
+ return refuse(`patch refused: target "${t.raw}" resolves outside project root`);
80
+ }
81
+ resolvedTargets.push({ raw: t.raw, deleted: t.deleted, abs: real });
82
+ }
83
+ const beforeContents = /* @__PURE__ */ new Map();
84
+ const beforeExisted = /* @__PURE__ */ new Set();
85
+ if (!dryRun) {
86
+ for (const target of resolvedTargets) {
87
+ const existed = (await fs.stat(target.abs).catch(() => null))?.isFile() ?? false;
88
+ if (existed) beforeExisted.add(target.abs);
89
+ beforeContents.set(target.abs, await readTextForTracking(target.abs));
90
+ }
91
+ }
92
+ const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), ".wstack_patch_"));
93
+ try {
94
+ await fs.chmod(tmpDir, 448).catch(() => {
95
+ });
96
+ const patchFile = path.join(tmpDir, "in.diff");
97
+ await fs.writeFile(patchFile, input.patch, { mode: 384 });
98
+ const args = [`-p${strip}`, "--merge", ...dryRun ? ["--dry-run"] : [], "-i", patchFile];
99
+ const result = await runPatch(args, dir, opts.signal, {
100
+ patchFile,
101
+ strip,
102
+ dryRun
103
+ });
104
+ const touched = [];
105
+ if (!dryRun) {
106
+ for (const target of resolvedTargets) {
107
+ const abs = target.abs;
108
+ const before = beforeContents.get(abs) ?? null;
109
+ const stat2 = await fs.stat(abs).catch(() => null);
110
+ if (!stat2?.isFile()) {
111
+ if (beforeExisted.has(abs)) {
112
+ touched.push(abs);
113
+ ctx.session?.recordFileChange?.({
114
+ path: abs,
115
+ action: "deleted",
116
+ before,
117
+ after: null
118
+ });
119
+ }
120
+ continue;
121
+ }
122
+ const after = await readTextForTracking(abs);
123
+ if (after === null || after === before) continue;
124
+ touched.push(abs);
125
+ ctx.recordRead?.(abs, stat2.mtimeMs, "write", sha256hex(after));
126
+ ctx.session?.recordFileChange?.({
127
+ path: abs,
128
+ action: before === null ? "created" : "modified",
129
+ before,
130
+ after
131
+ });
132
+ }
133
+ if (touched.length > 0) {
134
+ try {
135
+ enqueueReindex({ projectRoot: ctx.projectRoot, files: touched });
136
+ } catch {
137
+ }
138
+ }
139
+ }
140
+ if (result.exitCode !== 0) {
141
+ if (!dryRun) {
142
+ const partial = touched.length > 0 ? ` ${touched.length} file(s) were still modified on disk and have been recorded for rewind: ${touched.map((p) => path.relative(realRoot, p) || p).join(", ")}.` : "";
143
+ return {
144
+ applied: touched.length,
145
+ rejected: 1,
146
+ // Normalize to relative-to-realRoot for API consistency with the
147
+ // success path (which returns GNU patch's dir-relative names).
148
+ // `touched` entries are realpaths from resolveRealInsideRoot, and
149
+ // realRoot is also a realpath, so path.relative is like-for-like.
150
+ files: touched.map((p) => path.relative(realRoot, p) || p),
151
+ dry_run: dryRun,
152
+ message: `patch failed: ${result.stderr || result.stdout}${partial}`
153
+ };
154
+ }
155
+ const wouldPatch = extractPatchedFiles(result.stdout);
156
+ return {
157
+ applied: wouldPatch.length,
158
+ rejected: 1,
159
+ files: wouldPatch,
160
+ dry_run: dryRun,
161
+ message: `patch preview: would conflict \u2014 ${result.stderr || result.stdout}`
162
+ };
163
+ }
164
+ const patched = result.engine === "git" ? [
165
+ ...new Set(
166
+ resolvedTargets.map((target) => path.relative(dir, target.abs) || target.abs)
167
+ )
168
+ ] : extractPatchedFiles(result.stdout);
169
+ return {
170
+ applied: patched.length,
171
+ rejected: 0,
172
+ files: patched,
173
+ dry_run: dryRun,
174
+ message: result.stdout || "patch applied"
175
+ };
176
+ } finally {
177
+ await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {
178
+ });
179
+ }
180
+ }
181
+ };
182
+ var MAX_TRACKING_BYTES = 5 * 1024 * 1024;
183
+ async function readTextForTracking(absPath) {
184
+ try {
185
+ const stat2 = await fs.stat(absPath);
186
+ if (!stat2.isFile() || stat2.size > MAX_TRACKING_BYTES) return null;
187
+ const buf = await fs.readFile(absPath);
188
+ if (buf.includes(0)) return null;
189
+ return buf.toString("utf8");
190
+ } catch {
191
+ return null;
192
+ }
193
+ }
194
+ function extractDiffTargets(patch) {
195
+ const out = [];
196
+ const clean = (raw) => {
197
+ if (!raw) return "";
198
+ return (raw.length > 4096 ? raw.slice(0, 4096) : raw).trim();
199
+ };
200
+ let lastOld;
201
+ let inHunk = false;
202
+ let oldLinesLeft = 0;
203
+ let newLinesLeft = 0;
204
+ for (const line of patch.split(/\r?\n/)) {
205
+ const hunkMatch = /^@@ -\d+(?:,(\d+))? \+\d+(?:,(\d+))? @@/.exec(line);
206
+ if (hunkMatch) {
207
+ inHunk = true;
208
+ oldLinesLeft = hunkMatch[1] ? Number(hunkMatch[1]) : 1;
209
+ newLinesLeft = hunkMatch[2] ? Number(hunkMatch[2]) : 1;
210
+ lastOld = void 0;
211
+ continue;
212
+ }
213
+ if (inHunk) {
214
+ const ch = line[0];
215
+ if (ch === "-") oldLinesLeft--;
216
+ else if (ch === "+") newLinesLeft--;
217
+ else if (ch === " " || ch === void 0) {
218
+ oldLinesLeft--;
219
+ newLinesLeft--;
220
+ }
221
+ if (oldLinesLeft <= 0 && newLinesLeft <= 0) inHunk = false;
222
+ continue;
223
+ }
224
+ const oldMatch = /^---\s+([^\t\r\n]+)/.exec(line);
225
+ if (oldMatch) {
226
+ lastOld = clean(oldMatch[1]);
227
+ continue;
228
+ }
229
+ const newMatch = /^\+\+\+\s+([^\t\r\n]+)/.exec(line);
230
+ if (!newMatch) continue;
231
+ const newTarget = clean(newMatch[1]);
232
+ if (newTarget && newTarget !== "/dev/null") {
233
+ out.push({ raw: newTarget, deleted: false });
234
+ } else if (lastOld && lastOld !== "/dev/null") {
235
+ out.push({ raw: lastOld, deleted: true });
236
+ }
237
+ lastOld = void 0;
238
+ }
239
+ return out;
240
+ }
241
+ function stripPathComponents(p, strip) {
242
+ const s = p.replace(/\\/g, "/");
243
+ let idx = 0;
244
+ for (let i = 0; i < strip; i++) {
245
+ while (idx < s.length && s[idx] !== "/") idx++;
246
+ let hadSlash = false;
247
+ while (idx < s.length && s[idx] === "/") {
248
+ idx++;
249
+ hadSlash = true;
250
+ }
251
+ if (!hadSlash) return void 0;
252
+ }
253
+ return s.slice(idx) || void 0;
254
+ }
255
+ function runPatch(args, cwd, signal, fallback) {
256
+ return runPatchProcess("patch", args, cwd, signal).then(async (result) => {
257
+ if (!result.unavailable) return { ...result, engine: "patch" };
258
+ const gitArgs = [
259
+ "apply",
260
+ "--unsafe-paths",
261
+ `-p${fallback.strip}`,
262
+ "--verbose",
263
+ ...fallback.dryRun ? ["--check"] : [],
264
+ fallback.patchFile
265
+ ];
266
+ const gitResult = await runPatchProcess("git", gitArgs, cwd, signal);
267
+ return { ...gitResult, engine: "git" };
268
+ });
269
+ }
270
+ function runPatchProcess(command, args, cwd, signal) {
271
+ return new Promise((resolve2) => {
272
+ let stdout = "";
273
+ let stderr = "";
274
+ const env = { ...buildChildEnv(), LANG: "C", LC_ALL: "C" };
275
+ const child = spawn(command, args, {
276
+ cwd,
277
+ signal,
278
+ env,
279
+ stdio: ["pipe", "pipe", "pipe"],
280
+ windowsHide: true
281
+ });
282
+ child.stdout?.on("data", (c) => {
283
+ stdout += c.toString();
284
+ });
285
+ child.stderr?.on("data", (c) => {
286
+ stderr += c.toString();
287
+ });
288
+ child.on(
289
+ "close",
290
+ (code) => resolve2({ exitCode: code ?? 1, stdout, stderr, unavailable: false })
291
+ );
292
+ child.on(
293
+ "error",
294
+ (e) => resolve2({
295
+ exitCode: 1,
296
+ stdout: "",
297
+ stderr: e.message,
298
+ unavailable: e.code === "ENOENT"
299
+ })
300
+ );
301
+ });
302
+ }
303
+ function extractPatchedFiles(output) {
304
+ const files = [];
305
+ const re = /(?:patching|checking) file (.+)/gi;
306
+ for (const m of output.matchAll(re)) {
307
+ if (m[1]) files.push(m[1]);
308
+ }
309
+ return files;
310
+ }
311
+
312
+ export {
313
+ patchTool
314
+ };
315
+ //# sourceMappingURL=chunk-2ZCJNKFE.js.map