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
1 change: 1 addition & 0 deletions .review/pr-8274
Submodule pr-8274 added at e46929
158 changes: 158 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2275,6 +2275,164 @@ export class ClineProvider
await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
}

/**
* Performs a hard reset of Electron and VS Code caches to fix corrupted runtime files.
* This method clears all Electron cache directories, IndexedDB, Local Storage, Session Storage,
* and other cached data that may become corrupted and persist even after normal resets.
*
* The operation targets platform-specific cache locations:
* - macOS: ~/Library/Caches/com.microsoft.VSCode*, ~/Library/Application Support/Code/*
* - Windows: %APPDATA%/Code/*, %LOCALAPPDATA%/Microsoft/vscode-cpptools
* - Linux: ~/.cache/Code*, ~/.config/Code/*
*
* After clearing caches, it also performs a regular state reset and offers to restart VS Code.
*
* @returns {Promise<void>} Resolves when the cache clearing operation is complete
*/
async hardResetElectronCache() {
const answer = await vscode.window.showInformationMessage(
t("common:confirmation.hard_reset_electron_cache"),
{ modal: true, detail: t("common:confirmation.hard_reset_electron_cache_detail") },
t("common:answers.yes"),
)

if (answer !== t("common:answers.yes")) {
return
}

const platform = process.platform
const homeDir = os.homedir()
const pathsToDelete: string[] = []

// Platform-specific cache paths
if (platform === "darwin") {
// macOS paths - includes all VS Code and Electron cache locations
pathsToDelete.push(
// VS Code caches
path.join(homeDir, "Library", "Caches", "com.microsoft.VSCode"),
path.join(homeDir, "Library", "Caches", "com.microsoft.VSCode.ShipIt"),
path.join(homeDir, "Library", "Caches", "com.microsoft.VSCodeInsiders"),
// Electron caches
path.join(homeDir, "Library", "Caches", "Electron"),
// Application Support (VS Code specific)
path.join(homeDir, "Library", "Application Support", "Code", "Cache"),
path.join(homeDir, "Library", "Application Support", "Code", "CachedData"),
path.join(homeDir, "Library", "Application Support", "Code", "Code Cache"),
path.join(homeDir, "Library", "Application Support", "Code", "GPUCache"),
path.join(homeDir, "Library", "Application Support", "Code", "Local Storage"),
path.join(homeDir, "Library", "Application Support", "Code", "Session Storage"),
path.join(homeDir, "Library", "Application Support", "Code", "IndexedDB"),
// VS Code Insiders
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "Cache"),
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "CachedData"),
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "Code Cache"),
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "GPUCache"),
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "Local Storage"),
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "Session Storage"),
path.join(homeDir, "Library", "Application Support", "Code - Insiders", "IndexedDB"),
)
} else if (platform === "win32") {
// Windows paths
const appData = process.env.APPDATA || path.join(homeDir, "AppData", "Roaming")
const localAppData = process.env.LOCALAPPDATA || path.join(homeDir, "AppData", "Local")

pathsToDelete.push(
// VS Code caches
path.join(localAppData, "Microsoft", "vscode-cpptools"),
path.join(appData, "Code", "Cache"),
path.join(appData, "Code", "CachedData"),
path.join(appData, "Code", "Code Cache"),
path.join(appData, "Code", "GPUCache"),
path.join(appData, "Code", "Local Storage"),
path.join(appData, "Code", "Session Storage"),
path.join(appData, "Code", "IndexedDB"),
// VS Code Insiders
path.join(appData, "Code - Insiders", "Cache"),
path.join(appData, "Code - Insiders", "CachedData"),
path.join(appData, "Code - Insiders", "Code Cache"),
path.join(appData, "Code - Insiders", "GPUCache"),
path.join(appData, "Code - Insiders", "Local Storage"),
path.join(appData, "Code - Insiders", "Session Storage"),
path.join(appData, "Code - Insiders", "IndexedDB"),
)
} else {
// Linux paths
const configDir = process.env.XDG_CONFIG_HOME || path.join(homeDir, ".config")
const cacheDir = process.env.XDG_CACHE_HOME || path.join(homeDir, ".cache")

pathsToDelete.push(
// VS Code caches
path.join(cacheDir, "Code"),
path.join(cacheDir, "Code - Insiders"),
path.join(configDir, "Code", "Cache"),
path.join(configDir, "Code", "CachedData"),
path.join(configDir, "Code", "Code Cache"),
path.join(configDir, "Code", "GPUCache"),
path.join(configDir, "Code", "Local Storage"),
path.join(configDir, "Code", "Session Storage"),
path.join(configDir, "Code", "IndexedDB"),
// VS Code Insiders
path.join(configDir, "Code - Insiders", "Cache"),
path.join(configDir, "Code - Insiders", "CachedData"),
path.join(configDir, "Code - Insiders", "Code Cache"),
path.join(configDir, "Code - Insiders", "GPUCache"),
path.join(configDir, "Code - Insiders", "Local Storage"),
path.join(configDir, "Code - Insiders", "Session Storage"),
path.join(configDir, "Code - Insiders", "IndexedDB"),
)
}

