Vibe Check MCP

by PV-Bhat
Verified
import { addMistake, getMistakeCategorySummary, MistakeEntry } from '../utils/storage.js'; // Vibe Learn tool interfaces export interface VibeLearnInput { mistake: string; category: string; solution: string; sessionId?: string; } export interface VibeLearnOutput { added: boolean; currentTally: number; topCategories: Array<{ category: string; count: number; recentExample: MistakeEntry; }>; } /** * The vibe_learn tool records one-sentence mistakes and solutions * to build a pattern recognition system for future improvement */ export async function vibeLearnTool(input: VibeLearnInput): Promise<VibeLearnOutput> { try { // Validate input if (!input.mistake) { throw new Error('Mistake description is required'); } if (!input.category) { throw new Error('Mistake category is required'); } if (!input.solution) { throw new Error('Solution is required'); } // Enforce single-sentence constraints const mistake = enforceOneSentence(input.mistake); const solution = enforceOneSentence(input.solution); // Normalize category to one of our standard categories if possible const category = normalizeCategory(input.category); // Add mistake to log const entry = addMistake(mistake, category, solution); // Get category summaries const categorySummary = getMistakeCategorySummary(); // Find current tally for this category const categoryData = categorySummary.find(m => m.category === category); const currentTally = categoryData?.count || 1; // Get top 3 categories const topCategories = categorySummary.slice(0, 3); return { added: true, currentTally, topCategories }; } catch (error) { console.error('Error in vibe_learn tool:', error); return { added: false, currentTally: 0, topCategories: [] }; } } /** * Ensure text is a single sentence */ function enforceOneSentence(text: string): string { // Remove newlines let sentence = text.replace(/\r?\n/g, ' '); // Split by sentence-ending punctuation const sentences = sentence.split(/([.!?])\s+/); // Take just the first sentence if (sentences.length > 0) { // If there's punctuation, include it const firstSentence = sentences[0] + (sentences[1] || ''); sentence = firstSentence.trim(); } // Ensure it ends with sentence-ending punctuation if (!/[.!?]$/.test(sentence)) { sentence += '.'; } return sentence; } /** * Normalize category to one of our standard categories */ function normalizeCategory(category: string): string { // Standard categories const standardCategories = { 'Complex Solution Bias': ['complex', 'complicated', 'over-engineered', 'complexity'], 'Feature Creep': ['feature', 'extra', 'additional', 'scope creep'], 'Premature Implementation': ['premature', 'early', 'jumping', 'too quick'], 'Misalignment': ['misaligned', 'wrong direction', 'off target', 'misunderstood'], 'Overtooling': ['overtool', 'too many tools', 'unnecessary tools'] }; // Convert category to lowercase for matching const lowerCategory = category.toLowerCase(); // Try to match to a standard category for (const [standardCategory, keywords] of Object.entries(standardCategories)) { if (keywords.some(keyword => lowerCategory.includes(keyword))) { return standardCategory; } } // If no match, return the original category return category; }