From 1492d9b05a272bcaf15f3125b9d4894e1b446cb4 Mon Sep 17 00:00:00 2001 From: Jonas Kunert Date: Fri, 24 Jul 2026 10:41:43 +0200 Subject: [PATCH] fix: persist the plan-mode toggle across webview rebuilds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Plan toggle's state only lives in a webview variable, so closing and reopening the panel (or restarting VS Code) silently reset it to off — the user believed plan mode was still active and Claude went straight to making changes (#147). The toggle now reports changes to the extension host (planModeChanged -> workspaceState 'claude.planModeEnabled') and the host restores it during webview init via restorePlanMode, next to the existing input-draft restore. UI classes (switch + button) are applied on restore; the webview state stays authoritative while the webview is alive. Co-Authored-By: Claude Fable 5 --- src/extension.ts | 12 ++++++++++++ src/script.ts | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index 8fa37fb..d7a39f7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -421,6 +421,15 @@ class ClaudeChatProvider { data: this._draftMessage }); } + + // Restore the plan-mode toggle: its state only lives in the webview and + // would otherwise silently reset on every webview rebuild / VS Code restart. + if (this._context.workspaceState.get('claude.planModeEnabled', false)) { + this._postMessage({ + type: 'restorePlanMode', + data: true + }); + } } private async _handleWebviewMessage(message: any) { @@ -670,6 +679,9 @@ class ClaudeChatProvider { case 'enableYoloMode': this._enableYoloMode(); return; + case 'planModeChanged': + this._context.workspaceState.update('claude.planModeEnabled', !!message.enabled); + return; case 'saveInputText': this._saveInputText(message.text); return; diff --git a/src/script.ts b/src/script.ts index 4c949e2..f68db00 100644 --- a/src/script.ts +++ b/src/script.ts @@ -954,6 +954,7 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt function togglePlanMode() { planModeEnabled = !planModeEnabled; + vscode.postMessage({ type: 'planModeChanged', enabled: planModeEnabled }); const switchElement = document.getElementById('planModeSwitch'); if (planModeEnabled) { switchElement.classList.add('active'); @@ -1009,6 +1010,7 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt function cyclePlanMode() { planModeEnabled = !planModeEnabled; + vscode.postMessage({ type: 'planModeChanged', enabled: planModeEnabled }); sendStats('Plan mode toggled', { enabled: planModeEnabled }); var switchElement = document.getElementById('planModeSwitch'); var toggleBtn = document.getElementById('planToggleBtn'); @@ -3560,6 +3562,18 @@ const getScript = (isTelemetryEnabled: boolean, opencreditsApiUrl: string = 'htt inputField.style.height = Math.min(inputField.scrollHeight, 200) + 'px'; } break; + + case 'restorePlanMode': + // Plan mode state only lives in the webview; without this restore + // it silently resets on every webview rebuild / VS Code restart. + if (message.data && !planModeEnabled) { + planModeEnabled = true; + const planSwitchEl = document.getElementById('planModeSwitch'); + const planBtnEl = document.getElementById('planToggleBtn'); + if (planSwitchEl) planSwitchEl.classList.add('active'); + if (planBtnEl) planBtnEl.classList.add('active'); + } + break; case 'output': if (message.data.trim()) {