@usepipr/runtime 0.4.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -5
  3. package/dist/{commands-DA0Ij4Di.d.mts → commands-BHXh7P28.d.mts} +2 -2
  4. package/dist/{commands-DA0Ij4Di.d.mts.map → commands-BHXh7P28.d.mts.map} +1 -1
  5. package/dist/{commands-B9qNW4pk.mjs → commands-GWHklzvq.mjs} +1612 -466
  6. package/dist/commands-GWHklzvq.mjs.map +1 -0
  7. package/dist/index.d.mts +17 -4
  8. package/dist/index.d.mts.map +1 -1
  9. package/dist/index.mjs +117 -15
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/internal/action-result.d.mts +4 -2
  12. package/dist/internal/action-result.d.mts.map +1 -1
  13. package/dist/internal/action-result.mjs +28 -12
  14. package/dist/internal/action-result.mjs.map +1 -1
  15. package/dist/internal/docs.d.mts +1 -1
  16. package/dist/internal/docs.d.mts.map +1 -1
  17. package/dist/internal/docs.mjs +1 -1
  18. package/dist/internal/pipr-result.d.mts +24 -0
  19. package/dist/internal/pipr-result.d.mts.map +1 -0
  20. package/dist/internal/pipr-result.mjs +126 -0
  21. package/dist/internal/pipr-result.mjs.map +1 -0
  22. package/dist/internal/testing.d.mts +12 -11
  23. package/dist/internal/testing.d.mts.map +1 -1
  24. package/dist/internal/testing.mjs +1 -1
  25. package/dist/main-comment-envelope-DFirHYhW.mjs +69 -0
  26. package/dist/main-comment-envelope-DFirHYhW.mjs.map +1 -0
  27. package/dist/{official-github-workflow-Bjlu-FL3.mjs → official-github-workflow-B3yeaCgq.mjs} +421 -114
  28. package/dist/official-github-workflow-B3yeaCgq.mjs.map +1 -0
  29. package/dist/pi/runtime-tools-extension.d.mts.map +1 -1
  30. package/dist/pi/runtime-tools-extension.mjs +128 -2
  31. package/dist/pi/runtime-tools-extension.mjs.map +1 -1
  32. package/dist/{recipes-w72EpAOi.d.mts → recipes-C1kxJCgQ.d.mts} +2 -1
  33. package/dist/recipes-C1kxJCgQ.d.mts.map +1 -0
  34. package/dist/runtime-tools-core-BF8rSeNS.mjs +476 -0
  35. package/dist/runtime-tools-core-BF8rSeNS.mjs.map +1 -0
  36. package/dist/{types-BAis_Lwm.d.mts → types-w22wbdo9.d.mts} +72 -19
  37. package/dist/types-w22wbdo9.d.mts.map +1 -0
  38. package/package.json +16 -8
  39. package/dist/commands-B9qNW4pk.mjs.map +0 -1
  40. package/dist/official-github-workflow-Bjlu-FL3.mjs.map +0 -1
  41. package/dist/recipes-w72EpAOi.d.mts.map +0 -1
  42. package/dist/runtime-tools-core-D8_WsbL_.mjs +0 -179
  43. package/dist/runtime-tools-core-D8_WsbL_.mjs.map +0 -1
  44. package/dist/types-BAis_Lwm.d.mts.map +0 -1