// Delete the cache directories
let deletedPaths: string[] = []
let failedPaths: string[] = []

for (const cachePath of pathsToDelete) {
try {
// Check if path exists before trying to delete
await fs.access(cachePath)
await fs.rm(cachePath, { recursive: true, force: true })
deletedPaths.push(cachePath)
this.log(`Deleted cache: ${cachePath}`)
} catch (error) {
// Path doesn't exist or couldn't be deleted
if (error.code !== "ENOENT") {
failedPaths.push(cachePath)
this.log(`Failed to delete cache: ${cachePath} - ${error.message}`)
}
}
}

// Also perform the regular reset
await this.contextProxy.resetAllState()
await this.providerSettingsManager.resetAllConfigs()
await this.customModesManager.resetCustomModes()
await this.removeClineFromStack()
await this.postStateToWebview()

// Show result message
if (deletedPaths.length > 0) {
const message = t("common:confirmation.hard_reset_complete", {
count: deletedPaths.length,
failed:
failedPaths.length > 0
? t("common:confirmation.hard_reset_some_failed", { count: failedPaths.length })
: "",
})

vscode.window
.showInformationMessage(message, { modal: false }, t("common:answers.restart_vscode"))
.then((selection) => {
if (selection === t("common:answers.restart_vscode")) {
vscode.commands.executeCommand("workbench.action.reloadWindow")
}
})
} else {
vscode.window.showWarningMessage(t("common:confirmation.hard_reset_no_caches_found"))
}

await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
}

// logging

public log(message: string) {
Expand Down
3 changes: 3 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,9 @@ export const webviewMessageHandler = async (
case "resetState":
await provider.resetState()
break
case "hardResetElectronCache":
await provider.hardResetElectronCache()
break
case "flushRouterModels":
const routerNameFlush: RouterName = toRouterName(message.text)
await flushModels(routerNameFlush)
Expand Down
8 changes: 7 additions & 1 deletion src/i18n/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
},
"confirmation": {
"reset_state": "Are you sure you want to reset all state and secret storage in the extension? This cannot be undone.",
"hard_reset_electron_cache": "Are you sure you want to perform a hard reset? This will clear all Electron caches and VS Code data.",
"hard_reset_electron_cache_detail": "This action will:\n• Clear all VS Code caches\n• Clear all Electron caches\n• Clear IndexedDB, Local Storage, and Session Storage\n• Reset all extension settings\n\nYou will need to restart VS Code after this operation.",
"hard_reset_complete": "Hard reset completed. {{count}} cache directories were cleared.{{failed}}",
"hard_reset_some_failed": " ({{count}} directories could not be deleted)",
"hard_reset_no_caches_found": "No cache directories were found to clear.",
"delete_config_profile": "Are you sure you want to delete this configuration profile?",
"delete_custom_mode_with_rules": "Are you sure you want to delete this {scope} mode?\n\nThis will also delete the associated rules folder at:\n{rulesFolderPath}"
},
Expand Down Expand Up @@ -148,7 +153,8 @@
"yes": "Yes",
"no": "No",
"remove": "Remove",
"keep": "Keep"
"keep": "Keep",
"restart_vscode": "Restart VS Code"
},
"buttons": {
"save": "Save",
Expand Down
1 change: 1 addition & 0 deletions src/shared/WebviewMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export interface WebviewMessage {
| "importSettings"
| "exportSettings"
| "resetState"
| "hardResetElectronCache"
| "flushRouterModels"
| "requestRouterModels"
| "requestOpenAiModels"
Expand Down
1 change: 1 addition & 0 deletions tmp/pr-8287-Roo-Code
Submodule pr-8287-Roo-Code added at 88a473
1 change: 1 addition & 0 deletions tmp/pr-8412
Submodule pr-8412 added at 1339c7
7 changes: 7 additions & 0 deletions webview-ui/src/components/settings/About.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ export const About = ({ telemetrySetting, setTelemetrySetting, className, ...pro
<TriangleAlert className="p-0.5" />
{t("settings:footer.settings.reset")}
</Button>
<Button
variant="destructive"
onClick={() => vscode.postMessage({ type: "hardResetElectronCache" })}
className="w-32">
<TriangleAlert className="p-0.5" />
{t("settings:footer.settings.hardReset")}
</Button>
</div>
</Section>
</div>
Expand Down
3 changes: 2 additions & 1 deletion webview-ui/src/i18n/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,8 @@
"settings": {
"import": "Import",
"export": "Export",
"reset": "Reset"
"reset": "Reset",
"hardReset": "Hard Reset"
}
},
"thinkingBudget": {
Expand Down
Loading