[eric] windows 1.1.60: revert installer to nsis to test if squirrel was the renderer-crash trigger

This commit is contained in:
Eric
2026-05-26 01:20:20 -07:00
parent bb2de72f6f
commit fc8c35e5e0
2 changed files with 25 additions and 63 deletions
+13 -59
View File
@@ -25,17 +25,8 @@ process.on('unhandledRejection', (reason) => {
app.on('child-process-gone', (_event, details) => {
console.error('[diag][main:child-process-gone]', JSON.stringify(details));
});
// Platform-split auto-updater: electron-updater on Mac (full-featured: allowPrerelease, allowDowngrade, progress), Electron's built-in autoUpdater on Windows (required for Squirrel.Windows target; electron-updater dropped Squirrel support).
let autoUpdater;
let isSquirrelUpdater = false;
try {
if (process.platform === 'win32') {
autoUpdater = require('electron').autoUpdater;
isSquirrelUpdater = true;
} else {
autoUpdater = require('electron-updater').autoUpdater;
}
} catch (_) {}
try { autoUpdater = require('electron-updater').autoUpdater; } catch (_) {}
const path = require('path');
const { spawn, execFileSync } = require('child_process');
const os = require('os');
@@ -45,8 +36,8 @@ const http = require('http');
const affiliateTracking = require('./affiliateTracking');
const workflowsLifecycle = require('./workflowsLifecycle');
// Defender warmup helper. Touches bundled exes so Windows scans them now instead of on first launch.
function _squirrelPrewarmTouch() {
// Defender warmup: NSIS runs us with --prewarm right after install so Windows scans the bundled binaries while the user is already watching the installer instead of staring at a slow first launch.
if (process.argv.includes('--prewarm') && process.platform === 'win32') {
const touchExe = (rel) => {
const full = path.join(process.resourcesPath, rel);
try {
@@ -58,27 +49,9 @@ function _squirrelPrewarmTouch() {
touchExe(path.join('python-env', 'python.exe'));
touchExe(path.join('node', 'x64', 'node.exe'));
touchExe(path.join('node', 'arm64', 'node.exe'));
}
// Legacy NSIS prewarm path (kept for any user still on 1.1.40 stable NSIS install).
if (process.argv.includes('--prewarm') && process.platform === 'win32') {
_squirrelPrewarmTouch();
process.exit(0);
}
// Squirrel.Windows lifecycle: app is invoked with --squirrel-* args during install/update/uninstall. Handle and exit fast; --squirrel-firstrun is the only one we let fall through to normal boot.
(function handleSquirrelEvents() {
if (process.platform !== 'win32' || process.argv.length < 2) return;
const sq = process.argv[1];
if (sq === '--squirrel-install' || sq === '--squirrel-updated') {
_squirrelPrewarmTouch();
process.exit(0);
}
if (sq === '--squirrel-uninstall' || sq === '--squirrel-obsolete') {
process.exit(0);
}
})();
// Prevent duplicate instances. Without this, double-clicking the app icon
// (or macOS auto-launch + manual launch overlapping) spawns two independent
// processes — each with its own backend on a different port — resulting in
@@ -982,25 +955,15 @@ function sendToRenderer(channel, ...args) {
function setupAutoUpdater() {
if (!autoUpdater) return;
if (isSquirrelUpdater) {
// Squirrel.Windows: setFeedURL to GH Releases /latest/download/ so Squirrel fetches RELEASES from there. allowPrerelease/allowDowngrade not supported by built-in autoUpdater; experimental users on Windows get only the latest stable until we wire a separate Squirrel feed for prereleases.
try {
autoUpdater.setFeedURL({ url: 'https://github.com/openswarm-ai/openswarm/releases/latest/download/' });
} catch (err) {
console.warn('[updater] Squirrel setFeedURL failed:', err && err.message);
return;
}
} else {
// Silent background updates: download on detect, install on next quit.
// The OS gates the install on main-process exit (can't replace a
// running .app / locked .exe), so an active session is never disrupted.
autoUpdater.autoDownload = true;
autoUpdater.autoInstallOnAppQuit = true;
// Renderer pushes the user's experimental-updates setting via IPC right after settings load.
autoUpdater.allowPrerelease = false;
// Lets us un-ship a bad release: re-flip GH 'latest' to an older one and users hop back to it.
autoUpdater.allowDowngrade = true;
}
// Silent background updates: download on detect, install on next quit.
// The OS gates the install on main-process exit (can't replace a
// running .app / locked .exe), so an active session is never disrupted.
autoUpdater.autoDownload = true;
autoUpdater.autoInstallOnAppQuit = true;
// Renderer pushes the user's experimental-updates setting via IPC right after settings load.
autoUpdater.allowPrerelease = false;
// Lets us un-ship a bad release: re-flip GH 'latest' to an older one and users hop back to it.
autoUpdater.allowDowngrade = true;
autoUpdater.on('update-available', (info) => {
console.log(`Update available: ${info.version}`);
@@ -1670,8 +1633,6 @@ ipcMain.handle('check-for-updates', async () => {
ipcMain.handle('download-update', async () => {
if (!autoUpdater) return { success: false, error: 'Updater not available' };
// Squirrel built-in autoUpdater auto-downloads on detect; no manual trigger needed.
if (isSquirrelUpdater) return { success: true };
try {
await autoUpdater.downloadUpdate();
return { success: true };
@@ -1682,8 +1643,6 @@ ipcMain.handle('download-update', async () => {
ipcMain.handle('set-allow-prerelease', async (_e, value) => {
if (!autoUpdater) return { success: false, error: 'Updater not available' };
// Squirrel built-in autoUpdater has no allowPrerelease; experimental channel on Windows is a TODO once we wire a separate Squirrel feed URL.
if (isSquirrelUpdater) return { success: false, error: 'Experimental channel not yet supported on Windows Squirrel target' };
const next = Boolean(value);
if (autoUpdater.allowPrerelease === next) return { success: true, changed: false };
autoUpdater.allowPrerelease = next;
@@ -1703,12 +1662,7 @@ ipcMain.handle('install-update', async () => {
const vetoed = await workflowsLifecycle.maybeVetoInstall();
if (vetoed) return { vetoed: true };
} catch (_) {}
// Built-in autoUpdater on Windows takes no args; electron-updater on Mac takes (isSilent, isForceRunAfter).
if (isSquirrelUpdater) {
autoUpdater.quitAndInstall();
} else {
autoUpdater.quitAndInstall(false, true);
}
autoUpdater.quitAndInstall(false, true);
});
ipcMain.handle('capture-page', async (event, rect) => {
+12 -4
View File
@@ -1,6 +1,6 @@
{
"name": "openswarm",
"version": "1.1.59",
"version": "1.1.60",
"description": "OpenSwarm — AI Agent Orchestrator",
"author": "openswarm-ai",
"main": "main.js",
@@ -68,7 +68,7 @@
"icon": "build/icon.ico",
"target": [
{
"target": "squirrel",
"target": "nsis",
"arch": ["x64"]
}
],
@@ -77,8 +77,16 @@
"signingHashAlgorithms": ["sha256"],
"signDlls": false
},
"squirrelWindows": {
"iconUrl": "https://raw.githubusercontent.com/openswarm-ai/openswarm/main/electron/build/icon.ico"
"nsis": {
"oneClick": true,
"perMachine": false,
"allowToChangeInstallationDirectory": false,
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "OpenSwarm",
"deleteAppDataOnUninstall": false,
"artifactName": "OpenSwarm-Setup-${arch}.${ext}",
"include": "build/installer-recovery.nsh"
},
"extraResources": [
{