Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,10 @@ export class ClineProvider
await this.removeClineFromStack()
}

public async createTaskWithHistoryItem(historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task }) {
public async createTaskWithHistoryItem(
historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task },
startTask: boolean = true,
): Promise<Task> {
await this.removeClineFromStack()

// If the history item has a saved mode, restore it and its associated API configuration.
Expand Down Expand Up @@ -903,6 +906,41 @@ 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)
// Pass startTask: false to prevent the parent from automatically starting execution
restoredParentTask = await this.createTaskWithHistoryItem(parentHistoryItem, false)
} 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,
Expand All @@ -924,12 +962,13 @@ 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,
enableBridge: BridgeOrchestrator.isEnabled(cloudUserInfo, taskSyncEnabled),
startTask,
})

await this.addClineToStack(task)
Expand Down