All files / src/diff classify.ts

100% Statements 9/9
100% Branches 6/6
100% Functions 2/2
100% Lines 9/9

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                            19x                                                                                                       57x 7x 6x         51x 848x 31x         20x                   5x    
/**
 * File classification for chunking - determines how files should be processed
 */
 
import { matchGlob } from '../triggers/matcher.js';
import type { FilePattern } from '../config/schema.js';
 
/** Processing mode for a file */
export type FileMode = 'per-hunk' | 'whole-file' | 'skip';
 
/**
 * Built-in patterns that are always applied before user patterns.
 * These skip common lock files, minified code, and build artifacts.
 */
export const BUILTIN_SKIP_PATTERNS = [
  // Package manager lock files
  '**/pnpm-lock.yaml',
  '**/package-lock.json',
  '**/yarn.lock',
  '**/Cargo.lock',
  '**/go.sum',
  '**/poetry.lock',
  '**/composer.lock',
  '**/Gemfile.lock',
  '**/Pipfile.lock',
  '**/bun.lockb',
 
  // Minified/bundled code
  '**/*.min.js',
  '**/*.min.css',
  '**/*.bundle.js',
  '**/*.bundle.css',
 
  // Build artifacts
  '**/dist/**',
  '**/build/**',
  '**/node_modules/**',
  '**/.next/**',
  '**/out/**',
  '**/coverage/**',
 
  // Generated code
  '**/*.generated.*',
  '**/*.g.ts',
  '**/*.g.dart',
  '**/generated/**',
  '**/__generated__/**',
];
 
/**
 * Classify a file to determine how it should be processed.
 *
 * @param filename - The file path to classify
 * @param userPatterns - Optional user-defined patterns (can override built-ins)
 * @returns The processing mode: 'per-hunk', 'whole-file', or 'skip'
 *
 * Order of precedence:
 * 1. User patterns are checked first (higher priority, allows overriding built-ins)
 * 2. Built-in skip patterns are checked second
 * 3. Default is 'per-hunk' if no patterns match
 */
export function classifyFile(
  filename: string,
  userPatterns?: FilePattern[]
): FileMode {
  // Check user patterns first (allows overriding built-in skips)
  for (const { pattern, mode } of userPatterns ?? []) {
    if (matchGlob(pattern, filename)) {
      return mode;
    }
  }
 
  // Check built-in skip patterns
  for (const pattern of BUILTIN_SKIP_PATTERNS) {
    if (matchGlob(pattern, filename)) {
      return 'skip';
    }
  }
 
  // Default: process per-hunk
  return 'per-hunk';
}
 
/**
 * Check if a file should be skipped based on classification.
 */
export function shouldSkipFile(
  filename: string,
  userPatterns?: FilePattern[]
): boolean {
  return classifyFile(filename, userPatterns) === 'skip';
}