@evalops/maestro 0.10.38 → 0.10.40
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.
- package/dist/cli.js +145 -34
- package/dist/node_modules/@evalops/contracts/package.json +1 -1
- package/dist/node_modules/@evalops/tui/package.json +1 -1
- package/dist/tools/find.js +1 -1
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/parallel-ripgrep.d.ts.map +1 -1
- package/dist/tools/parallel-ripgrep.js +13 -1
- package/dist/tools/parallel-ripgrep.js.map +1 -1
- package/dist/tools/ripgrep-utils.d.ts +1 -0
- package/dist/tools/ripgrep-utils.d.ts.map +1 -1
- package/dist/tools/ripgrep-utils.js +68 -17
- package/dist/tools/ripgrep-utils.js.map +1 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +6 -1
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/tools-manager.d.ts +1 -1
- package/dist/tools/tools-manager.d.ts.map +1 -1
- package/dist/tools/tools-manager.js +60 -18
- package/dist/tools/tools-manager.js.map +1 -1
- package/dist/version.json +2 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -158629,6 +158629,14 @@ var init_extract_document = __esm2(() => {
|
|
|
158629
158629
|
}
|
|
158630
158630
|
});
|
|
158631
158631
|
});
|
|
158632
|
+
function toolInstallAbortError(config2) {
|
|
158633
|
+
return new Error(`${config2.name} installation aborted`);
|
|
158634
|
+
}
|
|
158635
|
+
function throwIfToolInstallAborted(config2, signal) {
|
|
158636
|
+
if (signal?.aborted) {
|
|
158637
|
+
throw toolInstallAbortError(config2);
|
|
158638
|
+
}
|
|
158639
|
+
}
|
|
158632
158640
|
function commandExists2(cmd) {
|
|
158633
158641
|
try {
|
|
158634
158642
|
const result2 = spawnSync9(cmd, ["--version"], { stdio: "pipe" });
|
|
@@ -158650,24 +158658,38 @@ function getToolPath(tool) {
|
|
|
158650
158658
|
}
|
|
158651
158659
|
return null;
|
|
158652
158660
|
}
|
|
158653
|
-
async function fetchWithTimeout(url, init2) {
|
|
158661
|
+
async function fetchWithTimeout(url, init2, signal) {
|
|
158654
158662
|
const controller = new AbortController();
|
|
158655
158663
|
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
158664
|
+
const onAbort = () => {
|
|
158665
|
+
controller.abort(signal?.reason);
|
|
158666
|
+
};
|
|
158667
|
+
if (signal?.aborted) {
|
|
158668
|
+
onAbort();
|
|
158669
|
+
} else {
|
|
158670
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
158671
|
+
}
|
|
158672
|
+
const clearFetchTimeout = () => clearTimeout(timeout);
|
|
158673
|
+
const cleanup = () => {
|
|
158674
|
+
clearFetchTimeout();
|
|
158675
|
+
signal?.removeEventListener("abort", onAbort);
|
|
158676
|
+
};
|
|
158656
158677
|
try {
|
|
158657
158678
|
const response = await fetch(url, { ...init2, signal: controller.signal });
|
|
158658
158679
|
return {
|
|
158659
158680
|
response,
|
|
158660
|
-
clearTimeout:
|
|
158681
|
+
clearTimeout: clearFetchTimeout,
|
|
158682
|
+
cleanup
|
|
158661
158683
|
};
|
|
158662
158684
|
} catch (error) {
|
|
158663
|
-
|
|
158685
|
+
cleanup();
|
|
158664
158686
|
throw error;
|
|
158665
158687
|
}
|
|
158666
158688
|
}
|
|
158667
|
-
async function getLatestVersion(repo) {
|
|
158668
|
-
const { response,
|
|
158689
|
+
async function getLatestVersion(repo, signal) {
|
|
158690
|
+
const { response, cleanup: cleanupFetch } = await fetchWithTimeout(`https://api.github.com/repos/${repo}/releases/latest`, {
|
|
158669
158691
|
headers: { "User-Agent": "composer-coding-agent" }
|
|
158670
|
-
});
|
|
158692
|
+
}, signal);
|
|
158671
158693
|
try {
|
|
158672
158694
|
if (!response.ok) {
|
|
158673
158695
|
throw new Error(`GitHub API error: ${response.status}`);
|
|
@@ -158675,11 +158697,15 @@ async function getLatestVersion(repo) {
|
|
|
158675
158697
|
const data = await response.json();
|
|
158676
158698
|
return data.tag_name.replace(/^v/, "");
|
|
158677
158699
|
} finally {
|
|
158678
|
-
|
|
158700
|
+
cleanupFetch();
|
|
158679
158701
|
}
|
|
158680
158702
|
}
|
|
158681
|
-
async function downloadFile2(url, dest) {
|
|
158682
|
-
const {
|
|
158703
|
+
async function downloadFile2(url, dest, signal) {
|
|
158704
|
+
const {
|
|
158705
|
+
response,
|
|
158706
|
+
clearTimeout: clearFetchTimeout,
|
|
158707
|
+
cleanup: cleanupFetch
|
|
158708
|
+
} = await fetchWithTimeout(url, void 0, signal);
|
|
158683
158709
|
try {
|
|
158684
158710
|
if (!response.ok) {
|
|
158685
158711
|
throw new Error(`Failed to download: ${response.status}`);
|
|
@@ -158691,6 +158717,11 @@ async function downloadFile2(url, dest) {
|
|
|
158691
158717
|
const stream = Readable2.fromWeb(response.body);
|
|
158692
158718
|
const fileStream = createWriteStream3(dest);
|
|
158693
158719
|
let idleTimeoutId = null;
|
|
158720
|
+
const onAbort = () => {
|
|
158721
|
+
const error = new Error("Tool download aborted");
|
|
158722
|
+
stream.destroy(error);
|
|
158723
|
+
fileStream.destroy(error);
|
|
158724
|
+
};
|
|
158694
158725
|
const clearIdleTimeout = () => {
|
|
158695
158726
|
if (idleTimeoutId) {
|
|
158696
158727
|
clearTimeout(idleTimeoutId);
|
|
@@ -158710,6 +158741,11 @@ async function downloadFile2(url, dest) {
|
|
|
158710
158741
|
clearIdleTimeout();
|
|
158711
158742
|
};
|
|
158712
158743
|
resetIdleTimeout();
|
|
158744
|
+
if (signal?.aborted) {
|
|
158745
|
+
onAbort();
|
|
158746
|
+
} else {
|
|
158747
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
158748
|
+
}
|
|
158713
158749
|
stream.on("data", resetIdleTimeout);
|
|
158714
158750
|
stream.on("end", onStreamEnd);
|
|
158715
158751
|
stream.on("close", onStreamEnd);
|
|
@@ -158721,10 +158757,11 @@ async function downloadFile2(url, dest) {
|
|
|
158721
158757
|
stream.off("end", onStreamEnd);
|
|
158722
158758
|
stream.off("close", onStreamEnd);
|
|
158723
158759
|
stream.off("error", onStreamEnd);
|
|
158760
|
+
signal?.removeEventListener("abort", onAbort);
|
|
158724
158761
|
clearIdleTimeout();
|
|
158725
158762
|
}
|
|
158726
158763
|
} finally {
|
|
158727
|
-
|
|
158764
|
+
cleanupFetch();
|
|
158728
158765
|
}
|
|
158729
158766
|
}
|
|
158730
158767
|
function runExtractor(command, args, description) {
|
|
@@ -158760,13 +158797,15 @@ function findBinary(root, binaryName) {
|
|
|
158760
158797
|
}
|
|
158761
158798
|
return null;
|
|
158762
158799
|
}
|
|
158763
|
-
async function downloadTool(tool) {
|
|
158800
|
+
async function downloadTool(tool, signal) {
|
|
158764
158801
|
const config2 = TOOLS[tool];
|
|
158765
158802
|
if (!config2)
|
|
158766
158803
|
throw new Error(`Unknown tool: ${tool}`);
|
|
158804
|
+
throwIfToolInstallAborted(config2, signal);
|
|
158767
158805
|
const plat = platform3();
|
|
158768
158806
|
const architecture = arch2();
|
|
158769
|
-
const version3 = await getLatestVersion(config2.repo);
|
|
158807
|
+
const version3 = await getLatestVersion(config2.repo, signal);
|
|
158808
|
+
throwIfToolInstallAborted(config2, signal);
|
|
158770
158809
|
const assetName = config2.getAssetName(version3, plat, architecture);
|
|
158771
158810
|
if (!assetName) {
|
|
158772
158811
|
throw new Error(`Unsupported platform: ${plat}/${architecture}`);
|
|
@@ -158776,7 +158815,8 @@ async function downloadTool(tool) {
|
|
|
158776
158815
|
const archivePath = join79(TOOLS_DIR, assetName);
|
|
158777
158816
|
const binaryExt = plat === "win32" ? ".exe" : "";
|
|
158778
158817
|
const binaryPath = join79(TOOLS_DIR, config2.binaryName + binaryExt);
|
|
158779
|
-
await downloadFile2(downloadUrl, archivePath);
|
|
158818
|
+
await downloadFile2(downloadUrl, archivePath, signal);
|
|
158819
|
+
throwIfToolInstallAborted(config2, signal);
|
|
158780
158820
|
const extractDir = mkdtempSync2(join79(TOOLS_DIR, "extract-"));
|
|
158781
158821
|
try {
|
|
158782
158822
|
if (assetName.endsWith(".tar.gz")) {
|
|
@@ -158800,24 +158840,28 @@ async function downloadTool(tool) {
|
|
|
158800
158840
|
}
|
|
158801
158841
|
return binaryPath;
|
|
158802
158842
|
}
|
|
158803
|
-
async function ensureTool(tool, silent = false) {
|
|
158843
|
+
async function ensureTool(tool, silent = false, signal) {
|
|
158844
|
+
const config2 = TOOLS[tool];
|
|
158845
|
+
if (!config2)
|
|
158846
|
+
return null;
|
|
158847
|
+
throwIfToolInstallAborted(config2, signal);
|
|
158804
158848
|
const existingPath = getToolPath(tool);
|
|
158805
158849
|
if (existingPath) {
|
|
158806
158850
|
return existingPath;
|
|
158807
158851
|
}
|
|
158808
|
-
const config2 = TOOLS[tool];
|
|
158809
|
-
if (!config2)
|
|
158810
|
-
return null;
|
|
158811
158852
|
if (!silent) {
|
|
158812
158853
|
console.log(chalk62.dim(`${config2.name} not found. Downloading...`));
|
|
158813
158854
|
}
|
|
158814
158855
|
try {
|
|
158815
|
-
const path3 = await downloadTool(tool);
|
|
158856
|
+
const path3 = await downloadTool(tool, signal);
|
|
158816
158857
|
if (!silent) {
|
|
158817
158858
|
console.log(chalk62.dim(`${config2.name} installed to ${path3}`));
|
|
158818
158859
|
}
|
|
158819
158860
|
return path3;
|
|
158820
158861
|
} catch (e2) {
|
|
158862
|
+
if (signal?.aborted) {
|
|
158863
|
+
throw toolInstallAbortError(config2);
|
|
158864
|
+
}
|
|
158821
158865
|
if (!silent) {
|
|
158822
158866
|
console.log(chalk62.yellow(`Failed to download ${config2.name}: ${e2 instanceof Error ? e2.message : e2}`));
|
|
158823
158867
|
}
|
|
@@ -159122,7 +159166,7 @@ var init_find = __esm2(() => {
|
|
|
159122
159166
|
throw new Error("Operation aborted");
|
|
159123
159167
|
}
|
|
159124
159168
|
const { pattern, path: searchDir, limit, includeHidden = true } = params;
|
|
159125
|
-
const fdPath = await ensureTool("fd", true);
|
|
159169
|
+
const fdPath = await ensureTool("fd", true, signal);
|
|
159126
159170
|
if (!fdPath) {
|
|
159127
159171
|
return respond.error("fd is not available and could not be downloaded").detail({
|
|
159128
159172
|
command: "fd",
|
|
@@ -160329,36 +160373,81 @@ function toArray(value) {
|
|
|
160329
160373
|
function ripgrepAbortError() {
|
|
160330
160374
|
return new Error("ripgrep search aborted before start");
|
|
160331
160375
|
}
|
|
160332
|
-
|
|
160333
|
-
ripgrepExecutablePromise
|
|
160334
|
-
|
|
160335
|
-
|
|
160336
|
-
|
|
160337
|
-
|
|
160376
|
+
function resetRipgrepExecutablePromise() {
|
|
160377
|
+
ripgrepExecutablePromise = null;
|
|
160378
|
+
ripgrepInstallController = null;
|
|
160379
|
+
}
|
|
160380
|
+
function getRipgrepExecutablePromise() {
|
|
160381
|
+
if (!ripgrepExecutablePromise) {
|
|
160382
|
+
const controller = new AbortController();
|
|
160383
|
+
ripgrepInstallController = controller;
|
|
160384
|
+
const promise = ensureTool("rg", true, controller.signal).then((executable) => {
|
|
160385
|
+
if (ripgrepInstallController === controller) {
|
|
160386
|
+
ripgrepInstallController = null;
|
|
160387
|
+
}
|
|
160388
|
+
if (ripgrepExecutablePromise === promise && !executable) {
|
|
160389
|
+
ripgrepExecutablePromise = null;
|
|
160390
|
+
}
|
|
160391
|
+
return executable;
|
|
160392
|
+
}, (error) => {
|
|
160393
|
+
if (ripgrepInstallController === controller) {
|
|
160394
|
+
ripgrepInstallController = null;
|
|
160395
|
+
}
|
|
160396
|
+
if (ripgrepExecutablePromise === promise) {
|
|
160397
|
+
ripgrepExecutablePromise = null;
|
|
160398
|
+
}
|
|
160399
|
+
throw error;
|
|
160400
|
+
});
|
|
160401
|
+
ripgrepExecutablePromise = promise;
|
|
160338
160402
|
}
|
|
160339
|
-
return
|
|
160403
|
+
return ripgrepExecutablePromise;
|
|
160340
160404
|
}
|
|
160341
|
-
function
|
|
160342
|
-
|
|
160343
|
-
|
|
160405
|
+
function releaseRipgrepExecutableWaiter(signal) {
|
|
160406
|
+
ripgrepExecutableWaiters = Math.max(0, ripgrepExecutableWaiters - 1);
|
|
160407
|
+
if (signal?.aborted && ripgrepExecutableWaiters === 0) {
|
|
160408
|
+
const controller = ripgrepInstallController;
|
|
160409
|
+
resetRipgrepExecutablePromise();
|
|
160410
|
+
controller?.abort(signal.reason);
|
|
160344
160411
|
}
|
|
160345
160412
|
}
|
|
160346
|
-
async function
|
|
160413
|
+
async function waitForRipgrepExecutableWithAbort(promise, signal) {
|
|
160347
160414
|
throwIfRipgrepAborted(signal);
|
|
160348
|
-
if (!signal) {
|
|
160349
|
-
return await resolveRipgrepExecutable();
|
|
160350
|
-
}
|
|
160351
160415
|
return await new Promise((resolve532, reject) => {
|
|
160352
160416
|
const onAbort = () => {
|
|
160353
160417
|
signal.removeEventListener("abort", onAbort);
|
|
160354
160418
|
reject(ripgrepAbortError());
|
|
160355
160419
|
};
|
|
160356
160420
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
160357
|
-
|
|
160421
|
+
promise.then(resolve532, reject).finally(() => {
|
|
160358
160422
|
signal.removeEventListener("abort", onAbort);
|
|
160359
160423
|
});
|
|
160360
160424
|
});
|
|
160361
160425
|
}
|
|
160426
|
+
async function resolveRipgrepExecutable(signal) {
|
|
160427
|
+
ripgrepExecutableWaiters += 1;
|
|
160428
|
+
try {
|
|
160429
|
+
const promise = getRipgrepExecutablePromise();
|
|
160430
|
+
const executable = signal ? await waitForRipgrepExecutableWithAbort(promise, signal) : await promise;
|
|
160431
|
+
if (!executable) {
|
|
160432
|
+
throw new Error("ripgrep is not available and could not be downloaded");
|
|
160433
|
+
}
|
|
160434
|
+
return executable;
|
|
160435
|
+
} finally {
|
|
160436
|
+
releaseRipgrepExecutableWaiter(signal);
|
|
160437
|
+
}
|
|
160438
|
+
}
|
|
160439
|
+
function throwIfRipgrepAborted(signal) {
|
|
160440
|
+
if (signal?.aborted) {
|
|
160441
|
+
throw ripgrepAbortError();
|
|
160442
|
+
}
|
|
160443
|
+
}
|
|
160444
|
+
async function resolveRipgrepExecutableWithAbort(signal) {
|
|
160445
|
+
throwIfRipgrepAborted(signal);
|
|
160446
|
+
if (!signal) {
|
|
160447
|
+
return await resolveRipgrepExecutable();
|
|
160448
|
+
}
|
|
160449
|
+
return await resolveRipgrepExecutable(signal);
|
|
160450
|
+
}
|
|
160362
160451
|
function shellQuoteArg(value) {
|
|
160363
160452
|
if (/^[A-Za-z0-9_/:=.,@%+-]+$/.test(value)) {
|
|
160364
160453
|
return value;
|
|
@@ -160368,6 +160457,9 @@ function shellQuoteArg(value) {
|
|
|
160368
160457
|
function formatRipgrepCommand(args) {
|
|
160369
160458
|
return ["rg", ...args].map(shellQuoteArg).join(" ");
|
|
160370
160459
|
}
|
|
160460
|
+
function isRipgrepPathError(message) {
|
|
160461
|
+
return /No such file or directory|IO error|os error 2|system cannot find the path/i.test(message);
|
|
160462
|
+
}
|
|
160371
160463
|
async function runRipgrep(args, signal, cwd) {
|
|
160372
160464
|
const executable = await resolveRipgrepExecutableWithAbort(signal);
|
|
160373
160465
|
throwIfRipgrepAborted(signal);
|
|
@@ -160438,6 +160530,8 @@ var pathSchema;
|
|
|
160438
160530
|
var globSchema;
|
|
160439
160531
|
var MAX_RIPGREP_OUTPUT_BYTES = 2e6;
|
|
160440
160532
|
var ripgrepExecutablePromise = null;
|
|
160533
|
+
var ripgrepInstallController = null;
|
|
160534
|
+
var ripgrepExecutableWaiters = 0;
|
|
160441
160535
|
var init_ripgrep_utils = __esm2(() => {
|
|
160442
160536
|
init_json();
|
|
160443
160537
|
init_tools_manager();
|
|
@@ -160695,6 +160789,18 @@ ${reason}`).detail({
|
|
|
160695
160789
|
for (const { pattern, result: result2 } of results) {
|
|
160696
160790
|
if (result2.exitCode === 2) {
|
|
160697
160791
|
const message = result2.stderr.trim() || result2.stdout.trim();
|
|
160792
|
+
if (isRipgrepPathError(message)) {
|
|
160793
|
+
return respond.error(`ripgrep failed
|
|
160794
|
+
|
|
160795
|
+
${message.length > 0 ? message : "ripgrep path lookup failed"}`).detail({
|
|
160796
|
+
commands,
|
|
160797
|
+
cwd: commandCwd,
|
|
160798
|
+
matchCount: 0,
|
|
160799
|
+
rangeCount: 0,
|
|
160800
|
+
ranges: [],
|
|
160801
|
+
truncated: false
|
|
160802
|
+
});
|
|
160803
|
+
}
|
|
160698
160804
|
throw new Error(message.length > 0 ? message : "ripgrep exited with an error");
|
|
160699
160805
|
}
|
|
160700
160806
|
if (result2.exitCode === 1 || result2.stdout.trim().length === 0) {
|
|
@@ -160972,6 +161078,11 @@ ${reason}`).detail({ command, cwd: commandCwd });
|
|
|
160972
161078
|
}
|
|
160973
161079
|
if (result2.exitCode === 2) {
|
|
160974
161080
|
const message = result2.stderr.trim() || result2.stdout.trim();
|
|
161081
|
+
if (isRipgrepPathError(message)) {
|
|
161082
|
+
return respond.error(`ripgrep failed
|
|
161083
|
+
|
|
161084
|
+
${message.length > 0 ? message : "ripgrep path lookup failed"}`).detail({ command, cwd: commandCwd });
|
|
161085
|
+
}
|
|
160975
161086
|
throw new Error(message.length > 0 ? message : "ripgrep exited with an error");
|
|
160976
161087
|
}
|
|
160977
161088
|
if (result2.exitCode === 1 || result2.stdout.trim().length === 0) {
|
package/dist/tools/find.js
CHANGED
|
@@ -308,7 +308,7 @@ export const findTool = createTool({
|
|
|
308
308
|
throw new Error("Operation aborted");
|
|
309
309
|
}
|
|
310
310
|
const { pattern, path: searchDir, limit, includeHidden = true } = params;
|
|
311
|
-
const fdPath = await ensureTool("fd", true);
|
|
311
|
+
const fdPath = await ensureTool("fd", true, signal);
|
|
312
312
|
if (!fdPath) {
|
|
313
313
|
return respond
|
|
314
314
|
.error("fd is not available and could not be downloaded")
|
package/dist/tools/find.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Find Tool - Fast File Discovery with fd\n *\n * This module provides a file search tool that uses `fd` (a fast alternative\n * to `find`) for discovering files by glob pattern. It respects .gitignore\n * files and falls back to glob when fd returns no results.\n *\n * ## Features\n *\n * - **Fast search**: Uses fd for performance on large codebases\n * - **Glob patterns**: Standard glob syntax (*.ts, **\\/*.json, etc.)\n * - **Git-aware**: Automatically respects .gitignore files\n * - **Hidden files**: Optional inclusion of dotfiles\n * - **Path handling**: Supports nested patterns with path separators\n * - **Auto-download**: Automatically downloads fd if not available\n *\n * ## Pattern Examples\n *\n * | Pattern | Matches |\n * |-------------------|----------------------------------|\n * | `*.ts` | TypeScript files in current dir |\n * | `**\\/*.spec.ts` | Test files anywhere |\n * | `src/**\\/*.json` | JSON files under src/ |\n *\n * ## Fallback Behavior\n *\n * If fd returns no results (which can happen with certain patterns on\n * some platforms), the tool falls back to Node.js glob matching to\n * ensure results are returned.\n *\n * ## Limits\n *\n * - Default limit: 1000 results\n * - Maximum buffer: 10MB\n * - Truncation indicator when limit is reached\n *\n * ## Example\n *\n * ```typescript\n * // Find all TypeScript test files\n * findTool.execute('call-id', {\n * pattern: '**\\/*.spec.ts',\n * path: 'src',\n * limit: 100,\n * });\n * ```\n *\n * @module tools/find\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport {\n\tdirname,\n\tisAbsolute,\n\trelative,\n\tresolve as resolvePath,\n\tsep,\n} from \"node:path\";\nimport { Type } from \"@sinclair/typebox\";\nimport { globSync } from \"glob\";\nimport { minimatch } from \"minimatch\";\nimport { getGitRoot } from \"../utils/git.js\";\nimport { expandTildePath } from \"../utils/path-expansion.js\";\nimport { createTool } from \"./tool-dsl.js\";\nimport { ensureTool } from \"./tools-manager.js\";\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription:\n\t\t\t\"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Directory to search in (default: current directory)\",\n\t\t}),\n\t),\n\tlimit: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: \"Maximum number of results (default: 1000)\",\n\t\t}),\n\t),\n\tincludeHidden: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription: \"Include hidden files (default: true)\",\n\t\t}),\n\t),\n});\n\nconst DEFAULT_LIMIT = 1000;\nconst FD_IGNORE_FILE_NAMES = [\".gitignore\", \".ignore\", \".fdignore\"] as const;\n\ntype FindToolDetails = {\n\tcommand: string;\n\tcwd: string;\n\tfileCount: number;\n\ttruncated: boolean;\n};\n\n/** @internal */\nexport type GitignoreRule = {\n\tpattern: string;\n\tnegated: boolean;\n\tdirectoryOnly: boolean;\n\tmatchPrefix?: string;\n};\n\nfunction collectGitignoreFiles(searchPath: string): string[] {\n\tconst gitignoreFiles = new Set<string>();\n\tconst ancestorDirs: string[] = [];\n\tlet currentDir = searchPath;\n\twhile (true) {\n\t\tancestorDirs.push(currentDir);\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\tbreak;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n\n\tfor (const dir of ancestorDirs.reverse()) {\n\t\tfor (const fileName of FD_IGNORE_FILE_NAMES) {\n\t\t\tconst ignoreFile = resolvePath(dir, fileName);\n\t\t\tif (existsSync(ignoreFile)) {\n\t\t\t\tgitignoreFiles.add(ignoreFile);\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tfor (const fileName of FD_IGNORE_FILE_NAMES) {\n\t\t\tconst nestedGitignores = globSync(`**/${fileName}`, {\n\t\t\t\tcwd: searchPath,\n\t\t\t\tdot: true,\n\t\t\t\tabsolute: true,\n\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t});\n\t\t\tfor (const file of nestedGitignores) {\n\t\t\t\tgitignoreFiles.add(file);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore glob errors\n\t}\n\n\treturn [...gitignoreFiles];\n}\n\nfunction toGlobPath(path: string): string {\n\treturn path.split(sep).join(\"/\");\n}\n\nfunction relativePathStaysInside(path: string): boolean {\n\treturn (\n\t\tpath === \"\" ||\n\t\t(path !== \"..\" && !path.startsWith(`..${sep}`) && !isAbsolute(path))\n\t);\n}\n\nfunction scopeGitignorePattern(\n\tsearchPath: string,\n\tignoreDir: string,\n\tpattern: string,\n\tanchored: boolean,\n): { matchPrefix?: string; pattern: string } | undefined {\n\tconst ignoreDirFromSearch = relative(searchPath, ignoreDir);\n\tif (relativePathStaysInside(ignoreDirFromSearch)) {\n\t\tconst relativeDir = toGlobPath(ignoreDirFromSearch);\n\t\tconst prefix = relativeDir && relativeDir !== \".\" ? `${relativeDir}/` : \"\";\n\t\treturn { pattern: `${prefix}${pattern}` };\n\t}\n\n\tconst searchPathFromIgnoreDir = relative(ignoreDir, searchPath);\n\tif (!relativePathStaysInside(searchPathFromIgnoreDir)) {\n\t\treturn undefined;\n\t}\n\n\tif (!anchored && !pattern.includes(\"/\")) {\n\t\treturn { pattern: `**/${pattern}` };\n\t}\n\tif (!anchored && pattern.startsWith(\"**/\")) {\n\t\treturn { pattern };\n\t}\n\n\tconst searchPrefix = toGlobPath(searchPathFromIgnoreDir);\n\tif (!searchPrefix || searchPrefix === \".\") {\n\t\treturn { pattern };\n\t}\n\tconst prefix = `${searchPrefix}/`;\n\treturn pattern.startsWith(prefix)\n\t\t? { pattern: pattern.slice(prefix.length) }\n\t\t: { matchPrefix: searchPrefix, pattern };\n}\n\nfunction stripUnescapedTrailingWhitespace(line: string): string {\n\tlet end = line.length;\n\twhile (end > 0 && /\\s/.test(line[end - 1] ?? \"\")) {\n\t\tlet slashCount = 0;\n\t\tfor (let index = end - 2; index >= 0 && line[index] === \"\\\\\"; index -= 1) {\n\t\t\tslashCount += 1;\n\t\t}\n\t\tif (slashCount % 2 === 1) {\n\t\t\tbreak;\n\t\t}\n\t\tend -= 1;\n\t}\n\treturn line.slice(0, end);\n}\n\nfunction unescapeGitignorePattern(pattern: string): string {\n\treturn pattern.replace(/\\\\([#!\\t ])/g, \"$1\");\n}\n\nfunction collectGitignoreRules(\n\tsearchPath: string,\n\tgitignoreFiles: string[],\n): GitignoreRule[] {\n\tconst rules: GitignoreRule[] = [];\n\n\tfor (const gitignorePath of gitignoreFiles) {\n\t\tconst ignoreDir = dirname(gitignorePath);\n\n\t\tlet contents: string;\n\t\ttry {\n\t\t\tcontents = readFileSync(gitignorePath, \"utf8\");\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const rawLine of contents.split(/\\r?\\n/)) {\n\t\t\tlet line = stripUnescapedTrailingWhitespace(rawLine);\n\t\t\tif (!line || line.startsWith(\"#\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst negated = line.startsWith(\"!\");\n\t\t\tif (negated) {\n\t\t\t\tline = line.slice(1);\n\t\t\t\tif (!line) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst anchored = line.startsWith(\"/\");\n\t\t\tconst directoryOnly = line.endsWith(\"/\");\n\t\t\tlet pattern = unescapeGitignorePattern(\n\t\t\t\tline.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\"),\n\t\t\t);\n\t\t\tif (!pattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!anchored && !pattern.includes(\"/\")) {\n\t\t\t\tpattern = `**/${pattern}`;\n\t\t\t}\n\n\t\t\tconst scopedPattern = scopeGitignorePattern(\n\t\t\t\tsearchPath,\n\t\t\t\tignoreDir,\n\t\t\t\tpattern,\n\t\t\t\tanchored,\n\t\t\t);\n\t\t\tif (!scopedPattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trules.push({\n\t\t\t\tpattern: scopedPattern.pattern,\n\t\t\t\tmatchPrefix: scopedPattern.matchPrefix,\n\t\t\t\tnegated,\n\t\t\t\tdirectoryOnly,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn rules;\n}\n\nfunction pathIsDirectory(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction pathAncestors(path: string): string[] {\n\tconst parts = path.split(\"/\").filter(Boolean);\n\tconst ancestors: string[] = [];\n\tfor (let index = 1; index < parts.length; index += 1) {\n\t\tancestors.push(parts.slice(0, index).join(\"/\"));\n\t}\n\treturn ancestors;\n}\n\nfunction gitignoreRuleMatchPath(path: string, rule: GitignoreRule): string {\n\treturn rule.matchPrefix\n\t\t? path === \".\"\n\t\t\t? rule.matchPrefix\n\t\t\t: `${rule.matchPrefix}/${path}`\n\t\t: path;\n}\n\nfunction matchesGitignoreSubject(\n\tpath: string,\n\trule: GitignoreRule,\n\tisDirectory: boolean,\n): boolean {\n\tconst matchPath = gitignoreRuleMatchPath(path, rule);\n\tconst options = { dot: true, nonegate: true };\n\tif (rule.directoryOnly) {\n\t\treturn isDirectory && minimatch(matchPath, rule.pattern, options);\n\t}\n\treturn minimatch(matchPath, rule.pattern, options);\n}\n\nfunction evaluateGitignoreSubject(\n\tpath: string,\n\trules: GitignoreRule[],\n\tisDirectory: boolean,\n): boolean {\n\tlet ignored = false;\n\tfor (const rule of rules) {\n\t\tif (matchesGitignoreSubject(path, rule, isDirectory)) {\n\t\t\tignored = !rule.negated;\n\t\t}\n\t}\n\treturn ignored;\n}\n\n/** @internal */\nexport function isIgnoredByGitignoreRules(\n\trelativePath: string,\n\trules: GitignoreRule[],\n\tisDirectory = false,\n): boolean {\n\tconst normalizedPath = toGlobPath(relativePath);\n\tfor (const ancestor of pathAncestors(normalizedPath)) {\n\t\tif (evaluateGitignoreSubject(ancestor, rules, true)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn evaluateGitignoreSubject(normalizedPath, rules, isDirectory);\n}\n\nfunction constrainGlobMatches(\n\tmatches: string[],\n\tsearchPath: string,\n\trules: GitignoreRule[],\n): string[] {\n\tconst searchRoot = searchPath.endsWith(sep)\n\t\t? searchPath\n\t\t: `${searchPath}${sep}`;\n\tconst constrained: string[] = [];\n\tfor (const match of matches) {\n\t\tconst resolved = resolvePath(match);\n\t\tif (resolved !== searchPath && !resolved.startsWith(searchRoot)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst relativeMatch = relative(searchPath, resolved) || \".\";\n\t\tif (\n\t\t\tisIgnoredByGitignoreRules(relativeMatch, rules, pathIsDirectory(resolved))\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tconstrained.push(resolved);\n\t}\n\treturn constrained;\n}\n\n/** @internal */\nexport function getFindGlobPatterns(pattern: string): string[] {\n\tconst patterns = [pattern];\n\tconst rootEquivalent = pattern.match(/^\\*\\*[\\\\/](.+)$/u)?.[1];\n\tif (rootEquivalent && rootEquivalent !== pattern) {\n\t\tpatterns.push(rootEquivalent);\n\t}\n\treturn patterns;\n}\n\nfunction findGlobMatches(\n\tpattern: string,\n\tsearchPath: string,\n\tincludeHidden: boolean,\n): string[] {\n\tconst matches = new Set<string>();\n\tfor (const globPattern of getFindGlobPatterns(pattern)) {\n\t\tfor (const match of globSync(globPattern, {\n\t\t\tcwd: searchPath,\n\t\t\tdot: includeHidden,\n\t\t\tnodir: false,\n\t\t\tabsolute: true,\n\t\t})) {\n\t\t\tmatches.add(resolvePath(match));\n\t\t}\n\t}\n\treturn [...matches];\n}\n\nexport const findTool = createTool<typeof findSchema, FindToolDetails>({\n\tname: \"find\",\n\tlabel: \"find\",\n\tdescription:\n\t\t\"Search for files by glob pattern using fd. Returns matching file paths relative to the search directory. Respects .gitignore. Use this for fast file discovery across large codebases.\",\n\tschema: findSchema,\n\tasync run(params, { signal, respond }) {\n\t\tif (signal?.aborted) {\n\t\t\tthrow new Error(\"Operation aborted\");\n\t\t}\n\n\t\tconst { pattern, path: searchDir, limit, includeHidden = true } = params;\n\n\t\tconst fdPath = await ensureTool(\"fd\", true);\n\t\tif (!fdPath) {\n\t\t\treturn respond\n\t\t\t\t.error(\"fd is not available and could not be downloaded\")\n\t\t\t\t.detail({\n\t\t\t\t\tcommand: \"fd\",\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tfileCount: 0,\n\t\t\t\t\ttruncated: false,\n\t\t\t\t});\n\t\t}\n\n\t\tconst searchPath = resolvePath(expandTildePath(searchDir || \".\"));\n\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\n\t\tconst args: string[] = [\n\t\t\t\"--glob\",\n\t\t\t\"--color=never\",\n\t\t\t\"--max-results\",\n\t\t\tString(effectiveLimit),\n\t\t];\n\n\t\t// If pattern includes path separators, match against the full path so nested globs work.\n\t\tif (pattern.includes(\"/\") || pattern.includes(\"\\\\\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t}\n\n\t\tif (includeHidden) {\n\t\t\targs.push(\"--hidden\");\n\t\t}\n\n\t\tconst gitRoot = getGitRoot(searchPath);\n\t\tconst gitignoreFiles = gitRoot ? [] : collectGitignoreFiles(searchPath);\n\t\tconst gitignoreRules = collectGitignoreRules(searchPath, gitignoreFiles);\n\t\tif (gitRoot) {\n\t\t\t// Force fd to honor repo-native ignore rules even if user config disables\n\t\t\t// VCS ignores, while keeping anchored patterns scoped to the repo root.\n\t\t\targs.push(\"--ignore-vcs\");\n\t\t} else {\n\t\t\t// Let fd discover .gitignore files in their native directories instead of\n\t\t\t// re-scoping them as current-directory --ignore-file inputs.\n\t\t\targs.push(\"--no-require-git\");\n\t\t}\n\n\t\targs.push(pattern);\n\n\t\tconst command = [fdPath, ...args].join(\" \");\n\n\t\tconst result = spawnSync(fdPath, args, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tmaxBuffer: 10 * 1024 * 1024,\n\t\t\tcwd: searchPath,\n\t\t});\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new Error(\"Operation aborted\");\n\t\t}\n\n\t\tif (result.error) {\n\t\t\treturn respond\n\t\t\t\t.error(`Failed to run fd: ${result.error.message}`)\n\t\t\t\t.detail({ command, cwd: searchPath, fileCount: 0, truncated: false });\n\t\t}\n\n\t\tlet output = result.stdout ?? \"\";\n\n\t\tif (result.status !== 0 && !output) {\n\t\t\tconst errorMsg =\n\t\t\t\tresult.stderr?.trim() || `fd exited with code ${result.status}`;\n\t\t\treturn respond\n\t\t\t\t.error(errorMsg)\n\t\t\t\t.detail({ command, cwd: searchPath, fileCount: 0, truncated: false });\n\t\t}\n\n\t\tif (!output) {\n\t\t\t// Fallback to globbing when fd returns nothing (handles patterns with subdirectories on some platforms)\n\t\t\tconst globMatches = findGlobMatches(pattern, searchPath, includeHidden);\n\t\t\tconst constrained = constrainGlobMatches(\n\t\t\t\tglobMatches,\n\t\t\t\tsearchPath,\n\t\t\t\tgitignoreRules,\n\t\t\t);\n\n\t\t\tif (constrained.length > 0) {\n\t\t\t\tconst limited = constrained.slice(0, effectiveLimit);\n\t\t\t\tconst truncated = constrained.length > effectiveLimit;\n\t\t\t\tconst text = limited\n\t\t\t\t\t.map((abs) => relative(searchPath, abs) || \".\")\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\treturn respond\n\t\t\t\t\t.text(\n\t\t\t\t\t\ttruncated\n\t\t\t\t\t\t\t? `${text}\\n\\n(truncated, ${effectiveLimit} results shown)`\n\t\t\t\t\t\t\t: text,\n\t\t\t\t\t)\n\t\t\t\t\t.detail({\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\tfileCount: constrained.length,\n\t\t\t\t\t\ttruncated,\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn respond\n\t\t\t\t.text(\"No files found matching pattern\")\n\t\t\t\t.detail({ command, cwd: searchPath, fileCount: 0, truncated: false });\n\t\t}\n\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst relativized: string[] = [];\n\n\t\tfor (const rawLine of lines) {\n\t\t\tconst line = rawLine.replace(/\\r$/, \"\");\n\t\t\tif (!line) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet relativePath = line;\n\t\t\tif (line.endsWith(\"\\\\\")) {\n\t\t\t\t// Normalize Windows-style trailing backslash to a single forward slash\n\t\t\t\trelativePath = `${line.slice(0, -1)}/`;\n\t\t\t}\n\n\t\t\tif (relativePath) {\n\t\t\t\tif (\n\t\t\t\t\t!gitRoot &&\n\t\t\t\t\tisIgnoredByGitignoreRules(\n\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\tgitignoreRules,\n\t\t\t\t\t\tpathIsDirectory(resolvePath(searchPath, relativePath)),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\trelativized.push(relativePath);\n\t\t\t}\n\t\t}\n\n\t\tif (!gitRoot && pattern.includes(\"**/\")) {\n\t\t\tconst searchRoot = searchPath.endsWith(sep)\n\t\t\t\t? searchPath\n\t\t\t\t: `${searchPath}${sep}`;\n\t\t\tconst seen = new Set(relativized);\n\t\t\tfor (const match of findGlobMatches(pattern, searchPath, includeHidden)) {\n\t\t\t\tconst resolved = resolvePath(match);\n\t\t\t\tif (resolved !== searchPath && !resolved.startsWith(searchRoot)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst relativeMatch = relative(searchPath, resolved) || \".\";\n\t\t\t\tif (\n\t\t\t\t\tisIgnoredByGitignoreRules(\n\t\t\t\t\t\trelativeMatch,\n\t\t\t\t\t\tgitignoreRules,\n\t\t\t\t\t\tpathIsDirectory(resolved),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!seen.has(relativeMatch)) {\n\t\t\t\t\tseen.add(relativeMatch);\n\t\t\t\t\trelativized.push(relativeMatch);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trelativized.sort();\n\t\toutput = relativized.slice(0, effectiveLimit).join(\"\\n\");\n\t\tconst count = relativized.length;\n\t\tconst truncated = count >= effectiveLimit;\n\t\tif (truncated) {\n\t\t\toutput += `\\n\\n(truncated, ${effectiveLimit} results shown)`;\n\t\t}\n\n\t\treturn respond\n\t\t\t.text(output)\n\t\t\t.detail({ command, cwd: searchPath, fileCount: count, truncated });\n\t},\n});\n"]}
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Find Tool - Fast File Discovery with fd\n *\n * This module provides a file search tool that uses `fd` (a fast alternative\n * to `find`) for discovering files by glob pattern. It respects .gitignore\n * files and falls back to glob when fd returns no results.\n *\n * ## Features\n *\n * - **Fast search**: Uses fd for performance on large codebases\n * - **Glob patterns**: Standard glob syntax (*.ts, **\\/*.json, etc.)\n * - **Git-aware**: Automatically respects .gitignore files\n * - **Hidden files**: Optional inclusion of dotfiles\n * - **Path handling**: Supports nested patterns with path separators\n * - **Auto-download**: Automatically downloads fd if not available\n *\n * ## Pattern Examples\n *\n * | Pattern | Matches |\n * |-------------------|----------------------------------|\n * | `*.ts` | TypeScript files in current dir |\n * | `**\\/*.spec.ts` | Test files anywhere |\n * | `src/**\\/*.json` | JSON files under src/ |\n *\n * ## Fallback Behavior\n *\n * If fd returns no results (which can happen with certain patterns on\n * some platforms), the tool falls back to Node.js glob matching to\n * ensure results are returned.\n *\n * ## Limits\n *\n * - Default limit: 1000 results\n * - Maximum buffer: 10MB\n * - Truncation indicator when limit is reached\n *\n * ## Example\n *\n * ```typescript\n * // Find all TypeScript test files\n * findTool.execute('call-id', {\n * pattern: '**\\/*.spec.ts',\n * path: 'src',\n * limit: 100,\n * });\n * ```\n *\n * @module tools/find\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport {\n\tdirname,\n\tisAbsolute,\n\trelative,\n\tresolve as resolvePath,\n\tsep,\n} from \"node:path\";\nimport { Type } from \"@sinclair/typebox\";\nimport { globSync } from \"glob\";\nimport { minimatch } from \"minimatch\";\nimport { getGitRoot } from \"../utils/git.js\";\nimport { expandTildePath } from \"../utils/path-expansion.js\";\nimport { createTool } from \"./tool-dsl.js\";\nimport { ensureTool } from \"./tools-manager.js\";\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription:\n\t\t\t\"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Directory to search in (default: current directory)\",\n\t\t}),\n\t),\n\tlimit: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: \"Maximum number of results (default: 1000)\",\n\t\t}),\n\t),\n\tincludeHidden: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription: \"Include hidden files (default: true)\",\n\t\t}),\n\t),\n});\n\nconst DEFAULT_LIMIT = 1000;\nconst FD_IGNORE_FILE_NAMES = [\".gitignore\", \".ignore\", \".fdignore\"] as const;\n\ntype FindToolDetails = {\n\tcommand: string;\n\tcwd: string;\n\tfileCount: number;\n\ttruncated: boolean;\n};\n\n/** @internal */\nexport type GitignoreRule = {\n\tpattern: string;\n\tnegated: boolean;\n\tdirectoryOnly: boolean;\n\tmatchPrefix?: string;\n};\n\nfunction collectGitignoreFiles(searchPath: string): string[] {\n\tconst gitignoreFiles = new Set<string>();\n\tconst ancestorDirs: string[] = [];\n\tlet currentDir = searchPath;\n\twhile (true) {\n\t\tancestorDirs.push(currentDir);\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\tbreak;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n\n\tfor (const dir of ancestorDirs.reverse()) {\n\t\tfor (const fileName of FD_IGNORE_FILE_NAMES) {\n\t\t\tconst ignoreFile = resolvePath(dir, fileName);\n\t\t\tif (existsSync(ignoreFile)) {\n\t\t\t\tgitignoreFiles.add(ignoreFile);\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tfor (const fileName of FD_IGNORE_FILE_NAMES) {\n\t\t\tconst nestedGitignores = globSync(`**/${fileName}`, {\n\t\t\t\tcwd: searchPath,\n\t\t\t\tdot: true,\n\t\t\t\tabsolute: true,\n\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t});\n\t\t\tfor (const file of nestedGitignores) {\n\t\t\t\tgitignoreFiles.add(file);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore glob errors\n\t}\n\n\treturn [...gitignoreFiles];\n}\n\nfunction toGlobPath(path: string): string {\n\treturn path.split(sep).join(\"/\");\n}\n\nfunction relativePathStaysInside(path: string): boolean {\n\treturn (\n\t\tpath === \"\" ||\n\t\t(path !== \"..\" && !path.startsWith(`..${sep}`) && !isAbsolute(path))\n\t);\n}\n\nfunction scopeGitignorePattern(\n\tsearchPath: string,\n\tignoreDir: string,\n\tpattern: string,\n\tanchored: boolean,\n): { matchPrefix?: string; pattern: string } | undefined {\n\tconst ignoreDirFromSearch = relative(searchPath, ignoreDir);\n\tif (relativePathStaysInside(ignoreDirFromSearch)) {\n\t\tconst relativeDir = toGlobPath(ignoreDirFromSearch);\n\t\tconst prefix = relativeDir && relativeDir !== \".\" ? `${relativeDir}/` : \"\";\n\t\treturn { pattern: `${prefix}${pattern}` };\n\t}\n\n\tconst searchPathFromIgnoreDir = relative(ignoreDir, searchPath);\n\tif (!relativePathStaysInside(searchPathFromIgnoreDir)) {\n\t\treturn undefined;\n\t}\n\n\tif (!anchored && !pattern.includes(\"/\")) {\n\t\treturn { pattern: `**/${pattern}` };\n\t}\n\tif (!anchored && pattern.startsWith(\"**/\")) {\n\t\treturn { pattern };\n\t}\n\n\tconst searchPrefix = toGlobPath(searchPathFromIgnoreDir);\n\tif (!searchPrefix || searchPrefix === \".\") {\n\t\treturn { pattern };\n\t}\n\tconst prefix = `${searchPrefix}/`;\n\treturn pattern.startsWith(prefix)\n\t\t? { pattern: pattern.slice(prefix.length) }\n\t\t: { matchPrefix: searchPrefix, pattern };\n}\n\nfunction stripUnescapedTrailingWhitespace(line: string): string {\n\tlet end = line.length;\n\twhile (end > 0 && /\\s/.test(line[end - 1] ?? \"\")) {\n\t\tlet slashCount = 0;\n\t\tfor (let index = end - 2; index >= 0 && line[index] === \"\\\\\"; index -= 1) {\n\t\t\tslashCount += 1;\n\t\t}\n\t\tif (slashCount % 2 === 1) {\n\t\t\tbreak;\n\t\t}\n\t\tend -= 1;\n\t}\n\treturn line.slice(0, end);\n}\n\nfunction unescapeGitignorePattern(pattern: string): string {\n\treturn pattern.replace(/\\\\([#!\\t ])/g, \"$1\");\n}\n\nfunction collectGitignoreRules(\n\tsearchPath: string,\n\tgitignoreFiles: string[],\n): GitignoreRule[] {\n\tconst rules: GitignoreRule[] = [];\n\n\tfor (const gitignorePath of gitignoreFiles) {\n\t\tconst ignoreDir = dirname(gitignorePath);\n\n\t\tlet contents: string;\n\t\ttry {\n\t\t\tcontents = readFileSync(gitignorePath, \"utf8\");\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const rawLine of contents.split(/\\r?\\n/)) {\n\t\t\tlet line = stripUnescapedTrailingWhitespace(rawLine);\n\t\t\tif (!line || line.startsWith(\"#\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst negated = line.startsWith(\"!\");\n\t\t\tif (negated) {\n\t\t\t\tline = line.slice(1);\n\t\t\t\tif (!line) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst anchored = line.startsWith(\"/\");\n\t\t\tconst directoryOnly = line.endsWith(\"/\");\n\t\t\tlet pattern = unescapeGitignorePattern(\n\t\t\t\tline.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\"),\n\t\t\t);\n\t\t\tif (!pattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!anchored && !pattern.includes(\"/\")) {\n\t\t\t\tpattern = `**/${pattern}`;\n\t\t\t}\n\n\t\t\tconst scopedPattern = scopeGitignorePattern(\n\t\t\t\tsearchPath,\n\t\t\t\tignoreDir,\n\t\t\t\tpattern,\n\t\t\t\tanchored,\n\t\t\t);\n\t\t\tif (!scopedPattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trules.push({\n\t\t\t\tpattern: scopedPattern.pattern,\n\t\t\t\tmatchPrefix: scopedPattern.matchPrefix,\n\t\t\t\tnegated,\n\t\t\t\tdirectoryOnly,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn rules;\n}\n\nfunction pathIsDirectory(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction pathAncestors(path: string): string[] {\n\tconst parts = path.split(\"/\").filter(Boolean);\n\tconst ancestors: string[] = [];\n\tfor (let index = 1; index < parts.length; index += 1) {\n\t\tancestors.push(parts.slice(0, index).join(\"/\"));\n\t}\n\treturn ancestors;\n}\n\nfunction gitignoreRuleMatchPath(path: string, rule: GitignoreRule): string {\n\treturn rule.matchPrefix\n\t\t? path === \".\"\n\t\t\t? rule.matchPrefix\n\t\t\t: `${rule.matchPrefix}/${path}`\n\t\t: path;\n}\n\nfunction matchesGitignoreSubject(\n\tpath: string,\n\trule: GitignoreRule,\n\tisDirectory: boolean,\n): boolean {\n\tconst matchPath = gitignoreRuleMatchPath(path, rule);\n\tconst options = { dot: true, nonegate: true };\n\tif (rule.directoryOnly) {\n\t\treturn isDirectory && minimatch(matchPath, rule.pattern, options);\n\t}\n\treturn minimatch(matchPath, rule.pattern, options);\n}\n\nfunction evaluateGitignoreSubject(\n\tpath: string,\n\trules: GitignoreRule[],\n\tisDirectory: boolean,\n): boolean {\n\tlet ignored = false;\n\tfor (const rule of rules) {\n\t\tif (matchesGitignoreSubject(path, rule, isDirectory)) {\n\t\t\tignored = !rule.negated;\n\t\t}\n\t}\n\treturn ignored;\n}\n\n/** @internal */\nexport function isIgnoredByGitignoreRules(\n\trelativePath: string,\n\trules: GitignoreRule[],\n\tisDirectory = false,\n): boolean {\n\tconst normalizedPath = toGlobPath(relativePath);\n\tfor (const ancestor of pathAncestors(normalizedPath)) {\n\t\tif (evaluateGitignoreSubject(ancestor, rules, true)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn evaluateGitignoreSubject(normalizedPath, rules, isDirectory);\n}\n\nfunction constrainGlobMatches(\n\tmatches: string[],\n\tsearchPath: string,\n\trules: GitignoreRule[],\n): string[] {\n\tconst searchRoot = searchPath.endsWith(sep)\n\t\t? searchPath\n\t\t: `${searchPath}${sep}`;\n\tconst constrained: string[] = [];\n\tfor (const match of matches) {\n\t\tconst resolved = resolvePath(match);\n\t\tif (resolved !== searchPath && !resolved.startsWith(searchRoot)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst relativeMatch = relative(searchPath, resolved) || \".\";\n\t\tif (\n\t\t\tisIgnoredByGitignoreRules(relativeMatch, rules, pathIsDirectory(resolved))\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tconstrained.push(resolved);\n\t}\n\treturn constrained;\n}\n\n/** @internal */\nexport function getFindGlobPatterns(pattern: string): string[] {\n\tconst patterns = [pattern];\n\tconst rootEquivalent = pattern.match(/^\\*\\*[\\\\/](.+)$/u)?.[1];\n\tif (rootEquivalent && rootEquivalent !== pattern) {\n\t\tpatterns.push(rootEquivalent);\n\t}\n\treturn patterns;\n}\n\nfunction findGlobMatches(\n\tpattern: string,\n\tsearchPath: string,\n\tincludeHidden: boolean,\n): string[] {\n\tconst matches = new Set<string>();\n\tfor (const globPattern of getFindGlobPatterns(pattern)) {\n\t\tfor (const match of globSync(globPattern, {\n\t\t\tcwd: searchPath,\n\t\t\tdot: includeHidden,\n\t\t\tnodir: false,\n\t\t\tabsolute: true,\n\t\t})) {\n\t\t\tmatches.add(resolvePath(match));\n\t\t}\n\t}\n\treturn [...matches];\n}\n\nexport const findTool = createTool<typeof findSchema, FindToolDetails>({\n\tname: \"find\",\n\tlabel: \"find\",\n\tdescription:\n\t\t\"Search for files by glob pattern using fd. Returns matching file paths relative to the search directory. Respects .gitignore. Use this for fast file discovery across large codebases.\",\n\tschema: findSchema,\n\tasync run(params, { signal, respond }) {\n\t\tif (signal?.aborted) {\n\t\t\tthrow new Error(\"Operation aborted\");\n\t\t}\n\n\t\tconst { pattern, path: searchDir, limit, includeHidden = true } = params;\n\n\t\tconst fdPath = await ensureTool(\"fd\", true, signal);\n\t\tif (!fdPath) {\n\t\t\treturn respond\n\t\t\t\t.error(\"fd is not available and could not be downloaded\")\n\t\t\t\t.detail({\n\t\t\t\t\tcommand: \"fd\",\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tfileCount: 0,\n\t\t\t\t\ttruncated: false,\n\t\t\t\t});\n\t\t}\n\n\t\tconst searchPath = resolvePath(expandTildePath(searchDir || \".\"));\n\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\n\t\tconst args: string[] = [\n\t\t\t\"--glob\",\n\t\t\t\"--color=never\",\n\t\t\t\"--max-results\",\n\t\t\tString(effectiveLimit),\n\t\t];\n\n\t\t// If pattern includes path separators, match against the full path so nested globs work.\n\t\tif (pattern.includes(\"/\") || pattern.includes(\"\\\\\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t}\n\n\t\tif (includeHidden) {\n\t\t\targs.push(\"--hidden\");\n\t\t}\n\n\t\tconst gitRoot = getGitRoot(searchPath);\n\t\tconst gitignoreFiles = gitRoot ? [] : collectGitignoreFiles(searchPath);\n\t\tconst gitignoreRules = collectGitignoreRules(searchPath, gitignoreFiles);\n\t\tif (gitRoot) {\n\t\t\t// Force fd to honor repo-native ignore rules even if user config disables\n\t\t\t// VCS ignores, while keeping anchored patterns scoped to the repo root.\n\t\t\targs.push(\"--ignore-vcs\");\n\t\t} else {\n\t\t\t// Let fd discover .gitignore files in their native directories instead of\n\t\t\t// re-scoping them as current-directory --ignore-file inputs.\n\t\t\targs.push(\"--no-require-git\");\n\t\t}\n\n\t\targs.push(pattern);\n\n\t\tconst command = [fdPath, ...args].join(\" \");\n\n\t\tconst result = spawnSync(fdPath, args, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tmaxBuffer: 10 * 1024 * 1024,\n\t\t\tcwd: searchPath,\n\t\t});\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new Error(\"Operation aborted\");\n\t\t}\n\n\t\tif (result.error) {\n\t\t\treturn respond\n\t\t\t\t.error(`Failed to run fd: ${result.error.message}`)\n\t\t\t\t.detail({ command, cwd: searchPath, fileCount: 0, truncated: false });\n\t\t}\n\n\t\tlet output = result.stdout ?? \"\";\n\n\t\tif (result.status !== 0 && !output) {\n\t\t\tconst errorMsg =\n\t\t\t\tresult.stderr?.trim() || `fd exited with code ${result.status}`;\n\t\t\treturn respond\n\t\t\t\t.error(errorMsg)\n\t\t\t\t.detail({ command, cwd: searchPath, fileCount: 0, truncated: false });\n\t\t}\n\n\t\tif (!output) {\n\t\t\t// Fallback to globbing when fd returns nothing (handles patterns with subdirectories on some platforms)\n\t\t\tconst globMatches = findGlobMatches(pattern, searchPath, includeHidden);\n\t\t\tconst constrained = constrainGlobMatches(\n\t\t\t\tglobMatches,\n\t\t\t\tsearchPath,\n\t\t\t\tgitignoreRules,\n\t\t\t);\n\n\t\t\tif (constrained.length > 0) {\n\t\t\t\tconst limited = constrained.slice(0, effectiveLimit);\n\t\t\t\tconst truncated = constrained.length > effectiveLimit;\n\t\t\t\tconst text = limited\n\t\t\t\t\t.map((abs) => relative(searchPath, abs) || \".\")\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\treturn respond\n\t\t\t\t\t.text(\n\t\t\t\t\t\ttruncated\n\t\t\t\t\t\t\t? `${text}\\n\\n(truncated, ${effectiveLimit} results shown)`\n\t\t\t\t\t\t\t: text,\n\t\t\t\t\t)\n\t\t\t\t\t.detail({\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\tfileCount: constrained.length,\n\t\t\t\t\t\ttruncated,\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn respond\n\t\t\t\t.text(\"No files found matching pattern\")\n\t\t\t\t.detail({ command, cwd: searchPath, fileCount: 0, truncated: false });\n\t\t}\n\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst relativized: string[] = [];\n\n\t\tfor (const rawLine of lines) {\n\t\t\tconst line = rawLine.replace(/\\r$/, \"\");\n\t\t\tif (!line) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet relativePath = line;\n\t\t\tif (line.endsWith(\"\\\\\")) {\n\t\t\t\t// Normalize Windows-style trailing backslash to a single forward slash\n\t\t\t\trelativePath = `${line.slice(0, -1)}/`;\n\t\t\t}\n\n\t\t\tif (relativePath) {\n\t\t\t\tif (\n\t\t\t\t\t!gitRoot &&\n\t\t\t\t\tisIgnoredByGitignoreRules(\n\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\tgitignoreRules,\n\t\t\t\t\t\tpathIsDirectory(resolvePath(searchPath, relativePath)),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\trelativized.push(relativePath);\n\t\t\t}\n\t\t}\n\n\t\tif (!gitRoot && pattern.includes(\"**/\")) {\n\t\t\tconst searchRoot = searchPath.endsWith(sep)\n\t\t\t\t? searchPath\n\t\t\t\t: `${searchPath}${sep}`;\n\t\t\tconst seen = new Set(relativized);\n\t\t\tfor (const match of findGlobMatches(pattern, searchPath, includeHidden)) {\n\t\t\t\tconst resolved = resolvePath(match);\n\t\t\t\tif (resolved !== searchPath && !resolved.startsWith(searchRoot)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst relativeMatch = relative(searchPath, resolved) || \".\";\n\t\t\t\tif (\n\t\t\t\t\tisIgnoredByGitignoreRules(\n\t\t\t\t\t\trelativeMatch,\n\t\t\t\t\t\tgitignoreRules,\n\t\t\t\t\t\tpathIsDirectory(resolved),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!seen.has(relativeMatch)) {\n\t\t\t\t\tseen.add(relativeMatch);\n\t\t\t\t\trelativized.push(relativeMatch);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trelativized.sort();\n\t\toutput = relativized.slice(0, effectiveLimit).join(\"\\n\");\n\t\tconst count = relativized.length;\n\t\tconst truncated = count >= effectiveLimit;\n\t\tif (truncated) {\n\t\t\toutput += `\\n\\n(truncated, ${effectiveLimit} results shown)`;\n\t\t}\n\n\t\treturn respond\n\t\t\t.text(output)\n\t\t\t.detail({ command, cwd: searchPath, fileCount: count, truncated });\n\t},\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parallel-ripgrep.d.ts","sourceRoot":"","sources":["../../src/tools/parallel-ripgrep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"parallel-ripgrep.d.ts","sourceRoot":"","sources":["../../src/tools/parallel-ripgrep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA8GH;;;GAGG;AACH,KAAK,WAAW,GAAG;IAClB,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,KAAK,sBAAsB,GAAG;IAC7B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;CACnB,CAAC;AA+HF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0O9B,CAAC"}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
import { promises as fs } from "node:fs";
|
|
23
23
|
import { resolve as resolvePath } from "node:path";
|
|
24
24
|
import { Type } from "@sinclair/typebox";
|
|
25
|
-
import { formatRipgrepCommand, globSchema, parseRipgrepJson, pathSchema, runRipgrep, toArray, } from "./ripgrep-utils.js";
|
|
25
|
+
import { formatRipgrepCommand, globSchema, isRipgrepPathError, parseRipgrepJson, pathSchema, runRipgrep, toArray, } from "./ripgrep-utils.js";
|
|
26
26
|
import { createTool, expandUserPath } from "./tool-dsl.js";
|
|
27
27
|
/** Maximum number of line ranges to include in detailed output */
|
|
28
28
|
const RANGE_DETAIL_LIMIT = 200;
|
|
@@ -279,6 +279,18 @@ export const parallelRipgrepTool = createTool({
|
|
|
279
279
|
for (const { pattern, result } of results) {
|
|
280
280
|
if (result.exitCode === 2) {
|
|
281
281
|
const message = result.stderr.trim() || result.stdout.trim();
|
|
282
|
+
if (isRipgrepPathError(message)) {
|
|
283
|
+
return respond
|
|
284
|
+
.error(`ripgrep failed\n\n${message.length > 0 ? message : "ripgrep path lookup failed"}`)
|
|
285
|
+
.detail({
|
|
286
|
+
commands,
|
|
287
|
+
cwd: commandCwd,
|
|
288
|
+
matchCount: 0,
|
|
289
|
+
rangeCount: 0,
|
|
290
|
+
ranges: [],
|
|
291
|
+
truncated: false,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
282
294
|
throw new Error(message.length > 0 ? message : "ripgrep exited with an error");
|
|
283
295
|
}
|
|
284
296
|
if (result.exitCode === 1 || result.stdout.trim().length === 0) {
|