#
tokens: 8560/50000 1/49 files (page 3/3)
lines: off (toggle) GitHub
raw markdown copy
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;
  }
}
```
Page 3/3FirstPrevNextLast