@@ -22,6 +22,8 @@ const A = {
2222 altOn : '\x1b[?1049h' ,
2323 altOff : '\x1b[?1049l' ,
2424 clear : '\x1b[2J\x1b[H' ,
25+ home : '\x1b[H' , // cursor to top-left without clearing — overwrite in place (no flicker)
26+ eos : '\x1b[0J' , // erase from cursor to end of screen — clears leftover rows from a taller frame
2527 // fg
2628 black : '\x1b[30m' ,
2729 red : '\x1b[31m' ,
@@ -44,10 +46,18 @@ const move = (row: number, col: number) => `${ESC}${row};${col}H`
4446const clearLine = ( ) => `${ ESC } 2K`
4547const w = process . stdout
4648
49+ // When frameBuf is non-null a render() is in progress: accumulate the whole frame into one string
50+ // and flush it with a single w.write() so the terminal paints it as one frame (no partial-frame
51+ // flicker). Outside render(), write() flushes immediately as before.
52+ let frameBuf : string | null = null
53+ let maxRow = 0
54+
4755function write ( s : string ) {
48- w . write ( s )
56+ if ( frameBuf !== null ) frameBuf += s
57+ else w . write ( s )
4958}
5059function writeln ( row : number , col : number , s : string ) {
60+ if ( row > maxRow ) maxRow = row
5161 write ( move ( row , col ) + clearLine ( ) + s )
5262}
5363
@@ -786,7 +796,17 @@ function computeTotalEta(job: any) {
786796
787797function render ( ) {
788798 const { rows, columns } = process . stdout
789- write ( A . reset + A . hide + A . clear )
799+ // Buffer the whole frame, then flush once. Home (not clear) + overwrite-in-place kills the flicker;
800+ // eos at the end erases any rows a shorter frame left behind (e.g. detail panel closed, resize).
801+ frameBuf = ''
802+ maxRow = 0
803+ write ( A . reset + A . hide + A . home )
804+ const flush = ( ) => {
805+ write ( move ( maxRow + 1 , 1 ) + A . eos + A . show )
806+ const out = frameBuf ?? ''
807+ frameBuf = null
808+ w . write ( out )
809+ }
790810
791811 const refreshStr = lastRefresh ? `last refresh: ${ lastRefresh } ` : 'loading…'
792812 const title = ` ${ A . bold } ${ A . cyan } OSSPCKGS Monitor${ A . reset } ${ A . dim } ${ refreshStr } ${ A . reset } `
@@ -796,7 +816,7 @@ function render() {
796816
797817 if ( error ) {
798818 writeln ( 3 , 1 , `${ A . red } DB Error: ${ error } ${ A . reset } ` )
799- write ( A . show )
819+ flush ( )
800820 return
801821 }
802822
@@ -865,7 +885,7 @@ function render() {
865885 }
866886 }
867887
868- write ( A . show )
888+ flush ( )
869889}
870890
871891// ── Data ───────────────────────────────────────────────────────────────────────
0 commit comments