Browse Source

fixed the missing case of cmd execution at the end of a subyask and added auto aprove option for finish task (and continue to the next task)

ShayBC 1 year ago
parent
commit
27624a25a5

+ 10 - 23
src/core/Cline.ts

@@ -2953,19 +2953,7 @@ export class Cline {
 									if (lastMessage && lastMessage.ask !== "command") {
 										// havent sent a command message yet so first send completion_result then command
 										await this.say("completion_result", result, undefined, false)
-										// telemetryService.captureTaskCompleted(this.taskId)
-										if (this.isSubTask) {
-											const didApprove = await askFinishSubTaskApproval()
-											if (!didApprove) {
-												break
-											}
-
-											// tell the provider to remove the current subtask and resume the previous task in the stack
-											await this.providerRef
-												.deref()
-												?.finishSubTask(`Task complete: ${lastMessage?.text}`)
-											break
-										}
+										telemetryService.captureTaskCompleted(this.taskId)
 									}
 
 									// complete command message
@@ -2983,19 +2971,18 @@ export class Cline {
 									commandResult = execCommandResult
 								} else {
 									await this.say("completion_result", result, undefined, false)
-									// telemetryService.captureTaskCompleted(this.taskId)
-									if (this.isSubTask) {
-										const didApprove = await askFinishSubTaskApproval()
-										if (!didApprove) {
-											break
-										}
+									telemetryService.captureTaskCompleted(this.taskId)
+								}
 
-										// tell the provider to remove the current subtask and resume the previous task in the stack
-										await this.providerRef
-											.deref()
-											?.finishSubTask(`Task complete: ${lastMessage?.text}`)
+								if (this.isSubTask) {
+									const didApprove = await askFinishSubTaskApproval()
+									if (!didApprove) {
 										break
 									}
+
+									// tell the provider to remove the current subtask and resume the previous task in the stack
+									await this.providerRef.deref()?.finishSubTask(`Task complete: ${lastMessage?.text}`)
+									break
 								}
 
 								// we already sent completion_result says, an empty string asks relinquishes control over button and field

+ 7 - 0
src/core/webview/ClineProvider.ts

@@ -984,6 +984,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 						await this.updateGlobalState("alwaysAllowModeSwitch", message.bool)
 						await this.postStateToWebview()
 						break
+					case "alwaysAllowFinishTask":
+						await this.updateGlobalState("alwaysAllowFinishTask", message.bool)
+						await this.postStateToWebview()
+						break
 					case "askResponse":
 						this.getCurrentCline()?.handleWebviewAskResponse(
 							message.askResponse!,
@@ -2177,6 +2181,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			alwaysAllowBrowser,
 			alwaysAllowMcp,
 			alwaysAllowModeSwitch,
+			alwaysAllowFinishTask,
 			soundEnabled,
 			diffEnabled,
 			enableCheckpoints,
@@ -2224,6 +2229,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			alwaysAllowBrowser: alwaysAllowBrowser ?? false,
 			alwaysAllowMcp: alwaysAllowMcp ?? false,
 			alwaysAllowModeSwitch: alwaysAllowModeSwitch ?? false,
+			alwaysAllowFinishTask: alwaysAllowFinishTask ?? false,
 			uriScheme: vscode.env.uriScheme,
 			currentTaskItem: this.getCurrentCline()?.taskId
 				? (taskHistory || []).find((item: HistoryItem) => item.id === this.getCurrentCline()?.taskId)
@@ -2385,6 +2391,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			alwaysAllowBrowser: stateValues.alwaysAllowBrowser ?? false,
 			alwaysAllowMcp: stateValues.alwaysAllowMcp ?? false,
 			alwaysAllowModeSwitch: stateValues.alwaysAllowModeSwitch ?? false,
+			alwaysAllowFinishTask: stateValues.alwaysAllowFinishTask ?? false,
 			taskHistory: stateValues.taskHistory,
 			allowedCommands: stateValues.allowedCommands,
 			soundEnabled: stateValues.soundEnabled ?? false,

+ 1 - 0
src/shared/globalState.ts

@@ -40,6 +40,7 @@ export const GLOBAL_STATE_KEYS = [
 	"alwaysAllowBrowser",
 	"alwaysAllowMcp",
 	"alwaysAllowModeSwitch",
+	"alwaysAllowFinishTask",
 	"taskHistory",
 	"openAiBaseUrl",
 	"openAiModelId",

+ 3 - 3
webview-ui/src/components/chat/AutoApproveMenu.tsx

@@ -85,10 +85,10 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
 		},
 		{
 			id: "finishTask",
-			label: "Finish subtasks tasks",
-			shortName: "Finish",
+			label: "Continue to next task",
+			shortName: "Continue",
 			enabled: alwaysAllowFinishTask ?? false,
-			description: "Allows automatic completeing a sub-task without requiring user review or approval.",
+			description: "Allow tasks to end execution and continue to the next task, without user review or approval.",
 		},
 		{
 			id: "retryRequests",

+ 7 - 1
webview-ui/src/components/chat/ChatView.tsx

@@ -149,6 +149,10 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
 									setPrimaryButtonText("Save")
 									setSecondaryButtonText("Reject")
 									break
+								case "finishTask":
+									setPrimaryButtonText("Approve & Continue to the next Task")
+									setSecondaryButtonText(undefined)
+									break
 								default:
 									setPrimaryButtonText("Approve")
 									setSecondaryButtonText("Reject")
@@ -644,7 +648,9 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
 					message.ask === "tool" &&
 					(JSON.parse(message.text || "{}")?.tool === "switchMode" ||
 						JSON.parse(message.text || "{}")?.tool === "newTask")) ||
-				(alwaysAllowFinishTask && message.ask === "finishTask")
+				(alwaysAllowFinishTask &&
+					message.ask === "tool" &&
+					JSON.parse(message.text || "{}")?.tool === "finishTask")
 			)
 		},
 		[

+ 14 - 0
webview-ui/src/components/settings/AutoApproveSettings.tsx

@@ -18,6 +18,7 @@ type AutoApproveSettingsProps = HTMLAttributes<HTMLDivElement> & {
 	requestDelaySeconds: number
 	alwaysAllowMcp?: boolean
 	alwaysAllowModeSwitch?: boolean
+	alwaysAllowFinishTask?: boolean
 	alwaysAllowExecute?: boolean
 	allowedCommands?: string[]
 	setCachedStateField: SetCachedStateField<keyof ExtensionStateContextType>
@@ -32,6 +33,7 @@ export const AutoApproveSettings = ({
 	requestDelaySeconds,
 	alwaysAllowMcp,
 	alwaysAllowModeSwitch,
+	alwaysAllowFinishTask,
 	alwaysAllowExecute,
 	allowedCommands,
 	setCachedStateField,
@@ -180,6 +182,18 @@ export const AutoApproveSettings = ({
 					</p>
 				</div>
 
+				<div>
+					<VSCodeCheckbox
+						checked={alwaysAllowFinishTask}
+						onChange={(e: any) => setCachedStateField("alwaysAllowFinishTask", e.target.checked)}>
+						<span className="font-medium">Always approve finish & continue to next task</span>
+					</VSCodeCheckbox>
+					<p className="text-vscode-descriptionForeground text-sm mt-0">
+						Automatically approve tasks to finish execution and continue to the next task, without user
+						review or approval
+					</p>
+				</div>
+
 				<div>
 					<VSCodeCheckbox
 						checked={alwaysAllowExecute}

+ 3 - 0
webview-ui/src/components/settings/SettingsView.tsx

@@ -63,6 +63,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone },
 		alwaysAllowExecute,
 		alwaysAllowMcp,
 		alwaysAllowModeSwitch,
+		alwaysAllowFinishTask,
 		alwaysAllowWrite,
 		alwaysApproveResubmit,
 		browserToolEnabled,
@@ -184,6 +185,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone },
 			vscode.postMessage({ type: "currentApiConfigName", text: currentApiConfigName })
 			vscode.postMessage({ type: "updateExperimental", values: experiments })
 			vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch })
+			vscode.postMessage({ type: "alwaysAllowFinishTask", bool: alwaysAllowFinishTask })
 			vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration })
 			vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting })
 			setChangeDetected(false)
@@ -364,6 +366,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone },
 						requestDelaySeconds={requestDelaySeconds}
 						alwaysAllowMcp={alwaysAllowMcp}
 						alwaysAllowModeSwitch={alwaysAllowModeSwitch}
+						alwaysAllowFinishTask={alwaysAllowFinishTask}
 						alwaysAllowExecute={alwaysAllowExecute}
 						allowedCommands={allowedCommands}
 						setCachedStateField={setCachedStateField}