@qwen-code/qwen-code 0.1.4 → 0.1.5-nightly.20251107.d17c37af
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 +258 -438
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -182650,7 +182650,7 @@ function createContentGeneratorConfig(config, authType, generationConfig) {
|
|
|
182650
182650
|
};
|
|
182651
182651
|
}
|
|
182652
182652
|
async function createContentGenerator(config, gcConfig, sessionId2) {
|
|
182653
|
-
const version2 = "0.1.
|
|
182653
|
+
const version2 = "0.1.5-nightly.20251107.d17c37af";
|
|
182654
182654
|
const userAgent2 = `QwenCode/${version2} (${process.platform}; ${process.arch})`;
|
|
182655
182655
|
const baseHeaders = {
|
|
182656
182656
|
"User-Agent": userAgent2
|
|
@@ -184491,6 +184491,7 @@ var init_gitUtils = __esm({
|
|
|
184491
184491
|
});
|
|
184492
184492
|
|
|
184493
184493
|
// packages/core/dist/src/utils/paths.js
|
|
184494
|
+
import fs19 from "node:fs";
|
|
184494
184495
|
import path15 from "node:path";
|
|
184495
184496
|
import os11 from "node:os";
|
|
184496
184497
|
import * as crypto11 from "node:crypto";
|
|
@@ -184579,11 +184580,51 @@ function isSubpath(parentPath, childPath) {
|
|
|
184579
184580
|
const relative10 = pathModule2.relative(parentPath, childPath);
|
|
184580
184581
|
return !relative10.startsWith(`..${pathModule2.sep}`) && relative10 !== ".." && !pathModule2.isAbsolute(relative10);
|
|
184581
184582
|
}
|
|
184583
|
+
function resolvePath(baseDir = process.cwd(), relativePath) {
|
|
184584
|
+
const homeDir = os11.homedir();
|
|
184585
|
+
if (relativePath === "~") {
|
|
184586
|
+
return homeDir;
|
|
184587
|
+
} else if (relativePath.startsWith("~/")) {
|
|
184588
|
+
return path15.join(homeDir, relativePath.slice(2));
|
|
184589
|
+
} else if (path15.isAbsolute(relativePath)) {
|
|
184590
|
+
return relativePath;
|
|
184591
|
+
} else {
|
|
184592
|
+
return path15.resolve(baseDir, relativePath);
|
|
184593
|
+
}
|
|
184594
|
+
}
|
|
184595
|
+
function validatePath(config, resolvedPath, options2 = {}) {
|
|
184596
|
+
const { allowFiles = false } = options2;
|
|
184597
|
+
const workspaceContext = config.getWorkspaceContext();
|
|
184598
|
+
if (!workspaceContext.isPathWithinWorkspace(resolvedPath)) {
|
|
184599
|
+
throw new Error("Path is not within workspace");
|
|
184600
|
+
}
|
|
184601
|
+
try {
|
|
184602
|
+
const stats = fs19.statSync(resolvedPath);
|
|
184603
|
+
if (!allowFiles && !stats.isDirectory()) {
|
|
184604
|
+
throw new Error(`Path is not a directory: ${resolvedPath}`);
|
|
184605
|
+
}
|
|
184606
|
+
} catch (error) {
|
|
184607
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
184608
|
+
throw new Error(`Path does not exist: ${resolvedPath}`);
|
|
184609
|
+
}
|
|
184610
|
+
throw error;
|
|
184611
|
+
}
|
|
184612
|
+
}
|
|
184613
|
+
function resolveAndValidatePath(config, relativePath, options2 = {}) {
|
|
184614
|
+
const targetDir = config.getTargetDir();
|
|
184615
|
+
if (!relativePath) {
|
|
184616
|
+
return targetDir;
|
|
184617
|
+
}
|
|
184618
|
+
const resolvedPath = resolvePath(targetDir, relativePath);
|
|
184619
|
+
validatePath(config, resolvedPath, options2);
|
|
184620
|
+
return resolvedPath;
|
|
184621
|
+
}
|
|
184582
184622
|
var QWEN_DIR5, SHELL_SPECIAL_CHARS;
|
|
184583
184623
|
var init_paths = __esm({
|
|
184584
184624
|
"packages/core/dist/src/utils/paths.js"() {
|
|
184585
184625
|
"use strict";
|
|
184586
184626
|
init_esbuild_shims();
|
|
184627
|
+
init_errors();
|
|
184587
184628
|
QWEN_DIR5 = ".qwen";
|
|
184588
184629
|
SHELL_SPECIAL_CHARS = /[ \t()[\]{};|*?$`'"#&<>!~]/;
|
|
184589
184630
|
__name(tildeifyPath, "tildeifyPath");
|
|
@@ -184593,11 +184634,14 @@ var init_paths = __esm({
|
|
|
184593
184634
|
__name(unescapePath, "unescapePath");
|
|
184594
184635
|
__name(getProjectHash, "getProjectHash");
|
|
184595
184636
|
__name(isSubpath, "isSubpath");
|
|
184637
|
+
__name(resolvePath, "resolvePath");
|
|
184638
|
+
__name(validatePath, "validatePath");
|
|
184639
|
+
__name(resolveAndValidatePath, "resolveAndValidatePath");
|
|
184596
184640
|
}
|
|
184597
184641
|
});
|
|
184598
184642
|
|
|
184599
184643
|
// packages/core/dist/src/tools/memoryTool.js
|
|
184600
|
-
import * as
|
|
184644
|
+
import * as fs20 from "node:fs/promises";
|
|
184601
184645
|
import * as path16 from "node:path";
|
|
184602
184646
|
function setGeminiMdFilename(newFilename) {
|
|
184603
184647
|
if (Array.isArray(newFilename)) {
|
|
@@ -184640,7 +184684,7 @@ function ensureNewlineSeparation(currentContent) {
|
|
|
184640
184684
|
}
|
|
184641
184685
|
async function readMemoryFileContent(scope = "global") {
|
|
184642
184686
|
try {
|
|
184643
|
-
return await
|
|
184687
|
+
return await fs20.readFile(getMemoryFilePath(scope), "utf-8");
|
|
184644
184688
|
} catch (err) {
|
|
184645
184689
|
const error = err;
|
|
184646
184690
|
if (!(error instanceof Error) || error.code !== "ENOENT")
|
|
@@ -184849,10 +184893,10 @@ Project: ${projectPath} (current project only)`;
|
|
|
184849
184893
|
const memoryFilePath = getMemoryFilePath(scope);
|
|
184850
184894
|
try {
|
|
184851
184895
|
if (modified_by_user && modified_content !== void 0) {
|
|
184852
|
-
await
|
|
184896
|
+
await fs20.mkdir(path16.dirname(memoryFilePath), {
|
|
184853
184897
|
recursive: true
|
|
184854
184898
|
});
|
|
184855
|
-
await
|
|
184899
|
+
await fs20.writeFile(memoryFilePath, modified_content, "utf-8");
|
|
184856
184900
|
const successMessage = `Okay, I've updated the ${scope} memory file with your modifications.`;
|
|
184857
184901
|
return {
|
|
184858
184902
|
llmContent: successMessage,
|
|
@@ -184860,9 +184904,9 @@ Project: ${projectPath} (current project only)`;
|
|
|
184860
184904
|
};
|
|
184861
184905
|
} else {
|
|
184862
184906
|
await MemoryTool.performAddMemoryEntry(fact, memoryFilePath, {
|
|
184863
|
-
readFile:
|
|
184864
|
-
writeFile:
|
|
184865
|
-
mkdir:
|
|
184907
|
+
readFile: fs20.readFile,
|
|
184908
|
+
writeFile: fs20.writeFile,
|
|
184909
|
+
mkdir: fs20.mkdir
|
|
184866
184910
|
});
|
|
184867
184911
|
const successMessage = `Okay, I've remembered that in ${scope} memory: "${fact}"`;
|
|
184868
184912
|
return {
|
|
@@ -184997,7 +185041,7 @@ ${newContent}`;
|
|
|
184997
185041
|
|
|
184998
185042
|
// packages/core/dist/src/core/prompts.js
|
|
184999
185043
|
import path17 from "node:path";
|
|
185000
|
-
import
|
|
185044
|
+
import fs21 from "node:fs";
|
|
185001
185045
|
import os12 from "node:os";
|
|
185002
185046
|
import process18 from "node:process";
|
|
185003
185047
|
function resolvePathFromEnv(envVar) {
|
|
@@ -185057,11 +185101,11 @@ function getCoreSystemPrompt(userMemory, model) {
|
|
|
185057
185101
|
if (!systemMdResolution.isSwitch) {
|
|
185058
185102
|
systemMdPath = systemMdResolution.value;
|
|
185059
185103
|
}
|
|
185060
|
-
if (!
|
|
185104
|
+
if (!fs21.existsSync(systemMdPath)) {
|
|
185061
185105
|
throw new Error(`missing system prompt file '${systemMdPath}'`);
|
|
185062
185106
|
}
|
|
185063
185107
|
}
|
|
185064
|
-
const basePrompt = systemMdEnabled ?
|
|
185108
|
+
const basePrompt = systemMdEnabled ? fs21.readFileSync(systemMdPath, "utf8") : `
|
|
185065
185109
|
You are Qwen Code, an interactive CLI agent developed by Alibaba Group, 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.
|
|
185066
185110
|
|
|
185067
185111
|
# Core Mandates
|
|
@@ -185241,8 +185285,8 @@ Your core function is efficient and safe assistance. Balance extreme conciseness
|
|
|
185241
185285
|
const writeSystemMdResolution = resolvePathFromEnv(process18.env["QWEN_WRITE_SYSTEM_MD"]);
|
|
185242
185286
|
if (writeSystemMdResolution.value && !writeSystemMdResolution.isDisabled) {
|
|
185243
185287
|
const writePath = writeSystemMdResolution.isSwitch ? systemMdPath : writeSystemMdResolution.value;
|
|
185244
|
-
|
|
185245
|
-
|
|
185288
|
+
fs21.mkdirSync(path17.dirname(writePath), { recursive: true });
|
|
185289
|
+
fs21.writeFileSync(writePath, basePrompt);
|
|
185246
185290
|
}
|
|
185247
185291
|
const memorySuffix = userMemory && userMemory.trim().length > 0 ? `
|
|
185248
185292
|
|
|
@@ -196828,7 +196872,7 @@ ${stderr}`));
|
|
|
196828
196872
|
});
|
|
196829
196873
|
|
|
196830
196874
|
// packages/core/dist/src/tools/shell.js
|
|
196831
|
-
import
|
|
196875
|
+
import fs22 from "node:fs";
|
|
196832
196876
|
import path18 from "node:path";
|
|
196833
196877
|
import os16, { EOL } from "node:os";
|
|
196834
196878
|
import crypto12 from "node:crypto";
|
|
@@ -197006,8 +197050,8 @@ var init_shell = __esm({
|
|
|
197006
197050
|
const result = await resultPromise;
|
|
197007
197051
|
const backgroundPIDs = [];
|
|
197008
197052
|
if (os16.platform() !== "win32") {
|
|
197009
|
-
if (
|
|
197010
|
-
const pgrepLines =
|
|
197053
|
+
if (fs22.existsSync(tempFilePath)) {
|
|
197054
|
+
const pgrepLines = fs22.readFileSync(tempFilePath, "utf8").split(EOL).filter(Boolean);
|
|
197011
197055
|
for (const line of pgrepLines) {
|
|
197012
197056
|
if (!/^\d+$/.test(line)) {
|
|
197013
197057
|
console.error(`pgrep: ${line}`);
|
|
@@ -197085,8 +197129,8 @@ ${result.output}`;
|
|
|
197085
197129
|
...executionError
|
|
197086
197130
|
};
|
|
197087
197131
|
} finally {
|
|
197088
|
-
if (
|
|
197089
|
-
|
|
197132
|
+
if (fs22.existsSync(tempFilePath)) {
|
|
197133
|
+
fs22.unlinkSync(tempFilePath);
|
|
197090
197134
|
}
|
|
197091
197135
|
}
|
|
197092
197136
|
}
|
|
@@ -197191,7 +197235,7 @@ Co-authored-by: ${gitCoAuthorSettings.name} <${gitCoAuthorSettings.email}>`;
|
|
|
197191
197235
|
});
|
|
197192
197236
|
|
|
197193
197237
|
// packages/core/dist/src/core/coreToolScheduler.js
|
|
197194
|
-
import * as
|
|
197238
|
+
import * as fs23 from "node:fs/promises";
|
|
197195
197239
|
import * as path19 from "node:path";
|
|
197196
197240
|
function createFunctionResponsePart(callId, toolName, output) {
|
|
197197
197241
|
return {
|
|
@@ -197271,7 +197315,7 @@ async function truncateAndSaveToFile(content, callId, projectTempDir, threshold,
|
|
|
197271
197315
|
const safeFileName = `${path19.basename(callId)}.output`;
|
|
197272
197316
|
const outputFile = path19.join(projectTempDir, safeFileName);
|
|
197273
197317
|
try {
|
|
197274
|
-
await
|
|
197318
|
+
await fs23.writeFile(outputFile, fileContent);
|
|
197275
197319
|
return {
|
|
197276
197320
|
content: `Tool output was too large and has been truncated.
|
|
197277
197321
|
The full output has been saved to: ${outputFile}
|
|
@@ -197886,7 +197930,7 @@ var init_thoughtUtils = __esm({
|
|
|
197886
197930
|
|
|
197887
197931
|
// packages/core/dist/src/services/chatRecordingService.js
|
|
197888
197932
|
import path20 from "node:path";
|
|
197889
|
-
import
|
|
197933
|
+
import fs24 from "node:fs";
|
|
197890
197934
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
197891
197935
|
var ChatRecordingService;
|
|
197892
197936
|
var init_chatRecordingService = __esm({
|
|
@@ -197928,7 +197972,7 @@ var init_chatRecordingService = __esm({
|
|
|
197928
197972
|
this.cachedLastConvData = null;
|
|
197929
197973
|
} else {
|
|
197930
197974
|
const chatsDir = path20.join(this.config.storage.getProjectTempDir(), "chats");
|
|
197931
|
-
|
|
197975
|
+
fs24.mkdirSync(chatsDir, { recursive: true });
|
|
197932
197976
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 16).replace(/:/g, "-");
|
|
197933
197977
|
const filename = `session-${timestamp}-${this.sessionId.slice(0, 8)}.json`;
|
|
197934
197978
|
this.conversationFile = path20.join(chatsDir, filename);
|
|
@@ -198101,7 +198145,7 @@ var init_chatRecordingService = __esm({
|
|
|
198101
198145
|
*/
|
|
198102
198146
|
readConversation() {
|
|
198103
198147
|
try {
|
|
198104
|
-
this.cachedLastConvData =
|
|
198148
|
+
this.cachedLastConvData = fs24.readFileSync(this.conversationFile, "utf8");
|
|
198105
198149
|
return JSON.parse(this.cachedLastConvData);
|
|
198106
198150
|
} catch (error) {
|
|
198107
198151
|
if (error.code !== "ENOENT") {
|
|
@@ -198130,7 +198174,7 @@ var init_chatRecordingService = __esm({
|
|
|
198130
198174
|
conversation.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
198131
198175
|
const newContent = JSON.stringify(conversation, null, 2);
|
|
198132
198176
|
this.cachedLastConvData = newContent;
|
|
198133
|
-
|
|
198177
|
+
fs24.writeFileSync(this.conversationFile, newContent);
|
|
198134
198178
|
}
|
|
198135
198179
|
} catch (error) {
|
|
198136
198180
|
console.error("Error writing conversation file:", error);
|
|
@@ -198153,7 +198197,7 @@ var init_chatRecordingService = __esm({
|
|
|
198153
198197
|
try {
|
|
198154
198198
|
const chatsDir = path20.join(this.config.storage.getProjectTempDir(), "chats");
|
|
198155
198199
|
const sessionPath = path20.join(chatsDir, `${sessionId2}.json`);
|
|
198156
|
-
|
|
198200
|
+
fs24.unlinkSync(sessionPath);
|
|
198157
198201
|
} catch (error) {
|
|
198158
198202
|
console.error("Error deleting session:", error);
|
|
198159
198203
|
throw error;
|
|
@@ -199002,7 +199046,7 @@ var init_constants3 = __esm({
|
|
|
199002
199046
|
});
|
|
199003
199047
|
|
|
199004
199048
|
// packages/core/dist/src/utils/getFolderStructure.js
|
|
199005
|
-
import * as
|
|
199049
|
+
import * as fs25 from "node:fs/promises";
|
|
199006
199050
|
import * as path21 from "node:path";
|
|
199007
199051
|
async function readFullStructure(rootPath, options2) {
|
|
199008
199052
|
const rootName = path21.basename(rootPath);
|
|
@@ -199030,7 +199074,7 @@ async function readFullStructure(rootPath, options2) {
|
|
|
199030
199074
|
}
|
|
199031
199075
|
let entries;
|
|
199032
199076
|
try {
|
|
199033
|
-
const rawEntries = await
|
|
199077
|
+
const rawEntries = await fs25.readdir(currentPath, { withFileTypes: true });
|
|
199034
199078
|
entries = rawEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
199035
199079
|
} catch (error) {
|
|
199036
199080
|
if (isNodeError(error) && (error.code === "EACCES" || error.code === "ENOENT")) {
|
|
@@ -206285,7 +206329,7 @@ var require_ignore = __commonJS({
|
|
|
206285
206329
|
});
|
|
206286
206330
|
|
|
206287
206331
|
// packages/core/dist/src/utils/gitIgnoreParser.js
|
|
206288
|
-
import * as
|
|
206332
|
+
import * as fs26 from "node:fs";
|
|
206289
206333
|
import * as path22 from "node:path";
|
|
206290
206334
|
var import_ignore, GitIgnoreParser;
|
|
206291
206335
|
var init_gitIgnoreParser = __esm({
|
|
@@ -206306,7 +206350,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
206306
206350
|
loadPatternsForFile(patternsFilePath) {
|
|
206307
206351
|
let content;
|
|
206308
206352
|
try {
|
|
206309
|
-
content =
|
|
206353
|
+
content = fs26.readFileSync(patternsFilePath, "utf-8");
|
|
206310
206354
|
} catch (_error) {
|
|
206311
206355
|
return [];
|
|
206312
206356
|
}
|
|
@@ -206366,7 +206410,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
206366
206410
|
ig.add(".git");
|
|
206367
206411
|
if (this.globalPatterns === void 0) {
|
|
206368
206412
|
const excludeFile = path22.join(this.projectRoot, ".git", "info", "exclude");
|
|
206369
|
-
this.globalPatterns =
|
|
206413
|
+
this.globalPatterns = fs26.existsSync(excludeFile) ? this.loadPatternsForFile(excludeFile) : [];
|
|
206370
206414
|
}
|
|
206371
206415
|
ig.add(this.globalPatterns);
|
|
206372
206416
|
const pathParts = relativePath.split(path22.sep);
|
|
@@ -206391,7 +206435,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
206391
206435
|
}
|
|
206392
206436
|
} else {
|
|
206393
206437
|
const gitignorePath = path22.join(dir, ".gitignore");
|
|
206394
|
-
if (
|
|
206438
|
+
if (fs26.existsSync(gitignorePath)) {
|
|
206395
206439
|
const patterns = this.loadPatternsForFile(gitignorePath);
|
|
206396
206440
|
this.cache.set(dir, patterns);
|
|
206397
206441
|
ig.add(patterns);
|
|
@@ -206410,7 +206454,7 @@ var init_gitIgnoreParser = __esm({
|
|
|
206410
206454
|
});
|
|
206411
206455
|
|
|
206412
206456
|
// packages/core/dist/src/utils/qwenIgnoreParser.js
|
|
206413
|
-
import * as
|
|
206457
|
+
import * as fs27 from "node:fs";
|
|
206414
206458
|
import * as path23 from "node:path";
|
|
206415
206459
|
var import_ignore2, QwenIgnoreParser;
|
|
206416
206460
|
var init_qwenIgnoreParser = __esm({
|
|
@@ -206433,7 +206477,7 @@ var init_qwenIgnoreParser = __esm({
|
|
|
206433
206477
|
const patternsFilePath = path23.join(this.projectRoot, ".qwenignore");
|
|
206434
206478
|
let content;
|
|
206435
206479
|
try {
|
|
206436
|
-
content =
|
|
206480
|
+
content = fs27.readFileSync(patternsFilePath, "utf-8");
|
|
206437
206481
|
} catch (_error) {
|
|
206438
206482
|
return;
|
|
206439
206483
|
}
|
|
@@ -213392,7 +213436,7 @@ var init_esm9 = __esm({
|
|
|
213392
213436
|
});
|
|
213393
213437
|
|
|
213394
213438
|
// packages/core/dist/src/services/fileSystemService.js
|
|
213395
|
-
import
|
|
213439
|
+
import fs28 from "node:fs/promises";
|
|
213396
213440
|
import * as path26 from "node:path";
|
|
213397
213441
|
var StandardFileSystemService;
|
|
213398
213442
|
var init_fileSystemService = __esm({
|
|
@@ -213405,10 +213449,10 @@ var init_fileSystemService = __esm({
|
|
|
213405
213449
|
__name(this, "StandardFileSystemService");
|
|
213406
213450
|
}
|
|
213407
213451
|
async readTextFile(filePath) {
|
|
213408
|
-
return
|
|
213452
|
+
return fs28.readFile(filePath, "utf-8");
|
|
213409
213453
|
}
|
|
213410
213454
|
async writeTextFile(filePath, content) {
|
|
213411
|
-
await
|
|
213455
|
+
await fs28.writeFile(filePath, content, "utf-8");
|
|
213412
213456
|
}
|
|
213413
213457
|
findFiles(fileName, searchPaths) {
|
|
213414
213458
|
return searchPaths.flatMap((searchPath) => {
|
|
@@ -218238,7 +218282,7 @@ var init_esm10 = __esm({
|
|
|
218238
218282
|
});
|
|
218239
218283
|
|
|
218240
218284
|
// packages/core/dist/src/services/gitService.js
|
|
218241
|
-
import * as
|
|
218285
|
+
import * as fs29 from "node:fs/promises";
|
|
218242
218286
|
import * as path27 from "node:path";
|
|
218243
218287
|
var GitService;
|
|
218244
218288
|
var init_gitService = __esm({
|
|
@@ -218287,9 +218331,9 @@ var init_gitService = __esm({
|
|
|
218287
218331
|
async setupShadowGitRepository() {
|
|
218288
218332
|
const repoDir = this.getHistoryDir();
|
|
218289
218333
|
const gitConfigPath = path27.join(repoDir, ".gitconfig");
|
|
218290
|
-
await
|
|
218334
|
+
await fs29.mkdir(repoDir, { recursive: true });
|
|
218291
218335
|
const gitConfigContent = "[user]\n name = Qwen Code\n email = qwen-code@qwen.ai\n[commit]\n gpgsign = false\n";
|
|
218292
|
-
await
|
|
218336
|
+
await fs29.writeFile(gitConfigPath, gitConfigContent);
|
|
218293
218337
|
const repo = simpleGit(repoDir);
|
|
218294
218338
|
const isRepoDefined = await repo.checkIsRepo(CheckRepoActions.IS_REPO_ROOT);
|
|
218295
218339
|
if (!isRepoDefined) {
|
|
@@ -218302,13 +218346,13 @@ var init_gitService = __esm({
|
|
|
218302
218346
|
const shadowGitIgnorePath = path27.join(repoDir, ".gitignore");
|
|
218303
218347
|
let userGitIgnoreContent = "";
|
|
218304
218348
|
try {
|
|
218305
|
-
userGitIgnoreContent = await
|
|
218349
|
+
userGitIgnoreContent = await fs29.readFile(userGitIgnorePath, "utf-8");
|
|
218306
218350
|
} catch (error) {
|
|
218307
218351
|
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
218308
218352
|
throw error;
|
|
218309
218353
|
}
|
|
218310
218354
|
}
|
|
218311
|
-
await
|
|
218355
|
+
await fs29.writeFile(shadowGitIgnorePath, userGitIgnoreContent);
|
|
218312
218356
|
}
|
|
218313
218357
|
get shadowGitRepository() {
|
|
218314
218358
|
const repoDir = this.getHistoryDir();
|
|
@@ -218989,7 +219033,7 @@ var init_ignorePatterns = __esm({
|
|
|
218989
219033
|
});
|
|
218990
219034
|
|
|
218991
219035
|
// packages/core/dist/src/utils/fileUtils.js
|
|
218992
|
-
import
|
|
219036
|
+
import fs30 from "node:fs";
|
|
218993
219037
|
import fsPromises from "node:fs/promises";
|
|
218994
219038
|
import path29 from "node:path";
|
|
218995
219039
|
function detectBOM(buf) {
|
|
@@ -219039,7 +219083,7 @@ function decodeUTF32(buf, littleEndian) {
|
|
|
219039
219083
|
return out;
|
|
219040
219084
|
}
|
|
219041
219085
|
async function readFileWithEncoding(filePath) {
|
|
219042
|
-
const full = await
|
|
219086
|
+
const full = await fs30.promises.readFile(filePath);
|
|
219043
219087
|
if (full.length === 0)
|
|
219044
219088
|
return "";
|
|
219045
219089
|
const bom = detectBOM(full);
|
|
@@ -219075,7 +219119,7 @@ function isWithinRoot(pathToCheck, rootDirectory) {
|
|
|
219075
219119
|
async function isBinaryFile(filePath) {
|
|
219076
219120
|
let fh = null;
|
|
219077
219121
|
try {
|
|
219078
|
-
fh = await
|
|
219122
|
+
fh = await fs30.promises.open(filePath, "r");
|
|
219079
219123
|
const stats = await fh.stat();
|
|
219080
219124
|
const fileSize = stats.size;
|
|
219081
219125
|
if (fileSize === 0)
|
|
@@ -219143,7 +219187,7 @@ async function detectFileType(filePath) {
|
|
|
219143
219187
|
}
|
|
219144
219188
|
async function processSingleFileContent(filePath, rootDirectory, fileSystemService, offset, limit2) {
|
|
219145
219189
|
try {
|
|
219146
|
-
if (!
|
|
219190
|
+
if (!fs30.existsSync(filePath)) {
|
|
219147
219191
|
return {
|
|
219148
219192
|
llmContent: "Could not read file because no file was found at the specified path.",
|
|
219149
219193
|
returnDisplay: "File not found.",
|
|
@@ -219151,7 +219195,7 @@ async function processSingleFileContent(filePath, rootDirectory, fileSystemServi
|
|
|
219151
219195
|
errorType: ToolErrorType.FILE_NOT_FOUND
|
|
219152
219196
|
};
|
|
219153
219197
|
}
|
|
219154
|
-
const stats = await
|
|
219198
|
+
const stats = await fs30.promises.stat(filePath);
|
|
219155
219199
|
if (stats.isDirectory()) {
|
|
219156
219200
|
return {
|
|
219157
219201
|
llmContent: "Could not read file because the provided path is a directory, not a file.",
|
|
@@ -219233,7 +219277,7 @@ async function processSingleFileContent(filePath, rootDirectory, fileSystemServi
|
|
|
219233
219277
|
case "pdf":
|
|
219234
219278
|
case "audio":
|
|
219235
219279
|
case "video": {
|
|
219236
|
-
const contentBuffer = await
|
|
219280
|
+
const contentBuffer = await fs30.promises.readFile(filePath);
|
|
219237
219281
|
const base64Data = contentBuffer.toString("base64");
|
|
219238
219282
|
return {
|
|
219239
219283
|
llmContent: {
|
|
@@ -219267,7 +219311,7 @@ async function processSingleFileContent(filePath, rootDirectory, fileSystemServi
|
|
|
219267
219311
|
}
|
|
219268
219312
|
async function fileExists(filePath) {
|
|
219269
219313
|
try {
|
|
219270
|
-
await fsPromises.access(filePath,
|
|
219314
|
+
await fsPromises.access(filePath, fs30.constants.F_OK);
|
|
219271
219315
|
return true;
|
|
219272
219316
|
} catch (_) {
|
|
219273
219317
|
return false;
|
|
@@ -229412,18 +229456,18 @@ var init_stdio2 = __esm({
|
|
|
229412
229456
|
});
|
|
229413
229457
|
|
|
229414
229458
|
// packages/core/dist/src/ide/ide-client.js
|
|
229415
|
-
import * as
|
|
229459
|
+
import * as fs31 from "node:fs";
|
|
229416
229460
|
import * as os18 from "node:os";
|
|
229417
229461
|
import * as path33 from "node:path";
|
|
229418
229462
|
function getRealPath(path108) {
|
|
229419
229463
|
try {
|
|
229420
|
-
return
|
|
229464
|
+
return fs31.realpathSync(path108);
|
|
229421
229465
|
} catch (_e) {
|
|
229422
229466
|
return path108;
|
|
229423
229467
|
}
|
|
229424
229468
|
}
|
|
229425
229469
|
function getIdeServerHost() {
|
|
229426
|
-
const isInContainer =
|
|
229470
|
+
const isInContainer = fs31.existsSync("/.dockerenv") || fs31.existsSync("/run/.containerenv");
|
|
229427
229471
|
return isInContainer ? "host.docker.internal" : "127.0.0.1";
|
|
229428
229472
|
}
|
|
229429
229473
|
var import_undici, logger, IDEConnectionStatus, IdeClient;
|
|
@@ -229814,14 +229858,14 @@ var init_ide_client = __esm({
|
|
|
229814
229858
|
}
|
|
229815
229859
|
try {
|
|
229816
229860
|
const portFile = path33.join(os18.tmpdir(), `qwen-code-ide-server-${this.ideProcessInfo.pid}.json`);
|
|
229817
|
-
const portFileContents = await
|
|
229861
|
+
const portFileContents = await fs31.promises.readFile(portFile, "utf8");
|
|
229818
229862
|
return JSON.parse(portFileContents);
|
|
229819
229863
|
} catch (_) {
|
|
229820
229864
|
}
|
|
229821
229865
|
const portFileDir = path33.join(os18.tmpdir(), "gemini", "ide");
|
|
229822
229866
|
let portFiles;
|
|
229823
229867
|
try {
|
|
229824
|
-
portFiles = await
|
|
229868
|
+
portFiles = await fs31.promises.readdir(portFileDir);
|
|
229825
229869
|
} catch (e2) {
|
|
229826
229870
|
logger.debug("Failed to read IDE connection directory:", e2);
|
|
229827
229871
|
return void 0;
|
|
@@ -229836,7 +229880,7 @@ var init_ide_client = __esm({
|
|
|
229836
229880
|
}
|
|
229837
229881
|
let fileContents;
|
|
229838
229882
|
try {
|
|
229839
|
-
fileContents = await Promise.all(matchingFiles.map((file) =>
|
|
229883
|
+
fileContents = await Promise.all(matchingFiles.map((file) => fs31.promises.readFile(path33.join(portFileDir, file), "utf8")));
|
|
229840
229884
|
} catch (e2) {
|
|
229841
229885
|
logger.debug("Failed to read IDE connection config file(s):", e2);
|
|
229842
229886
|
return void 0;
|
|
@@ -230015,7 +230059,7 @@ ${errorMessage}`, true);
|
|
|
230015
230059
|
});
|
|
230016
230060
|
|
|
230017
230061
|
// packages/core/dist/src/tools/edit.js
|
|
230018
|
-
import * as
|
|
230062
|
+
import * as fs32 from "node:fs";
|
|
230019
230063
|
import * as path34 from "node:path";
|
|
230020
230064
|
function applyReplacement(currentContent, oldString, newString, isNewFile) {
|
|
230021
230065
|
if (isNewFile) {
|
|
@@ -230313,8 +230357,8 @@ var init_edit = __esm({
|
|
|
230313
230357
|
*/
|
|
230314
230358
|
ensureParentDirectoriesExist(filePath) {
|
|
230315
230359
|
const dirName = path34.dirname(filePath);
|
|
230316
|
-
if (!
|
|
230317
|
-
|
|
230360
|
+
if (!fs32.existsSync(dirName)) {
|
|
230361
|
+
fs32.mkdirSync(dirName, { recursive: true });
|
|
230318
230362
|
}
|
|
230319
230363
|
}
|
|
230320
230364
|
};
|
|
@@ -230552,7 +230596,7 @@ Eg.
|
|
|
230552
230596
|
});
|
|
230553
230597
|
|
|
230554
230598
|
// packages/core/dist/src/tools/glob.js
|
|
230555
|
-
import
|
|
230599
|
+
import fs33 from "node:fs";
|
|
230556
230600
|
import path35 from "node:path";
|
|
230557
230601
|
function sortFileEntries(entries, nowTimestamp, recencyThresholdMs) {
|
|
230558
230602
|
const sortedEntries = [...entries];
|
|
@@ -230573,7 +230617,7 @@ function sortFileEntries(entries, nowTimestamp, recencyThresholdMs) {
|
|
|
230573
230617
|
});
|
|
230574
230618
|
return sortedEntries;
|
|
230575
230619
|
}
|
|
230576
|
-
var GlobToolInvocation, GlobTool;
|
|
230620
|
+
var MAX_FILE_COUNT, GlobToolInvocation, GlobTool;
|
|
230577
230621
|
var init_glob2 = __esm({
|
|
230578
230622
|
"packages/core/dist/src/tools/glob.js"() {
|
|
230579
230623
|
"use strict";
|
|
@@ -230585,116 +230629,78 @@ var init_glob2 = __esm({
|
|
|
230585
230629
|
init_config3();
|
|
230586
230630
|
init_constants3();
|
|
230587
230631
|
init_tool_error();
|
|
230632
|
+
init_errors();
|
|
230633
|
+
MAX_FILE_COUNT = 100;
|
|
230588
230634
|
__name(sortFileEntries, "sortFileEntries");
|
|
230589
230635
|
GlobToolInvocation = class extends BaseToolInvocation {
|
|
230590
230636
|
static {
|
|
230591
230637
|
__name(this, "GlobToolInvocation");
|
|
230592
230638
|
}
|
|
230593
230639
|
config;
|
|
230640
|
+
fileService;
|
|
230594
230641
|
constructor(config, params) {
|
|
230595
230642
|
super(params);
|
|
230596
230643
|
this.config = config;
|
|
230644
|
+
this.fileService = config.getFileService();
|
|
230597
230645
|
}
|
|
230598
230646
|
getDescription() {
|
|
230599
230647
|
let description = `'${this.params.pattern}'`;
|
|
230600
230648
|
if (this.params.path) {
|
|
230601
|
-
|
|
230602
|
-
const relativePath = makeRelative(searchDir, this.config.getTargetDir());
|
|
230603
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
230649
|
+
description += ` in path '${this.params.path}'`;
|
|
230604
230650
|
}
|
|
230605
230651
|
return description;
|
|
230606
230652
|
}
|
|
230607
230653
|
async execute(signal) {
|
|
230608
230654
|
try {
|
|
230609
|
-
const
|
|
230610
|
-
const
|
|
230611
|
-
let
|
|
230612
|
-
|
|
230613
|
-
|
|
230614
|
-
|
|
230615
|
-
|
|
230616
|
-
|
|
230617
|
-
|
|
230618
|
-
|
|
230619
|
-
|
|
230620
|
-
|
|
230621
|
-
|
|
230622
|
-
|
|
230623
|
-
|
|
230624
|
-
|
|
230625
|
-
searchDirectories = [searchDirAbsolute];
|
|
230626
|
-
} else {
|
|
230627
|
-
searchDirectories = workspaceDirectories;
|
|
230628
|
-
}
|
|
230629
|
-
const fileDiscovery = this.config.getFileService();
|
|
230630
|
-
const allEntries = [];
|
|
230631
|
-
for (const searchDir of searchDirectories) {
|
|
230632
|
-
let pattern = this.params.pattern;
|
|
230633
|
-
const fullPath = path35.join(searchDir, pattern);
|
|
230634
|
-
if (fs32.existsSync(fullPath)) {
|
|
230635
|
-
pattern = escape3(pattern);
|
|
230636
|
-
}
|
|
230637
|
-
const entries = await glob(pattern, {
|
|
230638
|
-
cwd: searchDir,
|
|
230639
|
-
withFileTypes: true,
|
|
230640
|
-
nodir: true,
|
|
230641
|
-
stat: true,
|
|
230642
|
-
nocase: !this.params.case_sensitive,
|
|
230643
|
-
dot: true,
|
|
230644
|
-
ignore: this.config.getFileExclusions().getGlobExcludes(),
|
|
230645
|
-
follow: false,
|
|
230646
|
-
signal
|
|
230647
|
-
});
|
|
230648
|
-
allEntries.push(...entries);
|
|
230649
|
-
}
|
|
230650
|
-
const relativePaths = allEntries.map((p) => path35.relative(this.config.getTargetDir(), p.fullpath()));
|
|
230651
|
-
const { filteredPaths, gitIgnoredCount, qwenIgnoredCount } = fileDiscovery.filterFilesWithReport(relativePaths, {
|
|
230652
|
-
respectGitIgnore: this.params?.respect_git_ignore ?? this.config.getFileFilteringOptions().respectGitIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectGitIgnore,
|
|
230653
|
-
respectQwenIgnore: this.params?.respect_qwen_ignore ?? this.config.getFileFilteringOptions().respectQwenIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectQwenIgnore
|
|
230655
|
+
const searchDirAbs = resolveAndValidatePath(this.config, this.params.path);
|
|
230656
|
+
const searchLocationDescription = this.params.path ? `within ${searchDirAbs}` : `in the workspace directory`;
|
|
230657
|
+
let pattern = this.params.pattern;
|
|
230658
|
+
const fullPath = path35.join(searchDirAbs, pattern);
|
|
230659
|
+
if (fs33.existsSync(fullPath)) {
|
|
230660
|
+
pattern = escape3(pattern);
|
|
230661
|
+
}
|
|
230662
|
+
const allEntries = await glob(pattern, {
|
|
230663
|
+
cwd: searchDirAbs,
|
|
230664
|
+
withFileTypes: true,
|
|
230665
|
+
nodir: true,
|
|
230666
|
+
stat: true,
|
|
230667
|
+
nocase: true,
|
|
230668
|
+
dot: true,
|
|
230669
|
+
follow: false,
|
|
230670
|
+
signal
|
|
230654
230671
|
});
|
|
230672
|
+
const relativePaths = allEntries.map((p) => path35.relative(this.config.getTargetDir(), p.fullpath()));
|
|
230673
|
+
const { filteredPaths } = this.fileService.filterFilesWithReport(relativePaths, this.getFileFilteringOptions());
|
|
230655
230674
|
const filteredAbsolutePaths = new Set(filteredPaths.map((p) => path35.resolve(this.config.getTargetDir(), p)));
|
|
230656
230675
|
const filteredEntries = allEntries.filter((entry) => filteredAbsolutePaths.has(entry.fullpath()));
|
|
230657
230676
|
if (!filteredEntries || filteredEntries.length === 0) {
|
|
230658
|
-
let message = `No files found matching pattern "${this.params.pattern}"`;
|
|
230659
|
-
if (searchDirectories.length === 1) {
|
|
230660
|
-
message += ` within ${searchDirectories[0]}`;
|
|
230661
|
-
} else {
|
|
230662
|
-
message += ` within ${searchDirectories.length} workspace directories`;
|
|
230663
|
-
}
|
|
230664
|
-
if (gitIgnoredCount > 0) {
|
|
230665
|
-
message += ` (${gitIgnoredCount} files were git-ignored)`;
|
|
230666
|
-
}
|
|
230667
|
-
if (qwenIgnoredCount > 0) {
|
|
230668
|
-
message += ` (${qwenIgnoredCount} files were qwen-ignored)`;
|
|
230669
|
-
}
|
|
230670
230677
|
return {
|
|
230671
|
-
llmContent:
|
|
230678
|
+
llmContent: `No files found matching pattern "${this.params.pattern}" ${searchLocationDescription}`,
|
|
230672
230679
|
returnDisplay: `No files found`
|
|
230673
230680
|
};
|
|
230674
230681
|
}
|
|
230675
230682
|
const oneDayInMs = 24 * 60 * 60 * 1e3;
|
|
230676
230683
|
const nowTimestamp = (/* @__PURE__ */ new Date()).getTime();
|
|
230677
230684
|
const sortedEntries = sortFileEntries(filteredEntries, nowTimestamp, oneDayInMs);
|
|
230678
|
-
const
|
|
230685
|
+
const totalFileCount = sortedEntries.length;
|
|
230686
|
+
const truncated = totalFileCount > MAX_FILE_COUNT;
|
|
230687
|
+
const entriesToShow = truncated ? sortedEntries.slice(0, MAX_FILE_COUNT) : sortedEntries;
|
|
230688
|
+
const sortedAbsolutePaths = entriesToShow.map((entry) => entry.fullpath());
|
|
230679
230689
|
const fileListDescription = sortedAbsolutePaths.join("\n");
|
|
230680
|
-
|
|
230681
|
-
let resultMessage = `Found ${fileCount} file(s) matching "${this.params.pattern}"`;
|
|
230682
|
-
if (searchDirectories.length === 1) {
|
|
230683
|
-
resultMessage += ` within ${searchDirectories[0]}`;
|
|
230684
|
-
} else {
|
|
230685
|
-
resultMessage += ` across ${searchDirectories.length} workspace directories`;
|
|
230686
|
-
}
|
|
230687
|
-
if (gitIgnoredCount > 0) {
|
|
230688
|
-
resultMessage += ` (${gitIgnoredCount} additional files were git-ignored)`;
|
|
230689
|
-
}
|
|
230690
|
-
if (qwenIgnoredCount > 0) {
|
|
230691
|
-
resultMessage += ` (${qwenIgnoredCount} additional files were qwen-ignored)`;
|
|
230692
|
-
}
|
|
230690
|
+
let resultMessage = `Found ${totalFileCount} file(s) matching "${this.params.pattern}" ${searchLocationDescription}`;
|
|
230693
230691
|
resultMessage += `, sorted by modification time (newest first):
|
|
230692
|
+
---
|
|
230694
230693
|
${fileListDescription}`;
|
|
230694
|
+
if (truncated) {
|
|
230695
|
+
const omittedFiles = totalFileCount - MAX_FILE_COUNT;
|
|
230696
|
+
const fileTerm = omittedFiles === 1 ? "file" : "files";
|
|
230697
|
+
resultMessage += `
|
|
230698
|
+
---
|
|
230699
|
+
[${omittedFiles} ${fileTerm} truncated] ...`;
|
|
230700
|
+
}
|
|
230695
230701
|
return {
|
|
230696
230702
|
llmContent: resultMessage,
|
|
230697
|
-
returnDisplay: `Found ${
|
|
230703
|
+
returnDisplay: `Found ${totalFileCount} matching file(s)${truncated ? " (truncated)" : ""}`
|
|
230698
230704
|
};
|
|
230699
230705
|
} catch (error) {
|
|
230700
230706
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -230702,7 +230708,7 @@ ${fileListDescription}`;
|
|
|
230702
230708
|
const rawError = `Error during glob search operation: ${errorMessage}`;
|
|
230703
230709
|
return {
|
|
230704
230710
|
llmContent: rawError,
|
|
230705
|
-
returnDisplay: `Error: An unexpected error occurred
|
|
230711
|
+
returnDisplay: `Error: ${errorMessage || "An unexpected error occurred."}`,
|
|
230706
230712
|
error: {
|
|
230707
230713
|
message: rawError,
|
|
230708
230714
|
type: ToolErrorType.GLOB_EXECUTION_ERROR
|
|
@@ -230710,6 +230716,13 @@ ${fileListDescription}`;
|
|
|
230710
230716
|
};
|
|
230711
230717
|
}
|
|
230712
230718
|
}
|
|
230719
|
+
getFileFilteringOptions() {
|
|
230720
|
+
const options2 = this.config.getFileFilteringOptions?.();
|
|
230721
|
+
return {
|
|
230722
|
+
respectGitIgnore: options2?.respectGitIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectGitIgnore,
|
|
230723
|
+
respectQwenIgnore: options2?.respectQwenIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectQwenIgnore
|
|
230724
|
+
};
|
|
230725
|
+
}
|
|
230713
230726
|
};
|
|
230714
230727
|
GlobTool = class _GlobTool extends BaseDeclarativeTool {
|
|
230715
230728
|
static {
|
|
@@ -230718,27 +230731,15 @@ ${fileListDescription}`;
|
|
|
230718
230731
|
config;
|
|
230719
230732
|
static Name = ToolNames.GLOB;
|
|
230720
230733
|
constructor(config) {
|
|
230721
|
-
super(_GlobTool.Name, "FindFiles",
|
|
230734
|
+
super(_GlobTool.Name, "FindFiles", '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.', Kind.Search, {
|
|
230722
230735
|
properties: {
|
|
230723
230736
|
pattern: {
|
|
230724
|
-
description: "The glob pattern to match against
|
|
230737
|
+
description: "The glob pattern to match files against",
|
|
230725
230738
|
type: "string"
|
|
230726
230739
|
},
|
|
230727
230740
|
path: {
|
|
230728
|
-
description:
|
|
230741
|
+
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.',
|
|
230729
230742
|
type: "string"
|
|
230730
|
-
},
|
|
230731
|
-
case_sensitive: {
|
|
230732
|
-
description: "Optional: Whether the search should be case-sensitive. Defaults to false.",
|
|
230733
|
-
type: "boolean"
|
|
230734
|
-
},
|
|
230735
|
-
respect_git_ignore: {
|
|
230736
|
-
description: "Optional: Whether to respect .gitignore patterns when finding files. Only available in git repositories. Defaults to true.",
|
|
230737
|
-
type: "boolean"
|
|
230738
|
-
},
|
|
230739
|
-
respect_qwen_ignore: {
|
|
230740
|
-
description: "Optional: Whether to respect .qwenignore patterns when finding files. Defaults to true.",
|
|
230741
|
-
type: "boolean"
|
|
230742
230743
|
}
|
|
230743
230744
|
},
|
|
230744
230745
|
required: ["pattern"],
|
|
@@ -230750,26 +230751,16 @@ ${fileListDescription}`;
|
|
|
230750
230751
|
* Validates the parameters for the tool.
|
|
230751
230752
|
*/
|
|
230752
230753
|
validateToolParamValues(params) {
|
|
230753
|
-
const searchDirAbsolute = path35.resolve(this.config.getTargetDir(), params.path || ".");
|
|
230754
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
230755
|
-
if (!workspaceContext.isPathWithinWorkspace(searchDirAbsolute)) {
|
|
230756
|
-
const directories = workspaceContext.getDirectories();
|
|
230757
|
-
return `Search path ("${searchDirAbsolute}") resolves outside the allowed workspace directories: ${directories.join(", ")}`;
|
|
230758
|
-
}
|
|
230759
|
-
const targetDir = searchDirAbsolute || this.config.getTargetDir();
|
|
230760
|
-
try {
|
|
230761
|
-
if (!fs32.existsSync(targetDir)) {
|
|
230762
|
-
return `Search path does not exist ${targetDir}`;
|
|
230763
|
-
}
|
|
230764
|
-
if (!fs32.statSync(targetDir).isDirectory()) {
|
|
230765
|
-
return `Search path is not a directory: ${targetDir}`;
|
|
230766
|
-
}
|
|
230767
|
-
} catch (e2) {
|
|
230768
|
-
return `Error accessing search path: ${e2}`;
|
|
230769
|
-
}
|
|
230770
230754
|
if (!params.pattern || typeof params.pattern !== "string" || params.pattern.trim() === "") {
|
|
230771
230755
|
return "The 'pattern' parameter cannot be empty.";
|
|
230772
230756
|
}
|
|
230757
|
+
if (params.path) {
|
|
230758
|
+
try {
|
|
230759
|
+
resolveAndValidatePath(this.config, params.path);
|
|
230760
|
+
} catch (error) {
|
|
230761
|
+
return getErrorMessage(error);
|
|
230762
|
+
}
|
|
230763
|
+
}
|
|
230773
230764
|
return null;
|
|
230774
230765
|
}
|
|
230775
230766
|
createInvocation(params) {
|
|
@@ -230780,12 +230771,11 @@ ${fileListDescription}`;
|
|
|
230780
230771
|
});
|
|
230781
230772
|
|
|
230782
230773
|
// packages/core/dist/src/tools/grep.js
|
|
230783
|
-
import fs33 from "node:fs";
|
|
230784
230774
|
import fsPromises2 from "node:fs/promises";
|
|
230785
230775
|
import path36 from "node:path";
|
|
230786
230776
|
import { EOL as EOL2 } from "node:os";
|
|
230787
230777
|
import { spawn as spawn5 } from "node:child_process";
|
|
230788
|
-
var GrepToolInvocation, GrepTool;
|
|
230778
|
+
var MAX_LLM_CONTENT_LENGTH, GrepToolInvocation, GrepTool;
|
|
230789
230779
|
var init_grep2 = __esm({
|
|
230790
230780
|
"packages/core/dist/src/tools/grep.js"() {
|
|
230791
230781
|
"use strict";
|
|
@@ -230797,6 +230787,7 @@ var init_grep2 = __esm({
|
|
|
230797
230787
|
init_errors();
|
|
230798
230788
|
init_gitUtils();
|
|
230799
230789
|
init_tool_error();
|
|
230790
|
+
MAX_LLM_CONTENT_LENGTH = 2e4;
|
|
230800
230791
|
GrepToolInvocation = class extends BaseToolInvocation {
|
|
230801
230792
|
static {
|
|
230802
230793
|
__name(this, "GrepToolInvocation");
|
|
@@ -230808,89 +230799,34 @@ var init_grep2 = __esm({
|
|
|
230808
230799
|
this.config = config;
|
|
230809
230800
|
this.fileExclusions = config.getFileExclusions();
|
|
230810
230801
|
}
|
|
230811
|
-
/**
|
|
230812
|
-
* Checks if a path is within the root directory and resolves it.
|
|
230813
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
230814
|
-
* @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
|
|
230815
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
230816
|
-
*/
|
|
230817
|
-
resolveAndValidatePath(relativePath) {
|
|
230818
|
-
if (!relativePath) {
|
|
230819
|
-
return null;
|
|
230820
|
-
}
|
|
230821
|
-
const targetPath = path36.resolve(this.config.getTargetDir(), relativePath);
|
|
230822
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
230823
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
230824
|
-
const directories = workspaceContext.getDirectories();
|
|
230825
|
-
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
230826
|
-
}
|
|
230827
|
-
try {
|
|
230828
|
-
const stats = fs33.statSync(targetPath);
|
|
230829
|
-
if (!stats.isDirectory()) {
|
|
230830
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
230831
|
-
}
|
|
230832
|
-
} catch (error) {
|
|
230833
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
230834
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
230835
|
-
}
|
|
230836
|
-
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
230837
|
-
}
|
|
230838
|
-
return targetPath;
|
|
230839
|
-
}
|
|
230840
230802
|
async execute(signal) {
|
|
230841
230803
|
try {
|
|
230842
|
-
const
|
|
230843
|
-
const searchDirAbs = this.resolveAndValidatePath(this.params.path);
|
|
230804
|
+
const searchDirAbs = resolveAndValidatePath(this.config, this.params.path);
|
|
230844
230805
|
const searchDirDisplay = this.params.path || ".";
|
|
230845
|
-
|
|
230846
|
-
|
|
230847
|
-
|
|
230848
|
-
|
|
230849
|
-
|
|
230850
|
-
}
|
|
230851
|
-
|
|
230852
|
-
const
|
|
230853
|
-
|
|
230854
|
-
|
|
230855
|
-
for (const searchDir of searchDirectories) {
|
|
230856
|
-
const matches = await this.performGrepSearch({
|
|
230857
|
-
pattern: this.params.pattern,
|
|
230858
|
-
path: searchDir,
|
|
230859
|
-
include: this.params.include,
|
|
230860
|
-
signal
|
|
230861
|
-
});
|
|
230862
|
-
totalMatchesFound += matches.length;
|
|
230863
|
-
if (searchDirectories.length > 1) {
|
|
230864
|
-
const dirName = path36.basename(searchDir);
|
|
230865
|
-
matches.forEach((match2) => {
|
|
230866
|
-
match2.filePath = path36.join(dirName, match2.filePath);
|
|
230867
|
-
});
|
|
230868
|
-
}
|
|
230869
|
-
const remainingSlots = maxResults - allMatches.length;
|
|
230870
|
-
if (remainingSlots <= 0) {
|
|
230871
|
-
searchTruncated = true;
|
|
230872
|
-
break;
|
|
230873
|
-
}
|
|
230874
|
-
if (matches.length > remainingSlots) {
|
|
230875
|
-
allMatches = allMatches.concat(matches.slice(0, remainingSlots));
|
|
230876
|
-
searchTruncated = true;
|
|
230877
|
-
break;
|
|
230878
|
-
} else {
|
|
230879
|
-
allMatches = allMatches.concat(matches);
|
|
230880
|
-
}
|
|
230881
|
-
}
|
|
230882
|
-
let searchLocationDescription;
|
|
230883
|
-
if (searchDirAbs === null) {
|
|
230884
|
-
const numDirs = workspaceContext.getDirectories().length;
|
|
230885
|
-
searchLocationDescription = numDirs > 1 ? `across ${numDirs} workspace directories` : `in the workspace directory`;
|
|
230886
|
-
} else {
|
|
230887
|
-
searchLocationDescription = `in path "${searchDirDisplay}"`;
|
|
230888
|
-
}
|
|
230889
|
-
if (allMatches.length === 0) {
|
|
230890
|
-
const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}.`;
|
|
230806
|
+
const rawMatches = await this.performGrepSearch({
|
|
230807
|
+
pattern: this.params.pattern,
|
|
230808
|
+
path: searchDirAbs,
|
|
230809
|
+
glob: this.params.glob,
|
|
230810
|
+
signal
|
|
230811
|
+
});
|
|
230812
|
+
const searchLocationDescription = this.params.path ? `in path "${searchDirDisplay}"` : `in the workspace directory`;
|
|
230813
|
+
const filterDescription = this.params.glob ? ` (filter: "${this.params.glob}")` : "";
|
|
230814
|
+
if (rawMatches.length === 0) {
|
|
230815
|
+
const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}.`;
|
|
230891
230816
|
return { llmContent: noMatchMsg, returnDisplay: `No matches found` };
|
|
230892
230817
|
}
|
|
230893
|
-
|
|
230818
|
+
let truncatedByLineLimit = false;
|
|
230819
|
+
let matchesToInclude = rawMatches;
|
|
230820
|
+
if (this.params.limit !== void 0 && rawMatches.length > this.params.limit) {
|
|
230821
|
+
matchesToInclude = rawMatches.slice(0, this.params.limit);
|
|
230822
|
+
truncatedByLineLimit = true;
|
|
230823
|
+
}
|
|
230824
|
+
const totalMatches = rawMatches.length;
|
|
230825
|
+
const matchTerm = totalMatches === 1 ? "match" : "matches";
|
|
230826
|
+
const header = `Found ${totalMatches} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}:
|
|
230827
|
+
---
|
|
230828
|
+
`;
|
|
230829
|
+
const matchesByFile = matchesToInclude.reduce((acc, match2) => {
|
|
230894
230830
|
const fileKey = match2.filePath;
|
|
230895
230831
|
if (!acc[fileKey]) {
|
|
230896
230832
|
acc[fileKey] = [];
|
|
@@ -230899,40 +230835,36 @@ var init_grep2 = __esm({
|
|
|
230899
230835
|
acc[fileKey].sort((a, b) => a.lineNumber - b.lineNumber);
|
|
230900
230836
|
return acc;
|
|
230901
230837
|
}, {});
|
|
230902
|
-
|
|
230903
|
-
const matchTerm = matchCount === 1 ? "match" : "matches";
|
|
230904
|
-
let headerText = `Found ${matchCount} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}`;
|
|
230905
|
-
if (searchTruncated) {
|
|
230906
|
-
headerText += ` (showing first ${matchCount} of ${totalMatchesFound}+ total matches)`;
|
|
230907
|
-
}
|
|
230908
|
-
let llmContent = `${headerText}:
|
|
230909
|
-
---
|
|
230910
|
-
`;
|
|
230838
|
+
let grepOutput = "";
|
|
230911
230839
|
for (const filePath in matchesByFile) {
|
|
230912
|
-
|
|
230840
|
+
grepOutput += `File: ${filePath}
|
|
230913
230841
|
`;
|
|
230914
230842
|
matchesByFile[filePath].forEach((match2) => {
|
|
230915
230843
|
const trimmedLine = match2.line.trim();
|
|
230916
|
-
|
|
230844
|
+
grepOutput += `L${match2.lineNumber}: ${trimmedLine}
|
|
230917
230845
|
`;
|
|
230918
230846
|
});
|
|
230919
|
-
|
|
230847
|
+
grepOutput += "---\n";
|
|
230920
230848
|
}
|
|
230921
|
-
|
|
230922
|
-
|
|
230923
|
-
|
|
230924
|
-
|
|
230925
|
-
|
|
230926
|
-
|
|
230927
|
-
|
|
230849
|
+
let truncatedByCharLimit = false;
|
|
230850
|
+
if (grepOutput.length > MAX_LLM_CONTENT_LENGTH) {
|
|
230851
|
+
grepOutput = grepOutput.slice(0, MAX_LLM_CONTENT_LENGTH) + "...";
|
|
230852
|
+
truncatedByCharLimit = true;
|
|
230853
|
+
}
|
|
230854
|
+
const finalLines = grepOutput.split("\n").filter((line) => line.trim() && !line.startsWith("File:") && !line.startsWith("---"));
|
|
230855
|
+
const includedLines = finalLines.length;
|
|
230856
|
+
let llmContent = header + grepOutput;
|
|
230857
|
+
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
230858
|
+
const omittedMatches = totalMatches - includedLines;
|
|
230859
|
+
llmContent += ` [${omittedMatches} ${omittedMatches === 1 ? "line" : "lines"} truncated] ...`;
|
|
230928
230860
|
}
|
|
230929
|
-
let
|
|
230930
|
-
if (
|
|
230931
|
-
|
|
230861
|
+
let displayMessage = `Found ${totalMatches} ${matchTerm}`;
|
|
230862
|
+
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
230863
|
+
displayMessage += ` (truncated)`;
|
|
230932
230864
|
}
|
|
230933
230865
|
return {
|
|
230934
230866
|
llmContent: llmContent.trim(),
|
|
230935
|
-
returnDisplay:
|
|
230867
|
+
returnDisplay: displayMessage
|
|
230936
230868
|
};
|
|
230937
230869
|
} catch (error) {
|
|
230938
230870
|
console.error(`Error during GrepLogic execution: ${error}`);
|
|
@@ -231011,34 +230943,19 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231011
230943
|
* @returns A string describing the grep
|
|
231012
230944
|
*/
|
|
231013
230945
|
getDescription() {
|
|
231014
|
-
let description = `'${this.params.pattern}'`;
|
|
231015
|
-
if (this.params.
|
|
231016
|
-
description += `
|
|
231017
|
-
}
|
|
231018
|
-
if (this.params.path) {
|
|
231019
|
-
const resolvedPath = path36.resolve(this.config.getTargetDir(), this.params.path);
|
|
231020
|
-
if (resolvedPath === this.config.getTargetDir() || this.params.path === ".") {
|
|
231021
|
-
description += ` within ./`;
|
|
231022
|
-
} else {
|
|
231023
|
-
const relativePath = makeRelative(resolvedPath, this.config.getTargetDir());
|
|
231024
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
231025
|
-
}
|
|
231026
|
-
} else {
|
|
231027
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
231028
|
-
const directories = workspaceContext.getDirectories();
|
|
231029
|
-
if (directories.length > 1) {
|
|
231030
|
-
description += ` across all workspace directories`;
|
|
231031
|
-
}
|
|
230946
|
+
let description = `'${this.params.pattern}' in path '${this.params.path || "./"}'`;
|
|
230947
|
+
if (this.params.glob) {
|
|
230948
|
+
description += ` (filter: '${this.params.glob}')`;
|
|
231032
230949
|
}
|
|
231033
230950
|
return description;
|
|
231034
230951
|
}
|
|
231035
230952
|
/**
|
|
231036
230953
|
* Performs the actual search using the prioritized strategies.
|
|
231037
|
-
* @param options Search options including pattern, absolute path, and
|
|
230954
|
+
* @param options Search options including pattern, absolute path, and glob filter.
|
|
231038
230955
|
* @returns A promise resolving to an array of match objects.
|
|
231039
230956
|
*/
|
|
231040
230957
|
async performGrepSearch(options2) {
|
|
231041
|
-
const { pattern, path: absolutePath,
|
|
230958
|
+
const { pattern, path: absolutePath, glob: glob2 } = options2;
|
|
231042
230959
|
let strategyUsed = "none";
|
|
231043
230960
|
try {
|
|
231044
230961
|
const isGit = isGitRepository(absolutePath);
|
|
@@ -231053,8 +230970,8 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231053
230970
|
"--ignore-case",
|
|
231054
230971
|
pattern
|
|
231055
230972
|
];
|
|
231056
|
-
if (
|
|
231057
|
-
gitArgs.push("--",
|
|
230973
|
+
if (glob2) {
|
|
230974
|
+
gitArgs.push("--", glob2);
|
|
231058
230975
|
}
|
|
231059
230976
|
try {
|
|
231060
230977
|
const output = await new Promise((resolve24, reject) => {
|
|
@@ -231104,8 +231021,8 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231104
231021
|
return null;
|
|
231105
231022
|
}).filter((dir) => !!dir);
|
|
231106
231023
|
commonExcludes.forEach((dir) => grepArgs.push(`--exclude-dir=${dir}`));
|
|
231107
|
-
if (
|
|
231108
|
-
grepArgs.push(`--include=${
|
|
231024
|
+
if (glob2) {
|
|
231025
|
+
grepArgs.push(`--include=${glob2}`);
|
|
231109
231026
|
}
|
|
231110
231027
|
grepArgs.push(pattern);
|
|
231111
231028
|
grepArgs.push(".");
|
|
@@ -231164,7 +231081,7 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231164
231081
|
}
|
|
231165
231082
|
console.debug("GrepLogic: Falling back to JavaScript grep implementation.");
|
|
231166
231083
|
strategyUsed = "javascript fallback";
|
|
231167
|
-
const globPattern =
|
|
231084
|
+
const globPattern = glob2 ? glob2 : "**/*";
|
|
231168
231085
|
const ignorePatterns = this.fileExclusions.getGlobExcludes();
|
|
231169
231086
|
const filesIterator = globStream(globPattern, {
|
|
231170
231087
|
cwd: absolutePath,
|
|
@@ -231210,25 +231127,23 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231210
231127
|
config;
|
|
231211
231128
|
static Name = ToolNames.GREP;
|
|
231212
231129
|
constructor(config) {
|
|
231213
|
-
super(_GrepTool.Name, "
|
|
231130
|
+
super(_GrepTool.Name, "Grep", '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', Kind.Search, {
|
|
231214
231131
|
properties: {
|
|
231215
231132
|
pattern: {
|
|
231216
|
-
|
|
231217
|
-
|
|
231133
|
+
type: "string",
|
|
231134
|
+
description: "The regular expression pattern to search for in file contents"
|
|
231218
231135
|
},
|
|
231219
|
-
|
|
231220
|
-
|
|
231221
|
-
|
|
231136
|
+
glob: {
|
|
231137
|
+
type: "string",
|
|
231138
|
+
description: 'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}")'
|
|
231222
231139
|
},
|
|
231223
|
-
|
|
231224
|
-
|
|
231225
|
-
|
|
231140
|
+
path: {
|
|
231141
|
+
type: "string",
|
|
231142
|
+
description: "File or directory to search in. Defaults to current working directory."
|
|
231226
231143
|
},
|
|
231227
|
-
|
|
231228
|
-
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.",
|
|
231144
|
+
limit: {
|
|
231229
231145
|
type: "number",
|
|
231230
|
-
|
|
231231
|
-
maximum: 100
|
|
231146
|
+
description: "Limit output to first N matching lines. Optional - shows all matches if not specified."
|
|
231232
231147
|
}
|
|
231233
231148
|
},
|
|
231234
231149
|
required: ["pattern"],
|
|
@@ -231236,35 +231151,6 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231236
231151
|
});
|
|
231237
231152
|
this.config = config;
|
|
231238
231153
|
}
|
|
231239
|
-
/**
|
|
231240
|
-
* Checks if a path is within the root directory and resolves it.
|
|
231241
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
231242
|
-
* @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
|
|
231243
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
231244
|
-
*/
|
|
231245
|
-
resolveAndValidatePath(relativePath) {
|
|
231246
|
-
if (!relativePath) {
|
|
231247
|
-
return null;
|
|
231248
|
-
}
|
|
231249
|
-
const targetPath = path36.resolve(this.config.getTargetDir(), relativePath);
|
|
231250
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
231251
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
231252
|
-
const directories = workspaceContext.getDirectories();
|
|
231253
|
-
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
231254
|
-
}
|
|
231255
|
-
try {
|
|
231256
|
-
const stats = fs33.statSync(targetPath);
|
|
231257
|
-
if (!stats.isDirectory()) {
|
|
231258
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
231259
|
-
}
|
|
231260
|
-
} catch (error) {
|
|
231261
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
231262
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
231263
|
-
}
|
|
231264
|
-
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
231265
|
-
}
|
|
231266
|
-
return targetPath;
|
|
231267
|
-
}
|
|
231268
231154
|
/**
|
|
231269
231155
|
* Validates the parameters for the tool
|
|
231270
231156
|
* @param params Parameters to validate
|
|
@@ -231274,16 +231160,11 @@ WARNING: Results truncated to prevent context overflow. To see more results:
|
|
|
231274
231160
|
try {
|
|
231275
231161
|
new RegExp(params.pattern);
|
|
231276
231162
|
} catch (error) {
|
|
231277
|
-
return `Invalid regular expression pattern
|
|
231278
|
-
}
|
|
231279
|
-
if (params.maxResults !== void 0) {
|
|
231280
|
-
if (!Number.isInteger(params.maxResults) || params.maxResults < 1 || params.maxResults > 100) {
|
|
231281
|
-
return `maxResults must be an integer between 1 and 100, got: ${params.maxResults}`;
|
|
231282
|
-
}
|
|
231163
|
+
return `Invalid regular expression pattern: ${params.pattern}. Error: ${getErrorMessage(error)}`;
|
|
231283
231164
|
}
|
|
231284
231165
|
if (params.path) {
|
|
231285
231166
|
try {
|
|
231286
|
-
this.
|
|
231167
|
+
resolveAndValidatePath(this.config, params.path);
|
|
231287
231168
|
} catch (error) {
|
|
231288
231169
|
return getErrorMessage(error);
|
|
231289
231170
|
}
|
|
@@ -231944,7 +231825,7 @@ import fs36 from "node:fs";
|
|
|
231944
231825
|
import path40 from "node:path";
|
|
231945
231826
|
import { EOL as EOL3 } from "node:os";
|
|
231946
231827
|
import { spawn as spawn6 } from "node:child_process";
|
|
231947
|
-
var
|
|
231828
|
+
var MAX_LLM_CONTENT_LENGTH2, GrepToolInvocation2, RipGrepTool;
|
|
231948
231829
|
var init_ripGrep = __esm({
|
|
231949
231830
|
"packages/core/dist/src/tools/ripGrep.js"() {
|
|
231950
231831
|
"use strict";
|
|
@@ -231956,7 +231837,7 @@ var init_ripGrep = __esm({
|
|
|
231956
231837
|
init_ripgrepUtils();
|
|
231957
231838
|
init_schemaValidator();
|
|
231958
231839
|
init_constants3();
|
|
231959
|
-
|
|
231840
|
+
MAX_LLM_CONTENT_LENGTH2 = 2e4;
|
|
231960
231841
|
GrepToolInvocation2 = class extends BaseToolInvocation {
|
|
231961
231842
|
static {
|
|
231962
231843
|
__name(this, "GrepToolInvocation");
|
|
@@ -231966,39 +231847,9 @@ var init_ripGrep = __esm({
|
|
|
231966
231847
|
super(params);
|
|
231967
231848
|
this.config = config;
|
|
231968
231849
|
}
|
|
231969
|
-
/**
|
|
231970
|
-
* Checks if a path is within the root directory and resolves it.
|
|
231971
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
231972
|
-
* @returns The absolute path to search within.
|
|
231973
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
231974
|
-
*/
|
|
231975
|
-
resolveAndValidatePath(relativePath) {
|
|
231976
|
-
const targetDir = this.config.getTargetDir();
|
|
231977
|
-
const targetPath = relativePath ? path40.resolve(targetDir, relativePath) : targetDir;
|
|
231978
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
231979
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
231980
|
-
const directories = workspaceContext.getDirectories();
|
|
231981
|
-
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
231982
|
-
}
|
|
231983
|
-
return this.ensureDirectory(targetPath);
|
|
231984
|
-
}
|
|
231985
|
-
ensureDirectory(targetPath) {
|
|
231986
|
-
try {
|
|
231987
|
-
const stats = fs36.statSync(targetPath);
|
|
231988
|
-
if (!stats.isDirectory()) {
|
|
231989
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
231990
|
-
}
|
|
231991
|
-
} catch (error) {
|
|
231992
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
231993
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
231994
|
-
}
|
|
231995
|
-
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
231996
|
-
}
|
|
231997
|
-
return targetPath;
|
|
231998
|
-
}
|
|
231999
231850
|
async execute(signal) {
|
|
232000
231851
|
try {
|
|
232001
|
-
const searchDirAbs =
|
|
231852
|
+
const searchDirAbs = resolveAndValidatePath(this.config, this.params.path, { allowFiles: true });
|
|
232002
231853
|
const searchDirDisplay = this.params.path || ".";
|
|
232003
231854
|
const rawOutput = await this.performRipgrepSearch({
|
|
232004
231855
|
pattern: this.params.pattern,
|
|
@@ -232018,26 +231869,36 @@ var init_ripGrep = __esm({
|
|
|
232018
231869
|
const header = `Found ${totalMatches} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}:
|
|
232019
231870
|
---
|
|
232020
231871
|
`;
|
|
232021
|
-
const maxTruncationNoticeLength = 100;
|
|
232022
|
-
const maxGrepOutputLength = MAX_LLM_CONTENT_LENGTH - header.length - maxTruncationNoticeLength;
|
|
232023
231872
|
let truncatedByLineLimit = false;
|
|
232024
231873
|
let linesToInclude = allLines;
|
|
232025
231874
|
if (this.params.limit !== void 0 && allLines.length > this.params.limit) {
|
|
232026
231875
|
linesToInclude = allLines.slice(0, this.params.limit);
|
|
232027
231876
|
truncatedByLineLimit = true;
|
|
232028
231877
|
}
|
|
232029
|
-
|
|
231878
|
+
const parts = [];
|
|
231879
|
+
let includedLines = 0;
|
|
232030
231880
|
let truncatedByCharLimit = false;
|
|
232031
|
-
|
|
232032
|
-
|
|
232033
|
-
|
|
231881
|
+
let currentLength = 0;
|
|
231882
|
+
for (const line of linesToInclude) {
|
|
231883
|
+
const sep7 = includedLines > 0 ? 1 : 0;
|
|
231884
|
+
includedLines++;
|
|
231885
|
+
if (currentLength + line.length <= MAX_LLM_CONTENT_LENGTH2) {
|
|
231886
|
+
parts.push(line);
|
|
231887
|
+
currentLength = currentLength + line.length + sep7;
|
|
231888
|
+
} else {
|
|
231889
|
+
const remaining = Math.max(MAX_LLM_CONTENT_LENGTH2 - currentLength - sep7, 10);
|
|
231890
|
+
parts.push(line.slice(0, remaining) + "...");
|
|
231891
|
+
truncatedByCharLimit = true;
|
|
231892
|
+
break;
|
|
231893
|
+
}
|
|
232034
231894
|
}
|
|
232035
|
-
const
|
|
232036
|
-
const includedLines = finalLines.length;
|
|
231895
|
+
const grepOutput = parts.join("\n");
|
|
232037
231896
|
let llmContent = header + grepOutput;
|
|
232038
231897
|
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
232039
231898
|
const omittedMatches = totalMatches - includedLines;
|
|
232040
|
-
llmContent += `
|
|
231899
|
+
llmContent += `
|
|
231900
|
+
---
|
|
231901
|
+
[${omittedMatches} ${omittedMatches === 1 ? "line" : "lines"} truncated] ...`;
|
|
232041
231902
|
}
|
|
232042
231903
|
let displayMessage = `Found ${totalMatches} ${matchTerm}`;
|
|
232043
231904
|
if (truncatedByLineLimit || truncatedByCharLimit) {
|
|
@@ -232133,23 +231994,11 @@ var init_ripGrep = __esm({
|
|
|
232133
231994
|
*/
|
|
232134
231995
|
getDescription() {
|
|
232135
231996
|
let description = `'${this.params.pattern}'`;
|
|
232136
|
-
if (this.params.glob) {
|
|
232137
|
-
description += ` in ${this.params.glob}`;
|
|
232138
|
-
}
|
|
232139
231997
|
if (this.params.path) {
|
|
232140
|
-
|
|
232141
|
-
|
|
232142
|
-
|
|
232143
|
-
|
|
232144
|
-
const relativePath = makeRelative(resolvedPath, this.config.getTargetDir());
|
|
232145
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
232146
|
-
}
|
|
232147
|
-
} else {
|
|
232148
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
232149
|
-
const directories = workspaceContext.getDirectories();
|
|
232150
|
-
if (directories.length > 1) {
|
|
232151
|
-
description += ` across all workspace directories`;
|
|
232152
|
-
}
|
|
231998
|
+
description += ` in path '${this.params.path}'`;
|
|
231999
|
+
}
|
|
232000
|
+
if (this.params.glob) {
|
|
232001
|
+
description += ` (filter: '${this.params.glob}')`;
|
|
232153
232002
|
}
|
|
232154
232003
|
return description;
|
|
232155
232004
|
}
|
|
@@ -232185,35 +232034,6 @@ var init_ripGrep = __esm({
|
|
|
232185
232034
|
});
|
|
232186
232035
|
this.config = config;
|
|
232187
232036
|
}
|
|
232188
|
-
/**
|
|
232189
|
-
* Checks if a path is within the root directory and resolves it.
|
|
232190
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
232191
|
-
* @returns The absolute path to search within.
|
|
232192
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
232193
|
-
*/
|
|
232194
|
-
resolveAndValidatePath(relativePath) {
|
|
232195
|
-
if (!relativePath) {
|
|
232196
|
-
return this.config.getTargetDir();
|
|
232197
|
-
}
|
|
232198
|
-
const targetPath = path40.resolve(this.config.getTargetDir(), relativePath);
|
|
232199
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
232200
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
232201
|
-
const directories = workspaceContext.getDirectories();
|
|
232202
|
-
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
232203
|
-
}
|
|
232204
|
-
try {
|
|
232205
|
-
const stats = fs36.statSync(targetPath);
|
|
232206
|
-
if (!stats.isDirectory()) {
|
|
232207
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
232208
|
-
}
|
|
232209
|
-
} catch (error) {
|
|
232210
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
232211
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
232212
|
-
}
|
|
232213
|
-
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
232214
|
-
}
|
|
232215
|
-
return targetPath;
|
|
232216
|
-
}
|
|
232217
232037
|
/**
|
|
232218
232038
|
* Validates the parameters for the tool
|
|
232219
232039
|
* @param params Parameters to validate
|
|
@@ -232231,7 +232051,7 @@ var init_ripGrep = __esm({
|
|
|
232231
232051
|
}
|
|
232232
232052
|
if (params.path) {
|
|
232233
232053
|
try {
|
|
232234
|
-
this.
|
|
232054
|
+
resolveAndValidatePath(this.config, params.path, { allowFiles: true });
|
|
232235
232055
|
} catch (error) {
|
|
232236
232056
|
return getErrorMessage(error);
|
|
232237
232057
|
}
|
|
@@ -316649,7 +316469,7 @@ init_esbuild_shims();
|
|
|
316649
316469
|
|
|
316650
316470
|
// packages/cli/src/generated/git-commit.ts
|
|
316651
316471
|
init_esbuild_shims();
|
|
316652
|
-
var GIT_COMMIT_INFO2 = "
|
|
316472
|
+
var GIT_COMMIT_INFO2 = "bc3a1686";
|
|
316653
316473
|
|
|
316654
316474
|
// packages/cli/src/ui/components/AboutBox.tsx
|
|
316655
316475
|
var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -338496,7 +338316,7 @@ import { homedir as homedir16 } from "node:os";
|
|
|
338496
338316
|
init_esbuild_shims();
|
|
338497
338317
|
import * as os26 from "node:os";
|
|
338498
338318
|
import * as path76 from "node:path";
|
|
338499
|
-
function
|
|
338319
|
+
function resolvePath2(p) {
|
|
338500
338320
|
if (!p) {
|
|
338501
338321
|
return "";
|
|
338502
338322
|
}
|
|
@@ -338508,7 +338328,7 @@ function resolvePath(p) {
|
|
|
338508
338328
|
}
|
|
338509
338329
|
return path76.normalize(expandedPath);
|
|
338510
338330
|
}
|
|
338511
|
-
__name(
|
|
338331
|
+
__name(resolvePath2, "resolvePath");
|
|
338512
338332
|
|
|
338513
338333
|
// packages/cli/src/utils/version.ts
|
|
338514
338334
|
init_esbuild_shims();
|
|
@@ -338744,7 +338564,7 @@ __name(getPackageJson, "getPackageJson");
|
|
|
338744
338564
|
// packages/cli/src/utils/version.ts
|
|
338745
338565
|
async function getCliVersion() {
|
|
338746
338566
|
const pkgJson = await getPackageJson();
|
|
338747
|
-
return "0.1.
|
|
338567
|
+
return "0.1.5-nightly.20251107.d17c37af";
|
|
338748
338568
|
}
|
|
338749
338569
|
__name(getCliVersion, "getCliVersion");
|
|
338750
338570
|
|
|
@@ -339541,7 +339361,7 @@ async function loadCliConfig(settings, extensions, extensionEnablementManager, s
|
|
|
339541
339361
|
...DEFAULT_MEMORY_FILE_FILTERING_OPTIONS,
|
|
339542
339362
|
...settings.context?.fileFiltering
|
|
339543
339363
|
};
|
|
339544
|
-
const includeDirectories = (settings.context?.includeDirectories || []).map(
|
|
339364
|
+
const includeDirectories = (settings.context?.includeDirectories || []).map(resolvePath2).concat((argv.includeDirectories || []).map(resolvePath2));
|
|
339545
339365
|
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
|
339546
339366
|
cwd7,
|
|
339547
339367
|
settings.context?.loadMemoryFromIncludeDirectories ? includeDirectories : [],
|