@kiberon-labs/behave-graph-flow 1.0.0 → 2.0.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 (314) hide show
  1. package/.fallowrc.json +16 -0
  2. package/.storybook/main.ts +32 -0
  3. package/.storybook/preview.ts +16 -0
  4. package/.storybook/styles.css +10 -0
  5. package/.storybook/vscode.css +814 -0
  6. package/.turbo/turbo-build.log +7 -0
  7. package/LICENSE +6 -0
  8. package/README.md +2 -2
  9. package/data/Polynomial.json +510 -0
  10. package/data/sequence.json +337 -0
  11. package/data/trigger-event.json +241 -0
  12. package/data/variable-change.json +210 -0
  13. package/dist/entry.css +4 -0
  14. package/dist/index.css +39 -0
  15. package/dist/index.css.map +1 -0
  16. package/dist/index.d.ts +2282 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +14873 -0
  19. package/dist/index.js.map +1 -0
  20. package/docs/notifications.md +246 -0
  21. package/docs/protocol.md +679 -0
  22. package/docs/specifics.md +191 -0
  23. package/package.json +85 -21
  24. package/postcss.config.ts +3 -4
  25. package/src/annotations/index.ts +32 -0
  26. package/src/components/FloatingToolbar/index.module.css +45 -0
  27. package/src/components/FloatingToolbar/index.tsx +256 -0
  28. package/src/components/Flow.tsx +276 -75
  29. package/src/components/contextMenus/NodePicker.module.css +274 -0
  30. package/src/components/contextMenus/NodePicker.tsx +481 -0
  31. package/src/components/contextMenus/edge.tsx +108 -0
  32. package/src/components/contextMenus/node.tsx +155 -0
  33. package/src/components/contextMenus/selection.tsx +77 -0
  34. package/src/components/controls/any/index.tsx +8 -0
  35. package/src/components/controls/boolean/index.tsx +13 -0
  36. package/src/components/controls/colorPicker/InputPopover.module.css +100 -0
  37. package/src/components/controls/colorPicker/InputPopover.tsx +31 -0
  38. package/src/components/controls/colorPicker/index.module.css +18 -0
  39. package/src/components/controls/colorPicker/index.tsx +61 -0
  40. package/src/components/controls/number/index.tsx +35 -0
  41. package/src/components/controls/string/index.tsx +16 -0
  42. package/src/components/edges/index.tsx +469 -0
  43. package/src/components/edges/offsetBezier.ts +134 -0
  44. package/src/components/hotKeys.tsx +20 -0
  45. package/src/components/layoutController/index.module.css +10 -0
  46. package/src/components/layoutController/index.tsx +117 -0
  47. package/src/components/layoutController/utils.ts +205 -0
  48. package/src/components/menubar/defaults.tsx +480 -0
  49. package/src/components/menubar/index.tsx +49 -0
  50. package/src/components/menubar/menuItem.module.css +16 -0
  51. package/src/components/menubar/menuItem.tsx +32 -0
  52. package/src/components/nodes/behave/Node.module.css +23 -0
  53. package/src/components/nodes/behave/Node.tsx +176 -0
  54. package/src/components/nodes/behave/NodeContainer.module.css +87 -0
  55. package/src/components/nodes/behave/NodeContainer.tsx +46 -0
  56. package/src/components/nodes/behave/index.tsx +14 -0
  57. package/src/components/nodes/comment/FormatToolbar.tsx +118 -0
  58. package/src/components/nodes/comment/comment.tsx +103 -0
  59. package/src/components/nodes/comment/styles.module.css +150 -0
  60. package/src/components/nodes/group/index.tsx +109 -0
  61. package/src/components/nodes/wrapper/index.tsx +73 -0
  62. package/src/components/nodes/wrapper/styles.module.css +113 -0
  63. package/src/components/notifications/NotificationProvider.tsx +81 -0
  64. package/src/components/notifications/index.ts +2 -0
  65. package/src/components/notifications/utils.ts +71 -0
  66. package/src/components/panels/alignment/index.module.css +20 -0
  67. package/src/components/panels/alignment/index.tsx +244 -0
  68. package/src/components/panels/base/index.tsx +5 -0
  69. package/src/components/panels/base/styles.module.css +12 -0
  70. package/src/components/panels/conversation/index.module.css +151 -0
  71. package/src/components/panels/conversation/index.tsx +162 -0
  72. package/src/components/panels/events/CustomEventsEditor.tsx +384 -0
  73. package/src/components/panels/events/EditEventPanel.tsx +315 -0
  74. package/src/components/panels/events/ManageEventsPanel.tsx +98 -0
  75. package/src/components/panels/events/index.tsx +23 -0
  76. package/src/components/panels/events/styles.module.css +236 -0
  77. package/src/components/panels/history/index.tsx +92 -0
  78. package/src/components/panels/history/styles.module.css +106 -0
  79. package/src/components/panels/keymaps/index.module.css +78 -0
  80. package/src/components/panels/keymaps/index.tsx +167 -0
  81. package/src/components/panels/layers/index.tsx +240 -0
  82. package/src/components/panels/layers/styles.module.css +110 -0
  83. package/src/components/panels/legend/index.module.css +6 -0
  84. package/src/components/panels/legend/index.tsx +76 -0
  85. package/src/components/panels/logs/index.module.css +212 -0
  86. package/src/components/panels/logs/index.tsx +288 -0
  87. package/src/components/panels/nodeInputs/InputControl.tsx +63 -0
  88. package/src/components/panels/nodeInputs/InputsGroup.tsx +64 -0
  89. package/src/components/panels/nodeInputs/MultipleNodesView.tsx +37 -0
  90. package/src/components/panels/nodeInputs/NodeSettings.tsx +92 -0
  91. package/src/components/panels/nodeInputs/NodeTitleEditor.tsx +125 -0
  92. package/src/components/panels/nodeInputs/OutputsGroup.tsx +65 -0
  93. package/src/components/panels/nodeInputs/SocketGenerators.tsx +32 -0
  94. package/src/components/panels/nodeInputs/index.module.css +284 -0
  95. package/src/components/panels/nodeInputs/index.tsx +339 -0
  96. package/src/components/panels/nodeInputs/useNodeHandlers.ts +76 -0
  97. package/src/components/panels/nodeInputs/useNodeInputsData.ts +173 -0
  98. package/src/components/panels/nodePicker/index.tsx +115 -0
  99. package/src/components/panels/panel/index.module.css +66 -0
  100. package/src/components/panels/panel/index.tsx +88 -0
  101. package/src/components/panels/search/index.module.css +66 -0
  102. package/src/components/panels/search/index.tsx +215 -0
  103. package/src/components/panels/systemSettings/index.tsx +206 -0
  104. package/src/components/panels/systemSettings/styles.module.css +11 -0
  105. package/src/components/panels/traces/GridLines.tsx +38 -0
  106. package/src/components/panels/traces/TimeGrid.tsx +48 -0
  107. package/src/components/panels/traces/TraceLane.tsx +62 -0
  108. package/src/components/panels/traces/TraceTooltip.tsx +22 -0
  109. package/src/components/panels/traces/TracesHeader.tsx +56 -0
  110. package/src/components/panels/traces/index.module.css +166 -0
  111. package/src/components/panels/traces/index.tsx +294 -0
  112. package/src/components/panels/traces/types.ts +48 -0
  113. package/src/components/panels/traces/useDerivedSpans.ts +212 -0
  114. package/src/components/panels/traces/utils.ts +25 -0
  115. package/src/components/panels/variables/CreateVariableScreen.tsx +162 -0
  116. package/src/components/panels/variables/ManageVariablesScreen.tsx +144 -0
  117. package/src/components/panels/variables/index.tsx +125 -0
  118. package/src/components/panels/variables/styles.module.css +236 -0
  119. package/src/components/primitives/icon.module.css +45 -0
  120. package/src/components/primitives/icon.tsx +38 -0
  121. package/src/components/sockets/input/index.tsx +76 -0
  122. package/src/components/sockets/input/styles.module.css +27 -0
  123. package/src/components/sockets/output/index.tsx +61 -0
  124. package/src/components/sockets/output/styles.module.css +27 -0
  125. package/src/css/prosemirror.css +57 -0
  126. package/src/css/rc-dock.css +112 -0
  127. package/src/css/rc-menu.css +100 -0
  128. package/src/css/vars.css +14 -0
  129. package/src/css/vscode.css +13 -0
  130. package/src/entry.css +4 -0
  131. package/src/generators/CustomEventOnTriggeredGenerator.tsx +85 -0
  132. package/src/generators/SequenceGenerator.tsx +104 -0
  133. package/src/generators/SwitchOnIntegerGenerator.tsx +256 -0
  134. package/src/generators/SwitchOnStringGenerator.tsx +263 -0
  135. package/src/generators/registerDefaultGenerators.ts +34 -0
  136. package/src/hooks/useBehaveGraphFlow.ts +17 -16
  137. package/src/hooks/useDetachNodes.ts +39 -0
  138. package/src/hooks/useFlowHandlers.ts +115 -29
  139. package/src/hooks/useWasdPan.ts +188 -0
  140. package/src/index.css +146 -0
  141. package/src/index.ts +36 -18
  142. package/src/layout/dagre.tsx +119 -0
  143. package/src/layout/elk.ts +200 -0
  144. package/src/plugin/alignment/index.ts +81 -0
  145. package/src/plugin/docs/index.tsx +299 -0
  146. package/src/plugin/docs/panel/index.tsx +200 -0
  147. package/src/plugin/docs/panel/styles.module.css +174 -0
  148. package/src/plugin/graphrunner/actions.ts +253 -0
  149. package/src/plugin/graphrunner/buttons.tsx +87 -0
  150. package/src/plugin/graphrunner/client.ts +704 -0
  151. package/src/plugin/graphrunner/index.tsx +255 -0
  152. package/src/plugin/graphrunner/panel.tsx +386 -0
  153. package/src/plugin/graphrunner/runner.ts +358 -0
  154. package/src/plugin/graphrunner/session.ts +243 -0
  155. package/src/plugin/graphrunner/store.ts +206 -0
  156. package/src/plugin/graphrunner/styles.module.css +211 -0
  157. package/src/plugin/graphrunner/transport.ts +224 -0
  158. package/src/plugin/graphrunner/types.ts +672 -0
  159. package/src/plugin/graphrunner-local/execution-utils.ts +457 -0
  160. package/src/plugin/graphrunner-local/index.tsx +166 -0
  161. package/src/plugin/graphrunner-local/panel.tsx +231 -0
  162. package/src/plugin/graphrunner-local/store.ts +41 -0
  163. package/src/plugin/graphrunner-local/styles.module.css +101 -0
  164. package/src/plugin/graphrunner-local/transport.ts +1372 -0
  165. package/src/plugin/graphrunner-local/types.ts +10 -0
  166. package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +633 -0
  167. package/src/plugin/graphrunner-webworker/index.tsx +146 -0
  168. package/src/plugin/graphrunner-webworker/panel.tsx +173 -0
  169. package/src/plugin/graphrunner-webworker/store.ts +89 -0
  170. package/src/plugin/graphrunner-webworker/types.ts +17 -0
  171. package/src/plugin/graphrunner-webworker/worker-transport.ts +123 -0
  172. package/src/plugin/realtime/realtimeRunner.ts +570 -0
  173. package/src/specifics/CustomEventOnTriggeredSpecific.tsx +92 -0
  174. package/src/specifics/CustomEventTriggerSpecific.tsx +141 -0
  175. package/src/specifics/VariableGetSpecific.tsx +110 -0
  176. package/src/specifics/VariableSetSpecific.tsx +110 -0
  177. package/src/specifics/registerDefaultSpecifics.ts +5 -0
  178. package/src/store/actions.tsx +698 -0
  179. package/src/store/chat.ts +73 -0
  180. package/src/store/controls.tsx +62 -0
  181. package/src/store/documentation.tsx +69 -0
  182. package/src/store/events.tsx +116 -0
  183. package/src/store/flow.tsx +245 -0
  184. package/src/store/graphRunnerClient.ts +110 -0
  185. package/src/store/hotKeys.tsx +323 -0
  186. package/src/store/layers.ts +259 -0
  187. package/src/store/legend.tsx +76 -0
  188. package/src/store/logs.ts +28 -0
  189. package/src/store/menubar.ts +41 -0
  190. package/src/store/refs.ts +84 -0
  191. package/src/store/registry.ts +43 -0
  192. package/src/store/selection.ts +22 -0
  193. package/src/store/settings.ts +99 -0
  194. package/src/store/socketGenerator.tsx +54 -0
  195. package/src/store/specific.tsx +75 -0
  196. package/src/store/specs.tsx +35 -0
  197. package/src/store/tabs.ts +278 -0
  198. package/src/store/toolbar.tsx +45 -0
  199. package/src/store/traces.ts +240 -0
  200. package/src/store/variables.ts +37 -0
  201. package/src/system/graph.ts +134 -0
  202. package/src/system/index.ts +3 -0
  203. package/src/system/notifications.ts +98 -0
  204. package/src/system/plugin.ts +27 -0
  205. package/src/system/provider.tsx +22 -0
  206. package/src/system/pubsub.ts +323 -0
  207. package/src/system/system.ts +223 -0
  208. package/src/system/tabLoader.tsx +265 -0
  209. package/src/system/undoRedo.ts +103 -0
  210. package/src/transformers/Uigraph.ts +60 -0
  211. package/src/transformers/behaveToFlow.ts +16 -4
  212. package/src/transformers/flowToBehave.ts +32 -12
  213. package/src/types/NodeMetadata.ts +27 -0
  214. package/src/types/graph.ts +49 -0
  215. package/src/types/nodes.ts +45 -0
  216. package/src/types.ts +16 -0
  217. package/src/util/colors.ts +1 -29
  218. package/src/util/downloadJson.ts +18 -0
  219. package/src/util/extractNodeMetadata.ts +16 -0
  220. package/src/util/getPickerFilters.ts +1 -1
  221. package/src/util/isBehaveNode.ts +6 -0
  222. package/src/util/isValidConnection.ts +28 -15
  223. package/src/util/mergeSockets.ts +29 -0
  224. package/src/util/serializeVariables.ts +66 -0
  225. package/src/util/sockets.ts +43 -0
  226. package/stories/apex/layoutController/example-graph.worker.ts +39 -0
  227. package/stories/apex/layoutController/index.stories.tsx +48 -0
  228. package/stories/apex/layoutController/webworker.stories.tsx +103 -0
  229. package/stories/apex/menubar/menubar.stories.tsx +19 -0
  230. package/stories/components/colorpicker/index.stories.tsx +20 -0
  231. package/stories/components/contextMenus/edge.stories.tsx +32 -0
  232. package/stories/components/contextMenus/node.stories.tsx +26 -0
  233. package/stories/components/contextMenus/nodePicker.stories.tsx +115 -0
  234. package/stories/components/controls/any/index.stories.tsx +19 -0
  235. package/stories/components/controls/boolean/index.stories.tsx +19 -0
  236. package/stories/components/controls/colorPicker/index.stories.tsx +49 -0
  237. package/stories/components/controls/number/index.stories.tsx +19 -0
  238. package/stories/components/controls/string/index.stories.tsx +19 -0
  239. package/stories/components/nodes/behaveNode.stories.tsx +108 -0
  240. package/stories/components/nodes/comment.stories.tsx +106 -0
  241. package/stories/components/panels/alignment.stories.tsx +24 -0
  242. package/stories/components/panels/events.stories.tsx +38 -0
  243. package/stories/components/panels/graphRunner.stories.tsx +317 -0
  244. package/stories/components/panels/history.stories.tsx +37 -0
  245. package/stories/components/panels/keymaps.stories.tsx +21 -0
  246. package/stories/components/panels/legend.stories.tsx +37 -0
  247. package/stories/components/panels/logs.stories.tsx +24 -0
  248. package/stories/components/panels/nodeInputs.stories.tsx +21 -0
  249. package/stories/components/panels/nodePicker.stories.tsx +37 -0
  250. package/stories/components/panels/panel.stories.tsx +39 -0
  251. package/stories/components/panels/search.stories.tsx +24 -0
  252. package/stories/components/panels/systemSettings.stories.tsx +26 -0
  253. package/stories/components/panels/traces.stories.tsx +225 -0
  254. package/stories/components/panels/variables.stories.tsx +24 -0
  255. package/stories/defaults/defaultStoryProvider.tsx +167 -0
  256. package/stories/defaults/systemGenerator.ts +38 -0
  257. package/tests/components/edges/offsetBezier.test.ts +51 -0
  258. package/tests/components/layoutController/utils.test.ts +68 -0
  259. package/tests/components/panels/traces/utils.test.ts +52 -0
  260. package/tests/flowToBehave.test.ts +26 -4
  261. package/tests/notifications.test.ts +87 -0
  262. package/tests/saveLoad.test.ts +372 -0
  263. package/tests/util/calculateNewEdge.test.ts +98 -0
  264. package/tests/util/getSocketsByNodeTypeAndHandleType.test.ts +31 -0
  265. package/tests/util/hasPositionMetaData.test.ts +33 -0
  266. package/tests/util/isBehaveNode.test.ts +22 -0
  267. package/tests/util/isHandleConnected.test.ts +37 -0
  268. package/tests/util/mergeSockets.test.ts +43 -0
  269. package/tests/visual/README.md +64 -0
  270. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-alignment-chromium-win32.png +0 -0
  271. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-conversation-chromium-win32.png +0 -0
  272. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-events-chromium-win32.png +0 -0
  273. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-history-chromium-win32.png +0 -0
  274. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-keymaps-chromium-win32.png +0 -0
  275. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-layers-chromium-win32.png +0 -0
  276. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-legend-chromium-win32.png +0 -0
  277. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-logs-chromium-win32.png +0 -0
  278. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodeInputs-chromium-win32.png +0 -0
  279. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodePicker-chromium-win32.png +0 -0
  280. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-panel-chromium-win32.png +0 -0
  281. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-search-chromium-win32.png +0 -0
  282. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-systemSettings-chromium-win32.png +0 -0
  283. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-traces-chromium-win32.png +0 -0
  284. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-variables-chromium-win32.png +0 -0
  285. package/tests/visual/panels.visual.test.tsx +76 -0
  286. package/tsconfig.base.json +39 -0
  287. package/tsconfig.json +18 -59
  288. package/tsconfig.prod.json +23 -0
  289. package/tsdown.config.ts +15 -3
  290. package/typedoc.json +7 -7
  291. package/vite.config.js +7 -0
  292. package/vitest.config.ts +5 -2
  293. package/vitest.visual.config.ts +48 -0
  294. package/src/components/AutoSizeInput.tsx +0 -65
  295. package/src/components/Controls.tsx +0 -87
  296. package/src/components/InputSocket.tsx +0 -142
  297. package/src/components/Node.tsx +0 -68
  298. package/src/components/NodeContainer.tsx +0 -46
  299. package/src/components/NodePicker.tsx +0 -77
  300. package/src/components/OutputSocket.tsx +0 -58
  301. package/src/components/modals/ClearModal.tsx +0 -40
  302. package/src/components/modals/HelpModal.tsx +0 -36
  303. package/src/components/modals/LoadModal.tsx +0 -96
  304. package/src/components/modals/Modal.tsx +0 -64
  305. package/src/components/modals/SaveModal.tsx +0 -60
  306. package/src/hooks/useCustomNodeTypes.tsx +0 -31
  307. package/src/hooks/useGraphRunner.ts +0 -104
  308. package/src/hooks/useMergeMap.ts +0 -14
  309. package/src/hooks/useNodeSpecJson.ts +0 -20
  310. package/src/hooks/useQueriableDefinitions.ts +0 -22
  311. package/src/styles.css +0 -8
  312. package/tailwind.config.ts +0 -19
  313. package/tests/tsconfig.json +0 -10
  314. /package/src/{types.d.ts → types-declarations.d.ts} +0 -0
