@@ -90,9 +90,12 @@ export const Chat = (): JSX.Element => {
9090 const [ messages , setMessages ] = useState < Message [ ] > ( [ ] ) ;
9191 const [ input , setInput ] = useState ( "" ) ;
9292 const [ loading , setLoading ] = useState ( false ) ;
93+ const [ queryHistory , setQueryHistory ] = useState < string [ ] > ( [ ] ) ;
9394 const inputRef = useRef < HTMLInputElement | HTMLTextAreaElement > ( null ) ;
9495 const listRef = useRef < HTMLDivElement > ( null ) ;
9596 const abortRef = useRef < AbortController | null > ( null ) ;
97+ const historyIndexRef = useRef ( - 1 ) ;
98+ const draftRef = useRef ( "" ) ;
9699 const { dimensions } = useLayoutDimensions ( ) ;
97100 const headerHeight = dimensions . header . height ;
98101
@@ -115,6 +118,9 @@ export const Chat = (): JSX.Element => {
115118 if ( ! query || loading ) return ;
116119
117120 setInput ( "" ) ;
121+ setQueryHistory ( ( prev ) => [ ...prev , query ] . slice ( - 50 ) ) ;
122+ historyIndexRef . current = - 1 ;
123+ draftRef . current = "" ;
118124 setMessages ( ( prev ) => [ ...prev , { text : query , type : "user" } ] ) ;
119125 setLoading ( true ) ;
120126
@@ -168,9 +174,40 @@ export const Chat = (): JSX.Element => {
168174 if ( e . key === "Enter" && ! e . shiftKey ) {
169175 e . preventDefault ( ) ;
170176 handleSend ( ) ;
177+ return ;
178+ }
179+
180+ // Up/Down arrow: navigate query history when input is empty or
181+ // cursor is at the very start (avoids interfering with multiline editing).
182+ const el = e . currentTarget ;
183+ const cursorAtStart = el . selectionStart === 0 && el . selectionEnd === 0 ;
184+
185+ if ( e . key === "ArrowUp" && ( input === "" || cursorAtStart ) ) {
186+ if ( queryHistory . length === 0 ) return ;
187+ e . preventDefault ( ) ;
188+ if ( historyIndexRef . current === - 1 ) {
189+ draftRef . current = input ;
190+ historyIndexRef . current = queryHistory . length - 1 ;
191+ } else if ( historyIndexRef . current > 0 ) {
192+ historyIndexRef . current -= 1 ;
193+ }
194+ setInput ( queryHistory [ historyIndexRef . current ] ) ;
195+ } else if (
196+ e . key === "ArrowDown" &&
197+ historyIndexRef . current >= 0 &&
198+ cursorAtStart
199+ ) {
200+ e . preventDefault ( ) ;
201+ if ( historyIndexRef . current < queryHistory . length - 1 ) {
202+ historyIndexRef . current += 1 ;
203+ setInput ( queryHistory [ historyIndexRef . current ] ) ;
204+ } else {
205+ historyIndexRef . current = - 1 ;
206+ setInput ( draftRef . current ) ;
207+ }
171208 }
172209 } ,
173- [ handleSend ]
210+ [ handleSend , input , queryHistory ]
174211 ) ;
175212
176213 return (
0 commit comments