@foresthubai/workflow-builder 0.3.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 (496) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +16 -0
  3. package/README.md +93 -0
  4. package/dist/BuilderLayout.d.ts +34 -0
  5. package/dist/BuilderLayout.d.ts.map +1 -0
  6. package/dist/BuilderLayout.js +172 -0
  7. package/dist/BuilderLayout.js.map +1 -0
  8. package/dist/Canvas.d.ts +23 -0
  9. package/dist/Canvas.d.ts.map +1 -0
  10. package/dist/Canvas.js +141 -0
  11. package/dist/Canvas.js.map +1 -0
  12. package/dist/CanvasEditor.d.ts +46 -0
  13. package/dist/CanvasEditor.d.ts.map +1 -0
  14. package/dist/CanvasEditor.js +57 -0
  15. package/dist/CanvasEditor.js.map +1 -0
  16. package/dist/CanvasTabsToolbar.d.ts +11 -0
  17. package/dist/CanvasTabsToolbar.d.ts.map +1 -0
  18. package/dist/CanvasTabsToolbar.js +101 -0
  19. package/dist/CanvasTabsToolbar.js.map +1 -0
  20. package/dist/RightConfigPanel.d.ts +27 -0
  21. package/dist/RightConfigPanel.d.ts.map +1 -0
  22. package/dist/RightConfigPanel.js +102 -0
  23. package/dist/RightConfigPanel.js.map +1 -0
  24. package/dist/WorkflowBuilder.d.ts +62 -0
  25. package/dist/WorkflowBuilder.d.ts.map +1 -0
  26. package/dist/WorkflowBuilder.js +275 -0
  27. package/dist/WorkflowBuilder.js.map +1 -0
  28. package/dist/cn.d.ts +3 -0
  29. package/dist/cn.d.ts.map +1 -0
  30. package/dist/cn.js +6 -0
  31. package/dist/cn.js.map +1 -0
  32. package/dist/components/ui/add-button.d.ts +16 -0
  33. package/dist/components/ui/add-button.d.ts.map +1 -0
  34. package/dist/components/ui/add-button.js +21 -0
  35. package/dist/components/ui/add-button.js.map +1 -0
  36. package/dist/components/ui/alert-dialog.d.ts +21 -0
  37. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  38. package/dist/components/ui/alert-dialog.js +30 -0
  39. package/dist/components/ui/alert-dialog.js.map +1 -0
  40. package/dist/components/ui/alert.d.ts +9 -0
  41. package/dist/components/ui/alert.d.ts.map +1 -0
  42. package/dist/components/ui/alert.js +23 -0
  43. package/dist/components/ui/alert.js.map +1 -0
  44. package/dist/components/ui/badge.d.ts +10 -0
  45. package/dist/components/ui/badge.d.ts.map +1 -0
  46. package/dist/components/ui/badge.js +21 -0
  47. package/dist/components/ui/badge.js.map +1 -0
  48. package/dist/components/ui/button.d.ts +13 -0
  49. package/dist/components/ui/button.d.ts.map +1 -0
  50. package/dist/components/ui/button.js +40 -0
  51. package/dist/components/ui/button.js.map +1 -0
  52. package/dist/components/ui/card.d.ts +9 -0
  53. package/dist/components/ui/card.d.ts.map +1 -0
  54. package/dist/components/ui/card.js +17 -0
  55. package/dist/components/ui/card.js.map +1 -0
  56. package/dist/components/ui/checkbox.d.ts +5 -0
  57. package/dist/components/ui/checkbox.d.ts.map +1 -0
  58. package/dist/components/ui/checkbox.js +9 -0
  59. package/dist/components/ui/checkbox.js.map +1 -0
  60. package/dist/components/ui/collapsible.d.ts +6 -0
  61. package/dist/components/ui/collapsible.d.ts.map +1 -0
  62. package/dist/components/ui/collapsible.js +6 -0
  63. package/dist/components/ui/collapsible.js.map +1 -0
  64. package/dist/components/ui/command.d.ts +82 -0
  65. package/dist/components/ui/command.d.ts.map +1 -0
  66. package/dist/components/ui/command.js +29 -0
  67. package/dist/components/ui/command.js.map +1 -0
  68. package/dist/components/ui/delete-button.d.ts +11 -0
  69. package/dist/components/ui/delete-button.d.ts.map +1 -0
  70. package/dist/components/ui/delete-button.js +14 -0
  71. package/dist/components/ui/delete-button.js.map +1 -0
  72. package/dist/components/ui/dialog.d.ts +22 -0
  73. package/dist/components/ui/dialog.d.ts.map +1 -0
  74. package/dist/components/ui/dialog.js +27 -0
  75. package/dist/components/ui/dialog.js.map +1 -0
  76. package/dist/components/ui/dropdown-menu.d.ts +28 -0
  77. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  78. package/dist/components/ui/dropdown-menu.js +36 -0
  79. package/dist/components/ui/dropdown-menu.js.map +1 -0
  80. package/dist/components/ui/input.d.ts +13 -0
  81. package/dist/components/ui/input.d.ts.map +1 -0
  82. package/dist/components/ui/input.js +34 -0
  83. package/dist/components/ui/input.js.map +1 -0
  84. package/dist/components/ui/label.d.ts +6 -0
  85. package/dist/components/ui/label.d.ts.map +1 -0
  86. package/dist/components/ui/label.js +10 -0
  87. package/dist/components/ui/label.js.map +1 -0
  88. package/dist/components/ui/readonly-banner.d.ts +7 -0
  89. package/dist/components/ui/readonly-banner.d.ts.map +1 -0
  90. package/dist/components/ui/readonly-banner.js +12 -0
  91. package/dist/components/ui/readonly-banner.js.map +1 -0
  92. package/dist/components/ui/resizable.d.ts +24 -0
  93. package/dist/components/ui/resizable.d.ts.map +1 -0
  94. package/dist/components/ui/resizable.js +9 -0
  95. package/dist/components/ui/resizable.js.map +1 -0
  96. package/dist/components/ui/scroll-area.d.ts +45 -0
  97. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  98. package/dist/components/ui/scroll-area.js +27 -0
  99. package/dist/components/ui/scroll-area.js.map +1 -0
  100. package/dist/components/ui/select.d.ts +14 -0
  101. package/dist/components/ui/select.d.ts.map +1 -0
  102. package/dist/components/ui/select.js +30 -0
  103. package/dist/components/ui/select.js.map +1 -0
  104. package/dist/components/ui/separator.d.ts +5 -0
  105. package/dist/components/ui/separator.d.ts.map +1 -0
  106. package/dist/components/ui/separator.js +8 -0
  107. package/dist/components/ui/separator.js.map +1 -0
  108. package/dist/components/ui/switch.d.ts +5 -0
  109. package/dist/components/ui/switch.d.ts.map +1 -0
  110. package/dist/components/ui/switch.js +8 -0
  111. package/dist/components/ui/switch.js.map +1 -0
  112. package/dist/components/ui/textarea.d.ts +12 -0
  113. package/dist/components/ui/textarea.d.ts.map +1 -0
  114. package/dist/components/ui/textarea.js +34 -0
  115. package/dist/components/ui/textarea.js.map +1 -0
  116. package/dist/components/ui/toast.d.ts +16 -0
  117. package/dist/components/ui/toast.d.ts.map +1 -0
  118. package/dist/components/ui/toast.js +34 -0
  119. package/dist/components/ui/toast.js.map +1 -0
  120. package/dist/components/ui/toaster.d.ts +2 -0
  121. package/dist/components/ui/toaster.d.ts.map +1 -0
  122. package/dist/components/ui/toaster.js +10 -0
  123. package/dist/components/ui/toaster.js.map +1 -0
  124. package/dist/components/ui/toggle-group.d.ts +13 -0
  125. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  126. package/dist/components/ui/toggle-group.js +21 -0
  127. package/dist/components/ui/toggle-group.js.map +1 -0
  128. package/dist/components/ui/toggle.d.ts +13 -0
  129. package/dist/components/ui/toggle.d.ts.map +1 -0
  130. package/dist/components/ui/toggle.js +26 -0
  131. package/dist/components/ui/toggle.js.map +1 -0
  132. package/dist/components/ui/tooltip.d.ts +8 -0
  133. package/dist/components/ui/tooltip.d.ts.map +1 -0
  134. package/dist/components/ui/tooltip.js +14 -0
  135. package/dist/components/ui/tooltip.js.map +1 -0
  136. package/dist/dialogs/NodePickerDialog.d.ts +10 -0
  137. package/dist/dialogs/NodePickerDialog.d.ts.map +1 -0
  138. package/dist/dialogs/NodePickerDialog.js +39 -0
  139. package/dist/dialogs/NodePickerDialog.js.map +1 -0
  140. package/dist/dialogs/ValidationDialog.d.ts +17 -0
  141. package/dist/dialogs/ValidationDialog.d.ts.map +1 -0
  142. package/dist/dialogs/ValidationDialog.js +29 -0
  143. package/dist/dialogs/ValidationDialog.js.map +1 -0
  144. package/dist/graph/BaseNode.d.ts +9 -0
  145. package/dist/graph/BaseNode.d.ts.map +1 -0
  146. package/dist/graph/BaseNode.js +318 -0
  147. package/dist/graph/BaseNode.js.map +1 -0
  148. package/dist/graph/CustomEdge.d.ts +14 -0
  149. package/dist/graph/CustomEdge.d.ts.map +1 -0
  150. package/dist/graph/CustomEdge.js +107 -0
  151. package/dist/graph/CustomEdge.js.map +1 -0
  152. package/dist/graph/CustomNode.d.ts +3 -0
  153. package/dist/graph/CustomNode.d.ts.map +1 -0
  154. package/dist/graph/CustomNode.js +15 -0
  155. package/dist/graph/CustomNode.js.map +1 -0
  156. package/dist/graph/FunctionCallNode.d.ts +3 -0
  157. package/dist/graph/FunctionCallNode.d.ts.map +1 -0
  158. package/dist/graph/FunctionCallNode.js +25 -0
  159. package/dist/graph/FunctionCallNode.js.map +1 -0
  160. package/dist/graph/PortHandle.d.ts +21 -0
  161. package/dist/graph/PortHandle.d.ts.map +1 -0
  162. package/dist/graph/PortHandle.js +113 -0
  163. package/dist/graph/PortHandle.js.map +1 -0
  164. package/dist/graph/reactFlowRegistry.d.ts +65 -0
  165. package/dist/graph/reactFlowRegistry.d.ts.map +1 -0
  166. package/dist/graph/reactFlowRegistry.js +24 -0
  167. package/dist/graph/reactFlowRegistry.js.map +1 -0
  168. package/dist/hooks/use-toast.d.ts +47 -0
  169. package/dist/hooks/use-toast.d.ts.map +1 -0
  170. package/dist/hooks/use-toast.js +95 -0
  171. package/dist/hooks/use-toast.js.map +1 -0
  172. package/dist/hooks/useAvailableVariables.d.ts +12 -0
  173. package/dist/hooks/useAvailableVariables.d.ts.map +1 -0
  174. package/dist/hooks/useAvailableVariables.js +16 -0
  175. package/dist/hooks/useAvailableVariables.js.map +1 -0
  176. package/dist/hooks/useCanvasHistory.d.ts +14 -0
  177. package/dist/hooks/useCanvasHistory.d.ts.map +1 -0
  178. package/dist/hooks/useCanvasHistory.js +20 -0
  179. package/dist/hooks/useCanvasHistory.js.map +1 -0
  180. package/dist/hooks/useCanvasTabs.d.ts +23 -0
  181. package/dist/hooks/useCanvasTabs.d.ts.map +1 -0
  182. package/dist/hooks/useCanvasTabs.js +136 -0
  183. package/dist/hooks/useCanvasTabs.js.map +1 -0
  184. package/dist/hooks/useFunctionDiagnosticsSync.d.ts +14 -0
  185. package/dist/hooks/useFunctionDiagnosticsSync.d.ts.map +1 -0
  186. package/dist/hooks/useFunctionDiagnosticsSync.js +38 -0
  187. package/dist/hooks/useFunctionDiagnosticsSync.js.map +1 -0
  188. package/dist/hooks/useFunctionRegistry.d.ts +15 -0
  189. package/dist/hooks/useFunctionRegistry.d.ts.map +1 -0
  190. package/dist/hooks/useFunctionRegistry.js +22 -0
  191. package/dist/hooks/useFunctionRegistry.js.map +1 -0
  192. package/dist/hooks/useFunctions.d.ts +15 -0
  193. package/dist/hooks/useFunctions.d.ts.map +1 -0
  194. package/dist/hooks/useFunctions.js +34 -0
  195. package/dist/hooks/useFunctions.js.map +1 -0
  196. package/dist/hooks/useGraph.d.ts +40 -0
  197. package/dist/hooks/useGraph.d.ts.map +1 -0
  198. package/dist/hooks/useGraph.js +102 -0
  199. package/dist/hooks/useGraph.js.map +1 -0
  200. package/dist/hooks/useNodeDefinitions.d.ts +17 -0
  201. package/dist/hooks/useNodeDefinitions.d.ts.map +1 -0
  202. package/dist/hooks/useNodeDefinitions.js +65 -0
  203. package/dist/hooks/useNodeDefinitions.js.map +1 -0
  204. package/dist/hooks/useParamErrors.d.ts +12 -0
  205. package/dist/hooks/useParamErrors.d.ts.map +1 -0
  206. package/dist/hooks/useParamErrors.js +28 -0
  207. package/dist/hooks/useParamErrors.js.map +1 -0
  208. package/dist/hooks/useResolvedTheme.d.ts +10 -0
  209. package/dist/hooks/useResolvedTheme.d.ts.map +1 -0
  210. package/dist/hooks/useResolvedTheme.js +29 -0
  211. package/dist/hooks/useResolvedTheme.js.map +1 -0
  212. package/dist/hooks/useResourceDiagnosticsSync.d.ts +40 -0
  213. package/dist/hooks/useResourceDiagnosticsSync.d.ts.map +1 -0
  214. package/dist/hooks/useResourceDiagnosticsSync.js +39 -0
  215. package/dist/hooks/useResourceDiagnosticsSync.js.map +1 -0
  216. package/dist/hooks/useSuppressThemeTransition.d.ts +32 -0
  217. package/dist/hooks/useSuppressThemeTransition.d.ts.map +1 -0
  218. package/dist/hooks/useSuppressThemeTransition.js +75 -0
  219. package/dist/hooks/useSuppressThemeTransition.js.map +1 -0
  220. package/dist/hooks/useWorkflowSerialization.d.ts +24 -0
  221. package/dist/hooks/useWorkflowSerialization.d.ts.map +1 -0
  222. package/dist/hooks/useWorkflowSerialization.js +113 -0
  223. package/dist/hooks/useWorkflowSerialization.js.map +1 -0
  224. package/dist/i18n/index.d.ts +4 -0
  225. package/dist/i18n/index.d.ts.map +1 -0
  226. package/dist/i18n/index.js +46 -0
  227. package/dist/i18n/index.js.map +1 -0
  228. package/dist/i18n/locales/de.json +501 -0
  229. package/dist/i18n/locales/en.json +557 -0
  230. package/dist/index.d.ts +9 -0
  231. package/dist/index.d.ts.map +1 -0
  232. package/dist/index.js +12 -0
  233. package/dist/index.js.map +1 -0
  234. package/dist/inputs/ExpressionInput.d.ts +12 -0
  235. package/dist/inputs/ExpressionInput.d.ts.map +1 -0
  236. package/dist/inputs/ExpressionInput.js +203 -0
  237. package/dist/inputs/ExpressionInput.js.map +1 -0
  238. package/dist/inputs/ParameterEditor.d.ts +13 -0
  239. package/dist/inputs/ParameterEditor.d.ts.map +1 -0
  240. package/dist/inputs/ParameterEditor.js +204 -0
  241. package/dist/inputs/ParameterEditor.js.map +1 -0
  242. package/dist/inputs/PortSection.d.ts +31 -0
  243. package/dist/inputs/PortSection.d.ts.map +1 -0
  244. package/dist/inputs/PortSection.js +26 -0
  245. package/dist/inputs/PortSection.js.map +1 -0
  246. package/dist/panels/BuilderSidebar.d.ts +24 -0
  247. package/dist/panels/BuilderSidebar.d.ts.map +1 -0
  248. package/dist/panels/BuilderSidebar.js +202 -0
  249. package/dist/panels/BuilderSidebar.js.map +1 -0
  250. package/dist/panels/ChannelConfigPanel.d.ts +8 -0
  251. package/dist/panels/ChannelConfigPanel.d.ts.map +1 -0
  252. package/dist/panels/ChannelConfigPanel.js +26 -0
  253. package/dist/panels/ChannelConfigPanel.js.map +1 -0
  254. package/dist/panels/ChannelsPanel.d.ts +2 -0
  255. package/dist/panels/ChannelsPanel.d.ts.map +1 -0
  256. package/dist/panels/ChannelsPanel.js +16 -0
  257. package/dist/panels/ChannelsPanel.js.map +1 -0
  258. package/dist/panels/DebugConsolePanel.d.ts +2 -0
  259. package/dist/panels/DebugConsolePanel.d.ts.map +1 -0
  260. package/dist/panels/DebugConsolePanel.js +32 -0
  261. package/dist/panels/DebugConsolePanel.js.map +1 -0
  262. package/dist/panels/DebugContextPanel.d.ts +2 -0
  263. package/dist/panels/DebugContextPanel.d.ts.map +1 -0
  264. package/dist/panels/DebugContextPanel.js +32 -0
  265. package/dist/panels/DebugContextPanel.js.map +1 -0
  266. package/dist/panels/DebugExternalIOPanel.d.ts +9 -0
  267. package/dist/panels/DebugExternalIOPanel.d.ts.map +1 -0
  268. package/dist/panels/DebugExternalIOPanel.js +66 -0
  269. package/dist/panels/DebugExternalIOPanel.js.map +1 -0
  270. package/dist/panels/DiagnosticsPanel.d.ts +8 -0
  271. package/dist/panels/DiagnosticsPanel.d.ts.map +1 -0
  272. package/dist/panels/DiagnosticsPanel.js +86 -0
  273. package/dist/panels/DiagnosticsPanel.js.map +1 -0
  274. package/dist/panels/EdgeConfigPanel.d.ts +14 -0
  275. package/dist/panels/EdgeConfigPanel.d.ts.map +1 -0
  276. package/dist/panels/EdgeConfigPanel.js +34 -0
  277. package/dist/panels/EdgeConfigPanel.js.map +1 -0
  278. package/dist/panels/FunctionConfigPanel.d.ts +16 -0
  279. package/dist/panels/FunctionConfigPanel.d.ts.map +1 -0
  280. package/dist/panels/FunctionConfigPanel.js +62 -0
  281. package/dist/panels/FunctionConfigPanel.js.map +1 -0
  282. package/dist/panels/FunctionListPanel.d.ts +14 -0
  283. package/dist/panels/FunctionListPanel.d.ts.map +1 -0
  284. package/dist/panels/FunctionListPanel.js +25 -0
  285. package/dist/panels/FunctionListPanel.js.map +1 -0
  286. package/dist/panels/MemoryConfigPanel.d.ts +8 -0
  287. package/dist/panels/MemoryConfigPanel.d.ts.map +1 -0
  288. package/dist/panels/MemoryConfigPanel.js +22 -0
  289. package/dist/panels/MemoryConfigPanel.js.map +1 -0
  290. package/dist/panels/MemoryPanel.d.ts +2 -0
  291. package/dist/panels/MemoryPanel.d.ts.map +1 -0
  292. package/dist/panels/MemoryPanel.js +25 -0
  293. package/dist/panels/MemoryPanel.js.map +1 -0
  294. package/dist/panels/ModelConfigPanel.d.ts +8 -0
  295. package/dist/panels/ModelConfigPanel.d.ts.map +1 -0
  296. package/dist/panels/ModelConfigPanel.js +14 -0
  297. package/dist/panels/ModelConfigPanel.js.map +1 -0
  298. package/dist/panels/ModelsPanel.d.ts +8 -0
  299. package/dist/panels/ModelsPanel.d.ts.map +1 -0
  300. package/dist/panels/ModelsPanel.js +24 -0
  301. package/dist/panels/ModelsPanel.js.map +1 -0
  302. package/dist/panels/NodeConfigPanel.d.ts +16 -0
  303. package/dist/panels/NodeConfigPanel.d.ts.map +1 -0
  304. package/dist/panels/NodeConfigPanel.js +248 -0
  305. package/dist/panels/NodeConfigPanel.js.map +1 -0
  306. package/dist/panels/NodeLibrary.d.ts +16 -0
  307. package/dist/panels/NodeLibrary.d.ts.map +1 -0
  308. package/dist/panels/NodeLibrary.js +125 -0
  309. package/dist/panels/NodeLibrary.js.map +1 -0
  310. package/dist/panels/ResourceConfigPanel.d.ts +37 -0
  311. package/dist/panels/ResourceConfigPanel.d.ts.map +1 -0
  312. package/dist/panels/ResourceConfigPanel.js +35 -0
  313. package/dist/panels/ResourceConfigPanel.js.map +1 -0
  314. package/dist/panels/ResourceListPanel.d.ts +35 -0
  315. package/dist/panels/ResourceListPanel.d.ts.map +1 -0
  316. package/dist/panels/ResourceListPanel.js +35 -0
  317. package/dist/panels/ResourceListPanel.js.map +1 -0
  318. package/dist/panels/VariableConfigPanel.d.ts +9 -0
  319. package/dist/panels/VariableConfigPanel.d.ts.map +1 -0
  320. package/dist/panels/VariableConfigPanel.js +50 -0
  321. package/dist/panels/VariableConfigPanel.js.map +1 -0
  322. package/dist/panels/VariablesPanel.d.ts +7 -0
  323. package/dist/panels/VariablesPanel.d.ts.map +1 -0
  324. package/dist/panels/VariablesPanel.js +56 -0
  325. package/dist/panels/VariablesPanel.js.map +1 -0
  326. package/dist/stores/canvasStore.d.ts +41 -0
  327. package/dist/stores/canvasStore.d.ts.map +1 -0
  328. package/dist/stores/canvasStore.js +187 -0
  329. package/dist/stores/canvasStore.js.map +1 -0
  330. package/dist/stores/debugStore.d.ts +42 -0
  331. package/dist/stores/debugStore.d.ts.map +1 -0
  332. package/dist/stores/debugStore.js +22 -0
  333. package/dist/stores/debugStore.js.map +1 -0
  334. package/dist/stores/diagnosticsStore.d.ts +41 -0
  335. package/dist/stores/diagnosticsStore.d.ts.map +1 -0
  336. package/dist/stores/diagnosticsStore.js +67 -0
  337. package/dist/stores/diagnosticsStore.js.map +1 -0
  338. package/dist/stores/editorStore.d.ts +76 -0
  339. package/dist/stores/editorStore.d.ts.map +1 -0
  340. package/dist/stores/editorStore.js +116 -0
  341. package/dist/stores/editorStore.js.map +1 -0
  342. package/dist/utils/categoryConstants.d.ts +4 -0
  343. package/dist/utils/categoryConstants.d.ts.map +1 -0
  344. package/dist/utils/categoryConstants.js +24 -0
  345. package/dist/utils/categoryConstants.js.map +1 -0
  346. package/dist/utils/channelOperations.d.ts +21 -0
  347. package/dist/utils/channelOperations.d.ts.map +1 -0
  348. package/dist/utils/channelOperations.js +84 -0
  349. package/dist/utils/channelOperations.js.map +1 -0
  350. package/dist/utils/connectionRules.d.ts +15 -0
  351. package/dist/utils/connectionRules.d.ts.map +1 -0
  352. package/dist/utils/connectionRules.js +113 -0
  353. package/dist/utils/connectionRules.js.map +1 -0
  354. package/dist/utils/functionOperations.d.ts +27 -0
  355. package/dist/utils/functionOperations.d.ts.map +1 -0
  356. package/dist/utils/functionOperations.js +140 -0
  357. package/dist/utils/functionOperations.js.map +1 -0
  358. package/dist/utils/graphOperations.d.ts +54 -0
  359. package/dist/utils/graphOperations.d.ts.map +1 -0
  360. package/dist/utils/graphOperations.js +461 -0
  361. package/dist/utils/graphOperations.js.map +1 -0
  362. package/dist/utils/history.d.ts +76 -0
  363. package/dist/utils/history.d.ts.map +1 -0
  364. package/dist/utils/history.js +93 -0
  365. package/dist/utils/history.js.map +1 -0
  366. package/dist/utils/memoryOperations.d.ts +14 -0
  367. package/dist/utils/memoryOperations.d.ts.map +1 -0
  368. package/dist/utils/memoryOperations.js +55 -0
  369. package/dist/utils/memoryOperations.js.map +1 -0
  370. package/dist/utils/migrateFunctionNodes.d.ts +9 -0
  371. package/dist/utils/migrateFunctionNodes.d.ts.map +1 -0
  372. package/dist/utils/migrateFunctionNodes.js +89 -0
  373. package/dist/utils/migrateFunctionNodes.js.map +1 -0
  374. package/dist/utils/modelOperations.d.ts +13 -0
  375. package/dist/utils/modelOperations.d.ts.map +1 -0
  376. package/dist/utils/modelOperations.js +53 -0
  377. package/dist/utils/modelOperations.js.map +1 -0
  378. package/dist/utils/paramDisplay.d.ts +12 -0
  379. package/dist/utils/paramDisplay.d.ts.map +1 -0
  380. package/dist/utils/paramDisplay.js +56 -0
  381. package/dist/utils/paramDisplay.js.map +1 -0
  382. package/dist/utils/resourceHelpers.d.ts +17 -0
  383. package/dist/utils/resourceHelpers.d.ts.map +1 -0
  384. package/dist/utils/resourceHelpers.js +32 -0
  385. package/dist/utils/resourceHelpers.js.map +1 -0
  386. package/dist/utils/translation.d.ts +20 -0
  387. package/dist/utils/translation.d.ts.map +1 -0
  388. package/dist/utils/translation.js +23 -0
  389. package/dist/utils/translation.js.map +1 -0
  390. package/dist/utils/variableOperations.d.ts +15 -0
  391. package/dist/utils/variableOperations.d.ts.map +1 -0
  392. package/dist/utils/variableOperations.js +71 -0
  393. package/dist/utils/variableOperations.js.map +1 -0
  394. package/package.json +79 -0
  395. package/src/BuilderLayout.tsx +345 -0
  396. package/src/Canvas.tsx +261 -0
  397. package/src/CanvasEditor.tsx +142 -0
  398. package/src/CanvasTabsToolbar.tsx +176 -0
  399. package/src/RightConfigPanel.tsx +266 -0
  400. package/src/WorkflowBuilder.tsx +412 -0
  401. package/src/cn.ts +6 -0
  402. package/src/components/ui/add-button.tsx +39 -0
  403. package/src/components/ui/alert-dialog.tsx +141 -0
  404. package/src/components/ui/alert.tsx +59 -0
  405. package/src/components/ui/badge.tsx +36 -0
  406. package/src/components/ui/button.tsx +85 -0
  407. package/src/components/ui/card.tsx +79 -0
  408. package/src/components/ui/checkbox.tsx +28 -0
  409. package/src/components/ui/collapsible.tsx +9 -0
  410. package/src/components/ui/command.tsx +153 -0
  411. package/src/components/ui/delete-button.tsx +23 -0
  412. package/src/components/ui/dialog.tsx +125 -0
  413. package/src/components/ui/dropdown-menu.tsx +198 -0
  414. package/src/components/ui/input.tsx +55 -0
  415. package/src/components/ui/label.tsx +24 -0
  416. package/src/components/ui/readonly-banner.tsx +15 -0
  417. package/src/components/ui/resizable.tsx +43 -0
  418. package/src/components/ui/scroll-area.tsx +102 -0
  419. package/src/components/ui/select.tsx +160 -0
  420. package/src/components/ui/separator.tsx +29 -0
  421. package/src/components/ui/switch.tsx +27 -0
  422. package/src/components/ui/textarea.tsx +51 -0
  423. package/src/components/ui/toast.tsx +127 -0
  424. package/src/components/ui/toaster.tsx +33 -0
  425. package/src/components/ui/toggle-group.tsx +59 -0
  426. package/src/components/ui/toggle.tsx +43 -0
  427. package/src/components/ui/tooltip.tsx +32 -0
  428. package/src/dialogs/NodePickerDialog.tsx +84 -0
  429. package/src/dialogs/ValidationDialog.tsx +184 -0
  430. package/src/graph/BaseNode.tsx +557 -0
  431. package/src/graph/CustomEdge.tsx +185 -0
  432. package/src/graph/CustomNode.tsx +16 -0
  433. package/src/graph/FunctionCallNode.tsx +30 -0
  434. package/src/graph/PortHandle.tsx +189 -0
  435. package/src/graph/reactFlowRegistry.ts +26 -0
  436. package/src/hooks/use-toast.ts +125 -0
  437. package/src/hooks/useAvailableVariables.ts +20 -0
  438. package/src/hooks/useCanvasHistory.ts +22 -0
  439. package/src/hooks/useCanvasTabs.ts +168 -0
  440. package/src/hooks/useFunctionDiagnosticsSync.ts +40 -0
  441. package/src/hooks/useFunctionRegistry.ts +26 -0
  442. package/src/hooks/useFunctions.ts +44 -0
  443. package/src/hooks/useGraph.ts +161 -0
  444. package/src/hooks/useNodeDefinitions.ts +82 -0
  445. package/src/hooks/useParamErrors.ts +26 -0
  446. package/src/hooks/useResolvedTheme.ts +30 -0
  447. package/src/hooks/useResourceDiagnosticsSync.ts +58 -0
  448. package/src/hooks/useSuppressThemeTransition.ts +79 -0
  449. package/src/hooks/useWorkflowSerialization.ts +127 -0
  450. package/src/i18n/index.ts +53 -0
  451. package/src/i18n/locales/de.json +501 -0
  452. package/src/i18n/locales/en.json +557 -0
  453. package/src/index.ts +27 -0
  454. package/src/inputs/ExpressionInput.tsx +297 -0
  455. package/src/inputs/ParameterEditor.tsx +515 -0
  456. package/src/inputs/PortSection.tsx +144 -0
  457. package/src/panels/BuilderSidebar.tsx +301 -0
  458. package/src/panels/ChannelConfigPanel.tsx +49 -0
  459. package/src/panels/ChannelsPanel.tsx +28 -0
  460. package/src/panels/DebugConsolePanel.tsx +73 -0
  461. package/src/panels/DebugContextPanel.tsx +77 -0
  462. package/src/panels/DebugExternalIOPanel.tsx +180 -0
  463. package/src/panels/DiagnosticsPanel.tsx +170 -0
  464. package/src/panels/EdgeConfigPanel.tsx +104 -0
  465. package/src/panels/FunctionConfigPanel.tsx +179 -0
  466. package/src/panels/FunctionListPanel.tsx +45 -0
  467. package/src/panels/MemoryConfigPanel.tsx +55 -0
  468. package/src/panels/MemoryPanel.tsx +40 -0
  469. package/src/panels/ModelConfigPanel.tsx +41 -0
  470. package/src/panels/ModelsPanel.tsx +36 -0
  471. package/src/panels/NodeConfigPanel.tsx +630 -0
  472. package/src/panels/NodeLibrary.tsx +288 -0
  473. package/src/panels/ResourceConfigPanel.tsx +132 -0
  474. package/src/panels/ResourceListPanel.tsx +113 -0
  475. package/src/panels/VariableConfigPanel.tsx +161 -0
  476. package/src/panels/VariablesPanel.tsx +145 -0
  477. package/src/stores/canvasStore.test.ts +44 -0
  478. package/src/stores/canvasStore.ts +245 -0
  479. package/src/stores/debugStore.ts +74 -0
  480. package/src/stores/diagnosticsStore.ts +130 -0
  481. package/src/stores/editorStore.ts +202 -0
  482. package/src/styles/index.css +526 -0
  483. package/src/utils/categoryConstants.ts +26 -0
  484. package/src/utils/channelOperations.ts +86 -0
  485. package/src/utils/connectionRules.ts +137 -0
  486. package/src/utils/functionOperations.ts +179 -0
  487. package/src/utils/graphOperations.ts +550 -0
  488. package/src/utils/history.ts +207 -0
  489. package/src/utils/memoryOperations.ts +57 -0
  490. package/src/utils/migrateFunctionNodes.ts +107 -0
  491. package/src/utils/modelOperations.ts +55 -0
  492. package/src/utils/paramDisplay.ts +71 -0
  493. package/src/utils/resourceHelpers.ts +32 -0
  494. package/src/utils/translation.ts +28 -0
  495. package/src/utils/variableOperations.ts +75 -0
  496. package/tailwind-preset.ts +166 -0
