diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index c3e90d4300..cd1ce7031d 100644
--- a/src/core/Cline.ts
+++ b/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
diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts
index 70feb45c2f..cc0b6f4f04 100644
--- a/src/core/webview/ClineProvider.ts
+++ b/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,
diff --git a/src/shared/globalState.ts b/src/shared/globalState.ts
index bfd24f4298..739fa11dad 100644
--- a/src/shared/globalState.ts
+++ b/src/shared/globalState.ts
@@ -40,6 +40,7 @@ export const GLOBAL_STATE_KEYS = [
"alwaysAllowBrowser",
"alwaysAllowMcp",
"alwaysAllowModeSwitch",
+ "alwaysAllowFinishTask",
"taskHistory",
"openAiBaseUrl",
"openAiModelId",
diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx
index 02f75cd28a..fba97f6c7d 100644
--- a/webview-ui/src/components/chat/AutoApproveMenu.tsx
+++ b/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",
diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx
index 0f352819ef..b92604e157 100644
--- a/webview-ui/src/components/chat/ChatView.tsx
+++ b/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")
)
},
[
diff --git a/webview-ui/src/components/settings/AutoApproveSettings.tsx b/webview-ui/src/components/settings/AutoApproveSettings.tsx
index b2da2cab75..1c8e6c9ea9 100644
--- a/webview-ui/src/components/settings/AutoApproveSettings.tsx
+++ b/webview-ui/src/components/settings/AutoApproveSettings.tsx
@@ -18,6 +18,7 @@ type AutoApproveSettingsProps = HTMLAttributes
+ Automatically approve tasks to finish execution and continue to the next task, without user + review or approval +
+