@@ -0,0 +1,476 @@
1
+ import { lstat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { spawn } from "node:child_process";
5
+ //#region src/shared/record.ts
6
+ function isRecord(value) {
7
+ return value !== null && typeof value === "object" && !Array.isArray(value);
8
+ }
9
+ //#endregion
10
+ //#region src/diff/manifest-structure.ts
11
+ const maxSymbolsPerFile = 32;
12
+ const maxSymbolCharacters = 120;
13
+ const maxSummaryCharacters = 200;
14
+ const maxDerivedMetadataBytes = 32 * 1024;
15
+ function enrichDiffManifestWithStructure(manifest, analysis) {
16
+ if (!analysis.available) return manifest;
17
+ const budget = {
18
+ remaining: maxDerivedMetadataBytes,
19
+ exhausted: false
20
+ };
21
+ return {
22
+ ...manifest,
23
+ files: manifest.files.map((file) => enrichFile(file, analysis, budget))
24
+ };
25
+ }
26
+ function findEnclosingDeclaration(file, range, analysis) {
27
+ if (!analysis.available) return;
28
+ const ref = range.side === "LEFT" ? "base" : "head";
29
+ const sourcePath = ref === "base" ? file.previousPath ?? file.path : file.path;
30
+ const declaration = (ref === "base" ? analysis.baseFiles : analysis.headFiles).find((candidate) => candidate.path === sourcePath)?.declarations.filter((candidate) => candidate.startLine <= range.startLine && candidate.endLine >= range.endLine).sort(compareContainingDeclarations)[0];
31
+ return declaration ? {
32
+ declaration,
33
+ ref,
34
+ sourcePath
35
+ } : void 0;
36
+ }
37
+ function enrichFile(file, analysis, budget) {
38
+ const owners = /* @__PURE__ */ new Map();
39
+ const commentableRanges = file.commentableRanges.map((range) => {
40
+ const owner = findEnclosingDeclaration(file, range, analysis)?.declaration;
41
+ if (owner) owners.set(owner.qualifiedName, owner);
42
+ if (!owner || range.summary !== void 0 || budget.exhausted) return range;
43
+ const summary = truncate(`Enclosing declaration: ${owner.kind} ${owner.qualifiedName}`, maxSummaryCharacters);
44
+ return consumeDerivedMetadata(budget, summary) ? {
45
+ ...range,
46
+ summary
47
+ } : range;
48
+ });
49
+ const existingSymbols = [...file.changedSymbols ?? []];
50
+ const symbolSet = new Set(existingSymbols);
51
+ const derivedSymbols = [];
52
+ for (const owner of [...owners.values()].sort(compareSourceOrder)) {
53
+ if (budget.exhausted || existingSymbols.length + derivedSymbols.length >= maxSymbolsPerFile) break;
54
+ const symbol = truncate(owner.qualifiedName, maxSymbolCharacters);
55
+ if (symbolSet.has(symbol)) continue;
56
+ if (!consumeDerivedMetadata(budget, symbol)) break;
57
+ symbolSet.add(symbol);
58
+ derivedSymbols.push(symbol);
59
+ }
60
+ return {
61
+ ...file,
62
+ ...existingSymbols.length > 0 || derivedSymbols.length > 0 ? { changedSymbols: [...existingSymbols, ...derivedSymbols] } : {},
63
+ commentableRanges
64
+ };
65
+ }
66
+ function compareContainingDeclarations(left, right) {
67
+ return left.endLine - left.startLine - (right.endLine - right.startLine) || right.startLine - left.startLine || left.qualifiedName.localeCompare(right.qualifiedName);
68
+ }
69
+ function compareSourceOrder(left, right) {
70
+ return left.startLine - right.startLine || left.endLine - right.endLine || left.qualifiedName.localeCompare(right.qualifiedName);
71
+ }
72
+ function consumeDerivedMetadata(budget, value) {
73
+ const bytes = Buffer.byteLength(value, "utf8");
74
+ if (bytes > budget.remaining) {
75
+ budget.exhausted = true;
76
+ return false;
77
+ }
78
+ budget.remaining -= bytes;
79
+ return true;
80
+ }
81
+ function truncate(value, maxCharacters) {
82
+ return value.length <= maxCharacters ? value : value.slice(0, maxCharacters);
83
+ }
84
+ //#endregion
85
+ //#region src/diff/ranges.ts
86
+ function createDiffRangeIndex(manifest) {
87
+ const filesByPath = new Map(manifest.files.map((file) => [file.path, file]));
88
+ const rangesById = /* @__PURE__ */ new Map();
89
+ for (const file of manifest.files) for (const range of file.commentableRanges) rangesById.set(range.id, {
90
+ file,
91
+ range
92
+ });
93
+ return {
94
+ fileByPath(filePath) {
95
+ return filesByPath.get(filePath);
96
+ },
97
+ excludedReason(filePath) {
98
+ return filesByPath.get(filePath)?.excludedReason;
99
+ },
100
+ findRange(rangeId) {
101
+ return rangesById.get(rangeId);
102
+ },
103
+ rangeById(rangeId) {
104
+ return rangesById.get(rangeId)?.range;
105
+ },
106
+ requireFile(filePath) {
107
+ const file = filesByPath.get(filePath);
108
+ if (!file) throw new Error(`Path '${filePath}' is not in the Diff Manifest`);
109
+ return file;
110
+ },
111
+ requireRangeInFile(file, rangeId) {
112
+ const range = file.commentableRanges.find((item) => item.id === rangeId);
113
+ if (range) return range;
114
+ if (rangesById.has(rangeId)) throw new Error(`Diff Manifest range '${rangeId}' is not in path '${file.path}'`);
115
+ throw new Error(`Unknown Diff Manifest range '${rangeId}'`);
116
+ },
117
+ requireHunk(file, range) {
118
+ const hunk = file.hunks.find((item) => item.hunkIndex === range.hunkIndex && item.contentHash === range.hunkContentHash);
119
+ if (!hunk) throw new Error(`Diff Manifest range '${range.id}' has no matching hunk`);
120
+ return hunk;
121
+ }
122
+ };
123
+ }
124
+ //#endregion
125
+ //#region src/pi/runtime-tools-core.ts
126
+ const readAtRefContextLines = 3;
127
+ const readDiffParamsSchema = z.preprocess((params) => {
128
+ const record = isRecord(params) ? params : {};
129
+ return {
130
+ path: typeof record.path === "string" ? record.path : void 0,
131
+ rangeId: typeof record.rangeId === "string" ? record.rangeId : void 0
132
+ };
133
+ }, z.object({
134
+ path: z.string().optional(),
135
+ rangeId: z.string().optional()
136
+ }));
137
+ const readAtRefParamsSchema = z.preprocess((params) => isRecord(params) ? params : {}, z.object({
138
+ path: z.unknown(),
139
+ ref: z.enum(["base", "head"], { error: (issue) => `Unsupported ref '${String(issue.input)}'` }),
140
+ rangeId: z.string({ error: "rangeId must be a string" })
141
+ }));
142
+ const astGrepSearchParamsSchema = z.strictObject({
143
+ pattern: z.string().min(1).max(4096),
144
+ language: z.string().min(1).max(64),
145
+ paths: z.array(z.string()).min(1).max(16)
146
+ });
147
+ const astGrepMatchSchema = z.looseObject({
148
+ text: z.string(),
149
+ file: z.string(),
150
+ range: z.object({
151
+ start: z.object({
152
+ line: z.number().int().nonnegative(),
153
+ column: z.number().int().nonnegative()
154
+ }),
155
+ end: z.object({
156
+ line: z.number().int().nonnegative(),
157
+ column: z.number().int().nonnegative()
158
+ })
159
+ })
160
+ });
161
+ const astGrepMatchesSchema = z.array(astGrepMatchSchema);
162
+ function readDiffFromRuntimeData(data, params) {
163
+ const { rangeId } = params;
164
+ const filePath = params.path === void 0 ? void 0 : parseManifestPath(params.path);
165
+ const ranges = createDiffRangeIndex(data.manifest);
166
+ if (filePath !== void 0) ranges.requireFile(filePath);
167
+ if (rangeId !== void 0 && !ranges.findRange(rangeId)) throw new Error(`Unknown Diff Manifest range '${rangeId}'`);
168
+ return boundedJson({ files: data.manifest.files.filter((file) => filePath === void 0 || file.path === filePath).map((file) => filterManifestFileRanges(file, rangeId)).filter((file) => rangeId === void 0 || file.commentableRanges.length > 0) }, data.toolResponseMaxBytes);
169
+ }
170
+ function boundedJson(value, maxBytes) {
171
+ const text = JSON.stringify(value, null, 2);
172
+ const bytes = Buffer.byteLength(text, "utf8");
173
+ if (bytes <= maxBytes) return {
174
+ truncated: false,
175
+ bytes,
176
+ value
177
+ };
178
+ return {
179
+ truncated: true,
180
+ bytes,
181
+ maxBytes,
182
+ text: Buffer.from(text, "utf8").subarray(0, maxBytes).toString("utf8")
183
+ };
184
+ }
185
+ function boundedLineSlice(content, window, maxBytes) {
186
+ const lines = content.match(/[^\n]*(?:\n|$)/g) ?? [];
187
+ if (lines.at(-1) === "") lines.pop();
188
+ const slice = lines.slice(window.startLine - 1, window.endLine).join("");
189
+ const buffer = Buffer.from(slice, "utf8");
190
+ return {
191
+ available: true,
192
+ content: buffer.subarray(0, maxBytes).toString("utf8"),
193
+ bytes: buffer.byteLength,
194
+ truncated: buffer.byteLength > maxBytes
195
+ };
196
+ }
197
+ function resolveReadAtRefRequest(manifest, params) {
198
+ const filePath = parseManifestPath(params.path);
199
+ const ranges = createDiffRangeIndex(manifest);
200
+ const file = ranges.requireFile(filePath);
201
+ const range = ranges.requireRangeInFile(file, params.rangeId);
202
+ const hunk = ranges.requireHunk(file, range);
203
+ const sourcePath = parseManifestPath(params.ref === "base" ? file.previousPath ?? file.path : file.path);
204
+ return {
205
+ file,
206
+ range,
207
+ hunk,
208
+ ref: params.ref,
209
+ sourcePath,
210
+ window: lineWindowForRange(range, hunk, params.ref)
211
+ };
212
+ }
213
+ function unavailableReadAtRefResult(request) {
214
+ return {
215
+ path: request.file.path,
216
+ ref: request.ref,
217
+ sourcePath: request.sourcePath,
218
+ rangeId: request.range.id,
219
+ startLine: 0,
220
+ endLine: 0,
221
+ available: false
222
+ };
223
+ }
224
+ function parseManifestPath(filePath) {
225
+ if (typeof filePath !== "string" || filePath.length === 0 || filePath.includes("\0") || path.isAbsolute(filePath) || filePath.split(/[\\/]/).some((part) => part === ".." || part === ".git" || part === "")) throw new Error(`Unsafe manifest path '${String(filePath)}'`);
226
+ return filePath;
227
+ }
228
+ function resolveAllowedPath(root, filePath) {
229
+ const resolved = path.resolve(root, filePath);
230
+ const relative = path.relative(root, resolved);
231
+ if (relative.startsWith("..") || path.isAbsolute(relative)) throw new Error(`Path '${filePath}' resolves outside the workspace`);
232
+ return resolved;
233
+ }
234
+ async function assertNoSymlinkPath(root, filePath) {
235
+ const parts = filePath.split(/[\\/]/);
236
+ let current = root;
237
+ for (const part of parts) {
238
+ current = path.join(current, part);
239
+ if ((await lstat(current)).isSymbolicLink()) throw new Error(`Path '${filePath}' crosses a symlink`);
240
+ }
241
+ }
242
+ function readDiffParams(params) {
243
+ return readDiffParamsSchema.parse(params);
244
+ }
245
+ function readAtRefParams(params) {
246
+ const parsed = readAtRefParamsSchema.parse(params);
247
+ return {
248
+ path: parseManifestPath(parsed.path),
249
+ ref: parsed.ref,
250
+ rangeId: parsed.rangeId
251
+ };
252
+ }
253
+ function readDeclarationParams(params) {
254
+ return readAtRefParams(params);
255
+ }
256
+ function astGrepSearchParams(params) {
257
+ const parsed = astGrepSearchParamsSchema.parse(params);
258
+ return {
259
+ pattern: parsed.pattern,
260
+ language: parsed.language,
261
+ paths: parsed.paths.map(parseSearchPath)
262
+ };
263
+ }
264
+ function resolveDeclarationRequest(data, params) {
265
+ const filePath = parseManifestPath(params.path);
266
+ const ranges = createDiffRangeIndex(data.manifest);
267
+ const file = ranges.requireFile(filePath);
268
+ const range = ranges.requireRangeInFile(file, params.rangeId);
269
+ const sourcePath = parseManifestPath(params.ref === "base" ? file.previousPath ?? file.path : file.path);
270
+ const expectedSide = params.ref === "base" ? "LEFT" : "RIGHT";
271
+ if (!data.structuralAnalysis || range.side !== expectedSide) return {
272
+ available: false,
273
+ path: file.path,
274
+ sourcePath,
275
+ ref: params.ref,
276
+ rangeId: range.id
277
+ };
278
+ const owner = findEnclosingDeclaration(file, range, data.structuralAnalysis);
279
+ if (!owner || owner.ref !== params.ref) return {
280
+ available: false,
281
+ path: file.path,
282
+ sourcePath,
283
+ ref: params.ref,
284
+ rangeId: range.id
285
+ };
286
+ return {
287
+ available: true,
288
+ path: file.path,
289
+ sourcePath: owner.sourcePath,
290
+ ref: params.ref,
291
+ rangeId: range.id,
292
+ declaration: owner.declaration
293
+ };
294
+ }
295
+ async function runAstGrepSearch(options) {
296
+ for (const searchPath of options.params.paths) if (searchPath !== ".") {
297
+ resolveAllowedPath(options.cwd, searchPath);
298
+ await assertNoSymlinkPath(options.cwd, searchPath);
299
+ }
300
+ const result = await runAstGrepProcess([
301
+ "ast-grep",
302
+ "run",
303
+ "--pattern",
304
+ options.params.pattern,
305
+ "--lang",
306
+ options.params.language,
307
+ "--json=compact",
308
+ "--color",
309
+ "never",
310
+ "--",
311
+ ...options.params.paths
312
+ ], {
313
+ cwd: options.cwd,
314
+ env: options.env,
315
+ timeoutMs: options.timeoutMs ?? 1e4
316
+ });
317
+ const output = result.stdout.trim();
318
+ if (result.exitCode === 1 && (output === "" || output === "[]")) return assertSerializedToolResponseFits({
319
+ available: true,
320
+ matches: [],
321
+ truncated: false
322
+ }, options.maxBytes, "pipr_ast_grep response limit is too small");
323
+ if (result.exitCode !== 0) throw new Error("pipr_ast_grep failed");
324
+ let json;
325
+ try {
326
+ json = JSON.parse(output);
327
+ } catch {
328
+ throw new Error("pipr_ast_grep returned invalid output");
329
+ }
330
+ const parsed = astGrepMatchesSchema.safeParse(json);
331
+ if (!parsed.success) throw new Error("pipr_ast_grep returned invalid output");
332
+ const matches = [];
333
+ let truncated = parsed.data.length > 100;
334
+ for (const match of parsed.data.slice(0, 100)) {
335
+ const normalized = {
336
+ path: parseSearchResultPath(match.file),
337
+ startLine: match.range.start.line + 1,
338
+ endLine: match.range.end.line + 1,
339
+ text: truncateUtf8(match.text, 2 * 1024)
340
+ };
341
+ if (serializedToolResponseBytes({
342
+ available: true,
343
+ matches: [...matches, normalized],
344
+ truncated
345
+ }) > options.maxBytes) {
346
+ truncated = true;
347
+ break;
348
+ }
349
+ matches.push(normalized);
350
+ }
351
+ return assertSerializedToolResponseFits({
352
+ available: true,
353
+ matches,
354
+ truncated
355
+ }, options.maxBytes, "pipr_ast_grep response limit is too small");
356
+ }
357
+ function serializedToolResponseBytes(value) {
358
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
359
+ }
360
+ function assertSerializedToolResponseFits(value, maxBytes, errorMessage) {
361
+ if (serializedToolResponseBytes(value) > maxBytes) throw new Error(errorMessage);
362
+ return value;
363
+ }
364
+ function boundToolResponseContent(value, maxBytes, errorMessage) {
365
+ if (serializedToolResponseBytes(value) <= maxBytes) return value;
366
+ const empty = {
367
+ ...value,
368
+ content: "",
369
+ truncated: true
370
+ };
371
+ assertSerializedToolResponseFits(empty, maxBytes, errorMessage);
372
+ const originalBuffer = Buffer.from(value.content, "utf8");
373
+ let low = 0;
374
+ let high = originalBuffer.byteLength;
375
+ let best = empty;
376
+ while (low <= high) {
377
+ const middle = Math.floor((low + high) / 2);
378
+ const candidate = {
379
+ ...value,
380
+ content: originalBuffer.subarray(0, middle).toString("utf8"),
381
+ truncated: true
382
+ };
383
+ if (serializedToolResponseBytes(candidate) <= maxBytes) {
384
+ best = candidate;
385
+ low = middle + 1;
386
+ } else high = middle - 1;
387
+ }
388
+ return best;
389
+ }
390
+ function filterManifestFileRanges(file, rangeId) {
391
+ if (rangeId === void 0) return file;
392
+ return {
393
+ ...file,
394
+ commentableRanges: file.commentableRanges.filter((range) => range.id === rangeId)
395
+ };
396
+ }
397
+ function lineWindowForRange(range, hunk, ref) {
398
+ const targetSide = ref === "base" ? "LEFT" : "RIGHT";
399
+ if (range.side !== targetSide) return;
400
+ const hunkStart = ref === "base" ? hunk.oldStart : hunk.newStart;
401
+ const hunkLines = ref === "base" ? hunk.oldLines : hunk.newLines;
402
+ if (hunkLines === 0) return;
403
+ const hunkEnd = hunkStart + hunkLines - 1;
404
+ return {
405
+ startLine: Math.max(hunkStart, range.startLine - readAtRefContextLines),
406
+ endLine: Math.min(hunkEnd, range.endLine + readAtRefContextLines)
407
+ };
408
+ }
409
+ function parseSearchPath(value) {
410
+ if (value === ".") return value;
411
+ if (value.includes("\\") || /[*?[\]{}]/.test(value) || path.isAbsolute(value) || value.includes("\0") || value.split("/").some((part) => part === "" || part === "." || part === ".." || part === ".git")) throw new Error(`Unsafe structural search path '${value}'`);
412
+ return value;
413
+ }
414
+ function parseSearchResultPath(value) {
415
+ try {
416
+ return parseSearchPath(value);
417
+ } catch {
418
+ throw new Error("pipr_ast_grep returned an unsafe path");
419
+ }
420
+ }
421
+ function truncateUtf8(value, maxBytes) {
422
+ const buffer = Buffer.from(value, "utf8");
423
+ return buffer.byteLength <= maxBytes ? value : buffer.subarray(0, maxBytes).toString("utf8");
424
+ }
425
+ async function runAstGrepProcess(command, options) {
426
+ return await new Promise((resolve, reject) => {
427
+ const child = spawn(command[0], command.slice(1), {
428
+ cwd: options.cwd,
429
+ env: options.env ?? process.env,
430
+ shell: false,
431
+ stdio: [
432
+ "ignore",
433
+ "pipe",
434
+ "pipe"
435
+ ]
436
+ });
437
+ const stdout = [];
438
+ let stdoutBytes = 0;
439
+ let stderrBytes = 0;
440
+ let settled = false;
441
+ const fail = (message) => {
442
+ if (settled) return;
443
+ settled = true;
444
+ clearTimeout(timer);
445
+ child.kill("SIGKILL");
446
+ reject(new Error(message));
447
+ };
448
+ const timer = setTimeout(() => fail("pipr_ast_grep timed out"), options.timeoutMs);
449
+ child.on("error", () => fail("pipr_ast_grep is unavailable"));
450
+ child.stdout.on("data", (chunk) => {
451
+ stdoutBytes += chunk.byteLength;
452
+ if (stdoutBytes > 16 * 1024 * 1024) {
453
+ fail("pipr_ast_grep exceeded its output limit");
454
+ return;
455
+ }
456
+ stdout.push(chunk);
457
+ });
458
+ child.stderr.on("data", (chunk) => {
459
+ stderrBytes += chunk.byteLength;
460
+ if (stderrBytes > 1024 * 1024) fail("pipr_ast_grep exceeded its output limit");
461
+ });
462
+ child.on("close", (exitCode) => {
463
+ if (settled) return;
464
+ settled = true;
465
+ clearTimeout(timer);
466
+ resolve({
467
+ stdout: Buffer.concat(stdout).toString("utf8"),
468
+ exitCode: exitCode ?? -1
469
+ });
470
+ });
471
+ });
472
+ }
473
+ //#endregion
474
+ export { enrichDiffManifestWithStructure as _, boundedLineSlice as a, readDeclarationParams as c, resolveAllowedPath as d, resolveDeclarationRequest as f, createDiffRangeIndex as g, unavailableReadAtRefResult as h, boundToolResponseContent as i, readDiffFromRuntimeData as l, runAstGrepSearch as m, assertSerializedToolResponseFits as n, parseManifestPath as o, resolveReadAtRefRequest as p, astGrepSearchParams as r, readAtRefParams as s, assertNoSymlinkPath as t, readDiffParams as u, findEnclosingDeclaration as v, isRecord as y };
475
+
476
+ //# sourceMappingURL=runtime-tools-core-BF8rSeNS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-tools-core-BF8rSeNS.mjs","names":[],"sources":["../src/shared/record.ts","../src/diff/manifest-structure.ts","../src/diff/ranges.ts","../src/pi/runtime-tools-core.ts"],"sourcesContent":["export function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type { CommentableRange, DiffManifest, DiffManifestFile } from \"../types.js\";\nimport type { DiffStructuralAnalysis, StructuralDeclaration } from \"./structural-analysis.js\";\n\nexport type EnclosingDeclaration = {\n declaration: StructuralDeclaration;\n ref: \"base\" | \"head\";\n sourcePath: string;\n};\n\nconst maxSymbolsPerFile = 32;\nconst maxSymbolCharacters = 120;\nconst maxSummaryCharacters = 200;\nconst maxDerivedMetadataBytes = 32 * 1024;\n\nexport function enrichDiffManifestWithStructure(\n manifest: DiffManifest,\n analysis: DiffStructuralAnalysis,\n): DiffManifest {\n if (!analysis.available) {\n return manifest;\n }\n const budget = { remaining: maxDerivedMetadataBytes, exhausted: false };\n return {\n ...manifest,\n files: manifest.files.map((file) => enrichFile(file, analysis, budget)),\n };\n}\n\nexport function findEnclosingDeclaration(\n file: DiffManifestFile,\n range: CommentableRange,\n analysis: DiffStructuralAnalysis,\n): EnclosingDeclaration | undefined {\n if (!analysis.available) {\n return undefined;\n }\n const ref = range.side === \"LEFT\" ? \"base\" : \"head\";\n const sourcePath = ref === \"base\" ? (file.previousPath ?? file.path) : file.path;\n const structuralFile = (ref === \"base\" ? analysis.baseFiles : analysis.headFiles).find(\n (candidate) => candidate.path === sourcePath,\n );\n const declaration = structuralFile?.declarations\n .filter(\n (candidate) => candidate.startLine <= range.startLine && candidate.endLine >= range.endLine,\n )\n .sort(compareContainingDeclarations)[0];\n return declaration ? { declaration, ref, sourcePath } : undefined;\n}\n\nfunction enrichFile(\n file: DiffManifestFile,\n analysis: DiffStructuralAnalysis,\n budget: { remaining: number; exhausted: boolean },\n): DiffManifestFile {\n const owners = new Map<string, StructuralDeclaration>();\n const commentableRanges = file.commentableRanges.map((range) => {\n const owner = findEnclosingDeclaration(file, range, analysis)?.declaration;\n if (owner) {\n owners.set(owner.qualifiedName, owner);\n }\n if (!owner || range.summary !== undefined || budget.exhausted) {\n return range;\n }\n const summary = truncate(\n `Enclosing declaration: ${owner.kind} ${owner.qualifiedName}`,\n maxSummaryCharacters,\n );\n return consumeDerivedMetadata(budget, summary) ? { ...range, summary } : range;\n });\n\n const existingSymbols = [...(file.changedSymbols ?? [])];\n const symbolSet = new Set(existingSymbols);\n const derivedSymbols: string[] = [];\n for (const owner of [...owners.values()].sort(compareSourceOrder)) {\n if (budget.exhausted || existingSymbols.length + derivedSymbols.length >= maxSymbolsPerFile) {\n break;\n }\n const symbol = truncate(owner.qualifiedName, maxSymbolCharacters);\n if (symbolSet.has(symbol)) {\n continue;\n }\n if (!consumeDerivedMetadata(budget, symbol)) {\n break;\n }\n symbolSet.add(symbol);\n derivedSymbols.push(symbol);\n }\n\n return {\n ...file,\n ...(existingSymbols.length > 0 || derivedSymbols.length > 0\n ? { changedSymbols: [...existingSymbols, ...derivedSymbols] }\n : {}),\n commentableRanges,\n };\n}\n\nfunction compareContainingDeclarations(\n left: StructuralDeclaration,\n right: StructuralDeclaration,\n): number {\n return (\n left.endLine - left.startLine - (right.endLine - right.startLine) ||\n right.startLine - left.startLine ||\n left.qualifiedName.localeCompare(right.qualifiedName)\n );\n}\n\nfunction compareSourceOrder(left: StructuralDeclaration, right: StructuralDeclaration): number {\n return (\n left.startLine - right.startLine ||\n left.endLine - right.endLine ||\n left.qualifiedName.localeCompare(right.qualifiedName)\n );\n}\n\nfunction consumeDerivedMetadata(\n budget: { remaining: number; exhausted: boolean },\n value: string,\n): boolean {\n const bytes = Buffer.byteLength(value, \"utf8\");\n if (bytes > budget.remaining) {\n budget.exhausted = true;\n return false;\n }\n budget.remaining -= bytes;\n return true;\n}\n\nfunction truncate(value: string, maxCharacters: number): string {\n return value.length <= maxCharacters ? value : value.slice(0, maxCharacters);\n}\n","import type { CommentableRange, DiffHunk, DiffManifest, DiffManifestFile } from \"../types.js\";\n\nexport type DiffRangeMatch = {\n file: DiffManifestFile;\n range: CommentableRange;\n};\n\nexport type DiffRangeIndex = {\n fileByPath(filePath: string): DiffManifestFile | undefined;\n excludedReason(filePath: string): string | undefined;\n findRange(rangeId: string): DiffRangeMatch | undefined;\n rangeById(rangeId: string): CommentableRange | undefined;\n requireFile(filePath: string): DiffManifestFile;\n requireRangeInFile(file: DiffManifestFile, rangeId: string): CommentableRange;\n requireHunk(file: DiffManifestFile, range: CommentableRange): DiffHunk;\n};\n\nexport function createDiffRangeIndex(manifest: DiffManifest): DiffRangeIndex {\n const filesByPath = new Map(manifest.files.map((file) => [file.path, file]));\n const rangesById = new Map<string, DiffRangeMatch>();\n for (const file of manifest.files) {\n for (const range of file.commentableRanges) {\n rangesById.set(range.id, { file, range });\n }\n }\n\n return {\n fileByPath(filePath) {\n return filesByPath.get(filePath);\n },\n excludedReason(filePath) {\n return filesByPath.get(filePath)?.excludedReason;\n },\n findRange(rangeId) {\n return rangesById.get(rangeId);\n },\n rangeById(rangeId) {\n return rangesById.get(rangeId)?.range;\n },\n requireFile(filePath) {\n const file = filesByPath.get(filePath);\n if (!file) {\n throw new Error(`Path '${filePath}' is not in the Diff Manifest`);\n }\n return file;\n },\n requireRangeInFile(file, rangeId) {\n const range = file.commentableRanges.find((item) => item.id === rangeId);\n if (range) {\n return range;\n }\n if (rangesById.has(rangeId)) {\n throw new Error(`Diff Manifest range '${rangeId}' is not in path '${file.path}'`);\n }\n throw new Error(`Unknown Diff Manifest range '${rangeId}'`);\n },\n requireHunk(file, range) {\n const hunk = file.hunks.find(\n (item) => item.hunkIndex === range.hunkIndex && item.contentHash === range.hunkContentHash,\n );\n if (!hunk) {\n throw new Error(`Diff Manifest range '${range.id}' has no matching hunk`);\n }\n return hunk;\n },\n };\n}\n","import { spawn } from \"node:child_process\";\nimport { lstat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { findEnclosingDeclaration } from \"../diff/manifest-structure.js\";\nimport { createDiffRangeIndex } from \"../diff/ranges.js\";\nimport type { DiffStructuralAnalysis, StructuralDeclaration } from \"../diff/structural-analysis.js\";\nimport { isRecord } from \"../shared/record.js\";\nimport type { CommentableRange, DiffHunk, DiffManifest, DiffManifestFile } from \"../types.js\";\n\nconst readAtRefContextLines = 3;\n\nexport type ReadDiffParams = {\n path?: string;\n rangeId?: string;\n};\n\nexport type ReadAtRefParams = {\n path: string;\n ref: \"base\" | \"head\";\n rangeId: string;\n};\n\nexport type RuntimeToolData = {\n manifest: DiffManifest;\n toolResponseMaxBytes: number;\n baseRanges: Record<string, BaseRangeSnapshot>;\n baseDeclarations?: Record<string, BaseDeclarationSnapshot>;\n structuralAnalysis?: Extract<DiffStructuralAnalysis, { available: true }>;\n};\n\nexport type BaseRangeSnapshot = {\n path: string;\n ref: \"base\" | \"head\";\n sourcePath: string;\n rangeId: string;\n startLine: number;\n endLine: number;\n available: boolean;\n relativePath?: string;\n bytes?: number;\n truncated?: boolean;\n};\n\nexport type BaseDeclarationSnapshot = {\n path: string;\n ref: \"base\";\n sourcePath: string;\n rangeId: string;\n declaration: StructuralDeclaration;\n available: boolean;\n relativePath?: string;\n bytes?: number;\n truncated?: boolean;\n};\n\nexport type ReadDeclarationParams = {\n path: string;\n ref: \"base\" | \"head\";\n rangeId: string;\n};\n\nexport type AstGrepSearchParams = {\n pattern: string;\n language: string;\n paths: string[];\n};\n\nexport type ReadAtRefRequest = {\n file: DiffManifestFile;\n range: CommentableRange;\n hunk: DiffHunk;\n ref: \"base\" | \"head\";\n sourcePath: string;\n window: LineWindow | undefined;\n};\n\nexport type LineWindow = {\n startLine: number;\n endLine: number;\n};\n\nexport type LineSliceResult = {\n available: true;\n content: string;\n bytes: number;\n truncated: boolean;\n};\n\nconst readDiffParamsSchema = z.preprocess(\n (params) => {\n const record = isRecord(params) ? params : {};\n return {\n path: typeof record.path === \"string\" ? record.path : undefined,\n rangeId: typeof record.rangeId === \"string\" ? record.rangeId : undefined,\n };\n },\n z.object({\n path: z.string().optional(),\n rangeId: z.string().optional(),\n }),\n);\n\nconst readAtRefParamsSchema = z.preprocess(\n (params) => (isRecord(params) ? params : {}),\n z.object({\n path: z.unknown(),\n ref: z.enum([\"base\", \"head\"], {\n error: (issue) => `Unsupported ref '${String(issue.input)}'`,\n }),\n rangeId: z.string({ error: \"rangeId must be a string\" }),\n }),\n);\nconst astGrepSearchParamsSchema = z.strictObject({\n pattern: z.string().min(1).max(4096),\n language: z.string().min(1).max(64),\n paths: z.array(z.string()).min(1).max(16),\n});\nconst astGrepMatchSchema = z.looseObject({\n text: z.string(),\n file: z.string(),\n range: z.object({\n start: z.object({\n line: z.number().int().nonnegative(),\n column: z.number().int().nonnegative(),\n }),\n end: z.object({\n line: z.number().int().nonnegative(),\n column: z.number().int().nonnegative(),\n }),\n }),\n});\nconst astGrepMatchesSchema = z.array(astGrepMatchSchema);\nexport function readDiffFromRuntimeData(data: RuntimeToolData, params: ReadDiffParams): unknown {\n const { rangeId } = params;\n const filePath = params.path === undefined ? undefined : parseManifestPath(params.path);\n const ranges = createDiffRangeIndex(data.manifest);\n if (filePath !== undefined) {\n ranges.requireFile(filePath);\n }\n if (rangeId !== undefined && !ranges.findRange(rangeId)) {\n throw new Error(`Unknown Diff Manifest range '${rangeId}'`);\n }\n const files = data.manifest.files\n .filter((file) => filePath === undefined || file.path === filePath)\n .map((file) => filterManifestFileRanges(file, rangeId))\n .filter((file) => rangeId === undefined || file.commentableRanges.length > 0);\n return boundedJson({ files }, data.toolResponseMaxBytes);\n}\n\nfunction boundedJson(value: unknown, maxBytes: number): unknown {\n const text = JSON.stringify(value, null, 2);\n const bytes = Buffer.byteLength(text, \"utf8\");\n if (bytes <= maxBytes) {\n return { truncated: false, bytes, value };\n }\n return {\n truncated: true,\n bytes,\n maxBytes,\n text: Buffer.from(text, \"utf8\").subarray(0, maxBytes).toString(\"utf8\"),\n };\n}\n\nexport function boundedLineSlice(\n content: string,\n window: LineWindow,\n maxBytes: number,\n): LineSliceResult {\n const lines = content.match(/[^\\n]*(?:\\n|$)/g) ?? [];\n if (lines.at(-1) === \"\") {\n lines.pop();\n }\n const slice = lines.slice(window.startLine - 1, window.endLine).join(\"\");\n const buffer = Buffer.from(slice, \"utf8\");\n return {\n available: true,\n content: buffer.subarray(0, maxBytes).toString(\"utf8\"),\n bytes: buffer.byteLength,\n truncated: buffer.byteLength > maxBytes,\n };\n}\n\nexport function resolveReadAtRefRequest(\n manifest: DiffManifest,\n params: ReadAtRefParams,\n): ReadAtRefRequest {\n const filePath = parseManifestPath(params.path);\n const ranges = createDiffRangeIndex(manifest);\n const file = ranges.requireFile(filePath);\n const range = ranges.requireRangeInFile(file, params.rangeId);\n const hunk = ranges.requireHunk(file, range);\n const sourcePath = parseManifestPath(\n params.ref === \"base\" ? (file.previousPath ?? file.path) : file.path,\n );\n return {\n file,\n range,\n hunk,\n ref: params.ref,\n sourcePath,\n window: lineWindowForRange(range, hunk, params.ref),\n };\n}\n\nexport function unavailableReadAtRefResult(request: ReadAtRefRequest): BaseRangeSnapshot {\n return {\n path: request.file.path,\n ref: request.ref,\n sourcePath: request.sourcePath,\n rangeId: request.range.id,\n startLine: 0,\n endLine: 0,\n available: false,\n };\n}\n\nexport function parseManifestPath(filePath: unknown): string {\n if (\n typeof filePath !== \"string\" ||\n filePath.length === 0 ||\n filePath.includes(\"\\0\") ||\n path.isAbsolute(filePath) ||\n filePath.split(/[\\\\/]/).some((part) => part === \"..\" || part === \".git\" || part === \"\")\n ) {\n throw new Error(`Unsafe manifest path '${String(filePath)}'`);\n }\n return filePath;\n}\n\nexport function resolveAllowedPath(root: string, filePath: string): string {\n const resolved = path.resolve(root, filePath);\n const relative = path.relative(root, resolved);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path '${filePath}' resolves outside the workspace`);\n }\n return resolved;\n}\n\nexport async function assertNoSymlinkPath(root: string, filePath: string): Promise<void> {\n const parts = filePath.split(/[\\\\/]/);\n let current = root;\n for (const part of parts) {\n current = path.join(current, part);\n const stats = await lstat(current);\n if (stats.isSymbolicLink()) {\n throw new Error(`Path '${filePath}' crosses a symlink`);\n }\n }\n}\n\nexport function readDiffParams(params: unknown): ReadDiffParams {\n return readDiffParamsSchema.parse(params);\n}\n\nexport function readAtRefParams(params: unknown): ReadAtRefParams {\n const parsed = readAtRefParamsSchema.parse(params);\n return { path: parseManifestPath(parsed.path), ref: parsed.ref, rangeId: parsed.rangeId };\n}\n\nexport function readDeclarationParams(params: unknown): ReadDeclarationParams {\n return readAtRefParams(params);\n}\n\nexport function astGrepSearchParams(params: unknown): AstGrepSearchParams {\n const parsed = astGrepSearchParamsSchema.parse(params);\n return {\n pattern: parsed.pattern,\n language: parsed.language,\n paths: parsed.paths.map(parseSearchPath),\n };\n}\n\nexport function resolveDeclarationRequest(\n data: RuntimeToolData,\n params: ReadDeclarationParams,\n):\n | {\n available: true;\n path: string;\n sourcePath: string;\n ref: \"base\" | \"head\";\n rangeId: string;\n declaration: StructuralDeclaration;\n }\n | {\n available: false;\n path: string;\n sourcePath: string;\n ref: \"base\" | \"head\";\n rangeId: string;\n } {\n const filePath = parseManifestPath(params.path);\n const ranges = createDiffRangeIndex(data.manifest);\n const file = ranges.requireFile(filePath);\n const range = ranges.requireRangeInFile(file, params.rangeId);\n const sourcePath = parseManifestPath(\n params.ref === \"base\" ? (file.previousPath ?? file.path) : file.path,\n );\n const expectedSide = params.ref === \"base\" ? \"LEFT\" : \"RIGHT\";\n if (!data.structuralAnalysis || range.side !== expectedSide) {\n return {\n available: false,\n path: file.path,\n sourcePath,\n ref: params.ref,\n rangeId: range.id,\n };\n }\n const owner = findEnclosingDeclaration(file, range, data.structuralAnalysis);\n if (!owner || owner.ref !== params.ref) {\n return {\n available: false,\n path: file.path,\n sourcePath,\n ref: params.ref,\n rangeId: range.id,\n };\n }\n return {\n available: true,\n path: file.path,\n sourcePath: owner.sourcePath,\n ref: params.ref,\n rangeId: range.id,\n declaration: owner.declaration,\n };\n}\n\nexport async function runAstGrepSearch(options: {\n cwd: string;\n params: AstGrepSearchParams;\n maxBytes: number;\n env?: NodeJS.ProcessEnv;\n timeoutMs?: number;\n}): Promise<unknown> {\n for (const searchPath of options.params.paths) {\n if (searchPath !== \".\") {\n resolveAllowedPath(options.cwd, searchPath);\n await assertNoSymlinkPath(options.cwd, searchPath);\n }\n }\n const result = await runAstGrepProcess(\n [\n \"ast-grep\",\n \"run\",\n \"--pattern\",\n options.params.pattern,\n \"--lang\",\n options.params.language,\n \"--json=compact\",\n \"--color\",\n \"never\",\n \"--\",\n ...options.params.paths,\n ],\n {\n cwd: options.cwd,\n env: options.env,\n timeoutMs: options.timeoutMs ?? 10_000,\n },\n );\n const output = result.stdout.trim();\n if (result.exitCode === 1 && (output === \"\" || output === \"[]\")) {\n return assertSerializedToolResponseFits(\n { available: true, matches: [], truncated: false },\n options.maxBytes,\n \"pipr_ast_grep response limit is too small\",\n );\n }\n if (result.exitCode !== 0) {\n throw new Error(\"pipr_ast_grep failed\");\n }\n let json: unknown;\n try {\n json = JSON.parse(output);\n } catch {\n throw new Error(\"pipr_ast_grep returned invalid output\");\n }\n const parsed = astGrepMatchesSchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(\"pipr_ast_grep returned invalid output\");\n }\n const matches: Array<{\n path: string;\n startLine: number;\n endLine: number;\n text: string;\n }> = [];\n let truncated = parsed.data.length > 100;\n for (const match of parsed.data.slice(0, 100)) {\n const normalized = {\n path: parseSearchResultPath(match.file),\n startLine: match.range.start.line + 1,\n endLine: match.range.end.line + 1,\n text: truncateUtf8(match.text, 2 * 1024),\n };\n const candidate = { available: true, matches: [...matches, normalized], truncated };\n if (serializedToolResponseBytes(candidate) > options.maxBytes) {\n truncated = true;\n break;\n }\n matches.push(normalized);\n }\n return assertSerializedToolResponseFits(\n { available: true, matches, truncated },\n options.maxBytes,\n \"pipr_ast_grep response limit is too small\",\n );\n}\n\nfunction serializedToolResponseBytes(value: unknown): number {\n return Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nexport function assertSerializedToolResponseFits<T>(\n value: T,\n maxBytes: number,\n errorMessage: string,\n): T {\n if (serializedToolResponseBytes(value) > maxBytes) {\n throw new Error(errorMessage);\n }\n return value;\n}\n\nexport function boundToolResponseContent<T extends { content: string }>(\n value: T,\n maxBytes: number,\n errorMessage: string,\n): T & { truncated: boolean } {\n if (serializedToolResponseBytes(value) <= maxBytes) {\n return value as T & { truncated: boolean };\n }\n const empty = { ...value, content: \"\", truncated: true };\n assertSerializedToolResponseFits(empty, maxBytes, errorMessage);\n const originalBuffer = Buffer.from(value.content, \"utf8\");\n let low = 0;\n let high = originalBuffer.byteLength;\n let best = empty;\n while (low <= high) {\n const middle = Math.floor((low + high) / 2);\n const candidate = {\n ...value,\n content: originalBuffer.subarray(0, middle).toString(\"utf8\"),\n truncated: true,\n };\n if (serializedToolResponseBytes(candidate) <= maxBytes) {\n best = candidate;\n low = middle + 1;\n } else {\n high = middle - 1;\n }\n }\n return best;\n}\n\nfunction filterManifestFileRanges(\n file: DiffManifestFile,\n rangeId: string | undefined,\n): DiffManifestFile {\n if (rangeId === undefined) {\n return file;\n }\n return {\n ...file,\n commentableRanges: file.commentableRanges.filter((range) => range.id === rangeId),\n };\n}\n\nfunction lineWindowForRange(\n range: CommentableRange,\n hunk: DiffHunk,\n ref: \"base\" | \"head\",\n): LineWindow | undefined {\n const targetSide: CommentableRange[\"side\"] = ref === \"base\" ? \"LEFT\" : \"RIGHT\";\n if (range.side !== targetSide) {\n return undefined;\n }\n const hunkStart = ref === \"base\" ? hunk.oldStart : hunk.newStart;\n const hunkLines = ref === \"base\" ? hunk.oldLines : hunk.newLines;\n if (hunkLines === 0) {\n return undefined;\n }\n const hunkEnd = hunkStart + hunkLines - 1;\n return {\n startLine: Math.max(hunkStart, range.startLine - readAtRefContextLines),\n endLine: Math.min(hunkEnd, range.endLine + readAtRefContextLines),\n };\n}\n\nfunction parseSearchPath(value: string): string {\n if (value === \".\") {\n return value;\n }\n if (\n value.includes(\"\\\\\") ||\n /[*?[\\]{}]/.test(value) ||\n path.isAbsolute(value) ||\n value.includes(\"\\0\") ||\n value.split(\"/\").some((part) => part === \"\" || part === \".\" || part === \"..\" || part === \".git\")\n ) {\n throw new Error(`Unsafe structural search path '${value}'`);\n }\n return value;\n}\n\nfunction parseSearchResultPath(value: string): string {\n try {\n return parseSearchPath(value);\n } catch {\n throw new Error(\"pipr_ast_grep returned an unsafe path\");\n }\n}\n\nfunction truncateUtf8(value: string, maxBytes: number): string {\n const buffer = Buffer.from(value, \"utf8\");\n return buffer.byteLength <= maxBytes ? value : buffer.subarray(0, maxBytes).toString(\"utf8\");\n}\n\nasync function runAstGrepProcess(\n command: [string, ...string[]],\n options: {\n cwd: string;\n env?: NodeJS.ProcessEnv;\n timeoutMs: number;\n },\n): Promise<{ stdout: string; exitCode: number }> {\n return await new Promise((resolve, reject) => {\n const child = spawn(command[0], command.slice(1), {\n cwd: options.cwd,\n env: options.env ?? process.env,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const stdout: Buffer[] = [];\n let stdoutBytes = 0;\n let stderrBytes = 0;\n let settled = false;\n const fail = (message: string) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n child.kill(\"SIGKILL\");\n reject(new Error(message));\n };\n const timer = setTimeout(() => fail(\"pipr_ast_grep timed out\"), options.timeoutMs);\n child.on(\"error\", () => fail(\"pipr_ast_grep is unavailable\"));\n child.stdout.on(\"data\", (chunk: Buffer) => {\n stdoutBytes += chunk.byteLength;\n if (stdoutBytes > 16 * 1024 * 1024) {\n fail(\"pipr_ast_grep exceeded its output limit\");\n return;\n }\n stdout.push(chunk);\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n stderrBytes += chunk.byteLength;\n if (stderrBytes > 1024 * 1024) {\n fail(\"pipr_ast_grep exceeded its output limit\");\n }\n });\n child.on(\"close\", (exitCode) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n resolve({\n stdout: Buffer.concat(stdout).toString(\"utf8\"),\n exitCode: exitCode ?? -1,\n });\n });\n });\n}\n"],"mappings":"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"}