@@ -148,6 +148,25 @@ export const ChatInput: React.FC<ChatInputProps> = (props) => {
148148 } , [ ] ) ;
149149 const inputRef = useRef < HTMLTextAreaElement > ( null ) ;
150150 const modelSelectorRef = useRef < ModelSelectorRef > ( null ) ;
151+
152+ // Draft state combines text input and image attachments
153+ // Use these helpers to avoid accidentally losing images when modifying text
154+ interface DraftState {
155+ text : string ;
156+ images : ImageAttachment [ ] ;
157+ }
158+ const getDraft = useCallback (
159+ ( ) : DraftState => ( { text : input , images : imageAttachments } ) ,
160+ [ input , imageAttachments ]
161+ ) ;
162+ const setDraft = useCallback (
163+ ( draft : DraftState ) => {
164+ setInput ( draft . text ) ;
165+ setImageAttachments ( draft . images ) ;
166+ } ,
167+ [ setInput ]
168+ ) ;
169+ const preEditDraftRef = useRef < DraftState > ( { text : "" , images : [ ] } ) ;
151170 const [ mode , setMode ] = useMode ( ) ;
152171 const { recentModels, addModel, defaultModel, setDefaultModel } = useModelLRU ( ) ;
153172 const commandListId = useId ( ) ;
@@ -346,10 +365,11 @@ export const ChatInput: React.FC<ChatInputProps> = (props) => {
346365 } ;
347366 } , [ focusMessageInput ] ) ;
348367
349- // When entering editing mode, populate input with message content
368+ // When entering editing mode, save current draft and populate with message content
350369 useEffect ( ( ) => {
351370 if ( editingMessage ) {
352- setInput ( editingMessage . content ) ;
371+ preEditDraftRef . current = getDraft ( ) ;
372+ setDraft ( { text : editingMessage . content , images : [ ] } ) ;
353373 // Auto-resize textarea and focus
354374 setTimeout ( ( ) => {
355375 if ( inputRef . current ) {
@@ -360,7 +380,8 @@ export const ChatInput: React.FC<ChatInputProps> = (props) => {
360380 }
361381 } , 0 ) ;
362382 }
363- } , [ editingMessage , setInput ] ) ;
383+ // eslint-disable-next-line react-hooks/exhaustive-deps -- only run when editingMessage changes
384+ } , [ editingMessage ] ) ;
364385
365386 // Watch input for slash commands
366387 useEffect ( ( ) => {
@@ -829,6 +850,7 @@ export const ChatInput: React.FC<ChatInputProps> = (props) => {
829850 // Handler for Escape in vim normal mode - cancels edit if editing
830851 const handleEscapeInNormalMode = ( ) => {
831852 if ( variant === "workspace" && editingMessage && props . onCancelEdit ) {
853+ setDraft ( preEditDraftRef . current ) ;
832854 props . onCancelEdit ( ) ;
833855 inputRef . current ?. blur ( ) ;
834856 }
@@ -884,6 +906,7 @@ export const ChatInput: React.FC<ChatInputProps> = (props) => {
884906 if ( matchesKeybind ( e , KEYBINDS . CANCEL_EDIT ) ) {
885907 if ( variant === "workspace" && editingMessage && props . onCancelEdit && ! vimEnabled ) {
886908 e . preventDefault ( ) ;
909+ setDraft ( preEditDraftRef . current ) ;
887910 props . onCancelEdit ( ) ;
888911 const isFocused = document . activeElement === inputRef . current ;
889912 if ( isFocused ) {
0 commit comments