@cere/cere-design-system 0.0.44 → 0.1.0

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 (154) hide show
  1. package/dist/WorkflowNode-BnxXO6t_.d.mts +46 -0
  2. package/dist/WorkflowNode-BnxXO6t_.d.ts +46 -0
  3. package/dist/buttons.d.mts +114 -0
  4. package/dist/buttons.d.ts +114 -0
  5. package/dist/buttons.js +19 -0
  6. package/dist/buttons.js.map +1 -0
  7. package/dist/buttons.mjs +19 -0
  8. package/dist/buttons.mjs.map +1 -0
  9. package/dist/carousel.d.mts +51 -0
  10. package/dist/carousel.d.ts +51 -0
  11. package/dist/carousel.js +185 -0
  12. package/dist/carousel.js.map +1 -0
  13. package/dist/carousel.mjs +185 -0
  14. package/dist/carousel.mjs.map +1 -0
  15. package/dist/charts.d.mts +209 -0
  16. package/dist/charts.d.ts +209 -0
  17. package/dist/charts.js +20 -0
  18. package/dist/charts.js.map +1 -0
  19. package/dist/charts.mjs +20 -0
  20. package/dist/charts.mjs.map +1 -0
  21. package/dist/chunk-27JEWSWA.mjs +233 -0
  22. package/dist/chunk-27JEWSWA.mjs.map +1 -0
  23. package/dist/chunk-2EBCST6X.js +25 -0
  24. package/dist/chunk-2EBCST6X.js.map +1 -0
  25. package/dist/chunk-3WCMINE5.mjs +490 -0
  26. package/dist/chunk-3WCMINE5.mjs.map +1 -0
  27. package/dist/chunk-463SRKKD.js +111 -0
  28. package/dist/chunk-463SRKKD.js.map +1 -0
  29. package/dist/chunk-5ASG6G6U.mjs +40 -0
  30. package/dist/chunk-5ASG6G6U.mjs.map +1 -0
  31. package/dist/chunk-6EUAU67C.mjs +374 -0
  32. package/dist/chunk-6EUAU67C.mjs.map +1 -0
  33. package/dist/chunk-AIY6222Q.js +11 -0
  34. package/dist/chunk-AIY6222Q.js.map +1 -0
  35. package/dist/chunk-AJBM7IE6.mjs +2366 -0
  36. package/dist/chunk-AJBM7IE6.mjs.map +1 -0
  37. package/dist/chunk-ATIFLPH6.mjs +278 -0
  38. package/dist/chunk-ATIFLPH6.mjs.map +1 -0
  39. package/dist/chunk-BIZK6FUD.js +37 -0
  40. package/dist/chunk-BIZK6FUD.js.map +1 -0
  41. package/dist/chunk-CCN6M4LI.js +103 -0
  42. package/dist/chunk-CCN6M4LI.js.map +1 -0
  43. package/dist/chunk-CUCKULYC.mjs +2658 -0
  44. package/dist/chunk-CUCKULYC.mjs.map +1 -0
  45. package/dist/chunk-CWJ4OU6W.mjs +45 -0
  46. package/dist/chunk-CWJ4OU6W.mjs.map +1 -0
  47. package/dist/chunk-EOF3QNPF.js +2366 -0
  48. package/dist/chunk-EOF3QNPF.js.map +1 -0
  49. package/dist/chunk-FFZ5S7PQ.mjs +146 -0
  50. package/dist/chunk-FFZ5S7PQ.mjs.map +1 -0
  51. package/dist/chunk-FN5YL4BK.js +278 -0
  52. package/dist/chunk-FN5YL4BK.js.map +1 -0
  53. package/dist/chunk-HLH2VWXL.js +2658 -0
  54. package/dist/chunk-HLH2VWXL.js.map +1 -0
  55. package/dist/chunk-IE6GCHDI.mjs +530 -0
  56. package/dist/chunk-IE6GCHDI.mjs.map +1 -0
  57. package/dist/chunk-JBHRAAN3.js +31 -0
  58. package/dist/chunk-JBHRAAN3.js.map +1 -0
  59. package/dist/chunk-JS4IB5IU.mjs +162 -0
  60. package/dist/chunk-JS4IB5IU.mjs.map +1 -0
  61. package/dist/chunk-KF2Y7HO3.js +595 -0
  62. package/dist/chunk-KF2Y7HO3.js.map +1 -0
  63. package/dist/chunk-KPDYKK3V.js +162 -0
  64. package/dist/chunk-KPDYKK3V.js.map +1 -0
  65. package/dist/chunk-KVBMZNWT.mjs +103 -0
  66. package/dist/chunk-KVBMZNWT.mjs.map +1 -0
  67. package/dist/chunk-L2TIGA7I.js +530 -0
  68. package/dist/chunk-L2TIGA7I.js.map +1 -0
  69. package/dist/chunk-MNM6HE72.js +146 -0
  70. package/dist/chunk-MNM6HE72.js.map +1 -0
  71. package/dist/chunk-NXTVJ6PY.js +374 -0
  72. package/dist/chunk-NXTVJ6PY.js.map +1 -0
  73. package/dist/chunk-OWWDNDF4.js +40 -0
  74. package/dist/chunk-OWWDNDF4.js.map +1 -0
  75. package/dist/chunk-PHMNZK2R.mjs +18 -0
  76. package/dist/chunk-PHMNZK2R.mjs.map +1 -0
  77. package/dist/chunk-PWF2NJDB.mjs +377 -0
  78. package/dist/chunk-PWF2NJDB.mjs.map +1 -0
  79. package/dist/chunk-QBCRH7YF.mjs +37 -0
  80. package/dist/chunk-QBCRH7YF.mjs.map +1 -0
  81. package/dist/chunk-QD6RLAO2.mjs +11 -0
  82. package/dist/chunk-QD6RLAO2.mjs.map +1 -0
  83. package/dist/chunk-QY65OUAC.mjs +111 -0
  84. package/dist/chunk-QY65OUAC.mjs.map +1 -0
  85. package/dist/chunk-QYYQYZHV.js +45 -0
  86. package/dist/chunk-QYYQYZHV.js.map +1 -0
  87. package/dist/chunk-T7LPABOL.mjs +595 -0
  88. package/dist/chunk-T7LPABOL.mjs.map +1 -0
  89. package/dist/chunk-THQKYTQE.js +490 -0
  90. package/dist/chunk-THQKYTQE.js.map +1 -0
  91. package/dist/chunk-U2QHFISG.js +18 -0
  92. package/dist/chunk-U2QHFISG.js.map +1 -0
  93. package/dist/chunk-UPGFBPFX.mjs +25 -0
  94. package/dist/chunk-UPGFBPFX.mjs.map +1 -0
  95. package/dist/chunk-X7E6GMFL.js +233 -0
  96. package/dist/chunk-X7E6GMFL.js.map +1 -0
  97. package/dist/chunk-XF66WQZE.mjs +1535 -0
  98. package/dist/chunk-XF66WQZE.mjs.map +1 -0
  99. package/dist/chunk-YQOZPLTY.js +1535 -0
  100. package/dist/chunk-YQOZPLTY.js.map +1 -0
  101. package/dist/chunk-ZGCN5WCG.js +377 -0
  102. package/dist/chunk-ZGCN5WCG.js.map +1 -0
  103. package/dist/chunk-ZP26PGMS.mjs +31 -0
  104. package/dist/chunk-ZP26PGMS.mjs.map +1 -0
  105. package/dist/feedback.d.mts +356 -0
  106. package/dist/feedback.d.ts +356 -0
  107. package/dist/feedback.js +43 -0
  108. package/dist/feedback.js.map +1 -0
  109. package/dist/feedback.mjs +43 -0
  110. package/dist/feedback.mjs.map +1 -0
  111. package/dist/icons.d.mts +22 -0
  112. package/dist/icons.d.ts +22 -0
  113. package/dist/icons.js +23 -0
  114. package/dist/icons.js.map +1 -0
  115. package/dist/icons.mjs +23 -0
  116. package/dist/icons.mjs.map +1 -0
  117. package/dist/index.d.mts +171 -3069
  118. package/dist/index.d.ts +171 -3069
  119. package/dist/index.js +320 -10077
  120. package/dist/index.js.map +1 -1
  121. package/dist/index.mjs +262 -9978
  122. package/dist/index.mjs.map +1 -1
  123. package/dist/inputs.d.mts +109 -0
  124. package/dist/inputs.d.ts +109 -0
  125. package/dist/inputs.js +43 -0
  126. package/dist/inputs.js.map +1 -0
  127. package/dist/inputs.mjs +43 -0
  128. package/dist/inputs.mjs.map +1 -0
  129. package/dist/layout.d.mts +927 -0
  130. package/dist/layout.d.ts +927 -0
  131. package/dist/layout.js +122 -0
  132. package/dist/layout.js.map +1 -0
  133. package/dist/layout.mjs +122 -0
  134. package/dist/layout.mjs.map +1 -0
  135. package/dist/navigation.d.mts +716 -0
  136. package/dist/navigation.d.ts +716 -0
  137. package/dist/navigation.js +58 -0
  138. package/dist/navigation.js.map +1 -0
  139. package/dist/navigation.mjs +58 -0
  140. package/dist/navigation.mjs.map +1 -0
  141. package/dist/third-party.d.mts +637 -0
  142. package/dist/third-party.d.ts +637 -0
  143. package/dist/third-party.js +45 -0
  144. package/dist/third-party.js.map +1 -0
  145. package/dist/third-party.mjs +45 -0
  146. package/dist/third-party.mjs.map +1 -0
  147. package/dist/tokens.css +2 -1
  148. package/dist/utilities.d.mts +39 -0
  149. package/dist/utilities.d.ts +39 -0
  150. package/dist/utilities.js +19 -0
  151. package/dist/utilities.js.map +1 -0
  152. package/dist/utilities.mjs +19 -0
  153. package/dist/utilities.mjs.map +1 -0
  154. package/package.json +55 -1
