agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
101 lines (93 loc) • 3.74 kB
JavaScript
/**
* @file Technical debt analyzer for code quality degradation detection
* @description Single responsibility: Identify and quantify technical debt indicators throughout codebases
*
* This analyzer systematically identifies technical debt patterns that indicate areas where
* code quality has degraded due to time pressure, changing requirements, or accumulated
* shortcuts. It provides quantitative debt scoring and categorized issue detection to help
* teams prioritize refactoring efforts and maintain long-term code health.
*
* Design rationale:
* - Comprehensive debt detection covers multiple technical debt categories and patterns
* - Severity-based classification helps prioritize remediation efforts by impact
* - Quantitative scoring enables tracking of debt reduction over time
* - Context-aware analysis reduces false positives through intelligent pattern matching
* - Line-level issue reporting provides precise location information for remediation
*
* Technical debt detection scope:
* - Documentation debt: TODO, FIXME, HACK comments indicating incomplete implementations
* - Code smell detection: Magic numbers, long parameter lists, excessive complexity
* - Maintainability issues: Code duplication, unclear naming, architectural violations
* - Performance debt: Inefficient algorithms, memory leaks, blocking operations
* - Security debt: Hardcoded secrets, insecure patterns, authentication bypasses
*/
/**
* Analyze technical debt in code content
* @param {string} content - Code content to analyze
* @returns {Object} Technical debt analysis results
*/
function analyzeTechnicalDebt(content) {
const issues = [];
const lines = content.split('\n');
let debtScore = 0;
lines.forEach((line, index) => {
const trimmed = line.trim().toLowerCase();
// Check for TODO/FIXME comments
if (trimmed.includes('todo') || trimmed.includes('fixme') || trimmed.includes('hack')) {
issues.push({
type: 'todo_comment',
line: index + 1,
severity: trimmed.includes('fixme') ? 'HIGH' : 'MEDIUM',
description: 'Technical debt marker found',
content: line.trim()
});
debtScore += trimmed.includes('fixme') ? 3 : 1;
}
// Check for magic numbers
const magicNumbers = line.match(/(?<![a-zA-Z_])\d{3,}(?![a-zA-Z_])/g);
if (magicNumbers && !trimmed.includes('//') && !trimmed.includes('const')) {
issues.push({
type: 'magic_number',
line: index + 1,
severity: 'LOW',
description: 'Magic number detected',
suggestion: 'Consider using named constants'
});
debtScore += 1;
}
// Check for long parameter lists
const paramMatch = line.match(/function\s+\w+\s*\(([^)]*)\)/);
if (paramMatch) {
const params = paramMatch[1].split(',').filter(p => p.trim());
if (params.length > 5) {
issues.push({
type: 'long_parameter_list',
line: index + 1,
severity: 'MEDIUM',
description: `Function has ${params.length} parameters`,
suggestion: 'Consider using configuration object or splitting function'
});
debtScore += 2;
}
}
// Check for deprecated patterns
if (trimmed.includes('var ') && !trimmed.includes('//')) {
issues.push({
type: 'deprecated_var',
line: index + 1,
severity: 'LOW',
description: 'Use of deprecated "var" keyword',
suggestion: 'Replace with "const" or "let"'
});
debtScore += 1;
}
});
return {
debtScore,
issues,
debtLevel: debtScore > 20 ? 'HIGH' : debtScore > 10 ? 'MEDIUM' : 'LOW'
};
}
module.exports = {
analyzeTechnicalDebt
};