@rdmind/rdmind 0.0.22-alpha.0 → 0.0.23-alpha.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/cli.js +277 -476
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -183770,7 +183770,7 @@ function createContentGeneratorConfig(config, authType, generationConfig) {
|
|
|
183770
183770
|
};
|
|
183771
183771
|
}
|
|
183772
183772
|
async function createContentGenerator(config, gcConfig, sessionId2) {
|
|
183773
|
-
const version2 = "0.0.
|
|
183773
|
+
const version2 = "0.0.23-alpha.0";
|
|
183774
183774
|
const userAgent2 = `QwenCode/${version2} (${process.platform}; ${process.arch})`;
|
|
183775
183775
|
const baseHeaders = {
|
|
183776
183776
|
"User-Agent": userAgent2
|
|
@@ -185708,6 +185708,7 @@ var init_gitUtils = __esm({
|
|
|
185708
185708
|
});
|
|
185709
185709
|
|
|
185710
185710
|
// packages/core/src/utils/paths.ts
|
|
185711
|
+
import fs19 from "node:fs";
|
|
185711
185712
|
import path15 from "node:path";
|
|
185712
185713
|
import os11 from "node:os";
|
|
185713
185714
|
import * as crypto11 from "node:crypto";
|
|
@@ -185799,11 +185800,51 @@ function isSubpath(parentPath, childPath) {
|
|
|
185799
185800
|
const relative10 = pathModule2.relative(parentPath, childPath);
|
|
185800
185801
|
return !relative10.startsWith(`..${pathModule2.sep}`) && relative10 !== ".." && !pathModule2.isAbsolute(relative10);
|
|
185801
185802
|
}
|
|
185803
|
+
function resolvePath(baseDir = process.cwd(), relativePath) {
|
|
185804
|
+
const homeDir = os11.homedir();
|
|
185805
|
+
if (relativePath === "~") {
|
|
185806
|
+
return homeDir;
|
|
185807
|
+
} else if (relativePath.startsWith("~/")) {
|
|
185808
|
+
return path15.join(homeDir, relativePath.slice(2));
|
|
185809
|
+
} else if (path15.isAbsolute(relativePath)) {
|
|
185810
|
+
return relativePath;
|
|
185811
|
+
} else {
|
|
185812
|
+
return path15.resolve(baseDir, relativePath);
|
|
185813
|
+
}
|
|
185814
|
+
}
|
|
185815
|
+
function validatePath(config, resolvedPath, options2 = {}) {
|
|
185816
|
+
const { allowFiles = false } = options2;
|
|
185817
|
+
const workspaceContext = config.getWorkspaceContext();
|
|
185818
|
+
if (!workspaceContext.isPathWithinWorkspace(resolvedPath)) {
|
|
185819
|
+
throw new Error("Path is not within workspace");
|
|
185820
|
+
}
|
|
185821
|
+
try {
|
|
185822
|
+
const stats = fs19.statSync(resolvedPath);
|
|
185823
|
+
if (!allowFiles && !stats.isDirectory()) {
|
|
185824
|
+
throw new Error(`Path is not a directory: ${resolvedPath}`);
|
|
185825
|
+
}
|
|
185826
|
+
} catch (error) {
|
|
185827
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
185828
|
+
throw new Error(`Path does not exist: ${resolvedPath}`);
|
|
185829
|
+
}
|
|
185830
|
+
throw error;
|
|
185831
|
+
}
|
|
185832
|
+
}
|
|
185833
|
+
function resolveAndValidatePath(config, relativePath, options2 = {}) {
|
|
185834
|
+
const targetDir = config.getTargetDir();
|
|
185835
|
+
if (!relativePath) {
|
|
185836
|
+
return targetDir;
|
|
185837
|
+
}
|
|
185838
|
+
const resolvedPath = resolvePath(targetDir, relativePath);
|
|
185839
|
+
validatePath(config, resolvedPath, options2);
|
|
185840
|
+
return resolvedPath;
|
|
185841
|
+
}
|
|
185802
185842
|
var QWEN_DIR5, SHELL_SPECIAL_CHARS;
|
|
185803
185843
|
var init_paths = __esm({
|
|
185804
185844
|
"packages/core/src/utils/paths.ts"() {
|
|
185805
185845
|
"use strict";
|
|
185806
185846
|
init_esbuild_shims();
|
|
185847
|
+
init_errors();
|
|
185807
185848
|
QWEN_DIR5 = ".rdmind";
|
|
185808
185849
|
SHELL_SPECIAL_CHARS = /[ \t()[\]{};|*?$`'"#&<>!~]/;
|
|
185809
185850
|
__name(tildeifyPath, "tildeifyPath");
|
|
@@ -185813,11 +185854,14 @@ var init_paths = __esm({
|
|
|
185813
185854
|
__name(unescapePath, "unescapePath");
|
|
185814
185855
|
__name(getProjectHash, "getProjectHash");
|
|
185815
185856
|
__name(isSubpath, "isSubpath");
|
|
185857
|
+
__name(resolvePath, "resolvePath");
|
|
185858
|
+
__name(validatePath, "validatePath");
|
|
185859
|
+
__name(resolveAndValidatePath, "resolveAndValidatePath");
|
|
185816
185860
|
}
|
|
185817
185861
|
});
|
|
185818
185862
|
|
|
185819
185863
|
// packages/core/src/tools/memoryTool.ts
|
|
185820
|
-
import * as
|
|
185864
|
+
import * as fs20 from "node:fs/promises";
|
|
185821
185865
|
import * as path16 from "node:path";
|
|
185822
185866
|
function setGeminiMdFilename(newFilename) {
|
|
185823
185867
|
if (Array.isArray(newFilename)) {
|
|
@@ -185859,7 +185903,7 @@ function ensureNewlineSeparation(currentContent) {
|
|
|
185859
185903
|
}
|
|
185860
185904
|
async function readMemoryFileContent(scope = "global") {
|
|
185861
185905
|
try {
|
|
185862
|
-
return await
|
|
185906
|
+
return await fs20.readFile(getMemoryFilePath(scope), "utf-8");
|
|
185863
185907
|
} catch (err) {
|
|
185864
185908
|
const error = err;
|
|
185865
185909
|
if (!(error instanceof Error) || error.code !== "ENOENT") throw err;
|
|
@@ -186084,10 +186128,10 @@ Project: ${projectPath} (current project only)`;
|
|
|
186084
186128
|
const memoryFilePath = getMemoryFilePath(scope);
|
|
186085
186129
|
try {
|
|
186086
186130
|
if (modified_by_user && modified_content !== void 0) {
|
|
186087
|
-
await
|
|
186131
|
+
await fs20.mkdir(path16.dirname(memoryFilePath), {
|
|
186088
186132
|
recursive: true
|
|
186089
186133
|
});
|
|
186090
|
-
await
|
|
186134
|
+
await fs20.writeFile(memoryFilePath, modified_content, "utf-8");
|
|
186091
186135
|
const successMessage = `Okay, I've updated the ${scope} memory file with your modifications.`;
|
|
186092
186136
|
return {
|
|
186093
186137
|
llmContent: successMessage,
|
|
@@ -186095,9 +186139,9 @@ Project: ${projectPath} (current project only)`;
|
|
|
186095
186139
|
};
|
|
186096
186140
|
} else {
|
|
186097
186141
|
await MemoryTool.performAddMemoryEntry(fact, memoryFilePath, {
|
|
186098
|
-
readFile:
|
|
186099
|
-
writeFile:
|
|
186100
|
-
mkdir:
|
|
186142
|
+
readFile: fs20.readFile,
|
|
186143
|
+
writeFile: fs20.writeFile,
|
|
186144
|
+
mkdir: fs20.mkdir
|
|
186101
186145
|
});
|
|
186102
186146
|
const successMessage = `Okay, I've remembered that in ${scope} memory: "${fact}"`;
|
|
186103
186147
|
return {
|
|
@@ -186256,7 +186300,7 @@ ${newContent}`;
|
|
|
186256
186300
|
|
|
186257
186301
|
// packages/core/src/core/prompts.ts
|
|
186258
186302
|
import path17 from "node:path";
|
|
186259
|
-
import
|
|
186303
|
+
import fs21 from "node:fs";
|
|
186260
186304
|
import os12 from "node:os";
|
|
186261
186305
|
import process18 from "node:process";
|
|
186262
186306
|
function resolvePathFromEnv(envVar) {
|
|
@@ -186321,11 +186365,11 @@ function getCoreSystemPrompt(userMemory, model) {
|
|
|
186321
186365
|
if (!systemMdResolution.isSwitch) {
|
|
186322
186366
|
systemMdPath = systemMdResolution.value;
|
|
186323
186367
|
}
|
|
186324
|
-
if (!
|
|
186368
|
+
if (!fs21.existsSync(systemMdPath)) {
|
|
186325
186369
|
throw new Error(`missing system prompt file '${systemMdPath}'`);
|
|
186326
186370
|
}
|
|
186327
186371
|
}
|
|
186328
|
-
const basePrompt = systemMdEnabled ?
|
|
186372
|
+
const basePrompt = systemMdEnabled ? fs21.readFileSync(systemMdPath, "utf8") : `
|
|
186329
186373
|
You are RDMind, an interactive CLI agent, specializing in software engineering tasks. Your primary goal is to help users safely and efficiently, adhering strictly to the following instructions and utilizing your available tools.
|
|
186330
186374
|
|
|
186331
186375
|
# Core Mandates
|
|
@@ -186507,8 +186551,8 @@ Your core function is efficient and safe assistance. Balance extreme conciseness
|
|
|
186507
186551
|
);
|
|
186508
186552
|
if (writeSystemMdResolution.value && !writeSystemMdResolution.isDisabled) {
|
|
186509
186553
|
const writePath = writeSystemMdResolution.isSwitch ? systemMdPath : writeSystemMdResolution.value;
|
|
186510
|
-
|
|
186511
|
-
|
|
186554
|
+
fs21.mkdirSync(path17.dirname(writePath), { recursive: true });
|
|
186555
|
+
fs21.writeFileSync(writePath, basePrompt);
|
|
186512
186556
|
}
|
|
186513
186557
|
const memorySuffix = userMemory && userMemory.trim().length > 0 ? `
|
|
186514
186558
|
|
|
@@ -198134,7 +198178,7 @@ ${stderr}`));
|
|
|
198134
198178
|
});
|
|
198135
198179
|
|
|
198136
198180
|
// packages/core/src/tools/shell.ts
|
|
198137
|
-
import
|
|
198181
|
+
import fs22 from "node:fs";
|
|
198138
198182
|
import path18 from "node:path";
|
|
198139
198183
|
import os16, { EOL } from "node:os";
|
|
198140
198184
|
import crypto12 from "node:crypto";
|
|
@@ -198321,8 +198365,8 @@ var init_shell = __esm({
|
|
|
198321
198365
|
const result = await resultPromise;
|
|
198322
198366
|
const backgroundPIDs = [];
|
|
198323
198367
|
if (os16.platform() !== "win32") {
|
|
198324
|
-
if (
|
|
198325
|
-
const pgrepLines =
|
|
198368
|
+
if (fs22.existsSync(tempFilePath)) {
|
|
198369
|
+
const pgrepLines = fs22.readFileSync(tempFilePath, "utf8").split(EOL).filter(Boolean);
|
|
198326
198370
|
for (const line of pgrepLines) {
|
|
198327
198371
|
if (!/^\d+$/.test(line)) {
|
|
198328
198372
|
console.error(`pgrep: ${line}`);
|
|
@@ -198407,8 +198451,8 @@ ${result.output}`;
|
|
|
198407
198451
|
...executionError
|
|
198408
198452
|
};
|
|
198409
198453
|
} finally {
|
|
198410
|
-
if (
|
|
198411
|
-
|
|
198454
|
+
if (fs22.existsSync(tempFilePath)) {
|
|
198455
|
+
fs22.unlinkSync(tempFilePath);
|
|
198412
198456
|
}
|
|
198413
198457
|
}
|
|
198414
198458
|
}
|
|
@@ -198517,7 +198561,7 @@ Co-authored-by: ${gitCoAuthorSettings.name} <${gitCoAuthorSettings.email}>`;
|
|
|
198517
198561
|
});
|
|
198518
198562
|
|
|
198519
198563
|
// packages/core/src/core/coreToolScheduler.ts
|
|
198520
|
-
import * as
|
|
198564
|
+
import * as fs23 from "node:fs/promises";
|
|
198521
198565
|
import * as path19 from "node:path";
|
|
198522
198566
|
function createFunctionResponsePart(callId, toolName, output) {
|
|
198523
198567
|
return {
|
|
@@ -198607,7 +198651,7 @@ async function truncateAndSaveToFile(content, callId, projectTempDir, threshold,
|
|
|
198607
198651
|
const safeFileName = `${path19.basename(callId)}.output`;
|
|
198608
198652
|
const outputFile = path19.join(projectTempDir, safeFileName);
|
|
198609
198653
|
try {
|
|
198610
|
-
await
|
|
198654
|
+
await fs23.writeFile(outputFile, fileContent);
|
|
198611
198655
|
return {
|
|
198612
198656
|
content: `Tool output was too large and has been truncated.
|
|
198613
198657
|
The full output has been saved to: ${outputFile}
|
|
@@ -199386,7 +199430,7 @@ var init_thoughtUtils = __esm({
|
|
|
199386
199430
|
|
|
199387
199431
|
// packages/core/src/services/chatRecordingService.ts
|
|
199388
199432
|
import path20 from "node:path";
|
|
199389
|
-
import
|
|
199433
|
+
import fs24 from "node:fs";
|
|
199390
199434
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
199391
199435
|
var ChatRecordingService;
|
|
199392
199436
|
var init_chatRecordingService = __esm({
|
|
@@ -199431,7 +199475,7 @@ var init_chatRecordingService = __esm({
|
|
|
199431
199475
|
this.config.storage.getProjectTempDir(),
|
|
199432
199476
|
"chats"
|
|
199433
199477
|
);
|
|
199434
|
-
|
|
199478
|
+
fs24.mkdirSync(chatsDir, { recursive: true });
|
|
199435
199479
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 16).replace(/:/g, "-");
|
|
199436
199480
|
const filename = `session-${timestamp}-${this.sessionId.slice(
|
|
199437
199481
|
0,
|
|
@@ -199607,7 +199651,7 @@ var init_chatRecordingService = __esm({
|
|
|
199607
199651
|
*/
|
|
199608
199652
|
readConversation() {
|
|
199609
199653
|
try {
|
|
199610
|
-
this.cachedLastConvData =
|
|
199654
|
+
this.cachedLastConvData = fs24.readFileSync(this.conversationFile, "utf8");
|
|
199611
199655
|
return JSON.parse(this.cachedLastConvData);
|
|
199612
199656
|
} catch (error) {
|
|
199613
199657
|
if (error.code !== "ENOENT") {
|
|
@@ -199634,7 +199678,7 @@ var init_chatRecordingService = __esm({
|
|
|
199634
199678
|
conversation.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
199635
199679
|
const newContent = JSON.stringify(conversation, null, 2);
|
|
199636
199680
|
this.cachedLastConvData = newContent;
|
|
199637
|
-
|
|
199681
|
+
fs24.writeFileSync(this.conversationFile, newContent);
|
|
199638
199682
|
}
|
|
199639
199683
|
} catch (error) {
|
|
199640
199684
|
console.error("Error writing conversation file:", error);
|
|
@@ -199660,7 +199704,7 @@ var init_chatRecordingService = __esm({
|
|
|
199660
199704
|
"chats"
|
|
199661
199705
|
);
|
|
199662
199706
|
const sessionPath = path20.join(chatsDir, `${sessionId2}.json`);
|
|
199663
|
-
|
|
199707
|
+
fs24.unlinkSync(sessionPath);
|
|
199664
199708
|
} catch (error) {
|
|
199665
199709
|
console.error("Error deleting session:", error);
|
|
199666
199710
|
throw error;
|
|
@@ -200532,7 +200576,7 @@ var init_constants3 = __esm({
|
|
|
200532
200576
|
});
|
|
200533
200577
|
|
|
200534
200578
|
// packages/core/src/utils/getFolderStructure.ts
|
|
200535
|
-
import * as
|
|
200579
|
+
import * as fs25 from "node:fs/promises";
|
|
200536
200580
|
import * as path21 from "node:path";
|
|
200537
200581
|
async function readFullStructure(rootPath, options2) {
|
|
200538
200582
|
const rootName = path21.basename(rootPath);
|
|
@@ -200560,7 +200604,7 @@ async function readFullStructure(rootPath, options2) {
|
|
|
200560
200604
|
}
|
|
200561
200605
|
let entries;
|
|
200562
200606
|
try {
|
|
200563
|
-
const rawEntries = await
|
|
200607
|
+
const rawEntries = await fs25.readdir(currentPath, { withFileTypes: true });
|
|
200564
200608
|
entries = rawEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
200565
200609
|
} catch (error) {
|
|
200566
200610
|
if (isNodeError(error) && (error.code === "EACCES" || error.code === "ENOENT")) {
|
|
@@ -208025,7 +208069,7 @@ var require_ignore = __commonJS({
|
|
|
208025
208069
|
});
|
|
208026
208070
|
|
|
208027
208071
|
// packages/core/src/utils/gitIgnoreParser.ts
|
|
208028
|
-
import * as
|
|
208072
|
+
import * as fs26 from "node:fs";
|
|
208029
208073
|
import * as path22 from "node:path";
|
|
208030
208074
|
var import_ignore, GitIgnoreParser;
|
|
208031
208075
|
var init_gitIgnoreParser = __esm({
|
|
@@ -208046,7 +208090,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
208046
208090
|
loadPatternsForFile(patternsFilePath) {
|
|
208047
208091
|
let content;
|
|
208048
208092
|
try {
|
|
208049
|
-
content =
|
|
208093
|
+
content = fs26.readFileSync(patternsFilePath, "utf-8");
|
|
208050
208094
|
} catch (_error) {
|
|
208051
208095
|
return [];
|
|
208052
208096
|
}
|
|
@@ -208113,7 +208157,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
208113
208157
|
"info",
|
|
208114
208158
|
"exclude"
|
|
208115
208159
|
);
|
|
208116
|
-
this.globalPatterns =
|
|
208160
|
+
this.globalPatterns = fs26.existsSync(excludeFile) ? this.loadPatternsForFile(excludeFile) : [];
|
|
208117
208161
|
}
|
|
208118
208162
|
ig.add(this.globalPatterns);
|
|
208119
208163
|
const pathParts = relativePath.split(path22.sep);
|
|
@@ -208138,7 +208182,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
208138
208182
|
}
|
|
208139
208183
|
} else {
|
|
208140
208184
|
const gitignorePath = path22.join(dir, ".gitignore");
|
|
208141
|
-
if (
|
|
208185
|
+
if (fs26.existsSync(gitignorePath)) {
|
|
208142
208186
|
const patterns = this.loadPatternsForFile(gitignorePath);
|
|
208143
208187
|
this.cache.set(dir, patterns);
|
|
208144
208188
|
ig.add(patterns);
|
|
@@ -208157,7 +208201,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
208157
208201
|
});
|
|
208158
208202
|
|
|
208159
208203
|
// packages/core/src/utils/qwenIgnoreParser.ts
|
|
208160
|
-
import * as
|
|
208204
|
+
import * as fs27 from "node:fs";
|
|
208161
208205
|
import * as path23 from "node:path";
|
|
208162
208206
|
var import_ignore2, QwenIgnoreParser;
|
|
208163
208207
|
var init_qwenIgnoreParser = __esm({
|
|
@@ -208180,7 +208224,7 @@ var init_qwenIgnoreParser = __esm({
|
|
|
208180
208224
|
const patternsFilePath = path23.join(this.projectRoot, ".rdmindignore");
|
|
208181
208225
|
let content;
|
|
208182
208226
|
try {
|
|
208183
|
-
content =
|
|
208227
|
+
content = fs27.readFileSync(patternsFilePath, "utf-8");
|
|
208184
208228
|
} catch (_error) {
|
|
208185
208229
|
return;
|
|
208186
208230
|
}
|
|
@@ -215142,7 +215186,7 @@ var init_esm9 = __esm({
|
|
|
215142
215186
|
});
|
|
215143
215187
|
|
|
215144
215188
|
// packages/core/src/services/fileSystemService.ts
|
|
215145
|
-
import
|
|
215189
|
+
import fs28 from "node:fs/promises";
|
|
215146
215190
|
import * as path26 from "node:path";
|
|
215147
215191
|
var StandardFileSystemService;
|
|
215148
215192
|
var init_fileSystemService = __esm({
|
|
@@ -215155,10 +215199,10 @@ var init_fileSystemService = __esm({
|
|
|
215155
215199
|
__name(this, "StandardFileSystemService");
|
|
215156
215200
|
}
|
|
215157
215201
|
async readTextFile(filePath) {
|
|
215158
|
-
return
|
|
215202
|
+
return fs28.readFile(filePath, "utf-8");
|
|
215159
215203
|
}
|
|
215160
215204
|
async writeTextFile(filePath, content) {
|
|
215161
|
-
await
|
|
215205
|
+
await fs28.writeFile(filePath, content, "utf-8");
|
|
215162
215206
|
}
|
|
215163
215207
|
findFiles(fileName, searchPaths) {
|
|
215164
215208
|
return searchPaths.flatMap((searchPath) => {
|
|
@@ -219988,7 +220032,7 @@ var init_esm10 = __esm({
|
|
|
219988
220032
|
});
|
|
219989
220033
|
|
|
219990
220034
|
// packages/core/src/services/gitService.ts
|
|
219991
|
-
import * as
|
|
220035
|
+
import * as fs29 from "node:fs/promises";
|
|
219992
220036
|
import * as path27 from "node:path";
|
|
219993
220037
|
var GitService;
|
|
219994
220038
|
var init_gitService = __esm({
|
|
@@ -220041,9 +220085,9 @@ var init_gitService = __esm({
|
|
|
220041
220085
|
async setupShadowGitRepository() {
|
|
220042
220086
|
const repoDir = this.getHistoryDir();
|
|
220043
220087
|
const gitConfigPath = path27.join(repoDir, ".gitconfig");
|
|
220044
|
-
await
|
|
220088
|
+
await fs29.mkdir(repoDir, { recursive: true });
|
|
220045
220089
|
const gitConfigContent = "[user]\n name = Qwen Code\n email = qwen-code@qwen.ai\n[commit]\n gpgsign = false\n";
|
|
220046
|
-
await
|
|
220090
|
+
await fs29.writeFile(gitConfigPath, gitConfigContent);
|
|
220047
220091
|
const repo = simpleGit(repoDir);
|
|
220048
220092
|
const isRepoDefined = await repo.checkIsRepo(CheckRepoActions.IS_REPO_ROOT);
|
|
220049
220093
|
if (!isRepoDefined) {
|
|
@@ -220056,13 +220100,13 @@ var init_gitService = __esm({
|
|
|
220056
220100
|
const shadowGitIgnorePath = path27.join(repoDir, ".gitignore");
|
|
220057
220101
|
let userGitIgnoreContent = "";
|
|
220058
220102
|
try {
|
|
220059
|
-
userGitIgnoreContent = await
|
|
220103
|
+
userGitIgnoreContent = await fs29.readFile(userGitIgnorePath, "utf-8");
|
|
220060
220104
|
} catch (error) {
|
|
220061
220105
|
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
220062
220106
|
throw error;
|
|
220063
220107
|
}
|
|
220064
220108
|
}
|
|
220065
|
-
await
|
|
220109
|
+
await fs29.writeFile(shadowGitIgnorePath, userGitIgnoreContent);
|
|
220066
220110
|
}
|
|
220067
220111
|
get shadowGitRepository() {
|
|
220068
220112
|
const repoDir = this.getHistoryDir();
|
|
@@ -220751,7 +220795,7 @@ var init_ignorePatterns = __esm({
|
|
|
220751
220795
|
});
|
|
220752
220796
|
|
|
220753
220797
|
// packages/core/src/utils/fileUtils.ts
|
|
220754
|
-
import
|
|
220798
|
+
import fs30 from "node:fs";
|
|
220755
220799
|
import fsPromises from "node:fs/promises";
|
|
220756
220800
|
import path29 from "node:path";
|
|
220757
220801
|
function detectBOM(buf) {
|
|
@@ -220799,7 +220843,7 @@ function decodeUTF32(buf, littleEndian) {
|
|
|
220799
220843
|
return out;
|
|
220800
220844
|
}
|
|
220801
220845
|
async function readFileWithEncoding(filePath) {
|
|
220802
|
-
const full = await
|
|
220846
|
+
const full = await fs30.promises.readFile(filePath);
|
|
220803
220847
|
if (full.length === 0) return "";
|
|
220804
220848
|
const bom = detectBOM(full);
|
|
220805
220849
|
if (!bom) {
|
|
@@ -220834,7 +220878,7 @@ function isWithinRoot(pathToCheck, rootDirectory) {
|
|
|
220834
220878
|
async function isBinaryFile(filePath) {
|
|
220835
220879
|
let fh = null;
|
|
220836
220880
|
try {
|
|
220837
|
-
fh = await
|
|
220881
|
+
fh = await fs30.promises.open(filePath, "r");
|
|
220838
220882
|
const stats = await fh.stat();
|
|
220839
220883
|
const fileSize = stats.size;
|
|
220840
220884
|
if (fileSize === 0) return false;
|
|
@@ -220904,7 +220948,7 @@ async function detectFileType(filePath) {
|
|
|
220904
220948
|
}
|
|
220905
220949
|
async function processSingleFileContent(filePath, rootDirectory, fileSystemService, offset, limit2) {
|
|
220906
220950
|
try {
|
|
220907
|
-
if (!
|
|
220951
|
+
if (!fs30.existsSync(filePath)) {
|
|
220908
220952
|
return {
|
|
220909
220953
|
llmContent: "Could not read file because no file was found at the specified path.",
|
|
220910
220954
|
returnDisplay: "File not found.",
|
|
@@ -220912,7 +220956,7 @@ async function processSingleFileContent(filePath, rootDirectory, fileSystemServi
|
|
|
220912
220956
|
errorType: "file_not_found" /* FILE_NOT_FOUND */
|
|
220913
220957
|
};
|
|
220914
220958
|
}
|
|
220915
|
-
const stats = await
|
|
220959
|
+
const stats = await fs30.promises.stat(filePath);
|
|
220916
220960
|
if (stats.isDirectory()) {
|
|
220917
220961
|
return {
|
|
220918
220962
|
llmContent: "Could not read file because the provided path is a directory, not a file.",
|
|
@@ -220994,7 +221038,7 @@ async function processSingleFileContent(filePath, rootDirectory, fileSystemServi
|
|
|
220994
221038
|
case "pdf":
|
|
220995
221039
|
case "audio":
|
|
220996
221040
|
case "video": {
|
|
220997
|
-
const contentBuffer = await
|
|
221041
|
+
const contentBuffer = await fs30.promises.readFile(filePath);
|
|
220998
221042
|
const base64Data = contentBuffer.toString("base64");
|
|
220999
221043
|
return {
|
|
221000
221044
|
llmContent: {
|
|
@@ -221028,7 +221072,7 @@ async function processSingleFileContent(filePath, rootDirectory, fileSystemServi
|
|
|
221028
221072
|
}
|
|
221029
221073
|
async function fileExists(filePath) {
|
|
221030
221074
|
try {
|
|
221031
|
-
await fsPromises.access(filePath,
|
|
221075
|
+
await fsPromises.access(filePath, fs30.constants.F_OK);
|
|
221032
221076
|
return true;
|
|
221033
221077
|
} catch (_) {
|
|
221034
221078
|
return false;
|
|
@@ -231286,18 +231330,18 @@ var init_stdio2 = __esm({
|
|
|
231286
231330
|
});
|
|
231287
231331
|
|
|
231288
231332
|
// packages/core/src/ide/ide-client.ts
|
|
231289
|
-
import * as
|
|
231333
|
+
import * as fs31 from "node:fs";
|
|
231290
231334
|
import * as os18 from "node:os";
|
|
231291
231335
|
import * as path33 from "node:path";
|
|
231292
231336
|
function getRealPath(path110) {
|
|
231293
231337
|
try {
|
|
231294
|
-
return
|
|
231338
|
+
return fs31.realpathSync(path110);
|
|
231295
231339
|
} catch (_e) {
|
|
231296
231340
|
return path110;
|
|
231297
231341
|
}
|
|
231298
231342
|
}
|
|
231299
231343
|
function getIdeServerHost() {
|
|
231300
|
-
const isInContainer =
|
|
231344
|
+
const isInContainer = fs31.existsSync("/.dockerenv") || fs31.existsSync("/run/.containerenv");
|
|
231301
231345
|
return isInContainer ? "host.docker.internal" : "127.0.0.1";
|
|
231302
231346
|
}
|
|
231303
231347
|
var import_undici, logger, IdeClient;
|
|
@@ -231739,14 +231783,14 @@ var init_ide_client = __esm({
|
|
|
231739
231783
|
os18.tmpdir(),
|
|
231740
231784
|
`qwen-code-ide-server-${this.ideProcessInfo.pid}.json`
|
|
231741
231785
|
);
|
|
231742
|
-
const portFileContents = await
|
|
231786
|
+
const portFileContents = await fs31.promises.readFile(portFile, "utf8");
|
|
231743
231787
|
return JSON.parse(portFileContents);
|
|
231744
231788
|
} catch (_) {
|
|
231745
231789
|
}
|
|
231746
231790
|
const portFileDir = path33.join(os18.tmpdir(), "gemini", "ide");
|
|
231747
231791
|
let portFiles;
|
|
231748
231792
|
try {
|
|
231749
|
-
portFiles = await
|
|
231793
|
+
portFiles = await fs31.promises.readdir(portFileDir);
|
|
231750
231794
|
} catch (e2) {
|
|
231751
231795
|
logger.debug("Failed to read IDE connection directory:", e2);
|
|
231752
231796
|
return void 0;
|
|
@@ -231765,7 +231809,7 @@ var init_ide_client = __esm({
|
|
|
231765
231809
|
try {
|
|
231766
231810
|
fileContents = await Promise.all(
|
|
231767
231811
|
matchingFiles.map(
|
|
231768
|
-
(file) =>
|
|
231812
|
+
(file) => fs31.promises.readFile(path33.join(portFileDir, file), "utf8")
|
|
231769
231813
|
)
|
|
231770
231814
|
);
|
|
231771
231815
|
} catch (e2) {
|
|
@@ -231977,7 +232021,7 @@ ${errorMessage}`,
|
|
|
231977
232021
|
});
|
|
231978
232022
|
|
|
231979
232023
|
// packages/core/src/tools/edit.ts
|
|
231980
|
-
import * as
|
|
232024
|
+
import * as fs32 from "node:fs";
|
|
231981
232025
|
import * as path34 from "node:path";
|
|
231982
232026
|
function applyReplacement(currentContent, oldString, newString, isNewFile) {
|
|
231983
232027
|
if (isNewFile) {
|
|
@@ -232307,8 +232351,8 @@ var init_edit = __esm({
|
|
|
232307
232351
|
*/
|
|
232308
232352
|
ensureParentDirectoriesExist(filePath) {
|
|
232309
232353
|
const dirName = path34.dirname(filePath);
|
|
232310
|
-
if (!
|
|
232311
|
-
|
|
232354
|
+
if (!fs32.existsSync(dirName)) {
|
|
232355
|
+
fs32.mkdirSync(dirName, { recursive: true });
|
|
232312
232356
|
}
|
|
232313
232357
|
}
|
|
232314
232358
|
};
|
|
@@ -232562,7 +232606,7 @@ Eg.
|
|
|
232562
232606
|
});
|
|
232563
232607
|
|
|
232564
232608
|
// packages/core/src/tools/glob.ts
|
|
232565
|
-
import
|
|
232609
|
+
import fs33 from "node:fs";
|
|
232566
232610
|
import path35 from "node:path";
|
|
232567
232611
|
function sortFileEntries(entries, nowTimestamp, recencyThresholdMs) {
|
|
232568
232612
|
const sortedEntries = [...entries];
|
|
@@ -232583,7 +232627,7 @@ function sortFileEntries(entries, nowTimestamp, recencyThresholdMs) {
|
|
|
232583
232627
|
});
|
|
232584
232628
|
return sortedEntries;
|
|
232585
232629
|
}
|
|
232586
|
-
var GlobToolInvocation, GlobTool;
|
|
232630
|
+
var MAX_FILE_COUNT, GlobToolInvocation, GlobTool;
|
|
232587
232631
|
var init_glob2 = __esm({
|
|
232588
232632
|
"packages/core/src/tools/glob.ts"() {
|
|
232589
232633
|
"use strict";
|
|
@@ -232595,80 +232639,55 @@ var init_glob2 = __esm({
|
|
|
232595
232639
|
init_config3();
|
|
232596
232640
|
init_constants3();
|
|
232597
232641
|
init_tool_error();
|
|
232642
|
+
init_errors();
|
|
232643
|
+
MAX_FILE_COUNT = 100;
|
|
232598
232644
|
__name(sortFileEntries, "sortFileEntries");
|
|
232599
232645
|
GlobToolInvocation = class extends BaseToolInvocation {
|
|
232600
232646
|
constructor(config, params) {
|
|
232601
232647
|
super(params);
|
|
232602
232648
|
this.config = config;
|
|
232649
|
+
this.fileService = config.getFileService();
|
|
232603
232650
|
}
|
|
232604
232651
|
static {
|
|
232605
232652
|
__name(this, "GlobToolInvocation");
|
|
232606
232653
|
}
|
|
232654
|
+
fileService;
|
|
232607
232655
|
getDescription() {
|
|
232608
232656
|
let description = `'${this.params.pattern}'`;
|
|
232609
232657
|
if (this.params.path) {
|
|
232610
|
-
|
|
232611
|
-
this.config.getTargetDir(),
|
|
232612
|
-
this.params.path || "."
|
|
232613
|
-
);
|
|
232614
|
-
const relativePath = makeRelative(searchDir, this.config.getTargetDir());
|
|
232615
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
232658
|
+
description += ` in path '${this.params.path}'`;
|
|
232616
232659
|
}
|
|
232617
232660
|
return description;
|
|
232618
232661
|
}
|
|
232619
232662
|
async execute(signal) {
|
|
232620
232663
|
try {
|
|
232621
|
-
const
|
|
232622
|
-
|
|
232623
|
-
|
|
232624
|
-
|
|
232625
|
-
|
|
232626
|
-
|
|
232627
|
-
|
|
232628
|
-
|
|
232629
|
-
|
|
232630
|
-
|
|
232631
|
-
|
|
232632
|
-
|
|
232633
|
-
|
|
232634
|
-
|
|
232635
|
-
|
|
232636
|
-
|
|
232637
|
-
|
|
232638
|
-
|
|
232639
|
-
|
|
232640
|
-
|
|
232641
|
-
} else {
|
|
232642
|
-
searchDirectories = workspaceDirectories;
|
|
232643
|
-
}
|
|
232644
|
-
const fileDiscovery = this.config.getFileService();
|
|
232645
|
-
const allEntries = [];
|
|
232646
|
-
for (const searchDir of searchDirectories) {
|
|
232647
|
-
let pattern = this.params.pattern;
|
|
232648
|
-
const fullPath = path35.join(searchDir, pattern);
|
|
232649
|
-
if (fs32.existsSync(fullPath)) {
|
|
232650
|
-
pattern = escape3(pattern);
|
|
232651
|
-
}
|
|
232652
|
-
const entries = await glob(pattern, {
|
|
232653
|
-
cwd: searchDir,
|
|
232654
|
-
withFileTypes: true,
|
|
232655
|
-
nodir: true,
|
|
232656
|
-
stat: true,
|
|
232657
|
-
nocase: !this.params.case_sensitive,
|
|
232658
|
-
dot: true,
|
|
232659
|
-
ignore: this.config.getFileExclusions().getGlobExcludes(),
|
|
232660
|
-
follow: false,
|
|
232661
|
-
signal
|
|
232662
|
-
});
|
|
232663
|
-
allEntries.push(...entries);
|
|
232664
|
-
}
|
|
232664
|
+
const searchDirAbs = resolveAndValidatePath(
|
|
232665
|
+
this.config,
|
|
232666
|
+
this.params.path
|
|
232667
|
+
);
|
|
232668
|
+
const searchLocationDescription = this.params.path ? `within ${searchDirAbs}` : `in the workspace directory`;
|
|
232669
|
+
let pattern = this.params.pattern;
|
|
232670
|
+
const fullPath = path35.join(searchDirAbs, pattern);
|
|
232671
|
+
if (fs33.existsSync(fullPath)) {
|
|
232672
|
+
pattern = escape3(pattern);
|
|
232673
|
+
}
|
|
232674
|
+
const allEntries = await glob(pattern, {
|
|
232675
|
+
cwd: searchDirAbs,
|
|
232676
|
+
withFileTypes: true,
|
|
232677
|
+
nodir: true,
|
|
232678
|
+
stat: true,
|
|
232679
|
+
nocase: true,
|
|
232680
|
+
dot: true,
|
|
232681
|
+
follow: false,
|
|
232682
|
+
signal
|
|
232683
|
+
});
|
|
232665
232684
|
const relativePaths = allEntries.map(
|
|
232666
232685
|
(p) => path35.relative(this.config.getTargetDir(), p.fullpath())
|
|
232667
232686
|
);
|
|
232668
|
-
const { filteredPaths
|
|
232669
|
-
|
|
232670
|
-
|
|
232671
|
-
|
|
232687
|
+
const { filteredPaths } = this.fileService.filterFilesWithReport(
|
|
232688
|
+
relativePaths,
|
|
232689
|
+
this.getFileFilteringOptions()
|
|
232690
|
+
);
|
|
232672
232691
|
const filteredAbsolutePaths = new Set(
|
|
232673
232692
|
filteredPaths.map((p) => path35.resolve(this.config.getTargetDir(), p))
|
|
232674
232693
|
);
|
|
@@ -232676,20 +232695,8 @@ var init_glob2 = __esm({
|
|
|
232676
232695
|
(entry) => filteredAbsolutePaths.has(entry.fullpath())
|
|
232677
232696
|
);
|
|
232678
232697
|
if (!filteredEntries || filteredEntries.length === 0) {
|
|
232679
|
-
let message = `No files found matching pattern "${this.params.pattern}"`;
|
|
232680
|
-
if (searchDirectories.length === 1) {
|
|
232681
|
-
message += ` within ${searchDirectories[0]}`;
|
|
232682
|
-
} else {
|
|
232683
|
-
message += ` within ${searchDirectories.length} workspace directories`;
|
|
232684
|
-
}
|
|
232685
|
-
if (gitIgnoredCount > 0) {
|
|
232686
|
-
message += ` (${gitIgnoredCount} files were git-ignored)`;
|
|
232687
|
-
}
|
|
232688
|
-
if (qwenIgnoredCount > 0) {
|
|
232689
|
-
message += ` (${qwenIgnoredCount} files were rdmind-ignored)`;
|
|
232690
|
-
}
|
|
232691
232698
|
return {
|
|
232692
|
-
llmContent:
|
|
232699
|
+
llmContent: `No files found matching pattern "${this.params.pattern}" ${searchLocationDescription}`,
|
|
232693
232700
|
returnDisplay: `No files found`
|
|
232694
232701
|
};
|
|
232695
232702
|
}
|
|
@@ -232700,28 +232707,27 @@ var init_glob2 = __esm({
|
|
|
232700
232707
|
nowTimestamp,
|
|
232701
232708
|
oneDayInMs
|
|
232702
232709
|
);
|
|
232703
|
-
const
|
|
232710
|
+
const totalFileCount = sortedEntries.length;
|
|
232711
|
+
const truncated = totalFileCount > MAX_FILE_COUNT;
|
|
232712
|
+
const entriesToShow = truncated ? sortedEntries.slice(0, MAX_FILE_COUNT) : sortedEntries;
|
|
232713
|
+
const sortedAbsolutePaths = entriesToShow.map(
|
|
232704
232714
|
(entry) => entry.fullpath()
|
|
232705
232715
|
);
|
|
232706
232716
|
const fileListDescription = sortedAbsolutePaths.join("\n");
|
|
232707
|
-
|
|
232708
|
-
let resultMessage = `Found ${fileCount} file(s) matching "${this.params.pattern}"`;
|
|
232709
|
-
if (searchDirectories.length === 1) {
|
|
232710
|
-
resultMessage += ` within ${searchDirectories[0]}`;
|
|
232711
|
-
} else {
|
|
232712
|
-
resultMessage += ` across ${searchDirectories.length} workspace directories`;
|
|
232713
|
-
}
|
|
232714
|
-
if (gitIgnoredCount > 0) {
|
|
232715
|
-
resultMessage += ` (${gitIgnoredCount} additional files were git-ignored)`;
|
|
232716
|
-
}
|
|
232717
|
-
if (qwenIgnoredCount > 0) {
|
|
232718
|
-
resultMessage += ` (${qwenIgnoredCount} additional files were rdmind-ignored)`;
|
|
232719
|
-
}
|
|
232717
|
+
let resultMessage = `Found ${totalFileCount} file(s) matching "${this.params.pattern}" ${searchLocationDescription}`;
|
|
232720
232718
|
resultMessage += `, sorted by modification time (newest first):
|
|
232719
|
+
---
|
|
232721
232720
|
${fileListDescription}`;
|
|
232721
|
+
if (truncated) {
|
|
232722
|
+
const omittedFiles = totalFileCount - MAX_FILE_COUNT;
|
|
232723
|
+
const fileTerm = omittedFiles === 1 ? "file" : "files";
|
|
232724
|
+
resultMessage += `
|
|
232725
|
+
---
|
|
232726
|
+
[${omittedFiles} ${fileTerm} truncated] ...`;
|
|
232727
|
+
}
|
|
232722
232728
|
return {
|
|
232723
232729
|
llmContent: resultMessage,
|
|
232724
|
-
returnDisplay: `Found ${
|
|
232730
|
+
returnDisplay: `Found ${totalFileCount} matching file(s)${truncated ? " (truncated)" : ""}`
|
|
232725
232731
|
};
|
|
232726
232732
|
} catch (error) {
|
|
232727
232733
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -232729,7 +232735,7 @@ ${fileListDescription}`;
|
|
|
232729
232735
|
const rawError = `Error during glob search operation: ${errorMessage}`;
|
|
232730
232736
|
return {
|
|
232731
232737
|
llmContent: rawError,
|
|
232732
|
-
returnDisplay: `Error: An unexpected error occurred
|
|
232738
|
+
returnDisplay: `Error: ${errorMessage || "An unexpected error occurred."}`,
|
|
232733
232739
|
error: {
|
|
232734
232740
|
message: rawError,
|
|
232735
232741
|
type: "glob_execution_error" /* GLOB_EXECUTION_ERROR */
|
|
@@ -232737,35 +232743,30 @@ ${fileListDescription}`;
|
|
|
232737
232743
|
};
|
|
232738
232744
|
}
|
|
232739
232745
|
}
|
|
232746
|
+
getFileFilteringOptions() {
|
|
232747
|
+
const options2 = this.config.getFileFilteringOptions?.();
|
|
232748
|
+
return {
|
|
232749
|
+
respectGitIgnore: options2?.respectGitIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectGitIgnore,
|
|
232750
|
+
respectQwenIgnore: options2?.respectQwenIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectQwenIgnore
|
|
232751
|
+
};
|
|
232752
|
+
}
|
|
232740
232753
|
};
|
|
232741
232754
|
GlobTool = class _GlobTool extends BaseDeclarativeTool {
|
|
232742
232755
|
constructor(config) {
|
|
232743
232756
|
super(
|
|
232744
232757
|
_GlobTool.Name,
|
|
232745
232758
|
"FindFiles",
|
|
232746
|
-
|
|
232759
|
+
'Fast file pattern matching tool that works with any codebase size\n- Supports glob patterns like "**/*.js" or "src/**/*.ts"\n- Returns matching file paths sorted by modification time\n- Use this tool when you need to find files by name patterns\n- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead\n- You have the capability to call multiple tools in a single response. It is always better to speculatively perform multiple searches as a batch that are potentially useful.',
|
|
232747
232760
|
"search" /* Search */,
|
|
232748
232761
|
{
|
|
232749
232762
|
properties: {
|
|
232750
232763
|
pattern: {
|
|
232751
|
-
description: "The glob pattern to match against
|
|
232764
|
+
description: "The glob pattern to match files against",
|
|
232752
232765
|
type: "string"
|
|
232753
232766
|
},
|
|
232754
232767
|
path: {
|
|
232755
|
-
description:
|
|
232768
|
+
description: 'The directory to search in. If not specified, the current working directory will be used. IMPORTANT: Omit this field to use the default directory. DO NOT enter "undefined" or "null" - simply omit it for the default behavior. Must be a valid directory path if provided.',
|
|
232756
232769
|
type: "string"
|
|
232757
|
-
},
|
|
232758
|
-
case_sensitive: {
|
|
232759
|
-
description: "Optional: Whether the search should be case-sensitive. Defaults to false.",
|
|
232760
|
-
type: "boolean"
|
|
232761
|
-
},
|
|
232762
|
-
respect_git_ignore: {
|
|
232763
|
-
description: "Optional: Whether to respect .gitignore patterns when finding files. Only available in git repositories. Defaults to true.",
|
|
232764
|
-
type: "boolean"
|
|
232765
|
-
},
|
|
232766
|
-
respect_qwen_ignore: {
|
|
232767
|
-
description: "Optional: Whether to respect .rdmindignore patterns when finding files. Defaults to true.",
|
|
232768
|
-
type: "boolean"
|
|
232769
232770
|
}
|
|
232770
232771
|
},
|
|
232771
232772
|
required: ["pattern"],
|
|
@@ -232782,29 +232783,16 @@ ${fileListDescription}`;
|
|
|
232782
232783
|
* Validates the parameters for the tool.
|
|
232783
232784
|
*/
|
|
232784
232785
|
validateToolParamValues(params) {
|
|
232785
|
-
const searchDirAbsolute = path35.resolve(
|
|
232786
|
-
this.config.getTargetDir(),
|
|
232787
|
-
params.path || "."
|
|
232788
|
-
);
|
|
232789
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
232790
|
-
if (!workspaceContext.isPathWithinWorkspace(searchDirAbsolute)) {
|
|
232791
|
-
const directories = workspaceContext.getDirectories();
|
|
232792
|
-
return `Search path ("${searchDirAbsolute}") resolves outside the allowed workspace directories: ${directories.join(", ")}`;
|
|
232793
|
-
}
|
|
232794
|
-
const targetDir = searchDirAbsolute || this.config.getTargetDir();
|
|
232795
|
-
try {
|
|
232796
|
-
if (!fs32.existsSync(targetDir)) {
|
|
232797
|
-
return `Search path does not exist ${targetDir}`;
|
|
232798
|
-
}
|
|
232799
|
-
if (!fs32.statSync(targetDir).isDirectory()) {
|
|
232800
|
-
return `Search path is not a directory: ${targetDir}`;
|
|
232801
|
-
}
|
|
232802
|
-
} catch (e2) {
|
|
232803
|
-
return `Error accessing search path: ${e2}`;
|
|
232804
|
-
}
|
|
232805
232786
|
if (!params.pattern || typeof params.pattern !== "string" || params.pattern.trim() === "") {
|
|
232806
232787
|
return "The 'pattern' parameter cannot be empty.";
|
|
232807
232788
|
}
|
|
232789
|
+
if (params.path) {
|
|
232790
|
+
try {
|
|
232791
|
+
resolveAndValidatePath(this.config, params.path);
|
|
232792
|
+
} catch (error) {
|
|
232793
|
+
return getErrorMessage(error);
|
|
232794
|
+
}
|
|
232795
|
+
}
|
|
232808
232796
|
return null;
|
|
232809
232797
|
}
|
|
232810
232798
|
createInvocation(params) {
|
|
@@ -232815,12 +232803,11 @@ ${fileListDescription}`;
|
|
|
232815
232803
|
});
|
|
232816
232804
|
|
|
232817
232805
|
// packages/core/src/tools/grep.ts
|
|
232818
|
-
import fs33 from "node:fs";
|
|
232819
232806
|
import fsPromises2 from "node:fs/promises";
|
|
232820
232807
|
import path36 from "node:path";
|
|
232821
232808
|
import { EOL as EOL2 } from "node:os";
|
|
232822
232809
|
import { spawn as spawn5 } from "node:child_process";
|
|
232823
|
-
var GrepToolInvocation, GrepTool;
|
|
232810
|
+
var MAX_LLM_CONTENT_LENGTH, GrepToolInvocation, GrepTool;
|
|
232824
232811
|
var init_grep2 = __esm({
|
|
232825
232812
|
"packages/core/src/tools/grep.ts"() {
|
|
232826
232813
|
"use strict";
|
|
@@ -232832,6 +232819,7 @@ var init_grep2 = __esm({
|
|
|
232832
232819
|
init_errors();
|
|
232833
232820
|
init_gitUtils();
|
|
232834
232821
|
init_tool_error();
|
|
232822
|
+
MAX_LLM_CONTENT_LENGTH = 2e4;
|
|
232835
232823
|
GrepToolInvocation = class extends BaseToolInvocation {
|
|
232836
232824
|
constructor(config, params) {
|
|
232837
232825
|
super(params);
|
|
@@ -232842,93 +232830,37 @@ var init_grep2 = __esm({
|
|
|
232842
232830
|
__name(this, "GrepToolInvocation");
|
|
232843
232831
|
}
|
|
232844
232832
|
fileExclusions;
|
|
232845
|
-
/**
|
|
232846
|
-
* Checks if a path is within the root directory and resolves it.
|
|
232847
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
232848
|
-
* @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
|
|
232849
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
232850
|
-
*/
|
|
232851
|
-
resolveAndValidatePath(relativePath) {
|
|
232852
|
-
if (!relativePath) {
|
|
232853
|
-
return null;
|
|
232854
|
-
}
|
|
232855
|
-
const targetPath = path36.resolve(this.config.getTargetDir(), relativePath);
|
|
232856
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
232857
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
232858
|
-
const directories = workspaceContext.getDirectories();
|
|
232859
|
-
throw new Error(
|
|
232860
|
-
`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`
|
|
232861
|
-
);
|
|
232862
|
-
}
|
|
232863
|
-
try {
|
|
232864
|
-
const stats = fs33.statSync(targetPath);
|
|
232865
|
-
if (!stats.isDirectory()) {
|
|
232866
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
232867
|
-
}
|
|
232868
|
-
} catch (error) {
|
|
232869
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
232870
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
232871
|
-
}
|
|
232872
|
-
throw new Error(
|
|
232873
|
-
`Failed to access path stats for ${targetPath}: ${error}`
|
|
232874
|
-
);
|
|
232875
|
-
}
|
|
232876
|
-
return targetPath;
|
|
232877
|
-
}
|
|
232878
232833
|
async execute(signal) {
|
|
232879
232834
|
try {
|
|
232880
|
-
const
|
|
232881
|
-
|
|
232835
|
+
const searchDirAbs = resolveAndValidatePath(
|
|
232836
|
+
this.config,
|
|
232837
|
+
this.params.path
|
|
232838
|
+
);
|
|
232882
232839
|
const searchDirDisplay = this.params.path || ".";
|
|
232883
|
-
|
|
232884
|
-
|
|
232885
|
-
|
|
232886
|
-
|
|
232887
|
-
|
|
232888
|
-
}
|
|
232889
|
-
|
|
232890
|
-
const
|
|
232891
|
-
|
|
232892
|
-
|
|
232893
|
-
for (const searchDir of searchDirectories) {
|
|
232894
|
-
const matches = await this.performGrepSearch({
|
|
232895
|
-
pattern: this.params.pattern,
|
|
232896
|
-
path: searchDir,
|
|
232897
|
-
include: this.params.include,
|
|
232898
|
-
signal
|
|
232899
|
-
});
|
|
232900
|
-
totalMatchesFound += matches.length;
|
|
232901
|
-
if (searchDirectories.length > 1) {
|
|
232902
|
-
const dirName = path36.basename(searchDir);
|
|
232903
|
-
matches.forEach((match2) => {
|
|
232904
|
-
match2.filePath = path36.join(dirName, match2.filePath);
|
|
232905
|
-
});
|
|
232906
|
-
}
|
|
232907
|
-
const remainingSlots = maxResults - allMatches.length;
|
|
232908
|
-
if (remainingSlots <= 0) {
|
|
232909
|
-
searchTruncated = true;
|
|
232910
|
-
break;
|
|
232911
|
-
}
|
|
232912
|
-
if (matches.length > remainingSlots) {
|
|
232913
|
-
allMatches = allMatches.concat(matches.slice(0, remainingSlots));
|
|
232914
|
-
searchTruncated = true;
|
|
232915
|
-
break;
|
|
232916
|
-
} else {
|
|
232917
|
-
allMatches = allMatches.concat(matches);
|
|
232918
|
-
}
|
|
232919
|
-
}
|
|
232920
|
-
let searchLocationDescription;
|
|
232921
|
-
if (searchDirAbs === null) {
|
|
232922
|
-
const numDirs = workspaceContext.getDirectories().length;
|
|
232923
|
-
searchLocationDescription = numDirs > 1 ? `across ${numDirs} workspace directories` : `in the workspace directory`;
|
|
232924
|
-
} else {
|
|
232925
|
-
searchLocationDescription = `in path "${searchDirDisplay}"`;
|
|
232926
|
-
}
|
|
232927
|
-
if (allMatches.length === 0) {
|
|
232928
|
-
const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}.`;
|
|
232840
|
+
const rawMatches = await this.performGrepSearch({
|
|
232841
|
+
pattern: this.params.pattern,
|
|
232842
|
+
path: searchDirAbs,
|
|
232843
|
+
glob: this.params.glob,
|
|
232844
|
+
signal
|
|
232845
|
+
});
|
|
232846
|
+
const searchLocationDescription = this.params.path ? `in path "${searchDirDisplay}"` : `in the workspace directory`;
|
|
232847
|
+
const filterDescription = this.params.glob ? ` (filter: "${this.params.glob}")` : "";
|
|
232848
|
+
if (rawMatches.length === 0) {
|
|
232849
|
+
const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}.`;
|
|
232929
232850
|
return { llmContent: noMatchMsg, returnDisplay: `No matches found` };
|
|
232930
232851
|
}
|
|
232931
|
-
|
|
232852
|
+
let truncatedByLineLimit = false;
|
|
232853
|
+
let matchesToInclude = rawMatches;
|
|
232854
|
+
if (this.params.limit !== void 0 && rawMatches.length > this.params.limit) {
|
|
232855
|
+
matchesToInclude = rawMatches.slice(0, this.params.limit);
|
|
232856
|
+
truncatedByLineLimit = true;
|
|
232857
|
+
}
|
|
232858
|
+
const totalMatches = rawMatches.length;
|
|
232859
|
+
const matchTerm = totalMatches === 1 ? "match" : "matches";
|
|
232860
|
+
const header = `Found ${totalMatches} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}:
|
|
232861
|
+
---
|
|
232862
|
+
`;
|
|
232863
|
+
const matchesByFile = matchesToInclude.reduce(
|
|
232932
232864
|
(acc, match2) => {
|
|
232933
232865
|
const fileKey = match2.filePath;
|
|
232934
232866
|
if (!acc[fileKey]) {
|
|
@@ -232940,40 +232872,38 @@ var init_grep2 = __esm({
|
|
|
232940
232872
|
},
|
|
232941
232873
|
{}
|
|
232942
232874
|
);
|
|
232943
|
-
|
|
232944
|
-
const matchTerm = matchCount === 1 ? "match" : "matches";
|
|
232945
|
-
let headerText = `Found ${matchCount} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}`;
|
|
232946
|
-
if (searchTruncated) {
|
|
232947
|
-
headerText += ` (showing first ${matchCount} of ${totalMatchesFound}+ total matches)`;
|
|
232948
|
-
}
|
|
232949
|
-
let llmContent = `${headerText}:
|
|
232950
|
-
---
|
|
232951
|
-
`;
|
|
232875
|
+
let grepOutput = "";
|
|
232952
232876
|
for (const filePath in matchesByFile) {
|
|
232953
|
-
|
|
232877
|
+
grepOutput += `File: ${filePath}
|
|
232954
232878
|
`;
|
|
232955
232879
|
matchesByFile[filePath].forEach((match2) => {
|
|
232956
232880
|
const trimmedLine = match2.line.trim();
|
|
232957
|
-
|
|
232881
|
+
grepOutput += `L${match2.lineNumber}: ${trimmedLine}
|
|
232958
232882
|
`;
|
|
232959
232883
|
});
|
|
232960
|
-
|
|
232884
|
+
grepOutput += "---\n";
|
|
232961
232885
|
}
|
|
232962
|
-
|
|
232963
|
-
|
|
232964
|
-
|
|
232965
|
-
|
|
232966
|
-
|
|
232967
|
-
|
|
232968
|
-
|
|
232886
|
+
let truncatedByCharLimit = false;
|
|
232887
|
+
if (grepOutput.length > MAX_LLM_CONTENT_LENGTH) {
|
|
232888
|
+
grepOutput = grepOutput.slice(0, MAX_LLM_CONTENT_LENGTH) + "...";
|
|
232889
|
+
truncatedByCharLimit = true;
|
|
232890
|
+
}
|
|
232891
|
+
const finalLines = grepOutput.split("\n").filter(
|
|
232892
|
+
(line) => line.trim() && !line.startsWith("File:") && !line.startsWith("---")
|
|
232893
|
+
);
|
|
232894
|
+
const includedLines = finalLines.length;
|
|
232895
|
+
let llmContent = header + grepOutput;
|
|
232896
|
+
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
232897
|
+
const omittedMatches = totalMatches - includedLines;
|
|
232898
|
+
llmContent += ` [${omittedMatches} ${omittedMatches === 1 ? "line" : "lines"} truncated] ...`;
|
|
232969
232899
|
}
|
|
232970
|
-
let
|
|
232971
|
-
if (
|
|
232972
|
-
|
|
232900
|
+
let displayMessage = `Found ${totalMatches} ${matchTerm}`;
|
|
232901
|
+
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
232902
|
+
displayMessage += ` (truncated)`;
|
|
232973
232903
|
}
|
|
232974
232904
|
return {
|
|
232975
232905
|
llmContent: llmContent.trim(),
|
|
232976
|
-
returnDisplay:
|
|
232906
|
+
returnDisplay: displayMessage
|
|
232977
232907
|
};
|
|
232978
232908
|
} catch (error) {
|
|
232979
232909
|
console.error(`Error during GrepLogic execution: ${error}`);
|
|
@@ -233051,40 +232981,19 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233051
232981
|
* @returns A string describing the grep
|
|
233052
232982
|
*/
|
|
233053
232983
|
getDescription() {
|
|
233054
|
-
let description = `'${this.params.pattern}'`;
|
|
233055
|
-
if (this.params.
|
|
233056
|
-
description += `
|
|
233057
|
-
}
|
|
233058
|
-
if (this.params.path) {
|
|
233059
|
-
const resolvedPath = path36.resolve(
|
|
233060
|
-
this.config.getTargetDir(),
|
|
233061
|
-
this.params.path
|
|
233062
|
-
);
|
|
233063
|
-
if (resolvedPath === this.config.getTargetDir() || this.params.path === ".") {
|
|
233064
|
-
description += ` within ./`;
|
|
233065
|
-
} else {
|
|
233066
|
-
const relativePath = makeRelative(
|
|
233067
|
-
resolvedPath,
|
|
233068
|
-
this.config.getTargetDir()
|
|
233069
|
-
);
|
|
233070
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
233071
|
-
}
|
|
233072
|
-
} else {
|
|
233073
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
233074
|
-
const directories = workspaceContext.getDirectories();
|
|
233075
|
-
if (directories.length > 1) {
|
|
233076
|
-
description += ` across all workspace directories`;
|
|
233077
|
-
}
|
|
232984
|
+
let description = `'${this.params.pattern}' in path '${this.params.path || "./"}'`;
|
|
232985
|
+
if (this.params.glob) {
|
|
232986
|
+
description += ` (filter: '${this.params.glob}')`;
|
|
233078
232987
|
}
|
|
233079
232988
|
return description;
|
|
233080
232989
|
}
|
|
233081
232990
|
/**
|
|
233082
232991
|
* Performs the actual search using the prioritized strategies.
|
|
233083
|
-
* @param options Search options including pattern, absolute path, and
|
|
232992
|
+
* @param options Search options including pattern, absolute path, and glob filter.
|
|
233084
232993
|
* @returns A promise resolving to an array of match objects.
|
|
233085
232994
|
*/
|
|
233086
232995
|
async performGrepSearch(options2) {
|
|
233087
|
-
const { pattern, path: absolutePath,
|
|
232996
|
+
const { pattern, path: absolutePath, glob: glob2 } = options2;
|
|
233088
232997
|
let strategyUsed = "none";
|
|
233089
232998
|
try {
|
|
233090
232999
|
const isGit = isGitRepository(absolutePath);
|
|
@@ -233099,8 +233008,8 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233099
233008
|
"--ignore-case",
|
|
233100
233009
|
pattern
|
|
233101
233010
|
];
|
|
233102
|
-
if (
|
|
233103
|
-
gitArgs.push("--",
|
|
233011
|
+
if (glob2) {
|
|
233012
|
+
gitArgs.push("--", glob2);
|
|
233104
233013
|
}
|
|
233105
233014
|
try {
|
|
233106
233015
|
const output = await new Promise((resolve26, reject) => {
|
|
@@ -233158,8 +233067,8 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233158
233067
|
return null;
|
|
233159
233068
|
}).filter((dir) => !!dir);
|
|
233160
233069
|
commonExcludes.forEach((dir) => grepArgs.push(`--exclude-dir=${dir}`));
|
|
233161
|
-
if (
|
|
233162
|
-
grepArgs.push(`--include=${
|
|
233070
|
+
if (glob2) {
|
|
233071
|
+
grepArgs.push(`--include=${glob2}`);
|
|
233163
233072
|
}
|
|
233164
233073
|
grepArgs.push(pattern);
|
|
233165
233074
|
grepArgs.push(".");
|
|
@@ -233226,7 +233135,7 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233226
233135
|
"GrepLogic: Falling back to JavaScript grep implementation."
|
|
233227
233136
|
);
|
|
233228
233137
|
strategyUsed = "javascript fallback";
|
|
233229
|
-
const globPattern =
|
|
233138
|
+
const globPattern = glob2 ? glob2 : "**/*";
|
|
233230
233139
|
const ignorePatterns = this.fileExclusions.getGlobExcludes();
|
|
233231
233140
|
const filesIterator = globStream(globPattern, {
|
|
233232
233141
|
cwd: absolutePath,
|
|
@@ -233277,28 +233186,26 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233277
233186
|
constructor(config) {
|
|
233278
233187
|
super(
|
|
233279
233188
|
_GrepTool.Name,
|
|
233280
|
-
"
|
|
233281
|
-
|
|
233189
|
+
"Grep",
|
|
233190
|
+
'A powerful search tool for finding patterns in files\n\n Usage:\n - ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access.\n - Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")\n - Filter files with glob parameter (e.g., "*.js", "**/*.tsx")\n - Case-insensitive by default\n - Use Task tool for open-ended searches requiring multiple rounds\n',
|
|
233282
233191
|
"search" /* Search */,
|
|
233283
233192
|
{
|
|
233284
233193
|
properties: {
|
|
233285
233194
|
pattern: {
|
|
233286
|
-
|
|
233287
|
-
|
|
233195
|
+
type: "string",
|
|
233196
|
+
description: "The regular expression pattern to search for in file contents"
|
|
233288
233197
|
},
|
|
233289
|
-
|
|
233290
|
-
|
|
233291
|
-
|
|
233198
|
+
glob: {
|
|
233199
|
+
type: "string",
|
|
233200
|
+
description: 'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}")'
|
|
233292
233201
|
},
|
|
233293
|
-
|
|
233294
|
-
|
|
233295
|
-
|
|
233202
|
+
path: {
|
|
233203
|
+
type: "string",
|
|
233204
|
+
description: "File or directory to search in. Defaults to current working directory."
|
|
233296
233205
|
},
|
|
233297
|
-
|
|
233298
|
-
description: "Optional: Maximum number of matches to return to prevent context overflow (default: 20, max: 100). Use lower values for broad searches, higher for specific searches.",
|
|
233206
|
+
limit: {
|
|
233299
233207
|
type: "number",
|
|
233300
|
-
|
|
233301
|
-
maximum: 100
|
|
233208
|
+
description: "Limit output to first N matching lines. Optional - shows all matches if not specified."
|
|
233302
233209
|
}
|
|
233303
233210
|
},
|
|
233304
233211
|
required: ["pattern"],
|
|
@@ -233311,39 +233218,6 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233311
233218
|
__name(this, "GrepTool");
|
|
233312
233219
|
}
|
|
233313
233220
|
static Name = ToolNames.GREP;
|
|
233314
|
-
/**
|
|
233315
|
-
* Checks if a path is within the root directory and resolves it.
|
|
233316
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
233317
|
-
* @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
|
|
233318
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
233319
|
-
*/
|
|
233320
|
-
resolveAndValidatePath(relativePath) {
|
|
233321
|
-
if (!relativePath) {
|
|
233322
|
-
return null;
|
|
233323
|
-
}
|
|
233324
|
-
const targetPath = path36.resolve(this.config.getTargetDir(), relativePath);
|
|
233325
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
233326
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
233327
|
-
const directories = workspaceContext.getDirectories();
|
|
233328
|
-
throw new Error(
|
|
233329
|
-
`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`
|
|
233330
|
-
);
|
|
233331
|
-
}
|
|
233332
|
-
try {
|
|
233333
|
-
const stats = fs33.statSync(targetPath);
|
|
233334
|
-
if (!stats.isDirectory()) {
|
|
233335
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
233336
|
-
}
|
|
233337
|
-
} catch (error) {
|
|
233338
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
233339
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
233340
|
-
}
|
|
233341
|
-
throw new Error(
|
|
233342
|
-
`Failed to access path stats for ${targetPath}: ${error}`
|
|
233343
|
-
);
|
|
233344
|
-
}
|
|
233345
|
-
return targetPath;
|
|
233346
|
-
}
|
|
233347
233221
|
/**
|
|
233348
233222
|
* Validates the parameters for the tool
|
|
233349
233223
|
* @param params Parameters to validate
|
|
@@ -233353,16 +233227,11 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
233353
233227
|
try {
|
|
233354
233228
|
new RegExp(params.pattern);
|
|
233355
233229
|
} catch (error) {
|
|
233356
|
-
return `Invalid regular expression pattern
|
|
233357
|
-
}
|
|
233358
|
-
if (params.maxResults !== void 0) {
|
|
233359
|
-
if (!Number.isInteger(params.maxResults) || params.maxResults < 1 || params.maxResults > 100) {
|
|
233360
|
-
return `maxResults must be an integer between 1 and 100, got: ${params.maxResults}`;
|
|
233361
|
-
}
|
|
233230
|
+
return `Invalid regular expression pattern: ${params.pattern}. Error: ${getErrorMessage(error)}`;
|
|
233362
233231
|
}
|
|
233363
233232
|
if (params.path) {
|
|
233364
233233
|
try {
|
|
233365
|
-
this.
|
|
233234
|
+
resolveAndValidatePath(this.config, params.path);
|
|
233366
233235
|
} catch (error) {
|
|
233367
233236
|
return getErrorMessage(error);
|
|
233368
233237
|
}
|
|
@@ -234114,7 +233983,7 @@ import fs36 from "node:fs";
|
|
|
234114
233983
|
import path40 from "node:path";
|
|
234115
233984
|
import { EOL as EOL3 } from "node:os";
|
|
234116
233985
|
import { spawn as spawn6 } from "node:child_process";
|
|
234117
|
-
var
|
|
233986
|
+
var MAX_LLM_CONTENT_LENGTH2, GrepToolInvocation2, RipGrepTool;
|
|
234118
233987
|
var init_ripGrep = __esm({
|
|
234119
233988
|
"packages/core/src/tools/ripGrep.ts"() {
|
|
234120
233989
|
"use strict";
|
|
@@ -234126,7 +233995,7 @@ var init_ripGrep = __esm({
|
|
|
234126
233995
|
init_ripgrepUtils();
|
|
234127
233996
|
init_schemaValidator();
|
|
234128
233997
|
init_constants3();
|
|
234129
|
-
|
|
233998
|
+
MAX_LLM_CONTENT_LENGTH2 = 2e4;
|
|
234130
233999
|
GrepToolInvocation2 = class extends BaseToolInvocation {
|
|
234131
234000
|
constructor(config, params) {
|
|
234132
234001
|
super(params);
|
|
@@ -234135,43 +234004,13 @@ var init_ripGrep = __esm({
|
|
|
234135
234004
|
static {
|
|
234136
234005
|
__name(this, "GrepToolInvocation");
|
|
234137
234006
|
}
|
|
234138
|
-
/**
|
|
234139
|
-
* Checks if a path is within the root directory and resolves it.
|
|
234140
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
234141
|
-
* @returns The absolute path to search within.
|
|
234142
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
234143
|
-
*/
|
|
234144
|
-
resolveAndValidatePath(relativePath) {
|
|
234145
|
-
const targetDir = this.config.getTargetDir();
|
|
234146
|
-
const targetPath = relativePath ? path40.resolve(targetDir, relativePath) : targetDir;
|
|
234147
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
234148
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
234149
|
-
const directories = workspaceContext.getDirectories();
|
|
234150
|
-
throw new Error(
|
|
234151
|
-
`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`
|
|
234152
|
-
);
|
|
234153
|
-
}
|
|
234154
|
-
return this.ensureDirectory(targetPath);
|
|
234155
|
-
}
|
|
234156
|
-
ensureDirectory(targetPath) {
|
|
234157
|
-
try {
|
|
234158
|
-
const stats = fs36.statSync(targetPath);
|
|
234159
|
-
if (!stats.isDirectory()) {
|
|
234160
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
234161
|
-
}
|
|
234162
|
-
} catch (error) {
|
|
234163
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
234164
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
234165
|
-
}
|
|
234166
|
-
throw new Error(
|
|
234167
|
-
`Failed to access path stats for ${targetPath}: ${error}`
|
|
234168
|
-
);
|
|
234169
|
-
}
|
|
234170
|
-
return targetPath;
|
|
234171
|
-
}
|
|
234172
234007
|
async execute(signal) {
|
|
234173
234008
|
try {
|
|
234174
|
-
const searchDirAbs =
|
|
234009
|
+
const searchDirAbs = resolveAndValidatePath(
|
|
234010
|
+
this.config,
|
|
234011
|
+
this.params.path,
|
|
234012
|
+
{ allowFiles: true }
|
|
234013
|
+
);
|
|
234175
234014
|
const searchDirDisplay = this.params.path || ".";
|
|
234176
234015
|
const rawOutput = await this.performRipgrepSearch({
|
|
234177
234016
|
pattern: this.params.pattern,
|
|
@@ -234191,26 +234030,39 @@ var init_ripGrep = __esm({
|
|
|
234191
234030
|
const header = `Found ${totalMatches} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}:
|
|
234192
234031
|
---
|
|
234193
234032
|
`;
|
|
234194
|
-
const maxTruncationNoticeLength = 100;
|
|
234195
|
-
const maxGrepOutputLength = MAX_LLM_CONTENT_LENGTH - header.length - maxTruncationNoticeLength;
|
|
234196
234033
|
let truncatedByLineLimit = false;
|
|
234197
234034
|
let linesToInclude = allLines;
|
|
234198
234035
|
if (this.params.limit !== void 0 && allLines.length > this.params.limit) {
|
|
234199
234036
|
linesToInclude = allLines.slice(0, this.params.limit);
|
|
234200
234037
|
truncatedByLineLimit = true;
|
|
234201
234038
|
}
|
|
234202
|
-
|
|
234039
|
+
const parts = [];
|
|
234040
|
+
let includedLines = 0;
|
|
234203
234041
|
let truncatedByCharLimit = false;
|
|
234204
|
-
|
|
234205
|
-
|
|
234206
|
-
|
|
234042
|
+
let currentLength = 0;
|
|
234043
|
+
for (const line of linesToInclude) {
|
|
234044
|
+
const sep7 = includedLines > 0 ? 1 : 0;
|
|
234045
|
+
includedLines++;
|
|
234046
|
+
if (currentLength + line.length <= MAX_LLM_CONTENT_LENGTH2) {
|
|
234047
|
+
parts.push(line);
|
|
234048
|
+
currentLength = currentLength + line.length + sep7;
|
|
234049
|
+
} else {
|
|
234050
|
+
const remaining = Math.max(
|
|
234051
|
+
MAX_LLM_CONTENT_LENGTH2 - currentLength - sep7,
|
|
234052
|
+
10
|
|
234053
|
+
);
|
|
234054
|
+
parts.push(line.slice(0, remaining) + "...");
|
|
234055
|
+
truncatedByCharLimit = true;
|
|
234056
|
+
break;
|
|
234057
|
+
}
|
|
234207
234058
|
}
|
|
234208
|
-
const
|
|
234209
|
-
const includedLines = finalLines.length;
|
|
234059
|
+
const grepOutput = parts.join("\n");
|
|
234210
234060
|
let llmContent = header + grepOutput;
|
|
234211
234061
|
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
234212
234062
|
const omittedMatches = totalMatches - includedLines;
|
|
234213
|
-
llmContent += `
|
|
234063
|
+
llmContent += `
|
|
234064
|
+
---
|
|
234065
|
+
[${omittedMatches} ${omittedMatches === 1 ? "line" : "lines"} truncated] ...`;
|
|
234214
234066
|
}
|
|
234215
234067
|
let displayMessage = `Found ${totalMatches} ${matchTerm}`;
|
|
234216
234068
|
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
@@ -234311,29 +234163,11 @@ var init_ripGrep = __esm({
|
|
|
234311
234163
|
*/
|
|
234312
234164
|
getDescription() {
|
|
234313
234165
|
let description = `'${this.params.pattern}'`;
|
|
234314
|
-
if (this.params.glob) {
|
|
234315
|
-
description += ` in ${this.params.glob}`;
|
|
234316
|
-
}
|
|
234317
234166
|
if (this.params.path) {
|
|
234318
|
-
|
|
234319
|
-
|
|
234320
|
-
|
|
234321
|
-
)
|
|
234322
|
-
if (resolvedPath === this.config.getTargetDir() || this.params.path === ".") {
|
|
234323
|
-
description += ` within ./`;
|
|
234324
|
-
} else {
|
|
234325
|
-
const relativePath = makeRelative(
|
|
234326
|
-
resolvedPath,
|
|
234327
|
-
this.config.getTargetDir()
|
|
234328
|
-
);
|
|
234329
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
234330
|
-
}
|
|
234331
|
-
} else {
|
|
234332
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
234333
|
-
const directories = workspaceContext.getDirectories();
|
|
234334
|
-
if (directories.length > 1) {
|
|
234335
|
-
description += ` across all workspace directories`;
|
|
234336
|
-
}
|
|
234167
|
+
description += ` in path '${this.params.path}'`;
|
|
234168
|
+
}
|
|
234169
|
+
if (this.params.glob) {
|
|
234170
|
+
description += ` (filter: '${this.params.glob}')`;
|
|
234337
234171
|
}
|
|
234338
234172
|
return description;
|
|
234339
234173
|
}
|
|
@@ -234374,39 +234208,6 @@ var init_ripGrep = __esm({
|
|
|
234374
234208
|
__name(this, "RipGrepTool");
|
|
234375
234209
|
}
|
|
234376
234210
|
static Name = ToolNames.GREP;
|
|
234377
|
-
/**
|
|
234378
|
-
* Checks if a path is within the root directory and resolves it.
|
|
234379
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
234380
|
-
* @returns The absolute path to search within.
|
|
234381
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
234382
|
-
*/
|
|
234383
|
-
resolveAndValidatePath(relativePath) {
|
|
234384
|
-
if (!relativePath) {
|
|
234385
|
-
return this.config.getTargetDir();
|
|
234386
|
-
}
|
|
234387
|
-
const targetPath = path40.resolve(this.config.getTargetDir(), relativePath);
|
|
234388
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
234389
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
234390
|
-
const directories = workspaceContext.getDirectories();
|
|
234391
|
-
throw new Error(
|
|
234392
|
-
`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`
|
|
234393
|
-
);
|
|
234394
|
-
}
|
|
234395
|
-
try {
|
|
234396
|
-
const stats = fs36.statSync(targetPath);
|
|
234397
|
-
if (!stats.isDirectory()) {
|
|
234398
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
234399
|
-
}
|
|
234400
|
-
} catch (error) {
|
|
234401
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
234402
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
234403
|
-
}
|
|
234404
|
-
throw new Error(
|
|
234405
|
-
`Failed to access path stats for ${targetPath}: ${error}`
|
|
234406
|
-
);
|
|
234407
|
-
}
|
|
234408
|
-
return targetPath;
|
|
234409
|
-
}
|
|
234410
234211
|
/**
|
|
234411
234212
|
* Validates the parameters for the tool
|
|
234412
234213
|
* @param params Parameters to validate
|
|
@@ -234427,7 +234228,7 @@ var init_ripGrep = __esm({
|
|
|
234427
234228
|
}
|
|
234428
234229
|
if (params.path) {
|
|
234429
234230
|
try {
|
|
234430
|
-
this.
|
|
234231
|
+
resolveAndValidatePath(this.config, params.path, { allowFiles: true });
|
|
234431
234232
|
} catch (error) {
|
|
234432
234233
|
return getErrorMessage(error);
|
|
234433
234234
|
}
|
|
@@ -320370,7 +320171,7 @@ init_esbuild_shims();
|
|
|
320370
320171
|
|
|
320371
320172
|
// packages/cli/src/generated/git-commit.ts
|
|
320372
320173
|
init_esbuild_shims();
|
|
320373
|
-
var GIT_COMMIT_INFO2 = "
|
|
320174
|
+
var GIT_COMMIT_INFO2 = "b7098a68";
|
|
320374
320175
|
|
|
320375
320176
|
// packages/cli/src/ui/components/AboutBox.tsx
|
|
320376
320177
|
var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -342283,7 +342084,7 @@ import { homedir as homedir16 } from "node:os";
|
|
|
342283
342084
|
init_esbuild_shims();
|
|
342284
342085
|
import * as os26 from "node:os";
|
|
342285
342086
|
import * as path77 from "node:path";
|
|
342286
|
-
function
|
|
342087
|
+
function resolvePath2(p) {
|
|
342287
342088
|
if (!p) {
|
|
342288
342089
|
return "";
|
|
342289
342090
|
}
|
|
@@ -342295,7 +342096,7 @@ function resolvePath(p) {
|
|
|
342295
342096
|
}
|
|
342296
342097
|
return path77.normalize(expandedPath);
|
|
342297
342098
|
}
|
|
342298
|
-
__name(
|
|
342099
|
+
__name(resolvePath2, "resolvePath");
|
|
342299
342100
|
|
|
342300
342101
|
// packages/cli/src/utils/version.ts
|
|
342301
342102
|
init_esbuild_shims();
|
|
@@ -342531,7 +342332,7 @@ __name(getPackageJson, "getPackageJson");
|
|
|
342531
342332
|
// packages/cli/src/utils/version.ts
|
|
342532
342333
|
async function getCliVersion() {
|
|
342533
342334
|
const pkgJson = await getPackageJson();
|
|
342534
|
-
return "0.0.
|
|
342335
|
+
return "0.0.23-alpha.0";
|
|
342535
342336
|
}
|
|
342536
342337
|
__name(getCliVersion, "getCliVersion");
|
|
342537
342338
|
|
|
@@ -343333,7 +343134,7 @@ async function loadCliConfig(settings, extensions, extensionEnablementManager, s
|
|
|
343333
343134
|
...DEFAULT_MEMORY_FILE_FILTERING_OPTIONS,
|
|
343334
343135
|
...settings.context?.fileFiltering
|
|
343335
343136
|
};
|
|
343336
|
-
const includeDirectories = (settings.context?.includeDirectories || []).map(
|
|
343137
|
+
const includeDirectories = (settings.context?.includeDirectories || []).map(resolvePath2).concat((argv.includeDirectories || []).map(resolvePath2));
|
|
343337
343138
|
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
|
343338
343139
|
cwd7,
|
|
343339
343140
|
settings.context?.loadMemoryFromIncludeDirectories ? includeDirectories : [],
|