sunpeak 0.17.4 → 0.17.6
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/dev.mjs +4 -3
- package/bin/commands/inspect.mjs +58 -33
- package/dist/chatgpt/globals.css +5 -0
- package/dist/chatgpt/index.cjs +2 -2
- package/dist/chatgpt/index.js +2 -2
- package/dist/claude/index.cjs +1 -1
- package/dist/claude/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +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/mcp/types.d.ts +7 -0
- package/dist/simulator/index.cjs +2 -2
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.js +2 -2
- package/dist/simulator/index.js.map +1 -1
- package/dist/simulator/simulator-url.d.ts +32 -41
- package/dist/simulator/simulator.d.ts +14 -10
- package/dist/simulator/use-mcp-connection.d.ts +12 -7
- package/dist/simulator/use-simulator-state.d.ts +1 -1
- package/dist/{simulator-Dl8B-Ljb.js → simulator-BijjlOXb.js} +278 -143
- package/dist/simulator-BijjlOXb.js.map +1 -0
- package/dist/{simulator-CH9hs0N6.cjs → simulator-DqWETA_1.cjs} +278 -143
- package/dist/simulator-DqWETA_1.cjs.map +1 -0
- package/dist/{simulator-url-CozKF1jf.cjs → simulator-url-3ATCsPOT.cjs} +11 -30
- package/dist/simulator-url-3ATCsPOT.cjs.map +1 -0
- package/dist/{simulator-url-KoS_ToP6.js → simulator-url-BbuuWa7S.js} +11 -30
- package/dist/simulator-url-BbuuWa7S.js.map +1 -0
- package/dist/style.css +5 -0
- package/package.json +1 -1
- package/template/dist/albums/albums.html +1 -1
- package/template/dist/albums/albums.json +1 -1
- package/template/dist/carousel/carousel.html +1 -1
- package/template/dist/carousel/carousel.json +1 -1
- package/template/dist/map/map.html +1 -1
- package/template/dist/map/map.json +1 -1
- package/template/dist/review/review.html +1 -1
- package/template/dist/review/review.json +1 -1
- package/template/tests/e2e/albums.spec.ts +3 -9
- package/template/tests/e2e/carousel.spec.ts +3 -9
- package/template/tests/e2e/map.spec.ts +3 -9
- package/template/tests/e2e/review.spec.ts +3 -9
- package/dist/simulator-CH9hs0N6.cjs.map +0 -1
- package/dist/simulator-Dl8B-Ljb.js.map +0 -1
- package/dist/simulator-url-CozKF1jf.cjs.map +0 -1
- package/dist/simulator-url-KoS_ToP6.js.map +0 -1
|
@@ -2185,13 +2185,14 @@ var DEFAULT_PLATFORM = "desktop";
|
|
|
2185
2185
|
* - touch: 'true' | 'false'
|
|
2186
2186
|
* - safeAreaTop, safeAreaBottom, safeAreaLeft, safeAreaRight: number
|
|
2187
2187
|
* - host: 'chatgpt' | 'claude'
|
|
2188
|
-
* -
|
|
2188
|
+
* - tool: tool name (e.g., 'show-albums') — selects tool without mock data
|
|
2189
2189
|
* - prodResources: 'true' | 'false'
|
|
2190
2190
|
*/
|
|
2191
2191
|
function parseUrlParams() {
|
|
2192
2192
|
if (typeof window === "undefined") return {};
|
|
2193
2193
|
const params = new URLSearchParams(window.location.search);
|
|
2194
2194
|
const simulation = params.get("simulation") ?? void 0;
|
|
2195
|
+
const tool = params.get("tool") ?? void 0;
|
|
2195
2196
|
const theme = params.get("theme");
|
|
2196
2197
|
const displayMode = params.get("displayMode");
|
|
2197
2198
|
const locale = params.get("locale");
|
|
@@ -2200,8 +2201,6 @@ function parseUrlParams() {
|
|
|
2200
2201
|
const maxWidthParam = params.get("maxWidth");
|
|
2201
2202
|
const containerMaxWidth = maxWidthParam ? Number(maxWidthParam) : void 0;
|
|
2202
2203
|
const host = params.get("host") ?? void 0;
|
|
2203
|
-
const prodToolsParam = params.get("prodTools");
|
|
2204
|
-
const prodTools = prodToolsParam === "true" ? true : prodToolsParam === "false" ? false : void 0;
|
|
2205
2204
|
const prodResourcesParam = params.get("prodResources");
|
|
2206
2205
|
const prodResources = prodResourcesParam === "true" ? true : prodResourcesParam === "false" ? false : void 0;
|
|
2207
2206
|
const deviceType = params.get("deviceType");
|
|
@@ -2226,6 +2225,7 @@ function parseUrlParams() {
|
|
|
2226
2225
|
} : void 0;
|
|
2227
2226
|
return {
|
|
2228
2227
|
simulation,
|
|
2228
|
+
tool,
|
|
2229
2229
|
theme: theme ?? void 0,
|
|
2230
2230
|
displayMode: displayMode ?? void 0,
|
|
2231
2231
|
locale: locale ?? void 0,
|
|
@@ -2235,7 +2235,6 @@ function parseUrlParams() {
|
|
|
2235
2235
|
deviceCapabilities,
|
|
2236
2236
|
safeAreaInsets,
|
|
2237
2237
|
host: host ?? void 0,
|
|
2238
|
-
prodTools,
|
|
2239
2238
|
prodResources
|
|
2240
2239
|
};
|
|
2241
2240
|
}
|
|
@@ -2486,7 +2485,7 @@ function useSimulatorState({ simulations, defaultHost = "chatgpt" }) {
|
|
|
2486
2485
|
csp,
|
|
2487
2486
|
permissions: resourceMeta?.permissions,
|
|
2488
2487
|
prefersBorder: resourceMeta?.prefersBorder ?? false,
|
|
2489
|
-
|
|
2488
|
+
urlTool: urlParams.tool,
|
|
2490
2489
|
urlProdResources: urlParams.prodResources
|
|
2491
2490
|
};
|
|
2492
2491
|
}
|
|
@@ -2495,17 +2494,21 @@ function useSimulatorState({ simulations, defaultHost = "chatgpt" }) {
|
|
|
2495
2494
|
/**
|
|
2496
2495
|
* Hook for managing MCP server connection status via the dev server proxy.
|
|
2497
2496
|
*
|
|
2498
|
-
* On mount (when `
|
|
2499
|
-
* by fetching `/__sunpeak/list-tools`.
|
|
2500
|
-
*
|
|
2497
|
+
* On mount (when `initialServerUrl` is provided), verifies the connection is alive
|
|
2498
|
+
* by fetching `/__sunpeak/list-tools`. URL changes are handled by the caller
|
|
2499
|
+
* via `reconnect()`, which posts to `/__sunpeak/connect`.
|
|
2501
2500
|
*
|
|
2502
|
-
*
|
|
2503
|
-
*
|
|
2501
|
+
* This split avoids React StrictMode issues: the mount-only health check runs
|
|
2502
|
+
* once (or safely twice with cancellation), while explicit `reconnect()` calls
|
|
2503
|
+
* are triggered by the Simulator's URL-change effect.
|
|
2504
2504
|
*/
|
|
2505
|
-
function useMcpConnection(
|
|
2506
|
-
const [status, setStatus] = useState(
|
|
2505
|
+
function useMcpConnection(initialServerUrl) {
|
|
2506
|
+
const [status, setStatus] = useState(initialServerUrl ? "connecting" : "disconnected");
|
|
2507
2507
|
const [error, setError] = useState();
|
|
2508
|
+
const [simulations, setSimulations] = useState();
|
|
2509
|
+
const [hasReconnected, setHasReconnected] = useState(false);
|
|
2508
2510
|
const reconnect = useCallback(async (url) => {
|
|
2511
|
+
setHasReconnected(true);
|
|
2509
2512
|
setStatus("connecting");
|
|
2510
2513
|
setError(void 0);
|
|
2511
2514
|
try {
|
|
@@ -2515,23 +2518,27 @@ function useMcpConnection(serverUrl) {
|
|
|
2515
2518
|
body: JSON.stringify({ url })
|
|
2516
2519
|
});
|
|
2517
2520
|
if (!res.ok) {
|
|
2518
|
-
|
|
2519
|
-
|
|
2521
|
+
let message = `Connection failed (${res.status})`;
|
|
2522
|
+
try {
|
|
2523
|
+
const json = await res.json();
|
|
2524
|
+
if (json.error) message = json.error;
|
|
2525
|
+
} catch {}
|
|
2526
|
+
throw new Error(message);
|
|
2520
2527
|
}
|
|
2528
|
+
const data = await res.json();
|
|
2521
2529
|
setStatus("connected");
|
|
2530
|
+
setSimulations(data.simulations ?? void 0);
|
|
2522
2531
|
} catch (err) {
|
|
2523
2532
|
setError(err instanceof Error ? err.message : String(err));
|
|
2524
2533
|
setStatus("error");
|
|
2534
|
+
setSimulations(void 0);
|
|
2525
2535
|
}
|
|
2526
2536
|
}, []);
|
|
2527
2537
|
useEffect(() => {
|
|
2528
|
-
if (!
|
|
2529
|
-
setStatus("disconnected");
|
|
2530
|
-
return;
|
|
2531
|
-
}
|
|
2538
|
+
if (!initialServerUrl) return;
|
|
2532
2539
|
let cancelled = false;
|
|
2540
|
+
setStatus("connecting");
|
|
2533
2541
|
(async () => {
|
|
2534
|
-
setStatus("connecting");
|
|
2535
2542
|
try {
|
|
2536
2543
|
const res = await fetch("/__sunpeak/list-tools");
|
|
2537
2544
|
if (cancelled) return;
|
|
@@ -2546,10 +2553,12 @@ function useMcpConnection(serverUrl) {
|
|
|
2546
2553
|
return () => {
|
|
2547
2554
|
cancelled = true;
|
|
2548
2555
|
};
|
|
2549
|
-
}, [
|
|
2556
|
+
}, []);
|
|
2550
2557
|
return {
|
|
2551
2558
|
status,
|
|
2552
2559
|
error,
|
|
2560
|
+
simulations,
|
|
2561
|
+
hasReconnected,
|
|
2553
2562
|
reconnect
|
|
2554
2563
|
};
|
|
2555
2564
|
}
|
|
@@ -2703,7 +2712,7 @@ function SimpleSidebar({ children, controls, headerRight }) {
|
|
|
2703
2712
|
]
|
|
2704
2713
|
});
|
|
2705
2714
|
}
|
|
2706
|
-
var DOCS_BASE_URL = "https://sunpeak.ai/docs";
|
|
2715
|
+
var DOCS_BASE_URL$1 = "https://sunpeak.ai/docs";
|
|
2707
2716
|
function HelpIcon({ tooltip, docsPath }) {
|
|
2708
2717
|
const [pos, setPos] = React.useState(null);
|
|
2709
2718
|
const ref = React.useRef(null);
|
|
@@ -2716,7 +2725,7 @@ function HelpIcon({ tooltip, docsPath }) {
|
|
|
2716
2725
|
};
|
|
2717
2726
|
return /* @__PURE__ */ jsxs("a", {
|
|
2718
2727
|
ref,
|
|
2719
|
-
href: `${DOCS_BASE_URL}/${docsPath}`,
|
|
2728
|
+
href: `${DOCS_BASE_URL$1}/${docsPath}`,
|
|
2720
2729
|
target: "_blank",
|
|
2721
2730
|
rel: "noopener noreferrer",
|
|
2722
2731
|
className: "inline-flex items-center justify-center no-underline flex-shrink-0 transition-colors",
|
|
@@ -2838,6 +2847,13 @@ function SidebarInput({ value, onChange, applyOnBlur = false, placeholder, type
|
|
|
2838
2847
|
setIsEditing(false);
|
|
2839
2848
|
onChange(draft);
|
|
2840
2849
|
},
|
|
2850
|
+
onKeyDown: (e) => {
|
|
2851
|
+
if (e.key === "Enter") {
|
|
2852
|
+
setIsEditing(false);
|
|
2853
|
+
onChange(draft);
|
|
2854
|
+
e.target.blur();
|
|
2855
|
+
}
|
|
2856
|
+
},
|
|
2841
2857
|
placeholder,
|
|
2842
2858
|
disabled,
|
|
2843
2859
|
className: "w-full h-7 text-xs rounded-md px-2 outline-none disabled:opacity-50 disabled:cursor-not-allowed",
|
|
@@ -2948,54 +2964,142 @@ function resolveServerToolResult(mock, args) {
|
|
|
2948
2964
|
}
|
|
2949
2965
|
//#endregion
|
|
2950
2966
|
//#region src/simulator/simulator.tsx
|
|
2951
|
-
|
|
2952
|
-
|
|
2967
|
+
var DOCS_BASE_URL = "https://sunpeak.ai/docs";
|
|
2968
|
+
/** Check whether a simulation has user-authored fixture data. */
|
|
2969
|
+
function hasFixtureData(sim) {
|
|
2970
|
+
return sim.toolResult != null || sim.toolInput != null || sim.serverTools != null;
|
|
2971
|
+
}
|
|
2972
|
+
function Simulator({ children, simulations: initialSimulations = {}, appName = "Sunpeak", appIcon, defaultHost = "chatgpt", onCallTool, onCallToolDirect, defaultProdResources = false, hideSimulatorModes = false, demoMode = false, sandboxUrl, mcpServerUrl }) {
|
|
2973
|
+
const [simulations, setSimulations] = React.useState(initialSimulations);
|
|
2974
|
+
React.useEffect(() => {
|
|
2975
|
+
setSimulations(initialSimulations);
|
|
2976
|
+
}, [initialSimulations]);
|
|
2977
|
+
const toolMap = React.useMemo(() => {
|
|
2978
|
+
const map = /* @__PURE__ */ new Map();
|
|
2979
|
+
for (const [simName, sim] of Object.entries(simulations)) {
|
|
2980
|
+
if (!sim.resource) continue;
|
|
2981
|
+
const toolName = sim.tool.name;
|
|
2982
|
+
if (!map.has(toolName)) map.set(toolName, {
|
|
2983
|
+
tool: sim.tool,
|
|
2984
|
+
resource: sim.resource,
|
|
2985
|
+
simNames: [],
|
|
2986
|
+
fixtureSimNames: []
|
|
2987
|
+
});
|
|
2988
|
+
const info = map.get(toolName);
|
|
2989
|
+
info.simNames.push(simName);
|
|
2990
|
+
if (hasFixtureData(sim)) info.fixtureSimNames.push(simName);
|
|
2991
|
+
}
|
|
2992
|
+
return map;
|
|
2993
|
+
}, [simulations]);
|
|
2994
|
+
const toolNames = React.useMemo(() => Array.from(toolMap.keys()).sort((a, b) => {
|
|
2995
|
+
const infoA = toolMap.get(a);
|
|
2996
|
+
const infoB = toolMap.get(b);
|
|
2997
|
+
const labelA = infoA.tool.title || a;
|
|
2998
|
+
const labelB = infoB.tool.title || b;
|
|
2999
|
+
return labelA.localeCompare(labelB);
|
|
3000
|
+
}), [toolMap]);
|
|
3001
|
+
const initUrlParams = React.useMemo(() => {
|
|
3002
|
+
if (typeof window === "undefined") return {
|
|
3003
|
+
tool: null,
|
|
3004
|
+
simulation: null,
|
|
3005
|
+
noMockData: false
|
|
3006
|
+
};
|
|
3007
|
+
const params = new URLSearchParams(window.location.search);
|
|
3008
|
+
const prodTools = params.get("prodTools") === "true";
|
|
3009
|
+
return {
|
|
3010
|
+
tool: params.get("tool"),
|
|
3011
|
+
simulation: params.get("simulation"),
|
|
3012
|
+
noMockData: prodTools
|
|
3013
|
+
};
|
|
3014
|
+
}, []);
|
|
3015
|
+
const [selectedToolName, setSelectedToolName] = React.useState(() => {
|
|
3016
|
+
if (initUrlParams.tool && toolMap.has(initUrlParams.tool)) return initUrlParams.tool;
|
|
3017
|
+
if (initUrlParams.simulation) {
|
|
3018
|
+
for (const [toolName, info] of toolMap) if (info.simNames.includes(initUrlParams.simulation)) return toolName;
|
|
3019
|
+
}
|
|
3020
|
+
return toolNames[0] ?? "";
|
|
3021
|
+
});
|
|
3022
|
+
const prevToolNamesRef = React.useRef(toolNames);
|
|
3023
|
+
if (prevToolNamesRef.current !== toolNames) {
|
|
3024
|
+
prevToolNamesRef.current = toolNames;
|
|
3025
|
+
if (toolNames.length > 0 && !toolMap.has(selectedToolName)) setSelectedToolName(toolNames[0]);
|
|
3026
|
+
}
|
|
3027
|
+
const selectedToolInfo = toolMap.get(selectedToolName);
|
|
3028
|
+
const [activeSimulationName, setActiveSimulationName] = React.useState(() => {
|
|
3029
|
+
if (!selectedToolInfo) return null;
|
|
3030
|
+
if (initUrlParams.noMockData) return null;
|
|
3031
|
+
if (initUrlParams.tool && !initUrlParams.simulation) return null;
|
|
3032
|
+
if (initUrlParams.simulation && selectedToolInfo.fixtureSimNames.includes(initUrlParams.simulation)) return initUrlParams.simulation;
|
|
3033
|
+
return selectedToolInfo.fixtureSimNames[0] ?? null;
|
|
3034
|
+
});
|
|
3035
|
+
const prevToolNameRef = React.useRef(selectedToolName);
|
|
3036
|
+
if (prevToolNameRef.current !== selectedToolName) {
|
|
3037
|
+
prevToolNameRef.current = selectedToolName;
|
|
3038
|
+
setActiveSimulationName(toolMap.get(selectedToolName)?.fixtureSimNames[0] ?? null);
|
|
3039
|
+
}
|
|
3040
|
+
const effectiveSimulationName = activeSimulationName ?? selectedToolInfo?.simNames[0] ?? "";
|
|
3041
|
+
const currentSim = simulations[effectiveSimulationName];
|
|
2953
3042
|
const state = useSimulatorState({
|
|
2954
3043
|
simulations,
|
|
2955
3044
|
defaultHost
|
|
2956
3045
|
});
|
|
2957
|
-
const
|
|
2958
|
-
const
|
|
3046
|
+
const [serverUrl, setServerUrl] = React.useState(mcpServerUrl ?? "");
|
|
3047
|
+
const connection = useMcpConnection(mcpServerUrl || void 0);
|
|
2959
3048
|
const [prodResources, setProdResources] = React.useState(state.urlProdResources ?? defaultProdResources);
|
|
2960
3049
|
const [isRunning, setIsRunning] = React.useState(false);
|
|
2961
3050
|
const [hasRun, setHasRun] = React.useState(false);
|
|
2962
3051
|
const [showCheck, setShowCheck] = React.useState(false);
|
|
2963
3052
|
const checkTimerRef = React.useRef(void 0);
|
|
2964
3053
|
React.useEffect(() => {
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
3054
|
+
state.setSelectedSimulationName(effectiveSimulationName);
|
|
3055
|
+
}, [effectiveSimulationName]);
|
|
3056
|
+
const prevServerUrlRef = React.useRef(serverUrl);
|
|
3057
|
+
React.useEffect(() => {
|
|
3058
|
+
const urlChanged = serverUrl !== prevServerUrlRef.current;
|
|
3059
|
+
prevServerUrlRef.current = serverUrl;
|
|
3060
|
+
if (!urlChanged) return;
|
|
3061
|
+
if (serverUrl) connection.reconnect(serverUrl);
|
|
3062
|
+
}, [serverUrl, connection.reconnect]);
|
|
3063
|
+
React.useEffect(() => {
|
|
3064
|
+
if (connection.simulations) setSimulations(connection.simulations);
|
|
3065
|
+
else if (connection.status === "error" && connection.hasReconnected) setSimulations({});
|
|
3066
|
+
}, [
|
|
3067
|
+
connection.simulations,
|
|
3068
|
+
connection.status,
|
|
3069
|
+
connection.hasReconnected
|
|
3070
|
+
]);
|
|
3071
|
+
const { setToolResult, setToolResultJson, setToolResultError } = state;
|
|
3072
|
+
React.useEffect(() => {
|
|
3073
|
+
if (activeSimulationName === null) {
|
|
3074
|
+
setToolResult(void 0);
|
|
3075
|
+
setToolResultJson("");
|
|
3076
|
+
setToolResultError("");
|
|
2970
3077
|
} else {
|
|
2971
|
-
const
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
React.useEffect(() => () => clearTimeout(checkTimerRef.current), []);
|
|
2976
|
-
const toolOptions = React.useMemo(() => {
|
|
2977
|
-
if (!prodTools) return [];
|
|
2978
|
-
const seen = /* @__PURE__ */ new Map();
|
|
2979
|
-
for (const simName of state.simulationNames) {
|
|
2980
|
-
const toolName = simulations[simName].tool.name;
|
|
2981
|
-
if (!seen.has(toolName)) seen.set(toolName, simName);
|
|
3078
|
+
const result = simulations[activeSimulationName]?.toolResult ?? void 0;
|
|
3079
|
+
setToolResult(result);
|
|
3080
|
+
setToolResultJson(result ? JSON.stringify(result, null, 2) : "");
|
|
3081
|
+
setToolResultError("");
|
|
2982
3082
|
}
|
|
2983
|
-
return Array.from(seen.entries()).map(([toolName, simName]) => ({
|
|
2984
|
-
value: simName,
|
|
2985
|
-
label: simulations[simName].tool.title || toolName
|
|
2986
|
-
}));
|
|
2987
3083
|
}, [
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
simulations
|
|
3084
|
+
activeSimulationName,
|
|
3085
|
+
effectiveSimulationName,
|
|
3086
|
+
simulations,
|
|
3087
|
+
setToolResult,
|
|
3088
|
+
setToolResultJson,
|
|
3089
|
+
setToolResultError
|
|
2991
3090
|
]);
|
|
3091
|
+
React.useEffect(() => {
|
|
3092
|
+
setHasRun(false);
|
|
3093
|
+
}, [effectiveSimulationName]);
|
|
3094
|
+
React.useEffect(() => () => clearTimeout(checkTimerRef.current), []);
|
|
2992
3095
|
const handleRun = React.useCallback(async () => {
|
|
2993
3096
|
const caller = onCallToolDirect ?? onCallTool;
|
|
2994
|
-
|
|
2995
|
-
|
|
3097
|
+
const sim = simulations[effectiveSimulationName];
|
|
3098
|
+
if (!caller || !sim) return;
|
|
3099
|
+
const toolName = sim.tool.name;
|
|
2996
3100
|
setIsRunning(true);
|
|
2997
3101
|
try {
|
|
2998
|
-
const result =
|
|
3102
|
+
const result = await caller({
|
|
2999
3103
|
name: toolName,
|
|
3000
3104
|
arguments: state.toolInput
|
|
3001
3105
|
});
|
|
@@ -3022,14 +3126,16 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3022
3126
|
}],
|
|
3023
3127
|
isError: true
|
|
3024
3128
|
}, null, 2));
|
|
3129
|
+
setHasRun(true);
|
|
3025
3130
|
} finally {
|
|
3026
3131
|
setIsRunning(false);
|
|
3027
3132
|
}
|
|
3028
3133
|
}, [
|
|
3029
3134
|
onCallTool,
|
|
3030
3135
|
onCallToolDirect,
|
|
3031
|
-
|
|
3032
|
-
|
|
3136
|
+
simulations,
|
|
3137
|
+
effectiveSimulationName,
|
|
3138
|
+
state
|
|
3033
3139
|
]);
|
|
3034
3140
|
const activeShell = getHostShell(state.activeHost);
|
|
3035
3141
|
const registeredHosts = getRegisteredHosts();
|
|
@@ -3063,8 +3169,8 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3063
3169
|
} else prevPageStyleKeysRef.current = [];
|
|
3064
3170
|
}, [activeShell]);
|
|
3065
3171
|
const handleCallTool = React.useCallback((params) => {
|
|
3066
|
-
if (
|
|
3067
|
-
const mock =
|
|
3172
|
+
if (activeSimulationName) {
|
|
3173
|
+
const mock = simulations[activeSimulationName]?.serverTools?.[params.name];
|
|
3068
3174
|
if (mock) {
|
|
3069
3175
|
const result = resolveServerToolResult(mock, params.arguments);
|
|
3070
3176
|
if (result) return result;
|
|
@@ -3073,15 +3179,15 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3073
3179
|
if (onCallTool) return onCallTool(params);
|
|
3074
3180
|
return { content: [{
|
|
3075
3181
|
type: "text",
|
|
3076
|
-
text: `[Simulator] Tool "${params.name}" called — no serverTools mock found in simulation "${
|
|
3182
|
+
text: `[Simulator] Tool "${params.name}" called — no serverTools mock found in simulation "${effectiveSimulationName}".`
|
|
3077
3183
|
}] };
|
|
3078
3184
|
}, [
|
|
3079
3185
|
onCallTool,
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3186
|
+
activeSimulationName,
|
|
3187
|
+
simulations,
|
|
3188
|
+
effectiveSimulationName
|
|
3083
3189
|
]);
|
|
3084
|
-
const
|
|
3190
|
+
const userMessage = currentSim ? currentSim.userMessage ?? `Call my ${currentSim.tool.title || currentSim.tool.name} tool` : void 0;
|
|
3085
3191
|
const prodResourcesPath = React.useMemo(() => {
|
|
3086
3192
|
if (!prodResources || !state.selectedSim?.resource) return void 0;
|
|
3087
3193
|
const name = state.selectedSim.resource.name;
|
|
@@ -3122,10 +3228,23 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3122
3228
|
}, [prodResourcesPath]);
|
|
3123
3229
|
const effectiveResourceUrl = (prodResourcesPath && prodResourcesReady ? prodResourcesPath : void 0) ?? state.resourceUrl;
|
|
3124
3230
|
const prodResourcesLoading = !!prodResourcesPath && !prodResourcesReady;
|
|
3125
|
-
const
|
|
3231
|
+
const hasTools = toolNames.length > 0;
|
|
3232
|
+
const showEmptyState = !(activeSimulationName !== null && currentSim?.toolResult != null) && !hasRun;
|
|
3126
3233
|
let content;
|
|
3127
3234
|
const iframeBg = "var(--sim-bg-conversation, var(--color-background-primary, transparent))";
|
|
3128
|
-
if (
|
|
3235
|
+
if (!hasTools) {
|
|
3236
|
+
const isConnected = connection.status === "connected";
|
|
3237
|
+
const isError = connection.status === "error";
|
|
3238
|
+
content = /* @__PURE__ */ jsx("div", {
|
|
3239
|
+
className: "h-full w-full flex items-center justify-center",
|
|
3240
|
+
style: { background: iframeBg },
|
|
3241
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
3242
|
+
className: "text-sm text-center max-w-xs",
|
|
3243
|
+
style: { color: "var(--color-text-secondary)" },
|
|
3244
|
+
children: isError ? "Could not connect to MCP server" : isConnected ? "No tools with UI resources found on this server" : serverUrl ? "Connecting…" : "Enter an MCP server URL to get started"
|
|
3245
|
+
})
|
|
3246
|
+
});
|
|
3247
|
+
} else if (showEmptyState) content = /* @__PURE__ */ jsx("div", {
|
|
3129
3248
|
className: "h-full w-full flex items-center justify-center",
|
|
3130
3249
|
style: { background: iframeBg },
|
|
3131
3250
|
children: /* @__PURE__ */ jsxs("span", {
|
|
@@ -3169,7 +3288,7 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3169
3288
|
injectOpenAIRuntime: state.activeHost === "chatgpt",
|
|
3170
3289
|
sandboxUrl,
|
|
3171
3290
|
className: "h-full w-full"
|
|
3172
|
-
}, `${state.activeHost}-${
|
|
3291
|
+
}, `${state.activeHost}-${effectiveResourceUrl}-${prodResources}-${prodResourcesGeneration}`)
|
|
3173
3292
|
});
|
|
3174
3293
|
else if (!prodResources && state.resourceScript) content = /* @__PURE__ */ jsx("div", {
|
|
3175
3294
|
className: "h-full w-full",
|
|
@@ -3194,10 +3313,37 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3194
3313
|
injectOpenAIRuntime: state.activeHost === "chatgpt",
|
|
3195
3314
|
sandboxUrl,
|
|
3196
3315
|
className: "h-full w-full"
|
|
3197
|
-
}, `${state.activeHost}-${state.
|
|
3316
|
+
}, `${state.activeHost}-${state.resourceScript}`)
|
|
3198
3317
|
});
|
|
3199
3318
|
else content = children;
|
|
3200
3319
|
const applyTheme = activeShell?.applyTheme;
|
|
3320
|
+
const runButton = !demoMode && onCallTool && currentSim && activeSimulationName === null ? /* @__PURE__ */ jsxs("button", {
|
|
3321
|
+
type: "button",
|
|
3322
|
+
onClick: handleRun,
|
|
3323
|
+
disabled: isRunning,
|
|
3324
|
+
className: "rounded-full px-3 py-1 text-sm font-medium transition-opacity disabled:opacity-40 flex items-center gap-1.5 cursor-pointer",
|
|
3325
|
+
style: {
|
|
3326
|
+
backgroundColor: "var(--color-text-primary)",
|
|
3327
|
+
color: "var(--color-background-primary)"
|
|
3328
|
+
},
|
|
3329
|
+
children: [showCheck ? /* @__PURE__ */ jsx("svg", {
|
|
3330
|
+
width: "12",
|
|
3331
|
+
height: "12",
|
|
3332
|
+
viewBox: "0 0 12 12",
|
|
3333
|
+
fill: "none",
|
|
3334
|
+
stroke: "currentColor",
|
|
3335
|
+
strokeWidth: "2",
|
|
3336
|
+
strokeLinecap: "round",
|
|
3337
|
+
strokeLinejoin: "round",
|
|
3338
|
+
children: /* @__PURE__ */ jsx("path", { d: "M2 6L5 9L10 3" })
|
|
3339
|
+
}) : /* @__PURE__ */ jsx("svg", {
|
|
3340
|
+
width: "10",
|
|
3341
|
+
height: "12",
|
|
3342
|
+
viewBox: "0 0 10 12",
|
|
3343
|
+
fill: "currentColor",
|
|
3344
|
+
children: /* @__PURE__ */ jsx("path", { d: "M0 0L10 6L0 12V0Z" })
|
|
3345
|
+
}), "Run"]
|
|
3346
|
+
}) : void 0;
|
|
3201
3347
|
return /* @__PURE__ */ jsx(ThemeProvider, {
|
|
3202
3348
|
theme: state.theme,
|
|
3203
3349
|
applyTheme,
|
|
@@ -3205,39 +3351,82 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3205
3351
|
controls: /* @__PURE__ */ jsxs("div", {
|
|
3206
3352
|
className: "space-y-1",
|
|
3207
3353
|
children: [
|
|
3208
|
-
|
|
3354
|
+
/* @__PURE__ */ jsx(SidebarControl, {
|
|
3209
3355
|
label: /* @__PURE__ */ jsxs("span", {
|
|
3210
3356
|
className: "flex items-center gap-1.5",
|
|
3211
|
-
children: ["MCP Server", /* @__PURE__ */ jsx("span", {
|
|
3357
|
+
children: ["MCP Server", serverUrl && !demoMode && /* @__PURE__ */ jsx("span", {
|
|
3212
3358
|
className: "inline-block w-2 h-2 rounded-full",
|
|
3213
|
-
"data-testid": "
|
|
3359
|
+
"data-testid": "connection-status",
|
|
3214
3360
|
style: { backgroundColor: connection.status === "connected" ? "#22c55e" : connection.status === "connecting" ? "#eab308" : connection.status === "error" ? "#ef4444" : "#6b7280" },
|
|
3215
3361
|
title: connection.error ?? connection.status
|
|
3216
3362
|
})]
|
|
3217
3363
|
}),
|
|
3218
|
-
tooltip: "MCP server URL
|
|
3219
|
-
"data-testid": "
|
|
3364
|
+
tooltip: "MCP server URL",
|
|
3365
|
+
"data-testid": "server-url",
|
|
3220
3366
|
children: /* @__PURE__ */ jsx(SidebarInput, {
|
|
3221
|
-
value:
|
|
3222
|
-
onChange: () => {},
|
|
3223
|
-
|
|
3224
|
-
placeholder: "http://localhost:8000/mcp"
|
|
3367
|
+
value: demoMode ? "http://localhost:8000/mcp" : serverUrl,
|
|
3368
|
+
onChange: demoMode ? () => {} : setServerUrl,
|
|
3369
|
+
applyOnBlur: true,
|
|
3370
|
+
placeholder: "http://localhost:8000/mcp",
|
|
3371
|
+
disabled: demoMode
|
|
3225
3372
|
})
|
|
3226
3373
|
}),
|
|
3227
|
-
!
|
|
3228
|
-
checked: prodTools,
|
|
3229
|
-
onChange: setProdTools,
|
|
3230
|
-
label: "Prod Tools",
|
|
3231
|
-
tooltip: "Use real tool handlers instead of simulations",
|
|
3232
|
-
docsPath: "api-reference/cli/dev#prod-tools-and-prod-resources-flags"
|
|
3233
|
-
}),
|
|
3234
|
-
!isInspectMode && !hideSimulatorModes && /* @__PURE__ */ jsx(SidebarCheckbox, {
|
|
3374
|
+
!hideSimulatorModes && !demoMode && /* @__PURE__ */ jsx(SidebarCheckbox, {
|
|
3235
3375
|
checked: prodResources,
|
|
3236
3376
|
onChange: setProdResources,
|
|
3237
3377
|
label: "Prod Resources",
|
|
3238
3378
|
tooltip: "Load resources from dist/ builds instead of HMR",
|
|
3239
3379
|
docsPath: "api-reference/cli/dev#prod-tools-and-prod-resources-flags"
|
|
3240
3380
|
}),
|
|
3381
|
+
hasTools && /* @__PURE__ */ jsxs("div", {
|
|
3382
|
+
className: "grid grid-cols-2 gap-2",
|
|
3383
|
+
"data-testid": "tool-simulation-row",
|
|
3384
|
+
children: [/* @__PURE__ */ jsx(SidebarControl, {
|
|
3385
|
+
label: "Tool",
|
|
3386
|
+
tooltip: "Tool to inspect",
|
|
3387
|
+
docsPath: "api-reference/cli/dev",
|
|
3388
|
+
"data-testid": "tool-selector",
|
|
3389
|
+
children: /* @__PURE__ */ jsx(SidebarSelect, {
|
|
3390
|
+
value: selectedToolName,
|
|
3391
|
+
onChange: (value) => setSelectedToolName(value),
|
|
3392
|
+
options: toolNames.map((name) => {
|
|
3393
|
+
return {
|
|
3394
|
+
value: name,
|
|
3395
|
+
label: toolMap.get(name).tool.title || name
|
|
3396
|
+
};
|
|
3397
|
+
})
|
|
3398
|
+
})
|
|
3399
|
+
}), /* @__PURE__ */ jsx(SidebarControl, {
|
|
3400
|
+
label: selectedToolInfo && selectedToolInfo.fixtureSimNames.length > 0 ? "Simulation" : /* @__PURE__ */ jsx("a", {
|
|
3401
|
+
href: `${DOCS_BASE_URL}/api-reference/simulations/simulation`,
|
|
3402
|
+
target: "_blank",
|
|
3403
|
+
rel: "noopener noreferrer",
|
|
3404
|
+
className: "no-underline transition-colors",
|
|
3405
|
+
style: { color: "var(--color-text-secondary)" },
|
|
3406
|
+
onMouseEnter: (e) => {
|
|
3407
|
+
e.target.style.color = "var(--color-text-primary)";
|
|
3408
|
+
},
|
|
3409
|
+
onMouseLeave: (e) => {
|
|
3410
|
+
e.target.style.color = "var(--color-text-secondary)";
|
|
3411
|
+
},
|
|
3412
|
+
children: "Simulation"
|
|
3413
|
+
}),
|
|
3414
|
+
tooltip: selectedToolInfo && selectedToolInfo.fixtureSimNames.length > 0 ? "Test fixture with mock data" : "Create simulations for faster testing",
|
|
3415
|
+
docsPath: "api-reference/simulations/simulation",
|
|
3416
|
+
"data-testid": "simulation-selector",
|
|
3417
|
+
children: /* @__PURE__ */ jsx(SidebarSelect, {
|
|
3418
|
+
value: activeSimulationName ?? "__none__",
|
|
3419
|
+
onChange: (value) => setActiveSimulationName(value === "__none__" ? null : value),
|
|
3420
|
+
options: [...demoMode ? [] : [{
|
|
3421
|
+
value: "__none__",
|
|
3422
|
+
label: selectedToolInfo && selectedToolInfo.fixtureSimNames.length > 0 ? "None (call server)" : "None"
|
|
3423
|
+
}], ...(selectedToolInfo?.fixtureSimNames ?? []).map((simName) => ({
|
|
3424
|
+
value: simName,
|
|
3425
|
+
label: simName
|
|
3426
|
+
}))]
|
|
3427
|
+
})
|
|
3428
|
+
})]
|
|
3429
|
+
}),
|
|
3241
3430
|
/* @__PURE__ */ jsxs("div", {
|
|
3242
3431
|
className: "grid grid-cols-2 gap-2",
|
|
3243
3432
|
children: [registeredHosts.length > 1 && /* @__PURE__ */ jsx(SidebarControl, {
|
|
@@ -3280,34 +3469,6 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3280
3469
|
})
|
|
3281
3470
|
})]
|
|
3282
3471
|
}),
|
|
3283
|
-
prodTools && toolOptions.length > 1 && /* @__PURE__ */ jsx(SidebarControl, {
|
|
3284
|
-
label: "Tool",
|
|
3285
|
-
tooltip: "Tool to call with prod handler",
|
|
3286
|
-
docsPath: "api-reference/cli/dev",
|
|
3287
|
-
children: /* @__PURE__ */ jsx(SidebarSelect, {
|
|
3288
|
-
value: state.selectedSimulationName,
|
|
3289
|
-
onChange: (value) => state.setSelectedSimulationName(value),
|
|
3290
|
-
options: toolOptions
|
|
3291
|
-
})
|
|
3292
|
-
}),
|
|
3293
|
-
!prodTools && state.simulationNames.length > 1 && /* @__PURE__ */ jsx(SidebarControl, {
|
|
3294
|
-
label: "Simulation",
|
|
3295
|
-
tooltip: "Test fixture to render",
|
|
3296
|
-
docsPath: "api-reference/simulations/simulation",
|
|
3297
|
-
children: /* @__PURE__ */ jsx(SidebarSelect, {
|
|
3298
|
-
value: state.selectedSimulationName,
|
|
3299
|
-
onChange: (value) => state.setSelectedSimulationName(value),
|
|
3300
|
-
options: state.simulationNames.map((name) => {
|
|
3301
|
-
const sim = simulations[name];
|
|
3302
|
-
const resourceTitle = sim.resource ? sim.resource.title || sim.resource.name : void 0;
|
|
3303
|
-
const toolTitle = sim.tool.title || sim.tool.name;
|
|
3304
|
-
return {
|
|
3305
|
-
value: name,
|
|
3306
|
-
label: resourceTitle ? `${resourceTitle}: ${toolTitle}` : toolTitle
|
|
3307
|
-
};
|
|
3308
|
-
})
|
|
3309
|
-
})
|
|
3310
|
-
}),
|
|
3311
3472
|
/* @__PURE__ */ jsx(SidebarCollapsibleControl, {
|
|
3312
3473
|
label: "Host Context",
|
|
3313
3474
|
defaultCollapsed: false,
|
|
@@ -3589,7 +3750,7 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3589
3750
|
}),
|
|
3590
3751
|
/* @__PURE__ */ jsx(SidebarCollapsibleControl, {
|
|
3591
3752
|
label: "Tool Input (JSON)",
|
|
3592
|
-
defaultCollapsed:
|
|
3753
|
+
defaultCollapsed: false,
|
|
3593
3754
|
tooltip: "Arguments passed to the tool",
|
|
3594
3755
|
docsPath: "api-reference/hooks/use-tool-data",
|
|
3595
3756
|
children: /* @__PURE__ */ jsx(SidebarTextarea, {
|
|
@@ -3600,10 +3761,10 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3600
3761
|
error: state.toolInputError,
|
|
3601
3762
|
maxRows: 8
|
|
3602
3763
|
})
|
|
3603
|
-
}
|
|
3764
|
+
}),
|
|
3604
3765
|
/* @__PURE__ */ jsx(SidebarCollapsibleControl, {
|
|
3605
3766
|
label: "Tool Result (JSON)",
|
|
3606
|
-
defaultCollapsed:
|
|
3767
|
+
defaultCollapsed: false,
|
|
3607
3768
|
tooltip: "Structured content returned by the tool",
|
|
3608
3769
|
docsPath: "api-reference/hooks/use-tool-data",
|
|
3609
3770
|
"data-testid": "tool-result-section",
|
|
@@ -3626,7 +3787,7 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3626
3787
|
error: state.toolResultError,
|
|
3627
3788
|
maxRows: 8
|
|
3628
3789
|
})
|
|
3629
|
-
}
|
|
3790
|
+
})
|
|
3630
3791
|
]
|
|
3631
3792
|
}),
|
|
3632
3793
|
children: ShellConversation ? /* @__PURE__ */ jsx(ShellConversation, {
|
|
@@ -3636,35 +3797,9 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3636
3797
|
onRequestDisplayMode: state.handleDisplayModeChange,
|
|
3637
3798
|
appName,
|
|
3638
3799
|
appIcon,
|
|
3639
|
-
userMessage
|
|
3800
|
+
userMessage,
|
|
3640
3801
|
onContentWidthChange: state.handleContentWidthChange,
|
|
3641
|
-
headerAction:
|
|
3642
|
-
type: "button",
|
|
3643
|
-
onClick: handleRun,
|
|
3644
|
-
disabled: isRunning,
|
|
3645
|
-
className: "rounded-full px-3 py-1 text-sm font-medium transition-opacity disabled:opacity-40 flex items-center gap-1.5 cursor-pointer",
|
|
3646
|
-
style: {
|
|
3647
|
-
backgroundColor: "var(--color-text-primary)",
|
|
3648
|
-
color: "var(--color-background-primary)"
|
|
3649
|
-
},
|
|
3650
|
-
children: [showCheck ? /* @__PURE__ */ jsx("svg", {
|
|
3651
|
-
width: "12",
|
|
3652
|
-
height: "12",
|
|
3653
|
-
viewBox: "0 0 12 12",
|
|
3654
|
-
fill: "none",
|
|
3655
|
-
stroke: "currentColor",
|
|
3656
|
-
strokeWidth: "2",
|
|
3657
|
-
strokeLinecap: "round",
|
|
3658
|
-
strokeLinejoin: "round",
|
|
3659
|
-
children: /* @__PURE__ */ jsx("path", { d: "M2 6L5 9L10 3" })
|
|
3660
|
-
}) : /* @__PURE__ */ jsx("svg", {
|
|
3661
|
-
width: "10",
|
|
3662
|
-
height: "12",
|
|
3663
|
-
viewBox: "0 0 10 12",
|
|
3664
|
-
fill: "currentColor",
|
|
3665
|
-
children: /* @__PURE__ */ jsx("path", { d: "M0 0L10 6L0 12V0Z" })
|
|
3666
|
-
}), "Run"]
|
|
3667
|
-
}) : void 0,
|
|
3802
|
+
headerAction: runButton,
|
|
3668
3803
|
children: content
|
|
3669
3804
|
}) : content
|
|
3670
3805
|
})
|
|
@@ -3673,4 +3808,4 @@ function Simulator({ children, simulations = {}, appName = "Sunpeak", appIcon, d
|
|
|
3673
3808
|
//#endregion
|
|
3674
3809
|
export { DEFAULT_STYLE_VARIABLES as S, McpAppHost as _, SidebarControl as a, getRegisteredHosts as b, SidebarTextarea as c, ThemeProvider as d, useThemeContext as f, extractResourceCSP as g, IframeResource as h, SidebarCollapsibleControl as i, SidebarToggle as l, useSimulatorState as m, resolveServerToolResult as n, SidebarInput as o, useMcpConnection as p, SidebarCheckbox as r, SidebarSelect as s, Simulator as t, SimpleSidebar as u, SCREEN_WIDTHS as v, registerHostShell as x, getHostShell as y };
|
|
3675
3810
|
|
|
3676
|
-
//# sourceMappingURL=simulator-
|
|
3811
|
+
//# sourceMappingURL=simulator-BijjlOXb.js.map
|