export async function ensureBinary()

in scripts/telemetry_utils.js [129:258]


export async function ensureBinary(
  executableName,
  repo,
  assetNameCallback,
  binaryNameInArchive,
  isJaeger = false,
) {
  const executablePath = path.join(BIN_DIR, executableName);
  if (fileExists(executablePath)) {
    console.log(`✅ ${executableName} already exists at ${executablePath}`);
    return executablePath;
  }

  console.log(`🔍 ${executableName} not found. Downloading from ${repo}...`);

  const platform = process.platform === 'win32' ? 'windows' : process.platform;
  const arch = process.arch === 'x64' ? 'amd64' : process.arch;
  const ext = platform === 'windows' ? 'zip' : 'tar.gz';

  if (isJaeger && platform === 'windows' && arch === 'arm64') {
    console.warn(
      `⚠️ Jaeger does not have a release for Windows on ARM64. Skipping.`,
    );
    return null;
  }

  let release;
  let asset;

  if (isJaeger) {
    console.log(`🔍 Finding latest Jaeger v2+ asset...`);
    const releases = getJson(`https://api.github.com/repos/${repo}/releases`);
    const sortedReleases = releases
      .filter((r) => !r.prerelease && r.tag_name.startsWith('v'))
      .sort((a, b) => {
        const aVersion = a.tag_name.substring(1).split('.').map(Number);
        const bVersion = b.tag_name.substring(1).split('.').map(Number);
        for (let i = 0; i < Math.max(aVersion.length, bVersion.length); i++) {
          if ((aVersion[i] || 0) > (bVersion[i] || 0)) return -1;
          if ((aVersion[i] || 0) < (bVersion[i] || 0)) return 1;
        }
        return 0;
      });

    for (const r of sortedReleases) {
      const expectedSuffix =
        platform === 'windows'
          ? `-${platform}-${arch}.zip`
          : `-${platform}-${arch}.tar.gz`;
      const foundAsset = r.assets.find(
        (a) =>
          a.name.startsWith('jaeger-2.') && a.name.endsWith(expectedSuffix),
      );

      if (foundAsset) {
        release = r;
        asset = foundAsset;
        console.log(
          `⬇️  Found ${asset.name} in release ${r.tag_name}, downloading...`,
        );
        break;
      }
    }
    if (!asset) {
      throw new Error(
        `Could not find a suitable Jaeger v2 asset for platform ${platform}/${arch}.`,
      );
    }
  } else {
    release = getJson(`https://api.github.com/repos/${repo}/releases/latest`);
    const version = release.tag_name.startsWith('v')
      ? release.tag_name.substring(1)
      : release.tag_name;
    const assetName = assetNameCallback(version, platform, arch, ext);
    asset = release.assets.find((a) => a.name === assetName);
    if (!asset) {
      throw new Error(
        `Could not find a suitable asset for ${repo} (version ${version}) on platform ${platform}/${arch}. Searched for: ${assetName}`,
      );
    }
  }

  const downloadUrl = asset.browser_download_url;
  const tmpDir = fs.mkdtempSync(
    path.join(os.tmpdir(), 'gemini-cli-telemetry-'),
  );
  const archivePath = path.join(tmpDir, asset.name);

  try {
    console.log(`⬇️  Downloading ${asset.name}...`);
    downloadFile(downloadUrl, archivePath);
    console.log(`📦 Extracting ${asset.name}...`);

    const actualExt = asset.name.endsWith('.zip') ? 'zip' : 'tar.gz';

    if (actualExt === 'zip') {
      execSync(`unzip -o "${archivePath}" -d "${tmpDir}"`, { stdio: 'pipe' });
    } else {
      execSync(`tar -xzf "${archivePath}" -C "${tmpDir}"`, { stdio: 'pipe' });
    }

    const nameToFind = binaryNameInArchive || executableName;
    const foundBinaryPath = findFile(tmpDir, (file) => {
      if (platform === 'windows') {
        return file === `${nameToFind}.exe`;
      }
      return file === nameToFind;
    });

    if (!foundBinaryPath) {
      throw new Error(
        `Could not find binary "${nameToFind}" in extracted archive at ${tmpDir}. Contents: ${fs.readdirSync(tmpDir).join(', ')}`,
      );
    }

    fs.renameSync(foundBinaryPath, executablePath);

    if (platform !== 'windows') {
      fs.chmodSync(executablePath, '755');
    }

    console.log(`✅ ${executableName} installed at ${executablePath}`);
    return executablePath;
  } finally {
    fs.rmSync(tmpDir, { recursive: true, force: true });
    if (fs.existsSync(archivePath)) {
      fs.unlinkSync(archivePath);
    }
  }
}