| import { app, BrowserWindow, clipboard, dialog, ipcMain, shell } from 'electron' | |
| import * as path from 'node:path' | |
| import * as fssync from 'node:fs' | |
| import { | |
| getDrivesWin, | |
| listDirectory, | |
| computeFolderSize, | |
| findLargeFiles, | |
| getProcessesWin, | |
| getServicesWin, | |
| getInstalledPrograms, | |
| getSystemSnapshot, | |
| getNetworkInterfaces, | |
| getEnvSnapshot, | |
| getStartupFolders, | |
| getTempAudit, | |
| getScheduledTasksSummary, | |
| openPathInExplorer, | |
| killProcess, | |
| getWindowsFeaturesSnippet, | |
| } from './audit' | |
| import { startPythonBackend, stopPythonBackend } from './pythonBackend' | |
| const isDev = !!process.env.VITE_DEV_SERVER_URL | |
| function notesPath() { | |
| return path.join(app.getPath('userData'), 'auditor-notes.json') | |
| } | |
| function loadNotes(): Record<string, string> { | |
| try { | |
| const raw = fssync.readFileSync(notesPath(), 'utf8') | |
| return JSON.parse(raw) as Record<string, string> | |
| } catch { | |
| return {} | |
| } | |
| } | |
| function saveNotes(n: Record<string, string>) { | |
| fssync.mkdirSync(path.dirname(notesPath()), { recursive: true }) | |
| fssync.writeFileSync(notesPath(), JSON.stringify(n, null, 2), 'utf8') | |
| } | |
| function createWindow() { | |
| const win = new BrowserWindow({ | |
| width: 1280, | |
| height: 800, | |
| minWidth: 960, | |
| minHeight: 640, | |
| backgroundColor: '#0d0f12', | |
| titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : 'default', | |
| webPreferences: { | |
| preload: path.join(__dirname, 'preload.js'), | |
| contextIsolation: true, | |
| nodeIntegration: false, | |
| sandbox: false, | |
| }, | |
| }) | |
| if (isDev) { | |
| win.loadURL(process.env.VITE_DEV_SERVER_URL!) | |
| } else { | |
| win.loadFile(path.join(__dirname, '../dist/index.html')) | |
| } | |
| } | |
| app.whenReady().then(async () => { | |
| try { | |
| await startPythonBackend() | |
| } catch (e) { | |
| dialog.showErrorBox( | |
| 'Python backend required', | |
| `${String(e)}\n\nInstall: cd backend && pip install -r requirements.txt` | |
| ) | |
| app.quit() | |
| return | |
| } | |
| ipcMain.handle('audit:drives', () => getDrivesWin()) | |
| ipcMain.handle('audit:listDir', (_e, dirPath: string, opts?: { maxEntries?: number }) => | |
| listDirectory(dirPath, opts ?? {}) | |
| ) | |
| ipcMain.handle('audit:folderSize', (_e, dirPath: string) => computeFolderSize(dirPath)) | |
| ipcMain.handle('audit:largeFiles', (_e, rootPath: string, minBytes: number, maxResults: number) => | |
| findLargeFiles(rootPath, minBytes, maxResults) | |
| ) | |
| ipcMain.handle('audit:processes', () => getProcessesWin()) | |
| ipcMain.handle('audit:services', () => getServicesWin()) | |
| ipcMain.handle('audit:installed', () => getInstalledPrograms()) | |
| ipcMain.handle('audit:system', () => getSystemSnapshot()) | |
| ipcMain.handle('audit:network', () => getNetworkInterfaces()) | |
| ipcMain.handle('audit:env', (_e, keys?: string[]) => getEnvSnapshot(keys)) | |
| ipcMain.handle('audit:startup', () => getStartupFolders()) | |
| ipcMain.handle('audit:temp', () => getTempAudit()) | |
| ipcMain.handle('audit:tasks', () => getScheduledTasksSummary()) | |
| ipcMain.handle('audit:features', () => getWindowsFeaturesSnippet()) | |
| ipcMain.handle('audit:openExplorer', (_e, p: string) => openPathInExplorer(p)) | |
| ipcMain.handle('audit:killProcess', (_e, pid: number) => killProcess(pid)) | |
| ipcMain.handle('audit:openExternal', (_e, url: string) => shell.openExternal(url)) | |
| ipcMain.handle('clipboard:writeText', (_e, text: string) => { | |
| clipboard.writeText(text) | |
| }) | |
| ipcMain.handle('notes:getAll', () => loadNotes()) | |
| ipcMain.handle('notes:set', (_e, key: string, value: string) => { | |
| const all = loadNotes() | |
| if (value.trim() === '') delete all[key] | |
| else all[key] = value | |
| saveNotes(all) | |
| return all | |
| }) | |
| ipcMain.handle('notes:delete', (_e, key: string) => { | |
| const all = loadNotes() | |
| delete all[key] | |
| saveNotes(all) | |
| return all | |
| }) | |
| createWindow() | |
| app.on('activate', () => { | |
| if (BrowserWindow.getAllWindows().length === 0) createWindow() | |
| }) | |
| }) | |
| app.on('window-all-closed', () => { | |
| if (process.platform !== 'darwin') app.quit() | |
| }) | |
| app.on('before-quit', () => { | |
| stopPythonBackend() | |
| }) | |