-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: preserve task state when extension host restarts in new window #8036
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
||
| private recentTasksCache?: string[] | ||
| private pendingOperations: Map<string, PendingEditOperation> = new Map() | ||
|
|
@@ -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 | ||
|
|
||
|
|
@@ -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( | ||
|
|
@@ -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) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider extracting this restoration logic into a separate method like |
||
| // 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() | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider wrapping this |
||
| } | ||
| } | ||
|
|
||
| public async createTaskWithHistoryItem(historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task }) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment seems redundant since the actual restoration is handled by |
||
| // The state will be posted by postStateToWebview() above, which includes the current task | ||
| } | ||
|
|
||
| provider.providerSettingsManager | ||
| .listConfig() | ||
| .then(async (listApiConfig) => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
isWebviewRestoredflag 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.