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
This commit is contained in:
Roo Code 2025-11-04 23:17:37 +00:00
parent 54745fc234
commit 5e3854ffd6

View file

@ -857,7 +857,9 @@ export class ClineProvider
await this.removeClineFromStack()
}
public async createTaskWithHistoryItem(historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task }) {
public async createTaskWithHistoryItem(
historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task },
): Promise<Task> {
await this.removeClineFromStack()
// If the history item has a saved mode, restore it and its associated API configuration.
@ -903,6 +905,40 @@ export class ClineProvider
}
}
// Restore parent-child task relationships if this is a subtask
let restoredParentTask: Task | undefined = undefined
let restoredRootTask: Task | undefined = undefined
if (historyItem.parentTaskId) {
// Try to find the parent task in the current task stack
restoredParentTask = this.clineStack.find((task) => task.taskId === historyItem.parentTaskId)
if (!restoredParentTask) {
// Parent task is not in the stack, try to restore it from history
this.log(`Restoring parent task ${historyItem.parentTaskId} for subtask ${historyItem.id}`)
try {
const { historyItem: parentHistoryItem } = await this.getTaskWithId(historyItem.parentTaskId)
// Recursively restore parent task (which may have its own parent)
restoredParentTask = await this.createTaskWithHistoryItem(parentHistoryItem)
} catch (error) {
this.log(
`Failed to restore parent task ${historyItem.parentTaskId}: ${error instanceof Error ? error.message : String(error)}`,
)
}
}
}
if (historyItem.rootTaskId) {
// Try to find the root task in the current task stack
restoredRootTask = this.clineStack.find((task) => task.taskId === historyItem.rootTaskId)
if (!restoredRootTask && historyItem.rootTaskId !== historyItem.parentTaskId) {
// Root task is different from parent and not in stack
this.log(`Note: Root task ${historyItem.rootTaskId} not found in current stack`)
// We could restore root task here if needed, but usually parent is enough
}
}
const {
apiConfiguration,
diffEnabled: enableDiff,
@ -924,8 +960,8 @@ export class ClineProvider
consecutiveMistakeLimit: apiConfiguration.consecutiveMistakeLimit,
historyItem,
experiments,
rootTask: historyItem.rootTask,
parentTask: historyItem.parentTask,
rootTask: restoredRootTask || historyItem.rootTask,
parentTask: restoredParentTask || historyItem.parentTask,
taskNumber: historyItem.number,
workspacePath: historyItem.workspace,
onCreated: this.taskCreationCallback,