(version: string)
| 917 | }; |
| 918 | |
| 919 | const promptInstallUpdate = async (version: string) => { |
| 920 | if (updateDialogOpen) return; |
| 921 | updateDialogOpen = true; |
| 922 | // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: dialog wrapper guarantees the open flag clears |
| 923 | try { |
| 924 | const response = await dialog.showMessageBox({ |
| 925 | type: "info", |
| 926 | title: "Update ready", |
| 927 | message: `Executor ${version} is ready to install.`, |
| 928 | detail: "Restart now to apply the update, or keep working — we'll prompt again later.", |
| 929 | buttons: ["Restart now", "Later"], |
| 930 | defaultId: 0, |
| 931 | cancelId: 1, |
| 932 | }); |
| 933 | if (response.response === 0) { |
| 934 | // Stop the sidecar cleanly before Squirrel.Mac swaps the bundle. A |
| 935 | // supervised daemon is left running — it's independent of this bundle. |
| 936 | stopSupervisedMonitor(); |
| 937 | if (connection) { |
| 938 | await stopConnection(connection); |
| 939 | connection = null; |
| 940 | } |
| 941 | autoUpdater.quitAndInstall(false, true); |
| 942 | return; |
| 943 | } |
| 944 | declinedUpdateVersion = version; |
| 945 | } finally { |
| 946 | updateDialogOpen = false; |
| 947 | } |
| 948 | }; |
| 949 | |
| 950 | // Re-check periodically so a long-running session picks up releases |
| 951 | // without requiring a quit + relaunch. The boot-time check still runs; |
no test coverage detected