#!/usr/bin/env node /** * OpenFang Binary Downloader * Automatically downloads the correct OpenFang binary for the current platform * Run during Tauri build process */ import { execSync } from 'child_process'; import { existsSync, mkdirSync, writeFileSync, renameSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { platform, arch } from 'os'; const __dirname = dirname(fileURLToPath(import.meta.url)); const RESOURCES_DIR = join(__dirname, '../src-tauri/resources/openfang-runtime'); // OpenFang release info const OPENFANG_REPO = 'RightNow-AI/openfang'; const OPENFANG_VERSION = process.env.OPENFANG_VERSION || 'latest'; interface PlatformConfig { binaryName: string; downloadName: string; } function getPlatformConfig(): PlatformConfig { const currentPlatform = platform(); const currentArch = arch(); switch (currentPlatform) { case 'win32': return { binaryName: 'openfang.exe', downloadName: currentArch === 'x64' ? 'openfang-x86_64-pc-windows-msvc.exe' : 'openfang-aarch64-pc-windows-msvc.exe', }; case 'darwin': return { binaryName: currentArch === 'arm64' ? 'openfang-aarch64-apple-darwin' : 'openfang-x86_64-apple-darwin', downloadName: currentArch === 'arm64' ? 'openfang-aarch64-apple-darwin' : 'openfang-x86_64-apple-darwin', }; case 'linux': return { binaryName: currentArch === 'arm64' ? 'openfang-aarch64-unknown-linux-gnu' : 'openfang-x86_64-unknown-linux-gnu', downloadName: currentArch === 'arm64' ? 'openfang-aarch64-unknown-linux-gnu' : 'openfang-x86_64-unknown-linux-gnu', }; default: throw new Error(`Unsupported platform: ${currentPlatform}`); } } function downloadBinary(): void { const config = getPlatformConfig(); const baseUrl = `https://github.com/${OPENFANG_REPO}/releases`; const downloadUrl = OPENFANG_VERSION === 'latest' ? `${baseUrl}/latest/download/${config.downloadName}` : `${baseUrl}/download/${OPENFANG_VERSION}/${config.downloadName}`; const outputPath = join(RESOURCES_DIR, config.binaryName); console.log('='.repeat(60)); console.log('OpenFang Binary Downloader'); console.log('='.repeat(60)); console.log(`Platform: ${platform()} (${arch()})`); console.log(`Binary: ${config.binaryName}`); console.log(`Version: ${OPENFANG_VERSION}`); console.log(`URL: ${downloadUrl}`); console.log('='.repeat(60)); // Ensure directory exists if (!existsSync(RESOURCES_DIR)) { mkdirSync(RESOURCES_DIR, { recursive: true }); } // Check if already downloaded if (existsSync(outputPath)) { console.log('✓ Binary already exists, skipping download.'); return; } // Download using curl (cross-platform via Node.js) console.log('Downloading...'); try { // Use curl for download (available on all platforms with Git/WSL) const tempPath = `${outputPath}.tmp`; if (platform() === 'win32') { // Windows: use PowerShell execSync( `powershell -Command "Invoke-WebRequest -Uri '${downloadUrl}' -OutFile '${tempPath}'"`, { stdio: 'inherit' } ); } else { // Unix: use curl execSync(`curl -fsSL -o "${tempPath}" "${downloadUrl}"`, { stdio: 'inherit' }); } // Rename temp file to final name renameSync(tempPath, outputPath); // Make executable on Unix if (platform() !== 'win32') { execSync(`chmod +x "${outputPath}"`); } console.log('✓ Download complete!'); } catch (error) { console.error('✗ Download failed:', error); console.log('\nPlease download manually from:'); console.log(` ${baseUrl}/${OPENFANG_VERSION === 'latest' ? 'latest' : 'tag/' + OPENFANG_VERSION}`); process.exit(1); } } function updateManifest(): void { const manifestPath = join(RESOURCES_DIR, 'runtime-manifest.json'); const manifest = { source: { binPath: platform() === 'win32' ? 'openfang.exe' : `openfang-${arch()}-${platform()}`, }, stagedAt: new Date().toISOString(), version: OPENFANG_VERSION === 'latest' ? new Date().toISOString().split('T')[0].replace(/-/g, '.') : OPENFANG_VERSION, runtimeType: 'openfang', description: 'OpenFang Agent OS - Single binary runtime (~32MB)', endpoints: { websocket: 'ws://127.0.0.1:4200/ws', rest: 'http://127.0.0.1:4200/api', }, }; writeFileSync(manifestPath, JSON.stringify(manifest, null, 2)); console.log('✓ Manifest updated'); } // Run downloadBinary(); updateManifest(); console.log('\n✓ OpenFang runtime ready for build!');