@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
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @foresthubai/workflow-builder
2
+
3
+ The ForestHub workflow **canvas/editor** — a reusable React component library. It
4
+ renders the visual builder (node graph, panels, dialogs) and pairs with the
5
+ headless [`@foresthubai/workflow-core`](../workflow-core) for the model, serialization
6
+ and validation. Core owns the data; this package owns the UI.
7
+
8
+ ## Requirements
9
+
10
+ - **React 18** (peer dependency).
11
+ - **Tailwind CSS 3** (peer dependency). This package is consumed the Tailwind way —
12
+ it ships design tokens + a Tailwind preset, not a prebuilt stylesheet. A host that
13
+ doesn't use Tailwind can't consume it as-is. This is the single supported path.
14
+
15
+ ## Setup
16
+
17
+ Four steps in the host app:
18
+
19
+ ```ts
20
+ // 1. Import the design-system tokens + builder CSS layers, once, at your entry.
21
+ import "@foresthubai/workflow-builder/styles/index.css";
22
+
23
+ // 2. Adopt the Tailwind preset (tokens → utilities, fonts, animations, plugin).
24
+ // tailwind.config.ts:
25
+ import workflowBuilderPreset from "@foresthubai/workflow-builder/tailwind-preset";
26
+ export default {
27
+ presets: [workflowBuilderPreset],
28
+ content: [
29
+ "./src/**/*.{ts,tsx}",
30
+ // 3. Scan the builder so the utility classes its components use are emitted.
31
+ "./node_modules/@foresthubai/workflow-builder/dist/**/*.js",
32
+ ],
33
+ };
34
+ ```
35
+
36
+ ```tsx
37
+ // 4. Render it inside a HEIGHT-CONSTRAINED container — the builder fills h-full/
38
+ // w-full and never assumes the viewport.
39
+ import { WorkflowBuilder } from "@foresthubai/workflow-builder";
40
+
41
+ <div style={{ height: "100vh" }}>
42
+ <WorkflowBuilder models={models} language="en" onChange={...} onError={...} />
43
+ </div>
44
+ ```
45
+
46
+ ## Ownership rules
47
+
48
+ The builder is a guest in your app. It dresses **itself** and speaks **its own**
49
+ language, but it never reaches into things the host owns.
50
+
51
+ ### Styles
52
+
53
+ - **The builder owns its base look** (font, text color, its panels/canvas/nodes)
54
+ and ships the design tokens as **defaults** on `:root` (dark) and `.light`.
55
+ - **The host owns the page.** The builder does **not** style `<body>` — no page
56
+ background, no page font, no `overscroll-behavior`. The host provides page chrome.
57
+ (The builder's translucent "glass" surfaces blur whatever's behind them, so give
58
+ the area a backdrop if you want the glass to read its best.)
59
+ - **The host drives color mode** by toggling a `.light` class on an ancestor
60
+ (typically `<html>`). Default — no class — is dark.
61
+ - **The host themes by overriding tokens.** Redeclare the CSS variables. The
62
+ contract: values are **HSL channels** (`262 83% 58%`, not `#hex`/`hsl()`); override
63
+ in **both** `:root` and `.light`; override at **`:root`/`html`, not a nested
64
+ wrapper** — Radix dialogs/menus/tooltips/selects portal to `<body>`, outside the
65
+ builder root, so a scoped override won't reach them. See
66
+ [`workflow-cli/src/theme-overrides.css`](../workflow-cli/src/theme-overrides.css) for a worked example.
67
+
68
+ ### Translations
69
+
70
+ - **The builder owns its strings** (ships `en` + `de`) in a **private** i18next
71
+ instance, served only through its own `I18nextProvider`. It deliberately does
72
+ **not** register with react-i18next's global default (no `initReactI18next`, hence
73
+ no `setI18n`) — that default is a single library-wide pointer with last-init-wins
74
+ semantics, and a guest component must not own it. So the builder never collides
75
+ with the host's i18next.
76
+ - **No host i18n setup is required.** A host with no i18next, or one using
77
+ react-i18next its own way (with or without an `<I18nextProvider>`), both work
78
+ unchanged — the builder's instance is reachable only inside its own subtree and
79
+ leaves the host's `useTranslation()` untouched.
80
+ - **The host drives locale** via the `language` prop. The builder follows it and
81
+ never auto-detects (no `LanguageDetector`, no localStorage writes).
82
+
83
+ ## What the builder relies on from the host
84
+
85
+ - React 18; Tailwind with the preset adopted and the builder in `content`.
86
+ - A **sized parent** container (the builder fills it; it never sizes the viewport).
87
+ - **Page chrome** (background/page font) — the builder no longer provides it.
88
+ - A **`.light`** class on an ancestor for light mode (default dark).
89
+ - The **`language`** prop for locale.
90
+ - The **`models`** catalog, `onChange` / `onError` (and other) callbacks, and the
91
+ imperative **ref handle** (`loadWorkflow` / `exportWorkflow` / `clear` / `validate`
92
+ / undo-redo / selection / `setDebugPhase`). See `WorkflowBuilderProps` and
93
+ `WorkflowBuilderHandle` in [`src/WorkflowBuilder.tsx`](./src/WorkflowBuilder.tsx).
@@ -0,0 +1,34 @@
1
+ import type { FunctionDeclaration } from "@foresthubai/workflow-core/function";
2
+ import type { CanvasTab } from "./hooks/useCanvasTabs";
3
+ /**
4
+ * Chrome composer. Stable across canvas switches — only the {@link CanvasEditor}
5
+ * child remounts via `key={activeCanvasId}`.
6
+ *
7
+ * Owns:
8
+ * - Sidebar tab state and the mode → sidebar-tab auto-switch effect.
9
+ * - viewportCenterRef (populated by ReactFlow, consumed by sidebar's
10
+ * click-to-add path).
11
+ * - Selection-drag flag (lifted here so RightConfigPanel can read it).
12
+ * - All graph mutation handlers — bound to active canvas via
13
+ * `useGraph(activeCanvasId)`. Handlers stay stable enough to pass to the
14
+ * sidebar; closures refresh automatically when the active canvas changes.
15
+ * - Document-level keyboard handlers (undo/redo/copy/paste/delete/escape).
16
+ *
17
+ * Receives the open-tab list and function-CRUD callbacks from
18
+ * {@link WorkflowBuilder} above (which owns long-lived editor state).
19
+ */
20
+ export interface BuilderLayoutProps {
21
+ functions: FunctionDeclaration[];
22
+ /** Open (and select) an existing function — used by the sidebar list and tab dropdown. */
23
+ onOpenFunction: (functionId: string) => void;
24
+ /** Create a new function and open it — the sidebar list's "Add" action. */
25
+ onCreateFunction: () => string;
26
+ canvasTabs: CanvasTab[];
27
+ onCanvasTabChange: (tabId: string) => void;
28
+ onCanvasTabClose: (tabId: string) => void;
29
+ onCanvasTabReorder: (fromIndex: number, toIndex: number) => void;
30
+ onTestNode?: (nodeId: string) => void;
31
+ onDebugStep?: (nodeId?: string) => void;
32
+ }
33
+ export declare const BuilderLayout: ({ functions, onOpenFunction, onCreateFunction, canvasTabs, onCanvasTabChange, onCanvasTabClose, onCanvasTabReorder, onTestNode, onDebugStep, }: BuilderLayoutProps) => import("react/jsx-runtime").JSX.Element;
34
+ //# sourceMappingURL=BuilderLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuilderLayout.d.ts","sourceRoot":"","sources":["../src/BuilderLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAe/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKvD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,0FAA0F;IAC1F,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,MAAM,CAAC;IAE/B,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAEjE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,aAAa,GAAI,gJAU3B,kBAAkB,4CAyRpB,CAAC"}
@@ -0,0 +1,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { toast } from "./hooks/use-toast";
4
+ import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./components/ui/resizable";
5
+ import { BuilderSidebar } from "./panels/BuilderSidebar";
6
+ import { CanvasTabsToolbar } from "./CanvasTabsToolbar";
7
+ import { CanvasEditor } from "./CanvasEditor";
8
+ import { RightConfigPanel } from "./RightConfigPanel";
9
+ import { useCanvasHistory } from "./hooks/useCanvasHistory";
10
+ import { useGraph } from "./hooks/useGraph";
11
+ import { useNodeDefinitions } from "./hooks/useNodeDefinitions";
12
+ import { DebugConsolePanel } from "./panels/DebugConsolePanel";
13
+ import { getOrCreateCanvasStore, MAIN_CANVAS_ID } from "./stores/canvasStore";
14
+ import { useEditorStore } from "./stores/editorStore";
15
+ import { isReadOnly } from "./WorkflowBuilder";
16
+ export const BuilderLayout = ({ functions, onOpenFunction, onCreateFunction, canvasTabs, onCanvasTabChange, onCanvasTabClose, onCanvasTabReorder, onTestNode, onDebugStep, }) => {
17
+ const activeCanvasId = useEditorStore((s) => s.activeCanvasId);
18
+ const builderMode = useEditorStore((s) => s.builderMode);
19
+ const readOnly = isReadOnly(builderMode);
20
+ const isDebugMode = builderMode.type === "debug";
21
+ // NodeRegistry (static) + dynamic function nodes — derived, not embedder-provided.
22
+ const { nodeDefinitions, getNodeDefinition, getAllCategories } = useNodeDefinitions();
23
+ const graph = useGraph(activeCanvasId, readOnly);
24
+ const { undo, redo, takeCheckpoint, canUndo, canRedo } = useCanvasHistory(activeCanvasId);
25
+ // Selection (project-wide in editorStore, mirrored to canvas store for RF visual)
26
+ const selection = useEditorStore((s) => s.selection);
27
+ const selectGraph = useEditorStore((s) => s.selectGraph);
28
+ const syncSelectionFromRF = useEditorStore((s) => s.syncSelectionFromRF);
29
+ const clearSelection = useEditorStore((s) => s.clearSelection);
30
+ // Sidebar tab state + mode auto-switch.
31
+ const activeSidebarTab = useEditorStore((s) => s.activeSidebarTab);
32
+ const setActiveSidebarTab = useEditorStore((s) => s.setActiveSidebarTab);
33
+ useEffect(() => {
34
+ const isDebugTab = activeSidebarTab === "debug-context";
35
+ if (isDebugMode && !isDebugTab) {
36
+ setActiveSidebarTab("debug-context");
37
+ }
38
+ else if (!isDebugMode && isDebugTab) {
39
+ setActiveSidebarTab("nodes");
40
+ }
41
+ }, [isDebugMode, activeSidebarTab, setActiveSidebarTab]);
42
+ // Selection-drag flag (used by RightConfigPanel to suppress during drag).
43
+ const [selectionDrag, setSelectionDrag] = useState(false);
44
+ // ViewportCenter ref (populated by ReactFlow inside CanvasEditor, consumed
45
+ // here for sidebar's click-to-add path).
46
+ const viewportCenterRef = useRef(null);
47
+ // ── Handlers ──────────────────────────────────────────────────────────────
48
+ const selectNodeById = useCallback((nodeId) => selectGraph([nodeId], []), [selectGraph]);
49
+ const selectEdgeById = useCallback((edgeId) => selectGraph([], [edgeId]), [selectGraph]);
50
+ const handleAddNode = useCallback((nodeDef, position) => {
51
+ const pos = position ?? viewportCenterRef.current?.();
52
+ const id = graph.addNode(nodeDef, pos);
53
+ if (id == null) {
54
+ toast({ title: `Only one ${nodeDef.label} node allowed per canvas`, variant: "destructive" });
55
+ }
56
+ return id;
57
+ }, [graph]);
58
+ const handleConnect = useCallback((conn) => {
59
+ const edgeType = graph.onConnect(conn);
60
+ // Auto-select agent edges so the config panel opens for parameter entry.
61
+ if (edgeType && edgeType !== "control" && edgeType !== "tool") {
62
+ const { edges: currentEdges } = getOrCreateCanvasStore(activeCanvasId).getState();
63
+ const newEdge = currentEdges.find((e) => e.source === conn.source &&
64
+ e.target === conn.target &&
65
+ e.sourceHandle === conn.sourceHandle &&
66
+ e.targetHandle === conn.targetHandle);
67
+ if (newEdge)
68
+ selectEdgeById(newEdge.id);
69
+ }
70
+ }, [graph, activeCanvasId, selectEdgeById]);
71
+ const handleAddNodeAndConnect = useCallback((nodeDef, position, connection) => {
72
+ const newNodeId = graph.addNodeAndConnect(nodeDef, position, connection);
73
+ if (newNodeId == null) {
74
+ toast({ title: `Only one ${nodeDef.label} node allowed per canvas`, variant: "destructive" });
75
+ }
76
+ return newNodeId;
77
+ }, [graph]);
78
+ const handleSelectionChange = useCallback(({ nodes: selNodes, edges: selEdges }) => {
79
+ syncSelectionFromRF(selNodes.map((n) => n.id), selEdges.map((e) => e.id));
80
+ }, [syncSelectionFromRF]);
81
+ const handleDeleteEdge = useCallback((edgeId) => {
82
+ graph.deleteEdges([edgeId]);
83
+ clearSelection();
84
+ }, [graph, clearSelection]);
85
+ const handleNodeDragStart = useCallback(() => {
86
+ takeCheckpoint();
87
+ }, [takeCheckpoint]);
88
+ const deleteSelected = useCallback(() => {
89
+ const sel = useEditorStore.getState().selection;
90
+ const nodeIds = sel.kind === "graph" ? sel.nodeIds : [];
91
+ const edgeIds = sel.kind === "graph" ? sel.edgeIds : [];
92
+ graph.deleteSelected(nodeIds, edgeIds);
93
+ clearSelection();
94
+ }, [graph, clearSelection]);
95
+ const handlePaste = useCallback((offset) => {
96
+ const result = graph.pasteSelection(offset);
97
+ if (result?.skippedLabels.length) {
98
+ for (const label of result.skippedLabels) {
99
+ toast({ title: `Only one ${label} node allowed per canvas`, variant: "destructive" });
100
+ }
101
+ }
102
+ return result;
103
+ }, [graph]);
104
+ // Debug mode: clicking a node sets the debug cursor.
105
+ // useEffect(() => {
106
+ // if (!isDebugMode || selectedNodeIds.length !== 1) return;
107
+ // const nodeId = selectedNodeIds[0];
108
+ // const phase = useDebugStore.getState().phase;
109
+ // if (phase.status === "idle") {
110
+ // useDebugStore
111
+ // .getState()
112
+ // .setPhase({ status: "paused", sessionId: phase.sessionId, cursorNodeId: nodeId });
113
+ // } else if (phase.status === "paused") {
114
+ // useDebugStore.getState().setPhase({ ...phase, cursorNodeId: nodeId });
115
+ // }
116
+ // }, [isDebugMode, selectedNodeIds]);
117
+ // Keyboard handlers — undo/redo/copy/paste/delete/escape.
118
+ useEffect(() => {
119
+ const handleKeyDown = (event) => {
120
+ const target = event.target;
121
+ if (target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.isContentEditable) {
122
+ return;
123
+ }
124
+ if (readOnly) {
125
+ if (event.key === "Escape")
126
+ clearSelection();
127
+ return;
128
+ }
129
+ if ((event.ctrlKey || event.metaKey) && event.key === "z" && !event.shiftKey) {
130
+ event.preventDefault();
131
+ if (canUndo()) {
132
+ clearSelection();
133
+ undo();
134
+ }
135
+ return;
136
+ }
137
+ if ((event.ctrlKey || event.metaKey) && (event.key === "y" || (event.key === "z" && event.shiftKey))) {
138
+ event.preventDefault();
139
+ if (canRedo()) {
140
+ clearSelection();
141
+ redo();
142
+ }
143
+ return;
144
+ }
145
+ if ((event.ctrlKey || event.metaKey) && event.key === "c") {
146
+ if (selection.kind === "graph" && selection.nodeIds.length > 0) {
147
+ event.preventDefault();
148
+ graph.copySelection(selection.nodeIds);
149
+ }
150
+ return;
151
+ }
152
+ if ((event.ctrlKey || event.metaKey) && event.key === "v") {
153
+ event.preventDefault();
154
+ handlePaste();
155
+ return;
156
+ }
157
+ if (event.key === "Delete" || event.key === "Backspace") {
158
+ deleteSelected();
159
+ }
160
+ if (event.key === "Escape") {
161
+ clearSelection();
162
+ }
163
+ };
164
+ document.addEventListener("keydown", handleKeyDown);
165
+ return () => document.removeEventListener("keydown", handleKeyDown);
166
+ }, [canUndo, canRedo, undo, redo, clearSelection, deleteSelected, selection, graph, handlePaste, readOnly]);
167
+ const isFunctionCanvas = activeCanvasId !== MAIN_CANVAS_ID;
168
+ // ── Render ───────────────────────────────────────────────────────────────
169
+ const canvasArea = (_jsxs("div", { className: "flex flex-col h-full min-w-0", children: [_jsx(CanvasTabsToolbar, { tabs: canvasTabs, activeTabId: activeCanvasId, onTabChange: onCanvasTabChange, onTabClose: onCanvasTabClose, onTabReorder: onCanvasTabReorder }), _jsx("div", { className: "flex-1 relative", children: _jsx(CanvasEditor, { canvasId: activeCanvasId, viewportCenterRef: viewportCenterRef, nodeDefinitions: nodeDefinitions, onConnect: handleConnect, onAddNode: handleAddNode, onAddNodeAndConnect: handleAddNodeAndConnect, onSelectionChange: handleSelectionChange, onPaneClick: clearSelection, onNodeDragStart: handleNodeDragStart, setSelectionDrag: setSelectionDrag }, activeCanvasId) })] }));
170
+ return (_jsx("div", { className: "h-full bg-canvas-bg flex flex-col", children: _jsxs("div", { className: "flex-1 flex overflow-hidden", children: [_jsx(BuilderSidebar, { canvasId: activeCanvasId, activeTab: activeSidebarTab, onTabChange: setActiveSidebarTab, onAddNode: handleAddNode, nodeDefinitions: nodeDefinitions, getAllCategories: getAllCategories, onSelectNode: selectNodeById, onSelectEdge: selectEdgeById, isFunctionCanvas: isFunctionCanvas, functions: functions, onOpenFunction: onOpenFunction, onCreateFunction: onCreateFunction, isDebugMode: isDebugMode }), _jsx("div", { className: "flex-1 flex flex-col h-full min-w-0", children: isDebugMode ? (_jsxs(ResizablePanelGroup, { direction: "vertical", children: [_jsx(ResizablePanel, { defaultSize: 75, minSize: 30, children: canvasArea }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 25, minSize: 10, children: _jsx(DebugConsolePanel, {}) })] })) : (canvasArea) }), _jsx(RightConfigPanel, { canvasId: activeCanvasId, isDebugMode: isDebugMode, selectionDrag: selectionDrag, getNodeDef: getNodeDefinition, onNodeUpdate: graph.updateNode, onNodeDelete: graph.deleteNode, onEdgeUpdate: graph.updateEdge, onEdgeDelete: handleDeleteEdge, onClearSelection: clearSelection, onTestNode: onTestNode, onDebugStep: onDebugStep })] }) }));
171
+ };
172
+ //# sourceMappingURL=BuilderLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuilderLayout.js","sourceRoot":"","sources":["../src/BuilderLayout.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Connection, Node, OnSelectionChangeFunc } from "@xyflow/react";
2
+ import React from "react";
3
+ import { NodeDefinition, NodeData } from "@foresthubai/workflow-core/node";
4
+ interface CanvasProps {
5
+ canvasId: string;
6
+ onConnect: (connection: Connection) => void;
7
+ onSelectionChange: OnSelectionChangeFunc;
8
+ onSelectionStart: () => void;
9
+ onSelectionStop: () => void;
10
+ onPaneClick: (event: React.MouseEvent) => void;
11
+ onAddNode: (nodeType: NodeDefinition, position?: {
12
+ x: number;
13
+ y: number;
14
+ }) => void;
15
+ onNodeDragStart: (event: React.MouseEvent, node: Node<NodeData>) => void;
16
+ viewportCenterRef: React.MutableRefObject<(() => {
17
+ x: number;
18
+ y: number;
19
+ }) | null>;
20
+ }
21
+ declare const Canvas: (props: CanvasProps) => import("react/jsx-runtime").JSX.Element;
22
+ export default Canvas;
23
+ //# sourceMappingURL=Canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../src/Canvas.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,UAAU,EAIV,IAAI,EAEJ,qBAAqB,EAMtB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAmD,MAAM,OAAO,CAAC;AAGxE,OAAO,EAAgB,cAAc,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAOzF,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5C,iBAAiB,EAAE,qBAAqB,CAAC;IACzC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC/C,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IACzE,iBAAiB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,MAAM;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;CACpF;AAoND,QAAA,MAAM,MAAM,GAAI,OAAO,WAAW,4CAQjC,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/Canvas.js ADDED
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { applyEdgeChanges, applyNodeChanges, Background, BackgroundVariant, Controls, MiniMap, ReactFlow, ReactFlowProvider, SelectionMode, useNodesInitialized, useReactFlow, } from "@xyflow/react";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { useResolvedTheme } from "./hooks/useResolvedTheme";
5
+ import { NodeCategory } from "@foresthubai/workflow-core/node";
6
+ import { isValidConnection as validateConnection } from "./utils/connectionRules";
7
+ import { getOrCreateCanvasStore } from "./stores/canvasStore";
8
+ import { useEditorStore } from "./stores/editorStore";
9
+ import { nodeTypes, edgeTypes } from "./graph/reactFlowRegistry";
10
+ import { isReadOnly } from "./WorkflowBuilder";
11
+ // Inner component that uses useReactFlow - must be inside ReactFlowProvider
12
+ const CanvasArea = ({ canvasId, onConnect, onSelectionChange, onSelectionStart, onSelectionStop, onPaneClick, onAddNode, onNodeDragStart, viewportCenterRef, }) => {
13
+ const readOnly = useEditorStore((s) => isReadOnly(s.builderMode));
14
+ const resolvedTheme = useResolvedTheme();
15
+ const { screenToFlowPosition, getViewport, fitView } = useReactFlow();
16
+ const nodesInitialized = useNodesInitialized();
17
+ // Expose viewport center calculation to parent via ref so new nodes can be dropped there.
18
+ useEffect(() => {
19
+ viewportCenterRef.current = () => {
20
+ const container = document.querySelector(".react-flow");
21
+ if (!container)
22
+ return { x: 250, y: 100 };
23
+ const { width, height } = container.getBoundingClientRect();
24
+ const { x, y, zoom } = getViewport();
25
+ // Offset by approximate half-node size so the node appears centered, not top-left aligned
26
+ return {
27
+ x: (-x + width / 2) / zoom - 90,
28
+ y: (-y + height / 2) / zoom - 50,
29
+ };
30
+ };
31
+ }, [getViewport, viewportCenterRef]);
32
+ // Get the independent store for this canvas - direct top-level access
33
+ const useStore = getOrCreateCanvasStore(canvasId);
34
+ const nodes = useStore((s) => s.nodes);
35
+ const edges = useStore((s) => s.edges);
36
+ const setNodes = useStore((s) => s.setNodes);
37
+ const setEdges = useStore((s) => s.setEdges);
38
+ const setViewport = useStore((s) => s.setViewport);
39
+ // This component remounts per canvas (key={canvasId} in BuilderLayout), so ReactFlow
40
+ // starts cold on every tab switch. Read the stored viewport ONCE at mount, non-reactively
41
+ // (a reactive read would re-render on every pan). Present → restore via defaultViewport so
42
+ // the FIRST painted frame is already correct. Absent (first visit) → fit once nodes are
43
+ // measured (effect below).
44
+ const initialViewport = useRef(useStore.getState().viewport).current;
45
+ // A first visit has nothing to restore, so the fit must run post-mount and would otherwise
46
+ // paint the default {0,0,1} frame first and jump to the fit on the next frame. Keep the
47
+ // canvas hidden until that fit lands, then reveal the already-correct frame. A restored
48
+ // viewport is right on frame 1, so it starts visible — only the first-visit fit is gated.
49
+ const [ready, setReady] = useState(initialViewport != null);
50
+ useEffect(() => {
51
+ if (ready || initialViewport != null)
52
+ return;
53
+ // An empty canvas has nothing to fit — and useNodesInitialized stays false forever with
54
+ // zero nodes — so reveal at the default viewport instead of staying hidden (which would
55
+ // blank the canvas: no background, can't drop nodes in).
56
+ if (nodes.length === 0) {
57
+ setReady(true);
58
+ return;
59
+ }
60
+ if (!nodesInitialized)
61
+ return;
62
+ // fitView updates ReactFlow's viewport, but the transform paints ONE FRAME LATER than this
63
+ // call (measured). Revealing now would show one frame at the identity viewport before the
64
+ // fit lands — the twitch. So fit now, then reveal on the next frame, once the transform has
65
+ // painted. Seed the store so re-entering this canvas restores the view instead of refitting.
66
+ fitView({ padding: 0.15, maxZoom: 1 });
67
+ const raf = requestAnimationFrame(() => {
68
+ setViewport(getViewport());
69
+ setReady(true);
70
+ });
71
+ return () => cancelAnimationFrame(raf);
72
+ }, [ready, initialViewport, nodes.length, nodesInitialized, fitView, getViewport, setViewport]);
73
+ // Function to determine node color for MiniMap (uses ReactFlow node types, not domain NodeType)
74
+ const nodeColor = (node) => {
75
+ switch (node.type) {
76
+ case NodeCategory.Trigger:
77
+ return "hsl(var(--node-trigger))";
78
+ case NodeCategory.Tool:
79
+ return "hsl(var(--node-tool))";
80
+ case NodeCategory.AI:
81
+ return "hsl(var(--node-agent))";
82
+ default:
83
+ return "hsl(var(--muted))";
84
+ }
85
+ };
86
+ // ReactFlow change handlers - apply changes directly to store
87
+ const onNodesChange = useCallback((changes) => {
88
+ setNodes((nds) => applyNodeChanges(changes, nds));
89
+ }, [setNodes]);
90
+ const onEdgesChange = useCallback((changes) => {
91
+ setEdges((eds) => applyEdgeChanges(changes, eds));
92
+ }, [setEdges]);
93
+ const handleDrop = useCallback((event) => {
94
+ event.preventDefault();
95
+ if (!onAddNode || readOnly)
96
+ return;
97
+ try {
98
+ const dragData = JSON.parse(event.dataTransfer.getData("application/json"));
99
+ // Convert screen coordinates to flow coordinates (accounting for pan/zoom)
100
+ const position = screenToFlowPosition({
101
+ x: event.clientX,
102
+ y: event.clientY,
103
+ });
104
+ onAddNode(dragData.nodeDef, position);
105
+ }
106
+ catch (error) {
107
+ console.error("Failed to parse node data:", error);
108
+ }
109
+ }, [onAddNode, screenToFlowPosition, readOnly]);
110
+ const handleDragOver = (event) => {
111
+ if (readOnly)
112
+ return;
113
+ event.preventDefault();
114
+ event.dataTransfer.dropEffect = "copy";
115
+ };
116
+ // Prevent browser middle-click auto-scroll which causes viewport jumps
117
+ const handleMouseDownCapture = (e) => {
118
+ if (e.button === 1) {
119
+ e.preventDefault();
120
+ }
121
+ };
122
+ const handleAuxClick = (e) => {
123
+ if (e.button === 1) {
124
+ e.preventDefault();
125
+ }
126
+ };
127
+ return (
128
+ // Gate the first-visit fit with opacity, NOT visibility/display:
129
+ // - visibility:hidden is overridden by ReactFlow, which sets visibility:visible on each
130
+ // measured node, so the nodes stay on screen and you still see the fit jump.
131
+ // - display:none removes layout boxes, so nodes never measure and the fit can't compute.
132
+ // opacity applies to the whole subtree as a group (children can't override it) yet keeps
133
+ // layout intact, so measurement/fitView work while it's invisible.
134
+ _jsx("div", { className: "w-full h-full", style: { opacity: ready ? 1 : 0 }, children: _jsxs(ReactFlow, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, onConnect: onConnect, isValidConnection: (c) => !!validateConnection(c.source, c.target, c.sourceHandle, c.targetHandle, nodes, edges), onPaneClick: onPaneClick, onNodeDragStart: onNodeDragStart, onSelectionChange: onSelectionChange, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionStop, onMoveEnd: (_, vp) => setViewport(vp), nodeTypes: nodeTypes, edgeTypes: edgeTypes, defaultViewport: initialViewport ?? undefined, selectionOnDrag: !readOnly, panOnDrag: [1, 2], selectionMode: SelectionMode.Partial, selectNodesOnDrag: false, nodesConnectable: !readOnly, nodesDraggable: !readOnly, zoomOnScroll: true, zoomOnPinch: true, onDrop: handleDrop, onDragOver: handleDragOver, deleteKeyCode: null, onContextMenu: (e) => e.preventDefault(), onMouseDownCapture: handleMouseDownCapture, onAuxClick: handleAuxClick, colorMode: resolvedTheme, style: { "--xy-background-color": "hsl(var(--canvas-background))" }, children: [_jsx(Background, { variant: BackgroundVariant.Dots, color: "hsl(var(--muted-foreground))", gap: 24, size: 1.5, className: "opacity-40" }), _jsx(Controls, { className: "glass-forest-panel !border !shadow-lg [&_button]:glass-forest-button [&_button]:!text-foreground hover:[&_button]:!scale-105" }), _jsx(MiniMap, { nodeColor: nodeColor, className: "glass-forest-panel !border !shadow-lg", maskColor: "hsl(var(--primary) / 0.15)", nodeBorderRadius: 12, nodeStrokeWidth: 2, style: { width: 120, height: 80 } })] }) }));
135
+ };
136
+ // Wrapper component that provides ReactFlowProvider context
137
+ const Canvas = (props) => {
138
+ return (_jsx("div", { className: "w-full h-full overflow-hidden overscroll-contain", children: _jsx(ReactFlowProvider, { children: _jsx(CanvasArea, { ...props }) }) }));
139
+ };
140
+ export default Canvas;
141
+ //# sourceMappingURL=Canvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvas.js","sourceRoot":"","sources":["../src/Canvas.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { Dispatch, MutableRefObject, SetStateAction } from "react";
2
+ import type { Connection, Node, OnSelectionChangeFunc } from "@xyflow/react";
3
+ import type { NodeDefinition, NodeData } from "@foresthubai/workflow-core/node";
4
+ /**
5
+ * The per-canvas editing surface. Wraps {@link Canvas} (the ReactFlow
6
+ * primitive) with the popup state and viewport-center machinery that has
7
+ * to remount when the user switches canvases.
8
+ *
9
+ * Mounted with `key={canvasId}` by {@link BuilderLayout} — when the active
10
+ * canvas changes, this component fully remounts so port-popup, selection-
11
+ * drag, and the viewport-center ref all reset cleanly without imperative
12
+ * teardown.
13
+ *
14
+ * Graph mutations, history, and keyboard handling live one level up in
15
+ * BuilderLayout so they can drive the sidebar and right panel siblings.
16
+ */
17
+ export interface CanvasEditorProps {
18
+ canvasId: string;
19
+ /** Populated by Canvas/ReactFlow on mount; read by sidebar's click-to-add. */
20
+ viewportCenterRef: MutableRefObject<(() => {
21
+ x: number;
22
+ y: number;
23
+ }) | null>;
24
+ /** Node-palette registry for the contextual port-plus picker. */
25
+ nodeDefinitions: NodeDefinition[];
26
+ onConnect: (connection: Connection) => void;
27
+ onAddNode: (nodeDef: NodeDefinition, position?: {
28
+ x: number;
29
+ y: number;
30
+ }) => string | null | undefined;
31
+ onAddNodeAndConnect: (nodeDef: NodeDefinition, position: {
32
+ x: number;
33
+ y: number;
34
+ }, connection: {
35
+ source: string;
36
+ sourceHandle: string;
37
+ target: string;
38
+ targetHandle: string;
39
+ }) => string | null | undefined;
40
+ onSelectionChange: OnSelectionChangeFunc;
41
+ onPaneClick: () => void;
42
+ onNodeDragStart: (event: React.MouseEvent, node: Node<NodeData>) => void;
43
+ setSelectionDrag: Dispatch<SetStateAction<boolean>>;
44
+ }
45
+ export declare const CanvasEditor: ({ canvasId, viewportCenterRef, nodeDefinitions, onConnect, onAddNode, onAddNodeAndConnect, onSelectionChange, onPaneClick, onNodeDragStart, setSelectionDrag, }: CanvasEditorProps) => import("react/jsx-runtime").JSX.Element;
46
+ //# sourceMappingURL=CanvasEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasEditor.d.ts","sourceRoot":"","sources":["../src/CanvasEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAShF;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IAEjB,8EAA8E;IAC9E,iBAAiB,EAAE,gBAAgB,CAAC,CAAC,MAAM;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAE7E,iEAAiE;IACjE,eAAe,EAAE,cAAc,EAAE,CAAC;IAGlC,SAAS,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvG,mBAAmB,EAAE,CACnB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClC,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,KACvF,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/B,iBAAiB,EAAE,qBAAqB,CAAC;IACzC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAGzE,gBAAgB,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CACrD;AAED,eAAO,MAAM,YAAY,GAAI,iKAW1B,iBAAiB,4CAgFnB,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { getPorts } from "@foresthubai/workflow-core/node";
4
+ import { getCompatibleNodeDefs } from "./utils/connectionRules";
5
+ import Canvas from "./Canvas";
6
+ import { NodePickerDialog } from "./dialogs/NodePickerDialog";
7
+ import { getOrCreateCanvasStore, MAIN_CANVAS_ID } from "./stores/canvasStore";
8
+ export const CanvasEditor = ({ canvasId, viewportCenterRef, nodeDefinitions, onConnect, onAddNode, onAddNodeAndConnect, onSelectionChange, onPaneClick, onNodeDragStart, setSelectionDrag, }) => {
9
+ const isFunctionCanvas = canvasId !== MAIN_CANVAS_ID;
10
+ // Contextual node picker ("+" on output ports). PortHandle lives deep
11
+ // inside ReactFlow's render tree, so it dispatches a bubbling CustomEvent
12
+ // that we catch on this container — no prop drilling through RF needed.
13
+ const [portAction, setPortAction] = useState(null);
14
+ const containerRef = useRef(null);
15
+ useEffect(() => {
16
+ const el = containerRef.current;
17
+ if (!el)
18
+ return;
19
+ const handler = (e) => setPortAction(e.detail);
20
+ el.addEventListener("port-plus-click", handler);
21
+ return () => el.removeEventListener("port-plus-click", handler);
22
+ }, []);
23
+ const compatibleDefs = useMemo(() => {
24
+ if (!portAction)
25
+ return [];
26
+ const { nodes, edges } = getOrCreateCanvasStore(canvasId).getState();
27
+ return getCompatibleNodeDefs(portAction.nodeId, portAction.handleId, nodes, edges, nodeDefinitions, isFunctionCanvas);
28
+ }, [portAction, canvasId, nodeDefinitions, isFunctionCanvas]);
29
+ const handleAddAndConnect = useCallback((nodeDef) => {
30
+ if (!portAction)
31
+ return;
32
+ const { nodes: currentNodes } = getOrCreateCanvasStore(canvasId).getState();
33
+ const originNode = currentNodes.find((n) => n.id === portAction.nodeId);
34
+ if (!originNode)
35
+ return;
36
+ const originPos = originNode.position;
37
+ const position = portAction.portType === "tool"
38
+ ? { x: originPos.x, y: originPos.y + 200 }
39
+ : { x: originPos.x + 280, y: originPos.y };
40
+ const newNodePorts = getPorts({ type: nodeDef.type });
41
+ const targetPort = newNodePorts.input.find((p) => p.type === portAction.portType);
42
+ if (!targetPort)
43
+ return;
44
+ onAddNodeAndConnect(nodeDef, position, {
45
+ source: portAction.nodeId,
46
+ sourceHandle: portAction.handleId,
47
+ target: "",
48
+ targetHandle: targetPort.id,
49
+ });
50
+ setPortAction(null);
51
+ }, [portAction, canvasId, onAddNodeAndConnect]);
52
+ return (_jsxs("div", { ref: containerRef, className: "h-full flex flex-col", children: [_jsx("div", { className: "flex-1 relative", children: _jsx(Canvas, { canvasId: canvasId, onConnect: onConnect, onSelectionChange: onSelectionChange, onSelectionStart: () => setSelectionDrag(true), onSelectionStop: () => setSelectionDrag(false), onPaneClick: onPaneClick, onAddNode: onAddNode, onNodeDragStart: onNodeDragStart, viewportCenterRef: viewportCenterRef }) }), _jsx(NodePickerDialog, { open: portAction !== null, onOpenChange: (open) => {
53
+ if (!open)
54
+ setPortAction(null);
55
+ }, compatibleDefs: compatibleDefs, onSelect: handleAddAndConnect })] }));
56
+ };
57
+ //# sourceMappingURL=CanvasEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasEditor.js","sourceRoot":"","sources":["../src/CanvasEditor.tsx"],"names":[],"mappings":"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"}