@cere/cere-design-system 0.0.29 → 0.0.30

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/dist/index.js CHANGED
@@ -60,6 +60,10 @@ __export(index_exports, {
60
60
  ClockIcon: () => ClockIcon,
61
61
  CloudFlashIcon: () => CloudFlashIcon,
62
62
  CodeEditor: () => CodeEditor,
63
+ CodeEditorFileTree: () => CodeEditorFileTree,
64
+ CodeEditorStatusBar: () => CodeEditorStatusBar,
65
+ CodeEditorTabs: () => CodeEditorTabs,
66
+ CodeEditorWorkspace: () => CodeEditorWorkspace,
63
67
  Collapse: () => Collapse,
64
68
  ConnectionLineType: () => import_reactflow2.ConnectionLineType,
65
69
  ConnectionStatus: () => ConnectionStatus,
@@ -78,6 +82,7 @@ __export(index_exports, {
78
82
  Drawer: () => Drawer2,
79
83
  Dropdown: () => Dropdown,
80
84
  DropdownAnchor: () => DropdownAnchor,
85
+ EXTENSION_LANGUAGE_MAP: () => EXTENSION_LANGUAGE_MAP,
81
86
  EmptyState: () => EmptyState,
82
87
  EntityHeader: () => EntityHeader,
83
88
  FilledFolderIcon: () => FilledFolderIcon,
@@ -164,9 +169,12 @@ __export(index_exports, {
164
169
  WorkspaceSelectorButton: () => WorkspaceSelectorButton,
165
170
  colors: () => colors,
166
171
  contextMenuItems: () => contextMenuItems,
172
+ detectLanguage: () => detectLanguage,
173
+ getFileName: () => getFileName,
167
174
  robPaletteExtended: () => robPaletteExtended,
168
175
  robPrimaryPalette: () => robPrimaryPalette,
169
176
  theme: () => theme,
177
+ useCodeEditorWorkspace: () => useCodeEditorWorkspace,
170
178
  useIsDesktop: () => useIsDesktop,
171
179
  useIsMobile: () => useIsMobile,
172
180
  useIsTablet: () => useIsTablet,
@@ -8735,7 +8743,8 @@ var CodeEditor = ({
8735
8743
  monacoRef,
8736
8744
  onFullscreenChange,
8737
8745
  containerProps,
8738
- typeDefinitions
8746
+ typeDefinitions,
8747
+ externalModelManagement = false
8739
8748
  }) => {
8740
8749
  const [isEditorReady, setIsEditorReady] = (0, import_react35.useState)(false);
8741
8750
  const [validationErrors, setValidationErrors] = (0, import_react35.useState)([]);
@@ -8881,6 +8890,7 @@ var CodeEditor = ({
8881
8890
  onChange(valueStr);
8882
8891
  };
8883
8892
  (0, import_react35.useEffect)(() => {
8893
+ if (externalModelManagement) return;
8884
8894
  if (value !== tsCode) {
8885
8895
  setTsCode(value);
8886
8896
  if (isEditorReady && finalEditorRef?.current) {
@@ -8891,7 +8901,7 @@ var CodeEditor = ({
8891
8901
  }
8892
8902
  }
8893
8903
  }
8894
- }, [value, tsCode, isEditorReady, finalEditorRef]);
8904
+ }, [value, tsCode, isEditorReady, finalEditorRef, externalModelManagement]);
8895
8905
  const editorMinHeight = minHeight ? typeof minHeight === "number" ? `${minHeight}px` : minHeight : "400px";
8896
8906
  const defaultOptions = {
8897
8907
  lineNumbers,
@@ -9119,6 +9129,832 @@ var WorkflowNodeHandle = ({
9119
9129
  /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_reactflow3.Handle, { type: "source", position: import_reactflow3.Position.Right, style: handleStyle })
9120
9130
  ] });
9121
9131
  };
9132
+
9133
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorWorkspace.types.ts
9134
+ var EXTENSION_LANGUAGE_MAP = {
9135
+ ts: "typescript",
9136
+ tsx: "typescript",
9137
+ js: "javascript",
9138
+ jsx: "javascript",
9139
+ json: "json",
9140
+ html: "html",
9141
+ htm: "html",
9142
+ css: "css",
9143
+ py: "python",
9144
+ yaml: "yaml",
9145
+ yml: "yaml",
9146
+ md: "markdown",
9147
+ sql: "sql",
9148
+ xml: "xml",
9149
+ txt: "plaintext"
9150
+ };
9151
+ function detectLanguage(path) {
9152
+ const ext = path.split(".").pop()?.toLowerCase() ?? "";
9153
+ return EXTENSION_LANGUAGE_MAP[ext] ?? "plaintext";
9154
+ }
9155
+ function getFileName(path) {
9156
+ return path.split("/").pop() ?? path;
9157
+ }
9158
+
9159
+ // src/components/third-party/CodeEditorWorkspace/useCodeEditorWorkspace.ts
9160
+ var import_react37 = require("react");
9161
+ function useCodeEditorWorkspace({
9162
+ files,
9163
+ initialOpenPaths,
9164
+ onFileChange,
9165
+ onValidationChange
9166
+ }) {
9167
+ const fileContentsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
9168
+ const originalContentsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
9169
+ const [openTabs, setOpenTabs] = (0, import_react37.useState)([]);
9170
+ const [activeFilePath, setActiveFilePath] = (0, import_react37.useState)(null);
9171
+ const monacoRef = (0, import_react37.useRef)(null);
9172
+ const editorRef = (0, import_react37.useRef)(null);
9173
+ const modelsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
9174
+ const [validationMarkers, setValidationMarkers] = (0, import_react37.useState)({});
9175
+ const [cursorPosition, setCursorPosition] = (0, import_react37.useState)(null);
9176
+ (0, import_react37.useEffect)(() => {
9177
+ for (const file of files) {
9178
+ if (!fileContentsRef.current.has(file.path)) {
9179
+ fileContentsRef.current.set(file.path, file.value);
9180
+ originalContentsRef.current.set(file.path, file.value);
9181
+ }
9182
+ const model = modelsRef.current.get(file.path);
9183
+ if (model && !model.isDisposed()) {
9184
+ if (file.value === fileContentsRef.current.get(file.path)) {
9185
+ originalContentsRef.current.set(file.path, file.value);
9186
+ continue;
9187
+ }
9188
+ if (originalContentsRef.current.get(file.path) !== file.value) {
9189
+ const localContent = fileContentsRef.current.get(file.path) ?? "";
9190
+ const previousOriginal = originalContentsRef.current.get(file.path) ?? "";
9191
+ originalContentsRef.current.set(file.path, file.value);
9192
+ if (localContent === previousOriginal) {
9193
+ fileContentsRef.current.set(file.path, file.value);
9194
+ model.setValue(file.value);
9195
+ }
9196
+ }
9197
+ }
9198
+ }
9199
+ }, [files]);
9200
+ (0, import_react37.useEffect)(() => {
9201
+ if (initialOpenPaths && initialOpenPaths.length > 0) {
9202
+ const tabs = initialOpenPaths.filter((p) => files.some((f) => f.path === p)).map((p) => ({
9203
+ path: p,
9204
+ label: getFileName(p),
9205
+ isDirty: false
9206
+ }));
9207
+ if (tabs.length > 0) {
9208
+ setOpenTabs(tabs);
9209
+ setActiveFilePath(tabs[0].path);
9210
+ }
9211
+ }
9212
+ }, []);
9213
+ const getOrCreateModel = (0, import_react37.useCallback)(
9214
+ (path) => {
9215
+ const monaco = monacoRef.current;
9216
+ if (!monaco) return null;
9217
+ const existing = modelsRef.current.get(path);
9218
+ if (existing && !existing.isDisposed()) return existing;
9219
+ const file = files.find((f) => f.path === path);
9220
+ const content = fileContentsRef.current.get(path) ?? file?.value ?? "";
9221
+ const lang = file?.language ?? detectLanguage(path);
9222
+ const uri = monaco.Uri.parse(`file:///${path}`);
9223
+ let model = monaco.editor.getModel(uri);
9224
+ if (!model) {
9225
+ model = monaco.editor.createModel(content, lang, uri);
9226
+ }
9227
+ modelsRef.current.set(path, model);
9228
+ return model;
9229
+ },
9230
+ [files]
9231
+ );
9232
+ const disposeModel = (0, import_react37.useCallback)((path) => {
9233
+ const model = modelsRef.current.get(path);
9234
+ if (model && !model.isDisposed()) {
9235
+ model.dispose();
9236
+ }
9237
+ modelsRef.current.delete(path);
9238
+ }, []);
9239
+ const switchToFile = (0, import_react37.useCallback)(
9240
+ (path) => {
9241
+ const ed = editorRef.current;
9242
+ if (!ed) return;
9243
+ const model = getOrCreateModel(path);
9244
+ if (model) {
9245
+ ed.setModel(model);
9246
+ }
9247
+ },
9248
+ [getOrCreateModel]
9249
+ );
9250
+ const openFile = (0, import_react37.useCallback)(
9251
+ (path) => {
9252
+ const file = files.find((f) => f.path === path);
9253
+ if (!file) return;
9254
+ if (!fileContentsRef.current.has(path)) {
9255
+ fileContentsRef.current.set(path, file.value);
9256
+ originalContentsRef.current.set(path, file.value);
9257
+ }
9258
+ setOpenTabs((prev) => {
9259
+ const exists = prev.some((t) => t.path === path);
9260
+ if (exists) return prev;
9261
+ return [
9262
+ ...prev,
9263
+ { path, label: getFileName(path), isDirty: false }
9264
+ ];
9265
+ });
9266
+ setActiveFilePath(path);
9267
+ switchToFile(path);
9268
+ },
9269
+ [files, switchToFile]
9270
+ );
9271
+ const closeFile = (0, import_react37.useCallback)(
9272
+ (path) => {
9273
+ disposeModel(path);
9274
+ setOpenTabs((prev) => {
9275
+ const newTabs = prev.filter((t) => t.path !== path);
9276
+ if (activeFilePath === path) {
9277
+ const closedIndex = prev.findIndex((t) => t.path === path);
9278
+ const nextTab = newTabs[Math.min(closedIndex, newTabs.length - 1)] ?? null;
9279
+ const nextPath = nextTab?.path ?? null;
9280
+ setActiveFilePath(nextPath);
9281
+ if (nextPath) {
9282
+ switchToFile(nextPath);
9283
+ }
9284
+ }
9285
+ return newTabs;
9286
+ });
9287
+ },
9288
+ [activeFilePath, disposeModel, switchToFile]
9289
+ );
9290
+ const setActiveFileAction = (0, import_react37.useCallback)(
9291
+ (path) => {
9292
+ setActiveFilePath(path);
9293
+ switchToFile(path);
9294
+ },
9295
+ [switchToFile]
9296
+ );
9297
+ const updateFileContent = (0, import_react37.useCallback)(
9298
+ (path, value) => {
9299
+ fileContentsRef.current.set(path, value);
9300
+ const model = modelsRef.current.get(path);
9301
+ if (model && !model.isDisposed() && model.getValue() !== value) {
9302
+ model.setValue(value);
9303
+ }
9304
+ const isDirty = value !== originalContentsRef.current.get(path);
9305
+ setOpenTabs(
9306
+ (prev) => prev.map((t) => t.path === path ? { ...t, isDirty } : t)
9307
+ );
9308
+ onFileChange?.(path, value);
9309
+ },
9310
+ [onFileChange]
9311
+ );
9312
+ const getFileContent = (0, import_react37.useCallback)((path) => {
9313
+ return fileContentsRef.current.get(path);
9314
+ }, []);
9315
+ const markSaved = (0, import_react37.useCallback)((path) => {
9316
+ const content = fileContentsRef.current.get(path);
9317
+ if (content !== void 0) {
9318
+ originalContentsRef.current.set(path, content);
9319
+ }
9320
+ setOpenTabs(
9321
+ (prev) => prev.map((t) => t.path === path ? { ...t, isDirty: false } : t)
9322
+ );
9323
+ }, []);
9324
+ const markAllSaved = (0, import_react37.useCallback)(() => {
9325
+ for (const [path, content] of fileContentsRef.current.entries()) {
9326
+ originalContentsRef.current.set(path, content);
9327
+ }
9328
+ setOpenTabs((prev) => prev.map((t) => ({ ...t, isDirty: false })));
9329
+ }, []);
9330
+ const handleEditorMount = (0, import_react37.useCallback)(
9331
+ (editorInstance, monacoInstance) => {
9332
+ monacoRef.current = monacoInstance;
9333
+ editorRef.current = editorInstance;
9334
+ if (activeFilePath) {
9335
+ const model = getOrCreateModel(activeFilePath);
9336
+ if (model) {
9337
+ editorInstance.setModel(model);
9338
+ }
9339
+ }
9340
+ editorInstance.onDidChangeCursorPosition((e) => {
9341
+ setCursorPosition({ line: e.position.lineNumber, column: e.position.column });
9342
+ });
9343
+ const pos = editorInstance.getPosition();
9344
+ if (pos) {
9345
+ setCursorPosition({ line: pos.lineNumber, column: pos.column });
9346
+ }
9347
+ monacoInstance.editor.onDidChangeMarkers((uris) => {
9348
+ const newMarkers = { ...validationMarkers };
9349
+ for (const uri of uris) {
9350
+ const path = uri.path.replace(/^\//, "");
9351
+ const markers = monacoInstance.editor.getModelMarkers({ resource: uri });
9352
+ newMarkers[path] = markers;
9353
+ }
9354
+ setValidationMarkers(newMarkers);
9355
+ onValidationChange?.(newMarkers);
9356
+ });
9357
+ },
9358
+ // eslint-disable-next-line react-hooks/exhaustive-deps
9359
+ [activeFilePath, getOrCreateModel, onValidationChange]
9360
+ );
9361
+ const handleEditorChange = (0, import_react37.useCallback)(
9362
+ (value) => {
9363
+ if (!activeFilePath) return;
9364
+ fileContentsRef.current.set(activeFilePath, value);
9365
+ const isDirty = value !== originalContentsRef.current.get(activeFilePath);
9366
+ setOpenTabs(
9367
+ (prev) => prev.map(
9368
+ (t) => t.path === activeFilePath ? { ...t, isDirty } : t
9369
+ )
9370
+ );
9371
+ onFileChange?.(activeFilePath, value);
9372
+ },
9373
+ [activeFilePath, onFileChange]
9374
+ );
9375
+ const activeFile = activeFilePath ? {
9376
+ path: activeFilePath,
9377
+ value: fileContentsRef.current.get(activeFilePath) ?? "",
9378
+ language: files.find((f) => f.path === activeFilePath)?.language ?? detectLanguage(activeFilePath)
9379
+ } : void 0;
9380
+ (0, import_react37.useEffect)(() => {
9381
+ return () => {
9382
+ for (const model of modelsRef.current.values()) {
9383
+ if (!model.isDisposed()) {
9384
+ model.dispose();
9385
+ }
9386
+ }
9387
+ modelsRef.current.clear();
9388
+ };
9389
+ }, []);
9390
+ return {
9391
+ openTabs,
9392
+ activeFilePath,
9393
+ openFile,
9394
+ closeFile,
9395
+ setActiveFile: setActiveFileAction,
9396
+ updateFileContent,
9397
+ getFileContent,
9398
+ activeFile,
9399
+ monacoRef,
9400
+ editorRef,
9401
+ handleEditorMount,
9402
+ handleEditorChange,
9403
+ validationMarkers,
9404
+ markSaved,
9405
+ markAllSaved,
9406
+ cursorPosition
9407
+ };
9408
+ }
9409
+
9410
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorTabs.tsx
9411
+ var import_react38 = __toESM(require("react"));
9412
+ var import_material74 = require("@mui/material");
9413
+ var import_Close5 = __toESM(require("@mui/icons-material/Close"));
9414
+ var import_jsx_runtime98 = require("react/jsx-runtime");
9415
+ var CodeEditorTabs = ({
9416
+ tabs,
9417
+ activeTab,
9418
+ onTabSelect,
9419
+ onTabClose,
9420
+ renderTab,
9421
+ containerProps
9422
+ }) => {
9423
+ if (tabs.length === 0) return null;
9424
+ return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
9425
+ import_material74.Box,
9426
+ {
9427
+ sx: {
9428
+ display: "flex",
9429
+ alignItems: "stretch",
9430
+ overflow: "auto",
9431
+ minHeight: 36,
9432
+ borderBottom: 1,
9433
+ borderColor: "divider",
9434
+ bgcolor: "background.default",
9435
+ "&::-webkit-scrollbar": { height: 2 },
9436
+ "&::-webkit-scrollbar-thumb": { bgcolor: "action.disabled", borderRadius: 1 }
9437
+ },
9438
+ ...containerProps,
9439
+ children: tabs.map((tab) => {
9440
+ const isActive = tab.path === activeTab;
9441
+ const label = tab.label ?? getFileName(tab.path);
9442
+ if (renderTab) {
9443
+ return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_react38.default.Fragment, { children: renderTab({
9444
+ tab,
9445
+ isActive,
9446
+ onSelect: () => onTabSelect?.(tab.path),
9447
+ onClose: () => onTabClose?.(tab.path)
9448
+ }) }, tab.path);
9449
+ }
9450
+ return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(
9451
+ import_material74.Box,
9452
+ {
9453
+ onClick: () => onTabSelect?.(tab.path),
9454
+ sx: {
9455
+ display: "flex",
9456
+ alignItems: "center",
9457
+ gap: 0.5,
9458
+ px: 1.5,
9459
+ py: 0.5,
9460
+ cursor: "pointer",
9461
+ whiteSpace: "nowrap",
9462
+ borderRight: 1,
9463
+ borderColor: "divider",
9464
+ bgcolor: isActive ? "background.paper" : "transparent",
9465
+ borderBottom: isActive ? "2px solid" : "2px solid transparent",
9466
+ borderBottomColor: isActive ? "primary.main" : "transparent",
9467
+ "&:hover": {
9468
+ bgcolor: isActive ? "background.paper" : "action.hover"
9469
+ },
9470
+ transition: "background-color 0.15s ease"
9471
+ },
9472
+ children: [
9473
+ tab.isDirty && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
9474
+ import_material74.Box,
9475
+ {
9476
+ sx: {
9477
+ width: 6,
9478
+ height: 6,
9479
+ borderRadius: "50%",
9480
+ bgcolor: "warning.main",
9481
+ flexShrink: 0
9482
+ }
9483
+ }
9484
+ ),
9485
+ /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_material74.Tooltip, { title: tab.path, enterDelay: 600, children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
9486
+ import_material74.Typography,
9487
+ {
9488
+ variant: "body2",
9489
+ sx: {
9490
+ fontSize: "0.8125rem",
9491
+ fontWeight: isActive ? 600 : 400,
9492
+ color: isActive ? "text.primary" : "text.secondary",
9493
+ userSelect: "none"
9494
+ },
9495
+ children: label
9496
+ }
9497
+ ) }),
9498
+ onTabClose && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
9499
+ import_material74.IconButton,
9500
+ {
9501
+ size: "small",
9502
+ onClick: (e) => {
9503
+ e.stopPropagation();
9504
+ onTabClose(tab.path);
9505
+ },
9506
+ sx: {
9507
+ p: 0.25,
9508
+ ml: 0.5,
9509
+ opacity: isActive ? 0.7 : 0,
9510
+ "&:hover": { opacity: 1 },
9511
+ ".MuiBox-root:hover > &": { opacity: 0.5 },
9512
+ transition: "opacity 0.15s ease"
9513
+ },
9514
+ "aria-label": `Close ${label}`,
9515
+ children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_Close5.default, { sx: { fontSize: 14 } })
9516
+ }
9517
+ )
9518
+ ]
9519
+ },
9520
+ tab.path
9521
+ );
9522
+ })
9523
+ }
9524
+ );
9525
+ };
9526
+
9527
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorFileTree.tsx
9528
+ var import_react39 = __toESM(require("react"));
9529
+ var import_material75 = require("@mui/material");
9530
+ var import_Folder = __toESM(require("@mui/icons-material/Folder"));
9531
+ var import_FolderOpen = __toESM(require("@mui/icons-material/FolderOpen"));
9532
+ var import_InsertDriveFileOutlined = __toESM(require("@mui/icons-material/InsertDriveFileOutlined"));
9533
+ var import_ExpandMore4 = __toESM(require("@mui/icons-material/ExpandMore"));
9534
+ var import_ChevronRight4 = __toESM(require("@mui/icons-material/ChevronRight"));
9535
+ var import_jsx_runtime99 = require("react/jsx-runtime");
9536
+ var CodeEditorFileTree = ({
9537
+ tree,
9538
+ selectedPath,
9539
+ onFileSelect,
9540
+ onFolderToggle,
9541
+ renderNode,
9542
+ defaultExpandedPaths,
9543
+ width = 220,
9544
+ containerProps
9545
+ }) => {
9546
+ const [expandedPaths, setExpandedPaths] = (0, import_react39.useState)(
9547
+ () => new Set(defaultExpandedPaths ?? [])
9548
+ );
9549
+ const toggleFolder = (0, import_react39.useCallback)(
9550
+ (path) => {
9551
+ setExpandedPaths((prev) => {
9552
+ const next = new Set(prev);
9553
+ const isExpanded = next.has(path);
9554
+ if (isExpanded) {
9555
+ next.delete(path);
9556
+ } else {
9557
+ next.add(path);
9558
+ }
9559
+ onFolderToggle?.(path, !isExpanded);
9560
+ return next;
9561
+ });
9562
+ },
9563
+ [onFolderToggle]
9564
+ );
9565
+ const renderTreeNode = (node, depth) => {
9566
+ const isFolder = node.type === "folder";
9567
+ const isExpanded = expandedPaths.has(node.path);
9568
+ const isSelected = node.path === selectedPath;
9569
+ if (renderNode) {
9570
+ return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_react39.default.Fragment, { children: [
9571
+ renderNode({
9572
+ node,
9573
+ depth,
9574
+ isSelected,
9575
+ isExpanded,
9576
+ onSelect: () => {
9577
+ if (isFolder) {
9578
+ toggleFolder(node.path);
9579
+ } else {
9580
+ onFileSelect?.(node.path);
9581
+ }
9582
+ },
9583
+ onToggle: () => toggleFolder(node.path)
9584
+ }),
9585
+ isFolder && isExpanded && node.children?.map((child) => renderTreeNode(child, depth + 1))
9586
+ ] }, node.path);
9587
+ }
9588
+ return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_react39.default.Fragment, { children: [
9589
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
9590
+ import_material75.ListItemButton,
9591
+ {
9592
+ selected: isSelected,
9593
+ onClick: () => {
9594
+ if (isFolder) {
9595
+ toggleFolder(node.path);
9596
+ } else {
9597
+ onFileSelect?.(node.path);
9598
+ }
9599
+ },
9600
+ sx: {
9601
+ pl: 1 + depth * 1.5,
9602
+ py: 0.25,
9603
+ minHeight: 28,
9604
+ "&.Mui-selected": {
9605
+ bgcolor: "action.selected",
9606
+ "&:hover": { bgcolor: "action.selected" }
9607
+ }
9608
+ },
9609
+ children: [
9610
+ isFolder && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_material75.ListItemIcon, { sx: { minWidth: 20 }, children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_ExpandMore4.default, { sx: { fontSize: 16 } }) : /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_ChevronRight4.default, { sx: { fontSize: 16 } }) }),
9611
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_material75.ListItemIcon, { sx: { minWidth: 24 }, children: node.icon ?? (isFolder ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_FolderOpen.default, { sx: { fontSize: 16, color: "warning.main" } }) : /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_Folder.default, { sx: { fontSize: 16, color: "warning.main" } }) : /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_InsertDriveFileOutlined.default, { sx: { fontSize: 16, color: "text.secondary" } })) }),
9612
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
9613
+ import_material75.ListItemText,
9614
+ {
9615
+ primary: node.name,
9616
+ slotProps: {
9617
+ primary: {
9618
+ sx: {
9619
+ fontSize: "0.8125rem",
9620
+ fontWeight: isSelected ? 600 : 400,
9621
+ overflow: "hidden",
9622
+ textOverflow: "ellipsis",
9623
+ whiteSpace: "nowrap"
9624
+ }
9625
+ }
9626
+ }
9627
+ }
9628
+ )
9629
+ ]
9630
+ }
9631
+ ),
9632
+ isFolder && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_material75.Collapse, { in: isExpanded, timeout: "auto", unmountOnExit: true, children: node.children?.map((child) => renderTreeNode(child, depth + 1)) })
9633
+ ] }, node.path);
9634
+ };
9635
+ return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
9636
+ import_material75.Box,
9637
+ {
9638
+ sx: {
9639
+ width: typeof width === "number" ? `${width}px` : width,
9640
+ minWidth: typeof width === "number" ? `${width}px` : width,
9641
+ height: "100%",
9642
+ overflow: "auto",
9643
+ borderRight: 1,
9644
+ borderColor: "divider",
9645
+ bgcolor: "background.default"
9646
+ },
9647
+ ...containerProps,
9648
+ children: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_material75.List, { dense: true, disablePadding: true, children: tree.map((node) => renderTreeNode(node, 0)) })
9649
+ }
9650
+ );
9651
+ };
9652
+
9653
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorStatusBar.tsx
9654
+ var import_material76 = require("@mui/material");
9655
+ var import_jsx_runtime100 = require("react/jsx-runtime");
9656
+ var LANGUAGE_LABELS = {
9657
+ typescript: "TypeScript",
9658
+ javascript: "JavaScript",
9659
+ json: "JSON",
9660
+ html: "HTML",
9661
+ css: "CSS",
9662
+ python: "Python",
9663
+ yaml: "YAML",
9664
+ markdown: "Markdown",
9665
+ sql: "SQL",
9666
+ xml: "XML",
9667
+ plaintext: "Plain Text"
9668
+ };
9669
+ var CodeEditorStatusBar = ({
9670
+ gitInfo,
9671
+ language,
9672
+ cursorPosition,
9673
+ items,
9674
+ renderStatusBar,
9675
+ containerProps
9676
+ }) => {
9677
+ if (renderStatusBar) {
9678
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_jsx_runtime100.Fragment, { children: renderStatusBar({ gitInfo, language, cursorPosition, items }) });
9679
+ }
9680
+ const leftItems = items?.filter((i) => i.align !== "right") ?? [];
9681
+ const rightItems = items?.filter((i) => i.align === "right") ?? [];
9682
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
9683
+ import_material76.Box,
9684
+ {
9685
+ sx: {
9686
+ display: "flex",
9687
+ alignItems: "center",
9688
+ justifyContent: "space-between",
9689
+ px: 1.5,
9690
+ py: 0.25,
9691
+ minHeight: 24,
9692
+ borderTop: 1,
9693
+ borderColor: "divider",
9694
+ bgcolor: "primary.main",
9695
+ color: "primary.contrastText",
9696
+ fontSize: "0.75rem",
9697
+ fontFamily: 'Monaco, Menlo, "Ubuntu Mono", Consolas, monospace',
9698
+ gap: 1,
9699
+ flexShrink: 0
9700
+ },
9701
+ ...containerProps,
9702
+ children: [
9703
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_material76.Box, { sx: { display: "flex", alignItems: "center", gap: 1.5, overflow: "hidden" }, children: [
9704
+ gitInfo && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9705
+ import_material76.Tooltip,
9706
+ {
9707
+ title: [
9708
+ gitInfo.remote && `Remote: ${gitInfo.remote}`,
9709
+ gitInfo.commitHash && `Commit: ${gitInfo.commitHash}`,
9710
+ gitInfo.ahead != null && `\u2191 ${gitInfo.ahead} ahead`,
9711
+ gitInfo.behind != null && `\u2193 ${gitInfo.behind} behind`
9712
+ ].filter(Boolean).join(" \xB7 ") || gitInfo.branch,
9713
+ enterDelay: 400,
9714
+ children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
9715
+ import_material76.Box,
9716
+ {
9717
+ sx: {
9718
+ display: "flex",
9719
+ alignItems: "center",
9720
+ gap: 0.5,
9721
+ cursor: "default",
9722
+ overflow: "hidden"
9723
+ },
9724
+ children: [
9725
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9726
+ "svg",
9727
+ {
9728
+ width: "14",
9729
+ height: "14",
9730
+ viewBox: "0 0 16 16",
9731
+ fill: "currentColor",
9732
+ style: { flexShrink: 0 },
9733
+ children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9734
+ "path",
9735
+ {
9736
+ fillRule: "evenodd",
9737
+ 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"
9738
+ }
9739
+ )
9740
+ }
9741
+ ),
9742
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9743
+ import_material76.Typography,
9744
+ {
9745
+ variant: "caption",
9746
+ sx: {
9747
+ fontSize: "inherit",
9748
+ fontFamily: "inherit",
9749
+ color: "inherit",
9750
+ lineHeight: 1,
9751
+ overflow: "hidden",
9752
+ textOverflow: "ellipsis",
9753
+ whiteSpace: "nowrap",
9754
+ maxWidth: 180
9755
+ },
9756
+ children: gitInfo.branch
9757
+ }
9758
+ ),
9759
+ gitInfo.isDirty && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9760
+ import_material76.Box,
9761
+ {
9762
+ component: "span",
9763
+ sx: {
9764
+ width: 6,
9765
+ height: 6,
9766
+ borderRadius: "50%",
9767
+ bgcolor: "warning.light",
9768
+ flexShrink: 0
9769
+ }
9770
+ }
9771
+ ),
9772
+ gitInfo.ahead != null && gitInfo.ahead > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_material76.Typography, { variant: "caption", sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, opacity: 0.85 }, children: [
9773
+ "\u2191",
9774
+ gitInfo.ahead
9775
+ ] }),
9776
+ gitInfo.behind != null && gitInfo.behind > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_material76.Typography, { variant: "caption", sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, opacity: 0.85 }, children: [
9777
+ "\u2193",
9778
+ gitInfo.behind
9779
+ ] })
9780
+ ]
9781
+ }
9782
+ )
9783
+ }
9784
+ ),
9785
+ leftItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(StatusBarItemElement, { item }, item.id))
9786
+ ] }),
9787
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_material76.Box, { sx: { display: "flex", alignItems: "center", gap: 1.5, overflow: "hidden" }, children: [
9788
+ rightItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(StatusBarItemElement, { item }, item.id)),
9789
+ cursorPosition && /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
9790
+ import_material76.Typography,
9791
+ {
9792
+ variant: "caption",
9793
+ sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, whiteSpace: "nowrap" },
9794
+ children: [
9795
+ "Ln ",
9796
+ cursorPosition.line,
9797
+ ", Col ",
9798
+ cursorPosition.column
9799
+ ]
9800
+ }
9801
+ ),
9802
+ language && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9803
+ import_material76.Typography,
9804
+ {
9805
+ variant: "caption",
9806
+ sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1, whiteSpace: "nowrap" },
9807
+ children: LANGUAGE_LABELS[language] ?? language
9808
+ }
9809
+ )
9810
+ ] })
9811
+ ]
9812
+ }
9813
+ );
9814
+ };
9815
+ var StatusBarItemElement = ({ item }) => {
9816
+ const inner = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9817
+ import_material76.Box,
9818
+ {
9819
+ onClick: item.onClick,
9820
+ sx: {
9821
+ display: "flex",
9822
+ alignItems: "center",
9823
+ cursor: item.onClick ? "pointer" : "default",
9824
+ lineHeight: 1,
9825
+ whiteSpace: "nowrap",
9826
+ "&:hover": item.onClick ? { opacity: 0.8 } : void 0
9827
+ },
9828
+ children: typeof item.content === "string" ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
9829
+ import_material76.Typography,
9830
+ {
9831
+ variant: "caption",
9832
+ sx: { fontSize: "inherit", fontFamily: "inherit", color: "inherit", lineHeight: 1 },
9833
+ children: item.content
9834
+ }
9835
+ ) : item.content
9836
+ }
9837
+ );
9838
+ if (item.tooltip) {
9839
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_material76.Tooltip, { title: item.tooltip, enterDelay: 400, children: inner });
9840
+ }
9841
+ return inner;
9842
+ };
9843
+
9844
+ // src/components/third-party/CodeEditorWorkspace/CodeEditorWorkspace.tsx
9845
+ var import_react40 = __toESM(require("react"));
9846
+ var import_material77 = require("@mui/material");
9847
+ var import_jsx_runtime101 = require("react/jsx-runtime");
9848
+ var CodeEditorWorkspace = ({
9849
+ files,
9850
+ initialOpenPaths,
9851
+ onFileChange,
9852
+ onValidationChange,
9853
+ fileTree,
9854
+ defaultExpandedPaths,
9855
+ showTabs = true,
9856
+ showFileTree = true,
9857
+ fileTreeWidth = 220,
9858
+ height = "500px",
9859
+ editorProps,
9860
+ containerProps,
9861
+ renderTabs,
9862
+ renderFileTree,
9863
+ renderEditor,
9864
+ renderStatusBar,
9865
+ gitInfo,
9866
+ showStatusBar = true,
9867
+ statusBarItems,
9868
+ onWorkspaceReady
9869
+ }) => {
9870
+ const workspace = useCodeEditorWorkspace({
9871
+ files,
9872
+ initialOpenPaths,
9873
+ onFileChange,
9874
+ onValidationChange
9875
+ });
9876
+ import_react40.default.useEffect(() => {
9877
+ onWorkspaceReady?.(workspace);
9878
+ }, []);
9879
+ const hasFileTree = showFileTree && fileTree && fileTree.length > 0;
9880
+ const tabsProps = {
9881
+ tabs: workspace.openTabs,
9882
+ activeTab: workspace.activeFilePath,
9883
+ onTabSelect: workspace.setActiveFile,
9884
+ onTabClose: workspace.closeFile
9885
+ };
9886
+ const tabsElement = showTabs ? renderTabs ? renderTabs({ ...tabsProps, workspace }) : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(CodeEditorTabs, { ...tabsProps }) : null;
9887
+ const fileTreeProps = {
9888
+ tree: fileTree ?? [],
9889
+ selectedPath: workspace.activeFilePath,
9890
+ onFileSelect: workspace.openFile,
9891
+ defaultExpandedPaths,
9892
+ width: fileTreeWidth
9893
+ };
9894
+ const fileTreeElement = hasFileTree ? renderFileTree ? renderFileTree({ ...fileTreeProps, workspace }) : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(CodeEditorFileTree, { ...fileTreeProps }) : null;
9895
+ const statusBarProps = {
9896
+ gitInfo,
9897
+ language: workspace.activeFile?.language,
9898
+ cursorPosition: workspace.cursorPosition ?? void 0,
9899
+ items: statusBarItems
9900
+ };
9901
+ const statusBarElement = showStatusBar ? renderStatusBar ? renderStatusBar({ ...statusBarProps, workspace }) : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(CodeEditorStatusBar, { ...statusBarProps }) : null;
9902
+ const editorElement = renderEditor ? renderEditor(workspace) : workspace.activeFile ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
9903
+ CodeEditor,
9904
+ {
9905
+ value: workspace.activeFile.value,
9906
+ onChange: workspace.handleEditorChange,
9907
+ language: workspace.activeFile.language,
9908
+ editorRef: workspace.editorRef,
9909
+ monacoRef: workspace.monacoRef,
9910
+ onMount: workspace.handleEditorMount,
9911
+ onValidate: (markers) => {
9912
+ if (workspace.activeFilePath) {
9913
+ workspace.validationMarkers[workspace.activeFilePath] = markers;
9914
+ }
9915
+ },
9916
+ externalModelManagement: true,
9917
+ height: "100%",
9918
+ ...editorProps
9919
+ }
9920
+ ) : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
9921
+ import_material77.Box,
9922
+ {
9923
+ sx: {
9924
+ flex: 1,
9925
+ display: "flex",
9926
+ alignItems: "center",
9927
+ justifyContent: "center",
9928
+ color: "text.secondary",
9929
+ fontSize: "0.875rem"
9930
+ },
9931
+ children: "Open a file to start editing"
9932
+ }
9933
+ );
9934
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
9935
+ import_material77.Box,
9936
+ {
9937
+ sx: {
9938
+ display: "flex",
9939
+ height: typeof height === "number" ? `${height}px` : height,
9940
+ border: 1,
9941
+ borderColor: "divider",
9942
+ borderRadius: 1,
9943
+ overflow: "hidden",
9944
+ bgcolor: "background.paper"
9945
+ },
9946
+ ...containerProps,
9947
+ children: [
9948
+ fileTreeElement,
9949
+ /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_material77.Box, { sx: { flex: 1, display: "flex", flexDirection: "column", minWidth: 0, overflow: "hidden" }, children: [
9950
+ tabsElement,
9951
+ /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_material77.Box, { sx: { flex: 1, overflow: "hidden" }, children: editorElement }),
9952
+ statusBarElement
9953
+ ] })
9954
+ ]
9955
+ }
9956
+ );
9957
+ };
9122
9958
  // Annotate the CommonJS export names for ESM import in node:
