diff --git a/src/core/diff/strategies/multi-search-replace.ts b/src/core/diff/strategies/multi-search-replace.ts
index 00cebd2bea..f8f4e656e8 100644
--- a/src/core/diff/strategies/multi-search-replace.ts
+++ b/src/core/diff/strategies/multi-search-replace.ts
@@ -423,8 +423,10 @@ Only use a single line of '=======' between search and replacement content, beca
let searchStartIndex = 0
let searchEndIndex = resultLines.length
+ startLine = endLine = 0
+
// Validate and handle line range if provided
- if (startLine) {
+ if (startLine && endLine) {
// Convert to 0-based index
const exactStartIndex = startLine - 1
const searchLen = searchLines.length
@@ -483,7 +485,7 @@ Only use a single line of '=======' between search and replacement content, beca
} else {
// No match found with either method
const originalContentSection =
- startLine !== undefined && endLine !== undefined
+ startLine && endLine
? `\n\nOriginal Content:\n${addLineNumbers(
resultLines
.slice(
diff --git a/src/core/prompts/tools/insert-content.ts b/src/core/prompts/tools/insert-content.ts
index 7e339513d5..c575c0eb5c 100644
--- a/src/core/prompts/tools/insert-content.ts
+++ b/src/core/prompts/tools/insert-content.ts
@@ -29,5 +29,23 @@ Example for appending to the end of file:
// This is the end of the file
+
+Example for creating very large files that exceed output limits:
+
+src/large_file.txt
+
+// This is the beginning of a very large file but you must terminate prematurely in order for line_count to be produced:
+
+100
+
+
+Then use insert_content to append the rest of the content starting immediately where you left off; repeat as many times as necessary:
+
+src/large_file.txt
+0
+
+// This is a continuation of very large file
+
+
`
}
diff --git a/src/core/tools/insertContentTool.ts b/src/core/tools/insertContentTool.ts
index 8e6c5fc89e..d85f6c35ed 100644
--- a/src/core/tools/insertContentTool.ts
+++ b/src/core/tools/insertContentTool.ts
@@ -78,6 +78,13 @@ export async function insertContentTool(
return
}
+ if (lineNumber !== 0) {
+ cline.consecutiveMistakeCount++
+ cline.recordToolError("insert_content")
+ pushToolResult(formatResponse.toolError("Invalid line number: only append is supported so line must be 0"))
+ return
+ }
+
cline.consecutiveMistakeCount = 0
// Read the file
diff --git a/src/core/tools/writeToFileTool.ts b/src/core/tools/writeToFileTool.ts
index a23aea9714..e0a302e1a1 100644
--- a/src/core/tools/writeToFileTool.ts
+++ b/src/core/tools/writeToFileTool.ts
@@ -1,6 +1,7 @@
import path from "path"
import delay from "delay"
import * as vscode from "vscode"
+import { countFileLines } from "../../integrations/misc/line-counter"
import { Cline } from "../Cline"
import { ClineSayTool } from "../../shared/ExtensionMessage"
@@ -69,6 +70,21 @@ export async function writeToFileTool(
const fullPath = relPath ? path.resolve(cline.cwd, removeClosingTag("path", relPath)) : ""
const isOutsideWorkspace = isPathOutsideWorkspace(fullPath)
+ if (fileExists) {
+ // Count the lines in the file
+ const absolutePath = path.resolve(cline.cwd, relPath)
+ const lineCount = await countFileLines(absolutePath)
+ // Only show error if file has more than 25 lines
+ if (lineCount > 25) {
+ pushToolResult(
+ formatResponse.toolError(
+ `File '${relPath}' already exists and is >25 lines long, write_to_file failed: You must use the '' or '' tool to change an existing file.`,
+ ),
+ )
+ return
+ }
+ }
+
const sharedMessageProps: ClineSayTool = {
tool: fileExists ? "editedExistingFile" : "newFileCreated",
path: getReadablePath(cline.cwd, removeClosingTag("path", relPath)),
diff --git a/src/integrations/misc/extract-text.ts b/src/integrations/misc/extract-text.ts
index 5bbbbf8514..924badc1d1 100644
--- a/src/integrations/misc/extract-text.ts
+++ b/src/integrations/misc/extract-text.ts
@@ -55,6 +55,8 @@ async function extractTextFromIPYNB(filePath: string): Promise {
}
export function addLineNumbers(content: string, startLine: number = 1): string {
+ return content
+
// If content is empty, return empty string - empty files should not have line numbers
// If content is empty but startLine > 1, return "startLine | " because we know the file is not empty
// but the content is empty at that line offset