openmagic 0.14.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1356,7 +1356,7 @@ async function handleLlmChat(params, onChunk, onDone, onError) {
1356
1356
  }
1357
1357
 
1358
1358
  // src/server.ts
1359
- var VERSION = "0.14.0";
1359
+ var VERSION = "0.14.2";
1360
1360
  var __dirname = dirname2(fileURLToPath(import.meta.url));
1361
1361
  function attachOpenMagic(httpServer, roots) {
1362
1362
  function handleRequest(req, res) {
@@ -1614,25 +1614,43 @@ function createProxyServer(targetHost, targetPort, roots) {
1614
1614
  proxy.on("proxyRes", (proxyRes, req, res) => {
1615
1615
  const contentType = proxyRes.headers["content-type"] || "";
1616
1616
  const isHtml = contentType.includes("text/html");
1617
- if (!isHtml) {
1618
- res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
1617
+ const status = proxyRes.statusCode || 200;
1618
+ if (!isHtml && status < 400) {
1619
+ res.writeHead(status, proxyRes.headers);
1619
1620
  proxyRes.pipe(res);
1620
1621
  return;
1621
1622
  }
1622
- const headers = { ...proxyRes.headers };
1623
- delete headers["content-length"];
1624
- delete headers["content-encoding"];
1625
- delete headers["transfer-encoding"];
1626
- delete headers["content-security-policy"];
1627
- delete headers["content-security-policy-report-only"];
1628
- delete headers["x-content-security-policy"];
1629
- delete headers["etag"];
1630
- delete headers["last-modified"];
1631
- headers["cache-control"] = "no-store";
1632
- res.writeHead(proxyRes.statusCode || 200, headers);
1633
- proxyRes.pipe(res, { end: false });
1623
+ if (isHtml) {
1624
+ const headers = { ...proxyRes.headers };
1625
+ delete headers["content-length"];
1626
+ delete headers["content-encoding"];
1627
+ delete headers["transfer-encoding"];
1628
+ delete headers["content-security-policy"];
1629
+ delete headers["content-security-policy-report-only"];
1630
+ delete headers["x-content-security-policy"];
1631
+ delete headers["etag"];
1632
+ delete headers["last-modified"];
1633
+ headers["cache-control"] = "no-store";
1634
+ res.writeHead(status, headers);
1635
+ proxyRes.pipe(res, { end: false });
1636
+ proxyRes.on("end", () => {
1637
+ res.end(buildInjectionScript(token));
1638
+ });
1639
+ return;
1640
+ }
1641
+ const chunks = [];
1642
+ proxyRes.on("data", (c) => chunks.push(c));
1634
1643
  proxyRes.on("end", () => {
1635
- res.end(buildInjectionScript(token));
1644
+ const body = Buffer.concat(chunks).toString("utf-8").slice(0, 2e3);
1645
+ const toolbarScript = buildInjectionScript(token);
1646
+ res.writeHead(status, { "Content-Type": "text/html", "Cache-Control": "no-store" });
1647
+ res.end(`<html><head><meta charset="utf-8"><title>Error ${status}</title></head>
1648
+ <body style="font-family:system-ui;padding:40px;background:#0f0f1e;color:#e0e0e0;">
1649
+ <h2 style="color:#e94560;">Error ${status}</h2>
1650
+ <pre style="color:#888;white-space:pre-wrap;max-width:800px;overflow:auto;font-size:13px;">${body.replace(/</g, "&lt;")}</pre>
1651
+ <p style="color:#555;font-size:13px;">This error is from your dev server, not OpenMagic. The toolbar is available below.</p>
1652
+ ${toolbarScript}
1653
+ </body></html>`);
1636
1654
  });
1637
1655
  });
1638
1656
  proxy.on("error", (err, _req, res) => {
@@ -1684,14 +1702,10 @@ var COMMON_DEV_PORTS = [
1684
1702
  // Vue CLI, generic
1685
1703
  8e3,
1686
1704
  // Django, Python
1687
- 8888,
1688
- // Jupyter, generic
1689
1705
  3001,
1690
1706
  // Common alternate
1691
1707
  4e3,
1692
1708
  // Phoenix, generic
1693
- 5e3,
1694
- // Flask
1695
1709
  1234,
1696
1710
  // Parcel
1697
1711
  4321,
@@ -1700,8 +1714,12 @@ var COMMON_DEV_PORTS = [
1700
1714
  // Remix
1701
1715
  8081,
1702
1716
  // Metro (React Native)
1703
- 9e3
1717
+ 9e3,
1704
1718
  // generic
1719
+ 8888,
1720
+ // Jupyter, generic
1721
+ 5e3
1722
+ // Flask (last — macOS AirPlay also uses 5000)
1705
1723
  ];
1706
1724
  function checkPort(port, host = "127.0.0.1") {
1707
1725
  return new Promise((resolve3) => {
@@ -1721,6 +1739,15 @@ function checkPort(port, host = "127.0.0.1") {
1721
1739
  });
1722
1740
  }
1723
1741
  async function detectDevServer() {
1742
+ const scripts = detectDevScripts();
1743
+ const scriptPorts = scripts.map((s) => s.defaultPort).filter((p, i, a) => a.indexOf(p) === i);
1744
+ if (scriptPorts.length > 0) {
1745
+ for (const port of scriptPorts) {
1746
+ if (await checkPort(port)) {
1747
+ return { port, host: "127.0.0.1" };
1748
+ }
1749
+ }
1750
+ }
1724
1751
  const checks = COMMON_DEV_PORTS.map(async (port) => {
1725
1752
  const isOpen = await checkPort(port);
1726
1753
  return isOpen ? port : null;
@@ -1843,7 +1870,7 @@ process.on("uncaughtException", (err) => {
1843
1870
  process.exit(1);
1844
1871
  });
1845
1872
  var childProcesses = [];
1846
- var VERSION2 = "0.14.0";
1873
+ var VERSION2 = "0.14.2";
1847
1874
  function ask(question) {
1848
1875
  const rl = createInterface({ input: process.stdin, output: process.stdout });
1849
1876
  return new Promise((resolve3) => {
@@ -1903,29 +1930,18 @@ function runCommand(cmd, args, cwd = process.cwd()) {
1903
1930
  }
1904
1931
  });
1905
1932
  }
1906
- async function healthCheck(proxyPort, targetPort) {
1933
+ async function healthCheck(proxyPort, _targetPort) {
1907
1934
  try {
1908
1935
  const controller = new AbortController();
1909
1936
  const timeout = setTimeout(() => controller.abort(), 5e3);
1910
- const res = await fetch(`http://127.0.0.1:${proxyPort}/`, {
1911
- signal: controller.signal,
1912
- headers: { Accept: "text/html" }
1937
+ const res = await fetch(`http://127.0.0.1:${proxyPort}/__openmagic__/health`, {
1938
+ signal: controller.signal
1913
1939
  });
1914
1940
  clearTimeout(timeout);
1915
1941
  if (res.ok) {
1916
- const text = await res.text();
1917
- if (text.includes("__OPENMAGIC_LOADED__")) {
1918
- console.log(chalk.green(" \u2713 Toolbar injection verified."));
1919
- } else {
1920
- console.log(chalk.yellow(" \u26A0 Page loaded but toolbar may not have injected (non-HTML response or CSP)."));
1921
- }
1942
+ console.log(chalk.green(" \u2713 Toolbar ready."));
1922
1943
  } else {
1923
- console.log(
1924
- chalk.yellow(` \u26A0 Dev server returned ${res.status}. Pages may have errors.`)
1925
- );
1926
- console.log(
1927
- chalk.dim(" The toolbar will still appear on pages that load successfully.")
1928
- );
1944
+ console.log(chalk.yellow(" \u26A0 Proxy started but toolbar health check failed."));
1929
1945
  }
1930
1946
  } catch {
1931
1947
  console.log(