From c4b8d2e3eec6132ea7905f4d22131d8ba3d99457 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Tue, 29 Jul 2025 18:32:39 +0000 Subject: [PATCH] fix: preserve .roomodes file formatting when importing modes - Modified updateModesInFile method to detect and preserve original YAML formatting - Analyzes existing file indentation and applies same formatting when rewriting - Prevents complete reformatting of .roomodes files during mode import operations - All existing tests continue to pass Fixes issue where importing a mode would reformat the entire .roomodes file, changing user-preferred formatting and layout. --- src/core/config/CustomModesManager.ts | 32 ++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index 095ed86cb7..d813964e20 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -458,12 +458,38 @@ export class CustomModesManager { private async updateModesInFile(filePath: string, operation: (modes: ModeConfig[]) => ModeConfig[]): Promise { let content = "{}" + let originalYamlOptions: yaml.ToStringOptions = { lineWidth: 0 } try { content = await fs.readFile(filePath, "utf-8") + + // Try to detect original YAML formatting style to preserve it + if (content.trim()) { + // Analyze the original content to preserve formatting style + const lines = content.split("\n") + let indentSize = 2 // default + let hasFlowStyle = false + + // Detect indentation size from the first indented line + for (const line of lines) { + const match = line.match(/^(\s+)/) + if (match && match[1].length > 0) { + indentSize = match[1].length + break + } + } + + // Check if the file uses flow style (arrays with brackets) + hasFlowStyle = content.includes("[") && content.includes("]") + + originalYamlOptions = { + lineWidth: 0, // Prevent line wrapping + indent: indentSize, + } + } } catch (error) { // File might not exist yet. - content = yaml.stringify({ customModes: [] }, { lineWidth: 0 }) + content = yaml.stringify({ customModes: [] }, originalYamlOptions) } let settings @@ -484,7 +510,7 @@ export class CustomModesManager { } settings.customModes = operation(settings.customModes) - await fs.writeFile(filePath, yaml.stringify(settings, { lineWidth: 0 }), "utf-8") + await fs.writeFile(filePath, yaml.stringify(settings, originalYamlOptions), "utf-8") } private async refreshMergedState(): Promise { @@ -786,7 +812,7 @@ export class CustomModesManager { // This excludes the rules-{slug} folder from the path const relativePath = path.relative(modeRulesDir, filePath) // Normalize path to use forward slashes for cross-platform compatibility - const normalizedRelativePath = relativePath.replace(/\\/g, '/') + const normalizedRelativePath = relativePath.replace(/\\/g, "/") rulesFiles.push({ relativePath: normalizedRelativePath, content: content.trim() }) } }