@kiberon-labs/behave-graph-flow 1.0.0 → 3.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 (378) hide show
  1. package/.fallowrc.json +16 -0
  2. package/.storybook/main.ts +32 -0
  3. package/.storybook/manager.ts +6 -0
  4. package/.storybook/preview.ts +64 -0
  5. package/.storybook/styles.css +16 -0
  6. package/.turbo/turbo-build.log +7 -0
  7. package/CHANGELOG.md +368 -0
  8. package/LICENSE +6 -0
  9. package/README.md +2 -2
  10. package/data/Polynomial.json +510 -0
  11. package/data/sequence.json +337 -0
  12. package/data/trigger-event.json +241 -0
  13. package/data/variable-change.json +210 -0
  14. package/dist/AnyControlImpl-Ds-CShIB.js +20 -0
  15. package/dist/AnyControlImpl-Ds-CShIB.js.map +1 -0
  16. package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js +166 -0
  17. package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js.map +1 -0
  18. package/dist/entry.css +4 -0
  19. package/dist/index.css +42 -0
  20. package/dist/index.css.map +1 -0
  21. package/dist/index.d.ts +3597 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +18009 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/noteImpl-KkrrWgJd.js +242 -0
  26. package/dist/noteImpl-KkrrWgJd.js.map +1 -0
  27. package/dist/styles.module-CvmpDkZj.css +3 -0
  28. package/dist/styles.module-CvmpDkZj.css.map +1 -0
  29. package/dist/styles.module-DZxg8aW9.js +271 -0
  30. package/dist/styles.module-DZxg8aW9.js.map +1 -0
  31. package/dist/useChangeNodeData-ChQGK7AI.js +23 -0
  32. package/dist/useChangeNodeData-ChQGK7AI.js.map +1 -0
  33. package/docs/notifications.md +246 -0
  34. package/docs/protocol.md +702 -0
  35. package/docs/specifics.md +191 -0
  36. package/package.json +82 -22
  37. package/postcss.config.ts +3 -4
  38. package/src/annotations/index.ts +32 -0
  39. package/src/components/FloatingToolbar/index.module.css +37 -0
  40. package/src/components/FloatingToolbar/index.tsx +256 -0
  41. package/src/components/Flow.tsx +287 -75
  42. package/src/components/contextMenus/DynamicContextMenu.tsx +85 -0
  43. package/src/components/contextMenus/NodePicker.module.css +274 -0
  44. package/src/components/contextMenus/NodePicker.tsx +481 -0
  45. package/src/components/contextMenus/edge.tsx +22 -0
  46. package/src/components/contextMenus/node.tsx +15 -0
  47. package/src/components/contextMenus/selection.tsx +11 -0
  48. package/src/components/controls/any/AnyControlImpl.tsx +14 -0
  49. package/src/components/controls/any/index.tsx +19 -0
  50. package/src/components/controls/boolean/index.tsx +13 -0
  51. package/src/components/controls/colorPicker/InputPopover.module.css +100 -0
  52. package/src/components/controls/colorPicker/InputPopover.tsx +31 -0
  53. package/src/components/controls/colorPicker/index.module.css +18 -0
  54. package/src/components/controls/colorPicker/index.tsx +61 -0
  55. package/src/components/controls/number/index.tsx +35 -0
  56. package/src/components/controls/string/index.tsx +16 -0
  57. package/src/components/edges/index.tsx +475 -0
  58. package/src/components/edges/offsetBezier.ts +134 -0
  59. package/src/components/hotKeys.tsx +20 -0
  60. package/src/components/layoutController/index.module.css +13 -0
  61. package/src/components/layoutController/index.tsx +140 -0
  62. package/src/components/layoutController/utils.ts +248 -0
  63. package/src/components/menubar/defaults.tsx +516 -0
  64. package/src/components/menubar/index.tsx +49 -0
  65. package/src/components/menubar/menuItem.module.css +31 -0
  66. package/src/components/menubar/menuItem.tsx +65 -0
  67. package/src/components/nodes/behave/Node.module.css +23 -0
  68. package/src/components/nodes/behave/Node.tsx +176 -0
  69. package/src/components/nodes/behave/NodeContainer.module.css +88 -0
  70. package/src/components/nodes/behave/NodeContainer.tsx +46 -0
  71. package/src/components/nodes/behave/index.tsx +14 -0
  72. package/src/components/nodes/group/index.tsx +109 -0
  73. package/src/components/nodes/wrapper/index.tsx +73 -0
  74. package/src/components/nodes/wrapper/styles.module.css +87 -0
  75. package/src/components/notifications/NotificationProvider.tsx +81 -0
  76. package/src/components/notifications/index.ts +2 -0
  77. package/src/components/notifications/utils.ts +71 -0
  78. package/src/components/panels/alignment/index.module.css +10 -0
  79. package/src/components/panels/alignment/index.tsx +244 -0
  80. package/src/components/panels/base/index.tsx +5 -0
  81. package/src/components/panels/base/styles.module.css +12 -0
  82. package/src/components/panels/common/PanelHeader.module.css +24 -0
  83. package/src/components/panels/common/PanelHeader.tsx +22 -0
  84. package/src/components/panels/common/SectionTitle.module.css +13 -0
  85. package/src/components/panels/common/SectionTitle.tsx +10 -0
  86. package/src/components/panels/events/EditEventPanel.tsx +324 -0
  87. package/src/components/panels/events/ManageEventsPanel.tsx +101 -0
  88. package/src/components/panels/events/index.tsx +23 -0
  89. package/src/components/panels/events/styles.module.css +178 -0
  90. package/src/components/panels/graphProperties/index.tsx +125 -0
  91. package/src/components/panels/history/index.tsx +92 -0
  92. package/src/components/panels/history/styles.module.css +97 -0
  93. package/src/components/panels/keymaps/index.module.css +68 -0
  94. package/src/components/panels/keymaps/index.tsx +166 -0
  95. package/src/components/panels/layers/index.tsx +245 -0
  96. package/src/components/panels/layers/styles.module.css +107 -0
  97. package/src/components/panels/legend/index.module.css +6 -0
  98. package/src/components/panels/legend/index.tsx +76 -0
  99. package/src/components/panels/logs/index.module.css +218 -0
  100. package/src/components/panels/logs/index.tsx +288 -0
  101. package/src/components/panels/nodeInputs/InputControl.tsx +63 -0
  102. package/src/components/panels/nodeInputs/InputsGroup.tsx +65 -0
  103. package/src/components/panels/nodeInputs/MultipleNodesView.tsx +37 -0
  104. package/src/components/panels/nodeInputs/NodeSettings.tsx +92 -0
  105. package/src/components/panels/nodeInputs/NodeTitleEditor.tsx +125 -0
  106. package/src/components/panels/nodeInputs/OutputsGroup.tsx +55 -0
  107. package/src/components/panels/nodeInputs/SocketGenerators.tsx +32 -0
  108. package/src/components/panels/nodeInputs/index.module.css +308 -0
  109. package/src/components/panels/nodeInputs/index.tsx +349 -0
  110. package/src/components/panels/nodeInputs/useNodeHandlers.ts +76 -0
  111. package/src/components/panels/nodeInputs/useNodeInputsData.ts +153 -0
  112. package/src/components/panels/nodePicker/index.tsx +115 -0
  113. package/src/components/panels/panel/index.module.css +66 -0
  114. package/src/components/panels/panel/index.tsx +88 -0
  115. package/src/components/panels/search/index.module.css +16 -0
  116. package/src/components/panels/search/index.tsx +215 -0
  117. package/src/components/panels/systemSettings/ConversionsSettings.tsx +203 -0
  118. package/src/components/panels/systemSettings/index.tsx +251 -0
  119. package/src/components/panels/systemSettings/styles.module.css +138 -0
  120. package/src/components/panels/traces/GridLines.tsx +38 -0
  121. package/src/components/panels/traces/TimeGrid.tsx +48 -0
  122. package/src/components/panels/traces/TraceLane.tsx +62 -0
  123. package/src/components/panels/traces/TraceTooltip.tsx +22 -0
  124. package/src/components/panels/traces/TracesHeader.tsx +56 -0
  125. package/src/components/panels/traces/index.module.css +159 -0
  126. package/src/components/panels/traces/index.tsx +298 -0
  127. package/src/components/panels/traces/types.ts +48 -0
  128. package/src/components/panels/traces/useDerivedSpans.ts +307 -0
  129. package/src/components/panels/traces/utils.ts +33 -0
  130. package/src/components/panels/variables/CreateVariableScreen.tsx +162 -0
  131. package/src/components/panels/variables/ManageVariablesScreen.tsx +147 -0
  132. package/src/components/panels/variables/index.tsx +125 -0
  133. package/src/components/panels/variables/styles.module.css +149 -0
  134. package/src/components/primitives/icon.module.css +45 -0
  135. package/src/components/primitives/icon.tsx +38 -0
  136. package/src/components/sockets/input/index.tsx +83 -0
  137. package/src/components/sockets/input/styles.module.css +26 -0
  138. package/src/components/sockets/output/index.tsx +68 -0
  139. package/src/components/sockets/output/styles.module.css +22 -0
  140. package/src/css/notes.css +135 -0
  141. package/src/css/prosemirror.css +57 -0
  142. package/src/css/rc-dock.css +212 -0
  143. package/src/css/rc-menu.css +101 -0
  144. package/src/css/themes/kiberon.css +127 -0
  145. package/src/css/vars.css +198 -0
  146. package/src/css/vscode-elements.css +124 -0
  147. package/src/entry.css +4 -0
  148. package/src/generators/CallSubgraphGenerator.tsx +136 -0
  149. package/src/generators/CustomEventOnTriggeredGenerator.tsx +85 -0
  150. package/src/generators/GraphBoundaryGenerator.module.css +32 -0
  151. package/src/generators/GraphBoundaryGenerator.tsx +193 -0
  152. package/src/generators/SequenceGenerator.tsx +104 -0
  153. package/src/generators/SwitchOnIntegerGenerator.tsx +256 -0
  154. package/src/generators/SwitchOnStringGenerator.tsx +263 -0
  155. package/src/generators/callSubgraphSync.ts +126 -0
  156. package/src/generators/registerDefaultGenerators.ts +55 -0
  157. package/src/generators/registerDefaults.ts +26 -0
  158. package/src/hooks/useBehaveGraphFlow.ts +17 -16
  159. package/src/hooks/useFlowHandlers.ts +154 -30
  160. package/src/hooks/useWasdPan.ts +210 -0
  161. package/src/index.css +134 -0
  162. package/src/index.ts +53 -18
  163. package/src/manifest/contributionRegistry.ts +93 -0
  164. package/src/manifest/index.ts +4 -0
  165. package/src/manifest/loadManifest.ts +82 -0
  166. package/src/manifest/manifestPlugin.ts +29 -0
  167. package/src/manifest/passthroughValueType.ts +40 -0
  168. package/src/plugin/alignment/index.ts +91 -0
  169. package/src/plugin/autosave/controller.ts +366 -0
  170. package/src/plugin/autosave/index.tsx +114 -0
  171. package/src/plugin/autosave/panel/BackupPanel.tsx +141 -0
  172. package/src/plugin/autosave/panel/index.tsx +1 -0
  173. package/src/plugin/autosave/panel/styles.module.css +56 -0
  174. package/src/plugin/autosave/settings.ts +65 -0
  175. package/src/plugin/autosave/storage.ts +147 -0
  176. package/src/plugin/docs/index.tsx +297 -0
  177. package/src/plugin/docs/panel/DocumentationBrowserPanelImpl.tsx +200 -0
  178. package/src/plugin/docs/panel/index.tsx +21 -0
  179. package/src/plugin/docs/panel/styles.module.css +174 -0
  180. package/src/plugin/graphrunner/actions.ts +326 -0
  181. package/src/plugin/graphrunner/buttons.tsx +95 -0
  182. package/src/plugin/graphrunner/client.ts +707 -0
  183. package/src/plugin/graphrunner/index.tsx +184 -0
  184. package/src/plugin/graphrunner/panel.tsx +386 -0
  185. package/src/plugin/graphrunner/runController.ts +283 -0
  186. package/src/plugin/graphrunner/runner.ts +187 -0
  187. package/src/plugin/graphrunner/session.ts +243 -0
  188. package/src/plugin/graphrunner/store.ts +196 -0
  189. package/src/plugin/graphrunner/styles.module.css +171 -0
  190. package/src/plugin/graphrunner/transport.ts +250 -0
  191. package/src/plugin/graphrunner/types.ts +693 -0
  192. package/src/plugin/graphrunner-local/execution-utils.ts +637 -0
  193. package/src/plugin/graphrunner-local/index.tsx +172 -0
  194. package/src/plugin/graphrunner-local/panel.tsx +187 -0
  195. package/src/plugin/graphrunner-local/store.ts +41 -0
  196. package/src/plugin/graphrunner-local/styles.module.css +82 -0
  197. package/src/plugin/graphrunner-local/transport.ts +1339 -0
  198. package/src/plugin/graphrunner-local/types.ts +10 -0
  199. package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +635 -0
  200. package/src/plugin/graphrunner-webworker/index.tsx +140 -0
  201. package/src/plugin/graphrunner-webworker/panel.tsx +173 -0
  202. package/src/plugin/graphrunner-webworker/store.ts +98 -0
  203. package/src/plugin/graphrunner-webworker/worker-transport.ts +123 -0
  204. package/src/plugin/kitchen-sink/index.ts +38 -0
  205. package/src/plugin/layout/dagre.ts +131 -0
  206. package/src/plugin/layout/elk.ts +216 -0
  207. package/src/plugin/layout/index.ts +80 -0
  208. package/src/plugin/notes/FormatToolbar.tsx +200 -0
  209. package/src/plugin/notes/index.tsx +191 -0
  210. package/src/plugin/notes/nodeActions.ts +100 -0
  211. package/src/plugin/notes/note.tsx +20 -0
  212. package/src/plugin/notes/noteImpl.tsx +89 -0
  213. package/src/plugin/realtime/realtimeRunner.ts +624 -0
  214. package/src/specifics/CustomEventOnTriggeredSpecific.tsx +92 -0
  215. package/src/specifics/CustomEventTriggerSpecific.tsx +141 -0
  216. package/src/specifics/VariableGetSpecific.tsx +110 -0
  217. package/src/specifics/VariableSetSpecific.tsx +110 -0
  218. package/src/store/actions.tsx +698 -0
  219. package/src/store/commands.ts +278 -0
  220. package/src/store/contextMenu.ts +192 -0
  221. package/src/store/controls.tsx +62 -0
  222. package/src/store/conversions.ts +47 -0
  223. package/src/store/documentation.tsx +69 -0
  224. package/src/store/events.tsx +116 -0
  225. package/src/store/flow.tsx +230 -0
  226. package/src/store/graphMeta.ts +39 -0
  227. package/src/store/hotKeys.tsx +364 -0
  228. package/src/store/layers.ts +259 -0
  229. package/src/store/legend.tsx +76 -0
  230. package/src/store/logs.ts +28 -0
  231. package/src/store/menubar.ts +41 -0
  232. package/src/store/refs.ts +84 -0
  233. package/src/store/registry.ts +51 -0
  234. package/src/store/selection.ts +22 -0
  235. package/src/store/settings.ts +99 -0
  236. package/src/store/settingsSchema.ts +210 -0
  237. package/src/store/socketGenerator.tsx +54 -0
  238. package/src/store/specific.tsx +75 -0
  239. package/src/store/specs.tsx +35 -0
  240. package/src/store/tabs.ts +282 -0
  241. package/src/store/toolbar.tsx +45 -0
  242. package/src/store/traces.ts +240 -0
  243. package/src/store/variables.ts +37 -0
  244. package/src/system/graph.ts +131 -0
  245. package/src/system/graphSession.ts +172 -0
  246. package/src/system/index.ts +6 -0
  247. package/src/system/notifications.ts +111 -0
  248. package/src/system/persistence.ts +82 -0
  249. package/src/system/plugin.ts +55 -0
  250. package/src/system/provider.tsx +86 -0
  251. package/src/system/pubsub.ts +323 -0
  252. package/src/system/system.ts +653 -0
  253. package/src/system/tabLoader.tsx +303 -0
  254. package/src/system/undoRedo.ts +103 -0
  255. package/src/transformers/Uigraph.ts +61 -0
  256. package/src/transformers/behaveToFlow.ts +16 -4
  257. package/src/transformers/contract.ts +87 -0
  258. package/src/transformers/flowToBehave.ts +40 -12
  259. package/src/types/NodeMetadata.ts +27 -0
  260. package/src/types/graph.ts +49 -0
  261. package/src/types/nodes.ts +50 -0
  262. package/src/types.ts +18 -0
  263. package/src/util/autoConvert.ts +200 -0
  264. package/src/util/colors.ts +1 -29
  265. package/src/util/downloadJson.ts +18 -0
  266. package/src/util/extractNodeMetadata.ts +16 -0
  267. package/src/util/getPickerFilters.ts +1 -1
  268. package/src/util/isBehaveNode.ts +6 -0
  269. package/src/util/isValidConnection.ts +51 -17
  270. package/src/util/mergeSockets.ts +29 -0
  271. package/src/util/serializeVariables.ts +66 -0
  272. package/src/util/sockets.ts +43 -0
  273. package/stories/apex/layoutController/example-graph.worker.ts +39 -0
  274. package/stories/apex/layoutController/index.stories.tsx +48 -0
  275. package/stories/apex/layoutController/webworker.stories.tsx +103 -0
  276. package/stories/apex/menubar/menubar.stories.tsx +19 -0
  277. package/stories/components/colorpicker/index.stories.tsx +20 -0
  278. package/stories/components/contextMenus/edge.stories.tsx +32 -0
  279. package/stories/components/contextMenus/node.stories.tsx +26 -0
  280. package/stories/components/contextMenus/nodePicker.stories.tsx +115 -0
  281. package/stories/components/controls/any/index.stories.tsx +19 -0
  282. package/stories/components/controls/boolean/index.stories.tsx +19 -0
  283. package/stories/components/controls/colorPicker/index.stories.tsx +49 -0
  284. package/stories/components/controls/number/index.stories.tsx +19 -0
  285. package/stories/components/controls/string/index.stories.tsx +19 -0
  286. package/stories/components/nodes/behaveNode.stories.tsx +108 -0
  287. package/stories/components/panels/alignment.stories.tsx +24 -0
  288. package/stories/components/panels/events.stories.tsx +38 -0
  289. package/stories/components/panels/graphRunner.stories.tsx +317 -0
  290. package/stories/components/panels/history.stories.tsx +37 -0
  291. package/stories/components/panels/keymaps.stories.tsx +21 -0
  292. package/stories/components/panels/legend.stories.tsx +37 -0
  293. package/stories/components/panels/logs.stories.tsx +24 -0
  294. package/stories/components/panels/nodeInputs.stories.tsx +21 -0
  295. package/stories/components/panels/nodePicker.stories.tsx +37 -0
  296. package/stories/components/panels/panel.stories.tsx +39 -0
  297. package/stories/components/panels/search.stories.tsx +24 -0
  298. package/stories/components/panels/systemSettings.stories.tsx +26 -0
  299. package/stories/components/panels/traces.stories.tsx +225 -0
  300. package/stories/components/panels/variables.stories.tsx +24 -0
  301. package/stories/defaults/defaultStoryProvider.tsx +170 -0
  302. package/stories/defaults/systemGenerator.ts +43 -0
  303. package/stories/plugins/notes.stories.tsx +100 -0
  304. package/tests/autoConvert.test.ts +329 -0
  305. package/tests/autosavePlugin.test.ts +204 -0
  306. package/tests/callSubgraphSync.test.ts +148 -0
  307. package/tests/commandRegistry.test.ts +137 -0
  308. package/tests/components/edges/offsetBezier.test.ts +51 -0
  309. package/tests/components/layoutController/utils.test.ts +68 -0
  310. package/tests/components/panels/traces/utils.test.ts +52 -0
  311. package/tests/contract.test.ts +51 -0
  312. package/tests/contractSerialize.test.ts +62 -0
  313. package/tests/deriveSpans.test.ts +71 -0
  314. package/tests/flowToBehave.test.ts +27 -4
  315. package/tests/hotkeys.test.ts +79 -0
  316. package/tests/keepAliveLifecycle.test.ts +167 -0
  317. package/tests/loadManifest.test.ts +113 -0
  318. package/tests/noteMarkdown.test.ts +65 -0
  319. package/tests/notesPlugin.test.ts +162 -0
  320. package/tests/notifications.test.ts +87 -0
  321. package/tests/persistence.test.ts +51 -0
  322. package/tests/saveLoad.test.ts +373 -0
  323. package/tests/settings.test.ts +178 -0
  324. package/tests/traceStore.test.ts +46 -0
  325. package/tests/util/calculateNewEdge.test.ts +98 -0
  326. package/tests/util/getSocketsByNodeTypeAndHandleType.test.ts +31 -0
  327. package/tests/util/hasPositionMetaData.test.ts +33 -0
  328. package/tests/util/isBehaveNode.test.ts +22 -0
  329. package/tests/util/isHandleConnected.test.ts +37 -0
  330. package/tests/util/mergeSockets.test.ts +43 -0
  331. package/tests/visual/README.md +64 -0
  332. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-alignment-chromium-win32.png +0 -0
  333. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-conversation-chromium-win32.png +0 -0
  334. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-events-chromium-win32.png +0 -0
  335. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-history-chromium-win32.png +0 -0
  336. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-keymaps-chromium-win32.png +0 -0
  337. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-layers-chromium-win32.png +0 -0
  338. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-legend-chromium-win32.png +0 -0
  339. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-localGraphRunner-chromium-win32.png +0 -0
  340. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-logs-chromium-win32.png +0 -0
  341. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodeInputs-chromium-win32.png +0 -0
  342. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodePicker-chromium-win32.png +0 -0
  343. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-panel-chromium-win32.png +0 -0
  344. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-search-chromium-win32.png +0 -0
  345. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-systemSettings-chromium-win32.png +0 -0
  346. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-traces-chromium-win32.png +0 -0
  347. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-variables-chromium-win32.png +0 -0
  348. package/tests/visual/panels.visual.test.tsx +76 -0
  349. package/tests/wasdPan.test.ts +71 -0
  350. package/tsconfig.base.json +39 -0
  351. package/tsconfig.json +18 -59
  352. package/tsconfig.prod.json +23 -0
  353. package/tsdown.config.ts +15 -3
  354. package/typedoc.json +7 -7
  355. package/vite.config.js +7 -0
  356. package/vitest.config.ts +5 -2
  357. package/vitest.visual.config.ts +55 -0
  358. package/src/components/AutoSizeInput.tsx +0 -65
  359. package/src/components/Controls.tsx +0 -87
  360. package/src/components/InputSocket.tsx +0 -142
  361. package/src/components/Node.tsx +0 -68
  362. package/src/components/NodeContainer.tsx +0 -46
  363. package/src/components/NodePicker.tsx +0 -77
  364. package/src/components/OutputSocket.tsx +0 -58
  365. package/src/components/modals/ClearModal.tsx +0 -40
  366. package/src/components/modals/HelpModal.tsx +0 -36
  367. package/src/components/modals/LoadModal.tsx +0 -96
  368. package/src/components/modals/Modal.tsx +0 -64
  369. package/src/components/modals/SaveModal.tsx +0 -60
  370. package/src/hooks/useCustomNodeTypes.tsx +0 -31
  371. package/src/hooks/useGraphRunner.ts +0 -104
  372. package/src/hooks/useMergeMap.ts +0 -14
  373. package/src/hooks/useNodeSpecJson.ts +0 -20
  374. package/src/hooks/useQueriableDefinitions.ts +0 -22
  375. package/src/styles.css +0 -8
  376. package/tailwind.config.ts +0 -19
  377. package/tests/tsconfig.json +0 -10
  378. /package/src/{types.d.ts → types-declarations.d.ts} +0 -0
