@flowdrop/flowdrop 1.4.0 → 1.6.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 (441) hide show
  1. package/README.md +94 -51
  2. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  3. package/dist/adapters/WorkflowAdapter.js +27 -47
  4. package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +2 -2
  5. package/dist/adapters/agentspec/AgentSpecAdapter.js +122 -133
  6. package/dist/adapters/agentspec/agentAdapter.d.ts +2 -2
  7. package/dist/adapters/agentspec/agentAdapter.js +10 -10
  8. package/dist/adapters/agentspec/autoLayout.d.ts +52 -6
  9. package/dist/adapters/agentspec/autoLayout.js +118 -23
  10. package/dist/adapters/agentspec/componentTypeDefaults.d.ts +1 -1
  11. package/dist/adapters/agentspec/componentTypeDefaults.js +120 -120
  12. package/dist/adapters/agentspec/defaultNodeTypes.d.ts +2 -2
  13. package/dist/adapters/agentspec/defaultNodeTypes.js +307 -307
  14. package/dist/adapters/agentspec/index.d.ts +10 -10
  15. package/dist/adapters/agentspec/index.js +6 -6
  16. package/dist/adapters/agentspec/validator.d.ts +2 -2
  17. package/dist/adapters/agentspec/validator.js +20 -22
  18. package/dist/api/enhanced-client.d.ts +3 -3
  19. package/dist/api/enhanced-client.js +72 -73
  20. package/dist/chat/commandClassifier.d.ts +19 -0
  21. package/dist/chat/commandClassifier.js +30 -0
  22. package/dist/chat/index.d.ts +27 -0
  23. package/dist/chat/index.js +32 -0
  24. package/dist/chat/responseParser.d.ts +21 -0
  25. package/dist/chat/responseParser.js +91 -0
  26. package/dist/commands/batch.d.ts +18 -0
  27. package/dist/commands/batch.js +54 -0
  28. package/dist/commands/executor.d.ts +37 -0
  29. package/dist/commands/executor.js +1133 -0
  30. package/dist/commands/index.d.ts +14 -0
  31. package/dist/commands/index.js +17 -0
  32. package/dist/commands/parser.d.ts +16 -0
  33. package/dist/commands/parser.js +295 -0
  34. package/dist/commands/positioner.d.ts +19 -0
  35. package/dist/commands/positioner.js +33 -0
  36. package/dist/commands/storeIntegration.svelte.d.ts +16 -0
  37. package/dist/commands/storeIntegration.svelte.js +67 -0
  38. package/dist/commands/types.d.ts +343 -0
  39. package/dist/commands/types.js +45 -0
  40. package/dist/components/App.svelte +522 -237
  41. package/dist/components/App.svelte.d.ts +11 -8
  42. package/dist/components/CanvasBanner.stories.svelte +10 -16
  43. package/dist/components/CanvasBanner.stories.svelte.d.ts +1 -1
  44. package/dist/components/CanvasBanner.svelte +2 -2
  45. package/dist/components/CanvasBanner.svelte.d.ts +1 -1
  46. package/dist/components/CanvasController.svelte +37 -0
  47. package/dist/components/CanvasController.svelte.d.ts +32 -0
  48. package/dist/components/ConfigForm.svelte +118 -256
  49. package/dist/components/ConfigForm.svelte.d.ts +2 -2
  50. package/dist/components/ConfigMappingRow.svelte +128 -0
  51. package/dist/components/ConfigMappingRow.svelte.d.ts +8 -0
  52. package/dist/components/ConfigModal.svelte +3 -3
  53. package/dist/components/ConfigModal.svelte.d.ts +1 -1
  54. package/dist/components/ConfigPanel.stories.svelte +19 -19
  55. package/dist/components/ConfigPanel.stories.svelte.d.ts +1 -1
  56. package/dist/components/ConfigPanel.svelte +57 -19
  57. package/dist/components/ConfigPanel.svelte.d.ts +3 -1
  58. package/dist/components/ConnectionLine.svelte +4 -4
  59. package/dist/components/EdgeRefresher.svelte +1 -1
  60. package/dist/components/FlowDropEdge.stories.svelte +110 -110
  61. package/dist/components/FlowDropEdge.svelte +11 -19
  62. package/dist/components/FlowDropEdge.svelte.d.ts +1 -1
  63. package/dist/components/FlowDropZone.svelte +6 -9
  64. package/dist/components/FlowDropZone.svelte.d.ts +1 -1
  65. package/dist/components/LoadingSpinner.stories.svelte +13 -13
  66. package/dist/components/LoadingSpinner.stories.svelte.d.ts +1 -1
  67. package/dist/components/LoadingSpinner.svelte +3 -3
  68. package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
  69. package/dist/components/Logo.stories.svelte +4 -4
  70. package/dist/components/Logo.stories.svelte.d.ts +1 -1
  71. package/dist/components/Logo.svelte +3 -9
  72. package/dist/components/LogsSidebar.svelte +46 -53
  73. package/dist/components/LogsSidebar.svelte.d.ts +1 -1
  74. package/dist/components/MarkdownDisplay.stories.svelte +10 -14
  75. package/dist/components/MarkdownDisplay.stories.svelte.d.ts +1 -1
  76. package/dist/components/MarkdownDisplay.svelte +4 -6
  77. package/dist/components/Navbar.stories.svelte +19 -19
  78. package/dist/components/Navbar.stories.svelte.d.ts +1 -1
  79. package/dist/components/Navbar.svelte +28 -49
  80. package/dist/components/Navbar.svelte.d.ts +2 -2
  81. package/dist/components/NodeSidebar.svelte +55 -135
  82. package/dist/components/NodeSidebar.svelte.d.ts +1 -1
  83. package/dist/components/NodeStatusOverlay.stories.svelte +19 -31
  84. package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +1 -1
  85. package/dist/components/NodeStatusOverlay.svelte +40 -55
  86. package/dist/components/NodeStatusOverlay.svelte.d.ts +3 -3
  87. package/dist/components/NodeSwapPicker.svelte +493 -0
  88. package/dist/components/NodeSwapPicker.svelte.d.ts +16 -0
  89. package/dist/components/PipelineStatus.svelte +63 -89
  90. package/dist/components/PipelineStatus.svelte.d.ts +4 -4
  91. package/dist/components/PortCoordinateTracker.svelte +5 -7
  92. package/dist/components/PortCoordinateTracker.svelte.d.ts +1 -1
  93. package/dist/components/PortMappingRow.svelte +205 -0
  94. package/dist/components/PortMappingRow.svelte.d.ts +12 -0
  95. package/dist/components/ReadOnlyDetails.svelte +1 -1
  96. package/dist/components/SchemaForm.stories.svelte +53 -53
  97. package/dist/components/SchemaForm.stories.svelte.d.ts +1 -1
  98. package/dist/components/SchemaForm.svelte +24 -51
  99. package/dist/components/SchemaForm.svelte.d.ts +2 -2
  100. package/dist/components/SettingsModal.svelte +6 -9
  101. package/dist/components/SettingsModal.svelte.d.ts +1 -1
  102. package/dist/components/SettingsPanel.svelte +138 -158
  103. package/dist/components/SettingsPanel.svelte.d.ts +1 -1
  104. package/dist/components/StatusIcon.stories.svelte +16 -29
  105. package/dist/components/StatusIcon.stories.svelte.d.ts +1 -1
  106. package/dist/components/StatusIcon.svelte +19 -19
  107. package/dist/components/StatusIcon.svelte.d.ts +2 -2
  108. package/dist/components/StatusLabel.stories.svelte +8 -8
  109. package/dist/components/StatusLabel.stories.svelte.d.ts +1 -1
  110. package/dist/components/SwapMappingEditor.svelte +529 -0
  111. package/dist/components/SwapMappingEditor.svelte.d.ts +12 -0
  112. package/dist/components/ThemeToggle.stories.svelte +10 -10
  113. package/dist/components/ThemeToggle.stories.svelte.d.ts +1 -1
  114. package/dist/components/ThemeToggle.svelte +22 -33
  115. package/dist/components/ThemeToggle.svelte.d.ts +1 -1
  116. package/dist/components/UniversalNode.svelte +29 -41
  117. package/dist/components/UniversalNode.svelte.d.ts +3 -3
  118. package/dist/components/WorkflowEditor.svelte +210 -170
  119. package/dist/components/WorkflowEditor.svelte.d.ts +12 -4
  120. package/dist/components/chat/AIChatPanel.svelte +797 -0
  121. package/dist/components/chat/AIChatPanel.svelte.d.ts +13 -0
  122. package/dist/components/chat/CommandPreview.svelte +234 -0
  123. package/dist/components/chat/CommandPreview.svelte.d.ts +9 -0
  124. package/dist/components/console/CommandConsole.stories.svelte +111 -0
  125. package/dist/components/console/CommandConsole.stories.svelte.d.ts +27 -0
  126. package/dist/components/console/CommandConsole.svelte +263 -0
  127. package/dist/components/console/CommandConsole.svelte.d.ts +11 -0
  128. package/dist/components/console/ConsoleAutocomplete.svelte +142 -0
  129. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +21 -0
  130. package/dist/components/console/ConsoleInput.svelte +771 -0
  131. package/dist/components/console/ConsoleInput.svelte.d.ts +16 -0
  132. package/dist/components/console/ConsoleOutput.svelte +116 -0
  133. package/dist/components/console/ConsoleOutput.svelte.d.ts +11 -0
  134. package/dist/components/console/formatters.d.ts +26 -0
  135. package/dist/components/console/formatters.js +116 -0
  136. package/dist/components/form/FormArray.svelte +75 -132
  137. package/dist/components/form/FormArray.svelte.d.ts +1 -1
  138. package/dist/components/form/FormAutocomplete.svelte +65 -108
  139. package/dist/components/form/FormAutocomplete.svelte.d.ts +1 -1
  140. package/dist/components/form/FormCheckboxGroup.stories.svelte +13 -16
  141. package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +1 -1
  142. package/dist/components/form/FormCheckboxGroup.svelte +2 -2
  143. package/dist/components/form/FormCodeEditor.svelte +42 -56
  144. package/dist/components/form/FormField.svelte +79 -90
  145. package/dist/components/form/FormField.svelte.d.ts +2 -2
  146. package/dist/components/form/FormFieldLight.svelte +72 -88
  147. package/dist/components/form/FormFieldLight.svelte.d.ts +1 -1
  148. package/dist/components/form/FormFieldWrapper.stories.svelte +14 -14
  149. package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +1 -1
  150. package/dist/components/form/FormFieldWrapper.svelte +2 -9
  151. package/dist/components/form/FormFieldWrapper.svelte.d.ts +1 -1
  152. package/dist/components/form/FormFieldset.svelte +3 -3
  153. package/dist/components/form/FormFieldset.svelte.d.ts +2 -2
  154. package/dist/components/form/FormMarkdownEditor.svelte +123 -156
  155. package/dist/components/form/FormNumberField.stories.svelte +18 -18
  156. package/dist/components/form/FormNumberField.stories.svelte.d.ts +1 -1
  157. package/dist/components/form/FormNumberField.svelte +6 -6
  158. package/dist/components/form/FormRangeField.stories.svelte +13 -13
  159. package/dist/components/form/FormRangeField.stories.svelte.d.ts +1 -1
  160. package/dist/components/form/FormRangeField.svelte +4 -12
  161. package/dist/components/form/FormSelect.stories.svelte +21 -21
  162. package/dist/components/form/FormSelect.stories.svelte.d.ts +1 -1
  163. package/dist/components/form/FormSelect.svelte +5 -5
  164. package/dist/components/form/FormSelect.svelte.d.ts +1 -1
  165. package/dist/components/form/FormTemplateEditor.svelte +126 -175
  166. package/dist/components/form/FormTemplateEditor.svelte.d.ts +1 -1
  167. package/dist/components/form/FormTextField.stories.svelte +17 -23
  168. package/dist/components/form/FormTextField.stories.svelte.d.ts +1 -1
  169. package/dist/components/form/FormTextField.svelte +4 -4
  170. package/dist/components/form/FormTextarea.stories.svelte +18 -21
  171. package/dist/components/form/FormTextarea.stories.svelte.d.ts +1 -1
  172. package/dist/components/form/FormTextarea.svelte +4 -4
  173. package/dist/components/form/FormToggle.stories.svelte +13 -16
  174. package/dist/components/form/FormToggle.stories.svelte.d.ts +1 -1
  175. package/dist/components/form/FormToggle.svelte +3 -3
  176. package/dist/components/form/FormUISchemaRenderer.svelte +12 -19
  177. package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +3 -3
  178. package/dist/components/form/index.d.ts +19 -19
  179. package/dist/components/form/index.js +18 -18
  180. package/dist/components/form/templateAutocomplete.d.ts +2 -2
  181. package/dist/components/form/templateAutocomplete.js +55 -64
  182. package/dist/components/form/types.d.ts +6 -6
  183. package/dist/components/form/types.js +4 -9
  184. package/dist/components/icons/AlertCircleIcon.svelte +1 -6
  185. package/dist/components/icons/CogIcon.svelte +1 -6
  186. package/dist/components/interrupt/ChoicePrompt.stories.svelte +27 -27
  187. package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +1 -1
  188. package/dist/components/interrupt/ChoicePrompt.svelte +17 -41
  189. package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +1 -1
  190. package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +17 -17
  191. package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +1 -1
  192. package/dist/components/interrupt/ConfirmationPrompt.svelte +10 -16
  193. package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +1 -1
  194. package/dist/components/interrupt/FormPrompt.svelte +10 -15
  195. package/dist/components/interrupt/FormPrompt.svelte.d.ts +1 -1
  196. package/dist/components/interrupt/InterruptBubble.svelte +87 -121
  197. package/dist/components/interrupt/InterruptBubble.svelte.d.ts +2 -2
  198. package/dist/components/interrupt/ReviewPrompt.stories.svelte +37 -37
  199. package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +1 -1
  200. package/dist/components/interrupt/ReviewPrompt.svelte +55 -75
  201. package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +1 -1
  202. package/dist/components/interrupt/TextInputPrompt.stories.svelte +16 -17
  203. package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +1 -1
  204. package/dist/components/interrupt/TextInputPrompt.svelte +13 -18
  205. package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +1 -1
  206. package/dist/components/interrupt/index.d.ts +6 -5
  207. package/dist/components/interrupt/index.js +6 -5
  208. package/dist/components/layouts/MainLayout.svelte +46 -84
  209. package/dist/components/layouts/MainLayout.svelte.d.ts +6 -6
  210. package/dist/components/nodes/GatewayNode.stories.svelte +64 -65
  211. package/dist/components/nodes/GatewayNode.svelte +37 -70
  212. package/dist/components/nodes/GatewayNode.svelte.d.ts +3 -3
  213. package/dist/components/nodes/IdeaNode.stories.svelte +25 -26
  214. package/dist/components/nodes/IdeaNode.svelte +22 -36
  215. package/dist/components/nodes/IdeaNode.svelte.d.ts +1 -1
  216. package/dist/components/nodes/NotesNode.stories.svelte +37 -38
  217. package/dist/components/nodes/NotesNode.svelte +28 -39
  218. package/dist/components/nodes/NotesNode.svelte.d.ts +1 -1
  219. package/dist/components/nodes/SimpleNode.stories.svelte +137 -138
  220. package/dist/components/nodes/SimpleNode.svelte +44 -74
  221. package/dist/components/nodes/SimpleNode.svelte.d.ts +1 -1
  222. package/dist/components/nodes/SquareNode.stories.svelte +75 -75
  223. package/dist/components/nodes/SquareNode.svelte +42 -68
  224. package/dist/components/nodes/SquareNode.svelte.d.ts +1 -1
  225. package/dist/components/nodes/TerminalNode.stories.svelte +10 -10
  226. package/dist/components/nodes/TerminalNode.svelte +74 -112
  227. package/dist/components/nodes/TerminalNode.svelte.d.ts +1 -1
  228. package/dist/components/nodes/ToolNode.stories.svelte +115 -116
  229. package/dist/components/nodes/ToolNode.svelte +31 -64
  230. package/dist/components/nodes/ToolNode.svelte.d.ts +1 -1
  231. package/dist/components/nodes/WorkflowNode.stories.svelte +84 -89
  232. package/dist/components/nodes/WorkflowNode.svelte +50 -103
  233. package/dist/components/nodes/WorkflowNode.svelte.d.ts +3 -3
  234. package/dist/components/playground/ChatPanel.svelte +47 -103
  235. package/dist/components/playground/ExecutionLogs.svelte +45 -68
  236. package/dist/components/playground/InputCollector.svelte +32 -51
  237. package/dist/components/playground/MessageBubble.stories.svelte +25 -25
  238. package/dist/components/playground/MessageBubble.stories.svelte.d.ts +1 -1
  239. package/dist/components/playground/MessageBubble.svelte +54 -70
  240. package/dist/components/playground/MessageBubble.svelte.d.ts +1 -1
  241. package/dist/components/playground/Playground.svelte +60 -91
  242. package/dist/components/playground/Playground.svelte.d.ts +3 -3
  243. package/dist/components/playground/PlaygroundModal.svelte +8 -12
  244. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -3
  245. package/dist/components/playground/SessionManager.svelte +34 -40
  246. package/dist/components/playground/SessionManager.svelte.d.ts +1 -1
  247. package/dist/config/agentSpecEndpoints.d.ts +1 -1
  248. package/dist/config/agentSpecEndpoints.js +20 -20
  249. package/dist/config/constants.js +2 -2
  250. package/dist/config/defaultCategories.d.ts +1 -1
  251. package/dist/config/defaultCategories.js +86 -86
  252. package/dist/config/defaultPortConfig.d.ts +1 -1
  253. package/dist/config/defaultPortConfig.js +144 -144
  254. package/dist/config/endpoints.d.ts +12 -4
  255. package/dist/config/endpoints.js +70 -65
  256. package/dist/config/runtimeConfig.d.ts +2 -2
  257. package/dist/config/runtimeConfig.js +8 -8
  258. package/dist/core/index.d.ts +68 -63
  259. package/dist/core/index.js +44 -35
  260. package/dist/display/index.d.ts +2 -2
  261. package/dist/display/index.js +2 -2
  262. package/dist/editor/index.d.ts +64 -62
  263. package/dist/editor/index.js +57 -55
  264. package/dist/form/code.d.ts +5 -5
  265. package/dist/form/code.js +14 -14
  266. package/dist/form/fieldRegistry.d.ts +3 -3
  267. package/dist/form/fieldRegistry.js +9 -11
  268. package/dist/form/full.d.ts +8 -8
  269. package/dist/form/full.js +9 -9
  270. package/dist/form/index.d.ts +18 -18
  271. package/dist/form/index.js +16 -16
  272. package/dist/form/markdown.d.ts +4 -4
  273. package/dist/form/markdown.js +8 -8
  274. package/dist/helpers/proximityConnect.d.ts +3 -3
  275. package/dist/helpers/proximityConnect.js +40 -35
  276. package/dist/helpers/workflowEditorHelper.d.ts +8 -58
  277. package/dist/helpers/workflowEditorHelper.js +73 -292
  278. package/dist/index.d.ts +6 -6
  279. package/dist/index.js +6 -6
  280. package/dist/mocks/app-environment.js +2 -2
  281. package/dist/mocks/app-forms.js +1 -1
  282. package/dist/mocks/app-navigation.js +2 -2
  283. package/dist/mocks/app-stores.js +3 -3
  284. package/dist/playground/index.d.ts +19 -19
  285. package/dist/playground/index.js +16 -16
  286. package/dist/playground/mount.d.ts +3 -3
  287. package/dist/playground/mount.js +24 -24
  288. package/dist/registry/builtinFormats.js +13 -13
  289. package/dist/registry/builtinNodes.d.ts +2 -2
  290. package/dist/registry/builtinNodes.js +77 -77
  291. package/dist/registry/index.d.ts +4 -4
  292. package/dist/registry/index.js +4 -4
  293. package/dist/registry/nodeComponentRegistry.d.ts +8 -8
  294. package/dist/registry/nodeComponentRegistry.js +9 -11
  295. package/dist/registry/plugin.d.ts +2 -2
  296. package/dist/registry/plugin.js +11 -11
  297. package/dist/registry/workflowFormatRegistry.d.ts +3 -3
  298. package/dist/registry/workflowFormatRegistry.js +2 -2
  299. package/dist/schema/index.d.ts +1 -1
  300. package/dist/schema/index.js +2 -2
  301. package/dist/schemas/v1/workflow.schema.json +107 -22
  302. package/dist/services/agentSpecExecutionService.d.ts +3 -3
  303. package/dist/services/agentSpecExecutionService.js +55 -56
  304. package/dist/services/api.d.ts +2 -2
  305. package/dist/services/api.js +37 -37
  306. package/dist/services/apiVariableService.d.ts +1 -1
  307. package/dist/services/apiVariableService.js +34 -41
  308. package/dist/services/autoSaveService.js +8 -8
  309. package/dist/services/categoriesApi.d.ts +2 -2
  310. package/dist/services/categoriesApi.js +8 -8
  311. package/dist/services/chatService.d.ts +65 -0
  312. package/dist/services/chatService.js +131 -0
  313. package/dist/services/draftStorage.d.ts +1 -1
  314. package/dist/services/draftStorage.js +11 -11
  315. package/dist/services/dynamicSchemaService.d.ts +1 -1
  316. package/dist/services/dynamicSchemaService.js +39 -41
  317. package/dist/services/globalSave.d.ts +2 -2
  318. package/dist/services/globalSave.js +38 -41
  319. package/dist/services/historyService.d.ts +7 -5
  320. package/dist/services/historyService.js +29 -14
  321. package/dist/services/interruptService.d.ts +1 -1
  322. package/dist/services/interruptService.js +29 -35
  323. package/dist/services/nodeExecutionService.d.ts +1 -1
  324. package/dist/services/nodeExecutionService.js +44 -45
  325. package/dist/services/playgroundService.d.ts +1 -1
  326. package/dist/services/playgroundService.js +29 -29
  327. package/dist/services/portConfigApi.d.ts +2 -2
  328. package/dist/services/portConfigApi.js +8 -8
  329. package/dist/services/settingsService.d.ts +2 -2
  330. package/dist/services/settingsService.js +19 -25
  331. package/dist/services/toastService.d.ts +4 -4
  332. package/dist/services/toastService.js +33 -33
  333. package/dist/services/variableService.d.ts +1 -1
  334. package/dist/services/variableService.js +36 -36
  335. package/dist/services/workflowStorage.d.ts +2 -2
  336. package/dist/services/workflowStorage.js +13 -13
  337. package/dist/settings/index.d.ts +7 -7
  338. package/dist/settings/index.js +6 -6
  339. package/dist/skins/default.d.ts +1 -1
  340. package/dist/skins/default.js +1 -1
  341. package/dist/skins/index.d.ts +3 -3
  342. package/dist/skins/index.js +7 -7
  343. package/dist/skins/slate.d.ts +1 -1
  344. package/dist/skins/slate.js +69 -69
  345. package/dist/stores/categoriesStore.svelte.d.ts +1 -1
  346. package/dist/stores/categoriesStore.svelte.js +5 -5
  347. package/dist/stores/editorStateMachine.svelte.d.ts +2 -2
  348. package/dist/stores/editorStateMachine.svelte.js +34 -34
  349. package/dist/stores/historyStore.svelte.d.ts +4 -4
  350. package/dist/stores/historyStore.svelte.js +4 -4
  351. package/dist/stores/interruptStore.svelte.d.ts +3 -3
  352. package/dist/stores/interruptStore.svelte.js +27 -22
  353. package/dist/stores/playgroundStore.svelte.d.ts +3 -3
  354. package/dist/stores/playgroundStore.svelte.js +29 -23
  355. package/dist/stores/portCoordinateStore.svelte.d.ts +6 -2
  356. package/dist/stores/portCoordinateStore.svelte.js +30 -39
  357. package/dist/stores/settingsStore.svelte.d.ts +2 -2
  358. package/dist/stores/settingsStore.svelte.js +57 -62
  359. package/dist/stores/workflowStore.svelte.d.ts +34 -5
  360. package/dist/stores/workflowStore.svelte.js +127 -108
  361. package/dist/stories/CanvasDecorator.svelte +7 -10
  362. package/dist/stories/CanvasDecorator.svelte.d.ts +2 -2
  363. package/dist/stories/EdgeDecorator.svelte +28 -31
  364. package/dist/stories/EdgeDecorator.svelte.d.ts +1 -1
  365. package/dist/stories/NodeDecorator.svelte +14 -20
  366. package/dist/stories/NodeDecorator.svelte.d.ts +1 -1
  367. package/dist/stories/utils.d.ts +2 -2
  368. package/dist/stories/utils.js +89 -93
  369. package/dist/styles/base.css +16 -50
  370. package/dist/styles/tokens.css +10 -28
  371. package/dist/svelte-app.d.ts +10 -10
  372. package/dist/svelte-app.js +39 -39
  373. package/dist/themes/default.d.ts +1 -1
  374. package/dist/themes/default.js +4 -4
  375. package/dist/themes/index.d.ts +3 -3
  376. package/dist/themes/index.js +11 -11
  377. package/dist/themes/minimal.d.ts +1 -1
  378. package/dist/themes/minimal.js +5 -5
  379. package/dist/types/agentspec.d.ts +18 -18
  380. package/dist/types/agentspec.js +2 -2
  381. package/dist/types/auth.d.ts +1 -1
  382. package/dist/types/auth.js +6 -6
  383. package/dist/types/chat.d.ts +63 -0
  384. package/dist/types/chat.js +9 -0
  385. package/dist/types/config.d.ts +6 -6
  386. package/dist/types/events.d.ts +28 -2
  387. package/dist/types/events.js +2 -1
  388. package/dist/types/index.d.ts +40 -32
  389. package/dist/types/index.js +6 -6
  390. package/dist/types/interrupt.d.ts +6 -6
  391. package/dist/types/interrupt.js +21 -21
  392. package/dist/types/interruptState.d.ts +12 -12
  393. package/dist/types/interruptState.js +66 -66
  394. package/dist/types/playground.d.ts +7 -7
  395. package/dist/types/playground.js +14 -14
  396. package/dist/types/settings.d.ts +12 -4
  397. package/dist/types/settings.js +21 -23
  398. package/dist/types/skin.d.ts +1 -1
  399. package/dist/types/theme.d.ts +2 -2
  400. package/dist/types/uischema.d.ts +4 -4
  401. package/dist/types/uischema.js +3 -3
  402. package/dist/utils/colors.d.ts +1 -1
  403. package/dist/utils/colors.js +95 -97
  404. package/dist/utils/config.d.ts +2 -2
  405. package/dist/utils/config.js +48 -48
  406. package/dist/utils/connections.d.ts +2 -2
  407. package/dist/utils/connections.js +15 -15
  408. package/dist/utils/edgeStyling.d.ts +42 -0
  409. package/dist/utils/edgeStyling.js +173 -0
  410. package/dist/utils/errors.js +3 -3
  411. package/dist/utils/fetchWithAuth.d.ts +1 -1
  412. package/dist/utils/fetchWithAuth.js +2 -2
  413. package/dist/utils/handleIds.d.ts +2 -2
  414. package/dist/utils/handleIds.js +8 -8
  415. package/dist/utils/handlePositioning.d.ts +1 -1
  416. package/dist/utils/handlePositioning.js +2 -2
  417. package/dist/utils/icons.d.ts +1 -1
  418. package/dist/utils/icons.js +74 -74
  419. package/dist/utils/logger.d.ts +1 -1
  420. package/dist/utils/logger.js +7 -7
  421. package/dist/utils/nodeIds.d.ts +31 -0
  422. package/dist/utils/nodeIds.js +42 -0
  423. package/dist/utils/nodeStatus.d.ts +1 -1
  424. package/dist/utils/nodeStatus.js +48 -48
  425. package/dist/utils/nodeSwap.d.ts +221 -0
  426. package/dist/utils/nodeSwap.js +680 -0
  427. package/dist/utils/nodeTypes.d.ts +1 -1
  428. package/dist/utils/nodeTypes.js +20 -21
  429. package/dist/utils/nodeWrapper.d.ts +7 -7
  430. package/dist/utils/nodeWrapper.js +19 -21
  431. package/dist/utils/performanceUtils.d.ts +1 -1
  432. package/dist/utils/performanceUtils.js +1 -2
  433. package/dist/utils/portUtils.d.ts +2 -2
  434. package/dist/utils/portUtils.js +1 -1
  435. package/dist/utils/sanitize.js +1 -1
  436. package/dist/utils/uischema.d.ts +2 -2
  437. package/dist/utils/uischema.js +8 -8
  438. package/dist/utils/validation.js +8 -8
  439. package/package.json +12 -11
  440. package/dist/helpers/nodeLayoutHelper.d.ts +0 -14
  441. package/dist/helpers/nodeLayoutHelper.js +0 -19
