var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import { D as DEFAULT_CORS_PROXY_URL, a as DefaultNetworkController, L as LOCAL_CORS_PROXY_PATH, b as LOCAL_WS_RELAY_PATH, N as NETWORK_CA_BUNDLE_PATH, c as NETWORK_DIAGNOSTIC_FAILURE_BUCKETS, d as NETWORK_ENV_KEYS, e as base64ToUint8Array, f as createNetworkController, g as createResponseFromNetwork, h as getDefaultNetworkController, i as getResolvedPolicy, j as hasExplicitDefaultNetworkController, k as headersToRecord, l as isModuleResolutionHostname, m as isTailnetIpv4, n as isTailnetIpv6, o as isTailscaleHostname, p as networkFetch, q as normalizeNetworkOptions, r as resolveBrowserFetchTarget, s as resolveBrowserWebSocketTarget, t as resolveNetworkPolicy, u as selectNetworkRouteForHost, v as selectNetworkRouteForUrl, w as selectWebSocketRouteForUrl, x as serializeFetchRequest, y as setDefaultNetworkController, z as setTailscaleAdapterFactory, A as shouldBypassProxy, R as Runtime, V as VirtualFS, B as getServerBridge, C as BufferPolyfill, E as initChildProcess, F as disposeChildProcessController, G as closeServersByOwner, H as almostnodeDebugLog, I as stripInternalChildProcessEnv } from "./fetch-virtual-server-BZi6n2Qk.js";
import { J, K, S, M, O, P, Q, T, U, W, X, Y, Z, _, $, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af, ag } from "./fetch-virtual-server-BZi6n2Qk.js";
import { wrap, proxy } from "comlink";
import { P as PackageManager } from "./index-DDTngCOi.js";
import { i, a } from "./index-DDTngCOi.js";
import { b, l } from "./electron-app-BI4Muz9y.js";
import { D } from "./dev-server-nWWQHf5q.js";
import { ViteDevServer } from "./vite-dev-server-CQ-84Km_.js";
import { NextDevServer } from "./next-dev-server-BYDY1pxM.js";
const TAILSCALE_SESSION_STORAGE_KEY = "__almostnodeTailscaleState";
function normalizeSnapshot(value) {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return null;
  }
  const snapshot = {};
  for (const [key, entry] of Object.entries(value)) {
    if (typeof entry !== "string") {
      return null;
    }
    snapshot[key] = entry;
  }
  return snapshot;
}
function parseTailscaleStateSnapshot(raw) {
  if (!raw) {
    return null;
  }
  try {
    return normalizeSnapshot(JSON.parse(raw));
  } catch {
    return null;
  }
}
function serializeTailscaleStateSnapshot(snapshot) {
  return JSON.stringify(snapshot);
}
function createTailscaleSessionPersistence(storage, key = TAILSCALE_SESSION_STORAGE_KEY) {
  return {
    load() {
      if (!storage) {
        return null;
      }
      try {
        const raw = storage.getItem(key);
        const snapshot = parseTailscaleStateSnapshot(raw);
        if (raw && !snapshot) {
          storage.removeItem(key);
        }
        return snapshot;
      } catch {
        return null;
      }
    },
    save(snapshot) {
      if (!storage) {
        return;
      }
      try {
        storage.setItem(key, serializeTailscaleStateSnapshot(snapshot));
      } catch {
      }
    },
    clear() {
      if (!storage) {
        return;
      }
      try {
        storage.removeItem(key);
      } catch {
      }
    }
  };
}
const PERSISTED_NETWORK_SESSION_STORAGE_KEY = "__almostnodeNetworkSession";
function normalizePersistedSession(value) {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return null;
  }
  const parsed = value;
  if (parsed.provider !== "tailscale" || typeof parsed.useExitNode !== "boolean") {
    return null;
  }
  const stateSnapshot = parsed.stateSnapshot;
  if (stateSnapshot !== null && stateSnapshot !== void 0 && (typeof stateSnapshot !== "object" || Array.isArray(stateSnapshot) || Object.values(stateSnapshot).some(
    (entry) => typeof entry !== "string"
  ))) {
    return null;
  }
  return {
    provider: "tailscale",
    useExitNode: parsed.useExitNode,
    exitNodeId: typeof parsed.exitNodeId === "string" && parsed.exitNodeId.trim() ? parsed.exitNodeId.trim() : null,
    acceptDns: parsed.acceptDns !== false,
    stateSnapshot: stateSnapshot && typeof stateSnapshot === "object" ? { ...stateSnapshot } : null
  };
}
function parsePersistedNetworkSession(raw) {
  if (!raw) {
    return null;
  }
  try {
    return normalizePersistedSession(JSON.parse(raw));
  } catch {
    return null;
  }
}
function serializePersistedNetworkSession(session) {
  return JSON.stringify(session);
}
function getBrowserSessionStorage() {
  try {
    if (typeof sessionStorage === "undefined") {
      return null;
    }
    return sessionStorage;
  } catch {
    return null;
  }
}
function createNetworkSessionPersistence(storage = getBrowserSessionStorage(), key = PERSISTED_NETWORK_SESSION_STORAGE_KEY) {
  return {
    load() {
      if (!storage) {
        return null;
      }
      try {
        const raw = storage.getItem(key);
        const session = parsePersistedNetworkSession(raw);
        if (raw && !session) {
          storage.removeItem(key);
        }
        return session;
      } catch {
        return null;
      }
    },
    save(session) {
      if (!storage) {
        return;
      }
      try {
        storage.setItem(key, serializePersistedNetworkSession(session));
      } catch {
      }
    },
    clear() {
      if (!storage) {
        return;
      }
      try {
        storage.removeItem(key);
      } catch {
      }
    }
  };
}
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  DEFAULT_CORS_PROXY_URL,
  DefaultNetworkController,
  LOCAL_CORS_PROXY_PATH,
  LOCAL_WS_RELAY_PATH,
  NETWORK_CA_BUNDLE_PATH,
  NETWORK_DIAGNOSTIC_FAILURE_BUCKETS,
  NETWORK_ENV_KEYS,
  PERSISTED_NETWORK_SESSION_STORAGE_KEY,
  TAILSCALE_SESSION_STORAGE_KEY,
  base64ToUint8Array,
  createNetworkController,
  createNetworkSessionPersistence,
  createResponseFromNetwork,
  createTailscaleSessionPersistence,
  getDefaultNetworkController,
  getResolvedPolicy,
  hasExplicitDefaultNetworkController,
  headersToRecord,
  isModuleResolutionHostname,
  isTailnetIpv4,
  isTailnetIpv6,
  isTailscaleHostname,
  networkFetch,
  normalizeNetworkOptions,
  parsePersistedNetworkSession,
  parseTailscaleStateSnapshot,
  resolveBrowserFetchTarget,
  resolveBrowserWebSocketTarget,
  resolveNetworkPolicy,
  selectNetworkRouteForHost,
  selectNetworkRouteForUrl,
  selectWebSocketRouteForUrl,
  serializeFetchRequest,
  serializePersistedNetworkSession,
  serializeTailscaleStateSnapshot,
  setDefaultNetworkController,
  setTailscaleAdapterFactory,
  shouldBypassProxy
}, Symbol.toStringTag, { value: "Module" }));
class WorkerRuntime {
  constructor(vfs, options = {}) {
    __publicField(this, "worker");
    __publicField(this, "workerApi");
    __publicField(this, "vfs");
    __publicField(this, "options");
    __publicField(this, "networkController");
    __publicField(this, "initialized");
    __publicField(this, "changeListener", null);
    __publicField(this, "deleteListener", null);
    this.vfs = vfs;
    this.options = options;
    this.networkController = getDefaultNetworkController();
    if (options.network) {
      void this.networkController.configure(options.network);
    }
    this.worker = new Worker(
      new URL(
        /* @vite-ignore */
        "/assets/runtime-worker-Dwd8wuYK.js",
        import.meta.url
      ),
      { type: "module" }
    );
    this.workerApi = wrap(this.worker);
    this.initialized = this.initWorker();
    this.setupVFSListeners();
  }
  /**
   * Initialize the worker with VFS snapshot and options
   */
  async initWorker() {
    const snapshot = this.vfs.toSnapshot();
    const workerOptions = {
      cwd: this.options.cwd,
      env: this.options.env,
      network: this.options.network
    };
    await this.workerApi.init(snapshot, workerOptions);
    if (this.options.onConsole) {
      await this.workerApi.setConsoleCallback(
        proxy(this.options.onConsole)
      );
    }
    console.log("[WorkerRuntime] Worker initialized");
  }
  /**
   * Set up listeners for VFS changes to sync to worker
   */
  setupVFSListeners() {
    this.changeListener = (path, content) => {
      this.workerApi.syncFile(path, content);
    };
    this.vfs.on("change", this.changeListener);
    this.deleteListener = (path) => {
      this.workerApi.syncFile(path, null);
    };
    this.vfs.on("delete", this.deleteListener);
  }
  /**
   * Execute code in the worker
   */
  async execute(code, filename) {
    await this.initialized;
    return this.workerApi.execute(code, filename);
  }
  /**
   * Run a file from the VFS in the worker
   */
  async runFile(filename) {
    await this.initialized;
    return this.workerApi.runFile(filename);
  }
  /**
   * Clear the module cache in the worker
   */
  clearCache() {
    this.workerApi.clearCache();
  }
  /**
   * Get the VFS (main thread instance)
   */
  getVFS() {
    return this.vfs;
  }
  getNetwork() {
    return this.networkController;
  }
  /**
   * Terminate the worker
   */
  terminate() {
    if (this.changeListener) {
      this.vfs.off("change", this.changeListener);
    }
    if (this.deleteListener) {
      this.vfs.off("delete", this.deleteListener);
    }
    this.worker.terminate();
    console.log("[WorkerRuntime] Worker terminated");
  }
}
class SandboxRuntime {
  constructor(sandboxUrl, vfs, options = {}) {
    __publicField(this, "iframe");
    __publicField(this, "sandboxOrigin");
    __publicField(this, "vfs");
    __publicField(this, "options");
    __publicField(this, "networkController");
    __publicField(this, "initialized");
    __publicField(this, "pending", /* @__PURE__ */ new Map());
    __publicField(this, "messageId", 0);
    __publicField(this, "changeListener", null);
    __publicField(this, "deleteListener", null);
    __publicField(this, "messageHandler", null);
    this.sandboxOrigin = new URL(sandboxUrl).origin;
    this.vfs = vfs;
    this.options = options;
    this.networkController = getDefaultNetworkController();
    if (options.network) {
      void this.networkController.configure(options.network);
    }
    this.iframe = document.createElement("iframe");
    this.iframe.src = sandboxUrl;
    this.iframe.style.display = "none";
    this.iframe.credentialless = true;
    this.iframe.setAttribute("credentialless", "");
    document.body.appendChild(this.iframe);
    this.setupMessageHandler();
    this.initialized = this.waitForReady().then(() => this.initSandbox());
    this.setupVFSListeners();
  }
  /**
   * Set up the message event handler
   */
  setupMessageHandler() {
    this.messageHandler = (event) => {
      if (event.origin !== this.sandboxOrigin) return;
      const message = event.data;
      if (message.type === "result" && message.id) {
        const pending = this.pending.get(message.id);
        if (pending && message.result) {
          pending.resolve(message.result);
          this.pending.delete(message.id);
        }
      } else if (message.type === "error" && message.id) {
        const pending = this.pending.get(message.id);
        if (pending) {
          pending.reject(new Error(message.error || "Unknown sandbox error"));
          this.pending.delete(message.id);
        }
      } else if (message.type === "console" && this.options.onConsole) {
        this.options.onConsole(message.consoleMethod || "log", message.consoleArgs || []);
      }
    };
    window.addEventListener("message", this.messageHandler);
  }
  /**
   * Wait for the sandbox iframe to signal it's ready
   */
  waitForReady() {
    return new Promise((resolve) => {
      const handler = (event) => {
        if (event.origin !== this.sandboxOrigin) return;
        const message = event.data;
        if (message.type === "ready") {
          window.removeEventListener("message", handler);
          resolve();
        }
      };
      window.addEventListener("message", handler);
    });
  }
  /**
   * Initialize the sandbox with VFS snapshot and options
   */
  async initSandbox() {
    var _a;
    const snapshot = this.vfs.toSnapshot();
    const message = {
      type: "init",
      vfsSnapshot: snapshot,
      options: {
        cwd: this.options.cwd,
        env: this.options.env,
        network: this.options.network
        // Note: onConsole callback can't be sent cross-origin,
        // sandbox will send console messages back via postMessage
      }
    };
    (_a = this.iframe.contentWindow) == null ? void 0 : _a.postMessage(message, this.sandboxOrigin);
    console.log("[SandboxRuntime] Sandbox initialized");
  }
  /**
   * Set up listeners for VFS changes to sync to sandbox
   */
  setupVFSListeners() {
    this.changeListener = (path, content) => {
      var _a;
      const message = {
        type: "syncFile",
        path,
        content
      };
      (_a = this.iframe.contentWindow) == null ? void 0 : _a.postMessage(message, this.sandboxOrigin);
    };
    this.vfs.on("change", this.changeListener);
    this.deleteListener = (path) => {
      var _a;
      const message = {
        type: "syncFile",
        path,
        content: null
      };
      (_a = this.iframe.contentWindow) == null ? void 0 : _a.postMessage(message, this.sandboxOrigin);
    };
    this.vfs.on("delete", this.deleteListener);
  }
  /**
   * Send a message and wait for response
   */
  sendAndWait(message) {
    return new Promise((resolve, reject) => {
      var _a;
      const id = String(this.messageId++);
      this.pending.set(id, { resolve, reject });
      (_a = this.iframe.contentWindow) == null ? void 0 : _a.postMessage(
        { ...message, id },
        this.sandboxOrigin
      );
      setTimeout(() => {
        if (this.pending.has(id)) {
          this.pending.delete(id);
          reject(new Error("Sandbox execution timeout"));
        }
      }, 6e4);
    });
  }
  /**
   * Execute code in the sandbox
   */
  async execute(code, filename) {
    await this.initialized;
    return this.sendAndWait({
      type: "execute",
      code,
      filename
    });
  }
  /**
   * Run a file from the VFS in the sandbox
   */
  async runFile(filename) {
    await this.initialized;
    return this.sendAndWait({
      type: "runFile",
      filename
    });
  }
  /**
   * Clear the module cache in the sandbox
   */
  clearCache() {
    var _a;
    const message = { type: "clearCache" };
    (_a = this.iframe.contentWindow) == null ? void 0 : _a.postMessage(message, this.sandboxOrigin);
  }
  /**
   * Get the VFS (main thread instance)
   */
  getVFS() {
    return this.vfs;
  }
  getNetwork() {
    return this.networkController;
  }
  /**
   * Terminate the sandbox
   */
  terminate() {
    if (this.changeListener) {
      this.vfs.off("change", this.changeListener);
    }
    if (this.deleteListener) {
      this.vfs.off("delete", this.deleteListener);
    }
    if (this.messageHandler) {
      window.removeEventListener("message", this.messageHandler);
    }
    this.iframe.remove();
    for (const [id, { reject }] of this.pending) {
      reject(new Error("Sandbox terminated"));
      this.pending.delete(id);
    }
    console.log("[SandboxRuntime] Sandbox terminated");
  }
}
function isWorkerAvailable() {
  return typeof Worker !== "undefined";
}
async function createRuntime(vfs, options = {}) {
  const { sandbox, dangerouslyAllowSameOrigin, useWorker = false, ...runtimeOptions } = options;
  if (sandbox) {
    console.log("[createRuntime] Creating SandboxRuntime (cross-origin isolated)");
    const sandboxRuntime = new SandboxRuntime(sandbox, vfs, runtimeOptions);
    await sandboxRuntime.execute("/* sandbox ready check */", "/__sandbox_init__.js");
    return sandboxRuntime;
  }
  if (!dangerouslyAllowSameOrigin) {
    throw new Error(
      'almostnode: For security, you must either:\n  1. Use sandbox mode: { sandbox: "https://your-sandbox.vercel.app" }\n  2. Explicitly opt-in to same-origin: { dangerouslyAllowSameOrigin: true }\n\nSame-origin execution allows code to access cookies, localStorage, and IndexedDB.\nOnly use dangerouslyAllowSameOrigin for trusted code or demos.\n\nFor sandbox setup instructions, see: https://github.com/BLamy/agent-wasm#sandbox-setup'
    );
  }
  let shouldUseWorker = false;
  if (useWorker === true) {
    shouldUseWorker = isWorkerAvailable();
    if (!shouldUseWorker) {
      console.warn("[createRuntime] Worker requested but not available, falling back to main thread");
    }
  } else if (useWorker === "auto") {
    shouldUseWorker = isWorkerAvailable();
    console.log(`[createRuntime] Auto mode: using ${shouldUseWorker ? "worker" : "main thread"}`);
  }
  if (shouldUseWorker) {
    console.log("[createRuntime] Creating WorkerRuntime (same-origin, thread-isolated)");
    const workerRuntime = new WorkerRuntime(vfs, runtimeOptions);
    await workerRuntime.execute("/* worker ready check */", "/__worker_init__.js");
    return workerRuntime;
  }
  console.log("[createRuntime] Creating main-thread Runtime (same-origin, least secure)");
  return new Runtime(vfs, runtimeOptions);
}
function getServiceWorkerContent() {
  if (typeof require === "undefined") {
    return null;
  }
  try {
    const fs = require("fs");
    const path = require("path");
    let dirname;
    try {
      const url = require("url");
      dirname = path.dirname(url.fileURLToPath(import.meta.url));
    } catch {
      dirname = __dirname;
    }
    let swPath = path.join(dirname, "__sw__.js");
    if (fs.existsSync(swPath)) {
      return fs.readFileSync(swPath, "utf-8");
    }
    swPath = path.join(dirname, "../dist/__sw__.js");
    if (fs.existsSync(swPath)) {
      return fs.readFileSync(swPath, "utf-8");
    }
    swPath = path.join(dirname, "../public/__sw__.js");
    if (fs.existsSync(swPath)) {
      return fs.readFileSync(swPath, "utf-8");
    }
    return null;
  } catch {
    return null;
  }
}
function getSandboxHtml(options = {}) {
  const opts = typeof options === "string" ? { almostnodeUrl: options } : options;
  const almostnodeUrl = opts.almostnodeUrl ?? "https://unpkg.com/almostnode/dist/index.js";
  const includeServiceWorker = opts.includeServiceWorker ?? true;
  const serviceWorkerScript = includeServiceWorker ? `
  // Register service worker for dev server support
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/__sw__.js', { scope: '/' })
      .then(reg => console.log('[Sandbox] Service worker registered'))
      .catch(err => console.warn('[Sandbox] Service worker registration failed:', err));
  }
` : "";
  return `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>almostnode Sandbox</title>
</head>
<body>
<script type="module">
  import { VirtualFS, Runtime } from '${almostnodeUrl}';
${serviceWorkerScript}

  let vfs = null;
  let runtime = null;
  let consoleCallback = null;

  // Handle messages from parent
  window.addEventListener('message', async (event) => {
    const { type, id, code, filename, vfsSnapshot, options, path, content } = event.data;

    try {
      switch (type) {
        case 'init':
          // Initialize VFS from snapshot
          vfs = VirtualFS.fromSnapshot(vfsSnapshot);

          // Create runtime with options
          runtime = new Runtime(vfs, {
            cwd: options?.cwd,
            env: options?.env,
            network: options?.network,
            onConsole: (method, args) => {
              // Forward console to parent
              parent.postMessage({
                type: 'console',
                consoleMethod: method,
                consoleArgs: args,
              }, '*');
            },
          });
          break;

        case 'syncFile':
          // Sync file changes from parent
          if (vfs) {
            if (content === null) {
              try { vfs.unlinkSync(path); } catch {}
            } else {
              vfs.writeFileSync(path, content);
            }
          }
          break;

        case 'execute':
          if (!runtime) {
            parent.postMessage({ type: 'error', id, error: 'Runtime not initialized' }, '*');
            return;
          }
          const execResult = await runtime.execute(code, filename);
          parent.postMessage({ type: 'result', id, result: execResult }, '*');
          break;

        case 'runFile':
          if (!runtime) {
            parent.postMessage({ type: 'error', id, error: 'Runtime not initialized' }, '*');
            return;
          }
          const runResult = await runtime.runFile(filename);
          parent.postMessage({ type: 'result', id, result: runResult }, '*');
          break;

        case 'clearCache':
          if (runtime) {
            runtime.clearCache();
          }
          break;
      }
    } catch (error) {
      if (id) {
        parent.postMessage({
          type: 'error',
          id,
          error: error instanceof Error ? error.message : String(error),
        }, '*');
      }
    }
  });

  // Signal ready to parent
  parent.postMessage({ type: 'ready' }, '*');
<\/script>
</body>
</html>`;
}
function getSandboxVercelConfig() {
  return {
    headers: [
      {
        source: "/(.*)",
        headers: [
          { key: "Access-Control-Allow-Origin", value: "*" },
          { key: "Cross-Origin-Resource-Policy", value: "cross-origin" }
        ]
      }
    ]
  };
}
function generateSandboxFiles(options = {}) {
  const opts = typeof options === "string" ? { almostnodeUrl: options } : options;
  const includeServiceWorker = opts.includeServiceWorker ?? true;
  const swContent = includeServiceWorker ? getServiceWorkerContent() : null;
  const files = {
    "index.html": getSandboxHtml(opts),
    "vercel.json": JSON.stringify(getSandboxVercelConfig(), null, 2)
  };
  if (swContent) {
    files["__sw__.js"] = swContent;
  }
  return files;
}
const SANDBOX_SETUP_INSTRUCTIONS = `
# Setting up a almostnode Sandbox on Vercel

## 1. Create sandbox directory
   mkdir sandbox

## 2. Generate sandbox files
   Use generateSandboxFiles() or copy the templates manually.

## 3. Deploy to Vercel
   cd sandbox
   vercel --prod

## 4. Use in your app
   const runtime = await createRuntime(vfs, {
     sandbox: 'https://your-sandbox.vercel.app'
   });

For more details, see: https://github.com/BLamy/agent-wasm#sandbox-setup
`.trim();
const PACKAGE_JSON = {
  name: "convex-todo-app",
  version: "0.1.0",
  private: true,
  scripts: {
    dev: "next dev",
    build: "next build",
    start: "next start"
  },
  dependencies: {
    "next": "^14.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  devDependencies: {
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "typescript": "^5.9.3"
  }
};
const DEMO_PACKAGES = [];
function createConvexAppProject(vfs) {
  vfs.writeFileSync("/package.json", JSON.stringify(PACKAGE_JSON, null, 2));
  vfs.mkdirSync("/app", { recursive: true });
  vfs.mkdirSync("/components", { recursive: true });
  vfs.mkdirSync("/lib", { recursive: true });
  vfs.mkdirSync("/convex", { recursive: true });
  vfs.mkdirSync("/public", { recursive: true });
  vfs.writeFileSync("/convex.json", JSON.stringify({
    functions: "convex/"
  }, null, 2));
  vfs.writeFileSync("/tsconfig.json", JSON.stringify({
    compilerOptions: {
      target: "es5",
      lib: ["dom", "dom.iterable", "esnext"],
      allowJs: true,
      skipLibCheck: true,
      strict: true,
      noEmit: true,
      esModuleInterop: true,
      module: "esnext",
      moduleResolution: "bundler",
      resolveJsonModule: true,
      isolatedModules: true,
      jsx: "preserve",
      incremental: true,
      paths: {
        "@/*": ["./*"]
      }
    },
    include: ["**/*.ts", "**/*.tsx"],
    exclude: ["node_modules"]
  }, null, 2));
  vfs.writeFileSync("/app/globals.css", `*, *::before, *::after {
  box-sizing: border-box;
}

body {
  background-color: hsl(222.2 84% 4.9%);
  color: hsl(210 40% 98%);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  margin: 0;
  line-height: 1.5;
}

input[type="text"], input:not([type]) {
  background-color: hsl(222.2 84% 4.9%);
  color: hsl(210 40% 98%);
  border: 1px solid hsl(217.2 32.6% 17.5%);
  border-radius: 0.375rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  height: 2.5rem;
  outline: none;
}
input:focus {
  border-color: hsl(212.7 26.8% 83.9%);
  box-shadow: 0 0 0 2px hsl(212.7 26.8% 83.9% / 0.2);
}
input::placeholder {
  color: hsl(215 20.2% 65.1%);
}

input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: hsl(210 40% 98%);
  cursor: pointer;
}

button {
  background-color: hsl(210 40% 98%);
  color: hsl(222.2 47.4% 11.2%);
  border: none;
  border-radius: 0.375rem;
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  height: 2.5rem;
}
button:hover {
  opacity: 0.9;
}

ul { list-style: none; padding: 0; margin: 0; }
`);
  vfs.writeFileSync("/convex/convex.config.ts", `import { defineApp } from "convex/server";

const app = defineApp();
export default app;
`);
  vfs.writeFileSync("/convex/convex.config.js", `import { defineApp } from "convex/server";

const app = defineApp();
export default app;
`);
  vfs.writeFileSync("/convex/schema.ts", `import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  todos: defineTable({
    title: v.string(),
    completed: v.boolean(),
    priority: v.optional(v.union(v.literal("low"), v.literal("medium"), v.literal("high"))),
  }),
});
`);
  vfs.writeFileSync("/convex/todos.ts", `import { query, mutation } from "./_generated/server";
import { v } from "convex/values";

export const list = query({
  args: {},
  handler: async (ctx) => {
    return await ctx.db.query("todos").order("desc").collect();
  },
});

export const create = mutation({
  args: { title: v.string() },
  handler: async (ctx, args) => {
    return await ctx.db.insert("todos", {
      title: args.title,
      completed: false,
    });
  },
});

export const toggle = mutation({
  args: { id: v.id("todos") },
  handler: async (ctx, args) => {
    const todo = await ctx.db.get(args.id);
    if (!todo) throw new Error("Todo not found");
    await ctx.db.patch(args.id, { completed: !todo.completed });
  },
});

export const remove = mutation({
  args: { id: v.id("todos") },
  handler: async (ctx, args) => {
    await ctx.db.delete(args.id);
  },
});
`);
  vfs.writeFileSync("/convex/_generated/api.ts", `// Convex API - manually created for browser demo
// In a real project, this is auto-generated by 'npx convex dev'

// Function references for the Convex client
// These are string identifiers that map to server functions
export const api = {
  todos: {
    list: "todos:list",
    create: "todos:create",
    toggle: "todos:toggle",
    remove: "todos:remove",
  },
} as const;
`);
  vfs.writeFileSync("/convex/_generated/server.ts", `// Server stubs for browser demo
// In a real project, this is auto-generated by Convex

export function query<Args, Output>(config: {
  args: Args;
  handler: (ctx: any, args: any) => Promise<Output>;
}) {
  return config;
}

export function mutation<Args, Output>(config: {
  args: Args;
  handler: (ctx: any, args: any) => Promise<Output>;
}) {
  return config;
}
`);
  vfs.writeFileSync("/lib/convex.tsx", `"use client";

import React, { useState, useEffect } from 'react';
import { ConvexProvider as BaseConvexProvider, ConvexReactClient, useQuery as useConvexQuery, useMutation as useConvexMutation } from 'convex/react';

// Re-export the API
export { api } from '../convex/_generated/api.ts';

// Get Convex URL using standard Next.js env var pattern
// Falls back to window.__CONVEX_URL__ for backwards compatibility
const getConvexUrl = () => {
  // Standard Next.js pattern: process.env.NEXT_PUBLIC_*
  if (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_CONVEX_URL) {
    return process.env.NEXT_PUBLIC_CONVEX_URL;
  }
  // Fallback for backwards compatibility
  if (typeof window !== 'undefined' && (window as any).__CONVEX_URL__) {
    return (window as any).__CONVEX_URL__;
  }
  return null;
};

// Create client lazily
let client: ConvexReactClient | null = null;

function getClient() {
  const url = getConvexUrl();
  if (!url) return null;
  if (!client || (client as any)._address !== url) {
    client = new ConvexReactClient(url);
  }
  return client;
}

// Wrapper hooks that handle the case when Convex is not connected
export function useQuery(query: any, ...args: any[]) {
  const url = getConvexUrl();
  // When not connected, return undefined
  if (!url) return undefined;
  return useConvexQuery(query, ...args);
}

export function useMutation(mutation: any) {
  const url = getConvexUrl();
  const convexMutation = url ? useConvexMutation(mutation) : null;

  return async (args: any) => {
    if (!convexMutation) {
      console.warn('Convex not connected - mutation ignored');
      return;
    }
    return convexMutation(args);
  };
}

export function ConvexProvider({ children }: { children: React.ReactNode }) {
  const [convexUrl, setConvexUrl] = useState(getConvexUrl());

  // Check for URL changes (after deploy)
  useEffect(() => {
    const checkUrl = () => {
      const url = getConvexUrl();
      if (url !== convexUrl) {
        setConvexUrl(url);
      }
    };

    // Check periodically for URL changes
    const interval = setInterval(checkUrl, 1000);
    return () => clearInterval(interval);
  }, [convexUrl]);

  const convexClient = getClient();

  if (!convexClient) {
    // Show a message when Convex is not configured
    return (
      <div style={{ maxWidth: 480, margin: "0 auto", padding: "4rem 1rem", textAlign: "center" }}>
        <h2 style={{ fontSize: "1.5rem", fontWeight: 700, marginBottom: "1rem" }}>Connect to Convex</h2>
        <p style={{ color: "hsl(215 20.2% 65.1%)", marginBottom: "1.5rem" }}>
          Enter your Convex deploy key in the console panel and click "Deploy Schema" to connect.
        </p>
        <p style={{ color: "hsl(215 20.2% 65.1%)", fontSize: "0.75rem" }}>
          Get a deploy key from your Convex dashboard at convex.dev
        </p>
      </div>
    );
  }

  return (
    <BaseConvexProvider client={convexClient}>
      {children}
    </BaseConvexProvider>
  );
}
`);
  vfs.writeFileSync("/components/task-list.tsx", `"use client";

import React from 'react';
import { useQuery, useMutation, api } from '../lib/convex.tsx';

type Todo = {
  _id: string;
  _creationTime: number;
  title: string;
  completed: boolean;
};

export function TaskList() {
  const todos = useQuery(api.todos.list) as Todo[] | undefined;
  const createTodo = useMutation(api.todos.create);
  const toggleTodo = useMutation(api.todos.toggle);
  const removeTodo = useMutation(api.todos.remove);

  const [newTitle, setNewTitle] = React.useState("");

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!newTitle.trim()) return;
    await createTodo({ title: newTitle.trim() });
    setNewTitle("");
  };

  return (
    <div style={{ maxWidth: 480, margin: "0 auto", padding: "2rem 1rem" }}>
      <h1 style={{ fontSize: "1.5rem", fontWeight: 700, marginBottom: "1.5rem" }}>
        Todos
      </h1>

      <form onSubmit={handleSubmit} style={{ display: "flex", gap: "0.5rem", marginBottom: "1.5rem" }}>
        <input
          placeholder="What needs to be done?"
          value={newTitle}
          onChange={(e) => setNewTitle(e.target.value)}
          style={{ flex: 1 }}
        />
        <button type="submit">Add</button>
      </form>

      {todos === undefined ? (
        <p style={{ color: "hsl(215 20.2% 65.1%)" }}>Loading...</p>
      ) : todos.length === 0 ? (
        <p style={{ color: "hsl(215 20.2% 65.1%)" }}>No todos yet.</p>
      ) : (
        <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
          {todos.map((todo) => (
            <li key={todo._id} style={{
              display: "flex",
              alignItems: "center",
              gap: "0.75rem",
              padding: "0.625rem 0",
              borderBottom: "1px solid hsl(217.2 32.6% 17.5%)",
            }}>
              <input
                type="checkbox"
                checked={todo.completed}
                onChange={() => toggleTodo({ id: todo._id })}
              />
              <span style={{
                flex: 1,
                textDecoration: todo.completed ? "line-through" : "none",
                opacity: todo.completed ? 0.5 : 1,
              }}>
                {todo.title}
              </span>
              <button
                onClick={() => removeTodo({ id: todo._id })}
                style={{
                  background: "transparent",
                  color: "hsl(0 62.8% 50%)",
                  padding: "0.25rem 0.5rem",
                  fontSize: "0.75rem",
                }}
              >
                Delete
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
`);
  vfs.writeFileSync("/app/layout.tsx", `import React from 'react';
import './globals.css';
import { ConvexProvider } from '../lib/convex.tsx';

export const metadata = {
  title: 'Convex Todo App',
  description: 'A simple todo app powered by Convex, running in the browser',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <ConvexProvider>
      {children}
    </ConvexProvider>
  );
}
`);
  vfs.writeFileSync("/app/page.tsx", `"use client";

import React from 'react';
import { TaskList } from '../components/task-list.tsx';

export default function HomePage() {
  return <TaskList />;
}
`);
  vfs.writeFileSync("/public/favicon.ico", "favicon placeholder");
  vfs.writeFileSync("/public/robots.txt", "User-agent: *\nAllow: /");
}
async function initConvexAppDemo(outputElement, options = {}) {
  const log = (message) => {
    const line = document.createElement("div");
    line.textContent = `[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] ${message}`;
    outputElement.appendChild(line);
    outputElement.scrollTop = outputElement.scrollHeight;
  };
  log("Creating virtual file system...");
  const vfs = new VirtualFS();
  log("Creating Convex App project structure...");
  createConvexAppProject(vfs);
  if (options.installPackages) {
    log("Installing npm packages (this may take a while)...");
    const npm = new PackageManager(vfs);
    for (const pkg of DEMO_PACKAGES) {
      try {
        log(`Installing ${pkg}...`);
        await npm.install(pkg, {
          onProgress: (msg) => log(`  ${msg}`)
        });
      } catch (error) {
        log(`Warning: Failed to install ${pkg}: ${error}`);
      }
    }
  }
  log("Initializing runtime...");
  const runtime = new Runtime(vfs, {
    cwd: "/",
    env: {
      NODE_ENV: "development"
    },
    onConsole: (method, args) => {
      const prefix = method === "error" ? "[ERROR]" : method === "warn" ? "[WARN]" : "";
      log(`${prefix} ${args.map((a10) => String(a10)).join(" ")}`);
    }
  });
  log("Setting up file watcher...");
  vfs.watch("/app", { recursive: true }, (eventType, filename) => {
    log(`File ${eventType}: ${filename}`);
  });
  log("Convex App demo initialized!");
  log("");
  log("Project structure:");
  listFiles(vfs, "/", log, "  ");
  return { vfs, runtime };
}
async function startConvexAppDevServer(vfs, options = {}) {
  const port = options.port || 3002;
  const log = options.log || console.log;
  log("Starting Convex App dev server...");
  const server = new NextDevServer(vfs, {
    port,
    root: "/",
    preferAppRouter: true
  });
  const bridge = getServerBridge();
  try {
    log("Initializing Service Worker...");
    await bridge.initServiceWorker();
    log("Service Worker ready");
  } catch (error) {
    log(`Warning: Service Worker failed to initialize: ${error}`);
    log("Falling back to direct request handling...");
  }
  bridge.on("server-ready", (p, u) => {
    log(`Server ready at ${u}`);
  });
  const httpServer = createHttpServerWrapper(server);
  bridge.registerServer(httpServer, port);
  server.start();
  log("File watcher started");
  server.on("hmr-update", (update) => {
    log(`HMR update: ${JSON.stringify(update)}`);
  });
  const url = bridge.getServerUrl(port);
  log(`Convex App dev server running at: ${url}/`);
  return {
    server,
    url: url + "/",
    stop: () => {
      server.stop();
      bridge.unregisterServer(port);
    }
  };
}
function createHttpServerWrapper(devServer) {
  return {
    listening: true,
    address: () => ({ port: devServer.getPort(), address: "0.0.0.0", family: "IPv4" }),
    async handleRequest(method, url, headers, body) {
      const bodyBuffer = body ? typeof body === "string" ? BufferPolyfill.from(body) : body : void 0;
      return devServer.handleRequest(method, url, headers, bodyBuffer);
    }
  };
}
function listFiles(vfs, path, log, indent) {
  try {
    const entries = vfs.readdirSync(path);
    for (const entry of entries) {
      if (entry === "node_modules") {
        log(`${indent}${entry}/ (skipped)`);
        continue;
      }
      const fullPath = path === "/" ? `/${entry}` : `${path}/${entry}`;
      try {
        const stat = vfs.statSync(fullPath);
        if (stat.isDirectory()) {
          log(`${indent}${entry}/`);
          listFiles(vfs, fullPath, log, indent + "  ");
        } else {
          log(`${indent}${entry}`);
        }
      } catch {
        log(`${indent}${entry}`);
      }
    }
  } catch {
  }
}
const GIT_ENV_KEYS = [
  "GIT_TOKEN",
  "GIT_USERNAME",
  "GIT_PASSWORD",
  "GIT_CORS_PROXY",
  "GIT_AUTHOR_NAME",
  "GIT_AUTHOR_EMAIL"
];
function sanitizeGitAuth(input) {
  if (!input) return {};
  const trim = (value) => {
    const next = value == null ? void 0 : value.trim();
    return next ? next : void 0;
  };
  return {
    token: trim(input.token),
    username: trim(input.username),
    password: trim(input.password),
    corsProxy: trim(input.corsProxy),
    authorName: trim(input.authorName),
    authorEmail: trim(input.authorEmail)
  };
}
function gitAuthToEnv(auth) {
  const env = {};
  if (auth.token) env.GIT_TOKEN = auth.token;
  if (auth.username) env.GIT_USERNAME = auth.username;
  if (auth.password) env.GIT_PASSWORD = auth.password;
  if (auth.corsProxy) env.GIT_CORS_PROXY = auth.corsProxy;
  if (auth.authorName) env.GIT_AUTHOR_NAME = auth.authorName;
  if (auth.authorEmail) env.GIT_AUTHOR_EMAIL = auth.authorEmail;
  return env;
}
function createContainer(options) {
  const containerId = crypto.randomUUID();
  const baseEnv = { ...(options == null ? void 0 : options.env) || {} };
  let gitAuth = sanitizeGitAuth(options == null ? void 0 : options.git);
  const vfs = new VirtualFS();
  const networkController = createNetworkController(
    options == null ? void 0 : options.network,
    (options == null ? void 0 : options.networkIntegration) ?? null
  );
  if (!hasExplicitDefaultNetworkController()) {
    setDefaultNetworkController(networkController);
  }
  const childProcessController = initChildProcess(vfs, {
    installMode: options == null ? void 0 : options.installMode,
    containerId,
    onInstallMutation: async (summary) => {
      var _a;
      if (summary.touchesNodeModules) {
        const { clearNpmBundleCache } = await import("./tailwind-config-loader-DYrGqMY-.js").then((n) => n.n);
        clearNpmBundleCache(vfs);
      }
      if (!(summary.touchesNodeModules || summary.touchesPackageJson)) {
        return;
      }
      for (const server of childProcessController.frameworkDevServers.values()) {
        (_a = server.clearInstalledPackagesCache) == null ? void 0 : _a.call(server);
      }
    }
  });
  for (const command of (options == null ? void 0 : options.shellCommands) || []) {
    childProcessController.registerShellCommand(command);
  }
  const resolveCommandEnv = (runEnv) => ({
    ...networkController.getResolvedPolicy().env,
    ...baseEnv,
    ...gitAuthToEnv(gitAuth),
    ...runEnv || {}
  });
  const runtimeOptions = {
    ...options,
    env: resolveCommandEnv(),
    childProcessController,
    networkController,
    // Servers created inside this runtime attribute to this container.
    ownerId: containerId
  };
  const runtime = new Runtime(vfs, runtimeOptions);
  const npmManager = new PackageManager(vfs, {
    cwd: (options == null ? void 0 : options.cwd) ?? runtime.getProcess().cwd(),
    installMode: options == null ? void 0 : options.installMode,
    onMutation: childProcessController.onInstallMutation || void 0
  });
  const serverBridge = getServerBridge({
    baseUrl: options == null ? void 0 : options.baseUrl,
    basePath: options == null ? void 0 : options.basePath
  });
  const handleServerReady = (...args) => {
    var _a;
    const [port, url, metadata] = args;
    if ((metadata == null ? void 0 : metadata.ownerId) && metadata.ownerId !== containerId) return;
    (_a = options == null ? void 0 : options.onServerReady) == null ? void 0 : _a.call(options, port, url);
  };
  if (options == null ? void 0 : options.onServerReady) {
    serverBridge.on("server-ready", handleServerReady);
  }
  const syncRuntimeEnvWithGitAuth = () => {
    const proc = runtime.getProcess();
    const env = proc.env;
    for (const key of GIT_ENV_KEYS) {
      delete env[key];
    }
    Object.assign(env, gitAuthToEnv(gitAuth));
  };
  syncRuntimeEnvWithGitAuth();
  let legacyActiveExecutionId = null;
  const sanitizeSessionEnv = (env) => {
    const next = stripInternalChildProcessEnv(env);
    for (const key of GIT_ENV_KEYS) {
      delete next[key];
    }
    for (const key of NETWORK_ENV_KEYS) {
      delete next[key];
    }
    return next;
  };
  const activeAbortControllers = /* @__PURE__ */ new Set();
  const createLinkedAbortController = (signal) => {
    const controller = new AbortController();
    activeAbortControllers.add(controller);
    const untrack = () => activeAbortControllers.delete(controller);
    if (!signal) {
      return { controller, cleanup: untrack };
    }
    if (signal.aborted) {
      controller.abort();
      return { controller, cleanup: untrack };
    }
    const onAbort = () => controller.abort();
    signal.addEventListener("abort", onAbort, { once: true });
    return {
      controller,
      cleanup: () => {
        untrack();
        signal.removeEventListener("abort", onAbort);
      }
    };
  };
  const toRunResult = (result) => ({
    stdout: String(result.stdout || ""),
    stderr: String(result.stderr || ""),
    exitCode: result.exitCode
  });
  const runLegacyCommand = async (command, runOptions) => {
    var _a;
    almostnodeDebugLog("commands", `runLegacyCommand(${command} ${runOptions}`);
    if ((_a = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a.aborted) {
      return { stdout: "", stderr: "", exitCode: 130 };
    }
    const resolvedCwd = (runOptions == null ? void 0 : runOptions.cwd) ?? runtime.getProcess().cwd();
    const env = resolveCommandEnv(runOptions == null ? void 0 : runOptions.env);
    const { controller, cleanup } = createLinkedAbortController(
      runOptions == null ? void 0 : runOptions.signal
    );
    const execution = childProcessController.createExecution({
      onStdout: runOptions == null ? void 0 : runOptions.onStdout,
      onStderr: runOptions == null ? void 0 : runOptions.onStderr,
      signal: controller.signal,
      interactive: runOptions == null ? void 0 : runOptions.interactive
    });
    legacyActiveExecutionId = execution.id;
    try {
      const result = await childProcessController.runCommand(
        command,
        { cwd: resolvedCwd, env },
        execution.id
      );
      return toRunResult({
        stdout: result.stdout,
        stderr: result.stderr,
        exitCode: result.exitCode
      });
    } finally {
      if (legacyActiveExecutionId === execution.id) {
        legacyActiveExecutionId = null;
      }
      cleanup();
      childProcessController.destroyExecution(execution.id);
    }
  };
  const createTerminalSession = (sessionOptions) => {
    let disposed2 = false;
    let activeExecutionId = null;
    let activeAbortController = null;
    const state = {
      cwd: (sessionOptions == null ? void 0 : sessionOptions.cwd) ?? runtime.getProcess().cwd(),
      env: sanitizeSessionEnv((sessionOptions == null ? void 0 : sessionOptions.env) || {}),
      running: false
    };
    return {
      run: async (command, sessionRunOptions) => {
        var _a;
        if (disposed2) {
          throw new Error("Terminal session has been disposed");
        }
        if (state.running) {
          throw new Error("Terminal session is already running a command");
        }
        if ((_a = sessionRunOptions == null ? void 0 : sessionRunOptions.signal) == null ? void 0 : _a.aborted) {
          return { stdout: "", stderr: "", exitCode: 130 };
        }
        const { controller, cleanup } = createLinkedAbortController(
          sessionRunOptions == null ? void 0 : sessionRunOptions.signal
        );
        const execution = childProcessController.createExecution({
          onStdout: sessionRunOptions == null ? void 0 : sessionRunOptions.onStdout,
          onStderr: sessionRunOptions == null ? void 0 : sessionRunOptions.onStderr,
          signal: controller.signal,
          interactive: sessionRunOptions == null ? void 0 : sessionRunOptions.interactive,
          cols: Number(state.env.COLUMNS || 80),
          rows: Number(state.env.LINES || 24)
        });
        state.running = true;
        activeExecutionId = execution.id;
        activeAbortController = controller;
        try {
          const result = await childProcessController.runCommand(
            command,
            {
              cwd: state.cwd,
              env: resolveCommandEnv(state.env)
            },
            execution.id
          );
          if (result.env) {
            const nextEnv = sanitizeSessionEnv(result.env);
            state.cwd = nextEnv.PWD || state.cwd;
            state.env = nextEnv;
          }
          return toRunResult({
            stdout: result.stdout,
            stderr: result.stderr,
            exitCode: result.exitCode
          });
        } finally {
          cleanup();
          state.running = false;
          activeAbortController = null;
          activeExecutionId = null;
          childProcessController.destroyExecution(execution.id);
        }
      },
      sendInput: (data) => {
        if (!activeExecutionId) return;
        childProcessController.sendInput(activeExecutionId, data);
      },
      resize: (cols, rows) => {
        const normalizedCols = Number.isFinite(cols) ? Math.max(1, Math.floor(cols)) : 80;
        const normalizedRows = Number.isFinite(rows) ? Math.max(1, Math.floor(rows)) : 24;
        state.env = {
          ...state.env,
          COLUMNS: String(normalizedCols),
          LINES: String(normalizedRows)
        };
        if (activeExecutionId) {
          childProcessController.updateExecutionSize(
            activeExecutionId,
            normalizedCols,
            normalizedRows
          );
        }
      },
      abort: () => {
        activeAbortController == null ? void 0 : activeAbortController.abort();
      },
      dispose: () => {
        disposed2 = true;
        activeAbortController == null ? void 0 : activeAbortController.abort();
      },
      getState: () => ({
        cwd: state.cwd,
        env: { ...state.env },
        running: state.running
      })
    };
  };
  let disposed = false;
  const dispose = () => {
    if (disposed) return;
    disposed = true;
    serverBridge.off("server-ready", handleServerReady);
    for (const controller of activeAbortControllers) {
      controller.abort();
    }
    activeAbortControllers.clear();
    disposeChildProcessController(childProcessController);
    closeServersByOwner(containerId);
    serverBridge.unregisterServersByOwner(containerId);
  };
  return {
    id: containerId,
    vfs,
    runtime,
    network: networkController,
    npm: npmManager,
    serverBridge,
    execute: (code, filename) => runtime.execute(code, filename),
    runFile: (filename) => runtime.runFile(filename),
    run: (command, runOptions) => runLegacyCommand(command, runOptions),
    createTerminalSession,
    registerShellCommand: (definition) => {
      childProcessController.registerShellCommand(definition);
    },
    unregisterShellCommand: (name) => {
      return childProcessController.unregisterShellCommand(name);
    },
    setGitAuth: (updates) => {
      const next = { ...gitAuth };
      const keys = Object.keys(updates);
      for (const key of keys) {
        const value = updates[key];
        if (value === null) {
          delete next[key];
          continue;
        }
        if (typeof value === "string") {
          const trimmed = value.trim();
          if (trimmed) {
            next[key] = trimmed;
          } else {
            delete next[key];
          }
        }
      }
      gitAuth = next;
      syncRuntimeEnvWithGitAuth();
    },
    getGitAuth: () => ({ ...gitAuth }),
    sendInput: (data) => {
      if (!legacyActiveExecutionId) return;
      childProcessController.sendInput(legacyActiveExecutionId, data);
    },
    createREPL: () => runtime.createREPL(),
    on: (event, listener) => {
      serverBridge.on(event, listener);
    },
    setKeychain: (kc) => {
      childProcessController.keychain = kc;
    },
    setSearchProvider: (provider) => {
      childProcessController.searchProvider = provider;
    },
    setHMRTargetForPort: (port, targetWindow) => {
      var _a;
      for (const server of childProcessController.frameworkDevServers.values()) {
        if (server.port === port) {
          (_a = server.setHMRTarget) == null ? void 0 : _a.call(server, targetWindow);
          return;
        }
      }
    },
    dispose
  };
}
export {
  DEMO_PACKAGES as CONVEX_APP_DEMO_PACKAGES,
  PACKAGE_JSON as CONVEX_APP_PACKAGE_JSON,
  D as DevServer,
  J as ELECTRON_IPC_KIND,
  K as ELECTRON_IPC_TAG,
  NextDevServer,
  PERSISTED_NETWORK_SESSION_STORAGE_KEY,
  PackageManager,
  Runtime,
  SANDBOX_SETUP_INSTRUCTIONS,
  SandboxRuntime,
  S as ServerBridge,
  TAILSCALE_SESSION_STORAGE_KEY,
  VirtualFS,
  ViteDevServer,
  WorkerRuntime,
  M as allocateElectronAppInstanceId,
  O as assert,
  b as buildElectronPreloadBootstrap,
  P as chokidar,
  createContainer,
  createConvexAppProject,
  Q as createFetchVirtualServer,
  T as createFsShim,
  createNetworkSessionPersistence,
  U as createProcess,
  createRuntime,
  createTailscaleSessionPersistence,
  createContainer as default,
  W as esbuild,
  X as events,
  Y as execute,
  Z as fsevents,
  generateSandboxFiles,
  _ as getElectronHost,
  getSandboxHtml,
  getSandboxVercelConfig,
  getServerBridge,
  $ as hasElectronHost,
  a0 as http,
  initConvexAppDemo,
  i as install,
  a1 as isElectronIpcEnvelope,
  l as launchElectronApp,
  a2 as module,
  a3 as net,
  index as network,
  a as npm,
  parsePersistedNetworkSession,
  parseTailscaleStateSnapshot,
  a4 as path,
  a5 as perf_hooks,
  a6 as querystring,
  a7 as readdirp,
  a8 as registerFetchVirtualServer,
  a9 as resetServerBridge,
  aa as rollup,
  serializePersistedNetworkSession,
  serializeTailscaleStateSnapshot,
  ab as setElectronHost,
  startConvexAppDevServer,
  ac as stream,
  ad as url,
  ae as util,
  af as worker_threads,
  ag as ws
};
//# sourceMappingURL=index.mjs.map
