"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // electron/main.ts var import_electron = require("electron"); var import_path3 = __toESM(require("path"), 1); var import_child_process3 = require("child_process"); // electron/features/scanner.ts var import_promises = __toESM(require("fs/promises"), 1); var import_path = __toESM(require("path"), 1); var import_os = __toESM(require("os"), 1); var import_child_process = require("child_process"); var import_util = __toESM(require("util"), 1); async function scanDirectory(rootDir, maxDepth = 5) { const results = []; async function traverse(currentPath, depth) { if (depth > maxDepth) return; try { const entries = await import_promises.default.readdir(currentPath, { withFileTypes: true }); for (const entry of entries) { const fullPath = import_path.default.join(currentPath, entry.name); if (entry.isDirectory()) { if (entry.name === "node_modules" || entry.name === "vendor" || entry.name === ".venv") { try { const stats = await import_promises.default.stat(fullPath); results.push({ path: fullPath, size: 0, // Calculating size is expensive, might do lazily or separate task lastAccessed: stats.atime, type: entry.name }); continue; } catch (e) { console.error(`Error stat-ing ${fullPath}`, e); } } else if (!entry.name.startsWith(".")) { await traverse(fullPath, depth + 1); } } } } catch (error) { console.error(`Error scanning ${currentPath}`, error); } } await traverse(rootDir, 0); return results; } async function findLargeFiles(rootDir, threshold = 100 * 1024 * 1024) { const results = []; async function traverse(currentPath) { try { const stats = await import_promises.default.stat(currentPath); if (stats.size > threshold && !stats.isDirectory()) { results.push({ path: currentPath, size: stats.size, isDirectory: false }); return; } if (stats.isDirectory()) { if (import_path.default.basename(currentPath) === "node_modules") return; const entries = await import_promises.default.readdir(currentPath, { withFileTypes: true }); for (const entry of entries) { if (entry.name.startsWith(".") && entry.name !== ".Trash") continue; await traverse(import_path.default.join(currentPath, entry.name)); } } } catch (e) { } } await traverse(rootDir); return results.sort((a, b) => b.size - a.size); } async function getDeepDiveSummary() { const home = import_os.default.homedir(); const targets = [ import_path.default.join(home, "Downloads"), import_path.default.join(home, "Documents"), import_path.default.join(home, "Desktop"), import_path.default.join(home, "Library/Application Support") ]; const results = []; for (const t of targets) { console.log(`Scanning ${t}...`); const large = await findLargeFiles(t, 50 * 1024 * 1024); console.log(`Found ${large.length} large files in ${t}`); results.push(...large); } return results.slice(0, 20); } var execPromise = import_util.default.promisify(import_child_process.exec); async function getDiskUsage() { try { const { stdout } = await execPromise("df -k /"); const lines = stdout.trim().split("\n"); if (lines.length < 2) return null; const parts = lines[1].split(/\s+/); const total = parseInt(parts[1]) * 1024; const used = parseInt(parts[2]) * 1024; const available = parseInt(parts[3]) * 1024; return { totalGB: (total / 1024 / 1024 / 1024).toFixed(2), usedGB: (used / 1024 / 1024 / 1024).toFixed(2), freeGB: (available / 1024 / 1024 / 1024).toFixed(2) }; } catch (e) { console.error("Error getting disk usage:", e); return null; } } async function findHeavyFolders(rootDir) { try { console.log(`Deepest scan on: ${rootDir}`); const { stdout } = await execPromise(`du -k -d 2 "${rootDir}" | sort -nr | head -n 50`); const lines = stdout.trim().split("\n"); const results = lines.map((line) => { const trimmed = line.trim(); const firstSpace = trimmed.indexOf(" "); const match = trimmed.match(/^(\d+)\s+(.+)$/); if (!match) return null; const sizeK = parseInt(match[1]); const fullPath = match[2]; return { path: fullPath, size: sizeK * 1024, // Convert KB to Bytes isDirectory: true }; }).filter((item) => item !== null && item.path !== rootDir); return results; } catch (e) { console.error("Deepest scan failed:", e); return []; } } // electron/features/updater.ts var import_child_process2 = require("child_process"); var import_util2 = __toESM(require("util"), 1); var execAsync = import_util2.default.promisify(import_child_process2.exec); async function disableAutoUpdates(password) { const cmds = [ "sudo -S softwareupdate --schedule off", "sudo -S defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled -bool false", "sudo -S defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticDownload -bool false", "sudo -S defaults write /Library/Preferences/com.apple.commerce AutoUpdate -bool false" ]; try { await execWithSudo("softwareupdate --schedule off"); return true; } catch (error) { console.error("Failed to disable updates", error); return false; } } async function execWithSudo(command) { const script = `do shell script "${command}" with administrator privileges`; return execAsync(`osascript -e '${script}'`); } // electron/features/cleaner.ts var import_promises2 = __toESM(require("fs/promises"), 1); var import_path2 = __toESM(require("path"), 1); var import_os2 = __toESM(require("os"), 1); async function clearCaches() { const cacheDir = import_path2.default.join(import_os2.default.homedir(), "Library/Caches"); try { const entries = await import_promises2.default.readdir(cacheDir); let freedSpace = 0; for (const entry of entries) { const fullPath = import_path2.default.join(cacheDir, entry); await import_promises2.default.rm(fullPath, { recursive: true, force: true }); } return true; } catch (error) { console.error("Error clearing caches", error); return false; } } async function purgePath(targetPath) { try { await import_promises2.default.rm(targetPath, { recursive: true, force: true }); return true; } catch (e) { console.error(`Failed to purge ${targetPath}`, e); return false; } } async function cleanupDocker() { try { const { exec: exec3 } = await import("child_process"); const util3 = await import("util"); const execAsync2 = util3.promisify(exec3); await execAsync2("docker system prune -a --volumes -f"); return true; } catch (e) { console.error("Failed to cleanup docker:", e); return false; } } async function cleanupTmp() { const tmpDir = import_os2.default.tmpdir(); let success = true; try { const entries = await import_promises2.default.readdir(tmpDir); for (const entry of entries) { try { await import_promises2.default.rm(import_path2.default.join(tmpDir, entry), { recursive: true, force: true }); } catch (e) { console.warn(`Skipped ${entry}`); } } } catch (e) { console.error("Failed to access tmp dir:", e); success = false; } return success; } async function cleanupXcode() { try { const home = import_os2.default.homedir(); const paths = [ import_path2.default.join(home, "Library/Developer/Xcode/DerivedData"), import_path2.default.join(home, "Library/Developer/Xcode/iOS DeviceSupport"), import_path2.default.join(home, "Library/Developer/Xcode/Archives"), import_path2.default.join(home, "Library/Caches/com.apple.dt.Xcode") ]; for (const p of paths) { try { await import_promises2.default.rm(p, { recursive: true, force: true }); } catch (e) { console.warn(`Failed to clean ${p}`, e); } } return true; } catch (e) { console.error("Failed to cleanup Xcode:", e); return false; } } async function cleanupTurnkey() { try { const home = import_os2.default.homedir(); const paths = [ import_path2.default.join(home, ".npm/_cacache"), import_path2.default.join(home, ".yarn/cache"), import_path2.default.join(home, "Library/pnpm/store"), // Mac default for pnpm store if not configured otherwise import_path2.default.join(home, ".cache/yarn"), import_path2.default.join(home, ".gradle/caches") ]; for (const p of paths) { try { await import_promises2.default.rm(p, { recursive: true, force: true }); } catch (e) { console.warn(`Failed to clean ${p}`, e); } } return true; } catch (e) { console.error("Failed to cleanup package managers:", e); return false; } } // electron/main.ts var mainWindow = null; var backendProcess = null; var tray = null; var startBackend = () => { if (process.env.NODE_ENV === "development") { console.log("Development mode: Backend should be running via start-go.sh"); return; } const backendPath = import_path3.default.join(process.resourcesPath, "backend"); console.log("Starting backend from:", backendPath); try { backendProcess = (0, import_child_process3.spawn)(backendPath, [], { stdio: "inherit" }); backendProcess.on("error", (err) => { console.error("Failed to start backend:", err); }); backendProcess.on("exit", (code, signal) => { console.log(`Backend exited with code ${code} and signal ${signal}`); }); } catch (error) { console.error("Error spawning backend:", error); } }; function createTray() { const iconPath = import_path3.default.join(__dirname, "../dist/tray/tray-iconTemplate.png"); let finalIconPath = iconPath; if (process.env.NODE_ENV === "development") { finalIconPath = import_path3.default.join(__dirname, "../public/tray/tray-iconTemplate.png"); } let image = import_electron.nativeImage.createFromPath(finalIconPath); image.setTemplateImage(true); tray = new import_electron.Tray(image.resize({ width: 18, height: 18 })); tray.setToolTip("Antigravity Cleaner"); updateTrayMenu("Initializing..."); } var isDockVisible = true; function updateTrayMenu(statusText) { if (!tray) return; const contextMenu = import_electron.Menu.buildFromTemplate([ { label: `Storage: ${statusText}`, enabled: false }, { type: "separator" }, { label: "Open Dashboard", click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } }, { label: "Free Up Storage", click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } }, { type: "separator" }, { label: "Show Dock Icon", type: "checkbox", checked: isDockVisible, click: (menuItem) => { isDockVisible = menuItem.checked; if (isDockVisible) { import_electron.app.dock.show(); } else { import_electron.app.dock.hide(); } } }, { type: "separator" }, { label: "Quit", click: () => import_electron.app.quit() } ]); tray.setContextMenu(contextMenu); tray.setTitle(statusText); } function createWindow() { mainWindow = new import_electron.BrowserWindow({ width: 1200, height: 800, backgroundColor: "#FFFFFF", // Helps prevent white flash webPreferences: { preload: import_path3.default.join(__dirname, "preload.cjs"), nodeIntegration: true, contextIsolation: true } }); const isDev = process.env.NODE_ENV === "development"; const port = process.env.PORT || 5173; if (isDev) { mainWindow.loadURL(`http://localhost:${port}`); } else { mainWindow.loadFile(import_path3.default.join(__dirname, "../dist/index.html")); } mainWindow.on("closed", () => { mainWindow = null; }); } import_electron.app.whenReady().then(() => { import_electron.ipcMain.handle("scan-directory", async (event, path4) => { return scanDirectory(path4); }); import_electron.ipcMain.handle("deep-dive-scan", async () => { return getDeepDiveSummary(); }); import_electron.ipcMain.handle("get-disk-usage", async () => { return getDiskUsage(); }); import_electron.ipcMain.handle("deepest-scan", async (event, targetPath) => { const target = targetPath || import_path3.default.join(import_electron.app.getPath("home"), "Documents"); return findHeavyFolders(target); }); import_electron.ipcMain.handle("disable-updates", async () => { return disableAutoUpdates(); }); import_electron.ipcMain.handle("clean-system", async () => { return clearCaches(); }); import_electron.ipcMain.handle("cleanup-docker", async () => { return cleanupDocker(); }); import_electron.ipcMain.handle("cleanup-tmp", async () => { return cleanupTmp(); }); import_electron.ipcMain.handle("cleanup-xcode", async () => { return cleanupXcode(); }); import_electron.ipcMain.handle("cleanup-turnkey", async () => { return cleanupTurnkey(); }); import_electron.ipcMain.handle("purge-path", async (event, targetPath) => { return purgePath(targetPath); }); import_electron.ipcMain.handle("update-tray-title", (event, title) => { if (tray) { tray.setTitle(title); updateTrayMenu(title); } }); import_electron.ipcMain.handle("get-app-icon", async (event, appPath) => { try { const icon = await import_electron.app.getFileIcon(appPath, { size: "normal" }); return icon.toDataURL(); } catch (e) { console.error("Failed to get icon for:", appPath, e); return ""; return ""; } }); import_electron.ipcMain.handle("update-tray-icon", (event, dataUrl) => { if (tray && dataUrl) { const image = import_electron.nativeImage.createFromDataURL(dataUrl); tray.setImage(image.resize({ width: 22, height: 22 })); } }); createWindow(); createTray(); startBackend(); }); import_electron.app.on("will-quit", () => { if (backendProcess) { console.log("Killing backend process..."); backendProcess.kill(); backendProcess = null; } }); import_electron.app.on("window-all-closed", () => { if (process.platform !== "darwin") { import_electron.app.quit(); } }); import_electron.app.on("activate", () => { if (mainWindow === null) { createWindow(); } });