diff --git a/.changeset/tough-coats-hear.md b/.changeset/tough-coats-hear.md new file mode 100644 index 00000000000..6189de0fda0 --- /dev/null +++ b/.changeset/tough-coats-hear.md @@ -0,0 +1,5 @@ +--- +"roo-cline": patch +--- + +Respect the setting to always read the full file diff --git a/src/core/__tests__/read-file-maxReadFileLine.test.ts b/src/core/__tests__/read-file-maxReadFileLine.test.ts index 0f3e3a0d67e..bbbbcb37eb7 100644 --- a/src/core/__tests__/read-file-maxReadFileLine.test.ts +++ b/src/core/__tests__/read-file-maxReadFileLine.test.ts @@ -186,7 +186,6 @@ describe("read_file tool with maxReadFileLine setting", () => { return toolResult } - describe("when maxReadFileLine is negative", () => { it("should read the entire file using extractTextFromFile", async () => { // Setup - use default mockInputContent @@ -201,6 +200,43 @@ describe("read_file tool with maxReadFileLine setting", () => { expect(mockedParseSourceCodeDefinitionsForFile).not.toHaveBeenCalled() expect(result).toBe(expectedFullFileXml) }) + + it("should ignore range parameters and read entire file when maxReadFileLine is -1", async () => { + // Setup - use default mockInputContent + mockInputContent = fileContent + + // Execute with range parameters + const result = await executeReadFileTool( + { + start_line: "2", + end_line: "4", + }, + { maxReadFileLine: -1 }, + ) + + // Verify that extractTextFromFile is still used (not readLines) + expect(mockedExtractTextFromFile).toHaveBeenCalledWith(absoluteFilePath) + expect(mockedReadLines).not.toHaveBeenCalled() + expect(mockedParseSourceCodeDefinitionsForFile).not.toHaveBeenCalled() + expect(result).toBe(expectedFullFileXml) + }) + + it("should not show line snippet in approval message when maxReadFileLine is -1", async () => { + // This test verifies the line snippet behavior for the approval message + // Setup - use default mockInputContent + mockInputContent = fileContent + + // Execute - we'll reuse executeReadFileTool to run the tool + await executeReadFileTool({}, { maxReadFileLine: -1 }) + + // Verify the empty line snippet for full read was passed to the approval message + // Look at the parameters passed to the 'ask' method in the approval message + const askCall = mockCline.ask.mock.calls[0] + const completeMessage = JSON.parse(askCall[1]) + + // Verify the reason (lineSnippet) is empty or undefined for full read + expect(completeMessage.reason).toBeFalsy() + }) }) describe("when maxReadFileLine is 0", () => { diff --git a/src/core/tools/readFileTool.ts b/src/core/tools/readFileTool.ts index 2a3fc6cca21..fdb74109c3e 100644 --- a/src/core/tools/readFileTool.ts +++ b/src/core/tools/readFileTool.ts @@ -51,13 +51,16 @@ export async function readFileTool( return } + const { maxReadFileLine = 500 } = (await cline.providerRef.deref()?.getState()) ?? {} + const isFullRead = maxReadFileLine === -1 + // Check if we're doing a line range read let isRangeRead = false let startLine: number | undefined = undefined let endLine: number | undefined = undefined - // Check if we have either range parameter - if (startLineStr || endLineStr) { + // Check if we have either range parameter and we're not doing a full read + if (!isFullRead && (startLineStr || endLineStr)) { isRangeRead = true } @@ -98,11 +101,11 @@ export async function readFileTool( return } - const { maxReadFileLine = 500 } = (await cline.providerRef.deref()?.getState()) ?? {} - // Create line snippet description for approval message let lineSnippet = "" - if (startLine !== undefined && endLine !== undefined) { + if (isFullRead) { + // No snippet for full read + } else if (startLine !== undefined && endLine !== undefined) { lineSnippet = t("tools:readFile.linesRange", { start: startLine + 1, end: endLine + 1 }) } else if (startLine !== undefined) { lineSnippet = t("tools:readFile.linesFromToEnd", { start: startLine + 1 })