9123
9959
  0 && (module.exports = {
9124
9960
  Accordion,
@@ -9151,6 +9987,10 @@ var WorkflowNodeHandle = ({
9151
9987
  ClockIcon,
9152
9988
  CloudFlashIcon,
9153
9989
  CodeEditor,
9990
+ CodeEditorFileTree,
9991
+ CodeEditorStatusBar,
9992
+ CodeEditorTabs,
9993
+ CodeEditorWorkspace,
9154
9994
  Collapse,
9155
9995
  ConnectionLineType,
9156
9996
  ConnectionStatus,
@@ -9169,6 +10009,7 @@ var WorkflowNodeHandle = ({
9169
10009
  Drawer,
9170
10010
  Dropdown,
9171
10011
  DropdownAnchor,
10012
+ EXTENSION_LANGUAGE_MAP,
9172
10013
  EmptyState,
9173
10014
  EntityHeader,
9174
10015
  FilledFolderIcon,
@@ -9255,9 +10096,12 @@ var WorkflowNodeHandle = ({
9255
10096
  WorkspaceSelectorButton,
9256
10097
  colors,
9257
10098
  contextMenuItems,
10099
+ detectLanguage,
10100
+ getFileName,
9258
10101
  robPaletteExtended,
9259
10102
  robPrimaryPalette,
9260
10103
  theme,
10104
+ useCodeEditorWorkspace,
9261
10105
  useIsDesktop,
9262
10106
  useIsMobile,
9263
10107
  useIsTablet,