@@ -4,6 +4,8 @@ import { Logger } from "../../services/logging/Logger"
44import { WebviewProvider } from "../../core/webview"
55import { AutoApprovalSettings } from "../../shared/AutoApprovalSettings"
66import { updateGlobalState , getAllExtensionState } from "../../core/storage/state"
7+ import { ClineAsk , ExtensionMessage } from "../../shared/ExtensionMessage"
8+ import { WebviewMessage } from "../../shared/WebviewMessage"
79
810// Task completion tracking
911let taskCompletionResolver : ( ( ) => void ) | null = null
@@ -211,6 +213,7 @@ export function createTestServer(webviewProvider?: WebviewProvider): http.Server
211213
212214/**
213215 * Creates a message catcher that logs all messages sent to the webview
216+ * and automatically responds to messages that require user intervention
214217 * @param webviewProvider The webview provider instance
215218 * @returns A disposable that can be used to clean up the message catcher
216219 */
@@ -219,7 +222,9 @@ export function createMessageCatcher(webviewProvider: WebviewProvider): vscode.D
219222
220223 if ( webviewProvider && webviewProvider . controller ) {
221224 const originalPostMessageToWebview = webviewProvider . controller . postMessageToWebview
222- webviewProvider . controller . postMessageToWebview = async ( message ) => {
225+
226+ // Intercept outgoing messages from extension to webview
227+ webviewProvider . controller . postMessageToWebview = async ( message : ExtensionMessage ) => {
223228 Logger . log ( "Cline message received: " + JSON . stringify ( message ) )
224229
225230 // Check for completion_result message
@@ -228,6 +233,17 @@ export function createMessageCatcher(webviewProvider: WebviewProvider): vscode.D
228233 completeTask ( )
229234 }
230235
236+ // Check for ask messages that require user intervention
237+ if ( message . type === "partialMessage" && message . partialMessage ?. type === "ask" && ! message . partialMessage . partial ) {
238+ const askType = message . partialMessage . ask as ClineAsk
239+ const askText = message . partialMessage . text
240+
241+ // Automatically respond to different types of asks
242+ setTimeout ( ( ) => {
243+ autoRespondToAsk ( webviewProvider , askType , askText )
244+ } , 100 ) // Small delay to ensure the message is processed first
245+ }
246+
231247 return originalPostMessageToWebview . call ( webviewProvider . controller , message )
232248 }
233249 } else {
@@ -240,6 +256,94 @@ export function createMessageCatcher(webviewProvider: WebviewProvider): vscode.D
240256 } )
241257}
242258
259+ /**
260+ * Automatically responds to ask messages to continue task execution without user intervention
261+ * @param webviewProvider The webview provider instance
262+ * @param askType The type of ask message
263+ * @param askText The text content of the ask message
264+ */
265+ function autoRespondToAsk ( webviewProvider : WebviewProvider , askType : ClineAsk , askText ?: string ) : void {
266+ if ( ! webviewProvider . controller ) {
267+ return
268+ }
269+
270+ Logger . log ( `Auto-responding to ask type: ${ askType } ` )
271+
272+ // Create a response message based on the ask type
273+ const response : WebviewMessage = {
274+ type : "askResponse" ,
275+ askResponse : "yesButtonClicked" , // Default to approving most actions
276+ }
277+
278+ // Handle specific ask types differently if needed
279+ switch ( askType ) {
280+ case "followup" :
281+ // For follow-up questions, provide a generic response
282+ response . askResponse = "messageResponse"
283+ response . text = "I can't answer any questions right now, use your best judgment."
284+ break
285+
286+ case "api_req_failed" :
287+ // Always retry API requests
288+ response . askResponse = "yesButtonClicked" // "Retry" button
289+ break
290+
291+ case "completion_result" :
292+ // Accept the completion
293+ response . askResponse = "messageResponse"
294+ response . text = "Task completed successfully."
295+ break
296+
297+ case "mistake_limit_reached" :
298+ // Provide guidance to continue
299+ response . askResponse = "messageResponse"
300+ response . text = "Try breaking down the task into smaller steps."
301+ break
302+
303+ case "auto_approval_max_req_reached" :
304+ // Reset the count to continue
305+ response . askResponse = "yesButtonClicked" // "Reset and continue" button
306+ break
307+
308+ case "resume_task" :
309+ case "resume_completed_task" :
310+ // Resume the task
311+ response . askResponse = "messageResponse"
312+ break
313+
314+ case "new_task" :
315+ // Decline creating a new task to keep the current task running
316+ response . askResponse = "messageResponse"
317+ response . text = "Continue with the current task."
318+ break
319+
320+ case "plan_mode_respond" :
321+ // Respond to plan mode with a message to toggle to Act mode
322+ response . askResponse = "messageResponse"
323+ response . text = "PLAN_MODE_TOGGLE_RESPONSE" // Special marker to toggle to Act mode
324+
325+ // Automatically toggle to Act mode after responding
326+ setTimeout ( async ( ) => {
327+ try {
328+ if ( webviewProvider . controller ) {
329+ Logger . log ( "Auto-toggling to Act mode from Plan mode" )
330+ await webviewProvider . controller . togglePlanActModeWithChatSettings ( { mode : "act" } )
331+ }
332+ } catch ( error ) {
333+ Logger . log ( `Error toggling to Act mode: ${ error } ` )
334+ }
335+ } , 500 ) // Small delay to ensure the response is processed first
336+ break
337+
338+ // For all other ask types (tool, command, browser_action_launch, use_mcp_server),
339+ // we use the default "yesButtonClicked" to approve the action
340+ }
341+
342+ // Send the response message
343+ webviewProvider . controller . handleWebviewMessage ( response )
344+ Logger . log ( `Auto-responded to ${ askType } with ${ response . askResponse } ` )
345+ }
346+
243347/**
244348 * Shuts down the test server if it exists
245349 */
0 commit comments