@@ -0,0 +1,223 @@
1
+ import { UndoManager } from './undoRedo';
2
+ import { type StoreApi } from 'zustand';
3
+ import type { Edge, Node, Viewport } from 'reactflow';
4
+ import { tabStoreFactory, type TabStore } from '@/store/tabs';
5
+ import { TabLoader } from './tabLoader';
6
+ import {
7
+ systemSettingsFactory,
8
+ type SystemSettingsStore
9
+ } from '../store/settings.js';
10
+ import { logStoreFactory, type LogStore } from '@/store/logs';
11
+ import { legendStoreFactory, type LegendStore } from '@/store/legend';
12
+ import { menubarStoreFactory, type MenuBarStore } from '@/store/menubar';
13
+ import { hotKeyStoreFactory, type HotkeyStore } from '@/store/hotKeys';
14
+ import { PubSub } from './pubsub';
15
+ import {
16
+ edgeStoreFactory,
17
+ flowStoreFactory,
18
+ nodeStoreFactory,
19
+ type EdgeStore,
20
+ type FlowStore,
21
+ type NodeStore
22
+ } from '@/store/flow';
23
+ import { controlsStoreFactory, type ControlsStore } from '@/store/controls';
24
+ import { variableStoreFactory, type VariableStore } from '@/store/variables';
25
+ import { selectionStoreFactory, type SelectionStore } from '@/store/selection';
26
+ import { refStoreFactory, type RefStore } from '@/store/refs';
27
+ import { Graph } from './graph';
28
+ import { actionStoreFactory, type ActionStore } from '@/store/actions';
29
+ import { registryStoreFactory, type RegistryStore } from '@/store/registry';
30
+ import { specsStoreFactory, type SpecsStore } from '@/store/specs';
31
+ import { traceStoreFactory, type TraceStore } from '@/store/traces';
32
+ import { specificStoreFactory, type SpecificStore } from '@/store/specific';
33
+ import {
34
+ socketGeneratorStoreFactory,
35
+ type SocketGeneratorStore
36
+ } from '@/store/socketGenerator';
37
+ import { eventsStoreFactory, type EventsStore } from '@/store/events';
38
+ import {
39
+ documentationStoreFactory,
40
+ type DocumentationStore
41
+ } from '@/store/documentation';
42
+ import { toolbarStoreFactory, type ToolbarStore } from '@/store/toolbar';
43
+ import { layerStoreFactory, type LayerStore } from '@/store/layers';
44
+ import { setupSystemActions } from '@/plugin/alignment';
45
+ import { Notifications } from './notifications';
46
+ import { chatStoreFactory, type ChatStore } from '@/store/chat';
47
+ import type { Renderable } from 'react-hot-toast';
48
+ import type { INodeRegistry } from '@/types/NodeMetadata';
49
+ import type { LoadablePlugin } from './plugin';
50
+ import type { UIGraphJSON } from '@/types/graph';
51
+ import type { GraphJSON } from '@kiberon-labs/behave-graph';
52
+ import type { LayoutBase } from 'rc-dock';
53
+
54
+ export type NotificationType = 'info' | 'success' | 'error' | 'loading';
55
+
56
+ export interface NotificationData {
57
+ type: NotificationType;
58
+ message: string;
59
+ options?: {
60
+ id?: string;
61
+ duration?: number;
62
+ position?: any;
63
+ icon?: Renderable;
64
+ style?: React.CSSProperties;
65
+ className?: string;
66
+ ariaLive?: any;
67
+ };
68
+ }
69
+
70
+ export interface PubSys {
71
+ 'edge:added': Edge;
72
+ 'node:added': Node;
73
+ 'edge:removed': Edge;
74
+ 'node:removed': Node;
75
+ graphAnnotationsChanged: {
76
+ [key: string]: any;
77
+ };
78
+ 'aiNode:trigger': {
79
+ nodeId: string;
80
+ };
81
+ saveViewport: {
82
+ index: number;
83
+ viewport: Viewport;
84
+ };
85
+ missingViewPort: {
86
+ index: number;
87
+ };
88
+
89
+ notification: NotificationData;
90
+ 'notification:dismiss': {
91
+ toastId?: string;
92
+ };
93
+ 'layout:saved': LayoutBase;
94
+ 'graph:saved': UIGraphJSON;
95
+ 'graph:inner:saved': GraphJSON;
96
+ 'chat:userMessage': {
97
+ content: string;
98
+ };
99
+ }
100
+
101
+ /**
102
+ * Use this to extend the System interface when adding plugins
103
+ */
104
+ export interface ISystem {}
105
+
106
+ export class System implements ISystem {
107
+ public readonly actionStore: StoreApi<ActionStore>;
108
+ public readonly pubsub = new PubSub<PubSys>();
109
+ public readonly undoManager = new UndoManager();
110
+ public readonly flowStore: StoreApi<FlowStore>;
111
+ public readonly controlStore: StoreApi<ControlsStore>;
112
+ public readonly variableStore: StoreApi<VariableStore>;
113
+ public readonly selectionStore: StoreApi<SelectionStore>;
114
+ public readonly refStore: StoreApi<RefStore>;
115
+ public readonly tabStore: StoreApi<TabStore>;
116
+ protected deps: Record<string, unknown> = {};
117
+ public readonly registry: StoreApi<RegistryStore>;
118
+ public readonly tabLoader: TabLoader;
119
+ public readonly systemSettings: StoreApi<SystemSettingsStore>;
120
+ public readonly logsStore: StoreApi<LogStore>;
121
+ public readonly legendStore: StoreApi<LegendStore>;
122
+ public readonly hotKeyStore: StoreApi<HotkeyStore>;
123
+ public readonly edgeStore: StoreApi<EdgeStore>;
124
+ public readonly nodeStore: StoreApi<NodeStore>;
125
+ public readonly specStore: StoreApi<SpecsStore>;
126
+ public readonly specificStore: StoreApi<SpecificStore>;
127
+ public readonly socketGeneratorStore: StoreApi<SocketGeneratorStore>;
128
+ public readonly eventsStore: StoreApi<EventsStore>;
129
+ public readonly documentationStore: StoreApi<DocumentationStore>;
130
+ public readonly toolbarStore: StoreApi<ToolbarStore>;
131
+ public readonly layerStore: StoreApi<LayerStore>;
132
+ public readonly menubarStore: StoreApi<MenuBarStore>;
133
+ public readonly graph: Graph;
134
+ public readonly traceStore: StoreApi<TraceStore>;
135
+ public readonly chatStore: StoreApi<ChatStore>;
136
+ public readonly notifications: Notifications = new Notifications(this);
137
+
138
+ /**
139
+ * Create a new System instance
140
+ * @param registry - INodeRegistry containing nodes and values metadata
141
+ */
142
+ constructor(registry?: INodeRegistry) {
143
+ this.tabStore = tabStoreFactory();
144
+ this.controlStore = controlsStoreFactory();
145
+ this.variableStore = variableStoreFactory();
146
+ this.refStore = refStoreFactory();
147
+ this.systemSettings = systemSettingsFactory();
148
+ this.logsStore = logStoreFactory();
149
+ this.legendStore = legendStoreFactory();
150
+ this.eventsStore = eventsStoreFactory();
151
+ this.nodeStore = nodeStoreFactory(this);
152
+ this.edgeStore = edgeStoreFactory(this);
153
+ this.flowStore = flowStoreFactory(this);
154
+ this.selectionStore = selectionStoreFactory(this);
155
+ this.hotKeyStore = hotKeyStoreFactory(this);
156
+ this.actionStore = actionStoreFactory(this);
157
+ this.registry = registryStoreFactory();
158
+ this.specStore = specsStoreFactory(this);
159
+ this.socketGeneratorStore = socketGeneratorStoreFactory();
160
+ this.specificStore = specificStoreFactory();
161
+ this.documentationStore = documentationStoreFactory();
162
+ this.toolbarStore = toolbarStoreFactory();
163
+ this.layerStore = layerStoreFactory(this);
164
+
165
+ this.chatStore = chatStoreFactory();
166
+ this.graph = new Graph(this);
167
+
168
+ // Handle registry initialization
169
+ if (registry) {
170
+ this.registry.getState().updateRegistry(registry);
171
+ this.specStore.getState().setSpecs(registry.specs);
172
+ }
173
+
174
+ this.menubarStore = menubarStoreFactory();
175
+ this.tabLoader = new TabLoader(this);
176
+
177
+ this.traceStore = traceStoreFactory(this);
178
+
179
+ // Setup system-level action subscribers
180
+ setupSystemActions(this);
181
+ }
182
+
183
+ /**
184
+ * Adds a new dependency to the system
185
+ * @param name
186
+ * @param val
187
+ */
188
+ decorate(name: keyof System, val: any) {
189
+ //@ts-ignore
190
+ this[name] = val;
191
+ }
192
+
193
+ /**
194
+ * Load a plugin into the system
195
+ * @param pluginInit - Plugin initialization function
196
+ * @param options - Optional configuration options for the plugin
197
+ * @template TOptions - Type of options object
198
+ *
199
+ * @example
200
+ * // Plugin without options
201
+ * system.registerPlugin(docsPlugin);
202
+ *
203
+ * @example
204
+ * // Plugin with typed options
205
+ * interface MyPluginOptions {
206
+ * enabled: boolean;
207
+ * apiKey: string;
208
+ * }
209
+ *
210
+ * const myPlugin: Plugin<MyPluginOptions> = (system, options) => {
211
+ * console.log('Plugin enabled:', options.enabled);
212
+ * };
213
+ *
214
+ * system.registerPlugin(myPlugin, { enabled: true, apiKey: 'secret' });
215
+ */
216
+ async registerPlugin<TOptions = void>(
217
+ plugin: LoadablePlugin<TOptions>,
218
+ options?: TOptions
219
+ ): Promise<void> {
220
+ await plugin.loader(this, options as TOptions);
221
+ console.log(`Plugin loaded: ${plugin.opts.name}`);
222
+ }
223
+ }
@@ -0,0 +1,265 @@
1
+ import { Flow } from '@/components/Flow';
2
+ import type { TabBase, TabData } from 'rc-dock';
3
+ import { ErrorBoundary } from 'react-error-boundary';
4
+ import type { System } from './system';
5
+ import { Settings } from '@/components/panels/systemSettings';
6
+ import { LogsPanel } from '@/components/panels/logs';
7
+ import { VariablesPanel } from '@/components/panels/variables';
8
+ import { NodeInputsPanel } from '@/components/panels/nodeInputs';
9
+ import { AlignmentPanel } from '@/components/panels/alignment';
10
+ import { SearchPanel } from '@/components/panels/search';
11
+ import { KeymapsPanel } from '@/components/panels/keymaps';
12
+ import { EventsPanel } from '@/components/panels/events';
13
+ import { TracesPanel } from '@/components/panels/traces';
14
+ import { LegendPanel } from '@/components/panels/legend';
15
+ import { HistoryPanel } from '@/components/panels/history';
16
+ import { HotKeys } from '@/components/hotKeys';
17
+ import { NodePickerPanel } from '@/components/panels/nodePicker';
18
+ import { PanelPanel } from '@/components/panels/panel';
19
+ import { ConversationPanel } from '@/components/panels/conversation';
20
+ import { LayersPanel } from '@/components/panels/layers';
21
+
22
+ export class TabLoader {
23
+ public readonly tabs: Record<string, () => TabData> = {};
24
+
25
+ constructor(_system: System) {
26
+ this.register('graph', () => {
27
+ return {
28
+ id: 'graph',
29
+ closable: true,
30
+ cached: true,
31
+ group: 'graph',
32
+ title: 'Graph',
33
+ content: () => (
34
+ <ErrorBoundary fallback={'whoops'}>
35
+ <HotKeys>
36
+ <Flow />
37
+ </HotKeys>
38
+ </ErrorBoundary>
39
+ )
40
+ };
41
+ });
42
+
43
+ this.register('system:settings', () => {
44
+ return {
45
+ id: 'system:settings',
46
+ closable: true,
47
+ group: 'default',
48
+ title: 'System Settings',
49
+ content: () => (
50
+ <ErrorBoundary fallback={'whoops'}>
51
+ <Settings />
52
+ </ErrorBoundary>
53
+ )
54
+ };
55
+ });
56
+
57
+ this.register('distribution', () => {
58
+ return {
59
+ id: 'distribution',
60
+ closable: true,
61
+ group: 'default',
62
+ title: 'Distribution + Alignment',
63
+ content: () => (
64
+ <ErrorBoundary fallback={'whoops'}>
65
+ <AlignmentPanel />
66
+ </ErrorBoundary>
67
+ )
68
+ };
69
+ });
70
+
71
+ this.register('variables', () => {
72
+ return {
73
+ id: 'variables',
74
+ closable: true,
75
+ title: 'Variables',
76
+ group: 'default',
77
+ content: () => (
78
+ <ErrorBoundary fallback={'whoops'}>
79
+ <VariablesPanel />
80
+ </ErrorBoundary>
81
+ )
82
+ };
83
+ });
84
+
85
+ this.register('logs', () => {
86
+ return {
87
+ id: 'logs',
88
+ closable: true,
89
+ title: 'Logs',
90
+ group: 'default',
91
+ content: () => (
92
+ <ErrorBoundary fallback={'whoops'}>
93
+ <LogsPanel />
94
+ </ErrorBoundary>
95
+ )
96
+ };
97
+ });
98
+ this.register('find', () => {
99
+ return {
100
+ id: 'find',
101
+ closable: true,
102
+ title: 'Find',
103
+ group: 'default',
104
+ content: () => (
105
+ <ErrorBoundary fallback={'whoops'}>
106
+ <SearchPanel />
107
+ </ErrorBoundary>
108
+ )
109
+ };
110
+ });
111
+
112
+ this.register('nodeInputs', () => {
113
+ return {
114
+ id: 'nodeInputs',
115
+ closable: true,
116
+ title: 'Node Inputs',
117
+ group: 'default',
118
+ content: () => (
119
+ <ErrorBoundary fallback={'whoops'}>
120
+ <NodeInputsPanel />
121
+ </ErrorBoundary>
122
+ )
123
+ };
124
+ });
125
+
126
+ this.register('keymaps', () => {
127
+ return {
128
+ id: 'keymaps',
129
+ closable: true,
130
+ title: 'Keyboard Shortcuts',
131
+ group: 'default',
132
+ content: () => (
133
+ <ErrorBoundary fallback={'whoops'}>
134
+ <KeymapsPanel />
135
+ </ErrorBoundary>
136
+ )
137
+ };
138
+ });
139
+
140
+ this.register('events', () => {
141
+ return {
142
+ id: 'events',
143
+ closable: true,
144
+ title: 'Events',
145
+ group: 'default',
146
+ content: () => (
147
+ <ErrorBoundary fallback={'whoops'}>
148
+ <EventsPanel />
149
+ </ErrorBoundary>
150
+ )
151
+ };
152
+ });
153
+
154
+ this.register('traces', () => {
155
+ return {
156
+ id: 'traces',
157
+ closable: true,
158
+ title: 'Traces',
159
+ group: 'default',
160
+ content: () => (
161
+ <ErrorBoundary fallback={'whoops'}>
162
+ <TracesPanel />
163
+ </ErrorBoundary>
164
+ )
165
+ };
166
+ });
167
+
168
+ this.register('legend', () => {
169
+ return {
170
+ id: 'legend',
171
+ closable: true,
172
+ title: 'Legend',
173
+ group: 'default',
174
+ content: () => (
175
+ <ErrorBoundary fallback={'whoops'}>
176
+ <LegendPanel />
177
+ </ErrorBoundary>
178
+ )
179
+ };
180
+ });
181
+
182
+ this.register('history', () => {
183
+ return {
184
+ id: 'history',
185
+ closable: true,
186
+ title: 'History',
187
+ group: 'default',
188
+ content: () => (
189
+ <ErrorBoundary fallback={'whoops'}>
190
+ <HistoryPanel />
191
+ </ErrorBoundary>
192
+ )
193
+ };
194
+ });
195
+
196
+ this.register('layers', () => {
197
+ return {
198
+ id: 'layers',
199
+ closable: true,
200
+ title: 'Layers',
201
+ group: 'default',
202
+ content: () => (
203
+ <ErrorBoundary fallback={'whoops'}>
204
+ <LayersPanel />
205
+ </ErrorBoundary>
206
+ )
207
+ };
208
+ });
209
+
210
+ this.register('nodepicker', () => {
211
+ return {
212
+ id: 'nodepicker',
213
+ closable: true,
214
+ cached: true,
215
+ title: 'Add Node',
216
+ group: 'headless',
217
+ content: () => (
218
+ <ErrorBoundary fallback={'whoops'}>
219
+ <NodePickerPanel />
220
+ </ErrorBoundary>
221
+ )
222
+ };
223
+ });
224
+
225
+ this.register('panels', () => {
226
+ return {
227
+ id: 'panels',
228
+ closable: true,
229
+ title: 'Panels',
230
+ group: 'default',
231
+ content: () => (
232
+ <ErrorBoundary fallback={'whoops'}>
233
+ <PanelPanel />
234
+ </ErrorBoundary>
235
+ )
236
+ };
237
+ });
238
+
239
+ this.register('conversation', () => {
240
+ return {
241
+ id: 'conversation',
242
+ closable: true,
243
+ cached: true,
244
+ title: 'Conversation',
245
+ group: 'default',
246
+ content: () => (
247
+ <ErrorBoundary fallback={'whoops'}>
248
+ <ConversationPanel />
249
+ </ErrorBoundary>
250
+ )
251
+ };
252
+ });
253
+ }
254
+
255
+ load(tab: TabBase): TabData | undefined {
256
+ if (!tab.id) {
257
+ return;
258
+ }
259
+ return this.tabs[tab.id]?.();
260
+ }
261
+
262
+ register(id: string, loader: () => TabData) {
263
+ this.tabs[id] = loader;
264
+ }
265
+ }
@@ -0,0 +1,103 @@
1
+ import { create } from 'zustand';
2
+
3
+ export interface Command {
4
+ name: string;
5
+ execute(): void;
6
+ undo(): void;
7
+ /**
8
+ * Optional redo method if different from execute
9
+ */
10
+ redo?(): void;
11
+ }
12
+
13
+ export type UndoStackEntry = {
14
+ name: string;
15
+ };
16
+
17
+ export type UndoStore = {
18
+ canUndo: boolean;
19
+ canRedo: boolean;
20
+ history: UndoStackEntry[];
21
+ redoStack: UndoStackEntry[];
22
+ setSnapshot: (snapshot: {
23
+ canUndo: boolean;
24
+ canRedo: boolean;
25
+ history: UndoStackEntry[];
26
+ redoStack: UndoStackEntry[];
27
+ }) => void;
28
+ };
29
+
30
+ export const undoStoreFactory = () =>
31
+ create<UndoStore>((set) => ({
32
+ canUndo: false,
33
+ canRedo: false,
34
+ history: [],
35
+ redoStack: [],
36
+ setSnapshot: (snapshot) => set(() => snapshot)
37
+ }));
38
+
39
+ export class UndoManager {
40
+ private history: Command[] = [];
41
+ private stack: Command[] = [];
42
+ private limit = 100; // optional limit
43
+ public store = undoStoreFactory();
44
+
45
+ constructor() {
46
+ this.syncStore();
47
+ }
48
+
49
+ private syncStore() {
50
+ this.store.getState().setSnapshot({
51
+ canUndo: this.canUndo(),
52
+ canRedo: this.canRedo(),
53
+ history: this.history.map((c) => ({ name: c.name })),
54
+ redoStack: this.stack.map((c) => ({ name: c.name }))
55
+ });
56
+ }
57
+
58
+ execute(command: Command) {
59
+ command.execute();
60
+ this.history.push(command);
61
+ this.stack = []; // clear redo stack
62
+
63
+ if (this.history.length > this.limit) {
64
+ this.history.shift();
65
+ }
66
+
67
+ this.syncStore();
68
+ }
69
+
70
+ undo() {
71
+ const command = this.history.pop();
72
+ if (command) {
73
+ command.undo();
74
+ this.stack.push(command);
75
+ this.syncStore();
76
+ }
77
+ }
78
+
79
+ redo() {
80
+ const command = this.stack.pop();
81
+ if (command) {
82
+ if (command.redo) {
83
+ command.redo();
84
+ } else {
85
+ command.execute();
86
+ }
87
+ this.history.push(command);
88
+ this.syncStore();
89
+ }
90
+ }
91
+
92
+ canUndo() {
93
+ return this.history.length > 0;
94
+ }
95
+ canRedo() {
96
+ return this.stack.length > 0;
97
+ }
98
+ clear() {
99
+ this.history = [];
100
+ this.stack = [];
101
+ this.syncStore();
102
+ }
103
+ }
@@ -0,0 +1,60 @@
1
+ import type { System } from '@/system/system';
2
+ import { annotatedTitle, uiVersion } from '@/annotations';
3
+ import type { UIGraphJSON } from '@/types/graph';
4
+
5
+ const DEFAULT_UI_GRAPH_VERSION = '1.0.0';
6
+ const DEFAULT_UI_GRAPH_NAME = 'Untitled Graph';
7
+
8
+ function getStringAnnotation(
9
+ annotations: Record<string, unknown>,
10
+ key: string
11
+ ): string | undefined {
12
+ const value = annotations[key];
13
+ return typeof value === 'string' && value.trim().length > 0
14
+ ? value
15
+ : undefined;
16
+ }
17
+
18
+ /**
19
+ * Assembles the full UI graph definition for saving.
20
+ */
21
+ export function buildUIGraphJSON(system: System): UIGraphJSON {
22
+ system.flowStore.getState().invalidateCache();
23
+
24
+ const flow = system.flowStore.getState().getGraph();
25
+ const nodes = system.nodeStore.getState().nodes;
26
+ const edges = system.edgeStore.getState().edges;
27
+
28
+ const annotations = system.graph.getAnnotations?.() ?? {};
29
+
30
+ const reactflow = system.refStore.getState().getRef('reactflow');
31
+ const viewport = reactflow?.getViewport?.() ??
32
+ system.graph.viewports[0] ?? { x: 0, y: 0, zoom: 1 };
33
+
34
+ const graphVersion =
35
+ getStringAnnotation(annotations, uiVersion) ?? DEFAULT_UI_GRAPH_VERSION;
36
+ const graphName =
37
+ getStringAnnotation(annotations, annotatedTitle) ??
38
+ flow.name ??
39
+ DEFAULT_UI_GRAPH_NAME;
40
+
41
+ const viewports = system.graph.viewports.length
42
+ ? system.graph.viewports.map((v) => ({ x: v.x, y: v.y, zoom: v.zoom }))
43
+ : undefined;
44
+
45
+ return {
46
+ v: graphVersion,
47
+ name: graphName,
48
+ annotations,
49
+ data: {
50
+ layers: system.layerStore.getState().serialize()
51
+ },
52
+ flow,
53
+ nodes,
54
+ edges,
55
+ user: {
56
+ viewport: { x: viewport.x, y: viewport.y, zoom: viewport.zoom },
57
+ viewports
58
+ }
59
+ };
60
+ }
@@ -1,3 +1,4 @@
1
+ import type { IBehaveNode } from '@/types/nodes';
1
2
  import type { GraphJSON } from '@kiberon-labs/behave-graph';
