sunpeak 0.18.6 → 0.18.7

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.
Files changed (49) hide show
  1. package/bin/commands/dev.mjs +6 -2
  2. package/bin/commands/inspect.mjs +13 -1
  3. package/bin/commands/new.mjs +5 -0
  4. package/bin/lib/dev-overlay.mjs +50 -0
  5. package/bin/lib/live/live-config.d.mts +3 -0
  6. package/bin/lib/live/live-config.mjs +3 -1
  7. package/dist/chatgpt/index.cjs +2 -2
  8. package/dist/chatgpt/index.js +2 -2
  9. package/dist/claude/index.cjs +1 -1
  10. package/dist/claude/index.js +1 -1
  11. package/dist/index.cjs +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/inspector/index.cjs +2 -2
  14. package/dist/inspector/index.js +2 -2
  15. package/dist/inspector/inspector-url.d.ts +13 -0
  16. package/dist/inspector/use-inspector-state.d.ts +2 -0
  17. package/dist/{inspector-DRD_Q66E.cjs → inspector-CKc58UuI.cjs} +60 -19
  18. package/dist/inspector-CKc58UuI.cjs.map +1 -0
  19. package/dist/{inspector-CjSoXm6N.js → inspector-DZrN0kej.js} +60 -19
  20. package/dist/inspector-DZrN0kej.js.map +1 -0
  21. package/dist/{inspector-url-7qhtJwY6.cjs → inspector-url-C3LTKgXt.cjs} +3 -1
  22. package/dist/inspector-url-C3LTKgXt.cjs.map +1 -0
  23. package/dist/{inspector-url-DuEFmxLP.js → inspector-url-CyQcuBI9.js} +3 -1
  24. package/dist/inspector-url-CyQcuBI9.js.map +1 -0
  25. package/dist/mcp/index.cjs +81 -7
  26. package/dist/mcp/index.cjs.map +1 -1
  27. package/dist/mcp/index.js +81 -7
  28. package/dist/mcp/index.js.map +1 -1
  29. package/dist/style.css +4 -0
  30. package/package.json +1 -1
  31. package/template/dist/albums/albums.html +1 -1
  32. package/template/dist/albums/albums.json +1 -1
  33. package/template/dist/carousel/carousel.html +1 -1
  34. package/template/dist/carousel/carousel.json +1 -1
  35. package/template/dist/map/map.html +1 -1
  36. package/template/dist/map/map.json +1 -1
  37. package/template/dist/review/review.html +1 -1
  38. package/template/dist/review/review.json +1 -1
  39. package/template/tests/e2e/albums.spec.ts +1 -1
  40. package/template/tests/e2e/carousel.spec.ts +1 -1
  41. package/template/tests/e2e/dev-overlay.spec.ts +118 -0
  42. package/template/tests/e2e/helpers.ts +13 -0
  43. package/template/tests/e2e/map.spec.ts +1 -1
  44. package/template/tests/e2e/review.spec.ts +1 -1
  45. package/template/tests/live/playwright.config.ts +1 -1
  46. package/dist/inspector-CjSoXm6N.js.map +0 -1
  47. package/dist/inspector-DRD_Q66E.cjs.map +0 -1
  48. package/dist/inspector-url-7qhtJwY6.cjs.map +0 -1
  49. package/dist/inspector-url-DuEFmxLP.js.map +0 -1
