Skip to content

Playground#309

Open
arcanis wants to merge 10 commits into
mainfrom
mael/playground
Open

Playground#309
arcanis wants to merge 10 commits into
mainfrom
mael/playground

Conversation

@arcanis

@arcanis arcanis commented Jun 12, 2026

Copy link
Copy Markdown
Member

Work in progress


Note

Medium Risk
Splits HTTP/TLS behavior by compile target (rustls vs native TLS) and adds a large new surface (BrowserPod API keys, COEP/COOP, WASM binary pipeline); native desktop builds should stay on rustls via cfg, but TLS and networking regressions on either target warrant careful review.

Overview
Adds a browser-based Yarn playground on /playground/: preset sample projects (PnP, workspaces, node-modules), a read-only Monaco file tree, and an xterm terminal backed by BrowserPod that mounts template files and optionally a prebuilt yarn-bin.wasm so users can run Yarn in the remote shell.

Rust / BrowserPod target: zpm and zpm-switch gain wasm64 + target_vendor = "browserpod" support—Cpu::Wasm64, rustc-check-cfg in build scripts, and target-specific reqwest TLS (default-tls in the browser pod vs rustls-tls elsewhere). PEM client identity is rejected on the browserpod build. Workspace reqwest/dialoguer defaults are trimmed; a build:browserpod-yarn script builds yarn-bin with the BrowserPod Rust toolchain and publishes assets under website/public/browserpod/.

Site wiring: Playground nav link, COOP/COEP headers on /playground* (middleware, Vite dev/preview plugin, static _headers) for SharedArrayBuffer, plus template loading from website/src/playground/templates with {{YARN_VERSION}} substitution.

Reviewed by Cursor Bugbot for commit ed94ea9. Bugbot is set up for automated code reviews on this repo. Configure here.

arcanis and others added 6 commits June 12, 2026 19:06
BrowserPod currently requires the usage of is own openssl build for
networking.
This will change in the future and this can be reverted then.
linux-raw-sys does not support the BrowserPod target.
In the future a patched version will be provided with the BrowserPod rust
toolchain, and this could be reverted.
BrowserPod matches target_arch = "wasm64"
@netlify

netlify Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploy Preview for yarn-v6 ready!

Name Link
🔨 Latest commit ed94ea9
🔍 Latest deploy log https://app.netlify.com/projects/yarn-v6/deploys/6a39a880b3a4900008124150
😎 Deploy Preview https://deploy-preview-309--yarn-v6.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: API key logged to console
    • Removed console.log statement that was exposing the BrowserPod API key to browser devtools.
  • ✅ Fixed: Share always shows Copied
    • Removed error handler and fallback that incorrectly showed 'Copied' on clipboard failures, now only shows on success.

Create PR

Or push these changes by commenting:

@cursor push b12af016ac
Preview (b12af016ac)
diff --git a/website/src/components/playground/PlaygroundTerminal.tsx b/website/src/components/playground/PlaygroundTerminal.tsx
--- a/website/src/components/playground/PlaygroundTerminal.tsx
+++ b/website/src/components/playground/PlaygroundTerminal.tsx
@@ -224,7 +224,6 @@
 
         writeLines(term, [`${cyan}[browserpod]${reset} Booting pod...`]);
 
-        console.log(`Booting pod...`, apiKey);
         const pod = await BrowserPod.boot({apiKey});
 
         if (disposed || !term)

diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -56,9 +56,7 @@
           };
 
           if (navigator.clipboard && window.isSecureContext)
-            navigator.clipboard.writeText(location.href).then(done, done);
-          else
-            done();
+            navigator.clipboard.writeText(location.href).then(done);
         });
     })();
   </script>

You can send follow-ups to the cloud agent here.

Comment thread website/src/components/playground/PlaygroundTerminal.tsx Outdated
Comment thread website/src/pages/playground.astro
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown

⏱️ Benchmark Results

gatsby install-full-cold

Metric Base Head Difference
Mean 4.392s 4.368s -0.54% ✅
Median 4.403s 4.371s -0.71% ✅
Min 4.237s 4.191s
Max 4.496s 4.475s
Std Dev 0.056s 0.060s
📊 Raw benchmark data (gatsby install-full-cold)

