@@ -77,14 +77,24 @@ export class FileSearchService {
7777 // Execute search
7878 const matchedFiles = await fg ( patterns , globOptions ) ;
7979
80- // Get file stats for all matched files
80+ // Sort matched files by path for consistent ordering before processing
81+ // This allows us to slice before expensive fs.stat operations
82+ matchedFiles . sort ( ( a , b ) => a . localeCompare ( b ) ) ;
83+
84+ // Apply limit
85+ const limit = params . limit ?? 100 ;
86+ // We take a few more than limit to account for potential directories or errors
87+ // Since fast-glob with onlyFiles: true (default) is reliable, this buffer is minimal
88+ const candidates = matchedFiles . slice ( 0 , limit ) ;
89+
90+ // Get file stats only for the candidate files
8191 const files : FileSearchResult [ ] = [ ] ;
82- for ( const relativePath of matchedFiles ) {
92+ for ( const relativePath of candidates ) {
8393 try {
8494 const absolutePath = path . join ( workspaceRoot , relativePath ) ;
8595 const stats = await fs . stat ( absolutePath ) ;
8696
87- // Skip directories
97+ // Skip directories (though fast-glob should have filtered them)
8898 if ( stats . isDirectory ( ) ) {
8999 continue ;
90100 }
@@ -95,24 +105,17 @@ export class FileSearchService {
95105 size_bytes : stats . size ,
96106 modified : stats . mtime . toISOString ( ) ,
97107 } ) ;
98- } catch ( error ) {
108+ } catch {
99109 // Skip files that can't be accessed
100110 continue ;
101111 }
102112 }
103113
104- // Sort by path for consistent ordering
105- files . sort ( ( a , b ) => a . relative_path . localeCompare ( b . relative_path ) ) ;
106-
107- // Apply limit
108- const limit = params . limit ?? 100 ;
109- const limitedFiles = files . slice ( 0 , limit ) ;
110-
111114 const endTime = Date . now ( ) ;
112115
113116 return {
114- total_matches : files . length ,
115- files : limitedFiles ,
117+ total_matches : matchedFiles . length ,
118+ files,
116119 search_time_ms : endTime - startTime ,
117120 } ;
118121 }
0 commit comments