| 1943 | // Create a hidden BrowserWindow to handle IPC (preload script needs a window) |
| 1944 | await createHiddenWindow(); |
| 1945 | // Schedule background hash generation for any existing models with missing hashes |
| 1946 | scheduleBackgroundHashGeneration('startup'); |
| 1947 | scheduleBackgroundThumbnailCompression('startup'); |
| 1948 | setTimeout(() => { |
| 1949 | try { |
| 1950 | verifyDatabaseIntegrity(); |
| 1951 | } catch (e) { |
| 1952 | console.error('Deferred database integrity check failed:', e); |
| 1953 | } |
| 1954 | }, 3000); |
| 1955 | // Don't quit when all windows are closed in server mode |
| 1956 | app.on('window-all-closed', () => { |
| 1957 | // Keep the app running in server mode |
| 1958 | }); |
| 1959 | } else { |
| 1960 | // Normal mode: start localhost-only HTTP server only when Browser Extension is enabled |
| 1961 | const enableExt = db.prepare('SELECT value FROM settings WHERE key = ?').get('enableBrowserExtension')?.value; |
| 1962 | const portRow = db.prepare('SELECT value FROM settings WHERE key = ?').get('browserExtensionPort'); |
| 1963 | const extPort = parseInt(portRow?.value || '5000', 10) || 5000; |
| 1964 | if (enableExt === '1') { |
| 1965 | console.log('[Browser extension] Setting enabled at startup — starting server on port', extPort); |
| 1966 | startHttpServer(extPort, true).then(() => { |
| 1967 | console.log('[Browser extension] Server started successfully at startup'); |
| 1968 | }).catch((err) => { |
| 1969 | console.error('[Browser extension] Failed to start server at startup:', err.message); |
| 1970 | console.error('[Browser extension] Run from Terminal to see this, or check entitlements (com.apple.security.network.server) and rebuild.'); |
| 1971 | if (dialog && dialog.showErrorBox) { |
| 1972 | dialog.showErrorBox('Browser Extension Server', `Could not start server on port ${extPort}: ${err.message}\n\nOn macOS, the app needs the "Allow incoming network connections" entitlement. Rebuild the app after adding com.apple.security.network.server to build/entitlements.mac.plist.`); |
| 1973 | } |
| 1974 | }); |
| 1975 | } |
| 1976 | // Normal mode: create window (UI served over localhost HTTP for Puter.js compatibility) |
| 1977 | await createWindow(); |
| 1978 | |
| 1979 | app.on('activate', () => { |
| 1980 | if (BrowserWindow.getAllWindows().length === 0) { |
| 1981 | createWindow().catch((err) => { |
| 1982 | console.error('Failed to recreate main window:', err); |
| 1983 | }); |
| 1984 | } |
| 1985 | }); |
| 1986 | |
| 1987 | createApplicationMenu(); |
| 1988 | |
| 1989 | // Version check after first window paint (HTTPS can block for seconds) |
| 1990 | setImmediate(() => { |
| 1991 | checkForUpdates().catch((updateError) => { |
| 1992 | console.error('Error checking version on startup:', updateError); |
| 1993 | }); |
| 1994 | }); |
| 1995 | |
| 1996 | // PRAGMA integrity_check + orphan cleanup can be slow on huge DBs — defer past cold start |
| 1997 | setTimeout(() => { |
| 1998 | try { |
| 1999 | verifyDatabaseIntegrity(); |
| 2000 | } catch (e) { |
| 2001 | console.error('Deferred database integrity check failed:', e); |
| 2002 | } |