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