diff --git a/scripts/init.js b/scripts/init.js index 933f2714..b5673a4f 100755 --- a/scripts/init.js +++ b/scripts/init.js @@ -477,26 +477,9 @@ function createProjectStructure(addAliases, dryRun) { // Create directories ensureDirectoryExists(path.join(targetDir, '.cursor', 'rules')); - - // Create Roo directories - ensureDirectoryExists(path.join(targetDir, '.roo')); - ensureDirectoryExists(path.join(targetDir, '.roo', 'rules')); - for (const mode of [ - 'architect', - 'ask', - 'boomerang', - 'code', - 'debug', - 'test' - ]) { - ensureDirectoryExists(path.join(targetDir, '.roo', `rules-${mode}`)); - } - ensureDirectoryExists(path.join(targetDir, 'scripts')); ensureDirectoryExists(path.join(targetDir, 'tasks')); - // Removed root-level MCP configuration; handled by brand-specific logic only. - // Copy template files with replacements const replacements = { year: new Date().getFullYear() @@ -545,32 +528,6 @@ function createProjectStructure(addAliases, dryRun) { path.join(targetDir, '.cursor', 'rules', 'self_improve.mdc') ); - const rooSourceDir = path.join(__dirname, '..', 'assets', 'roocode'); - const rooModesDir = path.join(rooSourceDir, '.roo'); - const rooModes = ['architect', 'ask', 'boomerang', 'code', 'debug', 'test']; - -// Copy .roomodes to project root -const roomodesSrc = path.join(rooSourceDir, '.roomodes'); -const roomodesDest = path.join(targetDir, '.roomodes'); -if (fs.existsSync(roomodesSrc)) { - fs.copyFileSync(roomodesSrc, roomodesDest); - log('info', `Copied .roomodes to ${roomodesDest}`); -} else { - log('warn', `.roomodes not found at ${roomodesSrc}`); -} - -// Copy each -rules file into the corresponding .roo/rules-/ folder -for (const mode of rooModes) { - const src = path.join(rooModesDir, `rules-${mode}`, `${mode}-rules`); - const dest = path.join(targetDir, '.roo', `rules-${mode}`, `${mode}-rules`); - if (fs.existsSync(src)) { - fs.copyFileSync(src, dest); - log('info', `Copied ${src} to ${dest}`); - } else { - log('warn', `Roo rule file not found for mode '${mode}': ${src}`); - } -} - // Copy example_prd.txt copyTemplateFile( 'example_prd.txt', diff --git a/scripts/modules/rule-transformer.js b/scripts/modules/rule-transformer.js index 89cbe51d..554e7cc9 100644 --- a/scripts/modules/rule-transformer.js +++ b/scripts/modules/rule-transformer.js @@ -12,13 +12,11 @@ import { log } from './utils.js'; // Import the shared MCP configuration helper import { setupMCPConfiguration } from './mcp-utils.js'; -// Import Roo Code conversionConfig and fileMap from profiles -import { conversionConfig, fileMap } from '../profiles/roo.js'; /** * Replace basic Cursor terms with brand equivalents */ -function replaceBasicTerms(content) { +function replaceBasicTerms(content, conversionConfig) { let result = content; // Apply brand term replacements @@ -41,7 +39,7 @@ function replaceBasicTerms(content) { /** * Replace Cursor tool references with brand tool equivalents */ -function replaceToolReferences(content) { +function replaceToolReferences(content, conversionConfig) { let result = content; // Basic pattern for direct tool name replacements @@ -72,7 +70,7 @@ function replaceToolReferences(content) { /** * Update documentation URLs to point to brand documentation */ -function updateDocReferences(content) { +function updateDocReferences(content, conversionConfig) { let result = content; // Apply documentation URL replacements @@ -90,7 +88,7 @@ function updateDocReferences(content) { /** * Update file references in markdown links */ -function updateFileReferences(content) { +function updateFileReferences(content, conversionConfig) { const { pathPattern, replacement } = conversionConfig.fileReferences; return content.replace(pathPattern, replacement); } @@ -218,6 +216,12 @@ function convertAllCursorRulesToBrandRules(projectDir, profile) { 'info', `Rule conversion complete: ${success} successful, ${failed} failed` ); + + // Call post-processing hook if defined (e.g., for Roo's rules-*mode* folders) + if (typeof profile.onPostConvertBrandRules === 'function') { + profile.onPostConvertBrandRules(projectDir); + } + return { success, failed }; } /** diff --git a/scripts/profiles/roo.js b/scripts/profiles/roo.js index af97fa81..a6d72af5 100644 --- a/scripts/profiles/roo.js +++ b/scripts/profiles/roo.js @@ -125,8 +125,46 @@ const conversionConfig = { export function onAddBrandRules(targetDir) { const sourceDir = path.resolve(__dirname, '../../assets/roocode'); copyRecursiveSync(sourceDir, targetDir); + + // Enhanced error checking and logging for .roomodes and rules-*mode* files + const rooModesDir = path.join(sourceDir, '.roo'); + const rooModes = ['architect', 'ask', 'boomerang', 'code', 'debug', 'test']; + + // Copy .roomodes to project root + const roomodesSrc = path.join(sourceDir, '.roomodes'); + const roomodesDest = path.join(targetDir, '.roomodes'); + if (fs.existsSync(roomodesSrc)) { + try { + fs.copyFileSync(roomodesSrc, roomodesDest); + console.log(`[Roo] Copied .roomodes to ${roomodesDest}`); + } catch (err) { + console.warn(`[Roo] Failed to copy .roomodes: ${err.message}`); + } + } else { + console.warn(`[Roo] .roomodes not found at ${roomodesSrc}`); + } + + // Copy each -rules file into the corresponding .roo/rules-/ folder + for (const mode of rooModes) { + const src = path.join(rooModesDir, `rules-${mode}`, `${mode}-rules`); + const dest = path.join(targetDir, '.roo', `rules-${mode}`, `${mode}-rules`); + if (fs.existsSync(src)) { + try { + // Ensure destination directory exists + const destDir = path.dirname(dest); + if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true }); + fs.copyFileSync(src, dest); + console.log(`[Roo] Copied ${src} to ${dest}`); + } catch (err) { + console.warn(`[Roo] Failed to copy ${src} to ${dest}: ${err.message}`); + } + } else { + console.warn(`[Roo] Roo rule file not found for mode '${mode}': ${src}`); + } + } } + function copyRecursiveSync(src, dest) { const exists = fs.existsSync(src); const stats = exists && fs.statSync(src); @@ -180,4 +218,10 @@ function isDirectoryEmpty(dirPath) { return fs.readdirSync(dirPath).length === 0; } -export { conversionConfig, fileMap, globalReplacements, brandName, rulesDir }; +function onPostConvertBrandRules(targetDir) { + onAddBrandRules(targetDir); +} + +export { conversionConfig, fileMap, globalReplacements, brandName, rulesDir, onPostConvertBrandRules }; + +