import { execSync } from "child_process"; import fs from "fs"; import os from "os"; import path from "path"; export type BinaryName = "sling" | "atlas"; export interface BinaryInfo { path: string; version: string; } export function resolveBinary(name: BinaryName): string | null { try { const out = execSync(`which ${name}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], }) .trim() .split("\n")[0]; if (out) return out; } catch { // not on PATH } if (name === "sling") { const fallback = path.join(os.homedir(), ".sling", "bin", "sling"); if (fs.existsSync(fallback)) return fallback; } return null; } function probe(name: BinaryName): BinaryInfo | null { const binPath = resolveBinary(name); if (!binPath) return null; let version = ""; try { version = execSync( name === "atlas" ? `"${binPath}" version` : `"${binPath}" --version`, { encoding: "utf8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] } ) .trim() .split("\n")[0]; } catch { // version probe failed; still report the path } return { path: binPath, version }; } export function checkBinaries(): { sling: BinaryInfo | null; atlas: BinaryInfo | null; } { return { sling: probe("sling"), atlas: probe("atlas") }; }