UNPKG

claude-gemini-multimodal-bridge

Version:

Enterprise-grade AI integration bridge connecting Claude Code, Gemini CLI, and Google AI Studio with intelligent routing and advanced multimodal processing capabilities

138 lines (137 loc) 4.06 kB
import { execSync } from 'child_process'; import { existsSync, mkdirSync } from 'fs'; import { join, normalize } from 'path'; import { homedir } from 'os'; const isWindows = process.platform === 'win32'; export function findExecutable(command) { try { const cmd = isWindows ? `where ${command} 2>nul` : `which ${command} 2>/dev/null`; const output = execSync(cmd, { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }); return output.split('\n')[0]?.trim() || undefined; } catch { return undefined; } } export function commandExists(command) { try { const cmd = isWindows ? `where ${command} 2>nul` : `which ${command} 2>/dev/null`; execSync(cmd, { stdio: 'ignore', timeout: 5000 }); return true; } catch { return false; } } export function getHomeDir() { const home = homedir(); if (home) { return home; } if (isWindows) { return process.env.USERPROFILE || process.env.HOME || 'C:\\Users\\Default'; } return process.env.HOME || '/home'; } export function getConfigDir() { if (isWindows) { const appData = process.env.APPDATA; if (appData) { return join(appData, 'claude-code'); } return join(getHomeDir(), '.config', 'claude-code'); } return join(getHomeDir(), '.config', 'claude-code'); } export function ensureDirectory(dir) { const normalizedDir = normalize(dir); if (!existsSync(normalizedDir)) { mkdirSync(normalizedDir, { recursive: true }); } } export function ensureOutputDirectory(type) { const baseDir = process.cwd(); const outputDir = join(baseDir, 'output', type); ensureDirectory(outputDir); return outputDir; } export function normalizeOutputPath(relativePath) { return normalize(join(process.cwd(), relativePath)); } export function getDefaultExecutablePath(tool) { if (isWindows) { return tool === 'gemini' ? 'gemini' : 'claude'; } const unixDefaults = { gemini: ['/usr/local/bin/gemini', '/opt/homebrew/bin/gemini'], claude: ['claude', '/opt/homebrew/bin/claude'] }; const paths = unixDefaults[tool] || []; for (const p of paths) { if (existsSync(p)) { return p; } } return tool; } export function getSpawnOptions(additionalOptions = {}) { return { ...additionalOptions, shell: isWindows }; } export function findProcesses(processName) { try { if (isWindows) { const output = execSync(`tasklist /FI "IMAGENAME eq node.exe" /FO CSV 2>nul`, { encoding: 'utf8', timeout: 5000 }); return output .split('\n') .filter(line => line.toLowerCase().includes(processName.toLowerCase())); } else { const output = execSync(`pgrep -f "${processName}" || true`, { encoding: 'utf8', timeout: 5000 }); return output.split('\n').filter(line => line.trim()); } } catch { return []; } } export function isPlatformWindows() { return isWindows; } export function getNpmGlobalDir() { if (isWindows) { return join(process.env.APPDATA || '', 'npm'); } return '/usr/local/lib/node_modules'; } export function normalizeCrossPlatformPath(filePath) { return filePath.replace(/\\/g, '/'); } export function toPlatformPath(filePath) { if (isWindows) { return filePath.replace(/\//g, '\\'); } return filePath; } export function resolveOutputPath(relativePath) { const normalizedRelative = normalizeCrossPlatformPath(relativePath); const absolutePath = join(process.cwd(), ...normalizedRelative.split('/')); return { normalized: normalizedRelative, absolute: absolutePath, native: absolutePath }; } export function isUrl(path) { return path.startsWith('http://') || path.startsWith('https://'); }