@kb-labs/agent-tools 2.89.0 → 2.93.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.
- package/dist/index.d.ts +20 -5
- package/dist/index.js +209 -103
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.d.ts
CHANGED
|
@@ -628,18 +628,33 @@ declare const SOURCE_FILE_EXTENSIONS: {
|
|
|
628
628
|
};
|
|
629
629
|
/** Flat list of all source file extensions */
|
|
630
630
|
declare const ALL_SOURCE_EXTENSIONS: readonly string[];
|
|
631
|
+
declare function shellSingleQuote(value: string): string;
|
|
631
632
|
/**
|
|
632
|
-
* Build `--include=
|
|
633
|
+
* Build `--include='*.ext'` flags for ripgrep / grep.
|
|
633
634
|
* @example toRgIncludes(ALL_SOURCE_EXTENSIONS)
|
|
634
|
-
* // →
|
|
635
|
+
* // → "--include='*.ts' --include='*.tsx' ..."
|
|
635
636
|
*/
|
|
636
637
|
declare function toRgIncludes(exts: readonly string[]): string;
|
|
637
638
|
/**
|
|
638
|
-
* Build
|
|
639
|
+
* Build `--include=*.ext` args for grep when using execa array mode (no shell).
|
|
640
|
+
* @example toRgIncludesArgs(['ts', 'tsx'])
|
|
641
|
+
* // → ['--include=*.ts', '--include=*.tsx']
|
|
642
|
+
*/
|
|
643
|
+
declare function toRgIncludesArgs(exts: readonly string[]): string[];
|
|
644
|
+
/**
|
|
645
|
+
* Build `-name '*.ext'` flags for `find` (joined with ` -o `).
|
|
639
646
|
* @example toFindNames(ALL_SOURCE_EXTENSIONS)
|
|
640
|
-
* // →
|
|
647
|
+
* // → "-name '*.ts' -o -name '*.tsx' ..."
|
|
641
648
|
*/
|
|
642
649
|
declare function toFindNames(exts: readonly string[]): string;
|
|
650
|
+
/**
|
|
651
|
+
* Build `-name *.ext` args for `find` when using execa array mode (no shell).
|
|
652
|
+
* Returns a flat list of alternating pairs: ['-name', '*.ts', '-o', '-name', '*.tsx', ...]
|
|
653
|
+
* with no leading/trailing `-o`.
|
|
654
|
+
* @example toFindNamesArgs(['ts', 'tsx'])
|
|
655
|
+
* // → ['-name', '*.ts', '-o', '-name', '*.tsx']
|
|
656
|
+
*/
|
|
657
|
+
declare function toFindNamesArgs(exts: readonly string[]): string[];
|
|
643
658
|
|
|
644
659
|
/**
|
|
645
660
|
* Shared utilities for agent tool implementations.
|
|
@@ -726,4 +741,4 @@ declare class RemoteWorkspaceProvider implements IWorkspaceProvider {
|
|
|
726
741
|
}): Promise<ShellResult>;
|
|
727
742
|
}
|
|
728
743
|
|
|
729
|
-
export { ALL_SOURCE_EXTENSIONS, DELEGATION_CONFIG, type DispatchFn, FILESYSTEM_CONFIG, type FileReadResult, type FileStatResult, type GlobResult, type GrepMatch, type GrepResult, type IArchiveMemory, type ITaskManager, type IWorkspaceProvider, MASS_REPLACE_CONFIG, PLAN_READ_ONLY_TOOL_NAMES, RemoteWorkspaceProvider, SEARCH_CONFIG, SHELL_CONFIG, SOURCE_FILE_EXTENSIONS, SUB_AGENT_PRESETS, type SessionMemoryBridge, type ShellResult, TODO_CONFIG, type Tool, type ToolContext, type ToolExecutionEnvelope, type ToolExecutor, ToolGateway, type ToolPolicy, ToolRegistry, type ToolResponseRequirements, createArchiveRecallTool, createAskParentTool, createAskUserTool, createCodeStatsTool, createFindDefinitionTool, createFsListTool, createFsPatchTool, createFsReadTool, createFsReplaceTool, createFsWriteTool, createGlobSearchTool, createGrepSearchTool, createListFilesTool, createMassReplaceTool, createMemoryBlockerTool, createMemoryConstraintTool, createMemoryCorrectionTool, createMemoryFindingTool, createMemoryGetTool, createMemoryPreferenceTool, createPlanValidateTool, createPlanWriteTool, createReportTool, createSessionSaveTool, createShellExecTool, createTaskCollectTool, createTaskStatusTool, createTaskSubmitTool, createTodoCreateTool, createTodoGetTool, createTodoUpdateTool, createToolRegistry, normalizeOffsetLimit, suggestDirectory, toFindNames, toRgIncludes, validatePath };
|
|
744
|
+
export { ALL_SOURCE_EXTENSIONS, DELEGATION_CONFIG, type DispatchFn, FILESYSTEM_CONFIG, type FileReadResult, type FileStatResult, type GlobResult, type GrepMatch, type GrepResult, type IArchiveMemory, type ITaskManager, type IWorkspaceProvider, MASS_REPLACE_CONFIG, PLAN_READ_ONLY_TOOL_NAMES, RemoteWorkspaceProvider, SEARCH_CONFIG, SHELL_CONFIG, SOURCE_FILE_EXTENSIONS, SUB_AGENT_PRESETS, type SessionMemoryBridge, type ShellResult, TODO_CONFIG, type Tool, type ToolContext, type ToolExecutionEnvelope, type ToolExecutor, ToolGateway, type ToolPolicy, ToolRegistry, type ToolResponseRequirements, createArchiveRecallTool, createAskParentTool, createAskUserTool, createCodeStatsTool, createFindDefinitionTool, createFsListTool, createFsPatchTool, createFsReadTool, createFsReplaceTool, createFsWriteTool, createGlobSearchTool, createGrepSearchTool, createListFilesTool, createMassReplaceTool, createMemoryBlockerTool, createMemoryConstraintTool, createMemoryCorrectionTool, createMemoryFindingTool, createMemoryGetTool, createMemoryPreferenceTool, createPlanValidateTool, createPlanWriteTool, createReportTool, createSessionSaveTool, createShellExecTool, createTaskCollectTool, createTaskStatusTool, createTaskSubmitTool, createTodoCreateTool, createTodoGetTool, createTodoUpdateTool, createToolRegistry, normalizeOffsetLimit, shellSingleQuote, suggestDirectory, toFindNames, toFindNamesArgs, toRgIncludes, toRgIncludesArgs, validatePath };
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,9 @@ import * as path4 from 'path';
|
|
|
3
3
|
import path4__default from 'path';
|
|
4
4
|
import * as crypto from 'crypto';
|
|
5
5
|
import { glob } from 'glob';
|
|
6
|
-
import {
|
|
6
|
+
import { execa } from 'execa';
|
|
7
7
|
import { useLLM } from '@kb-labs/sdk';
|
|
8
|
+
import { execSync } from 'child_process';
|
|
8
9
|
import * as readline from 'readline';
|
|
9
10
|
import { useLLM as useLLM$1 } from '@kb-labs/sdk/hooks';
|
|
10
11
|
|
|
@@ -303,11 +304,30 @@ var SOURCE_FILE_EXTENSIONS = {
|
|
|
303
304
|
cpp: ["cpp", "c", "h", "cc", "cxx"]
|
|
304
305
|
};
|
|
305
306
|
var ALL_SOURCE_EXTENSIONS = Object.values(SOURCE_FILE_EXTENSIONS).flat();
|
|
307
|
+
function shellSingleQuote(value) {
|
|
308
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
309
|
+
}
|
|
306
310
|
function toRgIncludes(exts) {
|
|
307
|
-
return exts.map((e) => `--include
|
|
311
|
+
return exts.map((e) => `--include=${shellSingleQuote(`*.${e}`)}`).join(" ");
|
|
312
|
+
}
|
|
313
|
+
function toRgIncludesArgs(exts) {
|
|
314
|
+
return exts.map((e) => `--include=*.${e}`);
|
|
308
315
|
}
|
|
309
316
|
function toFindNames(exts) {
|
|
310
|
-
return exts.map((e) => `-name
|
|
317
|
+
return exts.map((e) => `-name ${shellSingleQuote(`*.${e}`)}`).join(" -o ");
|
|
318
|
+
}
|
|
319
|
+
function toFindNamesArgs(exts) {
|
|
320
|
+
if (exts.length === 0) {
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
const result = [];
|
|
324
|
+
for (let i = 0; i < exts.length; i++) {
|
|
325
|
+
if (i > 0) {
|
|
326
|
+
result.push("-o");
|
|
327
|
+
}
|
|
328
|
+
result.push("-name", `*.${exts[i]}`);
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
311
331
|
}
|
|
312
332
|
function normalizeOffsetLimit(input, config) {
|
|
313
333
|
const rawOffset = Number(input.offset);
|
|
@@ -1307,16 +1327,16 @@ ${continuationHint}`;
|
|
|
1307
1327
|
var DEFAULT_EXCLUDES = SEARCH_CONFIG.defaultExcludes;
|
|
1308
1328
|
var MAX_OUTPUT_CHARS2 = SEARCH_CONFIG.maxOutputChars;
|
|
1309
1329
|
function buildFindExcludes(excludes) {
|
|
1310
|
-
|
|
1330
|
+
const args = [];
|
|
1331
|
+
for (const d of excludes) {
|
|
1332
|
+
args.push("!", "-path", `*/${d}/*`);
|
|
1333
|
+
}
|
|
1334
|
+
return args;
|
|
1311
1335
|
}
|
|
1312
1336
|
function buildGrepExcludes(excludes) {
|
|
1313
|
-
return excludes.map((d) => `--exclude-dir=${d}`)
|
|
1314
|
-
}
|
|
1315
|
-
function toSingleQuoted(value) {
|
|
1316
|
-
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
1337
|
+
return excludes.map((d) => `--exclude-dir=${d}`);
|
|
1317
1338
|
}
|
|
1318
1339
|
var SEARCH_TIMEOUT_MS = SEARCH_CONFIG.timeoutMs;
|
|
1319
|
-
var SEARCH_MAX_BUFFER = SEARCH_CONFIG.maxBuffer;
|
|
1320
1340
|
var DEFAULT_RESULT_LIMIT = SEARCH_CONFIG.defaultResultLimit;
|
|
1321
1341
|
var MAX_RESULT_LIMIT = SEARCH_CONFIG.maxResultLimit;
|
|
1322
1342
|
function validateDirectory(workingDir, directory) {
|
|
@@ -1400,14 +1420,20 @@ function createGlobSearchTool(context) {
|
|
|
1400
1420
|
return { success: true, output: dirError };
|
|
1401
1421
|
}
|
|
1402
1422
|
const windowSize = Math.min(2e3, Math.max(500, offset + limit));
|
|
1403
|
-
const
|
|
1404
|
-
|
|
1423
|
+
const args = [
|
|
1424
|
+
fullPath,
|
|
1425
|
+
"-type",
|
|
1426
|
+
"f",
|
|
1427
|
+
"-iname",
|
|
1428
|
+
pattern,
|
|
1429
|
+
...buildFindExcludes(excludes)
|
|
1430
|
+
];
|
|
1431
|
+
const result = await execa("find", args, {
|
|
1405
1432
|
cwd: context.workingDir,
|
|
1406
|
-
|
|
1407
|
-
maxBuffer: SEARCH_MAX_BUFFER,
|
|
1433
|
+
reject: false,
|
|
1408
1434
|
timeout: SEARCH_TIMEOUT_MS
|
|
1409
1435
|
});
|
|
1410
|
-
const files =
|
|
1436
|
+
const files = result.stdout.split("\n").filter(Boolean).slice(0, windowSize).map((f) => path4.relative(context.workingDir, f));
|
|
1411
1437
|
if (files.length === 0) {
|
|
1412
1438
|
return {
|
|
1413
1439
|
success: true,
|
|
@@ -1416,7 +1442,7 @@ function createGlobSearchTool(context) {
|
|
|
1416
1442
|
}
|
|
1417
1443
|
const page = paginate(files, offset, limit);
|
|
1418
1444
|
const excludeNote = `[Excluded: ${DEFAULT_EXCLUDES.join(", ")}${extra && extra.length > 0 ? ` + ${extra.join(", ")}` : ""}]`;
|
|
1419
|
-
const
|
|
1445
|
+
const resultText = [
|
|
1420
1446
|
`Found ${files.length} file(s) matching "${pattern}" in "${directory}" (showing ${page.page.length}, offset=${offset}, limit=${limit})`,
|
|
1421
1447
|
excludeNote,
|
|
1422
1448
|
"",
|
|
@@ -1426,7 +1452,7 @@ function createGlobSearchTool(context) {
|
|
|
1426
1452
|
const continuationHint = page.hasMore ? `Next page: glob_search(pattern="${pattern}", directory="${directory}", offset=${page.nextOffset}, limit=${limit})` : "";
|
|
1427
1453
|
return {
|
|
1428
1454
|
success: true,
|
|
1429
|
-
output: trimOutput2(
|
|
1455
|
+
output: trimOutput2(resultText, MAX_OUTPUT_CHARS2, continuationHint),
|
|
1430
1456
|
metadata: {
|
|
1431
1457
|
totalMatches: files.length,
|
|
1432
1458
|
offset,
|
|
@@ -1525,39 +1551,57 @@ function createGrepSearchTool(context) {
|
|
|
1525
1551
|
return { success: true, output: dirError };
|
|
1526
1552
|
}
|
|
1527
1553
|
const windowSize = Math.min(2e3, Math.max(500, offset + limit));
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1554
|
+
const buildArgs = (literal) => {
|
|
1555
|
+
const args = ["-rIn"];
|
|
1556
|
+
if (literal) {
|
|
1557
|
+
args.push("-F");
|
|
1558
|
+
}
|
|
1559
|
+
args.push(pattern, fullPath);
|
|
1560
|
+
args.push(...buildGrepExcludes(excludes));
|
|
1561
|
+
if (filePattern) {
|
|
1562
|
+
args.push(`--include=${filePattern}`);
|
|
1563
|
+
}
|
|
1564
|
+
return args;
|
|
1565
|
+
};
|
|
1532
1566
|
let output = "";
|
|
1533
1567
|
let usedLiteralFallback = false;
|
|
1534
|
-
|
|
1535
|
-
|
|
1568
|
+
const runGrep = async (literal) => {
|
|
1569
|
+
const res = await execa("grep", buildArgs(literal), {
|
|
1536
1570
|
cwd: context.workingDir,
|
|
1537
|
-
|
|
1538
|
-
maxBuffer: SEARCH_MAX_BUFFER,
|
|
1571
|
+
reject: false,
|
|
1539
1572
|
timeout: SEARCH_TIMEOUT_MS
|
|
1540
1573
|
});
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
const looksLikeInvalidRegex =
|
|
1546
|
-
if (
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1574
|
+
return { stdout: res.stdout, exitCode: res.exitCode ?? 0, stderr: res.stderr };
|
|
1575
|
+
};
|
|
1576
|
+
const initial = await runGrep(mode === "literal");
|
|
1577
|
+
if (initial.exitCode === 2) {
|
|
1578
|
+
const looksLikeInvalidRegex = /(unbalanced|parentheses|invalid regular expression|regular expression)/i.test(initial.stderr);
|
|
1579
|
+
if (looksLikeInvalidRegex && mode !== "regex") {
|
|
1580
|
+
usedLiteralFallback = true;
|
|
1581
|
+
const fallback = await runGrep(true);
|
|
1582
|
+
output = fallback.stdout;
|
|
1583
|
+
if (fallback.exitCode === 2) {
|
|
1584
|
+
return toolError({
|
|
1585
|
+
code: "SEARCH_FAILED",
|
|
1586
|
+
message: `Grep search failed: ${fallback.stderr}`,
|
|
1587
|
+
retryable: true,
|
|
1588
|
+
hint: 'Try mode="literal" for special characters, or narrow directory.',
|
|
1589
|
+
details: { directory, pattern, filePattern, mode }
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
} else {
|
|
1593
|
+
return toolError({
|
|
1594
|
+
code: "SEARCH_FAILED",
|
|
1595
|
+
message: `Grep search failed: ${initial.stderr}`,
|
|
1596
|
+
retryable: true,
|
|
1597
|
+
hint: 'Try mode="literal" for special characters, or narrow directory.',
|
|
1598
|
+
details: { directory, pattern, filePattern, mode }
|
|
1599
|
+
});
|
|
1552
1600
|
}
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
encoding: "utf-8",
|
|
1556
|
-
maxBuffer: SEARCH_MAX_BUFFER,
|
|
1557
|
-
timeout: SEARCH_TIMEOUT_MS
|
|
1558
|
-
});
|
|
1601
|
+
} else {
|
|
1602
|
+
output = initial.stdout;
|
|
1559
1603
|
}
|
|
1560
|
-
const lines = output.
|
|
1604
|
+
const lines = output.split("\n").filter(Boolean).slice(0, windowSize);
|
|
1561
1605
|
if (lines.length === 0) {
|
|
1562
1606
|
return {
|
|
1563
1607
|
success: true,
|
|
@@ -1566,7 +1610,7 @@ function createGrepSearchTool(context) {
|
|
|
1566
1610
|
}
|
|
1567
1611
|
const page = paginate(lines, offset, limit);
|
|
1568
1612
|
const excludeNote = `[Excluded: ${DEFAULT_EXCLUDES.join(", ")}${extra && extra.length > 0 ? ` + ${extra.join(", ")}` : ""}]`;
|
|
1569
|
-
const
|
|
1613
|
+
const resultText = [
|
|
1570
1614
|
`Found ${lines.length} match(es) for "${pattern}" in "${directory}"${filePattern ? ` (${filePattern})` : ""}${usedLiteralFallback ? " (literal fallback)" : ""} (showing ${page.page.length}, offset=${offset}, limit=${limit})`,
|
|
1571
1615
|
excludeNote,
|
|
1572
1616
|
"",
|
|
@@ -1585,7 +1629,7 @@ function createGrepSearchTool(context) {
|
|
|
1585
1629
|
const continuationHint = page.hasMore ? `Next page: grep_search(pattern="${pattern}", directory="${directory}", offset=${page.nextOffset}, limit=${limit})` : "";
|
|
1586
1630
|
return {
|
|
1587
1631
|
success: true,
|
|
1588
|
-
output: trimOutput2(
|
|
1632
|
+
output: trimOutput2(resultText, MAX_OUTPUT_CHARS2, continuationHint),
|
|
1589
1633
|
metadata: {
|
|
1590
1634
|
totalMatches: lines.length,
|
|
1591
1635
|
offset,
|
|
@@ -1596,12 +1640,6 @@ function createGrepSearchTool(context) {
|
|
|
1596
1640
|
}
|
|
1597
1641
|
};
|
|
1598
1642
|
} catch (error) {
|
|
1599
|
-
if (error instanceof Error && "status" in error && error.status === 1) {
|
|
1600
|
-
return {
|
|
1601
|
-
success: true,
|
|
1602
|
-
output: `No matches found for "${pattern}" in ${directory === "." ? "project root" : directory}.${filePattern ? "" : ' Try adding filePattern (e.g. "*.ts") to narrow the search.'}`
|
|
1603
|
-
};
|
|
1604
|
-
}
|
|
1605
1643
|
if (error instanceof Error && "killed" in error && error.killed) {
|
|
1606
1644
|
return toolError({
|
|
1607
1645
|
code: "SEARCH_TIMEOUT",
|
|
@@ -1667,19 +1705,30 @@ function createListFilesTool(context) {
|
|
|
1667
1705
|
const { offset, limit } = normalizeOffsetLimit2(input);
|
|
1668
1706
|
try {
|
|
1669
1707
|
const fullPath = path4.resolve(context.workingDir, directory);
|
|
1670
|
-
let cmd;
|
|
1671
1708
|
if (recursive) {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1709
|
+
const args = [
|
|
1710
|
+
fullPath,
|
|
1711
|
+
"-type",
|
|
1712
|
+
"f",
|
|
1713
|
+
"!",
|
|
1714
|
+
"-path",
|
|
1715
|
+
"*/node_modules/*",
|
|
1716
|
+
"!",
|
|
1717
|
+
"-path",
|
|
1718
|
+
"*/.git/*",
|
|
1719
|
+
"!",
|
|
1720
|
+
"-path",
|
|
1721
|
+
"*/dist/*",
|
|
1722
|
+
"!",
|
|
1723
|
+
"-path",
|
|
1724
|
+
"*/.kb/*"
|
|
1725
|
+
];
|
|
1726
|
+
const result = await execa("find", args, {
|
|
1727
|
+
cwd: context.workingDir,
|
|
1728
|
+
reject: false,
|
|
1729
|
+
timeout: SEARCH_TIMEOUT_MS
|
|
1730
|
+
});
|
|
1731
|
+
const files = result.stdout.split("\n").filter(Boolean).slice(0, 100).map((f) => path4.relative(context.workingDir, f));
|
|
1683
1732
|
const page = paginate(files, offset, limit);
|
|
1684
1733
|
return {
|
|
1685
1734
|
success: true,
|
|
@@ -1697,11 +1746,24 @@ Next page: list_files(directory="${directory}", recursive=true, offset=${page.ne
|
|
|
1697
1746
|
}
|
|
1698
1747
|
};
|
|
1699
1748
|
}
|
|
1749
|
+
let entries;
|
|
1750
|
+
try {
|
|
1751
|
+
entries = fs2.readdirSync(fullPath, { withFileTypes: true });
|
|
1752
|
+
} catch {
|
|
1753
|
+
return {
|
|
1754
|
+
success: true,
|
|
1755
|
+
output: "Directory not found"
|
|
1756
|
+
};
|
|
1757
|
+
}
|
|
1758
|
+
const lines = entries.sort((a, b) => a.name.localeCompare(b.name)).map((e) => {
|
|
1759
|
+
const indicator = e.isDirectory() ? "/" : e.isSymbolicLink() ? "@" : "";
|
|
1760
|
+
return `${e.name}${indicator}`;
|
|
1761
|
+
});
|
|
1700
1762
|
return {
|
|
1701
1763
|
success: true,
|
|
1702
1764
|
output: `Contents of ${directory}:
|
|
1703
1765
|
|
|
1704
|
-
${
|
|
1766
|
+
${lines.join("\n")}`
|
|
1705
1767
|
};
|
|
1706
1768
|
} catch (error) {
|
|
1707
1769
|
return {
|
|
@@ -1778,27 +1840,36 @@ function createFindDefinitionTool(context) {
|
|
|
1778
1840
|
`trait ${name}`,
|
|
1779
1841
|
`mod ${name}`
|
|
1780
1842
|
];
|
|
1781
|
-
let
|
|
1843
|
+
let includeArgs;
|
|
1782
1844
|
if (filePattern) {
|
|
1783
|
-
|
|
1845
|
+
includeArgs = [`--include=${filePattern}`];
|
|
1784
1846
|
} else {
|
|
1785
|
-
|
|
1786
|
-
}
|
|
1787
|
-
const
|
|
1788
|
-
|
|
1847
|
+
includeArgs = toRgIncludesArgs(ALL_SOURCE_EXTENSIONS);
|
|
1848
|
+
}
|
|
1849
|
+
const args = [
|
|
1850
|
+
"-rn",
|
|
1851
|
+
"-E",
|
|
1852
|
+
`(${patterns.join("|")})`,
|
|
1853
|
+
fullPath,
|
|
1854
|
+
...includeArgs,
|
|
1855
|
+
...buildGrepExcludes(DEFAULT_EXCLUDES),
|
|
1856
|
+
"--exclude-dir=bin",
|
|
1857
|
+
"--exclude-dir=obj",
|
|
1858
|
+
"--exclude-dir=target"
|
|
1859
|
+
];
|
|
1860
|
+
const result = await execa("grep", args, {
|
|
1789
1861
|
cwd: context.workingDir,
|
|
1790
|
-
|
|
1791
|
-
maxBuffer: 1024 * 1024,
|
|
1862
|
+
reject: false,
|
|
1792
1863
|
timeout: SEARCH_TIMEOUT_MS
|
|
1793
1864
|
});
|
|
1794
|
-
const lines =
|
|
1865
|
+
const lines = result.stdout.split("\n").filter(Boolean).slice(0, 30);
|
|
1795
1866
|
if (lines.length === 0) {
|
|
1796
1867
|
return {
|
|
1797
1868
|
success: true,
|
|
1798
1869
|
output: `No definition found for "${name}" in ${directory === "." ? "project root" : directory}. Try: grep_search for text matching, or glob_search with "*${name.toLowerCase()}*" for filename matching.`
|
|
1799
1870
|
};
|
|
1800
1871
|
}
|
|
1801
|
-
const
|
|
1872
|
+
const resultLines = lines.map((line) => {
|
|
1802
1873
|
const match = line.match(/^(.+?):(\d+):(.+)$/);
|
|
1803
1874
|
if (match) {
|
|
1804
1875
|
const [, filePath, lineNum, content] = match;
|
|
@@ -1812,15 +1883,9 @@ function createFindDefinitionTool(context) {
|
|
|
1812
1883
|
success: true,
|
|
1813
1884
|
output: `Found definition(s) for "${name}":
|
|
1814
1885
|
|
|
1815
|
-
${
|
|
1886
|
+
${resultLines.join("\n\n")}`
|
|
1816
1887
|
};
|
|
1817
1888
|
} catch (error) {
|
|
1818
|
-
if (error instanceof Error && "status" in error && error.status === 1) {
|
|
1819
|
-
return {
|
|
1820
|
-
success: true,
|
|
1821
|
-
output: `No definition found for "${name}" in ${directory === "." ? "project root" : directory}. Try: grep_search for text matching, or glob_search with "*${name.toLowerCase()}*" for filename matching.`
|
|
1822
|
-
};
|
|
1823
|
-
}
|
|
1824
1889
|
if (error instanceof Error && "killed" in error && error.killed) {
|
|
1825
1890
|
return {
|
|
1826
1891
|
success: false,
|
|
@@ -1875,28 +1940,68 @@ function createCodeStatsTool(context) {
|
|
|
1875
1940
|
if (dirError) {
|
|
1876
1941
|
return { success: true, output: dirError };
|
|
1877
1942
|
}
|
|
1878
|
-
let
|
|
1943
|
+
let extFilterArgs;
|
|
1879
1944
|
if (extensionsInput) {
|
|
1880
1945
|
const exts = extensionsInput.split(",").map((e) => e.trim());
|
|
1881
|
-
|
|
1946
|
+
extFilterArgs = toFindNamesArgs(exts);
|
|
1882
1947
|
} else {
|
|
1883
|
-
|
|
1884
|
-
}
|
|
1885
|
-
const
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1948
|
+
extFilterArgs = toFindNamesArgs(ALL_SOURCE_EXTENSIONS);
|
|
1949
|
+
}
|
|
1950
|
+
const commonExcludes = [
|
|
1951
|
+
"!",
|
|
1952
|
+
"-path",
|
|
1953
|
+
"*/node_modules/*",
|
|
1954
|
+
"!",
|
|
1955
|
+
"-path",
|
|
1956
|
+
"*/dist/*",
|
|
1957
|
+
"!",
|
|
1958
|
+
"-path",
|
|
1959
|
+
"*/.git/*",
|
|
1960
|
+
"!",
|
|
1961
|
+
"-path",
|
|
1962
|
+
"*/bin/*",
|
|
1963
|
+
"!",
|
|
1964
|
+
"-path",
|
|
1965
|
+
"*/obj/*",
|
|
1966
|
+
"!",
|
|
1967
|
+
"-path",
|
|
1968
|
+
"*/target/*",
|
|
1969
|
+
"!",
|
|
1970
|
+
"-path",
|
|
1971
|
+
"*/__pycache__/*"
|
|
1972
|
+
];
|
|
1973
|
+
const findArgs = [
|
|
1974
|
+
fullPath,
|
|
1975
|
+
"-type",
|
|
1976
|
+
"f",
|
|
1977
|
+
"(",
|
|
1978
|
+
...extFilterArgs,
|
|
1979
|
+
")",
|
|
1980
|
+
...commonExcludes
|
|
1981
|
+
];
|
|
1982
|
+
const findResult = await execa("find", findArgs, {
|
|
1897
1983
|
cwd: context.workingDir,
|
|
1898
|
-
|
|
1899
|
-
|
|
1984
|
+
reject: false,
|
|
1985
|
+
timeout: SEARCH_TIMEOUT_MS
|
|
1986
|
+
});
|
|
1987
|
+
const filePaths = findResult.stdout.split("\n").filter(Boolean);
|
|
1988
|
+
const fileCount = filePaths.length;
|
|
1989
|
+
const extCounts = /* @__PURE__ */ new Map();
|
|
1990
|
+
for (const fp of filePaths) {
|
|
1991
|
+
const ext = fp.includes(".") ? fp.split(".").pop() : "(no ext)";
|
|
1992
|
+
extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
1993
|
+
}
|
|
1994
|
+
const countByExt = [...extCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 200).map(([ext, count]) => ` ${count} ${ext}`);
|
|
1995
|
+
let totalOutput = "0 total";
|
|
1996
|
+
if (filePaths.length > 0) {
|
|
1997
|
+
const wcResult = await execa("wc", ["-l", ...filePaths], {
|
|
1998
|
+
cwd: context.workingDir,
|
|
1999
|
+
reject: false
|
|
2000
|
+
});
|
|
2001
|
+
const wcLines = wcResult.stdout.trim().split("\n").filter(Boolean);
|
|
2002
|
+
const lastLine = wcLines[wcLines.length - 1] ?? "";
|
|
2003
|
+
totalOutput = lastLine.trim();
|
|
2004
|
+
}
|
|
1900
2005
|
const page = paginate(countByExt, offset, limit);
|
|
1901
2006
|
return {
|
|
1902
2007
|
success: true,
|
|
@@ -3114,11 +3219,12 @@ ${trimmed || "(command completed with no output)"}`,
|
|
|
3114
3219
|
}
|
|
3115
3220
|
};
|
|
3116
3221
|
} catch (error) {
|
|
3117
|
-
const
|
|
3118
|
-
const
|
|
3119
|
-
const
|
|
3222
|
+
const e = error;
|
|
3223
|
+
const stderr = e.stderr?.toString() || "";
|
|
3224
|
+
const stdout = e.stdout?.toString() || "";
|
|
3225
|
+
const exitCode = e.status ?? -1;
|
|
3120
3226
|
const commandText = typeof command === "string" ? command.trim() : "";
|
|
3121
|
-
if (
|
|
3227
|
+
if (e.code === "ETIMEDOUT" || e.signal === "SIGTERM") {
|
|
3122
3228
|
return toolError({
|
|
3123
3229
|
code: "SHELL_TIMEOUT",
|
|
3124
3230
|
message: `Command timed out in ${resolvedCwd}`,
|
|
@@ -3981,6 +4087,6 @@ var RemoteWorkspaceProvider = class {
|
|
|
3981
4087
|
}
|
|
3982
4088
|
};
|
|
3983
4089
|
|
|
3984
|
-
export { ALL_SOURCE_EXTENSIONS, DELEGATION_CONFIG, FILESYSTEM_CONFIG, MASS_REPLACE_CONFIG, PLAN_READ_ONLY_TOOL_NAMES, RemoteWorkspaceProvider, SEARCH_CONFIG, SHELL_CONFIG, SOURCE_FILE_EXTENSIONS, SUB_AGENT_PRESETS, TODO_CONFIG, ToolGateway, ToolRegistry, createArchiveRecallTool, createAskParentTool, createAskUserTool, createCodeStatsTool, createFindDefinitionTool, createFsListTool, createFsPatchTool, createFsReadTool, createFsReplaceTool, createFsWriteTool, createGlobSearchTool, createGrepSearchTool, createListFilesTool, createMassReplaceTool, createMemoryBlockerTool, createMemoryConstraintTool, createMemoryCorrectionTool, createMemoryFindingTool, createMemoryGetTool, createMemoryPreferenceTool, createPlanValidateTool, createPlanWriteTool, createReportTool, createSessionSaveTool, createShellExecTool, createTaskCollectTool, createTaskStatusTool, createTaskSubmitTool, createTodoCreateTool, createTodoGetTool, createTodoUpdateTool, createToolRegistry, normalizeOffsetLimit, suggestDirectory, toFindNames, toRgIncludes, validatePath };
|
|
4090
|
+
export { ALL_SOURCE_EXTENSIONS, DELEGATION_CONFIG, FILESYSTEM_CONFIG, MASS_REPLACE_CONFIG, PLAN_READ_ONLY_TOOL_NAMES, RemoteWorkspaceProvider, SEARCH_CONFIG, SHELL_CONFIG, SOURCE_FILE_EXTENSIONS, SUB_AGENT_PRESETS, TODO_CONFIG, ToolGateway, ToolRegistry, createArchiveRecallTool, createAskParentTool, createAskUserTool, createCodeStatsTool, createFindDefinitionTool, createFsListTool, createFsPatchTool, createFsReadTool, createFsReplaceTool, createFsWriteTool, createGlobSearchTool, createGrepSearchTool, createListFilesTool, createMassReplaceTool, createMemoryBlockerTool, createMemoryConstraintTool, createMemoryCorrectionTool, createMemoryFindingTool, createMemoryGetTool, createMemoryPreferenceTool, createPlanValidateTool, createPlanWriteTool, createReportTool, createSessionSaveTool, createShellExecTool, createTaskCollectTool, createTaskStatusTool, createTaskSubmitTool, createTodoCreateTool, createTodoGetTool, createTodoUpdateTool, createToolRegistry, normalizeOffsetLimit, shellSingleQuote, suggestDirectory, toFindNames, toFindNamesArgs, toRgIncludes, toRgIncludesArgs, validatePath };
|
|
3985
4091
|
//# sourceMappingURL=index.js.map
|
|
3986
4092
|
//# sourceMappingURL=index.js.map
|