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
JavaScript
/**
* 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