This is page 3 of 3. Use http://codebase.md/thealchemist6/codecompass-mcp?page={x} to view the full context.
# Directory Structure
```
├── .dockerignore
├── .env.example
├── .gitignore
├── config
│ ├── .eslintrc.json
│ ├── .prettierignore
│ ├── .prettierrc
│ ├── README.md
│ └── tsconfig.dev.json
├── CONTRIBUTING.md
├── docker
│ ├── docker-compose.dev.yml
│ ├── docker-compose.yml
│ ├── Dockerfile.dev
│ └── README.md
├── Dockerfile
├── docs
│ ├── API.md
│ ├── DOCKER.md
│ ├── legacy-tools
│ │ ├── chat.ts
│ │ ├── extract.ts
│ │ ├── files.ts
│ │ ├── README.md
│ │ ├── refactor.ts
│ │ ├── repository.ts
│ │ ├── template.ts
│ │ └── transform.ts
│ ├── MONITORING.md
│ ├── README.md
│ └── SETUP.md
├── examples
│ ├── basic-usage.js
│ └── basic-usage.md
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│ ├── docker-build.sh
│ ├── docker-logs.sh
│ ├── docker-run.sh
│ ├── monitor.js
│ └── start-mcp.sh
├── src
│ ├── index.ts
│ ├── services
│ │ ├── github.ts
│ │ ├── openai.ts
│ │ └── refactor.ts
│ ├── tools
│ │ └── consolidated.ts
│ ├── types
│ │ ├── index.ts
│ │ └── responses.ts
│ └── utils
│ ├── config.ts
│ ├── file-processor.ts
│ ├── logger.ts
│ ├── monitoring.ts
│ ├── security.ts
│ └── validation.ts
├── tests
│ └── verify-installation.sh
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/src/services/refactor.ts:
--------------------------------------------------------------------------------
```typescript
import { RefactorResult, RefactorOptions, ExtractableComponent, ReusableUtility, GeneratedTemplate, ComponentLibrary } from '../types/index.js';
import { GitHubService } from './github.js';
export class RefactorService {
private githubService: GitHubService;
constructor() {
this.githubService = new GitHubService();
}
async extractFunctions(url: string, filePath: string, functionNames?: string[]): Promise<{ functions: any[], dependencies: string[] }> {
const content = await this.githubService.getFileContent(url, filePath);
const functions = this.parseFunctions(content, functionNames);
const dependencies = this.extractDependencies(content);
return {
functions,
dependencies,
};
}
async analyzeDependencies(url: string): Promise<any> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const dependencies = await this.githubService.analyzeDependencies(url);
return {
external: dependencies,
internal: this.analyzeInternalDependencies(repositoryInfo.keyFiles),
graph: this.buildDependencyGraph(repositoryInfo.keyFiles),
};
}
async refactorForProject(url: string, targetProject: any, refactorOptions: RefactorOptions): Promise<RefactorResult> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const keyFiles = repositoryInfo.keyFiles;
let refactoredCode = '';
const changes: any[] = [];
const warnings: string[] = [];
const dependencies: string[] = [];
const instructions: string[] = [];
// Process each file
for (const [filePath, content] of Object.entries(keyFiles)) {
let processedContent = content;
// Apply naming convention transformation
if (refactorOptions.namingConvention) {
const result = await this.transformNamingConvention(
processedContent,
refactorOptions.namingConvention
);
processedContent = result.code;
changes.push(...result.changes);
}
// Modernize code if requested
if (refactorOptions.modernizationLevel && refactorOptions.modernizationLevel !== 'minimal') {
const result = await this.modernizeCode(
processedContent,
this.detectLanguage(filePath),
refactorOptions.modernizationLevel
);
processedContent = result.refactoredCode;
changes.push(...result.changes);
}
// Remove project-specific coupling
if (refactorOptions.removeProjectSpecific) {
const result = await this.removeProjectCoupling(
processedContent,
this.detectLanguage(filePath)
);
processedContent = result.refactoredCode;
changes.push(...result.changes);
}
// Add TypeScript if requested
if (refactorOptions.addTypeScript && this.isJavaScriptFile(filePath)) {
const result = await this.addTypeScript(processedContent, filePath);
processedContent = result.code;
changes.push(...result.changes);
}
refactoredCode += `\n\n// === ${filePath} ===\n${processedContent}`;
}
// Generate integration instructions
instructions.push('1. Review the refactored code for compatibility with your project');
instructions.push('2. Update import paths to match your project structure');
instructions.push('3. Install any required dependencies');
instructions.push('4. Run tests to ensure functionality is preserved');
if (refactorOptions.extractComponents) {
instructions.push('5. Consider extracting reusable components into separate files');
}
return {
originalCode: Object.values(keyFiles).join('\n\n'),
refactoredCode,
changes,
warnings,
dependencies,
instructions,
};
}
async extractReusableComponents(url: string, componentTypes?: string[]): Promise<ExtractableComponent[]> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const components: ExtractableComponent[] = [];
for (const [filePath, content] of Object.entries(repositoryInfo.keyFiles)) {
if (this.isComponentFile(filePath, content)) {
const component = await this.analyzeComponent(filePath, content);
if (!componentTypes || componentTypes.includes(component.type)) {
components.push(component);
}
}
}
return components.sort((a, b) => b.reusabilityScore - a.reusabilityScore);
}
async adaptDependencies(code: string, dependencyMappings: Record<string, string>): Promise<string> {
let adaptedCode = code;
// Replace import statements
for (const [oldDep, newDep] of Object.entries(dependencyMappings)) {
const importRegex = new RegExp(`from\\s+['"]${oldDep}['"]`, 'g');
adaptedCode = adaptedCode.replace(importRegex, `from '${newDep}'`);
const requireRegex = new RegExp(`require\\(['"]${oldDep}['"]\\)`, 'g');
adaptedCode = adaptedCode.replace(requireRegex, `require('${newDep}')`);
}
return adaptedCode;
}
async transformNamingConventions(code: string, fromConvention: string, toConvention: string): Promise<string> {
const { code: transformedCode } = await this.transformNamingConvention(code, {
variables: toConvention as any,
functions: toConvention as any,
classes: toConvention as any,
files: toConvention as any,
folders: toConvention as any,
});
return transformedCode;
}
async modernizeCode(code: string, language: string, targetVersion?: string): Promise<RefactorResult> {
const changes: any[] = [];
let modernizedCode = code;
if (language === 'javascript' || language === 'typescript') {
// Convert var to const/let
const varMatches = code.match(/var\s+(\w+)/g);
if (varMatches) {
modernizedCode = modernizedCode.replace(/var\s+(\w+)/g, 'const $1');
changes.push({
type: 'modify',
file: 'current',
description: 'Replaced var with const/let',
oldValue: 'var',
newValue: 'const/let',
});
}
// Convert function declarations to arrow functions where appropriate
const functionRegex = /function\s+(\w+)\s*\(([^)]*)\)\s*\{/g;
modernizedCode = modernizedCode.replace(functionRegex, 'const $1 = ($2) => {');
// Use template literals instead of string concatenation
const concatRegex = /['"]([^'"]*)['"]\s*\+\s*(\w+)\s*\+\s*['"]([^'"]*)['"]/g;
modernizedCode = modernizedCode.replace(concatRegex, '`$1${$2}$3`');
// Convert promises to async/await if possible
if (modernizedCode.includes('.then(') && !modernizedCode.includes('async ')) {
changes.push({
type: 'modify',
file: 'current',
description: 'Consider converting promises to async/await',
});
}
}
return {
originalCode: code,
refactoredCode: modernizedCode,
changes,
warnings: [],
dependencies: [],
instructions: ['Review modernized code for compatibility'],
};
}
async removeProjectCoupling(code: string, language: string): Promise<RefactorResult> {
let decoupledCode = code;
const changes: any[] = [];
// Remove hard-coded URLs and endpoints
const urlRegex = /https?:\/\/[^\s'"]+/g;
const urls = code.match(urlRegex);
if (urls) {
for (const url of urls) {
decoupledCode = decoupledCode.replace(url, '${API_BASE_URL}/endpoint');
changes.push({
type: 'modify',
file: 'current',
description: `Parameterized hard-coded URL: ${url}`,
oldValue: url,
newValue: '${API_BASE_URL}/endpoint',
});
}
}
// Remove environment-specific imports
const envImports = [
'process.env',
'window.',
'document.',
'localStorage.',
'sessionStorage.',
];
for (const envImport of envImports) {
if (decoupledCode.includes(envImport)) {
changes.push({
type: 'modify',
file: 'current',
description: `Environment-specific code found: ${envImport}`,
});
}
}
// Replace hard-coded values with configuration
const configValues = this.extractConfigurableValues(code);
for (const value of configValues) {
decoupledCode = decoupledCode.replace(value.pattern, value.replacement);
changes.push({
type: 'modify',
file: 'current',
description: `Made configurable: ${value.description}`,
oldValue: value.pattern,
newValue: value.replacement,
});
}
return {
originalCode: code,
refactoredCode: decoupledCode,
changes,
warnings: [],
dependencies: [],
instructions: [
'Create a configuration file for parameterized values',
'Set up environment-specific configuration',
'Test with different configurations',
],
};
}
async generateBoilerplate(url: string, templateType: string, options: any): Promise<GeneratedTemplate> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const analysis = await this.githubService.analyzeRepository(url);
const template: GeneratedTemplate = {
name: options.name || `${repositoryInfo.name}-template`,
description: options.description || `Template based on ${repositoryInfo.name}`,
files: [],
dependencies: [],
scripts: {},
instructions: [],
};
// Generate package.json
const packageJson = await this.generatePackageJson(repositoryInfo, options);
template.files.push({
path: 'package.json',
content: JSON.stringify(packageJson, null, 2),
type: 'config',
});
// Generate main files based on template type
switch (templateType) {
case 'starter':
template.files.push(...await this.generateStarterFiles(repositoryInfo, options));
break;
case 'component-library':
template.files.push(...await this.generateComponentLibraryFiles(repositoryInfo, options));
break;
case 'microservice':
template.files.push(...await this.generateMicroserviceFiles(repositoryInfo, options));
break;
}
// Generate configuration files
if (options.includeConfig) {
template.files.push(...await this.generateConfigFiles(repositoryInfo, options));
}
// Generate test files
if (options.includeTests) {
template.files.push(...await this.generateTestFiles(repositoryInfo, options));
}
// Generate documentation
if (options.includeDocs) {
template.files.push(...await this.generateDocumentationFiles(repositoryInfo, options));
}
return template;
}
async createComponentLibrary(url: string, componentPaths?: string[]): Promise<ComponentLibrary> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const components = await this.extractReusableComponents(url, ['ui-components']);
const library: ComponentLibrary = {
name: `${repositoryInfo.name}-components`,
description: `Component library extracted from ${repositoryInfo.name}`,
components: [],
utilities: [],
types: [],
styles: [],
documentation: '',
packageJson: {},
};
// Process components
for (const component of components) {
if (!componentPaths || componentPaths.includes(component.path)) {
const libraryComponent = await this.convertToLibraryComponent(component);
library.components.push(libraryComponent);
}
}
// Extract utilities
const utilities = await this.extractReusableUtilities(url);
library.utilities = utilities.map(util => ({
...util,
documentation: util.description,
functions: util.functions.map(func => ({
name: func,
parameters: [],
returnType: 'any',
description: 'Function extracted from code',
examples: []
}))
}));
// Generate package.json for the library
library.packageJson = await this.generateLibraryPackageJson(repositoryInfo);
return library;
}
async scaffoldProjectStructure(url: string, projectType: string): Promise<any> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const analysis = await this.githubService.analyzeRepository(url);
const structure = {
name: `${repositoryInfo.name}-scaffold`,
type: projectType,
folders: this.generateFolderStructure(projectType, analysis),
files: this.generateScaffoldFiles(projectType, repositoryInfo),
scripts: this.generateScripts(projectType, repositoryInfo),
dependencies: this.extractRelevantDependencies(analysis.dependencies),
};
return structure;
}
// Helper methods
private parseFunctions(content: string, functionNames?: string[]): any[] {
const functions: any[] = [];
const functionRegex = /(?:function\s+(\w+)|const\s+(\w+)\s*=\s*(?:async\s+)?(?:\([^)]*\)\s*=>|\([^)]*\)\s*\{|function))/g;
let match;
while ((match = functionRegex.exec(content)) !== null) {
const functionName = match[1] || match[2];
if (functionName && (!functionNames || functionNames.includes(functionName))) {
const functionInfo = this.extractFunctionInfo(content, functionName, match.index);
functions.push(functionInfo);
}
}
return functions;
}
private extractFunctionInfo(content: string, name: string, startIndex: number): any {
// Find function body
const lines = content.split('\n');
let currentLine = 0;
let currentIndex = 0;
while (currentIndex < startIndex) {
currentIndex = content.indexOf('\n', currentIndex) + 1;
currentLine++;
}
// Extract function signature and body
const functionStart = content.indexOf('{', startIndex);
const functionEnd = this.findMatchingBrace(content, functionStart);
return {
name,
signature: content.substring(startIndex, functionStart).trim(),
body: content.substring(functionStart + 1, functionEnd).trim(),
startLine: currentLine,
endLine: currentLine + content.substring(functionStart, functionEnd).split('\n').length,
};
}
private findMatchingBrace(content: string, start: number): number {
let braceCount = 1;
let index = start + 1;
while (index < content.length && braceCount > 0) {
if (content[index] === '{') braceCount++;
else if (content[index] === '}') braceCount--;
index++;
}
return index - 1;
}
private extractDependencies(content: string): string[] {
const dependencies: string[] = [];
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
let match;
while ((match = importRegex.exec(content)) !== null) {
dependencies.push(match[1]);
}
while ((match = requireRegex.exec(content)) !== null) {
dependencies.push(match[1]);
}
return [...new Set(dependencies)];
}
private analyzeInternalDependencies(keyFiles: Record<string, string>): any {
const dependencies: Record<string, string[]> = {};
for (const [filePath, content] of Object.entries(keyFiles)) {
const fileDeps = this.extractDependencies(content);
dependencies[filePath] = fileDeps.filter(dep => dep.startsWith('.'));
}
return dependencies;
}
private buildDependencyGraph(keyFiles: Record<string, string>): any {
const graph: Record<string, string[]> = {};
const internalDeps = this.analyzeInternalDependencies(keyFiles);
for (const [file, deps] of Object.entries(internalDeps)) {
graph[file] = deps as string[];
}
return graph;
}
private async transformNamingConvention(code: string, convention: any): Promise<{ code: string; changes: any[] }> {
const changes: any[] = [];
let transformedCode = code;
// Variable naming
const variableRegex = /(?:let|const|var)\s+(\w+)/g;
transformedCode = transformedCode.replace(variableRegex, (match, varName) => {
const newName = this.convertNamingConvention(varName, convention.variables);
if (newName !== varName) {
changes.push({
type: 'modify',
description: `Renamed variable ${varName} to ${newName}`,
oldValue: varName,
newValue: newName,
});
}
return match.replace(varName, newName);
});
// Function naming
const functionRegex = /function\s+(\w+)/g;
transformedCode = transformedCode.replace(functionRegex, (match, funcName) => {
const newName = this.convertNamingConvention(funcName, convention.functions);
if (newName !== funcName) {
changes.push({
type: 'modify',
description: `Renamed function ${funcName} to ${newName}`,
oldValue: funcName,
newValue: newName,
});
}
return match.replace(funcName, newName);
});
return { code: transformedCode, changes };
}
private convertNamingConvention(name: string, targetConvention: string): string {
switch (targetConvention) {
case 'camelCase':
return name.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
case 'snake_case':
return name.replace(/([A-Z])/g, '_$1').toLowerCase();
case 'kebab-case':
return name.replace(/([A-Z])/g, '-$1').toLowerCase();
case 'PascalCase':
return name.charAt(0).toUpperCase() + name.slice(1);
default:
return name;
}
}
private detectLanguage(filePath: string): string {
const ext = filePath.split('.').pop()?.toLowerCase();
switch (ext) {
case 'js':
case 'jsx':
return 'javascript';
case 'ts':
case 'tsx':
return 'typescript';
case 'py':
return 'python';
case 'java':
return 'java';
case 'cpp':
case 'cc':
case 'c':
return 'cpp';
case 'go':
return 'go';
case 'rs':
return 'rust';
default:
return 'unknown';
}
}
private isJavaScriptFile(filePath: string): boolean {
return /\.(js|jsx)$/.test(filePath);
}
private async addTypeScript(code: string, filePath: string): Promise<{ code: string; changes: any[] }> {
const changes: any[] = [];
let tsCode = code;
// Add basic type annotations
tsCode = tsCode.replace(/function\s+(\w+)\s*\(([^)]*)\)/g, (match, funcName, params) => {
const typedParams = params.replace(/(\w+)/g, '$1: any');
changes.push({
type: 'modify',
description: `Added TypeScript types to function ${funcName}`,
});
return `function ${funcName}(${typedParams}): any`;
});
// Add interface definitions for objects
const objectRegex = /const\s+(\w+)\s*=\s*\{([^}]+)\}/g;
tsCode = tsCode.replace(objectRegex, (match, objName, objContent) => {
changes.push({
type: 'add',
description: `Added interface for object ${objName}`,
});
return `interface ${objName}Interface {\n // Add properties here\n}\n\n${match}: ${objName}Interface`;
});
return { code: tsCode, changes };
}
private isComponentFile(filePath: string, content: string): boolean {
return (
filePath.includes('component') ||
filePath.includes('Component') ||
content.includes('export default') ||
content.includes('React.Component') ||
content.includes('function Component')
);
}
private async analyzeComponent(filePath: string, content: string): Promise<ExtractableComponent> {
const name = this.extractComponentName(filePath);
const dependencies = this.extractDependencies(content);
const complexity = this.calculateComplexity(content);
const reusabilityScore = this.calculateReusabilityScore(content);
return {
name,
path: filePath,
type: this.determineComponentType(content),
dependencies,
complexity,
reusabilityScore,
description: this.extractDescription(content),
};
}
private extractComponentName(filePath: string): string {
const parts = filePath.split('/');
const fileName = parts[parts.length - 1];
return fileName.replace(/\.(js|ts|jsx|tsx)$/, '');
}
private determineComponentType(content: string): 'component' | 'hook' | 'utility' | 'service' | 'model' {
if (content.includes('React.Component') || content.includes('extends Component')) {
return 'component';
} else if (content.includes('useState') || content.includes('useEffect')) {
return 'hook';
} else if (content.includes('export function') || content.includes('export const')) {
return 'utility';
} else if (content.includes('class') && content.includes('constructor')) {
return 'service';
} else if (content.includes('interface') || content.includes('type ')) {
return 'model';
}
return 'utility';
}
private calculateComplexity(content: string): number {
const complexityPatterns = [
{ pattern: /\bif\b/g, type: 'if' },
{ pattern: /\belse\b/g, type: 'else' },
{ pattern: /\bfor\b/g, type: 'for' },
{ pattern: /\bwhile\b/g, type: 'while' },
{ pattern: /\bswitch\b/g, type: 'switch' },
{ pattern: /\bcase\b/g, type: 'case' },
{ pattern: /\bcatch\b/g, type: 'catch' },
{ pattern: /\bthrow\b/g, type: 'throw' },
{ pattern: /&&/g, type: '&&' },
{ pattern: /\|\|/g, type: '||' },
{ pattern: /\?/g, type: '?' },
{ pattern: /:/g, type: ':' },
{ pattern: /\bfunction\b/g, type: 'function' },
{ pattern: /\bclass\b/g, type: 'class' }
];
let complexity = 1;
for (const { pattern } of complexityPatterns) {
try {
const matches = content.match(pattern);
if (matches) {
complexity += matches.length;
}
} catch (error) {
// Skip invalid patterns
}
}
return complexity;
}
private calculateReusabilityScore(content: string): number {
let score = 50;
// Increase score for pure functions
if (content.includes('export') && !content.includes('import')) {
score += 20;
}
// Increase score for TypeScript
if (content.includes('interface') || content.includes('type ')) {
score += 15;
}
// Increase score for documentation
if (content.includes('/**') || content.includes('//')) {
score += 10;
}
// Decrease score for framework-specific code
if (content.includes('React') || content.includes('Vue') || content.includes('Angular')) {
score -= 10;
}
// Decrease score for external dependencies
const dependencies = this.extractDependencies(content);
score -= dependencies.length * 2;
return Math.max(0, Math.min(100, score));
}
private extractDescription(content: string): string {
const jsdocMatch = content.match(/\/\*\*\s*\n\s*\*\s*([^*]+)/);
if (jsdocMatch) {
return jsdocMatch[1].trim();
}
const commentMatch = content.match(/\/\/\s*(.+)/);
if (commentMatch) {
return commentMatch[1].trim();
}
return 'No description available';
}
private extractConfigurableValues(code: string): any[] {
const configurableValues: any[] = [];
// Hard-coded strings that might be configurable
const stringRegex = /['"]([^'"]{10,})['"](?!\s*:)/g;
let match;
while ((match = stringRegex.exec(code)) !== null) {
const value = match[1];
if (this.isLikelyConfigurable(value)) {
configurableValues.push({
pattern: match[0],
replacement: '${CONFIG.' + this.toConfigKey(value) + '}',
description: value.substring(0, 30) + '...',
});
}
}
return configurableValues;
}
private isLikelyConfigurable(value: string): boolean {
return (
value.includes('api') ||
value.includes('endpoint') ||
value.includes('url') ||
value.includes('key') ||
value.includes('secret') ||
value.includes('token') ||
value.length > 20
);
}
private toConfigKey(value: string): string {
return value
.replace(/[^a-zA-Z0-9]/g, '_')
.toUpperCase()
.substring(0, 20);
}
private async generatePackageJson(repositoryInfo: any, options: any): Promise<any> {
const originalDeps = repositoryInfo.dependencies || [];
return {
name: options.name || repositoryInfo.name,
version: '1.0.0',
description: options.description || repositoryInfo.description,
main: 'index.js',
scripts: {
start: 'node index.js',
dev: 'nodemon index.js',
test: 'jest',
build: 'webpack --mode production',
},
dependencies: originalDeps.filter((dep: any) => dep.type === 'dependency'),
devDependencies: originalDeps.filter((dep: any) => dep.type === 'devDependency'),
};
}
private async generateStarterFiles(repositoryInfo: any, options: any): Promise<any[]> {
const files: any[] = [];
// Generate main entry file
files.push({
path: 'index.js',
content: `// Main entry point for ${options.name || repositoryInfo.name}
console.log('Starting ${options.name || repositoryInfo.name}...');
// Add your application logic here
`,
type: 'source',
});
return files;
}
private async generateComponentLibraryFiles(repositoryInfo: any, options: any): Promise<any[]> {
const files: any[] = [];
// Generate index file
files.push({
path: 'src/index.js',
content: `// Component library entry point
export { default as Button } from './components/Button';
export { default as Input } from './components/Input';
// Add more component exports here
`,
type: 'source',
});
return files;
}
private async generateMicroserviceFiles(repositoryInfo: any, options: any): Promise<any[]> {
const files: any[] = [];
// Generate main service file
files.push({
path: 'src/server.js',
content: `// Microservice entry point
const express = require('express');
const app = express();
app.use(express.json());
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(\`Server running on port \${PORT}\`);
});
`,
type: 'source',
});
return files;
}
private async generateConfigFiles(repositoryInfo: any, options: any): Promise<any[]> {
const files: any[] = [];
// Generate .env template
files.push({
path: '.env.example',
content: `# Environment variables template
NODE_ENV=development
PORT=3000
API_URL=http://localhost:3000
`,
type: 'config',
});
return files;
}
private async generateTestFiles(repositoryInfo: any, options: any): Promise<any[]> {
const files: any[] = [];
// Generate test file
files.push({
path: 'tests/index.test.js',
content: `// Test file for ${options.name || repositoryInfo.name}
describe('${options.name || repositoryInfo.name}', () => {
test('should work correctly', () => {
expect(true).toBe(true);
});
});
`,
type: 'test',
});
return files;
}
private async generateDocumentationFiles(repositoryInfo: any, options: any): Promise<any[]> {
const files: any[] = [];
// Generate README
files.push({
path: 'README.md',
content: `# ${options.name || repositoryInfo.name}
${options.description || repositoryInfo.description || 'Generated template'}
## Installation
\`\`\`bash
npm install
\`\`\`
## Usage
\`\`\`bash
npm start
\`\`\`
## Documentation
Add your documentation here.
`,
type: 'documentation',
});
return files;
}
private async convertToLibraryComponent(component: ExtractableComponent): Promise<any> {
return {
name: component.name,
path: component.path,
props: [], // Extract props from component
examples: [], // Generate examples
documentation: component.description,
dependencies: component.dependencies,
};
}
private async extractReusableUtilities(url: string): Promise<ReusableUtility[]> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const utilities: ReusableUtility[] = [];
for (const [filePath, content] of Object.entries(repositoryInfo.keyFiles)) {
if (this.isUtilityFile(filePath, content)) {
const utility = await this.analyzeUtility(filePath, content);
utilities.push(utility);
}
}
return utilities;
}
private isUtilityFile(filePath: string, content: string): boolean {
return (
filePath.includes('util') ||
filePath.includes('helper') ||
filePath.includes('lib') ||
content.includes('export function') ||
content.includes('export const')
);
}
private async analyzeUtility(filePath: string, content: string): Promise<ReusableUtility> {
const name = this.extractUtilityName(filePath);
const functions = this.extractFunctionNames(content);
const dependencies = this.extractDependencies(content);
const description = this.extractDescription(content);
return {
name,
path: filePath,
functions,
description,
dependencies,
};
}
private extractUtilityName(filePath: string): string {
const parts = filePath.split('/');
const fileName = parts[parts.length - 1];
return fileName.replace(/\.(js|ts)$/, '');
}
private extractFunctionNames(content: string): string[] {
const functions: string[] = [];
const functionRegex = /function\s+(\w+)|const\s+(\w+)\s*=\s*\(|(\w+)\s*:\s*\(/g;
let match;
while ((match = functionRegex.exec(content)) !== null) {
const functionName = match[1] || match[2] || match[3];
if (functionName) {
functions.push(functionName);
}
}
return functions;
}
private async generateLibraryPackageJson(repositoryInfo: any): Promise<any> {
return {
name: `${repositoryInfo.name}-components`,
version: '1.0.0',
description: `Component library extracted from ${repositoryInfo.name}`,
main: 'dist/index.js',
module: 'dist/index.esm.js',
types: 'dist/index.d.ts',
scripts: {
build: 'rollup -c',
dev: 'rollup -c -w',
test: 'jest',
storybook: 'start-storybook -p 6006',
},
peerDependencies: {
react: '^16.8.0 || ^17.0.0 || ^18.0.0',
'react-dom': '^16.8.0 || ^17.0.0 || ^18.0.0',
},
devDependencies: {
'@rollup/plugin-babel': '^5.3.0',
'@rollup/plugin-commonjs': '^22.0.0',
'@rollup/plugin-node-resolve': '^13.3.0',
rollup: '^2.75.0',
jest: '^28.0.0',
'@storybook/react': '^6.5.0',
},
};
}
private generateFolderStructure(projectType: string, analysis: any): any {
const baseStructure = {
src: 'Source code',
tests: 'Test files',
docs: 'Documentation',
config: 'Configuration files',
};
switch (projectType) {
case 'web-app':
return {
...baseStructure,
components: 'React components',
pages: 'Page components',
hooks: 'Custom hooks',
utils: 'Utility functions',
};
case 'api':
return {
...baseStructure,
routes: 'API routes',
controllers: 'Route controllers',
models: 'Data models',
middleware: 'Express middleware',
};
case 'library':
return {
...baseStructure,
lib: 'Library source code',
examples: 'Usage examples',
types: 'TypeScript definitions',
};
default:
return baseStructure;
}
}
private generateScaffoldFiles(projectType: string, repositoryInfo: any): any[] {
const files: any[] = [];
// Generate based on project type
switch (projectType) {
case 'web-app':
files.push({
path: 'src/App.jsx',
content: 'import React from "react";\n\nfunction App() {\n return <div>Hello World</div>;\n}\n\nexport default App;',
type: 'source',
});
break;
case 'api':
files.push({
path: 'src/server.js',
content: 'const express = require("express");\nconst app = express();\n\napp.get("/", (req, res) => {\n res.json({ message: "Hello World" });\n});\n\napp.listen(3000);',
type: 'source',
});
break;
}
return files;
}
private generateScripts(projectType: string, repositoryInfo: any): any {
const baseScripts = {
test: 'jest',
lint: 'eslint src/',
};
switch (projectType) {
case 'web-app':
return {
...baseScripts,
start: 'react-scripts start',
build: 'react-scripts build',
dev: 'react-scripts start',
};
case 'api':
return {
...baseScripts,
start: 'node src/server.js',
dev: 'nodemon src/server.js',
};
default:
return baseScripts;
}
}
private extractRelevantDependencies(dependencies: any[]): string[] {
return dependencies
.filter(dep => dep.type === 'dependency')
.map(dep => dep.name);
}
// Additional methods for MCP tool handlers
async transformCode(code: string, transformations: any[], language: string, target_language?: string, options: any = {}): Promise<any> {
let transformedCode = code;
const changes = [];
const warnings = [];
for (const transformation of transformations) {
switch (transformation.type) {
case 'naming':
const namingResult = await this.transformNamingConvention(transformedCode, transformation.options);
transformedCode = namingResult.code;
changes.push(...namingResult.changes);
break;
case 'modernize':
const modernizeResult = await this.modernizeCode(transformedCode, language);
transformedCode = modernizeResult.refactoredCode;
changes.push(...modernizeResult.changes);
break;
case 'performance':
warnings.push('Performance optimization not implemented');
break;
case 'security':
warnings.push('Security transformation not implemented');
break;
}
}
return {
originalCode: code,
transformedCode,
changes,
warnings,
instructions: ['Review transformed code for correctness'],
};
}
async adaptCodeStructure(url: string, target_structure: any, options: any = {}): Promise<any> {
const repositoryInfo = await this.githubService.getRepositoryInfo(url);
const adaptedStructure: any = {
name: `${repositoryInfo.name}-adapted`,
structure: target_structure,
files: [],
changes: [],
instructions: [],
};
// Generate adapted structure based on target framework
if (target_structure.framework === 'react') {
adaptedStructure.files.push({
path: 'src/App.jsx',
content: 'import React from "react";\n\nfunction App() {\n return <div>Hello World</div>;\n}\n\nexport default App;',
});
}
return adaptedStructure;
}
}
```