Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/core/diff/strategies/multi-search-replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
18 changes: 18 additions & 0 deletions src/core/prompts/tools/insert-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,23 @@ Example for appending to the end of file:
// This is the end of the file
</content>
</insert_content>

Example for creating very large files that exceed output limits:
<write_to_file>
<path>src/large_file.txt</path>
<content>
// This is the beginning of a very large file but you must terminate prematurely in order for line_count to be produced:
</content>
<line_count>100</line_count>
</write_to_file>

Then use insert_content to append the rest of the content starting immediately where you left off; repeat as many times as necessary:
<insert_content>
<path>src/large_file.txt</path>
<line>0</line>
<content>
// This is a continuation of very large file
</content>
</insert_content>
`
}
7 changes: 7 additions & 0 deletions src/core/tools/insertContentTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/core/tools/writeToFileTool.ts
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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 '<apply_diff>' or '<search_and_replace>' tool to change an existing file.`,
),
)
return
}
}

const sharedMessageProps: ClineSayTool = {
tool: fileExists ? "editedExistingFile" : "newFileCreated",
path: getReadablePath(cline.cwd, removeClosingTag("path", relPath)),
Expand Down
2 changes: 2 additions & 0 deletions src/integrations/misc/extract-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ async function extractTextFromIPYNB(filePath: string): Promise<string> {
}

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
Expand Down
Loading