@@ -15,6 +15,7 @@ import { buildSubagentsPath, extractBaseDir } from '@main/utils/pathDecoder';
1515import { createLogger } from '@shared/utils/logger' ;
1616import * as fs from 'fs' ;
1717import * as path from 'path' ;
18+ import * as readline from 'readline' ;
1819
1920import type { FileSystemProvider } from '@main/services/infrastructure/FileSystemProvider' ;
2021
@@ -51,16 +52,13 @@ export class SubagentLocator {
5152 ) ;
5253
5354 // Check if at least one subagent file has content (not empty)
55+ // Uses stat() to check file size instead of reading file contents
5456 for ( const entry of subagentFiles ) {
5557 const filePath = path . join ( newSubagentsPath , entry . name ) ;
5658 try {
5759 const stats = await this . fsProvider . stat ( filePath ) ;
58- // File must have size > 0 and contain at least one line
5960 if ( stats . size > 0 ) {
60- const content = await this . fsProvider . readFile ( filePath ) ;
61- if ( content . trim ( ) . length > 0 ) {
62- return true ;
63- }
61+ return true ;
6462 }
6563 } catch ( error ) {
6664 // Skip this file if we can't read it - log for debugging
@@ -76,9 +74,6 @@ export class SubagentLocator {
7674 return false ;
7775 }
7876
79- /**
80- * Checks if a session has subagent files (session-specific only).
81- * Only checks the NEW structure: {projectId}/{sessionId}/subagents/
8277 * Verifies that at least one subagent file has non - empty content .
8378 *
8479 * @param projectId - The project ID
@@ -96,16 +91,13 @@ export class SubagentLocator {
9691 ) ;
9792
9893 // Check if at least one subagent file has content (not empty)
94+ // Uses statSync() to check file size instead of reading file contents
9995 for ( const fileName of subagentFiles ) {
10096 const filePath = path . join ( newSubagentsPath , fileName ) ;
10197 try {
10298 const stats = fs . statSync ( filePath ) ;
103- // File must have size > 0 and contain at least one line
10499 if ( stats . size > 0 ) {
105- const content = fs . readFileSync ( filePath , 'utf8' ) ;
106- if ( content . trim ( ) . length > 0 ) {
107- return true ;
108- }
100+ return true ;
109101 }
110102 } catch ( error ) {
111103 // Skip this file if we can't read it - log for debugging
@@ -210,17 +202,26 @@ export class SubagentLocator {
210202 */
211203 async subagentBelongsToSession ( filePath : string , sessionId : string ) : Promise < boolean > {
212204 try {
213- // Read just the first line to check sessionId
214- const content = await this . fsProvider . readFile ( filePath ) ;
215- const firstNewline = content . indexOf ( '\n' ) ;
216- const firstLine = firstNewline > 0 ? content . slice ( 0 , firstNewline ) : content ;
205+ // Stream only the first line instead of reading the entire file
206+ const fileStream = this . fsProvider . createReadStream ( filePath , { encoding : 'utf8' } ) ;
207+ const rl = readline . createInterface ( {
208+ input : fileStream ,
209+ crlfDelay : Infinity ,
210+ } ) ;
211+
212+ try {
213+ for await ( const line of rl ) {
214+ if ( ! line . trim ( ) ) continue ;
217215
218- if ( ! firstLine . trim ( ) ) {
219- return false ;
216+ const entry = JSON . parse ( line ) as { sessionId ?: string } ;
217+ return entry . sessionId === sessionId ;
218+ }
219+ } finally {
220+ rl . close ( ) ;
221+ fileStream . destroy ( ) ;
220222 }
221223
222- const entry = JSON . parse ( firstLine ) as { sessionId ?: string } ;
223- return entry . sessionId === sessionId ;
224+ return false ;
224225 } catch ( error ) {
225226 // If we can't read or parse the file, don't include it - log for debugging
226227 logger . debug ( `SubagentLocator: Could not parse file ${ filePath } :` , error ) ;
0 commit comments