@@ -0,0 +1,301 @@
1
+ import { Button } from "../components/ui/button";
2
+ import { ScrollArea } from "../components/ui/scroll-area";
3
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../components/ui/tooltip";
4
+ import { cn } from "../cn";
5
+ import { NodeCategory, NodeDefinition } from "@foresthubai/workflow-core/node";
6
+ import { useMemo } from "react";
7
+ import { Blocks, BrainCircuit, Braces, Bug, Cpu, Database, TriangleAlert, Variable, X } from "lucide-react";
8
+ import { useTranslation } from "react-i18next";
9
+ import { DiagnosticsPanel } from "./DiagnosticsPanel";
10
+ import { FunctionListPanel } from "./FunctionListPanel";
11
+ import NodeLibrary from "./NodeLibrary";
12
+ import { ChannelsPanel } from "./ChannelsPanel";
13
+ import { MemoryPanel } from "./MemoryPanel";
14
+ import { ModelsPanel } from "./ModelsPanel";
15
+ import { VariablesPanel } from "./VariablesPanel";
16
+ import { useDiagnosticsStore } from "../stores/diagnosticsStore";
17
+ import { DebugContextPanel } from "./DebugContextPanel";
18
+ import type { FunctionDeclaration } from "@foresthubai/workflow-core/function";
19
+
20
+ export type SidebarTab =
21
+ | "nodes"
22
+ | "variables"
23
+ | "channels"
24
+ | "memory"
25
+ | "models"
26
+ | "functions"
27
+ | "diagnostics"
28
+ | "debug-context"
29
+ | null;
30
+
31
+ interface BuilderSidebarProps {
32
+ canvasId: string;
33
+ activeTab: SidebarTab;
34
+ onTabChange: (tab: SidebarTab) => void;
35
+ onAddNode: (nodeType: NodeDefinition, position?: { x: number; y: number }) => void;
36
+ nodeDefinitions: NodeDefinition[];
37
+ getAllCategories: () => NodeCategory[];
38
+ onSelectNode: (nodeId: string) => void;
39
+ onSelectEdge: (edgeId: string) => void;
40
+ isFunctionCanvas: boolean;
41
+ // Function management
42
+ functions: FunctionDeclaration[];
43
+ onOpenFunction: (functionId: string) => void;
44
+ onCreateFunction: () => string;
45
+ // Debug mode
46
+ isDebugMode?: boolean;
47
+ }
48
+
49
+ export const BuilderSidebar = ({
50
+ canvasId,
51
+ activeTab,
52
+ onTabChange,
53
+ onAddNode,
54
+ nodeDefinitions,
55
+ getAllCategories,
56
+ onSelectNode,
57
+ onSelectEdge,
58
+ isFunctionCanvas,
59
+ functions,
60
+ onOpenFunction,
61
+ onCreateFunction,
62
+ isDebugMode,
63
+ }: BuilderSidebarProps) => {
64
+ const { t } = useTranslation();
65
+
66
+ const staticTabs = useMemo(
67
+ () => [
68
+ { id: "nodes" as const, icon: Blocks, label: t("nodeLibrary") },
69
+ { id: "variables" as const, icon: Variable, label: t("variables") },
70
+ { id: "channels" as const, icon: Cpu, label: t("channels") },
71
+ { id: "memory" as const, icon: Database, label: t("memoryFiles", "Memory") },
72
+ { id: "models" as const, icon: BrainCircuit, label: t("models", "AI Models") },
73
+ { id: "functions" as const, icon: Braces, label: t("functions") },
74
+ { id: "diagnostics" as const, icon: TriangleAlert, label: t("diagnostics") },
75
+ ],
76
+ [t],
77
+ );
78
+
79
+ const debugTabs = useMemo(() => [{ id: "debug-context" as const, icon: Bug, label: t("debug.context") }], [t]);
80
+
81
+ // Current-canvas diagnostics counts for the diagnostics tab — node + edge only.
82
+ const totalErrors = useDiagnosticsStore((s) => {
83
+ let count = 0;
84
+ for (const diags of Object.values(s.byNodeId)) for (const d of diags) if (d.severity === "error") count++;
85
+ for (const diags of Object.values(s.byEdgeId)) for (const d of diags) if (d.severity === "error") count++;
86
+ return count;
87
+ });
88
+ const totalWarnings = useDiagnosticsStore((s) => {
89
+ let count = 0;
90
+ for (const diags of Object.values(s.byNodeId)) for (const d of diags) if (d.severity === "warning") count++;
91
+ for (const diags of Object.values(s.byEdgeId)) for (const d of diags) if (d.severity === "warning") count++;
92
+ return count;
93
+ });
94
+
95
+ // Channels are project-scoped and own their own tab/badge — counts here
96
+ // drive the "channels" tab icon color + badge (mirrors the diagnostics tab).
97
+ const channelErrors = useDiagnosticsStore((s) => {
98
+ let count = 0;
99
+ for (const diags of Object.values(s.byChannelId)) for (const d of diags) if (d.severity === "error") count++;
100
+ return count;
101
+ });
102
+ const channelWarnings = useDiagnosticsStore((s) => {
103
+ let count = 0;
104
+ for (const diags of Object.values(s.byChannelId)) for (const d of diags) if (d.severity === "warning") count++;
105
+ return count;
106
+ });
107
+
108
+ // Memory primitives are project-scoped too — counts drive the "memory" tab
109
+ // icon color + badge (mirrors the channels tab).
110
+ const memoryErrors = useDiagnosticsStore((s) => {
111
+ let count = 0;
112
+ for (const diags of Object.values(s.byMemoryId)) for (const d of diags) if (d.severity === "error") count++;
113
+ return count;
114
+ });
115
+ const memoryWarnings = useDiagnosticsStore((s) => {
116
+ let count = 0;
117
+ for (const diags of Object.values(s.byMemoryId)) for (const d of diags) if (d.severity === "warning") count++;
118
+ return count;
119
+ });
120
+
121
+ // Declared models are project-scoped too — counts drive the "models" tab badge.
122
+ const modelErrors = useDiagnosticsStore((s) => {
123
+ let count = 0;
124
+ for (const diags of Object.values(s.byModelId)) for (const d of diags) if (d.severity === "error") count++;
125
+ return count;
126
+ });
127
+ const modelWarnings = useDiagnosticsStore((s) => {
128
+ let count = 0;
129
+ for (const diags of Object.values(s.byModelId)) for (const d of diags) if (d.severity === "warning") count++;
130
+ return count;
131
+ });
132
+
133
+ // Functions are project-scoped too — counts drive the "functions" tab badge.
134
+ const functionErrors = useDiagnosticsStore((s) => {
135
+ let count = 0;
136
+ for (const diags of Object.values(s.byFunctionId)) for (const d of diags) if (d.severity === "error") count++;
137
+ return count;
138
+ });
139
+ const functionWarnings = useDiagnosticsStore((s) => {
140
+ let count = 0;
141
+ for (const diags of Object.values(s.byFunctionId)) for (const d of diags) if (d.severity === "warning") count++;
142
+ return count;
143
+ });
144
+
145
+ const tabs = useMemo(() => (isDebugMode ? debugTabs : staticTabs), [isDebugMode, debugTabs, staticTabs]);
146
+
147
+ const handleTabClick = (tabId: SidebarTab) => {
148
+ onTabChange(activeTab === tabId ? null : tabId);
149
+ };
150
+
151
+ const renderTabContent = () => {
152
+ switch (activeTab) {
153
+ case "nodes":
154
+ return (
155
+ <NodeLibrary
156
+ onAddNode={onAddNode}
157
+ nodeDefinitions={nodeDefinitions}
158
+ getAllCategories={getAllCategories}
159
+ functions={functions}
160
+ isFunctionCanvas={!!isFunctionCanvas}
161
+ />
162
+ );
163
+ case "variables":
164
+ return <VariablesPanel canvasId={canvasId} onSelectNode={onSelectNode} />;
165
+ case "channels":
166
+ return <ChannelsPanel />;
167
+ case "memory":
168
+ return <MemoryPanel />;
169
+ case "models":
170
+ return <ModelsPanel />;
171
+ case "functions":
172
+ return <FunctionListPanel onOpenFunction={onOpenFunction} onCreateFunction={onCreateFunction} />;
173
+ case "diagnostics":
174
+ return <DiagnosticsPanel canvasId={canvasId} onSelectNode={onSelectNode} onSelectEdge={onSelectEdge} />;
175
+ case "debug-context":
176
+ return <DebugContextPanel />;
177
+ default:
178
+ return null;
179
+ }
180
+ };
181
+
182
+ const getTabLabel = (tabId: SidebarTab) => {
183
+ const tab = tabs.find((tab) => tab.id === tabId);
184
+ return tab?.label ?? "";
185
+ };
186
+
187
+ return (
188
+ <div className="flex h-full">
189
+ {/* Icon Rail - Always visible */}
190
+ <div className="w-14 bg-card border-r border-border/50 flex flex-col items-center py-3 gap-1 shrink-0">
191
+ {tabs.map((tab) => {
192
+ const Icon = tab.icon;
193
+ const isActive = activeTab === tab.id;
194
+
195
+ // Per-tab error/warning counts for icon coloring + badge.
196
+ // Diagnostics tab covers nodes+edges; channels tab covers channels.
197
+ let tabErrors = 0;
198
+ let tabWarnings = 0;
199
+ if (tab.id === "diagnostics") {
200
+ tabErrors = totalErrors;
201
+ tabWarnings = totalWarnings;
202
+ } else if (tab.id === "channels") {
203
+ tabErrors = channelErrors;
204
+ tabWarnings = channelWarnings;
205
+ } else if (tab.id === "memory") {
206
+ tabErrors = memoryErrors;
207
+ tabWarnings = memoryWarnings;
208
+ } else if (tab.id === "models") {
209
+ tabErrors = modelErrors;
210
+ tabWarnings = modelWarnings;
211
+ } else if (tab.id === "functions") {
212
+ tabErrors = functionErrors;
213
+ tabWarnings = functionWarnings;
214
+ }
215
+ const tabIssueCount = tabErrors + tabWarnings;
216
+ const showBadge = tabIssueCount > 0;
217
+
218
+ const iconColorClass =
219
+ showBadge && !isActive
220
+ ? tabErrors > 0
221
+ ? "text-destructive hover:text-destructive hover:bg-destructive/10"
222
+ : "text-warning hover:text-warning hover:bg-warning/10"
223
+ : undefined;
224
+
225
+ return (
226
+ <Tooltip key={tab.id} delayDuration={300}>
227
+ <TooltipTrigger asChild>
228
+ <Button
229
+ variant="ghost"
230
+ size="icon"
231
+ onClick={(e) => {
232
+ // Drop focus after a mouse click so a follow-up Enter doesn't
233
+ // re-fire (toggle) this tab. Keyboard activation (detail 0) keeps focus.
234
+ if (e.detail !== 0) e.currentTarget.blur();
235
+ handleTabClick(tab.id);
236
+ }}
237
+ className={cn(
238
+ "w-10 h-10 transition-all duration-200 relative",
239
+ isActive
240
+ ? "bg-accent text-primary shadow-sm"
241
+ : (iconColorClass ?? "text-muted-foreground hover:text-foreground hover:bg-accent/50"),
242
+ )}
243
+ >
244
+ <Icon className="w-5 h-5" />
245
+ {showBadge && (
246
+ <span
247
+ className={cn(
248
+ "absolute -top-0.5 -right-0.5 min-w-[16px] h-4 rounded-full text-[10px] font-bold flex items-center justify-center px-1 shadow-sm",
249
+ tabErrors > 0
250
+ ? "bg-destructive text-destructive-foreground"
251
+ : "bg-warning text-warning-foreground",
252
+ )}
253
+ >
254
+ {tabIssueCount}
255
+ </span>
256
+ )}
257
+ </Button>
258
+ </TooltipTrigger>
259
+ <TooltipContent side="right" sideOffset={8}>
260
+ {tab.label}
261
+ </TooltipContent>
262
+ </Tooltip>
263
+ );
264
+ })}
265
+ </div>
266
+
267
+ {/* Content Panel - Slides in/out */}
268
+ <div
269
+ className={cn(
270
+ "bg-card/95 backdrop-blur-xl border-r border-border/50 transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
271
+ activeTab ? "w-64 opacity-100" : "w-0 opacity-0",
272
+ )}
273
+ >
274
+ {activeTab && (
275
+ <>
276
+ {/* Panel Header */}
277
+ <div className="flex items-center justify-between p-3 border-b border-border/50 shrink-0">
278
+ <h3 className="font-semibold text-sm text-foreground">{getTabLabel(activeTab)}</h3>
279
+ <Button
280
+ variant="ghost"
281
+ size="icon"
282
+ onClick={() => onTabChange(null)}
283
+ className="w-7 h-7 text-muted-foreground hover:text-foreground"
284
+ >
285
+ <X className="w-4 h-4" />
286
+ </Button>
287
+ </div>
288
+
289
+ {/* Panel Content — ScrollArea overlays the scrollbar in the panel's
290
+ gutter so content width stays constant whether overflow is
291
+ present or not. Padding lives on the inner viewport because the
292
+ Root must clip cleanly for the absolute-positioned scrollbar. */}
293
+ <ScrollArea className="flex-1" viewportClassName="p-3">
294
+ {renderTabContent()}
295
+ </ScrollArea>
296
+ </>
297
+ )}
298
+ </div>
299
+ </div>
300
+ );
301
+ };
@@ -0,0 +1,49 @@
1
+ import { useTranslation } from "react-i18next";
2
+ import { CHANNEL_DEFINITION, type Channel, type ChannelType } from "@foresthubai/workflow-core/channel";
3
+ import { isParameterActive, type Parameter } from "@foresthubai/workflow-core/parameter";
4
+ import { useDiagnosticsStore } from "../stores/diagnosticsStore";
5
+ import { deleteChannel, updateChannel } from "../utils/channelOperations";
6
+ import { ResourceConfigPanel } from "./ResourceConfigPanel";
7
+
8
+ interface ChannelConfigPanelProps {
9
+ channel: Channel;
10
+ onClose: () => void;
11
+ }
12
+
13
+ export const ChannelConfigPanel = ({ channel, onClose }: ChannelConfigPanelProps) => {
14
+ const { t } = useTranslation();
15
+
16
+ // `type` is a parameter, so it's exposed through the same `arguments`-shaped
17
+ // record ParameterEditor reads — the top-level `type` is mirrored under the
18
+ // `type` key so the activation-rule evaluator can see it.
19
+ const allArguments: Record<string, unknown> = { ...channel.arguments, type: channel.type };
20
+ const parameters = CHANNEL_DEFINITION.parameters.filter((p) => isParameterActive(p, allArguments, false));
21
+ const channelDiags = useDiagnosticsStore((s) => s.byChannelId[channel.id]);
22
+
23
+ const handleParamChange = (paramId: string, value: unknown) => {
24
+ if (paramId === "type") {
25
+ updateChannel(channel.id, { type: value as ChannelType });
26
+ } else {
27
+ updateChannel(channel.id, { arguments: { [paramId]: value } });
28
+ }
29
+ };
30
+
31
+ return (
32
+ <ResourceConfigPanel
33
+ resetKey={channel.id}
34
+ label={channel.label}
35
+ labelTitle={t("channelLabel", "Channel label")}
36
+ onLabelChange={(label) => updateChannel(channel.id, { label })}
37
+ description={t("channelDescription", "Hardware interface declaration")}
38
+ parameters={parameters}
39
+ getValue={(p: Parameter) => (p.id === "type" ? channel.type : channel.arguments[p.id])}
40
+ allArguments={allArguments}
41
+ onParamChange={handleParamChange}
42
+ diagnostics={channelDiags}
43
+ translationPrefix="channels"
44
+ deleteLabel={t("deleteChannel", "Delete channel")}
45
+ onDelete={() => deleteChannel(channel.id)}
46
+ onClose={onClose}
47
+ />
48
+ );
49
+ };
@@ -0,0 +1,28 @@
1
+ import { useTranslation } from "react-i18next";
2
+ import { Cpu, Plus } from "lucide-react";
3
+ import { useDiagnosticsStore } from "../stores/diagnosticsStore";
4
+ import { useEditorStore } from "../stores/editorStore";
5
+ import { addChannel } from "../utils/channelOperations";
6
+ import { ResourceListPanel } from "./ResourceListPanel";
7
+
8
+ export const ChannelsPanel = () => {
9
+ const { t } = useTranslation();
10
+ const channels = useEditorStore((s) => s.channels);
11
+ const selection = useEditorStore((s) => s.selection);
12
+ const selectChannel = useEditorStore((s) => s.selectChannel);
13
+ const byChannelId = useDiagnosticsStore((s) => s.byChannelId);
14
+
15
+ return (
16
+ <ResourceListPanel
17
+ items={Object.values(channels)}
18
+ selectedId={selection.kind === "channel" ? selection.id : null}
19
+ onSelect={selectChannel}
20
+ diagnosticsSlot={byChannelId}
21
+ badge={(c) => c.type}
22
+ emptyIcon={Cpu}
23
+ emptyText={t("noChannels")}
24
+ emptyHint={t("noChannelsHint")}
25
+ addActions={[{ label: t("addChannel"), icon: Plus, onAdd: () => selectChannel(addChannel("GPIOIN").id) }]}
26
+ />
27
+ );
28
+ };
@@ -0,0 +1,73 @@
1
+ import { Button } from "../components/ui/button";
2
+ import { ScrollArea } from "../components/ui/scroll-area";
3
+ import { Trash2 } from "lucide-react";
4
+ import { useEffect, useRef } from "react";
5
+ import { useTranslation } from "react-i18next";
6
+ import { useDebugStore, type ConsoleEntry } from "../stores/debugStore";
7
+
8
+ export const DebugConsolePanel = () => {
9
+ const { t } = useTranslation();
10
+ const entries = useDebugStore((s) => s.console);
11
+ const clearConsole = useDebugStore((s) => s.clearConsole);
12
+ // Ref points at the ScrollArea Viewport (the element with overflow:scroll),
13
+ // not the Root — the Root is overflow:hidden and won't scroll.
14
+ const scrollRef = useRef<HTMLDivElement>(null);
15
+
16
+ // Auto-scroll to bottom on new entries
17
+ useEffect(() => {
18
+ if (scrollRef.current) {
19
+ scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
20
+ }
21
+ }, [entries]);
22
+
23
+ return (
24
+ <div className="h-full flex flex-col bg-background border-t border-border">
25
+ {/* Header */}
26
+ <div className="flex items-center justify-between px-3 py-1.5 border-b border-border/50 shrink-0">
27
+ <span className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
28
+ {t("debug.console")}
29
+ </span>
30
+ <Button
31
+ variant="ghost"
32
+ size="icon"
33
+ className="w-6 h-6 text-muted-foreground hover:text-foreground"
34
+ onClick={clearConsole}
35
+ title={t("debug.clearConsole")}
36
+ >
37
+ <Trash2 className="w-3.5 h-3.5" />
38
+ </Button>
39
+ </div>
40
+
41
+ {/* Console output. Radix wraps Viewport children in its own div, so
42
+ row-spacing utilities (space-y-*) on the Viewport don't reach the
43
+ actual rows — apply them on an explicit wrapper instead. */}
44
+ <ScrollArea className="flex-1" viewportRef={scrollRef} viewportClassName="p-2">
45
+ <div className="font-mono text-xs space-y-0.5">
46
+ {entries.length === 0 ? (
47
+ <div className="text-muted-foreground text-center py-4">{t("debug.consoleEmpty")}</div>
48
+ ) : (
49
+ entries.map((entry) => <ConsoleRow key={entry.id} entry={entry} />)
50
+ )}
51
+ </div>
52
+ </ScrollArea>
53
+ </div>
54
+ );
55
+ };
56
+
57
+ function ConsoleRow({ entry }: { entry: ConsoleEntry }) {
58
+ const time = new Date(entry.timestamp).toLocaleTimeString(undefined, {
59
+ hour: "2-digit",
60
+ minute: "2-digit",
61
+ second: "2-digit",
62
+ });
63
+
64
+ const colorClass =
65
+ entry.type === "error" ? "text-destructive" : entry.type === "system" ? "text-muted-foreground" : "text-foreground";
66
+
67
+ return (
68
+ <div className={`flex gap-2 leading-relaxed ${colorClass}`}>
69
+ <span className="text-muted-foreground/50 shrink-0">{time}</span>
70
+ <span className="whitespace-pre-wrap break-all">{entry.text}</span>
71
+ </div>
72
+ );
73
+ }
@@ -0,0 +1,77 @@
1
+ import { Input } from "../components/ui/input";
2
+ import { Label } from "../components/ui/label";
3
+ import { Switch } from "../components/ui/switch";
4
+ import { useTranslation } from "react-i18next";
5
+ import { useDebugStore } from "../stores/debugStore";
6
+ import { getOrCreateCanvasStore, MAIN_CANVAS_ID } from "../stores/canvasStore";
7
+ import type { DataType } from "@foresthubai/workflow-core";
8
+
9
+ interface VariableEntry {
10
+ key: string;
11
+ name: string;
12
+ dataType: DataType;
13
+ }
14
+
15
+ /** Build the list of editable variables from the main canvas store. */
16
+ function getVariableEntries(): VariableEntry[] {
17
+ const variables = getOrCreateCanvasStore(MAIN_CANVAS_ID).getState().variables;
18
+ const entries: VariableEntry[] = [];
19
+ for (const v of Object.values(variables)) {
20
+ if (v.kind === "declared" || v.kind === "node") {
21
+ entries.push({ key: v.name, name: v.name, dataType: v.dataType });
22
+ }
23
+ }
24
+ return entries.sort((a, b) => a.name.localeCompare(b.name));
25
+ }
26
+
27
+ export const DebugContextPanel = () => {
28
+ const { t } = useTranslation();
29
+ const context = useDebugStore((s) => s.context);
30
+ const updateContextVar = useDebugStore((s) => s.updateContextVar);
31
+ const entries = getVariableEntries();
32
+
33
+ if (entries.length === 0) {
34
+ return <div className="text-sm text-muted-foreground text-center py-4">{t("debug.noVariables")}</div>;
35
+ }
36
+
37
+ return (
38
+ <div className="space-y-3">
39
+ {entries.map(({ key, name, dataType }) => {
40
+ const value = context[key];
41
+ return (
42
+ <div key={key} className="space-y-1">
43
+ <Label className="text-xs font-medium flex items-center gap-1.5">
44
+ <span>{name}</span>
45
+ <span className="text-muted-foreground font-mono">({dataType})</span>
46
+ </Label>
47
+ {dataType === "bool" ? (
48
+ <Switch checked={!!value} onCheckedChange={(checked) => updateContextVar(key, checked)} />
49
+ ) : dataType === "int" ? (
50
+ <Input
51
+ type="number"
52
+ step={1}
53
+ value={(value as number) ?? 0}
54
+ onChange={(e) => updateContextVar(key, parseInt(e.target.value) || 0)}
55
+ className="h-8 font-mono text-sm"
56
+ />
57
+ ) : dataType === "float" ? (
58
+ <Input
59
+ type="number"
60
+ step={0.1}
61
+ value={(value as number) ?? 0}
62
+ onChange={(e) => updateContextVar(key, parseFloat(e.target.value) || 0)}
63
+ className="h-8 font-mono text-sm"
64
+ />
65
+ ) : (
66
+ <Input
67
+ value={String(value ?? "")}
68
+ onChange={(e) => updateContextVar(key, e.target.value)}
69
+ className="h-8 font-mono text-sm"
70
+ />
71
+ )}
72
+ </div>
73
+ );
74
+ })}
75
+ </div>
76
+ );
77
+ };