@linkshell/gateway 0.4.25 → 0.4.27

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": "@linkshell/gateway",
3
- "version": "0.4.25",
3
+ "version": "0.4.27",
4
4
  "type": "module",
5
5
  "main": "dist/gateway/src/index.js",
6
6
  "exports": {
package/src/embedded.ts CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  handleTunnelWsUpgrade,
26
26
  cleanupSessionTunnels,
27
27
  } from "./tunnel.js";
28
+ import { serveWeb, serveWebAsset, webEnabled, webDistPath } from "./static-web.js";
28
29
 
29
30
  export interface EmbeddedGatewayOptions {
30
31
  port?: number;
@@ -252,6 +253,11 @@ export function startEmbeddedGateway(
252
253
  return;
253
254
  }
254
255
 
256
+ // Serve the gateway's OWN built web assets (no SPA fallback) before the
257
+ // tunnel cookie fallback, so a real asset like /assets/index-xxx.js is
258
+ // served locally instead of being proxied via a stale tunnel cookie.
259
+ if (await serveWebAsset(req, res)) return;
260
+
255
261
  // Tunnel fallback: cookie-based routing for sub-resources (e.g. /_next/static/...)
256
262
  const tunnelCookie = parseTunnelCookie(req);
257
263
  if (tunnelCookie && shouldUseTunnelCookieFallback(req, url.pathname, (pathname) =>
@@ -272,6 +278,11 @@ export function startEmbeddedGateway(
272
278
  return;
273
279
  }
274
280
 
281
+ // Web SPA: last GET fallback, after every API route, so it never shadows
282
+ // them. Serves index.html for "/" and client-side routes; a no-op (false)
283
+ // when no web dist is bundled (e.g. an API-only embedded gateway).
284
+ if (await serveWeb(req, res)) return;
285
+
275
286
  json(res, 404, { error: "not_found" });
276
287
  } catch (err) {
277
288
  if (err instanceof ZodError) {
@@ -479,6 +490,14 @@ export function startEmbeddedGateway(
479
490
  const actualPort =
480
491
  typeof addr === "object" && addr ? addr.port : targetPort;
481
492
  log("info", `embedded gateway on port ${actualPort}`);
493
+ // Surface whether the bundled web SPA was found — the in-app WebView loads
494
+ // this gateway's "/", so a missing dist means a blank screen. Makes the
495
+ // LAN/self-hosted "WebView is blank" failure mode diagnosable from logs.
496
+ if (webEnabled()) {
497
+ log("info", `web UI served from ${webDistPath()}`);
498
+ } else {
499
+ log("warn", `web UI not bundled (WEB_DIST=${webDistPath()} has no index.html) — in-app agent console will be blank`);
500
+ }
482
501
  resolve({
483
502
  port: actualPort,
484
503
  httpUrl: `http://127.0.0.1:${actualPort}`,