@@ -67,6 +67,30 @@ export const webviewMessageHandler = async (
6767 operation : "delete" | "edit" ,
6868 editedContent ?: string ,
6969 ) : Promise < void > => {
70+ // Get current conversation state
71+ const currentCline = provider . getCurrentCline ( )
72+ if ( ! currentCline ) return
73+
74+ // Find the message index in the conversation
75+ const timeCutoff = messageTs - 1000 // 1 second buffer before the message
76+ const messageIndex = currentCline . clineMessages . findIndex ( ( msg ) => msg . ts && msg . ts >= timeCutoff )
77+
78+ if ( messageIndex === - 1 ) return
79+
80+ // Check if this is the last user message (no subsequent user messages)
81+ // Find the index of the last user message in the conversation
82+ const lastUserMessageIndex = [ ...currentCline . clineMessages ]
83+ . reverse ( )
84+ . findIndex ( ( msg ) => msg . type === "say" && msg . say === "user_feedback" )
85+
86+ // If lastUserMessageIndex is 0, it means the last message in the array is a user message
87+ // We need to convert this to the actual index in the original array
88+ const actualLastUserIndex =
89+ lastUserMessageIndex === - 1 ? - 1 : currentCline . clineMessages . length - 1 - lastUserMessageIndex
90+
91+ // Check if the current message is the last user message
92+ const isLastUserMessage = messageIndex === actualLastUserIndex
93+
7094 // Different visual order of options based on operation type
7195 const options =
7296 operation === "edit"
@@ -79,112 +103,119 @@ export const webviewMessageHandler = async (
79103 t ( "common:confirmation.delete_this_and_subsequent" ) ,
80104 ]
81105
82- const answer = await vscode . window . showInformationMessage (
83- operation === "edit" ? t ( "common:confirmation.edit_message" ) : t ( "common:confirmation.delete_message" ) ,
84- { modal : true } ,
85- ...options ,
86- )
87-
88- // Only proceed if user selected one of the options and we have a current cline
89- if ( answer && options . includes ( answer ) && provider . getCurrentCline ( ) ) {
90- const timeCutoff = messageTs - 1000 // 1 second buffer before the message
91- const currentCline = provider . getCurrentCline ( ) !
92-
93- const messageIndex = currentCline . clineMessages . findIndex ( ( msg ) => msg . ts && msg . ts >= timeCutoff )
106+ // Skip confirmation dialog if it's the last message
107+ let answer : string | undefined
108+
109+ if ( isLastUserMessage ) {
110+ // If it's the last message, default to "just_this_message" without showing dialog
111+ answer =
112+ operation === "edit"
113+ ? t ( "common:confirmation.edit_just_this_message" )
114+ : t ( "common:confirmation.delete_just_this_message" )
115+ } else {
116+ // Otherwise show the confirmation dialog
117+ answer = await vscode . window . showInformationMessage (
118+ operation === "edit" ? t ( "common:confirmation.edit_message" ) : t ( "common:confirmation.delete_message" ) ,
119+ { modal : true } ,
120+ ...options ,
121+ )
122+ }
94123
124+ // Only proceed if user selected one of the options or we're skipping the dialog for the last message
125+ if ( answer && ( options . includes ( answer ) || isLastUserMessage ) ) {
126+ // Find API conversation history index
95127 const apiConversationHistoryIndex = currentCline . apiConversationHistory . findIndex (
96128 ( msg ) => msg . ts && msg . ts >= timeCutoff ,
97129 )
98130
99- if ( messageIndex !== - 1 ) {
100- try {
101- const { historyItem } = await provider . getTaskWithId ( currentCline . taskId )
102-
103- // Check if user selected the "modify just this message" option
104- // For delete: options[0], for edit: options[1]
105- if (
106- ( operation === "delete" && answer === options [ 0 ] ) ||
107- ( operation === "edit" && answer === options [ 1 ] )
108- ) {
109- // Find the next user message first
110- const nextUserMessage = currentCline . clineMessages
111- . slice ( messageIndex + 1 )
112- . find ( ( msg ) => msg . type === "say" && msg . say === "user_feedback" )
113-
114- // Handle UI messages
115- if ( nextUserMessage ) {
116- // Find absolute index of next user message
117- const nextUserMessageIndex = currentCline . clineMessages . findIndex (
118- ( msg ) => msg === nextUserMessage ,
119- )
120-
121- // Keep messages before current message and after next user message
122- await currentCline . overwriteClineMessages ( [
123- ...currentCline . clineMessages . slice ( 0 , messageIndex ) ,
124- ...currentCline . clineMessages . slice ( nextUserMessageIndex ) ,
125- ] )
126- } else {
127- // If no next user message, keep only messages before current message
128- await currentCline . overwriteClineMessages ( currentCline . clineMessages . slice ( 0 , messageIndex ) )
129- }
131+ // Process the message operation
132+ try {
133+ const { historyItem } = await provider . getTaskWithId ( currentCline . taskId )
134+
135+ // Check if user selected the "modify just this message" option
136+ // For delete: options[0], for edit: options[1]
137+ if (
138+ ( operation === "delete" && answer === options [ 0 ] ) ||
139+ ( operation === "edit" && answer === options [ 1 ] )
140+ ) {
141+ // Find the next user message first
142+ const nextUserMessage = currentCline . clineMessages
143+ . slice ( messageIndex + 1 )
144+ . find ( ( msg ) => msg . type === "say" && msg . say === "user_feedback" )
145+
146+ // Handle UI messages
147+ if ( nextUserMessage ) {
148+ // Find absolute index of next user message
149+ const nextUserMessageIndex = currentCline . clineMessages . findIndex (
150+ ( msg ) => msg === nextUserMessage ,
151+ )
130152
131- // Handle API messages
132- if ( apiConversationHistoryIndex !== - 1 ) {
133- if ( nextUserMessage && nextUserMessage . ts ) {
134- // Keep messages before current API message and after next user message
135- await currentCline . overwriteApiConversationHistory ( [
136- ...currentCline . apiConversationHistory . slice ( 0 , apiConversationHistoryIndex ) ,
137- ...currentCline . apiConversationHistory . filter (
138- ( msg ) => msg . ts && msg . ts >= nextUserMessage . ts ,
139- ) ,
140- ] )
141- } else {
142- // If no next user message, keep only messages before current API message
143- await currentCline . overwriteApiConversationHistory (
144- currentCline . apiConversationHistory . slice ( 0 , apiConversationHistoryIndex ) ,
145- )
146- }
147- }
148- } else if (
149- // Check if user selected the "modify this and subsequent" option
150- // For delete: options[1], for edit: options[0]
151- ( operation === "delete" && answer === options [ 1 ] ) ||
152- ( operation === "edit" && answer === options [ 0 ] )
153- ) {
154- // Delete this message and all that follow
153+ // Keep messages before current message and after next user message
154+ await currentCline . overwriteClineMessages ( [
155+ ...currentCline . clineMessages . slice ( 0 , messageIndex ) ,
156+ ...currentCline . clineMessages . slice ( nextUserMessageIndex ) ,
157+ ] )
158+ } else {
159+ // If no next user message, keep only messages before current message
155160 await currentCline . overwriteClineMessages ( currentCline . clineMessages . slice ( 0 , messageIndex ) )
161+ }
156162
157- if ( apiConversationHistoryIndex !== - 1 ) {
163+ // Handle API messages
164+ if ( apiConversationHistoryIndex !== - 1 ) {
165+ if ( nextUserMessage && nextUserMessage . ts ) {
166+ // Keep messages before current API message and after next user message
167+ await currentCline . overwriteApiConversationHistory ( [
168+ ...currentCline . apiConversationHistory . slice ( 0 , apiConversationHistoryIndex ) ,
169+ ...currentCline . apiConversationHistory . filter (
170+ ( msg ) => msg . ts && msg . ts >= nextUserMessage . ts ,
171+ ) ,
172+ ] )
173+ } else {
174+ // If no next user message, keep only messages before current API message
158175 await currentCline . overwriteApiConversationHistory (
159176 currentCline . apiConversationHistory . slice ( 0 , apiConversationHistoryIndex ) ,
160177 )
161178 }
162179 }
163-
164- // Initialize with history item first for delete operations
165- if ( operation === "delete" ) {
166- await provider . initClineWithHistoryItem ( historyItem )
180+ } else if (
181+ // Check if user selected the "modify this and subsequent" option
182+ // For delete: options[1], for edit: options[0]
183+ ( operation === "delete" && answer === options [ 1 ] ) ||
184+ ( operation === "edit" && answer === options [ 0 ] )
185+ ) {
186+ // Delete this message and all that follow
187+ await currentCline . overwriteClineMessages ( currentCline . clineMessages . slice ( 0 , messageIndex ) )
188+
189+ if ( apiConversationHistoryIndex !== - 1 ) {
190+ await currentCline . overwriteApiConversationHistory (
191+ currentCline . apiConversationHistory . slice ( 0 , apiConversationHistoryIndex ) ,
192+ )
167193 }
194+ }
168195
169- // For edit operations, process the edited message
170- if ( operation === "edit" && editedContent ) {
171- // Process the edited message as a regular user message
172- // This will add it to the conversation and trigger an AI response
173- webviewMessageHandler ( provider , {
174- type : "askResponse" ,
175- askResponse : "messageResponse" ,
176- text : editedContent ,
177- } )
196+ // Initialize with history item first for delete operations
197+ if ( operation === "delete" ) {
198+ await provider . initClineWithHistoryItem ( historyItem )
199+ }
178200
179- // Don't initialize with history item for edit operations
180- // The webviewMessageHandler will handle the conversation state
181- }
182- } catch ( error ) {
183- console . error ( `Error in ${ operation } message:` , error )
184- vscode . window . showErrorMessage (
185- `Error ${ operation === "edit" ? "editing" : "deleting" } message: ${ error instanceof Error ? error . message : String ( error ) } ` ,
186- )
201+ // For edit operations, process the edited message
202+ if ( operation === "edit" && editedContent ) {
203+ // Process the edited message as a regular user message
204+ // This will add it to the conversation and trigger an AI response
205+ webviewMessageHandler ( provider , {
206+ type : "askResponse" ,
207+ askResponse : "messageResponse" ,
208+ text : editedContent ,
209+ } )
210+
211+ // Don't initialize with history item for edit operations
212+ // The webviewMessageHandler will handle the conversation state
187213 }
214+ } catch ( error ) {
215+ console . error ( `Error in ${ operation } message:` , error )
216+ vscode . window . showErrorMessage (
217+ `Error ${ operation === "edit" ? "editing" : "deleting" } message: ${ error instanceof Error ? error . message : String ( error ) } ` ,
218+ )
188219 }
189220 }
190221 }
0 commit comments