@@ -25,7 +25,7 @@ interface TerminalEntry {
2525}
2626
2727const terminalsMap = new Map < string , TerminalEntry > ( )
28- const lineAccumulators = new Map < string , string > ( )
28+ const bufferReadTimers = new Map < string , ReturnType < typeof setTimeout > > ( )
2929
3030export function applyThemeToAll ( themeId : string ) : void {
3131 const xtermTheme = getTerminalTheme ( themeId )
@@ -63,6 +63,9 @@ export function TerminalInstance({ tabId, projectId, cwd, initialCommand }: Term
6363
6464 if ( entry && ! document . body . contains ( entry . terminal . element ) ) {
6565 entry . unsubData ?.( )
66+ const staleTimer = bufferReadTimers . get ( tabId )
67+ if ( staleTimer ) clearTimeout ( staleTimer )
68+ bufferReadTimers . delete ( tabId )
6669 try { entry . terminal . dispose ( ) } catch { /* WebGL addon may throw */ }
6770 terminalsMap . delete ( tabId )
6871 entry = undefined
@@ -152,14 +155,25 @@ export function TerminalInstance({ tabId, projectId, cwd, initialCommand }: Term
152155 useTerminalStore . getState ( ) . setTabStatus ( tabId , 'idle' )
153156 } , 3000 )
154157
155- const cleaned = stripAnsi ( data )
156- const pending = ( lineAccumulators . get ( projectId ) ?? '' ) + cleaned
157- const parts = pending . split ( '\n' )
158- lineAccumulators . set ( projectId , parts . pop ( ) ! )
159- const lines = parts . filter ( ( l ) => l . trim ( ) . length > 0 )
160- if ( lines . length > 0 ) {
161- store . appendOutput ( projectId , lines )
162- }
158+ const prevTimer = bufferReadTimers . get ( tabId )
159+ if ( prevTimer ) clearTimeout ( prevTimer )
160+ bufferReadTimers . set ( tabId , setTimeout ( ( ) => {
161+ bufferReadTimers . delete ( tabId )
162+ const te = terminalsMap . get ( tabId )
163+ if ( ! te ) return
164+ const buf = te . terminal . buffer . active
165+ const extracted : string [ ] = [ ]
166+ for ( let y = 0 ; y < te . terminal . rows ; y ++ ) {
167+ const row = buf . getLine ( buf . baseY + y )
168+ if ( row ) {
169+ const text = row . translateToString ( true )
170+ if ( text . trim ( ) ) extracted . push ( text )
171+ }
172+ }
173+ if ( extracted . length > 0 ) {
174+ useTerminalStore . getState ( ) . setOutput ( projectId , extracted )
175+ }
176+ } , 200 ) )
163177 }
164178 }
165179 } )
@@ -333,6 +347,9 @@ export function disposeTerminal(tabId: string): void {
333347 const entry = terminalsMap . get ( tabId )
334348 if ( entry ) {
335349 entry . unsubData ?.( )
350+ const timer = bufferReadTimers . get ( tabId )
351+ if ( timer ) clearTimeout ( timer )
352+ bufferReadTimers . delete ( tabId )
336353 try { entry . terminal . dispose ( ) } catch { /* WebGL addon may throw during dispose */ }
337354 terminalsMap . delete ( tabId )
338355 }
0 commit comments