fix: CSP null for tool windows + tauri://error diagnostic listeners
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m0s

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) <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell 2026-03-30 12:20:40 -04:00
parent a36793563c
commit f7b806ffc0
3 changed files with 9 additions and 5 deletions

View File

@ -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
},

View File

@ -135,7 +135,7 @@ async function detachTab(): Promise<void> {
// 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<void> {
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 {

View File

@ -369,7 +369,7 @@ async function handleHelpAction(page: string): Promise<void> {
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<void> {
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<void> {
@ -414,7 +415,7 @@ async function handleToolAction(tool: string): Promise<void> {
// 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<void> {
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<void> {
@ -446,7 +448,7 @@ async function handleOpenFile(entry: FileEntry): Promise<void> {
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<void> {
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); }
}