@@ -267,10 +267,19 @@ export function IndexingProgress({
267267} : IndexingProgressProps ) {
268268 const { percent, filesProcessed, filesTotal, currentFile, functionsFound } = progress ;
269269
270- // Estimate remaining time
270+ // Safe values to prevent NaN/division by zero
271+ const safePercent = Number . isFinite ( percent ) ? Math . max ( 0 , Math . min ( 100 , percent ) ) : 0 ;
272+ const safeFilesProcessed = Number . isFinite ( filesProcessed ) ? Math . max ( 0 , filesProcessed ) : 0 ;
273+ const safeFilesTotal = Number . isFinite ( filesTotal ) ? Math . max ( 0 , filesTotal ) : 0 ;
274+ const safeFunctionsFound = Number . isFinite ( functionsFound ) ? Math . max ( 0 , functionsFound ) : 0 ;
275+
276+ // Is this the initial "starting" state?
277+ const isStarting = safeFilesTotal === 0 || ( safePercent === 0 && safeFilesProcessed === 0 ) ;
278+
279+ // Estimate remaining time (only when we have real data)
271280 const estimatedRemaining = ( ( ) => {
272- if ( percent <= 0 || filesProcessed <= 0 ) return null ;
273- const remainingFiles = Math . ceil ( ( filesProcessed / percent ) * ( 100 - percent ) ) ;
281+ if ( isStarting || safePercent <= 0 || safeFilesProcessed <= 0 ) return null ;
282+ const remainingFiles = Math . ceil ( ( safeFilesProcessed / safePercent ) * ( 100 - safePercent ) ) ;
274283 return Math . max ( 1 , Math . ceil ( remainingFiles * 0.15 ) ) ;
275284 } ) ( ) ;
276285
@@ -287,7 +296,7 @@ export function IndexingProgress({
287296 initial = { { opacity : 0 , y : 20 } }
288297 animate = { { opacity : 1 , y : 0 } }
289298 role = "status"
290- aria-label = { `Indexing ${ repoName || 'repository' } : ${ percent } % complete` }
299+ aria-label = { `Indexing ${ repoName || 'repository' } : ${ safePercent } % complete` }
291300 >
292301 { /* Header */ }
293302 < div className = "px-5 py-4 border-b border-zinc-800/50 bg-gradient-to-r from-zinc-900 to-zinc-900/50" >
@@ -308,12 +317,12 @@ export function IndexingProgress({
308317 </ div >
309318 < motion . span
310319 className = "text-3xl font-bold text-indigo-400"
311- key = { percent }
320+ key = { safePercent }
312321 initial = { { scale : 1.3 } }
313322 animate = { { scale : 1 } }
314323 transition = { { type : 'spring' , stiffness : 300 } }
315324 >
316- { percent } %
325+ { safePercent } %
317326 </ motion . span >
318327 </ div >
319328
@@ -323,16 +332,29 @@ export function IndexingProgress({
323332
324333 { /* Progress bar */ }
325334 < div className = "px-5 py-4" >
326- < GlowingProgress value = { percent } />
335+ < GlowingProgress value = { safePercent } />
327336 </ div >
328337
329338 { /* Stats grid */ }
330339 < div className = "px-5 py-4 bg-zinc-900/50 border-t border-b border-zinc-800/50" >
331340 < div className = "grid grid-cols-4 gap-4" >
332- < StatCard label = "Files" value = { `${ filesProcessed } /${ filesTotal } ` } />
333- < StatCard label = "Functions" value = { functionsFound } highlight />
334- < StatCard label = "Remaining" value = { estimatedRemaining ? `~${ estimatedRemaining } s` : '—' } />
335- < StatCard label = "Speed" value = { filesProcessed > 0 ? `${ Math . round ( functionsFound / filesProcessed ) } /file` : '—' } />
341+ < StatCard
342+ label = "Files"
343+ value = { isStarting ? 'Starting...' : `${ safeFilesProcessed } /${ safeFilesTotal } ` }
344+ />
345+ < StatCard
346+ label = "Functions"
347+ value = { isStarting ? '—' : safeFunctionsFound }
348+ highlight = { ! isStarting && safeFunctionsFound > 0 }
349+ />
350+ < StatCard
351+ label = "Remaining"
352+ value = { estimatedRemaining ? `~${ estimatedRemaining } s` : '—' }
353+ />
354+ < StatCard
355+ label = "Speed"
356+ value = { safeFilesProcessed > 0 ? `${ Math . round ( safeFunctionsFound / safeFilesProcessed ) } /file` : '—' }
357+ />
336358 </ div >
337359 </ div >
338360
0 commit comments