@maintainer-pro/ai-bridge 0.1.27 → 0.1.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maintainer-pro/ai-bridge",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "description": "Local bridge daemon that pairs a machine to Maintainer Pro and configures multiple client sandboxes.",
5
5
  "keywords": [
6
6
  "maintainer-pro",
@@ -28,7 +28,7 @@
28
28
  "node": ">=22"
29
29
  },
30
30
  "dependencies": {
31
- "@maintainer-pro/ai-cli": "^0.1.14",
31
+ "@maintainer-pro/ai-cli": "^0.1.15",
32
32
  "@maintainer-pro/ai-server": "^0.1.8"
33
33
  }
34
34
  }
@@ -150,15 +150,22 @@ export function shouldProcessShareResponse(headers) {
150
150
  return true;
151
151
  }
152
152
 
153
- function isImmutableAssetPath(path) {
154
- const p = String(path || "").split("?")[0] || "";
153
+ function hasContentHash(path) {
154
+ const base = String(path || "").split("?")[0].split("/").pop() || "";
155
155
  return (
156
- /\/_next\/static\//.test(p) ||
157
- /\/__nextjs_font\//.test(p) ||
158
- /\.[0-9a-f]{8,}\.(?:js|css|woff2?)$/i.test(p)
156
+ /\.[0-9a-f]{8,}\.(?:js|css|woff2?)$/i.test(base) ||
157
+ /^[0-9a-f]{8,}\.(?:js|css|woff2?)$/i.test(base) ||
158
+ /-[0-9a-f]{8,}[^/]*\.(?:js|css)$/i.test(base)
159
159
  );
160
160
  }
161
161
 
162
+ /** Production hashed assets only. Next/Vite dev chunks reuse the same URL. */
163
+ function isImmutableAssetPath(path) {
164
+ const p = String(path || "").split("?")[0] || "";
165
+ if (/\/__nextjs_font\//.test(p)) return true;
166
+ return hasContentHash(p);
167
+ }
168
+
162
169
  function isViteDevSourcePath(path) {
163
170
  const raw = String(path || "");
164
171
  const p = raw.split("?")[0] || "";
@@ -184,12 +191,12 @@ function isDocumentPath(path) {
184
191
 
185
192
  function isNoStorePath(path) {
186
193
  const p = String(path || "").split("?")[0] || "";
194
+ if (isImmutableAssetPath(path) || isCacheableMediaPath(path)) return false;
187
195
  return (
188
196
  /\/embed-config\.js$/i.test(p) ||
189
197
  p === "/api" ||
190
198
  p.startsWith("/api/") ||
191
- /\/_next\/webpack-hmr/i.test(p) ||
192
- /\/_next\/webpack\/hmr/i.test(p) ||
199
+ /\/_next\//i.test(p) ||
193
200
  /\/__nextjs_original-stack-frames/i.test(p) ||
194
201
  /\/__mp\//.test(p) ||
195
202
  isViteDevSourcePath(path) ||
@@ -241,9 +248,9 @@ function dropHopCacheNoise(headers) {
241
248
  }
242
249
 
243
250
  /**
244
- * Cache-Control for the share URL. Hashed Next/Vite assets can sit in the
245
- * browser for a year; HTML/RSC revalidate with ETag; secrets and HMR do not
246
- * cache.
251
+ * Cache-Control for the share URL. Only content-hashed assets are immutable.
252
+ * Next/Vite dev chunks reuse URLs, so they must not be cached or HMR/hydration
253
+ * breaks. HTML, RSC, and HMR stay no-store.
247
254
  *
248
255
  * @param {Record<string, string>} headers
249
256
  * @param {string} path
@@ -485,8 +492,11 @@ export function prefixShareOriginUrl(value, publicBase) {
485
492
  const basePort = base.port || (base.protocol === "https:" ? "443" : "80");
486
493
  if (reqPort !== basePort) return value;
487
494
  const path = u.pathname || "/";
488
- if (path === "/" || path === "") return value;
489
495
  if (path === prefix || path.indexOf(prefix + "/") === 0) return u.toString();
496
+ if (path === "/" || path === "") {
497
+ u.pathname = prefix || "/";
498
+ return u.toString();
499
+ }
490
500
  if (path.indexOf("/p/") === 0) return u.toString();
491
501
  u.pathname = prefix + path;
492
502
  return u.toString();
@@ -722,11 +732,11 @@ function rewriteShareAsLocalEnv(body) {
722
732
  let out = String(body);
723
733
  out = out.replace(
724
734
  /(\/\.\*localhost\.\*\/\.test\()([^)]+)(\))/g,
725
- "($1$2$3||location.pathname.indexOf(\"/p/\")===0)"
735
+ "($1$2$3||window.__MP_SHARE_PREFIX__)"
726
736
  );
727
737
  out = out.replace(
728
738
  /((?:window\.)?location\.hostname)\s*===\s*(['"])localhost\2/g,
729
- "($1===$2localhost$2||location.pathname.indexOf(\"/p/\")===0)"
739
+ "($1===$2localhost$2||window.__MP_SHARE_PREFIX__)"
730
740
  );
731
741
  return out;
732
742
  }
@@ -1026,6 +1036,7 @@ function injectMaintainerProEmbed(html, aiPublicBase) {
1026
1036
  function shareProxyShim(p, portMap, rewriteMappedLocalUrls, bypassCors) {
1027
1037
  if (!p || window.__MP_SHARE_SHIM__) return;
1028
1038
  window.__MP_SHARE_SHIM__ = 1;
1039
+ window.__MP_SHARE_PREFIX__ = p;
1029
1040
  window.__MP_PORT_MAP__ = portMap || {};
1030
1041
  window.__MP_BYPASS_CORS__ = Boolean(bypassCors);
1031
1042
  function rewriteText(text) {
@@ -1121,10 +1132,8 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls, bypassCors) {
1121
1132
  if (v.charAt(0) === "/" && v.charAt(1) !== "/") return prefixPath(v);
1122
1133
  try {
1123
1134
  var nav = new URL(v, location.href);
1124
- if (!loopback(nav.hostname)) return v;
1125
- if (nav.origin !== location.origin) return v;
1126
- if (nav.pathname === "/" || nav.pathname === "") return v;
1127
- nav.pathname = prefixPath(nav.pathname);
1135
+ if (!loopback(nav.hostname) && nav.origin !== location.origin) return v;
1136
+ nav.pathname = prefixPath(nav.pathname || "/");
1128
1137
  return nav.toString();
1129
1138
  } catch (e) {}
1130
1139
  return v;
@@ -1281,14 +1290,25 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls, bypassCors) {
1281
1290
  if (typeof body === "string") arguments[0] = rewriteText(body);
1282
1291
  return xs.apply(this, arguments);
1283
1292
  };
1293
+ function asNavUrl(u) {
1294
+ if (u == null || u === "") return u;
1295
+ if (typeof u === "string") return addNav(u);
1296
+ try {
1297
+ if (typeof URL !== "undefined" && u instanceof URL) return addNav(u.href);
1298
+ } catch (e) {}
1299
+ try {
1300
+ return addNav(String(u));
1301
+ } catch (e) {}
1302
+ return u;
1303
+ }
1284
1304
  var ps = history.pushState.bind(history);
1285
1305
  history.pushState = function (s, t, u) {
1286
- if (typeof u === "string") u = addNav(u);
1306
+ if (u != null && u !== "") u = asNavUrl(u);
1287
1307
  return ps(s, t, u);
1288
1308
  };
1289
1309
  var rs = history.replaceState.bind(history);
1290
1310
  history.replaceState = function (s, t, u) {
1291
- if (typeof u === "string") u = addNav(u);
1311
+ if (u != null && u !== "") u = asNavUrl(u);
1292
1312
  return rs(s, t, u);
1293
1313
  };
1294
1314
  var WS = window.WebSocket;
@@ -1352,6 +1372,24 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls, bypassCors) {
1352
1372
  });
1353
1373
  }
1354
1374
  } catch (e) {}
1375
+ document.addEventListener(
1376
+ "click",
1377
+ function (e) {
1378
+ if (e.defaultPrevented || e.button !== 0) return;
1379
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
1380
+ var a = e.target && e.target.closest ? e.target.closest("a[href]") : null;
1381
+ if (!a || (a.target && a.target !== "" && a.target !== "_self")) return;
1382
+ if (a.hasAttribute("download")) return;
1383
+ var href = a.getAttribute("href");
1384
+ if (!href || href.charAt(0) === "#") return;
1385
+ if (/^(mailto|tel|javascript):/i.test(href)) return;
1386
+ var next = addNav(href);
1387
+ if (!next || next === href) return;
1388
+ e.preventDefault();
1389
+ location.assign(next);
1390
+ },
1391
+ true
1392
+ );
1355
1393
  try {
1356
1394
  var tokenRoot = p.replace(/\/[^/]+$/, "/");
1357
1395
  if (navigator.serviceWorker && tokenRoot.indexOf("/p/") === 0) {
@@ -1475,9 +1513,8 @@ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls, bypa
1475
1513
  return backend + path + (u.search || "") + (u.hash || "");
1476
1514
  }
1477
1515
  if (u.origin !== self.location.origin) return url;
1478
- if (u.pathname === "/" || u.pathname === "") return url;
1479
1516
  if (u.pathname === prefix || u.pathname.indexOf(prefix + "/") === 0) return url;
1480
- u.pathname = u.pathname === "/" ? prefix : prefix + u.pathname;
1517
+ u.pathname = u.pathname === "/" || u.pathname === "" ? prefix : prefix + u.pathname;
1481
1518
  return u.toString();
1482
1519
  } catch (e) {}
1483
1520
  return url;