Base times: 4.344s, 4.496s, 4.429s, 4.306s, 4.237s, 4.365s, 4.422s, 4.331s, 4.422s, 4.395s, 4.429s, 4.418s, 4.396s, 4.343s, 4.434s, 4.447s, 4.297s, 4.368s, 4.320s, 4.379s, 4.408s, 4.457s, 4.409s, 4.374s, 4.442s, 4.417s, 4.398s, 4.375s, 4.450s, 4.453s

Head times: 4.402s, 4.401s, 4.377s, 4.348s, 4.313s, 4.398s, 4.350s, 4.395s, 4.400s, 4.318s, 4.343s, 4.377s, 4.378s, 4.378s, 4.361s, 4.449s, 4.475s, 4.353s, 4.362s, 4.191s, 4.356s, 4.361s, 4.357s, 4.310s, 4.378s, 4.226s, 4.400s, 4.462s, 4.366s, 4.461s


gatsby install-cache-only

Metric Base Head Difference
Mean 1.278s 1.274s -0.31% ✅
Median 1.278s 1.276s -0.13% ✅
Min 1.258s 1.258s
Max 1.312s 1.290s
Std Dev 0.011s 0.009s
📊 Raw benchmark data (gatsby install-cache-only)

Base times: 1.273s, 1.280s, 1.282s, 1.289s, 1.275s, 1.276s, 1.260s, 1.274s, 1.282s, 1.279s, 1.268s, 1.287s, 1.296s, 1.287s, 1.272s, 1.277s, 1.284s, 1.273s, 1.280s, 1.290s, 1.291s, 1.280s, 1.312s, 1.280s, 1.273s, 1.273s, 1.259s, 1.258s, 1.267s, 1.273s

Head times: 1.275s, 1.265s, 1.267s, 1.279s, 1.290s, 1.279s, 1.283s, 1.278s, 1.285s, 1.281s, 1.285s, 1.269s, 1.266s, 1.280s, 1.265s, 1.258s, 1.282s, 1.266s, 1.262s, 1.275s, 1.280s, 1.288s, 1.279s, 1.262s, 1.272s, 1.278s, 1.264s, 1.269s, 1.278s, 1.272s


gatsby install-cache-and-lock (warm, with lockfile)

Metric Base Head Difference
Mean 0.344s 0.344s -0.13% ✅
Median 0.343s 0.343s -0.12% ✅
Min 0.338s 0.340s
Max 0.352s 0.355s
Std Dev 0.004s 0.003s
📊 Raw benchmark data (gatsby install-cache-and-lock (warm, with lockfile))

Base times: 0.348s, 0.351s, 0.349s, 0.350s, 0.346s, 0.348s, 0.343s, 0.341s, 0.348s, 0.343s, 0.345s, 0.342s, 0.344s, 0.343s, 0.338s, 0.347s, 0.347s, 0.352s, 0.338s, 0.339s, 0.339s, 0.344s, 0.343s, 0.343s, 0.343s, 0.346s, 0.339s, 0.344s, 0.338s, 0.341s

Head times: 0.346s, 0.342s, 0.343s, 0.343s, 0.341s, 0.340s, 0.344s, 0.342s, 0.346s, 0.355s, 0.344s, 0.342s, 0.342s, 0.344s, 0.343s, 0.341s, 0.343s, 0.342s, 0.342s, 0.343s, 0.347s, 0.343s, 0.344s, 0.340s, 0.347s, 0.344s, 0.343s, 0.345s, 0.343s, 0.342s

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: BrowserPod sessions leak on remount
    • Added disposed check after writeProjectFiles and stored pod reference for cleanup to prevent multiple BrowserPod instances from running simultaneously.

Create PR

Or push these changes by commenting:

