fix(desktop-shell-window): stop blocking main process on untrusted-link dialog

showMessageBoxSync froze the main-process event loop while the user
decided whether to open an external link, stalling agent-event workers,
IPC, and the scheduler for the duration of the dialog. setWindowOpenHandler
still returns synchronously with action: "deny"; the confirmation dialog
runs in an async continuation that only reaches shell.openExternal when
the user approves.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-16 21:42:29 -04:00
1 parent f803b0b826
commit ff08ab3e35
1 file changed
+22 -12
+22 -12
View File
@@ -175,18 +175,28 @@ export function createDesktopShellWindow(deps: DesktopShellWindowDependencies) {
return { action: "deny" };
}
if (url.startsWith("https://") || url.startsWith("http://")) {
const choice = dialog.showMessageBoxSync({
type: "question",
buttons: ["Open Link", "Cancel"],
defaultId: 1,
cancelId: 1,
title: "Open External Link?",
message: "AgentCompany blocked an untrusted external link.",
detail: `${url}\n\nOnly trusted product and documentation domains open automatically. Review this destination before continuing.`,
});
if (choice === 0) {
void shell.openExternal(url);
}
// Dialog is dispatched asynchronously so the main-process event loop
// is not blocked while the user decides. setWindowOpenHandler must
// return synchronously, so the window is always denied here; if the
// user approves, shell.openExternal runs in the async continuation.
void (async () => {
const parentWindow = mainWindow && !mainWindow.isDestroyed() ? mainWindow : null;
const options: Electron.MessageBoxOptions = {
type: "question",
buttons: ["Open Link", "Cancel"],
defaultId: 1,
cancelId: 1,
title: "Open External Link?",
message: "AgentCompany blocked an untrusted external link.",
detail: `${url}\n\nOnly trusted product and documentation domains open automatically. Review this destination before continuing.`,
};
const result = parentWindow
? await dialog.showMessageBox(parentWindow, options)
: await dialog.showMessageBox(options);
if (result.response === 0) {
void shell.openExternal(url);
}
})();
}
return { action: "deny" };
});