@@ -0,0 +1,349 @@
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { useActiveGraph, GraphProvider } from '@/system/provider';
3
+ import {
4
+ VscodeTabHeader,
5
+ VscodeTabPanel,
6
+ VscodeTabs,
7
+ VscodeToolbarContainer
8
+ } from '@vscode-elements/react-elements';
9
+ import { useStore } from 'zustand';
10
+ import {
11
+ findTabInLayout,
12
+ removeTabFromLayout,
13
+ addFloatingTab
14
+ } from '@/components/layoutController/utils';
15
+
16
+ import styles from './index.module.css';
17
+ import { BasePanel } from '../base';
18
+ import { NodeTitleEditor } from './NodeTitleEditor';
19
+ import { MultipleNodesView } from './MultipleNodesView';
20
+ import { SocketGenerators } from './SocketGenerators';
21
+ import { InputsGroup } from './InputsGroup';
22
+ import { OutputsGroup } from './OutputsGroup';
23
+ import { NodeSettings } from './NodeSettings';
24
+ import { useNodeInputsData } from './useNodeInputsData';
25
+ import { useNodeHandlers } from './useNodeHandlers';
26
+ import { EyeClosed, EyeSolid } from 'iconoir-react';
27
+ import { Icon } from '@/components/primitives/icon';
28
+
29
+ export function NodeInputsPanel() {
30
+ const system = useActiveGraph()!;
31
+ const documentation = useStore(
32
+ system.editor.documentationStore,
33
+ (x) => x.docs
34
+ );
35
+
36
+ const {
37
+ allSpecsJson,
38
+ selectedNodes,
39
+ selectedNode,
40
+ nodeSpec,
41
+ inputsWithControls,
42
+ outputsWithInfo,
43
+ matchingGenerators,
44
+ generatorNode,
45
+ controls,
46
+ defaultControl
47
+ } = useNodeInputsData(system);
48
+
49
+ const { handleSaveTitle, handleValueChange } = useNodeHandlers(
50
+ system,
51
+ selectedNode
52
+ );
53
+
54
+ const hiddenInputs = useMemo(() => {
55
+ return selectedNode?.data.annotations?.hiddenInputs ?? {};
56
+ }, [selectedNode]);
57
+
58
+ const hiddenOutputs = useMemo(() => {
59
+ return selectedNode?.data.annotations?.hiddenOutputs ?? {};
60
+ }, [selectedNode]);
61
+
62
+ const handleToggleInput = useCallback(
63
+ (inputName: string) => {
64
+ if (!selectedNode) return;
65
+
66
+ const currentHidden = hiddenInputs[inputName] ?? false;
67
+ const newHiddenInputs = {
68
+ ...hiddenInputs,
69
+ [inputName]: !currentHidden
70
+ };
71
+
72
+ system.nodeStore.getState().setNodes((prev) =>
73
+ prev.map((n) =>
74
+ n.id === selectedNode.id
75
+ ? {
76
+ ...n,
77
+ data: {
78
+ ...(n as any).data,
79
+ annotations: {
80
+ ...(n as any).data.annotations,
81
+ hiddenInputs: newHiddenInputs
82
+ }
83
+ }
84
+ }
85
+ : n
86
+ )
87
+ );
88
+ },
89
+ [selectedNode, hiddenInputs, system]
90
+ );
91
+
92
+ const handleToggleOutput = useCallback(
93
+ (outputName: string) => {
94
+ if (!selectedNode) return;
95
+
96
+ const currentHidden = hiddenOutputs[outputName] ?? false;
97
+ const newHiddenOutputs = {
98
+ ...hiddenOutputs,
99
+ [outputName]: !currentHidden
100
+ };
101
+
102
+ system.nodeStore.getState().setNodes((prev) =>
103
+ prev.map((n) =>
104
+ n.id === selectedNode.id
105
+ ? {
106
+ ...n,
107
+ data: {
108
+ ...(n as any).data,
109
+ annotations: {
110
+ ...(n as any).data.annotations,
111
+ hiddenOutputs: newHiddenOutputs
112
+ }
113
+ }
114
+ }
115
+ : n
116
+ )
117
+ );
118
+ },
119
+ [selectedNode, hiddenOutputs, system]
120
+ );
121
+
122
+ const handleToggleAllInputs = useCallback(() => {
123
+ if (!selectedNode) return;
124
+
125
+ const allHidden = inputsWithControls.every(
126
+ (input) => hiddenInputs[input.name]
127
+ );
128
+ const newHiddenInputs: Record<string, boolean> = {};
129
+
130
+ inputsWithControls.forEach((input) => {
131
+ newHiddenInputs[input.name] = !allHidden;
132
+ });
133
+
134
+ system.nodeStore.getState().setNodes((prev) =>
135
+ prev.map((n) =>
136
+ n.id === selectedNode.id
137
+ ? {
138
+ ...n,
139
+ data: {
140
+ ...(n as any).data,
141
+ annotations: {
142
+ ...(n as any).data.annotations,
143
+ hiddenInputs: newHiddenInputs
144
+ }
145
+ }
146
+ }
147
+ : n
148
+ )
149
+ );
150
+ }, [selectedNode, inputsWithControls, hiddenInputs, system]);
151
+
152
+ const handleToggleAllOutputs = useCallback(() => {
153
+ if (!selectedNode) return;
154
+
155
+ const allHidden = outputsWithInfo.every(
156
+ (output) => hiddenOutputs[output.name]
157
+ );
158
+ const newHiddenOutputs: Record<string, boolean> = {};
159
+
160
+ outputsWithInfo.forEach((output) => {
161
+ newHiddenOutputs[output.name] = !allHidden;
162
+ });
163
+
164
+ system.nodeStore.getState().setNodes((prev) =>
165
+ prev.map((n) =>
166
+ n.id === selectedNode.id
167
+ ? {
168
+ ...n,
169
+ data: {
170
+ ...(n as any).data,
171
+ annotations: {
172
+ ...(n as any).data.annotations,
173
+ hiddenOutputs: newHiddenOutputs
174
+ }
175
+ }
176
+ }
177
+ : n
178
+ )
179
+ );
180
+ }, [selectedNode, outputsWithInfo, hiddenOutputs, system]);
181
+
182
+ const handleShowDocumentation = useCallback(
183
+ (nodeType: string) => {
184
+ // Set the selected documentation type
185
+ system.refStore.getState().setRef('selectedDocumentationType', nodeType);
186
+
187
+ // Open documentation browser panel
188
+ const currentLayout = system.editor.tabStore.getState().layout;
189
+
190
+ // Close existing doc browser if open
191
+ const existingPanel = findTabInLayout(currentLayout, 'docbrowser');
192
+ let layoutToUse = currentLayout;
193
+ if (existingPanel) {
194
+ layoutToUse = removeTabFromLayout(currentLayout, 'docbrowser');
195
+ }
196
+
197
+ // Create new floating panel
198
+ const tabData = {
199
+ id: 'docbrowser'
200
+ };
201
+
202
+ const newLayout = addFloatingTab(layoutToUse, tabData, {
203
+ left: 100,
204
+ top: 100,
205
+ width: 600,
206
+ height: 700
207
+ });
208
+
209
+ system.editor.tabStore.getState().setLayout(newLayout);
210
+ },
211
+ [system]
212
+ );
213
+
214
+ const hasDocumentation = useCallback(
215
+ (nodeType: string) => {
216
+ const doc = documentation?.get(nodeType);
217
+ return !!(doc?.markdownDescription || doc?.shortDescription);
218
+ },
219
+ [documentation]
220
+ );
221
+
222
+ const getNodeIcon = useCallback(
223
+ (nodeType: string) => {
224
+ const doc = documentation?.get(nodeType);
225
+ return doc?.icon;
226
+ },
227
+ [documentation]
228
+ );
229
+
230
+ // Handle multiple node selection
231
+ if (selectedNodes.length > 1) {
232
+ return (
233
+ <MultipleNodesView
234
+ selectedNodes={selectedNodes}
235
+ allSpecsJson={allSpecsJson}
236
+ />
237
+ );
238
+ }
239
+
240
+ if (!selectedNode || !nodeSpec) {
241
+ return (
242
+ <BasePanel>
243
+ <div className={styles.emptyState}>
244
+ No node selected. Select a node to edit its inputs.
245
+ </div>
246
+ </BasePanel>
247
+ );
248
+ }
249
+
250
+ return (
251
+ <BasePanel>
252
+ <NodeTitleEditor
253
+ selectedNode={selectedNode}
254
+ nodeLabel={nodeSpec?.label ?? ''}
255
+ onSave={handleSaveTitle}
256
+ nodeType={selectedNode.data.type}
257
+ nodeIcon={getNodeIcon(selectedNode.data.type)}
258
+ hasDocumentation={hasDocumentation(selectedNode.data.type)}
259
+ onShowDocumentation={handleShowDocumentation}
260
+ />
261
+
262
+ <VscodeToolbarContainer className={styles.toolbar}>
263
+ <VscodeTabs className={styles.tabs}>
264
+ <VscodeTabHeader>Properties</VscodeTabHeader>
265
+ <VscodeTabPanel>
266
+ {inputsWithControls.length > 0 && (
267
+ <div className={styles.panelHeader}>
268
+ <span className={styles.panelHeaderLabel}>Inputs</span>
269
+ <Icon
270
+ onClick={handleToggleAllInputs}
271
+ title="Toggle all input visibility"
272
+ >
273
+ {inputsWithControls.every(
274
+ (input) => hiddenInputs[input.name]
275
+ ) ? (
276
+ <EyeSolid />
277
+ ) : (
278
+ <EyeClosed />
279
+ )}
280
+ </Icon>
281
+ </div>
282
+ )}
283
+
284
+ {generatorNode &&
285
+ (
286
+ // Generators read per-graph state via useGraph(); bind them to the
287
+ // active session since this panel lives outside the graph tab.
288
+ <GraphProvider value={system}>
289
+ <SocketGenerators
290
+ generators={matchingGenerators}
291
+ generatorNode={generatorNode}
292
+ />
293
+ </GraphProvider>
294
+ )}
295
+ {inputsWithControls.length === 0 &&
296
+ matchingGenerators.length === 0 && (
297
+ <div className={styles.noInputs}>
298
+ This node has no editable inputs.
299
+ </div>
300
+ )}
301
+ <InputsGroup
302
+ inputs={inputsWithControls}
303
+ controls={controls}
304
+ defaultControl={defaultControl}
305
+ onValueChange={handleValueChange}
306
+ hiddenInputs={hiddenInputs}
307
+ onToggleInput={handleToggleInput}
308
+ />
309
+ </VscodeTabPanel>
310
+ <VscodeTabHeader>Outputs</VscodeTabHeader>
311
+ <VscodeTabPanel>
312
+ {outputsWithInfo.length > 0 && (
313
+ <div className={styles.panelHeader}>
314
+ <span className={styles.panelHeaderLabel}>Outputs</span>
315
+ <Icon
316
+ onClick={handleToggleAllOutputs}
317
+ title="Toggle all output visibility"
318
+ >
319
+ {outputsWithInfo.every(
320
+ (output) => hiddenOutputs[output.name]
321
+ ) ? (
322
+ <EyeSolid />
323
+ ) : (
324
+ <EyeClosed />
325
+ )}
326
+ </Icon>
327
+ </div>
328
+ )}
329
+ {outputsWithInfo.length === 0 && (
330
+ <div className={styles.noInputs}>This node has no outputs.</div>
331
+ )}
332
+ <OutputsGroup
333
+ outputs={outputsWithInfo}
334
+ hiddenOutputs={hiddenOutputs}
335
+ onToggleOutput={handleToggleOutput}
336
+ />
337
+ </VscodeTabPanel>
338
+ <VscodeTabHeader>Settings</VscodeTabHeader>
339
+ <VscodeTabPanel>
340
+ <NodeSettings
341
+ selectedNode={selectedNode}
342
+ onSave={handleSaveTitle}
343
+ />
344
+ </VscodeTabPanel>
345
+ </VscodeTabs>
346
+ </VscodeToolbarContainer>
347
+ </BasePanel>
348
+ );
349
+ }
@@ -0,0 +1,76 @@
1
+ import { useCallback } from 'react';
2
+ import type { IBehaveNode } from '@/types/nodes';
3
+ import type { GraphSession } from '@/system/graphSession';
4
+
5
+ export function useNodeHandlers(
6
+ system: GraphSession,
7
+ selectedNode: IBehaveNode | null
8
+ ) {
9
+ const handleSaveTitle = useCallback(
10
+ (annotationKey: string, rawValue: string) => {
11
+ if (!selectedNode) return;
12
+
13
+ const trimmed = rawValue.trim();
14
+
15
+ const currentAnnotations = (selectedNode as any)?.data
16
+ ?.annotations as unknown;
17
+ const isPlainObject =
18
+ !!currentAnnotations &&
19
+ typeof currentAnnotations === 'object' &&
20
+ !Array.isArray(currentAnnotations);
21
+
22
+ const nextAnnotations: Record<string, any> = isPlainObject
23
+ ? { ...(currentAnnotations as any) }
24
+ : {};
25
+ if (!trimmed) {
26
+ delete nextAnnotations[annotationKey];
27
+ } else {
28
+ nextAnnotations[annotationKey] = trimmed;
29
+ }
30
+
31
+ const updatedNode = {
32
+ ...selectedNode,
33
+ data: {
34
+ ...selectedNode.data,
35
+ annotations: nextAnnotations
36
+ }
37
+ };
38
+
39
+ system.nodeStore
40
+ .getState()
41
+ .setNodes((prev) =>
42
+ prev.map((n) => (n.id === selectedNode.id ? updatedNode : n))
43
+ );
44
+ },
45
+ [selectedNode, system.nodeStore]
46
+ );
47
+
48
+ const handleValueChange = useCallback(
49
+ (inputName: string, newValue: any) => {
50
+ if (!selectedNode) return;
51
+
52
+ const updatedNode = {
53
+ ...selectedNode,
54
+ data: {
55
+ ...selectedNode.data,
56
+ ports: {
57
+ ...selectedNode.data.ports,
58
+ [inputName]: newValue
59
+ }
60
+ }
61
+ };
62
+
63
+ system.nodeStore
64
+ .getState()
65
+ .setNodes((prev) =>
66
+ prev.map((n) => (n.id === selectedNode.id ? updatedNode : n))
67
+ );
68
+ },
69
+ [selectedNode, system.nodeStore]
70
+ );
71
+
72
+ return {
73
+ handleSaveTitle,
74
+ handleValueChange
75
+ };
76
+ }
@@ -0,0 +1,153 @@
1
+ import { useMemo } from 'react';
2
+ import { useStore } from 'zustand';
3
+ import { configureSockets } from '@/util/sockets';
4
+ import { isHandleConnected } from '@/util/isHandleConnected';
5
+ import type { IBehaveNode } from '@/types/nodes';
6
+ import type { GraphSession } from '@/system/graphSession';
7
+
8
+ export function useNodeInputsData(system: GraphSession) {
9
+ const selectedNodeId = useStore(
10
+ system.selectionStore,
11
+ (x) => x.selectedNodeId
12
+ );
13
+ const nodes = useStore(system.nodeStore, (x) => x.nodes);
14
+ const edges = useStore(system.edgeStore, (x) => x.edges);
15
+ const controls = useStore(system.controlStore, (x) => x.controls);
16
+ const defaultControl = useStore(system.controlStore, (x) => x.defaultControl);
17
+ const generators = useStore(
18
+ system.editor.socketGeneratorStore,
19
+ (s) => s.generators
20
+ );
21
+ const generatorLocation = useStore(
22
+ system.editor.systemSettings,
23
+ (s) => s.generatorLocation
24
+ );
25
+
26
+ const allSpecsJson = useStore(system.editor.specStore, (x) => x.specs);
27
+
28
+ const selectedNodes = useMemo(() => {
29
+ return nodes.filter(
30
+ (n) => (n as IBehaveNode).type == 'behaveNode' && n.selected
31
+ );
32
+ }, [nodes]);
33
+
34
+ const selectedNode = useMemo(() => {
35
+ if (!selectedNodeId) return null;
36
+ return nodes.find(
37
+ (n) => (n as IBehaveNode).type === 'behaveNode' && n.id === selectedNodeId
38
+ ) as IBehaveNode | null;
39
+ }, [selectedNodeId, nodes]);
40
+
41
+ const nodeSpec = useMemo(() => {
42
+ if (!selectedNode) return null;
43
+ return allSpecsJson.find((spec) => spec.type === selectedNode.data.type);
44
+ }, [selectedNode, allSpecsJson]);
45
+
46
+ const inputsWithControls = useMemo(() => {
47
+ if (!selectedNode || !nodeSpec) return [];
48
+
49
+ const { pairs, valueInputs } = configureSockets(
50
+ selectedNode.data.configuration,
51
+ nodeSpec,
52
+ selectedNode.data.dynamicPorts
53
+ );
54
+ const inputs: Array<{
55
+ name: string;
56
+ valueType: string;
57
+ defaultValue?: any;
58
+ choices?: Array<{ text: string; value: any }>;
59
+ value: any;
60
+ connected: boolean;
61
+ }> = [];
62
+
63
+ for (const [input] of pairs) {
64
+ if (input && input.valueType !== 'flow') {
65
+ inputs.push({
66
+ name: input.name,
67
+ valueType: input.valueType,
68
+ defaultValue: input.defaultValue,
69
+ choices: input.choices,
70
+ value: selectedNode.data.ports?.[input.name] ?? input.defaultValue,
71
+ connected: isHandleConnected(
72
+ edges,
73
+ selectedNode.id,
74
+ input.name,
75
+ 'target'
76
+ )
77
+ });
78
+ }
79
+ }
80
+
81
+ for (const input of valueInputs) {
82
+ inputs.push({
83
+ name: input.name,
84
+ valueType: input.valueType,
85
+ defaultValue: input.defaultValue,
86
+ choices: input.choices,
87
+ value: selectedNode.data.ports?.[input.name] ?? input.defaultValue,
88
+ connected: isHandleConnected(
89
+ edges,
90
+ selectedNode.id,
91
+ input.name,
92
+ 'target'
93
+ )
94
+ });
95
+ }
96
+
97
+ return inputs;
98
+ }, [selectedNode, nodeSpec, edges]);
99
+
100
+ const outputsWithInfo = useMemo(() => {
101
+ if (!selectedNode || !nodeSpec) return [];
102
+
103
+ // `valueOutputs` already contains every non-flow output. (The `pairs` from
104
+ // configureSockets also carry these value outputs in their second slot ,
105
+ // iterating both would render each value output twice and collide on the
106
+ // React key, e.g. `provider` / `agent`.)
107
+ const { valueOutputs } = configureSockets(
108
+ selectedNode.data.configuration,
109
+ nodeSpec,
110
+ selectedNode.data.dynamicPorts
111
+ );
112
+
113
+ return valueOutputs.map((output) => ({
114
+ name: output.name,
115
+ valueType: output.valueType,
116
+ connected: isHandleConnected(
117
+ edges,
118
+ selectedNode.id,
119
+ output.name,
120
+ 'source'
121
+ )
122
+ }));
123
+ }, [selectedNode, nodeSpec, edges]);
124
+
125
+ const matchingGenerators = useMemo(() => {
126
+ if (!nodeSpec || generatorLocation !== 'panel') return [];
127
+ return generators.filter((x) => x.check(nodeSpec));
128
+ }, [nodeSpec, generators, generatorLocation]);
129
+
130
+ const generatorNode = useMemo(() => {
131
+ if (!selectedNode || !nodeSpec) return null;
132
+ return {
133
+ id: selectedNode.id,
134
+ data: selectedNode.data,
135
+ spec: nodeSpec,
136
+ selected: !!selectedNode.selected
137
+ };
138
+ }, [selectedNode, nodeSpec]);
139
+
140
+ return {
141
+ allSpecsJson,
142
+ selectedNodes,
143
+ selectedNode,
144
+ nodeSpec,
145
+ inputsWithControls,
146
+ outputsWithInfo,
147
+
148
+ matchingGenerators,
149
+ generatorNode,
150
+ controls,
151
+ defaultControl
152
+ };
153
+ }
@@ -0,0 +1,115 @@
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { useActiveGraph } from '@/system/provider';
3
+ import { useStore } from 'zustand';
4
+ import { NodePicker } from '@/components/contextMenus/NodePicker';
5
+ import type { ExtendedNodeSpecJSON } from '@/components/contextMenus/NodePicker';
6
+ import type { XYPosition } from 'reactflow';
7
+ import { v4 as uuidv4 } from 'uuid';
8
+ import {
9
+ removeTabFromLayout,
10
+ addFloatingTab,
11
+ findTabInLayout
12
+ } from '@/components/layoutController/utils';
13
+
14
+ export function NodePickerPanel() {
15
+ const sys = useActiveGraph()!;
16
+ const specJson = useStore(sys.editor.specStore, (x) => x.specs);
17
+ const documentation = useStore(sys.editor.documentationStore, (x) => x.docs);
18
+ const reactflowRef = useStore(sys.refStore, (x) => x.refs.reactflow);
19
+ const screenPosition = useStore(
20
+ sys.refStore,
21
+ (x) => x.refs.nodePickerPosition
22
+ );
23
+
24
+ // Convert screen position to flow position
25
+ const flowPosition = useMemo(() => {
26
+ if (reactflowRef && screenPosition && reactflowRef.screenToFlowPosition) {
27
+ return reactflowRef.screenToFlowPosition(screenPosition);
28
+ }
29
+ return { x: 0, y: 0 };
30
+ }, [reactflowRef, screenPosition]);
31
+
32
+ // For now, we'll use undefined which means no filtering
33
+ const nodePickFilters = undefined;
34
+ const closeNodePicker = useCallback(() => {
35
+ const currentLayout = sys.editor.tabStore.getState().layout;
36
+ const newLayout = removeTabFromLayout(currentLayout, 'nodepicker');
37
+ sys.editor.tabStore.getState().setLayout(newLayout);
38
+ }, [sys]);
39
+
40
+ const handleShowDocumentation = useCallback(
41
+ (nodeType: string) => {
42
+ // Set the selected documentation type
43
+ sys.refStore.getState().setRef('selectedDocumentationType', nodeType);
44
+
45
+ // Open documentation browser panel
46
+ const currentLayout = sys.editor.tabStore.getState().layout;
47
+
48
+ // Close existing doc browser if open
49
+ const existingPanel = findTabInLayout(currentLayout, 'docbrowser');
50
+ let layoutToUse = currentLayout;
51
+ if (existingPanel) {
52
+ layoutToUse = removeTabFromLayout(currentLayout, 'docbrowser');
53
+ }
54
+
55
+ // Create new floating panel
56
+ const tabData = {
57
+ id: 'docbrowser'
58
+ };
59
+
60
+ const newLayout = addFloatingTab(layoutToUse, tabData, {
61
+ left: 100,
62
+ top: 100,
63
+ width: 600,
64
+ height: 700
65
+ });
66
+
67
+ sys.editor.tabStore.getState().setLayout(newLayout);
68
+ },
69
+ [sys]
70
+ );
71
+
72
+ const handleAddNode = useCallback(
73
+ (spec: ExtendedNodeSpecJSON, position: XYPosition) => {
74
+ const newNode = {
75
+ id: uuidv4(),
76
+ type: spec.nodeType ?? 'behaveNode',
77
+ position,
78
+ data: {
79
+ configuration: {},
80
+ type: spec.type,
81
+ ports: {}
82
+ }
83
+ };
84
+
85
+ sys.undoManager.execute({
86
+ name: `Add node (${spec.type})`,
87
+ execute: () => {
88
+ sys.nodeStore.getState().addNode(newNode);
89
+ },
90
+ undo: () => {
91
+ sys.nodeStore
92
+ .getState()
93
+ .setNodes((existing) =>
94
+ existing.filter((n) => n.id !== newNode.id)
95
+ );
96
+ }
97
+ });
98
+
99
+ closeNodePicker();
100
+ },
101
+ [closeNodePicker, sys]
102
+ );
103
+
104
+ return (
105
+ <NodePicker
106
+ position={flowPosition}
107
+ filters={nodePickFilters}
108
+ onPickNode={handleAddNode}
109
+ onClose={closeNodePicker}
110
+ specJSON={specJson}
111
+ documentation={documentation}
112
+ onShowDocumentation={handleShowDocumentation}
113
+ />
114
+ );
115
+ }