@@ -13,58 +13,54 @@
13
13
  BackgroundVariant,
14
14
  MiniMap,
15
15
  SvelteFlowProvider,
16
- type ColorMode,
17
- } from "@xyflow/svelte";
18
- import "@xyflow/svelte/dist/style.css";
16
+ type ColorMode
17
+ } from '@xyflow/svelte';
18
+ import '@xyflow/svelte/dist/style.css';
19
19
  import {
20
20
  getResolvedTheme,
21
21
  getEditorSettings,
22
- getBehaviorSettings,
23
- } from "../stores/settingsStore.svelte.js";
22
+ getBehaviorSettings
23
+ } from '../stores/settingsStore.svelte.js';
24
24
  import type {
25
25
  WorkflowNode as WorkflowNodeType,
26
26
  NodeMetadata,
27
27
  Workflow,
28
- WorkflowEdge,
29
- } from "../types/index.js";
30
- import CanvasBanner from "./CanvasBanner.svelte";
31
- import FlowDropZone from "./FlowDropZone.svelte";
32
- import EdgeRefresher from "./EdgeRefresher.svelte";
33
- import { tick, untrack } from "svelte";
34
- import type { EndpointConfig } from "../config/endpoints.js";
35
- import ConnectionLine from "./ConnectionLine.svelte";
36
- import FlowDropEdge from "./FlowDropEdge.svelte";
37
- import {
38
- getWorkflowStore,
39
- workflowActions,
40
- } from "../stores/workflowStore.svelte.js";
41
- import {
42
- historyActions,
43
- setOnRestoreCallback,
44
- } from "../stores/historyStore.svelte.js";
45
- import UniversalNode from "./UniversalNode.svelte";
28
+ WorkflowEdge
29
+ } from '../types/index.js';
30
+ import CanvasBanner from './CanvasBanner.svelte';
31
+ import CanvasController from './CanvasController.svelte';
32
+ import FlowDropZone from './FlowDropZone.svelte';
33
+ import EdgeRefresher from './EdgeRefresher.svelte';
34
+ import { tick, untrack } from 'svelte';
35
+ import type { EndpointConfig } from '../config/endpoints.js';
36
+ import ConnectionLine from './ConnectionLine.svelte';
37
+ import FlowDropEdge from './FlowDropEdge.svelte';
38
+ import { getWorkflowStore, workflowActions } from '../stores/workflowStore.svelte.js';
39
+ import { historyActions, setOnRestoreCallback } from '../stores/historyStore.svelte.js';
40
+ import UniversalNode from './UniversalNode.svelte';
46
41
  import {
47
42
  EdgeStylingHelper,
48
43
  NodeOperationsHelper,
49
44
  WorkflowOperationsHelper,
50
- ConfigurationHelper,
51
- } from "../helpers/workflowEditorHelper.js";
52
- import type { NodeExecutionInfo } from "../types/index.js";
53
- import { Toaster } from "svelte-5-french-toast";
45
+ ConfigurationHelper
46
+ } from '../helpers/workflowEditorHelper.js';
47
+ import type { NodeExecutionInfo } from '../types/index.js';
48
+ import { Toaster } from 'svelte-5-french-toast';
54
49
  import {
55
50
  flowdropToastOptions,
56
51
  FLOWDROP_TOASTER_CLASS,
57
- apiToasts,
58
- } from "../services/toastService.js";
52
+ apiToasts
53
+ } from '../services/toastService.js';
59
54
  import {
60
55
  ProximityConnectHelper,
61
- type ProximityEdgeCandidate,
62
- } from "../helpers/proximityConnect.js";
63
- import PortCoordinateTracker from "./PortCoordinateTracker.svelte";
64
- import { getPortCoordinateSnapshot } from "../stores/portCoordinateStore.svelte.js";
65
- import { logger } from "../utils/logger.js";
66
- import { validateWorkflowData } from "../utils/validation.js";
67
- import { createEditorStateMachine } from "../stores/editorStateMachine.svelte.js";
56
+ type ProximityEdgeCandidate
57
+ } from '../helpers/proximityConnect.js';
58
+ import PortCoordinateTracker from './PortCoordinateTracker.svelte';
59
+ import { getPortCoordinateSnapshot } from '../stores/portCoordinateStore.svelte.js';
60
+ import { logger } from '../utils/logger.js';
61
+ import { validateWorkflowData } from '../utils/validation.js';
62
+ import { createEditorStateMachine } from '../stores/editorStateMachine.svelte.js';
63
+ import Icon from '@iconify/svelte';
68
64
 
