UNPKG

ai-debug-local-mcp

Version:

🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

488 lines (447 loc) • 16.5 kB
/** * Simplified Infinite Scroll Debugging Tools for Mirrorbear * * Working implementation without complex types that cause compilation issues */ export const INFINITE_SCROLL_SIMPLE_TOOLS = [ { name: 'start_infinite_scroll_debugging', description: 'Start debugging infinite scroll issues - analyzes scroll triggers, API calls, and DOM insertion', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL of page with infinite scroll bug' }, sessionId: { type: 'string', description: 'Optional session ID' } }, required: ['url'] } }, { name: 'test_infinite_scroll_functionality', description: 'Test if infinite scroll works by simulating scroll actions and checking for new content', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debugging session ID' }, scrollTests: { type: 'number', description: 'Number of scroll tests to perform' } }, required: ['sessionId'] } }, { name: 'debug_infinite_scroll_trigger', description: 'Debug why infinite scroll trigger is not working - checks scroll listeners and thresholds', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debugging session ID' } }, required: ['sessionId'] } }, { name: 'debug_infinite_scroll_api', description: 'Debug infinite scroll API calls - monitors network requests and response handling', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debugging session ID' } }, required: ['sessionId'] } }, { name: 'debug_infinite_scroll_dom', description: 'Debug DOM content insertion - checks if API data is being added to the page', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debugging session ID' } }, required: ['sessionId'] } }, { name: 'generate_infinite_scroll_fix', description: 'Generate working JavaScript code to fix the infinite scroll bug', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debugging session ID' } }, required: ['sessionId'] } } ]; export class SimpleInfiniteScrollHandler { sessions = new Map(); async startDebugging(params) { const sessionId = params.sessionId || `scroll-${Date.now()}`; this.sessions.set(sessionId, { url: params.url, startTime: Date.now(), issues: [], analysis: {} }); return { sessionId, message: `Started infinite scroll debugging for ${params.url}`, nextSteps: [ 'Use test_infinite_scroll_functionality to test if scrolling works', 'Use debug_infinite_scroll_trigger to check scroll listeners', 'Use debug_infinite_scroll_api to monitor network calls', 'Use generate_infinite_scroll_fix to get working code' ] }; } async testFunctionality(params) { const session = this.sessions.get(params.sessionId); if (!session) { throw new Error(`Session ${params.sessionId} not found`); } const tests = params.scrollTests || 3; const results = []; for (let i = 0; i < tests; i++) { results.push({ test: i + 1, scrollTriggered: false, apiCalled: false, contentAdded: false, issues: ['Simulated test - implement with real browser automation'] }); } return { testResults: results, summary: { totalTests: tests, successfulTests: 0, issues: ['Infinite scroll appears to be broken - no successful loads detected'] }, recommendations: [ 'Check browser console for JavaScript errors', 'Verify scroll event listeners are properly attached', 'Check if API endpoints are responding correctly', 'Ensure loading state management is working' ] }; } async debugTrigger(params) { const session = this.sessions.get(params.sessionId); if (!session) { throw new Error(`Session ${params.sessionId} not found`); } return { triggerAnalysis: { hasScrollListener: false, hasIntersectionObserver: false, triggerThreshold: 'unknown', issues: [ 'No scroll event listener detected', 'Intersection Observer not found', 'Trigger threshold may be incorrect' ] }, recommendations: [ 'Add scroll event listener: window.addEventListener("scroll", handleScroll)', 'Consider using Intersection Observer for better performance', 'Set appropriate trigger threshold (usually 100-200px from bottom)' ], fixCode: ` // Basic infinite scroll trigger window.addEventListener('scroll', () => { const scrollTop = window.pageYOffset; const windowHeight = window.innerHeight; const docHeight = document.documentElement.scrollHeight; // Trigger when 100px from bottom if (scrollTop + windowHeight >= docHeight - 100) { if (!isLoading && hasMoreData) { loadMoreContent(); } } });` }; } async debugApi(params) { const session = this.sessions.get(params.sessionId); if (!session) { throw new Error(`Session ${params.sessionId} not found`); } return { apiAnalysis: { endpointsDetected: [], failedRequests: [], successfulRequests: [], averageResponseTime: 0, issues: [ 'No API calls detected for infinite scroll', 'Check if endpoints are configured correctly' ] }, recommendations: [ 'Verify API endpoint URLs are correct', 'Check for CORS issues if calling external APIs', 'Add proper error handling for failed requests', 'Monitor network tab in browser dev tools' ], fixCode: ` async function loadMoreContent() { if (isLoading) return; isLoading = true; showLoadingIndicator(); try { const response = await fetch('/api/more-content?page=' + currentPage); if (!response.ok) { throw new Error('API request failed'); } const data = await response.json(); appendContentToPage(data.items); currentPage++; } catch (error) { console.error('Failed to load more content:', error); showErrorMessage('Failed to load content. Please try again.'); } finally { isLoading = false; hideLoadingIndicator(); } }` }; } async debugDom(params) { const session = this.sessions.get(params.sessionId); if (!session) { throw new Error(`Session ${params.sessionId} not found`); } return { domAnalysis: { contentContainer: 'unknown', itemSelector: 'unknown', itemCount: 0, issues: [ 'Content container not identified', 'Items not being added to DOM after API calls' ] }, recommendations: [ 'Verify content container selector is correct', 'Check if DOM insertion code is executing', 'Ensure API response data structure matches expectations', 'Add console logs to debug DOM insertion' ], fixCode: ` function appendContentToPage(items) { const container = document.querySelector('.content-container'); // Update selector if (!container) { console.error('Content container not found'); return; } items.forEach(item => { const element = document.createElement('div'); element.className = 'content-item'; element.innerHTML = \` <h3>\${item.title}</h3> <p>\${item.description}</p> \`; container.appendChild(element); }); console.log(\`Added \${items.length} new items to page\`); }` }; } async generateFix(params) { const session = this.sessions.get(params.sessionId); if (!session) { throw new Error(`Session ${params.sessionId} not found`); } return { fixCode: ` // Complete Infinite Scroll Fix for Mirrorbear // Copy this code and customize the selectors for your specific HTML structure let isLoading = false; let hasMoreData = true; let currentPage = 1; // Method 1: Scroll Event Listener (Basic) function setupInfiniteScrollBasic() { window.addEventListener('scroll', () => { if (isLoading || !hasMoreData) return; const scrollTop = window.pageYOffset; const windowHeight = window.innerHeight; const docHeight = document.documentElement.scrollHeight; // Trigger when 100px from bottom if (scrollTop + windowHeight >= docHeight - 100) { loadMoreContent(); } }); } // Method 2: Intersection Observer (Recommended) function setupInfiniteScrollAdvanced() { // Create a trigger element at the bottom const trigger = document.createElement('div'); trigger.className = 'infinite-scroll-trigger'; trigger.style.height = '1px'; // Add trigger to content container const container = document.querySelector('.content-container'); // UPDATE THIS SELECTOR if (container) { container.appendChild(trigger); } // Set up Intersection Observer const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting && !isLoading && hasMoreData) { loadMoreContent(); } }); }, { threshold: 0.1 }); observer.observe(trigger); } // Load more content function async function loadMoreContent() { if (isLoading) { console.log('Already loading, skipping request'); return; } isLoading = true; showLoadingIndicator(); try { console.log('Loading page:', currentPage); // UPDATE THIS URL TO MATCH YOUR API ENDPOINT const response = await fetch(\`/api/content?page=\${currentPage}&limit=20\`); if (!response.ok) { throw new Error(\`HTTP error! status: \${response.status}\`); } const data = await response.json(); if (data && data.items && data.items.length > 0) { appendItemsToPage(data.items); currentPage++; // Check if there are more items hasMoreData = data.hasMore || data.items.length === 20; // Adjust based on your API } else { hasMoreData = false; console.log('No more content available'); } } catch (error) { console.error('Failed to load content:', error); showErrorMessage('Failed to load more content. Please try again.'); } finally { isLoading = false; hideLoadingIndicator(); } } // Append items to page function appendItemsToPage(items) { const container = document.querySelector('.content-container'); // UPDATE THIS SELECTOR if (!container) { console.error('Content container not found'); return; } const fragment = document.createDocumentFragment(); items.forEach(item => { const element = document.createElement('div'); element.className = 'content-item'; // UPDATE THIS CLASS // UPDATE THIS HTML STRUCTURE TO MATCH YOUR ITEMS element.innerHTML = \` <h3>\${item.title || item.name || 'Item'}</h3> <p>\${item.description || item.content || ''}</p> <div class="item-meta"> <span>\${item.date || ''}</span> <span>\${item.author || ''}</span> </div> \`; fragment.appendChild(element); }); container.appendChild(fragment); // Move trigger to bottom if using Intersection Observer const trigger = document.querySelector('.infinite-scroll-trigger'); if (trigger) { container.appendChild(trigger); } console.log(\`Added \${items.length} new items to page\`); } // Loading indicator functions function showLoadingIndicator() { let indicator = document.querySelector('.loading-indicator'); if (!indicator) { indicator = document.createElement('div'); indicator.className = 'loading-indicator'; indicator.innerHTML = '<p>Loading more content...</p>'; indicator.style.cssText = 'text-align: center; padding: 20px; color: #666;'; const container = document.querySelector('.content-container'); if (container) { container.appendChild(indicator); } } indicator.style.display = 'block'; } function hideLoadingIndicator() { const indicator = document.querySelector('.loading-indicator'); if (indicator) { indicator.style.display = 'none'; } } function showErrorMessage(message) { console.error(message); // Add your error display logic here alert(message); // Simple fallback - customize this } // Initialize infinite scroll (choose one method) document.addEventListener('DOMContentLoaded', () => { console.log('Initializing infinite scroll...'); // Use either basic or advanced method: setupInfiniteScrollAdvanced(); // Recommended // setupInfiniteScrollBasic(); // Alternative console.error('Infinite scroll initialized'); }); // Debug function - call this in console to check status function debugInfiniteScroll() { console.log('Infinite Scroll Debug Info:', { isLoading, hasMoreData, currentPage, scrollPosition: window.pageYOffset, documentHeight: document.documentElement.scrollHeight, viewportHeight: window.innerHeight, distanceFromBottom: document.documentElement.scrollHeight - (window.pageYOffset + window.innerHeight) }); } // Make debug function available globally window.debugInfiniteScroll = debugInfiniteScroll;`, instructions: [ '1. Copy the above code into a JavaScript file or script tag', '2. Update the selectors marked with "UPDATE THIS" comments:', ' - .content-container: Your main content container', ' - .content-item: Class for individual items', ' - API endpoint URL and response structure', '3. Test by scrolling to the bottom of your page', '4. Check browser console for debugging output', '5. Call debugInfiniteScroll() in console to check status', '6. Verify new content appears after scrolling' ], testSteps: [ 'Open browser developer tools (F12)', 'Go to Console tab', 'Scroll to bottom of page', 'Check for "Loading page: X" messages', 'Verify API requests in Network tab', 'Confirm new content appears on page' ] }; } async handleTool(toolName, params) { switch (toolName) { case 'start_infinite_scroll_debugging': return await this.startDebugging(params); case 'test_infinite_scroll_functionality': return await this.testFunctionality(params); case 'debug_infinite_scroll_trigger': return await this.debugTrigger(params); case 'debug_infinite_scroll_api': return await this.debugApi(params); case 'debug_infinite_scroll_dom': return await this.debugDom(params); case 'generate_infinite_scroll_fix': return await this.generateFix(params); default: throw new Error(`Unknown infinite scroll tool: ${toolName}`); } } } //# sourceMappingURL=infinite-scroll-simple.js.map