1- import { Container , Spacer , Text } from '@mariozechner/pi-tui' ;
1+ import { Container , Spacer , Text , type TUI } from '@mariozechner/pi-tui' ;
22import type { ApprovalDecision } from '../agent/types.js' ;
33import { theme } from '../theme.js' ;
44
@@ -56,13 +56,19 @@ function approvalLabel(decision: ApprovalDecision): string {
5656 }
5757}
5858
59+ const SPINNER_FRAMES = [ '⠋' , '⠙' , '⠹' , '⠸' , '⠼' , '⠴' , '⠦' , '⠧' , '⠇' , '⠏' ] ;
60+
5961export class ToolEventComponent extends Container {
62+ private readonly tui : TUI ;
6063 private readonly header : Text ;
6164 private completedDetails : Text [ ] = [ ] ;
6265 private activeDetail : Text | null = null ;
66+ private spinnerInterval : ReturnType < typeof setInterval > | null = null ;
67+ private spinnerFrame : number = 0 ;
6368
64- constructor ( _tui : unknown , tool : string , args : Record < string , unknown > ) {
69+ constructor ( tui : TUI , tool : string , args : Record < string , unknown > ) {
6570 super ( ) ;
71+ this . tui = tui ;
6672 this . addChild ( new Spacer ( 1 ) ) ;
6773 const title = `${ formatToolName ( tool ) } ${ args ? `${ theme . muted ( '(' ) } ${ formatArgs ( tool , args ) } ${ theme . muted ( ')' ) } ` : '' } ` ;
6874 this . header = new Text ( `⏺ ${ title } ` , 0 , 0 ) ;
@@ -72,8 +78,14 @@ export class ToolEventComponent extends Container {
7278 setActive ( progressMessage ?: string ) {
7379 this . clearDetail ( ) ;
7480 const message = progressMessage || 'Searching...' ;
75- this . activeDetail = new Text ( `${ theme . muted ( ' ⎿ ' ) } ${ message } ` , 0 , 0 ) ;
81+ this . activeDetail = new Text ( `${ theme . muted ( ` ⎿ ${ SPINNER_FRAMES [ 0 ] } ` ) } ${ message } ` , 0 , 0 ) ;
7682 this . addChild ( this . activeDetail ) ;
83+ this . spinnerFrame = 0 ;
84+ this . spinnerInterval = setInterval ( ( ) => {
85+ this . spinnerFrame = ( this . spinnerFrame + 1 ) % SPINNER_FRAMES . length ;
86+ this . activeDetail ?. setText ( `${ theme . muted ( `⎿ ${ SPINNER_FRAMES [ this . spinnerFrame ] } ` ) } ${ message } ` ) ;
87+ this . tui . requestRender ( ) ;
88+ } , 80 ) ;
7789 }
7890
7991 setComplete ( summary : string , duration : number ) {
@@ -120,7 +132,15 @@ export class ToolEventComponent extends Container {
120132 this . addChild ( detail ) ;
121133 }
122134
135+ dispose ( ) {
136+ this . clearDetail ( ) ;
137+ }
138+
123139 private clearDetail ( ) {
140+ if ( this . spinnerInterval ) {
141+ clearInterval ( this . spinnerInterval ) ;
142+ this . spinnerInterval = null ;
143+ }
124144 if ( this . activeDetail ) {
125145 this . removeChild ( this . activeDetail ) ;
126146 this . activeDetail = null ;
0 commit comments