// --------------------------------------------------------------------------- // CLI Detector -- Real auto-detection of Google Antigravity CLI // --------------------------------------------------------------------------- // Multi-strategy detection: // 1. ANTIGRAVITY_CLI_PATH env var // 2. Search system PATH // 3. Check common install locations // 4. Check npm global installs // 5. Probe for Gemini CLI as alternative // --------------------------------------------------------------------------- import { execSync } from 'child_process'; import fs from 'fs'; import path from 'path'; import os from 'os'; export interface CLIDetectionResult { detected: boolean; path: string | null; version: string | null; method: string; candidates: string[]; } const CLI_NAMES = [ 'antigravity', 'antigravity.exe', 'antigravity.cmd', 'gemini', 'gemini.exe', 'gemini.cmd', ]; export async function detectCLI(): Promise { const candidates: string[] = []; const result: CLIDetectionResult = { detected: false, path: null, version: null, method: 'none', candidates, }; // Strategy 1: Environment variable const envPath = process.env.ANTIGRAVITY_CLI_PATH; if (envPath) { candidates.push(`[env] ${envPath}`); const version = tryGetVersion(envPath); if (version) { result.detected = true; result.path = envPath; result.version = version; result.method = 'env:ANTIGRAVITY_CLI_PATH'; return result; } } // Strategy 2: Search system PATH using `where` (Windows) or `which` (Unix) for (const name of CLI_NAMES) { const found = findOnPath(name); if (found) { candidates.push(`[PATH] ${found}`); const version = tryGetVersion(found); if (version) { result.detected = true; result.path = found; result.version = version; result.method = `PATH:${name}`; return result; } } } // Strategy 3: Common install locations const commonPaths = getCommonInstallPaths(); for (const candidate of commonPaths) { candidates.push(`[common] ${candidate}`); if (fs.existsSync(candidate)) { const version = tryGetVersion(candidate); if (version) { result.detected = true; result.path = candidate; result.version = version; result.method = 'common-path'; return result; } } } // Strategy 4: npm global bin try { const npmBin = execSync('npm root -g', { timeout: 5000 }).toString().trim(); const npmParent = path.dirname(npmBin); for (const name of CLI_NAMES) { const candidate = path.join(npmParent, name); candidates.push(`[npm-global] ${candidate}`); if (fs.existsSync(candidate)) { const version = tryGetVersion(candidate); if (version) { result.detected = true; result.path = candidate; result.version = version; result.method = 'npm-global'; return result; } } } } catch { // npm not available } // Strategy 5: Try bare command execution as last resort for (const name of ['antigravity', 'gemini']) { candidates.push(`[bare] ${name}`); const version = tryGetVersion(name); if (version) { result.detected = true; result.path = name; result.version = version; result.method = `bare:${name}`; return result; } } return result; } function findOnPath(name: string): string | null { try { const cmd = process.platform === 'win32' ? `where ${name}` : `which ${name}`; const result = execSync(cmd, { timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }) .toString() .trim() .split('\n')[0] .trim(); return result || null; } catch { return null; } } function tryGetVersion(cliPath: string): string | null { const commands = [ `"${cliPath}" --version`, `"${cliPath}" -v`, `"${cliPath}" version`, ]; for (const cmd of commands) { try { const output = execSync(cmd, { timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], env: { ...process.env }, }).toString().trim(); if (output && output.length < 200) { return output; } } catch { // continue to next command variant } } return null; } function getCommonInstallPaths(): string[] { const home = os.homedir(); const paths: string[] = []; if (process.platform === 'win32') { paths.push( path.join(home, 'AppData', 'Local', 'Programs', 'antigravity', 'antigravity.exe'), path.join(home, 'AppData', 'Local', 'antigravity', 'antigravity.exe'), path.join(home, 'AppData', 'Roaming', 'npm', 'antigravity.cmd'), 'C:\\Program Files\\Google\\Antigravity\\antigravity.exe', 'C:\\Program Files (x86)\\Google\\Antigravity\\antigravity.exe', path.join(home, '.local', 'bin', 'antigravity'), // Gemini CLI alternatives path.join(home, 'AppData', 'Local', 'Programs', 'gemini', 'gemini.exe'), path.join(home, 'AppData', 'Roaming', 'npm', 'gemini.cmd'), ); } else { paths.push( '/usr/local/bin/antigravity', '/usr/bin/antigravity', path.join(home, '.local', 'bin', 'antigravity'), path.join(home, '.npm-global', 'bin', 'antigravity'), '/usr/local/bin/gemini', path.join(home, '.local', 'bin', 'gemini'), ); } return paths; }