Skip to content

Commit cb745e1

Browse files
author
Eric Wheeler
committed
feat: Reparent child tasks atomically on parent deletion
When a task is deleted, ensure its child tasks are correctly reparented to the deleted task's own parent. This change also consolidates the task history update into a single operation. This addresses an issue where the UI update for reparenting and deletion could appear delayed by ensuring all modifications to the task list are processed together before the UI is refreshed. Signed-off-by: Eric Wheeler <[email protected]>
1 parent 5a9e4b5 commit cb745e1

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,29 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
11121112
// this function deletes a task from task hidtory, and deletes it's checkpoints and delete the task folder
11131113
async deleteTaskWithId(id: string) {
11141114
try {
1115-
// get the task directory full path
1116-
const { taskDirPath } = await this.getTaskWithId(id)
1115+
// Get the task to be deleted to access its parent_task_id
1116+
const { historyItem: deletedTaskHistoryItem, taskDirPath } = await this.getTaskWithId(id)
1117+
const grandparentTaskId = deletedTaskHistoryItem.parent_task_id
1118+
1119+
let currentTaskHistory = (this.getGlobalState("taskHistory") as HistoryItem[] | undefined) || []
1120+
1121+
// Create a new array with reparented children
1122+
const reparentedTaskHistory = currentTaskHistory.map((task) => {
1123+
if (task.parent_task_id === id) {
1124+
this.log(`Reparenting task ${task.id} from ${id} to ${grandparentTaskId ?? "undefined (root)"}`)
1125+
return { ...task, parent_task_id: grandparentTaskId }
1126+
}
1127+
return task
1128+
})
1129+
1130+
// Filter out the deleted task: this is in lieu of `deleteTaskFromState(id)`
1131+
const finalTaskHistory = reparentedTaskHistory.filter((task) => task.id !== id)
1132+
1133+
// Update global state with the final list
1134+
await this.updateGlobalState("taskHistory", finalTaskHistory)
1135+
1136+
// Post the final state to the webview, ensuring UI reflects all changes at once
1137+
await this.postStateToWebview()
11171138

11181139
// remove task from stack if it's the current task
11191140
if (id === this.getCurrentCline()?.taskId) {
@@ -1122,9 +1143,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
11221143
await this.finishSubTask(t("common:tasks.deleted"))
11231144
}
11241145

1125-
// delete task from the task history state
1126-
await this.deleteTaskFromState(id)
1127-
11281146
// Delete associated shadow repository or branch.
11291147
// TODO: Store `workspaceDir` in the `HistoryItem` object.
11301148
const globalStorageDir = this.contextProxy.globalStorageUri.fsPath

0 commit comments

Comments
 (0)