UNPKG

mcp-booster

Version:

Servidor MCP com CoConuT (Continuous Chain of Thought) para uso com Cursor IDE - Pacote Global NPM

432 lines (430 loc) 16.7 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 () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.createCursorRules = createCursorRules; exports.cursorRulesExist = cursorRulesExist; exports.removeCursorRules = removeCursorRules; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const cache_1 = require("../utils/cache"); /** * Shows support information when errors occur */ function showSupportInfo() { console.log(''); console.log('🆘 Precisa de ajuda?'); console.log(' Nossa equipe de suporte está pronta para ajudar!'); console.log(' 📧 Entre em contato: https://llmbooster.com/suporte'); console.log(' ⏰ Horário de atendimento: Segunda a Sexta, 9h às 18h'); console.log(''); } /** * Cria cursor rules locais baseado no conteúdo do systemPrompt.md */ async function createCursorRules(config) { const debugMode = process.env.DEBUG === 'true'; try { if (debugMode) { console.log('🔍 [DEBUG] Starting cursor rules creation...'); console.log('🔍 [DEBUG] Config:', JSON.stringify(config, null, 2)); console.log('🔍 [DEBUG] Platform:', process.platform); } // Decodificar e normalizar o projectPath para resolver problemas de URL encoding no Windows const normalizedProjectPath = cache_1.PathUtils.normalizePath(config.projectPath); if (debugMode) { console.log('🔍 [DEBUG] Original path:', config.projectPath); console.log('🔍 [DEBUG] Normalized path:', normalizedProjectPath); } // Verificar se o systemPrompt.md existe antes de continuar if (!fs.existsSync(config.systemPromptPath)) { const error = `Arquivo systemPrompt.md não encontrado em: ${config.systemPromptPath}`; if (debugMode) { console.log('❌ [DEBUG] SystemPrompt file not found'); } return { success: false, message: 'SystemPrompt.md não encontrado', error }; } // Lê o conteúdo do systemPrompt.md e adiciona conteúdo do Windows se necessário const systemPromptContent = await readAndCombineSystemPrompt(config.systemPromptPath, config.windowsAuxPromptPath); if (debugMode) { console.log('🔍 [DEBUG] SystemPrompt content length:', systemPromptContent.length); } // Determina o caminho de destino (sempre local) const targetPath = getLocalCursorRulesPath(normalizedProjectPath); if (debugMode) { console.log('🔍 [DEBUG] Target path:', targetPath); } // Cria o arquivo de cursor rules locais com verificações robustas const createResult = await createCursorRulesFile(targetPath, systemPromptContent); if (!createResult.success) { return { success: false, message: 'Erro ao criar cursor rules', error: createResult.error, filePath: targetPath }; } // Verificar se o arquivo foi realmente criado e obter detalhes const verificationResult = await verifyCursorRulesFile(targetPath); if (debugMode) { console.log('🔍 [DEBUG] Verification result:', verificationResult); } return { success: true, message: 'Cursor rules locais criadas com sucesso', filePath: targetPath, details: verificationResult }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); if (debugMode) { console.log('❌ [DEBUG] Unexpected error:', errorMessage); console.log('❌ [DEBUG] Stack trace:', error instanceof Error ? error.stack : 'No stack trace'); } else { console.error('❌ Erro crítico na criação das cursor rules:', errorMessage); showSupportInfo(); } return { success: false, message: 'Erro inesperado ao criar cursor rules', error: errorMessage }; } } /** * Lê o conteúdo do arquivo systemPrompt.md base e adiciona conteúdo específico do Windows se necessário */ async function readAndCombineSystemPrompt(systemPromptPath, windowsAuxPromptPath) { const debugMode = process.env.DEBUG === 'true'; try { // Primeiro, lê o conteúdo base do systemPrompt.md const baseContent = await readSystemPrompt(systemPromptPath); // Detecta se estamos no Windows e se o arquivo auxiliar existe const { detectOS } = require('./os-detector'); const currentOS = detectOS(); if (currentOS === 'windows' && windowsAuxPromptPath && fs.existsSync(windowsAuxPromptPath)) { if (debugMode) { console.log('🪟 [DEBUG] Windows detected - adding Windows-specific content'); } // Lê o conteúdo específico do Windows const windowsContent = await readSystemPrompt(windowsAuxPromptPath); // Procura onde inserir o conteúdo do Windows no arquivo base // Vamos inserir após a seção "## Important" e antes da próxima seção const insertionPoint = baseContent.indexOf('\n## ⚠️ CRITICAL:'); if (insertionPoint !== -1) { // Insere o conteúdo do Windows antes da seção crítica const beforeInsertion = baseContent.substring(0, insertionPoint); const afterInsertion = baseContent.substring(insertionPoint); const combinedContent = beforeInsertion + '\n' + windowsContent + '\n' + afterInsertion; if (debugMode) { console.log('✅ [DEBUG] Windows content successfully combined with base content'); } return combinedContent; } else { // Se não encontrar o ponto de inserção, adiciona no final if (debugMode) { console.log('⚠️ [DEBUG] Insertion point not found, appending Windows content at the end'); } return baseContent + '\n\n' + windowsContent; } } // Se não for Windows ou arquivo não existir, retorna apenas o conteúdo base if (debugMode) { console.log(`🔍 [DEBUG] Using base system prompt only for OS: ${currentOS}`); } return baseContent; } catch (error) { if (debugMode) { console.log('❌ [DEBUG] Error combining system prompt content:', error); } throw error; } } /** * Lê o conteúdo do arquivo systemPrompt.md com verificação robusta */ async function readSystemPrompt(systemPromptPath) { const debugMode = process.env.DEBUG === 'true'; try { if (!fs.existsSync(systemPromptPath)) { throw new Error(`Arquivo systemPrompt.md não encontrado em: ${systemPromptPath}`); } // Verificar se é um arquivo e se podemos lê-lo const stats = fs.statSync(systemPromptPath); if (!stats.isFile()) { throw new Error(`O caminho não aponta para um arquivo: ${systemPromptPath}`); } // Verificar permissões de leitura try { fs.accessSync(systemPromptPath, fs.constants.R_OK); } catch { throw new Error(`Sem permissão de leitura para: ${systemPromptPath}`); } const content = fs.readFileSync(systemPromptPath, 'utf-8'); if (!content || content.trim().length === 0) { throw new Error(`Arquivo systemPrompt.md está vazio: ${systemPromptPath}`); } if (debugMode) { console.log('✅ [DEBUG] SystemPrompt read successfully, length:', content.length); } return content; } catch (error) { if (debugMode) { console.log('❌ [DEBUG] Error reading systemPrompt:', error); } throw error; } } /** * Obtém o caminho para cursor rules locais com criação segura de diretório */ function getLocalCursorRulesPath(projectPath) { const debugMode = process.env.DEBUG === 'true'; const rulesDir = path.join(projectPath, '.cursor', 'rules'); if (debugMode) { console.log('🔍 [DEBUG] Rules directory path:', rulesDir); } // Usar a função segura para criar diretório const createResult = cache_1.PathUtils.safeCreateDirectory(rulesDir); if (!createResult.success) { throw new Error(`Falha ao criar diretório .cursor/rules: ${createResult.error}`); } if (debugMode) { console.log('✅ [DEBUG] Rules directory ensured'); // Listar arquivos existentes para debug try { const existingFiles = fs.readdirSync(rulesDir).filter(file => file !== 'llmbooster.mdc'); if (existingFiles.length > 0) { console.log('🔍 [DEBUG] Existing files in rules directory:', existingFiles); } } catch (error) { console.log('⚠️ [DEBUG] Could not list existing files:', error); } } return path.join(rulesDir, 'llmbooster.mdc'); } /** * Cria o arquivo de cursor rules no formato MDC com verificações robustas */ async function createCursorRulesFile(targetPath, systemPromptContent) { const debugMode = process.env.DEBUG === 'true'; try { if (debugMode) { console.log('🔍 [DEBUG] Creating cursor rules file at:', targetPath); } // Verificar se o arquivo já existe const fileExists = fs.existsSync(targetPath); if (debugMode && fileExists) { console.log('🔍 [DEBUG] File already exists, will overwrite'); } // Verificar permissões no diretório pai const dirPath = path.dirname(targetPath); if (!cache_1.PathUtils.canWriteToDirectory(dirPath)) { return { success: false, error: `Sem permissão de escrita no diretório: ${dirPath}` }; } // Formato MDC para cursor rules locais const mdcContent = createMDCContent(systemPromptContent); if (debugMode) { console.log('🔍 [DEBUG] MDC content length:', mdcContent.length); } // Escrever o arquivo fs.writeFileSync(targetPath, mdcContent, 'utf-8'); // Verificar se foi escrito com sucesso if (!fs.existsSync(targetPath)) { return { success: false, error: `Arquivo não foi criado: ${targetPath}` }; } // Verificar se o conteúdo foi escrito corretamente const writtenContent = fs.readFileSync(targetPath, 'utf-8'); if (writtenContent !== mdcContent) { return { success: false, error: `Conteúdo do arquivo não confere com o esperado` }; } if (debugMode) { console.log('✅ [DEBUG] File created and verified successfully'); } return { success: true }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); if (debugMode) { console.log('❌ [DEBUG] Error creating file:', errorMessage); } return { success: false, error: `Erro ao escrever arquivo: ${errorMessage}` }; } } /** * Verifica se o arquivo foi criado corretamente e retorna detalhes */ async function verifyCursorRulesFile(filePath) { try { if (!fs.existsSync(filePath)) { return { fileExists: false }; } const stats = fs.statSync(filePath); // Verificar permissões let isReadable = false; let isWritable = false; try { fs.accessSync(filePath, fs.constants.R_OK); isReadable = true; } catch { } try { fs.accessSync(filePath, fs.constants.W_OK); isWritable = true; } catch { } return { fileExists: true, fileSize: stats.size, permissions: `${isReadable ? 'R' : ''}${isWritable ? 'W' : ''}`, isReadable, isWritable }; } catch (error) { return { fileExists: false }; } } /** * Cria o conteúdo no formato MDC (Markdown with metadata) */ function createMDCContent(systemPromptContent) { const metadata = { description: "LLM Booster - System Prompt Project Rules", alwaysApply: true }; return `--- description: ${metadata.description} alwaysApply: ${metadata.alwaysApply} --- ${systemPromptContent} `; } /** * Verifica se cursor rules já existem */ function cursorRulesExist(config) { try { // Decodificar o projectPath para resolver problemas de URL encoding no Windows const normalizedProjectPath = cache_1.PathUtils.normalizePath(config.projectPath); const targetPath = getLocalCursorRulesPath(normalizedProjectPath); return fs.existsSync(targetPath); } catch { return false; } } /** * Remove cursor rules existentes */ async function removeCursorRules(config) { const debugMode = process.env.DEBUG === 'true'; try { // Decodificar o projectPath para resolver problemas de URL encoding no Windows const normalizedProjectPath = cache_1.PathUtils.normalizePath(config.projectPath); const targetPath = getLocalCursorRulesPath(normalizedProjectPath); if (debugMode) { console.log('🔍 [DEBUG] Removing cursor rules at:', targetPath); } if (fs.existsSync(targetPath)) { // Verificar permissões antes de tentar remover try { fs.accessSync(targetPath, fs.constants.W_OK); } catch { return { success: false, message: 'Sem permissão para remover cursor rules', error: `Sem permissão de escrita para: ${targetPath}` }; } fs.unlinkSync(targetPath); // Verificar se foi removido if (fs.existsSync(targetPath)) { return { success: false, message: 'Falha ao remover cursor rules', error: 'Arquivo ainda existe após tentativa de remoção' }; } if (debugMode) { console.log('✅ [DEBUG] Cursor rules removed successfully'); } } return { success: true, message: 'Cursor rules locais removidas com sucesso' }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); if (debugMode) { console.log('❌ [DEBUG] Error removing cursor rules:', errorMessage); } else { console.error('❌ Erro ao remover cursor rules:', errorMessage); showSupportInfo(); } return { success: false, message: 'Erro ao remover cursor rules', error: errorMessage }; } }