Open script service URLs in-app or external

Adds a Service URLs setting (ask / in-Paseo / external browser) that
controls where URLs from running scripts open on desktop. First click
prompts with a "don't ask again" checkbox; in-Paseo opens a workspace
browser tab. Closing a browser tab now clears its session partition.
This commit is contained in:
Mohamed Boudra
2026-05-03 15:14:28 +07:00
parent 02adadbbc8
commit f58cfe9008
12 changed files with 257 additions and 18 deletions
+26
View File
@@ -7,6 +7,11 @@ interface AskOptions {
kind?: "info" | "warning" | "error";
}
interface AskWithCheckboxOptions extends AskOptions {
checkboxLabel: string;
checkboxChecked?: boolean;
}
interface OpenOptions {
title?: string;
defaultPath?: string;
@@ -35,6 +40,27 @@ export function registerDialogHandlers(): void {
return result.response === 1;
});
ipcMain.handle(
"paseo:dialog:askWithCheckbox",
async (event, message: string, options: AskWithCheckboxOptions) => {
const win = BrowserWindow.fromWebContents(event.sender);
const result = await dialog.showMessageBox(win ?? BrowserWindow.getFocusedWindow()!, {
type: resolveDialogType(options.kind),
title: options.title ?? "Confirm",
message,
buttons: [options.cancelLabel ?? "Cancel", options.okLabel ?? "OK"],
defaultId: 1,
cancelId: 0,
checkboxLabel: options.checkboxLabel,
checkboxChecked: options.checkboxChecked ?? false,
});
return {
confirmed: result.response === 1,
dontAskAgain: result.checkboxChecked,
};
},
);
ipcMain.handle("paseo:dialog:open", async (event, options?: OpenOptions) => {
const win = BrowserWindow.fromWebContents(event.sender);
const properties: Electron.OpenDialogOptions["properties"] = [];
+9 -1
View File
@@ -9,7 +9,7 @@ import path from "node:path";
import { pathToFileURL } from "node:url";
import { existsSync } from "node:fs";
import { execFileSync } from "node:child_process";
import { app, BrowserWindow, ipcMain, nativeImage, net, protocol } from "electron";
import { app, BrowserWindow, ipcMain, nativeImage, net, protocol, session } from "electron";
import { createDaemonCommandHandlers, registerDaemonManager } from "./daemon/daemon-manager.js";
import {
parseCliPassthroughArgsFromArgv,
@@ -219,6 +219,14 @@ ipcMain.handle("paseo:browser:set-active-pane", (_event, browserId: unknown) =>
setActivePaseoBrowserPaneId(typeof browserId === "string" ? browserId : null);
});
ipcMain.handle("paseo:browser:clear-partition", async (_event, browserId: unknown) => {
if (typeof browserId !== "string" || browserId.trim().length === 0) {
return;
}
const partition = `persist:paseo-browser-${browserId}`;
await session.fromPartition(partition).clearStorageData();
});
protocol.registerSchemesAsPrivileged([
{ scheme: APP_SCHEME, privileges: { standard: true, secure: true, supportFetchAPI: true } },
]);
+4
View File
@@ -43,6 +43,8 @@ contextBridge.exposeInMainWorld("paseoDesktop", {
dialog: {
ask: (message: string, options?: Record<string, unknown>) =>
ipcRenderer.invoke("paseo:dialog:ask", message, options),
askWithCheckbox: (message: string, options: Record<string, unknown>) =>
ipcRenderer.invoke("paseo:dialog:askWithCheckbox", message, options),
open: (options?: Record<string, unknown>) => ipcRenderer.invoke("paseo:dialog:open", options),
},
notification: {
@@ -60,5 +62,7 @@ contextBridge.exposeInMainWorld("paseoDesktop", {
browser: {
setActivePane: (browserId: string | null) =>
ipcRenderer.invoke("paseo:browser:set-active-pane", browserId),
clearPartition: (browserId: string) =>
ipcRenderer.invoke("paseo:browser:clear-partition", browserId),
},
});