-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Description
When exporting a Roo mode, the relativePath for rule files includes the rules-<slug> prefix (e.g., rules-old-slug/rule.xml). If a user changes the slug in the exported YAML file before importing, the rules are written to a directory based on the old slug instead of the new one.
Steps to Reproduce
- Export a mode that has rules files (e.g., slug: "old-slug")
- Open the exported YAML file
- Change the slug to a new value (e.g., "new-slug")
- Import the modified YAML file
- Check the
.roodirectory
Expected Behavior
Rules files should be imported into .roo/rules-new-slug/ based on the slug in the YAML file.
Actual Behavior
Rules files are created in .roo/rules-old-slug/ (using the path from the export), while .roo/rules-new-slug/ is deleted but remains empty.
Code Investigation
- Export function (
CustomModesManager.ts:787-788): CalculatesrelativePathincluding the rules folder prefix - Import function (
CustomModesManager.ts:884): Uses the exported path directly without adapting to the new slug
Impact
Users cannot rename modes by editing the exported YAML, which limits the reusability of exported modes. This affects anyone trying to:
- Share modes with different names
- Create variations of existing modes
- Organize modes with consistent naming
🔍 Comprehensive Issue Scoping
Root Cause / Implementation Target
The relativePath in exported mode YAML files includes the rules-<slug> prefix, making it dependent on the mode's slug. When users change the slug before importing, the rules files are written to the wrong directory (using the old slug) while the new slug's directory is deleted.
Affected Components
-
Primary Files:
src/core/config/CustomModesManager.ts(lines 786-788, 872-902): Export and import logicsrc/core/config/__tests__/CustomModesManager.spec.ts: Test expectations need updating
-
Secondary Impact:
src/services/marketplace/SimpleInstaller.ts: Uses importModeWithRulessrc/core/webview/webviewMessageHandler.ts: Handles export/import UI actions- No changes needed in secondary files
Current Implementation Analysis
The export function at line 787-788 calculates relativePath as:
const relativePath = isGlobalMode
? path.relative(baseDir, filePath)
: path.relative(path.join(baseDir, ".roo"), filePath)This results in paths like rules-old-slug/rule.md being stored in the YAML.
The import function at line 884 uses this path directly:
const targetPath = path.join(baseDir, normalizedRelativePath)This creates files at the old slug's location instead of the new one.
Proposed Implementation
Step 1: Fix Export Path Calculation
- File:
src/core/config/CustomModesManager.ts - Line: 787-788
- Change: Use
path.relative(modeRulesDir, filePath)to make paths relative to the rules directory - Rationale: This makes
relativePathslug-independent (e.g.,rule.mdinstead ofrules-slug/rule.md)
Step 2: Add Backwards Compatibility to Import
- File:
src/core/config/CustomModesManager.ts - Lines: 872-884
- Changes:
// Strip rules-<slug> prefix for backwards compatibility let cleanRelativePath = ruleFile.relativePath const rulesPrefix = cleanRelativePath.match(/^rules-[^\/]+\/(.*)$/) if (rulesPrefix) { cleanRelativePath = rulesPrefix[1] }
- Then use
path.join(rulesFolderPath, normalizedRelativePath)for the target path - Rationale: Supports both old and new export formats seamlessly
Code Architecture Considerations
- The solution follows existing patterns for path handling
- Maintains all security validations (path traversal prevention)
- No new dependencies or architectural changes needed
- Backwards compatibility ensures no breaking changes
Testing Requirements
- Unit Tests:
- Test export creates slug-independent paths
- Test import with new format works correctly
- Test import with old format (backwards compatibility)
- Test slug renaming scenario
- Test nested directory handling
- Integration Tests:
- Test full export/import cycle with slug change
- Edge Cases:
- Empty rules directory
- Path traversal attempts
- Multiple rules- prefixes in path
Performance Impact
- Expected performance change: Neutral
- Benchmarking needed: No
- Optimization opportunities: None identified
Security Considerations
- Path traversal prevention already in place (lines 876-892)
- No new security risks introduced
- Backwards compatibility regex is safe and specific
Migration Strategy
No migration needed - backwards compatibility handles all existing exports automatically.
Rollback Plan
If issues arise, revert the two changed methods in CustomModesManager.ts.
Dependencies and Breaking Changes
- External dependencies affected: None
- API contract changes: None (same YAML structure, just different paths)
- Breaking changes for users: None (backwards compatible)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status