fix formatting
This commit is contained in:
@@ -446,9 +446,15 @@ async function initializeProject(options = {}) {
|
|||||||
try {
|
try {
|
||||||
const mcpResult = await options.mcpServer.call('rules', mcpArgs);
|
const mcpResult = await options.mcpServer.call('rules', mcpArgs);
|
||||||
if (mcpResult && mcpResult.success) {
|
if (mcpResult && mcpResult.success) {
|
||||||
log('success', `Brand rules added via MCP: ${selectedBrandRules.join(', ')}`);
|
log(
|
||||||
|
'success',
|
||||||
|
`Brand rules added via MCP: ${selectedBrandRules.join(', ')}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
log('error', `MCP rules add failed: ${mcpResult?.error?.message || 'Unknown error'}`);
|
log(
|
||||||
|
'error',
|
||||||
|
`MCP rules add failed: ${mcpResult?.error?.message || 'Unknown error'}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log('error', `MCP server error: ${err.message}`);
|
log('error', `MCP server error: ${err.message}`);
|
||||||
|
|||||||
@@ -2,32 +2,37 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
describe('Cursor Profile Initialization Functionality', () => {
|
describe('Cursor Profile Initialization Functionality', () => {
|
||||||
let cursorProfileContent;
|
let cursorProfileContent;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
const cursorJsPath = path.join(process.cwd(), 'scripts', 'profiles', 'cursor.js');
|
const cursorJsPath = path.join(
|
||||||
cursorProfileContent = fs.readFileSync(cursorJsPath, 'utf8');
|
process.cwd(),
|
||||||
});
|
'scripts',
|
||||||
|
'profiles',
|
||||||
|
'cursor.js'
|
||||||
|
);
|
||||||
|
cursorProfileContent = fs.readFileSync(cursorJsPath, 'utf8');
|
||||||
|
});
|
||||||
|
|
||||||
test('cursor.js exports correct brandName and rulesDir', () => {
|
test('cursor.js exports correct brandName and rulesDir', () => {
|
||||||
expect(cursorProfileContent).toContain("const brandName = 'Cursor'");
|
expect(cursorProfileContent).toContain("const brandName = 'Cursor'");
|
||||||
expect(cursorProfileContent).toContain("const rulesDir = '.cursor/rules'");
|
expect(cursorProfileContent).toContain("const rulesDir = '.cursor/rules'");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cursor.js preserves .mdc filenames in fileMap', () => {
|
test('cursor.js preserves .mdc filenames in fileMap', () => {
|
||||||
expect(cursorProfileContent).toContain('fileMap = {');
|
expect(cursorProfileContent).toContain('fileMap = {');
|
||||||
// Should NOT contain any .md mapping
|
// Should NOT contain any .md mapping
|
||||||
expect(cursorProfileContent).not.toMatch(/\.md'/);
|
expect(cursorProfileContent).not.toMatch(/\.md'/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cursor.js contains tool naming logic and global replacements', () => {
|
test('cursor.js contains tool naming logic and global replacements', () => {
|
||||||
expect(cursorProfileContent).toContain('edit_file');
|
expect(cursorProfileContent).toContain('edit_file');
|
||||||
expect(cursorProfileContent).toContain('search tool');
|
expect(cursorProfileContent).toContain('search tool');
|
||||||
expect(cursorProfileContent).not.toContain('apply_diff');
|
expect(cursorProfileContent).not.toContain('apply_diff');
|
||||||
expect(cursorProfileContent).not.toContain('search_files tool');
|
expect(cursorProfileContent).not.toContain('search_files tool');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cursor.js contains correct documentation URL logic', () => {
|
test('cursor.js contains correct documentation URL logic', () => {
|
||||||
expect(cursorProfileContent).toContain('docs.cursor.com');
|
expect(cursorProfileContent).toContain('docs.cursor.com');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// Integration tests for rules transformer functions in MCP server context
|
||||||
|
import { jest } from '@jest/globals';
|
||||||
|
import {
|
||||||
|
convertAllRulesToBrandRules,
|
||||||
|
removeBrandRules
|
||||||
|
} from '../../../scripts/modules/rule-transformer.js';
|
||||||
|
import * as windsurfProfile from '../../../scripts/profiles/windsurf.js';
|
||||||
|
|
||||||
|
// Mock fs functions as in direct-functions.test.js
|
||||||
|
const mockExistsSync = jest.fn();
|
||||||
|
const mockWriteFileSync = jest.fn();
|
||||||
|
const mockReadFileSync = jest.fn();
|
||||||
|
const mockUnlinkSync = jest.fn();
|
||||||
|
const mockMkdirSync = jest.fn();
|
||||||
|
const mockRmSync = jest.fn();
|
||||||
|
const mockReaddirSync = jest.fn();
|
||||||
|
|
||||||
|
jest.mock('fs', () => ({
|
||||||
|
existsSync: mockExistsSync,
|
||||||
|
writeFileSync: mockWriteFileSync,
|
||||||
|
readFileSync: mockReadFileSync,
|
||||||
|
unlinkSync: mockUnlinkSync,
|
||||||
|
mkdirSync: mockMkdirSync,
|
||||||
|
rmSync: mockRmSync,
|
||||||
|
readdirSync: mockReaddirSync
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('rules transformer', () => {
|
||||||
|
const mockProjectDir = '/mock/project/root';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should convert all Cursor rules to windsurf brand rules', () => {
|
||||||
|
// Arrange
|
||||||
|
mockExistsSync.mockImplementation((p) => {
|
||||||
|
// Simulate that the cursor rules directory exists
|
||||||
|
if (p === '/mock/project/root/assets/rules') return true;
|
||||||
|
// Simulate that the brand rules directory does not exist initially
|
||||||
|
if (p === '/mock/project/root/.windsurf/rules') return false;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
mockReadFileSync.mockImplementation((p) => 'mock rule content');
|
||||||
|
mockReaddirSync.mockImplementation((dir) => ['sample-rule.mdc']);
|
||||||
|
mockWriteFileSync.mockImplementation(() => {});
|
||||||
|
mockMkdirSync.mockImplementation(() => {});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = convertAllRulesToBrandRules(mockProjectDir, windsurfProfile);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result.success).toBeGreaterThanOrEqual(0);
|
||||||
|
expect(mockWriteFileSync).toHaveBeenCalled();
|
||||||
|
expect(mockMkdirSync).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove windsurf brand rules', () => {
|
||||||
|
// Arrange
|
||||||
|
mockExistsSync.mockImplementation((p) => {
|
||||||
|
// Simulate that the brand rules directory exists
|
||||||
|
if (p === '/mock/project/root/.windsurf/rules') return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
mockRmSync.mockImplementation(() => {});
|
||||||
|
mockUnlinkSync.mockImplementation(() => {});
|
||||||
|
mockReaddirSync.mockImplementation((dir) => []);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const removed = removeBrandRules(mockProjectDir, windsurfProfile);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(removed).toBe(true);
|
||||||
|
expect(mockRmSync).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -22,20 +22,34 @@ describe('Roo Files Inclusion in Package', () => {
|
|||||||
const rooJsContent = fs.readFileSync(rooJsPath, 'utf8');
|
const rooJsContent = fs.readFileSync(rooJsPath, 'utf8');
|
||||||
|
|
||||||
// Check for the main handler function
|
// Check for the main handler function
|
||||||
expect(rooJsContent.includes("onAddBrandRules(targetDir)")).toBe(true);
|
expect(rooJsContent.includes('onAddBrandRules(targetDir)')).toBe(true);
|
||||||
|
|
||||||
// Check for general recursive copy of assets/roocode
|
// Check for general recursive copy of assets/roocode
|
||||||
expect(rooJsContent.includes("copyRecursiveSync(sourceDir, targetDir)")).toBe(true);
|
expect(
|
||||||
|
rooJsContent.includes('copyRecursiveSync(sourceDir, targetDir)')
|
||||||
|
).toBe(true);
|
||||||
|
|
||||||
// Check for .roomodes file copying logic (source and destination paths)
|
// Check for .roomodes file copying logic (source and destination paths)
|
||||||
expect(rooJsContent.includes("path.join(sourceDir, '.roomodes')")).toBe(true);
|
expect(rooJsContent.includes("path.join(sourceDir, '.roomodes')")).toBe(
|
||||||
expect(rooJsContent.includes("path.join(targetDir, '.roomodes')")).toBe(true);
|
true
|
||||||
|
);
|
||||||
|
expect(rooJsContent.includes("path.join(targetDir, '.roomodes')")).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
// Check for mode-specific rule file copying logic
|
// Check for mode-specific rule file copying logic
|
||||||
expect(rooJsContent.includes("for (const mode of rooModes)")).toBe(true);
|
expect(rooJsContent.includes('for (const mode of rooModes)')).toBe(true);
|
||||||
expect(rooJsContent.includes("path.join(rooModesDir, `rules-${mode}`, `${mode}-rules`)")).toBe(true);
|
expect(
|
||||||
expect(rooJsContent.includes("path.join(targetDir, '.roo', `rules-${mode}`, `${mode}-rules`)")).toBe(true);
|
rooJsContent.includes(
|
||||||
|
'path.join(rooModesDir, `rules-${mode}`, `${mode}-rules`)'
|
||||||
|
)
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
rooJsContent.includes(
|
||||||
|
"path.join(targetDir, '.roo', `rules-${mode}`, `${mode}-rules`)"
|
||||||
|
)
|
||||||
|
).toBe(true);
|
||||||
|
|
||||||
// Check for definition of rooModes array and all modes
|
// Check for definition of rooModes array and all modes
|
||||||
const rooModesArrayRegex = /const rooModes\s*=\s*\[([^\]]+)\]\s*;?/;
|
const rooModesArrayRegex = /const rooModes\s*=\s*\[([^\]]+)\]\s*;?/;
|
||||||
const rooModesMatch = rooJsContent.match(rooModesArrayRegex);
|
const rooModesMatch = rooJsContent.match(rooModesArrayRegex);
|
||||||
|
|||||||
@@ -19,26 +19,37 @@ describe('Roo Profile Initialization Functionality', () => {
|
|||||||
expect(rooProfileContent).toContain(
|
expect(rooProfileContent).toContain(
|
||||||
'copyRecursiveSync(sourceDir, targetDir)'
|
'copyRecursiveSync(sourceDir, targetDir)'
|
||||||
);
|
);
|
||||||
expect(rooProfileContent).toContain("path.resolve(__dirname, '../../assets/roocode')"); // Verifies sourceDir definition
|
expect(rooProfileContent).toContain(
|
||||||
|
"path.resolve(__dirname, '../../assets/roocode')"
|
||||||
|
); // Verifies sourceDir definition
|
||||||
|
|
||||||
// Check for the loop that processes rooModes
|
// Check for the loop that processes rooModes
|
||||||
expect(rooProfileContent).toContain('for (const mode of rooModes)');
|
expect(rooProfileContent).toContain('for (const mode of rooModes)');
|
||||||
|
|
||||||
// Check for creation of mode-specific rule directories (e.g., .roo/rules-architect)
|
// Check for creation of mode-specific rule directories (e.g., .roo/rules-architect)
|
||||||
// This is the line: if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
// This is the line: if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
||||||
expect(rooProfileContent).toContain("fs.mkdirSync(destDir, { recursive: true });");
|
expect(rooProfileContent).toContain(
|
||||||
expect(rooProfileContent).toContain("const destDir = path.dirname(dest);"); // part of the same logic block
|
'fs.mkdirSync(destDir, { recursive: true });'
|
||||||
|
);
|
||||||
|
expect(rooProfileContent).toContain('const destDir = path.dirname(dest);'); // part of the same logic block
|
||||||
});
|
});
|
||||||
|
|
||||||
test('roo.js profile copies .roomodes file via onAddBrandRules', () => {
|
test('roo.js profile copies .roomodes file via onAddBrandRules', () => {
|
||||||
expect(rooProfileContent).toContain('onAddBrandRules(targetDir)');
|
expect(rooProfileContent).toContain('onAddBrandRules(targetDir)');
|
||||||
|
|
||||||
// Check for the specific .roomodes copy logic
|
// Check for the specific .roomodes copy logic
|
||||||
expect(rooProfileContent).toContain('fs.copyFileSync(roomodesSrc, roomodesDest);');
|
expect(rooProfileContent).toContain(
|
||||||
expect(rooProfileContent).toContain("const roomodesSrc = path.join(sourceDir, '.roomodes');");
|
'fs.copyFileSync(roomodesSrc, roomodesDest);'
|
||||||
expect(rooProfileContent).toContain("const roomodesDest = path.join(targetDir, '.roomodes');");
|
);
|
||||||
expect(rooProfileContent).toContain("path.resolve(__dirname, '../../assets/roocode')"); // sourceDir for roomodesSrc
|
expect(rooProfileContent).toContain(
|
||||||
|
"const roomodesSrc = path.join(sourceDir, '.roomodes');"
|
||||||
|
);
|
||||||
|
expect(rooProfileContent).toContain(
|
||||||
|
"const roomodesDest = path.join(targetDir, '.roomodes');"
|
||||||
|
);
|
||||||
|
expect(rooProfileContent).toContain(
|
||||||
|
"path.resolve(__dirname, '../../assets/roocode')"
|
||||||
|
); // sourceDir for roomodesSrc
|
||||||
});
|
});
|
||||||
|
|
||||||
test('roo.js profile copies mode-specific rule files via onAddBrandRules', () => {
|
test('roo.js profile copies mode-specific rule files via onAddBrandRules', () => {
|
||||||
@@ -47,11 +58,17 @@ describe('Roo Profile Initialization Functionality', () => {
|
|||||||
|
|
||||||
// Check for the specific mode rule file copy logic
|
// Check for the specific mode rule file copy logic
|
||||||
expect(rooProfileContent).toContain('fs.copyFileSync(src, dest);');
|
expect(rooProfileContent).toContain('fs.copyFileSync(src, dest);');
|
||||||
|
|
||||||
// Check source path construction for mode rules
|
// Check source path construction for mode rules
|
||||||
expect(rooProfileContent).toContain("const src = path.join(rooModesDir, `rules-${mode}`, `${mode}-rules`);");
|
expect(rooProfileContent).toContain(
|
||||||
|
'const src = path.join(rooModesDir, `rules-${mode}`, `${mode}-rules`);'
|
||||||
|
);
|
||||||
// Check destination path construction for mode rules
|
// Check destination path construction for mode rules
|
||||||
expect(rooProfileContent).toContain("const dest = path.join(targetDir, '.roo', `rules-${mode}`, `${mode}-rules`);");
|
expect(rooProfileContent).toContain(
|
||||||
expect(rooProfileContent).toContain("const rooModesDir = path.join(sourceDir, '.roo');"); // part of src path
|
"const dest = path.join(targetDir, '.roo', `rules-${mode}`, `${mode}-rules`);"
|
||||||
|
);
|
||||||
|
expect(rooProfileContent).toContain(
|
||||||
|
"const rooModesDir = path.join(sourceDir, '.roo');"
|
||||||
|
); // part of src path
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,41 +2,41 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
describe('Rules Files Inclusion in Package', () => {
|
describe('Rules Files Inclusion in Package', () => {
|
||||||
test('package.json includes assets/** in the "files" array for rules files', () => {
|
test('package.json includes assets/** in the "files" array for rules files', () => {
|
||||||
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
||||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||||
expect(packageJson.files).toContain('assets/**');
|
expect(packageJson.files).toContain('assets/**');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('all rules files exist in assets/rules directory', () => {
|
test('all rules files exist in assets/rules directory', () => {
|
||||||
const rulesDir = path.join(process.cwd(), 'assets', 'rules');
|
const rulesDir = path.join(process.cwd(), 'assets', 'rules');
|
||||||
const expectedFiles = [
|
const expectedFiles = [
|
||||||
'ai_providers.mdc',
|
'ai_providers.mdc',
|
||||||
'ai_services.mdc',
|
'ai_services.mdc',
|
||||||
'architecture.mdc',
|
'architecture.mdc',
|
||||||
'changeset.mdc',
|
'changeset.mdc',
|
||||||
'commands.mdc',
|
'commands.mdc',
|
||||||
'cursor_rules.mdc',
|
'cursor_rules.mdc',
|
||||||
'dependencies.mdc',
|
'dependencies.mdc',
|
||||||
'dev_workflow.mdc',
|
'dev_workflow.mdc',
|
||||||
'glossary.mdc',
|
'glossary.mdc',
|
||||||
'mcp.mdc',
|
'mcp.mdc',
|
||||||
'new_features.mdc',
|
'new_features.mdc',
|
||||||
'self_improve.mdc',
|
'self_improve.mdc',
|
||||||
'taskmaster.mdc',
|
'taskmaster.mdc',
|
||||||
'tasks.mdc',
|
'tasks.mdc',
|
||||||
'tests.mdc',
|
'tests.mdc',
|
||||||
'ui.mdc',
|
'ui.mdc',
|
||||||
'utilities.mdc',
|
'utilities.mdc'
|
||||||
];
|
];
|
||||||
for (const file of expectedFiles) {
|
for (const file of expectedFiles) {
|
||||||
expect(fs.existsSync(path.join(rulesDir, file))).toBe(true);
|
expect(fs.existsSync(path.join(rulesDir, file))).toBe(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('assets/rules directory is not empty', () => {
|
test('assets/rules directory is not empty', () => {
|
||||||
const rulesDir = path.join(process.cwd(), 'assets', 'rules');
|
const rulesDir = path.join(process.cwd(), 'assets', 'rules');
|
||||||
const files = fs.readdirSync(rulesDir).filter(f => !f.startsWith('.'));
|
const files = fs.readdirSync(rulesDir).filter((f) => !f.startsWith('.'));
|
||||||
expect(files.length).toBeGreaterThan(0);
|
expect(files.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,35 +2,42 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
describe('Windsurf Profile Initialization Functionality', () => {
|
describe('Windsurf Profile Initialization Functionality', () => {
|
||||||
let windsurfProfileContent;
|
let windsurfProfileContent;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
const windsurfJsPath = path.join(process.cwd(), 'scripts', 'profiles', 'windsurf.js');
|
const windsurfJsPath = path.join(
|
||||||
windsurfProfileContent = fs.readFileSync(windsurfJsPath, 'utf8');
|
process.cwd(),
|
||||||
});
|
'scripts',
|
||||||
|
'profiles',
|
||||||
|
'windsurf.js'
|
||||||
|
);
|
||||||
|
windsurfProfileContent = fs.readFileSync(windsurfJsPath, 'utf8');
|
||||||
|
});
|
||||||
|
|
||||||
test('windsurf.js exports correct brandName and rulesDir', () => {
|
test('windsurf.js exports correct brandName and rulesDir', () => {
|
||||||
expect(windsurfProfileContent).toContain("const brandName = 'Windsurf'");
|
expect(windsurfProfileContent).toContain("const brandName = 'Windsurf'");
|
||||||
expect(windsurfProfileContent).toContain("const rulesDir = '.windsurf/rules'");
|
expect(windsurfProfileContent).toContain(
|
||||||
});
|
"const rulesDir = '.windsurf/rules'"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('windsurf.js contains fileMap for .mdc to .md mapping', () => {
|
test('windsurf.js contains fileMap for .mdc to .md mapping', () => {
|
||||||
expect(windsurfProfileContent).toContain("fileMap = {");
|
expect(windsurfProfileContent).toContain('fileMap = {');
|
||||||
expect(windsurfProfileContent).toContain(".mdc'");
|
expect(windsurfProfileContent).toContain(".mdc'");
|
||||||
expect(windsurfProfileContent).toContain(".md'");
|
expect(windsurfProfileContent).toContain(".md'");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('windsurf.js contains tool renaming and extension logic', () => {
|
test('windsurf.js contains tool renaming and extension logic', () => {
|
||||||
expect(windsurfProfileContent).toContain("edit_file");
|
expect(windsurfProfileContent).toContain('edit_file');
|
||||||
expect(windsurfProfileContent).toContain("apply_diff");
|
expect(windsurfProfileContent).toContain('apply_diff');
|
||||||
expect(windsurfProfileContent).toContain("search tool");
|
expect(windsurfProfileContent).toContain('search tool');
|
||||||
expect(windsurfProfileContent).toContain("search_files tool");
|
expect(windsurfProfileContent).toContain('search_files tool');
|
||||||
expect(windsurfProfileContent).toContain(".mdc");
|
expect(windsurfProfileContent).toContain('.mdc');
|
||||||
expect(windsurfProfileContent).toContain(".md");
|
expect(windsurfProfileContent).toContain('.md');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('windsurf.js contains correct documentation URL transformation', () => {
|
test('windsurf.js contains correct documentation URL transformation', () => {
|
||||||
expect(windsurfProfileContent).toContain('docs.cursor.com');
|
expect(windsurfProfileContent).toContain('docs.cursor.com');
|
||||||
expect(windsurfProfileContent).toContain('docs.windsurf.com');
|
expect(windsurfProfileContent).toContain('docs.windsurf.com');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -59,7 +59,14 @@ describe('Cursor Integration', () => {
|
|||||||
fs.mkdirSync(path.join(tempDir, '.cursor', 'rules'), { recursive: true });
|
fs.mkdirSync(path.join(tempDir, '.cursor', 'rules'), { recursive: true });
|
||||||
|
|
||||||
// Create mode-specific rule directories
|
// Create mode-specific rule directories
|
||||||
const cursorModes = ['architect', 'ask', 'boomerang', 'code', 'debug', 'test'];
|
const cursorModes = [
|
||||||
|
'architect',
|
||||||
|
'ask',
|
||||||
|
'boomerang',
|
||||||
|
'code',
|
||||||
|
'debug',
|
||||||
|
'test'
|
||||||
|
];
|
||||||
for (const mode of cursorModes) {
|
for (const mode of cursorModes) {
|
||||||
fs.mkdirSync(path.join(tempDir, '.cursor', `rules-${mode}`), {
|
fs.mkdirSync(path.join(tempDir, '.cursor', `rules-${mode}`), {
|
||||||
recursive: true
|
recursive: true
|
||||||
@@ -71,7 +78,10 @@ describe('Cursor Integration', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy .cursormodes file
|
// Copy .cursormodes file
|
||||||
fs.writeFileSync(path.join(tempDir, '.cursormodes'), 'Cursormodes file content');
|
fs.writeFileSync(
|
||||||
|
path.join(tempDir, '.cursormodes'),
|
||||||
|
'Cursormodes file content'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
test('creates all required .cursor directories', () => {
|
test('creates all required .cursor directories', () => {
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import { convertRuleToBrandRule, convertAllRulesToBrandRules } from '../../scripts/modules/rule-transformer.js';
|
import {
|
||||||
|
convertRuleToBrandRule,
|
||||||
|
convertAllRulesToBrandRules
|
||||||
|
} from '../../scripts/modules/rule-transformer.js';
|
||||||
import * as cursorProfile from '../../scripts/profiles/cursor.js';
|
import * as cursorProfile from '../../scripts/profiles/cursor.js';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
@@ -113,7 +116,4 @@ This references [dev_workflow.mdc](mdc:.cursor/rules/dev_workflow.mdc) and
|
|||||||
expect(convertedContent).not.toContain('(mdc:.roo/rules/');
|
expect(convertedContent).not.toContain('(mdc:.roo/rules/');
|
||||||
expect(convertedContent).not.toContain('(mdc:.windsurf/rules/');
|
expect(convertedContent).not.toContain('(mdc:.windsurf/rules/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import { convertRuleToBrandRule, convertAllRulesToBrandRules } from '../../scripts/modules/rule-transformer.js';
|
import {
|
||||||
|
convertRuleToBrandRule,
|
||||||
|
convertAllRulesToBrandRules
|
||||||
|
} from '../../scripts/modules/rule-transformer.js';
|
||||||
import * as rooProfile from '../../scripts/profiles/roo.js';
|
import * as rooProfile from '../../scripts/profiles/roo.js';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
@@ -111,17 +114,17 @@ This references [dev_workflow.mdc](mdc:.cursor/rules/dev_workflow.mdc) and
|
|||||||
expect(convertedContent).not.toContain('(mdc:.cursor/rules/');
|
expect(convertedContent).not.toContain('(mdc:.cursor/rules/');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run post-processing when converting all rules for Roo', () => {
|
it('should run post-processing when converting all rules for Roo', () => {
|
||||||
// Simulate a rules directory with a .mdc file
|
// Simulate a rules directory with a .mdc file
|
||||||
const assetsRulesDir = path.join(testDir, 'assets', 'rules');
|
const assetsRulesDir = path.join(testDir, 'assets', 'rules');
|
||||||
fs.mkdirSync(assetsRulesDir, { recursive: true });
|
fs.mkdirSync(assetsRulesDir, { recursive: true });
|
||||||
const assetRule = path.join(assetsRulesDir, 'dev_workflow.mdc');
|
const assetRule = path.join(assetsRulesDir, 'dev_workflow.mdc');
|
||||||
fs.writeFileSync(assetRule, 'dummy');
|
fs.writeFileSync(assetRule, 'dummy');
|
||||||
// Should create .roo/rules and call post-processing
|
// Should create .roo/rules and call post-processing
|
||||||
convertAllRulesToBrandRules(testDir, rooProfile);
|
convertAllRulesToBrandRules(testDir, rooProfile);
|
||||||
// Check for post-processing artifacts, e.g., rules-* folders or extra files
|
// Check for post-processing artifacts, e.g., rules-* folders or extra files
|
||||||
const rooDir = path.join(testDir, '.roo');
|
const rooDir = path.join(testDir, '.roo');
|
||||||
const found = fs.readdirSync(rooDir).some(f => f.startsWith('rules-'));
|
const found = fs.readdirSync(rooDir).some((f) => f.startsWith('rules-'));
|
||||||
expect(found).toBe(true); // There should be at least one rules-* folder
|
expect(found).toBe(true); // There should be at least one rules-* folder
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -110,6 +110,4 @@ This references [dev_workflow.mdc](mdc:.cursor/rules/dev_workflow.mdc) and
|
|||||||
expect(convertedContent).toContain('(mdc:.windsurf/rules/taskmaster.md)');
|
expect(convertedContent).toContain('(mdc:.windsurf/rules/taskmaster.md)');
|
||||||
expect(convertedContent).not.toContain('(mdc:.cursor/rules/');
|
expect(convertedContent).not.toContain('(mdc:.cursor/rules/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -59,7 +59,14 @@ describe('Windsurf Integration', () => {
|
|||||||
fs.mkdirSync(path.join(tempDir, '.windsurf', 'rules'), { recursive: true });
|
fs.mkdirSync(path.join(tempDir, '.windsurf', 'rules'), { recursive: true });
|
||||||
|
|
||||||
// Create mode-specific rule directories
|
// Create mode-specific rule directories
|
||||||
const windsurfModes = ['architect', 'ask', 'boomerang', 'code', 'debug', 'test'];
|
const windsurfModes = [
|
||||||
|
'architect',
|
||||||
|
'ask',
|
||||||
|
'boomerang',
|
||||||
|
'code',
|
||||||
|
'debug',
|
||||||
|
'test'
|
||||||
|
];
|
||||||
for (const mode of windsurfModes) {
|
for (const mode of windsurfModes) {
|
||||||
fs.mkdirSync(path.join(tempDir, '.windsurf', `rules-${mode}`), {
|
fs.mkdirSync(path.join(tempDir, '.windsurf', `rules-${mode}`), {
|
||||||
recursive: true
|
recursive: true
|
||||||
@@ -71,7 +78,10 @@ describe('Windsurf Integration', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy .windsurfmodes file
|
// Copy .windsurfmodes file
|
||||||
fs.writeFileSync(path.join(tempDir, '.windsurfmodes'), 'Windsurfmodes file content');
|
fs.writeFileSync(
|
||||||
|
path.join(tempDir, '.windsurfmodes'),
|
||||||
|
'Windsurfmodes file content'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
test('creates all required .windsurf directories', () => {
|
test('creates all required .windsurf directories', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user