UNPKG

advanced-live-server-installer

Version:

Auto-installer for Advanced Live Server VS Code Extension

1,057 lines (1,046 loc) 87 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.deactivate = exports.activate = void 0; const vscode = __importStar(require("vscode")); const live_server_1 = require("../server/live-server"); const config_manager_1 = require("../config/config-manager"); const status_bar_manager_1 = require("../ui/status-bar-manager"); // Import real feature implementations const cloud_preview_manager_1 = require("../premium/cloud-preview-manager"); const multi_ai_service_1 = require("./multi-ai-service"); const ai_settings_panel_1 = require("../ui/ai-settings-panel"); const custom_domains_1 = require("../premium/custom-domains"); const priority_support_1 = require("../premium/priority-support"); const advanced_analytics_1 = require("../premium/advanced-analytics"); let liveServer = null; let statusBarManager; let outputChannel; let collaborationStatusBarItem; let serverStatusBarItem; let quickActionsStatusBarItem; // Service singletons (initialized in activate) let cloudPreviewManager; let aiService; let aiSettingsPanel; let customDomainsService; let prioritySupportService; let analyticsService; // --- STUBS FOR PREMIUM FEATURES --- // REMOVE ALL STUBS AND UPGRADE MESSAGES // TODO: Import and wire up real feature implementations here // Example: // import { startCloudPreview } from '../premium/cloud-preview-manager'; // import { analyzeError } from '../premium/ai-service'; // ... // For now, just provide empty async functions as placeholders for all premium commands // --- COMMAND REGISTRATION --- // Only register free feature commands const commands = [ vscode.commands.registerCommand('advancedLiveServer.start', startServer), vscode.commands.registerCommand('advancedLiveServer.stop', stopServer), vscode.commands.registerCommand('advancedLiveServer.restart', restartServer), vscode.commands.registerCommand('advancedLiveServer.openInBrowser', openInBrowser), vscode.commands.registerCommand('advancedLiveServer.openCurrentFile', openCurrentFile), vscode.commands.registerCommand('advancedLiveServer.showStatus', showStatus), vscode.commands.registerCommand('advancedLiveServer.openSettings', openSettings), vscode.commands.registerCommand('advancedLiveServer.resetSettings', resetSettings), vscode.commands.registerCommand('advancedLiveServer.openVSCodeSettings', openVSCodeSettings), vscode.commands.registerCommand('advancedLiveServer.quickSettings', quickSettings), vscode.commands.registerCommand('advancedLiveServer.showCurrentSettings', showCurrentSettings), // Premium commands as stubs vscode.commands.registerCommand('advancedLiveServer.startCloudPreview', startCloudPreview), vscode.commands.registerCommand('advancedLiveServer.analyzeError', analyzeError), vscode.commands.registerCommand('advancedLiveServer.suggestImprovements', suggestImprovements), vscode.commands.registerCommand('advancedLiveServer.openAISettings', openAISettings), vscode.commands.registerCommand('advancedLiveServer.analyzeAccessibility', analyzeAccessibility), vscode.commands.registerCommand('advancedLiveServer.analyzePerformance', analyzePerformance), vscode.commands.registerCommand('advancedLiveServer.analyzeSEO', analyzeSEO), vscode.commands.registerCommand('advancedLiveServer.securityScan', securityScan), vscode.commands.registerCommand('advancedLiveServer.startCollaboration', startCollaboration), vscode.commands.registerCommand('advancedLiveServer.stopCollaboration', stopCollaboration), vscode.commands.registerCommand('advancedLiveServer.showCollaborationInfo', showCollaborationInfo), vscode.commands.registerCommand('advancedLiveServer.showAnalytics', showAnalytics), vscode.commands.registerCommand('advancedLiveServer.addCustomDomain', addCustomDomain), vscode.commands.registerCommand('advancedLiveServer.createSupportTicket', createSupportTicket), vscode.commands.registerCommand('advancedLiveServer.showWelcome', showWelcome), ]; async function activate(context) { console.log('Advanced Live Server extension is now active!'); // Initialize output channel outputChannel = vscode.window.createOutputChannel('Advanced Live Server'); // Initialize services statusBarManager = new status_bar_manager_1.StatusBarManager(); cloudPreviewManager = new cloud_preview_manager_1.CloudPreviewManager(outputChannel); aiService = new multi_ai_service_1.MultiAIService(context, outputChannel); aiSettingsPanel = new ai_settings_panel_1.AISettingsPanel(context); // Initialize AI service await aiService.initialize(); customDomainsService = new custom_domains_1.CustomDomainsService(context, outputChannel); prioritySupportService = new priority_support_1.PrioritySupportService(context, outputChannel); analyticsService = new advanced_analytics_1.AdvancedAnalyticsService(context, outputChannel); // Show welcome message on first install const isFirstInstall = context.globalState.get('hasShownWelcome', false); if (!isFirstInstall) { context.globalState.update('hasShownWelcome', true); // Show welcome message after a short delay setTimeout(() => { showWelcome(); }, 2000); } // Register commands commands.forEach(command => context.subscriptions.push(command)); // Update status bar statusBarManager.updateStatus(false); // Auto-start if configured const workspaceConfig = vscode.workspace.getConfiguration('advancedLiveServer'); if (workspaceConfig.get('autoStart', false)) { startServer(); } updateCollaborationStatusBar(); updateServerStatusBar(liveServer?.isRunning?.() || false); context.subscriptions.push({ dispose: () => collaborationStatusBarItem?.dispose() }); context.subscriptions.push({ dispose: () => serverStatusBarItem?.dispose() }); // Add Quick Actions menu button to the left side of the status bar quickActionsStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1); quickActionsStatusBarItem.text = '$(list-unordered) Live Server Menu'; quickActionsStatusBarItem.tooltip = 'Open Advanced Live Server Quick Actions'; quickActionsStatusBarItem.command = 'advancedLiveServer.showQuickActions'; quickActionsStatusBarItem.show(); context.subscriptions.push(quickActionsStatusBarItem); } exports.activate = activate; function deactivate() { if (liveServer) { liveServer.stop(); } // if (offlineCloudService) { // Removed // offlineCloudService.stop(); // Removed // } // Removed if (statusBarManager) { statusBarManager.dispose(); } if (quickActionsStatusBarItem) { quickActionsStatusBarItem.dispose(); } } exports.deactivate = deactivate; // Core server functions async function startServer() { try { const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (!workspaceFolder) { vscode.window.showErrorMessage('No workspace folder found. Please open a folder first.'); return; } // Always reload configuration const config = await config_manager_1.ConfigManager.loadConfig(workspaceFolder.uri.fsPath); // Debug: Log the exact config object being passed to LiveServer outputChannel.appendLine(`🔍 Debug - startServer - Config object being passed to LiveServer:`); outputChannel.appendLine(` Config object: ${JSON.stringify({ port: config.port, https: config.https, spa: config.spa, openBrowser: config.openBrowser, showOverlay: config.showOverlay, })}`); // Check if server is already running if (liveServer && liveServer.isRunning()) { vscode.window.showInformationMessage('Server is already running!'); return; } // Create and start server liveServer = new live_server_1.LiveServer(workspaceFolder.uri.fsPath, config, outputChannel); liveServer.on('started', (port, https) => { // Always use the correct protocol based on the current config const protocol = https ? 'https' : 'http'; const url = `${protocol}://localhost:${port}`; statusBarManager.updateStatus(true, port); outputChannel.appendLine(`✅ Server started at ${url}`); // Auto-open browser if configured if (config.openBrowser) { vscode.env.openExternal(vscode.Uri.parse(url)); outputChannel.appendLine(`🌐 Browser opened automatically: ${url}`); } // Show notification vscode.window .showInformationMessage(`Advanced Live Server started at ${url}`, 'Open Browser') .then(selection => { if (selection === 'Open Browser') { vscode.env.openExternal(vscode.Uri.parse(url)); } }); }); liveServer.on('stopped', () => { statusBarManager.updateStatus(false); outputChannel.appendLine('🛑 Server stopped'); }); liveServer.on('error', (error) => { vscode.window.showErrorMessage(`Server error: ${error}`); outputChannel.appendLine(`❌ Error: ${error}`); }); await liveServer.start(); updateServerStatusBar(true); } catch (error) { vscode.window.showErrorMessage(`Failed to start server: ${error}`); outputChannel.appendLine(`❌ Failed to start server: ${error}`); updateServerStatusBar(false); } } async function stopServer() { if (liveServer && liveServer.isRunning()) { await liveServer.stop(); liveServer = null; vscode.window.showInformationMessage('Server stopped'); updateServerStatusBar(false); } else { vscode.window.showInformationMessage('No server is currently running'); updateServerStatusBar(false); } } async function restartServer() { await stopServer(); // Add a small delay to ensure the old server is fully stopped setTimeout(async () => { try { // Force reload configuration before starting const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (workspaceFolder) { // Force VSCode to reload configuration await forceReloadVSCodeConfig(); // Wait a moment for any pending configuration changes to be processed await new Promise(resolve => setTimeout(resolve, 1000)); const config = await config_manager_1.ConfigManager.loadConfig(workspaceFolder.uri.fsPath); outputChannel.appendLine(`🔄 Restarting server with updated configuration...`); outputChannel.appendLine(`🔧 Port: ${config.port}`); outputChannel.appendLine(`🔒 HTTPS: ${config.https ? 'Enabled' : 'Disabled'}`); // Debug: Log the exact config object being passed to LiveServer outputChannel.appendLine(`🔍 Debug - Config object being passed to LiveServer:`); outputChannel.appendLine(` Config object: ${JSON.stringify({ port: config.port, https: config.https, spa: config.spa, openBrowser: config.openBrowser, showOverlay: config.showOverlay, })}`); // Create new server instance with fresh config liveServer = new live_server_1.LiveServer(workspaceFolder.uri.fsPath, config, outputChannel); liveServer.on('started', (port, https) => { const protocol = https ? 'https' : 'http'; const url = `${protocol}://localhost:${port}`; statusBarManager.updateStatus(true, port); outputChannel.appendLine(`✅ Server restarted at ${url}`); // Auto-open browser if configured if (config.openBrowser) { vscode.env.openExternal(vscode.Uri.parse(url)); outputChannel.appendLine(`🌐 Browser opened automatically: ${url}`); } // Show notification vscode.window .showInformationMessage(`Advanced Live Server restarted at ${url}`, 'Open Browser') .then(selection => { if (selection === 'Open Browser') { vscode.env.openExternal(vscode.Uri.parse(url)); } }); }); liveServer.on('stopped', () => { statusBarManager.updateStatus(false); outputChannel.appendLine('🛑 Server stopped'); }); liveServer.on('error', (error) => { vscode.window.showErrorMessage(`Server error: ${error}`); outputChannel.appendLine(`❌ Error: ${error}`); }); await liveServer.start(); updateServerStatusBar(true); } } catch (error) { vscode.window.showErrorMessage(`Failed to restart server: ${error}`); outputChannel.appendLine(`❌ Failed to restart server: ${error}`); updateServerStatusBar(false); } }, 500); } async function forceReloadVSCodeConfig() { // Force VSCode to reload the configuration by accessing it multiple times const config = vscode.workspace.getConfiguration('advancedLiveServer'); // Read all values to force a reload const values = { port: config.get('port'), https: config.get('https'), spa: config.get('spa'), openBrowser: config.get('openBrowser'), showOverlay: config.get('showOverlay'), }; outputChannel.appendLine(`🔄 Force reloading VSCode config: ${JSON.stringify(values)}`); // Wait for configuration to be fully loaded await new Promise(resolve => setTimeout(resolve, 500)); } async function openInBrowser() { if (!liveServer || !liveServer.isRunning()) { vscode.window.showErrorMessage('Server is not running'); return; } const editor = vscode.window.activeTextEditor; if (editor) { // If there's an active editor, try to open the current file const document = editor.document; const filePath = document.uri.fsPath; const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (workspaceFolder) { // Check if it's a web file const supportedExtensions = ['.html', '.htm', '.css', '.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte']; if (supportedExtensions.some(ext => filePath.toLowerCase().endsWith(ext))) { // Open the current file const relativePath = vscode.workspace.asRelativePath(filePath); const serverInfo = liveServer.getServerInfo(); if (serverInfo) { const fileUrl = `${serverInfo.url}/${relativePath.replace(/\\/g, '/')}`; outputChannel.appendLine(`🌐 Opening current file: ${fileUrl}`); vscode.env.openExternal(vscode.Uri.parse(fileUrl)); return; } } } } // Fallback to opening the root URL const serverInfo = liveServer.getServerInfo(); if (serverInfo) { outputChannel.appendLine(`🌐 Opening root URL: ${serverInfo.url}`); vscode.env.openExternal(vscode.Uri.parse(serverInfo.url)); } } async function openCurrentFile() { const editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showErrorMessage('No active editor'); return; } if (!liveServer || !liveServer.isRunning()) { vscode.window.showErrorMessage('Server is not running. Please start the server first.'); return; } const document = editor.document; const filePath = document.uri.fsPath; const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (!workspaceFolder) { vscode.window.showErrorMessage('No workspace folder found'); return; } // Get relative path from workspace root const relativePath = vscode.workspace.asRelativePath(filePath); // Debug: Log the file paths outputChannel.appendLine(`🔍 Debug - openCurrentFile:`); outputChannel.appendLine(` Full file path: ${filePath}`); outputChannel.appendLine(` Workspace folder: ${workspaceFolder.uri.fsPath}`); outputChannel.appendLine(` Relative path: ${relativePath}`); // Check if it's an HTML file or other web file const supportedExtensions = ['.html', '.htm', '.css', '.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte']; const fileExtension = document.languageId; if (!supportedExtensions.some(ext => filePath.toLowerCase().endsWith(ext))) { vscode.window.showInformationMessage('Current file is not a web file. Opening workspace root instead.'); openInBrowser(); return; } const serverInfo = liveServer.getServerInfo(); if (serverInfo) { const fileUrl = `${serverInfo.url}/${relativePath.replace(/\\/g, '/')}`; outputChannel.appendLine(`🌐 Opening current file: ${fileUrl}`); vscode.env.openExternal(vscode.Uri.parse(fileUrl)); } } function showStatus() { if (liveServer && liveServer.isRunning()) { const serverInfo = liveServer.getServerInfo(); vscode.window.showInformationMessage(`Server running on ${serverInfo?.url || 'unknown port'}`); } else { vscode.window.showInformationMessage('Server is not running'); } } async function stopCloudPreview() { // if (cloudPreviewManager.isTunnelActive()) { // Removed // await cloudPreviewManager.stopTunnel(); // Removed // } else { // Removed // vscode.window.showInformationMessage( // Removed // 'No cloud preview is currently running' // Removed // ); // Removed // } // Removed } // Settings functions function openSettings() { vscode.commands.executeCommand('workbench.action.openSettings', '@ext:teck.advanced-live-server'); } async function resetSettings() { try { const confirm = await vscode.window.showWarningMessage('Are you sure you want to reset all Advanced Live Server settings to defaults?', { modal: true }, 'Reset Settings'); if (confirm === 'Reset Settings') { const config = vscode.workspace.getConfiguration('advancedLiveServer'); // Reset to defaults await config.update('port', 5500, vscode.ConfigurationTarget.Global); await config.update('https', false, vscode.ConfigurationTarget.Global); await config.update('spa', false, vscode.ConfigurationTarget.Global); await config.update('openBrowser', true, vscode.ConfigurationTarget.Global); await config.update('showOverlay', true, vscode.ConfigurationTarget.Global); await config.update('autoStart', false, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage('✅ Settings reset to defaults!'); } } catch (error) { vscode.window.showErrorMessage(`Failed to reset settings: ${error}`); } } async function openVSCodeSettings() { vscode.commands.executeCommand('workbench.action.openSettings', '@ext:teck.advanced-live-server'); } async function quickSettings() { const items = [ { label: '🔧 Port', description: 'Change server port', command: 'changePort' }, { label: '🔒 HTTPS', description: 'Toggle HTTPS', command: 'toggleHttps' }, { label: '📱 SPA Mode', description: 'Toggle SPA mode', command: 'toggleSpa' }, { label: '🌐 Auto-open Browser', description: 'Toggle auto-open browser', command: 'toggleAutoOpen' }, { label: '📊 Show Overlay', description: 'Toggle status overlay', command: 'toggleOverlay' }, { label: '🚀 Auto-start', description: 'Toggle auto-start on workspace open', command: 'toggleAutoStart' }, { label: '📋 Show Current Settings', description: 'View all current settings', command: 'showCurrentSettings' }, { label: '⚙️ Open Full Settings', description: 'Open VS Code settings', command: 'openVSCodeSettings' }, ]; const selected = await vscode.window.showQuickPick(items, { placeHolder: 'Select a setting to change...', }); if (selected) { switch (selected.command) { case 'changePort': const port = await vscode.window.showInputBox({ prompt: 'Enter new port number:', value: '5500', validateInput: (value) => { const num = parseInt(value); return (num >= 1 && num <= 65535) ? null : 'Port must be between 1 and 65535'; } }); if (port) { await vscode.workspace.getConfiguration('advancedLiveServer').update('port', parseInt(port), vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`✅ Port changed to ${port}`); } break; case 'toggleHttps': const currentHttps = vscode.workspace.getConfiguration('advancedLiveServer').get('https', false); await vscode.workspace.getConfiguration('advancedLiveServer').update('https', !currentHttps, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`✅ HTTPS ${!currentHttps ? 'enabled' : 'disabled'}`); break; case 'toggleSpa': const currentSpa = vscode.workspace.getConfiguration('advancedLiveServer').get('spa', false); await vscode.workspace.getConfiguration('advancedLiveServer').update('spa', !currentSpa, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`✅ SPA mode ${!currentSpa ? 'enabled' : 'disabled'}`); break; case 'toggleAutoOpen': const currentAutoOpen = vscode.workspace.getConfiguration('advancedLiveServer').get('openBrowser', true); await vscode.workspace.getConfiguration('advancedLiveServer').update('openBrowser', !currentAutoOpen, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`✅ Auto-open browser ${!currentAutoOpen ? 'enabled' : 'disabled'}`); break; case 'toggleOverlay': const currentOverlay = vscode.workspace.getConfiguration('advancedLiveServer').get('showOverlay', true); await vscode.workspace.getConfiguration('advancedLiveServer').update('showOverlay', !currentOverlay, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`✅ Status overlay ${!currentOverlay ? 'enabled' : 'disabled'}`); break; case 'toggleAutoStart': const currentAutoStart = vscode.workspace.getConfiguration('advancedLiveServer').get('autoStart', false); await vscode.workspace.getConfiguration('advancedLiveServer').update('autoStart', !currentAutoStart, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`✅ Auto-start ${!currentAutoStart ? 'enabled' : 'disabled'}`); break; case 'showCurrentSettings': showCurrentSettings(); break; case 'openVSCodeSettings': openVSCodeSettings(); break; } } } async function showCurrentSettings() { const config = vscode.workspace.getConfiguration('advancedLiveServer'); const settings = { 'Port': config.get('port', 5500), 'HTTPS': config.get('https', false) ? '✅ Enabled' : '❌ Disabled', 'SPA Mode': config.get('spa', false) ? '✅ Enabled' : '❌ Disabled', 'Auto-open Browser': config.get('openBrowser', true) ? '✅ Enabled' : '❌ Disabled', 'Show Overlay': config.get('showOverlay', true) ? '✅ Enabled' : '❌ Disabled', 'Auto-start': config.get('autoStart', false) ? '✅ Enabled' : '❌ Disabled', }; const content = Object.entries(settings) .map(([key, value]) => `${key}: ${value}`) .join('\n'); const doc = await vscode.workspace.openTextDocument({ content: `Advanced Live Server - Current Settings\n\n${content}\n\nLast updated: ${new Date().toLocaleString()}`, language: 'markdown', }); await vscode.window.showTextDocument(doc); } function showAIAnalysis(result) { const panel = vscode.window.createWebviewPanel('aiAnalysis', `AI Analysis: ${result.title}`, vscode.ViewColumn.One, { enableScripts: true }); panel.webview.html = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>AI Analysis</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; padding: 20px; background-color: var(--vscode-editor-background, #1e1e1e); color: var(--vscode-editor-foreground, #222); } h1, h2, p, li { color: var(--vscode-editor-foreground, #222); } .severity-high { color: var(--vscode-editorError-foreground, #d73a49); } .severity-medium { color: var(--vscode-editorWarning-foreground, #f6a434); } .severity-low { color: var(--vscode-editorInfo-foreground, #28a745); } .suggestion { background: var(--vscode-editorWidget-background, #f6f8fa); color: var(--vscode-editor-foreground, #222); padding: 10px; margin: 10px 0; border-radius: 4px; border: 1px solid var(--vscode-editorWidget-border, #ccc); } </style> </head> <body> <h1>${result.title}</h1> <p class="severity-${result.severity}"><strong>Severity: ${result.severity}</strong></p> <div>${result.description.replace(/\n/g, '<br>')}</div> <h2>Suggestions:</h2> <ul> ${result.suggestions.map((s) => `<li class="suggestion">${s}</li>`).join('')} </ul> </body> </html> `; } // CI/CD functions async function triggerBuild() { const providers = ['github', 'gitlab', 'netlify', 'vercel', 'custom']; const provider = await vscode.window.showQuickPick(providers, { placeHolder: 'Select build provider', }); if (provider) { try { // cicdService.triggerBuild(provider as any); // Removed vscode.window.showInformationMessage(`Build ${'started' /* result.success ? 'started' : 'failed' */}: ${'output' /* result.output */}`); } catch (error) { vscode.window.showErrorMessage(`Build failed: ${error}`); } } } async function runTests() { try { // testingService.runTests(); // Removed vscode.window.showInformationMessage(`Tests completed: ${'passed' /* results.filter(r => r.success).length */}/${'total' /* results.length */} passed`); } catch (error) { vscode.window.showErrorMessage(`Tests failed: ${error}`); } } async function deploy() { const providers = ['netlify', 'vercel', 'custom']; const provider = await vscode.window.showQuickPick(providers, { placeHolder: 'Select deployment provider', }); if (provider) { try { // cicdService.triggerBuild(provider as any); // Removed vscode.window.showInformationMessage(`Deployed to: ${'url' /* result.url */}`); } catch (error) { vscode.window.showErrorMessage(`Deployment failed: ${error}`); } } } // DOM Inspector functions async function openDOMInspector() { try { // domInspector.openInspector(); // Removed } catch (error) { vscode.window.showErrorMessage(`Failed to open DOM inspector: ${error}`); } } async function analyzeDOM() { const editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showErrorMessage('No active editor'); return; } try { // domInspector.analyzeDOM(editor.document.getText()); // Removed vscode.window.showInformationMessage(`DOM Analysis: ${'analysis.nodes.length' /* analysis.nodes.length */} nodes, ${'analysis.issues.length' /* analysis.issues.length */} issues`); } catch (error) { vscode.window.showErrorMessage(`DOM analysis failed: ${error}`); } } function highlightNode(node) { // Implementation for highlighting nodes in the editor vscode.window.showInformationMessage(`Highlighting node: ${node.tagName}`); } // Testing functions async function runUnitTests() { try { // testingService.runTests('jest'); // Removed const result = { passedTests: 'result.passedTests', totalTests: 'result.totalTests' }; vscode.window.showInformationMessage(`Unit tests: ${result.passedTests}/${result.totalTests} passed`); } catch (error) { vscode.window.showErrorMessage(`Unit tests failed: ${error}`); } } async function runIntegrationTests() { try { // testingService.runTests('cypress'); // Removed const result = { passedTests: 'result.passedTests', totalTests: 'result.totalTests' }; vscode.window.showInformationMessage(`Integration tests: ${result.passedTests}/${result.totalTests} passed`); } catch (error) { vscode.window.showErrorMessage(`Integration tests failed: ${error}`); } } async function runVisualTests() { try { // testingService.runVisualRegressionTests(); // Removed vscode.window.showInformationMessage(`Visual tests: N/A`); } catch (error) { vscode.window.showErrorMessage(`Visual tests failed: ${error}`); } } function showTestResults() { const results = { /* testingService.getTestResults() */}; const panel = vscode.window.createWebviewPanel('testResults', 'Test Results', vscode.ViewColumn.One, { enableScripts: true }); panel.webview.html = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Test Results</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; padding: 20px; } .test-result { margin: 10px 0; padding: 10px; border-radius: 4px; } .passed { background: #d4edda; color: #155724; } .failed { background: #f8d7da; color: #721c24; } </style> </head> <body> <h1>Test Results</h1> ${''} </body> </html> `; } // Plugin functions async function installPlugin() { const query = await vscode.window.showInputBox({ placeHolder: 'Search for plugins...', }); if (query) { try { // pluginManager.searchPlugins(query); // Removed vscode.window.showInformationMessage('No plugins found'); } catch (error) { vscode.window.showErrorMessage(`Failed to install plugin: ${error}`); } } } async function uninstallPlugin() { const plugins = []; if (plugins.length === 0) { vscode.window.showInformationMessage('No plugins installed'); return; } const plugin = await vscode.window.showQuickPick(plugins.map(p => ({ label: p.name, description: p.version, plugin: p })), { placeHolder: 'Select plugin to uninstall' }); if (plugin) { try { // pluginManager.uninstallPlugin(plugin.plugin.id); // Removed vscode.window.showInformationMessage(`Plugin ${plugin.plugin.name} uninstalled`); } catch (error) { vscode.window.showErrorMessage(`Failed to uninstall plugin: ${error}`); } } } async function enablePlugin() { const plugins = []; if (plugins.length === 0) { vscode.window.showInformationMessage('No disabled plugins'); return; } const plugin = await vscode.window.showQuickPick(plugins.map(p => ({ label: p.name, description: p.version, plugin: p })), { placeHolder: 'Select plugin to enable' }); if (plugin) { try { // pluginManager.enablePlugin(plugin.plugin.id); // Removed vscode.window.showInformationMessage(`Plugin ${plugin.plugin.name} enabled`); } catch (error) { vscode.window.showErrorMessage(`Failed to enable plugin: ${error}`); } } } async function disablePlugin() { const plugins = []; if (plugins.length === 0) { vscode.window.showInformationMessage('No enabled plugins'); return; } const plugin = await vscode.window.showQuickPick(plugins.map(p => ({ label: p.name, description: p.version, plugin: p })), { placeHolder: 'Select plugin to disable' }); if (plugin) { try { // pluginManager.disablePlugin(plugin.plugin.id); // Removed vscode.window.showInformationMessage(`Plugin ${plugin.plugin.name} disabled`); } catch (error) { vscode.window.showErrorMessage(`Failed to disable plugin: ${error}`); } } } async function updatePlugin() { const plugins = []; if (plugins.length === 0) { vscode.window.showInformationMessage('No plugins installed'); return; } const plugin = await vscode.window.showQuickPick(plugins.map(p => ({ label: p.name, description: p.version, plugin: p })), { placeHolder: 'Select plugin to update' }); if (plugin) { try { // pluginManager.updatePlugin(plugin.plugin.id); // Removed vscode.window.showInformationMessage(`Plugin ${plugin.plugin.name} updated`); } catch (error) { vscode.window.showErrorMessage(`Failed to update plugin: ${error}`); } } } async function searchPlugins() { const query = await vscode.window.showInputBox({ placeHolder: 'Search for plugins...', }); if (query) { try { // pluginManager.searchPlugins(query); // Removed vscode.window.showInformationMessage(`Found ${'0' /* plugins.length */} plugins`); } catch (error) { vscode.window.showErrorMessage(`Search failed: ${error}`); } } } function showPlugins() { const plugins = []; const panel = vscode.window.createWebviewPanel('plugins', 'Installed Plugins', vscode.ViewColumn.One, { enableScripts: true }); panel.webview.html = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Installed Plugins</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; padding: 20px; } .plugin { margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; } .enabled { border-left: 4px solid #28a745; } .disabled { border-left: 4px solid #dc3545; } </style> </head> <body> <h1>Installed Plugins (${plugins.length})</h1> ${''} </body> </html> `; } // Offline Cloud functions async function startOfflineCloud() { try { // offlineCloudService.start(); // Removed const url = { /* offlineCloudService.getServiceUrl() */}; vscode.window.showInformationMessage(`Offline cloud started: ${url}`); } catch (error) { vscode.window.showErrorMessage(`Failed to start offline cloud: ${error}`); } } async function stopOfflineCloud() { try { // offlineCloudService.stop(); // Removed vscode.window.showInformationMessage('Offline cloud stopped'); } catch (error) { vscode.window.showErrorMessage(`Failed to stop offline cloud: ${error}`); } } function showCloudAnalytics() { const analytics = { /* offlineCloudService.getAnalytics() */}; const resources = { /* offlineCloudService.getResources() */}; const panel = vscode.window.createWebviewPanel('cloudAnalytics', 'Cloud Analytics', vscode.ViewColumn.One, { enableScripts: true }); panel.webview.html = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Cloud Analytics</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; padding: 20px; } .metric { display: inline-block; margin: 10px; padding: 15px; background: #f8f9fa; border-radius: 4px; } .metric-value { font-size: 24px; font-weight: bold; color: #007bff; } </style> </head> <body> <h1>Cloud Analytics</h1> <div> <div class="metric"> <div class="metric-value">0</div> <div>Requests</div> </div> <div class="metric"> <div class="metric-value">0</div> <div>Bandwidth (MB)</div> </div> <div class="metric"> <div class="metric-value">0</div> <div>Errors</div> </div> <div class="metric"> <div class="metric-value">0</div> <div>Resources</div> </div> </div> </body> </html> `; } // REMOVED DUPLICATE updateCodeAnalyzers function // Project-wide AI analysis functions - REMOVED DUPLICATE async function showProjectAnalysis(results, processedFiles, totalFiles, type = 'Project') { // Helper function to safely extract issue information const getIssueInfo = (result) => { if (result.severity && result.message && result.file) { return { severity: result.severity, message: result.message, file: result.file, line: result.line || 'N/A', }; } // Handle old format with suggestions array if (result.suggestions && Array.isArray(result.suggestions)) { return result.suggestions.map((suggestion) => ({ severity: 'medium', message: suggestion, file: result.fileName || 'Unknown', line: 'N/A', })); } // Handle string messages if (typeof result === 'string') { return { severity: 'medium', message: result, file: 'Unknown', line: 'N/A', }; } return null; }; // Extract and flatten all issues const allIssues = results.flatMap(result => { const issueInfo = getIssueInfo(result); return issueInfo ? Array.isArray(issueInfo) ? issueInfo : [issueInfo] : []; }); // Count issues by severity const criticalIssues = allIssues.filter(issue => issue.severity === 'critical'); const highIssues = allIssues.filter(issue => issue.severity === 'high'); const mediumIssues = allIssues.filter(issue => issue.severity === 'medium'); const lowIssues = allIssues.filter(issue => issue.severity === 'low'); const document = await vscode.workspace.openTextDocument({ content: `# ${type} Analysis Results ## 📊 Summary - **Files analyzed:** ${processedFiles}/${totalFiles} - **Critical issues:** ${criticalIssues.length} - **High priority issues:** ${highIssues.length} - **Medium priority issues:** ${mediumIssues.length} - **Low priority issues:** ${lowIssues.length} ## 🔴 Critical Issues ${criticalIssues.length > 0 ? criticalIssues .map(issue => ` ### ${issue.file} - **${issue.message}** (Line ${issue.line}) `) .join('') : '- No critical issues found'} ## 🟠 High Priority Issues ${highIssues.length > 0 ? highIssues .slice(0, 10) .map(issue => ` ### ${issue.file} - **${issue.message}** (Line ${issue.line}) `) .join('') : '- No high priority issues found'} ## 🟡 Medium Priority Issues ${mediumIssues.length > 0 ? mediumIssues .slice(0, 5) .map(issue => ` ### ${issue.file} - **${issue.message}** (Line ${issue.line}) `) .join('') : '- No medium priority issues found'} ## 📈 Recommendations ### Security ${allIssues.some(issue => issue.message && (issue.message.includes('XSS') || issue.message.includes('CSP') || issue.message.includes('security'))) ? ` - **Add Content Security Policy headers** to prevent XSS attacks - **Use textContent instead of innerHTML** for user-generated content - **Validate and sanitize all user inputs** ` : '- No critical security issues found'} ### Performance ${allIssues.some(issue => issue.message && (issue.message.includes('performance') || issue.message.includes('optimization'))) ? ` - **Optimize long lines** for better readability - **Consider code splitting** for large files ` : '- No performance issues detected'} ### Code Quality ${allIssues.some(issue => issue.message && (issue.message.includes('indentation') || issue.message.includes('formatting'))) ? ` - **Run a code formatter** (Prettier, ESLint) to fix formatting issues - **Use consistent indentation** (2 or 4 spaces) - **Add "use strict" directive** for better error checking ` : '- Code quality looks good'} ## 🛠️ Quick Fixes 1. **Format code:** Run \`npm run format\` or use Prettier 2. **Fix security:** Add CSP headers and use textContent 3. **Add linting:** Install ESLint for automatic code quality checks ## 📋 Detailed Report For a complete list of all issues, run the analysis again with detailed mode enabled. --- *Analysis generated by Advanced Live Server on ${new Date().toLocaleString()}*`, language: 'markdown', }); await vscode.window.showTextDocument(document); } // Minimal Quick Actions menu for open source core async function showQuickActions() { const items = [ { label: '✨ Advanced Live Server — All Features Free!', kind: 2 }, { label: ' ', kind: 2 }, { label: '🚀 Server Actions', kind: 2 }, { label: ' • Start Server', description: 'Start the live server', command: 'advancedLiveServer.start', detail: 'Launch your local development server.' }, { label: ' • Stop Server', description: 'Stop the live server', command: 'advancedLiveServer.stop', detail: 'Shut down the running server.' }, { label: ' • Restart Server', description: 'Restart the live server', command: 'advancedLiveServer.restart', detail: 'Restart the server for fresh config.' }, { label: ' • Open in Browser', description: 'Open the current file in browser', command: 'advancedLiveServer.openInBrowser', detail: 'Preview your site instantly.' }, { label: ' ', kind: 2 }, { label: '⚙️ Settings', kind: 2 }, { label: ' • Quick Settings', description: 'Quick settings menu', command: 'advancedLiveServer.quickSettings', detail: 'Change common settings fast.' }, { label: ' • Show Settings', description: 'Show current settings', command: 'advancedLiveServer.showCurrentSettings', detail: 'View all current config values.' }, { label: ' • Open Settings Panel', description: 'Open extension settings panel', command: 'advancedLiveServer.openSettings', detail: 'Full-featured settings UI.' }, { label: ' ', kind: 2 }, { label: '🤖 AI Tools', kind: 2 }, { label: ' • AI Error Analysis', description: 'Analyze errors with AI', command: 'advancedLiveServer.analyzeError', detail: 'Get smart explanations for errors.' }, { label: ' • AI Code Suggestions', description: 'Get AI-powered code improvements', command: 'advancedLiveServer.suggestImprovements', detail: 'Improve your code with AI.' }, { label: ' • AI Accessibility Analysis', description: 'Check accessibility with AI', command: 'advancedLiveServer.analyzeAccessibility', detail: 'Make your site more accessible.' }, { label: ' • AI Settings', description: 'Configure AI providers', command: 'advancedLiveServer.openAISettings', detail: 'Set up OpenAI, Ollama, OpenRouter, and more.' }, { label: ' ', kind: 2 }, { label: '☁️ Cloud & Collaboration', kind: 2 }, { label: ' • Start Cloud Preview', description: 'Share your server with a public URL (ngrok)', command: 'advancedLiveServer.startCloudPreview', detail: 'Get a public link for your site.' }, { label: ' • Start Collaboration', description: 'Collaborate with your team', command: 'advancedLiveServer.startCollaboration', detail: 'Work together in real time.' }, { label: ' • Add Custom Domain', description: 'Add a custom domain for cloud preview', command: 'advancedLiveServer.addCustomDomain', detail: 'Use your own domain for previews.' }, { label: ' ', kind: 2 }, { label: '📊 Analytics & Support', kind: 2 }, { label: ' • Performance Analysis', description: 'Analyze site performance', command: 'advancedLiveServer.analyzePerformance', detail: 'Audit speed and best practices.' }, { label: ' • SEO Analysis', description: 'Analyze SEO for your site', command: 'advancedLiveServer.analyzeSEO', detail: 'Get tips to boost search ranking.' }, { label: ' • Security Scan', description: 'Scan for security issues', command: 'advancedLiveServer.securityScan', detail: 'Find and fix vulnerabilities.' }, { label: ' • Show Analytics', description: 'View advanced analytics', command: 'advancedLiveServer.showAnalytics', detail: 'See usage and performance stats.' }, { label: ' • Create Support Ticket', description: 'Request support or features', command: 'advancedLiveServer.createSupportTicket', detail: 'Get help or suggest new features.' }, { label: ' ', kind: 2 }, { label: '📚 Help & Documentation', kind: 2 }, { label: ' • Show Welcome', description: 'Show welcome page with full guide', command: 'advancedLiveServer.showWelcome', detail: 'Complete guide to all features.' }, { label: ' ', kind: 2 }, { label: '❤️ Thank you for using Advanced Live Server!', kind: 2 }, ]; const selected = await vscode.window.showQuickPick(items, { placeHolder: '✨ Select an action — all features are now free and open source!', matchOnDescription: true, matchOnDetail: true, ignoreFocusOut: true, }); if (selected && selected.command) { vscode.commands.executeCommand(selected.command); } } // Register the quick actions command commands.push(vscode.commands.registerCommand('advancedLiveServer.showQuickActions', showQuickActions)); // REMOVED DUPLICATE captureScreenshot function // Licensing and Premium Features functions async function showLicenseStatus() { try { // licensingService.showLicenseStatus(); // Removed } catch (error) { vscode.window.showErrorMessage(`Failed to show license status: ${error}`); } } async function enterLicenseKey() { try { // licensingService.promptForLicenseKey(); // Removed } catch (error) { vscode.window.showErrorMessage(`Failed to enter license key: ${error}`); } } async function showPremiumStatus() { try { //