@cursor push 1370c6a18b
Preview (1370c6a18b)
diff --git a/website/src/components/playground/PlaygroundTerminal.tsx b/website/src/components/playground/PlaygroundTerminal.tsx
--- a/website/src/components/playground/PlaygroundTerminal.tsx
+++ b/website/src/components/playground/PlaygroundTerminal.tsx
@@ -1,6 +1,6 @@
-import '@xterm/xterm/css/xterm.css';
-import type {Terminal as XtermTerminal} from '@xterm/xterm';
-import {useEffect, useRef}              from 'react';
+import "@xterm/xterm/css/xterm.css";
+import type { Terminal as XtermTerminal } from "@xterm/xterm";
+import { useEffect, useRef } from "react";
 
 interface Props {
   files: Array<PlaygroundFile>;
@@ -20,14 +20,18 @@
     rows?: number;
     onOutput: (buffer: ArrayBuffer) => void;
   }): Promise<BrowserPodTerminal>;
-  createDirectory(path: string, opts?: {recursive?: boolean}): Promise<void>;
+  createDirectory(path: string, opts?: { recursive?: boolean }): Promise<void>;
   createFile(path: string, mode: `binary` | `utf-8`): Promise<BrowserPodFile>;
-  run(executable: string, args: Array<string>, opts: {
-    cwd?: string;
-    echo?: boolean;
-    env?: Array<string>;
-    terminal: BrowserPodTerminal;
-  }): Promise<unknown>;
+  run(
+    executable: string,
+    args: Array<string>,
+    opts: {
+      cwd?: string;
+      echo?: boolean;
+      env?: Array<string>;
+      terminal: BrowserPodTerminal;
+    },
+  ): Promise<unknown>;
 };
 
 type BrowserPodFile = {
@@ -65,7 +69,12 @@
 
 function getBrowserPodApiKey() {
   const env = import.meta.env as Record<string, string | undefined>;
-  return env.PUBLIC_BROWSERPOD_API_KEY ?? env.VITE_BPAPIKEY ?? env.VITE_BP_APIKEY ?? ``;
+  return (
+    env.PUBLIC_BROWSERPOD_API_KEY ??
+    env.VITE_BPAPIKEY ??
+    env.VITE_BP_APIKEY ??
+    ``
+  );
 }
 
 function dirname(path: string) {
@@ -74,11 +83,9 @@
 }
 
 function formatUnknownError(error: unknown) {
-  if (error instanceof Error)
-    return error.message;
+  if (error instanceof Error) return error.message;
 
-  if (typeof error === `string`)
-    return error;
+  if (typeof error === `string`) return error;
 
   if (error === undefined)
     return `BrowserPod rejected without an error message`;
@@ -90,11 +97,16 @@
   }
 }
 
