advanced-live-server-installer
Version:
Auto-installer for Advanced Live Server VS Code Extension
1,057 lines (1,046 loc) • 87 kB
JavaScript
"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 {
//