sunpeak 0.16.3 → 0.16.5

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 (35) hide show
  1. package/README.md +3 -1
  2. package/bin/commands/build.mjs +1 -0
  3. package/bin/commands/dev.mjs +2 -0
  4. package/dist/chatgpt/globals.css +0 -8
  5. package/dist/mcp/index.cjs +61 -48
  6. package/dist/mcp/index.cjs.map +1 -1
  7. package/dist/mcp/index.js +61 -48
  8. package/dist/mcp/index.js.map +1 -1
  9. package/dist/style.css +0 -8
  10. package/package.json +1 -1
  11. package/template/package.json +0 -3
  12. package/template/src/components/avatar.tsx +1 -1
  13. package/template/src/resources/albums/components/album-card.tsx +2 -2
  14. package/template/src/resources/albums/components/album-carousel.tsx +3 -3
  15. package/template/src/resources/albums/components/film-strip.tsx +2 -2
  16. package/template/src/resources/albums/components/fullscreen-viewer.tsx +1 -1
  17. package/template/src/resources/carousel/components/card.tsx +2 -2
  18. package/template/src/resources/carousel/components/carousel.tsx +3 -3
  19. package/template/src/resources/map/components/map-view.tsx +1 -1
  20. package/template/src/resources/map/components/map.tsx +3 -3
  21. package/template/src/resources/map/components/place-card.tsx +2 -2
  22. package/template/src/resources/map/components/place-carousel.tsx +1 -1
  23. package/template/src/resources/map/components/place-inspector.tsx +4 -4
  24. package/template/src/resources/map/components/place-list.tsx +2 -2
  25. package/template/src/resources/review/review.tsx +59 -29
  26. package/template/src/tools/review-diff.ts +3 -1
  27. package/template/src/tools/review-post.ts +3 -1
  28. package/template/src/tools/review-purchase.ts +3 -1
  29. package/template/src/tools/show-albums.ts +3 -1
  30. package/template/src/tools/show-carousel.ts +3 -1
  31. package/template/src/tools/show-map.ts +3 -1
  32. package/template/tsconfig.json +7 -2
  33. package/template/vitest.config.ts +1 -0
  34. package/template/node_modules/.bin/nodemon +0 -21
  35. package/template/node_modules/.bin/tsx +0 -21
package/dist/mcp/index.js CHANGED
@@ -15518,27 +15518,30 @@ function createAppServer(config, simulations, viteMode) {
15518
15518
  },
15519
15519
  { capabilities: { resources: {}, tools: {} } }
15520
15520
  );
