sunpeak 0.20.34 → 0.20.36

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 (43) hide show
  1. package/bin/commands/inspect.mjs +63 -10
  2. package/bin/commands/test-init.mjs +57 -44
  3. package/bin/lib/test/test-fixtures.d.mts +9 -1
  4. package/bin/lib/test/test-fixtures.mjs +25 -7
  5. package/dist/chatgpt/index.cjs +1 -1
  6. package/dist/chatgpt/index.js +1 -1
  7. package/dist/claude/index.cjs +1 -1
  8. package/dist/claude/index.js +1 -1
  9. package/dist/embed.css +1 -1
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/inspector/app-types.d.ts +6 -4
  13. package/dist/inspector/index.cjs +1 -1
  14. package/dist/inspector/index.cjs.map +1 -1
  15. package/dist/inspector/index.d.ts +1 -1
  16. package/dist/inspector/index.js +1 -1
  17. package/dist/inspector/index.js.map +1 -1
  18. package/dist/inspector/inspector.d.ts +10 -4
  19. package/dist/inspector/simple-sidebar.d.ts +20 -6
  20. package/dist/inspector/use-inspector-state.d.ts +10 -0
  21. package/dist/{inspector-CJA_uM9g.cjs → inspector-BNWla95w.cjs} +307 -149
  22. package/dist/{inspector-CJA_uM9g.cjs.map → inspector-BNWla95w.cjs.map} +1 -1
  23. package/dist/{inspector-mGvDvMCR.js → inspector-CiuT_2yA.js} +307 -149
  24. package/dist/{inspector-mGvDvMCR.js.map → inspector-CiuT_2yA.js.map} +1 -1
  25. package/dist/style.css +6 -24
  26. package/package.json +1 -1
  27. package/template/dist/albums/albums.html +1 -1
  28. package/template/dist/albums/albums.json +1 -1
  29. package/template/dist/carousel/carousel.html +1 -1
  30. package/template/dist/carousel/carousel.json +1 -1
  31. package/template/dist/map/map.html +1 -1
  32. package/template/dist/map/map.json +1 -1
  33. package/template/dist/review/review.html +1 -1
  34. package/template/dist/review/review.json +1 -1
  35. package/template/tests/e2e/visual.spec.ts +0 -8
  36. package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-chatgpt-darwin.png +0 -0
  37. package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-chatgpt-linux.png +0 -0
  38. package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-claude-darwin.png +0 -0
  39. package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-claude-linux.png +0 -0
  40. package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-chatgpt-darwin.png +0 -0
  41. package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-chatgpt-linux.png +0 -0
  42. package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-claude-darwin.png +0 -0
  43. package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-claude-linux.png +0 -0
@@ -1349,16 +1349,20 @@ async function getApiKeyStatus(provider) {
1349
1349
  };
1350
1350
  }
1351
1351
 
1352
- function toolResourceUri(tool) {
1353
- return tool?._meta?.ui?.resourceUri ?? tool?._meta?.['ui/resourceUri'];
1354
- }
1355
-
1356
1352
  function isToolVisibleToModel(tool) {
1357
1353
  const visibility = tool?._meta?.ui?.visibility ?? tool?._meta?.['ui/visibility'];
1358
1354
  if (visibility == null) return true;
1359
1355
  return Array.isArray(visibility) && visibility.includes('model');
1360
1356
  }
1361
1357
 
