| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | 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<CLIDetectionResult> {
|
| | const candidates: string[] = [];
|
| | const result: CLIDetectionResult = {
|
| | detected: false,
|
| | path: null,
|
| | version: null,
|
| | method: 'none',
|
| | candidates,
|
| | };
|
| |
|
| |
|
| | 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;
|
| | }
|
| | }
|
| |
|
| |
|
| | 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;
|
| | }
|
| | }
|
| | }
|
| |
|
| |
|
| | 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;
|
| | }
|
| | }
|
| | }
|
| |
|
| |
|
| | 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 {
|
| |
|
| | }
|
| |
|
| |
|
| | 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 {
|
| |
|
| | }
|
| | }
|
| | 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'),
|
| |
|
| | 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;
|
| | }
|
| |
|