From d397d131b944dd2d7301018baaec96c2cab4ae39 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 27 Jun 2025 14:04:17 -0500 Subject: [PATCH] fix: restore JSON backwards compatibility for .roomodes files (#5199) --- src/core/config/CustomModesManager.ts | 45 +++++++++++---------- src/services/marketplace/SimpleInstaller.ts | 8 +--- src/utils/migrateSettings.ts | 2 +- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index 5ce94b0e38..b96293ee49 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -123,18 +123,29 @@ export class CustomModesManager { try { return yaml.parse(cleanedContent) - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error) - console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) - - // Show user-friendly error message for .roomodes files + } catch (yamlError) { + // For .roomodes files, try JSON as fallback if (filePath.endsWith(ROOMODES_FILENAME)) { - const lineMatch = errorMsg.match(/at line (\d+)/) - const line = lineMatch ? lineMatch[1] : "unknown" - vscode.window.showErrorMessage(t("common:customModes.errors.yamlParseError", { line })) + try { + // Try parsing the original content as JSON (not the cleaned content) + return JSON.parse(content) + } catch (jsonError) { + // JSON also failed, show the original YAML error + const errorMsg = yamlError instanceof Error ? yamlError.message : String(yamlError) + console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) + + const lineMatch = errorMsg.match(/at line (\d+)/) + const line = lineMatch ? lineMatch[1] : "unknown" + vscode.window.showErrorMessage(t("common:customModes.errors.yamlParseError", { line })) + + // Return empty object to prevent duplicate error handling + return {} + } } - // Return empty object to prevent duplicate error handling + // For non-.roomodes files, just log and return empty object + const errorMsg = yamlError instanceof Error ? yamlError.message : String(yamlError) + console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) return {} } } @@ -205,12 +216,7 @@ export class CustomModesManager { const fileExists = await fileExistsAtPath(filePath) if (!fileExists) { - await this.queueWrite(() => - fs.writeFile( - filePath, - yaml.stringify({ customModes: [] }, { lineWidth: 0, defaultStringType: "PLAIN" }), - ), - ) + await this.queueWrite(() => fs.writeFile(filePath, yaml.stringify({ customModes: [] }, { lineWidth: 0 }))) } return filePath @@ -414,7 +420,7 @@ export class CustomModesManager { content = await fs.readFile(filePath, "utf-8") } catch (error) { // File might not exist yet. - content = yaml.stringify({ customModes: [] }, { lineWidth: 0, defaultStringType: "PLAIN" }) + content = yaml.stringify({ customModes: [] }, { lineWidth: 0 }) } let settings @@ -427,7 +433,7 @@ export class CustomModesManager { } settings.customModes = operation(settings.customModes || []) - await fs.writeFile(filePath, yaml.stringify(settings, { lineWidth: 0, defaultStringType: "PLAIN" }), "utf-8") + await fs.writeFile(filePath, yaml.stringify(settings, { lineWidth: 0 }), "utf-8") } private async refreshMergedState(): Promise { @@ -485,10 +491,7 @@ export class CustomModesManager { public async resetCustomModes(): Promise { try { const filePath = await this.getCustomModesFilePath() - await fs.writeFile( - filePath, - yaml.stringify({ customModes: [] }, { lineWidth: 0, defaultStringType: "PLAIN" }), - ) + await fs.writeFile(filePath, yaml.stringify({ customModes: [] }, { lineWidth: 0 })) await this.context.globalState.update("customModes", []) this.clearCache() await this.onUpdate() diff --git a/src/services/marketplace/SimpleInstaller.ts b/src/services/marketplace/SimpleInstaller.ts index 7ead5e2442..91f5bcad26 100644 --- a/src/services/marketplace/SimpleInstaller.ts +++ b/src/services/marketplace/SimpleInstaller.ts @@ -84,7 +84,7 @@ export class SimpleInstaller { // Write back to file await fs.mkdir(path.dirname(filePath), { recursive: true }) - const yamlContent = yaml.stringify(existingData, { lineWidth: 0, defaultStringType: "PLAIN" }) + const yamlContent = yaml.stringify(existingData, { lineWidth: 0 }) await fs.writeFile(filePath, yamlContent, "utf-8") // Calculate approximate line number where the new mode was added @@ -282,11 +282,7 @@ export class SimpleInstaller { existingData.customModes = existingData.customModes.filter((mode: any) => mode.slug !== modeData.slug) // Always write back the file, even if empty - await fs.writeFile( - filePath, - yaml.stringify(existingData, { lineWidth: 0, defaultStringType: "PLAIN" }), - "utf-8", - ) + await fs.writeFile(filePath, yaml.stringify(existingData, { lineWidth: 0 }), "utf-8") } } catch (error: any) { if (error.code === "ENOENT") { diff --git a/src/utils/migrateSettings.ts b/src/utils/migrateSettings.ts index 3007a6bcfb..43b1d7291f 100644 --- a/src/utils/migrateSettings.ts +++ b/src/utils/migrateSettings.ts @@ -93,7 +93,7 @@ async function migrateCustomModesToYaml(settingsDir: string, outputChannel: vsco const customModesData = yaml.parse(jsonContent) // Convert to YAML with no line width limit to prevent line breaks - const yamlContent = yaml.stringify(customModesData, { lineWidth: 0, defaultStringType: "PLAIN" }) + const yamlContent = yaml.stringify(customModesData, { lineWidth: 0 }) // Write YAML file await fs.writeFile(newYamlPath, yamlContent, "utf-8")