@@ -0,0 +1,1535 @@
1
+ import {
2
+ WORKFLOW_NODE_SHADOW,
3
+ WorkflowNode
4
+ } from "./chunk-27JEWSWA.mjs";
5
+ import {
6
+ CereIcon
7
+ } from "./chunk-UPGFBPFX.mjs";
8
+ import {
9
+ workflowNodeColors
10
+ } from "./chunk-PWF2NJDB.mjs";
11
+
12
+ // src/components/third-party/FlowEditor.tsx
13
+ import { useCallback } from "react";
14
+ import ReactFlow, {
15
+ Background,
16
+ Controls,
17
+ MiniMap,
18
+ ReactFlowProvider,
19
+ BackgroundVariant,
20
+ ConnectionLineType
21
+ } from "reactflow";
22
+ import { Box } from "@mui/material";
23
+ import { useTheme } from "@mui/material/styles";
24
+ import { Background as Background2, Controls as Controls2, MiniMap as MiniMap2, Panel, BackgroundVariant as BackgroundVariant2, ConnectionLineType as ConnectionLineType2 } from "reactflow";
25
+ import { jsx, jsxs } from "react/jsx-runtime";
26
+ var FlowEditor = ({
27
+ nodes,
28
+ edges,
29
+ onNodesChange,
30
+ onEdgesChange,
31
+ nodeTypes,
32
+ edgeTypes,
33
+ height = "600px",
34
+ showBackground = true,
35
+ backgroundVariant = BackgroundVariant.Dots,
36
+ showControls = true,
37
+ showMinimap = false,
38
+ showBorder = true,
39
+ borderRadius = 1,
40
+ nodesDraggable = true,
41
+ containerProps,
42
+ minimapProps,
43
+ onInit,
44
+ ...reactFlowProps
45
+ }) => {
46
+ const theme = useTheme();
47
+ const handleInit = useCallback(
48
+ (instance) => {
49
+ if (onInit) {
50
+ onInit(instance);
51
+ }
52
+ },
53
+ [onInit]
54
+ );
55
+ const { sx: containerSx, ...restContainerProps } = containerProps ?? {};
56
+ return /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
57
+ Box,
58
+ {
59
+ sx: [
60
+ {
61
+ width: "100%",
62
+ height: typeof height === "number" ? `${height}px` : height,
63
+ overflow: "hidden",
64
+ ...showBorder && { border: `1px solid ${theme.palette.divider}` },
65
+ borderRadius,
66
+ backgroundColor: theme.palette.background.paper
67
+ },
68
+ ...Array.isArray(containerSx) ? containerSx : [containerSx]
69
+ ],
70
+ ...restContainerProps,
71
+ children: /* @__PURE__ */ jsxs(
72
+ ReactFlow,
73
+ {
74
+ nodes,
75
+ edges,
76
+ onNodesChange,
77
+ onEdgesChange,
78
+ nodeTypes,
79
+ edgeTypes,
80
+ onInit: handleInit,
81
+ nodesDraggable,
82
+ connectionLineType: ConnectionLineType.SmoothStep,
83
+ defaultEdgeOptions: {
84
+ style: {
85
+ stroke: theme.palette.primary.main,
86
+ strokeWidth: 2
87
+ }
88
+ },
89
+ style: {
90
+ backgroundColor: "transparent"
91
+ },
92
+ ...reactFlowProps,
93
+ children: [
94
+ showBackground && /* @__PURE__ */ jsx(
95
+ Background,
96
+ {
97
+ variant: backgroundVariant,
98
+ gap: 16,
99
+ size: 1,
100
+ color: theme.palette.divider
101
+ }
102
+ ),
103
+ showControls && /* @__PURE__ */ jsx(Controls, {}),
104
+ showMinimap && /* @__PURE__ */ jsx(
105
+ MiniMap,
106
+ {
107
+ nodeColor: (node) => {
108
+ const color = node.data?.color || theme.palette.primary.main;
109
+ return typeof color === "string" ? color : theme.palette.primary.main;
110
+ },
111
+ nodeStrokeWidth: 3,
112
+ nodeBorderRadius: 8,
113
+ maskColor: `${theme.palette.background.paper}80`,
114
+ style: {
115
+ backgroundColor: theme.palette.background.paper
116
+ },
117
+ ...minimapProps
118
+ }
119
+ )
120
+ ]
121
+ }
122
+ )
123
+ }
124
+ ) });
125
+ };
126
+
127
+ // src/components/third-party/CodeEditor.tsx
128
+ import { useCallback as useCallback2, useEffect, useState, useRef } from "react";
129
+ import Editor from "@monaco-editor/react";
130
+ import { Box as Box2, IconButton, Tooltip } from "@mui/material";
131
+ import FullscreenIcon from "@mui/icons-material/Fullscreen";
132
+ import FullscreenExitIcon from "@mui/icons-material/FullscreenExit";
133
+ import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
134
+ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
135
+ import ExpandLessIcon from "@mui/icons-material/ExpandLess";
136
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
137
+ var configureTypeScript = (monaco) => {
138
+ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
139
+ target: monaco.languages.typescript.ScriptTarget.ES2020,
140
+ allowNonTsExtensions: true,
141
+ moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
142
+ module: monaco.languages.typescript.ModuleKind.ESNext,
143
+ noEmit: false,
144
+ lib: ["es2020", "dom"],
145
+ noUnusedLocals: false,
146
+ noUnusedParameters: false,
147
+ noImplicitAny: false,
148
+ noImplicitReturns: false,
149
+ noFallthroughCasesInSwitch: false,
150
+ // Treat every file as a module so top-level declarations don't clash
151
+ // across files in the workspace (prevents false "Cannot redeclare" errors).
152
+ moduleDetection: 3
153
+ // ts.ModuleDetectionKind.Force
154
+ });
155
+ monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
156
+ noSemanticValidation: false,
157
+ noSyntaxValidation: false,
158
+ noSuggestionDiagnostics: true,
159
+ diagnosticCodesToIgnore: [
160
+ 6133,
161
+ // 'x' is declared but its value is never read
162
+ 6196
163
+ // 'x' is declared but its value is never read (different variant)
164
+ ]
165
+ });
166
+ };
167
+ var CodeEditor = ({
168
+ value,
169
+ onChange,
170
+ language = "typescript",
171
+ height = "400px",
172
+ minHeight,
173
+ theme: themeProp,
174
+ lineNumbers = "on",
175
+ options,
176
+ onMount,
177
+ onValidate,
178
+ editorRef,
179
+ monacoRef,
180
+ onFullscreenChange,
181
+ containerProps,
182
+ typeDefinitions,
183
+ externalModelManagement = false
184
+ }) => {
185
+ const [isEditorReady, setIsEditorReady] = useState(false);
186
+ const [validationErrors, setValidationErrors] = useState([]);
187
+ const [isFullscreen, setIsFullscreen] = useState(false);
188
+ const [tsCode, setTsCode] = useState(value);
189
+ const [actualHeight, setActualHeight] = useState(
190
+ typeof height === "number" ? `${height}px` : height
191
+ );
192
+ const [showProblems, setShowProblems] = useState(false);
193
+ const [hasUserToggledProblems, setHasUserToggledProblems] = useState(false);
194
+ useEffect(() => {
195
+ if (hasUserToggledProblems) return;
196
+ if (validationErrors.length > 0) {
197
+ setShowProblems(true);
198
+ } else {
199
+ setShowProblems(false);
200
+ }
201
+ }, [validationErrors, hasUserToggledProblems]);
202
+ const internalEditorRef = useRef(null);
203
+ const internalMonacoRef = useRef(null);
204
+ const finalEditorRef = editorRef || internalEditorRef;
205
+ const finalMonacoRef = monacoRef || internalMonacoRef;
206
+ useEffect(() => {
207
+ if (isFullscreen) {
208
+ setActualHeight("calc(100vh - 80px)");
209
+ } else {
210
+ setActualHeight(typeof height === "number" ? `${height}px` : height);
211
+ }
212
+ }, [height, isFullscreen]);
213
+ const toggleFullscreen = useCallback2(() => {
214
+ const newFullscreenState = !isFullscreen;
215
+ setIsFullscreen(newFullscreenState);
216
+ if (onFullscreenChange) {
217
+ onFullscreenChange(newFullscreenState);
218
+ }
219
+ }, [isFullscreen, onFullscreenChange]);
220
+ const gotoMarker = useCallback2(
221
+ (marker) => {
222
+ const ed = finalEditorRef?.current;
223
+ if (!ed) return;
224
+ const position = { lineNumber: marker.startLineNumber, column: marker.startColumn || 1 };
225
+ try {
226
+ ed.revealPositionInCenter(position);
227
+ ed.setPosition(position);
228
+ ed.focus();
229
+ } catch (e) {
230
+ console.error("CodeEditor: Failed to navigate to marker", e);
231
+ }
232
+ },
233
+ [finalEditorRef]
234
+ );
235
+ useEffect(() => {
236
+ if (!isFullscreen) return;
237
+ function escapeHandler(event) {
238
+ if (event.key === "Escape") {
239
+ event.preventDefault();
240
+ event.stopPropagation();
241
+ setIsFullscreen(false);
242
+ if (onFullscreenChange) {
243
+ onFullscreenChange(false);
244
+ }
245
+ }
246
+ }
247
+ window.addEventListener("keydown", escapeHandler, { capture: true });
248
+ return () => {
249
+ window.removeEventListener("keydown", escapeHandler, { capture: true });
250
+ };
251
+ }, [isFullscreen, onFullscreenChange]);
252
+ const handleEditorDidMount = useCallback2(
253
+ (editor, monaco) => {
254
+ console.log("CodeEditor: onMount called", { editor: !!editor, monaco: !!monaco });
255
+ try {
256
+ configureTypeScript(monaco);
257
+ } catch (e) {
258
+ console.error("CodeEditor: Failed to configure TypeScript", e);
259
+ }
260
+ if (finalEditorRef) {
261
+ finalEditorRef.current = editor;
262
+ }
263
+ if (finalMonacoRef) {
264
+ finalMonacoRef.current = monaco;
265
+ }
266
+ setIsEditorReady(true);
267
+ console.log("CodeEditor: Editor ready");
268
+ try {
269
+ editor.addCommand(monaco.KeyCode.Escape, () => {
270
+ if (isFullscreen) {
271
+ setIsFullscreen(false);
272
+ if (onFullscreenChange) {
273
+ onFullscreenChange(false);
274
+ }
275
+ return true;
276
+ }
277
+ return false;
278
+ });
279
+ editor.onDidChangeModelDecorations(() => {
280
+ const model2 = editor.getModel();
281
+ if (model2 && onValidate) {
282
+ const markers = monaco.editor.getModelMarkers({ resource: model2.uri });
283
+ onValidate(markers);
284
+ setValidationErrors(markers);
285
+ }
286
+ });
287
+ const model = editor.getModel();
288
+ if (model && onValidate) {
289
+ const markers = monaco.editor.getModelMarkers({ resource: model.uri });
290
+ onValidate(markers);
291
+ setValidationErrors(markers);
292
+ }
293
+ } catch (e) {
294
+ console.error("CodeEditor: Error setting up editor callbacks", e);
295
+ }
296
+ if (onMount) {
297
+ try {
298
+ onMount(editor, monaco);
299
+ } catch (e) {
300
+ console.error("CodeEditor: Error in custom onMount", e);
301
+ }
302
+ }
303
+ },
304
+ [isFullscreen, onFullscreenChange, onValidate, onMount, finalEditorRef, finalMonacoRef]
305
+ );
306
+ useEffect(() => {
307
+ if (!isEditorReady || !finalMonacoRef?.current || !typeDefinitions) return;
308
+ const monaco = finalMonacoRef.current;
309
+ const definitions = Array.isArray(typeDefinitions) ? typeDefinitions : [typeDefinitions];
310
+ const uris = [];
311
+ try {
312
+ definitions.forEach((def, index) => {
313
+ if (def && def.trim()) {
314
+ const uri = `ts:filename/custom-types-${index}.d.ts`;
315
+ uris.push(uri);
316
+ monaco.languages.typescript.typescriptDefaults.addExtraLib(def, uri);
317
+ }
318
+ });
319
+ } catch (error) {
320
+ console.error("CodeEditor: Error adding type definitions:", error);
321
+ }
322
+ }, [isEditorReady, finalMonacoRef, typeDefinitions]);
323
+ const handleCodeChange = (newValue) => {
324
+ const valueStr = newValue || "";
325
+ setTsCode(valueStr);
326
+ onChange(valueStr);
327
+ };
328
+ useEffect(() => {
329
+ if (externalModelManagement) return;
330
+ if (value !== tsCode) {
331
+ setTsCode(value);
332
+ if (isEditorReady && finalEditorRef?.current) {
333
+ const editor = finalEditorRef.current;
334
+ const currentValue = editor.getValue();
335
+ if (currentValue !== value) {
336
+ editor.setValue(value);
337
+ }
338
+ }
339
+ }
340
+ }, [value, tsCode, isEditorReady, finalEditorRef, externalModelManagement]);
341
+ const editorMinHeight = minHeight ? typeof minHeight === "number" ? `${minHeight}px` : minHeight : "400px";
342
+ const defaultOptions = {
343
+ lineNumbers,
344
+ minimap: { enabled: false },
345
+ readOnly: false,
346
+ wordWrap: "on",
347
+ fontSize: 14,
348
+ fontFamily: 'Monaco, Menlo, "Ubuntu Mono", Consolas, "source-code-pro", monospace',
349
+ automaticLayout: true,
350
+ scrollBeyondLastLine: false,
351
+ theme: themeProp || "vs",
352
+ ...options
353
+ };
354
+ return /* @__PURE__ */ jsx2(
355
+ Box2,
356
+ {
357
+ sx: {
358
+ display: "flex",
359
+ flexDirection: "column",
360
+ height: isFullscreen ? "100vh" : "100%",
361
+ minHeight: isFullscreen ? "100vh" : editorMinHeight,
362
+ position: isFullscreen ? "fixed" : "relative",
363
+ top: isFullscreen ? 0 : "auto",
364
+ left: isFullscreen ? 0 : "auto",
365
+ right: isFullscreen ? 0 : "auto",
366
+ bottom: isFullscreen ? 0 : "auto",
367
+ zIndex: isFullscreen ? 9999 : "auto",
368
+ bgcolor: "background.paper",
369
+ pt: isFullscreen ? "80px" : 0,
370
+ // Add padding top in fullscreen to account for header (64px) + spacing (16px)
371
+ px: isFullscreen ? 2 : 0,
372
+ pb: isFullscreen ? 2 : 0,
373
+ overflow: isFullscreen ? "hidden" : "visible"
374
+ },
375
+ children: /* @__PURE__ */ jsxs2(
376
+ Box2,
377
+ {
378
+ sx: {
379
+ flex: 1,
380
+ border: 1,
381
+ borderColor: validationErrors.length > 0 ? "error.main" : "divider",
382
+ borderRadius: 1,
383
+ minHeight: editorMinHeight,
384
+ overflow: "hidden",
385
+ position: "relative",
386
+ display: "flex",
387
+ flexDirection: "column"
388
+ },
389
+ ...containerProps,
390
+ children: [
391
+ /* @__PURE__ */ jsx2(Tooltip, { title: isFullscreen ? "Exit Fullscreen" : "Fullscreen", children: /* @__PURE__ */ jsx2(
392
+ IconButton,
393
+ {
394
+ onClick: toggleFullscreen,
395
+ size: "small",
396
+ sx: {
397
+ position: isFullscreen ? "fixed" : "absolute",
398
+ top: isFullscreen ? 72 : 8,
399
+ // Position below header in fullscreen mode (header is ~64px)
400
+ right: isFullscreen ? 16 : 8,
401
+ zIndex: 1e4,
402
+ // Ensure it's above other elements
403
+ bgcolor: "rgba(255, 255, 255, 0.7)",
404
+ "&:hover": {
405
+ bgcolor: "rgba(255, 255, 255, 0.9)"
406
+ },
407
+ boxShadow: 1
408
+ },
409
+ children: isFullscreen ? /* @__PURE__ */ jsx2(FullscreenExitIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx2(FullscreenIcon, { fontSize: "small" })
410
+ }
411
+ ) }),
412
+ /* @__PURE__ */ jsx2(
413
+ Box2,
414
+ {
415
+ sx: {
416
+ flex: 1,
417
+ display: "flex",
418
+ flexDirection: "column",
419
+ overflow: "hidden",
420
+ minHeight: editorMinHeight,
421
+ position: "relative",
422
+ height: isFullscreen ? "100%" : actualHeight
423
+ },
424
+ children: /* @__PURE__ */ jsx2(
425
+ Editor,
426
+ {
427
+ height: "100%",
428
+ defaultLanguage: language,
429
+ defaultValue: value,
430
+ value: tsCode,
431
+ onChange: handleCodeChange,
432
+ onMount: handleEditorDidMount,
433
+ theme: themeProp || "vs",
434
+ options: defaultOptions,
435
+ loading: /* @__PURE__ */ jsx2(Box2, { sx: { p: 2, textAlign: "center" }, children: "Loading Monaco Editor..." }),
436
+ beforeMount: (monaco) => {
437
+ console.log("CodeEditor: beforeMount called", { monaco: !!monaco });
438
+ }
439
+ }
440
+ )
441
+ }
442
+ ),
443
+ validationErrors.length > 0 && /* @__PURE__ */ jsxs2(
444
+ Box2,
445
+ {
446
+ sx: {
447
+ borderTop: 1,
448
+ borderColor: "divider",
449
+ bgcolor: "background.default",
450
+ display: "flex",
451
+ flexDirection: "column",
452
+ maxHeight: showProblems ? 180 : 40,
453
+ minHeight: 40,
454
+ transition: "max-height 0.2s ease"
455
+ },
456
+ children: [
457
+ /* @__PURE__ */ jsxs2(
458
+ Box2,
459
+ {
460
+ sx: {
461
+ display: "flex",
462
+ alignItems: "center",
463
+ px: 1,
464
+ py: 0.5,
465
+ gap: 1,
466
+ borderBottom: showProblems ? "1px solid" : "none",
467
+ borderColor: "divider",
468
+ fontSize: "0.875rem",
469
+ color: "text.secondary"
470
+ },
471
+ children: [
472
+ /* @__PURE__ */ jsx2(ErrorOutlineIcon, { color: "error", fontSize: "small" }),
473
+ /* @__PURE__ */ jsx2(Box2, { sx: { fontWeight: 600, color: "text.primary" }, children: "Problems" }),
474
+ /* @__PURE__ */ jsxs2(Box2, { sx: { ml: 1 }, children: [
475
+ validationErrors.length,
476
+ " error",
477
+ validationErrors.length > 1 ? "s" : ""
478
+ ] }),
479
+ /* @__PURE__ */ jsx2(Box2, { sx: { flex: 1 } }),
480
+ /* @__PURE__ */ jsx2(
481
+ IconButton,
482
+ {
483
+ size: "small",
484
+ "aria-label": "Toggle problems panel",
485
+ onClick: () => {
486
+ setHasUserToggledProblems(true);
487
+ setShowProblems((s) => !s);
488
+ },
489
+ children: showProblems ? /* @__PURE__ */ jsx2(ExpandMoreIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx2(ExpandLessIcon, { fontSize: "small" })
490
+ }
491
+ )
492
+ ]
493
+ }
494
+ ),
495
+ showProblems && /* @__PURE__ */ jsx2(Box2, { sx: { overflow: "auto" }, children: validationErrors.map((error, index) => /* @__PURE__ */ jsxs2(
496
+ Box2,
497
+ {
498
+ onClick: () => gotoMarker(error),
499
+ sx: {
500
+ display: "flex",
501
+ alignItems: "center",
502
+ px: 1.5,
503
+ py: 0.75,
504
+ gap: 1,
505
+ cursor: "pointer",
506
+ "&:hover": { bgcolor: "action.hover" },
507
+ borderBottom: "1px dashed",
508
+ borderColor: "divider",
509
+ fontSize: "0.85rem"
510
+ },
511
+ children: [
512
+ /* @__PURE__ */ jsx2(ErrorOutlineIcon, { color: "error", sx: { fontSize: 18 } }),
513
+ /* @__PURE__ */ jsxs2(Box2, { sx: { color: "text.secondary", width: 64 }, children: [
514
+ "Line ",
515
+ error.startLineNumber
516
+ ] }),
517
+ /* @__PURE__ */ jsx2(Box2, { sx: { color: "text.primary", flex: 1, minWidth: 0 }, children: error.message })
518
+ ]
519
+ },
520
+ `${error.startLineNumber}-${error.startColumn}-${index}`
521
+ )) })
522
+ ]
523
+ }
524
+ )
525
+ ]
526
+ }
527
+ )
528
+ }
529
+ );
530
+ };
531
+
532
+ // src/components/third-party/index.ts
533
+ import { Panel as Panel2 } from "reactflow";
534
+
535
+ // src/components/third-party/WorkflowNodeHandle.tsx
536
+ import { Handle, Position } from "reactflow";
537
+ import { useTheme as useTheme2 } from "@mui/material";
538
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
539
+ var WorkflowNodeHandle = ({
540
+ data,
541
+ selected
542
+ }) => {
543
+ const theme = useTheme2();
544
+ const handleColor = workflowNodeColors[data.nodeType].accent;
545
+ const handleStyle = {
546
+ width: 8,
547
+ height: 8,
548
+ borderRadius: "999px",
549
+ border: `2px solid ${theme.palette.common.white}`,
550
+ background: handleColor,
551
+ boxShadow: WORKFLOW_NODE_SHADOW
552
+ };
553
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
554
+ /* @__PURE__ */ jsx3(Handle, { type: "target", position: Position.Left, style: handleStyle }),
555
+ /* @__PURE__ */ jsx3(
556
+ WorkflowNode,
557
+ {
558
+ nodeType: data.nodeType,
559
+ title: data.title,
560
+ description: data.description,
561
+ icon: data.icon,
562
+ badgeLabel: data.badgeLabel,
563
+ selected,
564
+ showSideDots: false
565
+ }
566
+ ),
567
+ /* @__PURE__ */ jsx3(Handle, { type: "source", position: Position.Right, style: handleStyle })
568
+ ] });
569
+ };
570
+
571
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorWorkspace.types.ts
572
+ var EXTENSION_LANGUAGE_MAP = {
573
+ ts: "typescript",
574
+ tsx: "typescript",
575
+ js: "javascript",
576
+ jsx: "javascript",
577
+ json: "json",
578
+ html: "html",
579
+ htm: "html",
580
+ css: "css",
581
+ py: "python",
582
+ yaml: "yaml",
583
+ yml: "yaml",
584
+ md: "markdown",
585
+ sql: "sql",
586
+ xml: "xml",
587
+ txt: "plaintext"
588
+ };
589
+ function detectLanguage(path) {
590
+ const ext = path.split(".").pop()?.toLowerCase() ?? "";
591
+ return EXTENSION_LANGUAGE_MAP[ext] ?? "plaintext";
592
+ }
593
+ function getFileName(path) {
594
+ return path.split("/").pop() ?? path;
595
+ }
596
+
597
+ // src/components/third-party/CodeEditorWorkspace/useCodeEditorWorkspace.ts
598
+ import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
599
+ function useCodeEditorWorkspace({
600
+ files,
601
+ initialOpenPaths,
602
+ onFileChange,
603
+ onValidationChange
604
+ }) {
605
+ const fileContentsRef = useRef2(/* @__PURE__ */ new Map());
606
+ const originalContentsRef = useRef2(/* @__PURE__ */ new Map());
607
+ const [openTabs, setOpenTabs] = useState2([]);
608
+ const [activeFilePath, setActiveFilePath] = useState2(null);
609
+ const monacoRef = useRef2(null);
610
+ const editorRef = useRef2(null);
611
+ const modelsRef = useRef2(/* @__PURE__ */ new Map());
612
+ const [validationMarkers, setValidationMarkers] = useState2({});
613
+ const [cursorPosition, setCursorPosition] = useState2(null);
614
+ useEffect2(() => {
615
+ for (const file of files) {
616
+ if (!fileContentsRef.current.has(file.path)) {
617
+ fileContentsRef.current.set(file.path, file.value);
618
+ originalContentsRef.current.set(file.path, file.value);
619
+ }
620
+ const model = modelsRef.current.get(file.path);
621
+ if (model && !model.isDisposed()) {
622
+ if (file.value === fileContentsRef.current.get(file.path)) {
623
+ originalContentsRef.current.set(file.path, file.value);
624
+ continue;
625
+ }
626
+ if (originalContentsRef.current.get(file.path) !== file.value) {
627
+ const localContent = fileContentsRef.current.get(file.path) ?? "";
628
+ const previousOriginal = originalContentsRef.current.get(file.path) ?? "";
629
+ originalContentsRef.current.set(file.path, file.value);
630
+ if (localContent === previousOriginal) {
631
+ fileContentsRef.current.set(file.path, file.value);
632
+ model.setValue(file.value);
633
+ }
634
+ }
635
+ }
636
+ }
637
+ }, [files]);
638
+ useEffect2(() => {
639
+ if (initialOpenPaths && initialOpenPaths.length > 0) {
640
+ const tabs = initialOpenPaths.filter((p) => files.some((f) => f.path === p)).map((p) => ({
641
+ path: p,
642
+ label: getFileName(p),
643
+ isDirty: false
644
+ }));
645
+ if (tabs.length > 0) {
646
+ setOpenTabs(tabs);
647
+ setActiveFilePath(tabs[0].path);
648
+ }
649
+ }
650
+ }, []);
651
+ const getOrCreateModel = useCallback3(
652
+ (path) => {
653
+ const monaco = monacoRef.current;
654
+ if (!monaco) return null;
655
+ const existing = modelsRef.current.get(path);
656
+ if (existing && !existing.isDisposed()) return existing;
657
+ const file = files.find((f) => f.path === path);
658
+ const content = fileContentsRef.current.get(path) ?? file?.value ?? "";
659
+ const lang = file?.language ?? detectLanguage(path);
660
+ const uri = monaco.Uri.parse(`file:///${path}`);
661
+ let model = monaco.editor.getModel(uri);
662
+ if (!model) {
663
+ model = monaco.editor.createModel(content, lang, uri);
664
+ }
665
+ modelsRef.current.set(path, model);
666
+ return model;
667
+ },
668
+ [files]
669
+ );
670
+ const disposeModel = useCallback3((path) => {
671
+ const model = modelsRef.current.get(path);
672
+ if (model && !model.isDisposed()) {
673
+ model.dispose();
674
+ }
675
+ modelsRef.current.delete(path);
676
+ }, []);
677
+ const switchToFile = useCallback3(
678
+ (path) => {
679
+ const ed = editorRef.current;
680
+ if (!ed) return;
681
+ const model = getOrCreateModel(path);
682
+ if (model) {
683
+ ed.setModel(model);
684
+ }
685
+ },
686
+ [getOrCreateModel]
687
+ );
688
+ const openFile = useCallback3(
689
+ (path) => {
690
+ const file = files.find((f) => f.path === path);
691
+ if (!file) return;
692
+ if (!fileContentsRef.current.has(path)) {
693
+ fileContentsRef.current.set(path, file.value);
694
+ originalContentsRef.current.set(path, file.value);
695
+ }
696
+ setOpenTabs((prev) => {
697
+ const exists = prev.some((t) => t.path === path);
698
+ if (exists) return prev;
699
+ return [
700
+ ...prev,
701
+ { path, label: getFileName(path), isDirty: false }
702
+ ];
703
+ });
704
+ setActiveFilePath(path);
705
+ switchToFile(path);
706
+ },
707
+ [files, switchToFile]
708
+ );
709
+ const closeFile = useCallback3(
710
+ (path) => {
711
+ disposeModel(path);
712
+ setOpenTabs((prev) => {
713
+ const newTabs = prev.filter((t) => t.path !== path);
714
+ if (activeFilePath === path) {
715
+ const closedIndex = prev.findIndex((t) => t.path === path);
716
+ const nextTab = newTabs[Math.min(closedIndex, newTabs.length - 1)] ?? null;
717
+ const nextPath = nextTab?.path ?? null;
718
+ setActiveFilePath(nextPath);
719
+ if (nextPath) {
720
+ switchToFile(nextPath);
721
+ }
722
+ }
723
+ return newTabs;
724
+ });
725
+ },
726
+ [activeFilePath, disposeModel, switchToFile]
727
+ );
728
+ const setActiveFileAction = useCallback3(
729
+ (path) => {
730
+ setActiveFilePath(path);
731
+ switchToFile(path);
732
+ },
733
+ [switchToFile]
734
+ );
735
+ const updateFileContent = useCallback3(
736
+ (path, value) => {
737
+ fileContentsRef.current.set(path, value);
738
+ const model = modelsRef.current.get(path);
739
+ if (model && !model.isDisposed() && model.getValue() !== value) {
740
+ model.setValue(value);
741
+ }
742
+ const isDirty = value !== originalContentsRef.current.get(path);
743
+ setOpenTabs(
744
+ (prev) => prev.map((t) => t.path === path ? { ...t, isDirty } : t)
745
+ );
746
+ onFileChange?.(path, value);
747
+ },
748
+ [onFileChange]
749
+ );
750
+ const getFileContent = useCallback3((path) => {
751
+ return fileContentsRef.current.get(path);
752
+ }, []);
753
+ const markSaved = useCallback3((path) => {
754
+ const content = fileContentsRef.current.get(path);
755
+ if (content !== void 0) {
756
+ originalContentsRef.current.set(path, content);
757
+ }
758
+ setOpenTabs(
759
+ (prev) => prev.map((t) => t.path === path ? { ...t, isDirty: false } : t)
760
+ );
761
+ }, []);
762
+ const markAllSaved = useCallback3(() => {
763
+ for (const [path, content] of fileContentsRef.current.entries()) {
764
+ originalContentsRef.current.set(path, content);
765
+ }
766
+ setOpenTabs((prev) => prev.map((t) => ({ ...t, isDirty: false })));
767
+ }, []);
768
+ const handleEditorMount = useCallback3(
769
+ (editorInstance, monacoInstance) => {
770
+ monacoRef.current = monacoInstance;
771
+ editorRef.current = editorInstance;
772
+ if (activeFilePath) {
773
+ const model = getOrCreateModel(activeFilePath);
774
+ if (model) {
775
+ editorInstance.setModel(model);
776
+ }
777
+ }
778
+ editorInstance.onDidChangeCursorPosition((e) => {
779
+ setCursorPosition({ line: e.position.lineNumber, column: e.position.column });
780
+ });
781
+ const pos = editorInstance.getPosition();
782
+ if (pos) {
783
+ setCursorPosition({ line: pos.lineNumber, column: pos.column });
784
+ }
785
+ monacoInstance.editor.onDidChangeMarkers((uris) => {
786
+ const newMarkers = { ...validationMarkers };
787
+ for (const uri of uris) {
788
+ const path = uri.path.replace(/^\//, "");
789
+ const markers = monacoInstance.editor.getModelMarkers({ resource: uri });
790
+ newMarkers[path] = markers;
791
+ }
792
+ setValidationMarkers(newMarkers);
793
+ onValidationChange?.(newMarkers);
794
+ });
795
+ },
796
+ // eslint-disable-next-line react-hooks/exhaustive-deps
797
+ [activeFilePath, getOrCreateModel, onValidationChange]
798
+ );
799
+ const handleEditorChange = useCallback3(
800
+ (value) => {
801
+ if (!activeFilePath) return;
802
+ fileContentsRef.current.set(activeFilePath, value);
803
+ const isDirty = value !== originalContentsRef.current.get(activeFilePath);
804
+ setOpenTabs(
805
+ (prev) => prev.map(
806
+ (t) => t.path === activeFilePath ? { ...t, isDirty } : t
807
+ )
808
+ );
809
+ onFileChange?.(activeFilePath, value);
810
+ },
811
+ [activeFilePath, onFileChange]
812
+ );
813
+ const activeFile = activeFilePath ? {
814
+ path: activeFilePath,
815
+ value: fileContentsRef.current.get(activeFilePath) ?? "",
816
+ language: files.find((f) => f.path === activeFilePath)?.language ?? detectLanguage(activeFilePath)
817
+ } : void 0;
818
+ useEffect2(() => {
819
+ return () => {
820
+ for (const model of modelsRef.current.values()) {
821
+ if (!model.isDisposed()) {
822
+ model.dispose();
823
+ }
824
+ }
825
+ modelsRef.current.clear();
826
+ };
827
+ }, []);
828
+ return {
829
+ openTabs,
830
+ activeFilePath,
831
+ openFile,
832
+ closeFile,
833
+ setActiveFile: setActiveFileAction,
834
+ updateFileContent,
835
+ getFileContent,
836
+ activeFile,
837
+ monacoRef,
838
+ editorRef,
839
+ handleEditorMount,
840
+ handleEditorChange,
841
+ validationMarkers,
842
+ markSaved,
843
+ markAllSaved,
844
+ cursorPosition
845
+ };
846
+ }
847
+
848
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorTabs.tsx
849
+ import React3 from "react";
850
+ import { Box as Box3, IconButton as IconButton2, Tooltip as Tooltip2, Typography } from "@mui/material";
851
+ import CloseIcon from "@mui/icons-material/Close";
852
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
853
+ var CodeEditorTabs = ({
854
+ tabs,
855
+ activeTab,
856
+ onTabSelect,
857
+ onTabClose,
858
+ renderTab,
859
+ containerProps
860
+ }) => {
861
+ if (tabs.length === 0) return null;
862
+ return /* @__PURE__ */ jsx4(
863
+ Box3,
864
+ {
865
+ sx: {
866
+ display: "flex",
867
+ alignItems: "stretch",
868
+ overflow: "auto",
869
+ minHeight: 36,
870
+ borderBottom: 1,
871
+ borderColor: "divider",
872
+ bgcolor: "background.default",
873
+ "&::-webkit-scrollbar": { height: 2 },
874
+ "&::-webkit-scrollbar-thumb": { bgcolor: "action.disabled", borderRadius: 1 }
875
+ },
876
+ ...containerProps,
877
+ children: tabs.map((tab) => {
878
+ const isActive = tab.path === activeTab;
879
+ const label = tab.label ?? getFileName(tab.path);
880
+ if (renderTab) {
881
+ return /* @__PURE__ */ jsx4(React3.Fragment, { children: renderTab({
882
+ tab,
883
+ isActive,
884
+ onSelect: () => onTabSelect?.(tab.path),
885
+ onClose: () => onTabClose?.(tab.path)
886
+ }) }, tab.path);
887
+ }
888
+ return /* @__PURE__ */ jsxs4(
889
+ Box3,
890
+ {
891
+ onClick: () => onTabSelect?.(tab.path),
892
+ sx: {
893
+ display: "flex",
894
+ alignItems: "center",
895
+ gap: 0.5,
896
+ px: 1.5,
897
+ py: 0.5,
898
+ cursor: "pointer",
899
+ whiteSpace: "nowrap",
900
+ borderRight: 1,
901
+ borderColor: "divider",
902
+ bgcolor: isActive ? "background.paper" : "transparent",
903
+ borderBottom: isActive ? "2px solid" : "2px solid transparent",
904
+ borderBottomColor: isActive ? "primary.main" : "transparent",
905
+ "&:hover": {
906
+ bgcolor: isActive ? "background.paper" : "action.hover"
907
+ },
908
+ transition: "background-color 0.15s ease"
909
+ },
910
+ children: [
911
+ tab.isDirty && /* @__PURE__ */ jsx4(
912
+ Box3,
913
+ {
914
+ sx: {
915
+ width: 6,
916
+ height: 6,
917
+ borderRadius: "50%",
918
+ bgcolor: "warning.main",
919
+ flexShrink: 0
920
+ }
921
+ }
922
+ ),
923
+ tab.syncStatus && /* @__PURE__ */ jsx4(
924
+ Box3,
925
+ {
926
+ component: "span",
927
+ sx: {
928
+ fontSize: "0.6rem",
929
+ fontWeight: 700,
930
+ lineHeight: 1,
931
+ color: tab.syncStatus === "new" ? "success.main" : "warning.main",
932
+ flexShrink: 0
933
+ },
934
+ children: tab.syncStatus === "new" ? "N" : "M"
935
+ }
936
+ ),
937
+ /* @__PURE__ */ jsx4(Tooltip2, { title: tab.path, enterDelay: 600, children: /* @__PURE__ */ jsx4(
938
+ Typography,
939
+ {
940
+ variant: "body2",
941
+ sx: {
942
+ fontSize: "0.8125rem",
943
+ fontWeight: isActive ? 600 : 400,
944
+ color: isActive ? "text.primary" : "text.secondary",
945
+ userSelect: "none"
946
+ },
947
+ children: label
948
+ }
949
+ ) }),
950
+ onTabClose && /* @__PURE__ */ jsx4(
951
+ IconButton2,
952
+ {
953
+ size: "small",
954
+ onClick: (e) => {
955
+ e.stopPropagation();
956
+ onTabClose(tab.path);
957
+ },
958
+ sx: {
959
+ p: 0.25,
960
+ ml: 0.5,
961
+ opacity: isActive ? 0.7 : 0,
962
+ "&:hover": { opacity: 1 },
963
+ ".MuiBox-root:hover > &": { opacity: 0.5 },
964
+ transition: "opacity 0.15s ease"
965
+ },
966
+ "aria-label": `Close ${label}`,
967
+ children: /* @__PURE__ */ jsx4(CloseIcon, { sx: { fontSize: 14 } })
968
+ }
969
+ )
970
+ ]
971
+ },
972
+ tab.path
973
+ );
974
+ })
975
+ }
976
+ );
977
+ };
978
+
979
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorFileTree.tsx
980
+ import React4, { useCallback as useCallback4, useState as useState3 } from "react";
981
+ import { Box as Box4, Collapse, List, ListItemButton, ListItemIcon, ListItemText } from "@mui/material";
982
+ import FolderIcon from "@mui/icons-material/Folder";
983
+ import FolderOpenIcon from "@mui/icons-material/FolderOpen";
984
+ import InsertDriveFileOutlinedIcon from "@mui/icons-material/InsertDriveFileOutlined";
985
+ import ExpandMoreIcon2 from "@mui/icons-material/ExpandMore";
986
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
987
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
988
+ var STATUS_CONFIG = {
989
+ new: { label: "N", color: "success.main" },
990
+ modified: { label: "M", color: "warning.main" },
991
+ deleted: { label: "D", color: "error.main" }
992
+ };
993
+ function computeFolderStatus(node) {
994
+ if (node.status) return node.status;
995
+ if (node.type !== "folder" || !node.children) return void 0;
996
+ const childStatuses = node.children.map((c) => c.type === "folder" ? computeFolderStatus(c) : c.status).filter((s) => !!s);
997
+ if (childStatuses.length === 0) return void 0;
998
+ if (childStatuses.includes("new")) return "new";
999
+ if (childStatuses.includes("modified")) return "modified";
1000
+ return "deleted";
1001
+ }
1002
+ var CodeEditorFileTree = ({
1003
+ tree,
1004
+ selectedPath,
1005
+ onFileSelect,
1006
+ onFolderToggle,
1007
+ renderNode,
1008
+ defaultExpandedPaths,
1009
+ width = 220,
1010
+ containerProps
1011
+ }) => {
1012
+ const [expandedPaths, setExpandedPaths] = useState3(
1013
+ () => new Set(defaultExpandedPaths ?? [])
1014
+ );
1015
+ const toggleFolder = useCallback4(
1016
+ (path) => {
1017
+ setExpandedPaths((prev) => {
1018
+ const next = new Set(prev);
1019
+ const isExpanded = next.has(path);
1020
+ if (isExpanded) {
1021
+ next.delete(path);
1022
+ } else {
1023
+ next.add(path);
1024
+ }
1025
+ onFolderToggle?.(path, !isExpanded);
1026
+ return next;
1027
+ });
1028
+ },
1029
+ [onFolderToggle]
1030
+ );
1031
+ const renderTreeNode = (node, depth) => {
1032
+ const isFolder = node.type === "folder";
1033
+ const isExpanded = expandedPaths.has(node.path);
1034
+ const isSelected = node.path === selectedPath;
1035
+ if (renderNode) {
1036
+ return /* @__PURE__ */ jsxs5(React4.Fragment, { children: [
1037
+ renderNode({
1038
+ node,
1039
+ depth,
1040
+ isSelected,
1041
+ isExpanded,
1042
+ onSelect: () => {
1043
+ if (isFolder) {
1044
+ toggleFolder(node.path);
1045
+ } else {
1046
+ onFileSelect?.(node.path);
1047
+ }
1048
+ },
1049
+ onToggle: () => toggleFolder(node.path)
1050
+ }),
1051
+ isFolder && isExpanded && node.children?.map((child) => renderTreeNode(child, depth + 1))
1052
+ ] }, node.path);
1053
+ }
1054
+ return /* @__PURE__ */ jsxs5(React4.Fragment, { children: [
1055
+ /* @__PURE__ */ jsxs5(
1056
+ ListItemButton,
1057
+ {
1058
+ selected: isSelected,
1059
+ onClick: () => {
1060
+ if (isFolder) {
1061
+ toggleFolder(node.path);
1062
+ } else {
1063
+ onFileSelect?.(node.path);
1064
+ }
1065
+ },
1066
+ sx: {
1067
+ pl: 1 + depth * 1.5,
1068
+ py: 0.25,
1069
+ minHeight: 28,
1070
+ "&.Mui-selected": {
1071
+ bgcolor: "action.selected",
1072
+ "&:hover": { bgcolor: "action.selected" }
1073
+ }
1074
+ },
1075
+ children: [
1076
+ isFolder && /* @__PURE__ */ jsx5(ListItemIcon, { sx: { minWidth: 20 }, children: isExpanded ? /* @__PURE__ */ jsx5(ExpandMoreIcon2, { sx: { fontSize: 16 } }) : /* @__PURE__ */ jsx5(ChevronRightIcon, { sx: { fontSize: 16 } }) }),
1077
+ /* @__PURE__ */ jsx5(ListItemIcon, { sx: { minWidth: 24 }, children: node.icon ?? (isFolder ? isExpanded ? /* @__PURE__ */ jsx5(FolderOpenIcon, { sx: { fontSize: 16, color: "warning.main" } }) : /* @__PURE__ */ jsx5(FolderIcon, { sx: { fontSize: 16, color: "warning.main" } }) : /* @__PURE__ */ jsx5(InsertDriveFileOutlinedIcon, { sx: { fontSize: 16, color: "text.secondary" } })) }),
1078
+ /* @__PURE__ */ jsx5(
1079
+ ListItemText,
1080
+ {
1081
+ primary: node.name,
1082
+ slotProps: {
1083
+ primary: {
1084
+ sx: {
1085
+ fontSize: "0.8125rem",
1086
+ fontWeight: isSelected ? 600 : 400,
1087
+ overflow: "hidden",
1088
+ textOverflow: "ellipsis",
1089
+ whiteSpace: "nowrap"
1090
+ }
1091
+ }
1092
+ }
1093
+ }
1094
+ ),
1095
+ (() => {
1096
+ const effectiveStatus = isFolder ? computeFolderStatus(node) : node.status;
1097
+ if (!effectiveStatus) return null;
1098
+ const cfg = STATUS_CONFIG[effectiveStatus];
1099
+ return /* @__PURE__ */ jsx5(
1100
+ Box4,
1101
+ {
1102
+ component: "span",
1103
+ sx: {
1104
+ ml: "auto",
1105
+ pl: 0.5,
1106
+ fontSize: "0.65rem",
1107
+ fontWeight: 700,
1108
+ lineHeight: 1,
1109
+ color: cfg.color,
1110
+ flexShrink: 0
1111
+ },
1112
+ children: cfg.label
1113
+ }
1114
+ );
1115
+ })()
1116
+ ]
1117
+ }
1118
+ ),
1119
+ isFolder && /* @__PURE__ */ jsx5(Collapse, { in: isExpanded, timeout: "auto", unmountOnExit: true, children: node.children?.map((child) => renderTreeNode(child, depth + 1)) })
1120
+ ] }, node.path);
1121
+ };
1122
+ return /* @__PURE__ */ jsx5(
1123
+ Box4,
1124
+ {
1125
+ sx: {
1126
+ width: typeof width === "number" ? `${width}px` : width,
1127
+ minWidth: typeof width === "number" ? `${width}px` : width,
1128
+ height: "100%",
1129
+ overflow: "auto",
1130
+ borderRight: 1,
1131
+ borderColor: "divider",
1132
+ bgcolor: "background.default"
1133
+ },
1134
+ ...containerProps,
1135
+ children: /* @__PURE__ */ jsx5(List, { dense: true, disablePadding: true, children: tree.map((node) => renderTreeNode(node, 0)) })
1136
+ }
1137
+ );
1138
+ };
1139
+
1140
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorStatusBar.tsx
1141
+ import { Box as Box5, Tooltip as Tooltip3, Typography as Typography2 } from "@mui/material";
1142
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1143
+ var LANGUAGE_LABELS = {
1144
+ typescript: "TypeScript",
1145
+ javascript: "JavaScript",
1146
+ json: "JSON",
1147
+ html: "HTML",
1148
+ css: "CSS",
1149
+ python: "Python",
1150
+ yaml: "YAML",
1151
+ markdown: "Markdown",
1152
+ sql: "SQL",
1153
+ xml: "XML",
1154
+ plaintext: "Plain Text"
1155
+ };
1156
+ var CodeEditorStatusBar = ({
1157
+ gitInfo,
1158
+ language,
1159
+ cursorPosition,
1160
+ items,
1161
+ renderStatusBar,
1162
+ onBranchClick,
1163
+ containerProps
1164
+ }) => {
1165
+ if (renderStatusBar) {
1166
+ return /* @__PURE__ */ jsx6(Fragment2, { children: renderStatusBar({ gitInfo, language, cursorPosition, items }) });
1167
+ }
1168
+ const leftItems = items?.filter((i) => i.align !== "right") ?? [];
1169
+ const rightItems = items?.filter((i) => i.align === "right") ?? [];
1170
+ return /* @__PURE__ */ jsxs6(
1171
+ Box5,
1172
+ {
1173
+ sx: {
1174
+ display: "flex",
1175
+ alignItems: "center",
1176
+ justifyContent: "space-between",
1177
+ px: 1.5,
1178
+ py: 0.25,
1179
+ minHeight: 24,
1180
+ borderTop: 1,
1181
+ borderColor: "divider",
1182
+ bgcolor: "primary.main",
1183
+ color: "primary.contrastText",
1184
+ fontSize: "0.75rem",
1185
+ fontFamily: 'Monaco, Menlo, "Ubuntu Mono", Consolas, monospace',
1186
+ gap: 1,
1187
+ flexShrink: 0
1188
+ },
1189
+ ...containerProps,
1190
+ children: [
1191
+ /* @__PURE__ */ jsxs6(Box5, { sx: { display: "flex", alignItems: "center", gap: 1.5, overflow: "hidden" }, children: [
1192
+ gitInfo && /* @__PURE__ */ jsx6(
1193
+ Tooltip3,
1194
+ {
1195
+ title: [
1196
+ gitInfo.remote && `Remote: ${gitInfo.remote}`,
1197
+ gitInfo.commitHash && `Commit: ${gitInfo.commitHash}`,
1198
+ gitInfo.ahead != null && `\u2191 ${gitInfo.ahead} ahead`,
1199
+ gitInfo.behind != null && `\u2193 ${gitInfo.behind} behind`
1200
+ ].filter(Boolean).join(" \xB7 ") || gitInfo.branch,
1201
+ enterDelay: 400,
1202
+ children: /* @__PURE__ */ jsxs6(
1203
+ Box5,
1204
+ {
1205
+ onClick: onBranchClick,
1206
+ sx: {
1207
+ display: "flex",
1208
+ alignItems: "center",
1209
+ gap: 0.5,
1210
+ cursor: onBranchClick ? "pointer" : "default",
1211
+ overflow: "hidden",
1212
+ "&:hover": onBranchClick ? { opacity: 0.8 } : void 0
1213
+ },
1214
+ children: [
1215
+ /* @__PURE__ */ jsx6(
1216
+ "svg",
1217
+ {
1218
+ width: "14",
1219
+ height: "14",
1220
+ viewBox: "0 0 16 16",
1221
+ fill: "currentColor",
1222
+ style: { flexShrink: 0 },
1223
+ children: /* @__PURE__ */ jsx6(
1224
+ "path",
1225
+ {
1226
+ fillRule: "evenodd",
1227
+ d: "M11.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5zm-2.25.75a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.492 2.492 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25zM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5zM3.5 3.25a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0z"
1228
+ }
1229
+ )
1230
+ }
1231
+ ),
1232
+ /* @__PURE__ */ jsx6(
1233
+ Typography2,
1234
+ {
1235
+ variant: "caption",
1236
+ sx: {
1237
+ fontSize: "inherit",
1238
+ fontFamily: "inherit",
1239
+ color: "inherit",
1240
+ lineHeight: 1,
1241
+ overflow: "hidden",
1242
+ textOverflow: "ellipsis",
1243
+ whiteSpace: "nowrap",
1244
+ maxWidth: 180
1245
+ },
1246
+ children: gitInfo.branch
1247
+ }
1248
+ ),
1249
+ gitInfo.isDirty && /* @__PURE__ */ jsx6(
1250
+ Box5,
1251
+ {
1252
+ component: "span",
1253
+ sx: {
1254
+ width: 6,
1255
+ height: 6,
1256
+ borderRadius: "50%",
1257
+ bgcolor: "warning.light",
1258
+ flexShrink: 0
1259
+ }
1260
+ }
1261
+ ),
1262
+ gitInfo.ahead != null && gitInfo.ahead > 0 && /* @__PURE__ */ jsxs6(Typography2, { variant: "caption", sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, opacity: 0.85 }, children: [
1263
+ "\u2191",
1264
+ gitInfo.ahead
1265
+ ] }),
1266
+ gitInfo.behind != null && gitInfo.behind > 0 && /* @__PURE__ */ jsxs6(Typography2, { variant: "caption", sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, opacity: 0.85 }, children: [
1267
+ "\u2193",
1268
+ gitInfo.behind
1269
+ ] })
1270
+ ]
1271
+ }
1272
+ )
1273
+ }
1274
+ ),
1275
+ leftItems.map((item) => /* @__PURE__ */ jsx6(StatusBarItemElement, { item }, item.id))
1276
+ ] }),
1277
+ /* @__PURE__ */ jsxs6(Box5, { sx: { display: "flex", alignItems: "center", gap: 1.5, overflow: "hidden" }, children: [
1278
+ rightItems.map((item) => /* @__PURE__ */ jsx6(StatusBarItemElement, { item }, item.id)),
1279
+ cursorPosition && /* @__PURE__ */ jsxs6(
1280
+ Typography2,
1281
+ {
1282
+ variant: "caption",
1283
+ sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, whiteSpace: "nowrap" },
1284
+ children: [
1285
+ "Ln ",
1286
+ cursorPosition.line,
1287
+ ", Col ",
1288
+ cursorPosition.column
1289
+ ]
1290
+ }
1291
+ ),
1292
+ language && /* @__PURE__ */ jsx6(
1293
+ Typography2,
1294
+ {
1295
+ variant: "caption",
1296
+ sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, whiteSpace: "nowrap" },
1297
+ children: LANGUAGE_LABELS[language] ?? language
1298
+ }
1299
+ )
1300
+ ] })
1301
+ ]
1302
+ }
1303
+ );
1304
+ };
1305
+ var StatusBarItemElement = ({ item }) => {
1306
+ const inner = /* @__PURE__ */ jsx6(
1307
+ Box5,
1308
+ {
1309
+ onClick: item.onClick,
1310
+ sx: {
1311
+ display: "flex",
1312
+ alignItems: "center",
1313
+ cursor: item.onClick ? "pointer" : "default",
1314
+ lineHeight: 1,
1315
+ whiteSpace: "nowrap",
1316
+ "&:hover": item.onClick ? { opacity: 0.8 } : void 0
1317
+ },
1318
+ children: typeof item.content === "string" ? /* @__PURE__ */ jsx6(
1319
+ Typography2,
1320
+ {
1321
+ variant: "caption",
1322
+ sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1 },
1323
+ children: item.content
1324
+ }
1325
+ ) : item.content
1326
+ }
1327
+ );
1328
+ if (item.tooltip) {
1329
+ return /* @__PURE__ */ jsx6(Tooltip3, { title: item.tooltip, enterDelay: 400, children: inner });
1330
+ }
1331
+ return inner;
1332
+ };
1333
+
1334
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorWelcomeScreen.tsx
1335
+ import { Box as Box6 } from "@mui/material";
1336
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1337
+ var CodeEditorWelcomeScreen = ({
1338
+ logo,
1339
+ children,
1340
+ containerProps
1341
+ }) => {
1342
+ const defaultLogo = /* @__PURE__ */ jsx7(
1343
+ CereIcon,
1344
+ {
1345
+ sx: {
1346
+ fontSize: 80,
1347
+ color: "text.disabled",
1348
+ opacity: 0.4
1349
+ }
1350
+ }
1351
+ );
1352
+ return /* @__PURE__ */ jsxs7(
1353
+ Box6,
1354
+ {
1355
+ sx: {
1356
+ flex: 1,
1357
+ display: "flex",
1358
+ flexDirection: "column",
1359
+ alignItems: "center",
1360
+ justifyContent: "center",
1361
+ gap: 3,
1362
+ p: 4,
1363
+ userSelect: "none"
1364
+ },
1365
+ ...containerProps,
1366
+ children: [
1367
+ logo !== void 0 ? logo : defaultLogo,
1368
+ children && /* @__PURE__ */ jsx7(
1369
+ Box6,
1370
+ {
1371
+ sx: {
1372
+ display: "flex",
1373
+ flexDirection: "column",
1374
+ alignItems: "center",
1375
+ gap: 1
1376
+ },
1377
+ children
1378
+ }
1379
+ )
1380
+ ]
1381
+ }
1382
+ );
1383
+ };
1384
+
1385
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorWorkspace.tsx
1386
+ import React5 from "react";
1387
+ import { Box as Box7 } from "@mui/material";
1388
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1389
+ var CodeEditorWorkspace = ({
1390
+ files,
1391
+ initialOpenPaths,
1392
+ onFileChange,
1393
+ onValidationChange,
1394
+ fileTree,
1395
+ defaultExpandedPaths,
1396
+ showTabs = true,
1397
+ showFileTree = true,
1398
+ fileTreeWidth = 220,
1399
+ height = "500px",
1400
+ editorProps,
1401
+ containerProps,
1402
+ renderTabs,
1403
+ renderFileTree,
1404
+ renderEditor,
1405
+ renderStatusBar,
1406
+ renderWelcomeScreen,
1407
+ welcomeScreen,
1408
+ welcomeScreenProps,
1409
+ gitInfo,
1410
+ showStatusBar = true,
1411
+ statusBarItems,
1412
+ onWorkspaceReady,
1413
+ onSave,
1414
+ onBranchClick
1415
+ }) => {
1416
+ const workspace = useCodeEditorWorkspace({
1417
+ files,
1418
+ initialOpenPaths,
1419
+ onFileChange,
1420
+ onValidationChange
1421
+ });
1422
+ React5.useEffect(() => {
1423
+ onWorkspaceReady?.(workspace);
1424
+ }, []);
1425
+ React5.useEffect(() => {
1426
+ if (!onSave) return;
1427
+ const handleKeyDown = (e) => {
1428
+ if ((e.ctrlKey || e.metaKey) && e.key === "s") {
1429
+ e.preventDefault();
1430
+ const dirtyFiles = workspace.openTabs.filter((t) => t.isDirty).map((t) => {
1431
+ const file = files.find((f) => f.path === t.path);
1432
+ if (!file) return null;
1433
+ return {
1434
+ ...file,
1435
+ value: workspace.getFileContent(file.path) ?? file.value
1436
+ };
1437
+ }).filter((f) => f !== null);
1438
+ if (dirtyFiles.length > 0) {
1439
+ onSave(dirtyFiles);
1440
+ }
1441
+ }
1442
+ };
1443
+ window.addEventListener("keydown", handleKeyDown);
1444
+ return () => window.removeEventListener("keydown", handleKeyDown);
1445
+ }, [onSave, workspace, files]);
1446
+ const hasFileTree = showFileTree && fileTree && fileTree.length > 0;
1447
+ const tabsProps = {
1448
+ tabs: workspace.openTabs,
1449
+ activeTab: workspace.activeFilePath,
1450
+ onTabSelect: workspace.setActiveFile,
1451
+ onTabClose: workspace.closeFile
1452
+ };
1453
+ const tabsElement = showTabs ? renderTabs ? renderTabs({ ...tabsProps, workspace }) : /* @__PURE__ */ jsx8(CodeEditorTabs, { ...tabsProps }) : null;
1454
+ const fileTreeProps = {
1455
+ tree: fileTree ?? [],
1456
+ selectedPath: workspace.activeFilePath,
1457
+ onFileSelect: workspace.openFile,
1458
+ defaultExpandedPaths,
1459
+ width: fileTreeWidth
1460
+ };
1461
+ const fileTreeElement = hasFileTree ? renderFileTree ? renderFileTree({ ...fileTreeProps, workspace }) : /* @__PURE__ */ jsx8(CodeEditorFileTree, { ...fileTreeProps }) : null;
1462
+ const statusBarProps = {
1463
+ gitInfo,
1464
+ language: workspace.activeFile?.language,
1465
+ cursorPosition: workspace.cursorPosition ?? void 0,
1466
+ items: statusBarItems,
1467
+ onBranchClick
1468
+ };
1469
+ const statusBarElement = showStatusBar ? renderStatusBar ? renderStatusBar({ ...statusBarProps, workspace }) : /* @__PURE__ */ jsx8(CodeEditorStatusBar, { ...statusBarProps }) : null;
1470
+ const welcomeElement = renderWelcomeScreen ? renderWelcomeScreen(workspace) : welcomeScreen !== void 0 ? welcomeScreen : /* @__PURE__ */ jsx8(CodeEditorWelcomeScreen, { ...welcomeScreenProps });
1471
+ const editorElement = renderEditor ? renderEditor(workspace) : workspace.activeFile ? /* @__PURE__ */ jsx8(
1472
+ CodeEditor,
1473
+ {
1474
+ value: workspace.activeFile.value,
1475
+ onChange: workspace.handleEditorChange,
1476
+ language: workspace.activeFile.language,
1477
+ editorRef: workspace.editorRef,
1478
+ monacoRef: workspace.monacoRef,
1479
+ onMount: workspace.handleEditorMount,
1480
+ onValidate: (markers) => {
1481
+ if (workspace.activeFilePath) {
1482
+ workspace.validationMarkers[workspace.activeFilePath] = markers;
1483
+ }
1484
+ },
1485
+ externalModelManagement: true,
1486
+ height: "100%",
1487
+ ...editorProps
1488
+ }
1489
+ ) : welcomeElement;
1490
+ return /* @__PURE__ */ jsxs8(
1491
+ Box7,
1492
+ {
1493
+ sx: {
1494
+ display: "flex",
1495
+ height: typeof height === "number" ? `${height}px` : height,
1496
+ border: 1,
1497
+ borderColor: "divider",
1498
+ borderRadius: 1,
1499
+ overflow: "hidden",
1500
+ bgcolor: "background.paper"
1501
+ },
1502
+ ...containerProps,
1503
+ children: [
1504
+ fileTreeElement,
1505
+ /* @__PURE__ */ jsxs8(Box7, { sx: { flex: 1, display: "flex", flexDirection: "column", minWidth: 0, overflow: "hidden" }, children: [
1506
+ tabsElement,
1507
+ /* @__PURE__ */ jsx8(Box7, { sx: { flex: 1, overflow: "hidden" }, children: editorElement }),
1508
+ statusBarElement
1509
+ ] })
1510
+ ]
1511
+ }
1512
+ );
1513
+ };
1514
+
1515
+ export {
1516
+ FlowEditor,
1517
+ Background2 as Background,
1518
+ Controls2 as Controls,
1519
+ MiniMap2 as MiniMap,
1520
+ BackgroundVariant2 as BackgroundVariant,
1521
+ ConnectionLineType2 as ConnectionLineType,
1522
+ CodeEditor,
1523
+ WorkflowNodeHandle,
1524
+ EXTENSION_LANGUAGE_MAP,
1525
+ detectLanguage,
1526
+ getFileName,
1527
+ useCodeEditorWorkspace,
1528
+ CodeEditorTabs,
1529
+ CodeEditorFileTree,
1530
+ CodeEditorStatusBar,
1531
+ CodeEditorWelcomeScreen,
1532
+ CodeEditorWorkspace,
1533
+ Panel2 as Panel
1534
+ };
1535
+ //# sourceMappingURL=chunk-XF66WQZE.mjs.map