UNPKG

promptrix-mcp

Version:

MCP Server for Promptrix - AI prompt enhancement and optimization for Claude Code

160 lines 7.83 kB
/** * Prompt Quality Analyzer * * Analyzes prompt quality and provides improvement suggestions. */ /** * Quality Analyzer class for consistent prompt analysis */ export class QualityAnalyzer { analyzePromptQuality(prompt) { const issues = { tooShort: false, lacksSpecificity: false, missingContext: false, poorStructure: false, ambiguousLanguage: false }; const suggestions = []; let score = 80; // Start with lower base score for stricter evaluation // Check length - stricter penalties if (prompt.length < 15) { issues.tooShort = true; suggestions.push("Your prompt is too brief. Add more specific details"); score -= 35; } else if (prompt.length < 30) { issues.tooShort = true; suggestions.push("Consider adding more details and context"); score -= 25; } else if (prompt.length < 50) { suggestions.push("Adding more context could improve results"); score -= 15; } // Enhanced specificity checks - more comprehensive vague word detection const vagueWords = /\b(some|any|stuff|things|something|anything|good|bad|nice|cool|awesome|great|fine|ok|okay)\b/gi; const informalWords = /\b(func|app|thingy|gonna|wanna|kinda|sorta)\b/gi; const casualWords = /\b(hey|hi|hello|yo|sup)\b/gi; const vagueMatches = prompt.match(vagueWords) || []; const informalMatches = prompt.match(informalWords) || []; const casualMatches = prompt.match(casualWords) || []; if (vagueMatches.length > 0 || informalMatches.length > 0) { issues.lacksSpecificity = true; suggestions.push("Replace vague or informal terms with specific technical language"); score -= 20 + (vagueMatches.length + informalMatches.length) * 5; } if (casualMatches.length > 0) { suggestions.push("Use professional language instead of casual greetings"); score -= 10; } // Grammar and punctuation checks const hasProperCapitalization = /^[A-Z]/.test(prompt.trim()); const hasEndingPunctuation = /[.!?]$/.test(prompt.trim()); const hasMissingArticles = /\b(create|write|make|build)\s+(?!a|an|the)\b[a-z]/gi.test(prompt); if (!hasProperCapitalization) { suggestions.push("Start your prompt with a capital letter"); score -= 10; } if (!hasEndingPunctuation && prompt.length > 20) { suggestions.push("End your prompt with proper punctuation"); score -= 8; } if (hasMissingArticles) { suggestions.push("Include proper articles (a, an, the) for better clarity"); score -= 12; } // Enhanced context detection const hasContext = /\b(for|in|with|about|regarding|concerning|related to|context|background|purpose|goal|use case|requirement|specification)\b/i.test(prompt); const hasExamples = /\b(example|sample|instance|demo|illustration)\b/i.test(prompt); const hasConstraints = /\b(must|should|need|require|constraint|limit|restriction)\b/i.test(prompt); if (!hasContext && prompt.length > 25) { issues.missingContext = true; suggestions.push("Add context about your specific use case or goal"); score -= 20; } // Structure analysis - more stringent const hasStructure = prompt.includes('\n') || prompt.includes(':') || prompt.includes('-') || prompt.includes('1.') || prompt.includes('•') || prompt.includes(','); const sentences = prompt.split(/[.!?]+/).filter(s => s.trim().length > 0); const isLongButUnstructured = prompt.length > 80 && !hasStructure && sentences.length < 2; if (isLongButUnstructured) { issues.poorStructure = true; suggestions.push("Break down complex requests into structured points or sentences"); score -= 18; } // Ambiguous language detection - expanded const ambiguousWords = /\b(maybe|perhaps|might|could|should|probably|possibly|sometimes|usually|often|generally)\b/gi; const weakWords = /\b(just|simply|basically|kind of|sort of|pretty much)\b/gi; const ambiguousMatches = prompt.match(ambiguousWords) || []; const weakMatches = prompt.match(weakWords) || []; if (ambiguousMatches.length > 0 || weakMatches.length > 0) { issues.ambiguousLanguage = true; suggestions.push("Use definitive language instead of uncertain or weak terms"); score -= 12 + (ambiguousMatches.length + weakMatches.length) * 3; } // Action word analysis - commands vs questions const hasQuestionMarks = (prompt.match(/\?/g) || []).length; const hasCommands = /\b(create|make|write|build|generate|develop|design|implement|explain|describe|analyze|show|demonstrate|provide|give)\b/i.test(prompt); if (hasQuestionMarks > 1 && !hasCommands) { suggestions.push("Use clear commands instead of multiple questions"); score -= 8; } if (!hasCommands && !hasQuestionMarks) { suggestions.push("Include clear action words to specify what you want"); score -= 15; } // Positive indicators - refined scoring let bonusPoints = 0; if (hasExamples) bonusPoints += 8; if (hasConstraints) bonusPoints += 6; if (hasContext) bonusPoints += 10; if (/\b(specific|detailed|comprehensive|step-by-step|requirements?)\b/i.test(prompt)) bonusPoints += 8; if (hasProperCapitalization && hasEndingPunctuation) bonusPoints += 5; if (prompt.includes('please') || prompt.includes('thank you')) bonusPoints += 3; score += bonusPoints; // Technical depth bonus const technicalTerms = /\b(function|class|method|API|database|algorithm|framework|library|module|component)\b/gi; const techMatches = prompt.match(technicalTerms) || []; if (techMatches.length > 0) { score += Math.min(10, techMatches.length * 3); } // Ensure score bounds score = Math.max(0, Math.min(100, score)); // Calculate confidence - adjusted for stricter analysis let confidence = 0.85; if (prompt.length < 25) confidence = 0.95; // Very confident about short prompts if (prompt.length > 200) confidence = 0.75; // Less confident about very long prompts if (suggestions.length > 4) confidence = 0.8; // Less confident with many issues return { overall: Math.round(score), issues, suggestions: suggestions.length > 0 ? suggestions : ['Your prompt looks good!'], confidence: Math.round(confidence * 100) / 100 }; } formatIssues(issues) { const issueDescriptions = { tooShort: '❌ Prompt is too brief', lacksSpecificity: '❌ Contains vague or unclear terms', missingContext: '❌ Missing context or background information', poorStructure: '❌ Lacks clear structure for complex request', ambiguousLanguage: '❌ Uses uncertain or ambiguous language' }; const detectedIssues = Object.entries(issues) .filter(([_, hasIssue]) => hasIssue) .map(([issue, _]) => issueDescriptions[issue]); return detectedIssues.length > 0 ? detectedIssues.join('\n') : '✅ No significant issues detected'; } } //# sourceMappingURL=quality-analyzer.js.map