Files
ag-x/dist/updater.js
admin 43e2a2f78f AG X v2.0.3 - Antigravity fork with multi-provider support
Features:
- Welcome screen on first run (provider choice before LS starts)
- 15+ AI providers (Google Gemini, OpenAI, Anthropic, DeepSeek, Ollama, etc.)
- Provider config syncs to endpoints.json for translation proxy
- Built-in Node.js translation proxy for non-native backends
- Auto-update support, tray integration, URI scheme handler
2026-05-22 23:20:10 +04:00

242 lines
9.7 KiB
JavaScript

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateActions = exports.MenuUpdateStep = void 0;
exports.broadcastState = broadcastState;
exports.initAutoUpdater = initAutoUpdater;
exports.checkForUpdates = checkForUpdates;
exports.quitAndInstall = quitAndInstall;
const electron_updater_1 = require("electron-updater");
const electron_1 = require("electron");
const path = __importStar(require("path"));
const child_process_1 = require("child_process");
var MenuUpdateStep;
(function (MenuUpdateStep) {
MenuUpdateStep["CheckForUpdates"] = "Check for Updates";
MenuUpdateStep["CheckingForUpdates"] = "Checking for Updates...";
MenuUpdateStep["DownloadingUpdate"] = "Downloading Update...";
MenuUpdateStep["RestartToUpdate"] = "Restart to Update";
})(MenuUpdateStep || (exports.MenuUpdateStep = MenuUpdateStep = {}));
exports.updateActions = {
[MenuUpdateStep.CheckForUpdates]: () => checkForUpdates(true),
[MenuUpdateStep.CheckingForUpdates]: undefined,
[MenuUpdateStep.DownloadingUpdate]: undefined,
[MenuUpdateStep.RestartToUpdate]: () => quitAndInstall(),
};
// True if the last call to check for updates was from a user click in the menu.
let isManualCheck = false;
// How long to wait after app start before first update check (ms)
const INITIAL_CHECK_DELAY_MS = 10000; // 10 seconds
// How often to re-check for updates after the initial check (ms)
const CHECK_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
/** Broadcast a state change to every open BrowserWindow. */
function broadcastState(state) {
for (const win of electron_1.BrowserWindow.getAllWindows()) {
win.webContents.send('updater:state-changed', state);
}
}
/**
* Updates the state of the menu item based on the current step of the updater.
*/
function updateMenuState(step) {
const menu = electron_1.Menu.getApplicationMenu();
if (menu) {
const item = menu.getMenuItemById('check-for-updates');
if (item) {
item.label = step;
item.enabled = exports.updateActions[step] !== undefined;
}
}
}
/**
* Initializes the auto-updater and registers IPC handlers.
* Call once after the first window is created.
*
* The updater will:
* 1. Wait INITIAL_CHECK_DELAY_MS ms, then check for updates.
* 2. Re-check every CHECK_INTERVAL_MS ms.
* 3. Download updates automatically in the background.
* 4. Broadcast state to the renderer so AppUpdateButton can display progress.
*/
function initAutoUpdater(isHeadless) {
// In dev mode (npm start), electron-updater skips checks because the app
// isn't packaged. Force it to use the dev config file instead.
if (!electron_1.app.isPackaged) {
electron_updater_1.autoUpdater.forceDevUpdateConfig = true;
electron_updater_1.autoUpdater.updateConfigPath = path.join(electron_1.app.getAppPath(), 'dev-app-update.yml');
}
// Set the channel based on architecture and OS.
// On Windows, we need to explicitly append '-win' to match the artifact name.
// On macOS and linux, Electron automatically appends the OS to the channel name.
if (process.platform === 'win32') {
electron_updater_1.autoUpdater.channel = `latest-${process.arch}-win`;
}
else {
electron_updater_1.autoUpdater.channel = `latest-${process.arch}`;
}
electron_updater_1.autoUpdater.autoDownload = true;
electron_updater_1.autoUpdater.autoInstallOnAppQuit = electron_1.app.isPackaged;
// Auto-updater event handlers → broadcast to renderer
electron_updater_1.autoUpdater.on('checking-for-update', () => {
console.log('[AutoUpdater] Checking for update…');
broadcastState({ type: 'checking for updates' });
updateMenuState(MenuUpdateStep.CheckingForUpdates);
});
electron_updater_1.autoUpdater.on('update-available', (info) => {
console.log(`[AutoUpdater] Update available: ${info.version}`);
broadcastState({
type: 'available for download',
update: { version: info.version },
});
updateMenuState(MenuUpdateStep.DownloadingUpdate);
isManualCheck = false;
});
electron_updater_1.autoUpdater.on('update-not-available', (info) => {
console.log(`[AutoUpdater] Up to date (${info.version})`);
broadcastState({ type: 'idle' });
updateMenuState(MenuUpdateStep.CheckForUpdates);
if (isManualCheck && !isHeadless) {
const win = electron_1.BrowserWindow.getFocusedWindow();
const options = {
type: 'info',
title: 'Check for Updates',
message: 'No updates available',
buttons: ['OK'],
};
if (win) {
electron_1.dialog.showMessageBox(win, options);
}
else {
electron_1.dialog.showMessageBox(options);
}
}
isManualCheck = false;
});
electron_updater_1.autoUpdater.on('download-progress', () => {
broadcastState({ type: 'downloading' });
updateMenuState(MenuUpdateStep.DownloadingUpdate);
});
electron_updater_1.autoUpdater.on('update-downloaded', (info) => {
console.log(`[AutoUpdater] Update downloaded: ${info.version}`);
if (isHeadless) {
// Proceed to auto install in headless mode
if (electron_1.app.isPackaged) {
if (process.platform === 'linux') {
const downloadedFilePath = info.downloadedFile;
headlessQuitAndInstall(downloadedFilePath);
}
else {
electron_updater_1.autoUpdater.quitAndInstall();
}
}
else {
console.log('[AutoUpdater] Headless mode: Skipping quitAndInstall (not packaged).');
}
return;
}
broadcastState({
type: 'ready',
update: { version: info.version },
});
updateMenuState(MenuUpdateStep.RestartToUpdate);
});
electron_updater_1.autoUpdater.on('error', (err) => {
console.error('[AutoUpdater] Error:', err.message);
broadcastState({ type: 'idle' });
updateMenuState(MenuUpdateStep.CheckForUpdates);
isManualCheck = false;
});
// Schedule periodic checks
setTimeout(() => {
checkForUpdates();
setInterval(checkForUpdates, CHECK_INTERVAL_MS);
}, INITIAL_CHECK_DELAY_MS);
}
function checkForUpdates(isManual = false) {
isManualCheck = isManual;
electron_updater_1.autoUpdater.checkForUpdates().catch((err) => {
console.error('[AutoUpdater] Failed to check for updates:', err.message);
});
}
function quitAndInstall() {
electron_updater_1.autoUpdater.quitAndInstall();
}
/**
* Electron native quitAndInstall doesn't relaunch the app with command line arguments.
* This function waits for the app process to quit, manually replaces the executable with
* the downloaded update, and then relaunches it with the right headless flags.
*/
function headlessQuitAndInstall(downloadedFilePath) {
console.log('[AutoUpdater] Headless mode: Scheduling post-quit restart.');
try {
const currentPid = process.pid;
const appPath = process.env.APPIMAGE || process.execPath;
const args = [
'--ozone-platform=headless',
'--headless',
'--disable-gpu',
'--no-sandbox',
];
let script = '';
if (downloadedFilePath) {
console.log(`[AutoUpdater] Will manually replace ${appPath} with ${downloadedFilePath}`);
script = `
while kill -0 ${currentPid} 2>/dev/null; do sleep 0.5; done
cp -f "${downloadedFilePath}" "${appPath}"
chmod +x "${appPath}"
"${appPath}" ${args.join(' ')}
`;
}
else {
console.warn('[AutoUpdater] No downloaded file path found, relaunching without update.');
script = `
while kill -0 ${currentPid} 2>/dev/null; do sleep 0.5; done
sleep 3
"${appPath}" ${args.join(' ')}
`;
}
const child = (0, child_process_1.spawn)('sh', ['-c', script], {
detached: true,
stdio: 'ignore',
env: { ...process.env, ELECTRON_OZONE_PLATFORM_HINT: 'headless' },
});
child.unref();
}
catch (e) {
console.error('[AutoUpdater] Failed to schedule restart:', e);
}
electron_1.app.quit();
}