Skip to content

Commit 5e3854f

Browse files
committed
fix: restore parent task references for subtasks after VS Code restart
When VS Code is closed during a subtask execution and then restarted, the subtask now properly restores its parent task reference from the persisted history. This ensures that when the subtask completes, it can report its final state back to the parent task. The implementation: - Restores parent task reference from history when resuming a subtask - Recursively restores parent tasks if they are not already in the task stack - Maintains the parent-child relationship across VS Code sessions - Ensures subtask completion properly reports back to parent after restart Fixes #9038
1 parent 54745fc commit 5e3854f

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,9 @@ export class ClineProvider
857857
await this.removeClineFromStack()
858858
}
859859

860-
public async createTaskWithHistoryItem(historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task }) {
860+
public async createTaskWithHistoryItem(
861+
historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task },
862+
): Promise<Task> {
861863
await this.removeClineFromStack()
862864

863865
// If the history item has a saved mode, restore it and its associated API configuration.
@@ -903,6 +905,40 @@ export class ClineProvider
903905
}
904906
}
905907

908+
// Restore parent-child task relationships if this is a subtask
909+
let restoredParentTask: Task | undefined = undefined
910+
let restoredRootTask: Task | undefined = undefined
911+
912+
if (historyItem.parentTaskId) {
913+
// Try to find the parent task in the current task stack
914+
restoredParentTask = this.clineStack.find((task) => task.taskId === historyItem.parentTaskId)
915+
916+
if (!restoredParentTask) {
917+
// Parent task is not in the stack, try to restore it from history
918+
this.log(`Restoring parent task ${historyItem.parentTaskId} for subtask ${historyItem.id}`)
919+
try {
920+
const { historyItem: parentHistoryItem } = await this.getTaskWithId(historyItem.parentTaskId)
921+
// Recursively restore parent task (which may have its own parent)
922+
restoredParentTask = await this.createTaskWithHistoryItem(parentHistoryItem)
923+
} catch (error) {
924+
this.log(
925+
`Failed to restore parent task ${historyItem.parentTaskId}: ${error instanceof Error ? error.message : String(error)}`,
926+
)
927+
}
928+
}
929+
}
930+
931+
if (historyItem.rootTaskId) {
932+
// Try to find the root task in the current task stack
933+
restoredRootTask = this.clineStack.find((task) => task.taskId === historyItem.rootTaskId)
934+
935+
if (!restoredRootTask && historyItem.rootTaskId !== historyItem.parentTaskId) {
936+
// Root task is different from parent and not in stack
937+
this.log(`Note: Root task ${historyItem.rootTaskId} not found in current stack`)
938+
// We could restore root task here if needed, but usually parent is enough
939+
}
940+
}
941+
906942
const {
907943
apiConfiguration,
908944
diffEnabled: enableDiff,
@@ -924,8 +960,8 @@ export class ClineProvider
924960
consecutiveMistakeLimit: apiConfiguration.consecutiveMistakeLimit,
925961
historyItem,
926962
experiments,
927-
rootTask: historyItem.rootTask,
928-
parentTask: historyItem.parentTask,
963+
rootTask: restoredRootTask || historyItem.rootTask,
964+
parentTask: restoredParentTask || historyItem.parentTask,
929965
taskNumber: historyItem.number,
930966
workspacePath: historyItem.workspace,
931967
onCreated: this.taskCreationCallback,

0 commit comments

Comments
 (0)