All files / src remediation.ts

78.04% Statements 32/41
72.41% Branches 21/29
100% Functions 2/2
81.57% Lines 31/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160                              20x   1x           3x         2x         6x         1x         1x         1x         1x         1x         1x                   1x           1x                                                           3x 3x 3x   3x 1x     1x     1x     3x           3x 1x     1x     1x     3x 1x 1x     1x     3x                   3x    
import type { FileClassification } from './types';
 
/**
 * Get classification-specific recommendations
 *
 * @param classification - The identified type of file (e.g., 'barrel-export', 'utility-module').
 * @param file - File path or identifier.
 * @param issues - Initial list of issues to supplement.
 * @returns Array of tailored recommendations.
 */
export function getClassificationRecommendations(
  classification: FileClassification,
  file: string,
  issues: string[]
): string[] {
  switch (classification) {
    case 'boilerplate-barrel':
      return [
        'Redundant indirection detected (architectural theater)',
        'Remove this pass-through barrel export to reduce cognitive load',
        'Consider combining into meaningful domain exports if necessary',
      ];
    case 'barrel-export':
      return [
        'Barrel export file detected - multiple domains are expected here',
        'Consider if this barrel export improves or hinders discoverability',
      ];
    case 'type-definition':
      return [
        'Type definition file - centralized types improve consistency',
        'Consider splitting if file becomes too large (>500 lines)',
      ];
    case 'cohesive-module':
      return [
        'Module has good cohesion despite its size',
        'Consider documenting the module boundaries for AI assistants',
      ];
    case 'utility-module':
      return [
        'Utility module detected - multiple domains are acceptable here',
        'Consider grouping related utilities by prefix or domain for better discoverability',
      ];
    case 'service-file':
      return [
        'Service file detected - orchestration of multiple dependencies is expected',
        'Consider documenting service boundaries and dependencies',
      ];
    case 'lambda-handler':
      return [
        'Lambda handler detected - coordination of services is expected',
        'Ensure handler has clear single responsibility',
      ];
    case 'email-template':
      return [
        'Email template detected - references multiple domains for rendering',
        'Template structure is cohesive by design',
      ];
    case 'parser-file':
      return [
        'Parser/transformer file detected - handles multiple data sources',
        'Consider documenting input/output schemas',
      ];
    case 'nextjs-page':
      return [
        'Next.js App Router page detected - metadata/JSON-LD/component pattern is cohesive',
        'Multiple exports (metadata, faqJsonLd, default) serve single page purpose',
      ];
    case 'spoke-module':
      return [
        'Spoke module detected - intentional monorepo separation is good for modularity',
        'Ensure this spoke only exports what is necessary for the hub or other spokes',
      ];
    case 'mixed-concerns':
      return [
        'Consider splitting this file by domain',
        'Identify independent responsibilities and extract them',
        'Review import dependencies to understand coupling',
      ];
    default:
      return issues;
  }
}
 
/**
 * Generate general context recommendations based on cross-tool metrics and thresholds.
 *
 * @param metrics - Object containing context budget, depth, circular dependencies, cohesion, and fragmentation.
 * @param thresholds - Configurable limits for each metric.
 * @returns Object with recommendations array, issues array, and overall severity level.
 */
export function getGeneralRecommendations(
  metrics: {
    contextBudget: number;
    importDepth: number;
    circularDeps: string[][];
    cohesionScore: number;
    fragmentationScore: number;
  },
  thresholds: {
    maxContextBudget: number;
    maxDepth: number;
    minCohesion: number;
    maxFragmentation: number;
  }
): {
  recommendations: string[];
  issues: string[];
  severity: any;
} {
  const recommendations: string[] = [];
  const issues: string[] = [];
  let severity: string = 'info';
 
  if (metrics.contextBudget > thresholds.maxContextBudget) {
    issues.push(
      `High context budget: ${Math.round(metrics.contextBudget / 1000)}k tokens`
    );
    recommendations.push(
      'Reduce dependencies or split the file to lower context window requirements'
    );
    severity = 'major';
  }
 
  Iif (metrics.importDepth > thresholds.maxDepth) {
    issues.push(`Deep import chain: ${metrics.importDepth} levels`);
    recommendations.push('Flatten the dependency graph by reducing nesting');
    if (severity !== 'critical') severity = 'major';
  }
 
  if (metrics.circularDeps.length > 0) {
    issues.push(
      `Circular dependencies detected: ${metrics.circularDeps.length}`
    );
    recommendations.push(
      'Refactor to remove circular imports (use dependency injection or interfaces)'
    );
    severity = 'critical';
  }
 
  if (metrics.cohesionScore < thresholds.minCohesion) {
    issues.push(`Low cohesion score: ${metrics.cohesionScore.toFixed(2)}`);
    recommendations.push(
      'Extract unrelated exports into separate domain-specific modules'
    );
    Eif (severity === 'info') severity = 'minor';
  }
 
  Iif (metrics.fragmentationScore > thresholds.maxFragmentation) {
    issues.push(
      `High domain fragmentation: ${metrics.fragmentationScore.toFixed(2)}`
    );
    recommendations.push(
      'Consolidate domain-related files into fewer directories'
    );
    if (severity === 'info') severity = 'minor';
  }
 
  return { recommendations, issues, severity: severity as any };
}