Skip to main content
Glama
script-generator.js7.14 kB
const fs = require('fs'); const path = require('path'); const os = require('os'); const chalk = require('chalk'); /** * 脚本生成器 - 为服务器生成连接脚本 */ class ScriptGenerator { constructor(configManager) { this.configManager = configManager; this.templatePath = path.join(__dirname, '..', 'templates', 'connection-script-template.sh'); this.outputDir = path.join(os.homedir(), '.cursor-bridge', 'scripts'); } /** * 为所有服务器生成连接脚本 */ async generateAllScripts() { const servers = this.configManager.listServers(); if (servers.length === 0) { console.log(chalk.yellow('❌ 没有找到服务器配置')); return false; } // 确保输出目录存在 if (!fs.existsSync(this.outputDir)) { fs.mkdirSync(this.outputDir, { recursive: true }); console.log(chalk.blue(`📁 创建脚本目录: ${this.outputDir}`)); } let successCount = 0; for (const server of servers) { try { await this.generateScript(server); successCount++; } catch (error) { console.log(chalk.red(`❌ 生成脚本失败 (${server.id}): ${error.message}`)); } } console.log(chalk.green(`✅ 成功生成 ${successCount}/${servers.length} 个连接脚本`)); console.log(chalk.gray(`📁 脚本位置: ${this.outputDir}`)); return successCount > 0; } /** * 为特定服务器生成连接脚本 */ async generateScript(server, sessionName = 'default') { if (!fs.existsSync(this.templatePath)) { throw new Error(`模板文件不存在: ${this.templatePath}`); } // 读取模板 const template = fs.readFileSync(this.templatePath, 'utf8'); // 替换变量 const script = this.replaceTemplateVariables(template, server, sessionName); // 生成脚本文件名 const scriptName = `connect_${server.id}.sh`; const scriptPath = path.join(this.outputDir, scriptName); // 写入脚本文件 fs.writeFileSync(scriptPath, script); // 设置执行权限 fs.chmodSync(scriptPath, 0o755); console.log(chalk.green(`✅ 生成脚本: ${scriptName}`)); return scriptPath; } /** * 替换模板变量 */ replaceTemplateVariables(template, server, sessionName) { const replacements = { '{{SERVER_ID}}': server.id || 'unknown', '{{SERVER_NAME}}': server.name || server.id, '{{SERVER_HOST}}': server.host || 'localhost', '{{JUMP_HOST}}': server.jump_host || '', '{{CONTAINER_NAME}}': server.container_name || 'user_container', '{{SESSION_NAME}}': sessionName || 'default' }; let result = template; for (const [placeholder, value] of Object.entries(replacements)) { result = result.replace(new RegExp(placeholder, 'g'), value); } return result; } /** * 获取特定服务器的脚本路径 */ getScriptPath(serverId) { const scriptName = `connect_${serverId}.sh`; return path.join(this.outputDir, scriptName); } /** * 检查脚本是否存在 */ scriptExists(serverId) { const scriptPath = this.getScriptPath(serverId); return fs.existsSync(scriptPath); } /** * 列出所有生成的脚本 */ listGeneratedScripts() { if (!fs.existsSync(this.outputDir)) { return []; } const files = fs.readdirSync(this.outputDir); return files .filter(file => file.startsWith('connect_') && file.endsWith('.sh')) .map(file => { const serverId = file.replace('connect_', '').replace('.sh', ''); const scriptPath = path.join(this.outputDir, file); const stats = fs.statSync(scriptPath); return { serverId, fileName: file, path: scriptPath, size: stats.size, modified: stats.mtime }; }); } /** * 显示脚本使用说明 */ showUsageInstructions() { const scripts = this.listGeneratedScripts(); if (scripts.length === 0) { console.log(chalk.yellow('❌ 没有找到生成的脚本')); return; } console.log(chalk.blue('\\n🚀 连接脚本使用说明:\\n')); scripts.forEach(script => { const server = this.configManager.getServerConfig(script.serverId); const serverName = server ? server.name : script.serverId; console.log(chalk.green(`📋 ${serverName} (${script.serverId})`)); console.log(chalk.gray(` 脚本: ${script.path}`)); console.log(chalk.gray(' 用法:')); console.log(chalk.gray(` ${script.path} connect # SSH连接`)); console.log(chalk.gray(` ${script.path} docker # Docker环境`)); console.log(chalk.gray(` ${script.path} tmux # tmux会话`)); console.log(chalk.gray(` ${script.path} full # 完整流程`)); console.log(''); }); console.log(chalk.blue('💡 提示:')); console.log(' • 脚本支持多种连接模式'); console.log(' • 使用 full 模式获得最佳体验'); console.log(' • 可以直接在终端中执行这些脚本'); } /** * 更新所有脚本 */ async updateAllScripts() { console.log(chalk.blue('🔄 更新所有连接脚本...')); // 删除旧脚本 if (fs.existsSync(this.outputDir)) { const oldScripts = fs.readdirSync(this.outputDir) .filter(file => file.startsWith('connect_') && file.endsWith('.sh')); oldScripts.forEach(script => { fs.unlinkSync(path.join(this.outputDir, script)); }); console.log(chalk.gray(`🗑️ 删除了 ${oldScripts.length} 个旧脚本`)); } // 生成新脚本 return await this.generateAllScripts(); } /** * 清理所有脚本 */ cleanupScripts() { if (!fs.existsSync(this.outputDir)) { console.log(chalk.yellow('❌ 脚本目录不存在')); return false; } const scripts = fs.readdirSync(this.outputDir) .filter(file => file.startsWith('connect_') && file.endsWith('.sh')); scripts.forEach(script => { fs.unlinkSync(path.join(this.outputDir, script)); }); console.log(chalk.green(`🗑️ 清理了 ${scripts.length} 个脚本`)); return true; } } module.exports = ScriptGenerator;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/maricoxu/remote-terminal-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server