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

456 lines (378 loc) • 13.2 kB
#!/usr/bin/env node /** * AI-Debug Automated Setup Script * Configures AI-Debug for various AI coding environments */ const fs = require('fs'); const path = require('path'); const os = require('os'); const { execSync } = require('child_process'); // Colors for terminal output const colors = { reset: '\x1b[0m', bright: '\x1b[1m', green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m', blue: '\x1b[34m' }; function log(message, color = '') { console.log(color + message + colors.reset); } function success(message) { log('āœ… ' + message, colors.green); } function warn(message) { log('āš ļø ' + message, colors.yellow); } function error(message) { log('āŒ ' + message, colors.red); } function info(message) { log('ā„¹ļø ' + message, colors.blue); } // Get AI-Debug command path function getAiDebugPath() { try { const npmBin = execSync('npm bin -g', { encoding: 'utf8' }).trim(); const aiDebugPath = path.join(npmBin, 'ai-debug-mcp'); if (fs.existsSync(aiDebugPath)) { return aiDebugPath; } // Fallback to which command const whichPath = execSync('which ai-debug-mcp', { encoding: 'utf8' }).trim(); if (whichPath) return whichPath; } catch (e) { // Try common locations const commonPaths = [ '/usr/local/bin/ai-debug-mcp', '/usr/bin/ai-debug-mcp', path.join(os.homedir(), '.npm/bin/ai-debug-mcp'), 'ai-debug-mcp' // Let system resolve it ]; for (const p of commonPaths) { if (fs.existsSync(p)) return p; } } return 'ai-debug-mcp'; // Default fallback } // Claude Desktop setup function setupClaude() { log('\nšŸ¤– Setting up AI-Debug for Claude Desktop...', colors.bright); const platform = process.platform; let configPath; if (platform === 'darwin') { configPath = path.join(os.homedir(), 'Library/Application Support/Claude/claude_desktop_config.json'); } else if (platform === 'win32') { configPath = path.join(process.env.APPDATA || '', 'Claude/claude_desktop_config.json'); } else { configPath = path.join(os.homedir(), '.config/Claude/claude_desktop_config.json'); } // Create directory if it doesn't exist const configDir = path.dirname(configPath); if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); } let config = {}; // Read existing config if (fs.existsSync(configPath)) { try { const content = fs.readFileSync(configPath, 'utf8'); config = JSON.parse(content); info(`Found existing Claude config at: ${configPath}`); // Backup existing config const backupPath = configPath + '.backup.' + Date.now(); fs.copyFileSync(configPath, backupPath); info(`Created backup: ${backupPath}`); } catch (e) { error(`Failed to parse existing config: ${e.message}`); return false; } } // Add AI-Debug configuration if (!config.mcpServers) { config.mcpServers = {}; } const aiDebugPath = getAiDebugPath(); config.mcpServers['ai-debug'] = { command: aiDebugPath, args: [] }; // Write updated config try { fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); success('Claude Desktop configuration updated!'); info(`Config location: ${configPath}`); info(`AI-Debug command: ${aiDebugPath}`); // Check if Claude is running if (platform === 'darwin') { try { execSync('pgrep -x Claude', { stdio: 'ignore' }); warn('Claude Desktop is running. Please restart it for changes to take effect.'); } catch (e) { // Claude not running, that's fine } } return true; } catch (e) { error(`Failed to write config: ${e.message}`); return false; } } // Cursor setup function setupCursor() { log('\nāœļø Setting up AI-Debug for Cursor...', colors.bright); const platform = process.platform; let settingsPath; // Find Cursor settings path if (platform === 'darwin') { settingsPath = path.join(os.homedir(), 'Library/Application Support/Cursor/User/settings.json'); } else if (platform === 'win32') { settingsPath = path.join(process.env.APPDATA || '', 'Cursor/User/settings.json'); } else { settingsPath = path.join(os.homedir(), '.config/Cursor/User/settings.json'); } if (!fs.existsSync(settingsPath)) { warn('Cursor settings not found. Is Cursor installed?'); info('Expected location: ' + settingsPath); info('\nManual setup instructions:'); info('1. Open Cursor'); info('2. Press Cmd+, (Mac) or Ctrl+, (Windows/Linux)'); info('3. Search for "MCP"'); info('4. Add this configuration:'); console.log(JSON.stringify({ "mcp.servers": { "ai-debug": { "command": getAiDebugPath(), "args": [] } } }, null, 2)); return false; } try { // Read existing settings let settings = {}; if (fs.existsSync(settingsPath)) { const content = fs.readFileSync(settingsPath, 'utf8'); settings = JSON.parse(content); // Backup const backupPath = settingsPath + '.backup.' + Date.now(); fs.copyFileSync(settingsPath, backupPath); info(`Created backup: ${backupPath}`); } // Add MCP configuration if (!settings['mcp.servers']) { settings['mcp.servers'] = {}; } settings['mcp.servers']['ai-debug'] = { command: getAiDebugPath(), args: [] }; // Write updated settings fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2)); success('Cursor configuration updated!'); info('Please restart Cursor for changes to take effect.'); return true; } catch (e) { error(`Failed to update Cursor settings: ${e.message}`); return false; } } // Project-specific setup for Claude Code function setupProject() { log('\nšŸ“ Setting up AI-Debug for this project (Claude Code)...', colors.bright); const projectRoot = process.cwd(); const claudeDir = path.join(projectRoot, '.claude'); const configPath = path.join(claudeDir, 'claude_desktop_config.json'); // Check if we're in a project directory if (!fs.existsSync(path.join(projectRoot, 'package.json')) && !fs.existsSync(path.join(projectRoot, '.git'))) { warn('This doesn\'t appear to be a project directory.'); warn('Run this command from your project root (where package.json or .git exists)'); return false; } try { // Create .claude directory if (!fs.existsSync(claudeDir)) { fs.mkdirSync(claudeDir, { recursive: true }); info('Created .claude directory'); } let config = {}; // Check if config already exists if (fs.existsSync(configPath)) { const content = fs.readFileSync(configPath, 'utf8'); config = JSON.parse(content); info('Found existing project config'); // Backup const backupPath = configPath + '.backup.' + Date.now(); fs.copyFileSync(configPath, backupPath); info(`Created backup: ${backupPath}`); } // Add AI-Debug if (!config.mcpServers) { config.mcpServers = {}; } config.mcpServers['ai-debug'] = { command: getAiDebugPath(), args: [] }; // Write config fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); success('Project-specific AI-Debug configuration created!'); info(`Config location: ${configPath}`); // Check if .gitignore exists and offer to add .claude const gitignorePath = path.join(projectRoot, '.gitignore'); if (fs.existsSync(gitignorePath)) { const gitignore = fs.readFileSync(gitignorePath, 'utf8'); if (!gitignore.includes('.claude')) { info('\nTip: Add .claude/ to .gitignore if you don\'t want to commit this config'); info('Or commit it to share the debugging setup with your team'); } } info('\nNext steps:'); info('1. Open this project in Claude Code'); info('2. AI-Debug will be available for this project only'); info('3. Test with: await get_current_mode()'); return true; } catch (e) { error(`Failed to setup project config: ${e.message}`); return false; } } // Windsurf setup function setupWindsurf() { log('\nšŸ„ Setting up AI-Debug for Windsurf...', colors.bright); // Windsurf uses a different configuration approach // It stores MCP servers in a separate config file const platform = process.platform; let configPath; if (platform === 'darwin') { configPath = path.join(os.homedir(), 'Library/Application Support/Windsurf/mcp-servers.json'); } else if (platform === 'win32') { configPath = path.join(process.env.APPDATA || '', 'Windsurf/mcp-servers.json'); } else { configPath = path.join(os.homedir(), '.config/Windsurf/mcp-servers.json'); } const configDir = path.dirname(configPath); if (!fs.existsSync(configDir)) { warn('Windsurf configuration directory not found. Is Windsurf installed?'); info('\nManual setup instructions:'); info('1. Open Windsurf'); info('2. Go to Preferences → Extensions → MCP'); info('3. Add new MCP server:'); info(' - Name: ai-debug'); info(' - Command: ' + getAiDebugPath()); info(' - Arguments: (leave empty)'); return false; } try { let servers = {}; if (fs.existsSync(configPath)) { const content = fs.readFileSync(configPath, 'utf8'); servers = JSON.parse(content); // Backup const backupPath = configPath + '.backup.' + Date.now(); fs.copyFileSync(configPath, backupPath); info(`Created backup: ${backupPath}`); } // Add AI-Debug servers['ai-debug'] = { name: 'AI-Debug MCP Server', command: getAiDebugPath(), args: [], enabled: true }; // Write config fs.writeFileSync(configPath, JSON.stringify(servers, null, 2)); success('Windsurf configuration updated!'); info('Please restart Windsurf for changes to take effect.'); return true; } catch (e) { error(`Failed to update Windsurf config: ${e.message}`); return false; } } // Verify installation function verifyInstallation() { log('\nšŸ” Verifying AI-Debug installation...', colors.bright); const aiDebugPath = getAiDebugPath(); // Check if command exists try { const version = execSync(`${aiDebugPath} --version`, { encoding: 'utf8' }).trim(); success(`AI-Debug installed: ${aiDebugPath}`); info(`Version: ${version}`); // Check Playwright try { execSync('npx playwright --version', { stdio: 'ignore' }); success('Playwright is installed'); } catch (e) { warn('Playwright not found. Installing browser dependencies...'); try { execSync('npx playwright install chromium', { stdio: 'inherit' }); success('Playwright chromium installed'); } catch (e) { error('Failed to install Playwright. You may need to run: npx playwright install chromium'); } } return true; } catch (e) { error('AI-Debug command not found. Please ensure it\'s installed globally:'); info('npm install -g ai-debug-local-mcp'); return false; } } // Main setup function function main() { const args = process.argv.slice(2); const target = args[0] || 'all'; log('šŸš€ AI-Debug Automated Setup', colors.bright + colors.blue); log('===========================\n', colors.bright); // First verify installation if (!verifyInstallation()) { error('\nPlease install AI-Debug first:'); info('npm install -g ai-debug-local-mcp'); process.exit(1); } let setupCount = 0; let successCount = 0; if (target === 'all' || target === 'claude') { setupCount++; if (setupClaude()) successCount++; } if (target === 'all' || target === 'cursor') { setupCount++; if (setupCursor()) successCount++; } if (target === 'all' || target === 'windsurf') { setupCount++; if (setupWindsurf()) successCount++; } if (target === 'project') { setupCount++; if (setupProject()) successCount++; } if (setupCount === 0) { error(`\nUnknown target: ${target}`); info('Usage: npx ai-debug-setup [claude|cursor|windsurf|project|all]'); process.exit(1); } // Summary log('\n' + '='.repeat(50), colors.bright); if (successCount === setupCount) { success(`\nSetup complete! ${successCount}/${setupCount} environments configured.`); info('\nNext steps:'); info('1. Restart your AI coding environment'); info('2. Test with: await get_current_mode()'); info('3. Start debugging with: await inject_debugging({ url: "..." })'); } else { warn(`\nSetup partially complete: ${successCount}/${setupCount} succeeded.`); info('Check the errors above and try manual setup for failed environments.'); } info('\nFor help: https://github.com/yourusername/ai-debug-mcp'); } // Run if called directly if (require.main === module) { main(); } module.exports = { setupClaude, setupCursor, setupWindsurf };