@sampleapp.ai/sdk 1.0.36 → 1.0.38

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 (82) hide show
  1. package/dist/components/sandbox/Sandbox.js +5 -0
  2. package/dist/components/sandbox/api.js +2 -2
  3. package/dist/components/sandbox/guardian/guardian-component.js +7 -38
  4. package/dist/components/sandbox/guardian/guardian-playground.js +2 -2
  5. package/dist/components/sandbox/guardian/hooks/use-sandbox-url-loader.js +12 -10
  6. package/dist/components/sandbox/guardian/index.js +1 -1
  7. package/dist/components/sandbox/guardian/right-view/right-top-down-view.js +2 -1
  8. package/dist/components/sandbox/guardian/ui/markdown.js +2 -2
  9. package/dist/components/sandbox/guardian/utils.js +4 -22
  10. package/dist/components/sandbox/index.js +1 -1
  11. package/dist/components/sandbox/sandbox-home/SandboxHome.js +5 -0
  12. package/dist/index.d.ts +8 -40
  13. package/dist/index.es.js +834 -870
  14. package/dist/index.js +1 -1
  15. package/dist/lib/api-client.js +9 -26
  16. package/package.json +1 -1
  17. package/dist/components/guardian/app-layout-no-sidebar.js +0 -8
  18. package/dist/components/guardian/ask-ai-view.js +0 -249
  19. package/dist/components/guardian/code-focus-section.d.ts +0 -41
  20. package/dist/components/guardian/code-focus-section.js +0 -174
  21. package/dist/components/guardian/context/guardian-context.js +0 -94
  22. package/dist/components/guardian/context/vm-context.js +0 -28
  23. package/dist/components/guardian/default-guide-view.js +0 -34
  24. package/dist/components/guardian/demo/guardian-demo.js +0 -35
  25. package/dist/components/guardian/demo/left-view/toggle.js +0 -28
  26. package/dist/components/guardian/demo/left-view.js +0 -49
  27. package/dist/components/guardian/guardian-component.js +0 -79
  28. package/dist/components/guardian/guardian-demo.js +0 -35
  29. package/dist/components/guardian/guardian-home.d.ts +0 -4
  30. package/dist/components/guardian/guardian-home.js +0 -61
  31. package/dist/components/guardian/guardian-playground.js +0 -45
  32. package/dist/components/guardian/guardian-style-wrapper.js +0 -29
  33. package/dist/components/guardian/guardian-upload-spec.d.ts +0 -14
  34. package/dist/components/guardian/guardian-upload-spec.js +0 -160
  35. package/dist/components/guardian/header/glassmorphic-combobox.d.ts +0 -15
  36. package/dist/components/guardian/header/glassmorphic-combobox.js +0 -30
  37. package/dist/components/guardian/header.js +0 -61
  38. package/dist/components/guardian/hooks/use-frame-messages.js +0 -65
  39. package/dist/components/guardian/hooks/use-frame-params.js +0 -44
  40. package/dist/components/guardian/hooks/use-sandbox-url-loader.js +0 -101
  41. package/dist/components/guardian/ide/browser.js +0 -538
  42. package/dist/components/guardian/index.js +0 -8
  43. package/dist/components/guardian/layout/app-layout-no-sidebar.js +0 -8
  44. package/dist/components/guardian/layout/header/glassmorphic-combobox.js +0 -48
  45. package/dist/components/guardian/layout/header.js +0 -63
  46. package/dist/components/guardian/right-view/code-view.js +0 -56
  47. package/dist/components/guardian/right-view/pill-file-selector.js +0 -233
  48. package/dist/components/guardian/right-view/preview-control-bar.js +0 -25
  49. package/dist/components/guardian/right-view/right-panel-view.js +0 -38
  50. package/dist/components/guardian/right-view/right-top-down-view.js +0 -289
  51. package/dist/components/guardian/right-view/right-view.js +0 -28
  52. package/dist/components/guardian/right-view/simplified-editor.js +0 -234
  53. package/dist/components/guardian/types/ide-types.js +0 -162
  54. package/dist/components/guardian/types.js +0 -3
  55. package/dist/components/guardian/ui/ai-loader.js +0 -48
  56. package/dist/components/guardian/ui/badge.js +0 -24
  57. package/dist/components/guardian/ui/button.js +0 -45
  58. package/dist/components/guardian/ui/command.js +0 -63
  59. package/dist/components/guardian/ui/console-with-app.js +0 -17
  60. package/dist/components/guardian/ui/dialog.js +0 -57
  61. package/dist/components/guardian/ui/dropdown-menu.js +0 -82
  62. package/dist/components/guardian/ui/markdown.js +0 -57
  63. package/dist/components/guardian/ui/popover.js +0 -25
  64. package/dist/components/guardian/ui/tooltip.js +0 -25
  65. package/dist/components/guardian/utils.js +0 -88
  66. package/dist/components/guardian/zip-to-codebase.js +0 -246
  67. package/dist/components/guardian/zip-to-filetree.js +0 -284
  68. package/dist/components/sandbox/SandboxHome.js +0 -141
  69. package/dist/components/sandbox/guardian/guardian-demo.js +0 -35
  70. package/dist/components/sandbox/guardian/guardian-home.d.ts +0 -4
  71. package/dist/components/sandbox/guardian/guardian-home.js +0 -61
  72. package/dist/components/sandbox/guardian/guardian-upload-spec.d.ts +0 -14
  73. package/dist/components/sandbox/guardian/guardian-upload-spec.js +0 -160
  74. package/dist/components/sandbox/guardian/ui/theme-color-context.d.ts +0 -6
  75. package/dist/components/sandbox/sandbox-control-bar.js +0 -91
  76. package/dist/components/sandbox/sandbox-header.js +0 -52
  77. package/dist/components/sandbox/sandbox-left-panel.js +0 -248
  78. package/dist/components/sandbox/sandbox-loading.js +0 -48
  79. package/dist/components/sandbox/sandbox-right-panel.js +0 -247
  80. package/dist/components/sandbox.js +0 -32
  81. package/dist/lib/api-client.example.js +0 -60
  82. package/dist/lib/ssr-safe-decode-entity.js +0 -16
