chore: remove deprecated files and configurations
- Deleted .gitignore, biome.json, next.config.ts, package.json, pnpm-lock.yaml, pnpm-workspace.yaml, postcss.config.mjs, README.md, and various API, component, and utility files to clean up the codebase. - Removed unused database files and migration scripts to streamline the project structure. - Eliminated obsolete hooks and services to enhance maintainability and reduce clutter.
This commit is contained in:
1 parent
a8bb7cc22d
commit
ad9d5d32d2
119 files changed
-17633
No files matched your search
@@ -1,123 +0,0 @@
|
||||
# Ensures Ollama is running on localhost using WSL (Ubuntu) when available,
|
||||
# with a Windows-native fallback. Designed to be idempotent.
|
||||
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
function Write-Info($msg) { Write-Host "[ensure-ollama] $msg" }
|
||||
function Write-Warn($msg) { Write-Warning "[ensure-ollama] $msg" }
|
||||
|
||||
function Get-EnvOrDefault([string]$name, [string]$default) {
|
||||
$val = [Environment]::GetEnvironmentVariable($name)
|
||||
if ([string]::IsNullOrWhiteSpace($val)) { return $default }
|
||||
return $val
|
||||
}
|
||||
|
||||
function Test-Port([int]$Port) {
|
||||
try {
|
||||
$res = Test-NetConnection -ComputerName localhost -Port $Port -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
|
||||
return [bool]$res.TcpTestSucceeded
|
||||
} catch { return $false }
|
||||
}
|
||||
|
||||
function Wait-Healthy([int]$Port, [int]$TimeoutSeconds) {
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
if (Test-Port -Port $Port) { return $true }
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
function Has-WSL() {
|
||||
return $null -ne (Get-Command wsl.exe -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
function WSL-HasDistro([string]$Distro) {
|
||||
try {
|
||||
$list = & wsl.exe -l -q 2>$null
|
||||
return $list -split "`r?`n" | Where-Object { $_ -eq $Distro } | ForEach-Object { $true } | Select-Object -First 1
|
||||
} catch { return $false }
|
||||
}
|
||||
|
||||
function Invoke-WSL([string]$Distro, [string]$Cmd) {
|
||||
& wsl.exe -d $Distro -- bash -lc $Cmd
|
||||
}
|
||||
|
||||
function Ensure-Ollama-WSL([string]$Distro) {
|
||||
Write-Info "Verificando/instalando Ollama na WSL ($Distro)"
|
||||
$installCmd = 'command -v ollama >/dev/null 2>&1 || (curl -fsSL https://ollama.com/install.sh | sh)'
|
||||
Invoke-WSL -Distro $Distro -Cmd $installCmd | Out-Null
|
||||
}
|
||||
|
||||
function Start-Ollama-WSL([string]$Distro) {
|
||||
Write-Info "Iniciando ollama serve em background (WSL:$Distro)"
|
||||
$startCmd = 'mkdir -p "$HOME/.ollama"; nohup ollama serve > "$HOME/.ollama/ollama.log" 2>&1 & disown || true'
|
||||
Invoke-WSL -Distro $Distro -Cmd $startCmd | Out-Null
|
||||
}
|
||||
|
||||
function Has-Ollama-OnWindows() {
|
||||
return $null -ne (Get-Command ollama -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
function Start-Ollama-Windows() {
|
||||
try {
|
||||
$ollama = (Get-Command ollama -ErrorAction Stop).Source
|
||||
Write-Info "Iniciando ollama serve no Windows (hidden)"
|
||||
Start-Process -FilePath $ollama -ArgumentList 'serve' -WindowStyle Hidden | Out-Null
|
||||
return $true
|
||||
} catch {
|
||||
Write-Warn "Ollama não encontrado no PATH do Windows."
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
# Main
|
||||
$port = [int](Get-EnvOrDefault 'OLLAMA_PORT' '11434')
|
||||
$timeout = [int](Get-EnvOrDefault 'OLLAMA_START_TIMEOUT' '20')
|
||||
$distro = Get-EnvOrDefault 'OLLAMA_WSL_DISTRO' 'Ubuntu'
|
||||
|
||||
if (Test-Port -Port $port) {
|
||||
Write-Info "Porta $port já está respondendo. Nada a fazer."
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (Has-WSL) {
|
||||
if (-not (WSL-HasDistro -Distro $distro)) {
|
||||
Write-Warn "Distro '$distro' não encontrada. Tentando WSL padrão..."
|
||||
$distro = 'Ubuntu'
|
||||
}
|
||||
|
||||
Write-Info "Tentando iniciar Ollama via WSL ($distro)"
|
||||
Ensure-Ollama-WSL -Distro $distro
|
||||
Start-Ollama-WSL -Distro $distro
|
||||
|
||||
if (Wait-Healthy -Port $port -TimeoutSeconds $timeout) {
|
||||
Write-Info "Ollama disponível em localhost:$port (via WSL)."
|
||||
exit 0
|
||||
} else {
|
||||
Write-Warn "Timeout aguardando Ollama (WSL). Prosseguindo com fallback Windows."
|
||||
}
|
||||
}
|
||||
|
||||
# Fallback Windows
|
||||
if (-not (Has-Ollama-OnWindows)) {
|
||||
Write-Warn "Ollama não encontrado no Windows e WSL não atendeu no tempo."
|
||||
Write-Warn "Instale o Ollama no Windows ou habilite WSL/Ubuntu."
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (Start-Ollama-Windows) {
|
||||
if (Wait-Healthy -Port $port -TimeoutSeconds $timeout) {
|
||||
Write-Info "Ollama disponível em localhost:$port (Windows)."
|
||||
exit 0
|
||||
} else {
|
||||
Write-Warn "Timeout aguardando Ollama (Windows)."
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
import Database from "better-sqlite3";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { ensureModelExists } from "@/lib/ollama";
|
||||
|
||||
let db: Database.Database | null = null;
|
||||
|
||||
function getDatabase(): Database.Database {
|
||||
if (!db) {
|
||||
const dbPath = path.join(process.cwd(), "database", "ollahub.db");
|
||||
|
||||
// Garantir que o diretório existe
|
||||
const dbDir = path.dirname(dbPath);
|
||||
if (!fs.existsSync(dbDir)) {
|
||||
fs.mkdirSync(dbDir, { recursive: true });
|
||||
}
|
||||
|
||||
db = new Database(dbPath);
|
||||
|
||||
// Configurações de performance
|
||||
db.pragma("journal_mode = WAL");
|
||||
db.pragma("synchronous = NORMAL");
|
||||
db.pragma("foreign_keys = ON");
|
||||
db.pragma("cache_size = 10000");
|
||||
db.pragma("temp_store = memory");
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
function runMigrations(db: Database.Database): void {
|
||||
// Criar tabela de migrações
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS _migrations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
applied_at INTEGER NOT NULL
|
||||
);
|
||||
`);
|
||||
|
||||
// Verificar migrações aplicadas
|
||||
const applied = db.prepare("SELECT name FROM _migrations").all() as Array<{
|
||||
name: string;
|
||||
}>;
|
||||
const appliedNames = new Set(applied.map((m) => m.name));
|
||||
|
||||
// Aplicar migração inicial se não foi aplicada
|
||||
if (!appliedNames.has("001_initial_schema")) {
|
||||
console.log("📋 Aplicando migração: 001_initial_schema");
|
||||
|
||||
const schemaPath = path.join(process.cwd(), "database", "schema.sql");
|
||||
const schema = fs.readFileSync(schemaPath, "utf-8");
|
||||
|
||||
db.exec(schema);
|
||||
|
||||
// Registrar migração
|
||||
db.prepare("INSERT INTO _migrations (name, applied_at) VALUES (?, ?)").run(
|
||||
"001_initial_schema",
|
||||
Date.now()
|
||||
);
|
||||
|
||||
console.log("✅ Migração 001_initial_schema aplicada");
|
||||
}
|
||||
|
||||
// Aplicar migração para tabela MCP se não foi aplicada
|
||||
if (!appliedNames.has("002_mcp_installations")) {
|
||||
console.log("📋 Aplicando migração: 002_mcp_installations");
|
||||
|
||||
db.exec(`
|
||||
-- Tabela para gerenciar MCPs instalados
|
||||
CREATE TABLE IF NOT EXISTS mcp_installations (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner TEXT NOT NULL,
|
||||
repo TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
config JSON NOT NULL,
|
||||
tools JSON,
|
||||
installed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Índices para performance
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_owner_repo ON mcp_installations(owner, repo);
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_installed_at ON mcp_installations(installed_at DESC);
|
||||
`);
|
||||
|
||||
// Registrar migração
|
||||
db.prepare("INSERT INTO _migrations (name, applied_at) VALUES (?, ?)").run(
|
||||
"002_mcp_installations",
|
||||
Date.now()
|
||||
);
|
||||
|
||||
console.log("✅ Migração 002_mcp_installations aplicada");
|
||||
}
|
||||
|
||||
// Migração de marketplace removida
|
||||
|
||||
// Inicializar extensão vetorial se disponível
|
||||
try {
|
||||
const extPath = path.join(
|
||||
process.cwd(),
|
||||
"database",
|
||||
"extensions",
|
||||
"vector.so"
|
||||
);
|
||||
if (fs.existsSync(extPath)) {
|
||||
db.loadExtension(extPath);
|
||||
|
||||
// Inicializar índice vetorial
|
||||
db.exec(`
|
||||
SELECT vector_init('embeddings', 'vector', 'type=FLOAT32,dimension=384');
|
||||
`);
|
||||
|
||||
// Quantizar para busca mais rápida
|
||||
db.exec(`
|
||||
SELECT vector_quantize('embeddings', 'vector');
|
||||
`);
|
||||
|
||||
console.log("🔍 Extensão vetorial carregada e inicializada");
|
||||
} else {
|
||||
console.log(
|
||||
"⚠️ Extensão vetorial não encontrada - busca vetorial desabilitada"
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("⚠️ Erro ao carregar extensão vetorial:", error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function initializeDatabase(): Promise<void> {
|
||||
console.log("🔧 Inicializando banco de dados OllaHub...");
|
||||
|
||||
try {
|
||||
// Conectar ao banco
|
||||
const db = getDatabase();
|
||||
|
||||
// Executar migrações
|
||||
runMigrations(db);
|
||||
|
||||
console.log("✅ Banco de dados inicializado com sucesso!");
|
||||
} catch (error) {
|
||||
console.error("❌ Erro ao inicializar banco de dados:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function initializeTitleModel(): Promise<void> {
|
||||
console.log("🤖 Verificando modelo para geração de títulos...");
|
||||
|
||||
try {
|
||||
await ensureModelExists(
|
||||
"qwen2.5:0.5b",
|
||||
"Este modelo será usado para gerar títulos automáticos das conversas"
|
||||
);
|
||||
console.log("✅ Modelo de título pronto!");
|
||||
} catch (error) {
|
||||
console.error("❌ Erro ao inicializar modelo de título:", error);
|
||||
console.log("⚠️ Títulos de conversa podem não funcionar corretamente");
|
||||
}
|
||||
}
|
||||
|
||||
export async function initializeEmbeddingModel(): Promise<void> {
|
||||
console.log("🔍 Verificando modelo para embeddings...");
|
||||
|
||||
try {
|
||||
await ensureModelExists(
|
||||
"nomic-embed-text",
|
||||
"Este modelo será usado para busca vetorial das mensagens (274MB - 768 dimensões)"
|
||||
);
|
||||
console.log("✅ Modelo de embedding pronto!");
|
||||
} catch (error) {
|
||||
console.error("❌ Erro ao inicializar modelo de embedding:", error);
|
||||
console.log("⚠️ Busca vetorial desabilitada - usando fallback");
|
||||
}
|
||||
}
|
||||
|
||||
// Executar se chamado diretamente
|
||||
if (require.main === module) {
|
||||
Promise.all([
|
||||
initializeDatabase(),
|
||||
initializeTitleModel(),
|
||||
initializeEmbeddingModel(),
|
||||
])
|
||||
.then(async () => {
|
||||
console.log("🎉 Inicialização concluída");
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("💥 Falha na inicialização:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
#!/usr/bin/env tsx
|
||||
/**
|
||||
* Script para testar instalação completa de servidores MCP
|
||||
*
|
||||
* Uso: tsx scripts/test-mcp-installation.ts [npm|python|rust]
|
||||
*/
|
||||
|
||||
import { MCPInstallerService } from "../lib/services/mcp-installer";
|
||||
import { MCPValidatorService } from "../lib/services/mcp-validator";
|
||||
import { MCPEnvironmentService } from "../lib/services/mcp-environment";
|
||||
import type {
|
||||
InstallationConfig,
|
||||
InstallationProgress,
|
||||
} from "../lib/types/mcp-installer";
|
||||
|
||||
// Configurações de teste por tipo
|
||||
const TEST_CONFIGS = {
|
||||
npm: {
|
||||
mcpId: "test-npm-filesystem",
|
||||
packageName: "@modelcontextprotocol/server-filesystem",
|
||||
packageRegistry: "npm" as const,
|
||||
config: {
|
||||
name: "filesystem",
|
||||
command: "npx",
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
|
||||
},
|
||||
enableLogs: true,
|
||||
},
|
||||
python: {
|
||||
mcpId: "test-python-git",
|
||||
packageName: "mcp-server-git",
|
||||
packageRegistry: "pypi" as const,
|
||||
config: {
|
||||
name: "git",
|
||||
command: "python",
|
||||
args: ["-m", "mcp_server_git"],
|
||||
},
|
||||
enableLogs: true,
|
||||
},
|
||||
rust: {
|
||||
mcpId: "test-rust-example",
|
||||
packageName: "example-mcp-server",
|
||||
packageRegistry: "cargo" as const,
|
||||
repositoryUrl: "https://github.com/example/mcp-server-rust", // Exemplo - ajustar para repo real
|
||||
config: {
|
||||
name: "example",
|
||||
command: "./target/release/example-mcp-server",
|
||||
args: [],
|
||||
},
|
||||
enableLogs: true,
|
||||
},
|
||||
};
|
||||
|
||||
async function testInstallation(type: keyof typeof TEST_CONFIGS) {
|
||||
console.log(`\n${"=".repeat(60)}`);
|
||||
console.log(`🧪 Testing ${type.toUpperCase()} installation`);
|
||||
console.log(`${"=".repeat(60)}\n`);
|
||||
|
||||
const config = TEST_CONFIGS[type];
|
||||
|
||||
try {
|
||||
// 1. Verificar dependências do sistema
|
||||
console.log("1️⃣ Checking system dependencies...");
|
||||
const deps = await MCPEnvironmentService.checkSystemDependencies();
|
||||
console.log(" Dependencies:", deps);
|
||||
|
||||
const requiredDep =
|
||||
type === "npm" ? "npm" : type === "python" ? "python" : "cargo";
|
||||
|
||||
if (!deps[requiredDep as keyof typeof deps]) {
|
||||
console.error(` ❌ ${requiredDep} not found on system`);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(` ✓ ${requiredDep} is available\n`);
|
||||
|
||||
// 2. Testar instalação
|
||||
console.log("2️⃣ Installing MCP server...");
|
||||
|
||||
const installConfig: InstallationConfig = {
|
||||
...config,
|
||||
};
|
||||
|
||||
const onProgress = (progress: InstallationProgress) => {
|
||||
console.log(
|
||||
` [${progress.percentage}%] ${progress.status}: ${progress.message}`
|
||||
);
|
||||
|
||||
if (progress.logs && progress.logs.length > 0) {
|
||||
progress.logs.forEach((log) => {
|
||||
if (log.trim()) {
|
||||
console.log(` ${log.trim().substring(0, 100)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const environment = await MCPInstallerService.install(
|
||||
installConfig,
|
||||
onProgress
|
||||
);
|
||||
|
||||
console.log("\n ✓ Installation completed");
|
||||
console.log(` Environment: ${environment.path}`);
|
||||
console.log(
|
||||
` Executable: ${environment.executable} ${environment.args?.join(
|
||||
" "
|
||||
)}\n`
|
||||
);
|
||||
|
||||
// 3. Validar servidor MCP
|
||||
console.log("3️⃣ Validating MCP server (JSON-RPC protocol)...");
|
||||
|
||||
const validation = await MCPValidatorService.validateMCPServer(
|
||||
environment,
|
||||
config.config,
|
||||
15000 // 15 segundos timeout para teste
|
||||
);
|
||||
|
||||
if (validation.success) {
|
||||
console.log(` ✓ Validation successful`);
|
||||
console.log(` Protocol: ${validation.protocol}`);
|
||||
console.log(` Tools found: ${validation.tools.length}`);
|
||||
|
||||
if (validation.tools.length > 0) {
|
||||
console.log("\n Available tools:");
|
||||
validation.tools.forEach((tool) => {
|
||||
console.log(
|
||||
` - ${tool.name}: ${tool.description || "No description"}`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (validation.capabilities) {
|
||||
console.log(
|
||||
"\n Capabilities:",
|
||||
JSON.stringify(validation.capabilities, null, 2)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.warn(` ⚠️ JSON-RPC validation failed: ${validation.error}`);
|
||||
console.log("\n Trying simple validation...");
|
||||
|
||||
const simpleResult = await MCPValidatorService.simpleValidation(
|
||||
environment,
|
||||
config.config
|
||||
);
|
||||
|
||||
if (simpleResult.success) {
|
||||
console.log(" ✓ Simple validation passed (server starts)");
|
||||
} else {
|
||||
console.error(` ❌ Simple validation failed: ${simpleResult.error}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Cleanup (opcional)
|
||||
console.log("\n4️⃣ Cleaning up test installation...");
|
||||
await MCPEnvironmentService.cleanupEnvironment(environment);
|
||||
console.log(" ✓ Cleanup completed\n");
|
||||
|
||||
console.log(`${"=".repeat(60)}`);
|
||||
console.log(`✅ ${type.toUpperCase()} test PASSED`);
|
||||
console.log(`${"=".repeat(60)}\n`);
|
||||
|
||||
return true;
|
||||
} catch (error: any) {
|
||||
console.error(`\n❌ ${type.toUpperCase()} test FAILED`);
|
||||
console.error(`Error: ${error.message}`);
|
||||
if (error.stack) {
|
||||
console.error(`Stack: ${error.stack}`);
|
||||
}
|
||||
|
||||
console.log(`${"=".repeat(60)}\n`);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Main
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const type = args[0] as keyof typeof TEST_CONFIGS;
|
||||
|
||||
if (!type) {
|
||||
console.log(
|
||||
"Usage: tsx scripts/test-mcp-installation.ts [npm|python|rust|all]"
|
||||
);
|
||||
console.log("\nExamples:");
|
||||
console.log(" tsx scripts/test-mcp-installation.ts npm");
|
||||
console.log(" tsx scripts/test-mcp-installation.ts python");
|
||||
console.log(" tsx scripts/test-mcp-installation.ts rust");
|
||||
console.log(" tsx scripts/test-mcp-installation.ts all");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (type === "all") {
|
||||
console.log("🧪 Running ALL installation tests\n");
|
||||
|
||||
const results = {
|
||||
npm: await testInstallation("npm"),
|
||||
python: await testInstallation("python"),
|
||||
rust: await testInstallation("rust"),
|
||||
};
|
||||
|
||||
console.log("\n" + "=".repeat(60));
|
||||
console.log("📊 Test Summary");
|
||||
console.log("=".repeat(60));
|
||||
console.log(`NPM: ${results.npm ? "✅ PASSED" : "❌ FAILED"}`);
|
||||
console.log(`Python: ${results.python ? "✅ PASSED" : "❌ FAILED"}`);
|
||||
console.log(`Rust: ${results.rust ? "✅ PASSED" : "❌ FAILED"}`);
|
||||
console.log("=".repeat(60) + "\n");
|
||||
|
||||
const allPassed = Object.values(results).every((r) => r);
|
||||
process.exit(allPassed ? 0 : 1);
|
||||
}
|
||||
|
||||
if (!TEST_CONFIGS[type]) {
|
||||
console.error(`❌ Unknown type: ${type}`);
|
||||
console.error("Valid types: npm, python, rust, all");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const success = await testInstallation(type);
|
||||
process.exit(success ? 0 : 1);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("Fatal error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in new issue
Block a user