69
65
  interface Props {
70
66
  nodes?: NodeMetadata[];
@@ -78,12 +74,12 @@
78
74
  // New configuration options for pipeline status mode
79
75
  lockWorkflow?: boolean;
80
76
  readOnly?: boolean;
81
- nodeStatuses?: Record<
82
- string,
83
- "pending" | "running" | "completed" | "error"
84
- >;
77
+ nodeStatuses?: Record<string, 'pending' | 'running' | 'completed' | 'error'>;
85
78
  // Pipeline ID for fetching node execution info from jobs
86
79
  pipelineId?: string;
80
+ // Console toggle
81
+ consoleOpen?: boolean;
82
+ onToggleConsole?: () => void;
87
83
  }
88
84
 
89
85
  let props: Props = $props();
@@ -125,18 +121,15 @@
125
121
  * Key for SvelteFlow component — changes when workflow ID changes.
126
122
  * Forces SvelteFlow to remount with fresh state, allowing fitView to work correctly.
127
123
  */
128
- let svelteFlowKey = $derived(getWorkflowStore()?.id ?? "default");
124
+ let svelteFlowKey = $derived(getWorkflowStore()?.id ?? 'default');
129
125
 
130
126
  /**
131
127
  * Derive snap grid configuration from editor settings
132
128
  */
