import { $ } from "bun" import { writeFileSync } from "fs" console.log(` ========================================== Yellow Phone Setup Bootstrap ========================================== `) // Check if running as root if (process.getuid && process.getuid() !== 0) { console.error("Please run with sudo: sudo bun bootstrap.ts [install-dir]") console.error("Or use full path: sudo ~/.bun/bin/bun bootstrap.ts [install-dir]") process.exit(1) } // Get install directory from argument or use default const INSTALL_DIR = process.argv[2] || "/home/corey/yellow-phone" const AP_SERVICE_FILE = "/etc/systemd/system/phone-ap.service" const WEB_SERVICE_FILE = "/etc/systemd/system/phone-web.service" console.log(`Install directory: ${INSTALL_DIR}`) console.log("\nStep 1: Ensuring directory exists...") await $`mkdir -p ${INSTALL_DIR}` console.log(`✓ Directory ready: ${INSTALL_DIR}`) console.log("\nStep 2: Installing dependencies...") await $`cd ${INSTALL_DIR} && bun install` console.log(`✓ Dependencies installed`) console.log("\nStep 3: Installing systemd services...") // Find where bun is installed const bunPath = await $`which bun` .quiet() .nothrow() .text() .then((p) => p.trim()) if (!bunPath) { console.error("Error: bun not found in PATH. Please ensure bun is available system-wide.") process.exit(1) } console.log(`Using bun at: ${bunPath}`) // Create AP monitor service const apServiceContent = `[Unit] Description=Yellow Phone WiFi AP Monitor After=network.target Before=phone-web.service [Service] Type=simple ExecStart=${bunPath} ${INSTALL_DIR}/services/ap-monitor.ts Restart=on-failure RestartSec=5 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ` writeFileSync(AP_SERVICE_FILE, apServiceContent, "utf8") console.log("✓ Created phone-ap.service") // Create web server service const webServiceContent = `[Unit] Description=Yellow Phone Web Server After=network.target phone-ap.service [Service] Type=simple ExecStart=${bunPath} ${INSTALL_DIR}/services/server/server.tsx WorkingDirectory=${INSTALL_DIR} Restart=on-failure RestartSec=5 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ` writeFileSync(WEB_SERVICE_FILE, webServiceContent, "utf8") console.log("✓ Created phone-web.service") await $`systemctl daemon-reload` await $`systemctl enable phone-ap.service` await $`systemctl enable phone-web.service` console.log("✓ Services enabled") console.log("\nStep 4: Starting the services...") await $`systemctl start phone-ap.service` await $`systemctl start phone-web.service` console.log("✓ Services started") console.log(` ========================================== ✓ Bootstrap complete! ========================================== Both services are now running and will start automatically on boot: - phone-ap.service: Monitors WiFi and manages AP - phone-web.service: Web server for configuration How it works: - If connected to WiFi: Access at http://yellow-phone.local - If NOT connected: WiFi AP "yellow-phone-setup" will start automatically Connect to the AP at the same address http://yellow-phone.local To check status use ./cli `)