@@ -87,6 +87,7 @@ type Props = {
8787 screenWidth : number ;
8888 promptHistory : string [ ] ;
8989 busy : boolean ;
90+ cursorLayoutKey ?: string ;
9091 loadingText ?: string | null ;
9192 disabled ?: boolean ;
9293 placeholder ?: string ;
@@ -99,27 +100,12 @@ type Props = {
99100 onToggleProcessStdout ?: ( ) => void ;
100101} ;
101102
102- const SPINNER_FRAMES = [ "⠋" , "⠙" , "⠹" , "⠸" , "⠼" , "⠴" , "⠦" , "⠧" , "⠇" , "⠏" ] ;
103103const PROMPT_PREFIX_WIDTH = 2 ;
104104
105- const PromptPrefixLine = React . memo ( function PromptPrefixLine ( { busy } : { busy : boolean } ) : React . ReactElement {
106- const [ spinnerIndex , setSpinnerIndex ] = useState ( 0 ) ;
107-
108- useEffect ( ( ) => {
109- if ( ! busy ) {
110- setSpinnerIndex ( 0 ) ;
111- return ;
112- }
113- const timer = setInterval ( ( ) => {
114- setSpinnerIndex ( ( index ) => ( index + 1 ) % SPINNER_FRAMES . length ) ;
115- } , 80 ) ;
116- return ( ) => clearInterval ( timer ) ;
117- } , [ busy ] ) ;
118-
119- const prefix = busy ? `${ SPINNER_FRAMES [ spinnerIndex ] } ` : "> " ;
105+ const PromptPrefixLine = React . memo ( function PromptPrefixLine ( ) : React . ReactElement {
120106 return (
121- < Box width = { 2 } >
122- < Text color = { busy ? "yellow" : " #229ac3"} > { prefix } </ Text >
107+ < Box width = { PROMPT_PREFIX_WIDTH } >
108+ < Text color = " #229ac3"> { "> " } </ Text >
123109 </ Box >
124110 ) ;
125111} ) ;
@@ -131,6 +117,7 @@ export const PromptInput = React.memo(function PromptInput({
131117 screenWidth,
132118 promptHistory,
133119 busy,
120+ cursorLayoutKey,
134121 loadingText,
135122 disabled,
136123 placeholder,
@@ -205,12 +192,14 @@ export const PromptInput = React.memo(function PromptInput({
205192 : hasExpandedRegions
206193 ? " · ctrl+o collapse"
207194 : "" ;
195+ const busyStatusText =
196+ loadingText && loadingText . trim ( )
197+ ? `${ loadingText } ${ processOrPasteHint } `
198+ : `esc to interrupt · ctrl+c to cancel input${ processOrPasteHint } ` ;
208199 const footerText = statusMessage
209200 ? statusMessage
210201 : busy
211- ? loadingText && loadingText . trim ( )
212- ? `${ loadingText } ${ processOrPasteHint } `
213- : `esc to interrupt · ctrl+c to cancel input${ processOrPasteHint } `
202+ ? busyStatusText
214203 : `enter send · shift+enter newline · @ files · ctrl+v image · / commands · ctrl+d exit${ processOrPasteHint } ` ;
215204 const showFooterText = useMemo (
216205 ( ) => showMenu || showSkillsDropdown || openRawModelDropdown || showModelDropdown || showFileMentionMenu ,
@@ -225,19 +214,25 @@ export const PromptInput = React.memo(function PromptInput({
225214 const useInlineCursor = isPromptCursorAtWrapBoundary ( buffer , inputContentWidth ) ;
226215 const usePositionedCursor = ! disabled && hasTerminalFocus && ! showFooterText && stdout . isTTY && ! useInlineCursor ;
227216 const promptCursorLayoutKey = useMemo (
228- ( ) => [ screenWidth , imageUrls . length , selectedSkills . map ( ( skill ) => skill . name ) . join ( "\u001F" ) ] . join ( "\u001E" ) ,
229- [ imageUrls . length , screenWidth , selectedSkills ]
217+ ( ) =>
218+ [
219+ screenWidth ,
220+ cursorLayoutKey ?? "default" ,
221+ imageUrls . length ,
222+ selectedSkills . map ( ( skill ) => skill . name ) . join ( "\u001F" ) ,
223+ ] . join ( "\u001E" ) ,
224+ [ cursorLayoutKey , imageUrls . length , screenWidth , selectedSkills ]
230225 ) ;
231226 useTerminalFocusReporting ( stdout , ! disabled ) ;
232227 useTerminalExtendedKeys ( stdout , ! disabled ) ;
233228 useBracketedPaste ( stdout , ! disabled ) ;
234229 const terminalCursorActive = usePromptTerminalCursor (
235230 inputTextRef ,
236231 cursorPlacement ,
237- usePositionedCursor ,
232+ ! busy && usePositionedCursor ,
238233 promptCursorLayoutKey
239234 ) ;
240- useHiddenTerminalCursor ( stdout , ! disabled && ! terminalCursorActive ) ;
235+ useHiddenTerminalCursor ( stdout , ! disabled && ( busy || ! terminalCursorActive ) ) ;
241236
242237 const refreshFileMentionItems = React . useCallback ( ( ) => {
243238 setFileMentionItems ( scanFileMentionItems ( projectRoot ) ) ;
@@ -779,15 +774,15 @@ export const PromptInput = React.memo(function PromptInput({
779774 borderRight = { false }
780775 borderDimColor
781776 >
782- < PromptPrefixLine busy = { busy } />
777+ < PromptPrefixLine />
783778 < Box ref = { inputTextRef } flexGrow = { 1 } flexShrink = { 1 } width = { inputContentWidth } >
784779 < Text wrap = "hard" >
785780 { renderBufferWithCursor (
786781 buffer ,
787782 ! disabled && hasTerminalFocus ,
788783 placeholder ,
789784 pastesRef . current ,
790- ! terminalCursorActive
785+ ! busy && ! terminalCursorActive
791786 ) }
792787 </ Text >
793788 { inlineHint ? < Text dimColor > { inlineHint } </ Text > : null }
0 commit comments