133
129
  let snapGrid = $derived(
134
130
  getEditorSettings().snapToGrid
135
- ? ([getEditorSettings().gridSize, getEditorSettings().gridSize] as [
136
- number,
137
- number,
138
- ])
139
- : undefined,
131
+ ? ([getEditorSettings().gridSize, getEditorSettings().gridSize] as [number, number])
132
+ : undefined
140
133
  );
141
134
 
142
135
  /**
@@ -145,7 +138,7 @@
145
138
  let initialViewport = $derived({
146
139
  zoom: getEditorSettings().defaultZoom,
147
140
  x: 0,
148
- y: 0,
141
+ y: 0
149
142
  });
150
143
 
151
144
  // ---------------------------------------------------------------------------
@@ -159,13 +152,10 @@
159
152
  ...node,
160
153
  data: {
161
154
  ...node.data,
162
- onConfigOpen: props.openConfigSidebar,
163
- },
155
+ onConfigOpen: props.openConfigSidebar
156
+ }
164
157
  }));
165
- const styledEdges = EdgeStylingHelper.updateEdgeStyles(
166
- workflow.edges,
167
- nodesWithCallbacks,
168
- );
158
+ const styledEdges = EdgeStylingHelper.updateEdgeStyles(workflow.edges, nodesWithCallbacks);
169
159
  return { nodes: nodesWithCallbacks, edges: styledEdges };
170
160
  }
171
161
 
@@ -178,7 +168,7 @@
178
168
  const updatedWorkflow = WorkflowOperationsHelper.updateWorkflow(
179
169
  storeValue,
180
170
  flowNodes,
181
- flowEdges,
171
+ flowEdges
182
172
  );
183
173
  workflowActions.updateWorkflow(updatedWorkflow);
184
174
  }
@@ -201,7 +191,7 @@
201
191
  flowNodes = [];
202
192
  flowEdges = [];
203
193
  previousSyncedWorkflowId = null;
204
- untrack(() => machine.send("WORKFLOW_CLEARED"));
194
+ untrack(() => machine.send('WORKFLOW_CLEARED'));
205
195
  }
206
196
  return;
207
197
  }
@@ -210,9 +200,7 @@
210
200
 
211
201
  if (isNewWorkflow) {
212
202
  untrack(() =>
213
- machine.send(
214
- previousSyncedWorkflowId ? "WORKFLOW_SWITCHED" : "WORKFLOW_LOADED",
215
- ),
203
+ machine.send(previousSyncedWorkflowId ? 'WORKFLOW_SWITCHED' : 'WORKFLOW_LOADED')
216
204
  );
217
205
  }
218
206
 
@@ -228,7 +216,7 @@
228
216
  }
229
217
 
230
218
  if (isNewWorkflow) {
231
- untrack(() => machine.send("LOAD_COMPLETE"));
219
+ untrack(() => machine.send('LOAD_COMPLETE'));
232
220
  }
233
221
  });
234
222
 
@@ -263,12 +251,12 @@
263
251
  }
264
252
 
265
253
  // Schedule loading with requestIdleCallback (falls back to setTimeout)
266
- if (typeof requestIdleCallback !== "undefined") {
254
+ if (typeof requestIdleCallback !== 'undefined') {
267
255
  loadExecutionInfoTimeout = requestIdleCallback(
268
256
  () => {
269
257
  loadNodeExecutionInfo();
270
258
  },
271
- { timeout: 500 },
259
+ { timeout: 500 }
272
260
  ) as unknown as number;
273
261
  } else {
274
262
  loadExecutionInfoTimeout = setTimeout(() => {
@@ -282,14 +270,14 @@
282
270
  // ---------------------------------------------------------------------------
283
271
  $effect(() => {
284
272
  setOnRestoreCallback((restoredWorkflow: Workflow) => {
285
- machine.send("START_RESTORE");
273
+ machine.send('START_RESTORE');
286
274
  // Update the store (effect is suppressed during 'restoring')
287
275
  workflowActions.restoreFromHistory(restoredWorkflow);
288
276
  // Derive flowNodes/flowEdges directly for immediate visual update
289
277
  const derived = buildFlowNodesFromStore(restoredWorkflow);
290
278
  flowNodes = derived.nodes;
291
279
  flowEdges = derived.edges;
292
- machine.send("RESTORE_COMPLETE");
280
+ machine.send('RESTORE_COMPLETE');
293
281
  // After RESTORE_COMPLETE → idle, the sync effect runs but produces
294
282
  // the same data (no-op re-derive).
295
283
  });
@@ -311,15 +299,15 @@
311
299
 
312
300
  const executionInfo = await NodeOperationsHelper.loadNodeExecutionInfo(
313
301
  workflow,
314
- props.pipelineId,
302
+ props.pipelineId
315
303
  );
316
304
 
317
305
  if (executionInfoAbortController?.signal.aborted) return;
318
306
 
319
307
  const defaultExecutionInfo: NodeExecutionInfo = {
320
- status: "idle" as const,
308
+ status: 'idle' as const,
321
309
  executionCount: 0,
322
- isExecuting: false,
310
+ isExecuting: false
323
311
  };
324
312
 
325
313
  // Update flowNodes with execution info (visual-only, no store sync needed)
@@ -327,14 +315,14 @@
327
315
  ...node,
328
316
  data: {
329
317
  ...node.data,
330
- executionInfo: executionInfo[node.id] || defaultExecutionInfo,
331
- },
318
+ executionInfo: executionInfo[node.id] || defaultExecutionInfo
319
+ }
332
320
  }));
333
321
 
334
322
  executionInfoAbortController = null;
335
323
  } catch (error) {
336
- if (error instanceof Error && error.name !== "AbortError") {
337
- logger.error("Failed to load node execution info:", error);
324
+ if (error instanceof Error && error.name !== 'AbortError') {
325
+ logger.error('Failed to load node execution info:', error);
338
326
  }
339
327
  }
340
328
  }
@@ -346,12 +334,12 @@
346
334
  // Node types for Svelte Flow - using UniversalNode for all node types
347
335
  // All nodes use 'universalNode' type, and UniversalNode handles internal switching
348
336
  const nodeTypes = {
349
- universalNode: UniversalNode,
337
+ universalNode: UniversalNode
350
338
  };
351
339
 
352
340
  // Use custom edge that shortens the path so the stroke ends at the arrow base
353
341
  const edgeTypes = {
354
- default: FlowDropEdge,
342
+ default: FlowDropEdge
355
343
  };
356
344
 
357
345
  // Handle arrows in our custom connection handler
@@ -365,7 +353,7 @@
365
353
  * position updates. SvelteFlow mutates flowNodes directly via bind:nodes.
366
354
  */
