Revert "fix(core-tools): resolve defensive path resolution for at-reference files" (#27992)

This commit is contained in:
Gal Zahavi
2026-06-17 13:23:03 -07:00
committed by GitHub
parent f741d03282
commit 4d3dcdce1f
6 changed files with 29 additions and 882 deletions
+3 -9
View File
@@ -8,7 +8,6 @@ import * as fs from 'node:fs';
import * as path from 'node:path';
import type { Config } from '../config/config.js';
import { bfsFileSearchSync } from './bfsFileSearch.js';
import { resolveDefensiveToolPath } from './paths.js';
type SuccessfulPathCorrection = {
success: true;
@@ -35,13 +34,8 @@ export function correctPath(
filePath: string,
config: Config,
): PathCorrectionResult {
const sanitizedPath = resolveDefensiveToolPath(
filePath,
config.getTargetDir(),
);
// Check for direct path relative to the primary target directory.
const directPath = path.join(config.getTargetDir(), sanitizedPath);
const directPath = path.join(config.getTargetDir(), filePath);
if (fs.existsSync(directPath)) {
return { success: true, correctedPath: directPath };
}
@@ -49,8 +43,8 @@ export function correctPath(
// If not found directly, search across all workspace directories for ambiguous matches.
const workspaceContext = config.getWorkspaceContext();
const searchPaths = workspaceContext.getDirectories();
const basename = path.basename(sanitizedPath);
const normalizedTarget = sanitizedPath.replace(/\\/g, '/');
const basename = path.basename(filePath);
const normalizedTarget = filePath.replace(/\\/g, '/');
// Normalize path for matching and check if it ends with the provided relative path
const foundFiles = searchPaths
-56
View File
@@ -572,59 +572,3 @@ export function isTrustedSystemPath(filePath: string): boolean {
);
}
}
/**
* Defensively resolves and sanitizes a file path generated by the LLM,
* stripping user-facing reference prefixes if necessary.
*/
export function resolveDefensiveToolPath(
filePath: string,
targetDir: string,
): string {
if (filePath.includes('\0')) {
return filePath;
}
try {
const literalPath = path.resolve(targetDir, filePath);
// If the file literally exists on disk as-is, return the resolved literal path immediately
if (fs.existsSync(literalPath)) {
return filePath;
}
// If the model supplied a leading @ prefix and the literal path doesn't exist:
if (filePath.startsWith('@') && filePath.length > 1) {
if (filePath.startsWith('@/') || filePath.startsWith('@\\')) {
return filePath.substring(1).replace(/^[\\/]+/, '');
}
const strippedPath = filePath.substring(1).replace(/^[\\/]+/, '');
// Check if a literal directory/file starting with '@' exists for the first segment.
// If it does, we should preserve the '@' prefix.
const parts = strippedPath.split(/[\\/]/);
const firstSegment = parts[0];
if (firstSegment) {
const literalFirstSegment = path.resolve(targetDir, '@' + firstSegment);
if (fs.existsSync(literalFirstSegment)) {
return filePath;
}
// Only strip the '@' prefix if the stripped path's first segment actually exists
const strippedFirstSegment = path.resolve(targetDir, firstSegment);
if (fs.existsSync(strippedFirstSegment)) {
return strippedPath;
}
}
// Otherwise, preserve the '@' prefix to allow creating new files/directories starting with '@'
return filePath;
}
} catch {
// Fallback to original path if any filesystem or resolution error occurs
}
// Fallback: return the original path
return filePath;
}