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

273 lines • 10.9 kB
/** * Flutter Configuration & Setup Module * * Handles Flutter framework detection, configuration retrieval, and basic monitoring setup. * This module provides the foundation for all other Flutter debugging capabilities. */ export class FlutterConfigSetup { page; config; diagnostics; async attachToPage(page) { this.page = page; await this.injectFlutterMonitoring(); await this.detectFlutterConfig(); } async detectFlutter(page) { return await page.evaluate(() => { // Multiple Flutter detection methods const hasFlutterView = document.querySelector('flutter-view') !== null || document.querySelector('flt-glass-pane') !== null; const hasFlutterObject = !!window._flutter; const hasCanvasKit = !!window.CanvasKit || !!window.flutterCanvasKit; const hasFlutterLoader = document.querySelector('script[src*="flutter.js"]') !== null || document.querySelector('script[src*="flutter_service_worker.js"]') !== null; return hasFlutterView || hasFlutterObject || hasCanvasKit || hasFlutterLoader; }); } async getFlutterConfig() { if (!this.page) return null; try { const config = await this.page.evaluate(() => { const flutter = window._flutter || window.flutter; const flutterDebug = window.__FLUTTER_DEBUG__; if (!flutter && !flutterDebug) return null; // Detect renderer type let renderer = 'auto'; if (window.CanvasKit) { renderer = 'CanvasKit'; } else if (document.querySelector('flt-scene')) { renderer = 'HTML'; } // Detect build mode const isDebug = !!window.__flutter_debug__; const isProfile = !!window.__flutter_profile__; const buildMode = isDebug ? 'debug' : (isProfile ? 'profile' : 'release'); // Get version info const version = flutter?.version || 'unknown'; const dartVersion = flutter?.dartVersion || 'unknown'; const flutterChannel = flutter?.channel || 'unknown'; // Web configuration const serviceWorker = 'serviceWorker' in navigator && navigator.serviceWorker.controller !== null; const canvasKitUrl = window.flutterCanvasKitUrl; const fontManifest = window.flutterFontManifest; return { framework: 'Flutter', version, renderer, buildMode, dartVersion, flutterChannel, webConfig: { serviceWorker, canvasKitUrl, fontManifest } }; }); this.config = config || undefined; return config; } catch (error) { return null; } } async getFlutterDiagnostics() { if (!this.page) { return this.getDefaultDiagnostics(); } try { const diagnostics = await this.page.evaluate(() => { const flutterDebug = window.__FLUTTER_DEBUG__; // Renderer diagnostics const rendererType = window.CanvasKit ? 'CanvasKit' : 'HTML'; const wasmLoaded = !!window.CanvasKit; const loadTime = performance.now(); const canvasKitVersion = window.CanvasKit?.version(); // Platform channels const platformChannels = flutterDebug?.platformChannels ? Array.from(flutterDebug.platformChannels.entries()).map((entry) => { const [name, info] = entry; return { name, available: true, messageCount: info.messageCount || 0, lastError: info.lastError }; }) : []; // Font diagnostics const fontManifest = window.flutterFontManifest || []; const loadedFonts = []; try { // Check if document.fonts supports forEach method if (document.fonts && typeof document.fonts.forEach === 'function') { document.fonts.forEach((font) => { loadedFonts.push(font.family); }); } } catch (error) { // Fallback if forEach method is not available } const failedFonts = []; // Gesture handling const glassPane = document.querySelector('flt-glass-pane') !== null; const pointerEvents = document.body.style.pointerEvents || 'auto'; const touchSupport = 'ontouchstart' in window; const conflictingGestures = flutterDebug?.gestures?.conflicts?.length || 0; // Text input const textInputMode = document.querySelector('flt-text-editing-host') ? 'native' : 'custom'; const focusIssues = 0; // Would need more complex detection const imeSupport = 'InputMethodContext' in window; return { renderer: { type: rendererType, wasmLoaded, loadTime, canvasKitVersion }, platformChannels, fonts: { manifest: fontManifest, loaded: loadedFonts, failed: failedFonts, loadTime: 0 }, gestureHandling: { glassPane, pointerEvents, touchSupport, conflictingGestures }, textInput: { mode: textInputMode, focusIssues, imeSupport } }; }); this.diagnostics = diagnostics || this.getDefaultDiagnostics(); return this.diagnostics; } catch (error) { return this.getDefaultDiagnostics(); } } async injectFlutterMonitoring() { if (!this.page) return; await this.page.addInitScript(() => { window.__FLUTTER_DEBUG__ = { config: { renderer: 'unknown', buildMode: 'unknown', version: 'unknown' }, performance: { frames: [], fps: 0, jankFrames: 0, shaderCompilations: [] }, widgets: { rebuilds: new Map(), tree: null, inefficientPatterns: [] }, memory: { snapshots: [], leaks: [] }, platformChannels: new Map(), errors: [], gestures: { conflicts: [], recognizers: [] }, initialize: function () { // Detect renderer type if (window.CanvasKit) { this.config.renderer = 'CanvasKit'; } else if (document.querySelector('flt-scene')) { this.config.renderer = 'HTML'; } // Detect build mode const isDebug = !!window.__flutter_debug__; const isProfile = !!window.__flutter_profile__; this.config.buildMode = isDebug ? 'debug' : (isProfile ? 'profile' : 'release'); // Hook into Flutter internals this.hookFlutterInternals(); }, hookFlutterInternals: function () { // Try to access Flutter's internal APIs const flutter = window._flutter || window.flutter; if (!flutter) return; // Monitor platform channels if (flutter.platformChannels) { const originalSend = flutter.platformChannels.send; flutter.platformChannels.send = function (channel, message) { if (!this.platformChannels.has(channel)) { this.platformChannels.set(channel, { messageCount: 0, lastMessage: null, lastError: null }); } const channelInfo = this.platformChannels.get(channel); channelInfo.messageCount++; channelInfo.lastMessage = message; return originalSend.call(this, channel, message); }; } } }; // Initialize the debug system window.__FLUTTER_DEBUG__.initialize(); }); } async detectFlutterConfig() { if (!this.page) return; try { const config = await this.getFlutterConfig(); this.config = config || undefined; } catch (error) { // Configuration detection failed, but that's okay } } getDefaultDiagnostics() { return { renderer: { type: 'HTML', wasmLoaded: false, loadTime: 0 }, platformChannels: [], fonts: { manifest: [], loaded: [], failed: [], loadTime: 0 }, gestureHandling: { glassPane: false, pointerEvents: 'auto', touchSupport: false, conflictingGestures: 0 }, textInput: { mode: 'native', focusIssues: 0, imeSupport: false } }; } } //# sourceMappingURL=flutter-config-setup.js.map