sunpeak 0.20.28 → 0.20.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.
@@ -6574,6 +6574,40 @@ function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
6574
6574
  };
6575
6575
  }
6576
6576
  //#endregion
6577
+ //#region src/inspector/inspector-api.ts
6578
+ function inspectorApiEndpoint(path, apiBaseUrl) {
6579
+ if (!apiBaseUrl) return path;
6580
+ return `${apiBaseUrl.replace(/\/+$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
6581
+ }
6582
+ async function readInspectorJson(res, endpoint) {
6583
+ const text = await res.text();
6584
+ if (!text) return {};
6585
+ try {
6586
+ return JSON.parse(text);
6587
+ } catch {
6588
+ const contentType = res.headers.get("content-type");
6589
+ const preview = text.trim().replace(/\s+/g, " ").slice(0, 120);
6590
+ const typeHint = contentType ? ` (${contentType})` : "";
6591
+ throw new Error(`Expected JSON from ${endpoint} but received a non-JSON response${typeHint}: ${preview}`);
6592
+ }
6593
+ }
6594
+ function resolveInspectorResourceUrls(simulations, apiBaseUrl) {
6595
+ if (!apiBaseUrl || !simulations || typeof simulations !== "object") return simulations;
6596
+ const resolved = {};
6597
+ for (const [key, value] of Object.entries(simulations)) {
6598
+ if (!value || typeof value !== "object") {
6599
+ resolved[key] = value;
6600
+ continue;
6601
+ }
6602
+ const sim = value;
6603
+ resolved[key] = {
6604
+ ...sim,
6605
+ resourceUrl: typeof sim.resourceUrl === "string" && sim.resourceUrl.startsWith("/") ? inspectorApiEndpoint(sim.resourceUrl, apiBaseUrl) : sim.resourceUrl
6606
+ };
6607
+ }
6608
+ return resolved;
6609
+ }
6610
+ //#endregion
6577
6611
  //#region src/inspector/use-mcp-connection.ts
6578
6612
  /**
6579
6613
  * Hook for managing MCP server connection status via the dev server proxy.
@@ -6586,7 +6620,7 @@ function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
6586
6620
  * once (or safely twice with cancellation), while explicit `reconnect()` calls
6587
6621
  * are triggered by the Inspector's URL-change effect.
6588
6622
  */
6589
- function useMcpConnection(initialServerUrl) {
6623
+ function useMcpConnection(initialServerUrl, inspectorApiBaseUrl) {
6590
6624
  const [status, setStatus] = (0, react.useState)(initialServerUrl ? "connecting" : "disconnected");
6591
6625
  const [error, setError] = (0, react.useState)();
6592
6626
  const [simulations, setSimulations] = (0, react.useState)();
@@ -6598,7 +6632,8 @@ function useMcpConnection(initialServerUrl) {
6598
6632
  try {
6599
6633
  const body = { url };
6600
6634
  if (auth && auth.type !== "none") body.auth = auth;
6601
- const res = await fetch("/__sunpeak/connect", {
6635
+ const endpoint = inspectorApiEndpoint("/__sunpeak/connect", inspectorApiBaseUrl);
6636
+ const res = await fetch(endpoint, {
6602
6637
  method: "POST",
6603
6638
  headers: { "Content-Type": "application/json" },
6604
6639
  body: JSON.stringify(body)
@@ -6606,7 +6641,7 @@ function useMcpConnection(initialServerUrl) {
6606
6641
  if (!res.ok) {
6607
6642
  let message;
6608
6643
  try {
6609
- const json = await res.json();
6644
+ const json = await readInspectorJson(res, endpoint);
6610
6645
  if (json.error) message = json.error;
6611
6646
  } catch {}
6612
6647
  if (!message) if (res.status === 404) message = "Server not found at this URL. Check the URL and make sure the server is running.";
@@ -6614,9 +6649,9 @@ function useMcpConnection(initialServerUrl) {
6614
6649
  else message = `Connection failed (${res.status})`;
6615
6650
  throw new Error(message);
6616
6651
  }
6617
- const data = await res.json();
6652
+ const data = await readInspectorJson(res, endpoint);
6618
6653
  setStatus("connected");
6619
- setSimulations(data.simulations ?? void 0);
6654
+ setSimulations(resolveInspectorResourceUrls(data.simulations, inspectorApiBaseUrl));
6620
6655
  } catch (err) {
6621
6656
  let message = err instanceof Error ? err.message : String(err);
6622
6657
  if (err instanceof TypeError && message === "Failed to fetch") message = "Cannot reach MCP server. Is it running?";
@@ -6624,20 +6659,21 @@ function useMcpConnection(initialServerUrl) {
6624
6659
  setStatus("error");
6625
6660
  setSimulations(void 0);
6626
6661
  }
6627
- }, []);
6662
+ }, [inspectorApiBaseUrl]);
6628
6663
  const setConnected = (0, react.useCallback)((sims) => {
6629
6664
  setHasReconnected(true);
6630
6665
  setStatus("connected");
6631
6666
  setError(void 0);
6632
- setSimulations(sims);
6633
- }, []);
6667
+ setSimulations(resolveInspectorResourceUrls(sims, inspectorApiBaseUrl));
6668
+ }, [inspectorApiBaseUrl]);
6634
6669
  (0, react.useEffect)(() => {
6635
6670
  if (!initialServerUrl) return;
6636
6671
  let cancelled = false;
6637
6672
  setStatus("connecting");
6638
6673
  (async () => {
6639
6674
  try {
6640
- const res = await fetch("/__sunpeak/list-tools");
6675
+ const endpoint = inspectorApiEndpoint("/__sunpeak/list-tools", inspectorApiBaseUrl);
6676
+ const res = await fetch(endpoint);
6641
6677
  if (cancelled) return;
6642
6678
  if (!res.ok) {
6643
6679
  const msg = res.status === 404 ? "MCP server not reachable. Is it running?" : `Health check failed (${res.status}). Check the MCP server logs.`;
@@ -7137,7 +7173,7 @@ function hasFixtureData(sim) {
7137
7173
  return sim.toolResult != null || sim.toolInput != null || sim.serverTools != null;
7138
7174
  }
7139
7175
  var EMPTY_SIMULATIONS = Object.freeze({});
7140
- function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_SIMULATIONS, appName: appNameProp, appIcon: appIconProp, defaultHost = "chatgpt", onCallTool, onCallToolDirect, defaultProdResources = false, hideInspectorModes = false, demoMode = false, sandboxUrl, mcpServerUrl }) {
7176
+ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_SIMULATIONS, appName: appNameProp, appIcon: appIconProp, defaultHost = "chatgpt", onCallTool, onCallToolDirect, defaultProdResources = false, hideInspectorModes = false, demoMode = false, sandboxUrl, mcpServerUrl, inspectorApiBaseUrl }) {
7141
7177
  const initialSimulations = react.useMemo(() => app ? flattenAppToSimulations(app) : initialSimulationsProp, [app, initialSimulationsProp]);
7142
7178
  const appName = app?.name ?? appNameProp ?? "Sunpeak";
7143
7179
  const appIcon = app?.icon ?? appIconProp;
@@ -7233,13 +7269,14 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
7233
7269
  const [oauthClientSecret, setOauthClientSecret] = react.useState("");
7234
7270
  const [oauthStatus, setOauthStatus] = react.useState("none");
7235
7271
  const [oauthError, setOauthError] = react.useState();
7236
- const connection = useMcpConnection(isEmbedded ? void 0 : mcpServerUrl || void 0);
7272
+ const connection = useMcpConnection(isEmbedded ? void 0 : mcpServerUrl || void 0, inspectorApiBaseUrl);
7237
7273
  const [prodResources, setProdResources] = react.useState(state.urlProdResources ?? defaultProdResources);
7238
7274
  const showSidebar = state.urlSidebar !== false;
7239
7275
  const showDevOverlay = state.urlDevOverlay !== false;
7240
7276
  const [isRunning, setIsRunning] = react.useState(false);
7241
7277
  const [hasRun, setHasRun] = react.useState(false);
7242
7278
  const [showCheck, setShowCheck] = react.useState(false);
7279
+ const [serverPreviewGeneration, setServerPreviewGeneration] = react.useState(0);
7243
7280
  const checkTimerRef = react.useRef(void 0);
7244
7281
  const oauthCleanupRef = react.useRef(void 0);
7245
7282
  react.useEffect(() => {
@@ -7275,7 +7312,8 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
7275
7312
  setOauthError(void 0);
7276
7313
  const popup = window.open("about:blank", `sunpeak-oauth-${Date.now()}`, "width=600,height=700,popup=yes");
7277
7314
  try {
7278
- const res = await fetch("/__sunpeak/oauth/start", {
7315
+ const endpoint = inspectorApiEndpoint("/__sunpeak/oauth/start", inspectorApiBaseUrl);
7316
+ const res = await fetch(endpoint, {
7279
7317
  method: "POST",
7280
7318
  headers: { "Content-Type": "application/json" },
7281
7319
  body: JSON.stringify({
@@ -7285,15 +7323,12 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
7285
7323
  clientSecret: oauthClientSecret || void 0
7286
7324
  })
7287
7325
  });
7326
+ const data = await readInspectorJson(res, endpoint);
7288
7327
  if (!res.ok) {
7289
7328
  let message = `OAuth start failed (${res.status})`;
7290
- try {
7291
- const json = await res.json();
7292
- if (json.error) message = json.error;
7293
- } catch {}
7329
+ if (data.error) message = data.error;
7294
7330
  throw new Error(message);
7295
7331
  }
7296
- const data = await res.json();
7297
7332
  if (data.error) {
7298
7333
  popup?.close();
7299
7334
  setOauthError(data.error);
@@ -7374,11 +7409,14 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
7374
7409
  oauthClientId,
7375
7410
  oauthClientSecret,
7376
7411
  demoMode,
7377
- connection
7412
+ connection,
7413
+ inspectorApiBaseUrl
7378
7414
  ]);
7379
7415
  react.useEffect(() => {
7380
- if (connection.simulations) setSimulations(connection.simulations);
7381
- else if (connection.status === "error" && connection.hasReconnected) setSimulations({});
7416
+ if (connection.simulations) {
7417
+ setSimulations(connection.simulations);
7418
+ setServerPreviewGeneration((generation) => generation + 1);
7419
+ } else if (connection.status === "error" && connection.hasReconnected) setSimulations({});
7382
7420
  }, [
7383
7421
  connection.simulations,
7384
7422
  connection.status,
@@ -7700,7 +7738,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
7700
7738
  injectOpenAIRuntime: state.activeHost === "chatgpt",
7701
7739
  sandboxUrl,
7702
7740
  className: "h-full w-full"
7703
- }, `${state.activeHost}-${state.selectedSimulationName}-${effectiveResourceUrl}-${prodResources}-${prodResourcesGeneration}`)
7741
+ }, `${state.activeHost}-${state.selectedSimulationName}-${effectiveResourceUrl}-${prodResources}-${prodResourcesGeneration}-${serverPreviewGeneration}`)
7704
7742
  });
7705
7743
  else if (!prodResources && state.resourceScript) content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7706
7744
  className: "h-full w-full",
@@ -8468,4 +8506,4 @@ Object.defineProperty(exports, "useThemeContext", {
8468
8506
  }
8469
8507
  });
8470
8508
 
8471
- //# sourceMappingURL=inspector-DSX76Z-W.cjs.map
8509
+ //# sourceMappingURL=inspector-CJPO4f12.cjs.map