package/dist/mcp/index.js CHANGED
@@ -9105,6 +9105,10 @@ function injectDefaultDomain(meta, clientName, serverUrl) {
9105
9105
  //#region src/mcp/server.ts
9106
9106
  var localDevServerUrl = "http://localhost:8000";
9107
9107
  var localHmrWsUrl = "ws://localhost:24678";
9108
+ var lastToolTimingMs = null;
9109
+ function isDevOverlayEnabled() {
9110
+ return process.env.SUNPEAK_DEV_OVERLAY !== "false";
9111
+ }
9108
9112
  /**
9109
9113
  * Detect whether this request needs pre-built HTML (no Vite HMR).
9110
9114
  *
@@ -9130,6 +9134,57 @@ function readResourceHtmlProd(distPath) {
9130
9134
  return fs.readFileSync(htmlPath, "utf8");
9131
9135
  }
9132
9136
  /**
9137
+ * Generate an inline script that shows a dev overlay with resource served timestamp
9138
+ * and tool call request timing.
9139
+ *
9140
+ * The resource timestamp is baked into the HTML at readResource time. Tool timing
9141
+ * arrives two ways:
9142
+ * 1. Baked-in `toolMs` from readResource time (works when the tool call precedes the
9143
+ * resource read, which is the case for Claude and the inspector's initial render).
9144
+ * 2. `_meta._sunpeak.requestTimeMs` on the tool result PostMessage (handles inspector
9145
+ * Re-run and hosts that pass `_meta` through to the resource iframe).
9146
+ *
9147
+ * NOTE: Keep in sync with bin/lib/dev-overlay.mjs (used by the standalone inspector).
9148
+ *
9149
+ * @param servedAt - Unix timestamp (ms) when the resource HTML was generated/served.
9150
+ * @param toolMs - Most recent tool call duration (ms), or null if no call yet.
9151
+ */
9152
+ function getDevOverlayScript(servedAt, toolMs) {
9153
+ return `<script>
9154
+ (function(){
9155
+ var servedAt=${servedAt};
9156
+ var el=null,hidden=false,lastMs=${toolMs ?? "null"};
9157
+ function fmt(ts){var d=new Date(ts);var h=d.getHours(),m=d.getMinutes(),s=d.getSeconds();return (h<10?'0':'')+h+':'+(m<10?'0':'')+m+':'+(s<10?'0':'')+s}
9158
+ function make(){
9159
+ var existing=document.getElementById('__sunpeak-dev-timing');
9160
+ if(existing)return existing;
9161
+ var b=document.createElement('button');b.id='__sunpeak-dev-timing';
9162
+ b.style.cssText='position:fixed;bottom:8px;right:8px;z-index:2147483647;display:grid;grid-template-columns:auto auto;gap:0 6px;align-items:baseline;padding:5px 8px;border-radius:6px;border:1px solid rgba(128,128,128,0.25);background:rgba(0,0,0,0.75);backdrop-filter:blur(8px);color:#e5e5e5;font-size:11px;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;line-height:1.4;cursor:pointer;user-select:none;opacity:0.85;transition:opacity 150ms;';
9163
+ b.onmouseenter=function(){b.style.opacity='1'};
9164
+ b.onmouseleave=function(){b.style.opacity='0.85'};
9165
+ b.onclick=function(){hidden=!hidden;upd()};
9166
+ document.body.appendChild(b);return b;
9167
+ }
9168
+ function upd(){
9169
+ if(!el)el=make();
9170
+ if(hidden){el.title='Show dev info';el.innerHTML='<span style="grid-column:1/-1;font-size:9px;text-align:center">DEV</span>';return}
9171
+ var h='';
9172
+ h+='<span style="text-align:right;color:rgba(255,255,255,0.5);white-space:nowrap">Resource:</span><span style="white-space:nowrap">'+fmt(servedAt)+'</span>';
9173
+ if(lastMs!=null)h+='<span style="text-align:right;color:rgba(255,255,255,0.5);white-space:nowrap">Tool:</span><span style="white-space:nowrap">'+(lastMs%1===0?lastMs:lastMs.toFixed(1))+'ms</span>';
9174
+ el.title='Hide dev info';el.innerHTML=h;
9175
+ }
9176
+ upd();
9177
+ window.addEventListener('message',function(e){
9178
+ var d=e.data;if(!d||typeof d!=='object')return;
9179
+ if(d.method!=='ui/notifications/tool-result')return;
9180
+ var p=d.params;if(!p)return;
9181
+ var ms=p._meta&&p._meta._sunpeak&&p._meta._sunpeak.requestTimeMs;
9182
+ if(typeof ms==='number'){lastMs=ms;upd()}
9183
+ });
9184
+ })();
9185
+ <\/script>`;
9186
+ }
9187
+ /**
9133
9188
  * Generate HTML that loads from Vite dev server with HMR.
9134
9189
  * Used for direct connections (e.g. ChatGPT connecting to localhost).
9135
9190
  */
@@ -9172,6 +9227,7 @@ function getViteResourceHtml(srcPath) {
9172
9227
  src: srcPath,
9173
9228
  component: componentName
9174
9229
  }).toString()}`}"><\/script>
9230
+ ${isDevOverlayEnabled() ? getDevOverlayScript(Date.now(), lastToolTimingMs) : ""}
9175
9231
  </body>
9176
9232
  </html>`;
9177
9233
  }
@@ -9183,7 +9239,9 @@ function getViteResourceHtml(srcPath) {
9183
9239
  */
9184
9240
  function getResourceHtml(simulation, viteMode, prodBuild) {
9185
9241
  if (viteMode && simulation.srcPath && !prodBuild) return getViteResourceHtml(simulation.srcPath);
9186
- return readResourceHtmlProd(simulation.distPath);
9242
+ let html = readResourceHtmlProd(simulation.distPath);
9243
+ if (isDevOverlayEnabled()) html = html.replace("</body>", `${getDevOverlayScript(Date.now(), lastToolTimingMs)}\n</body>`);
9244
+ return html;
9187
9245
  }
9188
9246
  /**
9189
9247
  * Inject localhost Vite dev server URLs into CSP metadata.
@@ -9304,14 +9362,29 @@ function createAppServer(config, simulations, viteMode) {
9304
9362
  const realHandler = simulation.handler;
9305
9363
  if (realHandler && (config.prodTools || !hasMockResult)) {
9306
9364
  console.log(`[MCP] CallTool: ${tool.name}${argsStr} → live handler`);
9365
+ const startTime = performance.now();
9307
9366
  try {
9308
9367
  const result = await realHandler(args, extra);
9309
- if (typeof result === "string") return { content: [{
9310
- type: "text",
9311
- text: result
9312
- }] };
9313
- return result;
9368
+ const durationMs = Math.round((performance.now() - startTime) * 10) / 10;
9369
+ lastToolTimingMs = durationMs;
9370
+ if (typeof result === "string") return {
9371
+ content: [{
9372
+ type: "text",
9373
+ text: result
9374
+ }],
9375
+ _meta: { _sunpeak: { requestTimeMs: durationMs } }
9376
+ };
9377
+ const typed = result;
9378
+ return {
9379
+ ...typed,
9380
+ _meta: {
9381
+ ...typed._meta,
9382
+ _sunpeak: { requestTimeMs: durationMs }
9383
+ }
9384
+ };
9314
9385
  } catch (error) {
9386
+ const durationMs = Math.round((performance.now() - startTime) * 10) / 10;
9387
+ lastToolTimingMs = durationMs;
9315
9388
  const msg = error instanceof Error ? error.message : String(error);
9316
9389
  console.error(`[MCP] CallTool error (${tool.name}): ${msg}`);
9317
9390
  return {
@@ -9319,7 +9392,8 @@ function createAppServer(config, simulations, viteMode) {
9319
9392
  type: "text",
9320
9393
  text: `Error: ${msg}`
9321
9394
  }],
9322
- isError: true
9395
+ isError: true,
9396
+ _meta: { _sunpeak: { requestTimeMs: durationMs } }
9323
9397
  };
9324
9398
  }
9325
9399
  }