(id: string, cascadeSubtasks: boolean = true)
| 1980 | // this function deletes a task from task history, and deletes its checkpoints and delete the task folder |
| 1981 | // If the task has subtasks (childIds), they will also be deleted recursively |
| 1982 | async deleteTaskWithId(id: string, cascadeSubtasks: boolean = true) { |
| 1983 | try { |
| 1984 | // get the task directory full path and history item |
| 1985 | const { taskDirPath, historyItem } = await this.getTaskWithId(id) |
| 1986 | |
| 1987 | // Collect all task IDs to delete (parent + all subtasks) |
| 1988 | const allIdsToDelete: string[] = [id] |
| 1989 | |
| 1990 | if (cascadeSubtasks) { |
| 1991 | // Recursively collect all child IDs |
| 1992 | const collectChildIds = async (taskId: string): Promise<void> => { |
| 1993 | try { |
| 1994 | const { historyItem: item } = await this.getTaskWithId(taskId) |
| 1995 | if (item.childIds && item.childIds.length > 0) { |
| 1996 | for (const childId of item.childIds) { |
| 1997 | allIdsToDelete.push(childId) |
| 1998 | await collectChildIds(childId) |
| 1999 | } |
| 2000 | } |
| 2001 | } catch (error) { |
| 2002 | // Child task may already be deleted or not found, continue |
| 2003 | console.log(`[deleteTaskWithId] child task ${taskId} not found, skipping`) |
| 2004 | } |
| 2005 | } |
| 2006 | |
| 2007 | await collectChildIds(id) |
| 2008 | } |
| 2009 | |
| 2010 | // Remove from stack if any of the tasks to delete are in the current task stack |
| 2011 | for (const taskId of allIdsToDelete) { |
| 2012 | if (taskId === this.getCurrentTask()?.taskId) { |
| 2013 | // Close the current task instance; delegation flows will be handled via metadata if applicable. |
| 2014 | await this.removeClineFromStack() |
| 2015 | break |
| 2016 | } |
| 2017 | } |
| 2018 | |
| 2019 | // Delete all tasks from state in one batch |
| 2020 | await this.taskHistoryStore.deleteMany(allIdsToDelete) |
| 2021 | this.recentTasksCache = undefined |
| 2022 | |
| 2023 | // Delete associated shadow repositories or branches and task directories |
| 2024 | const globalStorageDir = this.contextProxy.globalStorageUri.fsPath |
| 2025 | const workspaceDir = this.cwd |
| 2026 | const { getTaskDirectoryPath } = await import("../../utils/storage") |
| 2027 | const globalStoragePath = this.contextProxy.globalStorageUri.fsPath |
| 2028 | |
| 2029 | for (const taskId of allIdsToDelete) { |
| 2030 | try { |
| 2031 | await ShadowCheckpointService.deleteTask({ taskId, globalStorageDir, workspaceDir }) |
| 2032 | } catch (error) { |
| 2033 | console.error( |
| 2034 | `[deleteTaskWithId${taskId}] failed to delete associated shadow repository or branch: ${error instanceof Error ? error.message : String(error)}`, |
| 2035 | ) |
| 2036 | } |
| 2037 | |
| 2038 | // Delete the task directory |
| 2039 | try { |
no test coverage detected