sunpeak 0.20.51 → 0.20.53
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/bin/commands/inspect.mjs +79 -10
- package/dist/chatgpt/index.cjs +1 -1
- package/dist/chatgpt/index.js +1 -1
- package/dist/claude/index.cjs +1 -1
- package/dist/claude/index.js +1 -1
- package/dist/host/chatgpt/index.cjs +1 -1
- package/dist/host/chatgpt/index.js +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/inspector/index.cjs +1 -1
- package/dist/inspector/index.js +1 -1
- package/dist/{inspector-WPF8mKwk.cjs → inspector-BtYInER9.cjs} +2 -2
- package/dist/{inspector-WPF8mKwk.cjs.map → inspector-BtYInER9.cjs.map} +1 -1
- package/dist/{inspector-DQyl36w3.js → inspector-CEmRtVwc.js} +2 -2
- package/dist/{inspector-DQyl36w3.js.map → inspector-CEmRtVwc.js.map} +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/{use-app-DzgUHmdH.cjs → use-app-DrKg-OJp.cjs} +2 -2
- package/dist/{use-app-DzgUHmdH.cjs.map → use-app-DrKg-OJp.cjs.map} +1 -1
- package/dist/{use-app-j3as_y6c.js → use-app-nZXXvUxc.js} +2 -2
- package/dist/{use-app-j3as_y6c.js.map → use-app-nZXXvUxc.js.map} +1 -1
- package/package.json +2 -2
- package/template/dist/albums/albums.json +1 -1
- package/template/dist/carousel/carousel.json +1 -1
- package/template/dist/map/map.json +1 -1
- package/template/dist/review/review.json +1 -1
- package/template/node_modules/.vite/deps/_metadata.json +3 -3
- package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js +1 -1
- package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js.map +1 -1
- package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js +1 -1
- package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js.map +1 -1
- package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js +1 -1
- package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js.map +1 -1
- package/template/node_modules/.vite-mcp/deps/_metadata.json +22 -22
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-dark-chatgpt-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-dark-claude-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-chatgpt-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-claude-darwin.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-claude-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-light-chatgpt-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-light-claude-linux.png +0 -0
package/bin/commands/inspect.mjs
CHANGED
|
@@ -19,6 +19,7 @@ const { existsSync, readdirSync, readFileSync } = fs;
|
|
|
19
19
|
const { join, resolve, dirname, sep } = path;
|
|
20
20
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
21
21
|
import { execFile, spawn } from 'node:child_process';
|
|
22
|
+
import { randomBytes } from 'node:crypto';
|
|
22
23
|
import { lookup as dnsLookup } from 'node:dns/promises';
|
|
23
24
|
import { createServer as createHttpServer } from 'http';
|
|
24
25
|
import { isIP } from 'node:net';
|
|
@@ -971,6 +972,42 @@ async function discoverSimulations(client) {
|
|
|
971
972
|
return simulations;
|
|
972
973
|
}
|
|
973
974
|
|
|
975
|
+
function createInspectorRequestToken() {
|
|
976
|
+
return randomBytes(32).toString('base64url');
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
function appendInspectorRequestToken(resourceUrl, requestToken) {
|
|
980
|
+
if (!resourceUrl || !requestToken) return resourceUrl;
|
|
981
|
+
try {
|
|
982
|
+
const parsed = new URL(resourceUrl, 'http://sunpeak.local');
|
|
983
|
+
parsed.searchParams.set('__sunpeak_token', requestToken);
|
|
984
|
+
if (resourceUrl.startsWith('http://') || resourceUrl.startsWith('https://')) {
|
|
985
|
+
return parsed.toString();
|
|
986
|
+
}
|
|
987
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
988
|
+
} catch {
|
|
989
|
+
return resourceUrl;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
function addInspectorRequestTokenToSimulations(simulations, requestToken) {
|
|
994
|
+
if (!requestToken || !simulations || typeof simulations !== 'object') return simulations;
|
|
995
|
+
return Object.fromEntries(
|
|
996
|
+
Object.entries(simulations).map(([name, sim]) => {
|
|
997
|
+
if (!sim || typeof sim !== 'object' || typeof sim.resourceUrl !== 'string') {
|
|
998
|
+
return [name, sim];
|
|
999
|
+
}
|
|
1000
|
+
return [
|
|
1001
|
+
name,
|
|
1002
|
+
{
|
|
1003
|
+
...sim,
|
|
1004
|
+
resourceUrl: appendInspectorRequestToken(sim.resourceUrl, requestToken),
|
|
1005
|
+
},
|
|
1006
|
+
];
|
|
1007
|
+
})
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
974
1011
|
/**
|
|
975
1012
|
* Load simulation JSON fixtures from a directory and merge into discovered simulations.
|
|
976
1013
|
*
|
|
@@ -1810,6 +1847,7 @@ async function runModelChat({
|
|
|
1810
1847
|
* @param {string} appName - Display name
|
|
1811
1848
|
* @param {string|null} appIcon - Icon URL or emoji
|
|
1812
1849
|
* @param {string} sandboxUrl - Sandbox server URL
|
|
1850
|
+
* @param {string} requestToken - Unguessable token for frameable inspector resource URLs
|
|
1813
1851
|
* @param {{ defaultProdResources?: boolean, hideInspectorModes?: boolean }} [modeFlags] - Mode toggles
|
|
1814
1852
|
*/
|
|
1815
1853
|
function sunpeakInspectVirtualPlugin(
|
|
@@ -1818,6 +1856,7 @@ function sunpeakInspectVirtualPlugin(
|
|
|
1818
1856
|
appName,
|
|
1819
1857
|
appIcon,
|
|
1820
1858
|
sandboxUrl,
|
|
1859
|
+
requestToken,
|
|
1821
1860
|
modeFlags = {}
|
|
1822
1861
|
) {
|
|
1823
1862
|
const ENTRY_ID = 'virtual:sunpeak-inspect-entry';
|
|
@@ -1837,7 +1876,7 @@ import { createRoot } from 'react-dom/client';
|
|
|
1837
1876
|
import { Inspector } from 'sunpeak/inspector';
|
|
1838
1877
|
import 'sunpeak/style.css';
|
|
1839
1878
|
|
|
1840
|
-
const simulations = ${JSON.stringify(simulations)};
|
|
1879
|
+
const simulations = ${JSON.stringify(addInspectorRequestTokenToSimulations(simulations, requestToken))};
|
|
1841
1880
|
const appName = ${JSON.stringify(appName ?? 'MCP Inspector')};
|
|
1842
1881
|
const appIcon = ${JSON.stringify(appIcon ?? null)};
|
|
1843
1882
|
const sandboxUrl = ${JSON.stringify(sandboxUrl)};
|
|
@@ -1897,7 +1936,7 @@ root.render(
|
|
|
1897
1936
|
* Vite plugin for MCP server proxy endpoints.
|
|
1898
1937
|
* @param {() => import('@modelcontextprotocol/sdk/client/index.js').Client} getClient
|
|
1899
1938
|
* @param {(client: import('@modelcontextprotocol/sdk/client/index.js').Client) => void} setClient
|
|
1900
|
-
* @param {{ callToolDirect?: (name: string, args: Record<string, unknown>) => Promise<object>, simulationsDir?: string | null, serverUrl?: string, liveServerUrl?: string }} [pluginOpts]
|
|
1939
|
+
* @param {{ callToolDirect?: (name: string, args: Record<string, unknown>) => Promise<object>, simulationsDir?: string | null, serverUrl?: string, liveServerUrl?: string, requestToken?: string }} [pluginOpts]
|
|
1901
1940
|
*/
|
|
1902
1941
|
function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
1903
1942
|
// Server URL and options for automatic session recovery.
|
|
@@ -1941,6 +1980,34 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
|
1941
1980
|
if (pluginOpts.liveServerUrl) _liveServerUrl = pluginOpts.liveServerUrl;
|
|
1942
1981
|
if (pluginOpts.connectionOpts) _connectionOpts = pluginOpts.connectionOpts;
|
|
1943
1982
|
|
|
1983
|
+
function sendTokenedSimulations(res, payload) {
|
|
1984
|
+
const body = {
|
|
1985
|
+
...payload,
|
|
1986
|
+
...(payload.simulations
|
|
1987
|
+
? {
|
|
1988
|
+
simulations: addInspectorRequestTokenToSimulations(
|
|
1989
|
+
payload.simulations,
|
|
1990
|
+
pluginOpts.requestToken
|
|
1991
|
+
),
|
|
1992
|
+
}
|
|
1993
|
+
: {}),
|
|
1994
|
+
};
|
|
1995
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1996
|
+
res.end(JSON.stringify(body));
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
function requireInspectorRequestToken(req, res) {
|
|
2000
|
+
if (!pluginOpts.requestToken) return true;
|
|
2001
|
+
const fetchSiteHeader = req.headers['sec-fetch-site'];
|
|
2002
|
+
const fetchSite = Array.isArray(fetchSiteHeader) ? fetchSiteHeader[0] : fetchSiteHeader;
|
|
2003
|
+
if (fetchSite !== 'cross-site') return true;
|
|
2004
|
+
const url = new URL(req.url, 'http://localhost');
|
|
2005
|
+
if (url.searchParams.get('__sunpeak_token') === pluginOpts.requestToken) return true;
|
|
2006
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
2007
|
+
res.end('Forbidden: missing or invalid inspector request token');
|
|
2008
|
+
return false;
|
|
2009
|
+
}
|
|
2010
|
+
|
|
1944
2011
|
async function withModelChatClient(callback) {
|
|
1945
2012
|
const targetUrl = _liveServerUrl || _serverUrl;
|
|
1946
2013
|
if (!targetUrl?.startsWith('http://') && !targetUrl?.startsWith('https://')) {
|
|
@@ -2333,8 +2400,7 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
|
2333
2400
|
if (pluginOpts.simulationsDir) {
|
|
2334
2401
|
mergeSimulationFixtures(pluginOpts.simulationsDir, simulations);
|
|
2335
2402
|
}
|
|
2336
|
-
res
|
|
2337
|
-
res.end(JSON.stringify({ status: 'ok', simulations }));
|
|
2403
|
+
sendTokenedSimulations(res, { status: 'ok', simulations });
|
|
2338
2404
|
} catch (err) {
|
|
2339
2405
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2340
2406
|
res.end(JSON.stringify({ error: err.message }));
|
|
@@ -2432,8 +2498,7 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
|
2432
2498
|
if (pluginOpts.simulationsDir) {
|
|
2433
2499
|
mergeSimulationFixtures(pluginOpts.simulationsDir, simulations);
|
|
2434
2500
|
}
|
|
2435
|
-
res
|
|
2436
|
-
res.end(JSON.stringify({ status: 'authorized', simulations }));
|
|
2501
|
+
sendTokenedSimulations(res, { status: 'authorized', simulations });
|
|
2437
2502
|
return;
|
|
2438
2503
|
} catch {
|
|
2439
2504
|
// Tokens may be expired, fall through to fresh auth below
|
|
@@ -2512,8 +2577,7 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
|
2512
2577
|
if (pluginOpts.simulationsDir) {
|
|
2513
2578
|
mergeSimulationFixtures(pluginOpts.simulationsDir, simulations);
|
|
2514
2579
|
}
|
|
2515
|
-
res
|
|
2516
|
-
res.end(JSON.stringify({ status: 'authorized', simulations }));
|
|
2580
|
+
sendTokenedSimulations(res, { status: 'authorized', simulations });
|
|
2517
2581
|
}
|
|
2518
2582
|
} catch (err) {
|
|
2519
2583
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
@@ -2700,8 +2764,7 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
|
2700
2764
|
mergeSimulationFixtures(pluginOpts.simulationsDir, simulations);
|
|
2701
2765
|
}
|
|
2702
2766
|
|
|
2703
|
-
res
|
|
2704
|
-
res.end(JSON.stringify({ status: 'ok', simulations }));
|
|
2767
|
+
sendTokenedSimulations(res, { status: 'ok', simulations });
|
|
2705
2768
|
} catch (err) {
|
|
2706
2769
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
2707
2770
|
res.end(JSON.stringify({ error: err.message }));
|
|
@@ -2826,6 +2889,7 @@ function sunpeakInspectEndpointsPlugin(getClient, setClient, pluginOpts = {}) {
|
|
|
2826
2889
|
// Read resource from connected server
|
|
2827
2890
|
server.middlewares.use('/__sunpeak/read-resource', async (req, res) => {
|
|
2828
2891
|
if (!requireSameOrigin(req, res, { allowCrossSiteIframeNavigation: true })) return;
|
|
2892
|
+
if (!requireInspectorRequestToken(req, res)) return;
|
|
2829
2893
|
const url = new URL(req.url, 'http://localhost');
|
|
2830
2894
|
const uri = url.searchParams.get('uri');
|
|
2831
2895
|
if (!uri) {
|
|
@@ -2956,6 +3020,8 @@ export const _securityTestExports = {
|
|
|
2956
3020
|
executeModelChatToolCall,
|
|
2957
3021
|
formatModelVisibleToolResult,
|
|
2958
3022
|
formatSharedAppContextForModel,
|
|
3023
|
+
addInspectorRequestTokenToSimulations,
|
|
3024
|
+
appendInspectorRequestToken,
|
|
2959
3025
|
normalizeApiKey,
|
|
2960
3026
|
normalizeModelChatMessages,
|
|
2961
3027
|
normalizeModelAppContext,
|
|
@@ -3210,6 +3276,7 @@ export async function inspectServer(opts) {
|
|
|
3210
3276
|
const inspectorServerUrl = resolvedServerUrl;
|
|
3211
3277
|
const liveInspectorServerUrl =
|
|
3212
3278
|
liveServerArg ?? defaultLiveMcpServerUrl(resolvedServerUrl) ?? resolvedServerUrl;
|
|
3279
|
+
const inspectorRequestToken = createInspectorRequestToken();
|
|
3213
3280
|
|
|
3214
3281
|
// Create the Vite server.
|
|
3215
3282
|
// Use the sunpeak package dir as root to avoid scanning the user's project
|
|
@@ -3268,6 +3335,7 @@ export async function inspectServer(opts) {
|
|
|
3268
3335
|
serverAppName,
|
|
3269
3336
|
serverAppIcon,
|
|
3270
3337
|
sandbox.url,
|
|
3338
|
+
inspectorRequestToken,
|
|
3271
3339
|
{ defaultProdResources, hideInspectorModes: !frameworkMode }
|
|
3272
3340
|
),
|
|
3273
3341
|
sunpeakInspectEndpointsPlugin(
|
|
@@ -3280,6 +3348,7 @@ export async function inspectServer(opts) {
|
|
|
3280
3348
|
simulationsDir,
|
|
3281
3349
|
serverUrl: resolvedServerUrl,
|
|
3282
3350
|
liveServerUrl: liveInspectorServerUrl,
|
|
3351
|
+
requestToken: inspectorRequestToken,
|
|
3283
3352
|
connectionOpts,
|
|
3284
3353
|
}
|
|
3285
3354
|
),
|
package/dist/chatgpt/index.cjs
CHANGED
|
@@ -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-
|
|
3
|
+
const require_inspector = require("../inspector-BtYInER9.cjs");
|
|
4
4
|
const require_inspector_url = require("../inspector-url-C0I97f8-.cjs");
|
|
5
5
|
const require_discovery = require("../discovery-31_n0zcu.cjs");
|
|
6
6
|
//#region src/chatgpt/index.ts
|
package/dist/chatgpt/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Ct as __exportAll } from "../protocol-Cw9Op_hM.js";
|
|
2
|
-
import { C as McpAppHost, S as extractResourceCSP, f as ThemeProvider, p as useThemeContext, r as resolveServerToolResult, t as Inspector, w as SCREEN_WIDTHS, x as IframeResource } from "../inspector-
|
|
2
|
+
import { C as McpAppHost, S as extractResourceCSP, f as ThemeProvider, p as useThemeContext, r as resolveServerToolResult, t as Inspector, w as SCREEN_WIDTHS, x as IframeResource } from "../inspector-CEmRtVwc.js";
|
|
3
3
|
import { t as createInspectorUrl } from "../inspector-url-vtW8g8yB.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
|
package/dist/claude/index.cjs
CHANGED
|
@@ -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-
|
|
3
|
+
const require_inspector = require("../inspector-BtYInER9.cjs");
|
|
4
4
|
exports.Inspector = require_inspector.Inspector;
|
package/dist/claude/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as Inspector } from "../inspector-
|
|
1
|
+
import { t as Inspector } from "../inspector-CEmRtVwc.js";
|
|
2
2
|
export { Inspector };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.cjs");
|
|
3
|
-
const require_use_app = require("../../use-app-
|
|
3
|
+
const require_use_app = require("../../use-app-DrKg-OJp.cjs");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
//#region src/host/chatgpt/openai-types.ts
|
|
6
6
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.cjs");
|
|
3
3
|
const require_protocol = require("./protocol-BDytMFPA.cjs");
|
|
4
|
-
const require_use_app = require("./use-app-
|
|
5
|
-
const require_inspector = require("./inspector-
|
|
4
|
+
const require_use_app = require("./use-app-DrKg-OJp.cjs");
|
|
5
|
+
const require_inspector = require("./inspector-BtYInER9.cjs");
|
|
6
6
|
const require_host_index = require("./host/index.cjs");
|
|
7
7
|
const require_inspector_index = require("./inspector/index.cjs");
|
|
8
8
|
const require_chatgpt_index = require("./chatgpt/index.cjs");
|
|
9
9
|
let react = require("react");
|
|
10
10
|
react = require_chunk.__toESM(react, 1);
|
|
11
11
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
12
|
-
//#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.7.
|
|
12
|
+
//#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.7.4_@modelcontextprotocol+sdk@1.29.0_zod@4.4.3__react-_bc4d5adeaec14d46b9a46bfff8177b13/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.js
|
|
13
13
|
((K) => typeof require < "u" ? require : typeof Proxy < "u" ? new Proxy(K, { get: (Q, X) => (typeof require < "u" ? require : Q)[X] }) : K)(function(K) {
|
|
14
14
|
if (typeof require < "u") return require.apply(this, arguments);
|
|
15
15
|
throw Error("Dynamic require of \"" + K + "\" is not supported");
|