367
355
  function handleNodeDragStart(): void {
368
- machine.send("START_DRAG");
356
+ machine.send('START_DRAG');
369
357
  // Clear any leftover proximity previews
370
358
  currentProximityCandidates = [];
371
359
  }
@@ -376,7 +364,7 @@
376
364
  * Uses port-to-port distance via the port coordinate store.
377
365
  */
378
366
  function handleNodeDrag({
379
- targetNode,
367
+ targetNode
380
368
  }: {
381
369
  targetNode: WorkflowNodeType | null;
382
370
  nodes: WorkflowNodeType[];
@@ -410,13 +398,13 @@
410
398
  targetNode.id,
411
399
  portCoordinates,
412
400
  baseEdges,
413
- getEditorSettings().proximityConnectDistance,
401
+ getEditorSettings().proximityConnectDistance
414
402
  )
415
403
  : ProximityConnectHelper.findCompatibleEdges(
416
404
  targetNode,
417
405
  flowNodes,
418
406
  baseEdges,
419
- getEditorSettings().proximityConnectDistance,
407
+ getEditorSettings().proximityConnectDistance
420
408
  );
421
409
 
422
410
  // Create preview edges
@@ -437,24 +425,17 @@
437
425
  portCoordNodeToUpdate = null;
438
426
 
439
427
  // Finalize proximity connect if there are candidates
440
- if (
441
- getEditorSettings().proximityConnect &&
442
- currentProximityCandidates.length > 0
443
- ) {
428
+ if (getEditorSettings().proximityConnect && currentProximityCandidates.length > 0) {
444
429
  const baseEdges = ProximityConnectHelper.removePreviewEdges(flowEdges);
445
430
  const permanentEdges = ProximityConnectHelper.createPermanentEdges(
446
- currentProximityCandidates,
431
+ currentProximityCandidates
447
432
  );
448
433
 
449
434
  for (const edge of permanentEdges) {
450
435
  const sourceNode = flowNodes.find((n) => n.id === edge.source);
451
436
  const targetNode = flowNodes.find((n) => n.id === edge.target);
452
437
  if (sourceNode && targetNode) {
453
- EdgeStylingHelper.applyConnectionStyling(
454
- edge,
455
- sourceNode,
456
- targetNode,
457
- );
438
+ EdgeStylingHelper.applyConnectionStyling(edge, sourceNode, targetNode);
458
439
  }
459
440
  }
460
441
 
@@ -468,11 +449,11 @@
468
449
  // Push history AFTER the drag completed
469
450
  const storeValue = getWorkflowStore();
470
451
  if (storeValue) {
471
- workflowActions.pushHistory("Move node", storeValue);
452
+ workflowActions.pushHistory('Move node', storeValue);
472
453
  }
473
454
 
474
455
  // Transition to idle — sync effect is now unblocked
475
- machine.send("STOP_DRAG");
456
+ machine.send('STOP_DRAG');
476
457
  }
477
458
 
478
459
  /**
@@ -484,7 +465,7 @@
484
465
  sourceHandle?: string;
485
466
  targetHandle?: string;
486
467
  }): Promise<void> {
487
- machine.send("START_CONNECT");
468
+ machine.send('START_CONNECT');
488
469
 
489
470
  // SvelteFlow auto-creates the edge via bind:edges — wait for DOM update
490
471
  await tick();
@@ -497,10 +478,10 @@
497
478
 
498
479
  const storeValue = getWorkflowStore();
499
480
  if (storeValue) {
500
- workflowActions.pushHistory("Add connection", storeValue);
481
+ workflowActions.pushHistory('Add connection', storeValue);
501
482
  }
502
483
 
503
- machine.send("CONNECTION_MADE");
484
+ machine.send('CONNECTION_MADE');
504
485
  }
505
486
 
506
487
  /**
@@ -522,17 +503,17 @@
522
503
  const edgeCount = params.edges.length;
523
504
 
524
505
  // Build a descriptive message
525
- let message = "Are you sure you want to delete ";
506
+ let message = 'Are you sure you want to delete ';
526
507
  const parts: string[] = [];
527
508
 
528
509
  if (nodeCount > 0) {
529
- parts.push(`${nodeCount} node${nodeCount > 1 ? "s" : ""}`);
510
+ parts.push(`${nodeCount} node${nodeCount > 1 ? 's' : ''}`);
530
511
  }
531
512
  if (edgeCount > 0) {
532
- parts.push(`${edgeCount} connection${edgeCount > 1 ? "s" : ""}`);
513
+ parts.push(`${edgeCount} connection${edgeCount > 1 ? 's' : ''}`);
533
514
  }
534
515
 
535
- message += parts.join(" and ") + "?";
516
+ message += parts.join(' and ') + '?';
536
517
 
537
518
  // Show native confirmation dialog
538
519
  const confirmed = window.confirm(message);
@@ -549,18 +530,14 @@
549
530
  /**
550
531
  * Handle node deletion - automatically remove connected edges and push to history
551
532
  */
552
- function handleNodesDelete(params: {
553
- nodes: WorkflowNodeType[];
554
- edges: WorkflowEdge[];
555
- }): void {
556
- machine.send("START_DELETE");
533
+ function handleNodesDelete(params: { nodes: WorkflowNodeType[]; edges: WorkflowEdge[] }): void {
534
+ machine.send('START_DELETE');
557
535
 
558
536
  const deletedNodeIds = new Set(params.nodes.map((node) => node.id));
559
537
 
560
538
  // Filter out edges connected to deleted nodes
561
539
  flowEdges = flowEdges.filter(
562
- (edge) =>
563
- !deletedNodeIds.has(edge.source) && !deletedNodeIds.has(edge.target),
540
+ (edge) => !deletedNodeIds.has(edge.source) && !deletedNodeIds.has(edge.target)
564
541
  );
565
542
 
566
543
  // Sync to store
@@ -569,20 +546,20 @@
569
546
  // Push to history AFTER the deletion so undo restores the previous state
570
547
  const nodeCount = params.nodes.length;
571
548
  const edgeCount = params.edges.length;
572
- let description = "Delete";
549
+ let description = 'Delete';
573
550
  if (nodeCount > 0 && edgeCount > 0) {
574
- description = `Delete ${nodeCount} node${nodeCount > 1 ? "s" : ""} and ${edgeCount} connection${edgeCount > 1 ? "s" : ""}`;
551
+ description = `Delete ${nodeCount} node${nodeCount > 1 ? 's' : ''} and ${edgeCount} connection${edgeCount > 1 ? 's' : ''}`;
575
552
  } else if (nodeCount > 0) {
576
- description = `Delete ${nodeCount} node${nodeCount > 1 ? "s" : ""}`;
553
+ description = `Delete ${nodeCount} node${nodeCount > 1 ? 's' : ''}`;
577
554
  } else if (edgeCount > 0) {
578
- description = `Delete ${edgeCount} connection${edgeCount > 1 ? "s" : ""}`;
555
+ description = `Delete ${edgeCount} connection${edgeCount > 1 ? 's' : ''}`;
579
556
  }
580
557
  const storeValue = getWorkflowStore();
581
558
  if (storeValue) {
582
559
  workflowActions.pushHistory(description, storeValue);
583
560
  }
584
561
 
585
- machine.send("DELETE_COMPLETE");
562
+ machine.send('DELETE_COMPLETE');
586
563
  }
587
564
 
588
565
  // Edge styling will be handled when edges are first created or manually updated
@@ -595,32 +572,30 @@
595
572
  });
596
573
 
597
574
  /**
598
- * Check if workflow has cycles
575
+ * Cached cycle check skips DFS during drag/connect via FSM suppressEffect guard.
576
+ * $derived deduplicates the boolean result so the template only re-renders on change.
599
577
  */
600
- function checkWorkflowCycles(): boolean {
578
+ let hasCycles = $derived.by(() => {
579
+ if (machine.permissions.suppressEffect) return false;
601
580
  return WorkflowOperationsHelper.checkWorkflowCycles(flowNodes, flowEdges);
602
- }
581
+ });
603
582
 
604
583
  /**
605
584
  * Handle drop event and add new node to canvas
606
585
  */
607
586
  async function handleNodeDrop(
608
587
  nodeTypeData: string,
609
- position: { x: number; y: number },
588
+ position: { x: number; y: number }
610
589
  ): Promise<void> {
611
- machine.send("START_DROP");
590
+ machine.send('START_DROP');
612
591
 
613
- const newNode = NodeOperationsHelper.createNodeFromDrop(
614
- nodeTypeData,
615
- position,
616
- flowNodes,
617
- );
592
+ const newNode = NodeOperationsHelper.createNodeFromDrop(nodeTypeData, position, flowNodes);
618
593
 
619
594
  if (newNode) {
620
595
  // Add onConfigOpen callback and append to flowNodes for immediate visual feedback
621
596
  const nodeWithCallback = {
622
597
  ...newNode,
623
- data: { ...newNode.data, onConfigOpen: props.openConfigSidebar },
598
+ data: { ...newNode.data, onConfigOpen: props.openConfigSidebar }
624
599
  };
625
600
  flowNodes = [...flowNodes, nodeWithCallback];
626
601
 
@@ -631,13 +606,13 @@
631
606
 
632
607
  const storeValue = getWorkflowStore();
633
608
  if (storeValue) {
634
- workflowActions.pushHistory("Add node", storeValue);
609
+ workflowActions.pushHistory('Add node', storeValue);
635
610
  }
636
611
  } else {
637
- logger.warn("Failed to create node from drop data");
612
+ logger.warn('Failed to create node from drop data');
638
613
  }
639
614
 
640
- machine.send("DROP_COMPLETE");
615
+ machine.send('DROP_COMPLETE');
641
616
  }
642
617
 
643
618
  /**
@@ -651,34 +626,27 @@
651
626
  reader.onload = (event) => {
652
627
  try {
653
628
  const text = event.target?.result;
654
- if (typeof text !== "string") {
655
- throw new Error("Could not read file contents.");
629
+ if (typeof text !== 'string') {
630
+ throw new Error('Could not read file contents.');
656
631
  }
657
632
  const data = JSON.parse(text);
658
633
  const validation = validateWorkflowData(data);
659
634
  if (!validation.valid) {
660
- apiToasts.error(
661
- "Import workflow",
662
- validation.error ?? "Invalid workflow JSON",
663
- );
664
- logger.warn(
665
- "Workflow file drop validation failed:",
666
- validation.error,
667
- );
635
+ apiToasts.error('Import workflow', validation.error ?? 'Invalid workflow JSON');
636
+ logger.warn('Workflow file drop validation failed:', validation.error);
668
637
  return;
669
638
  }
670
639
  workflowActions.initialize(data as Workflow);
671
640
  } catch (error) {
672
- const errorObj =
673
- error instanceof Error ? error : new Error("Unknown error occurred");
674
- logger.error("Workflow file drop import failed:", errorObj);
675
- apiToasts.error("Import workflow", errorObj.message);
641
+ const errorObj = error instanceof Error ? error : new Error('Unknown error occurred');
642
+ logger.error('Workflow file drop import failed:', errorObj);
643
+ apiToasts.error('Import workflow', errorObj.message);
676
644
  }
677
645
  };
678
646
  reader.onerror = () => {
679
- const message = "Failed to read the dropped file.";
647
+ const message = 'Failed to read the dropped file.';
680
648
  logger.error(message);
681
- apiToasts.error("Import workflow", message);
649
+ apiToasts.error('Import workflow', message);
682
650
  };
683
651
  reader.readAsText(file);
684
652
  }
@@ -688,6 +656,9 @@
688
656
  */
689
657
  let nodeIdToRefresh = $state<string | null>(null);
690
658
 
659
+ // Canvas viewport controller ref (rendered inside SvelteFlowProvider)
660
+ let canvasControllerRef: CanvasController | undefined = $state();
661
+
691
662
  /**
692
663
  * Update a node's data in the local editor state.
693
664
  * Called by App.svelte AFTER it has already updated the global store via
@@ -699,9 +670,9 @@
699
670
  */
700
671
  export function updateNodeData(
701
672
  nodeId: string,
702
- dataUpdates: Partial<WorkflowNodeType["data"]>,
673
+ dataUpdates: Partial<WorkflowNodeType['data']>
703
674
  ): void {
704
- machine.send("START_NODE_UPDATE");
675
+ machine.send('START_NODE_UPDATE');
705
676
 
706
677
  flowNodes = flowNodes.map((node) => {
707
678
  if (node.id === nodeId) {
@@ -709,14 +680,14 @@
709
680
  ...node,
710
681
  data: {
711
682
  ...node.data,
712
- ...dataUpdates,
713
- },
683
+ ...dataUpdates
684
+ }
714
685
  };
715
686
  }
716
687
  return node;
717
688
  });
