Skip to content
Closed
Show file tree
Hide file tree
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
20 changes: 18 additions & 2 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export class ClineProvider
private taskCreationCallback: (task: Task) => void
private taskEventListeners: WeakMap<Task, Array<() => void>> = new WeakMap()
private currentWorkspacePath: string | undefined
private isWebviewRestored: boolean = false // Track if webview is being restored after restart
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The isWebviewRestored flag is set here but never cleared. If the webview is disposed and recreated multiple times during the extension's lifecycle, this could lead to incorrect behavior. Consider resetting this flag in the disposal logic or when appropriate to ensure proper state management across multiple webview lifecycles.


private recentTasksCache?: string[]
private pendingOperations: Map<string, PendingEditOperation> = new Map()
Expand Down Expand Up @@ -686,6 +687,9 @@ export class ClineProvider
}

async resolveWebviewView(webviewView: vscode.WebviewView | vscode.WebviewPanel) {
// Check if we already have a task stack (indicating a restore after extension host restart)
const hasExistingTasks = this.clineStack.length > 0

this.view = webviewView
const inTabMode = "onDidChangeViewState" in webviewView

Expand All @@ -695,6 +699,9 @@ export class ClineProvider
setPanel(webviewView, "sidebar")
}

// Mark that we're restoring if we have existing tasks
this.isWebviewRestored = hasExistingTasks

// Initialize out-of-scope variables that need to receive persistent
// global state values.
this.getState().then(
Expand Down Expand Up @@ -810,8 +817,17 @@ export class ClineProvider
})
this.webviewDisposables.push(configDisposable)

// If the extension is starting a new session, clear previous task state.
await this.removeClineFromStack()
// Only clear task state if this is a fresh start, not when restoring after extension host restart
// When the extension host restarts in a new window, we want to preserve the task state
if (!hasExistingTasks) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting this restoration logic into a separate method like shouldPreserveTaskState() for better readability and testability. This would make the intent clearer and allow for easier unit testing of the preservation logic.

// This is a fresh start, clear any previous task state
await this.removeClineFromStack()
} else {
// We're restoring after an extension host restart, preserve the task state
this.log("Preserving task state after extension host restart")
// Post the current state to the webview so it can restore the UI
await this.postStateToWebview()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider wrapping this postStateToWebview() call in a try-catch block or checking if the view is available first. If the webview isn't ready or has been disposed, this could throw an error.

}
}

public async createTaskWithHistoryItem(historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task }) {
Expand Down
7 changes: 7 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,13 @@ export const webviewMessageHandler = async (
provider.postMessageToWebview({ type: "mcpServers", mcpServers: mcpHub.getAllServers() })
}

// If we have an active task (after extension host restart), notify the webview to restore it
const activeTask = provider.getCurrentTask()
if (activeTask) {
provider.log("Restoring active task after extension host restart")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems redundant since the actual restoration is handled by postStateToWebview() in ClineProvider. The logging statement already indicates what's happening. Consider removing the comment or making it more concise.

// The state will be posted by postStateToWebview() above, which includes the current task
}

provider.providerSettingsManager
.listConfig()
.then(async (listApiConfig) => {
Expand Down
Loading