@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 @@
1
+ {"version":3,"sources":["../src/components/third-party/FlowEditor.tsx","../src/components/third-party/CodeEditor.tsx","../src/components/third-party/index.ts","../src/components/third-party/WorkflowNodeHandle.tsx","../src/components/third-party/CodeEditorWorkspace/CodeEditorWorkspace.types.ts","../src/components/third-party/CodeEditorWorkspace/useCodeEditorWorkspace.ts","../src/components/third-party/CodeEditorWorkspace/CodeEditorTabs.tsx","../src/components/third-party/CodeEditorWorkspace/CodeEditorFileTree.tsx","../src/components/third-party/CodeEditorWorkspace/CodeEditorStatusBar.tsx","../src/components/third-party/CodeEditorWorkspace/CodeEditorWelcomeScreen.tsx","../src/components/third-party/CodeEditorWorkspace/CodeEditorWorkspace.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\nimport ReactFlow, {\n Background,\n Controls,\n MiniMap,\n ReactFlowProvider,\n BackgroundVariant,\n ConnectionLineType,\n Node,\n Edge,\n OnNodesChange,\n OnEdgesChange,\n NodeTypes,\n EdgeTypes,\n ReactFlowInstance,\n ReactFlowProps,\n MiniMapProps,\n} from 'reactflow';\n// Note: reactflow CSS should be imported in Storybook preview.tsx\n// This ensures styles are available globally\nimport { Box, BoxProps } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\n\nexport interface FlowEditorProps extends Omit<ReactFlowProps, 'nodes' | 'edges'> {\n /**\n * Nodes to display in the flow\n */\n nodes: Node[];\n /**\n * Edges to display in the flow\n */\n edges: Edge[];\n /**\n * Callback when nodes change\n */\n onNodesChange?: OnNodesChange;\n /**\n * Callback when edges change\n */\n onEdgesChange?: OnEdgesChange;\n /**\n * Custom node types\n */\n nodeTypes?: NodeTypes;\n /**\n * Custom edge types\n */\n edgeTypes?: EdgeTypes;\n /**\n * Height of the flow editor\n * @default '600px'\n */\n height?: string | number;\n /**\n * Show background grid\n * @default true\n */\n showBackground?: boolean;\n /**\n * Background variant\n * @default 'dots'\n */\n backgroundVariant?: BackgroundVariant;\n /**\n * Show controls\n * @default true\n */\n showControls?: boolean;\n /**\n * Show minimap\n * @default false\n */\n showMinimap?: boolean;\n /**\n * Allow nodes to be dragged by the user\n * @default true\n */\n nodesDraggable?: boolean;\n /**\n * Show border around the container\n * @default true\n */\n showBorder?: boolean;\n /**\n * Border radius of the container in theme spacing units (e.g. 1 = 8px, 2 = 16px)\n * @default 1\n */\n borderRadius?: number;\n /**\n * Container props\n */\n containerProps?: BoxProps;\n /**\n * Props passed directly to the ReactFlow MiniMap component, allowing full customization\n * of colors, mask, style, and any other MiniMap option. Consumer values override defaults.\n */\n minimapProps?: Partial<MiniMapProps>;\n /**\n * Callback when flow instance is initialized\n */\n onInit?: (instance: ReactFlowInstance) => void;\n}\n\n/**\n * FlowEditor component - wrapper around ReactFlow with theme integration\n * \n * @example\n * ```tsx\n * <FlowEditor\n * nodes={nodes}\n * edges={edges}\n * onNodesChange={onNodesChange}\n * onEdgesChange={onEdgesChange}\n * height=\"500px\"\n * showBackground\n * showControls\n * />\n * ```\n */\nexport const FlowEditor: React.FC<FlowEditorProps> = ({\n nodes,\n edges,\n onNodesChange,\n onEdgesChange,\n nodeTypes,\n edgeTypes,\n height = '600px',\n showBackground = true,\n backgroundVariant = BackgroundVariant.Dots,\n showControls = true,\n showMinimap = false,\n showBorder = true,\n borderRadius = 1,\n nodesDraggable = true,\n containerProps,\n minimapProps,\n onInit,\n ...reactFlowProps\n}) => {\n const theme = useTheme();\n\n const handleInit = useCallback(\n (instance: ReactFlowInstance) => {\n if (onInit) {\n onInit(instance);\n }\n },\n [onInit]\n );\n\n const { sx: containerSx, ...restContainerProps } = containerProps ?? {};\n\n return (\n <ReactFlowProvider>\n <Box\n sx={[\n {\n width: '100%',\n height: typeof height === 'number' ? `${height}px` : height,\n overflow: 'hidden',\n ...(showBorder && { border: `1px solid ${theme.palette.divider}` }),\n borderRadius: borderRadius,\n backgroundColor: theme.palette.background.paper,\n },\n ...(Array.isArray(containerSx) ? containerSx : [containerSx]),\n ]}\n {...restContainerProps}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n onInit={handleInit}\n nodesDraggable={nodesDraggable}\n connectionLineType={ConnectionLineType.SmoothStep}\n defaultEdgeOptions={{\n style: {\n stroke: theme.palette.primary.main,\n strokeWidth: 2,\n },\n }}\n style={{\n backgroundColor: 'transparent',\n }}\n {...reactFlowProps}\n >\n {showBackground && (\n <Background\n variant={backgroundVariant}\n gap={16}\n size={1}\n color={theme.palette.divider}\n />\n )}\n {showControls && <Controls />}\n {showMinimap && (\n <MiniMap\n nodeColor={(node) => {\n const color = node.data?.color || theme.palette.primary.main;\n return typeof color === 'string' ? color : theme.palette.primary.main;\n }}\n nodeStrokeWidth={3}\n nodeBorderRadius={8}\n maskColor={`${theme.palette.background.paper}80`}\n style={{\n backgroundColor: theme.palette.background.paper,\n }}\n {...minimapProps}\n />\n )}\n </ReactFlow>\n </Box>\n </ReactFlowProvider>\n );\n};\n\nexport default FlowEditor;\n\n// Re-export commonly used types and components from reactflow\nexport type {\n Node,\n Edge,\n NodeTypes,\n EdgeTypes,\n ReactFlowInstance,\n OnNodesChange,\n OnEdgesChange,\n MiniMapProps,\n} from 'reactflow';\nexport { Background, Controls, MiniMap, Panel, BackgroundVariant, ConnectionLineType } from 'reactflow';\n\n","import React, { useCallback, useEffect, useState, useRef } from 'react';\nimport Editor, { Monaco } from '@monaco-editor/react';\nimport { Box, BoxProps, IconButton, Tooltip } from '@mui/material';\nimport FullscreenIcon from '@mui/icons-material/Fullscreen';\nimport FullscreenExitIcon from '@mui/icons-material/FullscreenExit';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport ExpandLessIcon from '@mui/icons-material/ExpandLess';\nimport type { editor } from 'monaco-editor';\n\nexport type CodeEditorLanguage =\n | 'typescript'\n | 'javascript'\n | 'json'\n | 'html'\n | 'css'\n | 'python'\n | 'yaml'\n | 'markdown'\n | 'sql'\n | 'xml'\n | 'plaintext';\n\nexport interface CodeEditorProps {\n /**\n * Current value of the editor\n */\n value: string;\n /**\n * Callback when value changes\n */\n onChange: (value: string) => void;\n /**\n * Programming language\n * @default 'typescript'\n */\n language?: CodeEditorLanguage;\n /**\n * Height of the editor\n * @default '400px'\n */\n height?: string | number;\n /**\n * Minimum height\n */\n minHeight?: string | number;\n /**\n * Theme ('light' | 'dark' | 'vs-dark' | 'hc-black')\n * If not provided, will use theme from design system\n */\n theme?: string;\n /**\n * Show line numbers\n * @default 'on'\n */\n lineNumbers?: 'on' | 'off' | 'relative' | 'interval';\n /**\n * Editor options (monaco editor options)\n */\n options?: editor.IStandaloneEditorConstructionOptions;\n /**\n * Callback when editor is mounted\n */\n onMount?: (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => void;\n /**\n * Callback for validation errors\n */\n onValidate?: (markers: editor.IMarker[]) => void;\n /**\n * Ref to editor instance\n */\n editorRef?: React.MutableRefObject<editor.IStandaloneCodeEditor | null>;\n /**\n * Ref to Monaco instance\n */\n monacoRef?: React.MutableRefObject<Monaco | null>;\n /**\n * Callback when fullscreen state changes\n */\n onFullscreenChange?: (isFullscreen: boolean) => void;\n /**\n * Props for the container Box.\n */\n containerProps?: BoxProps;\n /**\n * Additional TypeScript type definitions to add to the editor context.\n * Can be a string with type definitions or an array of type definition strings.\n * Each string will be added as a separate extra lib to Monaco.\n *\n * @example\n * ```tsx\n * <CodeEditor\n * value={code}\n * onChange={setCode}\n * typeDefinitions={`\n * declare interface MyCustomType {\n * id: string;\n * name: string;\n * }\n * `}\n * />\n * ```\n */\n typeDefinitions?: string | string[];\n /**\n * When true, the editor skips internal value syncing and lets an external\n * source (e.g. useCodeEditorWorkspace) manage Monaco models directly.\n * The `value` prop is still used as the initial/display value but won't\n * be force-synced to the editor.\n * @default false\n */\n externalModelManagement?: boolean;\n}\n\n// Monaco Editor will use the local version from node_modules automatically\n// No need to configure loader.config() - @monaco-editor/react handles it\n\n// Configure TypeScript settings when Monaco is loaded\nexport const configureTypeScript = (monaco: Monaco) => {\n // Configure TypeScript settings\n monaco.languages.typescript.typescriptDefaults.setCompilerOptions({\n target: monaco.languages.typescript.ScriptTarget.ES2020,\n allowNonTsExtensions: true,\n moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,\n module: monaco.languages.typescript.ModuleKind.ESNext,\n noEmit: false,\n lib: ['es2020', 'dom'],\n noUnusedLocals: false,\n noUnusedParameters: false,\n noImplicitAny: false,\n noImplicitReturns: false,\n noFallthroughCasesInSwitch: false,\n // Treat every file as a module so top-level declarations don't clash\n // across files in the workspace (prevents false \"Cannot redeclare\" errors).\n moduleDetection: 3, // ts.ModuleDetectionKind.Force\n });\n\n monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({\n noSemanticValidation: false,\n noSyntaxValidation: false,\n noSuggestionDiagnostics: true,\n diagnosticCodesToIgnore: [\n 6133, // 'x' is declared but its value is never read\n 6196, // 'x' is declared but its value is never read (different variant)\n ],\n });\n};\n\n/**\n * CodeEditor component - wrapper around Monaco Editor matching dynamic-indexer-client implementation\n *\n * @example\n * ```tsx\n * <CodeEditor\n * value={code}\n * onChange={setCode}\n * language=\"typescript\"\n * height=\"500px\"\n * onValidate={(markers) => console.log('Errors:', markers)}\n * />\n * ```\n */\nexport const CodeEditor: React.FC<CodeEditorProps> = ({\n value,\n onChange,\n language = 'typescript',\n height = '400px',\n minHeight,\n theme: themeProp,\n lineNumbers = 'on',\n options,\n onMount,\n onValidate,\n editorRef,\n monacoRef,\n onFullscreenChange,\n containerProps,\n typeDefinitions,\n externalModelManagement = false,\n}) => {\n const [isEditorReady, setIsEditorReady] = useState(false);\n const [validationErrors, setValidationErrors] = useState<editor.IMarker[]>([]);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [tsCode, setTsCode] = useState<string>(value);\n const [actualHeight, setActualHeight] = useState<string>(\n typeof height === 'number' ? `${height}px` : height\n );\n const [showProblems, setShowProblems] = useState(false);\n const [hasUserToggledProblems, setHasUserToggledProblems] = useState(false);\n\n // Auto-open the Problems panel only until the user manually toggles it.\n useEffect(() => {\n if (hasUserToggledProblems) return; // respect user's choice after first toggle\n if (validationErrors.length > 0) {\n setShowProblems(true);\n } else {\n setShowProblems(false);\n }\n }, [validationErrors, hasUserToggledProblems]);\n\n const internalEditorRef = useRef<editor.IStandaloneCodeEditor | null>(null);\n const internalMonacoRef = useRef<Monaco | null>(null);\n\n // Use provided refs or internal refs\n const finalEditorRef = editorRef || internalEditorRef;\n const finalMonacoRef = monacoRef || internalMonacoRef;\n\n useEffect(() => {\n if (isFullscreen) {\n // Account for header height (64px) + padding (16px) = 80px\n setActualHeight('calc(100vh - 80px)');\n } else {\n setActualHeight(typeof height === 'number' ? `${height}px` : height);\n }\n }, [height, isFullscreen]);\n\n // Toggle fullscreen\n const toggleFullscreen = useCallback(() => {\n const newFullscreenState = !isFullscreen;\n setIsFullscreen(newFullscreenState);\n if (onFullscreenChange) {\n onFullscreenChange(newFullscreenState);\n }\n }, [isFullscreen, onFullscreenChange]);\n\n // Jump to a marker position in the editor\n const gotoMarker = useCallback(\n (marker: editor.IMarker) => {\n const ed = finalEditorRef?.current;\n if (!ed) return;\n const position = { lineNumber: marker.startLineNumber, column: marker.startColumn || 1 };\n try {\n ed.revealPositionInCenter(position);\n ed.setPosition(position);\n ed.focus();\n } catch (e) {\n console.error('CodeEditor: Failed to navigate to marker', e);\n }\n },\n [finalEditorRef]\n );\n\n // Handle ESC key for fullscreen exit\n useEffect(() => {\n if (!isFullscreen) return;\n\n function escapeHandler(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n\n setIsFullscreen(false);\n if (onFullscreenChange) {\n onFullscreenChange(false);\n }\n }\n }\n\n window.addEventListener('keydown', escapeHandler, { capture: true });\n\n return () => {\n window.removeEventListener('keydown', escapeHandler, { capture: true });\n };\n }, [isFullscreen, onFullscreenChange]);\n\n const handleEditorDidMount = useCallback(\n (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => {\n console.log('CodeEditor: onMount called', { editor: !!editor, monaco: !!monaco });\n\n try {\n // Configure TypeScript settings when Monaco is loaded\n configureTypeScript(monaco);\n } catch (e) {\n console.error('CodeEditor: Failed to configure TypeScript', e);\n }\n\n if (finalEditorRef) {\n finalEditorRef.current = editor;\n }\n if (finalMonacoRef) {\n finalMonacoRef.current = monaco;\n }\n\n setIsEditorReady(true);\n console.log('CodeEditor: Editor ready');\n\n try {\n // Add ESC key binding directly in editor\n editor.addCommand(monaco.KeyCode.Escape, () => {\n if (isFullscreen) {\n setIsFullscreen(false);\n if (onFullscreenChange) {\n onFullscreenChange(false);\n }\n return true; // Command handled\n }\n return false; // Let default behavior work when not fullscreen\n });\n\n // Add validation callback\n editor.onDidChangeModelDecorations(() => {\n const model = editor.getModel();\n if (model && onValidate) {\n const markers = monaco.editor.getModelMarkers({ resource: model.uri });\n onValidate(markers);\n setValidationErrors(markers);\n }\n });\n\n // Also check initial markers\n const model = editor.getModel();\n if (model && onValidate) {\n const markers = monaco.editor.getModelMarkers({ resource: model.uri });\n onValidate(markers);\n setValidationErrors(markers);\n }\n } catch (e) {\n console.error('CodeEditor: Error setting up editor callbacks', e);\n }\n\n // Call custom onMount if provided\n if (onMount) {\n try {\n onMount(editor, monaco);\n } catch (e) {\n console.error('CodeEditor: Error in custom onMount', e);\n }\n }\n },\n [isFullscreen, onFullscreenChange, onValidate, onMount, finalEditorRef, finalMonacoRef]\n );\n\n // Add custom type definitions when Monaco is ready and typeDefinitions change\n useEffect(() => {\n if (!isEditorReady || !finalMonacoRef?.current || !typeDefinitions) return;\n\n const monaco = finalMonacoRef.current;\n const definitions = Array.isArray(typeDefinitions) ? typeDefinitions : [typeDefinitions];\n const uris: string[] = [];\n\n try {\n // Add each type definition as a separate extra lib\n definitions.forEach((def: string, index: number) => {\n if (def && def.trim()) {\n const uri = `ts:filename/custom-types-${index}.d.ts`;\n uris.push(uri);\n monaco.languages.typescript.typescriptDefaults.addExtraLib(def, uri);\n }\n });\n } catch (error) {\n console.error('CodeEditor: Error adding type definitions:', error);\n }\n\n // Note: Monaco doesn't have a direct removeExtraLib method\n // The definitions will be replaced when the component updates with new definitions\n // This is acceptable as extra libs are additive and don't cause conflicts\n }, [isEditorReady, finalMonacoRef, typeDefinitions]);\n\n const handleCodeChange = (newValue: string | undefined) => {\n const valueStr = newValue || '';\n setTsCode(valueStr);\n onChange(valueStr);\n };\n\n // Sync external value prop with internal state\n // Skip when externalModelManagement is true (workspace hook manages models)\n useEffect(() => {\n if (externalModelManagement) return;\n if (value !== tsCode) {\n setTsCode(value);\n if (isEditorReady && finalEditorRef?.current) {\n const editor = finalEditorRef.current;\n const currentValue = editor.getValue();\n if (currentValue !== value) {\n editor.setValue(value);\n }\n }\n }\n }, [value, tsCode, isEditorReady, finalEditorRef, externalModelManagement]);\n\n const editorMinHeight = minHeight\n ? typeof minHeight === 'number'\n ? `${minHeight}px`\n : minHeight\n : '400px';\n\n const defaultOptions: editor.IStandaloneEditorConstructionOptions = {\n lineNumbers,\n minimap: { enabled: false },\n readOnly: false,\n wordWrap: 'on',\n fontSize: 14,\n fontFamily: 'Monaco, Menlo, \"Ubuntu Mono\", Consolas, \"source-code-pro\", monospace',\n automaticLayout: true,\n scrollBeyondLastLine: false,\n theme: themeProp || 'vs',\n ...options,\n };\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: isFullscreen ? '100vh' : '100%',\n minHeight: isFullscreen ? '100vh' : editorMinHeight,\n position: isFullscreen ? 'fixed' : 'relative',\n top: isFullscreen ? 0 : 'auto',\n left: isFullscreen ? 0 : 'auto',\n right: isFullscreen ? 0 : 'auto',\n bottom: isFullscreen ? 0 : 'auto',\n zIndex: isFullscreen ? 9999 : 'auto',\n bgcolor: 'background.paper',\n pt: isFullscreen ? '80px' : 0, // Add padding top in fullscreen to account for header (64px) + spacing (16px)\n px: isFullscreen ? 2 : 0,\n pb: isFullscreen ? 2 : 0,\n overflow: isFullscreen ? 'hidden' : 'visible',\n }}\n >\n <Box\n sx={{\n flex: 1,\n border: 1,\n borderColor: validationErrors.length > 0 ? 'error.main' : 'divider',\n borderRadius: 1,\n minHeight: editorMinHeight,\n overflow: 'hidden',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n }}\n {...containerProps}\n >\n <Tooltip title={isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'}>\n <IconButton\n onClick={toggleFullscreen}\n size=\"small\"\n sx={{\n position: isFullscreen ? 'fixed' : 'absolute',\n top: isFullscreen ? 72 : 8, // Position below header in fullscreen mode (header is ~64px)\n right: isFullscreen ? 16 : 8,\n zIndex: 10000, // Ensure it's above other elements\n bgcolor: 'rgba(255, 255, 255, 0.7)',\n '&:hover': {\n bgcolor: 'rgba(255, 255, 255, 0.9)',\n },\n boxShadow: 1,\n }}\n >\n {isFullscreen ? (\n <FullscreenExitIcon fontSize=\"small\" />\n ) : (\n <FullscreenIcon fontSize=\"small\" />\n )}\n </IconButton>\n </Tooltip>\n\n <Box\n sx={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n minHeight: editorMinHeight,\n position: 'relative',\n height: isFullscreen ? '100%' : actualHeight,\n }}\n >\n <Editor\n height=\"100%\"\n defaultLanguage={language}\n defaultValue={value}\n value={tsCode}\n onChange={handleCodeChange}\n onMount={handleEditorDidMount}\n theme={themeProp || 'vs'}\n options={defaultOptions}\n loading={\n <Box sx={{ p: 2, textAlign: 'center' }}>\n Loading Monaco Editor...\n </Box>\n }\n beforeMount={(monaco) => {\n console.log('CodeEditor: beforeMount called', { monaco: !!monaco });\n }}\n />\n </Box>\n\n {/* Problems panel at the bottom (Monaco-style) */}\n {validationErrors.length > 0 && (\n <Box\n sx={{\n borderTop: 1,\n borderColor: 'divider',\n bgcolor: 'background.default',\n display: 'flex',\n flexDirection: 'column',\n maxHeight: showProblems ? 180 : 40,\n minHeight: 40,\n transition: 'max-height 0.2s ease',\n }}\n >\n {/* Panel header */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1,\n py: 0.5,\n gap: 1,\n borderBottom: showProblems ? '1px solid' : 'none',\n borderColor: 'divider',\n fontSize: '0.875rem',\n color: 'text.secondary',\n }}\n >\n <ErrorOutlineIcon color=\"error\" fontSize=\"small\" />\n <Box sx={{ fontWeight: 600, color: 'text.primary' }}>Problems</Box>\n <Box sx={{ ml: 1 }}>\n {validationErrors.length} error{validationErrors.length > 1 ? 's' : ''}\n </Box>\n <Box sx={{ flex: 1 }} />\n <IconButton\n size=\"small\"\n aria-label=\"Toggle problems panel\"\n onClick={() => {\n setHasUserToggledProblems(true);\n setShowProblems((s) => !s);\n }}\n >\n {showProblems ? <ExpandMoreIcon fontSize=\"small\" /> : <ExpandLessIcon fontSize=\"small\" />}\n </IconButton>\n </Box>\n {/* Problems list */}\n {showProblems && (\n <Box sx={{ overflow: 'auto' }}>\n {validationErrors.map((error, index) => (\n <Box\n key={`${error.startLineNumber}-${error.startColumn}-${index}`}\n onClick={() => gotoMarker(error)}\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1.5,\n py: 0.75,\n gap: 1,\n cursor: 'pointer',\n '&:hover': { bgcolor: 'action.hover' },\n borderBottom: '1px dashed',\n borderColor: 'divider',\n fontSize: '0.85rem',\n }}\n >\n <ErrorOutlineIcon color=\"error\" sx={{ fontSize: 18 }} />\n <Box sx={{ color: 'text.secondary', width: 64 }}>Line {error.startLineNumber}</Box>\n <Box sx={{ color: 'text.primary', flex: 1, minWidth: 0 }}>\n {error.message}\n </Box>\n </Box>\n ))}\n </Box>\n )}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nexport default CodeEditor;\n","export { FlowEditor } from './FlowEditor';\nexport type { FlowEditorProps } from './FlowEditor';\nexport { CodeEditor } from './CodeEditor';\nexport type { CodeEditorProps, CodeEditorLanguage } from './CodeEditor';\n// Re-export commonly used ReactFlow types\nexport type {\n Node,\n Edge,\n NodeTypes,\n EdgeTypes,\n ReactFlowInstance,\n OnNodesChange,\n OnEdgesChange,\n} from './FlowEditor';\nexport {\n Background,\n Controls,\n MiniMap,\n BackgroundVariant,\n ConnectionLineType,\n} from './FlowEditor';\nexport { Panel } from 'reactflow';\nexport { WorkflowNodeHandle } from './WorkflowNodeHandle';\nexport type { WorkflowNodeData } from './WorkflowNodeHandle';\n\n// CodeEditor Workspace (multi-file editor)\nexport {\n CodeEditorWorkspace,\n CodeEditorWelcomeScreen,\n CodeEditorTabs,\n CodeEditorFileTree,\n CodeEditorStatusBar,\n useCodeEditorWorkspace,\n detectLanguage,\n getFileName,\n EXTENSION_LANGUAGE_MAP,\n} from './CodeEditorWorkspace';\nexport type {\n CodeEditorWorkspaceProps,\n CodeEditorWelcomeScreenProps,\n CodeEditorTabsProps,\n CodeEditorTabRenderProps,\n CodeEditorFileTreeProps,\n FileTreeNodeRenderProps,\n CodeEditorStatusBarProps,\n CodeEditorStatusBarRenderProps,\n UseCodeEditorWorkspaceOptions,\n UseCodeEditorWorkspaceReturn,\n CodeEditorFile,\n CodeEditorTab,\n FileTreeNode,\n GitInfo,\n CodeEditorStatusBarItem,\n} from './CodeEditorWorkspace';\n","import React from 'react';\nimport { Handle, Position } from 'reactflow';\nimport type { NodeProps } from 'reactflow';\nimport { useTheme } from '@mui/material';\nimport {\n WorkflowNode,\n WORKFLOW_NODE_SHADOW,\n type WorkflowNodeType,\n} from '../layout/WorkflowNode/WorkflowNode';\nimport { workflowNodeColors } from '../../theme';\n\n/** Data shape expected by the WorkflowNodeHandle custom ReactFlow node */\nexport interface WorkflowNodeData {\n /** Workflow node type — drives accent color, icon, and badge */\n nodeType: WorkflowNodeType;\n /** Primary title */\n title: string;\n /** Optional description */\n description?: string;\n /** Override default icon */\n icon?: React.ReactNode;\n /** Override default badge label */\n badgeLabel?: string;\n}\n\n/**\n * Thin ReactFlow custom-node wrapper around WorkflowNode.\n *\n * Renders a target Handle (top), the WorkflowNode card, and a source Handle (bottom).\n * Register as a custom nodeType:\n *\n * @example\n * ```tsx\n * const nodeTypes = { workflowNode: WorkflowNodeHandle };\n * <FlowEditor nodes={nodes} edges={edges} nodeTypes={nodeTypes} />\n * ```\n */\nexport const WorkflowNodeHandle: React.FC<NodeProps<WorkflowNodeData>> = ({\n data,\n selected,\n}) => {\n const theme = useTheme();\n const handleColor = workflowNodeColors[data.nodeType].accent;\n\n const handleStyle: React.CSSProperties = {\n width: 8,\n height: 8,\n borderRadius: '999px',\n border: `2px solid ${theme.palette.common.white}`,\n background: handleColor,\n boxShadow: WORKFLOW_NODE_SHADOW,\n };\n\n return (\n <>\n <Handle type=\"target\" position={Position.Left} style={handleStyle} />\n <WorkflowNode\n nodeType={data.nodeType}\n title={data.title}\n description={data.description}\n icon={data.icon}\n badgeLabel={data.badgeLabel}\n selected={selected}\n showSideDots={false}\n />\n <Handle type=\"source\" position={Position.Right} style={handleStyle} />\n </>\n );\n};\n","import type { ReactNode } from 'react';\nimport type { CodeEditorLanguage } from '../CodeEditor';\n\n/**\n * Represents a single file in the workspace.\n */\nexport interface CodeEditorFile {\n /** Unique file path, e.g. \"src/index.ts\" */\n path: string;\n /** Programming language (auto-detected from extension when omitted) */\n language?: CodeEditorLanguage;\n /** File content */\n value: string;\n}\n\n/**\n * Represents an open tab in the editor.\n */\nexport interface CodeEditorTab {\n /** File path this tab corresponds to */\n path: string;\n /** Display label (defaults to the filename portion of path) */\n label?: string;\n /** Whether the file has unsaved changes */\n isDirty?: boolean;\n /** Git sync status — distinct from isDirty (editor changes) */\n syncStatus?: 'new' | 'modified';\n}\n\n/** Git sync status for a file tree node. */\nexport type FileTreeNodeStatus = 'new' | 'modified' | 'deleted';\n\n/**\n * A node in the file tree.\n */\nexport interface FileTreeNode {\n /** Display name */\n name: string;\n /** Full path (unique identifier) */\n path: string;\n /** Whether this is a file or folder */\n type: 'file' | 'folder';\n /** Children nodes (only for folders) */\n children?: FileTreeNode[];\n /** Optional custom icon */\n icon?: ReactNode;\n /** Git sync status indicator (new / modified / deleted) */\n status?: FileTreeNodeStatus;\n}\n\n/**\n * Git repository information passed into the workspace.\n * The consuming app is responsible for fetching this data.\n */\nexport interface GitInfo {\n /** Current branch name, e.g. \"feat/advanced-code-editor\" */\n branch: string;\n /** Whether the working tree has uncommitted changes */\n isDirty?: boolean;\n /** Short commit hash of HEAD */\n commitHash?: string;\n /** Remote name, e.g. \"origin\" */\n remote?: string;\n /** Number of commits ahead of remote */\n ahead?: number;\n /** Number of commits behind remote */\n behind?: number;\n}\n\n/**\n * A custom item to render in the status bar.\n */\nexport interface CodeEditorStatusBarItem {\n /** Unique key */\n id: string;\n /** Content to display (string or ReactNode) */\n content: ReactNode;\n /** Side of the status bar */\n align?: 'left' | 'right';\n /** Optional click handler */\n onClick?: () => void;\n /** Tooltip text */\n tooltip?: string;\n}\n\n/**\n * Map from file extension to CodeEditorLanguage.\n */\nexport const EXTENSION_LANGUAGE_MAP: Record<string, CodeEditorLanguage> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n json: 'json',\n html: 'html',\n htm: 'html',\n css: 'css',\n py: 'python',\n yaml: 'yaml',\n yml: 'yaml',\n md: 'markdown',\n sql: 'sql',\n xml: 'xml',\n txt: 'plaintext',\n};\n\n/**\n * Detect language from a file path extension.\n */\nexport function detectLanguage(path: string): CodeEditorLanguage {\n const ext = path.split('.').pop()?.toLowerCase() ?? '';\n return EXTENSION_LANGUAGE_MAP[ext] ?? 'plaintext';\n}\n\n/**\n * Extract the filename from a path.\n */\nexport function getFileName(path: string): string {\n return path.split('/').pop() ?? path;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { Monaco } from '@monaco-editor/react';\nimport type { editor, Uri } from 'monaco-editor';\nimport type { CodeEditorFile, CodeEditorTab } from './CodeEditorWorkspace.types';\nimport { detectLanguage, getFileName } from './CodeEditorWorkspace.types';\n\nexport interface UseCodeEditorWorkspaceOptions {\n /** All files available in the workspace */\n files: CodeEditorFile[];\n /** File paths to open as tabs initially */\n initialOpenPaths?: string[];\n /** Called when a file's content is modified in the editor */\n onFileChange?: (path: string, value: string) => void;\n /** Called when validation markers change across all open models */\n onValidationChange?: (markers: Record<string, editor.IMarker[]>) => void;\n}\n\nexport interface UseCodeEditorWorkspaceReturn {\n /** Currently open tabs */\n openTabs: CodeEditorTab[];\n /** Path of the active file (shown in editor) */\n activeFilePath: string | null;\n /** Open a file by path (creates tab if not already open, sets it active) */\n openFile: (path: string) => void;\n /** Close a tab by path */\n closeFile: (path: string) => void;\n /** Set a specific file as active */\n setActiveFile: (path: string) => void;\n /** Programmatically update file content */\n updateFileContent: (path: string, value: string) => void;\n /** Get the current content of a file */\n getFileContent: (path: string) => string | undefined;\n /** Get the active file data */\n activeFile: CodeEditorFile | undefined;\n /** Ref to hold the Monaco instance — pass to CodeEditor's monacoRef */\n monacoRef: React.MutableRefObject<Monaco | null>;\n /** Ref to hold the editor instance — pass to CodeEditor's editorRef */\n editorRef: React.MutableRefObject<editor.IStandaloneCodeEditor | null>;\n /** Handler to pass to CodeEditor's onMount */\n handleEditorMount: (editorInstance: editor.IStandaloneCodeEditor, monacoInstance: Monaco) => void;\n /** Handler to pass to CodeEditor's onChange */\n handleEditorChange: (value: string) => void;\n /** Aggregated validation markers keyed by file path */\n validationMarkers: Record<string, editor.IMarker[]>;\n /** Mark a file as saved (clears dirty flag) */\n markSaved: (path: string) => void;\n /** Mark all files as saved */\n markAllSaved: () => void;\n /** Current cursor position in the active editor */\n cursorPosition: { line: number; column: number } | null;\n}\n\n/**\n * Headless hook for managing a multi-file Monaco editor workspace.\n *\n * Manages Monaco models, open tabs, active file, and dirty tracking.\n * Pass the returned refs/handlers to a `CodeEditor` component.\n *\n * @example\n * ```tsx\n * const workspace = useCodeEditorWorkspace({ files, onFileChange });\n *\n * <CodeEditorTabs\n * tabs={workspace.openTabs}\n * activeTab={workspace.activeFilePath}\n * onTabSelect={workspace.setActiveFile}\n * onTabClose={workspace.closeFile}\n * />\n * <CodeEditor\n * value={workspace.activeFile?.value ?? ''}\n * onChange={workspace.handleEditorChange}\n * language={workspace.activeFile?.language}\n * editorRef={workspace.editorRef}\n * monacoRef={workspace.monacoRef}\n * onMount={workspace.handleEditorMount}\n * />\n * ```\n */\nexport function useCodeEditorWorkspace({\n files,\n initialOpenPaths,\n onFileChange,\n onValidationChange,\n}: UseCodeEditorWorkspaceOptions): UseCodeEditorWorkspaceReturn {\n // --- Internal file content store (local copy that tracks edits) ---\n const fileContentsRef = useRef<Map<string, string>>(new Map());\n const originalContentsRef = useRef<Map<string, string>>(new Map());\n\n // --- Tabs & active file ---\n const [openTabs, setOpenTabs] = useState<CodeEditorTab[]>([]);\n const [activeFilePath, setActiveFilePath] = useState<string | null>(null);\n\n // --- Monaco refs ---\n const monacoRef = useRef<Monaco | null>(null);\n const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null);\n const modelsRef = useRef<Map<string, editor.ITextModel>>(new Map());\n\n // --- Validation ---\n const [validationMarkers, setValidationMarkers] = useState<Record<string, editor.IMarker[]>>({});\n\n // --- Cursor position ---\n const [cursorPosition, setCursorPosition] = useState<{ line: number; column: number } | null>(null);\n\n // Sync file contents from props\n useEffect(() => {\n for (const file of files) {\n // Only update if we don't already have local content (i.e. user hasn't edited)\n if (!fileContentsRef.current.has(file.path)) {\n fileContentsRef.current.set(file.path, file.value);\n originalContentsRef.current.set(file.path, file.value);\n }\n\n // Update Monaco model if it exists and content differs from external source\n const model = modelsRef.current.get(file.path);\n if (model && !model.isDisposed()) {\n // If the incoming value already matches our local content, this is just\n // the consumer echoing back a local edit — skip to avoid resetting cursor.\n if (file.value === fileContentsRef.current.get(file.path)) {\n originalContentsRef.current.set(file.path, file.value);\n continue;\n }\n\n // Truly external change — update model only if user hasn't diverged\n if (originalContentsRef.current.get(file.path) !== file.value) {\n const localContent = fileContentsRef.current.get(file.path) ?? '';\n const previousOriginal = originalContentsRef.current.get(file.path) ?? '';\n originalContentsRef.current.set(file.path, file.value);\n\n // Only safe to overwrite if local content still matches the previous original\n if (localContent === previousOriginal) {\n fileContentsRef.current.set(file.path, file.value);\n model.setValue(file.value);\n }\n }\n }\n }\n }, [files]);\n\n // Open initial tabs\n useEffect(() => {\n if (initialOpenPaths && initialOpenPaths.length > 0) {\n const tabs: CodeEditorTab[] = initialOpenPaths\n .filter((p) => files.some((f) => f.path === p))\n .map((p) => ({\n path: p,\n label: getFileName(p),\n isDirty: false,\n }));\n if (tabs.length > 0) {\n setOpenTabs(tabs);\n setActiveFilePath(tabs[0].path);\n }\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // --- Model management helpers ---\n const getOrCreateModel = useCallback(\n (path: string): editor.ITextModel | null => {\n const monaco = monacoRef.current;\n if (!monaco) return null;\n\n const existing = modelsRef.current.get(path);\n if (existing && !existing.isDisposed()) return existing;\n\n const file = files.find((f) => f.path === path);\n const content = fileContentsRef.current.get(path) ?? file?.value ?? '';\n const lang = file?.language ?? detectLanguage(path);\n\n const uri = monaco.Uri.parse(`file:///${path}`);\n // Check if Monaco already has a model for this URI\n let model = monaco.editor.getModel(uri);\n if (!model) {\n model = monaco.editor.createModel(content, lang, uri);\n }\n modelsRef.current.set(path, model);\n return model;\n },\n [files],\n );\n\n const disposeModel = useCallback((path: string) => {\n const model = modelsRef.current.get(path);\n if (model && !model.isDisposed()) {\n model.dispose();\n }\n modelsRef.current.delete(path);\n }, []);\n\n // Switch the editor to a different model\n const switchToFile = useCallback(\n (path: string) => {\n const ed = editorRef.current;\n if (!ed) return;\n\n const model = getOrCreateModel(path);\n if (model) {\n ed.setModel(model);\n // Restore cursor position could be added here if needed\n }\n },\n [getOrCreateModel],\n );\n\n // --- Public actions ---\n const openFile = useCallback(\n (path: string) => {\n const file = files.find((f) => f.path === path);\n if (!file) return;\n\n // Ensure we have content stored\n if (!fileContentsRef.current.has(path)) {\n fileContentsRef.current.set(path, file.value);\n originalContentsRef.current.set(path, file.value);\n }\n\n setOpenTabs((prev) => {\n const exists = prev.some((t) => t.path === path);\n if (exists) return prev;\n return [\n ...prev,\n { path, label: getFileName(path), isDirty: false },\n ];\n });\n setActiveFilePath(path);\n switchToFile(path);\n },\n [files, switchToFile],\n );\n\n const closeFile = useCallback(\n (path: string) => {\n disposeModel(path);\n\n setOpenTabs((prev) => {\n const newTabs = prev.filter((t) => t.path !== path);\n // If we're closing the active tab, switch to an adjacent one\n if (activeFilePath === path) {\n const closedIndex = prev.findIndex((t) => t.path === path);\n const nextTab =\n newTabs[Math.min(closedIndex, newTabs.length - 1)] ?? null;\n const nextPath = nextTab?.path ?? null;\n setActiveFilePath(nextPath);\n if (nextPath) {\n switchToFile(nextPath);\n }\n }\n return newTabs;\n });\n },\n [activeFilePath, disposeModel, switchToFile],\n );\n\n const setActiveFileAction = useCallback(\n (path: string) => {\n setActiveFilePath(path);\n switchToFile(path);\n },\n [switchToFile],\n );\n\n const updateFileContent = useCallback(\n (path: string, value: string) => {\n fileContentsRef.current.set(path, value);\n\n const model = modelsRef.current.get(path);\n if (model && !model.isDisposed() && model.getValue() !== value) {\n model.setValue(value);\n }\n\n const isDirty = value !== originalContentsRef.current.get(path);\n setOpenTabs((prev) =>\n prev.map((t) => (t.path === path ? { ...t, isDirty } : t)),\n );\n\n onFileChange?.(path, value);\n },\n [onFileChange],\n );\n\n const getFileContent = useCallback((path: string) => {\n return fileContentsRef.current.get(path);\n }, []);\n\n const markSaved = useCallback((path: string) => {\n const content = fileContentsRef.current.get(path);\n if (content !== undefined) {\n originalContentsRef.current.set(path, content);\n }\n setOpenTabs((prev) =>\n prev.map((t) => (t.path === path ? { ...t, isDirty: false } : t)),\n );\n }, []);\n\n const markAllSaved = useCallback(() => {\n for (const [path, content] of fileContentsRef.current.entries()) {\n originalContentsRef.current.set(path, content);\n }\n setOpenTabs((prev) => prev.map((t) => ({ ...t, isDirty: false })));\n }, []);\n\n // --- Editor event handlers ---\n const handleEditorMount = useCallback(\n (editorInstance: editor.IStandaloneCodeEditor, monacoInstance: Monaco) => {\n monacoRef.current = monacoInstance;\n editorRef.current = editorInstance;\n\n // If we already have an active file, set its model\n if (activeFilePath) {\n const model = getOrCreateModel(activeFilePath);\n if (model) {\n editorInstance.setModel(model);\n }\n }\n\n // Track cursor position\n editorInstance.onDidChangeCursorPosition((e) => {\n setCursorPosition({ line: e.position.lineNumber, column: e.position.column });\n });\n // Set initial cursor position\n const pos = editorInstance.getPosition();\n if (pos) {\n setCursorPosition({ line: pos.lineNumber, column: pos.column });\n }\n\n // Listen for marker changes to track validation across all models\n monacoInstance.editor.onDidChangeMarkers((uris: readonly Uri[]) => {\n const newMarkers: Record<string, editor.IMarker[]> = { ...validationMarkers };\n for (const uri of uris) {\n const path = uri.path.replace(/^\\//, ''); // remove leading slash\n const markers = monacoInstance.editor.getModelMarkers({ resource: uri });\n newMarkers[path] = markers;\n }\n setValidationMarkers(newMarkers);\n onValidationChange?.(newMarkers);\n });\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [activeFilePath, getOrCreateModel, onValidationChange],\n );\n\n const handleEditorChange = useCallback(\n (value: string) => {\n if (!activeFilePath) return;\n\n fileContentsRef.current.set(activeFilePath, value);\n\n const isDirty = value !== originalContentsRef.current.get(activeFilePath);\n setOpenTabs((prev) =>\n prev.map((t) =>\n t.path === activeFilePath ? { ...t, isDirty } : t,\n ),\n );\n\n onFileChange?.(activeFilePath, value);\n },\n [activeFilePath, onFileChange],\n );\n\n // --- Derived state ---\n const activeFile: CodeEditorFile | undefined = activeFilePath\n ? {\n path: activeFilePath,\n value: fileContentsRef.current.get(activeFilePath) ?? '',\n language:\n files.find((f) => f.path === activeFilePath)?.language ??\n detectLanguage(activeFilePath),\n }\n : undefined;\n\n // Cleanup models on unmount\n useEffect(() => {\n return () => {\n for (const model of modelsRef.current.values()) {\n if (!model.isDisposed()) {\n model.dispose();\n }\n }\n modelsRef.current.clear();\n };\n }, []);\n\n return {\n openTabs,\n activeFilePath,\n openFile,\n closeFile,\n setActiveFile: setActiveFileAction,\n updateFileContent,\n getFileContent,\n activeFile,\n monacoRef,\n editorRef,\n handleEditorMount,\n handleEditorChange,\n validationMarkers,\n markSaved,\n markAllSaved,\n cursorPosition,\n };\n}\n","import React from 'react';\nimport { Box, BoxProps, IconButton, Tooltip, Typography } from '@mui/material';\nimport CloseIcon from '@mui/icons-material/Close';\nimport type { CodeEditorTab } from './CodeEditorWorkspace.types';\nimport { getFileName } from './CodeEditorWorkspace.types';\n\nexport interface CodeEditorTabRenderProps {\n tab: CodeEditorTab;\n isActive: boolean;\n onSelect: () => void;\n onClose: () => void;\n}\n\nexport interface CodeEditorTabsProps {\n /** Open tabs to display */\n tabs: CodeEditorTab[];\n /** Path of the currently active tab */\n activeTab?: string | null;\n /** Called when a tab is selected */\n onTabSelect?: (path: string) => void;\n /** Called when a tab's close button is clicked */\n onTabClose?: (path: string) => void;\n /**\n * Render prop for full tab customisation.\n * When provided, default tab rendering is skipped entirely.\n */\n renderTab?: (props: CodeEditorTabRenderProps) => React.ReactNode;\n /** Props for the outer container */\n containerProps?: BoxProps;\n}\n\n/**\n * Tab bar for the CodeEditor workspace.\n *\n * Provides default MUI-based rendering, but consumers can fully replace it\n * via the `renderTab` render prop.\n *\n * @example\n * ```tsx\n * <CodeEditorTabs\n * tabs={workspace.openTabs}\n * activeTab={workspace.activeFilePath}\n * onTabSelect={workspace.setActiveFile}\n * onTabClose={workspace.closeFile}\n * />\n * ```\n */\nexport const CodeEditorTabs: React.FC<CodeEditorTabsProps> = ({\n tabs,\n activeTab,\n onTabSelect,\n onTabClose,\n renderTab,\n containerProps,\n}) => {\n if (tabs.length === 0) return null;\n\n return (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'stretch',\n overflow: 'auto',\n minHeight: 36,\n borderBottom: 1,\n borderColor: 'divider',\n bgcolor: 'background.default',\n '&::-webkit-scrollbar': { height: 2 },\n '&::-webkit-scrollbar-thumb': { bgcolor: 'action.disabled', borderRadius: 1 },\n }}\n {...containerProps}\n >\n {tabs.map((tab) => {\n const isActive = tab.path === activeTab;\n const label = tab.label ?? getFileName(tab.path);\n\n if (renderTab) {\n return (\n <React.Fragment key={tab.path}>\n {renderTab({\n tab,\n isActive,\n onSelect: () => onTabSelect?.(tab.path),\n onClose: () => onTabClose?.(tab.path),\n })}\n </React.Fragment>\n );\n }\n\n return (\n <Box\n key={tab.path}\n onClick={() => onTabSelect?.(tab.path)}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 0.5,\n px: 1.5,\n py: 0.5,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n borderRight: 1,\n borderColor: 'divider',\n bgcolor: isActive ? 'background.paper' : 'transparent',\n borderBottom: isActive ? '2px solid' : '2px solid transparent',\n borderBottomColor: isActive ? 'primary.main' : 'transparent',\n '&:hover': {\n bgcolor: isActive ? 'background.paper' : 'action.hover',\n },\n transition: 'background-color 0.15s ease',\n }}\n >\n {tab.isDirty && (\n <Box\n sx={{\n width: 6,\n height: 6,\n borderRadius: '50%',\n bgcolor: 'warning.main',\n flexShrink: 0,\n }}\n />\n )}\n {tab.syncStatus && (\n <Box\n component=\"span\"\n sx={{\n fontSize: '0.6rem',\n fontWeight: 700,\n lineHeight: 1,\n color: tab.syncStatus === 'new' ? 'success.main' : 'warning.main',\n flexShrink: 0,\n }}\n >\n {tab.syncStatus === 'new' ? 'N' : 'M'}\n </Box>\n )}\n <Tooltip title={tab.path} enterDelay={600}>\n <Typography\n variant=\"body2\"\n sx={{\n fontSize: '0.8125rem',\n fontWeight: isActive ? 600 : 400,\n color: isActive ? 'text.primary' : 'text.secondary',\n userSelect: 'none',\n }}\n >\n {label}\n </Typography>\n </Tooltip>\n {onTabClose && (\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n onTabClose(tab.path);\n }}\n sx={{\n p: 0.25,\n ml: 0.5,\n opacity: isActive ? 0.7 : 0,\n '&:hover': { opacity: 1 },\n '.MuiBox-root:hover > &': { opacity: 0.5 },\n transition: 'opacity 0.15s ease',\n }}\n aria-label={`Close ${label}`}\n >\n <CloseIcon sx={{ fontSize: 14 }} />\n </IconButton>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nexport default CodeEditorTabs;\n","import React, { useCallback, useState } from 'react';\nimport { Box, BoxProps, Collapse, List, ListItemButton, ListItemIcon, ListItemText } from '@mui/material';\nimport FolderIcon from '@mui/icons-material/Folder';\nimport FolderOpenIcon from '@mui/icons-material/FolderOpen';\nimport InsertDriveFileOutlinedIcon from '@mui/icons-material/InsertDriveFileOutlined';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport ChevronRightIcon from '@mui/icons-material/ChevronRight';\nimport type { FileTreeNode, FileTreeNodeStatus } from './CodeEditorWorkspace.types';\n\nexport interface FileTreeNodeRenderProps {\n node: FileTreeNode;\n depth: number;\n isSelected: boolean;\n isExpanded: boolean;\n onSelect: () => void;\n onToggle: () => void;\n}\n\n/** Status badge label and color config */\nconst STATUS_CONFIG: Record<FileTreeNodeStatus, { label: string; color: string }> = {\n new: { label: 'N', color: 'success.main' },\n modified: { label: 'M', color: 'warning.main' },\n deleted: { label: 'D', color: 'error.main' },\n};\n\n/** Compute the aggregate status for a folder from its descendants. */\nfunction computeFolderStatus(node: FileTreeNode): FileTreeNodeStatus | undefined {\n if (node.status) return node.status;\n if (node.type !== 'folder' || !node.children) return undefined;\n const childStatuses = node.children\n .map((c) => (c.type === 'folder' ? computeFolderStatus(c) : c.status))\n .filter((s): s is FileTreeNodeStatus => !!s);\n if (childStatuses.length === 0) return undefined;\n // Priority: new > modified > deleted\n if (childStatuses.includes('new')) return 'new';\n if (childStatuses.includes('modified')) return 'modified';\n return 'deleted';\n}\n\nexport interface CodeEditorFileTreeProps {\n /** Tree data to render */\n tree: FileTreeNode[];\n /** Currently selected file path */\n selectedPath?: string | null;\n /** Called when a file node is clicked */\n onFileSelect?: (path: string) => void;\n /** Called when a folder is expanded/collapsed */\n onFolderToggle?: (path: string, isExpanded: boolean) => void;\n /**\n * Render prop for full node customisation.\n * When provided, default rendering is skipped.\n */\n renderNode?: (props: FileTreeNodeRenderProps) => React.ReactNode;\n /** Paths of folders that should be expanded initially */\n defaultExpandedPaths?: string[];\n /** Width of the file tree panel */\n width?: string | number;\n /** Props for the outer container */\n containerProps?: BoxProps;\n}\n\n/**\n * File tree navigator for the CodeEditor workspace.\n *\n * Provides default MUI-based rendering with collapsible folders.\n * Consumers can fully replace rendering via `renderNode`.\n *\n * @example\n * ```tsx\n * <CodeEditorFileTree\n * tree={fileTree}\n * selectedPath={workspace.activeFilePath}\n * onFileSelect={workspace.openFile}\n * />\n * ```\n */\nexport const CodeEditorFileTree: React.FC<CodeEditorFileTreeProps> = ({\n tree,\n selectedPath,\n onFileSelect,\n onFolderToggle,\n renderNode,\n defaultExpandedPaths,\n width = 220,\n containerProps,\n}) => {\n const [expandedPaths, setExpandedPaths] = useState<Set<string>>(\n () => new Set(defaultExpandedPaths ?? []),\n );\n\n const toggleFolder = useCallback(\n (path: string) => {\n setExpandedPaths((prev) => {\n const next = new Set(prev);\n const isExpanded = next.has(path);\n if (isExpanded) {\n next.delete(path);\n } else {\n next.add(path);\n }\n onFolderToggle?.(path, !isExpanded);\n return next;\n });\n },\n [onFolderToggle],\n );\n\n const renderTreeNode = (node: FileTreeNode, depth: number) => {\n const isFolder = node.type === 'folder';\n const isExpanded = expandedPaths.has(node.path);\n const isSelected = node.path === selectedPath;\n\n if (renderNode) {\n return (\n <React.Fragment key={node.path}>\n {renderNode({\n node,\n depth,\n isSelected,\n isExpanded,\n onSelect: () => {\n if (isFolder) {\n toggleFolder(node.path);\n } else {\n onFileSelect?.(node.path);\n }\n },\n onToggle: () => toggleFolder(node.path),\n })}\n {isFolder && isExpanded && node.children?.map((child) => renderTreeNode(child, depth + 1))}\n </React.Fragment>\n );\n }\n\n return (\n <React.Fragment key={node.path}>\n <ListItemButton\n selected={isSelected}\n onClick={() => {\n if (isFolder) {\n toggleFolder(node.path);\n } else {\n onFileSelect?.(node.path);\n }\n }}\n sx={{\n pl: 1 + depth * 1.5,\n py: 0.25,\n minHeight: 28,\n '&.Mui-selected': {\n bgcolor: 'action.selected',\n '&:hover': { bgcolor: 'action.selected' },\n },\n }}\n >\n {isFolder && (\n <ListItemIcon sx={{ minWidth: 20 }}>\n {isExpanded ? (\n <ExpandMoreIcon sx={{ fontSize: 16 }} />\n ) : (\n <ChevronRightIcon sx={{ fontSize: 16 }} />\n )}\n </ListItemIcon>\n )}\n <ListItemIcon sx={{ minWidth: 24 }}>\n {node.icon ?? (\n isFolder ? (\n isExpanded ? (\n <FolderOpenIcon sx={{ fontSize: 16, color: 'warning.main' }} />\n ) : (\n <FolderIcon sx={{ fontSize: 16, color: 'warning.main' }} />\n )\n ) : (\n <InsertDriveFileOutlinedIcon sx={{ fontSize: 16, color: 'text.secondary' }} />\n )\n )}\n </ListItemIcon>\n <ListItemText\n primary={node.name}\n slotProps={{\n primary: {\n sx: {\n fontSize: '0.8125rem',\n fontWeight: isSelected ? 600 : 400,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n },\n }}\n />\n {(() => {\n const effectiveStatus = isFolder ? computeFolderStatus(node) : node.status;\n if (!effectiveStatus) return null;\n const cfg = STATUS_CONFIG[effectiveStatus];\n return (\n <Box\n component=\"span\"\n sx={{\n ml: 'auto',\n pl: 0.5,\n fontSize: '0.65rem',\n fontWeight: 700,\n lineHeight: 1,\n color: cfg.color,\n flexShrink: 0,\n }}\n >\n {cfg.label}\n </Box>\n );\n })()}\n </ListItemButton>\n {isFolder && (\n <Collapse in={isExpanded} timeout=\"auto\" unmountOnExit>\n {node.children?.map((child) => renderTreeNode(child, depth + 1))}\n </Collapse>\n )}\n </React.Fragment>\n );\n };\n\n return (\n <Box\n sx={{\n width: typeof width === 'number' ? `${width}px` : width,\n minWidth: typeof width === 'number' ? `${width}px` : width,\n height: '100%',\n overflow: 'auto',\n borderRight: 1,\n borderColor: 'divider',\n bgcolor: 'background.default',\n }}\n {...containerProps}\n >\n <List dense disablePadding>\n {tree.map((node) => renderTreeNode(node, 0))}\n </List>\n </Box>\n );\n};\n\nexport default CodeEditorFileTree;\n","import React from 'react';\nimport { Box, BoxProps, Tooltip, Typography } from '@mui/material';\nimport type { GitInfo, CodeEditorStatusBarItem } from './CodeEditorWorkspace.types';\nimport type { CodeEditorLanguage } from '../CodeEditor';\n\nexport interface CodeEditorStatusBarRenderProps {\n gitInfo?: GitInfo;\n language?: CodeEditorLanguage;\n cursorPosition?: { line: number; column: number };\n items?: CodeEditorStatusBarItem[];\n}\n\nexport interface CodeEditorStatusBarProps {\n /** Git repository information */\n gitInfo?: GitInfo;\n /** Language of the active file */\n language?: CodeEditorLanguage;\n /** Current cursor position */\n cursorPosition?: { line: number; column: number };\n /** Additional custom items */\n items?: CodeEditorStatusBarItem[];\n /**\n * Render prop for full status bar customisation.\n * When provided, default rendering is skipped entirely.\n */\n renderStatusBar?: (props: CodeEditorStatusBarRenderProps) => React.ReactNode;\n /** Called when the user clicks the branch name in the status bar */\n onBranchClick?: () => void;\n /** Props for the outer container */\n containerProps?: BoxProps;\n}\n\nconst LANGUAGE_LABELS: Record<string, string> = {\n typescript: 'TypeScript',\n javascript: 'JavaScript',\n json: 'JSON',\n html: 'HTML',\n css: 'CSS',\n python: 'Python',\n yaml: 'YAML',\n markdown: 'Markdown',\n sql: 'SQL',\n xml: 'XML',\n plaintext: 'Plain Text',\n};\n\n/**\n * Status bar for the CodeEditor workspace.\n *\n * Displays git branch info, cursor position, file language, and custom items.\n * Fully replaceable via `renderStatusBar` render prop.\n *\n * @example\n * ```tsx\n * <CodeEditorStatusBar\n * gitInfo={{ branch: 'main', isDirty: true, commitHash: 'a1b2c3d' }}\n * language=\"typescript\"\n * cursorPosition={{ line: 10, column: 5 }}\n * />\n * ```\n */\nexport const CodeEditorStatusBar: React.FC<CodeEditorStatusBarProps> = ({\n gitInfo,\n language,\n cursorPosition,\n items,\n renderStatusBar,\n onBranchClick,\n containerProps,\n}) => {\n if (renderStatusBar) {\n return (\n <>{renderStatusBar({ gitInfo, language, cursorPosition, items })}</>\n );\n }\n\n const leftItems = items?.filter((i) => i.align !== 'right') ?? [];\n const rightItems = items?.filter((i) => i.align === 'right') ?? [];\n\n return (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n px: 1.5,\n py: 0.25,\n minHeight: 24,\n borderTop: 1,\n borderColor: 'divider',\n bgcolor: 'primary.main',\n color: 'primary.contrastText',\n fontSize: '0.75rem',\n fontFamily: 'Monaco, Menlo, \"Ubuntu Mono\", Consolas, monospace',\n gap: 1,\n flexShrink: 0,\n }}\n {...containerProps}\n >\n {/* Left side */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, overflow: 'hidden' }}>\n {/* Git branch */}\n {gitInfo && (\n <Tooltip\n title={\n [\n gitInfo.remote && `Remote: ${gitInfo.remote}`,\n gitInfo.commitHash && `Commit: ${gitInfo.commitHash}`,\n gitInfo.ahead != null && `↑ ${gitInfo.ahead} ahead`,\n gitInfo.behind != null && `↓ ${gitInfo.behind} behind`,\n ]\n .filter(Boolean)\n .join(' · ') || gitInfo.branch\n }\n enterDelay={400}\n >\n <Box\n onClick={onBranchClick}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 0.5,\n cursor: onBranchClick ? 'pointer' : 'default',\n overflow: 'hidden',\n '&:hover': onBranchClick ? { opacity: 0.8 } : undefined,\n }}\n >\n {/* Branch icon (SVG inline for no extra dependency) */}\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n style={{ flexShrink: 0 }}\n >\n <path\n fillRule=\"evenodd\"\n 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\"\n />\n </svg>\n <Typography\n variant=\"caption\"\n sx={{\n fontSize: 'inherit',\n fontFamily: 'inherit',\n color: 'inherit',\n lineHeight: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: 180,\n }}\n >\n {gitInfo.branch}\n </Typography>\n {gitInfo.isDirty && (\n <Box\n component=\"span\"\n sx={{\n width: 6,\n height: 6,\n borderRadius: '50%',\n bgcolor: 'warning.light',\n flexShrink: 0,\n }}\n />\n )}\n {(gitInfo.ahead != null && gitInfo.ahead > 0) && (\n <Typography variant=\"caption\" sx={{ fontSize: 'inherit', fontFamily: 'inherit', color: 'inherit', lineHeight: 1, opacity: 0.85 }}>\n ↑{gitInfo.ahead}\n </Typography>\n )}\n {(gitInfo.behind != null && gitInfo.behind > 0) && (\n <Typography variant=\"caption\" sx={{ fontSize: 'inherit', fontFamily: 'inherit', color: 'inherit', lineHeight: 1, opacity: 0.85 }}>\n ↓{gitInfo.behind}\n </Typography>\n )}\n </Box>\n </Tooltip>\n )}\n\n {/* Custom left items */}\n {leftItems.map((item) => (\n <StatusBarItemElement key={item.id} item={item} />\n ))}\n </Box>\n\n {/* Right side */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, overflow: 'hidden' }}>\n {/* Custom right items */}\n {rightItems.map((item) => (\n <StatusBarItemElement key={item.id} item={item} />\n ))}\n\n {/* Cursor position */}\n {cursorPosition && (\n <Typography\n variant=\"caption\"\n sx={{ fontSize: 'inherit', fontFamily: 'inherit', color: 'inherit', lineHeight: 1, whiteSpace: 'nowrap' }}\n >\n Ln {cursorPosition.line}, Col {cursorPosition.column}\n </Typography>\n )}\n\n {/* Language */}\n {language && (\n <Typography\n variant=\"caption\"\n sx={{ fontSize: 'inherit', fontFamily: 'inherit', color: 'inherit', lineHeight: 1, whiteSpace: 'nowrap' }}\n >\n {LANGUAGE_LABELS[language] ?? language}\n </Typography>\n )}\n </Box>\n </Box>\n );\n};\n\n/** Renders a single custom status bar item. */\nconst StatusBarItemElement: React.FC<{ item: CodeEditorStatusBarItem }> = ({ item }) => {\n const inner = (\n <Box\n onClick={item.onClick}\n sx={{\n display: 'flex',\n alignItems: 'center',\n cursor: item.onClick ? 'pointer' : 'default',\n lineHeight: 1,\n whiteSpace: 'nowrap',\n '&:hover': item.onClick ? { opacity: 0.8 } : undefined,\n }}\n >\n {typeof item.content === 'string' ? (\n <Typography\n variant=\"caption\"\n sx={{ fontSize: 'inherit', fontFamily: 'inherit', color: 'inherit', lineHeight: 1 }}\n >\n {item.content}\n </Typography>\n ) : (\n item.content\n )}\n </Box>\n );\n\n if (item.tooltip) {\n return <Tooltip title={item.tooltip} enterDelay={400}>{inner}</Tooltip>;\n }\n return inner;\n};\n\nexport default CodeEditorStatusBar;\n","import React from 'react';\nimport { Box, type BoxProps } from '@mui/material';\nimport { CereIcon } from '../../icons/CereIcon';\n\nexport interface CodeEditorWelcomeScreenProps {\n /** Custom logo or icon displayed in the center. Defaults to the Cere logo. */\n logo?: React.ReactNode;\n /**\n * Content rendered below the logo. Accepts any ReactNode —\n * shortcut hints, action buttons, descriptive text, etc.\n */\n children?: React.ReactNode;\n /** Props forwarded to the outer container `Box`. */\n containerProps?: BoxProps;\n}\n\n/**\n * Default empty-state screen shown inside `CodeEditorWorkspace` when no file\n * is open. Renders a centered logo with an optional content slot underneath.\n *\n * @example\n * ```tsx\n * <CodeEditorWelcomeScreen>\n * <Typography variant=\"body2\" color=\"text.secondary\">\n * Open a file from the tree to start editing\n * </Typography>\n * </CodeEditorWelcomeScreen>\n * ```\n */\nexport const CodeEditorWelcomeScreen: React.FC<CodeEditorWelcomeScreenProps> = ({\n logo,\n children,\n containerProps,\n}) => {\n const defaultLogo = (\n <CereIcon\n sx={{\n fontSize: 80,\n color: 'text.disabled',\n opacity: 0.4,\n }}\n />\n );\n\n return (\n <Box\n sx={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 3,\n p: 4,\n userSelect: 'none',\n }}\n {...containerProps}\n >\n {logo !== undefined ? logo : defaultLogo}\n\n {children && (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 1,\n }}\n >\n {children}\n </Box>\n )}\n </Box>\n );\n};\n","import React from 'react';\nimport { Box, BoxProps } from '@mui/material';\nimport { CodeEditor } from '../CodeEditor';\nimport type { CodeEditorProps } from '../CodeEditor';\nimport { CodeEditorTabs } from './CodeEditorTabs';\nimport type { CodeEditorTabsProps } from './CodeEditorTabs';\nimport { CodeEditorFileTree } from './CodeEditorFileTree';\nimport type { CodeEditorFileTreeProps } from './CodeEditorFileTree';\nimport { useCodeEditorWorkspace } from './useCodeEditorWorkspace';\nimport type { UseCodeEditorWorkspaceOptions, UseCodeEditorWorkspaceReturn } from './useCodeEditorWorkspace';\nimport { CodeEditorStatusBar } from './CodeEditorStatusBar';\nimport type { CodeEditorStatusBarProps } from './CodeEditorStatusBar';\nimport { CodeEditorWelcomeScreen } from './CodeEditorWelcomeScreen';\nimport type { CodeEditorWelcomeScreenProps } from './CodeEditorWelcomeScreen';\nimport type { FileTreeNode, GitInfo, CodeEditorStatusBarItem, CodeEditorFile } from './CodeEditorWorkspace.types';\n\nexport interface CodeEditorWorkspaceProps\n extends Pick<UseCodeEditorWorkspaceOptions, 'files' | 'initialOpenPaths' | 'onFileChange' | 'onValidationChange'> {\n /** File tree data. When omitted the file tree panel is hidden. */\n fileTree?: FileTreeNode[];\n /** Paths of folders expanded by default in the file tree */\n defaultExpandedPaths?: string[];\n /** Whether to show the tab bar. @default true */\n showTabs?: boolean;\n /** Whether to show the file tree panel. @default true (when fileTree is provided) */\n showFileTree?: boolean;\n /** Width of the file tree panel */\n fileTreeWidth?: string | number;\n /** Overall height of the workspace */\n height?: string | number;\n /** Props passed through to the inner CodeEditor */\n editorProps?: Partial<Omit<CodeEditorProps, 'value' | 'onChange' | 'language' | 'editorRef' | 'monacoRef' | 'onMount'>>;\n /** Props for the outer container */\n containerProps?: BoxProps;\n /** Replace the default tab bar rendering */\n renderTabs?: (props: CodeEditorTabsProps & { workspace: UseCodeEditorWorkspaceReturn }) => React.ReactNode;\n /** Replace the default file tree rendering */\n renderFileTree?: (props: CodeEditorFileTreeProps & { workspace: UseCodeEditorWorkspaceReturn }) => React.ReactNode;\n /** Replace the default editor rendering */\n renderEditor?: (workspace: UseCodeEditorWorkspaceReturn) => React.ReactNode;\n /** Replace the default status bar rendering */\n renderStatusBar?: (props: CodeEditorStatusBarProps & { workspace: UseCodeEditorWorkspaceReturn }) => React.ReactNode;\n /** Replace the default welcome screen rendering (shown when no file is open) */\n renderWelcomeScreen?: (workspace: UseCodeEditorWorkspaceReturn) => React.ReactNode;\n /** Static ReactNode that replaces the default welcome screen entirely */\n welcomeScreen?: React.ReactNode;\n /** Props forwarded to the default `CodeEditorWelcomeScreen` (ignored when `welcomeScreen` or `renderWelcomeScreen` is provided) */\n welcomeScreenProps?: CodeEditorWelcomeScreenProps;\n /** Git repository information to display in the status bar */\n gitInfo?: GitInfo;\n /** Whether to show the status bar. @default true */\n showStatusBar?: boolean;\n /** Additional custom items for the status bar */\n statusBarItems?: CodeEditorStatusBarItem[];\n /** Expose the workspace instance to the parent via ref-like callback */\n onWorkspaceReady?: (workspace: UseCodeEditorWorkspaceReturn) => void;\n /** Called when the user presses Ctrl+S / Cmd+S. Receives all dirty files. */\n onSave?: (dirtyFiles: CodeEditorFile[]) => void;\n /** Called when the user clicks the branch name in the status bar */\n onBranchClick?: () => void;\n}\n\n/**\n * Convenience composed workspace that combines `CodeEditorFileTree`,\n * `CodeEditorTabs`, and `CodeEditor` into a single layout.\n *\n * For full control, use `useCodeEditorWorkspace` directly and assemble\n * the pieces yourself.\n *\n * @example\n * ```tsx\n * <CodeEditorWorkspace\n * files={files}\n * fileTree={tree}\n * initialOpenPaths={['src/index.ts']}\n * height=\"600px\"\n * gitInfo={{ branch: 'main', isDirty: true, commitHash: 'a1b2c3d' }}\n * onFileChange={(path, value) => console.log(path, value)}\n * />\n * ```\n */\nexport const CodeEditorWorkspace: React.FC<CodeEditorWorkspaceProps> = ({\n files,\n initialOpenPaths,\n onFileChange,\n onValidationChange,\n fileTree,\n defaultExpandedPaths,\n showTabs = true,\n showFileTree = true,\n fileTreeWidth = 220,\n height = '500px',\n editorProps,\n containerProps,\n renderTabs,\n renderFileTree,\n renderEditor,\n renderStatusBar,\n renderWelcomeScreen,\n welcomeScreen,\n welcomeScreenProps,\n gitInfo,\n showStatusBar = true,\n statusBarItems,\n onWorkspaceReady,\n onSave,\n onBranchClick,\n}) => {\n const workspace = useCodeEditorWorkspace({\n files,\n initialOpenPaths,\n onFileChange,\n onValidationChange,\n });\n\n // Notify parent when workspace is ready\n React.useEffect(() => {\n onWorkspaceReady?.(workspace);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Ctrl+S / Cmd+S handler\n React.useEffect(() => {\n if (!onSave) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.ctrlKey || e.metaKey) && e.key === 's') {\n e.preventDefault();\n const dirtyFiles = workspace.openTabs\n .filter((t) => t.isDirty)\n .map((t) => {\n const file = files.find((f) => f.path === t.path);\n if (!file) return null;\n return {\n ...file,\n value: workspace.getFileContent(file.path) ?? file.value,\n };\n })\n .filter((f): f is CodeEditorFile => f !== null);\n\n if (dirtyFiles.length > 0) {\n onSave(dirtyFiles);\n }\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [onSave, workspace, files]);\n\n const hasFileTree = showFileTree && fileTree && fileTree.length > 0;\n\n // --- Tab bar ---\n const tabsProps: CodeEditorTabsProps = {\n tabs: workspace.openTabs,\n activeTab: workspace.activeFilePath,\n onTabSelect: workspace.setActiveFile,\n onTabClose: workspace.closeFile,\n };\n\n const tabsElement = showTabs\n ? renderTabs\n ? renderTabs({ ...tabsProps, workspace })\n : <CodeEditorTabs {...tabsProps} />\n : null;\n\n // --- File tree ---\n const fileTreeProps: CodeEditorFileTreeProps = {\n tree: fileTree ?? [],\n selectedPath: workspace.activeFilePath,\n onFileSelect: workspace.openFile,\n defaultExpandedPaths,\n width: fileTreeWidth,\n };\n\n const fileTreeElement = hasFileTree\n ? renderFileTree\n ? renderFileTree({ ...fileTreeProps, workspace })\n : <CodeEditorFileTree {...fileTreeProps} />\n : null;\n\n // --- Status bar ---\n const statusBarProps: CodeEditorStatusBarProps = {\n gitInfo,\n language: workspace.activeFile?.language,\n cursorPosition: workspace.cursorPosition ?? undefined,\n items: statusBarItems,\n onBranchClick,\n };\n\n const statusBarElement = showStatusBar\n ? renderStatusBar\n ? renderStatusBar({ ...statusBarProps, workspace })\n : <CodeEditorStatusBar {...statusBarProps} />\n : null;\n\n // --- Welcome screen (empty state) ---\n const welcomeElement = renderWelcomeScreen\n ? renderWelcomeScreen(workspace)\n : welcomeScreen !== undefined\n ? welcomeScreen\n : <CodeEditorWelcomeScreen {...welcomeScreenProps} />;\n\n // --- Editor ---\n const editorElement = renderEditor\n ? renderEditor(workspace)\n : workspace.activeFile\n ? (\n <CodeEditor\n value={workspace.activeFile.value}\n onChange={workspace.handleEditorChange}\n language={workspace.activeFile.language}\n editorRef={workspace.editorRef}\n monacoRef={workspace.monacoRef}\n onMount={workspace.handleEditorMount}\n onValidate={(markers) => {\n if (workspace.activeFilePath) {\n workspace.validationMarkers[workspace.activeFilePath] = markers;\n }\n }}\n externalModelManagement\n height=\"100%\"\n {...editorProps}\n />\n )\n : welcomeElement;\n\n return (\n <Box\n sx={{\n display: 'flex',\n height: typeof height === 'number' ? `${height}px` : height,\n border: 1,\n borderColor: 'divider',\n borderRadius: 1,\n overflow: 'hidden',\n bgcolor: 'background.paper',\n }}\n {...containerProps}\n >\n {/* File tree */}\n {fileTreeElement}\n\n {/* Right side: tabs + editor + status bar */}\n <Box sx={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, overflow: 'hidden' }}>\n {tabsElement}\n <Box sx={{ flex: 1, overflow: 'hidden' }}>\n {editorElement}\n </Box>\n {statusBarElement}\n </Box>\n </Box>\n );\n};\n\nexport default CodeEditorWorkspace;\n"],"mappings":"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","names":["Background","Controls","MiniMap","BackgroundVariant","ConnectionLineType","useCallback","Box","jsx","jsxs","model","Panel","useTheme","jsx","jsxs","useTheme","useCallback","useEffect","useRef","useState","useRef","useState","useEffect","useCallback","React","Box","IconButton","Tooltip","jsx","jsxs","Box","React","Tooltip","IconButton","React","useCallback","useState","Box","ExpandMoreIcon","jsx","jsxs","Box","Tooltip","Typography","Fragment","jsx","jsxs","Box","jsx","jsxs","Box","React","Box","jsx","jsxs","React","Box"]}