718
689
 
719
- machine.send("UPDATE_COMPLETE");
690
+ machine.send('UPDATE_COMPLETE');
720
691
  }
721
692
 
722
693
  /**
@@ -733,6 +704,32 @@
733
704
  nodeIdToRefresh = nodeId;
734
705
  }
735
706
 
707
+ // Canvas viewport methods (forwarded to CanvasController inside SvelteFlowProvider)
708
+
709
+ export function canvasFitView(): void {
710
+ canvasControllerRef?.canvasFitView();
711
+ }
712
+
713
+ export function canvasZoomIn(): void {
714
+ canvasControllerRef?.canvasZoomIn();
715
+ }
716
+
717
+ export function canvasZoomOut(): void {
718
+ canvasControllerRef?.canvasZoomOut();
719
+ }
720
+
721
+ export function canvasZoomTo(level: number): void {
722
+ canvasControllerRef?.canvasZoomTo(level);
723
+ }
724
+
725
+ export function canvasPanTo(x: number, y: number): void {
726
+ canvasControllerRef?.canvasPanTo(x, y);
727
+ }
728
+
729
+ export function canvasResetView(): void {
730
+ canvasControllerRef?.canvasResetView();
731
+ }
732
+
736
733
  /**
737
734
  * Callback when edge refresh is complete
738
735
  */
