/**
* List Rules Tool
* Lists all Magento coding standard rules with filtering options.
*/
import {
MAGENTO_RULES,
SEVERITY_LEVELS,
getAllCategories,
getRulesBySeverity,
getRulesByCategory,
type Rule,
} from '../knowledge/index.js';
import { getActiveTheme } from '../themes/index.js';
export interface ListRulesResult {
totalRules: number;
filters: {
category?: string;
minSeverity?: number;
searchTerm?: string;
};
categories: string[];
severityLevels: typeof SEVERITY_LEVELS;
rules: Rule[];
}
/**
* List rules with optional filtering
*/
export function listRules(options: {
category?: string;
minSeverity?: number;
searchTerm?: string;
} = {}): ListRulesResult {
let rules = [...MAGENTO_RULES];
// Filter by category
if (options.category) {
rules = rules.filter(r =>
r.category.toLowerCase() === options.category!.toLowerCase()
);
}
// Filter by minimum severity
if (options.minSeverity !== undefined) {
rules = rules.filter(r => r.severity >= options.minSeverity!);
}
// Filter by search term
if (options.searchTerm) {
const term = options.searchTerm.toLowerCase();
rules = rules.filter(r =>
r.name.toLowerCase().includes(term) ||
r.description.toLowerCase().includes(term) ||
r.category.toLowerCase().includes(term)
);
}
// Append active theme rules
const theme = getActiveTheme();
if (theme) {
for (const themeRule of theme.validationRules) {
const asRule: Rule = {
name: themeRule.rule,
description: themeRule.message,
severity: themeRule.severity,
type: themeRule.type,
category: theme.name,
fixable: !!themeRule.suggestion,
};
// Apply filters to theme rules too
if (options.category && theme.name.toLowerCase() !== options.category.toLowerCase()) {
continue;
}
if (options.minSeverity !== undefined && asRule.severity < options.minSeverity) {
continue;
}
if (options.searchTerm) {
const term = options.searchTerm.toLowerCase();
if (!asRule.name.toLowerCase().includes(term) &&
!asRule.description.toLowerCase().includes(term) &&
!asRule.category.toLowerCase().includes(term)) {
continue;
}
}
rules.push(asRule);
}
}
// Sort by severity (highest first), then by name
rules.sort((a, b) => {
if (b.severity !== a.severity) {
return b.severity - a.severity;
}
return a.name.localeCompare(b.name);
});
const categories = getAllCategories();
if (theme && !categories.includes(theme.name)) {
categories.push(theme.name);
}
return {
totalRules: rules.length,
filters: options,
categories,
severityLevels: SEVERITY_LEVELS,
rules
};
}
/**
* Get summary of rules by category
*/
export function getRulesSummary(): Record<string, {
total: number;
errors: number;
warnings: number;
rules: string[];
}> {
const summary: Record<string, {
total: number;
errors: number;
warnings: number;
rules: string[];
}> = {};
for (const rule of MAGENTO_RULES) {
if (!summary[rule.category]) {
summary[rule.category] = {
total: 0,
errors: 0,
warnings: 0,
rules: []
};
}
summary[rule.category].total++;
if (rule.type === 'error') {
summary[rule.category].errors++;
} else {
summary[rule.category].warnings++;
}
summary[rule.category].rules.push(rule.name);
}
return summary;
}