refactor(core): centralize path validation and allow temp dir access for tools (#17185)

Co-authored-by: Your Name <joshualitt@google.com>
This commit is contained in:
N. Taylor Mullen
2026-01-27 13:17:40 -08:00
committed by GitHub
parent c9340a9c6f
commit 5f569fa103
26 changed files with 1149 additions and 609 deletions
+20 -8
View File
@@ -5,6 +5,7 @@
*/
import fs from 'node:fs';
import fsPromises from 'node:fs/promises';
import path from 'node:path';
import * as Diff from 'diff';
import { WRITE_FILE_TOOL_NAME } from './tool-names.js';
@@ -245,6 +246,18 @@ class WriteFileToolInvocation extends BaseToolInvocation<
}
async execute(abortSignal: AbortSignal): Promise<ToolResult> {
const validationError = this.config.validatePathAccess(this.resolvedPath);
if (validationError) {
return {
llmContent: validationError,
returnDisplay: 'Error: Path not in workspace.',
error: {
message: validationError,
type: ToolErrorType.PATH_NOT_IN_WORKSPACE,
},
};
}
const { content, ai_proposed_content, modified_by_user } = this.params;
const correctedContentResult = await getCorrectedFileContent(
this.config,
@@ -282,8 +295,10 @@ class WriteFileToolInvocation extends BaseToolInvocation<
try {
const dirName = path.dirname(this.resolvedPath);
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName, { recursive: true });
try {
await fsPromises.access(dirName);
} catch {
await fsPromises.mkdir(dirName, { recursive: true });
}
await this.config
@@ -453,12 +468,9 @@ export class WriteFileTool
const resolvedPath = path.resolve(this.config.getTargetDir(), filePath);
const workspaceContext = this.config.getWorkspaceContext();
if (!workspaceContext.isPathWithinWorkspace(resolvedPath)) {
const directories = workspaceContext.getDirectories();
return `File path must be within one of the workspace directories: ${directories.join(
', ',
)}`;
const validationError = this.config.validatePathAccess(resolvedPath);
if (validationError) {
return validationError;
}
try {