fix(desktop): stop daemon before auto-update restart
The daemon is a detached process that survives Electron restarts, so after an auto-update the old daemon version would keep running. Now we stop it before quitAndInstall so the new app instance starts a fresh daemon with the updated binary.
This commit is contained in:
@@ -548,7 +548,9 @@ export function createDaemonCommandHandlers(): Record<string, DesktopCommandHand
|
|||||||
},
|
},
|
||||||
install_app_update: async () => {
|
install_app_update: async () => {
|
||||||
const currentVersion = await resolveCurrentUpdateVersion();
|
const currentVersion = await resolveCurrentUpdateVersion();
|
||||||
return downloadAndInstallUpdate(currentVersion);
|
return downloadAndInstallUpdate(currentVersion, async () => {
|
||||||
|
await stopDaemon();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
get_local_daemon_version: () => getLocalDaemonVersion(),
|
get_local_daemon_version: () => getLocalDaemonVersion(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ export async function checkForAppUpdate(currentVersion: string): Promise<AppUpda
|
|||||||
|
|
||||||
export async function downloadAndInstallUpdate(
|
export async function downloadAndInstallUpdate(
|
||||||
currentVersion: string,
|
currentVersion: string,
|
||||||
|
onBeforeQuit?: () => Promise<void>,
|
||||||
): Promise<AppUpdateInstallResult> {
|
): Promise<AppUpdateInstallResult> {
|
||||||
if (!app.isPackaged) {
|
if (!app.isPackaged) {
|
||||||
return {
|
return {
|
||||||
@@ -131,8 +132,9 @@ export async function downloadAndInstallUpdate(
|
|||||||
await autoUpdater.downloadUpdate();
|
await autoUpdater.downloadUpdate();
|
||||||
// quitAndInstall restarts the app with the new version.
|
// quitAndInstall restarts the app with the new version.
|
||||||
// Use a short delay to allow the renderer to receive the response.
|
// Use a short delay to allow the renderer to receive the response.
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
|
if (onBeforeQuit) await onBeforeQuit();
|
||||||
autoUpdater.quitAndInstall(/* isSilent */ false, /* isForceRunAfter */ true);
|
autoUpdater.quitAndInstall(/* isSilent */ false, /* isForceRunAfter */ true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[auto-updater] quitAndInstall failed:", error);
|
console.error("[auto-updater] quitAndInstall failed:", error);
|
||||||
|
|||||||
@@ -83,30 +83,6 @@ const CODEX_MODES: AgentProviderModeDefinition[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const COPILOT_MODES: AgentProviderModeDefinition[] = [
|
|
||||||
{
|
|
||||||
id: "https://agentclientprotocol.com/protocol/session-modes#agent",
|
|
||||||
label: "Agent",
|
|
||||||
description: "Default agent mode for conversational interactions",
|
|
||||||
icon: "ShieldAlert",
|
|
||||||
colorTier: "moderate",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "https://agentclientprotocol.com/protocol/session-modes#plan",
|
|
||||||
label: "Plan",
|
|
||||||
description: "Plan mode for creating and executing multi-step plans",
|
|
||||||
icon: "ShieldCheck",
|
|
||||||
colorTier: "planning",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "https://agentclientprotocol.com/protocol/session-modes#autopilot",
|
|
||||||
label: "Autopilot",
|
|
||||||
description: "Autonomous mode that runs until task completion without user interaction",
|
|
||||||
icon: "ShieldOff",
|
|
||||||
colorTier: "dangerous",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const OPENCODE_MODES: AgentProviderModeDefinition[] = [
|
const OPENCODE_MODES: AgentProviderModeDefinition[] = [
|
||||||
{
|
{
|
||||||
id: "build",
|
id: "build",
|
||||||
|
|||||||
Reference in New Issue
Block a user