@@ -758,23 +755,21 @@
758
755
  // Don't handle shortcuts if user is typing in an input, textarea, or contenteditable
759
756
  const target = event.target as HTMLElement;
760
757
  const isInputElement =
761
- target.tagName === "INPUT" ||
762
- target.tagName === "TEXTAREA" ||
763
- target.isContentEditable;
758
+ target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
764
759
 
765
760
  if (isInputElement) {
766
761
  return;
767
762
  }
768
763
 
769
764
  // Undo: Ctrl+Z (without Shift)
770
- if (event.key === "z" && !event.shiftKey) {
765
+ if (event.key === 'z' && !event.shiftKey) {
771
766
  event.preventDefault();
772
767
  historyActions.undo();
773
768
  return;
774
769
  }
775
770
 
776
771
  // Redo: Ctrl+Shift+Z or Ctrl+Y
777
- if ((event.key === "z" && event.shiftKey) || event.key === "y") {
772
+ if ((event.key === 'z' && event.shiftKey) || event.key === 'y') {
778
773
  event.preventDefault();
779
774
  historyActions.redo();
780
775
  return;
@@ -785,11 +780,11 @@
785
780
  <svelte:window onkeydown={handleKeydown} />
786
781
 
787
782
  <SvelteFlowProvider>
783
+ <!-- Canvas viewport controller - provides fitView, zoom, pan methods -->
784
+ <CanvasController bind:this={canvasControllerRef} />
785
+
788
786
  <!-- EdgeRefresher component - handles updateNodeInternals calls -->
789
- <EdgeRefresher
790
- {nodeIdToRefresh}
791
- onRefreshComplete={handleEdgeRefreshComplete}
792
- />
787
+ <EdgeRefresher {nodeIdToRefresh} onRefreshComplete={handleEdgeRefreshComplete} />
793
788
 
794
789
  <!-- Port Coordinate Tracker - maintains port positions for proximity connect -->
795
790
  <PortCoordinateTracker
@@ -803,10 +798,7 @@
803
798
  <div class="flowdrop-workflow-editor__main">
804
799
  <!-- Flow Canvas -->
805
800
  <div class="flowdrop-canvas">
806
- <FlowDropZone
807
- ondrop={handleNodeDrop}
808
- onfiledrop={handleWorkflowFileDrop}
809
- >
801
+ <FlowDropZone ondrop={handleNodeDrop} onfiledrop={handleWorkflowFileDrop}>
810
802
  {#key svelteFlowKey}
811
803
  <SvelteFlow
812
804
  bind:nodes={flowNodes}
@@ -819,7 +811,7 @@
819
811
  source: connection.source,
820
812
  target: connection.target,
821
813
  sourceHandle: connection.sourceHandle ?? undefined,
822
- targetHandle: connection.targetHandle ?? undefined,
814
+ targetHandle: connection.targetHandle ?? undefined
823
815
  })}
824
816
  onbeforedelete={handleBeforeDelete}
825
817
  ondelete={handleNodesDelete}
@@ -838,14 +830,24 @@
838
830
  fitView={getEditorSettings().fitViewOnLoad}
839
831
  >
840
832
  <Controls />
833
+ {#if !props.readOnly && !props.lockWorkflow && props.onToggleConsole}
834
+ <button
835
+ class="flowdrop-console-toggle"
836
+ class:flowdrop-console-toggle--active={props.consoleOpen}
837
+ onclick={props.onToggleConsole}
838
+ aria-label="Command Console (`)"
839
+ title="Command Console (`)"
840
+ type="button"
841
+ >
842
+ <Icon icon="heroicons:command-line" width="18" height="18" />
843
+ </button>
844
+ {/if}
841
845
  <!-- Always render Background for consistent bg color in dark/light mode -->
842
846
  <Background
843
847
  gap={getEditorSettings().gridSize}
844
848
  bgColor="var(--fd-background)"
845
849
  variant={BackgroundVariant.Dots}
846
- patternColor={getEditorSettings().showGrid
847
- ? undefined
848
- : "transparent"}
850
+ patternColor={getEditorSettings().showGrid ? undefined : 'transparent'}
849
851
  />
850
852
  {#if getEditorSettings().showMinimap}
851
853
  <MiniMap />
@@ -886,18 +888,14 @@
886
888
  <div class="flowdrop-status-bar" aria-live="polite" aria-atomic="true">
887
889
  <div class="flowdrop-status-bar__content">
888
890
  <div class="flowdrop-flex flowdrop-gap--4">
889
- <span class="flowdrop-text--xs flowdrop-text--gray"
890
- >{flowNodes.length} nodes</span
891
- >
891
+ <span class="flowdrop-text--xs flowdrop-text--gray">{flowNodes.length} nodes</span>
892
892
  <span class="flowdrop-text--xs flowdrop-text--gray">•</span>
893
- <span class="flowdrop-text--xs flowdrop-text--gray"
894
- >{flowEdges.length} connections</span
893
+ <span class="flowdrop-text--xs flowdrop-text--gray">{flowEdges.length} connections</span
895
894
  >
896
895
 
897
- {#if checkWorkflowCycles()}
896
+ {#if hasCycles}
898
897
  <span class="flowdrop-text--xs flowdrop-text--gray">•</span>
899
- <span
900
- class="flowdrop-text--xs flowdrop-font--medium flowdrop-text--error"
898
+ <span class="flowdrop-text--xs flowdrop-font--medium flowdrop-text--error"
901
899
  >⚠️ Cycles detected</span
902
900
  >
903
901
  {/if}
@@ -964,6 +962,50 @@
964
962
  justify-content: space-between;
965
963
  }
966
964
 
965
+ .flowdrop-console-toggle {
966
+ position: absolute;
967
+ bottom: 140px;
968
+ left: 12px;
969
+ z-index: 5;
970
+ display: flex;
971
+ align-items: center;
972
+ justify-content: center;
973
+ width: 2rem;
974
+ height: 2rem;
975
+ border: 1px solid var(--fd-border);
976
+ border-radius: var(--fd-radius-md);
977
+ background-color: var(--fd-background);
978
+ color: var(--fd-muted-foreground);
979
+ cursor: pointer;
980
+ box-shadow: var(--fd-shadow-sm);
981
+ transition:
982
+ color var(--fd-transition-fast),
983
+ background-color var(--fd-transition-fast),
984
+ box-shadow var(--fd-transition-fast);
985
+ }
986
+
987
+ .flowdrop-console-toggle:hover {
988
+ color: var(--fd-foreground);
989
+ background-color: var(--fd-subtle);
990
+ box-shadow: var(--fd-shadow-md);
991
+ }
992
+
993
+ .flowdrop-console-toggle:focus {
994
+ outline: none;
995
+ box-shadow: 0 0 0 2px var(--fd-ring);
996
+ }
997
+
998
+ .flowdrop-console-toggle--active {
999
+ color: var(--fd-primary);
1000
+ background-color: var(--fd-primary-muted);
1001
+ border-color: var(--fd-primary);
1002
+ }
1003
+
1004
+ .flowdrop-console-toggle--active:hover {
1005
+ color: var(--fd-primary);
1006
+ background-color: var(--fd-primary-muted);
1007
+ }
1008
+
967
1009
  :global(.flowdrop-workflow-editor .svelte-flow__node:hover) {
968
1010
  transform: translateY(-2px);
969
1011
  }
@@ -990,9 +1032,7 @@
990
1032
  :global(.flowdrop-workflow-editor .svelte-flow__edge.selected) {
991
1033
  stroke: var(--fd-primary) !important;
992
1034
  stroke-width: 3 !important;
993
- filter: drop-shadow(
994
- 0 0 4px color-mix(in srgb, var(--fd-primary) 50%, transparent)
995
- );
1035
+ filter: drop-shadow(0 0 4px color-mix(in srgb, var(--fd-primary) 50%, transparent));
996
1036
  }
997
1037
 
998
1038
  :global(.flowdrop-workflow-editor .svelte-flow__edge.selected path) {