validate_ui_usage
Check Webasyst projects for hardcoded colors and outdated UI patterns, then get suggestions to fix them.
Instructions
Проверить использование UI 2.0 (хардкод цветов, устаревшие паттерны)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Путь к приложению/плагину | |
| check_colors | No | Проверять хардкод цвета | |
| check_components | No | Проверять устаревшие паттерны | |
| fix_suggestions | No | Показывать предложения по исправлению |
Implementation Reference
- webasyst-mcp.js:1387-1490 (handler)The main handler function that executes the tool logic: scans CSS files for hardcoded colors (skipping var() and comments), checks HTML templates for outdated patterns (e.g., 'btn' classes, inline color styles), collects issues and suggestions, and returns a text report.async function validateUIUsageTool({ project_path, check_colors = true, check_components = true, fix_suggestions = true }) { const issues = []; const suggestions = []; // Find CSS files const cssFiles = []; const cssDir = path.join(project_path, 'css'); if (await fileExists(cssDir)) { for (const file of await fs.readdir(cssDir)) { if (file.endsWith('.css') || file.endsWith('.styl')) { cssFiles.push(path.join(cssDir, file)); } } } // Check for hardcoded colors if (check_colors) { const colorPatterns = [ { pattern: /#[0-9a-fA-F]{3,6}(?![0-9a-fA-F])/g, name: 'HEX color' }, { pattern: /rgb\([^)]+\)/gi, name: 'RGB color' }, { pattern: /rgba\([^)]+\)/gi, name: 'RGBA color' } ]; for (const cssFile of cssFiles) { const content = await fs.readFile(cssFile, 'utf-8'); const lines = content.split('\n'); for (let i = 0; i < lines.length; i++) { const line = lines[i]; // Skip lines with var() - they're using variables correctly if (line.includes('var(')) continue; // Skip comments if (line.trim().startsWith('/*') || line.trim().startsWith('//')) continue; for (const { pattern, name } of colorPatterns) { const matches = line.match(pattern); if (matches) { for (const match of matches) { issues.push({ file: cssFile, line: i + 1, type: 'hardcoded_color', value: match, message: `Hardcoded ${name}: ${match}` }); if (fix_suggestions) { suggestions.push(`Line ${i + 1}: Replace "${match}" with CSS variable like var(--text-color), var(--accent-color), etc.`); } } } } } } } // Check for old UI patterns if (check_components) { const templatesDir = path.join(project_path, 'templates'); if (await fileExists(templatesDir)) { const htmlFiles = []; const findHtml = async (dir) => { for (const entry of await fs.readdir(dir, { withFileTypes: true })) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { await findHtml(fullPath); } else if (entry.name.endsWith('.html')) { htmlFiles.push(fullPath); } } }; await findHtml(templatesDir); const oldPatterns = [ { pattern: /class="[^"]*btn[^"]*"/g, suggestion: 'Use class="button" instead of "btn"' }, { pattern: /style="[^"]*color:\s*#/gi, suggestion: 'Move inline color styles to CSS with variables' }, { pattern: /style="[^"]*background:\s*#/gi, suggestion: 'Move inline background styles to CSS with variables' } ]; for (const htmlFile of htmlFiles) { const content = await fs.readFile(htmlFile, 'utf-8'); const lines = content.split('\n'); for (let i = 0; i < lines.length; i++) { for (const { pattern, suggestion } of oldPatterns) { if (pattern.test(lines[i])) { issues.push({ file: htmlFile, line: i + 1, type: 'old_pattern', message: suggestion }); } } } } } } const report = issues.length === 0 ? 'UI validation passed! No issues found.' : `Found ${issues.length} issue(s):\n\n${issues.map(i => `${i.file}:${i.line} - ${i.message}`).join('\n')}${suggestions.length > 0 ? '\n\nSuggestions:\n' + suggestions.join('\n') : ''}`; return { content: [{ type: 'text', text: report }] }; }
- webasyst-mcp.js:1749-1751 (registration)Registers the 'validate_ui_usage' tool in the MCP ListTools response, including its name, description, and input schema definition.{ name: 'validate_ui_usage', description: 'Проверить использование UI 2.0 (хардкод цветов, устаревшие паттерны)', inputSchema: { type: 'object', properties: { project_path: { type: 'string', description: 'Путь к приложению/плагину' }, check_colors: { type: 'boolean', default: true, description: 'Проверять хардкод цвета' }, check_components: { type: 'boolean', default: true, description: 'Проверять устаревшие паттерны' }, fix_suggestions: { type: 'boolean', default: true, description: 'Показывать предложения по исправлению' } }, required: ['project_path'] } }, { name: 'generate_color_scheme', description: 'Сгенерировать CSS-переменные цветовой схемы', inputSchema: { type: 'object', properties: { app_id: { type: 'string', description: 'ID приложения' }, scheme_name: { type: 'string', default: 'custom', description: 'Название схемы' }, primary_color: { type: 'string', description: 'Основной цвет (или CSS-переменная)' }, secondary_color: { type: 'string', description: 'Вторичный цвет' }, accent_color: { type: 'string', description: 'Акцентный цвет' }, text_color: { type: 'string', description: 'Цвет текста' }, background_color: { type: 'string', description: 'Цвет фона' } }, required: ['app_id'] } }, { name: 'create_responsive_layout', description: 'Создать адаптивные лейауты (Desktop + Mobile) с isMobile()', inputSchema: { type: 'object', properties: { app_id: { type: 'string', description: 'ID приложения' }, with_sidebar: { type: 'boolean', default: true, description: 'Включить сайдбар в Desktop' }, with_bottombar: { type: 'boolean', default: true, description: 'Включить bottombar в Mobile' } }, required: ['app_id'] } },
- webasyst-mcp.js:1811-1811 (registration)Routes calls to the 'validate_ui_usage' tool to its handler function in the CallToolRequestHandler switch statement.case 'validate_ui_usage': return await validateUIUsageTool(args);