fix formatting
This commit is contained in:
@@ -19,8 +19,7 @@ import { RULES_PROFILES } from '../../../src/constants/profiles.js';
|
|||||||
export function registerRulesTool(server) {
|
export function registerRulesTool(server) {
|
||||||
server.addTool({
|
server.addTool({
|
||||||
name: 'rules',
|
name: 'rules',
|
||||||
description:
|
description: 'Add or remove rules profiles from the project.',
|
||||||
'Add or remove rules profiles from the project.',
|
|
||||||
parameters: z.object({
|
parameters: z.object({
|
||||||
action: z
|
action: z
|
||||||
.enum(['add', 'remove'])
|
.enum(['add', 'remove'])
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ export function setupMCPConfiguration(projectDir, mcpConfigPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create config directory if it doesn't exist
|
// Create config directory if it doesn't exist
|
||||||
if (!fs.existsSync(configDir)) {
|
if (!fs.existsSync(configDir)) {
|
||||||
fs.mkdirSync(configDir, { recursive: true });
|
fs.mkdirSync(configDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.existsSync(mcpPath)) {
|
if (fs.existsSync(mcpPath)) {
|
||||||
log(
|
log(
|
||||||
'info',
|
'info',
|
||||||
|
|||||||
@@ -203,7 +203,9 @@ export function convertRuleToProfileRule(sourcePath, targetPath, profile) {
|
|||||||
* Convert all Cursor rules to profile rules for a specific profile
|
* Convert all Cursor rules to profile rules for a specific profile
|
||||||
*/
|
*/
|
||||||
export function convertAllRulesToProfileRules(projectDir, profile) {
|
export function convertAllRulesToProfileRules(projectDir, profile) {
|
||||||
const sourceDir = fileURLToPath(new URL('../../assets/rules', import.meta.url));
|
const sourceDir = fileURLToPath(
|
||||||
|
new URL('../../assets/rules', import.meta.url)
|
||||||
|
);
|
||||||
const targetDir = path.join(projectDir, profile.rulesDir);
|
const targetDir = path.join(projectDir, profile.rulesDir);
|
||||||
|
|
||||||
// Ensure target directory exists
|
// Ensure target directory exists
|
||||||
@@ -213,10 +215,7 @@ export function convertAllRulesToProfileRules(projectDir, profile) {
|
|||||||
|
|
||||||
// Setup MCP configuration if enabled
|
// Setup MCP configuration if enabled
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
setupMCPConfiguration(
|
setupMCPConfiguration(projectDir, profile.mcpConfigPath);
|
||||||
projectDir,
|
|
||||||
profile.mcpConfigPath
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let success = 0;
|
let success = 0;
|
||||||
@@ -228,10 +227,13 @@ export function convertAllRulesToProfileRules(projectDir, profile) {
|
|||||||
for (const sourceFile of sourceFiles) {
|
for (const sourceFile of sourceFiles) {
|
||||||
try {
|
try {
|
||||||
const sourcePath = path.join(sourceDir, sourceFile);
|
const sourcePath = path.join(sourceDir, sourceFile);
|
||||||
|
|
||||||
// Check if source file exists
|
// Check if source file exists
|
||||||
if (!fs.existsSync(sourcePath)) {
|
if (!fs.existsSync(sourcePath)) {
|
||||||
log('warn', `[Rule Transformer] Source file not found: ${sourceFile}, skipping`);
|
log(
|
||||||
|
'warn',
|
||||||
|
`[Rule Transformer] Source file not found: ${sourceFile}, skipping`
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,24 +31,29 @@ describe('MCP Configuration Validation', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.entries(expectedMcpConfigurations).forEach(([profileName, expected]) => {
|
Object.entries(expectedMcpConfigurations).forEach(
|
||||||
test(`should have correct MCP configuration for ${profileName} profile`, () => {
|
([profileName, expected]) => {
|
||||||
const profile = getRulesProfile(profileName);
|
test(`should have correct MCP configuration for ${profileName} profile`, () => {
|
||||||
expect(profile).toBeDefined();
|
const profile = getRulesProfile(profileName);
|
||||||
expect(profile.mcpConfig).toBe(expected.shouldHaveMcp);
|
expect(profile).toBeDefined();
|
||||||
expect(profile.profileDir).toBe(expected.expectedDir);
|
expect(profile.mcpConfig).toBe(expected.shouldHaveMcp);
|
||||||
expect(profile.mcpConfigName).toBe(expected.expectedConfigName);
|
expect(profile.profileDir).toBe(expected.expectedDir);
|
||||||
expect(profile.mcpConfigPath).toBe(expected.expectedPath);
|
expect(profile.mcpConfigName).toBe(expected.expectedConfigName);
|
||||||
});
|
expect(profile.mcpConfigPath).toBe(expected.expectedPath);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('MCP Configuration Path Consistency', () => {
|
describe('MCP Configuration Path Consistency', () => {
|
||||||
test('should ensure all profiles have consistent mcpConfigPath construction', () => {
|
test('should ensure all profiles have consistent mcpConfigPath construction', () => {
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
const expectedPath = path.join(profile.profileDir, profile.mcpConfigName);
|
const expectedPath = path.join(
|
||||||
|
profile.profileDir,
|
||||||
|
profile.mcpConfigName
|
||||||
|
);
|
||||||
expect(profile.mcpConfigPath).toBe(expectedPath);
|
expect(profile.mcpConfigPath).toBe(expectedPath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -56,7 +61,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
|
|
||||||
test('should ensure no two profiles have the same MCP config path', () => {
|
test('should ensure no two profiles have the same MCP config path', () => {
|
||||||
const mcpPaths = new Set();
|
const mcpPaths = new Set();
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
expect(mcpPaths.has(profile.mcpConfigPath)).toBe(false);
|
expect(mcpPaths.has(profile.mcpConfigPath)).toBe(false);
|
||||||
@@ -66,7 +71,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should ensure all MCP-enabled profiles use proper directory structure', () => {
|
test('should ensure all MCP-enabled profiles use proper directory structure', () => {
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
expect(profile.mcpConfigPath).toMatch(/^\.[\w-]+\/[\w_.]+$/);
|
expect(profile.mcpConfigPath).toMatch(/^\.[\w-]+\/[\w_.]+$/);
|
||||||
@@ -75,7 +80,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should ensure all profiles have required MCP properties', () => {
|
test('should ensure all profiles have required MCP properties', () => {
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
expect(profile).toHaveProperty('mcpConfig');
|
expect(profile).toHaveProperty('mcpConfig');
|
||||||
expect(profile).toHaveProperty('profileDir');
|
expect(profile).toHaveProperty('profileDir');
|
||||||
@@ -88,7 +93,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
describe('MCP Configuration File Names', () => {
|
describe('MCP Configuration File Names', () => {
|
||||||
test('should use standard mcp.json for MCP-enabled profiles', () => {
|
test('should use standard mcp.json for MCP-enabled profiles', () => {
|
||||||
const standardMcpProfiles = ['cursor', 'windsurf', 'roo'];
|
const standardMcpProfiles = ['cursor', 'windsurf', 'roo'];
|
||||||
standardMcpProfiles.forEach(profileName => {
|
standardMcpProfiles.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
expect(profile.mcpConfigName).toBe('mcp.json');
|
expect(profile.mcpConfigName).toBe('mcp.json');
|
||||||
});
|
});
|
||||||
@@ -103,7 +108,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
describe('Profile Directory Structure', () => {
|
describe('Profile Directory Structure', () => {
|
||||||
test('should ensure each profile has a unique directory', () => {
|
test('should ensure each profile has a unique directory', () => {
|
||||||
const profileDirs = new Set();
|
const profileDirs = new Set();
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
expect(profileDirs.has(profile.profileDir)).toBe(false);
|
expect(profileDirs.has(profile.profileDir)).toBe(false);
|
||||||
profileDirs.add(profile.profileDir);
|
profileDirs.add(profile.profileDir);
|
||||||
@@ -111,7 +116,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should ensure profile directories follow expected naming convention', () => {
|
test('should ensure profile directories follow expected naming convention', () => {
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
expect(profile.profileDir).toMatch(/^\.[\w-]+$/);
|
expect(profile.profileDir).toMatch(/^\.[\w-]+$/);
|
||||||
});
|
});
|
||||||
@@ -120,11 +125,11 @@ describe('MCP Configuration Validation', () => {
|
|||||||
|
|
||||||
describe('MCP Configuration Creation Logic', () => {
|
describe('MCP Configuration Creation Logic', () => {
|
||||||
test('should indicate which profiles require MCP configuration creation', () => {
|
test('should indicate which profiles require MCP configuration creation', () => {
|
||||||
const mcpEnabledProfiles = RULES_PROFILES.filter(profileName => {
|
const mcpEnabledProfiles = RULES_PROFILES.filter((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
return profile.mcpConfig !== false;
|
return profile.mcpConfig !== false;
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(mcpEnabledProfiles).toContain('cursor');
|
expect(mcpEnabledProfiles).toContain('cursor');
|
||||||
expect(mcpEnabledProfiles).toContain('windsurf');
|
expect(mcpEnabledProfiles).toContain('windsurf');
|
||||||
expect(mcpEnabledProfiles).toContain('roo');
|
expect(mcpEnabledProfiles).toContain('roo');
|
||||||
@@ -132,7 +137,7 @@ describe('MCP Configuration Validation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should provide all necessary information for MCP config creation', () => {
|
test('should provide all necessary information for MCP config creation', () => {
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
expect(profile.mcpConfigPath).toBeDefined();
|
expect(profile.mcpConfigPath).toBeDefined();
|
||||||
@@ -147,13 +152,13 @@ describe('MCP Configuration Validation', () => {
|
|||||||
test('should verify that rule transformer functions use mcpConfigPath correctly', () => {
|
test('should verify that rule transformer functions use mcpConfigPath correctly', () => {
|
||||||
// This test verifies that the mcpConfigPath property exists and is properly formatted
|
// This test verifies that the mcpConfigPath property exists and is properly formatted
|
||||||
// for use with the setupMCPConfiguration function
|
// for use with the setupMCPConfiguration function
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
// Verify the path is properly formatted for path.join usage
|
// Verify the path is properly formatted for path.join usage
|
||||||
expect(profile.mcpConfigPath.startsWith('/')).toBe(false);
|
expect(profile.mcpConfigPath.startsWith('/')).toBe(false);
|
||||||
expect(profile.mcpConfigPath).toContain('/');
|
expect(profile.mcpConfigPath).toContain('/');
|
||||||
|
|
||||||
// Verify it matches the expected pattern: profileDir/configName
|
// Verify it matches the expected pattern: profileDir/configName
|
||||||
const expectedPath = `${profile.profileDir}/${profile.mcpConfigName}`;
|
const expectedPath = `${profile.profileDir}/${profile.mcpConfigName}`;
|
||||||
expect(profile.mcpConfigPath).toBe(expectedPath);
|
expect(profile.mcpConfigPath).toBe(expectedPath);
|
||||||
@@ -162,13 +167,13 @@ describe('MCP Configuration Validation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should verify that mcpConfigPath is properly constructed for path.join usage', () => {
|
test('should verify that mcpConfigPath is properly constructed for path.join usage', () => {
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
// Test that path.join works correctly with the mcpConfigPath
|
// Test that path.join works correctly with the mcpConfigPath
|
||||||
const testProjectRoot = '/test/project';
|
const testProjectRoot = '/test/project';
|
||||||
const fullPath = path.join(testProjectRoot, profile.mcpConfigPath);
|
const fullPath = path.join(testProjectRoot, profile.mcpConfigPath);
|
||||||
|
|
||||||
// Should result in a proper absolute path
|
// Should result in a proper absolute path
|
||||||
expect(fullPath).toBe(`${testProjectRoot}/${profile.mcpConfigPath}`);
|
expect(fullPath).toBe(`${testProjectRoot}/${profile.mcpConfigPath}`);
|
||||||
expect(fullPath).toContain(profile.profileDir);
|
expect(fullPath).toContain(profile.profileDir);
|
||||||
@@ -181,14 +186,14 @@ describe('MCP Configuration Validation', () => {
|
|||||||
describe('MCP Configuration Function Integration', () => {
|
describe('MCP Configuration Function Integration', () => {
|
||||||
test('should verify that setupMCPConfiguration receives the correct mcpConfigPath parameter', () => {
|
test('should verify that setupMCPConfiguration receives the correct mcpConfigPath parameter', () => {
|
||||||
// This test verifies the integration between rule transformer and mcp-utils
|
// This test verifies the integration between rule transformer and mcp-utils
|
||||||
RULES_PROFILES.forEach(profileName => {
|
RULES_PROFILES.forEach((profileName) => {
|
||||||
const profile = getRulesProfile(profileName);
|
const profile = getRulesProfile(profileName);
|
||||||
if (profile.mcpConfig !== false) {
|
if (profile.mcpConfig !== false) {
|
||||||
// Verify that the mcpConfigPath can be used directly with setupMCPConfiguration
|
// Verify that the mcpConfigPath can be used directly with setupMCPConfiguration
|
||||||
// The function signature is: setupMCPConfiguration(projectDir, mcpConfigPath)
|
// The function signature is: setupMCPConfiguration(projectDir, mcpConfigPath)
|
||||||
expect(profile.mcpConfigPath).toBeDefined();
|
expect(profile.mcpConfigPath).toBeDefined();
|
||||||
expect(typeof profile.mcpConfigPath).toBe('string');
|
expect(typeof profile.mcpConfigPath).toBe('string');
|
||||||
|
|
||||||
// Verify the path structure is correct for the new function signature
|
// Verify the path structure is correct for the new function signature
|
||||||
const parts = profile.mcpConfigPath.split('/');
|
const parts = profile.mcpConfigPath.split('/');
|
||||||
expect(parts).toHaveLength(2); // Should be profileDir/configName
|
expect(parts).toHaveLength(2); // Should be profileDir/configName
|
||||||
@@ -198,4 +203,4 @@ describe('MCP Configuration Validation', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ describe('Rule Transformer - General', () => {
|
|||||||
// Ensure RULES_PROFILES is properly defined and contains expected profiles
|
// Ensure RULES_PROFILES is properly defined and contains expected profiles
|
||||||
expect(Array.isArray(RULES_PROFILES)).toBe(true);
|
expect(Array.isArray(RULES_PROFILES)).toBe(true);
|
||||||
expect(RULES_PROFILES.length).toBeGreaterThan(0);
|
expect(RULES_PROFILES.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
// Verify expected profiles are present
|
// Verify expected profiles are present
|
||||||
const expectedProfiles = ['cline', 'cursor', 'roo', 'windsurf'];
|
const expectedProfiles = ['cline', 'cursor', 'roo', 'windsurf'];
|
||||||
expectedProfiles.forEach(profile => {
|
expectedProfiles.forEach((profile) => {
|
||||||
expect(RULES_PROFILES).toContain(profile);
|
expect(RULES_PROFILES).toContain(profile);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -82,8 +82,13 @@ describe('Rule Transformer - General', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have valid fileMap with required files for each profile', () => {
|
it('should have valid fileMap with required files for each profile', () => {
|
||||||
const expectedFiles = ['cursor_rules.mdc', 'dev_workflow.mdc', 'self_improve.mdc', 'taskmaster.mdc'];
|
const expectedFiles = [
|
||||||
|
'cursor_rules.mdc',
|
||||||
|
'dev_workflow.mdc',
|
||||||
|
'self_improve.mdc',
|
||||||
|
'taskmaster.mdc'
|
||||||
|
];
|
||||||
|
|
||||||
RULES_PROFILES.forEach((profile) => {
|
RULES_PROFILES.forEach((profile) => {
|
||||||
const profileConfig = getRulesProfile(profile);
|
const profileConfig = getRulesProfile(profile);
|
||||||
|
|
||||||
@@ -97,7 +102,7 @@ describe('Rule Transformer - General', () => {
|
|||||||
expect(fileMapKeys.length).toBeGreaterThan(0);
|
expect(fileMapKeys.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
// Check that all expected source files are defined in fileMap
|
// Check that all expected source files are defined in fileMap
|
||||||
expectedFiles.forEach(expectedFile => {
|
expectedFiles.forEach((expectedFile) => {
|
||||||
expect(fileMapKeys).toContain(expectedFile);
|
expect(fileMapKeys).toContain(expectedFile);
|
||||||
expect(typeof profileConfig.fileMap[expectedFile]).toBe('string');
|
expect(typeof profileConfig.fileMap[expectedFile]).toBe('string');
|
||||||
expect(profileConfig.fileMap[expectedFile].length).toBeGreaterThan(0);
|
expect(profileConfig.fileMap[expectedFile].length).toBeGreaterThan(0);
|
||||||
@@ -171,12 +176,16 @@ describe('Rule Transformer - General', () => {
|
|||||||
|
|
||||||
// The mcpConfigPath should start with the profileDir
|
// The mcpConfigPath should start with the profileDir
|
||||||
expect(profileConfig.mcpConfigPath).toMatch(
|
expect(profileConfig.mcpConfigPath).toMatch(
|
||||||
new RegExp(`^${profileConfig.profileDir.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/`)
|
new RegExp(
|
||||||
|
`^${profileConfig.profileDir.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/`
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// The mcpConfigPath should end with the mcpConfigName
|
// The mcpConfigPath should end with the mcpConfigName
|
||||||
expect(profileConfig.mcpConfigPath).toMatch(
|
expect(profileConfig.mcpConfigPath).toMatch(
|
||||||
new RegExp(`${profileConfig.mcpConfigName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`)
|
new RegExp(
|
||||||
|
`${profileConfig.mcpConfigName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user