1358
+ function getModelCallableTools(tools) {
1359
+ return tools.filter((tool) => isToolVisibleToModel(tool));
1360
+ }
1361
+
1362
+ function toolRendersApp(tool) {
1363
+ return !!(tool?._meta?.ui?.resourceUri ?? tool?._meta?.['ui/resourceUri']);
1364
+ }
1365
+
1362
1366
  function sanitizeAiSdkSchema(schema) {
1363
1367
  const clean = { ...(schema || { type: 'object', properties: {} }) };
1364
1368
  delete clean.$schema;
@@ -1402,6 +1406,32 @@ async function createModelInstance(provider, modelId, apiKey) {
1402
1406
  return createAnthropic({ apiKey })(normalizedModelId);
1403
1407
  }
1404
1408
 
1409
+ const MODEL_VISIBLE_JSON_LIMIT_BYTES = 20000;
1410
+
1411
+ function formatJsonForModel(value) {
1412
+ const json = JSON.stringify(value);
1413
+ if (json.length <= MODEL_VISIBLE_JSON_LIMIT_BYTES) return json;
1414
+ return `${json.slice(0, MODEL_VISIBLE_JSON_LIMIT_BYTES)}...`;
1415
+ }
1416
+
1417
+ function normalizeModelAppContext(appContext) {
1418
+ if (!appContext || typeof appContext !== 'object') return undefined;
1419
+ const normalized = {};
1420
+ if (Array.isArray(appContext.content) && appContext.content.length > 0) {
1421
+ normalized.content = appContext.content;
1422
+ }
1423
+ if (appContext.structuredContent !== undefined) {
1424
+ normalized.structuredContent = appContext.structuredContent;
1425
+ }
1426
+ return Object.keys(normalized).length > 0 ? normalized : undefined;
1427
+ }
1428
+
1429
+ function formatSharedAppContextForModel(appContext) {
1430
+ const normalized = normalizeModelAppContext(appContext);
1431
+ if (!normalized) return '';
1432
+ return formatJsonForModel(normalized);
1433
+ }
1434
+
1405
1435
  function formatModelVisibleToolResult(tool, result) {
1406
1436
  const toolName = tool?.name || 'MCP tool';
1407
1437
  if (result?.isError) {
@@ -1412,7 +1442,19 @@ function formatModelVisibleToolResult(tool, result) {
1412
1442
  .trim();
1413
1443
  return text || `${toolName} returned an error.`;
1414
1444
  }
1415
- return `${toolName} completed. The MCP App is ready to render.`;
1445
+
1446
+ const visibleResult = {};
1447
+ if (Array.isArray(result?.content) && result.content.length > 0) {
1448
+ visibleResult.content = result.content;
1449
+ }
1450
+ if (result?.structuredContent !== undefined) {
1451
+ visibleResult.structuredContent = result.structuredContent;
1452
+ }
1453
+ return Object.keys(visibleResult).length > 0
1454
+ ? formatJsonForModel(visibleResult)
1455
+ : toolRendersApp(tool)
1456
+ ? `${toolName} completed. The MCP App is ready to render.`
1457
+ : `${toolName} completed.`;
1416
1458
  }
1417
1459
 
1418
1460
  async function executeModelChatToolCall({ client, name, arguments: args }) {
@@ -1424,7 +1466,7 @@ async function executeModelChatToolCall({ client, name, arguments: args }) {
1424
1466
  };
1425
1467
  }
1426
1468
 
1427
- async function runModelChat({ client, provider, modelId, messages, apiKey }) {
1469
+ async function runModelChat({ client, provider, modelId, messages, apiKey, appContext }) {
1428
1470
  assertModelProvider(provider);
1429
1471
  const { generateText, tool: aiTool, jsonSchema } = await import('ai');
1430
1472
  const model = await createModelInstance(provider, modelId, apiKey);
@@ -1432,9 +1474,7 @@ async function runModelChat({ client, provider, modelId, messages, apiKey }) {
1432
1474
  const capturedToolCalls = [];
1433
1475
  const tools = {};
1434
1476
 
1435
- for (const mcpTool of mcpTools.filter(
1436
- (tool) => !!toolResourceUri(tool) && isToolVisibleToModel(tool)
1437
- )) {
1477
+ for (const mcpTool of getModelCallableTools(mcpTools)) {
1438
1478
  tools[mcpTool.name] = aiTool({
1439
1479
  description: mcpTool.description || mcpTool.title || '',
1440
1480
  inputSchema: jsonSchema(sanitizeAiSdkSchema(mcpTool.inputSchema)),
@@ -1451,11 +1491,19 @@ async function runModelChat({ client, provider, modelId, messages, apiKey }) {
1451
1491
  });
1452
1492
  }
1453
1493
 
1494
+ const sharedAppContext = formatSharedAppContextForModel(appContext);
1495
+
1454
1496
  const result = await generateText({
1455
1497
  model,
1456
1498
  tools,
1457
- system:
1499
+ system: [
1458
1500
  'You are chatting inside the Sunpeak Inspector. When you call an MCP tool that renders an app, the host will render the app below your message. Do not repeat raw tool output, JSON, image URLs, markdown image lists, or full item inventories. Keep any narration brief and let the app carry the visual result.',
1501
+ sharedAppContext
1502
+ ? `Shared MCP App context from the currently rendered app, available for this turn:\n${sharedAppContext}`
1503
+ : '',
1504
+ ]
1505
+ .filter(Boolean)
1506
+ .join('\n\n'),
1459
1507
  messages: messages.map((message) => ({
1460
1508
  role: message.role,
1461
1509
  content: String(message.content ?? ''),
@@ -2485,6 +2533,7 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
2485
2533
  modelId: parsed.modelId,
2486
2534
  messages: safeMessages,
2487
2535
  apiKey,
2536
+ appContext: normalizeModelAppContext(parsed.appContext),
2488
2537
  })
2489
2538
  );
2490
2539
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -2623,9 +2672,13 @@ export const _securityTestExports = {
2623
2672
  isLoopbackRemoteAddress,
2624
2673
  isPrivateNetworkAddress,
2625
2674
  isToolVisibleToModel,
2675
+ getModelCallableTools,
2676
+ toolRendersApp,
2626
2677
  executeModelChatToolCall,
2627
2678
  formatModelVisibleToolResult,
2679
+ formatSharedAppContextForModel,
2628
2680
  normalizeApiKey,
2681
+ normalizeModelAppContext,
2629
2682
  normalizeModelId,
2630
2683
  quoteSecurityInteractiveArg,
2631
2684
  readRequestBody,
@@ -77,10 +77,7 @@ export async function testInit(args = [], deps = defaultDeps) {
77
77
 
78
78
  // Parse --server flag from CLI args
79
79
  const serverIdx = args.indexOf('--server');
80
- const cliServer =
81
- serverIdx !== -1 && args[serverIdx + 1]
82
- ? args[serverIdx + 1]
83
- : undefined;
80
+ const cliServer = serverIdx !== -1 && args[serverIdx + 1] ? args[serverIdx + 1] : undefined;
84
81
 
85
82
  const projectType = detectProjectType(d);
86
83
  const interactive = d.isTTY();
@@ -119,7 +116,10 @@ export async function testInit(args = [], deps = defaultDeps) {
119
116
  for (const prov of providers) {
120
117
  for (const model of prov.models) {
121
118
  config = config.replace(
122
- new RegExp(`^(\\s*)// ('${model.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}',?.*)$`, 'm'),
119
+ new RegExp(
120
+ `^(\\s*)// ('${model.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}',?.*)$`,
121
+ 'm'
122
+ ),
123
123
  '$1$2'
124
124
  );
125
125
  }
@@ -139,12 +139,16 @@ export async function testInit(args = [], deps = defaultDeps) {
139
139
  });
140
140
  if (!d.isCancel(key) && key) {
141
141
  // Strip newlines so a pasted value can't inject extra .env entries.
142
- const cleanKey = String(key).replace(/[\r\n]+/g, '').trim();
142
+ const cleanKey = String(key)
143
+ .replace(/[\r\n]+/g, '')
144
+ .trim();
143
145
  if (cleanKey) envLines.push(`${prov.envVar}=${cleanKey}`);
144
146
  }
145
147
  }
146
148
  if (envLines.length > 0 && evalDir) {
147
- const relEnvPath = evalDir.startsWith(d.cwd()) ? evalDir.slice(d.cwd().length + 1) : evalDir;
149
+ const relEnvPath = evalDir.startsWith(d.cwd())
150
+ ? evalDir.slice(d.cwd().length + 1)
151
+ : evalDir;
148
152
  d.writeFileSync(join(evalDir, '.env'), envLines.join('\n') + '\n');
149
153
  d.log.info(`API keys saved to ${relEnvPath}/.env (gitignored)`);
150
154
  }
@@ -165,7 +169,9 @@ export async function testInit(args = [], deps = defaultDeps) {
165
169
  stdio: 'inherit',
166
170
  });
167
171
  } catch {
168
- d.log.info(`Skill install skipped. Install later: ${dlx} skills add Sunpeak-AI/sunpeak@test-mcp-server`);
172
+ d.log.info(
173
+ `Skill install skipped. Install later: ${dlx} skills add Sunpeak-AI/sunpeak@test-mcp-server`
174
+ );
169
175
  }
170
176
  }
171
177
  }
@@ -303,9 +309,10 @@ function scaffoldEvals(evalsDir, { server, isSunpeak, d: deps } = {}) {
303
309
  d.mkdirSync(evalsDir, { recursive: true });
304
310
 
305
311
  // Generate server line for eval config
306
- let serverLine = ' // server: \'http://localhost:8000/mcp\',';
312
+ let serverLine = " // server: 'http://localhost:8000/mcp',";
307
313
  if (isSunpeak) {
308
- serverLine = ' // Omit server for sunpeak projects (auto-detected).\n // server: \'http://localhost:8000/mcp\',';
314
+ serverLine =
315
+ " // Omit server for sunpeak projects (auto-detected).\n // server: 'http://localhost:8000/mcp',";
309
316
  } else if (server?.type === 'url') {
310
317
  serverLine = ` server: ${JSON.stringify(server.value)},`;
311
318
  } else if (server?.type === 'command') {
@@ -315,27 +322,27 @@ function scaffoldEvals(evalsDir, { server, isSunpeak, d: deps } = {}) {
315
322
  // Build the eval config content
316
323
  const configLines = [
317
324
  "import { defineEvalConfig } from 'sunpeak/eval';",
318
- "",
319
- "// API keys are loaded automatically from .env in this directory (gitignored).",
320
- "// See .env.example for the format.",
321
- "",
322
- "export default defineEvalConfig({",
323
- " // MCP server to test.",
325
+ '',
326
+ '// API keys are loaded automatically from .env in this directory (gitignored).',
327
+ '// See .env.example for the format.',
328
+ '',
329
+ 'export default defineEvalConfig({',
330
+ ' // MCP server to test.',
324
331
  serverLine,
325
- "",
326
- " models: [",
327
- " // Uncomment models and install their provider packages:",
332
+ '',
333
+ ' models: [',
334
+ ' // Uncomment models and install their provider packages:',
328
335
  ...generateModelLines(),
329
- " ],",
330
- "",
331
- " defaults: {",
332
- " runs: 5, // Number of times to run each case per model",
333
- " maxSteps: 1, // Max tool call steps per run",
334
- " temperature: 0, // 0 for most deterministic results",
335
- " timeout: 30_000, // Timeout per run in ms",
336
- " },",
337
- "});",
338
- "",
336
+ ' ],',
337
+ '',
338
+ ' defaults: {',
339
+ ' runs: 5, // Number of times to run each case per model',
340
+ ' maxSteps: 1, // Max tool call steps per run',
341
+ ' temperature: 0, // 0 for most deterministic results',
342
+ ' timeout: 30_000, // Timeout per run in ms',
343
+ ' },',
344
+ '});',
345
+ '',
339
346
  ];
340
347
 
341
348
  d.writeFileSync(join(evalsDir, 'eval.config.ts'), configLines.join('\n'));
@@ -437,13 +444,8 @@ function scaffoldVisualTest(filePath, d) {
437
444
  // // await result.screenshot('tool-dark');
438
445
  // });
439
446
 
440
- // Full-page screenshot (captures the inspector chrome too):
441
- // test('full page renders correctly', async ({ inspector }) => {
442
- // const result = await inspector.renderTool('your-tool', {}, { theme: 'light' });
443
- // const app = result.app();
444
- // await expect(app.getByText('Expected text')).toBeVisible();
445
- // await result.screenshot('tool-page', { target: 'page', maxDiffPixelRatio: 0.02 });
446
- // });
447
+ // renderTool() hides inspector sidebars by default, and screenshot() captures only
448
+ // the MCP App iframe area, so inspector UI changes do not break your visual baselines.
447
449
  `
448
450
  );
449
451
  d.log.success(`Created ${filePath}`);
@@ -485,9 +487,10 @@ function scaffoldLiveTests(liveDir, { isSunpeak, server, d } = {}) {
485
487
  const parts = server.value.split(/\s+/);
486
488
  const cmd = parts[0];
487
489
  const args = parts.slice(1);
488
- serverOption = args.length > 0
489
- ? `\n server: { command: ${JSON.stringify(cmd)}, args: [${args.map(a => JSON.stringify(a)).join(', ')}] },`
490
- : `\n server: { command: ${JSON.stringify(cmd)} },`;
490
+ serverOption =
491
+ args.length > 0
492
+ ? `\n server: { command: ${JSON.stringify(cmd)}, args: [${args.map((a) => JSON.stringify(a)).join(', ')}] },`
493
+ : `\n server: { command: ${JSON.stringify(cmd)} },`;
491
494
  }
492
495
 
493
496
  const configContent = `${liveConfigPreamble}
@@ -637,7 +640,9 @@ test('server exposes tools', async ({ mcp }) => {
637
640
 
638
641
  d.log.success('Created tests/sunpeak/ with all test types.');
639
642
  if (server.type === 'later') {
640
- d.log.warn('Server not configured. Edit tests/sunpeak/playwright.config.ts before running tests.');
643
+ d.log.warn(
644
+ 'Server not configured. Edit tests/sunpeak/playwright.config.ts before running tests.'
645
+ );
641
646
  }
642
647
 
643
648
  // Auto-install dependencies so users can run tests immediately
@@ -653,14 +658,22 @@ test('server exposes tools', async ({ mcp }) => {
653
658
  try {
654
659
  d.execSync(`${pm} exec playwright install chromium`, { cwd: testDir, stdio: 'inherit' });
655
660
  } catch {
656
- d.log.warn(`Browser install failed. Run manually: cd tests/sunpeak && ${pm} exec playwright install chromium`);
661
+ d.log.warn(
662
+ `Browser install failed. Run manually: cd tests/sunpeak && ${pm} exec playwright install chromium`
663
+ );
657
664
  }
658
665
 
659
666
  d.log.step('Ready! Run tests with:');
660
667
  d.log.message(' npx sunpeak test # E2E tests');
661
- d.log.message(' npx sunpeak test --visual # Visual regression (generates baselines on first run)');
662
- d.log.message(' npx sunpeak test --live # Live tests against real hosts (requires login)');
663
- d.log.message(' npx sunpeak test --eval # Multi-model evals (configure models in evals/eval.config.ts)');
668
+ d.log.message(
669
+ ' npx sunpeak test --visual # Visual regression (generates baselines on first run)'
670
+ );
671
+ d.log.message(
672
+ ' npx sunpeak test --live # Live tests against real hosts (requires login)'
673
+ );
674
+ d.log.message(
675
+ ' npx sunpeak test --eval # Multi-model evals (configure models in evals/eval.config.ts)'
676
+ );
664
677
  }
665
678
 
666
679
  async function initJsProject(cliServer, d) {
@@ -37,12 +37,20 @@ export interface CallToolResult {
37
37
  export interface RenderToolOptions {
38
38
  theme?: 'light' | 'dark';
39
39
  displayMode?: 'inline' | 'pip' | 'fullscreen';
40
+ /**
41
+ * Show inspector sidebars while rendering the tool.
42
+ * Defaults to false so e2e and visual tests are isolated from inspector UI layout changes.
43
+ */
44
+ sidebar?: boolean;
40
45
  timeout?: number;
41
46
  [key: string]: unknown;
42
47
  }
43
48
 
44
49
  export interface ScreenshotOptions extends PageAssertionsToHaveScreenshotOptions {
45
- /** What to screenshot: 'app' (inner iframe content) or 'page' (full inspector). Default: 'app'. */
50
+ /**
51
+ * Screenshot target. Visual snapshots capture the app iframe area by default.
52
+ * @deprecated `target: 'page'` is ignored so inspector UI changes do not break app baselines.
53
+ */
46
54
  target?: 'app' | 'page';
47
55
  /** Specific locator to screenshot instead of the default target. */
48
56
  element?: Locator;
@@ -44,6 +44,13 @@ function buildInspectorUrl(params) {
44
44
  return qs ? `/?${qs}` : '/';
45
45
  }
46
46
 
47
+ function withDefaultRenderParams(params) {
48
+ return {
49
+ ...params,
50
+ sidebar: params.sidebar == null ? 'false' : params.sidebar,
51
+ };
52
+ }
53
+
47
54
  function resolveHostId(projectName) {
48
55
  if (!projectName) return 'chatgpt';
49
56
  if (projectName.startsWith('chatgpt')) return 'chatgpt';
@@ -83,7 +90,10 @@ async function readToolResult(page, timeout) {
83
90
  }
84
91
  });
85
92
  observer.observe(el, { childList: true, characterData: true, subtree: true });
86
- timer = setTimeout(() => { observer.disconnect(); resolve(null); }, t);
93
+ timer = setTimeout(() => {
94
+ observer.disconnect();
95
+ resolve(null);
96
+ }, t);
87
97
  };
88
98
  check();
89
99
  }),
@@ -135,13 +145,17 @@ function createInspectorResult(page, resultData) {
135
145
  name = undefined;
136
146
  }
137
147
 
138
- const { target = 'app', element, ...playwrightOptions } = options;
148
+ const { target, element, ...playwrightOptions } = options;
139
149
  let locator;
140
150
  if (element) {
141
151
  locator = element;
142
- } else if (target === 'page') {
143
- locator = page.locator('#root');
144
152
  } else {
153
+ if (target && target !== 'app') {
154
+ console.warn(
155
+ `[sunpeak] result.screenshot({ target: "${target}" }) is deprecated. ` +
156
+ 'Visual snapshots always capture the app iframe area so inspector UI changes do not break user baselines.'
157
+ );
158
+ }
145
159
  locator = page.frameLocator('iframe').frameLocator('iframe').locator('body');
146
160
  }
147
161
  const fullName = name && !name.endsWith('.png') ? `${name}.png` : name;
@@ -171,7 +185,9 @@ const test = base.extend({
171
185
  data: { name, arguments: input || {} },
172
186
  });
173
187
  if (!response.ok()) {
174
- throw new Error(`callTool(${name}) returned ${response.status()}: ${await response.text()}`);
188
+ throw new Error(
189
+ `callTool(${name}) returned ${response.status()}: ${await response.text()}`
190
+ );
175
191
  }
176
192
  return response.json();
177
193
  },
@@ -187,7 +203,9 @@ const test = base.extend({
187
203
  `${baseURL}/__sunpeak/read-resource?uri=${encodeURIComponent(uri)}`
188
204
  );
189
205
  if (!response.ok()) {
190
- throw new Error(`readResource(${uri}) returned ${response.status()}: ${await response.text()}`);
206
+ throw new Error(
207
+ `readResource(${uri}) returned ${response.status()}: ${await response.text()}`
208
+ );
191
209
  }
192
210
  return response.text();
193
211
  },
@@ -237,7 +255,7 @@ const test = base.extend({
237
255
  ...rest,
238
256
  };
239
257
 
240
- await page.goto(buildInspectorUrl(params));
258
+ await page.goto(buildInspectorUrl(withDefaultRenderParams(params)));
241
259
 
242
260
  const resolvedTimeout = callTimeout ?? testInfo.project.use?.mcpTimeout ?? 15_000;
243
261
  try {
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../chunk-Cek0wNdY.cjs");
3
- const require_inspector = require("../inspector-CJA_uM9g.cjs");
3
+ const require_inspector = require("../inspector-BNWla95w.cjs");
4
4
  const require_inspector_url = require("../inspector-url-BxScdDag.cjs");
5
5
  const require_discovery = require("../discovery-31_n0zcu.cjs");
6
6
  //#region src/chatgpt/index.ts
@@ -1,5 +1,5 @@
1
1
  import { Ct as __exportAll } from "../protocol-bhrz2H_E.js";
2
- import { _ as extractResourceCSP, f as ThemeProvider, g as IframeResource, p as useThemeContext, r as resolveServerToolResult, t as Inspector, v as McpAppHost, y as SCREEN_WIDTHS } from "../inspector-mGvDvMCR.js";
2
+ import { _ as extractResourceCSP, f as ThemeProvider, g as IframeResource, p as useThemeContext, r as resolveServerToolResult, t as Inspector, v as McpAppHost, y as SCREEN_WIDTHS } from "../inspector-CiuT_2yA.js";
3
3
  import { t as createInspectorUrl } from "../inspector-url-xUMGbWis.js";
4
4
  import { c as toPascalCase, i as findResourceKey, n as extractSimulationKey, r as findResourceDirs, s as getComponentName, t as extractResourceKey } from "../discovery-DOVner--.js";
5
5
  //#region src/chatgpt/index.ts
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../chunk-Cek0wNdY.cjs");
3
- const require_inspector = require("../inspector-CJA_uM9g.cjs");
3
+ const require_inspector = require("../inspector-BNWla95w.cjs");
4
4
  exports.Inspector = require_inspector.Inspector;
@@ -1,2 +1,2 @@
1
- import { t as Inspector } from "../inspector-mGvDvMCR.js";
1
+ import { t as Inspector } from "../inspector-CiuT_2yA.js";
2
2
  export { Inspector };