15521
- const registeredResources = /* @__PURE__ */ new Set();
15521
+ const registeredUriSet = /* @__PURE__ */ new Set();
15522
+ const resourceHandles = /* @__PURE__ */ new Map();
15523
+ const toolHandles = [];
15522
15524
  for (const simulation of simulations) {
15523
15525
  const resource = simulation.resource;
15524
15526
  const tool = simulation.tool;
15525
15527
  const toolResult = simulation.toolResult ?? { structuredContent: null };
15526
15528
  const uri2 = resource.uri ?? `ui://${resource.name}`;
15529
+ const resourceName = resource.name;
15527
15530
  const resourceMeta = resource._meta ?? {};
15528
15531
  const toolMeta = tool._meta ?? {};
15529
- if (!registeredResources.has(uri2)) {
15530
- registeredResources.add(uri2);
15532
+ if (!registeredUriSet.has(uri2)) {
15533
+ registeredUriSet.add(uri2);
15531
15534
  const listMeta = viteMode ? injectViteCSP(resourceMeta) : resourceMeta;
15532
15535
  console.log(`[MCP] RegisterResource: ${uri2}`);
15533
- ak(
15534
- mcpServer,
15535
- resource.name,
15536
+ const handle = mcpServer.registerResource(
15537
+ resourceName,
15536
15538
  uri2,
15537
15539
  {
15540
+ mimeType: EI,
15538
15541
  description: resource.description,
15539
15542
  _meta: listMeta
15540
15543
  },
15541
- async (_uri, extra) => {
15544
+ async (readUri, extra) => {
15542
15545
  const prodBuild = needsProdBuild(
15543
15546
  extra?.requestInfo?.headers ?? {}
15544
15547
  );
@@ -15547,17 +15550,18 @@ function createAppServer(config, simulations, viteMode) {
15547
15550
  try {
15548
15551
  content = getResourceHtml(simulation, viteMode, prodBuild);
15549
15552
  } catch (error) {
15550
- console.error(`[MCP] ReadResource error for ${uri2}:`, error);
15553
+ console.error(`[MCP] ReadResource error for ${readUri.href}:`, error);
15551
15554
  throw error;
15552
15555
  }
15553
15556
  const sizeKB = (content.length / 1024).toFixed(1);
15554
15557
  console.log(
15555
- `[MCP] ReadResource: ${uri2} → ${sizeKB}KB${prodBuild ? " (prod build)" : " (vite)"}`
15558
+ `[MCP] ReadResource: ${readUri.href} → ${sizeKB}KB${prodBuild ? " (prod build)" : " (vite)"}`
15556
15559
  );
15557
15560
  return {
15558
15561
  contents: [
15559
15562
  {
15560
- uri: uri2,
15563
+ // Use readUri (not closure variable) so the response URI matches after updates
15564
+ uri: readUri.href,
15561
15565
  mimeType: EI,
15562
15566
  text: content,
15563
15567
  _meta: readMeta
@@ -15566,20 +15570,22 @@ function createAppServer(config, simulations, viteMode) {
15566
15570
  };
15567
15571
  }
15568
15572
  );
15573
+ resourceHandles.set(resourceName, handle);
15569
15574
  }
15570
- hk(
15575
+ const fullToolMeta = {
15576
+ ...toolMeta,
15577
+ ui: {
15578
+ resourceUri: uri2,
15579
+ // Preserve tool visibility from simulation metadata if declared
15580
+ ...toolMeta.ui?.visibility ? { visibility: toolMeta.ui.visibility } : {}
15581
+ }
15582
+ };
15583
+ const toolHandle = hk(
15571
15584
  mcpServer,
15572
15585
  tool.name,
15573
15586
  {
15574
15587
  description: tool.description,
15575
- _meta: {
15576
- ...toolMeta,
15577
- ui: {
15578
- resourceUri: uri2,
15579
- // Preserve tool visibility from simulation metadata if declared
15580
- ...toolMeta.ui?.visibility ? { visibility: toolMeta.ui.visibility } : {}
15581
- }
15582
- }
15588
+ _meta: fullToolMeta
15583
15589
  },
15584
15590
  async (extra) => {
15585
15591
  const args = extra.request?.params?.arguments ?? {};
@@ -15600,12 +15606,13 @@ function createAppServer(config, simulations, viteMode) {
15600
15606
  };
15601
15607
  }
15602
15608
  );
15609
+ toolHandles.push({ handle: toolHandle, resourceName, toolMeta: fullToolMeta });
15603
15610
  }
15604
- const registeredUris = Array.from(registeredResources).join(", ");
15611
+ const registeredUris = Array.from(registeredUriSet).join(", ");
15605
15612
  console.log(
15606
15613
  `[MCP] Registered ${simulations.length} tool(s) and resource(s)${viteMode ? " (vite mode)" : ""}: ${registeredUris}`
15607
15614
  );
15608
- return mcpServer;
15615
+ return { server: mcpServer, resourceHandles, toolHandles };
15609
15616
  }
15610
15617
  const SESSION_IDLE_TIMEOUT_MS$1 = 5 * 60 * 1e3;
15611
15618
  function isLocalConnection(req) {
@@ -15624,10 +15631,8 @@ const cleanupInterval = setInterval(() => {
15624
15631
  const now = Date.now();
15625
15632
  for (const [id2, session] of sessions) {
15626
15633
  if (now - session.lastActivity > SESSION_IDLE_TIMEOUT_MS$1) {
15627
- sessions.delete(id2);
15628
- session.transport.close?.();
15629
- session.server.close();
15630
- console.log(`[MCP] Session expired: ${id2.substring(0, 8)}... (${sessions.size} active)`);
15634
+ console.log(`[MCP] Session expired: ${id2.substring(0, 8)}...`);
15635
+ void session.server.close();
15631
15636
  }
15632
15637
  }
15633
15638
  }, 6e4);
@@ -15674,11 +15679,18 @@ async function handleMcpRequest(req, res, config, simulations, viteMode) {
15674
15679
  }
15675
15680
  if (req.method === "POST") {
15676
15681
  const isLocal = isLocalConnection(req);
15677
- const server = createAppServer(config, simulations, viteMode);
15682
+ const { server, resourceHandles, toolHandles } = createAppServer(config, simulations, viteMode);
15678
15683
  const transport = new StreamableHTTPServerTransport({
15679
15684
  sessionIdGenerator: () => randomUUID(),
15680
15685
  onsessioninitialized: (id2) => {
15681
- sessions.set(id2, { server, transport, isLocal, lastActivity: Date.now() });
15686
+ sessions.set(id2, {
15687
+ server,
15688
+ transport,
15689
+ isLocal,
15690
+ lastActivity: Date.now(),
15691
+ resourceHandles,
15692
+ toolHandles
15693
+ });
15682
15694
  const origin = isLocal ? "local" : "tunnel";
15683
15695
  console.log(
15684
15696
  `[MCP] Session started: ${id2.substring(0, 8)}... (${origin}, ${sessions.size} active)`
@@ -15693,13 +15705,12 @@ async function handleMcpRequest(req, res, config, simulations, viteMode) {
15693
15705
  const id2 = transport.sessionId;
15694
15706
  console.error(`[MCP] Transport error${id2 ? ` (${id2.substring(0, 8)}...)` : ""}:`, error);
15695
15707
  };
15696
- transport.onclose = async () => {
15708
+ transport.onclose = () => {
15697
15709
  const id2 = transport.sessionId;
15698
15710
  if (id2 && sessions.has(id2)) {
15699
15711
  sessions.delete(id2);
15700
15712
  console.log(`[MCP] Session closed: ${id2.substring(0, 8)}... (${sessions.size} active)`);
15701
15713
  }
15702
- await server.close();
15703
15714
  };
15704
15715
  await server.connect(transport);
15705
15716
  await transport.handleRequest(req, res, parsedBody);
@@ -15794,16 +15805,24 @@ function runMCPServer(config) {
15794
15805
  process.on("SIGINT", () => void shutdown());
15795
15806
  return {
15796
15807
  invalidateResources() {
15797
- let notified = 0;
15808
+ if (sessions.size === 0) return;
15809
+ const timestamp = Date.now();
15798
15810
  for (const [, session] of sessions) {
15799
- if (!session.isLocal) {
15800
- session.server.sendResourceListChanged();
15801
- notified++;
15811
+ for (const [name, handle] of session.resourceHandles) {
15812
+ handle.update({ uri: `ui://${name}-${timestamp}` });
15813
+ }
15814
+ for (const { handle, resourceName, toolMeta } of session.toolHandles) {
15815
+ const newUri = `ui://${resourceName}-${timestamp}`;
15816
+ handle.update({
15817
+ _meta: {
15818
+ ...toolMeta,
15819
+ ui: { ...toolMeta.ui, resourceUri: newUri },
15820
+ "ui/resourceUri": newUri
15821
+ }
15822
+ });
15802
15823
  }
15803
15824
  }
15804
- if (notified > 0) {
15805
- console.log(`[MCP] Notified ${notified} session(s) of resource changes`);
15806
- }
15825
+ console.log(`[MCP] Cache-busted ${sessions.size} session(s) with timestamp ${timestamp}`);
15807
15826
  }
15808
15827
  };
15809
15828
  }
@@ -15914,10 +15933,8 @@ function createMcpHandler(config) {
15914
15933
  const now = Date.now();
15915
15934
  for (const [id2, session] of sessions2) {
15916
15935
  if (now - session.lastActivity > SESSION_IDLE_TIMEOUT_MS) {
15917
- sessions2.delete(id2);
15918
- session.transport.close?.();
15919
- session.server.close();
15920
- console.log(`[MCP] Session expired: ${id2.substring(0, 8)}... (${sessions2.size} active)`);
15936
+ console.log(`[MCP] Session expired: ${id2.substring(0, 8)}...`);
15937
+ void session.server.close();
15921
15938
  }
15922
15939
  }
15923
15940
  }, 6e4);
@@ -15995,13 +16012,12 @@ function createMcpHandler(config) {
15995
16012
  const id2 = transport.sessionId;
15996
16013
  console.error(`[MCP] Transport error${id2 ? ` (${id2.substring(0, 8)}...)` : ""}:`, error);
15997
16014
  };
15998
- transport.onclose = async () => {
16015
+ transport.onclose = () => {
15999
16016
  const id2 = transport.sessionId;
16000
16017
  if (id2 && sessions2.has(id2)) {
16001
16018
  sessions2.delete(id2);
16002
16019
  console.log(`[MCP] Session closed: ${id2.substring(0, 8)}... (${sessions2.size} active)`);
16003
16020
  }
16004
- await server.close();
16005
16021
  };
16006
16022
  await server.connect(transport);
16007
16023
  await transport.handleRequest(req, res, parsedBody);
@@ -16017,10 +16033,8 @@ function createHandler(config) {
16017
16033
  const now = Date.now();
16018
16034
  for (const [id2, session] of sessions2) {
16019
16035
  if (now - session.lastActivity > SESSION_IDLE_TIMEOUT_MS) {
16020
- sessions2.delete(id2);
16021
- session.transport.close?.();
16022
- session.server.close();
16023
- console.log(`[MCP] Session expired: ${id2.substring(0, 8)}... (${sessions2.size} active)`);
16036
+ console.log(`[MCP] Session expired: ${id2.substring(0, 8)}...`);
16037
+ void session.server.close();
16024
16038
  }
16025
16039
  }
16026
16040
  }, 6e4);
@@ -16075,12 +16089,11 @@ function createHandler(config) {
16075
16089
  transport.onerror = (error) => {
16076
16090
  console.error("[MCP] Transport error:", error);
16077
16091
  };
16078
- transport.onclose = async () => {
16092
+ transport.onclose = () => {
16079
16093
  const id2 = transport.sessionId;
16080
16094
  if (id2 && sessions2.has(id2)) {
16081
16095
  sessions2.delete(id2);
16082
16096
  }
16083
- await server.close();
16084
16097
  };
16085
16098
  await server.connect(transport);
16086
16099
  const response = await transport.handleRequest(req, { parsedBody, authInfo });