import { app, dialog } from "electron" import pkg from "electron-updater" import { UPDATER_ENABLED } from "./constants" import { createUpdaterController, type UpdaterReadyRecord } from "./updater-controller" import { getLogger } from "./logging" import { getStore } from "./store" const { autoUpdater } = pkg const key = "ready" export function setupAutoUpdater(stop: () => Promise) { const logger = getLogger() autoUpdater.logger = logger autoUpdater.channel = "latest" autoUpdater.allowPrerelease = false autoUpdater.allowDowngrade = true autoUpdater.autoDownload = false autoUpdater.autoInstallOnAppQuit = false logger.log("auto updater configured", { channel: autoUpdater.channel, allowPrerelease: autoUpdater.allowPrerelease, allowDowngrade: autoUpdater.allowDowngrade, currentVersion: app.getVersion(), }) const store = getStore("opencode.updater") return createUpdaterController({ enabled: UPDATER_ENABLED, currentVersion: app.getVersion(), backend: autoUpdater, persistence: { get() { const value = store.get(key) if (!value || typeof value !== "object" || !("version" in value) || typeof value.version !== "string") return return { version: value.version } satisfies UpdaterReadyRecord }, set: (value) => store.set(key, value), clear: () => store.delete(key), }, stop, log: (message, data) => logger.log(message, data), }) } export async function showUpdaterDialog(controller: ReturnType, alertOnFail: boolean) { const state = await controller.check() if (state.status === "error") { if (!alertOnFail) return await dialog.showMessageBox({ type: "error", message: "Update check failed.", title: "Update Error" }) return } if (state.status === "up-to-date") { if (!alertOnFail) return await dialog.showMessageBox({ type: "info", message: "You're up to date.", title: "No Updates" }) return } if (state.status !== "ready") return const response = await dialog.showMessageBox({ type: "info", message: `Update ${state.version} downloaded. Restart now?`, title: "Update Ready", buttons: ["Restart", "Later"], defaultId: 0, cancelId: 1, }) if (response.response === 0) await controller.install() }