2
3
  import type { Edge, Node } from 'reactflow';
3
4
  import { v4 as uuidv4 } from 'uuid';
@@ -7,9 +8,9 @@ export const behaveToFlow = (graph: GraphJSON): [Node[], Edge[]] => {
7
8
  const edges: Edge[] = [];
8
9
 
9
10
  graph.nodes?.forEach((nodeJSON) => {
10
- const node: Node = {
11
+ const node: IBehaveNode = {
11
12
  id: nodeJSON.id,
12
- type: nodeJSON.type,
13
+ type: 'behaveNode',
13
14
  position: {
14
15
  x: nodeJSON.metadata?.positionX
15
16
  ? Number(nodeJSON.metadata?.positionX)
@@ -18,11 +19,21 @@ export const behaveToFlow = (graph: GraphJSON): [Node[], Edge[]] => {
18
19
  ? Number(nodeJSON.metadata?.positionY)
19
20
  : 0
20
21
  },
21
- data: {} as { [key: string]: any }
22
+ data: {
23
+ annotations: {},
24
+ configuration: {},
25
+ type: nodeJSON.type,
26
+ ports: {},
27
+ dynamicPorts: {}
28
+ }
22
29
  };
23
30
 
24
31
  nodes.push(node);
25
32
 
33
+ if (nodeJSON.configuration && typeof nodeJSON.configuration === 'object') {
34
+ node.data.configuration = { ...nodeJSON.configuration };
35
+ }
36
+
26
37
  if (nodeJSON.parameters) {
27
38
  for (const [inputKey, input] of Object.entries(nodeJSON.parameters)) {
28
39
  if ('link' in input && input.link !== undefined) {
@@ -35,7 +46,8 @@ export const behaveToFlow = (graph: GraphJSON): [Node[], Edge[]] => {
35
46
  });
36
47
  }
37
48
  if ('value' in input) {
38
- node.data[inputKey] = input.value;
49
+ node.data.ports ??= {};
50
+ node.data.ports[inputKey] = input.value;
39
51
  }
40
52
  }
41
53
  }