From f7b806ffc00c421b9c9f25c6f0489801ed027387 Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Mon, 30 Mar 2026 12:20:40 -0400 Subject: [PATCH] fix: CSP null for tool windows + tauri://error diagnostic listeners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tool windows open/close immediately — diagnostic build: - CSP set to null to eliminate it as a variable. The CSP was blocking IPC initialization in child WebviewWindows on macOS WKWebView. - Added tauri://error listeners to ALL WebviewWindow creations (tool, help, editor, detach). If window creation fails on the Rust side, an alert will show the error instead of silently closing. - If tool windows work with csp:null, we know the CSP was the cause and can craft a macOS-compatible policy. If they still fail, the error alert will reveal the actual Rust-side error. Co-Authored-By: Claude Opus 4.6 (1M context) --- src-tauri/tauri.conf.json | 2 +- src/components/session/TabBar.vue | 3 ++- src/layouts/MainLayout.vue | 9 ++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c167224..651883e 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -23,7 +23,7 @@ } ], "security": { - "csp": "default-src 'self' 'unsafe-inline' asset: https://asset.localhost; img-src 'self' asset: https://asset.localhost data: blob:; connect-src ipc: http://ipc.localhost https://ipc.localhost" + "csp": null }, "withGlobalTauri": false }, diff --git a/src/components/session/TabBar.vue b/src/components/session/TabBar.vue index df2b946..496480c 100644 --- a/src/components/session/TabBar.vue +++ b/src/components/session/TabBar.vue @@ -135,7 +135,7 @@ async function detachTab(): Promise { // Open a new Tauri window for this session const { WebviewWindow } = await import("@tauri-apps/api/webviewWindow"); const label = `detached-${session.id.substring(0, 8)}-${Date.now()}`; - new WebviewWindow(label, { + const wv = new WebviewWindow(label, { title: `${session.name} — Wraith`, width: 900, height: 600, @@ -143,6 +143,7 @@ async function detachTab(): Promise { center: true, url: `index.html#/detached-session?sessionId=${session.id}&name=${encodeURIComponent(session.name)}&protocol=${session.protocol}`, }); + wv.once("tauri://error", (e) => { console.error("Detach window error:", e); }); } function closeMenuTab(): void { diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index a555d1d..37075d9 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -369,7 +369,7 @@ async function handleHelpAction(page: string): Promise { showHelpMenu.value = false; const { WebviewWindow } = await import("@tauri-apps/api/webviewWindow"); const label = `help-${page}-${Date.now()}`; - new WebviewWindow(label, { + const wv = new WebviewWindow(label, { title: `Wraith — Help`, width: 750, height: 600, @@ -377,6 +377,7 @@ async function handleHelpAction(page: string): Promise { center: true, url: `index.html#/tool/help?page=${page}`, }); + wv.once("tauri://error", (e) => { console.error("Help window error:", e); alert("Window error: " + JSON.stringify(e.payload)); }); } async function handleToolAction(tool: string): Promise { @@ -414,7 +415,7 @@ async function handleToolAction(tool: string): Promise { // Open tool in a new Tauri window const label = `tool-${tool}-${Date.now()}`; - new WebviewWindow(label, { + const wv = new WebviewWindow(label, { title: `Wraith — ${config.title}`, width: config.width, height: config.height, @@ -422,6 +423,7 @@ async function handleToolAction(tool: string): Promise { center: true, url: `index.html#/tool/${tool}?sessionId=${sessionId}`, }); + wv.once("tauri://error", (e) => { console.error("Tool window error:", e); alert("Window error: " + JSON.stringify(e.payload)); }); } async function handleFileMenuAction(action: string): Promise { @@ -446,7 +448,7 @@ async function handleOpenFile(entry: FileEntry): Promise { const label = `editor-${Date.now()}`; const sessionId = activeSessionId.value; - new WebviewWindow(label, { + const wv = new WebviewWindow(label, { title: `${fileName} — Wraith Editor`, width: 800, height: 600, @@ -454,6 +456,7 @@ async function handleOpenFile(entry: FileEntry): Promise { center: true, url: `index.html#/tool/editor?sessionId=${sessionId}&path=${encodeURIComponent(entry.path)}`, }); + wv.once("tauri://error", (e) => { console.error("Editor window error:", e); alert("Window error: " + JSON.stringify(e.payload)); }); } catch (err) { console.error("Failed to open editor:", err); } }