Skip to main content
Glama
role-validator.js5.01 kB
/** * Smart AI Bridge v1.3.0 - Role Validator * * Validates spawn_subagent requests: * - Role existence * - Required parameters * - File pattern syntax * - Task description quality */ import { isValidRole, getRoleTemplate } from '../config/role-templates.js'; import { minimatch } from 'minimatch'; /** * Validate spawn_subagent request * @param {Object} params - Request parameters * @returns {Object} Validation result */ export function validateSpawnSubagentRequest(params) { const errors = []; const warnings = []; // Validate role if (!params.role) { errors.push('role is required'); } else if (!isValidRole(params.role)) { errors.push(`Unknown role: ${params.role}`); } // Validate task if (!params.task) { errors.push('task is required'); } else if (typeof params.task !== 'string') { errors.push('task must be a string'); } else if (params.task.length < 10) { warnings.push('task description is very short, consider providing more detail'); } else if (params.task.length > 10000) { errors.push('task description is too long (max 10000 characters)'); } // Validate file_patterns (if provided) if (params.file_patterns) { if (!Array.isArray(params.file_patterns)) { errors.push('file_patterns must be an array'); } else { for (const pattern of params.file_patterns) { if (typeof pattern !== 'string') { errors.push(`Invalid file pattern: ${pattern} (must be string)`); } else { // Validate glob syntax try { minimatch('test.js', pattern); } catch (error) { errors.push(`Invalid glob pattern: ${pattern} - ${error.message}`); } } } } } // Validate context (if provided) if (params.context && typeof params.context !== 'object') { errors.push('context must be an object'); } // Validate verdict_mode if (params.verdict_mode && !['summary', 'full'].includes(params.verdict_mode)) { errors.push('verdict_mode must be "summary" or "full"'); } return { valid: errors.length === 0, errors, warnings }; } /** * Validate file patterns can match files * @param {string[]} patterns - Glob patterns * @param {string[]} files - File paths to test * @returns {Object} Validation result */ export function validateFilePatterns(patterns, files) { const matched = []; const unmatched = []; for (const pattern of patterns) { const matches = files.filter(file => minimatch(file, pattern)); if (matches.length === 0) { unmatched.push(pattern); } else { matched.push({ pattern, matches: matches.slice(0, 10) }); // Limit examples } } return { hasMatches: matched.length > 0, matched, unmatched, totalMatches: matched.reduce((sum, m) => sum + m.matches.length, 0) }; } /** * Suggest file patterns based on role * @param {string} role - Role name * @returns {string[]} Suggested patterns */ export function suggestFilePatternsForRole(role) { const suggestions = { 'code-reviewer': ['**/*.js', '**/*.ts', '**/*.jsx', '**/*.tsx', '**/*.py'], 'security-auditor': ['**/auth/**/*.js', '**/api/**/*.js', '**/middleware/**/*.js', '**/*security*.js'], 'planner': ['**/*.md', '**/package.json', '**/README*'], 'refactor-specialist': ['**/*.js', '**/*.ts', '**/*.jsx', '**/*.tsx'], 'test-generator': ['**/src/**/*.js', '**/lib/**/*.js', '!**/*.test.js', '!**/*.spec.js'], 'documentation-writer': ['**/README*', '**/docs/**/*.md', '**/*.js', '**/*.ts'] }; return suggestions[role] || ['**/*']; } /** * Validate task description quality * @param {string} task - Task description * @returns {Object} Quality assessment */ export function assessTaskQuality(task) { const issues = []; const suggestions = []; // Too vague const vagueWords = ['this', 'that', 'it', 'thing', 'stuff']; const hasVagueWords = vagueWords.some(word => task.toLowerCase().includes(` ${word} `) ); if (hasVagueWords) { suggestions.push('Be more specific - avoid vague references like "this" or "it"'); } // Missing action verb const actionVerbs = ['review', 'audit', 'plan', 'refactor', 'generate', 'write', 'analyze', 'test']; const hasActionVerb = actionVerbs.some(verb => task.toLowerCase().includes(verb) ); if (!hasActionVerb) { suggestions.push('Start with an action verb (review, audit, plan, etc.)'); } // Missing context if (task.length < 30) { suggestions.push('Provide more context - what should the subagent focus on?'); } // Too generic const genericPhrases = ['review code', 'check security', 'write tests']; const isGeneric = genericPhrases.some(phrase => task.toLowerCase() === phrase ); if (isGeneric) { suggestions.push('Add specifics - which code? What aspects? What type of tests?'); } return { quality: suggestions.length === 0 ? 'good' : suggestions.length < 2 ? 'fair' : 'poor', issues, suggestions }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Platano78/Smart-AI-Bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server