Replace: Creating and Updating Files
Replace writes or overwrites entire files on the filesystem, handling complete file creation or replacement rather than targeted edits.
Complete Prompt
export const PROMPT = `Write a file to the local filesystem. Overwrites the existing file if there is one.
Before using this tool:
1. Use the ReadFile tool to understand the file's contents and context
2. Directory Verification (only applicable when creating new files):
- Use the LS tool to verify the parent directory exists and is the correct location`
export const DESCRIPTION = 'Write a file to the local filesystem.'
Tool Prompt: Replace
Write a file to the local filesystem. Overwrites the existing file if there is one.
Before using this tool:
Use the ReadFile tool to understand the file's contents and context
Directory Verification (only applicable when creating new files):
- Use the LS tool to verify the parent directory exists and is the correct location
How It Works
Replace takes two required parameters and handles file operations with contextual awareness:
const inputSchema = z.strictObject({
file_path: z
.string()
.describe(
'The absolute path to the file to write (must be absolute, not relative)',
),
content: z.string().describe('The content to write to the file'),
})
The implementation handles both creating new files and updating existing ones with appropriate safety checks:
async *call({ file_path, content }, { readFileTimestamps }) {
const fullFilePath = isAbsolute(file_path)
? file_path
: resolve(getCwd(), file_path)
const dir = dirname(fullFilePath)
const oldFileExists = existsSync(fullFilePath)
const enc = oldFileExists ? detectFileEncoding(fullFilePath) : 'utf-8'
const oldContent = oldFileExists ? readFileSync(fullFilePath, enc) : null
const endings = oldFileExists
? detectLineEndings(fullFilePath)
: await detectRepoLineEndings(getCwd())
mkdirSync(dir, { recursive: true })
writeTextContent(fullFilePath, content, enc, endings!)
// Update read timestamp, to invalidate stale writes
readFileTimestamps[fullFilePath] = statSync(fullFilePath).mtimeMs
if (oldContent) {
const patch = getPatch({
filePath: file_path,
fileContents: oldContent,
oldStr: oldContent,
newStr: content,
})
// Return update result with diff information
const data = {
type: 'update' as const,
filePath: file_path,
content,
structuredPatch: patch,
}
yield {
type: 'result',
data,
resultForAssistant: this.renderResultForAssistant(data),
}
return
}
// Return create result
const data = {
type: 'create' as const,
filePath: file_path,
content,
structuredPatch: [],
}
yield {
type: 'result',
data,
resultForAssistant: this.renderResultForAssistant(data),
}
}
Key Features
Replace includes these important capabilities:
-
Input Validation
- Validates file paths
- Prevents timestamp conflicts
- Creates directories for new files
-
Content Management
- Detects encoding for existing files (UTF-8, UTF-16LE, ASCII)
- Preserves line endings (CRLF/LF)
- Maintains consistent formatting
-
Change Visualization
- Shows diffs for file updates
- Provides previews for new files
- Truncates large files for display
-
Conflict Prevention
- Tracks read timestamps
- Detects external modifications
- Prevents overwriting recently modified files
Architecture
The Replace tool follows a structured flow:
FileWriteTool.tsx (React component)
↓
validateInput() → Checks if file can be safely written
↓
call() → Writes content with appropriate encoding and line endings
↓
renderToolResultMessage() → Shows changes to user
↓
renderResultForAssistant() → Returns formatted result for Claude
The tool handles two main operations with different display approaches:
- Create: Shows complete file content with syntax highlighting
- Update: Shows diff between old and new versions
Permissions
Replace enforces a strict permission model:
needsPermissions({ file_path }) {
return !hasWritePermission(file_path)
}
This requires explicit user approval before writing to any location. The permission UI shows:
- Content preview for new files
- Structured diff for file updates
- The exact file path being modified
Additional validation safeguards include:
async validateInput({ file_path }, { readFileTimestamps }) {
// Allow creating new files without read check
if (!existsSync(fullFilePath)) {
return { result: true }
}
// Require existing files to be read first
const readTimestamp = readFileTimestamps[fullFilePath]
if (!readTimestamp) {
return {
result: false,
message: 'File has not been read yet. Read it first before writing to it.',
}
}
// Prevent race conditions with external changes
const stats = statSync(fullFilePath)
const lastWriteTime = stats.mtimeMs
if (lastWriteTime > readTimestamp) {
return {
result: false,
message: 'File has been modified since read... Read it again before attempting to write it.',
}
}
return { result: true }
}
Usage Examples
Common usage patterns:
-
Creating a new file
Replace(file_path: "/path/to/new-file.txt", content: "New file content here")
-
Overwriting an existing file
Replace(file_path: "/path/to/existing-file.js", content: "Updated content here")
FileWriteTool complements FileEditTool by handling complete file creation or replacement rather than targeted edits, making it the preferred choice when:
- Creating entirely new files
- Completely rewriting an existing file's contents
- Avoiding multiple sequential edits to the same file