@@ -115,6 +115,27 @@ async function findLatestRollout(dir: string, workDir: string, excludeClaimed =
115115 return null ;
116116}
117117
118+ async function findLatestMatchingRollout ( sessionName : string , projectDir : string , currentUuid : string | null , currentPath : string | null ) : Promise < string | null > {
119+ let latestPath : string | null = null ;
120+ let latestMtime = - 1 ;
121+ for ( const dir of recentSessionDirs ( ) ) {
122+ const found = await findLatestRollout ( dir , projectDir , false ) ;
123+ if ( ! found || found === currentPath || isFileClaimedByOther ( sessionName , found ) ) continue ;
124+ if ( currentUuid ) {
125+ const candidateUuid = extractUuidFromPath ( found ) ;
126+ if ( candidateUuid && candidateUuid !== currentUuid ) continue ;
127+ }
128+ try {
129+ const s = await stat ( found ) ;
130+ if ( s . mtimeMs > latestMtime ) {
131+ latestMtime = s . mtimeMs ;
132+ latestPath = found ;
133+ }
134+ } catch { }
135+ }
136+ return latestPath ;
137+ }
138+
118139function normalizePath ( p : string ) : string {
119140 const normalized = p
120141 . replace ( / \\ / g, '/' )
@@ -548,7 +569,17 @@ export async function refreshTrackedSession(sessionName: string): Promise<boolea
548569 await drainNewLines ( sessionName , state ) ;
549570 state . _lastRotationCheck = Date . now ( ) ;
550571 const uuid = state . activeFile ? extractUuidFromPath ( state . activeFile ) : null ;
551- if ( uuid ) {
572+ const latestPath = state . projectDir
573+ ? await findLatestMatchingRollout ( sessionName , state . projectDir , uuid , state . activeFile )
574+ : null ;
575+ if ( latestPath && await checkNewer ( latestPath , state . activeFile ) ) {
576+ if ( state . activeFile ) claimedFiles . delete ( state . activeFile ) ;
577+ state . activeFile = latestPath ;
578+ state . workDir = latestPath . substring ( 0 , latestPath . lastIndexOf ( '/' ) ) ;
579+ state . fileOffset = 0 ;
580+ claimedFiles . set ( latestPath , sessionName ) ;
581+ void watchDir ( sessionName , state , state . workDir ) ;
582+ } else if ( uuid ) {
552583 for ( const dir of recentSessionDirs ( ) ) {
553584 if ( dir === state . workDir ) continue ;
554585 try {
@@ -579,23 +610,7 @@ export async function retrackLatestRollout(sessionName: string): Promise<boolean
579610 if ( ! projectDir ) return false ;
580611 const currentUuid = state . activeFile ? extractUuidFromPath ( state . activeFile ) : null ;
581612
582- let latestPath : string | null = null ;
583- let latestMtime = - 1 ;
584- for ( const dir of recentSessionDirs ( ) ) {
585- const found = await findLatestRollout ( dir , projectDir , false ) ;
586- if ( ! found || found === state . activeFile || isFileClaimedByOther ( sessionName , found ) ) continue ;
587- if ( currentUuid ) {
588- const candidateUuid = extractUuidFromPath ( found ) ;
589- if ( candidateUuid && candidateUuid !== currentUuid ) continue ;
590- }
591- try {
592- const s = await stat ( found ) ;
593- if ( s . mtimeMs > latestMtime ) {
594- latestMtime = s . mtimeMs ;
595- latestPath = found ;
596- }
597- } catch { }
598- }
613+ const latestPath = await findLatestMatchingRollout ( sessionName , projectDir , currentUuid , state . activeFile ) ;
599614
600615 if ( ! latestPath ) return false ;
601616 logger . info ( { sessionName, old : state . activeFile , new : latestPath } , 'codex-watcher: retracking latest rollout after no-text turn' ) ;
0 commit comments