@@ -1,289 +0,0 @@
1
- "use client";
2
- import React from "react";
3
- import Browser from "../ide/browser";
4
- import { Component as AiLoader } from "../ui/ai-loader";
5
- import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
6
- import SimplifiedEditor from "./simplified-editor";
7
- import PillFileSelector from "./pill-file-selector";
8
- import { useGuardianContext } from "../context/guardian-context";
9
- import { useEffect, useMemo, useState } from "react";
10
- import { zipPathToFileTree } from "../zip-to-filetree";
11
- import { zipPathToCodebase } from "../zip-to-codebase";
12
- import { DownloadIcon, Globe, Code2 } from "lucide-react";
13
- import { useFrameParams } from "../hooks/use-frame-params";
14
- import { cn } from "../../../lib/utils";
15
- export default function RightView({ reloadCounter, overlayStage, browserUrl, useVm, codeZipFile, themeColor, completeCodeZipFile, hasPreview, isPreviewMinimized = false, isGuardian = false, isBrowserMaximized = false, }) {
16
- const { setFileTree, setGeneratedCode } = useGuardianContext();
17
- const frameParams = useFrameParams();
18
- const [activeTab, setActiveTab] = useState("code");
19
- const [networkRequests, setNetworkRequests] = useState([]);
20
- // Use frame param override for theme if in frame mode
21
- const effectiveThemeColor = frameParams.isFrame && frameParams.theme ? frameParams.theme : themeColor;
22
- const normalizedZipDownloadPath = useMemo(() => {
23
- let normalizedPath = completeCodeZipFile;
24
- if (normalizedPath.startsWith("/public/")) {
25
- normalizedPath = normalizedPath.slice("/public".length);
26
- }
27
- if (!normalizedPath.startsWith("/")) {
28
- normalizedPath = "/" + normalizedPath;
29
- }
30
- return normalizedPath;
31
- }, [completeCodeZipFile]);
32
- // Extract only the nested children (actual API calls to external services)
33
- const childrenRequests = useMemo(() => {
34
- const children = [];
35
- for (const request of networkRequests) {
36
- if (request.children && request.children.length > 0) {
37
- children.push(...request.children);
38
- }
39
- }
40
- return children;
41
- }, [networkRequests]);
42
- useEffect(() => {
43
- let isMounted = true;
44
- zipPathToFileTree(completeCodeZipFile)
45
- .then((fileTree) => {
46
- if (isMounted) {
47
- setFileTree(fileTree);
48
- }
49
- })
50
- .catch((error) => {
51
- console.error("Failed to load zip file:", error);
52
- });
53
- zipPathToCodebase(codeZipFile)
54
- .then((codebase) => {
55
- if (isMounted) {
56
- setGeneratedCode(codebase);
57
- }
58
- })
59
- .catch((error) => {
60
- console.error("Failed to load codebase:", error);
61
- });
62
- return () => {
63
- isMounted = false;
64
- };
65
- }, [codeZipFile, completeCodeZipFile, setFileTree, setGeneratedCode]);
66
- // Listen for network requests from iframe
67
- useEffect(() => {
68
- const handleMessage = (event) => {
69
- if (event.origin.endsWith("sampleapp.love")) {
70
- // Handle network requests
71
- if (event.data.type === "NETWORK_REQUEST") {
72
- const request = event.data.request;
73
- setNetworkRequests((prev) => [...prev, request]);
74
- }
75
- // Handle runtime errors
76
- if (event.data.type === "CONTAINER_APP_ERROR") {
77
- console.error("Container app error:", event.data);
78
- }
79
- }
80
- };
81
- window.addEventListener("message", handleMessage);
82
- return () => {
83
- window.removeEventListener("message", handleMessage);
84
- };
85
- }, []);
86
- // When browser is maximized, render only the browser at full size
87
- if (isBrowserMaximized) {
88
- return (React.createElement("div", { className: "h-full w-full" }, !browserUrl ? (React.createElement("div", { className: "h-full w-full relative overflow-hidden" },
89
- React.createElement(AiLoader, { text: "Booting up...", fullScreen: false }))) : (React.createElement(Browser, { previewUrl: browserUrl, setPreviewUrl: () => { }, containerEndpoint: browserUrl, outerContainerClassName: "h-full w-full border-none", reloadSignal: reloadCounter, useVm: useVm, isGuardian: isGuardian }, overlayStage !== "hidden" && (React.createElement("div", { className: "absolute inset-0 z-20 flex items-center justify-center" },
90
- overlayStage === "error" && (React.createElement("div", { className: "w-full h-full bg-red-950 text-red-200 flex items-center justify-center" },
91
- React.createElement("div", { className: "text-center" },
92
- React.createElement("div", { className: "text-2xl font-semibold" }, "Service Unavailable"),
93
- React.createElement("div", { className: "text-sm mt-2 opacity-80" }, "Elevated error rates detected. Initiating rollback...")))),
94
- overlayStage === "rebuilding" && (React.createElement("div", { className: "w-full h-full bg-amber-900 text-amber-100 flex items-center justify-center" },
95
- React.createElement("div", { className: "text-center" },
96
- React.createElement("div", { className: "text-2xl font-semibold" }, "Rebuilding preview\u2026"),
97
- React.createElement("div", { className: "text-sm mt-2 opacity-80" }, "Applying safe configuration"),
98
- React.createElement("div", { className: "mt-4 inline-flex items-center gap-2" },
99
- React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse" }),
100
- React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse [animation-delay:150ms]" }),
101
- React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse [animation-delay:300ms]" })))))))))));
102
- }
103
- return (React.createElement("div", { className: "h-full w-full flex flex-col" },
104
- React.createElement(PanelGroup, { direction: "vertical", className: "relative h-full" },
105
- hasPreview && !isPreviewMinimized && (React.createElement(React.Fragment, null,
106
- React.createElement(Panel, { defaultSize: 58, minSize: 20, maxSize: 80, order: 1 },
107
- React.createElement("div", { className: "h-full w-full" }, !browserUrl ? (React.createElement("div", { className: "h-full w-full relative overflow-hidden" },
108
- React.createElement(AiLoader, { text: "Booting up...", fullScreen: false }))) : (React.createElement(Browser, { previewUrl: browserUrl, setPreviewUrl: () => { }, containerEndpoint: browserUrl, outerContainerClassName: "h-full w-full border-none", reloadSignal: reloadCounter, useVm: useVm, isGuardian: isGuardian }, overlayStage !== "hidden" && (React.createElement("div", { className: "absolute inset-0 z-20 flex items-center justify-center" },
109
- overlayStage === "error" && (React.createElement("div", { className: "w-full h-full bg-red-950 text-red-200 flex items-center justify-center" },
110
- React.createElement("div", { className: "text-center" },
111
- React.createElement("div", { className: "text-2xl font-semibold" }, "Service Unavailable"),
112
- React.createElement("div", { className: "text-sm mt-2 opacity-80" }, "Elevated error rates detected. Initiating rollback...")))),
113
- overlayStage === "rebuilding" && (React.createElement("div", { className: "w-full h-full bg-amber-900 text-amber-100 flex items-center justify-center" },
114
- React.createElement("div", { className: "text-center" },
115
- React.createElement("div", { className: "text-2xl font-semibold" }, "Rebuilding preview\u2026"),
116
- React.createElement("div", { className: "text-sm mt-2 opacity-80" }, "Applying safe configuration"),
117
- React.createElement("div", { className: "mt-4 inline-flex items-center gap-2" },
118
- React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse" }),
119
- React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse [animation-delay:150ms]" }),
120
- React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse [animation-delay:300ms]" }))))))))))),
121
- React.createElement(PanelResizeHandle, { className: "h-2 relative group flex-shrink-0" },
122
- React.createElement("div", { className: "absolute inset-x-0 top-1/2 -translate-y-1/2 h-2 transition-colors flex justify-center items-center bg-transparent" },
123
- React.createElement("div", { className: "absolute inset-x-0 top-0 h-1/2 group-hover:bg-blue-400/20 transition-colors" }),
124
- React.createElement("div", { className: "absolute inset-x-0 bottom-0 h-1/2 group-hover:bg-blue-400/20 transition-colors" }),
125
- React.createElement("div", { className: "h-full w-px bg-border group-hover:bg-blue-400 transition-colors relative z-10" }))))),
126
- React.createElement(Panel, { defaultSize: 42, minSize: 20, maxSize: 80, order: 2 },
127
- React.createElement("div", { className: "h-full w-full flex flex-col" },
128
- React.createElement("div", { className: "flex items-center justify-between border-b border-zinc-800 dark:border-zinc-700 bg-zinc-900 dark:bg-zinc-950 flex-shrink-0" },
129
- React.createElement("div", { className: "flex" },
130
- React.createElement("button", { type: "button", onClick: () => setActiveTab("code"), className: cn("flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium transition-colors border-b-2", activeTab === "code"
131
- ? "border-current text-white"
132
- : "border-transparent text-zinc-500 hover:text-zinc-300"), style: activeTab === "code"
133
- ? {
134
- borderColor: effectiveThemeColor,
135
- color: effectiveThemeColor,
136
- }
137
- : undefined },
138
- React.createElement(Code2, { className: "w-3.5 h-3.5" }),
139
- "Code"),
140
- React.createElement("button", { type: "button", onClick: () => setActiveTab("network"), className: cn("flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium transition-colors border-b-2", activeTab === "network"
141
- ? "border-current text-white"
142
- : "border-transparent text-zinc-500 hover:text-zinc-300"), style: activeTab === "network"
143
- ? {
144
- borderColor: effectiveThemeColor,
145
- color: effectiveThemeColor,
146
- }
147
- : undefined },
148
- React.createElement(Globe, { className: "w-3.5 h-3.5" }),
149
- "Network",
150
- childrenRequests.length > 0 && (React.createElement("span", { className: "ml-1 px-1.5 py-0.5 text-[10px] rounded-full bg-zinc-700 text-zinc-300" }, childrenRequests.length)))),
151
- activeTab === "network" && childrenRequests.length > 0 && (React.createElement("button", { type: "button", className: "px-2 text-[10px] font-medium text-zinc-500 hover:text-zinc-300 transition-colors", onClick: () => setNetworkRequests([]) }, "Clear"))),
152
- React.createElement("div", { className: "flex-1 min-h-0 flex flex-col" }, activeTab === "code" ? (React.createElement(React.Fragment, null,
153
- React.createElement("div", { className: "flex items-center justify-between border-b border-zinc-800 dark:border-zinc-700 bg-zinc-900 dark:bg-zinc-950" },
154
- React.createElement(PillFileSelector, { themeColor: effectiveThemeColor }),
155
- React.createElement("div", { className: "px-2 flex-shrink-0" },
156
- React.createElement("button", { type: "button", className: "inline-flex items-center gap-1 text-[10px] font-medium transition-colors hover:opacity-80", style: { color: effectiveThemeColor }, onClick: () => {
157
- window.open(normalizedZipDownloadPath, "_blank");
158
- } },
159
- React.createElement(DownloadIcon, { className: "w-4 h-4" }),
160
- "Download Code"))),
161
- React.createElement("div", { className: "flex-1 min-h-0" },
162
- React.createElement(SimplifiedEditor, { themeColor: effectiveThemeColor })))) : (React.createElement(NetworkRequestsView, { requests: childrenRequests, themeColor: effectiveThemeColor }))))))));
163
- }
164
- // Simple Network Requests View Component
165
- function NetworkRequestsView({ requests, themeColor, }) {
166
- var _a, _b, _c, _d;
167
- const [selectedRequest, setSelectedRequest] = useState(null);
168
- const getMethodColor = (method) => {
169
- switch (method.toUpperCase()) {
170
- case "GET":
171
- return "text-emerald-400";
172
- case "POST":
173
- return "text-blue-400";
174
- case "PUT":
175
- return "text-amber-400";
176
- case "PATCH":
177
- return "text-orange-400";
178
- case "DELETE":
179
- return "text-red-400";
180
- default:
181
- return "text-zinc-400";
182
- }
183
- };
184
- const getStatusColor = (status) => {
185
- if (!status)
186
- return "text-zinc-500";
187
- if (status >= 200 && status < 300)
188
- return "text-emerald-400";
189
- if (status >= 300 && status < 400)
190
- return "text-blue-400";
191
- if (status >= 400 && status < 500)
192
- return "text-amber-400";
193
- return "text-red-400";
194
- };
195
- const formatDuration = (duration) => {
196
- if (!duration)
197
- return "—";
198
- if (duration < 1000)
199
- return `${duration}ms`;
200
- return `${(duration / 1000).toFixed(2)}s`;
201
- };
202
- const formatUrl = (url) => {
203
- try {
204
- const urlObj = new URL(url);
205
- return urlObj.pathname + urlObj.search;
206
- }
207
- catch (_a) {
208
- return url;
209
- }
210
- };
211
- const formatBody = (body) => {
212
- // Handle string bodies (common from server-side tracking)
213
- if (typeof body === "string") {
214
- // Handle potentially double-encoded JSON strings
215
- let current = body;
216
- let iterations = 0;
217
- const maxIterations = 3; // Prevent infinite loops
218
- while (typeof current === "string" && iterations < maxIterations) {
219
- try {
220
- const parsed = JSON.parse(current);
221
- current = parsed;
222
- iterations++;
223
- }
224
- catch (_a) {
225
- // Not valid JSON, break out
226
- break;
227
- }
228
- }
229
- // If we successfully parsed to a non-string, format it
230
- if (typeof current !== "string") {
231
- try {
232
- return JSON.stringify(current, null, 2);
233
- }
234
- catch (_b) {
235
- return String(current);
236
- }
237
- }
238
- // Return the string as-is
239
- return current;
240
- }
241
- // Handle object/array bodies
242
- if (body !== null && body !== undefined) {
243
- try {
244
- return JSON.stringify(body, null, 2);
245
- }
246
- catch (_c) {
247
- return String(body);
248
- }
249
- }
250
- return String(body);
251
- };
252
- if (requests.length === 0) {
253
- return (React.createElement("div", { className: "h-full w-full flex items-center justify-center bg-zinc-950" },
254
- React.createElement("div", { className: "text-center text-zinc-500" },
255
- React.createElement(Globe, { className: "w-8 h-8 mx-auto mb-2 opacity-50" }),
256
- React.createElement("p", { className: "text-sm" }, "No network requests yet"),
257
- React.createElement("p", { className: "text-xs mt-1 opacity-70" }, "Requests will appear here as they happen"))));
258
- }
259
- return (React.createElement("div", { className: "h-full w-full flex bg-zinc-950" },
260
- React.createElement("div", { className: cn("flex-1 overflow-auto border-r border-zinc-800", selectedRequest ? "w-1/2" : "w-full") },
261
- React.createElement("div", { className: "divide-y divide-zinc-800/50" }, requests.map((request, index) => {
262
- var _a, _b, _c, _d;
263
- return (React.createElement("button", { key: request.id || index, type: "button", onClick: () => setSelectedRequest((selectedRequest === null || selectedRequest === void 0 ? void 0 : selectedRequest.id) === request.id ? null : request), className: cn("w-full text-left px-3 py-2 hover:bg-zinc-900 transition-colors", (selectedRequest === null || selectedRequest === void 0 ? void 0 : selectedRequest.id) === request.id && "bg-zinc-900") },
264
- React.createElement("div", { className: "flex items-center gap-2 text-xs" },
265
- React.createElement("span", { className: cn("font-mono font-semibold w-12", getMethodColor(request.method)) }, request.method),
266
- React.createElement("span", { className: cn("font-mono w-10 text-center", getStatusColor((_a = request.responseStatus) !== null && _a !== void 0 ? _a : request.status)) }, (_c = (_b = request.responseStatus) !== null && _b !== void 0 ? _b : request.status) !== null && _c !== void 0 ? _c : "..."),
267
- React.createElement("span", { className: "flex-1 font-mono text-zinc-300 truncate" }, formatUrl(request.url)),
268
- React.createElement("span", { className: "text-zinc-500 font-mono text-[10px]" }, formatDuration((_d = request.duration) !== null && _d !== void 0 ? _d : request.ms)))));
269
- }))),
270
- selectedRequest && (React.createElement("div", { className: "w-1/2 overflow-auto" },
271
- React.createElement("div", { className: "p-3 space-y-3" },
272
- React.createElement("div", null,
273
- React.createElement("div", { className: "text-[10px] font-semibold uppercase tracking-wide mb-1", style: { color: themeColor } }, "Request"),
274
- React.createElement("div", { className: "bg-zinc-900 rounded p-2 text-xs font-mono" },
275
- React.createElement("div", { className: "flex items-center gap-2 mb-2" },
276
- React.createElement("span", { className: getMethodColor(selectedRequest.method) }, selectedRequest.method),
277
- React.createElement("span", { className: "text-zinc-300 break-all" }, selectedRequest.url)),
278
- selectedRequest.requestBody !== undefined &&
279
- selectedRequest.requestBody !== null && (React.createElement("pre", { className: "text-[10px] text-zinc-400 overflow-x-auto overflow-y-auto max-h-32 mt-2 pt-2 border-t border-zinc-800 whitespace-pre-wrap break-words" }, formatBody(selectedRequest.requestBody))))),
280
- React.createElement("div", null,
281
- React.createElement("div", { className: "text-[10px] font-semibold uppercase tracking-wide mb-1", style: { color: themeColor } }, "Response"),
282
- React.createElement("div", { className: "bg-zinc-900 rounded p-2 text-xs font-mono" },
283
- React.createElement("div", { className: "flex items-center gap-3 mb-2" },
284
- React.createElement("span", { className: getStatusColor((_a = selectedRequest.responseStatus) !== null && _a !== void 0 ? _a : selectedRequest.status) }, (_c = (_b = selectedRequest.responseStatus) !== null && _b !== void 0 ? _b : selectedRequest.status) !== null && _c !== void 0 ? _c : "Pending"),
285
- React.createElement("span", { className: "text-zinc-500" }, formatDuration((_d = selectedRequest.duration) !== null && _d !== void 0 ? _d : selectedRequest.ms))),
286
- selectedRequest.responseBody !== undefined &&
287
- selectedRequest.responseBody !== null && (React.createElement("pre", { className: "text-[10px] text-zinc-400 overflow-x-auto overflow-y-auto max-h-48 mt-2 pt-2 border-t border-zinc-800 whitespace-pre-wrap break-words" }, formatBody(selectedRequest.responseBody))),
288
- selectedRequest.error && (React.createElement("div", { className: "text-red-400 mt-2 pt-2 border-t border-zinc-800" }, selectedRequest.error)))))))));
289
- }
@@ -1,28 +0,0 @@
1
- "use client";
2
- import React, { useState, useEffect } from "react";
3
- import RightPanelView from "./right-panel-view";
4
- import RightTopDownView from "./right-top-down-view";
5
- import PreviewControlBar from "./preview-control-bar";
6
- export default function RightView({ reloadCounter, overlayStage, browserUrl, useVm, codeZipFile, completeCodeZipFile, variant = "top-down", themeColor, hasPreview, isGuardian = false, isBrowserMaximized = false, }) {
7
- const [isPreviewMinimized, setIsPreviewMinimized] = useState(false);
8
- const [reloadCounterState, setReloadCounterState] = useState(reloadCounter);
9
- // Sync with external reloadCounter changes
10
- useEffect(() => {
11
- setReloadCounterState(reloadCounter);
12
- }, [reloadCounter]);
13
- const handleRefresh = () => {
14
- setReloadCounterState((c) => c + 1);
15
- };
16
- if (variant === "panel") {
17
- return (React.createElement(RightPanelView, { reloadCounter: reloadCounterState, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile }));
18
- }
19
- else if (variant === "top-down") {
20
- return (React.createElement("div", { className: "h-full w-full flex flex-col" },
21
- hasPreview && (React.createElement(PreviewControlBar, { isMinimized: isPreviewMinimized, onToggle: () => setIsPreviewMinimized(!isPreviewMinimized), onRefresh: handleRefresh, themeColor: themeColor, externalUrl: browserUrl })),
22
- React.createElement("div", { className: "flex-1 min-h-0" },
23
- React.createElement(RightTopDownView, { reloadCounter: reloadCounterState, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, hasPreview: hasPreview, isPreviewMinimized: isPreviewMinimized, isGuardian: isGuardian, isBrowserMaximized: isBrowserMaximized }))));
24
- }
25
- else {
26
- return null;
27
- }
28
- }
@@ -1,234 +0,0 @@
1
- "use client";
2
- import React, { useEffect, useRef } from "react";
3
- import MonacoEditor from "@monaco-editor/react";
4
- import { useGuardianContext } from "../context/guardian-context";
5
- import { CodeLanguage } from "../types/ide-types";
6
- // import {useTheme} from "next-themes"; // Removed - not available in SDK
7
- import { useFrameParams } from "../hooks/use-frame-params";
8
- // Convert a hex color (e.g. "#3b82f6") to an rgba string with the given alpha.
9
- const hexToRgba = (hex, alpha) => {
10
- const normalized = hex.replace("#", "");
11
- const bigint = parseInt(normalized.length === 3
12
- ? normalized
13
- .split("")
14
- .map((c) => c + c)
15
- .join("")
16
- : normalized, 16);
17
- const r = (bigint >> 16) & 255;
18
- const g = (bigint >> 8) & 255;
19
- const b = bigint & 255;
20
- return `rgba(${r}, ${g}, ${b}, ${alpha})`;
21
- };
22
- export default function SimplifiedEditor({ themeColor }) {
23
- const { code, language, activeFileName: fileName, isGeneratingCode: isGenerating, activeLineNumber: contextActiveLineNumber, setActiveLineNumber, activeLineRange: contextActiveLineRange, } = useGuardianContext();
24
- // Use dark theme by default (next-themes not available in SDK)
25
- const theme = "dark";
26
- // Read frame params - these override context when isFrame=true
27
- const frameParams = useFrameParams();
28
- // Use frame param overrides when in frame mode
29
- const effectiveThemeColor = frameParams.isFrame && frameParams.theme ? frameParams.theme : themeColor;
30
- // Override line range if frame params specify them
31
- const activeLineNumber = frameParams.isFrame && frameParams.linesStart
32
- ? frameParams.linesStart
33
- : contextActiveLineNumber;
34
- const activeLineRange = frameParams.isFrame && frameParams.linesStart && frameParams.linesEnd
35
- ? { start: frameParams.linesStart, end: frameParams.linesEnd }
36
- : frameParams.isFrame && frameParams.linesStart
37
- ? { start: frameParams.linesStart, end: frameParams.linesStart }
38
- : contextActiveLineRange;
39
- // Add ref for the editor
40
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- const editorRef = useRef(null);
42
- // Store current decorations to clear them
43
- const currentDecorationsRef = useRef([]);
44
- // Define editor themes based on current system theme
45
- const editorTheme = theme === "dark" ? "vs-dark" : "vs-light";
46
- // Shared theme configuration
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- const configureEditorTheme = (monaco) => {
49
- monaco.editor.defineTheme("custom-dark", {
50
- base: "vs-dark",
51
- inherit: true,
52
- rules: [
53
- // Custom syntax highlighting rules for dark mode
54
- { token: "comment", foreground: "6A9955", fontStyle: "italic" },
55
- { token: "keyword", foreground: "C586C0", fontStyle: "bold" },
56
- { token: "string", foreground: "CE9178" },
57
- { token: "number", foreground: "B5CEA8" },
58
- ],
59
- colors: {
60
- // Custom UI colors for dark mode
61
- "editor.background": "#000000",
62
- "editor.foreground": "#D4D4D4",
63
- "editorCursor.foreground": "#AEAFAD",
64
- "editor.lineHighlightBackground": "#18181b",
65
- "editorLineNumber.foreground": "#858585",
66
- "editor.selectionBackground": "#264F78",
67
- "editor.inactiveSelectionBackground": "#3A3D41",
68
- },
69
- });
70
- // Apply the theme
71
- monaco.editor.setTheme(theme === "dark" ? "custom-dark" : "vs-light");
72
- };
73
- // Configure Monaco editor on mount
74
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
- const handleEditorDidMount = (editor, monaco) => {
76
- editorRef.current = editor;
77
- configureEditorTheme(monaco);
78
- };
79
- // Helper function to clear all decorations
80
- const clearAllDecorations = () => {
81
- if (currentDecorationsRef.current.length > 0) {
82
- if (editorRef.current) {
83
- editorRef.current.deltaDecorations(currentDecorationsRef.current, []);
84
- }
85
- currentDecorationsRef.current = [];
86
- }
87
- };
88
- // Effect to handle line navigation when activeLineNumber or activeLineRange changes
89
- useEffect(() => {
90
- // Always clear all existing decorations first
91
- clearAllDecorations();
92
- // Determine which line(s) to highlight
93
- let startLine;
94
- let endLine;
95
- if (activeLineRange) {
96
- startLine = activeLineRange.start;
97
- endLine = activeLineRange.end;
98
- }
99
- else if (activeLineNumber) {
100
- startLine = activeLineNumber;
101
- endLine = activeLineNumber;
102
- }
103
- // Only add new decorations if we have a line to highlight
104
- if (!startLine || !editorRef.current)
105
- return;
106
- const model = editorRef.current.getModel();
107
- if (!model)
108
- return;
109
- const totalLines = model.getLineCount();
110
- // Validate line numbers
111
- if (startLine < 1 || startLine > totalLines) {
112
- console.warn(`Invalid start line number ${startLine}. File has ${totalLines} lines.`);
113
- setActiveLineNumber === null || setActiveLineNumber === void 0 ? void 0 : setActiveLineNumber(undefined);
114
- return;
115
- }
116
- // If endLine is not provided, use startLine (single line)
117
- // If endLine is provided, validate it
118
- if (endLine === undefined) {
119
- endLine = startLine;
120
- }
121
- else if (endLine < 1 || endLine > totalLines) {
122
- // If endLine is invalid, default to startLine
123
- endLine = startLine;
124
- }
125
- // Ensure startLine <= endLine
126
- if (startLine > endLine) {
127
- [startLine, endLine] = [endLine, startLine];
128
- }
129
- // Center the entire highlighted range in the editor viewport
130
- editorRef.current.revealRangeInCenter({
131
- startLineNumber: startLine,
132
- startColumn: 1,
133
- endLineNumber: endLine,
134
- endColumn: model.getLineMaxColumn(endLine),
135
- });
136
- editorRef.current.setPosition({
137
- lineNumber: startLine,
138
- column: 1,
139
- });
140
- // Create decorations for all lines: highlight active range, mute others
141
- const decorations = [];
142
- for (let line = 1; line <= totalLines; line++) {
143
- const maxColumn = model.getLineMaxColumn(line);
144
- const isInHighlightRange = line >= startLine && line <= endLine;
145
- if (isInHighlightRange) {
146
- // Active lines: blue background highlight
147
- decorations.push({
148
- range: {
149
- startLineNumber: line,
150
- startColumn: 1,
151
- endLineNumber: line,
152
- endColumn: maxColumn,
153
- },
154
- options: {
155
- isWholeLine: true,
156
- className: "search-highlight-line",
157
- glyphMarginClassName: "search-highlight-glyph",
158
- },
159
- });
160
- }
161
- else {
162
- // All other lines: muted text
163
- decorations.push({
164
- range: {
165
- startLineNumber: line,
166
- startColumn: 1,
167
- endLineNumber: line,
168
- endColumn: maxColumn,
169
- },
170
- options: {
171
- inlineClassName: "muted-code-text",
172
- },
173
- });
174
- }
175
- }
176
- // Add new decorations
177
- const newDecorations = editorRef.current.deltaDecorations([], decorations);
178
- // Store the new decorations
179
- currentDecorationsRef.current = newDecorations;
180
- }, [activeLineNumber, activeLineRange, setActiveLineNumber]);
181
- // Update the theme when it changes
182
- useEffect(() => {
183
- const monaco = window.monaco;
184
- if (monaco) {
185
- monaco.editor.setTheme(theme === "dark" ? "custom-dark" : "vs-light");
186
- }
187
- }, [theme]);
188
- const highlightBackground = hexToRgba(effectiveThemeColor, 0.2);
189
- const glyphBackground = hexToRgba(effectiveThemeColor, 0.3);
190
- return (React.createElement("div", { className: "flex-1 flex flex-col min-h-0 h-full" },
191
- React.createElement("div", { className: "flex-1 min-h-0 relative" },
192
- React.createElement(MonacoEditor, { height: "100%", language: language
193
- ? language === CodeLanguage.TYPESCRIPT ||
194
- language === "tsx"
195
- ? "javascript"
196
- : language
197
- : CodeLanguage.TEXT, value: code, path: fileName, theme: editorTheme, onMount: handleEditorDidMount, options: Object.assign(Object.assign({ minimap: { enabled: false }, fontSize: 13, lineNumbers: "on", formatOnPaste: true, formatOnType: true, stickyScroll: {
198
- enabled: false,
199
- }, scrollBeyondLastLine: false, wordWrap: "on", wordWrapColumn: 120, wrappingIndent: "indent", wrappingStrategy: "advanced", automaticLayout: true, scrollbar: {
200
- vertical: "auto",
201
- horizontal: "hidden",
202
- verticalScrollbarSize: 8,
203
- horizontalScrollbarSize: 0,
204
- }, lineNumbersMinChars: 4, padding: { top: 6 } }, (theme === "dark" && {
205
- renderLineHighlight: "all",
206
- renderIndentGuides: true,
207
- colorDecorators: true,
208
- })), { domReadOnly: isGenerating, readOnly: isGenerating }) })),
209
- React.createElement("style", null, `
210
- :global(.search-highlight-line) {
211
- background-color: ${highlightBackground} !important;
212
- }
213
- :global(.search-highlight-glyph) {
214
- background-color: ${glyphBackground};
215
- }
216
- :global(.muted-code-text) {
217
- opacity: 0.5;
218
- filter: grayscale(0.4);
219
- }
220
- /* Remove blue focus outline from Monaco Editor */
221
- :global(.monaco-editor .inputarea.ime-input) {
222
- outline: none !important;
223
- }
224
- :global(.monaco-editor) {
225
- outline: none !important;
226
- }
227
- :global(.monaco-editor .monaco-editor-background) {
228
- outline: none !important;
229
- }
230
- :global(.monaco-editor .view-overlays) {
231
- outline: none !important;
232
- }
233
- `)));
234
- }