UNPKG

bugger-mcp

Version:

MCP Server for managing bugs, feature requests, and improvements

164 lines 6.34 kB
// Status normalization utilities for better UX with MCP tool // Provides fuzzy matching for status values to reduce tool call failures /** * Normalize user input status to valid MCP tool status values */ export class StatusNormalizer { static BUG_STATUS_MAPPINGS = { // Exact matches (case-insensitive) 'open': 'Open', 'in progress': 'In Progress', 'inprogress': 'In Progress', 'in-progress': 'In Progress', 'fixed': 'Fixed', 'closed': 'Closed', 'temporarily resolved': 'Temporarily Resolved', 'temp resolved': 'Temporarily Resolved', // Common alternatives 'new': 'Open', 'active': 'In Progress', 'working': 'In Progress', 'in work': 'In Progress', 'doing': 'In Progress', 'done': 'Fixed', 'resolved': 'Fixed', 'completed': 'Fixed', 'finished': 'Fixed' }; static FEATURE_STATUS_MAPPINGS = { // Exact matches (case-insensitive) 'proposed': 'Proposed', 'in discussion': 'In Discussion', 'indiscussion': 'In Discussion', 'approved': 'Approved', 'in development': 'In Development', 'indevelopment': 'In Development', 'in-development': 'In Development', 'research phase': 'Research Phase', 'research': 'Research Phase', 'partially implemented': 'Partially Implemented', 'partial': 'Partially Implemented', 'completed': 'Completed', 'rejected': 'Rejected', // Common alternatives 'new': 'Proposed', 'discussing': 'In Discussion', 'accepted': 'Approved', 'working': 'In Development', 'in progress': 'In Development', 'developing': 'In Development', 'building': 'In Development', 'researching': 'Research Phase', 'done': 'Completed', 'finished': 'Completed', 'declined': 'Rejected', 'canceled': 'Rejected', 'cancelled': 'Rejected' }; static IMPROVEMENT_STATUS_MAPPINGS = { // Exact matches (case-insensitive) 'proposed': 'Proposed', 'in discussion': 'In Discussion', 'indiscussion': 'In Discussion', 'approved': 'Approved', 'in development': 'In Development', 'indevelopment': 'In Development', 'in-development': 'In Development', 'completed (awaiting human verification)': 'Completed (Awaiting Human Verification)', 'awaiting verification': 'Completed (Awaiting Human Verification)', 'pending verification': 'Completed (Awaiting Human Verification)', 'completed': 'Completed', 'rejected': 'Rejected', // Common alternatives 'new': 'Proposed', 'discussing': 'In Discussion', 'accepted': 'Approved', 'working': 'In Development', 'in progress': 'In Development', 'developing': 'In Development', 'implementing': 'In Development', 'done': 'Completed', 'finished': 'Completed', 'verified': 'Completed', 'declined': 'Rejected', 'canceled': 'Rejected', 'cancelled': 'Rejected' }; /** * Normalize a status string for the given item type */ static normalizeStatus(inputStatus, itemType) { if (!inputStatus || typeof inputStatus !== 'string') { return null; } const normalized = inputStatus.toLowerCase().trim(); let mappings; switch (itemType) { case 'bug': mappings = this.BUG_STATUS_MAPPINGS; break; case 'feature': mappings = this.FEATURE_STATUS_MAPPINGS; break; case 'improvement': mappings = this.IMPROVEMENT_STATUS_MAPPINGS; break; default: return null; } return mappings[normalized] || null; } /** * Get all valid status values for an item type */ static getValidStatuses(itemType) { switch (itemType) { case 'bug': return ['Open', 'In Progress', 'Fixed', 'Closed', 'Temporarily Resolved']; case 'feature': return ['Proposed', 'In Discussion', 'Approved', 'In Development', 'Research Phase', 'Partially Implemented', 'Completed', 'Rejected']; case 'improvement': return ['Proposed', 'In Discussion', 'Approved', 'In Development', 'Completed (Awaiting Human Verification)', 'Completed', 'Rejected']; default: return []; } } /** * Generate a helpful error message with valid status suggestions */ static generateStatusErrorMessage(inputStatus, itemType) { const validStatuses = this.getValidStatuses(itemType); const itemTypeDisplay = itemType.charAt(0).toUpperCase() + itemType.slice(1); return `Invalid status: "${inputStatus}" for ${itemTypeDisplay} items. Valid statuses are: ${validStatuses.join(', ')}`; } /** * Find the closest matching status using simple string similarity */ static suggestClosestStatus(inputStatus, itemType) { if (!inputStatus) return null; const validStatuses = this.getValidStatuses(itemType); const input = inputStatus.toLowerCase(); // First try exact word matches for (const status of validStatuses) { if (status.toLowerCase().includes(input) || input.includes(status.toLowerCase())) { return status; } } // If no exact match, try normalized mapping return this.normalizeStatus(inputStatus, itemType); } } /** * Helper function for MCP tool usage - attempts to normalize status or provides helpful error */ export function validateAndNormalizeStatus(inputStatus, itemType) { const normalized = StatusNormalizer.normalizeStatus(inputStatus, itemType); if (normalized) { return { status: normalized, error: null, suggestion: null }; } const suggestion = StatusNormalizer.suggestClosestStatus(inputStatus, itemType); const error = StatusNormalizer.generateStatusErrorMessage(inputStatus, itemType); return { status: null, error, suggestion }; } //# sourceMappingURL=status-utils.js.map