-async function writeProjectFiles(pod: BrowserPodInstance, files: Array<PlaygroundFile>) {
+async function writeProjectFiles(
+  pod: BrowserPodInstance,
+  files: Array<PlaygroundFile>,
+) {
   try {
-    await pod.createDirectory(PROJECT_PATH, {recursive: true});
+    await pod.createDirectory(PROJECT_PATH, { recursive: true });
   } catch (error) {
-    throw new Error(`Failed to create ${PROJECT_PATH}: ${formatUnknownError(error)}`);
+    throw new Error(
+      `Failed to create ${PROJECT_PATH}: ${formatUnknownError(error)}`,
+    );
   }
 
   const directories = new Set<string>();
@@ -102,15 +114,14 @@
   for (const file of files) {
     const directory = dirname(file.path);
 
-    if (directory)
-      directories.add(directory);
+    if (directory) directories.add(directory);
   }
 
   for (const directory of directories) {
     const path = `${PROJECT_PATH}/${directory}`;
 
     try {
-      await pod.createDirectory(path, {recursive: true});
+      await pod.createDirectory(path, { recursive: true });
     } catch (error) {
       throw new Error(`Failed to create ${path}: ${formatUnknownError(error)}`);
     }
@@ -132,10 +143,9 @@
 async function writeYarnBinary(pod: BrowserPodInstance) {
   const response = await fetch(YARN_BIN_ASSET);
 
-  if (!response.ok)
-    return false;
+  if (!response.ok) return false;
 
-  await pod.createDirectory(YARN_BIN_DIR, {recursive: true});
+  await pod.createDirectory(YARN_BIN_DIR, { recursive: true });
 
   const podFile = await pod.createFile(YARN_BIN_PATH, `binary`);
   await podFile.write(await response.arrayBuffer());
@@ -146,40 +156,41 @@
 async function writeShellConfig(pod: BrowserPodInstance) {
   const podFile = await pod.createFile(BASHRC_PATH, `utf-8`);
 
-  await podFile.write([
-    `export PATH="${YARN_BIN_DIR}:$PATH"`,
-    `export npm_config_user_agent="yarn-playground"`,
-    `export PS1="\\[\\e[38;2;134;239;172m\\]yarn-playground\\[\\e[0m\\] \\[\\e[38;2;148;163;184m\\]\\w\\[\\e[0m\\] $ "`,
-    ``,
-    `cd ${PROJECT_PATH}`,
-    ``,
-  ].join(`\n`));
+  await podFile.write(
+    [
+      `export PATH="${YARN_BIN_DIR}:$PATH"`,
+      `export npm_config_user_agent="yarn-playground"`,
+      `export PS1="\\[\\e[38;2;134;239;172m\\]yarn-playground\\[\\e[0m\\] \\[\\e[38;2;148;163;184m\\]\\w\\[\\e[0m\\] $ "`,
+      ``,
+      `cd ${PROJECT_PATH}`,
+      ``,
+    ].join(`\n`),
+  );
 
   await podFile.close();
 }
 
-export function PlaygroundTerminal({files, version}: Props) {
+export function PlaygroundTerminal({ files, version }: Props) {
   const containerRef = useRef<HTMLDivElement>(null);
 
   useEffect(() => {
     const container = containerRef.current;
-    if (!container)
-      return undefined;
+    if (!container) return undefined;
 
     let disposed = false;
     let term: XtermTerminal | null = null;
     let browserPodTerminal: BrowserPodTerminal | null = null;
     let resizeObserver: ResizeObserver | null = null;
     let focusTerm: (() => void) | null = null;
+    let pod: BrowserPodInstance | null = null;
 
     async function start() {
-      const [{Terminal}, {FitAddon}] = await Promise.all([
+      const [{ Terminal }, { FitAddon }] = await Promise.all([
         import(`@xterm/xterm`),
         import(`@xterm/addon-fit`),
       ]);
 
-      if (disposed)
-        return;
+      if (disposed) return;
 
       const fitAddon = new FitAddon();
       term = new Terminal({
@@ -218,22 +229,20 @@
 
       term.loadAddon(fitAddon);
       term.open(container);
-      term.onData(data => browserPodTerminal?.readData(data));
+      term.onData((data) => browserPodTerminal?.readData(data));
 
       focusTerm = () => term?.focus();
       container.addEventListener(`pointerdown`, focusTerm);
 
       requestAnimationFrame(() => {
-        if (!term || disposed)
-          return;
+        if (!term || disposed) return;
 
         fitAddon.fit();
         term.focus();
       });
 
       resizeObserver = new ResizeObserver(() => {
-        if (!term || disposed)
-          return;
+        if (!term || disposed) return;
 
         fitAddon.fit();
       });
@@ -261,22 +270,21 @@
       }
 
       try {
-        const {BrowserPod} = await import(/* @vite-ignore */ BROWSERPOD_RUNTIME_URL) as {BrowserPod: BrowserPodApi | null};
+        const { BrowserPod } = (await import(
+          /* @vite-ignore */ BROWSERPOD_RUNTIME_URL
+        )) as { BrowserPod: BrowserPodApi | null };
 
-        if (!BrowserPod)
-          throw new Error(`BrowserPod runtime failed to load`);
+        if (!BrowserPod) throw new Error(`BrowserPod runtime failed to load`);
 
-        const pod = await BrowserPod.boot({apiKey});
+        pod = await BrowserPod.boot({ apiKey });
 
-        if (disposed || !term)
-          return;
+        if (disposed || !term) return;
 
         browserPodTerminal = await pod.createCustomTerminal({
           cols: term.cols,
           rows: term.rows,
-          onOutput: buffer => {
-            if (!term || disposed)
-              return;
+          onOutput: (buffer) => {
+            if (!term || disposed) return;
 
             term.write(new Uint8Array(buffer));
           },
@@ -284,6 +292,8 @@
 
         await writeProjectFiles(pod, files);
 
+        if (disposed || !term) return;
+
         if (await writeYarnBinary(pod)) {
           writeLines(term, [
             `${cyan}[browserpod]${reset} Mounted ${YARN_BIN_ASSET}`,
@@ -304,11 +314,13 @@
             `${cyan}[browserpod]${reset} Opening BrowserPod bash in the mounted project instead.`,
           ]);
 
-          await pod.run(`bash`, [], {cwd: PROJECT_PATH, terminal: browserPodTerminal});
+          await pod.run(`bash`, [], {
+            cwd: PROJECT_PATH,
+            terminal: browserPodTerminal,
+          });
         }
       } catch (error) {
-        if (!term || disposed)
-          return;
+        if (!term || disposed) return;
 
         writeLines(term, [
           `${red}[browserpod]${reset} ${formatUnknownError(error)}`,
@@ -321,12 +333,18 @@
 
     return () => {
       disposed = true;
+      pod = null;
+      browserPodTerminal = null;
       resizeObserver?.disconnect();
-      if (focusTerm)
-        container.removeEventListener(`pointerdown`, focusTerm);
+      if (focusTerm) container.removeEventListener(`pointerdown`, focusTerm);
       term?.dispose();
     };
   }, [files, version]);
 
-  return <div ref={containerRef} className={`playground-terminal-mount absolute inset-[20px_22px] min-h-0 min-w-0 rounded-xl max-[560px]:inset-3.5`} />;
+  return (
+    <div
+      ref={containerRef}
+      className={`playground-terminal-mount absolute inset-[20px_22px] min-h-0 min-w-0 rounded-xl max-[560px]:inset-3.5`}
+    />
+  );
 }

You can send follow-ups to the cloud agent here.

if (focusTerm)
container.removeEventListener(`pointerdown`, focusTerm);
term?.dispose();
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BrowserPod sessions leak on remount

Medium Severity

The terminal effect calls BrowserPod.boot and pod.run but cleanup only disposes xterm. Changing presets or when files/version change retriggers the effect without stopping the prior pod or shell, so multiple BrowserPod instances and bash sessions can run and keep consuming memory and API quota.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4d90be3. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: BrowserPod cfg wrong architecture
    • Changed all cfg conditions from target_arch='wasm64' to target_arch='wasm32' to match the actual wasm32-browserpod-linux-musl build target.

Create PR

Or push these changes by commenting:

@cursor push b55bf90779
Preview (b55bf90779)
diff --git a/packages/zpm-switch/Cargo.toml b/packages/zpm-switch/Cargo.toml
--- a/packages/zpm-switch/Cargo.toml
+++ b/packages/zpm-switch/Cargo.toml
@@ -35,10 +35,10 @@
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
 
-[target.'cfg(all(target_arch = "wasm64", target_vendor = "browserpod"))'.dependencies]
+[target.'cfg(all(target_arch = "wasm32", target_vendor = "browserpod"))'.dependencies]
 reqwest = { workspace = true, default-features = false, features = ["default-tls"] }
 
-[target.'cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))'.dependencies]
+[target.'cfg(not(all(target_arch = "wasm32", target_vendor = "browserpod")))'.dependencies]
 reqwest = { workspace = true, default-features = false, features = ["rustls-tls"] }
 
 [dev-dependencies]

diff --git a/packages/zpm-switch/src/http.rs b/packages/zpm-switch/src/http.rs
--- a/packages/zpm-switch/src/http.rs
+++ b/packages/zpm-switch/src/http.rs
@@ -8,7 +8,7 @@
 static HTTP_CLIENT: LazyLock<Result<Client, Error>> = LazyLock::new(|| {
     let mut builder = reqwest::Client::builder();
 
-    #[cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))]
+    #[cfg(not(all(target_arch = "wasm32", target_vendor = "browserpod")))]
     {
         builder = builder.use_rustls_tls();
     }

diff --git a/packages/zpm-utils/src/system.rs b/packages/zpm-utils/src/system.rs
--- a/packages/zpm-utils/src/system.rs
+++ b/packages/zpm-utils/src/system.rs
@@ -24,7 +24,7 @@
 #[cfg(target_arch = "x86")]
 const ARCH: Cpu = Cpu::I386;
 
-#[cfg(target_arch = "wasm64")]
+#[cfg(target_arch = "wasm32")]
 const ARCH: Cpu = Cpu::Wasm64;
 
 #[cfg(target_os = "linux")]

diff --git a/packages/zpm/Cargo.toml b/packages/zpm/Cargo.toml
--- a/packages/zpm/Cargo.toml
+++ b/packages/zpm/Cargo.toml
@@ -75,10 +75,10 @@
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
 
-[target.'cfg(all(target_arch = "wasm64", target_vendor = "browserpod"))'.dependencies]
+[target.'cfg(all(target_arch = "wasm32", target_vendor = "browserpod"))'.dependencies]
 reqwest = { workspace = true, default-features = false, features = ["default-tls"] }
 
-[target.'cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))'.dependencies]
+[target.'cfg(not(all(target_arch = "wasm32", target_vendor = "browserpod")))'.dependencies]
 reqwest = { workspace = true, default-features = false, features = ["rustls-tls"] }
 
 [build-dependencies]

diff --git a/packages/zpm/src/http.rs b/packages/zpm/src/http.rs
--- a/packages/zpm/src/http.rs
+++ b/packages/zpm/src/http.rs
@@ -5,7 +5,7 @@
 use hickory_resolver::{config::LookupIpStrategy, TokioResolver};
 use http::HeaderMap;
 use itertools::Itertools;
-#[cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))]
+#[cfg(not(all(target_arch = "wasm32", target_vendor = "browserpod")))]
 use reqwest::Identity;
 use reqwest::{dns::{self, Addrs}, header::{HeaderName, HeaderValue}, Body, Certificate, Client, ClientBuilder, Method, Proxy, RequestBuilder, Response, Url};
 use tokio::sync::OnceCell;
@@ -282,7 +282,7 @@
     fn build_client(config: &Configuration, network_settings: Option<&NetworkSettings>) -> Result<Client, Error> {
         let mut client_builder = reqwest::Client::builder();
 
-        #[cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))]
+        #[cfg(not(all(target_arch = "wasm32", target_vendor = "browserpod")))]
         {
             client_builder = client_builder.use_rustls_tls();
         }
@@ -347,14 +347,14 @@
 
         match (https_cert_file_path, https_key_file_path) {
             (Some(cert_path), Some(key_path)) => {
-                #[cfg(all(target_arch = "wasm64", target_vendor = "browserpod"))]
+                #[cfg(all(target_arch = "wasm32", target_vendor = "browserpod"))]
                 {
                     let _ = (cert_path, key_path);
 
                     return Err(Error::ConflictingOptions("httpsCertFilePath / httpsKeyFilePath (PEM client identity) require reqwest's rustls-tls feature, currently disabled for the browserpod target".to_string()));
                 }
 
-                #[cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))]
+                #[cfg(not(all(target_arch = "wasm32", target_vendor = "browserpod")))]
                 {
                 let cert_content
                     = cert_path.fs_read_prealloc()?;

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit ed94ea9. Configure here.

Comment thread packages/zpm/Cargo.toml
reqwest = { workspace = true, default-features = false, features = ["default-tls"] }

[target.'cfg(not(all(target_arch = "wasm64", target_vendor = "browserpod")))'.dependencies]
reqwest = { workspace = true, default-features = false, features = ["rustls-tls"] }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BrowserPod cfg wrong architecture

High Severity

BrowserPod-specific TLS and CPU setup is gated on target_arch = "wasm64", but the playground WASM build and manifest use the triple wasm32-browserpod-linux-musl, where Rust exposes target_arch = "wasm32". The BrowserPod branches (default TLS, skipping rustls, ARCH) may never run on the actual build target.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ed94ea9. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants