Skip to content

Windows path normalization missing in mode export causing cross-platform compatibility issues #6307

@hannesrudolph

Description

@hannesrudolph

App Version

Latest (main branch)

API Provider

Not Applicable / Other

Model Used

N/A

🔁 Steps to Reproduce

  1. On a Windows machine, create or have a custom mode with rules files
  2. Export the mode using the export functionality
  3. The exported YAML contains Windows-style paths with backslashes (e.g., rules-issue-fixer-orchestrator\1_workflow.xml)
  4. Try to import this exported mode on a Linux or macOS machine
  5. The import may fail or create incorrectly structured directories due to path separator mismatch

💥 Outcome Summary

Expected: Exported mode YAML should contain normalized paths with forward slashes for cross-platform compatibility
Actual: Windows exports contain backslash paths that don't work correctly on Unix-based systems

📄 Relevant Logs or Errors (Optional)

Example of problematic export on Windows:

rulesFiles:
  - relativePath: rules-issue-fixer-orchestrator\1_workflow.xml
    content: "..."

🔍 Comprehensive Issue Scoping

Root Cause / Implementation Target

The issue is in src/core/config/CustomModesManager.ts in the exportModeWithRules method (lines 788-789). The code uses path.relative() which returns platform-specific path separators, but doesn't normalize them to forward slashes for cross-platform compatibility.

Affected Components

  • Primary Files:

    • src/core/config/CustomModesManager.ts (lines 788-789): Export functionality needs path normalization
  • Secondary Impact:

    • Import functionality works correctly as it uses path.normalize() during import
    • No changes needed to import logic

Current Implementation Analysis

The current code at line 788-789:

const relativePath = isGlobalMode
    ? path.relative(baseDir, filePath)
    : path.relative(path.join(baseDir, ".roo"), filePath)
rulesFiles.push({ relativePath, content: content.trim() })

The path.relative() function returns:

  • On Windows: rules-mode\file.xml (backslashes)
  • On Unix: rules-mode/file.xml (forward slashes)

Proposed Implementation

Step 1: Add path normalization to export

  • File: src/core/config/CustomModesManager.ts
  • Changes: After calculating relativePath, normalize it using the existing toPosix() utility
  • Rationale: The codebase already has a toPosix() extension method that converts backslashes to forward slashes
const relativePath = isGlobalMode
    ? path.relative(baseDir, filePath)
    : path.relative(path.join(baseDir, ".roo"), filePath)
const normalizedRelativePath = relativePath.toPosix()
rulesFiles.push({ relativePath: normalizedRelativePath, content: content.trim() })

Code Architecture Considerations

  • The toPosix() method is already available as a String prototype extension (defined in src/utils/path.ts)
  • This pattern is used throughout the codebase for path normalization
  • The import functionality already handles both forward and backward slashes correctly

Testing Requirements

  • Unit Tests:
    • Test case 1: Export on Windows produces forward-slash paths
    • Test case 2: Export on Unix produces forward-slash paths (no change)
    • Test case 3: Exported YAML can be imported on any platform
  • Edge Cases:
    • Edge case 1: Paths with spaces are handled correctly
    • Edge case 2: Deeply nested paths are normalized correctly

Performance Impact

  • Expected performance change: Neutral
  • Benchmarking needed: No
  • Optimization opportunities: None - single string operation per file

Security Considerations

  • Input validation requirements: None - using existing validated paths
  • Authentication/Authorization changes: None
  • Data exposure risks: None

Migration Strategy

Not applicable - this is a bug fix that makes exports more compatible

Rollback Plan

If issues arise, revert the single line change. No data migration needed.

Dependencies and Breaking Changes

  • External dependencies affected: None
  • API contract changes: None
  • Breaking changes for users: None - this improves compatibility

Metadata

Metadata

Assignees

Labels

Issue - In ProgressSomeone is actively working on this. Should link to a PR soon.bugSomething isn't working

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions