diff --git a/packages/web-ui/src/components/SandboxedIframe.ts b/packages/web-ui/src/components/SandboxedIframe.ts index a6131858..fba7b7d8 100644 --- a/packages/web-ui/src/components/SandboxedIframe.ts +++ b/packages/web-ui/src/components/SandboxedIframe.ts @@ -559,14 +559,18 @@ ${runtimeFunctions.join("\n")} } }, true); - // Prevent window.location changes - const originalLocation = window.location; - Object.defineProperty(window, 'location', { - get: function() { return originalLocation; }, - set: function(url) { - window.parent.postMessage({ type: 'open-external-url', url: url.toString() }, '*'); - } - }); + // Prevent window.location changes (only if not already redefined) + try { + const originalLocation = window.location; + Object.defineProperty(window, 'location', { + get: function() { return originalLocation; }, + set: function(url) { + window.parent.postMessage({ type: 'open-external-url', url: url.toString() }, '*'); + } + }); + } catch (e) { + // Already defined, skip + } })(); `; } diff --git a/packages/web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts b/packages/web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts index 5f2509f1..b0a7c3a5 100644 --- a/packages/web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts +++ b/packages/web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts @@ -43,7 +43,7 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider { (window as any).listArtifacts = async (): Promise => { // Online: ask extension - if ((window as any).__isExtensionContext?.()) { + if ((window as any).sendRuntimeMessage) { const response = await (window as any).sendRuntimeMessage({ type: "artifact-operation", action: "list", @@ -61,7 +61,7 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider { let content: string; // Online: ask extension - if ((window as any).__isExtensionContext?.()) { + if ((window as any).sendRuntimeMessage) { const response = await (window as any).sendRuntimeMessage({ type: "artifact-operation", action: "get", @@ -94,7 +94,7 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider { content: any, mimeType?: string, ): Promise => { - if (!(window as any).__isExtensionContext?.()) { + if (!(window as any).sendRuntimeMessage) { throw new Error("Cannot create/update artifacts in offline mode (read-only)"); } @@ -117,7 +117,7 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider { }; (window as any).deleteArtifact = async (filename: string): Promise => { - if (!(window as any).__isExtensionContext?.()) { + if (!(window as any).sendRuntimeMessage) { throw new Error("Cannot delete artifacts in offline mode (read-only)"); } diff --git a/packages/web-ui/src/components/sandbox/ConsoleRuntimeProvider.ts b/packages/web-ui/src/components/sandbox/ConsoleRuntimeProvider.ts index d3b34eba..f5f4be5f 100644 --- a/packages/web-ui/src/components/sandbox/ConsoleRuntimeProvider.ts +++ b/packages/web-ui/src/components/sandbox/ConsoleRuntimeProvider.ts @@ -52,7 +52,7 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider { (originalConsole as any)[method].apply(console, args); // Send immediately and track the promise (only in extension context) - if ((window as any).__isExtensionContext?.()) { + if ((window as any).sendRuntimeMessage) { const sendPromise = (window as any) .sendRuntimeMessage({ type: "console", @@ -108,7 +108,7 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider { const finalError = error || lastError; - if ((window as any).__isExtensionContext?.()) { + if ((window as any).sendRuntimeMessage) { if (finalError) { await (window as any).sendRuntimeMessage({ type: "execution-error", diff --git a/packages/web-ui/src/components/sandbox/FileDownloadRuntimeProvider.ts b/packages/web-ui/src/components/sandbox/FileDownloadRuntimeProvider.ts index 313cc900..824ae125 100644 --- a/packages/web-ui/src/components/sandbox/FileDownloadRuntimeProvider.ts +++ b/packages/web-ui/src/components/sandbox/FileDownloadRuntimeProvider.ts @@ -53,7 +53,7 @@ export class FileDownloadRuntimeProvider implements SandboxRuntimeProvider { } // Send to extension if in extension context (online mode) - if ((window as any).__isExtensionContext?.()) { + if ((window as any).sendRuntimeMessage) { const response = await (window as any).sendRuntimeMessage({ type: "file-returned", fileName, diff --git a/packages/web-ui/src/components/sandbox/RuntimeMessageBridge.ts b/packages/web-ui/src/components/sandbox/RuntimeMessageBridge.ts index 1e838b15..b2e754e5 100644 --- a/packages/web-ui/src/components/sandbox/RuntimeMessageBridge.ts +++ b/packages/web-ui/src/components/sandbox/RuntimeMessageBridge.ts @@ -28,13 +28,6 @@ export class RuntimeMessageBridge { // Returns stringified function that uses window.parent.postMessage return ` window.__completionCallbacks = []; -// Check if we're in an extension context by examining the URL -window.__isExtensionContext = () => { - const url = window.location.href; - return url.startsWith('chrome-extension://') || - url.startsWith('moz-extension://') || - url === 'about:srcdoc'; -}; window.sendRuntimeMessage = async (message) => { const messageId = 'msg_' + Date.now() + '_' + Math.random().toString(36).substring(2, 9); @@ -75,13 +68,6 @@ window.onCompleted = (callback) => { // Returns stringified function that uses chrome.runtime.sendMessage return ` window.__completionCallbacks = []; -// Check if we're in an extension context by examining the URL -window.__isExtensionContext = () => { - const url = window.location.href; - return url.startsWith('chrome-extension://') || - url.startsWith('moz-extension://') || - url === 'about:srcdoc'; -}; window.sendRuntimeMessage = async (message) => { return await chrome.runtime.sendMessage({ ...message,