@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,140 @@
1
+ import { generateId } from "@foresthubai/workflow-core/id";
2
+ import { ensureUid } from "@foresthubai/workflow-core/variable";
3
+ import { useEditorStore } from "../stores/editorStore";
4
+ import { getCanvasStore, getOrCreateCanvasStore, deleteCanvasStore, syncFunctionArgVariables, notifyCanvasRegistryChange, } from "../stores/canvasStore";
5
+ import { uniqueName } from "./resourceHelpers";
6
+ /**
7
+ * Functions are a project-scoped resource: the declaration ({@link FunctionDeclaration}
8
+ * — signature + bundled output assignments) lives in editorStore, the body lives in
9
+ * the matching canvas store (id === fn.id). These operations keep the two in sync.
10
+ * Like channel/memory/model operations they write straight to the store (no undo
11
+ * history). A declaration change (name/arguments/outputs) forward-reconciles call
12
+ * sites via the migration subscription; an output *expression* edit does not (call
13
+ * sites never see the callee's expressions), so it doesn't bump the version.
14
+ */
15
+ const emptyExpression = (dataType) => ({ expression: "", references: [], dataType });
16
+ /** Re-derive the body's fnarg variables from the declaration's current arguments. */
17
+ function syncBody(fn) {
18
+ const store = getCanvasStore(fn.id);
19
+ if (store)
20
+ syncFunctionArgVariables(store, fn.arguments);
21
+ }
22
+ /**
23
+ * Apply an update to one function. `bumpVersion` is true for signature changes
24
+ * (name/arguments/outputs declaration) so call sites detect staleness, and false for
25
+ * pure output-expression edits. Version-bumping changes re-sync the body's fnargs.
26
+ */
27
+ function mutate(id, updater, bumpVersion) {
28
+ let next;
29
+ useEditorStore.getState().setFunctions((fns) => {
30
+ const fn = fns[id];
31
+ if (!fn)
32
+ return fns;
33
+ const updated = updater(fn);
34
+ next = bumpVersion ? { ...updated, version: fn.version + 1 } : updated;
35
+ return { ...fns, [id]: next };
36
+ });
37
+ if (next && bumpVersion)
38
+ syncBody(next);
39
+ }
40
+ /** Create a new (empty) function + its body canvas. Returns the new definition. */
41
+ export function addFunction() {
42
+ const id = generateId();
43
+ const existing = Object.values(useEditorStore.getState().functions).map((f) => f.name);
44
+ const fn = {
45
+ id,
46
+ version: 1,
47
+ name: uniqueName("function", existing),
48
+ arguments: [],
49
+ outputs: [],
50
+ };
51
+ useEditorStore.getState().setFunctions((fns) => ({ ...fns, [id]: fn }));
52
+ // Create the body canvas (seeds an OnFunctionCall node) and watch it.
53
+ getOrCreateCanvasStore(id);
54
+ notifyCanvasRegistryChange();
55
+ return fn;
56
+ }
57
+ /** Delete a function: its declaration, its body canvas, and any selection of it. */
58
+ export function deleteFunction(id) {
59
+ useEditorStore.getState().setFunctions((fns) => {
60
+ const { [id]: _drop, ...rest } = fns;
61
+ return rest;
62
+ });
63
+ deleteCanvasStore(id);
64
+ const sel = useEditorStore.getState().selection;
65
+ if (sel.kind === "function" && sel.id === id) {
66
+ useEditorStore.getState().clearSelection();
67
+ }
68
+ }
69
+ /** Rename a function. Call-site migration detects this via the name comparison, so
70
+ * it needs no version bump. */
71
+ export function renameFunction(id, name) {
72
+ mutate(id, (fn) => ({ ...fn, name }), false);
73
+ }
74
+ // ── Input arguments (declarations) ─────────────────────────────────────────────
75
+ export function addArgument(id) {
76
+ mutate(id, (fn) => ({
77
+ ...fn,
78
+ arguments: [...fn.arguments, ensureUid({ name: `input${fn.arguments.length + 1}`, dataType: "string" })],
79
+ }), true);
80
+ }
81
+ export function updateArgument(id, index, patch) {
82
+ mutate(id, (fn) => {
83
+ const existing = fn.arguments[index];
84
+ if (!existing)
85
+ return fn;
86
+ const next = [...fn.arguments];
87
+ next[index] = { ...existing, ...patch };
88
+ return { ...fn, arguments: next };
89
+ }, true);
90
+ }
91
+ export function removeArgument(id, index) {
92
+ mutate(id, (fn) => ({ ...fn, arguments: fn.arguments.filter((_, i) => i !== index) }), true);
93
+ }
94
+ // ── Outputs (declaration + assignment bundled) ─────────────────────────────────
95
+ export function addOutput(id) {
96
+ mutate(id, (fn) => {
97
+ const dataType = "string";
98
+ return {
99
+ ...fn,
100
+ outputs: [...fn.outputs, { uid: generateId(), name: `output${fn.outputs.length + 1}`, dataType, expression: emptyExpression(dataType) }],
101
+ };
102
+ }, true);
103
+ }
104
+ /** Update an output's declaration (name/dataType). A dataType change retags the
105
+ * bundled expression's dataType but keeps the entered text. */
106
+ export function updateOutput(id, index, patch) {
107
+ mutate(id, (fn) => {
108
+ const existing = fn.outputs[index];
109
+ if (!existing)
110
+ return fn;
111
+ const dataType = patch.dataType ?? existing.dataType;
112
+ const next = [...fn.outputs];
113
+ next[index] = {
114
+ ...existing,
115
+ ...patch,
116
+ dataType,
117
+ expression: patch.dataType ? { ...existing.expression, dataType } : existing.expression,
118
+ };
119
+ return { ...fn, outputs: next };
120
+ }, true);
121
+ }
122
+ export function removeOutput(id, index) {
123
+ mutate(id, (fn) => ({ ...fn, outputs: fn.outputs.filter((_, i) => i !== index) }), true);
124
+ }
125
+ /** Set one output's return-value expression. Not a signature change → no version bump. */
126
+ export function setOutputExpression(id, index, expression) {
127
+ mutate(id, (fn) => {
128
+ const existing = fn.outputs[index];
129
+ if (!existing)
130
+ return fn;
131
+ const next = [...fn.outputs];
132
+ next[index] = { ...existing, expression };
133
+ return { ...fn, outputs: next };
134
+ }, false);
135
+ }
136
+ /** Read a function declaration without subscribing (for non-component callers). */
137
+ export function getFunction(id) {
138
+ return useEditorStore.getState().functions[id];
139
+ }
140
+ //# sourceMappingURL=functionOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functionOperations.js","sourceRoot":"","sources":["../../src/utils/functionOperations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { NodeDefinition, NodeData, NodeType } from "@foresthubai/workflow-core/node";
2
+ import type { FunctionInfo } from "@foresthubai/workflow-core/function";
3
+ import { Connection, Edge, Node } from "@xyflow/react";
4
+ import type { EdgeData, EdgeType } from "@foresthubai/workflow-core/edge";
5
+ import { CanvasStore } from "../stores/canvasStore";
6
+ /** Check if a node definition can be added to the store (respects isUnremovable and isSingleton). */
7
+ export declare function canAddNode(store: CanvasStore, nodeDef: NodeDefinition): boolean;
8
+ /** Add a node to the store given a node definition and optional position. Returns the new node ID, or null if the node cannot be added. */
9
+ export declare function addNodeToStore(store: CanvasStore, nodeDef: NodeDefinition, position?: {
10
+ x: number;
11
+ y: number;
12
+ }): string | null;
13
+ /**
14
+ * Update a node's data in the store. Returns true if the node was found and updated.
15
+ *
16
+ * FunctionCallNode is no longer a special case — its arguments are flat, so the same
17
+ * shallow-merge path handles input edits, output binding edits, and migrations uniformly.
18
+ * Migration callers simply pass the full replacement arguments record alongside
19
+ * `functionInfo`; normal edits pass the single changed key.
20
+ */
21
+ export declare function updateNodeInStore(store: CanvasStore, nodeId: string, updates: {
22
+ arguments?: Record<string, unknown>;
23
+ label?: string;
24
+ functionInfo?: FunctionInfo;
25
+ }): boolean;
26
+ /**
27
+ * Delete a node from the store, removing connected edges and variables.
28
+ * Takes optional getNodeDefinition callback for isUnremovable check.
29
+ * Returns true if the node was deleted.
30
+ */
31
+ export declare function deleteNodeFromStore(store: CanvasStore, nodeId: string, getNodeDefinition?: (node: NodeData) => NodeDefinition | undefined): boolean;
32
+ /** Add an edge if the connection is valid. Returns true if the edge was added. */
33
+ export declare function connectNodesInStore(store: CanvasStore, connection: Connection): EdgeType | false;
34
+ /** Update an edge's data in the store. Returns true if the edge was found and updated. */
35
+ export declare function updateEdgeInStore(store: CanvasStore, edgeId: string, updates: Record<string, unknown>): boolean;
36
+ /** Delete edges by ID from the store. */
37
+ export declare function deleteEdgesFromStore(store: CanvasStore, edgeIds: string[]): void;
38
+ export interface Clipboard {
39
+ nodes: Node<NodeData>[];
40
+ edges: Edge<EdgeData>[];
41
+ }
42
+ export interface PasteResult {
43
+ pasted: boolean;
44
+ /** Labels of nodes that were skipped because they cannot be added (singleton already present or unremovable). */
45
+ skippedLabels: string[];
46
+ }
47
+ /** Paste clipboard contents into the store with new IDs and optional position offset. */
48
+ export declare function pasteToStore(store: CanvasStore, clipboard: Clipboard, offset?: {
49
+ x: number;
50
+ y: number;
51
+ }, getNodeDefinition?: (node: NodeData) => NodeDefinition | undefined): PasteResult;
52
+ /** Determine React Flow node type based on NodeCategory */
53
+ export declare function getReactFlowType(type: NodeType): string;
54
+ //# sourceMappingURL=graphOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphOperations.d.ts","sourceRoot":"","sources":["../../src/utils/graphOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EACd,QAAQ,EAGR,QAAQ,EAMT,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAExE,OAAO,EAAW,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAoEpD,qGAAqG;AACrG,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAO/E;AAED,2IAA2I;AAC3I,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CA2E9H;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,GACA,OAAO,CAoFT;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,cAAc,GAAG,SAAS,GACjE,OAAO,CA4BT;AAoBD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,GAAG,QAAQ,GAAG,KAAK,CAahG;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO/G;AAED,yCAAyC;AACzC,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAIhF;AAMD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,iHAAiH;IACjH,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,yFAAyF;AACzF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,SAAS,EACpB,MAAM,GAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAqB,EACnD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,cAAc,GAAG,SAAS,GACjE,WAAW,CA+Fb;AAoDD,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAavD"}
@@ -0,0 +1,461 @@
1
+ import { NodeCategory, NodeRegistry, getArguments, getNodeOutput, } from "@foresthubai/workflow-core/node";
2
+ import { addEdge } from "@xyflow/react";
3
+ import { computeVariablesFromNodes } from "@foresthubai/workflow-core/workflow";
4
+ import { nodeOutputVarKey, paramKey } from "@foresthubai/workflow-core/variable";
5
+ import { isExpression } from "@foresthubai/workflow-core/expression";
6
+ import { isValidConnection } from "./connectionRules";
7
+ import { generateId } from "@foresthubai/workflow-core/id";
8
+ import { uniqueName } from "./resourceHelpers";
9
+ // ============================================================================
10
+ // Output Name Deduplication
11
+ // ============================================================================
12
+ /** Collect all output variable names currently in the store. */
13
+ function collectVariableNames(store) {
14
+ const vars = store.getState().variables;
15
+ return new Set(Object.values(vars).map((v) => v.name));
16
+ }
17
+ /**
18
+ * Walk a node instance and rename any emit bindings/declarations whose name collides
19
+ * with `existingNames`. Mutates in place. Handles all three locations:
20
+ * - Static outputs, incl. FunctionCall returns (direct field on arguments — OutputBinding)
21
+ * - List output entries (each entry IS an OutputDeclaration — mutate its `name` field directly
22
+ * when mode === "emit". Assign-mode entries have no name to rename, so they're skipped.)
23
+ * `existingNames` is updated with each rename so subsequent calls see the new names.
24
+ */
25
+ function deduplicateEmitNames(node, existingNames) {
26
+ const args = node.arguments;
27
+ const renameBindingAt = (key) => {
28
+ const binding = args[key];
29
+ // Only active emit bindings produce a variable that could collide.
30
+ if (!binding || !binding.active || binding.mode !== "emit" || !existingNames.has(binding.name))
31
+ return;
32
+ const deduped = uniqueName(binding.name, existingNames);
33
+ existingNames.add(deduped);
34
+ args[key] = { active: true, mode: "emit", name: deduped };
35
+ };
36
+ if (node.type === "FunctionCall") {
37
+ for (const ret of node.functionInfo.returns) {
38
+ renameBindingAt(paramKey(ret));
39
+ }
40
+ return;
41
+ }
42
+ const def = NodeRegistry.getByType(node.type);
43
+ if (!def?.outputs)
44
+ return;
45
+ for (const out of def.outputs) {
46
+ if (out.type === "static") {
47
+ renameBindingAt(out.id);
48
+ }
49
+ else {
50
+ const entries = args[out.id] ?? [];
51
+ for (const entry of entries) {
52
+ if (entry.mode !== "emit")
53
+ continue;
54
+ if (!existingNames.has(entry.name))
55
+ continue;
56
+ const deduped = uniqueName(entry.name, existingNames);
57
+ existingNames.add(deduped);
58
+ entry.name = deduped;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ // ============================================================================
64
+ // Pure Store Operations
65
+ // ============================================================================
66
+ /** Check if a node definition can be added to the store (respects isUnremovable and isSingleton). */
67
+ export function canAddNode(store, nodeDef) {
68
+ if (nodeDef.isUnremovable)
69
+ return false;
70
+ if (nodeDef.isSingleton) {
71
+ const { nodes } = store.getState();
72
+ if (nodes.some((n) => n.data.type === nodeDef.type))
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ /** Add a node to the store given a node definition and optional position. Returns the new node ID, or null if the node cannot be added. */
78
+ export function addNodeToStore(store, nodeDef, position) {
79
+ if (!canAddNode(store, nodeDef))
80
+ return null;
81
+ const nodeId = generateId();
82
+ // Initialize parameters with default values. Clone so object/array defaults
83
+ // (Expression, weekdays `[]`, memory-refs `[]`) aren't shared by reference
84
+ // across instances or with the definition itself — a shared mutable default
85
+ // would alias on edit.
86
+ const args = {};
87
+ nodeDef.parameters.forEach((param) => {
88
+ if (param.default !== undefined) {
89
+ args[param.id] = structuredClone(param.default);
90
+ }
91
+ });
92
+ // Seed outputs directly into args:
93
+ // - Static outputs: `args[out.id] = { active: true, mode: "emit", name: out.id }` (OutputBinding)
94
+ // - List outputs: `args[out.id] = []` (empty OutputDeclaration[] — user adds entries)
95
+ for (const out of nodeDef.outputs ?? []) {
96
+ if (out.type === "static") {
97
+ args[out.id] = { active: true, mode: "emit", name: out.id };
98
+ }
99
+ else {
100
+ args[out.id] = [];
101
+ }
102
+ }
103
+ const nodeData = {
104
+ id: nodeId,
105
+ type: nodeDef.type,
106
+ arguments: args,
107
+ };
108
+ if (nodeDef.type === "FunctionCall") {
109
+ const functionDef = nodeDef;
110
+ const functionNode = nodeData;
111
+ functionNode.functionInfo = functionDef.functionInfo;
112
+ // Seed input bindings keyed by arg uid — empty expressions with the declared dataType.
113
+ // Output bindings were already seeded above by the generic outputs[] loop since
114
+ // buildFunctionNodeDef now emits real StaticOutput entries.
115
+ for (const arg of functionDef.functionInfo.arguments) {
116
+ args[paramKey(arg)] = { expression: "", references: [], dataType: arg.dataType };
117
+ }
118
+ // Generic seeding uses the output id as the default emit name, but for function
119
+ // returns we want the return's variable name.
120
+ for (const ret of functionDef.functionInfo.returns) {
121
+ args[paramKey(ret)] = { active: true, mode: "emit", name: ret.name };
122
+ }
123
+ }
124
+ // Deduplicate emit binding names against existing variables on the canvas
125
+ const existingNames = collectVariableNames(store);
126
+ deduplicateEmitNames(nodeData, existingNames);
127
+ // Nudge position if another node is already nearby (avoids stacking on click-to-add)
128
+ const currentNodes = store.getState().nodes;
129
+ let pos = position || { x: 250, y: 100 };
130
+ const SNAP_DISTANCE = 50;
131
+ while (currentNodes.some((n) => Math.abs(n.position.x - pos.x) < SNAP_DISTANCE && Math.abs(n.position.y - pos.y) < SNAP_DISTANCE)) {
132
+ pos = { x: pos.x + 40, y: pos.y + 40 };
133
+ }
134
+ const newNode = {
135
+ id: nodeData.id,
136
+ type: getReactFlowType(nodeDef.type),
137
+ position: pos,
138
+ data: nodeData,
139
+ };
140
+ const { setNodes, setVariables } = store.getState();
141
+ setNodes((nds) => [...nds, newNode]);
142
+ // Add new node's output variables to store (computed via getNodeOutput)
143
+ setVariables((vars) => ({ ...vars, ...computeVariablesFromNodes([newNode.data]) }));
144
+ return nodeId;
145
+ }
146
+ /**
147
+ * Update a node's data in the store. Returns true if the node was found and updated.
148
+ *
149
+ * FunctionCallNode is no longer a special case — its arguments are flat, so the same
150
+ * shallow-merge path handles input edits, output binding edits, and migrations uniformly.
151
+ * Migration callers simply pass the full replacement arguments record alongside
152
+ * `functionInfo`; normal edits pass the single changed key.
153
+ */
154
+ export function updateNodeInStore(store, nodeId, updates) {
155
+ const { setNodes, setVariables } = store.getState();
156
+ // Track output changes to update variables store
157
+ let oldOutputs = {};
158
+ let newOutputs = {};
159
+ let outputsChanged = false;
160
+ let found = false;
161
+ setNodes((nds) => {
162
+ const targetNodeIndex = nds.findIndex((node) => node.id === nodeId);
163
+ if (targetNodeIndex === -1)
164
+ return nds;
165
+ const targetNode = nds[targetNodeIndex];
166
+ if (!targetNode)
167
+ return nds;
168
+ found = true;
169
+ const currentData = targetNode.data;
170
+ oldOutputs = getNodeOutput(currentData);
171
+ // When functionInfo changes (FunctionCall signature update), arguments are a
172
+ // full replacement so stale keys for removed args/returns get dropped;
173
+ // otherwise shallow-merge.
174
+ let updatedNodeData;
175
+ if (updates.arguments) {
176
+ const mergedArgs = updates.functionInfo
177
+ ? updates.arguments
178
+ : { ...currentData.arguments, ...updates.arguments };
179
+ updatedNodeData = {
180
+ ...currentData,
181
+ ...updates,
182
+ arguments: mergedArgs,
183
+ };
184
+ }
185
+ else {
186
+ updatedNodeData = { ...currentData, ...updates };
187
+ }
188
+ newOutputs = getNodeOutput(updatedNodeData);
189
+ // Build the updated nodes array
190
+ const updatedNodes = nds.map((node, index) => {
191
+ if (index === targetNodeIndex) {
192
+ return { ...node, data: updatedNodeData };
193
+ }
194
+ return node;
195
+ });
196
+ // Check if any output variable changed (keys added/removed or values changed)
197
+ const oldKeys = Object.keys(oldOutputs);
198
+ const newKeys = Object.keys(newOutputs);
199
+ outputsChanged =
200
+ oldKeys.length !== newKeys.length ||
201
+ newKeys.some((key) => {
202
+ const oldVar = oldOutputs[key];
203
+ const newVar = newOutputs[key];
204
+ return !oldVar || !newVar || oldVar.name !== newVar.name || oldVar.dataType !== newVar.dataType;
205
+ });
206
+ return updatedNodes;
207
+ });
208
+ // Update variables store if outputs changed
209
+ if (outputsChanged) {
210
+ setVariables((vars) => {
211
+ const updated = { ...vars };
212
+ // Remove old outputs that no longer exist in new outputs
213
+ for (const outputId of Object.keys(oldOutputs)) {
214
+ if (!(outputId in newOutputs)) {
215
+ delete updated[nodeOutputVarKey(nodeId, outputId)];
216
+ }
217
+ }
218
+ // Add/update new outputs (only if actually changed)
219
+ for (const [outputId, variable] of Object.entries(newOutputs)) {
220
+ const key = nodeOutputVarKey(nodeId, outputId);
221
+ const oldVar = vars[key];
222
+ if (!oldVar || oldVar.name !== variable.name || oldVar.dataType !== variable.dataType) {
223
+ updated[key] = { kind: "node", nodeId, outputId, name: variable.name, dataType: variable.dataType };
224
+ }
225
+ }
226
+ return updated;
227
+ });
228
+ }
229
+ return found;
230
+ }
231
+ /**
232
+ * Delete a node from the store, removing connected edges and variables.
233
+ * Takes optional getNodeDefinition callback for isUnremovable check.
234
+ * Returns true if the node was deleted.
235
+ */
236
+ export function deleteNodeFromStore(store, nodeId, getNodeDefinition) {
237
+ const { nodes, edges, setNodes, setEdges, setVariables } = store.getState();
238
+ // Check if node can be deleted
239
+ const nodeToDelete = nodes.find((node) => node.id === nodeId);
240
+ if (!nodeToDelete)
241
+ return false;
242
+ if (getNodeDefinition) {
243
+ const nodeDef = getNodeDefinition(nodeToDelete.data);
244
+ if (nodeDef?.isUnremovable ?? false)
245
+ return false;
246
+ }
247
+ setNodes((nds) => nds.filter((node) => node.id !== nodeId));
248
+ setEdges((eds) => eds.filter((edge) => edge.source !== nodeId && edge.target !== nodeId));
249
+ // Remove deleted node's emitted variables from store
250
+ const outputKeys = Object.keys(getNodeOutput(nodeToDelete.data));
251
+ if (outputKeys.length > 0) {
252
+ setVariables((vars) => {
253
+ const updated = { ...vars };
254
+ for (const outputId of outputKeys) {
255
+ delete updated[nodeOutputVarKey(nodeId, outputId)];
256
+ }
257
+ return updated;
258
+ });
259
+ }
260
+ return true;
261
+ }
262
+ /**
263
+ * Determine the specific edge type based on base port type and connected nodes.
264
+ * Agent nodes get specialized control-edge types (agentTask, agentChoice, agentDelegate).
265
+ * Tool edges have no agent-specific variant — every tool edge points at an agent.
266
+ */
267
+ function resolveEdgeType(basePortType, sourceNode, targetNode) {
268
+ const sourceIsAgent = sourceNode.data.type === "Agent";
269
+ const targetIsAgent = targetNode.data.type === "Agent";
270
+ if (basePortType === "control") {
271
+ if (sourceIsAgent && targetIsAgent)
272
+ return "agentDelegate";
273
+ if (targetIsAgent)
274
+ return "agentTask";
275
+ if (sourceIsAgent)
276
+ return "agentChoice";
277
+ return "control";
278
+ }
279
+ return basePortType;
280
+ }
281
+ /** Add an edge if the connection is valid. Returns true if the edge was added. */
282
+ export function connectNodesInStore(store, connection) {
283
+ const { nodes, edges, setEdges } = store.getState();
284
+ const portType = isValidConnection(connection.source, connection.target, connection.sourceHandle, connection.targetHandle, nodes, edges);
285
+ if (!portType)
286
+ return false;
287
+ const sourceNode = nodes.find((n) => n.id === connection.source);
288
+ const targetNode = nodes.find((n) => n.id === connection.target);
289
+ if (!sourceNode || !targetNode)
290
+ return false;
291
+ const edgeType = resolveEdgeType(portType, sourceNode, targetNode);
292
+ setEdges((eds) => addEdge({ ...connection, type: edgeType }, eds));
293
+ return edgeType;
294
+ }
295
+ /** Update an edge's data in the store. Returns true if the edge was found and updated. */
296
+ export function updateEdgeInStore(store, edgeId, updates) {
297
+ const { edges, setEdges } = store.getState();
298
+ const edge = edges.find((e) => e.id === edgeId);
299
+ if (!edge)
300
+ return false;
301
+ setEdges((eds) => eds.map((e) => (e.id === edgeId ? { ...e, data: { ...e.data, ...updates } } : e)));
302
+ return true;
303
+ }
304
+ /** Delete edges by ID from the store. */
305
+ export function deleteEdgesFromStore(store, edgeIds) {
306
+ const { setEdges } = store.getState();
307
+ const idSet = new Set(edgeIds);
308
+ setEdges((eds) => eds.filter((e) => !idSet.has(e.id)));
309
+ }
310
+ /** Paste clipboard contents into the store with new IDs and optional position offset. */
311
+ export function pasteToStore(store, clipboard, offset = { x: 50, y: 50 }, getNodeDefinition) {
312
+ const empty = { pasted: false, skippedLabels: [] };
313
+ if (clipboard.nodes.length === 0)
314
+ return empty;
315
+ const { setNodes, setEdges, setVariables } = store.getState();
316
+ // Filter out nodes that cannot be pasted (unremovable or singleton already on canvas)
317
+ const skippedLabels = [];
318
+ const pastableNodes = clipboard.nodes.filter((node) => {
319
+ if (!getNodeDefinition)
320
+ return true;
321
+ const def = getNodeDefinition(node.data);
322
+ if (!def)
323
+ return true;
324
+ if (!canAddNode(store, def)) {
325
+ skippedLabels.push(def.label);
326
+ return false;
327
+ }
328
+ return true;
329
+ });
330
+ if (pastableNodes.length === 0)
331
+ return { pasted: false, skippedLabels };
332
+ // Build old ID -> new ID mapping (only for pastable nodes)
333
+ const idMap = new Map();
334
+ pastableNodes.forEach((node) => {
335
+ const newId = generateId();
336
+ idMap.set(node.id, newId);
337
+ });
338
+ // Create new nodes with updated IDs and positions
339
+ const newNodes = pastableNodes.map((node) => {
340
+ const newId = idMap.get(node.id);
341
+ // Deep copy and update node data
342
+ const newData = JSON.parse(JSON.stringify(node.data));
343
+ newData.id = newId;
344
+ // Update expression references to point to new node IDs
345
+ newData.arguments = updateExpressionsInArgs(getArguments(newData), idMap);
346
+ return {
347
+ ...node,
348
+ id: newId,
349
+ position: {
350
+ x: node.position.x + offset.x,
351
+ y: node.position.y + offset.y,
352
+ },
353
+ data: newData,
354
+ selected: true,
355
+ };
356
+ });
357
+ // Dedupe emit binding names on pasted nodes against existing variables.
358
+ // (Pasted nodes come from JSON.parse(JSON.stringify(...)) of live nodes, so
359
+ // their bindings are already present in the correct arguments locations.)
360
+ const existingNames = collectVariableNames(store);
361
+ for (const node of newNodes) {
362
+ deduplicateEmitNames(node.data, existingNames);
363
+ }
364
+ // Create new edges with updated IDs (only for edges where both nodes are pasted)
365
+ const newEdges = clipboard.edges
366
+ .filter((edge) => idMap.has(edge.source) && idMap.has(edge.target))
367
+ .map((edge) => {
368
+ const newEdge = {
369
+ ...edge,
370
+ id: generateId(),
371
+ source: idMap.get(edge.source),
372
+ target: idMap.get(edge.target),
373
+ data: edge.data ? { ...edge.data } : edge.data,
374
+ };
375
+ // Remap prompt references on agentTask edges
376
+ if (newEdge.data?.prompt && isExpression(newEdge.data.prompt)) {
377
+ const prompt = newEdge.data.prompt;
378
+ newEdge.data = {
379
+ ...newEdge.data,
380
+ prompt: {
381
+ ...prompt,
382
+ references: prompt.references.map((ref) => ({
383
+ srcId: idMap.get(ref.srcId) ?? ref.srcId,
384
+ varId: ref.varId,
385
+ })),
386
+ },
387
+ };
388
+ }
389
+ return newEdge;
390
+ });
391
+ // Deselect existing nodes before adding new ones
392
+ setNodes((nds) => [...nds.map((n) => ({ ...n, selected: false })), ...newNodes]);
393
+ setEdges((eds) => [...eds, ...newEdges]);
394
+ // Add pasted nodes' variables to store
395
+ setVariables((vars) => ({ ...vars, ...computeVariablesFromNodes(newNodes.map((n) => n.data)) }));
396
+ return { pasted: true, skippedLabels };
397
+ }
398
+ // ============================================================================
399
+ // Expression Reference Updater (for paste)
400
+ // ============================================================================
401
+ /** Update expression references to point to new node IDs after paste */
402
+ function updateExpressionsInArgs(args, idMap) {
403
+ const updated = {};
404
+ for (const [key, value] of Object.entries(args)) {
405
+ if (isExpression(value)) {
406
+ // Update references with new node IDs
407
+ const updatedExpr = {
408
+ expression: value.expression,
409
+ dataType: value.dataType,
410
+ references: value.references.map((ref) => ({
411
+ srcId: idMap.get(ref.srcId) ?? ref.srcId,
412
+ varId: ref.varId,
413
+ })),
414
+ };
415
+ updated[key] = updatedExpr;
416
+ }
417
+ else if (Array.isArray(value)) {
418
+ // Handle arrays of expressions
419
+ updated[key] = value.map((item) => {
420
+ if (isExpression(item)) {
421
+ return {
422
+ expression: item.expression,
423
+ dataType: item.dataType,
424
+ references: item.references.map((ref) => ({
425
+ srcId: idMap.get(ref.srcId) ?? ref.srcId,
426
+ varId: ref.varId,
427
+ })),
428
+ };
429
+ }
430
+ return item;
431
+ });
432
+ }
433
+ else if (value !== null && typeof value === "object") {
434
+ // Handle nested objects
435
+ updated[key] = updateExpressionsInArgs(value, idMap);
436
+ }
437
+ else {
438
+ updated[key] = value;
439
+ }
440
+ }
441
+ return updated;
442
+ }
443
+ // ============================================================================
444
+ // ReactFlow Type Resolution
445
+ // ============================================================================
446
+ /** Determine React Flow node type based on NodeCategory */
447
+ export function getReactFlowType(type) {
448
+ if (type === "FunctionCall") {
449
+ return "FunctionCall";
450
+ }
451
+ const category = NodeRegistry.getByType(type)?.category ?? "Uncategorized";
452
+ switch (category) {
453
+ case NodeCategory.Trigger:
454
+ case NodeCategory.Tool:
455
+ case NodeCategory.AI:
456
+ return category;
457
+ default:
458
+ return "Standard";
459
+ }
460
+ }
461
+ //# sourceMappingURL=graphOperations.js.map