@@ -6,7 +6,7 @@ import { countFileLines } from "../../../integrations/misc/line-counter"
66import { readLines } from "../../../integrations/misc/read-lines"
77import { extractTextFromFile } from "../../../integrations/misc/extract-text"
88import { parseSourceCodeDefinitionsForFile } from "../../../services/tree-sitter"
9- import { isBinaryFile } from "isbinaryfile "
9+ import { isBinaryFileWithEncodingDetection } from "../../../utils/encoding "
1010import { ReadFileToolUse , ToolParamName , ToolResponse } from "../../../shared/tools"
1111import { readFileTool } from "../readFileTool"
1212import { formatResponse } from "../../prompts/responses"
@@ -23,7 +23,9 @@ vi.mock("path", async () => {
2323
2424// Already mocked above with hoisted fsPromises
2525
26- vi . mock ( "isbinaryfile" )
26+ vi . mock ( "../../../utils/encoding" , ( ) => ( {
27+ isBinaryFileWithEncodingDetection : vi . fn ( ) ,
28+ } ) )
2729
2830vi . mock ( "../../../integrations/misc/line-counter" )
2931vi . mock ( "../../../integrations/misc/read-lines" )
@@ -238,7 +240,7 @@ describe("read_file tool with maxReadFileLine setting", () => {
238240 const mockedExtractTextFromFile = vi . mocked ( extractTextFromFile )
239241 const mockedParseSourceCodeDefinitionsForFile = vi . mocked ( parseSourceCodeDefinitionsForFile )
240242
241- const mockedIsBinaryFile = vi . mocked ( isBinaryFile )
243+ const mockedIsBinaryFileWithEncodingDetection = vi . mocked ( isBinaryFileWithEncodingDetection )
242244 const mockedPathResolve = vi . mocked ( path . resolve )
243245
244246 let mockCline : any
@@ -249,7 +251,7 @@ describe("read_file tool with maxReadFileLine setting", () => {
249251 // Clear specific mocks (not all mocks to preserve shared state)
250252 mockedCountFileLines . mockClear ( )
251253 mockedExtractTextFromFile . mockClear ( )
252- mockedIsBinaryFile . mockClear ( )
254+ mockedIsBinaryFileWithEncodingDetection . mockClear ( )
253255 mockedPathResolve . mockClear ( )
254256 addLineNumbersMock . mockClear ( )
255257 extractTextFromFileMock . mockClear ( )
@@ -264,7 +266,7 @@ describe("read_file tool with maxReadFileLine setting", () => {
264266 setImageSupport ( mockCline , false )
265267
266268 mockedPathResolve . mockReturnValue ( absoluteFilePath )
267- mockedIsBinaryFile . mockResolvedValue ( false )
269+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( false )
268270
269271 mockInputContent = fileContent
270272
@@ -502,7 +504,7 @@ describe("read_file tool with maxReadFileLine setting", () => {
502504 describe ( "when file is binary" , ( ) => {
503505 it ( "should always use extractTextFromFile regardless of maxReadFileLine" , async ( ) => {
504506 // Setup
505- mockedIsBinaryFile . mockResolvedValue ( true )
507+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
506508 mockedCountFileLines . mockResolvedValue ( 3 )
507509 mockedExtractTextFromFile . mockResolvedValue ( "" )
508510
@@ -544,7 +546,7 @@ describe("read_file tool XML output structure", () => {
544546
545547 const mockedCountFileLines = vi . mocked ( countFileLines )
546548 const mockedExtractTextFromFile = vi . mocked ( extractTextFromFile )
547- const mockedIsBinaryFile = vi . mocked ( isBinaryFile )
549+ const mockedIsBinaryFileWithEncodingDetection = vi . mocked ( isBinaryFileWithEncodingDetection )
548550 const mockedPathResolve = vi . mocked ( path . resolve )
549551 const mockedFsReadFile = vi . mocked ( fsPromises . readFile )
550552 const imageBuffer = Buffer . from (
@@ -560,7 +562,7 @@ describe("read_file tool XML output structure", () => {
560562 // Clear specific mocks (not all mocks to preserve shared state)
561563 mockedCountFileLines . mockClear ( )
562564 mockedExtractTextFromFile . mockClear ( )
563- mockedIsBinaryFile . mockClear ( )
565+ mockedIsBinaryFileWithEncodingDetection . mockClear ( )
564566 mockedPathResolve . mockClear ( )
565567 addLineNumbersMock . mockClear ( )
566568 extractTextFromFileMock . mockClear ( )
@@ -580,7 +582,7 @@ describe("read_file tool XML output structure", () => {
580582 setImageSupport ( mockCline , true )
581583
582584 mockedPathResolve . mockReturnValue ( absoluteFilePath )
583- mockedIsBinaryFile . mockResolvedValue ( false )
585+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( false )
584586
585587 // Set default implementation for extractTextFromFile
586588 mockedExtractTextFromFile . mockImplementation ( ( filePath ) => {
@@ -617,7 +619,7 @@ describe("read_file tool XML output structure", () => {
617619
618620 mockProvider . getState . mockResolvedValue ( { maxReadFileLine, maxImageFileSize : 20 , maxTotalImageSize : 20 } )
619621 mockedCountFileLines . mockResolvedValue ( totalLines )
620- mockedIsBinaryFile . mockResolvedValue ( isBinary )
622+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( isBinary )
621623 mockCline . rooIgnoreController . validateAccess = vi . fn ( ) . mockReturnValue ( validateAccess )
622624
623625 let argsContent = `<file><path>${ testFilePath } </path></file>`
@@ -758,7 +760,7 @@ describe("read_file tool XML output structure", () => {
758760
759761 it ( "should allow multiple images under the total memory limit" , async ( ) => {
760762 // Setup required mocks (don't clear all mocks - preserve API setup)
761- mockedIsBinaryFile . mockResolvedValue ( true )
763+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
762764 mockedCountFileLines . mockResolvedValue ( 0 )
763765 fsPromises . readFile . mockResolvedValue (
764766 Buffer . from (
@@ -831,7 +833,7 @@ describe("read_file tool XML output structure", () => {
831833
832834 it ( "should skip images that would exceed the total memory limit" , async ( ) => {
833835 // Setup required mocks (don't clear all mocks)
834- mockedIsBinaryFile . mockResolvedValue ( true )
836+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
835837 mockedCountFileLines . mockResolvedValue ( 0 )
836838 fsPromises . readFile . mockResolvedValue (
837839 Buffer . from (
@@ -917,7 +919,7 @@ describe("read_file tool XML output structure", () => {
917919 // Setup mocks (don't clear all mocks)
918920
919921 // Setup required mocks
920- mockedIsBinaryFile . mockResolvedValue ( true )
922+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
921923 mockedCountFileLines . mockResolvedValue ( 0 )
922924 fsPromises . readFile . mockResolvedValue (
923925 Buffer . from (
@@ -990,7 +992,7 @@ describe("read_file tool XML output structure", () => {
990992 // Setup mocks (don't clear all mocks)
991993
992994 // Setup required mocks
993- mockedIsBinaryFile . mockResolvedValue ( true )
995+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
994996 mockedCountFileLines . mockResolvedValue ( 0 )
995997 fsPromises . readFile . mockResolvedValue (
996998 Buffer . from (
@@ -1084,7 +1086,7 @@ describe("read_file tool XML output structure", () => {
10841086 maxTotalImageSize : 20 , // 20MB total
10851087 } )
10861088
1087- mockedIsBinaryFile . mockResolvedValue ( true )
1089+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
10881090 mockedCountFileLines . mockResolvedValue ( 0 )
10891091 mockedFsReadFile . mockResolvedValue ( imageBuffer )
10901092
@@ -1115,7 +1117,7 @@ describe("read_file tool XML output structure", () => {
11151117 // Setup mocks (don't clear all mocks)
11161118
11171119 // Setup required mocks for first batch
1118- mockedIsBinaryFile . mockResolvedValue ( true )
1120+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
11191121 mockedCountFileLines . mockResolvedValue ( 0 )
11201122 fsPromises . readFile . mockResolvedValue (
11211123 Buffer . from (
@@ -1161,7 +1163,7 @@ describe("read_file tool XML output structure", () => {
11611163 await executeReadMultipleImagesTool ( firstBatch . map ( ( img ) => img . path ) )
11621164
11631165 // Setup second batch (don't clear all mocks)
1164- mockedIsBinaryFile . mockResolvedValue ( true )
1166+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
11651167 mockedCountFileLines . mockResolvedValue ( 0 )
11661168 fsPromises . readFile . mockResolvedValue (
11671169 Buffer . from (
@@ -1203,7 +1205,7 @@ describe("read_file tool XML output structure", () => {
12031205 // Clear and reset file system mocks for second batch
12041206 fsPromises . stat . mockClear ( )
12051207 fsPromises . readFile . mockClear ( )
1206- mockedIsBinaryFile . mockClear ( )
1208+ mockedIsBinaryFileWithEncodingDetection . mockClear ( )
12071209 mockedCountFileLines . mockClear ( )
12081210
12091211 // Reset mocks for second batch
@@ -1214,7 +1216,7 @@ describe("read_file tool XML output structure", () => {
12141216 "base64" ,
12151217 ) ,
12161218 )
1217- mockedIsBinaryFile . mockResolvedValue ( true )
1219+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
12181220 mockedCountFileLines . mockResolvedValue ( 0 )
12191221 mockedPathResolve . mockImplementation ( ( cwd , relPath ) => `/${ relPath } ` )
12201222
@@ -1241,7 +1243,7 @@ describe("read_file tool XML output structure", () => {
12411243 ]
12421244
12431245 // Setup mocks
1244- mockedIsBinaryFile . mockResolvedValue ( true )
1246+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
12451247 mockedCountFileLines . mockResolvedValue ( 0 )
12461248 fsPromises . readFile . mockResolvedValue ( imageBuffer )
12471249
@@ -1289,7 +1291,7 @@ describe("read_file tool XML output structure", () => {
12891291 // starts with fresh memory tracking
12901292
12911293 // Setup mocks
1292- mockedIsBinaryFile . mockResolvedValue ( true )
1294+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
12931295 mockedCountFileLines . mockResolvedValue ( 0 )
12941296 fsPromises . readFile . mockResolvedValue ( imageBuffer )
12951297
@@ -1394,7 +1396,7 @@ describe("read_file tool with image support", () => {
13941396 const imageBuffer = Buffer . from ( base64ImageData , "base64" )
13951397
13961398 const mockedCountFileLines = vi . mocked ( countFileLines )
1397- const mockedIsBinaryFile = vi . mocked ( isBinaryFile )
1399+ const mockedIsBinaryFileWithEncodingDetection = vi . mocked ( isBinaryFileWithEncodingDetection )
13981400 const mockedPathResolve = vi . mocked ( path . resolve )
13991401 const mockedFsReadFile = vi . mocked ( fsPromises . readFile )
14001402 const mockedExtractTextFromFile = vi . mocked ( extractTextFromFile )
@@ -1406,7 +1408,7 @@ describe("read_file tool with image support", () => {
14061408 beforeEach ( ( ) => {
14071409 // Clear specific mocks (not all mocks to preserve shared state)
14081410 mockedPathResolve . mockClear ( )
1409- mockedIsBinaryFile . mockClear ( )
1411+ mockedIsBinaryFileWithEncodingDetection . mockClear ( )
14101412 mockedCountFileLines . mockClear ( )
14111413 mockedFsReadFile . mockClear ( )
14121414 mockedExtractTextFromFile . mockClear ( )
@@ -1425,7 +1427,7 @@ describe("read_file tool with image support", () => {
14251427 setImageSupport ( localMockCline , true )
14261428
14271429 mockedPathResolve . mockReturnValue ( absoluteImagePath )
1428- mockedIsBinaryFile . mockResolvedValue ( true )
1430+ mockedIsBinaryFileWithEncodingDetection . mockResolvedValue ( true )
14291431 mockedCountFileLines . mockResolvedValue ( 0 )
14301432 mockedFsReadFile . mockResolvedValue ( imageBuffer )
14311433
0 commit comments