@probelabs/probe 0.6.0-rc270 → 0.6.0-rc272
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-rc272-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-rc272-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/probe-v0.6.0-rc272-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc272-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc272-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/index.js +72 -23
- package/build/tools/vercel.js +67 -6
- package/cjs/agent/ProbeAgent.cjs +124 -83
- package/cjs/index.cjs +99 -58
- package/package.json +1 -1
- package/src/tools/vercel.js +67 -6
- 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
- package/bin/binaries/probe-v0.6.0-rc270-x86_64-unknown-linux-musl.tar.gz +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.",
|
|
@@ -9135,7 +9147,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
|
|
|
9135
9147
|
"",
|
|
9136
9148
|
"Strategy for complex queries:",
|
|
9137
9149
|
"1. Analyze the query - identify key concepts, entities, and relationships",
|
|
9138
|
-
'2. Run focused searches for each concept (e.g., "
|
|
9150
|
+
'2. Run focused searches for each independent concept (e.g., for "how do payments work and how are emails sent", search "payments" and "emails" separately since they are unrelated)',
|
|
9139
9151
|
"3. Use extract to verify relevance of promising results",
|
|
9140
9152
|
"4. Combine all relevant targets in your final response",
|
|
9141
9153
|
"",
|
|
@@ -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.',
|
|
@@ -132,7 +145,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
|
|
|
132
145
|
'',
|
|
133
146
|
'Strategy for complex queries:',
|
|
134
147
|
'1. Analyze the query - identify key concepts, entities, and relationships',
|
|
135
|
-
'2. Run focused searches for each concept (e.g., "
|
|
148
|
+
'2. Run focused searches for each independent concept (e.g., for "how do payments work and how are emails sent", search "payments" and "emails" separately since they are unrelated)',
|
|
136
149
|
'3. Use extract to verify relevance of promising results',
|
|
137
150
|
'4. Combine all relevant targets in your final response',
|
|
138
151
|
'',
|
|
@@ -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
|
};
|