@probelabs/probe 0.6.0-rc270 → 0.6.0-rc271
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/bin/binaries/probe-v0.6.0-rc271-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/{probe-v0.6.0-rc270-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc271-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/probe-v0.6.0-rc271-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc271-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/{probe-v0.6.0-rc270-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc271-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/index.js +71 -22
- package/build/tools/vercel.js +66 -5
- package/cjs/agent/ProbeAgent.cjs +106 -57
- package/cjs/index.cjs +81 -32
- package/package.json +1 -1
- package/src/tools/vercel.js +66 -5
- package/bin/binaries/probe-v0.6.0-rc270-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc270-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc270-x86_64-pc-windows-msvc.zip +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/build/agent/index.js
CHANGED
|
@@ -9045,6 +9045,7 @@ var init_hashline = __esm({
|
|
|
9045
9045
|
|
|
9046
9046
|
// src/tools/vercel.js
|
|
9047
9047
|
import { tool } from "ai";
|
|
9048
|
+
import { existsSync } from "fs";
|
|
9048
9049
|
function normalizeTargets(targets) {
|
|
9049
9050
|
if (!Array.isArray(targets)) return [];
|
|
9050
9051
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -9121,6 +9122,17 @@ function parseDelegatedTargets(rawResponse) {
|
|
|
9121
9122
|
}
|
|
9122
9123
|
return normalizeTargets(fallbackTargetsFromText(trimmed));
|
|
9123
9124
|
}
|
|
9125
|
+
function splitTargetSuffix(target) {
|
|
9126
|
+
const searchStart = target.length > 2 && target[1] === ":" && /[a-zA-Z]/.test(target[0]) ? 2 : 0;
|
|
9127
|
+
const colonIdx = target.indexOf(":", searchStart);
|
|
9128
|
+
const hashIdx = target.indexOf("#");
|
|
9129
|
+
if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
|
|
9130
|
+
return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
|
|
9131
|
+
} else if (hashIdx !== -1) {
|
|
9132
|
+
return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
|
|
9133
|
+
}
|
|
9134
|
+
return { filePart: target, suffix: "" };
|
|
9135
|
+
}
|
|
9124
9136
|
function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
|
|
9125
9137
|
return [
|
|
9126
9138
|
"You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.",
|
|
@@ -9284,10 +9296,47 @@ var init_vercel = __esm({
|
|
|
9284
9296
|
}
|
|
9285
9297
|
return fallbackResult;
|
|
9286
9298
|
}
|
|
9299
|
+
const delegateBase = options.allowedFolders?.[0] || options.cwd || ".";
|
|
9287
9300
|
const resolutionBase = searchPaths[0] || options.cwd || ".";
|
|
9288
|
-
const resolvedTargets = targets.map((target) => resolveTargetPath(target,
|
|
9301
|
+
const resolvedTargets = targets.map((target) => resolveTargetPath(target, delegateBase));
|
|
9302
|
+
const validatedTargets = [];
|
|
9303
|
+
for (const target of resolvedTargets) {
|
|
9304
|
+
const { filePart, suffix } = splitTargetSuffix(target);
|
|
9305
|
+
if (existsSync(filePart)) {
|
|
9306
|
+
validatedTargets.push(target);
|
|
9307
|
+
continue;
|
|
9308
|
+
}
|
|
9309
|
+
let fixed = false;
|
|
9310
|
+
const parts = filePart.split("/").filter(Boolean);
|
|
9311
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
9312
|
+
if (parts[i] === parts[i + 1]) {
|
|
9313
|
+
const candidate = "/" + [...parts.slice(0, i), ...parts.slice(i + 1)].join("/");
|
|
9314
|
+
if (existsSync(candidate)) {
|
|
9315
|
+
validatedTargets.push(candidate + suffix);
|
|
9316
|
+
if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} \u2192 ${candidate}`);
|
|
9317
|
+
fixed = true;
|
|
9318
|
+
break;
|
|
9319
|
+
}
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9322
|
+
if (fixed) continue;
|
|
9323
|
+
for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
|
|
9324
|
+
if (altBase === delegateBase) continue;
|
|
9325
|
+
const altResolved = resolveTargetPath(target, altBase);
|
|
9326
|
+
const { filePart: altFile } = splitTargetSuffix(altResolved);
|
|
9327
|
+
if (existsSync(altFile)) {
|
|
9328
|
+
validatedTargets.push(altResolved);
|
|
9329
|
+
if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} \u2192 ${altFile}`);
|
|
9330
|
+
fixed = true;
|
|
9331
|
+
break;
|
|
9332
|
+
}
|
|
9333
|
+
}
|
|
9334
|
+
if (fixed) continue;
|
|
9335
|
+
if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
|
|
9336
|
+
validatedTargets.push(target);
|
|
9337
|
+
}
|
|
9289
9338
|
const extractOptions = {
|
|
9290
|
-
files:
|
|
9339
|
+
files: validatedTargets,
|
|
9291
9340
|
cwd: resolutionBase,
|
|
9292
9341
|
allowTests: allow_tests ?? true
|
|
9293
9342
|
};
|
|
@@ -10805,7 +10854,7 @@ var init_bashPermissions = __esm({
|
|
|
10805
10854
|
// src/agent/bashExecutor.js
|
|
10806
10855
|
import { spawn as spawn2 } from "child_process";
|
|
10807
10856
|
import { resolve as resolve2, join } from "path";
|
|
10808
|
-
import { existsSync } from "fs";
|
|
10857
|
+
import { existsSync as existsSync2 } from "fs";
|
|
10809
10858
|
function splitCommandComponents(command) {
|
|
10810
10859
|
const parts = [];
|
|
10811
10860
|
let current2 = "";
|
|
@@ -10935,7 +10984,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
10935
10984
|
let cwd = workingDirectory;
|
|
10936
10985
|
try {
|
|
10937
10986
|
cwd = resolve2(cwd);
|
|
10938
|
-
if (!
|
|
10987
|
+
if (!existsSync2(cwd)) {
|
|
10939
10988
|
throw new Error(`Working directory does not exist: ${cwd}`);
|
|
10940
10989
|
}
|
|
10941
10990
|
} catch (error) {
|
|
@@ -11191,7 +11240,7 @@ function validateExecutionOptions(options = {}) {
|
|
|
11191
11240
|
if (options.workingDirectory) {
|
|
11192
11241
|
if (typeof options.workingDirectory !== "string") {
|
|
11193
11242
|
errors.push("workingDirectory must be a string");
|
|
11194
|
-
} else if (!
|
|
11243
|
+
} else if (!existsSync2(options.workingDirectory)) {
|
|
11195
11244
|
errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
|
|
11196
11245
|
}
|
|
11197
11246
|
}
|
|
@@ -11716,7 +11765,7 @@ var init_lineEditHeuristics = __esm({
|
|
|
11716
11765
|
import { tool as tool3 } from "ai";
|
|
11717
11766
|
import { promises as fs6 } from "fs";
|
|
11718
11767
|
import { dirname, resolve as resolve4, isAbsolute as isAbsolute3, sep as sep2 } from "path";
|
|
11719
|
-
import { existsSync as
|
|
11768
|
+
import { existsSync as existsSync3 } from "fs";
|
|
11720
11769
|
function isPathAllowed(filePath, allowedFolders) {
|
|
11721
11770
|
if (!allowedFolders || allowedFolders.length === 0) {
|
|
11722
11771
|
const resolvedPath2 = safeRealpath(filePath);
|
|
@@ -11994,7 +12043,7 @@ Parameters:
|
|
|
11994
12043
|
const relativePath = toRelativePath(resolvedPath, workspaceRoot);
|
|
11995
12044
|
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
11996
12045
|
}
|
|
11997
|
-
if (!
|
|
12046
|
+
if (!existsSync3(resolvedPath)) {
|
|
11998
12047
|
return `Error editing file: File not found - ${file_path}. Verify the path is correct and the file exists. Use 'search' to find files by name, or 'create' to make a new file.`;
|
|
11999
12048
|
}
|
|
12000
12049
|
if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath)) {
|
|
@@ -12127,10 +12176,10 @@ Important:
|
|
|
12127
12176
|
const relativePath = toRelativePath(resolvedPath, workspaceRoot);
|
|
12128
12177
|
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
12129
12178
|
}
|
|
12130
|
-
if (
|
|
12179
|
+
if (existsSync3(resolvedPath) && !overwrite) {
|
|
12131
12180
|
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
12132
12181
|
}
|
|
12133
|
-
const existed =
|
|
12182
|
+
const existed = existsSync3(resolvedPath);
|
|
12134
12183
|
const dir = dirname(resolvedPath);
|
|
12135
12184
|
await fs6.mkdir(dir, { recursive: true });
|
|
12136
12185
|
await fs6.writeFile(resolvedPath, content, "utf-8");
|
|
@@ -30374,7 +30423,7 @@ var init_fileTracker = __esm({
|
|
|
30374
30423
|
});
|
|
30375
30424
|
|
|
30376
30425
|
// src/agent/simpleTelemetry.js
|
|
30377
|
-
import { existsSync as
|
|
30426
|
+
import { existsSync as existsSync4, mkdirSync, createWriteStream } from "fs";
|
|
30378
30427
|
import { dirname as dirname2 } from "path";
|
|
30379
30428
|
function initializeSimpleTelemetryFromOptions(options) {
|
|
30380
30429
|
const telemetry = new SimpleTelemetry({
|
|
@@ -30403,7 +30452,7 @@ var init_simpleTelemetry = __esm({
|
|
|
30403
30452
|
initializeFileExporter() {
|
|
30404
30453
|
try {
|
|
30405
30454
|
const dir = dirname2(this.filePath);
|
|
30406
|
-
if (!
|
|
30455
|
+
if (!existsSync4(dir)) {
|
|
30407
30456
|
mkdirSync(dir, { recursive: true });
|
|
30408
30457
|
}
|
|
30409
30458
|
this.stream = createWriteStream(this.filePath, { flags: "a" });
|
|
@@ -70834,7 +70883,7 @@ When troubleshooting:
|
|
|
70834
70883
|
});
|
|
70835
70884
|
|
|
70836
70885
|
// src/agent/mcp/config.js
|
|
70837
|
-
import { readFileSync, existsSync as
|
|
70886
|
+
import { readFileSync, existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
70838
70887
|
import { join as join2, dirname as dirname3 } from "path";
|
|
70839
70888
|
import { homedir } from "os";
|
|
70840
70889
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
@@ -70889,7 +70938,7 @@ function loadMCPConfigurationFromPath(configPath) {
|
|
|
70889
70938
|
if (!configPath) {
|
|
70890
70939
|
throw new Error("Config path is required");
|
|
70891
70940
|
}
|
|
70892
|
-
if (!
|
|
70941
|
+
if (!existsSync5(configPath)) {
|
|
70893
70942
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
70894
70943
|
}
|
|
70895
70944
|
try {
|
|
@@ -70918,7 +70967,7 @@ function loadMCPConfiguration() {
|
|
|
70918
70967
|
].filter(Boolean);
|
|
70919
70968
|
let config = null;
|
|
70920
70969
|
for (const configPath of configPaths) {
|
|
70921
|
-
if (
|
|
70970
|
+
if (existsSync5(configPath)) {
|
|
70922
70971
|
try {
|
|
70923
70972
|
const content = readFileSync(configPath, "utf8");
|
|
70924
70973
|
config = JSON.parse(content);
|
|
@@ -79122,7 +79171,7 @@ var init_parser7 = __esm({
|
|
|
79122
79171
|
});
|
|
79123
79172
|
|
|
79124
79173
|
// src/agent/skills/registry.js
|
|
79125
|
-
import { existsSync as
|
|
79174
|
+
import { existsSync as existsSync6 } from "fs";
|
|
79126
79175
|
import { readdir as readdir2, readFile as readFile2, realpath as realpath2, lstat as lstat2 } from "fs/promises";
|
|
79127
79176
|
import { resolve as resolve6, join as join3, isAbsolute as isAbsolute5, sep as sep4, relative } from "path";
|
|
79128
79177
|
function isPathInside(basePath, targetPath) {
|
|
@@ -79215,7 +79264,7 @@ var init_registry = __esm({
|
|
|
79215
79264
|
return resolvedReal;
|
|
79216
79265
|
}
|
|
79217
79266
|
async _scanSkillDir(dirPath) {
|
|
79218
|
-
if (!
|
|
79267
|
+
if (!existsSync6(dirPath)) return [];
|
|
79219
79268
|
let entries;
|
|
79220
79269
|
try {
|
|
79221
79270
|
entries = await readdir2(dirPath, { withFileTypes: true });
|
|
@@ -79255,7 +79304,7 @@ var init_registry = __esm({
|
|
|
79255
79304
|
}
|
|
79256
79305
|
continue;
|
|
79257
79306
|
}
|
|
79258
|
-
if (!
|
|
79307
|
+
if (!existsSync6(skillFilePath)) continue;
|
|
79259
79308
|
const { skill, error } = await parseSkillFile(skillFilePath, entry.name);
|
|
79260
79309
|
if (!skill) {
|
|
79261
79310
|
if (error) {
|
|
@@ -81771,7 +81820,7 @@ import { createAmazonBedrock as createAmazonBedrock2 } from "@ai-sdk/amazon-bedr
|
|
|
81771
81820
|
import { streamText as streamText2, tool as tool5, stepCountIs, jsonSchema } from "ai";
|
|
81772
81821
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
81773
81822
|
import { EventEmitter as EventEmitter5 } from "events";
|
|
81774
|
-
import { existsSync as
|
|
81823
|
+
import { existsSync as existsSync7 } from "fs";
|
|
81775
81824
|
import { readFile as readFile3, stat, readdir as readdir3 } from "fs/promises";
|
|
81776
81825
|
import { resolve as resolve7, isAbsolute as isAbsolute6, dirname as dirname5, basename, normalize as normalize2, sep as sep5 } from "path";
|
|
81777
81826
|
var ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
@@ -83782,7 +83831,7 @@ var init_ProbeAgent = __esm({
|
|
|
83782
83831
|
} else {
|
|
83783
83832
|
guidanceCandidates = ["agents.md", "claude.md"];
|
|
83784
83833
|
}
|
|
83785
|
-
if (!
|
|
83834
|
+
if (!existsSync7(rootDirectory)) {
|
|
83786
83835
|
this._architectureContextLoaded = true;
|
|
83787
83836
|
return null;
|
|
83788
83837
|
}
|
|
@@ -85351,7 +85400,7 @@ import {
|
|
|
85351
85400
|
ListToolsRequestSchema as ListToolsRequestSchema2,
|
|
85352
85401
|
McpError
|
|
85353
85402
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
85354
|
-
import { readFileSync as readFileSync2, existsSync as
|
|
85403
|
+
import { readFileSync as readFileSync2, existsSync as existsSync8 } from "fs";
|
|
85355
85404
|
import { resolve as resolve8 } from "path";
|
|
85356
85405
|
|
|
85357
85406
|
// src/agent/acp/server.js
|
|
@@ -86027,7 +86076,7 @@ function readInputContent(input) {
|
|
|
86027
86076
|
if (!input) return null;
|
|
86028
86077
|
try {
|
|
86029
86078
|
const resolvedPath = resolve8(input);
|
|
86030
|
-
if (
|
|
86079
|
+
if (existsSync8(resolvedPath)) {
|
|
86031
86080
|
return readFileSync2(resolvedPath, "utf-8").trim();
|
|
86032
86081
|
}
|
|
86033
86082
|
} catch (error) {
|
|
@@ -86715,7 +86764,7 @@ async function main() {
|
|
|
86715
86764
|
bashConfig.timeout = timeout;
|
|
86716
86765
|
}
|
|
86717
86766
|
if (config.bashWorkingDir) {
|
|
86718
|
-
if (!
|
|
86767
|
+
if (!existsSync8(config.bashWorkingDir)) {
|
|
86719
86768
|
console.error(`Error: Bash working directory does not exist: ${config.bashWorkingDir}`);
|
|
86720
86769
|
process.exit(1);
|
|
86721
86770
|
}
|
package/build/tools/vercel.js
CHANGED
|
@@ -10,6 +10,7 @@ import { extract } from '../extract.js';
|
|
|
10
10
|
import { delegate } from '../delegate.js';
|
|
11
11
|
import { analyzeAll } from './analyzeAll.js';
|
|
12
12
|
import { searchSchema, querySchema, extractSchema, delegateSchema, analyzeAllSchema, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, parseTargets, parseAndResolvePaths, resolveTargetPath } from './common.js';
|
|
13
|
+
import { existsSync } from 'fs';
|
|
13
14
|
import { formatErrorForAI } from '../utils/error-types.js';
|
|
14
15
|
import { annotateOutputWithHashes } from './hashline.js';
|
|
15
16
|
|
|
@@ -118,6 +119,18 @@ function parseDelegatedTargets(rawResponse) {
|
|
|
118
119
|
return normalizeTargets(fallbackTargetsFromText(trimmed));
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
function splitTargetSuffix(target) {
|
|
123
|
+
const searchStart = (target.length > 2 && target[1] === ':' && /[a-zA-Z]/.test(target[0])) ? 2 : 0;
|
|
124
|
+
const colonIdx = target.indexOf(':', searchStart);
|
|
125
|
+
const hashIdx = target.indexOf('#');
|
|
126
|
+
if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
|
|
127
|
+
return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
|
|
128
|
+
} else if (hashIdx !== -1) {
|
|
129
|
+
return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
|
|
130
|
+
}
|
|
131
|
+
return { filePart: target, suffix: '' };
|
|
132
|
+
}
|
|
133
|
+
|
|
121
134
|
function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
|
|
122
135
|
return [
|
|
123
136
|
'You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.',
|
|
@@ -286,13 +299,61 @@ export const searchTool = (options = {}) => {
|
|
|
286
299
|
return fallbackResult;
|
|
287
300
|
}
|
|
288
301
|
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
|
|
302
|
+
// The delegate runs from workspace root (allowedFolders[0] or cwd), NOT from searchPaths[0].
|
|
303
|
+
// It returns paths relative to that workspace root. Resolve against the same base.
|
|
304
|
+
const delegateBase = options.allowedFolders?.[0] || options.cwd || '.';
|
|
292
305
|
const resolutionBase = searchPaths[0] || options.cwd || '.';
|
|
293
|
-
const resolvedTargets = targets.map(target => resolveTargetPath(target,
|
|
306
|
+
const resolvedTargets = targets.map(target => resolveTargetPath(target, delegateBase));
|
|
307
|
+
|
|
308
|
+
// Auto-fix: detect and repair invalid paths (doubled segments, AI hallucinations)
|
|
309
|
+
const validatedTargets = [];
|
|
310
|
+
for (const target of resolvedTargets) {
|
|
311
|
+
const { filePart, suffix } = splitTargetSuffix(target);
|
|
312
|
+
|
|
313
|
+
// 1. Path exists as-is
|
|
314
|
+
if (existsSync(filePart)) {
|
|
315
|
+
validatedTargets.push(target);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// 2. Detect doubled directory segments: /ws/proj/proj/src → /ws/proj/src
|
|
320
|
+
let fixed = false;
|
|
321
|
+
const parts = filePart.split('/').filter(Boolean);
|
|
322
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
323
|
+
if (parts[i] === parts[i + 1]) {
|
|
324
|
+
const candidate = '/' + [...parts.slice(0, i), ...parts.slice(i + 1)].join('/');
|
|
325
|
+
if (existsSync(candidate)) {
|
|
326
|
+
validatedTargets.push(candidate + suffix);
|
|
327
|
+
if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} → ${candidate}`);
|
|
328
|
+
fixed = true;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (fixed) continue;
|
|
334
|
+
|
|
335
|
+
// 3. Try resolving against alternative bases (searchPaths[0], cwd)
|
|
336
|
+
for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
|
|
337
|
+
if (altBase === delegateBase) continue;
|
|
338
|
+
const altResolved = resolveTargetPath(target, altBase);
|
|
339
|
+
const { filePart: altFile } = splitTargetSuffix(altResolved);
|
|
340
|
+
if (existsSync(altFile)) {
|
|
341
|
+
validatedTargets.push(altResolved);
|
|
342
|
+
if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} → ${altFile}`);
|
|
343
|
+
fixed = true;
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (fixed) continue;
|
|
348
|
+
|
|
349
|
+
// 4. Keep target anyway (probe binary will report the error)
|
|
350
|
+
// but log a warning
|
|
351
|
+
if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
|
|
352
|
+
validatedTargets.push(target);
|
|
353
|
+
}
|
|
354
|
+
|
|
294
355
|
const extractOptions = {
|
|
295
|
-
files:
|
|
356
|
+
files: validatedTargets,
|
|
296
357
|
cwd: resolutionBase,
|
|
297
358
|
allowTests: allow_tests ?? true
|
|
298
359
|
};
|
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -36502,6 +36502,17 @@ function parseDelegatedTargets(rawResponse) {
|
|
|
36502
36502
|
}
|
|
36503
36503
|
return normalizeTargets(fallbackTargetsFromText(trimmed));
|
|
36504
36504
|
}
|
|
36505
|
+
function splitTargetSuffix(target) {
|
|
36506
|
+
const searchStart = target.length > 2 && target[1] === ":" && /[a-zA-Z]/.test(target[0]) ? 2 : 0;
|
|
36507
|
+
const colonIdx = target.indexOf(":", searchStart);
|
|
36508
|
+
const hashIdx = target.indexOf("#");
|
|
36509
|
+
if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
|
|
36510
|
+
return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
|
|
36511
|
+
} else if (hashIdx !== -1) {
|
|
36512
|
+
return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
|
|
36513
|
+
}
|
|
36514
|
+
return { filePart: target, suffix: "" };
|
|
36515
|
+
}
|
|
36505
36516
|
function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
|
|
36506
36517
|
return [
|
|
36507
36518
|
"You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.",
|
|
@@ -36530,7 +36541,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
|
|
|
36530
36541
|
"Deduplicate targets. Do NOT explain or answer - ONLY return the JSON targets."
|
|
36531
36542
|
].join("\n");
|
|
36532
36543
|
}
|
|
36533
|
-
var import_ai, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
|
|
36544
|
+
var import_ai, import_fs4, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
|
|
36534
36545
|
var init_vercel = __esm({
|
|
36535
36546
|
"src/tools/vercel.js"() {
|
|
36536
36547
|
"use strict";
|
|
@@ -36541,6 +36552,7 @@ var init_vercel = __esm({
|
|
|
36541
36552
|
init_delegate();
|
|
36542
36553
|
init_analyzeAll();
|
|
36543
36554
|
init_common2();
|
|
36555
|
+
import_fs4 = require("fs");
|
|
36544
36556
|
init_error_types();
|
|
36545
36557
|
init_hashline();
|
|
36546
36558
|
CODE_SEARCH_SCHEMA = {
|
|
@@ -36666,10 +36678,47 @@ var init_vercel = __esm({
|
|
|
36666
36678
|
}
|
|
36667
36679
|
return fallbackResult;
|
|
36668
36680
|
}
|
|
36681
|
+
const delegateBase = options.allowedFolders?.[0] || options.cwd || ".";
|
|
36669
36682
|
const resolutionBase = searchPaths[0] || options.cwd || ".";
|
|
36670
|
-
const resolvedTargets = targets.map((target) => resolveTargetPath(target,
|
|
36683
|
+
const resolvedTargets = targets.map((target) => resolveTargetPath(target, delegateBase));
|
|
36684
|
+
const validatedTargets = [];
|
|
36685
|
+
for (const target of resolvedTargets) {
|
|
36686
|
+
const { filePart, suffix } = splitTargetSuffix(target);
|
|
36687
|
+
if ((0, import_fs4.existsSync)(filePart)) {
|
|
36688
|
+
validatedTargets.push(target);
|
|
36689
|
+
continue;
|
|
36690
|
+
}
|
|
36691
|
+
let fixed = false;
|
|
36692
|
+
const parts = filePart.split("/").filter(Boolean);
|
|
36693
|
+
for (let i5 = 0; i5 < parts.length - 1; i5++) {
|
|
36694
|
+
if (parts[i5] === parts[i5 + 1]) {
|
|
36695
|
+
const candidate = "/" + [...parts.slice(0, i5), ...parts.slice(i5 + 1)].join("/");
|
|
36696
|
+
if ((0, import_fs4.existsSync)(candidate)) {
|
|
36697
|
+
validatedTargets.push(candidate + suffix);
|
|
36698
|
+
if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} \u2192 ${candidate}`);
|
|
36699
|
+
fixed = true;
|
|
36700
|
+
break;
|
|
36701
|
+
}
|
|
36702
|
+
}
|
|
36703
|
+
}
|
|
36704
|
+
if (fixed) continue;
|
|
36705
|
+
for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
|
|
36706
|
+
if (altBase === delegateBase) continue;
|
|
36707
|
+
const altResolved = resolveTargetPath(target, altBase);
|
|
36708
|
+
const { filePart: altFile } = splitTargetSuffix(altResolved);
|
|
36709
|
+
if ((0, import_fs4.existsSync)(altFile)) {
|
|
36710
|
+
validatedTargets.push(altResolved);
|
|
36711
|
+
if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} \u2192 ${altFile}`);
|
|
36712
|
+
fixed = true;
|
|
36713
|
+
break;
|
|
36714
|
+
}
|
|
36715
|
+
}
|
|
36716
|
+
if (fixed) continue;
|
|
36717
|
+
if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
|
|
36718
|
+
validatedTargets.push(target);
|
|
36719
|
+
}
|
|
36671
36720
|
const extractOptions = {
|
|
36672
|
-
files:
|
|
36721
|
+
files: validatedTargets,
|
|
36673
36722
|
cwd: resolutionBase,
|
|
36674
36723
|
allowTests: allow_tests ?? true
|
|
36675
36724
|
};
|
|
@@ -38314,7 +38363,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
38314
38363
|
let cwd = workingDirectory;
|
|
38315
38364
|
try {
|
|
38316
38365
|
cwd = (0, import_path6.resolve)(cwd);
|
|
38317
|
-
if (!(0,
|
|
38366
|
+
if (!(0, import_fs5.existsSync)(cwd)) {
|
|
38318
38367
|
throw new Error(`Working directory does not exist: ${cwd}`);
|
|
38319
38368
|
}
|
|
38320
38369
|
} catch (error2) {
|
|
@@ -38570,7 +38619,7 @@ function validateExecutionOptions(options = {}) {
|
|
|
38570
38619
|
if (options.workingDirectory) {
|
|
38571
38620
|
if (typeof options.workingDirectory !== "string") {
|
|
38572
38621
|
errors.push("workingDirectory must be a string");
|
|
38573
|
-
} else if (!(0,
|
|
38622
|
+
} else if (!(0, import_fs5.existsSync)(options.workingDirectory)) {
|
|
38574
38623
|
errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
|
|
38575
38624
|
}
|
|
38576
38625
|
}
|
|
@@ -38583,13 +38632,13 @@ function validateExecutionOptions(options = {}) {
|
|
|
38583
38632
|
warnings
|
|
38584
38633
|
};
|
|
38585
38634
|
}
|
|
38586
|
-
var import_child_process6, import_path6,
|
|
38635
|
+
var import_child_process6, import_path6, import_fs5;
|
|
38587
38636
|
var init_bashExecutor = __esm({
|
|
38588
38637
|
"src/agent/bashExecutor.js"() {
|
|
38589
38638
|
"use strict";
|
|
38590
38639
|
import_child_process6 = require("child_process");
|
|
38591
38640
|
import_path6 = require("path");
|
|
38592
|
-
|
|
38641
|
+
import_fs5 = require("fs");
|
|
38593
38642
|
init_bashCommandUtils();
|
|
38594
38643
|
}
|
|
38595
38644
|
});
|
|
@@ -39147,7 +39196,7 @@ Example: <edit><file_path>${file_path}</file_path><symbol>${allMatches[0].qualif
|
|
|
39147
39196
|
Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
39148
39197
|
}
|
|
39149
39198
|
}
|
|
39150
|
-
const content = await
|
|
39199
|
+
const content = await import_fs6.promises.readFile(resolvedPath2, "utf-8");
|
|
39151
39200
|
const lines = content.split("\n");
|
|
39152
39201
|
if (position) {
|
|
39153
39202
|
const refIndent = detectBaseIndent(symbolInfo.code);
|
|
@@ -39158,7 +39207,7 @@ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
|
39158
39207
|
} else {
|
|
39159
39208
|
lines.splice(symbolInfo.startLine - 1, 0, ...newLines, "");
|
|
39160
39209
|
}
|
|
39161
|
-
await
|
|
39210
|
+
await import_fs6.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
39162
39211
|
if (fileTracker) {
|
|
39163
39212
|
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
39164
39213
|
if (updated) {
|
|
@@ -39176,7 +39225,7 @@ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
|
39176
39225
|
const reindented = reindent(new_string, originalIndent);
|
|
39177
39226
|
const newLines = reindented.split("\n");
|
|
39178
39227
|
lines.splice(symbolInfo.startLine - 1, symbolInfo.endLine - symbolInfo.startLine + 1, ...newLines);
|
|
39179
|
-
await
|
|
39228
|
+
await import_fs6.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
39180
39229
|
if (fileTracker) {
|
|
39181
39230
|
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
39182
39231
|
if (updated) {
|
|
@@ -39231,7 +39280,7 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
|
|
|
39231
39280
|
if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
|
|
39232
39281
|
return 'Error editing file: Invalid position - must be "before" or "after". Use position="before" to insert before the line, or position="after" to insert after it.';
|
|
39233
39282
|
}
|
|
39234
|
-
const content = await
|
|
39283
|
+
const content = await import_fs6.promises.readFile(resolvedPath2, "utf-8");
|
|
39235
39284
|
const fileLines = content.split("\n");
|
|
39236
39285
|
if (startLine > fileLines.length) {
|
|
39237
39286
|
return `Error editing file: Line ${startLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
|
|
@@ -39260,20 +39309,20 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
|
|
|
39260
39309
|
const newLines = cleaned === "" ? [] : cleaned.split("\n");
|
|
39261
39310
|
if (position === "after") {
|
|
39262
39311
|
fileLines.splice(startLine, 0, ...newLines);
|
|
39263
|
-
await
|
|
39312
|
+
await import_fs6.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
39264
39313
|
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39265
39314
|
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted after line ${startLine}`;
|
|
39266
39315
|
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine, action, modifications);
|
|
39267
39316
|
} else if (position === "before") {
|
|
39268
39317
|
fileLines.splice(startLine - 1, 0, ...newLines);
|
|
39269
|
-
await
|
|
39318
|
+
await import_fs6.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
39270
39319
|
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39271
39320
|
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted before line ${startLine}`;
|
|
39272
39321
|
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
39273
39322
|
} else {
|
|
39274
39323
|
const replacedCount = endLine - startLine + 1;
|
|
39275
39324
|
fileLines.splice(startLine - 1, replacedCount, ...newLines);
|
|
39276
|
-
await
|
|
39325
|
+
await import_fs6.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
39277
39326
|
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39278
39327
|
let action;
|
|
39279
39328
|
if (newLines.length === 0) {
|
|
@@ -39286,14 +39335,14 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
|
|
|
39286
39335
|
return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
39287
39336
|
}
|
|
39288
39337
|
}
|
|
39289
|
-
var import_ai3,
|
|
39338
|
+
var import_ai3, import_fs6, import_path8, import_fs7, editTool, createTool, multiEditTool, editSchema, createSchema, multiEditSchema, editDescription, createDescription, multiEditDescription, editToolDefinition, createToolDefinition, multiEditToolDefinition;
|
|
39290
39339
|
var init_edit = __esm({
|
|
39291
39340
|
"src/tools/edit.js"() {
|
|
39292
39341
|
"use strict";
|
|
39293
39342
|
import_ai3 = require("ai");
|
|
39294
|
-
import_fs5 = require("fs");
|
|
39295
|
-
import_path8 = require("path");
|
|
39296
39343
|
import_fs6 = require("fs");
|
|
39344
|
+
import_path8 = require("path");
|
|
39345
|
+
import_fs7 = require("fs");
|
|
39297
39346
|
init_path_validation();
|
|
39298
39347
|
init_fuzzyMatch();
|
|
39299
39348
|
init_symbolEdit();
|
|
@@ -39377,7 +39426,7 @@ Parameters:
|
|
|
39377
39426
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
39378
39427
|
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
39379
39428
|
}
|
|
39380
|
-
if (!(0,
|
|
39429
|
+
if (!(0, import_fs7.existsSync)(resolvedPath2)) {
|
|
39381
39430
|
return `Error editing file: File not found - ${file_path}. Verify the path is correct and the file exists. Use 'search' to find files by name, or 'create' to make a new file.`;
|
|
39382
39431
|
}
|
|
39383
39432
|
if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath2)) {
|
|
@@ -39407,7 +39456,7 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
|
39407
39456
|
Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
39408
39457
|
}
|
|
39409
39458
|
}
|
|
39410
|
-
const content = await
|
|
39459
|
+
const content = await import_fs6.promises.readFile(resolvedPath2, "utf-8");
|
|
39411
39460
|
let matchTarget = old_string;
|
|
39412
39461
|
let matchStrategy = "exact";
|
|
39413
39462
|
if (!content.includes(old_string)) {
|
|
@@ -39439,7 +39488,7 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
|
39439
39488
|
if (newContent === content) {
|
|
39440
39489
|
return `Error editing file: No changes made - the replacement result is identical to the original. Verify that old_string and new_string are actually different. If fuzzy matching was used, the matched text may already equal new_string.`;
|
|
39441
39490
|
}
|
|
39442
|
-
await
|
|
39491
|
+
await import_fs6.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
39443
39492
|
if (options.fileTracker) {
|
|
39444
39493
|
await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39445
39494
|
options.fileTracker.recordTextEdit(resolvedPath2);
|
|
@@ -39510,13 +39559,13 @@ Important:
|
|
|
39510
39559
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
39511
39560
|
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
39512
39561
|
}
|
|
39513
|
-
if ((0,
|
|
39562
|
+
if ((0, import_fs7.existsSync)(resolvedPath2) && !overwrite) {
|
|
39514
39563
|
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
39515
39564
|
}
|
|
39516
|
-
const existed = (0,
|
|
39565
|
+
const existed = (0, import_fs7.existsSync)(resolvedPath2);
|
|
39517
39566
|
const dir = (0, import_path8.dirname)(resolvedPath2);
|
|
39518
|
-
await
|
|
39519
|
-
await
|
|
39567
|
+
await import_fs6.promises.mkdir(dir, { recursive: true });
|
|
39568
|
+
await import_fs6.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
39520
39569
|
if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39521
39570
|
const action = existed && overwrite ? "overwrote" : "created";
|
|
39522
39571
|
const bytes = Buffer.byteLength(content, "utf-8");
|
|
@@ -53822,22 +53871,22 @@ var init_esm3 = __esm({
|
|
|
53822
53871
|
});
|
|
53823
53872
|
|
|
53824
53873
|
// node_modules/path-scurry/dist/esm/index.js
|
|
53825
|
-
var import_node_path, import_node_url,
|
|
53874
|
+
var import_node_path, import_node_url, import_fs8, actualFS, import_promises, realpathSync2, defaultFS, fsFromOption, uncDriveRegexp, uncToDrive, eitherSep, UNKNOWN, IFIFO, IFCHR, IFDIR, IFBLK, IFREG, IFLNK, IFSOCK, IFMT, IFMT_UNKNOWN, READDIR_CALLED, LSTAT_CALLED, ENOTDIR, ENOENT, ENOREADLINK, ENOREALPATH, ENOCHILD, TYPEMASK, entToType, normalizeCache, normalize, normalizeNocaseCache, normalizeNocase, ResolveCache, ChildrenCache, setAsCwd, PathBase, PathWin32, PathPosix, PathScurryBase, PathScurryWin32, PathScurryPosix, PathScurryDarwin, Path, PathScurry;
|
|
53826
53875
|
var init_esm4 = __esm({
|
|
53827
53876
|
"node_modules/path-scurry/dist/esm/index.js"() {
|
|
53828
53877
|
init_esm2();
|
|
53829
53878
|
import_node_path = require("node:path");
|
|
53830
53879
|
import_node_url = require("node:url");
|
|
53831
|
-
|
|
53880
|
+
import_fs8 = require("fs");
|
|
53832
53881
|
actualFS = __toESM(require("node:fs"), 1);
|
|
53833
53882
|
import_promises = require("node:fs/promises");
|
|
53834
53883
|
init_esm3();
|
|
53835
|
-
realpathSync2 =
|
|
53884
|
+
realpathSync2 = import_fs8.realpathSync.native;
|
|
53836
53885
|
defaultFS = {
|
|
53837
|
-
lstatSync:
|
|
53838
|
-
readdir:
|
|
53839
|
-
readdirSync:
|
|
53840
|
-
readlinkSync:
|
|
53886
|
+
lstatSync: import_fs8.lstatSync,
|
|
53887
|
+
readdir: import_fs8.readdir,
|
|
53888
|
+
readdirSync: import_fs8.readdirSync,
|
|
53889
|
+
readlinkSync: import_fs8.readlinkSync,
|
|
53841
53890
|
realpathSync: realpathSync2,
|
|
53842
53891
|
promises: {
|
|
53843
53892
|
lstat: import_promises.lstat,
|
|
@@ -57366,10 +57415,10 @@ async function listFilesByLevel(options) {
|
|
|
57366
57415
|
maxFiles = 100,
|
|
57367
57416
|
respectGitignore = true
|
|
57368
57417
|
} = options;
|
|
57369
|
-
if (!
|
|
57418
|
+
if (!import_fs9.default.existsSync(directory)) {
|
|
57370
57419
|
throw new Error(`Directory does not exist: ${directory}`);
|
|
57371
57420
|
}
|
|
57372
|
-
const gitDirExists =
|
|
57421
|
+
const gitDirExists = import_fs9.default.existsSync(import_path9.default.join(directory, ".git"));
|
|
57373
57422
|
if (gitDirExists && respectGitignore) {
|
|
57374
57423
|
try {
|
|
57375
57424
|
return await listFilesUsingGit(directory, maxFiles);
|
|
@@ -57400,7 +57449,7 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
57400
57449
|
while (queue.length > 0 && result.length < maxFiles) {
|
|
57401
57450
|
const { dir, level } = queue.shift();
|
|
57402
57451
|
try {
|
|
57403
|
-
const entries =
|
|
57452
|
+
const entries = import_fs9.default.readdirSync(dir, { withFileTypes: true });
|
|
57404
57453
|
const files = entries.filter((entry) => {
|
|
57405
57454
|
const fullPath = import_path9.default.join(dir, entry.name);
|
|
57406
57455
|
return getEntryTypeSync(entry, fullPath).isFile;
|
|
@@ -57431,11 +57480,11 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
57431
57480
|
}
|
|
57432
57481
|
function loadGitignorePatterns(directory) {
|
|
57433
57482
|
const gitignorePath = import_path9.default.join(directory, ".gitignore");
|
|
57434
|
-
if (!
|
|
57483
|
+
if (!import_fs9.default.existsSync(gitignorePath)) {
|
|
57435
57484
|
return [];
|
|
57436
57485
|
}
|
|
57437
57486
|
try {
|
|
57438
|
-
const content =
|
|
57487
|
+
const content = import_fs9.default.readFileSync(gitignorePath, "utf8");
|
|
57439
57488
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
57440
57489
|
} catch (error2) {
|
|
57441
57490
|
console.error(`Warning: Could not read .gitignore: ${error2.message}`);
|
|
@@ -57453,11 +57502,11 @@ function shouldIgnore(filePath, ignorePatterns) {
|
|
|
57453
57502
|
}
|
|
57454
57503
|
return false;
|
|
57455
57504
|
}
|
|
57456
|
-
var
|
|
57505
|
+
var import_fs9, import_path9, import_util11, import_child_process7, execAsync3;
|
|
57457
57506
|
var init_file_lister = __esm({
|
|
57458
57507
|
"src/utils/file-lister.js"() {
|
|
57459
57508
|
"use strict";
|
|
57460
|
-
|
|
57509
|
+
import_fs9 = __toESM(require("fs"), 1);
|
|
57461
57510
|
import_path9 = __toESM(require("path"), 1);
|
|
57462
57511
|
import_util11 = require("util");
|
|
57463
57512
|
import_child_process7 = require("child_process");
|
|
@@ -57757,11 +57806,11 @@ var init_fileTracker = __esm({
|
|
|
57757
57806
|
});
|
|
57758
57807
|
|
|
57759
57808
|
// src/agent/simpleTelemetry.js
|
|
57760
|
-
var
|
|
57809
|
+
var import_fs10, import_path11;
|
|
57761
57810
|
var init_simpleTelemetry = __esm({
|
|
57762
57811
|
"src/agent/simpleTelemetry.js"() {
|
|
57763
57812
|
"use strict";
|
|
57764
|
-
|
|
57813
|
+
import_fs10 = require("fs");
|
|
57765
57814
|
import_path11 = require("path");
|
|
57766
57815
|
}
|
|
57767
57816
|
});
|
|
@@ -57868,7 +57917,7 @@ function createWrappedTools(baseTools) {
|
|
|
57868
57917
|
}
|
|
57869
57918
|
return wrappedTools;
|
|
57870
57919
|
}
|
|
57871
|
-
var import_child_process8, import_util12, import_crypto4, import_events,
|
|
57920
|
+
var import_child_process8, import_util12, import_crypto4, import_events, import_fs11, import_fs12, import_path12, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
57872
57921
|
var init_probeTool = __esm({
|
|
57873
57922
|
"src/agent/probeTool.js"() {
|
|
57874
57923
|
"use strict";
|
|
@@ -57877,8 +57926,8 @@ var init_probeTool = __esm({
|
|
|
57877
57926
|
import_util12 = require("util");
|
|
57878
57927
|
import_crypto4 = require("crypto");
|
|
57879
57928
|
import_events = require("events");
|
|
57880
|
-
|
|
57881
|
-
|
|
57929
|
+
import_fs11 = __toESM(require("fs"), 1);
|
|
57930
|
+
import_fs12 = require("fs");
|
|
57882
57931
|
import_path12 = __toESM(require("path"), 1);
|
|
57883
57932
|
init_esm5();
|
|
57884
57933
|
init_symlink_utils();
|
|
@@ -57987,7 +58036,7 @@ var init_probeTool = __esm({
|
|
|
57987
58036
|
console.log(`[DEBUG] Listing files in directory: ${targetDir}`);
|
|
57988
58037
|
}
|
|
57989
58038
|
try {
|
|
57990
|
-
const files = await
|
|
58039
|
+
const files = await import_fs12.promises.readdir(targetDir, { withFileTypes: true });
|
|
57991
58040
|
const formatSize = (size) => {
|
|
57992
58041
|
if (size < 1024) return `${size}B`;
|
|
57993
58042
|
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}K`;
|
|
@@ -97834,11 +97883,11 @@ function loadMCPConfigurationFromPath(configPath) {
|
|
|
97834
97883
|
if (!configPath) {
|
|
97835
97884
|
throw new Error("Config path is required");
|
|
97836
97885
|
}
|
|
97837
|
-
if (!(0,
|
|
97886
|
+
if (!(0, import_fs13.existsSync)(configPath)) {
|
|
97838
97887
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
97839
97888
|
}
|
|
97840
97889
|
try {
|
|
97841
|
-
const content = (0,
|
|
97890
|
+
const content = (0, import_fs13.readFileSync)(configPath, "utf8");
|
|
97842
97891
|
const config = JSON.parse(content);
|
|
97843
97892
|
if (process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1") {
|
|
97844
97893
|
console.error(`[MCP DEBUG] Loaded configuration from: ${configPath}`);
|
|
@@ -97863,9 +97912,9 @@ function loadMCPConfiguration() {
|
|
|
97863
97912
|
].filter(Boolean);
|
|
97864
97913
|
let config = null;
|
|
97865
97914
|
for (const configPath of configPaths) {
|
|
97866
|
-
if ((0,
|
|
97915
|
+
if ((0, import_fs13.existsSync)(configPath)) {
|
|
97867
97916
|
try {
|
|
97868
|
-
const content = (0,
|
|
97917
|
+
const content = (0, import_fs13.readFileSync)(configPath, "utf8");
|
|
97869
97918
|
config = JSON.parse(content);
|
|
97870
97919
|
if (process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1") {
|
|
97871
97920
|
console.error(`[MCP DEBUG] Loaded configuration from: ${configPath}`);
|
|
@@ -97986,11 +98035,11 @@ function parseEnabledServers(config) {
|
|
|
97986
98035
|
}
|
|
97987
98036
|
return servers;
|
|
97988
98037
|
}
|
|
97989
|
-
var
|
|
98038
|
+
var import_fs13, import_path13, import_os3, import_url4, __filename4, __dirname5, DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_CONFIG;
|
|
97990
98039
|
var init_config = __esm({
|
|
97991
98040
|
"src/agent/mcp/config.js"() {
|
|
97992
98041
|
"use strict";
|
|
97993
|
-
|
|
98042
|
+
import_fs13 = require("fs");
|
|
97994
98043
|
import_path13 = require("path");
|
|
97995
98044
|
import_os3 = require("os");
|
|
97996
98045
|
import_url4 = require("url");
|
|
@@ -106085,11 +106134,11 @@ function isSafeEntryName(name14) {
|
|
|
106085
106134
|
if (name14.includes("\0")) return false;
|
|
106086
106135
|
return !name14.includes("/") && !name14.includes("\\");
|
|
106087
106136
|
}
|
|
106088
|
-
var
|
|
106137
|
+
var import_fs14, import_promises3, import_path15, DEFAULT_SKILL_DIRS, SKILL_FILE_NAME, SkillRegistry;
|
|
106089
106138
|
var init_registry = __esm({
|
|
106090
106139
|
"src/agent/skills/registry.js"() {
|
|
106091
106140
|
"use strict";
|
|
106092
|
-
|
|
106141
|
+
import_fs14 = require("fs");
|
|
106093
106142
|
import_promises3 = require("fs/promises");
|
|
106094
106143
|
import_path15 = require("path");
|
|
106095
106144
|
init_parser7();
|
|
@@ -106164,7 +106213,7 @@ var init_registry = __esm({
|
|
|
106164
106213
|
return resolvedReal;
|
|
106165
106214
|
}
|
|
106166
106215
|
async _scanSkillDir(dirPath) {
|
|
106167
|
-
if (!(0,
|
|
106216
|
+
if (!(0, import_fs14.existsSync)(dirPath)) return [];
|
|
106168
106217
|
let entries;
|
|
106169
106218
|
try {
|
|
106170
106219
|
entries = await (0, import_promises3.readdir)(dirPath, { withFileTypes: true });
|
|
@@ -106204,7 +106253,7 @@ var init_registry = __esm({
|
|
|
106204
106253
|
}
|
|
106205
106254
|
continue;
|
|
106206
106255
|
}
|
|
106207
|
-
if (!(0,
|
|
106256
|
+
if (!(0, import_fs14.existsSync)(skillFilePath)) continue;
|
|
106208
106257
|
const { skill, error: error2 } = await parseSkillFile(skillFilePath, entry.name);
|
|
106209
106258
|
if (!skill) {
|
|
106210
106259
|
if (error2) {
|
|
@@ -108712,7 +108761,7 @@ __export(ProbeAgent_exports, {
|
|
|
108712
108761
|
ProbeAgent: () => ProbeAgent
|
|
108713
108762
|
});
|
|
108714
108763
|
module.exports = __toCommonJS(ProbeAgent_exports);
|
|
108715
|
-
var import_dotenv2, import_anthropic2, import_openai2, import_google2, import_ai6, import_crypto9, import_events4,
|
|
108764
|
+
var import_dotenv2, import_anthropic2, import_openai2, import_google2, import_ai6, import_crypto9, import_events4, import_fs15, import_promises6, import_path18, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
108716
108765
|
var init_ProbeAgent = __esm({
|
|
108717
108766
|
"src/agent/ProbeAgent.js"() {
|
|
108718
108767
|
import_dotenv2 = __toESM(require_main(), 1);
|
|
@@ -108723,7 +108772,7 @@ var init_ProbeAgent = __esm({
|
|
|
108723
108772
|
import_ai6 = require("ai");
|
|
108724
108773
|
import_crypto9 = require("crypto");
|
|
108725
108774
|
import_events4 = require("events");
|
|
108726
|
-
|
|
108775
|
+
import_fs15 = require("fs");
|
|
108727
108776
|
import_promises6 = require("fs/promises");
|
|
108728
108777
|
import_path18 = require("path");
|
|
108729
108778
|
init_tokenCounter();
|
|
@@ -110730,7 +110779,7 @@ var init_ProbeAgent = __esm({
|
|
|
110730
110779
|
} else {
|
|
110731
110780
|
guidanceCandidates = ["agents.md", "claude.md"];
|
|
110732
110781
|
}
|
|
110733
|
-
if (!(0,
|
|
110782
|
+
if (!(0, import_fs15.existsSync)(rootDirectory)) {
|
|
110734
110783
|
this._architectureContextLoaded = true;
|
|
110735
110784
|
return null;
|
|
110736
110785
|
}
|
package/cjs/index.cjs
CHANGED
|
@@ -110630,6 +110630,17 @@ function parseDelegatedTargets(rawResponse) {
|
|
|
110630
110630
|
}
|
|
110631
110631
|
return normalizeTargets(fallbackTargetsFromText(trimmed));
|
|
110632
110632
|
}
|
|
110633
|
+
function splitTargetSuffix(target) {
|
|
110634
|
+
const searchStart = target.length > 2 && target[1] === ":" && /[a-zA-Z]/.test(target[0]) ? 2 : 0;
|
|
110635
|
+
const colonIdx = target.indexOf(":", searchStart);
|
|
110636
|
+
const hashIdx = target.indexOf("#");
|
|
110637
|
+
if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
|
|
110638
|
+
return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
|
|
110639
|
+
} else if (hashIdx !== -1) {
|
|
110640
|
+
return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
|
|
110641
|
+
}
|
|
110642
|
+
return { filePart: target, suffix: "" };
|
|
110643
|
+
}
|
|
110633
110644
|
function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
|
|
110634
110645
|
return [
|
|
110635
110646
|
"You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.",
|
|
@@ -110658,7 +110669,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
|
|
|
110658
110669
|
"Deduplicate targets. Do NOT explain or answer - ONLY return the JSON targets."
|
|
110659
110670
|
].join("\n");
|
|
110660
110671
|
}
|
|
110661
|
-
var import_ai5, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
|
|
110672
|
+
var import_ai5, import_fs11, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
|
|
110662
110673
|
var init_vercel = __esm({
|
|
110663
110674
|
"src/tools/vercel.js"() {
|
|
110664
110675
|
"use strict";
|
|
@@ -110669,6 +110680,7 @@ var init_vercel = __esm({
|
|
|
110669
110680
|
init_delegate();
|
|
110670
110681
|
init_analyzeAll();
|
|
110671
110682
|
init_common2();
|
|
110683
|
+
import_fs11 = require("fs");
|
|
110672
110684
|
init_error_types();
|
|
110673
110685
|
init_hashline();
|
|
110674
110686
|
CODE_SEARCH_SCHEMA = {
|
|
@@ -110794,10 +110806,47 @@ var init_vercel = __esm({
|
|
|
110794
110806
|
}
|
|
110795
110807
|
return fallbackResult;
|
|
110796
110808
|
}
|
|
110809
|
+
const delegateBase = options.allowedFolders?.[0] || options.cwd || ".";
|
|
110797
110810
|
const resolutionBase = searchPaths[0] || options.cwd || ".";
|
|
110798
|
-
const resolvedTargets = targets.map((target) => resolveTargetPath(target,
|
|
110811
|
+
const resolvedTargets = targets.map((target) => resolveTargetPath(target, delegateBase));
|
|
110812
|
+
const validatedTargets = [];
|
|
110813
|
+
for (const target of resolvedTargets) {
|
|
110814
|
+
const { filePart, suffix } = splitTargetSuffix(target);
|
|
110815
|
+
if ((0, import_fs11.existsSync)(filePart)) {
|
|
110816
|
+
validatedTargets.push(target);
|
|
110817
|
+
continue;
|
|
110818
|
+
}
|
|
110819
|
+
let fixed = false;
|
|
110820
|
+
const parts = filePart.split("/").filter(Boolean);
|
|
110821
|
+
for (let i5 = 0; i5 < parts.length - 1; i5++) {
|
|
110822
|
+
if (parts[i5] === parts[i5 + 1]) {
|
|
110823
|
+
const candidate = "/" + [...parts.slice(0, i5), ...parts.slice(i5 + 1)].join("/");
|
|
110824
|
+
if ((0, import_fs11.existsSync)(candidate)) {
|
|
110825
|
+
validatedTargets.push(candidate + suffix);
|
|
110826
|
+
if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} \u2192 ${candidate}`);
|
|
110827
|
+
fixed = true;
|
|
110828
|
+
break;
|
|
110829
|
+
}
|
|
110830
|
+
}
|
|
110831
|
+
}
|
|
110832
|
+
if (fixed) continue;
|
|
110833
|
+
for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
|
|
110834
|
+
if (altBase === delegateBase) continue;
|
|
110835
|
+
const altResolved = resolveTargetPath(target, altBase);
|
|
110836
|
+
const { filePart: altFile } = splitTargetSuffix(altResolved);
|
|
110837
|
+
if ((0, import_fs11.existsSync)(altFile)) {
|
|
110838
|
+
validatedTargets.push(altResolved);
|
|
110839
|
+
if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} \u2192 ${altFile}`);
|
|
110840
|
+
fixed = true;
|
|
110841
|
+
break;
|
|
110842
|
+
}
|
|
110843
|
+
}
|
|
110844
|
+
if (fixed) continue;
|
|
110845
|
+
if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
|
|
110846
|
+
validatedTargets.push(target);
|
|
110847
|
+
}
|
|
110799
110848
|
const extractOptions = {
|
|
110800
|
-
files:
|
|
110849
|
+
files: validatedTargets,
|
|
110801
110850
|
cwd: resolutionBase,
|
|
110802
110851
|
allowTests: allow_tests ?? true
|
|
110803
110852
|
};
|
|
@@ -111350,7 +111399,7 @@ Example: <edit><file_path>${file_path}</file_path><symbol>${allMatches[0].qualif
|
|
|
111350
111399
|
Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
111351
111400
|
}
|
|
111352
111401
|
}
|
|
111353
|
-
const content = await
|
|
111402
|
+
const content = await import_fs12.promises.readFile(resolvedPath2, "utf-8");
|
|
111354
111403
|
const lines = content.split("\n");
|
|
111355
111404
|
if (position) {
|
|
111356
111405
|
const refIndent = detectBaseIndent(symbolInfo.code);
|
|
@@ -111361,7 +111410,7 @@ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
|
111361
111410
|
} else {
|
|
111362
111411
|
lines.splice(symbolInfo.startLine - 1, 0, ...newLines, "");
|
|
111363
111412
|
}
|
|
111364
|
-
await
|
|
111413
|
+
await import_fs12.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
111365
111414
|
if (fileTracker) {
|
|
111366
111415
|
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
111367
111416
|
if (updated) {
|
|
@@ -111379,7 +111428,7 @@ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
|
111379
111428
|
const reindented = reindent(new_string, originalIndent);
|
|
111380
111429
|
const newLines = reindented.split("\n");
|
|
111381
111430
|
lines.splice(symbolInfo.startLine - 1, symbolInfo.endLine - symbolInfo.startLine + 1, ...newLines);
|
|
111382
|
-
await
|
|
111431
|
+
await import_fs12.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
111383
111432
|
if (fileTracker) {
|
|
111384
111433
|
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
111385
111434
|
if (updated) {
|
|
@@ -111434,7 +111483,7 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
|
|
|
111434
111483
|
if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
|
|
111435
111484
|
return 'Error editing file: Invalid position - must be "before" or "after". Use position="before" to insert before the line, or position="after" to insert after it.';
|
|
111436
111485
|
}
|
|
111437
|
-
const content = await
|
|
111486
|
+
const content = await import_fs12.promises.readFile(resolvedPath2, "utf-8");
|
|
111438
111487
|
const fileLines = content.split("\n");
|
|
111439
111488
|
if (startLine > fileLines.length) {
|
|
111440
111489
|
return `Error editing file: Line ${startLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
|
|
@@ -111463,20 +111512,20 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
|
|
|
111463
111512
|
const newLines = cleaned === "" ? [] : cleaned.split("\n");
|
|
111464
111513
|
if (position === "after") {
|
|
111465
111514
|
fileLines.splice(startLine, 0, ...newLines);
|
|
111466
|
-
await
|
|
111515
|
+
await import_fs12.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
111467
111516
|
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
111468
111517
|
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted after line ${startLine}`;
|
|
111469
111518
|
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine, action, modifications);
|
|
111470
111519
|
} else if (position === "before") {
|
|
111471
111520
|
fileLines.splice(startLine - 1, 0, ...newLines);
|
|
111472
|
-
await
|
|
111521
|
+
await import_fs12.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
111473
111522
|
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
111474
111523
|
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted before line ${startLine}`;
|
|
111475
111524
|
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
111476
111525
|
} else {
|
|
111477
111526
|
const replacedCount = endLine - startLine + 1;
|
|
111478
111527
|
fileLines.splice(startLine - 1, replacedCount, ...newLines);
|
|
111479
|
-
await
|
|
111528
|
+
await import_fs12.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
111480
111529
|
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
111481
111530
|
let action;
|
|
111482
111531
|
if (newLines.length === 0) {
|
|
@@ -111489,14 +111538,14 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
|
|
|
111489
111538
|
return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
111490
111539
|
}
|
|
111491
111540
|
}
|
|
111492
|
-
var import_ai6,
|
|
111541
|
+
var import_ai6, import_fs12, import_path16, import_fs13, editTool, createTool, multiEditTool, editSchema, createSchema, multiEditSchema, editDescription, createDescription, multiEditDescription, editToolDefinition, createToolDefinition, multiEditToolDefinition;
|
|
111493
111542
|
var init_edit = __esm({
|
|
111494
111543
|
"src/tools/edit.js"() {
|
|
111495
111544
|
"use strict";
|
|
111496
111545
|
import_ai6 = require("ai");
|
|
111497
|
-
import_fs11 = require("fs");
|
|
111498
|
-
import_path16 = require("path");
|
|
111499
111546
|
import_fs12 = require("fs");
|
|
111547
|
+
import_path16 = require("path");
|
|
111548
|
+
import_fs13 = require("fs");
|
|
111500
111549
|
init_path_validation();
|
|
111501
111550
|
init_fuzzyMatch();
|
|
111502
111551
|
init_symbolEdit();
|
|
@@ -111580,7 +111629,7 @@ Parameters:
|
|
|
111580
111629
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
111581
111630
|
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
111582
111631
|
}
|
|
111583
|
-
if (!(0,
|
|
111632
|
+
if (!(0, import_fs13.existsSync)(resolvedPath2)) {
|
|
111584
111633
|
return `Error editing file: File not found - ${file_path}. Verify the path is correct and the file exists. Use 'search' to find files by name, or 'create' to make a new file.`;
|
|
111585
111634
|
}
|
|
111586
111635
|
if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath2)) {
|
|
@@ -111610,7 +111659,7 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
|
111610
111659
|
Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
111611
111660
|
}
|
|
111612
111661
|
}
|
|
111613
|
-
const content = await
|
|
111662
|
+
const content = await import_fs12.promises.readFile(resolvedPath2, "utf-8");
|
|
111614
111663
|
let matchTarget = old_string;
|
|
111615
111664
|
let matchStrategy = "exact";
|
|
111616
111665
|
if (!content.includes(old_string)) {
|
|
@@ -111642,7 +111691,7 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
|
111642
111691
|
if (newContent === content) {
|
|
111643
111692
|
return `Error editing file: No changes made - the replacement result is identical to the original. Verify that old_string and new_string are actually different. If fuzzy matching was used, the matched text may already equal new_string.`;
|
|
111644
111693
|
}
|
|
111645
|
-
await
|
|
111694
|
+
await import_fs12.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
111646
111695
|
if (options.fileTracker) {
|
|
111647
111696
|
await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
111648
111697
|
options.fileTracker.recordTextEdit(resolvedPath2);
|
|
@@ -111713,13 +111762,13 @@ Important:
|
|
|
111713
111762
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
111714
111763
|
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
111715
111764
|
}
|
|
111716
|
-
if ((0,
|
|
111765
|
+
if ((0, import_fs13.existsSync)(resolvedPath2) && !overwrite) {
|
|
111717
111766
|
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
111718
111767
|
}
|
|
111719
|
-
const existed = (0,
|
|
111768
|
+
const existed = (0, import_fs13.existsSync)(resolvedPath2);
|
|
111720
111769
|
const dir = (0, import_path16.dirname)(resolvedPath2);
|
|
111721
|
-
await
|
|
111722
|
-
await
|
|
111770
|
+
await import_fs12.promises.mkdir(dir, { recursive: true });
|
|
111771
|
+
await import_fs12.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
111723
111772
|
if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
111724
111773
|
const action = existed && overwrite ? "overwrote" : "created";
|
|
111725
111774
|
const bytes = Buffer.byteLength(content, "utf-8");
|
|
@@ -112361,10 +112410,10 @@ async function listFilesByLevel(options) {
|
|
|
112361
112410
|
maxFiles = 100,
|
|
112362
112411
|
respectGitignore = true
|
|
112363
112412
|
} = options;
|
|
112364
|
-
if (!
|
|
112413
|
+
if (!import_fs14.default.existsSync(directory)) {
|
|
112365
112414
|
throw new Error(`Directory does not exist: ${directory}`);
|
|
112366
112415
|
}
|
|
112367
|
-
const gitDirExists =
|
|
112416
|
+
const gitDirExists = import_fs14.default.existsSync(import_path17.default.join(directory, ".git"));
|
|
112368
112417
|
if (gitDirExists && respectGitignore) {
|
|
112369
112418
|
try {
|
|
112370
112419
|
return await listFilesUsingGit(directory, maxFiles);
|
|
@@ -112395,7 +112444,7 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
112395
112444
|
while (queue.length > 0 && result.length < maxFiles) {
|
|
112396
112445
|
const { dir, level } = queue.shift();
|
|
112397
112446
|
try {
|
|
112398
|
-
const entries =
|
|
112447
|
+
const entries = import_fs14.default.readdirSync(dir, { withFileTypes: true });
|
|
112399
112448
|
const files = entries.filter((entry) => {
|
|
112400
112449
|
const fullPath = import_path17.default.join(dir, entry.name);
|
|
112401
112450
|
return getEntryTypeSync(entry, fullPath).isFile;
|
|
@@ -112426,11 +112475,11 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
112426
112475
|
}
|
|
112427
112476
|
function loadGitignorePatterns(directory) {
|
|
112428
112477
|
const gitignorePath = import_path17.default.join(directory, ".gitignore");
|
|
112429
|
-
if (!
|
|
112478
|
+
if (!import_fs14.default.existsSync(gitignorePath)) {
|
|
112430
112479
|
return [];
|
|
112431
112480
|
}
|
|
112432
112481
|
try {
|
|
112433
|
-
const content =
|
|
112482
|
+
const content = import_fs14.default.readFileSync(gitignorePath, "utf8");
|
|
112434
112483
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
112435
112484
|
} catch (error2) {
|
|
112436
112485
|
console.error(`Warning: Could not read .gitignore: ${error2.message}`);
|
|
@@ -112448,11 +112497,11 @@ function shouldIgnore(filePath, ignorePatterns) {
|
|
|
112448
112497
|
}
|
|
112449
112498
|
return false;
|
|
112450
112499
|
}
|
|
112451
|
-
var
|
|
112500
|
+
var import_fs14, import_path17, import_util12, import_child_process10, execAsync3;
|
|
112452
112501
|
var init_file_lister = __esm({
|
|
112453
112502
|
"src/utils/file-lister.js"() {
|
|
112454
112503
|
"use strict";
|
|
112455
|
-
|
|
112504
|
+
import_fs14 = __toESM(require("fs"), 1);
|
|
112456
112505
|
import_path17 = __toESM(require("path"), 1);
|
|
112457
112506
|
import_util12 = require("util");
|
|
112458
112507
|
import_child_process10 = require("child_process");
|
|
@@ -112471,11 +112520,11 @@ function initializeSimpleTelemetryFromOptions(options) {
|
|
|
112471
112520
|
});
|
|
112472
112521
|
return telemetry;
|
|
112473
112522
|
}
|
|
112474
|
-
var
|
|
112523
|
+
var import_fs15, import_path18, SimpleTelemetry, SimpleAppTracer;
|
|
112475
112524
|
var init_simpleTelemetry = __esm({
|
|
112476
112525
|
"src/agent/simpleTelemetry.js"() {
|
|
112477
112526
|
"use strict";
|
|
112478
|
-
|
|
112527
|
+
import_fs15 = require("fs");
|
|
112479
112528
|
import_path18 = require("path");
|
|
112480
112529
|
SimpleTelemetry = class {
|
|
112481
112530
|
constructor(options = {}) {
|
|
@@ -112491,10 +112540,10 @@ var init_simpleTelemetry = __esm({
|
|
|
112491
112540
|
initializeFileExporter() {
|
|
112492
112541
|
try {
|
|
112493
112542
|
const dir = (0, import_path18.dirname)(this.filePath);
|
|
112494
|
-
if (!(0,
|
|
112495
|
-
(0,
|
|
112543
|
+
if (!(0, import_fs15.existsSync)(dir)) {
|
|
112544
|
+
(0, import_fs15.mkdirSync)(dir, { recursive: true });
|
|
112496
112545
|
}
|
|
112497
|
-
this.stream = (0,
|
|
112546
|
+
this.stream = (0, import_fs15.createWriteStream)(this.filePath, { flags: "a" });
|
|
112498
112547
|
this.stream.on("error", (error2) => {
|
|
112499
112548
|
console.error(`[SimpleTelemetry] Stream error: ${error2.message}`);
|
|
112500
112549
|
});
|
package/package.json
CHANGED
package/src/tools/vercel.js
CHANGED
|
@@ -10,6 +10,7 @@ import { extract } from '../extract.js';
|
|
|
10
10
|
import { delegate } from '../delegate.js';
|
|
11
11
|
import { analyzeAll } from './analyzeAll.js';
|
|
12
12
|
import { searchSchema, querySchema, extractSchema, delegateSchema, analyzeAllSchema, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, parseTargets, parseAndResolvePaths, resolveTargetPath } from './common.js';
|
|
13
|
+
import { existsSync } from 'fs';
|
|
13
14
|
import { formatErrorForAI } from '../utils/error-types.js';
|
|
14
15
|
import { annotateOutputWithHashes } from './hashline.js';
|
|
15
16
|
|
|
@@ -118,6 +119,18 @@ function parseDelegatedTargets(rawResponse) {
|
|
|
118
119
|
return normalizeTargets(fallbackTargetsFromText(trimmed));
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
function splitTargetSuffix(target) {
|
|
123
|
+
const searchStart = (target.length > 2 && target[1] === ':' && /[a-zA-Z]/.test(target[0])) ? 2 : 0;
|
|
124
|
+
const colonIdx = target.indexOf(':', searchStart);
|
|
125
|
+
const hashIdx = target.indexOf('#');
|
|
126
|
+
if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
|
|
127
|
+
return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
|
|
128
|
+
} else if (hashIdx !== -1) {
|
|
129
|
+
return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
|
|
130
|
+
}
|
|
131
|
+
return { filePart: target, suffix: '' };
|
|
132
|
+
}
|
|
133
|
+
|
|
121
134
|
function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
|
|
122
135
|
return [
|
|
123
136
|
'You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.',
|
|
@@ -286,13 +299,61 @@ export const searchTool = (options = {}) => {
|
|
|
286
299
|
return fallbackResult;
|
|
287
300
|
}
|
|
288
301
|
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
|
|
302
|
+
// The delegate runs from workspace root (allowedFolders[0] or cwd), NOT from searchPaths[0].
|
|
303
|
+
// It returns paths relative to that workspace root. Resolve against the same base.
|
|
304
|
+
const delegateBase = options.allowedFolders?.[0] || options.cwd || '.';
|
|
292
305
|
const resolutionBase = searchPaths[0] || options.cwd || '.';
|
|
293
|
-
const resolvedTargets = targets.map(target => resolveTargetPath(target,
|
|
306
|
+
const resolvedTargets = targets.map(target => resolveTargetPath(target, delegateBase));
|
|
307
|
+
|
|
308
|
+
// Auto-fix: detect and repair invalid paths (doubled segments, AI hallucinations)
|
|
309
|
+
const validatedTargets = [];
|
|
310
|
+
for (const target of resolvedTargets) {
|
|
311
|
+
const { filePart, suffix } = splitTargetSuffix(target);
|
|
312
|
+
|
|
313
|
+
// 1. Path exists as-is
|
|
314
|
+
if (existsSync(filePart)) {
|
|
315
|
+
validatedTargets.push(target);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// 2. Detect doubled directory segments: /ws/proj/proj/src → /ws/proj/src
|
|
320
|
+
let fixed = false;
|
|
321
|
+
const parts = filePart.split('/').filter(Boolean);
|
|
322
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
323
|
+
if (parts[i] === parts[i + 1]) {
|
|
324
|
+
const candidate = '/' + [...parts.slice(0, i), ...parts.slice(i + 1)].join('/');
|
|
325
|
+
if (existsSync(candidate)) {
|
|
326
|
+
validatedTargets.push(candidate + suffix);
|
|
327
|
+
if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} → ${candidate}`);
|
|
328
|
+
fixed = true;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (fixed) continue;
|
|
334
|
+
|
|
335
|
+
// 3. Try resolving against alternative bases (searchPaths[0], cwd)
|
|
336
|
+
for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
|
|
337
|
+
if (altBase === delegateBase) continue;
|
|
338
|
+
const altResolved = resolveTargetPath(target, altBase);
|
|
339
|
+
const { filePart: altFile } = splitTargetSuffix(altResolved);
|
|
340
|
+
if (existsSync(altFile)) {
|
|
341
|
+
validatedTargets.push(altResolved);
|
|
342
|
+
if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} → ${altFile}`);
|
|
343
|
+
fixed = true;
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (fixed) continue;
|
|
348
|
+
|
|
349
|
+
// 4. Keep target anyway (probe binary will report the error)
|
|
350
|
+
// but log a warning
|
|
351
|
+
if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
|
|
352
|
+
validatedTargets.push(target);
|
|
353
|
+
}
|
|
354
|
+
|
|
294
355
|
const extractOptions = {
|
|
295
|
-
files:
|
|
356
|
+
files: validatedTargets,
|
|
296
357
|
cwd: resolutionBase,
|
|
297
358
|
allowTests: allow_tests ?? true
|
|
298
359
|
};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|